From ca72a5ca8f05b93fe41ddf6d2229e5ff891e7cc0 Mon Sep 17 00:00:00 2001 From: ItsLemmy Date: Thu, 30 Oct 2025 14:02:42 -0400 Subject: [PATCH] Calendar: conditional weather card - wip --- Assets/Translations/de.json | 4 + Assets/Translations/en.json | 4 + Assets/Translations/es.json | 4 + Assets/Translations/pt.json | 4 + Assets/Translations/zh-CN.json | 4 + Commons/Settings.qml | 1 + Modules/Bar/Calendar/CalendarPanel.qml | 129 +++++--------------- Modules/Bar/Calendar/ClockLoader.qml | 5 +- Modules/ControlCenter/Cards/WeatherCard.qml | 6 +- Modules/Settings/Tabs/LocationTab.qml | 9 ++ Modules/SetupWizard/SetupDockStep.qml | 2 +- 11 files changed, 66 insertions(+), 106 deletions(-) diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index 0db25861..00381abc 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -649,6 +649,10 @@ "fahrenheit": { "label": "Temperatur in Fahrenheit (°F) anzeigen", "description": "Temperatur in Fahrenheit statt Celsius anzeigen." + }, + "show-in-calendar": { + "description": "Zeige die tägliche Wettervorhersage direkt in deiner Kalenderansicht an.", + "label": "Wetter im Kalender anzeigen" } }, "date-time": { diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index be483282..da81a679 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -649,6 +649,10 @@ "fahrenheit": { "label": "Display temperature in Fahrenheit (°F)", "description": "Display temperature in Fahrenheit instead of Celsius." + }, + "show-in-calendar": { + "label": "Display weather in calendar", + "description": "Show the daily weather forecast directly in your calendar view." } }, "date-time": { diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index 4e0286d2..4585cd11 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -649,6 +649,10 @@ "fahrenheit": { "label": "Mostrar temperatura en Fahrenheit (°F)", "description": "Muestra la temperatura en Fahrenheit en lugar de Celsius." + }, + "show-in-calendar": { + "description": "Muestra el pronóstico del tiempo diario directamente en la vista de tu calendario.", + "label": "Mostrar el clima en el calendario" } }, "date-time": { diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index bb5f8786..3da19f27 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -611,6 +611,10 @@ "fahrenheit": { "label": "Exibir temperatura em Fahrenheit (°F)", "description": "Exibe a temperatura em Fahrenheit em vez de Celsius." + }, + "show-in-calendar": { + "description": "Mostre a previsão do tempo diária diretamente na sua visualização de calendário.", + "label": "Exibir clima no calendário" } }, "date-time": { diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index 90826432..9744a2aa 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -649,6 +649,10 @@ "fahrenheit": { "label": "以华氏度显示温度 (°F)", "description": "以华氏度而非摄氏度显示温度。" + }, + "show-in-calendar": { + "description": "直接在您的日历视图中显示每日天气预报。", + "label": "在日历中显示天气" } }, "date-time": { diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 29b803ff..6d57672b 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -203,6 +203,7 @@ Singleton { property bool use12hourFormat: false property bool showWeekNumberInCalendar: false property bool showCalendarEvents: true + property bool showCalendarWeather: false property bool analogClockInCalendar: false } diff --git a/Modules/Bar/Calendar/CalendarPanel.qml b/Modules/Bar/Calendar/CalendarPanel.qml index 1baeb407..c75b5973 100644 --- a/Modules/Bar/Calendar/CalendarPanel.qml +++ b/Modules/Bar/Calendar/CalendarPanel.qml @@ -4,6 +4,7 @@ import QtQuick.Layouts import Quickshell import Quickshell.Wayland import qs.Commons +import qs.Modules.ControlCenter.Cards import qs.Services import qs.Widgets @@ -14,7 +15,7 @@ NPanel { readonly property var now: Time.date preferredWidth: (Settings.data.location.showWeekNumberInCalendar ? 400 : 380) * Style.uiScaleRatio - preferredHeight: 520 * Style.uiScaleRatio + preferredHeight: (Settings.data.location.showCalendarWeather ? 600 : 480) * Style.uiScaleRatio panelKeyboardFocus: true // Helper function to calculate ISO week number @@ -64,22 +65,25 @@ NPanel { } } - // Combined blue banner with date/time and weather summary + // Banner with date/time/clock Rectangle { Layout.fillWidth: true - Layout.preferredHeight: blueColumn.implicitHeight + Style.marginM * 2 + Layout.preferredHeight: capsuleColumn.implicitHeight + Style.marginS * 2 + Layout.bottomMargin: Style.marginM radius: Style.radiusL color: Color.mPrimary ColumnLayout { - id: blueColumn + id: capsuleColumn anchors.top: parent.top anchors.left: parent.left anchors.bottom: parent.bottom - anchors.topMargin: Style.marginM - anchors.leftMargin: Style.marginM - anchors.bottomMargin: Style.marginM - anchors.rightMargin: clockItem.width + (Style.marginM * 2) + + anchors.topMargin: Style.marginS + anchors.bottomMargin: Style.marginS + anchors.rightMargin: clockLoader.width + (Style.marginL * 2) + anchors.leftMargin: Style.marginL + spacing: 0 // Combined layout for weather icon, date, and weather text @@ -89,41 +93,6 @@ NPanel { clip: true spacing: Style.marginS - // Weather icon and temperature - ColumnLayout { - visible: Settings.data.location.weatherEnabled && weatherReady - Layout.alignment: Qt.AlignVCenter - spacing: Style.marginXXS - - NIcon { - Layout.alignment: Qt.AlignHCenter - icon: Settings.data.location.weatherEnabled && weatherReady ? LocationService.weatherSymbolFromCode(LocationService.data.weather.current_weather.weathercode) : "" - pointSize: Style.fontSizeXXL - color: Color.mOnPrimary - } - - NText { - Layout.alignment: Qt.AlignHCenter - text: { - if (!Settings.data.location.weatherEnabled) - return "" - if (!weatherReady) - return "" - var temp = LocationService.data.weather.current_weather.temperature - var suffix = "C" - if (Settings.data.location.useFahrenheit) { - temp = LocationService.celsiusToFahrenheit(temp) - suffix = "F" - } - temp = Math.round(temp) - return `${temp}°${suffix}` - } - pointSize: Style.fontSizeM - font.weight: Style.fontWeightBold - color: Color.mOnPrimary - } - } - // Today day number - with simple, stable animation NText { opacity: content.isCurrentMonth ? 1.0 : 0.0 @@ -216,7 +185,7 @@ NPanel { // Analog clock ClockLoader { - id: clockItem + id: clockLoader anchors.right: parent.right anchors.rightMargin: Style.marginM anchors.verticalCenter: parent.verticalCenter @@ -226,61 +195,6 @@ NPanel { } } - RowLayout { - visible: weatherReady - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - spacing: Style.marginL - Repeater { - model: weatherReady ? Math.min(6, LocationService.data.weather.daily.time.length) : 0 - delegate: ColumnLayout { - Layout.preferredWidth: 0 - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - spacing: Style.marginS - NText { - text: { - var weatherDate = new Date(LocationService.data.weather.daily.time[index].replace(/-/g, "/")) - return Qt.locale().toString(weatherDate, "ddd") - } - color: Color.mOnSurfaceVariant - pointSize: Style.fontSizeM - font.weight: Style.fontWeightMedium - Layout.alignment: Qt.AlignHCenter - } - NIcon { - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - icon: LocationService.weatherSymbolFromCode(LocationService.data.weather.daily.weathercode[index]) - pointSize: Style.fontSizeXXL * 1.5 - color: Color.mPrimary - } - NText { - Layout.alignment: Qt.AlignHCenter - text: { - var max = LocationService.data.weather.daily.temperature_2m_max[index] - var min = LocationService.data.weather.daily.temperature_2m_min[index] - if (Settings.data.location.useFahrenheit) { - max = LocationService.celsiusToFahrenheit(max) - min = LocationService.celsiusToFahrenheit(min) - } - max = Math.round(max) - min = Math.round(min) - return `${max}°/${min}°` - } - pointSize: Style.fontSizeXS - color: Color.mOnSurfaceVariant - font.weight: Style.fontWeightMedium - } - } - } - } - RowLayout { - visible: Settings.data.location.weatherEnabled && !weatherReady - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - NBusyIndicator {} - } - Item {} RowLayout { Layout.fillWidth: true spacing: Style.marginS @@ -367,7 +281,8 @@ NPanel { } RowLayout { Layout.fillWidth: true - Layout.fillHeight: true + Layout.preferredHeight: 240 * Style.uiScaleRatio + Layout.maximumHeight: 240 * Style.uiScaleRatio spacing: 0 // Helper function to check if a date has events @@ -564,5 +479,19 @@ NPanel { } } } + + NDivider { + visible: Settings.data.location.showCalendarWeather + Layout.fillWidth: true + Layout.topMargin: Style.marginM + Layout.bottomMargin: Style.marginM + } + + WeatherCard { + visible: Settings.data.location.showCalendarWeather + Layout.fillWidth: true + Layout.preferredHeight: implicitHeight + forecastDays: 6 + } } } diff --git a/Modules/Bar/Calendar/ClockLoader.qml b/Modules/Bar/Calendar/ClockLoader.qml index 37f0f64b..98da9a12 100644 --- a/Modules/Bar/Calendar/ClockLoader.qml +++ b/Modules/Bar/Calendar/ClockLoader.qml @@ -29,10 +29,7 @@ Item { var defaultColor = Color.mError var bestContrast = 1.0 // 1.0 is "no contrast" var bestColor = defaultColor - var candidates = [Color.mSecondary, - Color.mTertiary, - Color.mError, - ] + var candidates = [Color.mSecondary, Color.mTertiary, Color.mError] const minContrast = 1.149 diff --git a/Modules/ControlCenter/Cards/WeatherCard.qml b/Modules/ControlCenter/Cards/WeatherCard.qml index 1bb73055..0e0f5282 100644 --- a/Modules/ControlCenter/Cards/WeatherCard.qml +++ b/Modules/ControlCenter/Cards/WeatherCard.qml @@ -9,8 +9,12 @@ import qs.Widgets NBox { id: root + property int forecastDays: 7 readonly property bool weatherReady: Settings.data.location.weatherEnabled && (LocationService.data.weather !== null) + visible: Settings.data.location.weatherEnabled + implicitHeight: Math.max(100 * Style.uiScaleRatio, content.implicitHeight + (Style.marginXL * 2)) + ColumnLayout { id: content anchors.left: parent.left @@ -87,7 +91,7 @@ NBox { spacing: Style.marginM Repeater { - model: weatherReady ? LocationService.data.weather.daily.time : [] + model: weatherReady ? Math.min(root.forecastDays, LocationService.data.weather.daily.time.length) : 0 delegate: ColumnLayout { Layout.fillWidth: true spacing: Style.marginXS diff --git a/Modules/Settings/Tabs/LocationTab.qml b/Modules/Settings/Tabs/LocationTab.qml index f257f3ff..473b75f8 100644 --- a/Modules/Settings/Tabs/LocationTab.qml +++ b/Modules/Settings/Tabs/LocationTab.qml @@ -86,6 +86,15 @@ ColumnLayout { enabled: Settings.data.location.weatherEnabled opacity: Settings.data.location.weatherEnabled ? 1.0 : 0.5 } + + NToggle { + label: I18n.tr("settings.location.weather.show-in-calendar.label") + description: I18n.tr("settings.location.weather.show-in-calendar.description") + checked: Settings.data.location.showCalendarWeather + onToggled: checked => Settings.data.location.showCalendarWeather = checked + enabled: Settings.data.location.weatherEnabled + opacity: Settings.data.location.weatherEnabled ? 1.0 : 0.5 + } } NDivider { diff --git a/Modules/SetupWizard/SetupDockStep.qml b/Modules/SetupWizard/SetupDockStep.qml index 5614f1c0..79164869 100644 --- a/Modules/SetupWizard/SetupDockStep.qml +++ b/Modules/SetupWizard/SetupDockStep.qml @@ -174,7 +174,7 @@ ColumnLayout { delegate: NCheckbox { Layout.fillWidth: true label: modelData.name || "Unknown" - visible: Settings.data.dock.enabled + visible: Settings.data.dock.enabled description: { const compositorScale = CompositorService.getDisplayScale(modelData.name) I18n.tr("system.monitor-description", {