aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/user/UserRow.qml
blob: f9833e4e54597b9e7db8c7b4907f1a59c6a45050 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// 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, a random greeting, 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
    // A header, not a card: nothing behind it until hovered, so it does not
    // read as one more notification in the list below.
    color: area.containsMouse ? Qt.alpha(Theme.accent, 0.12) : "transparent"

    function read() {
        reader.running = false;
        reader.running = true;
    }
    onVisibleChanged: if (visible) read()
    Component.onCompleted: read()

    // Read on creation, which is every drawer open, so an edit to the file
    // shows on the next one with no watch.
    property string greeting: "Hello " + Quickshell.env("USER")
    FileView {
        path: (Quickshell.env("XDG_CONFIG_HOME") || Quickshell.env("HOME") + "/.config") + "/keystone/greetings"
        printErrors: false
        onLoaded: row.greeting = U.greeting(text(), Quickshell.env("USER"))
        onLoadFailed: row.greeting = U.greeting("", Quickshell.env("USER"))
    }

    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.split("/").map(encodeURIComponent).join("/") : ""
            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: row.greeting
            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()
    }
}