summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-08-10 23:15:32 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-08-10 23:15:32 +1000
commit87b491d8e794995950c6667e1d831061e36aa186 (patch)
treef17fc2be88041dda842d2e3d7db05b09768d3c0d
parentlock: better lock anim (diff)
downloadcaelestia-shell-87b491d8e794995950c6667e1d831061e36aa186.tar.gz
caelestia-shell-87b491d8e794995950c6667e1d831061e36aa186.tar.bz2
caelestia-shell-87b491d8e794995950c6667e1d831061e36aa186.zip
lock: add weather
Also refactor weather service
-rw-r--r--modules/dashboard/dash/Weather.qml6
-rw-r--r--modules/lock/Content.qml6
-rw-r--r--modules/lock/WeatherInfo.qml169
-rw-r--r--services/Weather.qml19
4 files changed, 160 insertions, 40 deletions
diff --git a/modules/dashboard/dash/Weather.qml b/modules/dashboard/dash/Weather.qml
index 0160229..c90ccf0a 100644
--- a/modules/dashboard/dash/Weather.qml
+++ b/modules/dashboard/dash/Weather.qml
@@ -20,7 +20,7 @@ Item {
anchors.left: parent.left
animate: true
- text: Weather.icon || "cloud_alert"
+ text: Weather.icon
color: Colours.palette.m3secondary
font.pointSize: Appearance.font.size.extraLarge * 2
}
@@ -38,7 +38,7 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
animate: true
- text: Config.services.useFahrenheit ? Weather.tempF : Weather.tempC
+ text: Weather.temp
color: Colours.palette.m3primary
font.pointSize: Appearance.font.size.extraLarge
font.weight: 500
@@ -48,7 +48,7 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
animate: true
- text: Weather.description || qsTr("No weather")
+ text: Weather.description
elide: Text.ElideRight
width: Math.min(implicitWidth, root.parent.width - icon.implicitWidth - info.anchors.leftMargin - Appearance.padding.large * 2)
diff --git a/modules/lock/Content.qml b/modules/lock/Content.qml
index 102d8cf..ba19616 100644
--- a/modules/lock/Content.qml
+++ b/modules/lock/Content.qml
@@ -21,12 +21,14 @@ RowLayout {
StyledRect {
Layout.fillWidth: true
- Layout.fillHeight: true
+ implicitHeight: weather.implicitHeight
radius: Appearance.rounding.small
color: Colours.tPalette.m3surfaceContainer
- // WeatherInfo {}
+ WeatherInfo {
+ id: weather
+ }
}
StyledRect {
diff --git a/modules/lock/WeatherInfo.qml b/modules/lock/WeatherInfo.qml
index 1b5b29e..da35a92 100644
--- a/modules/lock/WeatherInfo.qml
+++ b/modules/lock/WeatherInfo.qml
@@ -1,46 +1,163 @@
import qs.components
import qs.services
import qs.config
+import qs.utils
import QtQuick
import QtQuick.Layouts
-RowLayout {
+ColumnLayout {
id: root
- anchors.fill: parent
- spacing: Appearance.spacing.large
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.margins: Appearance.padding.large * 2
- MaterialIcon {
- animate: true
- text: Weather.icon || "cloud_alert"
- color: Colours.palette.m3secondary
- font.pointSize: Appearance.font.size.extraLarge * 2.5
+ spacing: Appearance.spacing.small
+
+ StyledText {
+ Layout.topMargin: Appearance.padding.large * 2
+ Layout.alignment: Qt.AlignHCenter
+ text: qsTr("Weather")
+ color: Colours.palette.m3primary
+ font.pointSize: Appearance.font.size.extraLarge
+ font.weight: 500
}
- ColumnLayout {
- Layout.alignment: Qt.AlignVCenter
+ RowLayout {
+ Layout.fillWidth: true
+ spacing: Appearance.spacing.large
- spacing: Appearance.spacing.small
+ MaterialIcon {
+ animate: true
+ text: Weather.icon
+ color: Colours.palette.m3secondary
+ font.pointSize: Appearance.font.size.extraLarge * 2.5
+ }
- StyledText {
- Layout.fillWidth: true
+ ColumnLayout {
+ spacing: Appearance.spacing.small
- animate: true
- text: Config.services.useFahrenheit ? Weather.tempF : Weather.tempC
- color: Colours.palette.m3primary
- horizontalAlignment: Text.AlignHCenter
- font.pointSize: Appearance.font.size.extraLarge
- font.weight: 500
+ StyledText {
+ Layout.fillWidth: true
+
+ animate: true
+ text: Weather.description
+ color: Colours.palette.m3secondary
+ font.pointSize: Appearance.font.size.large
+ font.weight: 500
+ elide: Text.ElideRight
+ }
+
+ StyledText {
+ Layout.fillWidth: true
+
+ animate: true
+ text: qsTr("Humidity: %1%").arg(Weather.humidity)
+ color: Colours.palette.m3onSurfaceVariant
+ font.pointSize: Appearance.font.size.normal
+ elide: Text.ElideRight
+ }
}
- StyledText {
- Layout.fillWidth: true
+ ColumnLayout {
+ Layout.rightMargin: Appearance.padding.smaller
+ spacing: Appearance.spacing.small
- animate: true
- text: Weather.description || qsTr("No weather")
- horizontalAlignment: Text.AlignHCenter
- font.pointSize: Appearance.font.size.large
- elide: Text.ElideRight
+ StyledText {
+ Layout.fillWidth: true
+
+ animate: true
+ text: Weather.temp
+ color: Colours.palette.m3primary
+ horizontalAlignment: Text.AlignRight
+ font.pointSize: Appearance.font.size.extraLarge
+ font.weight: 500
+ elide: Text.ElideLeft
+ }
+
+ StyledText {
+ Layout.fillWidth: true
+
+ animate: true
+ text: qsTr("Feels like: %1").arg(Weather.feelsLike)
+ color: Colours.palette.m3outline
+ horizontalAlignment: Text.AlignRight
+ font.pointSize: Appearance.font.size.smaller
+ elide: Text.ElideLeft
+ }
+ }
+ }
+
+ RowLayout {
+ Layout.topMargin: Appearance.spacing.smaller
+ Layout.bottomMargin: Appearance.padding.large * 2
+ Layout.fillWidth: true
+ spacing: Appearance.spacing.large
+
+ Repeater {
+ model: {
+ const forecast = Weather.forecast;
+ if (!forecast)
+ return Array.from({
+ length: 5
+ }, () => null);
+
+ const hours = [];
+ const hour = new Date().getHours();
+ let count = 5;
+
+ const today = forecast[0].hourly;
+ const arr = [...today, ...forecast[1].hourly];
+ for (let i = 0; i < arr.length; i++) {
+ const time = parseInt(arr[i].time, 10) / 100;
+
+ if (i > today.length ? time < hour : time > hour) {
+ hours.push(arr[i]);
+ count--;
+ }
+
+ if (count === 0)
+ break;
+ }
+
+ return hours;
+ }
+
+ ColumnLayout {
+ id: forecastHour
+
+ required property var modelData
+
+ Layout.fillWidth: true
+ spacing: Appearance.spacing.small
+
+ StyledText {
+ Layout.fillWidth: true
+ text: {
+ if (!forecastHour.modelData)
+ return "00 AM";
+ const hour = parseInt(forecastHour.modelData.time, 10) / 100;
+ return hour > 12 ? `${(hour - 12).toString().padStart(2, "0")} PM` : `${hour.toString().padStart(2, "0")} AM`;
+ }
+ color: Colours.palette.m3outline
+ horizontalAlignment: Text.AlignHCenter
+ font.pointSize: Appearance.font.size.larger
+ }
+
+ MaterialIcon {
+ Layout.alignment: Qt.AlignHCenter
+ text: forecastHour.modelData ? Icons.getWeatherIcon(forecastHour.modelData.weatherCode) : "cloud_alert"
+ font.pointSize: Appearance.font.size.extraLarge * 1.5
+ font.weight: 500
+ }
+
+ StyledText {
+ Layout.alignment: Qt.AlignHCenter
+ text: Config.services.useFahrenheit ? `${forecastHour.modelData?.tempF ?? 0}°F` : `${forecastHour.modelData?.tempC ?? 0}°C`
+ color: Colours.palette.m3secondary
+ font.pointSize: Appearance.font.size.larger
+ }
+ }
}
}
diff --git a/services/Weather.qml b/services/Weather.qml
index 38750ae..02458c2 100644
--- a/services/Weather.qml
+++ b/services/Weather.qml
@@ -9,10 +9,13 @@ Singleton {
id: root
property string loc
- property string icon
- property string description
- property string tempC: "0°C"
- property string tempF: "0°F"
+ property var cc
+ property var forecast
+ readonly property string icon: cc ? Icons.getWeatherIcon(cc.weatherCode) : "cloud_alert"
+ readonly property string description: cc?.weatherDesc[0].value ?? qsTr("No weather")
+ readonly property string temp: Config.services.useFahrenheit ? `${cc?.temp_F ?? 0}°F` : `${cc?.temp_C ?? 0}°C`
+ readonly property string feelsLike: Config.services.useFahrenheit ? `${cc?.FeelsLikeF ?? 0}°F` : `${cc?.FeelsLikeC ?? 0}°C`
+ readonly property int humidity: cc?.humidity ?? 0
function reload(): void {
if (Config.services.weatherLocation)
@@ -25,11 +28,9 @@ Singleton {
}
onLocChanged: Requests.get(`https://wttr.in/${loc}?format=j1`, text => {
- const json = JSON.parse(text).current_condition[0];
- icon = Icons.getWeatherIcon(json.weatherCode);
- description = json.weatherDesc[0].value;
- tempC = `${parseFloat(json.temp_C)}°C`;
- tempF = `${parseFloat(json.temp_F)}°F`;
+ const json = JSON.parse(text);
+ cc = json.current_condition[0];
+ forecast = json.weather;
})
Component.onCompleted: reload()