add WeatherService, WeatherApplet with hover panel and lock screen widget
This commit is contained in:
parent
6f385130ff
commit
9285365732
8 changed files with 150 additions and 26 deletions
|
|
@ -121,6 +121,11 @@ in
|
|||
default = true;
|
||||
description = "Show volume slider on the lock screen.";
|
||||
};
|
||||
weather = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Show weather summary on the lock screen.";
|
||||
};
|
||||
};
|
||||
notifications = moduleOpt "notifications" {
|
||||
timeout = lib.mkOption {
|
||||
|
|
|
|||
41
shell/applets/WeatherApplet.qml
Normal file
41
shell/applets/WeatherApplet.qml
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import QtQuick
|
||||
import "../services" as S
|
||||
|
||||
Column {
|
||||
id: root
|
||||
|
||||
required property color accentColor
|
||||
|
||||
// Weather icon + summary
|
||||
Item {
|
||||
width: parent.width
|
||||
height: 28
|
||||
|
||||
Text {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 12
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: S.WeatherService.icon
|
||||
color: root.accentColor
|
||||
font.pixelSize: S.Theme.fontSize + 2
|
||||
font.family: S.Theme.fontFamily
|
||||
}
|
||||
}
|
||||
|
||||
// Forecast details from wttrbar tooltip
|
||||
Text {
|
||||
width: parent.width - 24
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: S.WeatherService.tooltip
|
||||
color: S.Theme.base05
|
||||
font.pixelSize: S.Theme.fontSize - 2
|
||||
font.family: S.Theme.fontFamily
|
||||
wrapMode: Text.WordWrap
|
||||
lineHeight: 1.3
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 1
|
||||
height: 4
|
||||
}
|
||||
}
|
||||
|
|
@ -11,4 +11,5 @@ MprisApplet 1.0 MprisApplet.qml
|
|||
NetworkApplet 1.0 NetworkApplet.qml
|
||||
TemperatureApplet 1.0 TemperatureApplet.qml
|
||||
VolumeApplet 1.0 VolumeApplet.qml
|
||||
WeatherApplet 1.0 WeatherApplet.qml
|
||||
# keep-sorted end
|
||||
|
|
|
|||
|
|
@ -27,13 +27,34 @@ Item {
|
|||
}
|
||||
|
||||
implicitHeight: _widgetContent.implicitHeight
|
||||
visible: _mprisCard.visible || _volumeCard.visible || _backlightCard.visible || _notifPills.visible
|
||||
visible: _weatherCard.visible || _mprisCard.visible || _volumeCard.visible || _backlightCard.visible || _notifPills.visible
|
||||
|
||||
Column {
|
||||
id: _widgetContent
|
||||
width: parent.width
|
||||
spacing: 12
|
||||
|
||||
// Weather widget
|
||||
Rectangle {
|
||||
id: _weatherCard
|
||||
width: parent.width
|
||||
height: _weatherContent.implicitHeight + 16
|
||||
radius: S.Theme.radius + 2
|
||||
color: Qt.rgba(S.Theme.base01.r, S.Theme.base01.g, S.Theme.base01.b, 0.7)
|
||||
border.color: Qt.rgba(S.Theme.base03.r, S.Theme.base03.g, S.Theme.base03.b, 0.3)
|
||||
border.width: 1
|
||||
visible: (S.Modules.lock.weather ?? true) && S.WeatherService.available
|
||||
|
||||
C.WeatherApplet {
|
||||
id: _weatherContent
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 8
|
||||
accentColor: S.Theme.base0C
|
||||
}
|
||||
}
|
||||
|
||||
// Notification pills
|
||||
LockNotifPills {
|
||||
id: _notifPills
|
||||
|
|
|
|||
|
|
@ -1,41 +1,53 @@
|
|||
import QtQuick
|
||||
import Quickshell.Io
|
||||
import Quickshell
|
||||
import "." as M
|
||||
import "../services" as S
|
||||
import "../applets" as C
|
||||
|
||||
M.BarSection {
|
||||
id: root
|
||||
spacing: S.Theme.moduleSpacing
|
||||
tooltip: root.weatherTooltip
|
||||
tooltip: ""
|
||||
visible: S.Modules.weather.enable && S.WeatherService.available
|
||||
|
||||
property string weatherTooltip: ""
|
||||
property bool _pinned: false
|
||||
readonly property bool _anyHover: root._hovered || hoverPanel.panelHovered
|
||||
readonly property bool _showPanel: _anyHover || _pinned
|
||||
|
||||
Process {
|
||||
id: proc
|
||||
running: true
|
||||
command: ["wttrbar"].concat(S.Modules.weather.args)
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
try {
|
||||
const data = JSON.parse(text);
|
||||
label.icon = data.text ?? "";
|
||||
root.weatherTooltip = data.tooltip ?? "";
|
||||
} catch (e) {
|
||||
label.icon = "";
|
||||
root.weatherTooltip = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
on_AnyHoverChanged: {
|
||||
if (_anyHover)
|
||||
_unpinTimer.stop();
|
||||
else if (_pinned)
|
||||
_unpinTimer.start();
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: S.Modules.weather.interval || 3600000
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: proc.running = true
|
||||
id: _unpinTimer
|
||||
interval: 500
|
||||
onTriggered: root._pinned = false
|
||||
}
|
||||
|
||||
M.BarIcon {
|
||||
id: label
|
||||
icon: S.WeatherService.icon
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
TapHandler {
|
||||
onTapped: root._pinned = !root._pinned
|
||||
}
|
||||
}
|
||||
|
||||
M.HoverPanel {
|
||||
id: hoverPanel
|
||||
showPanel: root._showPanel
|
||||
screen: QsWindow.window?.screen ?? null
|
||||
anchorItem: root
|
||||
accentColor: root.accentColor
|
||||
panelNamespace: "nova-weather"
|
||||
panelTitle: "Weather"
|
||||
contentWidth: 280
|
||||
|
||||
C.WeatherApplet {
|
||||
width: hoverPanel.contentWidth
|
||||
accentColor: root.accentColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ QtObject {
|
|||
screenshot: true,
|
||||
notifications: true,
|
||||
mpris: true,
|
||||
volume: true
|
||||
volume: true,
|
||||
weather: true
|
||||
})
|
||||
property var statsDaemon: ({
|
||||
interval: -1
|
||||
|
|
|
|||
42
shell/services/WeatherService.qml
Normal file
42
shell/services/WeatherService.qml
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import "." as S
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
property string icon: ""
|
||||
property string tooltip: ""
|
||||
readonly property bool available: icon !== ""
|
||||
|
||||
property Process _proc: Process {
|
||||
running: S.Modules.weather.enable
|
||||
command: ["wttrbar"].concat(S.Modules.weather.args)
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
try {
|
||||
const data = JSON.parse(text);
|
||||
root.icon = data.text ?? "";
|
||||
root.tooltip = data.tooltip ?? "";
|
||||
} catch (e) {
|
||||
root.icon = "";
|
||||
root.tooltip = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property Timer _poll: Timer {
|
||||
interval: S.Modules.weather.interval || 3600000
|
||||
running: S.Modules.weather.enable
|
||||
repeat: true
|
||||
onTriggered: root._proc.running = true
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
_proc.running = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -15,4 +15,5 @@ singleton PowerProfileService 1.0 PowerProfileService.qml
|
|||
singleton ScreenshotService 1.0 ScreenshotService.qml
|
||||
singleton SystemStats 1.0 SystemStats.qml
|
||||
singleton Theme 1.0 Theme.qml
|
||||
singleton WeatherService 1.0 WeatherService.qml
|
||||
# keep-sorted end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue