feat(settings): add location search to theme & gamma coordinates (#3010)

* feat(settings): add location search to theme & gamma coordinates

* fix(settings): refresh coordinate fields after manual edits
This commit is contained in:
Curious authored and GitHub committed 2026-08-07 13:00:37 -04:00
1 parent a1ba5cf9ad
commit 40a9ca348c
3 files changed
+165 -186

No files matched your search

@@ -320,100 +320,10 @@ Item {
}
}
Column {
property bool isLocationMode: SessionData.nightModeAutoMode === "location"
visible: isLocationMode
spacing: Theme.spacingM
SettingsLocationSection {
width: parent.width
DankToggle {
id: ipLocationToggle
width: parent.width
text: I18n.tr("Use IP Location")
description: I18n.tr("Automatically detect location based on IP address")
checked: SessionData.nightModeUseIPLocation || false
onToggled: checked => {
SessionData.setNightModeUseIPLocation(checked);
}
Connections {
target: SessionData
function onNightModeUseIPLocationChanged() {
ipLocationToggle.checked = SessionData.nightModeUseIPLocation;
}
}
}
Column {
width: parent.width
spacing: Theme.spacingM
leftPadding: Theme.spacingM
visible: !SessionData.nightModeUseIPLocation
StyledText {
text: I18n.tr("Manual Coordinates")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
}
Row {
spacing: Theme.spacingL
Column {
spacing: Theme.spacingXS
StyledText {
text: I18n.tr("Latitude")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
DankTextField {
width: 120
height: 40
text: SessionData.latitude.toString()
placeholderText: "0.0"
onEditingFinished: {
const lat = parseFloat(text);
if (!isNaN(lat) && lat >= -90 && lat <= 90 && lat !== SessionData.latitude) {
SessionData.setLatitude(lat);
}
}
}
}
Column {
spacing: Theme.spacingXS
StyledText {
text: I18n.tr("Longitude")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
DankTextField {
width: 120
height: 40
text: SessionData.longitude.toString()
placeholderText: "0.0"
onEditingFinished: {
const lon = parseFloat(text);
if (!isNaN(lon) && lon >= -180 && lon <= 180 && lon !== SessionData.longitude) {
SessionData.setLongitude(lon);
}
}
}
}
}
StyledText {
text: I18n.tr("Uses sunrise/sunset times to automatically adjust night mode based on your location.")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: parent.width - parent.leftPadding
wrapMode: Text.WordWrap
}
}
visible: SessionData.nightModeAutoMode === "location"
description: I18n.tr("Uses sunrise/sunset times to automatically adjust night mode based on your location.")
}
Rectangle {
+3 -93
View File
@@ -1486,101 +1486,11 @@ Item {
}
}
Column {
SettingsLocationSection {
width: parent.width
spacing: Theme.spacingM
visible: SessionData.themeModeAutoMode === "location" && !SessionData.themeModeShareGammaSettings
DankToggle {
id: themeModeIpLocationToggle
width: parent.width
text: I18n.tr("Use IP Location")
checked: SessionData.nightModeUseIPLocation || false
onToggled: checked => {
SessionData.setNightModeUseIPLocation(checked);
}
Connections {
target: SessionData
function onNightModeUseIPLocationChanged() {
themeModeIpLocationToggle.checked = SessionData.nightModeUseIPLocation;
}
}
}
Column {
width: parent.width
spacing: Theme.spacingM
visible: !SessionData.nightModeUseIPLocation
StyledText {
text: I18n.tr("Manual Coordinates")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
horizontalAlignment: Text.AlignHCenter
width: parent.width
}
Row {
spacing: Theme.spacingL
anchors.horizontalCenter: parent.horizontalCenter
Column {
spacing: Theme.spacingXS
StyledText {
text: I18n.tr("Latitude")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
DankTextField {
width: 120
height: 40
text: SessionData.latitude.toString()
placeholderText: "0.0"
onEditingFinished: {
const lat = parseFloat(text);
if (!isNaN(lat) && lat >= -90 && lat <= 90 && lat !== SessionData.latitude) {
SessionData.setLatitude(lat);
}
}
}
}
Column {
spacing: Theme.spacingXS
StyledText {
text: I18n.tr("Longitude")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
DankTextField {
width: 120
height: 40
text: SessionData.longitude.toString()
placeholderText: "0.0"
onEditingFinished: {
const lon = parseFloat(text);
if (!isNaN(lon) && lon >= -180 && lon <= 180 && lon !== SessionData.longitude) {
SessionData.setLongitude(lon);
}
}
}
}
}
StyledText {
text: I18n.tr("Uses sunrise/sunset times based on your location.")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: parent.width
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
}
}
centered: true
description: I18n.tr("Uses sunrise/sunset times based on your location.")
}
StyledText {
@@ -0,0 +1,159 @@
pragma ComponentBehavior: Bound
import QtQuick
import qs.Common
import qs.Widgets
Column {
id: root
property string description: I18n.tr("Uses sunrise/sunset times based on your location.")
property bool centered: false
width: parent.width
spacing: Theme.spacingM
DankToggle {
id: ipLocationToggle
width: parent.width
text: I18n.tr("Use IP Location")
description: I18n.tr("Automatically detect location based on IP address")
checked: SessionData.nightModeUseIPLocation || false
onToggled: checked => {
SessionData.setNightModeUseIPLocation(checked);
}
Connections {
target: SessionData
function onNightModeUseIPLocationChanged() {
ipLocationToggle.checked = SessionData.nightModeUseIPLocation;
}
}
}
Column {
width: parent.width
spacing: Theme.spacingM
visible: !SessionData.nightModeUseIPLocation
StyledText {
text: I18n.tr("Manual Coordinates")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
width: parent.width
horizontalAlignment: root.centered ? Text.AlignHCenter : Text.AlignLeft
}
Row {
spacing: Theme.spacingL
anchors.horizontalCenter: root.centered ? parent.horizontalCenter : undefined
Column {
spacing: Theme.spacingXS
StyledText {
text: I18n.tr("Latitude")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
DankTextField {
id: latitudeField
width: 120
height: 40
text: ""
placeholderText: "0.0"
Component.onCompleted: {
text = SessionData.latitude.toString();
}
Connections {
target: SessionData
function onLatitudeChanged() {
latitudeField.text = SessionData.latitude.toString();
}
}
onEditingFinished: {
const lat = parseFloat(text);
if (!isNaN(lat) && lat >= -90 && lat <= 90 && lat !== SessionData.latitude) {
SessionData.setLatitude(lat);
}
}
}
}
Column {
spacing: Theme.spacingXS
StyledText {
text: I18n.tr("Longitude")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
DankTextField {
id: longitudeField
width: 120
height: 40
text: ""
placeholderText: "0.0"
Component.onCompleted: {
text = SessionData.longitude.toString();
}
Connections {
target: SessionData
function onLongitudeChanged() {
longitudeField.text = SessionData.longitude.toString();
}
}
onEditingFinished: {
const lon = parseFloat(text);
if (!isNaN(lon) && lon >= -180 && lon <= 180 && lon !== SessionData.longitude) {
SessionData.setLongitude(lon);
}
}
}
}
}
StyledText {
text: I18n.tr("Location Search")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
font.weight: Font.Medium
}
DankLocationSearch {
width: parent.width
onLocationSelected: (displayName, coordinates) => {
const coords = coordinates.split(',');
if (coords.length >= 2) {
const lat = parseFloat(coords[0]);
const lon = parseFloat(coords[1]);
if (!isNaN(lat) && lat >= -90 && lat <= 90) {
SessionData.setLatitude(lat);
latitudeField.text = coords[0].trim();
}
if (!isNaN(lon) && lon >= -180 && lon <= 180) {
SessionData.setLongitude(lon);
longitudeField.text = coords[1].trim();
}
}
}
}
StyledText {
text: root.description
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: parent.width
wrapMode: Text.WordWrap
horizontalAlignment: root.centered ? Text.AlignHCenter : Text.AlignLeft
}
}
}