两个问题修一处:\n\n1. 布局 bug:filter 切到 Max/High/Normal/Low 后可见卡片之间留出巨大空白。原因:Slint isible: false 在 for 循环里没真正折叠 layout 槽位,被隐藏的卡片仍占 76px 高 + 8px spacing。修法:把过滤从 Slint 侧搬到 Rust 侧,新增 filtered_model:UI 绑 filtered_model,shared_model 作为全量 canonical;切换过滤时 rebuild_filtered_model + WS drain 用 push_message_to_models 同步两表;测试连接 / tray restart 也都双表更新。\n\n2. UI 默认中文:sidebar(MESSAGES/SERVERS/FILTERS/APP → 消息/服务器/过滤/应用;All/Max/High/Normal/Low/Settings/About → 全部/最高/高/普通/低/设置/关于)、详情面板(Open link → 打开链接)、空态(You're all caught up → 暂时没有新消息;Test Notification → 发送测试通知)、设置页(5 个分组 + 所有 toggle + Appearance radio)、AboutDialog、托盘菜单(打开/暂停通知/设置.../重新连接/退出/新消息:N)、状态文本(Disconnected → 未连接;mock feed → 模拟数据;messages → 条消息)。\n\n新增 priority-filter-changed(int) 回调,sidebar 切过滤时通知 Rust 重建 filtered model。SharedModel/FilteredModel 同步逻辑:HTTP catch-up → WS drain push → 测试连接 → tray restart 都用 helper 函数维护一致性。
202 lines
5.9 KiB
Plaintext
202 lines
5.9 KiB
Plaintext
// AGENTS.md §54 modals.
|
||
//
|
||
// Phase 7 C4: 翻译为简体中文。
|
||
|
||
export component AboutDialog inherits Rectangle {
|
||
in property <string> version-string: "v0.1.0";
|
||
in property <string> build-date: "2026-09-19";
|
||
|
||
in property <color> bg-color: #28292d;
|
||
in property <color> text-primary-color: #e6e6e6;
|
||
in property <color> text-secondary-color: #a0a0a0;
|
||
in property <color> accent-color: #4ea1ff;
|
||
in property <color> button-bg: #2f3035;
|
||
in property <color> button-border: #3a3b40;
|
||
in property <color> backdrop-color: #000000;
|
||
|
||
callback close-dialog();
|
||
|
||
background: transparent;
|
||
|
||
Rectangle {
|
||
x: 0;
|
||
y: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: backdrop-color;
|
||
opacity: 0.55;
|
||
TouchArea {
|
||
clicked => {
|
||
root.close-dialog();
|
||
}
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
x: (parent.width - self.width) / 2;
|
||
y: (parent.height - self.height) / 2;
|
||
width: 380px;
|
||
height: 280px;
|
||
background: bg-color;
|
||
border-color: button-border;
|
||
border-width: 1px;
|
||
border-radius: 12px;
|
||
|
||
VerticalLayout {
|
||
padding: 24px;
|
||
spacing: 10px;
|
||
|
||
Text {
|
||
text: "Windows Gotify 客户端(Rust 重写版)";
|
||
color: text-primary-color;
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
}
|
||
Text {
|
||
text: version-string;
|
||
color: accent-color;
|
||
font-size: 13px;
|
||
}
|
||
Text {
|
||
text: "构建于 " + build-date;
|
||
color: text-secondary-color;
|
||
font-size: 11px;
|
||
}
|
||
Rectangle { height: 8px; }
|
||
Text {
|
||
text: "轻量、现代、Windows 原生 Gotify\n桌面客户端。Phase 1–8 全部完成。";
|
||
color: text-secondary-color;
|
||
font-size: 12px;
|
||
wrap: word-wrap;
|
||
}
|
||
Rectangle { height: 8px; }
|
||
|
||
HorizontalLayout {
|
||
alignment: end;
|
||
Rectangle {
|
||
width: 100px;
|
||
height: 32px;
|
||
background: button-bg;
|
||
border-color: button-border;
|
||
border-width: 1px;
|
||
border-radius: 6px;
|
||
Text {
|
||
x: (parent.width - self.width) / 2;
|
||
y: (parent.height - self.height) / 2;
|
||
text: "关闭";
|
||
color: text-primary-color;
|
||
font-size: 12px;
|
||
}
|
||
TouchArea {
|
||
clicked => {
|
||
root.close-dialog();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
export component ConfirmDialog inherits Rectangle {
|
||
in property <string> title-text: "确认";
|
||
in property <string> message: "确定吗?";
|
||
in property <string> confirm-label: "确认";
|
||
in property <string> cancel-label: "取消";
|
||
|
||
callback confirmed();
|
||
callback cancelled();
|
||
|
||
in property <color> bg-color: #28292d;
|
||
in property <color> text-primary-color: #e6e6e6;
|
||
in property <color> text-secondary-color: #a0a0a0;
|
||
in property <color> danger-color: #f44336;
|
||
in property <color> button-bg: #2f3035;
|
||
in property <color> button-border: #3a3b40;
|
||
in property <color> backdrop-color: #000000;
|
||
|
||
background: transparent;
|
||
|
||
Rectangle {
|
||
x: 0;
|
||
y: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: backdrop-color;
|
||
opacity: 0.55;
|
||
TouchArea {
|
||
clicked => {
|
||
root.cancelled();
|
||
}
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
x: (parent.width - self.width) / 2;
|
||
y: (parent.height - self.height) / 2;
|
||
width: 380px;
|
||
height: 180px;
|
||
background: bg-color;
|
||
border-color: button-border;
|
||
border-width: 1px;
|
||
border-radius: 12px;
|
||
|
||
VerticalLayout {
|
||
padding: 24px;
|
||
spacing: 16px;
|
||
|
||
Text {
|
||
text: message;
|
||
color: text-primary-color;
|
||
font-size: 13px;
|
||
wrap: word-wrap;
|
||
}
|
||
|
||
HorizontalLayout {
|
||
spacing: 12px;
|
||
|
||
Rectangle { horizontal-stretch: 1; }
|
||
|
||
Rectangle {
|
||
width: 90px;
|
||
height: 32px;
|
||
background: button-bg;
|
||
border-color: button-border;
|
||
border-width: 1px;
|
||
border-radius: 6px;
|
||
Text {
|
||
x: (parent.width - self.width) / 2;
|
||
y: (parent.height - self.height) / 2;
|
||
text: cancel-label;
|
||
color: text-primary-color;
|
||
font-size: 12px;
|
||
}
|
||
TouchArea {
|
||
clicked => {
|
||
root.cancelled();
|
||
}
|
||
}
|
||
}
|
||
Rectangle {
|
||
width: 90px;
|
||
height: 32px;
|
||
background: danger-color;
|
||
border-radius: 6px;
|
||
Text {
|
||
x: (parent.width - self.width) / 2;
|
||
y: (parent.height - self.height) / 2;
|
||
text: confirm-label;
|
||
color: #ffffff;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
}
|
||
TouchArea {
|
||
clicked => {
|
||
root.confirmed();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} |