mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-20 03:01:52 +08:00
[feat] add announcement inbox with local read tracking
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { LineEdit, ScrollView } from "std-widgets.slint";
|
||||
import { AnnouncementItem, MessagePanel, MessageStrings } from "message_panel.slint";
|
||||
import { FontAwesomeIcons, IconButton, CompactComboBox, ImGuiCheckBox, MiniToggleSwitch, CompactButton, PrimaryButton, SecondaryButton, ToggleSwitch, SectionTitle, DialogSurface, ImGuiLineStyle, ImGuiFontStyle } from "common.slint";
|
||||
|
||||
export struct RecentConnection {
|
||||
@@ -273,6 +274,23 @@ export component MainWindow inherits Window {
|
||||
in property <bool> signal-connected: false;
|
||||
in property <bool> signal-tls-error: false;
|
||||
in property <[RecentConnection]> recent-connections;
|
||||
in property <[AnnouncementItem]> announcements;
|
||||
in property <int> announcement-unread;
|
||||
in property <int> announcement-total;
|
||||
in property <int> announcement-offset;
|
||||
in property <bool> announcement-loading;
|
||||
in property <bool> announcement-failed;
|
||||
in property <bool> announcement-read-save-failed;
|
||||
in property <bool> announcement-loaded;
|
||||
in-out property <bool> messages-open: false;
|
||||
in property <string> announcement-selected-id;
|
||||
in property <string> announcement-selected-title;
|
||||
in property <string> announcement-selected-body;
|
||||
in property <string> announcement-selected-date;
|
||||
in property <bool> announcement-selected-read;
|
||||
callback open-announcement(string, string);
|
||||
callback refresh-announcements;
|
||||
callback announcement-page(int);
|
||||
in property <bool> update-available: false;
|
||||
in property <UpdateCheckStatus> update-check-status: idle;
|
||||
private property <string> update-status-text:
|
||||
@@ -410,6 +428,10 @@ export component MainWindow inherits Window {
|
||||
if root.wayland-notice-open { focus-sink.focus(); }
|
||||
}
|
||||
|
||||
changed messages-open => {
|
||||
if root.messages-open { focus-sink.focus(); }
|
||||
}
|
||||
|
||||
reset-remote-id => {
|
||||
root.remote-id-input = "";
|
||||
remote-id-editor.focus();
|
||||
@@ -623,6 +645,10 @@ export component MainWindow inherits Window {
|
||||
}
|
||||
return accept;
|
||||
}
|
||||
if root.messages-open {
|
||||
if event.text == Key.Escape { root.messages-open = false; }
|
||||
return accept;
|
||||
}
|
||||
return reject;
|
||||
}
|
||||
}
|
||||
@@ -651,11 +677,12 @@ export component MainWindow inherits Window {
|
||||
icon-size: 14px;
|
||||
hover-background: #e1e5eb;
|
||||
pressed-background: #cbd1d9;
|
||||
tooltip: root.announcement-unread > 0 ? MessageStrings.unread + " " + root.announcement-unread : "";
|
||||
z: 8;
|
||||
clicked => { root.menu-open = !root.menu-open; }
|
||||
}
|
||||
if root.update-available && !root.menu-open && root.update-icon-blink-on: Text {
|
||||
x: menu-button.x + 16px;
|
||||
x: menu-button.x + (root.announcement-unread > 0 ? -18px : 16px);
|
||||
y: menu-button.y + 1px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
@@ -668,6 +695,33 @@ export component MainWindow inherits Window {
|
||||
vertical-alignment: center;
|
||||
z: 9;
|
||||
}
|
||||
if root.announcement-unread > 0: Rectangle {
|
||||
x: menu-button.x + menu-button.width - self.width + 4px;
|
||||
y: menu-button.y - 1px;
|
||||
width: max(16px, unread-badge-label.preferred-width + 8px);
|
||||
height: 16px;
|
||||
border-radius: 8px;
|
||||
border-width: 1px;
|
||||
border-color: white;
|
||||
background: #d92d20;
|
||||
z: 9;
|
||||
accessible-role: button;
|
||||
accessible-label: MessageStrings.messages + " · " + MessageStrings.unread + " " + root.announcement-unread;
|
||||
accessible-action-default => { root.menu-open = !root.menu-open; }
|
||||
unread-badge-label := Text {
|
||||
text: root.announcement-unread > 99 ? "99+" : "" + root.announcement-unread;
|
||||
color: white;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
accessible-role: none;
|
||||
}
|
||||
TouchArea {
|
||||
mouse-cursor: pointer;
|
||||
clicked => { root.menu-open = !root.menu-open; }
|
||||
}
|
||||
}
|
||||
|
||||
// Local and remote desktop panels.
|
||||
Rectangle {
|
||||
@@ -1146,9 +1200,10 @@ export component MainWindow inherits Window {
|
||||
if root.menu-open: Rectangle {
|
||||
x: menu-button.x + menu-button.width - self.width;
|
||||
y: menu-button.y + menu-button.height + 2px;
|
||||
width: min(118px, max(menu-settings-label.preferred-width,
|
||||
menu-about-label.preferred-width + (root.update-available ? 25px : 0px)) + 28px);
|
||||
height: 64px;
|
||||
width: max(menu-settings-label.preferred-width,
|
||||
max(menu-messages-label.preferred-width,
|
||||
menu-about-label.preferred-width + (root.update-available ? 25px : 0px))) + 28px;
|
||||
height: 93px;
|
||||
background: white;
|
||||
border-width: 1px;
|
||||
border-color: ImGuiLineStyle.border;
|
||||
@@ -1181,6 +1236,31 @@ export component MainWindow inherits Window {
|
||||
clicked => { root.menu-open = false; root.settings-open = true; }
|
||||
}
|
||||
}
|
||||
menu-messages := Rectangle {
|
||||
height: 27px;
|
||||
background: messages-touch.pressed ? #d8dadd
|
||||
: messages-touch.has-hover ? #f0f1f2 : white;
|
||||
border-radius: 3px;
|
||||
accessible-role: button;
|
||||
accessible-label: menu-messages-label.text;
|
||||
accessible-action-default => { messages-touch.clicked(); }
|
||||
menu-messages-label := Text {
|
||||
x: 9px;
|
||||
height: parent.height;
|
||||
text: MessageStrings.messages + (root.announcement-unread > 0 ? " (" + root.announcement-unread + ")" : "");
|
||||
color: #2d3138;
|
||||
vertical-alignment: center;
|
||||
accessible-role: none;
|
||||
}
|
||||
messages-touch := TouchArea {
|
||||
mouse-cursor: pointer;
|
||||
clicked => {
|
||||
root.menu-open = false;
|
||||
root.messages-open = true;
|
||||
root.refresh-announcements();
|
||||
}
|
||||
}
|
||||
}
|
||||
menu-about := Rectangle {
|
||||
height: 27px;
|
||||
background: about-touch.pressed ? #d8dadd
|
||||
@@ -1226,6 +1306,38 @@ export component MainWindow inherits Window {
|
||||
background: ImGuiLineStyle.separator;
|
||||
z: 1;
|
||||
}
|
||||
Rectangle {
|
||||
x: 4px;
|
||||
y: 60.5px;
|
||||
width: parent.width - 8px;
|
||||
height: 1px;
|
||||
background: ImGuiLineStyle.separator;
|
||||
z: 1;
|
||||
}
|
||||
}
|
||||
|
||||
if root.messages-open: Rectangle {
|
||||
background: #00000042;
|
||||
z: 40;
|
||||
TouchArea { clicked => { focus-sink.focus(); } }
|
||||
MessagePanel {
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
width: 520px;
|
||||
height: 330px;
|
||||
items: root.announcements;
|
||||
unread-count: root.announcement-unread; total: root.announcement-total; offset: root.announcement-offset;
|
||||
loading: root.announcement-loading; failed: root.announcement-failed; loaded: root.announcement-loaded;
|
||||
read-save-failed: root.announcement-read-save-failed;
|
||||
connected: root.signal-connected;
|
||||
selected-id: root.announcement-selected-id; selected-title: root.announcement-selected-title;
|
||||
selected-body: root.announcement-selected-body; selected-date: root.announcement-selected-date;
|
||||
selected-read: root.announcement-selected-read;
|
||||
open-message(id, revision) => { root.open-announcement(id, revision); }
|
||||
refresh => { root.refresh-announcements(); }
|
||||
change-page(offset) => { root.announcement-page(offset); }
|
||||
close => { root.messages-open = false; }
|
||||
}
|
||||
}
|
||||
|
||||
copy-timer := Timer {
|
||||
|
||||
Reference in New Issue
Block a user