From aaabb4f7eaa977c0e4e46c53c67cb0923cf62459 Mon Sep 17 00:00:00 2001 From: Qiu Yuzhou Date: Sat, 3 Oct 2026 13:29:15 +0800 Subject: [PATCH] =?UTF-8?q?refactor(ui):=20=E8=AE=A2=E9=98=85=E4=B8=8E?= =?UTF-8?q?=E8=AF=8A=E6=96=AD=E5=88=86=E5=8C=BA=E8=87=AA=E6=8C=81=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E5=BC=B9=E7=AA=97,=E5=A1=8C=E7=BC=A9=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=20destination=20=E5=8C=85=E8=A3=85=E5=A3=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SubscriptionsView/DiagnosticsView 改为自持 ErrorAlertPresenter 并经 presentingErrors 挂载(与 ServersView 同法),只为转发 presenter 而存在的 WorkspaceSubscriptionsView/WorkspaceDiagnosticsView 整体删除,窗口壳 destinationView 直挂分区视图;WorkspaceHomeView 因承载旧版导入主动弹窗 保留。穿透链 13 个类型减至 11 个,presenter owner 减至 3 个。 --- ShadowsocksX-NG2/App/DiagnosticsView.swift | 4 ++- ShadowsocksX-NG2/App/MainWindowView.swift | 4 +-- ShadowsocksX-NG2/App/SubscriptionsView.swift | 4 ++- .../App/WorkspaceDestinations.swift | 36 ++----------------- 4 files changed, 11 insertions(+), 37 deletions(-) diff --git a/ShadowsocksX-NG2/App/DiagnosticsView.swift b/ShadowsocksX-NG2/App/DiagnosticsView.swift index 90c26e1e..a5e451c6 100644 --- a/ShadowsocksX-NG2/App/DiagnosticsView.swift +++ b/ShadowsocksX-NG2/App/DiagnosticsView.swift @@ -8,7 +8,8 @@ import SwiftUI /// 的唯一 UI-facing seam);本视图只负责生命周期触发、呈现与复制动作。 struct DiagnosticsView: View { @ObservedObject var diagnostics: DiagnosticsWorkflow - let errors: ErrorAlertPresenter + /// 共享错误弹窗呈现(UI 持有;typed error → 本地化文案的呈现边缘)。 + @StateObject private var errors = ErrorAlertPresenter() let clipboard: any TextClipboard enum LogSource: String, CaseIterable, Identifiable { @@ -49,6 +50,7 @@ struct DiagnosticsView: View { .padding(.bottom, 36) } .task { await diagnostics.readWhileActive() } + .presentingErrors(errors) } // MARK: - 状态摘要 diff --git a/ShadowsocksX-NG2/App/MainWindowView.swift b/ShadowsocksX-NG2/App/MainWindowView.swift index 5a8deb8f..9f907356 100644 --- a/ShadowsocksX-NG2/App/MainWindowView.swift +++ b/ShadowsocksX-NG2/App/MainWindowView.swift @@ -211,7 +211,7 @@ struct MainWindowView: View { clipboard: clipboard, configurationGroupFileExporter: configurationGroupFileExporter) case .subscriptions: - WorkspaceSubscriptionsView( + SubscriptionsView( workflow: workflow, onNodesRemoved: clearSelectionIfInvalidated) case .rules: @@ -225,7 +225,7 @@ struct MainWindowView: View { ) .frame(maxWidth: .infinity, maxHeight: .infinity) case .diagnostics: - WorkspaceDiagnosticsView( + DiagnosticsView( diagnostics: diagnostics, clipboard: clipboard) } diff --git a/ShadowsocksX-NG2/App/SubscriptionsView.swift b/ShadowsocksX-NG2/App/SubscriptionsView.swift index b4496306..70feea09 100644 --- a/ShadowsocksX-NG2/App/SubscriptionsView.swift +++ b/ShadowsocksX-NG2/App/SubscriptionsView.swift @@ -7,7 +7,8 @@ import SwiftUI /// (非敏感);结构化刷新状态在呈现层本地化(story 42)。 struct SubscriptionsView: View { @ObservedObject var workflow: CatalogWorkflow - let errors: ErrorAlertPresenter + /// 共享错误弹窗呈现(UI 持有;typed error → 本地化文案的呈现边缘)。 + @StateObject private var errors = ErrorAlertPresenter() /// 删除完成后回调(被删身份集合;主窗口据此清除失效选择)。 let onNodesRemoved: (Set) -> Void @@ -60,6 +61,7 @@ struct SubscriptionsView: View { "将移除订阅源、固定分组与全部远端成员;若代理正走此订阅,代理会停止。此操作不可撤销。" ) } + .presentingErrors(errors) } private func commitDelete() { diff --git a/ShadowsocksX-NG2/App/WorkspaceDestinations.swift b/ShadowsocksX-NG2/App/WorkspaceDestinations.swift index 481cdab8..166e63f7 100644 --- a/ShadowsocksX-NG2/App/WorkspaceDestinations.swift +++ b/ShadowsocksX-NG2/App/WorkspaceDestinations.swift @@ -1,7 +1,8 @@ import SwiftUI -/// 主窗口各 destination 的包装视图(票 #53/#54):负责每个分区的共享 -/// alert/sheet 生命周期,行为委托给既有分区视图。 +/// 首页 destination 的包装视图:承载旧版导入主动弹窗与共享错误弹窗挂载 +/// (票 #53/#54),行为委托给 HomeView。订阅/诊断分区自持错误弹窗(与 +/// ServersView 同法),不再需要包装。 struct WorkspaceHomeView: View { @ObservedObject var workflow: CatalogWorkflow @@ -34,34 +35,3 @@ struct WorkspaceHomeView: View { .presentingErrors(errors) } } - -struct WorkspaceSubscriptionsView: View { - @ObservedObject var workflow: CatalogWorkflow - let onNodesRemoved: (Set) -> Void - @StateObject private var errors = ErrorAlertPresenter() - - var body: some View { - SubscriptionsView( - workflow: workflow, - errors: errors, - onNodesRemoved: onNodesRemoved - ) - .presentingErrors(errors) - } -} - -struct WorkspaceDiagnosticsView: View { - @ObservedObject var diagnostics: DiagnosticsWorkflow - let clipboard: any TextClipboard - @StateObject private var errors = ErrorAlertPresenter() - - var body: some View { - // 导出诊断动作在窗口工具栏(票 #58);本包装只承载复制错误呈现。 - DiagnosticsView( - diagnostics: diagnostics, - errors: errors, - clipboard: clipboard - ) - .presentingErrors(errors) - } -}