refactor(ui): 错误弹窗挂载收成 presentingErrors modifier

五处逐字复制的 10 行 .alert 样板(窗口壳、三个 destination 包装、服务器
分区)各变一行;ErrorAlertPresenter 的挂载边缘收进 UIErrorAlert.swift,
照 WindowActivationPolicy 的 ViewModifier 先例。AppPresentation 文案
映射边缘不动,presenter 所有权与穿透面不变,零行为变化。
This commit is contained in:
Qiu Yuzhou
2026-10-03 13:25:19 +08:00
parent b24029acab
commit 64ff12dc4c
4 changed files with 34 additions and 51 deletions
+1 -10
View File
@@ -99,16 +99,7 @@ struct MainWindowView: View {
.onChange(of: route.destination) { _, destination in
if destination != .rules { ruleDraft = nil }
}
.alert(
"操作失败",
isPresented: Binding(
get: { shellActionErrors.isPresented },
set: { if !$0 { shellActionErrors.dismiss() } })
) {
Button("好", role: .cancel) {}
} message: {
Text(shellActionErrors.message ?? "")
}
.presentingErrors(shellActionErrors)
.alert(
"诊断已导出",
isPresented: Binding(
+1 -10
View File
@@ -61,16 +61,7 @@ struct ServersView: View {
Button("创建") { commitNewGroup() }
Button("取消", role: .cancel) { cancelNewGroup() }
}
.alert(
"操作失败",
isPresented: Binding(
get: { errors.isPresented },
set: { if !$0 { errors.dismiss() } })
) {
Button("好", role: .cancel) {}
} message: {
Text(errors.message ?? "")
}
.presentingErrors(errors)
.confirmationDialog(
deleteTitle,
isPresented: Binding(
+29 -1
View File
@@ -1,4 +1,4 @@
import Foundation
import SwiftUI
/// 主窗口共享的错误弹窗呈现状态(UI 持有的窗口状态,issue #41):目录工作流
/// module 以 typed error 上抛且不生成本地化文案,这里在呈现边缘统一转换。
@@ -20,3 +20,31 @@ final class ErrorAlertPresenter: ObservableObject {
message = nil
}
}
/// `ErrorAlertPresenter` 的唯一 alert 挂载边缘:标题固定「操作失败」,文案取
/// presenter 当前消息。此前这段 10 行样板复制在窗口壳、destination 包装与
/// 服务器分区共五处;挂载点各自独立呈现,互不冲突。
private struct PresentingErrors: ViewModifier {
@ObservedObject var presenter: ErrorAlertPresenter
func body(content: Content) -> some View {
content
.alert(
"操作失败",
isPresented: Binding(
get: { presenter.isPresented },
set: { if !$0 { presenter.dismiss() } })
) {
Button("好", role: .cancel) {}
} message: {
Text(presenter.message ?? "")
}
}
}
extension View {
/// 挂载共享错误弹窗:present 进 `presenter` 的失败由此统一弹出。
func presentingErrors(_ presenter: ErrorAlertPresenter) -> some View {
modifier(PresentingErrors(presenter: presenter))
}
}
@@ -31,16 +31,7 @@ struct WorkspaceHomeView: View {
didOfferLegacyImport = true
showLegacyImportSheet = true
}
.alert(
"操作失败",
isPresented: Binding(
get: { errors.isPresented },
set: { if !$0 { errors.dismiss() } })
) {
Button("好", role: .cancel) {}
} message: {
Text(errors.message ?? "")
}
.presentingErrors(errors)
}
}
@@ -55,16 +46,7 @@ struct WorkspaceSubscriptionsView: View {
errors: errors,
onNodesRemoved: onNodesRemoved
)
.alert(
"操作失败",
isPresented: Binding(
get: { errors.isPresented },
set: { if !$0 { errors.dismiss() } })
) {
Button("好", role: .cancel) {}
} message: {
Text(errors.message ?? "")
}
.presentingErrors(errors)
}
}
@@ -80,15 +62,6 @@ struct WorkspaceDiagnosticsView: View {
errors: errors,
clipboard: clipboard
)
.alert(
"操作失败",
isPresented: Binding(
get: { errors.isPresented },
set: { if !$0 { errors.dismiss() } })
) {
Button("好", role: .cancel) {}
} message: {
Text(errors.message ?? "")
}
.presentingErrors(errors)
}
}