Four accounts distinguished only by a line of small grey text are four rows that have to be read rather than recognised. GOA already knows what each one is. It hands back a serialised GThemedIcon -- ". GThemedIcon goa-account-google goa-account goa …" -- a preference-ordered fallback chain. The helper passes the whole chain on rather than resolving it, because which of those names exists is a property of the icon theme in use and not something a python script talking to D-Bus should be deciding. The page walks the chain and takes the first name the active theme actually has. Both simpler readings were wrong and looked right: taking the first name blindly assumes it resolves, and taking the last as a fallback assumes the most generic name is the most likely to exist. On Adwaita the tails of these very chains -- "mail", "goa-symbolic" -- do not exist at all, so a miss would have drawn nothing. Checked by asking Quickshell.iconPath directly, which returns empty for a name the theme lacks; the fallback is avatar-default-symbolic, which is present. SettingsCard grew an optional icon for this. It is empty by default and the header lays out exactly as before when unset, so no other card moves. Last-sync is not here because there is nothing to show: GOA exposes no sync-related property at all, on any of these accounts. Better to say so than to invent a timestamp from when the page last refreshed. Claude-Session: https://claude.ai/code/session_01BRvzt4H8XXLPVH5MyYdk9L
88 lines
2.6 KiB
QML
88 lines
2.6 KiB
QML
import QtQuick
|
|
import qs.config
|
|
import qs.widgets
|
|
|
|
Rectangle {
|
|
id: root
|
|
|
|
default property alias contentData: body.data
|
|
property string title: ""
|
|
property string subtitle: ""
|
|
|
|
// An optional themed icon beside the title, for cards that represent a
|
|
// specific thing rather than a topic -- an online account is one of four
|
|
// that otherwise differ only by a line of small grey text. Empty by
|
|
// default, and when empty the header lays out exactly as it did before.
|
|
property string icon: ""
|
|
property string iconFallback: "dialog-information-symbolic"
|
|
|
|
width: parent ? parent.width : 680
|
|
implicitHeight: body.implicitHeight + 30
|
|
radius: Theme.cardRadius + 2
|
|
color: Theme.alpha(Theme.bgPanel, 0.72)
|
|
border.width: 1
|
|
border.color: Theme.alpha(Theme.fg, 0.07)
|
|
|
|
PrismEdge {
|
|
anchors.top: parent.top
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
inset: root.radius
|
|
opacity: 0.36
|
|
}
|
|
|
|
Column {
|
|
id: body
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.top: parent.top
|
|
anchors.margins: 15
|
|
spacing: 0
|
|
|
|
Row {
|
|
width: parent.width
|
|
visible: root.title !== ""
|
|
spacing: root.icon === "" ? 0 : 10
|
|
|
|
ThemedIcon {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
visible: root.icon !== ""
|
|
width: root.icon === "" ? 0 : 22
|
|
icon: root.icon
|
|
iconFallback: root.iconFallback
|
|
size: 22
|
|
}
|
|
|
|
Text {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: parent.width - (root.icon === "" ? 0 : 32)
|
|
text: root.title
|
|
color: Theme.fg
|
|
font.family: Theme.fontFamily
|
|
font.pixelSize: Theme.fontSizeLarge
|
|
font.weight: Font.DemiBold
|
|
elide: Text.ElideRight
|
|
}
|
|
}
|
|
|
|
// The title's bottom padding lived on the title Text; it moves here so
|
|
// the Row above can centre an icon against it without the padding
|
|
// pushing the icon off-centre.
|
|
Item {
|
|
width: 1
|
|
height: root.title === "" ? 0 : (root.subtitle === "" ? 10 : 3)
|
|
}
|
|
|
|
Text {
|
|
width: parent.width
|
|
visible: root.subtitle !== ""
|
|
text: root.subtitle
|
|
color: Theme.fgDim
|
|
font.family: Theme.fontFamily
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
wrapMode: Text.WordWrap
|
|
bottomPadding: 12
|
|
}
|
|
}
|
|
}
|