Files
Windows-Gotify-Client-Rust/ui/settings-page.slint
T
KennethCheng 383bb404a9 fix(ui): Phase 7 C4 — 卡片间距修复 + 全 UI 翻译为简体中文
两个问题修一处:\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 函数维护一致性。
2026-09-19 20:27:15 +08:00

339 lines
10 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// AGENTS.md §10 / §11 settings page.
//
// Phase 7 C4: 全部翻译为简体中文。
import { SectionLabel } from "./components.slint";
import { ServerCard } from "./server-card.slint";
export component SettingsToggleRow inherits Rectangle {
in property <string> label;
in-out property <bool> value: false;
in property <bool> enabled: true;
callback toggled(string, bool);
in property <color> row-bg: #28292d;
in property <color> row-border: #3a3b40;
in property <color> label-color: #e6e6e6;
in property <color> toggle-on: #4ea1ff;
in property <color> toggle-off: #6a6a6a;
width: 100%;
height: 44px;
border-radius: 8px;
background: row-bg;
border-color: row-border;
border-width: 1px;
opacity: enabled ? 1.0 : 0.5;
HorizontalLayout {
padding-top: 0;
padding-bottom: 0;
padding-left: 16px;
padding-right: 16px;
alignment: center;
Text {
text: label;
color: label-color;
font-size: 13px;
horizontal-stretch: 1;
}
Rectangle {
width: 36px;
height: 20px;
border-radius: 10px;
background: value ? toggle-on : toggle-off;
y: parent.height / 2 - self.height / 2;
Rectangle {
width: 16px;
height: 16px;
border-radius: 8px;
background: #ffffff;
x: value ? parent.width - self.width - 2px : 2px;
y: (parent.height - self.height) / 2;
}
TouchArea {
enabled: root.enabled;
clicked => {
root.value = !root.value;
root.toggled(root.label, root.value);
}
}
}
}
}
export component AppearanceRadio inherits Rectangle {
in property <string> label;
in property <string> description;
in property <bool> selected: false;
callback chosen();
in property <color> row-bg: #28292d;
in property <color> row-border: #3a3b40;
in property <color> row-border-selected: #4ea1ff;
in property <color> label-color: #e6e6e6;
in property <color> hint-color: #6a6a6a;
width: 160px;
height: 64px;
border-radius: 8px;
background: row-bg;
border-color: selected ? row-border-selected : row-border;
border-width: selected ? 2px : 1px;
VerticalLayout {
padding: 12px;
spacing: 2px;
Text {
text: label;
color: label-color;
font-size: 13px;
font-weight: 600;
}
Text {
text: description;
color: hint-color;
font-size: 11px;
}
}
TouchArea {
clicked => {
root.chosen();
}
}
}
export component SettingsPage inherits Rectangle {
in-out property <int> appearance-index: 2;
callback appearance-changed(int);
in-out property <bool> desktop-notify: true;
in-out property <bool> sound: true;
in-out property <bool> notify-high: true;
in-out property <bool> notify-max: true;
in-out property <bool> start-with-windows: false;
in-out property <bool> start-minimized: false;
in-out property <bool> close-to-tray: true;
in-out property <bool> advanced-expanded: false;
in-out property <bool> test-in-progress: false;
callback test-connection-requested();
callback toggle-persist(string, bool);
in property <color> divider-color: #3a3b40;
in property <color> hint-color: #6a6a6a;
background: transparent;
VerticalLayout {
padding: 24px;
spacing: 24px;
// 连接
VerticalLayout {
spacing: 8px;
SectionLabel { label: "连接"; text-color: hint-color; }
Rectangle {
width: 160px;
height: 32px;
background: #2f3035;
border-radius: 6px;
Text {
x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2;
text: root.test-in-progress ? "测试中…" : "测试连接";
color: #e6e6e6;
font-size: 12px;
}
TouchArea {
enabled: !root.test-in-progress;
clicked => {
root.test-connection-requested();
}
}
}
ServerCard {
server-name: "Home";
server-url: "https://gotify.example.com";
enabled: true;
is-current: true;
}
ServerCard {
server-name: "NAS";
server-url: "http://192.168.50.103:50334";
enabled: true;
is-current: false;
}
}
// 通知
VerticalLayout {
spacing: 10px;
SectionLabel { label: "通知"; text-color: hint-color; }
SettingsToggleRow {
label: "启用桌面通知";
value: root.desktop-notify;
toggled(l, v) => {
root.desktop-notify = v;
root.toggle-persist(l, v);
}
}
SettingsToggleRow {
label: "播放声音";
value: root.sound;
enabled: root.desktop-notify;
toggled(l, v) => {
root.sound = v;
root.toggle-persist(l, v);
}
}
SettingsToggleRow {
label: "高级别时通知";
value: root.notify-high;
enabled: root.desktop-notify;
toggled(l, v) => {
root.notify-high = v;
root.toggle-persist(l, v);
}
}
SettingsToggleRow {
label: "最高级别时通知";
value: root.notify-max;
enabled: root.desktop-notify;
toggled(l, v) => {
root.notify-max = v;
root.toggle-persist(l, v);
}
}
}
// 开机启动
VerticalLayout {
spacing: 10px;
SectionLabel { label: "开机启动"; text-color: hint-color; }
SettingsToggleRow {
label: "随 Windows 一起启动";
value: root.start-with-windows;
toggled(l, v) => {
root.start-with-windows = v;
root.toggle-persist(l, v);
}
}
SettingsToggleRow {
label: "启动时最小化到托盘";
value: root.start-minimized;
toggled(l, v) => {
root.start-minimized = v;
root.toggle-persist(l, v);
}
}
SettingsToggleRow {
label: "关闭按钮最小化到托盘";
value: root.close-to-tray;
toggled(l, v) => {
root.close-to-tray = v;
root.toggle-persist(l, v);
}
}
}
// 外观
VerticalLayout {
spacing: 10px;
SectionLabel { label: "外观"; text-color: hint-color; }
HorizontalLayout {
spacing: 12px;
AppearanceRadio {
label: "跟随系统";
description: "跟随 Windows 主题";
selected: root.appearance-index == 0;
chosen => {
root.appearance-index = 0;
root.appearance-changed(0);
}
}
AppearanceRadio {
label: "浅色";
description: "明亮中性色";
selected: root.appearance-index == 1;
chosen => {
root.appearance-index = 1;
root.appearance-changed(1);
}
}
AppearanceRadio {
label: "深色";
description: "石墨灰";
selected: root.appearance-index == 2;
chosen => {
root.appearance-index = 2;
root.appearance-changed(2);
}
}
}
SettingsToggleRow {
label: "紧凑消息密度";
value: false;
enabled: false;
}
}
// 高级(默认折叠,见 §10)
VerticalLayout {
spacing: 10px;
HorizontalLayout {
spacing: 8px;
alignment: center;
Text {
text: advanced-expanded ? "v" : ">";
color: hint-color;
font-size: 11px;
}
Text {
text: "高级";
color: hint-color;
font-size: 11px;
font-weight: 700;
}
TouchArea {
clicked => {
root.advanced-expanded = !root.advanced-expanded;
}
}
}
if advanced-expanded: VerticalLayout {
spacing: 10px;
SettingsToggleRow {
label: "日志级别:Info(release 默认)";
value: false;
enabled: false;
}
SettingsToggleRow {
label: "清除本地状态(消息 + 窗口大小)";
value: false;
enabled: false;
}
SettingsToggleRow {
label: "恢复默认设置";
value: false;
enabled: false;
}
}
}
}
}