Files
Windows-Gotify-Client-Rust/ui/settings-page.slint
T
KennethCheng a091e6839a fix(ui): Phase 7 C5 — 移除假按钮 + 真实托盘图标
用户报告设置页很多按钮无反应 + 关闭后托盘看不到图标。两处问题:\n\n1. ServerCard 占位按钮无回调:\n- server-card.slint:去掉了 toggled/edit-clicked/remove-clicked 三个回调以及 enabled 切换、Edit / Remove 按钮;变成纯展示卡(状态点 + name + url + 当前标记)\n- settings-page.slint:去掉硬编码的 Home / NAS 占位,改用 active-server-name / active-server-url / active-server-enabled 三个属性(MainWindow → AppConfig 实时填充);空时显示 '(未配置服务器)' 空态提示\n- app.slint:MainWindow 加三个属性 + 转发给 SettingsPage\n- lib.rs:startup 阶段把活跃服务器信息塞进 UI;测试连接成功/失败时更新 enabled 状态\n\n2. 托盘图标看不见:\n- tray.rs:原本 hIcon 写 null,Win10+ 上 Shell_NotifyIconW(NIM_ADD, NULL hIcon) 实际渲染为空白或很弱的小方块。改用 LoadIconW(NULL, IDI_APPLICATION) 加载 Windows 自带的应用程序图标(无需嵌入 .ico 资源,主题感知)。show_toast / Drop 的 hIcon 维持 null(让 NIM_MODIFY/NIM_DELETE 不动原有图标)。AGENTS.md §53 标记真 .ico 资源为 V2 项。
2026-09-19 20:40:33 +08:00

366 lines
12 KiB
Plaintext
Raw Permalink 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);
// Phase 7 C5: active server config (forwarded from MainWindow →
// AppConfig). Empty strings mean "未配置服务器". The page used to
// hardcode two placeholder rows ("Home" / "NAS") with Edit /
// Remove buttons that didn't do anything — that's what the user
// reported as "很多都没反应". V1 only has the single active
// server anyway, so a single card is honest about scope.
in property <string> active-server-name: "";
in property <string> active-server-url: "";
in property <bool> active-server-enabled: false;
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();
}
}
}
// Phase 7 C5: 单卡显示活跃服务器。多 server 添加/编辑/
// 删除 UI 在 V2 实现(AGENTS.md §21),V1 只有一个活跃
// server。空字符串 → 空态。
if root.active-server-url != "":
ServerCard {
server-name: root.active-server-name;
server-url: root.active-server-url;
enabled: root.active-server-enabled;
is-current: true;
}
if root.active-server-url == "":
Rectangle {
width: 100%;
height: 56px;
border-radius: 8px;
background: #28292d;
border-color: #3a3b40;
border-width: 1px;
Text {
x: 16px;
y: (parent.height - self.height) / 2;
text: "(未配置服务器 — V1 暂不支持 UI 添加,请手动编辑 %APPDATA%\\WindowsGotify\\config.json)";
color: #6a6a6a;
font-size: 12px;
wrap: word-wrap;
width: parent.width - 32px;
}
}
}
// 通知
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;
}
}
}
}
}