aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/user/UserRow.qml
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/modules/user/UserRow.qml')
-rw-r--r--desktop/modules/user/UserRow.qml102
1 files changed, 102 insertions, 0 deletions
diff --git a/desktop/modules/user/UserRow.qml b/desktop/modules/user/UserRow.qml
new file mode 100644
index 0000000..106a490
--- /dev/null
+++ b/desktop/modules/user/UserRow.qml
@@ -0,0 +1,102 @@
+// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+import Quickshell
+import Quickshell.Io
+import Quickshell.Widgets
+import QtQuick
+import "../.."
+import "User.js" as U
+
+// The drawer's greeting: avatar, login name, real name. It re-reads each time
+// it becomes visible, which is every drawer open and every return from a
+// page, so a save on the user page shows here on the way back.
+Rectangle {
+ id: row
+
+ signal clicked
+ property var info: ({})
+
+ implicitHeight: 64
+ radius: 12
+ color: area.containsMouse ? Qt.alpha(Theme.accent, 0.22) : Qt.alpha(Theme.surface, 0.35)
+ border.width: 1
+ border.color: Qt.alpha(Theme.text, 0.08)
+
+ function read() {
+ reader.running = false;
+ reader.running = true;
+ }
+ onVisibleChanged: if (visible) read()
+ Component.onCompleted: read()
+
+ Process {
+ id: reader
+ command: [Qt.resolvedUrl("userctl").toString().replace(/^file:\/\//, ""), "get"]
+ // Cleared first: the icon path never changes, so only a source going
+ // through "" makes an uncached Image load the new picture.
+ stdout: StdioCollector {
+ onStreamFinished: { row.info = ({}); row.info = U.parse(text); }
+ }
+ }
+
+ ClippingRectangle {
+ id: face
+ anchors { left: parent.left; leftMargin: 12; verticalCenter: parent.verticalCenter }
+ width: 44
+ height: 44
+ radius: 22
+ color: Theme.surfaceAlt
+
+ Image {
+ id: pic
+ anchors.fill: parent
+ source: row.info.avatar ? "file://" + row.info.avatar : ""
+ fillMode: Image.PreserveAspectCrop
+ sourceSize: Qt.size(88, 88)
+ cache: false
+ }
+ Text {
+ anchors.centerIn: parent
+ visible: pic.status !== Image.Ready
+ text: ""
+ font { family: Theme.iconFamily; pixelSize: 20 }
+ color: Theme.subtext
+ }
+ }
+
+ Column {
+ anchors { left: face.right; leftMargin: 12; right: parent.right; rightMargin: 12
+ verticalCenter: parent.verticalCenter }
+ spacing: 2
+ Text {
+ text: "Hello " + Quickshell.env("USER")
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize + 2; bold: true }
+ color: Theme.text
+ }
+ Text {
+ width: parent.width
+ visible: text !== ""
+ text: row.info.name ?? ""
+ elide: Text.ElideRight
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 3 }
+ color: Theme.subtext
+ }
+ }
+
+ MouseArea {
+ id: area
+ anchors.fill: parent
+ hoverEnabled: true
+ cursorShape: Qt.PointingHandCursor
+ onClicked: row.clicked()
+ }
+}