75 lines
2.0 KiB
Swift
75 lines
2.0 KiB
Swift
import Foundation
|
|
import Combine
|
|
|
|
@MainActor
|
|
final class AppSettingsController: ObservableObject, TerminalSessionConfigurationProviding {
|
|
static let shared = AppSettingsController(
|
|
store: UserDefaultsAppSettingsStore(),
|
|
observeExternalChanges: true
|
|
)
|
|
|
|
@Published private(set) var settings: AppSettings
|
|
|
|
private let store: any AppSettingsStoreType
|
|
private let notificationCenter: NotificationCenter
|
|
private var defaultsObserver: NSObjectProtocol?
|
|
|
|
init(
|
|
store: any AppSettingsStoreType,
|
|
observeExternalChanges: Bool = false,
|
|
notificationCenter: NotificationCenter = .default
|
|
) {
|
|
self.store = store
|
|
self.notificationCenter = notificationCenter
|
|
self.settings = store.load()
|
|
|
|
if observeExternalChanges {
|
|
defaultsObserver = notificationCenter.addObserver(
|
|
forName: UserDefaults.didChangeNotification,
|
|
object: nil,
|
|
queue: .main
|
|
) { [weak self] _ in
|
|
Task { @MainActor in
|
|
self?.refresh()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
if let defaultsObserver {
|
|
notificationCenter.removeObserver(defaultsObserver)
|
|
}
|
|
}
|
|
|
|
var terminalSessionConfiguration: TerminalSessionConfiguration {
|
|
TerminalSessionConfiguration(
|
|
fontSize: CGFloat(settings.terminal.fontSize),
|
|
theme: settings.terminal.theme,
|
|
shellPath: settings.terminal.shellPath
|
|
)
|
|
}
|
|
|
|
var hotkeySettings: AppSettings.HotkeySettings {
|
|
settings.hotkeys
|
|
}
|
|
|
|
var terminalSizePresets: [TerminalSizePreset] {
|
|
settings.terminal.sizePresets
|
|
}
|
|
|
|
func refresh() {
|
|
let loaded = store.load()
|
|
guard loaded != settings else { return }
|
|
settings = loaded
|
|
}
|
|
|
|
func update(_ mutate: (inout AppSettings) -> Void) {
|
|
var updated = settings
|
|
mutate(&updated)
|
|
guard updated != settings else { return }
|
|
settings = updated
|
|
store.save(updated)
|
|
}
|
|
}
|