summaryrefslogtreecommitdiff
path: root/accounts/gkleen@sif/shell/quickshell/YtDlpWidget.qml
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2026-07-08 22:51:44 +0200
committerGregor Kleen <gkleen@yggdrasil.li>2026-07-08 22:51:44 +0200
commitf4d01d2d9f7a921f40a3b192637959ddf9129669 (patch)
treef5f85751d7042088fd152722576f72943a26b472 /accounts/gkleen@sif/shell/quickshell/YtDlpWidget.qml
parent4751f7390f1e2d4fd5a6a7e22ca111444e915583 (diff)
downloadnixos-flakes.tar
nixos-flakes.tar.gz
nixos-flakes.tar.bz2
nixos-flakes.tar.xz
nixos-flakes.zip
Diffstat (limited to 'accounts/gkleen@sif/shell/quickshell/YtDlpWidget.qml')
-rw-r--r--accounts/gkleen@sif/shell/quickshell/YtDlpWidget.qml190
1 files changed, 190 insertions, 0 deletions
diff --git a/accounts/gkleen@sif/shell/quickshell/YtDlpWidget.qml b/accounts/gkleen@sif/shell/quickshell/YtDlpWidget.qml
new file mode 100644
index 00000000..ff338d49
--- /dev/null
+++ b/accounts/gkleen@sif/shell/quickshell/YtDlpWidget.qml
@@ -0,0 +1,190 @@
1import QtQml.Models
2import QtQuick
3import QtQuick.Layouts
4import QtQuick.Controls.Material
5import Quickshell
6import Quickshell.Io
7import Quickshell.Widgets
8import Custom as Custom
9
10Item {
11 id: root
12
13 height: parent.height
14 width: icon.width
15 anchors.verticalCenter: parent.verticalCenter
16
17 visible: Boolean(unitsModel.values.length)
18
19 WrapperMouseArea {
20 id: widgetMouseArea
21
22 anchors.fill: parent
23 hoverEnabled: true
24
25 Item {
26 anchors.fill: parent
27
28 MaterialDesignIcon {
29 id: icon
30
31 implicitSize: 14
32 anchors.centerIn: parent
33
34 icon: "tray-arrow-down"
35 color: "white"
36 }
37 }
38 }
39
40 PopupWindow {
41 id: tooltip
42
43 property bool openPopup: false
44 property bool nextVisible: widgetMouseArea.containsMouse || tooltipMouseArea.containsMouse || openPopup
45
46 anchor {
47 item: widgetMouseArea
48 edges: Edges.Bottom | Edges.Left
49 }
50 visible: false
51
52 onNextVisibleChanged: hangTimer.restart()
53
54 Timer {
55 id: hangTimer
56 interval: 100
57 onTriggered: tooltip.visible = tooltip.nextVisible
58 }
59
60 implicitWidth: tooltipContent.width
61 implicitHeight: tooltipContent.height
62 color: "transparent"
63
64 Rectangle {
65 width: tooltip.width
66 height: tooltipLayout.childrenRect.height + 16
67 color: "black"
68 }
69
70 WrapperItem {
71 id: tooltipContent
72
73 WrapperMouseArea {
74 id: tooltipMouseArea
75
76 hoverEnabled: true
77 enabled: true
78
79 WrapperItem {
80 margin: 8
81
82 child: GridLayout {
83 id: tooltipLayout
84
85 columns: 2
86 }
87
88 Repeater {
89 model: ScriptModel {
90 id: unitsModel
91
92 values: [...Custom.Systemd.userUnits.values].filter(unit => unit.id.match(/^yt-dlp@.+\.service$/) && unit.activeState === "active" && unit.runtimeDirectory)
93 }
94
95 Item {
96 id: unitDelegate
97
98 Component.onCompleted: {
99 while (children.length) { children[0].parent = tooltipLayout; }
100 }
101
102 required property var modelData
103 required property int index
104
105 property var state: null
106
107 Socket {
108 id: socket
109
110 path: Quickshell.env("XDG_RUNTIME_DIR") + "/" + unitDelegate.modelData.runtimeDirectory[0] + "/status.sock"
111 connected: true
112 onError: e => {
113 console.warn("YtDlpWidget: Error in Socket:", socket.path, e);
114 }
115 parser: SplitParser {
116 onRead: line => {
117 try {
118 unitDelegate.state = JSON.parse(line)
119 } catch (e) {
120 console.warn("YtDlpWidget: Failed to parse state:", line, e)
121 }
122 }
123 }
124 }
125
126 WrapperItem {
127 Layout.column: 0
128 Layout.row: unitDelegate.index
129
130 implicitWidth: descText.contentWidth
131 implicitHeight: descText.contentHeight
132
133 Text {
134 id: descText
135
136 color: "white"
137 font.pointSize: 10
138 font.family: "Fira Sans"
139
140 text: unitDelegate.state?.title || unitDelegate.modelData.id
141 }
142 }
143
144 /*
145 WrapperItem {
146 Layout.column: 1
147 Layout.row: unitDelegate.index
148
149 implicitWidth: fragText.contentWidth
150 implicitHeight: fragText.contentHeight
151
152 visible: Boolean(unitDelegate.state)
153
154 Text {
155 id: fragText
156
157 color: "white"
158 font.pointSize: 10
159 font.family: "Fira Sans"
160
161 text: `${unitDelegate.state?.fragment_index}/${unitDelegate.state?.fragment_count}`
162 }
163 }
164 */
165
166 WrapperItem {
167 Layout.column: 1
168 Layout.row: unitDelegate.index
169
170 visible: Boolean(unitDelegate.state)
171
172 ProgressBar {
173 id: progress
174
175 Material.background: "black"
176 Material.accent: "white"
177
178 from: 0
179 to: unitDelegate.state?.total_bytes || unitDelegate.state?.total_bytes_estimate || 0
180 value: unitDelegate.state?.downloaded_bytes || 0
181 indeterminate: !Boolean(unitDelegate.state?.total_bytes || unitDelegate.state?.total_bytes_estimate) || unitDelegate.state?.status !== "downloading"
182 }
183 }
184 }
185 }
186 }
187 }
188 }
189 }
190}