From 814abf4725576979a94208508f6fe4dd76b42506 Mon Sep 17 00:00:00 2001 From: lysec Date: Thu, 16 Oct 2025 12:25:22 +0200 Subject: [PATCH] LocationTab: add toggle to fully disable weather (as requested in #488) --- Assets/Translations/de.json | 7 +++++++ Assets/Translations/en.json | 18 +++++++++++----- Assets/Translations/es.json | 7 +++++++ Assets/Translations/fr.json | 7 +++++++ Assets/Translations/pt.json | 7 +++++++ Assets/Translations/zh-CN.json | 7 +++++++ Assets/settings-default.json | 1 + Commons/Settings.qml | 1 + Modules/Bar/Calendar/CalendarPanel.qml | 11 +++++++--- Modules/Bar/Widgets/Battery.qml | 22 +++++++++++++++----- Modules/ControlCenter/Cards/WeatherCard.qml | 2 +- Modules/ControlCenter/ControlCenterPanel.qml | 10 ++++++--- Modules/LockScreen/LockScreen.qml | 15 +++++++++++-- Modules/Settings/Tabs/LocationTab.qml | 9 ++++++++ Services/LocationService.qml | 6 +++++- 15 files changed, 110 insertions(+), 20 deletions(-) diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index 34bd7764..2be6197b 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -576,6 +576,10 @@ "label": "Wetter", "description": "Bevorzugte Temperatureinheit wählen." }, + "enabled": { + "label": "Wetter aktivieren", + "description": "Wetterinformationen in der gesamten Benutzeroberfläche anzeigen und Wetterdaten abrufen. Wenn deaktiviert, werden alle Wetterelemente ausgeblendet und es werden keine Netzwerkanfragen gestellt." + }, "fahrenheit": { "label": "Temperatur in Fahrenheit (°F) anzeigen", "description": "Temperatur in Fahrenheit statt Celsius anzeigen." @@ -1203,6 +1207,9 @@ "calendar": { "panel": { "week": "Woche" + }, + "weather": { + "loading": "Wetter wird geladen…" } }, "tooltips": { diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index 5603af49..915b75d1 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -576,6 +576,10 @@ "label": "Weather", "description": "Choose your preferred temperature unit." }, + "enabled": { + "label": "Enable weather", + "description": "Show weather information throughout the interface and fetch weather data. When disabled, all weather elements will be hidden and no network requests will be made." + }, "fahrenheit": { "label": "Display temperature in Fahrenheit (°F)", "description": "Display temperature in Fahrenheit instead of Celsius." @@ -1183,11 +1187,7 @@ "scan-again": "Scan again" } }, - "calendar": { - "panel": { - "week": "Week" - } - }, + "tooltips": { "refresh": "Refresh", "close": "Close", @@ -1244,6 +1244,14 @@ "clock": { "tooltip": "Open calendar" }, + "calendar": { + "panel": { + "week": "Week" + }, + "weather": { + "loading": "Loading weather…" + } + }, "dock": { "menu": { "focus": "Focus", diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index 67bb2d0f..72251b3f 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -576,6 +576,10 @@ "label": "Clima", "description": "Elige tu unidad de temperatura preferida." }, + "enabled": { + "label": "Activar clima", + "description": "Mostrar información del clima en toda la interfaz y obtener datos meteorológicos. Cuando está desactivado, todos los elementos del clima estarán ocultos y no se realizarán solicitudes de red." + }, "fahrenheit": { "label": "Mostrar temperatura en Fahrenheit (°F)", "description": "Muestra la temperatura en Fahrenheit en lugar de Celsius." @@ -1186,6 +1190,9 @@ "calendar": { "panel": { "week": "Semana" + }, + "weather": { + "loading": "Cargando el clima…" } }, "tooltips": { diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index 3533f3a1..8399a63a 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -576,6 +576,10 @@ "label": "Météo", "description": "Choisissez votre unité de température préférée." }, + "enabled": { + "label": "Activer la météo", + "description": "Afficher les informations météorologiques dans toute l'interface et récupérer les données météo. Lorsque désactivé, tous les éléments météo seront masqués et aucune requête réseau ne sera effectuée." + }, "fahrenheit": { "label": "Afficher la température en Fahrenheit (°F)", "description": "Afficher la température en Fahrenheit au lieu de Celsius." @@ -1186,6 +1190,9 @@ "calendar": { "panel": { "week": "Semaine" + }, + "weather": { + "loading": "Chargement de la météo…" } }, "tooltips": { diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index 61eba991..c4c3ea52 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -538,6 +538,10 @@ "label": "Clima", "description": "Escolha sua unidade de temperatura preferida." }, + "enabled": { + "label": "Ativar clima", + "description": "Mostrar informações meteorológicas em toda a interface e buscar dados do clima. Quando desativado, todos os elementos do clima serão ocultados e nenhuma solicitação de rede será feita." + }, "fahrenheit": { "label": "Exibir temperatura em Fahrenheit (°F)", "description": "Exibe a temperatura em Fahrenheit em vez de Celsius." @@ -1186,6 +1190,9 @@ "calendar": { "panel": { "week": "Semana" + }, + "weather": { + "loading": "Carregando o clima…" } }, "tooltips": { diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index 20aa587b..0116a5da 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -576,6 +576,10 @@ "label": "天气", "description": "选择您喜欢的温度单位。" }, + "enabled": { + "label": "启用天气", + "description": "在整个界面中显示天气信息并获取天气数据。禁用后,所有天气元素将被隐藏,不会进行网络请求。" + }, "fahrenheit": { "label": "以华氏度显示温度 (°F)", "description": "以华氏度而非摄氏度显示温度。" @@ -1186,6 +1190,9 @@ "calendar": { "panel": { "week": "周" + }, + "weather": { + "loading": "正在加载天气…" } }, "tooltips": { diff --git a/Assets/settings-default.json b/Assets/settings-default.json index 8d3d6ce8..dbb01840 100644 --- a/Assets/settings-default.json +++ b/Assets/settings-default.json @@ -69,6 +69,7 @@ }, "location": { "name": "Tokyo", + "weatherEnabled": true, "useFahrenheit": false, "use12hourFormat": false, "showWeekNumberInCalendar": false diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 22a1c2ff..271cecb7 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -195,6 +195,7 @@ Singleton { // location property JsonObject location: JsonObject { property string name: defaultLocation + property bool weatherEnabled: true property bool useFahrenheit: false property bool use12hourFormat: false property bool showWeekNumberInCalendar: false diff --git a/Modules/Bar/Calendar/CalendarPanel.qml b/Modules/Bar/Calendar/CalendarPanel.qml index 68b27ab3..b882324d 100644 --- a/Modules/Bar/Calendar/CalendarPanel.qml +++ b/Modules/Bar/Calendar/CalendarPanel.qml @@ -24,7 +24,7 @@ NPanel { readonly property int firstDayOfWeek: Qt.locale().firstDayOfWeek property bool isCurrentMonth: checkIsCurrentMonth() - readonly property bool weatherReady: (LocationService.data.weather !== null) + readonly property bool weatherReady: Settings.data.location.weatherEnabled && (LocationService.data.weather !== null) function checkIsCurrentMonth() { return (Time.date.getMonth() === grid.month) && (Time.date.getFullYear() === grid.year) @@ -78,12 +78,13 @@ NPanel { // Weather icon and temperature ColumnLayout { + visible: Settings.data.location.weatherEnabled && weatherReady Layout.alignment: Qt.AlignVCenter spacing: Style.marginXXS NIcon { Layout.alignment: Qt.AlignHCenter - icon: weatherReady ? LocationService.weatherSymbolFromCode(LocationService.data.weather.current_weather.weathercode) : "cloud" + icon: Settings.data.location.weatherEnabled && weatherReady ? LocationService.weatherSymbolFromCode(LocationService.data.weather.current_weather.weathercode) : "" pointSize: Style.fontSizeXXL color: Color.mOnPrimary } @@ -91,6 +92,8 @@ NPanel { NText { Layout.alignment: Qt.AlignHCenter text: { + if (!Settings.data.location.weatherEnabled) + return "" if (!weatherReady) return "" var temp = LocationService.data.weather.current_weather.temperature @@ -168,6 +171,8 @@ NPanel { NText { text: { + if (!Settings.data.location.weatherEnabled) + return "" if (!weatherReady) return I18n.tr("calendar.weather.loading") const chunks = Settings.data.location.name.split(",") @@ -323,7 +328,7 @@ NPanel { } } RowLayout { - visible: !weatherReady + visible: Settings.data.location.weatherEnabled && !weatherReady Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter NBusyIndicator {} diff --git a/Modules/Bar/Widgets/Battery.qml b/Modules/Bar/Widgets/Battery.qml index ec307841..d29c817e 100644 --- a/Modules/Bar/Widgets/Battery.qml +++ b/Modules/Bar/Widgets/Battery.qml @@ -106,17 +106,27 @@ Item { return I18n.tr("battery.no-battery-detected") } if (battery.timeToEmpty > 0) { - lines.push(I18n.tr("battery.time-left", {"time": Time.formatVagueHumanReadableDuration(battery.timeToEmpty)})) + lines.push(I18n.tr("battery.time-left", { + "time": Time.formatVagueHumanReadableDuration(battery.timeToEmpty) + })) } if (battery.timeToFull > 0) { - lines.push(I18n.tr("battery.time-until-full", {"time": Time.formatVagueHumanReadableDuration(battery.timeToFull)})) + lines.push(I18n.tr("battery.time-until-full", { + "time": Time.formatVagueHumanReadableDuration(battery.timeToFull) + })) } if (battery.changeRate !== undefined) { const rate = battery.changeRate if (rate > 0) { - lines.push(charging ? I18n.tr("battery.charging-rate", {"rate": rate.toFixed(2)}) : I18n.tr("battery.discharging-rate", {"rate": rate.toFixed(2)})) + lines.push(charging ? I18n.tr("battery.charging-rate", { + "rate": rate.toFixed(2) + }) : I18n.tr("battery.discharging-rate", { + "rate": rate.toFixed(2) + })) } else if (rate < 0) { - lines.push(I18n.tr("battery.discharging-rate", {"rate": Math.abs(rate).toFixed(2)})) + lines.push(I18n.tr("battery.discharging-rate", { + "rate": Math.abs(rate).toFixed(2) + })) } else { // Rate is 0 - check if plugged in (charging state) or idle lines.push(charging ? I18n.tr("battery.plugged-in") : I18n.tr("battery.idle")) @@ -125,7 +135,9 @@ Item { lines.push(charging ? I18n.tr("battery.charging") : I18n.tr("battery.discharging")) } if (battery.healthPercentage !== undefined && battery.healthPercentage > 0) { - lines.push(I18n.tr("battery.health", {"percent": Math.round(battery.healthPercentage)})) + lines.push(I18n.tr("battery.health", { + "percent": Math.round(battery.healthPercentage) + })) } return lines.join("\n") } diff --git a/Modules/ControlCenter/Cards/WeatherCard.qml b/Modules/ControlCenter/Cards/WeatherCard.qml index e6b366ff..4b5fe5df 100644 --- a/Modules/ControlCenter/Cards/WeatherCard.qml +++ b/Modules/ControlCenter/Cards/WeatherCard.qml @@ -9,7 +9,7 @@ import qs.Widgets NBox { id: root - readonly property bool weatherReady: (LocationService.data.weather !== null) + readonly property bool weatherReady: Settings.data.location.weatherEnabled && (LocationService.data.weather !== null) ColumnLayout { id: content diff --git a/Modules/ControlCenter/ControlCenterPanel.qml b/Modules/ControlCenter/ControlCenterPanel.qml index 45cf6a9c..fcc13cb8 100644 --- a/Modules/ControlCenter/ControlCenterPanel.qml +++ b/Modules/ControlCenter/ControlCenterPanel.qml @@ -17,9 +17,13 @@ NPanel { var count = 0 for (var i = 0; i < Settings.data.controlCenter.cards.length; i++) { const card = Settings.data.controlCenter.cards[i] - if (!card.enabled) { + if (!card.enabled) continue - } + + const contributes = (card.id !== "weather-card" || Settings.data.location.weatherEnabled) + if (!contributes) + continue + count++ switch (card.id) { case "profile-card": @@ -72,7 +76,7 @@ NPanel { Repeater { model: Settings.data.controlCenter.cards Loader { - active: modelData.enabled + active: modelData.enabled && (modelData.id !== "weather-card" || Settings.data.location.weatherEnabled) visible: active Layout.fillWidth: true Layout.preferredHeight: { diff --git a/Modules/LockScreen/LockScreen.qml b/Modules/LockScreen/LockScreen.qml index 8b646e57..68d1c114 100644 --- a/Modules/LockScreen/LockScreen.qml +++ b/Modules/LockScreen/LockScreen.qml @@ -548,16 +548,18 @@ Loader { anchors.margins: 14 spacing: 14 - // Weather section + // Top info row RowLayout { Layout.fillWidth: true Layout.preferredHeight: 65 spacing: 18 - visible: !Settings.data.general.compactLockScreen && LocationService.coordinatesReady && LocationService.data.weather !== null + visible: !Settings.data.general.compactLockScreen // Media widget with visualizer Rectangle { Layout.preferredWidth: 220 + // Expand to take remaining space when weather is hidden + Layout.fillWidth: !(Settings.data.location.weatherEnabled && LocationService.data.weather !== null) Layout.preferredHeight: 50 radius: 25 color: Color.transparent @@ -666,6 +668,7 @@ Loader { // Current weather RowLayout { + visible: Settings.data.location.weatherEnabled && LocationService.data.weather !== null Layout.preferredWidth: 180 spacing: 8 @@ -738,6 +741,7 @@ Loader { // 3-day forecast RowLayout { + visible: Settings.data.location.weatherEnabled && LocationService.data.weather !== null Layout.preferredWidth: 260 Layout.rightMargin: 8 spacing: 4 @@ -785,9 +789,16 @@ Loader { } } + Item { + Layout.fillWidth: true + visible: !(Settings.data.location.weatherEnabled && LocationService.data.weather !== null) + Layout.preferredWidth: visible ? 1 : 0 + } + // Battery and Keyboard Layout (full mode only) ColumnLayout { Layout.preferredWidth: 60 + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter spacing: 8 // Battery diff --git a/Modules/Settings/Tabs/LocationTab.qml b/Modules/Settings/Tabs/LocationTab.qml index b4ccfe4f..7b6c340b 100644 --- a/Modules/Settings/Tabs/LocationTab.qml +++ b/Modules/Settings/Tabs/LocationTab.qml @@ -71,11 +71,20 @@ ColumnLayout { description: I18n.tr("settings.location.weather.section.description") } + NToggle { + label: I18n.tr("settings.location.weather.enabled.label") + description: I18n.tr("settings.location.weather.enabled.description") + checked: Settings.data.location.weatherEnabled + onToggled: checked => Settings.data.location.weatherEnabled = checked + } + NToggle { label: I18n.tr("settings.location.weather.fahrenheit.label") description: I18n.tr("settings.location.weather.fahrenheit.description") checked: Settings.data.location.useFahrenheit onToggled: checked => Settings.data.location.useFahrenheit = checked + enabled: Settings.data.location.weatherEnabled + opacity: Settings.data.location.weatherEnabled ? 1.0 : 0.5 } } diff --git a/Services/LocationService.qml b/Services/LocationService.qml index 79b4aa58..0e3c0c9b 100644 --- a/Services/LocationService.qml +++ b/Services/LocationService.qml @@ -69,7 +69,7 @@ Singleton { Timer { id: updateTimer interval: 20 * 1000 - running: true + running: Settings.data.location.weatherEnabled repeat: true onTriggered: { updateWeather() @@ -114,6 +114,10 @@ Singleton { // -------------------------------- function updateWeather() { + if (!Settings.data.location.weatherEnabled) { + return + } + if (isFetchingWeather) { Logger.warn("Location", "Weather is still fetching") return