| 1 | import RastrilloApple |
| 2 | import DocsKit |
| 3 | import SwiftUI |
| 4 | |
| 5 | /// Each window owns its navigation and model lifetime. Switching an account in |
| 6 | /// one window must never discard another window's unconfirmed edits. |
| 7 | struct DocsAccountWindow: View { |
| 8 | @StateObject private var connection = NativeConnection(defaultServer: "https://docs.oficina.works") |
| 9 | #if os(macOS) |
| 10 | @Bindable var windows: DocsWindows |
| 11 | @Environment(\.openWindow) private var openWindow |
| 12 | #endif |
| 13 | private func transport(for account: String?) -> @MainActor () -> NativeTransport? { |
| 14 | let connection = connection |
| 15 | return DocsAccountTransport.supplier(account: account, |
| 16 | active: { [weak connection] in connection?.activeAccountID }, |
| 17 | client: { [weak connection] in connection?.client }) |
| 18 | } |
| 19 | |
| 20 | var body: some View { |
| 21 | Group { |
| 22 | if let client = connection.client { |
| 23 | #if os(macOS) |
| 24 | if let account = connection.activeAccountID { |
| 25 | DocsWorkspace(client: client, accountID: account, transport: transport(for: account), accounts: connection.showAccounts, signOut: { |
| 26 | guard connection.activeAccountID == account, windows.canSignOut(account) else { return } |
| 27 | windows.entries.removeAll { $0.account == account } |
| 28 | connection.signOut() |
| 29 | }, createDocument: { |
| 30 | guard connection.activeAccountID == account else { return } |
| 31 | let id = windows.reserveDraft(account: account, client: client) |
| 32 | openWindow(id: "document", value: id) |
| 33 | }, canSignOut: windows.canSignOut(account), createRequested: $windows.createRequested, accountsRequested: $windows.accountsRequested, openDocument: { document, title in |
| 34 | guard connection.activeAccountID == account else { return } |
| 35 | let id = windows.reserve(account: account, document: document, title: title, client: client) |
| 36 | openWindow(id: "document", value: id) |
| 37 | }, updateRecents: { documents in |
| 38 | guard connection.activeAccountID == account else { return } |
| 39 | windows.updateRecents(documents, account: account, client: client) |
| 40 | }) |
| 41 | .id(account) |
| 42 | } |
| 43 | #else |
| 44 | DocsWorkspace(client: client, accountID: connection.activeAccountID, transport: transport(for: connection.activeAccountID), accounts: connection.showAccounts, signOut: connection.signOut) |
| 45 | .id(connection.activeAccountID) |
| 46 | #endif |
| 47 | } else { |
| 48 | NativeAccountsView("Oficina Docs", systemImage: "doc.text", connection: connection) |
| 49 | } |
| 50 | }.onOpenURL(perform: connection.handleOpenURL) |
| 51 | #if os(macOS) |
| 52 | .onChange(of: windows.accountsRequested, initial: true) { _, requested in |
| 53 | if requested && connection.client == nil { windows.accountsRequested = false } |
| 54 | } |
| 55 | .focusedSceneValue(\.docsWindowAccount, connection.activeAccountID) |
| 56 | .onChange(of: connection.activeAccountID, initial: true) { _, value in windows.activeAccount = value } |
| 57 | #endif |
| 58 | } |
| 59 | } |
| 60 | |