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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
import SwiftUI
import SwiftData
import UniformTypeIdentifiers
@main
struct Application: App {
#if os(iOS)
private var model = Hotline(trackerClient: HotlineTrackerClient(), client: HotlineClient())
#endif
#if os(macOS)
@Environment(\.openWindow) private var openWindow
#endif
@State private var preferences = Prefs()
@State private var soundEffects = SoundEffectPlayer()
@State private var bookmarks = Bookmarks()
@FocusedValue(\.activeHotlineModel) private var activeHotline: Hotline?
@FocusedValue(\.activeServerState) private var activeServerState: ServerState?
var body: some Scene {
#if os(iOS)
WindowGroup {
TrackerView()
.environment(model)
}
#elseif os(macOS)
// MARK: Tracker Window
Window("Servers", id: "servers") {
TrackerView()
.frame(minWidth: 250, minHeight: 250)
.environment(bookmarks)
}
.keyboardShortcut(.init(.init("R"), modifiers: .command))
.defaultSize(width: 700, height: 550)
.defaultPosition(.center)
// MARK: Server Window
WindowGroup(id: "server", for: Server.self) { server in
ServerView(server: server)
.frame(minWidth: 430, minHeight: 300)
.environment(preferences)
.environment(soundEffects)
.environment(bookmarks)
} defaultValue: {
Server(name: nil, description: nil, address: "")
}
.defaultSize(width: 750, height: 700)
.defaultPosition(.center)
.commands {
CommandGroup(replacing: CommandGroupPlacement.newItem) {
Button("Connect to Server...") {
openWindow(id: "server")
}
.keyboardShortcut(.init("K"), modifiers: .command)
}
CommandMenu("Server") {
Button("Disconnect") {
activeHotline?.disconnect()
}
.disabled(activeHotline?.status == .disconnected)
Divider()
Button("Broadcast Message...") {
// TODO: Implement broadcast message when user is allowed.
}
.disabled(true)
.keyboardShortcut(.init("B"), modifiers: .command)
Divider()
Button("Show Chat") {
activeServerState?.selection = .chat
}
.disabled(activeHotline?.status != .loggedIn)
.keyboardShortcut(.init("1"), modifiers: .command)
Button("Show News") {
activeServerState?.selection = .news
}
.disabled(activeHotline?.status != .loggedIn)
.keyboardShortcut(.init("2"), modifiers: .command)
Button("Show Message Board") {
activeServerState?.selection = .board
}
.disabled(activeHotline?.status != .loggedIn)
.keyboardShortcut(.init("3"), modifiers: .command)
Button("Show Files") {
activeServerState?.selection = .files
}
.disabled(activeHotline?.status != .loggedIn)
.keyboardShortcut(.init("4"), modifiers: .command)
}
}
// MARK: Settings Window
Settings {
SettingsView()
.environment(preferences)
}
// MARK: News Editor Window
// WindowGroup(id: "news-editor", for: NewsArticle.self) { $article in
// NewsEditorView(article: $article)
// }
// .windowResizability(.contentSize)
// .windowStyle(.titleBar)
// .windowToolbarStyle(.unifiedCompact(showsTitle: true))
// .defaultSize(width: 450, height: 550)
// .defaultPosition(.center)
// MARK: Image Preview Window
WindowGroup(id: "preview-image", for: PreviewFileInfo.self) { $info in
FilePreviewImageView(info: $info)
}
.windowResizability(.contentSize)
.windowStyle(.titleBar)
.windowToolbarStyle(.unifiedCompact(showsTitle: true))
.defaultSize(width: 350, height: 150)
.defaultPosition(.center)
// MARK: Text Preview Window
WindowGroup(id: "preview-text", for: PreviewFileInfo.self) { $info in
FilePreviewTextView(info: $info)
}
.windowResizability(.automatic)
.windowStyle(.titleBar)
.windowToolbarStyle(.unifiedCompact(showsTitle: true))
.defaultSize(width: 450, height: 550)
.defaultPosition(.center)
#endif
}
}
|