// // AppDelegate.swift // MastoSearch // // Created by Shadowfacts on 12/10/21. // import Cocoa import UniformTypeIdentifiers import AuthenticationServices import Combine import OSLog import MastoSearchCore @main class AppDelegate: NSObject, NSApplicationDelegate { @IBOutlet weak var accountMenu: NSMenu! func applicationWillFinishLaunching(_ notification: Notification) { DatabaseController.shared.initialize() updateAccountMenu() } func applicationDidFinishLaunching(_ aNotification: Notification) { SyncController.shared.syncStatuses(errorHandler: self.handleSyncError(_:)) } func applicationWillTerminate(_ aNotification: Notification) { DatabaseController.shared.close() } func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { return true } private func updateAccountMenu() { accountMenu.removeAllItems() if let account = LocalData.account { let item = accountMenu.addItem(withTitle: "Logged in to \(account.instanceURL.host!)", action: nil, keyEquivalent: "") item.isEnabled = false accountMenu.addItem(withTitle: "Log out", action: #selector(logOut), keyEquivalent: "") } else { accountMenu.addItem(withTitle: "Log in...", action: #selector(logIn), keyEquivalent: "") } } @IBAction func importFile(_ sender: Any) { let panel = NSOpenPanel() panel.canChooseFiles = true panel.canChooseDirectories = false panel.allowsMultipleSelection = false panel.allowedContentTypes = [.commaSeparatedText] panel.beginSheetModal(for: NSApp.mainWindow!) { (resp) in guard resp == .OK else { return } ImportController.shared.importCSV(url: panel.url!) SyncController.shared.onSync.send() SyncController.shared.syncStatuses(errorHandler: self.handleSyncError(_:)) } } @objc func logIn() { let alert = NSAlert() alert.messageText = "Enter instance URL:" alert.addButton(withTitle: "OK") alert.addButton(withTitle: "Cancel") let textField = NSTextField(frame: NSRect(x: 0, y: 0, width: 300, height: 24)) textField.placeholderString = "https://mastodon.social/" alert.accessoryView = textField guard alert.runModal() == .alertFirstButtonReturn, let url = URL(string: textField.stringValue) else { return } LoginController.shared.logIn(with: url, presentationContextProvider: self) { self.updateAccountMenu() SyncController.shared.syncStatuses(errorHandler: self.handleSyncError(_:)) } } @objc func logOut() { LocalData.account = nil updateAccountMenu() } private func handleSyncError(_ error: APIController.Error) { let alert = NSAlert() alert.alertStyle = .warning alert.messageText = "Error syncing statuses" alert.informativeText = error.localizedDescription alert.runModal() } } extension AppDelegate: ASWebAuthenticationPresentationContextProviding { func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { return NSApp.keyWindow! } }