Files
shadcn-slint/docs/plans/2026-01-30-slint-proxy-app-design.md
2026-01-30 20:27:24 +08:00

15 KiB
Raw Blame History

Slint 代理管理应用设计文档

创建日期: 2026-01-30 状态: 设计完成,待实施

项目概述

将 web 目录下的 Tauri + React 实现的代理管理工具,使用 Slint UI 组件库完整重新实现。应用包含 6 个主要页面,采用模块化架构,通过 Callback 与 Rust 后端交互。

整体架构

目录结构

ui/
├── app.slint                    # 主应用入口(替代 demo.slint
├── types.slint                  # 数据结构定义
├── components/                  # 通用组件(已有 + 新增)
│   ├── button.slint            # ✓ 已有
│   ├── badge.slint             # ✓ 已有
│   ├── card.slint              # ✓ 已有
│   ├── input.slint             # ✓ 已有
│   ├── item.slint              # ✓ 已有
│   ├── dialog.slint            # ✓ 已有
│   ├── toast.slint             # ✓ 已有
│   ├── sidebar.slint           # ✓ 已有
│   ├── tabs.slint              # ✓ 已有
│   ├── accordion.slint         # ✓ 已有
│   ├── switch.slint            # ✓ 已有
│   ├── select.slint            # ✓ 已有
│   ├── label.slint             # ✓ 已有
│   ├── progress.slint          # ✓ 已有
│   ├── separator.slint         # ✓ 已有
│   ├── tooltip.slint           # ✓ 已有
│   └── empty.slint             # ☐ 待实现
├── layouts/                     # 布局组件(新增)
│   ├── page-layout.slint       # ☐ 待实现
│   └── container.slint         # ☐ 待实现
├── pages/                       # 页面模块(新增)
│   ├── home.slint              # ☐ 待实现
│   ├── proxies.slint           # ☐ 待实现
│   ├── profiles.slint          # ☐ 待实现
│   ├── connections.slint       # ☐ 待实现
│   ├── logs.slint              # ☐ 待实现
│   └── settings.slint          # ☐ 待实现
└── theme/                       # 主题系统(已有)
    ├── theme.slint             # ✓ 已有
    ├── colors.slint            # ✓ 已有
    ├── spacing.slint           # ✓ 已有
    └── typography.slint        # ✓ 已有

核心设计原则

  1. 页面独立性 - 每个页面是独立的 component通过 if current-view == "xxx" 条件渲染
  2. Callback 驱动 - 所有数据通过 callback 从 Rust 获取,页面只负责展示
  3. 状态提升 - 应用状态(当前页面、数据)在主应用层管理,向下传递
  4. 组件复用 - 最大化复用现有 components缺失的通用组件补充到 components/
  5. 固定布局 - 桌面应用不需要响应式布局800x600 最小尺寸)
  6. Emoji 图标 - 使用 emoji 作为图标方案(简单且项目已在使用)

数据结构设计

核心数据类型ui/types.slint

// 配置文件信息
export struct Profile {
    id: string,
    name: string,
    url: string,
    type: string,           // "remote" | "local"
    updated-at: string,
    usage: string,          // "1.26GB / 100GB"
    expire-at: string,
    selected: bool,
}

// 代理节点
export struct ProxyNode {
    name: string,
    type: string,           // "Vmess", "Shadowsocks", etc.
    delay: int,             // 延迟 ms-1 表示未测试
    udp: bool,
}

// 代理组
export struct ProxyGroup {
    name: string,
    type: string,           // "Selector", "URLTest", etc.
    now: string,            // 当前选中的节点
    nodes: [ProxyNode],
}

// 连接信息
export struct Connection {
    id: string,
    host: string,
    process: string,
    rule: string,
    chains: string,
    upload: string,
    download: string,
 tring,
}

// 日志条目
export struct LogEntry {
    time: string,
    level: string,          // "debug", "info", "warn", "error"
    message: string,
}

// 设置项
export struct SettingItem {
    key: string,
    label: string,
    value: string,
    type: string,           // "switch", "select", "button", "text"
    enabled: bool,
}

主应用架构

应用状态与 Callbackui/app.slint

export component App inherits Window {
    // ===== 应用状态 =====
    in-out property <string> current-view: "home";
    in-out property <bool> sidebar-collapsed: false;

    数据状态 =====
    in-out property <Profile> current-profile;
    in-out property <[Profile]> profiles;
    in-out property <[ProxyGroup]> proxy-groups;
    in-out property <[Connection]> connections;
    in-out property <[LogEntry]> mihomo-logs;
    in-out property <[LogEntry]> app-logs;
    in-out property <[SettingItem]> app-settings;
    in-out property <[SettingItem]> clash-settings;

    // ===== CallbacksRust 实现) =====
    // 数据加载
    callback load-profiles();
    callback load-proxy-groups(string /* mode: rule/global/direct */);
    callback load-connections();
    callback load-logs(string /* type: mihomo/app */);
    callback load-settings();

    // 用户操作
    callback select-profile(string /* profile-id */);
    callback select-proxy(string /* group-name */, string /* node-name */);
    callback test-proxy-delay(string /* node-name */);
    callback toggle-setting(string /* key */, bool /* value */);
    callback update-profile(string /* profile-id */);
    callback delete-profile(string /* profile-id */);
    callback add-profile(string /* url */);

    // Toast 通知
    callback show-toast(string /* message */, string /* type */);
}

Callback 调用流程

  1. 页面初始化时调用 load-xxx() 获取数据
  2. 用户交互触发操作 callbackselect-profile
  3. Rust 处理后更新对应的 property
  4. Slint 自动重新渲染相关 UI

布局组件设计

PageLayoutui/layouts/page-layout.slint

页面布局:包含固定头部 + 可滚动内容区

export component PageLayout inherits Rectangle {
    in property <string> title;
    in property <bool> show-actions: false;

    @children  // 头部右侧操作区(可选)

    background: Theme.colors.background;

    VerticalLayout {
        // 固定头部48px
        Rectangle {
            height: 48px;
            HorizontalLayout {
                padding: SpacingSystem.spacing.s4;
                alignment: space-between;

                Text { text: root.title; }
                // 右侧操作区
            }
        }

        // 可滚动内容
        Flickable {
            VerticalLayout {
                padding: SpacingSystem.spacing.s4;
                spacing: SpacingSystem.spacing.s4;
            }
        }
    }
}

Containerui/layouts/container.slint

内容容器:带边框和圆角的卡片式容器

export component Container inherits Rectangle {
    @children

    background: Theme.colors.card;
    border-radius: SpacingSystem.radius.md;
    border-width: 1px;
    border-color: Theme.colors.border;

    VerticalLayout {
        padding: SpacingSystem.spacing.s4;
        spacing: SpacingSystem.spacing.s3;
    }
}

页面功能说明

1. Home 页面ui/pages/home.slint

功能: 显示当前配置文件信息、位置信息、快捷设置

布局:

  • ProfileCard当前配置文件信息名称、类型、流量使用、到期时间
  • LocationCard当前连接位置信息
  • SettingCard快捷设置开关

数据依赖:

  • current-profile: Profile
  • 部分 app-settingsclash-settings

2. Proxies 页面ui/pages/proxies.slint

功能: 代理节点管理,支持 Rule/Global/Direct 三种模式

布局:

  • Tabs切换模式Rule/Global/Direct
  • 每个模式下:
    • 多个 Accordion代理组
    • 每个 Accordion 内网格ode 卡片

数据依赖:

  • proxy-groups: [ProxyGroup]

交互:

  • 切换 Tab 时调用 load-proxy-groups(mode)
  • 点击节点时调用 select-proxy(group, node)
  • 测试延迟调用 test-proxy-delay(node)

3. Profiles 页面ui/pages/profiles.slint

功能: 配置文件管理,网格布局展示所有配置文件

布局:

  • 头部:标题 + 添加按钮 + 刷新按钮
  • 网格布局ProfileCard 列表(每行自适应,最小 18rem

数据依赖:

  • profiles: [Profile]

交互:

  • 点击配置文件调用 select-profile(id)
  • 更新配置文件调用 update-profile(id)
  • 删除配置文件调用 delete-profile(id)
  • 添加配置文件调用 add-profile(url)

4. Connections 页面ui/pages/connections.slint

功能: 显示当前活动连接列表

布局:

  • 简单列表,每个连接使用 Item 组件展示

数据依赖:

  • connections: [Connection]

交互:

  • 定时刷新(每秒调用 load-connections()

5. Logs 页面ui/pages/logs.slint

功能: 日志查看,支持 Mihomo 日志和 App 日志切换

布局:

  • Tabs切换日志类型Mihomo/App
  • 每个 Tab滚动列表展示日志条目
  • 日志条目:时间 + 级别 + 消息(不同级别不同颜色)

数据依赖:

  • mihomo-logs: [LogEntry]
  • app-logs: [LogEntry]

交互:

  • 切换 Tab 时调用 load-logs(type)
  • 定时刷新(每秒)

6. Settings 页面ui/pages/settings.slint

功能: 应用设置和 Clash 设置

布局:

  • 多个 Container每个包含一组设置项
  • 设置项使用 Item 组件:图标 + 标题 + Switch/Button

数据依赖:

  • app-settings: [SettingItem]
  • clash-settings: [SettingItem]

交互:

  • 切换开关调用 tg(key, value)

实现计划

Phase 1: 基础设施 ✓

优先级: 最高 预估代码量: ~150 行 完成日期: 2026-01-30

  • ui/types.slint - 数据结构定义(~50 行)
  • ui/layouts/container.slint - 容器组件(~30 行)
  • ui/layouts/page-layout.slint - 页面布局(~70 行)
  • ui/app.slint - 主应用框架(侧边栏 + 路由)(~200 行)
  • build.rs - 修改编译入口为 app.slint~5 行)
  • src/main.rs - 基础 callback 框架(~100 行)
  • 恢复 ui/theme/ 目录(从 git 历史)

Phase 2: 简单页面 ✓

优先级:预估代码量: ~180 行 完成日期: 2026-01-30

  • ui/components/empty.slint - 空状态组件(~40 行)
  • ui/pages/connections.slint - 连接列表(~60 行)
  • ui/pages/logs.slint - 日志查看(~210 行)

Phase 3: 中等复杂页面 ✓

优先级:预估代码量: ~350 行 完成日期: 2026-01-30

  • ui/pages/settings.slint - 设置页面(~280 行)
  • ui/pages/profiles.slint - 配置文件管理(~230 行)

Phase 4: 复杂页面 ✓

优先级:预估代码量: ~550 行 完成日期: 2026-01-30

  • ui/pages/home.slint - 首页(~380 行)
  • ui/pages/proxies.slint - 代理管理(~280 行)

Phase 5: Rust 集成 ✓

优先级:预估代码量: ~200 行 完成日期: 2026-01-30

  • src/main.rs - 实现所有 callback 的 mock 数据(~450 行)
    • Mock 数据生成函数
    • 用户交互处理
    • 数据状态更新

项目完成总结

实现成果

总代码量: ~2100 行(超出预估的 ~1430 行)

完成时间: 2026-01-30单日完成

实现的文件:

  1. 基础设施7 个文件)

    • ui/types.slint - 数据结构定义
    • ui/layouts/container.slint - 容器组件
    • ui/layouts/page-layout.slint - 页面布局
    • ui/app.slint - 主应用框架
    • ui/theme/ - 主题系统(从 git 恢复)
    • build.rs - 编译配置
    • src/main.rs - Rust 集成
  2. UI 组件1 个新增)

    • ui/components/empty.slint - 空状态组件
  3. 页面模块6 个页面)

    • ui/pages/home.slint - 首页
    • ui/pages/proxies.slint - 代理管理
    • ui/pages/profiles.slint - 配置文件管理
    • ui/pages/connections.slint - 连接列表
    • ui/pages/logs.slint - 日志查看
    • ui/pages/settings.slint - 设置页面

功能特性

完整的 6 页面应用

  • Home - 配置文件信息、位置、快捷设置
  • Proxies - 代理节点管理Rule/Global/Direct 模式)
  • Profiles - 配置文件管理(网格布局)
  • Connections - 活动连接列表
  • Logs - 日志查看Mihomo/App 切换)
  • Settings - 应用和 Clash 设置

主题系统

  • 亮色/暗色模式切换
  • 响应式主题颜色
  • 统一的设计系统

交互功能

  • 侧边栏导航
  • 页面路由
  • 数据加载和更新
  • Toast 通知
  • 用户操作反馈

Mock 数据

  • 3 个配置文件
  • 2 个代理组(多个节点)
  • 3 个活动连接
  • 多条日志记录
  • 完整的设置项

技术亮点

  1. 模块化架构 - 清晰的目录结构和职责划分
  2. Callback 驱动 - 单向数据流,易于维护
  3. 组件复用 - 最大化利用现有 shadcn-slint 组件
  4. 类型安全 - Slint 类型系统保证数据一致性
  5. Mock 数据完整 - 所有页面都有真实的数据展示

运行方式

# 编译并运行
cargo run

# 发布版本
cargo run --release

下一步建议

  1. 后端集成

    • 替换 mock 数据为真实的 Tauri 命令调用
    • 实现配置文件的增删改查
    • 实现代理节点的延迟测试
    • 实现实时连接监控
  2. 功能增强

    • 添加搜索和过滤功能
    • 实现配置导入导出
    • 添加更多设置选项
    • 实现 TUN 模式配置对话框
  3. 用户体验优化

    • 添加加载状态指示器
    • 优化动画效果
    • 添加键盘快捷键
    • 实现拖拽排序
  4. 性能优化

    • 虚拟滚动(大量数据时)
    • 按需加载数据
    • 优化渲染性能

总体进度

总预估代码量: ~1430 行

完成情况:

  • ✓ Phase 1: 基础设施7/7
  • ✓ Phase 2: 简单页面3/3
  • ✓ Phase 3: 中等复杂页面2/2
  • ✓ Phase 4: 复杂页面2/2
  • ✓ Phase 5: Rust 集成1/1

总进度: 15/15 (100%)

项目状态: 已完成

技术决策

图标方案

选择: Emoji 理由: 简单、无需额外资前项目已在使用

布局方案

选择: 固定桌面布局 理由: 桌面应用,不需要响应式

数据流方案

选择: Callback + Property 理由: 清晰的单向数据流,便于维护和测试

模块划分方案

选择: pages/ + layouts/ + components/ 理由: 清晰的职责划分,易于维护和扩展

后续优化方向

  1. 性能优化

    • 虚拟滚动(如果列表数据量大)
    • 按需加载页面数据
  2. 用户体验

    • 加载状态提示
    • 错误处理和提示
    • 操作确认对话框
  3. 功能扩展

    • 搜索和过滤
    • 排序功能
    • 导入导出配置

参考资料

  • 原 Tauri 实现:web/src/ 目录
  • Slint 文档:https://slint.dev/
  • 现有组件库:ui/components/ 目录