import QtQuick import QtQuick.Layouts import Quickshell.Io import "../../../config" as Cfg Item { id: root implicitHeight: contentCol.implicitHeight readonly property var t: Cfg.Config.theme property string icon: "—" property string condition: "—" property string temp: "—" property string feelsLike: "—" property string humidity: "—" property string wind: "—" property string location: "—" readonly property string _url: { var loc = Cfg.Config.weatherLocation.trim() if (!loc) return "wttr.in?format=%t|%f|%c|%C|%h|%w|%l&m" loc = loc.replace(/ /g, "+") return "wttr.in/" + loc + "?format=%t|%f|%c|%C|%h|%w|%l&m" } function fetchWeather() { weatherProc.command = ["sh", "-c", "curl -s \"" + root._url + "\""] weatherProc.running = true } Timer { interval: Cfg.Config.weatherRefreshMin * 60000 running: true repeat: true triggeredOnStart: true onTriggered: root.fetchWeather() } Process { id: weatherProc property string _buf: "" command: ["sh", "-c", ""] stdout: SplitParser { onRead: d => { weatherProc._buf = d } } onRunningChanged: { if (running || !_buf) return var parts = _buf.trim().split("|") if (parts.length >= 7) { root.temp = parts[0] || "—" root.feelsLike = parts[1] || "—" root.icon = parts[2] || "—" root.condition = parts[3] || "—" root.humidity = parts[4] || "—" root.wind = parts[5] || "—" root.location = parts[6] || "—" } _buf = "" } } ColumnLayout { id: contentCol anchors { left: parent.left; right: parent.right; top: parent.top } spacing: 0 Rectangle { Layout.fillWidth: true height: 32 color: "transparent" RowLayout { anchors.fill: parent spacing: 10 Rectangle { width: 32; height: 32 radius: 8 color: Qt.alpha(root.t.weatherAccent, 0.12) border.color: Qt.alpha(root.t.weatherAccent, 0.22) border.width: 1 Layout.alignment: Qt.AlignVCenter Text { anchors.centerIn: parent text: root.icon color: root.t.weatherAccent font.pixelSize: 18 font.weight: Font.Bold } } ColumnLayout { spacing: 2 Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter Text { text: root.condition color: root.t.weatherTextMain font.pixelSize: 13 font.weight: Font.Bold elide: Text.ElideRight Layout.fillWidth: true } Text { text: root.location color: root.t.weatherTextDim font.pixelSize: 10 font.weight: Font.Bold opacity: 0.75 elide: Text.ElideRight Layout.fillWidth: true } } Rectangle { width: 24; height: 24 radius: 6 color: refreshMouse.containsMouse ? (refreshMouse.pressed ? Qt.alpha(root.t.weatherAccent, 0.25) : Qt.alpha(root.t.weatherAccent, 0.12)) : "transparent" Layout.alignment: Qt.AlignVCenter Behavior on color { ColorAnimation { duration: 150 } } Text { id: refreshIcon anchors.centerIn: parent text: "󰑐" color: refreshMouse.containsMouse ? root.t.weatherAccent : root.t.weatherTextDim font.pixelSize: 14 font.weight: Font.Bold Behavior on color { ColorAnimation { duration: 150 } } RotationAnimator { id: spinAnim target: refreshIcon from: 0; to: 360 duration: 600 easing.type: Easing.OutCubic running: false } } MouseArea { id: refreshMouse anchors.fill: parent; hoverEnabled: true; cursorShape: Qt.PointingHandCursor onClicked: { spinAnim.restart() root.fetchWeather() } } } } } Item { Layout.preferredHeight: 12 } Rectangle { Layout.fillWidth: true height: 1 gradient: Gradient { orientation: Gradient.Horizontal GradientStop { position: 0.0; color: Qt.alpha(root.t.weatherAccent, 0.5) } GradientStop { position: 1.0; color: "transparent" } } } Item { Layout.preferredHeight: 10 } RowLayout { Layout.fillWidth: true spacing: 10 Rectangle { width: 18; height: 18 radius: 4 color: Qt.alpha(root.t.weatherTempColor, 0.15) Layout.alignment: Qt.AlignVCenter Text { anchors.centerIn: parent text: "󰔄" color: root.t.weatherTempColor font.pixelSize: 12 font.weight: Font.Bold } } Text { text: "Temperature" color: root.t.weatherTextDim font.pixelSize: 12 font.weight: Font.Bold Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter } Text { text: root.temp color: root.t.weatherTextMain font.pixelSize: 12 font.weight: Font.Bold Layout.alignment: Qt.AlignVCenter } } Item { Layout.preferredHeight: 9 } RowLayout { Layout.fillWidth: true spacing: 10 Rectangle { width: 18; height: 18 radius: 4 color: Qt.alpha(root.t.weatherFeelsColor, 0.15) Layout.alignment: Qt.AlignVCenter Text { anchors.centerIn: parent text: "󰔄" color: root.t.weatherFeelsColor font.pixelSize: 12 font.weight: Font.Bold } } Text { text: "Feels like" color: root.t.weatherTextDim font.pixelSize: 12 font.weight: Font.Bold Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter } Text { text: root.feelsLike color: root.t.weatherTextMain font.pixelSize: 12 font.weight: Font.Bold Layout.alignment: Qt.AlignVCenter } } Item { Layout.preferredHeight: 9 } RowLayout { Layout.fillWidth: true spacing: 10 Rectangle { width: 18; height: 18 radius: 4 color: Qt.alpha(root.t.weatherHumidColor, 0.15) Layout.alignment: Qt.AlignVCenter Text { anchors.centerIn: parent text: "󰃚" color: root.t.weatherHumidColor font.pixelSize: 12 font.weight: Font.Bold } } Text { text: "Humidity" color: root.t.weatherTextDim font.pixelSize: 12 font.weight: Font.Bold Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter } Text { text: root.humidity color: root.t.weatherTextMain font.pixelSize: 12 font.weight: Font.Bold Layout.alignment: Qt.AlignVCenter } } Item { Layout.preferredHeight: 9 } RowLayout { Layout.fillWidth: true spacing: 10 Rectangle { width: 18; height: 18 radius: 4 color: Qt.alpha(root.t.weatherWindColor, 0.15) Layout.alignment: Qt.AlignVCenter Text { anchors.centerIn: parent text: "󰖝" color: root.t.weatherWindColor font.pixelSize: 12 font.weight: Font.Bold } } Text { text: "Wind" color: root.t.weatherTextDim font.pixelSize: 12 font.weight: Font.Bold Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter } Text { text: root.wind color: root.t.weatherTextMain font.pixelSize: 12 font.weight: Font.Bold Layout.alignment: Qt.AlignVCenter } } Item { Layout.preferredHeight: 6 } } }