feat: add hourly forecast to lock weather
Shows if screen is large
This commit is contained in:
parent
18af8ab4ac
commit
318d20fec2
4 changed files with 135 additions and 6 deletions
|
|
@ -7,9 +7,15 @@ import qs.services
|
|||
StyledRect {
|
||||
id: root
|
||||
|
||||
required property int rootHeight // TODO: add forecast when large height
|
||||
required property int rootHeight
|
||||
readonly property bool showForecast: rootHeight >= Tokens.sizes.lock.showForecastHeight
|
||||
|
||||
implicitHeight: layout.implicitHeight + Tokens.padding.extraLarge * 2
|
||||
implicitHeight: {
|
||||
const base = brief.implicitHeight + brief.anchors.topMargin;
|
||||
if (showForecast)
|
||||
return base + Tokens.spacing.largeIncreased + forecast.implicitHeight + forecast.anchors.margins;
|
||||
return base + brief.anchors.topMargin;
|
||||
}
|
||||
radius: Tokens.rounding.extraExtraLarge
|
||||
color: Colours.tPalette.m3surfaceContainer
|
||||
|
||||
|
|
@ -22,8 +28,24 @@ StyledRect {
|
|||
}
|
||||
|
||||
BriefInfo {
|
||||
id: layout
|
||||
id: brief
|
||||
|
||||
anchors.centerIn: parent
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Tokens.padding.extraLarge
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: forecast
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: Tokens.padding.large
|
||||
|
||||
active: root.showForecast
|
||||
asynchronous: true
|
||||
|
||||
sourceComponent: Forecast {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
105
modules/lock/weather/Forecast.qml
Normal file
105
modules/lock/weather/Forecast.qml
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import M3Shapes
|
||||
import Caelestia
|
||||
import Caelestia.Config
|
||||
import qs.components
|
||||
import qs.services
|
||||
|
||||
StyledRect {
|
||||
id: root
|
||||
|
||||
color: Colours.layer(Colours.palette.m3surfaceContainerHigh, 2)
|
||||
radius: Tokens.rounding.extraLargeIncreased
|
||||
implicitHeight: header.anchors.margins + header.implicitHeight + Tokens.spacing.medium + layout.implicitHeight + layout.anchors.bottomMargin
|
||||
|
||||
RowLayout {
|
||||
id: header
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.margins: Tokens.padding.largeIncreased
|
||||
|
||||
spacing: Tokens.spacing.small
|
||||
|
||||
MaterialIcon {
|
||||
Layout.topMargin: Math.round(fontInfo.pointSize * 0.12)
|
||||
text: "schedule"
|
||||
fontStyle: Tokens.font.icon.builders.medium.weight(title.font.weight).build()
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: title
|
||||
|
||||
text: qsTr("Hourly forecast")
|
||||
font: Tokens.font.title.medium
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Tokens.padding.largeIncreased
|
||||
anchors.margins: Tokens.padding.large
|
||||
|
||||
spacing: Tokens.spacing.small
|
||||
|
||||
Repeater {
|
||||
model: CUtils.clamp(Math.floor((layout.width + layout.spacing) / (Tokens.sizes.lock.forecastItemWidth + layout.spacing)), 0, Weather.hourlyForecast.length)
|
||||
|
||||
ColumnLayout {
|
||||
id: hour
|
||||
|
||||
required property int index
|
||||
readonly property var cond: Weather.hourlyForecast[index]
|
||||
|
||||
Layout.fillWidth: true
|
||||
spacing: Tokens.spacing.extraSmall
|
||||
|
||||
MaterialShape {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitSize: temp.implicitHeight + Tokens.padding.medium * 2
|
||||
shape: MaterialShape.Cookie4Sided
|
||||
color: Qt.alpha(Colours.palette.m3primary, hour.index === 0 ? 1 : 0)
|
||||
|
||||
Behavior on color {
|
||||
CAnim {}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: temp
|
||||
|
||||
anchors.centerIn: parent
|
||||
text: Weather.formatTemp(hour.cond.tempC).slice(0, -1) // Remove C/F
|
||||
color: hour.index === 0 ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
|
||||
font: Tokens.font.title.medium
|
||||
}
|
||||
}
|
||||
|
||||
MaterialIcon {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: hour.cond.icon
|
||||
color: Colours.palette.m3secondary
|
||||
fontStyle: Tokens.font.icon.large
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: hour.cond.precipChance + "%"
|
||||
color: Colours.palette.m3primary
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.topMargin: Tokens.spacing.extraSmall
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: hour.index === 0 ? qsTr("Now") : Qt.formatDateTime(new Date(hour.cond.timestamp.replace("T", " ")), GlobalConfig.services.useTwelveHourClock ? "ha" : "hh00")
|
||||
color: Colours.palette.m3onSurfaceVariant
|
||||
font: Tokens.font.body.medium
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -285,6 +285,8 @@ class LockTokens : public ConfigObject {
|
|||
CONFIG_PROPERTY(qreal, heightMult, 0.7)
|
||||
CONFIG_PROPERTY(qreal, ratio, 16.0 / 9.0)
|
||||
CONFIG_PROPERTY(int, centerWidth, 600)
|
||||
CONFIG_PROPERTY(int, showForecastHeight, 975)
|
||||
CONFIG_PROPERTY(int, forecastItemWidth, 51)
|
||||
|
||||
public:
|
||||
explicit LockTokens(QObject* parent = nullptr)
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ Singleton {
|
|||
timestamp: json.hourly.time[i],
|
||||
hour: time.getHours(),
|
||||
tempC: Math.round(json.hourly.temperature_2m[i]),
|
||||
tempF: Math.round(toFahrenheit(json.hourly.temperature_2m[i])),
|
||||
precipChance: json.hourly.precipitation_probability[i],
|
||||
weatherCode: json.hourly.weather_code[i],
|
||||
icon: Icons.getWeatherIcon(json.hourly.weather_code[i])
|
||||
});
|
||||
|
|
@ -169,7 +169,7 @@ Singleton {
|
|||
|
||||
const [lat, lon] = loc.split(",").map(s => s.trim());
|
||||
const baseUrl = "https://api.open-meteo.com/v1/forecast";
|
||||
const params = ["latitude=" + lat, "longitude=" + lon, "hourly=weather_code,temperature_2m", "daily=weather_code,temperature_2m_max,temperature_2m_min,sunrise,sunset", "current=temperature_2m,relative_humidity_2m,apparent_temperature,is_day,weather_code,wind_speed_10m", "timezone=auto", "forecast_days=7"];
|
||||
const params = ["latitude=" + lat, "longitude=" + lon, "hourly=weather_code,temperature_2m,precipitation_probability", "daily=weather_code,temperature_2m_max,temperature_2m_min,sunrise,sunset", "current=temperature_2m,relative_humidity_2m,apparent_temperature,is_day,weather_code,wind_speed_10m", "timezone=auto", "forecast_days=7"];
|
||||
|
||||
return baseUrl + "?" + params.join("&");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue