import SwiftUI struct RequestTabCloseAction { let perform: (UUID) -> Void func callAsFunction(_ id: UUID) { perform(id) } } private struct RequestTabCloseKey: EnvironmentKey { static let defaultValue = RequestTabCloseAction { _ in } } extension EnvironmentValues { var requestTabClose: RequestTabCloseAction { get { self[RequestTabCloseKey.self] } set { self[RequestTabCloseKey.self] = newValue } } } struct UnsavedChangesAlert: ViewModifier { @ObservedObject var editorState: EditorState let buildService: BuildService @State private var pendingTabId: UUID? @State private var showAlert = false func body(content: Content) -> some View { content .environment(\.requestTabClose, RequestTabCloseAction { tabId in if let tab = editorState.tabs.first(where: { $0.id == tabId }), tab.isDirty { pendingTabId = tabId; showAlert = true } else { editorState.closeTab(id: tabId) } }) .alert("Unsaved Changes", isPresented: $showAlert) { Button("Save & Close") { if let id = pendingTabId, let tab = editorState.tabs.first(where: { $0.id == id }) { Task { await buildService.saveFile(path: tab.path, content: tab.content) editorState.closeTab(id: id) } } } Button("Discard", role: .destructive) { if let id = pendingTabId { editorState.closeTab(id: id) } } Button("Cancel", role: .cancel) { pendingTabId = nil } } message: { if let id = pendingTabId, let name = editorState.tabs.first(where: { $0.id == id })?.fileName { Text("\"\(name)\" has unsaved changes.") } } } } extension View { func unsavedChangesGuard(editorState: EditorState, buildService: BuildService) -> some View { modifier(UnsavedChangesAlert(editorState: editorState, buildService: buildService)) } }