Connect to several servers, one coloured window each

This commit is contained in:
Ian Gulliver
2026-10-18 20:58:56 -07:00
parent c0b2f38584
commit 4347d4e9e4
15 changed files with 456 additions and 209 deletions
+62 -31
View File
@@ -9,7 +9,6 @@ typealias ViewState = State
@MainActor
final class AppDelegate: NSObject, NSApplicationDelegate {
var connection: Connection?
private var quitting = false
func applicationDidFinishLaunching(_ notification: Notification) {
@@ -21,8 +20,17 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
false
}
func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
if flag {
return true
}
Servers.shared.openAll()
return false
}
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
guard let store = connection?.store, !quitting else {
let stores = Servers.shared.connections.values.compactMap(\.store)
guard !stores.isEmpty, !quitting else {
return .terminateNow
}
quitting = true
@@ -34,7 +42,13 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
}
}
Task {
await store.stop()
await withTaskGroup(of: Void.self) { group in
for store in stores {
group.addTask {
await store.stop()
}
}
}
reply()
}
Task {
@@ -48,49 +62,66 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
@main
struct ByreApp: App {
@NSApplicationDelegateAdaptor private var delegate: AppDelegate
@ViewState private var connection = Connection()
@ViewState private var overlays = Overlays()
var body: some Scene {
Window("byre", id: "main") {
RootView()
.environment(connection)
.environment(overlays)
.font(Fonts.font(13))
.frame(minWidth: 640, minHeight: 400)
.onAppear {
delegate.connection = connection
}
WindowGroup(id: "main", for: String.self) { $origin in
ServerWindow(origin: $origin)
}
.defaultSize(width: 1280, height: 820)
.restorationBehavior(.disabled)
.defaultLaunchBehavior(.presented)
.commands {
CommandGroup(after: .appInfo) {
Button("Check for Updates…") {
Updater.shared.check()
}
Button("Change Server…") {
connection.changeServer()
ByreCommands()
}
}
}
struct ByreCommands: Commands {
@FocusedValue(\.serverWindow) private var focus
@Environment(\.openWindow) private var openWindow
var body: some Commands {
CommandGroup(after: .appInfo) {
Button("Check for Updates…") {
Updater.shared.check()
}
Button("Forget Server") {
focus?.forget?()
}
.disabled(focus?.forget == nil)
}
CommandGroup(replacing: .newItem) {
Button("New Server Window") {
openWindow(id: "main")
}
.keyboardShortcut("n")
Menu("Open Server") {
ForEach(Servers.shared.origins, id: \.self) { origin in
Button(URL(string: origin)?.host() ?? origin) {
openWindow(id: "main", value: origin)
}
}
}
PasteboardCommands()
CommandMenu("Go") {
goButton("Switch Task", "k")
goButton("Project", "p")
goButton("Lead", "l")
goButton("Merge", "s")
Divider()
goButton("Keyboard Shortcuts", "/")
}
.disabled(Servers.shared.origins.isEmpty)
}
PasteboardCommands()
CommandMenu("Go") {
goButton("Switch Task", "k")
goButton("Project", "p")
goButton("Lead", "l")
goButton("Merge", "s")
Divider()
goButton("Keyboard Shortcuts", "/")
}
}
private func goButton(_ label: String, _ key: String) -> some View {
Button(label) {
if let store = connection.store {
if let store = focus?.store, let overlays = focus?.overlays {
runGo(key, store, overlays)
}
}
.keyboardShortcut(KeyEquivalent(Character(key)))
.disabled(connection.store == nil || overlays.dialogOpen)
.disabled(focus?.store == nil || focus?.overlays.dialogOpen == true)
}
}