| 1 | #if os(macOS) |
| 2 | import Foundation |
| 3 | import DocsKit |
| 4 | import Observation |
| 5 | import RastrilloApple |
| 6 | import SwiftUI |
| 7 | |
| 8 | /// Scene values are opaque IDs, never credentials. Reserve before opening a scene. |
| 9 | @MainActor @Observable final class DocsWindows { |
| 10 | struct Entry: Identifiable { |
| 11 | let id: UUID |
| 12 | let account: String |
| 13 | var document: String |
| 14 | let client: NativeHTTP |
| 15 | var title: String |
| 16 | var isOpen = false |
| 17 | var isDraft = false |
| 18 | } |
| 19 | var entries: [Entry] = [] |
| 20 | var activeAccount: String? |
| 21 | var createRequested = false |
| 22 | var accountsRequested = false |
| 23 | func reserve(account: String, document: String, title: String, client: NativeHTTP) -> UUID { |
| 24 | if let index = entries.firstIndex(where: { $0.account == account && $0.client.origin == client.origin && $0.document == document }) { |
| 25 | var entry = entries.remove(at: index) |
| 26 | entry.title = title |
| 27 | entry.isOpen = true |
| 28 | entries.insert(entry, at: 0) |
| 29 | return entry.id |
| 30 | } |
| 31 | let entry = Entry(id: UUID(), account: account, document: document, client: client, title: title, isOpen: true) |
| 32 | entries.insert(entry, at: 0) |
| 33 | return entry.id |
| 34 | } |
| 35 | func reserveDraft(account: String, client: NativeHTTP) -> UUID { |
| 36 | let id = UUID() |
| 37 | entries.insert(Entry(id: id, account: account, document: "draft-" + id.uuidString, client: client, title: docsMacString("Untitled document"), isOpen: true, isDraft: true), at: 0) |
| 38 | return id |
| 39 | } |
| 40 | func attach(_ id: UUID, document: String, title: String) { |
| 41 | guard let index = entries.firstIndex(where: { $0.id == id }) else { return } |
| 42 | entries[index].document = document; entries[index].title = title; entries[index].isDraft = false |
| 43 | let account = entries[index].account |
| 44 | entries.removeAll { $0.id != id && !$0.isOpen && $0.account == account && $0.document == document } |
| 45 | } |
| 46 | func updateRecents(_ documents: [(String, String)], account: String, client: NativeHTTP) { |
| 47 | for (document, title) in documents { |
| 48 | if let index = entries.firstIndex(where: { $0.account == account && $0.client.origin == client.origin && $0.document == document }) { |
| 49 | entries[index].title = title |
| 50 | } else { |
| 51 | entries.append(Entry(id: UUID(), account: account, document: document, client: client, title: title)) |
| 52 | } |
| 53 | } |
| 54 | } |
| 55 | func setOpen(_ id: UUID, _ value: Bool) { |
| 56 | if let index = entries.firstIndex(where: { $0.id == id }) { |
| 57 | if !value && entries[index].isDraft { entries.remove(at: index) } else { entries[index].isOpen = value } |
| 58 | } |
| 59 | } |
| 60 | func canSignOut(_ account: String?) -> Bool { !entries.contains { $0.account == account && $0.isOpen } } |
| 61 | } |
| 62 | extension FocusedValues { @Entry var docsWindowAccount: String? } |
| 63 | #endif |
| 64 | |