feat(ui): Conduit 全页面 1:1 视觉移植 + TS出口/探测/内核 运行时增强 + 死代码清理#270
Merged
Conversation
- 合并 ConnectionStatusCard+ProxyControlCard → ConnectionControlCard(出口 npick+三态圆钮+接管/分流 seg),全功能保留 - 新增 .npick 一步选节点(基于 radix dropdown-menu,纯逻辑解耦 node-picker-logic,供后续页复用) - 拓扑桑基 hero 窗口高自适应(topology-layout canvasHeight 参数化,向后兼容) - 新增 HomeStatusBar 聚合当前态; 保留 NetworkInfoCard(不砍功能); sidebar 总览→主页
- 双视图切换自制双按钮 → 设计系统 ui/segmented-control,与首页接管/分流同款 - 新增共享谓词 meshIsExitCapable(meshInternetOff 正向补集),ServerCard/ServerRow 补 teal「出口」chip,与 amber「仅内网」互斥;出口能力与当前 ring 正交两层 - server-list-helpers.test 加 meshIsExitCapable 6 例; 5 语言补 servers.exitCapableBadge
- 目标节点 Select+手风琴 → 复用 ui/node-picker(.npick 一步选+分组+延迟+搜索),与首页统一,跟随全局哨兵置顶 - 规则集 ResourcePicker 常开内联列表 → 收起下拉复选(dropdown-menu+checkbox,勾选不关菜单+搜索+内置/外置分组+fail-closed+已选chips+前往资源跳转) - 表单校验 toast → 字段级内联红字(空条件/备注必填),仅系统级 saveFailed 仍 toast; 新增 rule-dialog-logic/resource-picker-logic 纯逻辑模块 36 单测
- server-page 停止滤出 TS + 删 TailscaleConnectionCard; TS 作为统一 ServerCard(登录态 badge/current ring/ⓘ), 点卡=选出口 - 新增 mesh-tailscale-control(5 态连接生命周期, dododook#174/dododook#254 handler 逐字迁移: 取消乐观清/打开登录页回落/loginActive 门控/出口警示 auto-open 全保住) - 重写 mesh-access-entry: WG 恒新增/TS 已接入管理/WARP 单例(findWarpNode+warpSlotTaken 守卫, 注销走 WarpDeregisterQueue 防孤儿计费) - 补登录态→卡角标映射 + WARP 单例守卫单测; 5 语言 i18n parity; deriveTsCardState/emitTailscaleStatus/mesh-login-fallback 未触碰
- 分类分组(groupPresetsByCategory)+ 空组隐(组内无卡整组不渲染)+ 顶部策略计数摘要(代理/指定/直连/阻止 形色双编码) - 指定节点改用 .npick: 卡由整卡 Select 重构为展开式(卡首摘要+四态 matrix+点指定节点一步展开+回填规则集 chips) - 视图 Button pair→SegmentedControl; 搜索扩展 geosite/geoip/进程名; 分类归属自定义输入; 前往资源跳转; 表单内联校验(去 toast) - 补 CustomAppPreset.processNames(§5 能力镜像: 自定义应用进程名补全后端消费, 唯一 config 生成变更, 需真机验); 新增 app-rules-logic 纯逻辑 14 单测; 5 语言 parity
- 重置为出厂加 alert-dialog 二次确认(问句+丢失后果+危险色); 删除按钮 text-destructive err 色 - 进度条抽出共享 ui/progress.tsx(role=progressbar 无障碍, 确定/不确定态), 本页+资源库对话框改用; about-settings 手搓 bar 待批 9 迁移 - 新增 rule-resources-logic 纯逻辑(分类过滤/内置守卫/进度分区/全部更新禁用) 17 单测; 5 语言 parity - 已落地未动: 图标操作/全部更新/内置随包不可下载/删除引用确认/GitHub 加速/自动更新/URL 下载
- 顶栏裸文本 count → KPI(大号 mono tabular 连接总数+活跃标签)+ 实时/暂停指示 pill(运行未暂停→teal 呼吸点实时/暂停→中性静态点) - 状态即形: 阻断行整行 text-muted-foreground 弱化 + 零速率读数转中性灰 - 新增 isBlockedAction 纯 helper(badge 配色与行弱化共用消除漂移)+ 单测; 5 语言 parity - 已落地未动: 实时列表/10 列/8 键排序/9 字段搜索/单条+全部关闭确认/暂停恢复/隐私屏蔽/三空态
- 清空日志加 alert-dialog 二次确认(destructive 动词); 搜索高亮复用 ui/highlight-text - 级别形编码左脊(error/fatal destructive脊+底/warn warning脊,info/debug 透明脊占位不跳)+ 底栏 N 行 mono tabular + 折叠头级别 pill; getLevelColorClass 补 fatal - 新增 real-time-logs-logic 纯逻辑(搜索匹配/截断/级别形色)13 单测; 5 语言 parity - 已落地未动: 级别 Select/写盘开关/诊断采集导出/日志流/吸附滚动暂停/环形缓冲截断
- about-settings 手搓 bar(div bg-secondary>div bg-primary) → <Progress value={downloadProgress}/>,与资源下载共用 ui/progress
- 设置 5 子节近 100% 已落地(sidebar 接管/通用/外观/网络 DNS竞速双形态全字段/高级 内核管理全套+控制面板+数据备份6类弹窗/关于 AppUpdateBanner),本批仅补批 6 遗留进度条
- 需签核: 内核下载进度条(真实无 progress IPC,越界未加)/DNS竞速 label(真实信息量高保留)
- subscription-dialog 名称/URL 必填、resource-url-dialog URL 格式: toast → 内联(border-destructive+aria-invalid+text-destructive) - WARP 注销补 AlertDialog 二次确认(批 3b 埋 meshWarpDeregisterTitle/Desc key 漏接线, 复用现有 key+危险色, 镜像 re-register 确认) - 全局元素核对全已落地(ErrorHandler/Toaster/PrivacyOverlay/主题/托盘/进度条统一); 高危确认 17 项 15 有+WARP 注销补齐 - 待定: ErrorHandler toast 治理(推迟真机联调)/内核回滚确认(签核中)
- 必修 i18n 6 key×5 语言补齐(批4 遗漏,parity 绿) - dotTone 硬编码删×3 交回 dotToneOf 派生; connect-button hasError 门控; warpSlotTaken 接 saveServer/cloneServer 硬闸门(editingId 排除自身) - §6 network-settings/local-import toast→内联; getLevelPillClass 抽出消两处真值; WARP 重注册文案 - 内核回滚单层轻确认(目标版本+重启,无不可撤销红字); Toaster visibleToasts=4 - nit 全清: node-picker Enter选首/aria/FOLLOW_GLOBAL_NODE_ID 常量; showsTargetNode 接线; DropdownMenuCheckboxItem; WG 名内联; 状态栏中性色; 日志 命中/总量 双数; ui/badge 补 success/warning variant 消自绘 pill - 批5 进程名复用 ProcessPickerDialog(零新增 key); 补 warp/connect-button/log-pill 单测
- M1: common.search/noResults/home.exitNode 三 key 补齐 5 语言(原五缺俱缺、外语见简中) - L2: 删 15 个孤儿 i18n key×5(替换后零引用, 精确 grep 逐个复核, 保留 home.disconnecting, parity 通过) - L1: 延迟色档收敛单真值(getLatencyColor/getLatencyBg 派生自 latencyTone, LATENCY_TONE_*_CLASS 上移 node-picker-logic) - N1: 5 处 stale 注释改「原/已退役」; N2: resource-picker 复用 node-picker-logic.shouldShowSearch 去重 - 补 warpSlotTaken 硬闸门(editingId 排除自身, saveServer/cloneServer 接线, f63dffa 只 add src/renderer 漏了 src/shared/warp.ts)
- NodePicker 加 disabled?/note? 可选 item 字段 + firstSelectable() 纯函数(搜索 Enter 跳 disabled); 4 消费方不传→零影响 - exit-node-field Select→NodePicker: 抽纯映射 exit-node-field-logic(sortPeers/matchPeer/peerDisabled/peerNote/peersToitems 供 jest 直测); 删 interacted 守卫(npick 无受控 value 回调路径、结构性免疫 radix Select form.reset 伪 onValueChange 清空 bug); 保留 ip/hostName 双匹配/customMode/无peer退化/disabled; i18n 复用 tsExitNode* 零新增 - 补 tray-actions.ts N1 注释(beadb2b 只 add src/renderer/src/shared 漏 src/main)
- server-config-dialog detour Select→DetourPicker 子组件(隔离 latencyMap 订阅,测速期只重渲下拉): 直连哨兵置顶+分组+延迟徽标; excludeId 自身/组网协议喂 items 前过滤 - use-node-sort-store 失效注释订正(server-select-groups 退役已随上一 commit) - 至此所有节点选择统一 .npick(首页/规则/应用分流/TS出口/detour)
- F1: exit-node-field pickerValue 三元序还原 isCustom 优先(customMode 且值匹配设备时保「自定义」态不误回填) - F3(复用治理): 抽 server-picker-items.ts(buildServerPickerModel), ServerConfig→NodePickerItem 映射层, 开关覆盖 sentinel/excludeId/excludeEndpoint/withAddress/sort/label 四处差异; home/rule-dialog/app-rules-card/DetourPicker 四消费方统一一份(逐处等价核对), 14 单测, 净-81 行 - F2: nodeAddress 双写收敛 helper export; F4: mesh-fields 注释订正(不动其 radix 守卫)
- 🔴 真bug: node-picker 空 query bare Enter 选顶部哨兵→onChange('') 清空 exit_node/切直连; 抽 enterSelection(仅非空 query 才选首项)+测试
- 🔴 真bug: DetourPicker 悬挂 detour id 回写; 抽 isPickerCandidate 单一候选谓词, 保存前校验目标在列表否则视直连
- 复用: 抽 searchable-dropdown.tsx 共享壳(触发器+搜索框 ui/input+面板+空态), node/resource picker 改用, Enter gate 统一
- 冗余: multiSection 死运算化简 / add-custom-app 3 error state→submitAttempted 派生 / confirmOpen→pendingModeType 派生 / peerMatches 谓词复用
- memo 一致性(ExitNodePicker/DetourPicker); truncateToBuffer max<=0 guard
- 三谓词(name/geosite/category 空校验)在派生 memo + 提交 gate 各写一份 → 抽 fieldErrors memo(纯字段派生、不 gate submitAttempted) - 展示 errors=submitAttempted?fieldErrors:空; gate 直接用 fieldErrors; 行为等价、谓词单写、消漂移(同 peerMatches 治理)
…变更 push-model banner
…#3) 顺带清理 STATS_GET/refreshStatistics 死链(移除孤儿 store action + IPC 通道 + handler)。
…顺序 + 接入设置弹窗宽度对齐节点编辑窗
冲突解决:server-page.tsx 取 UI-port Conduit 结构 + 并入 dododook#268 的 updatingSubIds(Set)/异步 saveSubscription 切 tab。 补 merge 丢失 import:app(PlatformPrivilegeService macOS reseed)、toast(subscription-dialog 预检错误)。 gate 全绿:tsc 0 / eslint 0 / jest 2895 passed。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Conduit 设计系统全页面 1:1 视觉移植收尾 + 一批运行时增强 + 死代码清理。基于当前 main(含 #268 订阅预检/安全加固批)。
UI / 视觉
运行时 / 网络
清理
验证
tsc 0 · eslint 0 · jest 2895 passed / 37 snapshots · macOS 真机部署冒烟(8 页遍历 0 JS 异常,设计完好)