diff options
Diffstat (limited to 'mail-overview/MailPanel.qml')
| -rw-r--r-- | mail-overview/MailPanel.qml | 213 |
1 files changed, 212 insertions, 1 deletions
diff --git a/mail-overview/MailPanel.qml b/mail-overview/MailPanel.qml index 7e81a33..7457fb2 100644 --- a/mail-overview/MailPanel.qml +++ b/mail-overview/MailPanel.qml @@ -23,7 +23,12 @@ Scope { readonly property var screenObj: Quickshell.screens.find(s => s.name === root.monitor) ?? Quickshell.screens[0] - function show() { root.open = true; } + function show() { + // Mail has almost certainly arrived since this was last opened, and + // for an autostarted shell that is the whole session. + Accounts.refresh(); + root.open = true; + } function close() { root.open = false; } function toggle() { root.open ? close() : show(); } @@ -38,4 +43,210 @@ Scope { mask: Region {} WlrLayershell.keyboardFocus: WlrKeyboardFocus.None } + + LazyLoader { + active: root.open + + PanelWindow { + id: win + screen: root.screenObj + + anchors { top: true; left: true; right: true; bottom: true } + color: "transparent" + + // Normal, not Ignore: waybar claims an exclusive zone at the top + // of this screen, so respecting it puts the drawer below the bar + // without this file knowing the bar's height. The backdrop then + // starts below waybar too, which is why waybar stays un-dimmed. + exclusionMode: ExclusionMode.Normal + + WlrLayershell.layer: WlrLayer.Overlay + WlrLayershell.namespace: "quickshell-mail" + WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive + + Rectangle { + anchors.fill: parent + color: "#000000" + opacity: 0.5 + MouseArea { anchors.fill: parent; onClicked: root.close() } + } + + // Keys reach a focused item, never the window itself: setting + // keyboardFocus above is necessary but not sufficient, and + // Keys.onEscapePressed on a PanelWindow never fires. + Item { + anchors.fill: parent + focus: true + Keys.onEscapePressed: root.close() + } + + // Top right, under the waybar icon, which sits in modules-right. + Rectangle { + id: drawer + anchors { top: parent.top; right: parent.right; topMargin: 8; rightMargin: 8 } + width: 460 + height: Math.min(content.implicitHeight + 32, win.height - 24) + radius: 14 + color: Qt.alpha(Theme.base, 0.72) + border.width: 1 + border.color: Qt.alpha(Theme.text, 0.12) + + // Swallows clicks so they do not reach the backdrop and close + // the drawer. + MouseArea { anchors.fill: parent } + + Column { + id: content + anchors { left: parent.left; right: parent.right; top: parent.top; margins: 16 } + spacing: 10 + + Item { + width: parent.width + implicitHeight: Math.max(title.implicitHeight, totalText.implicitHeight) + + Text { + id: title + anchors.verticalCenter: parent.verticalCenter + text: "Mail" + color: Theme.text + font.family: Theme.fontFamily + font.pixelSize: Theme.fontSize + 2 + font.bold: true + } + + Text { + id: totalText + anchors { right: parent.right; verticalCenter: parent.verticalCenter } + // A dash rather than a possibly-wrong number while + // any account is still unknown. + text: Accounts.anyUnknown ? "—" : `${Accounts.total} unread` + color: Theme.subtext + font.family: Theme.fontFamily + font.pixelSize: Theme.fontSize + } + } + + Rectangle { width: parent.width; height: 1; color: Qt.alpha(Theme.text, 0.12) } + + Text { + visible: Accounts.error !== "" + width: parent.width + text: Accounts.error + color: Theme.red + wrapMode: Text.WordWrap + font.family: Theme.fontFamily + font.pixelSize: Theme.fontSize - 2 + } + + Repeater { + model: Accounts.accounts + + Column { + required property var modelData + width: content.width + spacing: 4 + + Item { + width: parent.width + implicitHeight: 26 + + Rectangle { + id: dot + anchors.verticalCenter: parent.verticalCenter + width: 8; height: 8; radius: 4 + // The account's own colour from the config. + // Per-account identity, not a palette. + color: modelData.color || Theme.accent + } + + Text { + anchors { left: dot.right; leftMargin: 10; verticalCenter: parent.verticalCenter } + text: modelData.label + color: Theme.text + font.family: Theme.fontFamily + font.pixelSize: Theme.fontSize + } + + Text { + anchors { right: parent.right; verticalCenter: parent.verticalCenter } + text: modelData.count < 0 ? "—" : String(modelData.count) + color: modelData.count > 0 ? Theme.text : Theme.subtext + font.family: Theme.fontFamily + font.pixelSize: Theme.fontSize + font.bold: modelData.count > 0 + } + } + + // The newest three unread threads. Read-only: + // qtmaildir takes no arguments, so there is no way + // to ask it for a particular thread. + Repeater { + model: modelData.threads + + Column { + required property var modelData + width: content.width - 18 + x: 18 + spacing: 1 + bottomPadding: 4 + + Item { + width: parent.width + implicitHeight: who.implicitHeight + + Text { + id: who + anchors.left: parent.left + width: parent.width - when.implicitWidth - 10 + text: modelData.authors + elide: Text.ElideRight + color: Theme.subtext + font.family: Theme.fontFamily + font.pixelSize: Theme.fontSize - 3 + } + + Text { + id: when + anchors.right: parent.right + text: modelData.date + color: Theme.overlay + font.family: Theme.fontFamily + font.pixelSize: Theme.fontSize - 3 + } + } + + Text { + width: parent.width + text: modelData.subject + elide: Text.ElideRight + color: Theme.text + font.family: Theme.fontFamily + font.pixelSize: Theme.fontSize - 2 + } + } + } + } + } + + Rectangle { width: parent.width; height: 1; color: Qt.alpha(Theme.text, 0.12) } + + Row { + anchors.right: parent.right + spacing: 10 + + Button { + text: Accounts.syncing ? "Syncing..." : "Sync now" + enabled: !Accounts.syncing + onClicked: Accounts.sync() + } + + Button { + text: "Open qtmaildir" + onClicked: { Accounts.openClient(); root.close(); } + } + } + } + } + } + } } |
