diff options
Diffstat (limited to 'desktop')
| -rw-r--r-- | desktop/Drawer.qml | 11 | ||||
| -rw-r--r-- | desktop/Module.qml | 4 | ||||
| -rw-r--r-- | desktop/modules/user/UserRow.qml | 102 |
3 files changed, 115 insertions, 2 deletions
diff --git a/desktop/Drawer.qml b/desktop/Drawer.qml index 92c4fca..72aa4d8 100644 --- a/desktop/Drawer.qml +++ b/desktop/Drawer.qml @@ -13,6 +13,7 @@ import Quickshell import Quickshell.Io import Quickshell.Wayland import QtQuick +import "modules/user" Scope { id: root @@ -165,9 +166,15 @@ Scope { // The notification engine's space. The live queue lists // here while the drawer is open; the balloons stand down // because the drawer flag above is set. + UserRow { + id: user + anchors { top: parent.top; left: parent.left; right: parent.right } + onClicked: root.show("user") + } + NotificationList { id: notifications - anchors { top: parent.top; left: parent.left; right: parent.right } + anchors { top: user.bottom; topMargin: 12; left: parent.left; right: parent.right } anchors.bottom: tiles.top anchors.bottomMargin: 16 onHistory: root.history = true @@ -191,7 +198,7 @@ Scope { spacing: 10 Repeater { - model: root.modules + model: root.modules.filter(m => m.tiled) Tile { required property QtObject modelData diff --git a/desktop/Module.qml b/desktop/Module.qml index 7c13b9b..2ce2939 100644 --- a/desktop/Module.qml +++ b/desktop/Module.qml @@ -38,6 +38,10 @@ QtObject { // Whether the tile should render in its active accent. Default false. property bool active: false + // Whether the drawer's grid shows a tile. False for a module reached + // some other way: the user page opens from the drawer's header row. + property bool tiled: true + // Rendered inside the tile, below the icon: a short state line. Null for // a tile that says nothing beyond its label. property Component tileContent: null 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() + } +} |
