aboutsummaryrefslogtreecommitdiff
path: root/Hotline/Application-macOS.swift
diff options
context:
space:
mode:
authorDustin Mierau <dustin@mierau.me>2025-10-20 22:15:48 -0700
committerDustin Mierau <dustin@mierau.me>2025-10-20 22:15:48 -0700
commitede41868962ffed386b0da694d14cdfe6cfdb34f (patch)
treef0b91edd1d9c1bbc23de525224b49d6f8e48e815 /Hotline/Application-macOS.swift
parent77b3ac3c051fc4e8fa126cd21e261be28f4aad1a (diff)
Cleanup and a bunch of work to fix issues syncing, loading, and general bookmark states in TrackerView. Added search field (substring conjunctive filter on server/bookmark names and descriptions).
Diffstat (limited to 'Hotline/Application-macOS.swift')
-rw-r--r--Hotline/Application-macOS.swift303
1 files changed, 0 insertions, 303 deletions
diff --git a/Hotline/Application-macOS.swift b/Hotline/Application-macOS.swift
deleted file mode 100644
index fe3a828..0000000
--- a/Hotline/Application-macOS.swift
+++ /dev/null
@@ -1,303 +0,0 @@
-import SwiftUI
-import SwiftData
-import CloudKit
-import UniformTypeIdentifiers
-
-@Observable
-final class AppLaunchState {
- static let shared = AppLaunchState()
-
- enum LaunchState {
- case loading
- case launched
- case terminated
- }
-
- var launchState = LaunchState.loading
-}
-
-class AppDelegate: NSObject, NSApplicationDelegate {
- private var cloudKitObserverToken: Any? = nil
-
- func applicationDidFinishLaunching(_ notification: Notification) {
- AppLaunchState.shared.launchState = .launched
-
- CKContainer.default().accountStatus { status, error in
- switch status {
- case .noAccount:
- print("iCloud Unavailable")
-
- // We mark CloudKit has available now since we're not waiting on
- // a server sync or anything.
- ApplicationState.shared.cloudKitReady = true
- default:
- print("iCloud Available")
-
- self.cloudKitObserverToken = NotificationCenter.default.addObserver(forName: NSPersistentCloudKitContainer.eventChangedNotification, object: nil, queue: OperationQueue.main) { [weak self] note in
- print("iCloud Changed!")
- ApplicationState.shared.cloudKitReady = true
-
- guard let token = self?.cloudKitObserverToken else { return }
- NotificationCenter.default.removeObserver(token)
- }
- }
- }
-
-// if FileManager.default.ubiquityIdentityToken == nil {
-// print("iCloud Unavailable")
-//
-// // We mark CloudKit has available now since we're not waiting on
-// // a server sync or anything.
-// ApplicationState.shared.cloudKitReady = true
-// }
-// else {
-// print("iCloud Available")
-//
-// self.cloudKitObserverToken = NotificationCenter.default.addObserver(forName: NSPersistentCloudKitContainer.eventChangedNotification, object: nil, queue: OperationQueue.main) { [weak self] note in
-// print("iCloud Changed!")
-// ApplicationState.shared.cloudKitReady = true
-//
-// guard let token = self?.cloudKitObserverToken else { return }
-// NotificationCenter.default.removeObserver(token)
-// }
-// }
- }
-
- func applicationWillTerminate(_ notification: Notification) {
- AppLaunchState.shared.launchState = .terminated
- }
-}
-
-@main
-struct Application: App {
- @Environment(\.scenePhase) private var scenePhase
- @Environment(\.openWindow) private var openWindow
- @Environment(\.openURL) private var openURL
-
- @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
-
- @State private var hotlinePanel: HotlinePanel? = nil
- @State private var selection: Bookmark? = nil
-
- @FocusedValue(\.activeHotlineModel) private var activeHotline: Hotline?
- @FocusedValue(\.activeServerState) private var activeServerState: ServerState?
-
- private var modelContainer: ModelContainer = {
- let schema = Schema([
- Bookmark.self
- ])
- let config = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false, cloudKitDatabase: .private("iCloud.co.goodmake.hotline"))
- let modelContainer = try! ModelContainer(for: schema, configurations: [config])
-
- // Print local SwiftData sqlite file.
-// print(modelContainer.configurations.first?.url.path(percentEncoded: false))
-
- return modelContainer
- }()
-
- var body: some Scene {
- // MARK: Tracker Window
- Window("Servers", id: "servers") {
- TrackerView(selection: $selection)
- .frame(minWidth: 250, minHeight: 250)
- }
- .modelContainer(self.modelContainer)
- .defaultSize(width: 700, height: 550)
- .defaultPosition(.center)
- .keyboardShortcut(.init("R"), modifiers: .command)
- .onChange(of: AppLaunchState.shared.launchState) {
- if AppLaunchState.shared.launchState == .launched {
- if Prefs.shared.showBannerToolbar {
- showBannerWindow()
- }
- }
- }
-
- // MARK: About Box
- Window("About", id: "about") {
- AboutView()
- .ignoresSafeArea()
- .background(Color.hotlineRed)
- }
- .windowResizability(.contentSize)
- .windowStyle(.hiddenTitleBar)
- .defaultPosition(.center)
- .commandsRemoved() // Remove About that was automatically added to Window menu.
- .commands {
- CommandGroup(replacing: CommandGroupPlacement.appInfo) {
- Button("About Hotline") {
- openWindow(id: "about")
- }
- }
- }
-
- // MARK: Server Window
- WindowGroup(id: "server", for: Server.self) { server in
- ServerView(server: server)
- .frame(minWidth: 430, minHeight: 300)
- } defaultValue: {
- Server(name: nil, description: nil, address: "")
- }
- .modelContainer(self.modelContainer)
- .defaultSize(width: 750, height: 700)
- .defaultPosition(.center)
- .onChange(of: activeServerState) {
- ApplicationState.shared.activeServerState = activeServerState
- }
- .onChange(of: activeHotline) {
- ApplicationState.shared.activeHotline = activeHotline
- }
- .onChange(of: activeHotline?.serverTitle) {
- if let hotline = activeHotline {
- ApplicationState.shared.activeServerName = hotline.serverTitle
- }
- }
- .onChange(of: activeHotline?.bannerImage) {
- withAnimation {
- ApplicationState.shared.activeServerBanner = activeHotline?.bannerImage
- }
- }
- .onChange(of: activeHotline) {
- ApplicationState.shared.activeHotline = activeHotline
- if let hotline = activeHotline {
- ApplicationState.shared.activeServerName = hotline.serverTitle
- }
- }
- .commands {
- CommandGroup(replacing: .newItem) {
- Button("Connect to Server...") {
- openWindow(id: "server")
- }
- .keyboardShortcut(.init("K"), modifiers: .command)
- }
- CommandGroup(after: .singleWindowList) {
- Button("Toolbar") {
- toggleBannerWindow()
- }
- .keyboardShortcut(.init("\\"), modifiers: [.shift, .command])
- }
- CommandGroup(after: .help) {
- Divider()
- Button("Request Feature...") {
- if let url = URL(string: "https://github.com/mierau/hotline/issues/new?labels=enhancement") {
- openURL(url)
- }
- }
- Button("Report Bug...") {
- if let url = URL(string: "https://github.com/mierau/hotline/issues/new?labels=bug") {
- openURL(url)
- }
- }
- Divider()
- Button("Download Latest...") {
- if let url = URL(string: "https://github.com/mierau/hotline/releases/latest") {
- openURL(url)
- }
- }
- }
- CommandMenu("Server") {
- Button("Connect") {
- guard let selection else {
- return
- }
- connect(to: selection)
- }
- .disabled(selection == nil || selection?.server == nil)
- .keyboardShortcut(.downArrow, modifiers: .command)
- 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 || (activeHotline?.serverVersion ?? 0) < 151)
- .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)
- Button("Show Accounts") {
- activeServerState?.selection = .accounts
- }
- .disabled(activeHotline?.status != .loggedIn || activeHotline?.access?.contains(.canOpenUsers) != true )
- .keyboardShortcut(.init("5"), modifiers: .command)
- }
- }
-
- // MARK: Settings Window
- Settings {
- SettingsView()
- }
-
- // 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)
- }
-
- func connect(to item: Bookmark) {
- if let server = item.server {
- openWindow(id: "server", value: server)
- }
- }
-
- func showBannerWindow() {
- if hotlinePanel == nil {
- hotlinePanel = HotlinePanel(HotlinePanelView())
- }
-
- if hotlinePanel?.isVisible == false {
- hotlinePanel?.orderFront(nil)
- Prefs.shared.showBannerToolbar = true
- }
- }
-
- func toggleBannerWindow() {
- if hotlinePanel == nil {
- hotlinePanel = HotlinePanel(HotlinePanelView())
- }
-
- if hotlinePanel?.isVisible == true {
- hotlinePanel?.orderOut(nil)
- Prefs.shared.showBannerToolbar = false
- }
- else {
- hotlinePanel?.orderFront(nil)
- Prefs.shared.showBannerToolbar = true
- }
- }
-}