1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
// Copyright (C) 2024 Rubén Beltrán del Río
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see https://map.tranquil.systems.
import AppKit
import Sparkle
import SwiftUI
@main
struct MapApp: App {
private let updaterController: SPUStandardUpdaterController = SPUStandardUpdaterController(
startingUpdater: true, updaterDelegate: nil, userDriverDelegate: nil)
var body: some Scene {
DocumentGroup(newDocument: MapDocument(text: nil)) { file in
LazyMapEditor(document: file.$document, url: file.fileURL)
.focusedSceneValue(\.document, file.$document)
.focusedSceneValue(\.fileURL, file.fileURL)
}
.windowToolbarStyle(.unifiedCompact)
.commands {
MapCommands()
UpdateCommands(updaterController: updaterController)
}
Settings {
PreferencesWindow()
}
}
}
struct LazyMapEditor: View {
@Binding var document: MapDocument
var url: URL?
@FocusedBinding(\.document) var focusedDocument: MapDocument?
@FocusedValue(\.fileURL) var focusedFileURL: URL?
@State private var shouldRender = false
@State private var renderTask: Task<Void, Never>?
var isActiveDocument: Bool {
guard let focusedDocument else { return false }
// Use URL for identification if available, otherwise fall back to text comparison
if let documentURL = url,
let focusedURL = focusedFileURL
{
return documentURL == focusedURL
}
// For new documents without URLs, use text comparison as fallback
return focusedDocument.text == document.text
}
var body: some View {
if isActiveDocument && shouldRender {
MapEditor(document: $document, url: url)
} else {
Rectangle()
.fill(Color(NSColor.windowBackgroundColor))
.overlay(
VStack(spacing: 16) {
Text("document.inactive")
.font(.title2)
.foregroundColor(.secondary)
if let url = url {
Text(url.lastPathComponent)
.font(.caption)
.foregroundColor(.secondary)
}
}
)
.onChange(of: isActiveDocument) { _, newValue in
renderTask?.cancel()
renderTask = nil
if newValue {
renderTask = Task {
try? await Task.sleep(nanoseconds: 50_000_000)
if !Task.isCancelled {
await MainActor.run {
shouldRender = true
}
}
}
} else {
shouldRender = false
}
}
.onAppear {
// Initialize focus state properly - don't render by default
shouldRender = false
}
}
}
}
|