summaryrefslogtreecommitdiff
path: root/modules/dashboard/Weather.qml
diff options
context:
space:
mode:
Diffstat (limited to 'modules/dashboard/Weather.qml')
-rw-r--r--modules/dashboard/Weather.qml278
1 files changed, 278 insertions, 0 deletions
diff --git a/modules/dashboard/Weather.qml b/modules/dashboard/Weather.qml
new file mode 100644
index 0000000..fd1caa4
--- /dev/null
+++ b/modules/dashboard/Weather.qml
@@ -0,0 +1,278 @@
+import qs.components
+import qs.services
+import qs.config
+import qs.utils
+import QtQuick
+import QtQuick.Layouts
+
+Item {
+ id: root
+
+ implicitWidth: layout.implicitWidth > 800 ? layout.implicitWidth : 840
+ implicitHeight: layout.implicitHeight
+
+ readonly property var today: Weather.forecast && Weather.forecast.length > 0 ? Weather.forecast[0] : null
+
+ Component.onCompleted: Weather.reload()
+
+ ColumnLayout {
+ id: layout
+
+ anchors.fill: parent
+ spacing: Appearance.spacing.smaller
+
+ RowLayout {
+ Layout.leftMargin: Appearance.padding.large
+ Layout.rightMargin: Appearance.padding.large
+ Layout.fillWidth: true
+
+ Column {
+ spacing: Appearance.spacing.small / 2
+
+ StyledText {
+ text: Weather.city || qsTr("Loading...")
+ font.pointSize: Appearance.font.size.extraLarge
+ font.weight: 600
+ color: Colours.palette.m3onSurface
+ }
+
+ StyledText {
+ text: new Date().toLocaleDateString(Qt.locale(), "dddd, MMMM d")
+ font.pointSize: Appearance.font.size.small
+ color: Colours.palette.m3onSurfaceVariant
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ Row {
+ spacing: Appearance.spacing.large
+
+ WeatherStat {
+ icon: "wb_twilight"
+ label: "Sunrise"
+ value: Weather.sunrise
+ colour: Colours.palette.m3tertiary
+ }
+
+ WeatherStat {
+ icon: "bedtime"
+ label: "Sunset"
+ value: Weather.sunset
+ colour: Colours.palette.m3tertiary
+ }
+ }
+ }
+
+ StyledRect {
+ Layout.fillWidth: true
+ implicitHeight: bigInfoRow.implicitHeight + Appearance.padding.small * 2
+
+ radius: Appearance.rounding.large * 2
+ color: Colours.tPalette.m3surfaceContainer
+
+ RowLayout {
+ id: bigInfoRow
+
+ anchors.centerIn: parent
+ spacing: Appearance.spacing.large
+
+ MaterialIcon {
+ Layout.alignment: Qt.AlignVCenter
+ text: Weather.icon
+ font.pointSize: Appearance.font.size.extraLarge * 3
+ color: Colours.palette.m3secondary
+ animate: true
+ }
+
+ ColumnLayout {
+ Layout.alignment: Qt.AlignVCenter
+ spacing: -Appearance.spacing.small
+
+ StyledText {
+ text: Weather.temp
+ font.pointSize: Appearance.font.size.extraLarge * 2
+ font.weight: 500
+ color: Colours.palette.m3primary
+ }
+
+ StyledText {
+ Layout.leftMargin: Appearance.padding.small
+ text: Weather.description
+ font.pointSize: Appearance.font.size.normal
+ color: Colours.palette.m3onSurfaceVariant
+ }
+ }
+ }
+ }
+
+ RowLayout {
+ Layout.fillWidth: true
+ spacing: Appearance.spacing.smaller
+
+ DetailCard {
+ icon: "water_drop"
+ label: "Humidity"
+ value: Weather.humidity + "%"
+ colour: Colours.palette.m3secondary
+ }
+ DetailCard {
+ icon: "thermostat"
+ label: "Feels Like"
+ value: Weather.feelsLike
+ colour: Colours.palette.m3primary
+ }
+ DetailCard {
+ icon: "air"
+ label: "Wind"
+ value: Weather.windSpeed ? Weather.windSpeed + " km/h" : "--"
+ colour: Colours.palette.m3tertiary
+ }
+ }
+
+ StyledText {
+ Layout.topMargin: Appearance.spacing.normal
+ visible: forecastRepeater.count > 0
+ text: qsTr("7-Day Forecast")
+ font.pointSize: Appearance.font.size.normal
+ font.weight: 600
+ color: Colours.palette.m3onSurface
+ }
+
+ RowLayout {
+ Layout.fillWidth: true
+ spacing: Appearance.spacing.smaller
+
+ Repeater {
+ id: forecastRepeater
+
+ model: Weather.forecast
+
+ StyledRect {
+ id: forecastItem
+
+ required property int index
+ required property var modelData
+
+ Layout.fillWidth: true
+ implicitHeight: forecastItemColumn.implicitHeight + Appearance.padding.normal * 2
+
+ radius: Appearance.rounding.normal
+ color: Colours.palette.m3surfaceContainer
+
+ ColumnLayout {
+ id: forecastItemColumn
+
+ anchors.centerIn: parent
+ spacing: Appearance.spacing.small
+
+ StyledText {
+ Layout.alignment: Qt.AlignHCenter
+ text: forecastItem.index === 0 ? qsTr("Today") : new Date(forecastItem.modelData.date).toLocaleDateString(Qt.locale(), "ddd")
+ font.pointSize: Appearance.font.size.normal
+ font.weight: 600
+ color: Colours.palette.m3primary
+ }
+
+ StyledText {
+ Layout.topMargin: -Appearance.spacing.small / 2
+ Layout.alignment: Qt.AlignHCenter
+ text: new Date(forecastItem.modelData.date).toLocaleDateString(Qt.locale(), "MMM d")
+ font.pointSize: Appearance.font.size.small
+ opacity: 0.7
+ color: Colours.palette.m3onSurfaceVariant
+ }
+
+ MaterialIcon {
+ Layout.alignment: Qt.AlignHCenter
+ text: forecastItem.modelData.icon
+ font.pointSize: Appearance.font.size.extraLarge
+ color: Colours.palette.m3secondary
+ }
+
+ StyledText {
+ Layout.alignment: Qt.AlignHCenter
+ text: Config.services.useFahrenheit ? forecastItem.modelData.maxTempF + "°" + " / " + forecastItem.modelData.minTempF + "°" : forecastItem.modelData.maxTempC + "°" + " / " + forecastItem.modelData.minTempC + "°"
+ font.weight: 600
+ color: Colours.palette.m3tertiary
+ }
+ }
+ }
+ }
+ }
+ }
+
+ component DetailCard: StyledRect {
+ id: detailRoot
+
+ property string icon
+ property string label
+ property string value
+ property color colour
+
+ Layout.fillWidth: true
+ Layout.preferredHeight: 60
+ radius: Appearance.rounding.small
+ color: Colours.palette.m3surfaceContainer
+
+ Row {
+ anchors.centerIn: parent
+ spacing: Appearance.spacing.normal
+
+ MaterialIcon {
+ text: detailRoot.icon
+ color: detailRoot.colour
+ font.pointSize: Appearance.font.size.large
+ anchors.verticalCenter: parent.verticalCenter
+ }
+
+ Column {
+ anchors.verticalCenter: parent.verticalCenter
+ spacing: 0
+
+ StyledText {
+ text: detailRoot.label
+ font.pointSize: Appearance.font.size.smaller
+ opacity: 0.7
+ horizontalAlignment: Text.AlignLeft
+ }
+ StyledText {
+ text: detailRoot.value
+ font.weight: 600
+ horizontalAlignment: Text.AlignLeft
+ }
+ }
+ }
+ }
+
+ component WeatherStat: Row {
+ id: weatherStat
+
+ property string icon
+ property string label
+ property string value
+ property color colour
+ spacing: Appearance.spacing.small
+
+ MaterialIcon {
+ text: weatherStat.icon
+ font.pointSize: Appearance.font.size.extraLarge
+ color: weatherStat.colour
+ }
+ Column {
+ StyledText {
+ text: weatherStat.label
+ font.pointSize: Appearance.font.size.smaller
+ color: Colours.palette.m3onSurfaceVariant
+ }
+ StyledText {
+ text: weatherStat.value
+ font.pointSize: Appearance.font.size.small
+ font.weight: 600
+ color: Colours.palette.m3onSurface
+ }
+ }
+ }
+}