Files
ShadowsocksX-NG/ShadowsocksX-NG2/App/UIErrorAlert.swift
T
Qiu Yuzhou 2fe401cd50 feat(ng2): add catalog workflow module as single UI-facing seam (#41)
建立目录工作流深 module(App/CatalogWorkflow/),收窄主窗口与配置 UI 对
配置目录、凭据存储、订阅快照、Legacy 导入与运行时收敛的访问:

- UI-facing interface:非敏感树/编辑面/订阅 projection、opaque NodeID 查询、
  typed command(ServerEditDraft 等)、typed error 与 structured outcome
  (BatchImportOutcome 逐行点名、RemovalOutcome selection invalidation);
  秘密值只在显式编辑/分享/订阅 URL 命令中出现。
- 服务器编辑:配置与凭据作为一个逻辑变更,CredentialWriteJournal 保证目录
  持久化失败时旧配置与旧凭据都保持有效(story 12/13,含测试)。
- 提交与收敛分离:目录提交成功与 runtimeSync 收敛阶段是独立观察面,运行时
  失败不回滚已提交目录(story 38/39,含测试)。
- 订阅:创建/刷新/换址/删除沿用原子快照、last-good 保留与凭据回滚;卡片
  projection 只含 host,结构化刷新状态由呈现层本地化。
- Legacy 导入端到端编排:不驱动运行时收敛、不自动重复、显式再导入创建独立
  分组;handoff 仍经组合根注入的独立边界。
- Deletion test:删除 CatalogViewModel/Types/+Subscriptions 旧 facade,全部
  视图与状态菜单迁移到新 seam;选择、pane、sheet、alert 状态收归 UI 持有
  (ErrorAlertPresenter)。导入失败行以行号点名,不再回显 ss:// 行内容。

测试经 module interface 观察(395 项全部通过):持久化失败凭据回滚、提交/
收敛阶段分离、收敛失败不回滚、导入不触发运行时等新增场景;既有 Domain、
协调器与运行时测试保持不变。

Out of scope(spec #41):设置编辑、ProxyRuntimeController、Legacy handoff、
新视觉设计、独立编译 target。
2026-09-22 11:39:07 +08:00

23 lines
543 B
Swift

import Foundation
/// 主窗口共享的错误弹窗呈现状态(UI 持有的窗口状态,issue #41):目录工作流
/// module 以 typed error 上抛且不生成本地化文案,这里在呈现边缘统一转换。
@MainActor
final class ErrorAlertPresenter: ObservableObject {
@Published var message: String?
var isPresented: Bool { message != nil }
func present(_ error: Error) {
message = error.presentableMessage
}
func present(text: String) {
message = text
}
func dismiss() {
message = nil
}
}