Calendar: conditional weather card - wip

This commit is contained in:
ItsLemmy
2025-10-30 14:02:42 -04:00
parent 114cbc9f9f
commit ca72a5ca8f
11 changed files with 66 additions and 106 deletions
+29 -100
View File
@@ -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
}
}
}
+1 -4
View File
@@ -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
+5 -1
View File
@@ -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
+9
View File
@@ -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 {
+1 -1
View File
@@ -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", {