Files
RSync-Studio/Rsync Studio/Rsync StudioApp.swift
T

89 lines
3.4 KiB
Swift
Executable File

import SwiftUI
import SwiftData
@main
@MainActor
struct RsyncStudioApp: App {
let sharedModelContainer: ModelContainer
let startupStorageError: String?
@StateObject private var runner: RsyncRunner
@StateObject private var automation: BackgroundSyncCoordinator
@StateObject private var licensing: LicensingManager
init() {
let schema = Schema([
SyncJob.self,
SyncRun.self,
])
let configuration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
KeychainStore.delete("defaultSSHPassword")
_licensing = StateObject(wrappedValue: LicensingManager())
do {
let container = try ModelContainer(for: schema, configurations: [configuration])
sharedModelContainer = container
startupStorageError = nil
let rsyncRunner = RsyncRunner()
_runner = StateObject(wrappedValue: rsyncRunner)
_automation = StateObject(wrappedValue: BackgroundSyncCoordinator(modelContext: container.mainContext, runner: rsyncRunner))
} catch {
let fallbackConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: true)
do {
let fallback = try ModelContainer(for: schema, configurations: [fallbackConfiguration])
sharedModelContainer = fallback
startupStorageError = "Rsync Studio could not open its persistent database and is running with temporary in-memory storage for this session. Jobs or history created now will not persist. Original error: \(error.localizedDescription)"
let rsyncRunner = RsyncRunner()
_runner = StateObject(wrappedValue: rsyncRunner)
_automation = StateObject(wrappedValue: BackgroundSyncCoordinator(modelContext: fallback.mainContext, runner: rsyncRunner))
} catch {
fatalError("Rsync Studio could not initialise persistent or temporary storage: \(error)")
}
}
}
var body: some Scene {
WindowGroup {
ContentView(startupStorageError: startupStorageError)
.frame(minWidth: 1040, minHeight: 680)
.environmentObject(runner)
.environmentObject(automation)
.environmentObject(licensing)
.onAppear {
licensing.refresh()
if licensing.canUseApp { automation.start() } else { automation.stop() }
}
.onChange(of: licensing.canUseApp) { _, allowed in
if allowed { automation.start() } else { automation.stop() }
}
}
.modelContainer(sharedModelContainer)
.commands {
RsyncStudioCommands()
}
Window("Rsync Studio Help", id: "help") {
HelpView()
}
.defaultSize(width: 940, height: 780)
Settings {
SettingsView()
.environmentObject(automation)
.environmentObject(licensing)
}
}
}
private struct RsyncStudioCommands: Commands {
@Environment(\.openWindow) private var openWindow
var body: some Commands {
CommandGroup(replacing: .help) {
Button("Rsync Studio Help") {
openWindow(id: "help")
}
.keyboardShortcut("?", modifiers: [.command])
}
}
}