123 lines
4.1 KiB
Swift
123 lines
4.1 KiB
Swift
//
|
|
// Swiftfin is subject to the terms of the Mozilla Public
|
|
// License, v2.0. If a copy of the MPL was not distributed with this
|
|
// file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
|
//
|
|
// Copyright (c) 2025 Jellyfin & Jellyfin Contributors
|
|
//
|
|
|
|
import Combine
|
|
import Defaults
|
|
import Foundation
|
|
import SwiftUI
|
|
|
|
// Following class is necessary to observe values that can either
|
|
// be a user *or* an app setting and only one should apply at a time.
|
|
//
|
|
// Also just to separate out value observation
|
|
|
|
// TODO: could clean up?
|
|
|
|
extension SwiftfinApp {
|
|
|
|
class ValueObservation: ObservableObject {
|
|
|
|
private var accentColorCancellable: AnyCancellable?
|
|
private var appearanceCancellable: AnyCancellable?
|
|
private var lastSignInUserIDCancellable: AnyCancellable?
|
|
private var splashScreenCancellable: AnyCancellable?
|
|
|
|
init() {
|
|
|
|
// MARK: signed in observation
|
|
|
|
lastSignInUserIDCancellable = Task {
|
|
for await newValue in Defaults.updates(.lastSignedInUserID) {
|
|
if case .signedIn = newValue {
|
|
setUserDefaultsObservation()
|
|
} else {
|
|
setAppDefaultsObservation()
|
|
}
|
|
}
|
|
}
|
|
.asAnyCancellable()
|
|
}
|
|
|
|
// MARK: user observation
|
|
|
|
private func setUserDefaultsObservation() {
|
|
accentColorCancellable?.cancel()
|
|
appearanceCancellable?.cancel()
|
|
splashScreenCancellable?.cancel()
|
|
|
|
accentColorCancellable = Task {
|
|
for await newValue in Defaults.updates(.userAccentColor) {
|
|
await MainActor.run {
|
|
Defaults[.accentColor] = newValue
|
|
UIApplication.shared.setAccentColor(newValue.uiColor)
|
|
}
|
|
}
|
|
}
|
|
.asAnyCancellable()
|
|
|
|
appearanceCancellable = Task {
|
|
for await newValue in Defaults.updates(.userAppearance) {
|
|
await MainActor.run {
|
|
Defaults[.appearance] = newValue
|
|
UIApplication.shared.setAppearance(newValue.style)
|
|
}
|
|
}
|
|
}
|
|
.asAnyCancellable()
|
|
}
|
|
|
|
// MARK: app observation
|
|
|
|
private func setAppDefaultsObservation() {
|
|
accentColorCancellable?.cancel()
|
|
appearanceCancellable?.cancel()
|
|
splashScreenCancellable?.cancel()
|
|
|
|
accentColorCancellable = Task {
|
|
for await newValue in Defaults.updates(.appAccentColor) {
|
|
await MainActor.run {
|
|
Defaults[.accentColor] = newValue
|
|
UIApplication.shared.setAccentColor(newValue.uiColor)
|
|
}
|
|
}
|
|
}
|
|
.asAnyCancellable()
|
|
|
|
appearanceCancellable = Task {
|
|
for await newValue in Defaults.updates(.appAppearance) {
|
|
|
|
// other cancellable will set appearance if enabled
|
|
// and need to avoid races
|
|
guard !Defaults[.selectUserUseSplashscreen] else { continue }
|
|
|
|
await MainActor.run {
|
|
Defaults[.appearance] = newValue
|
|
UIApplication.shared.setAppearance(newValue.style)
|
|
}
|
|
}
|
|
}
|
|
.asAnyCancellable()
|
|
|
|
splashScreenCancellable = Task {
|
|
for await newValue in Defaults.updates(.selectUserUseSplashscreen) {
|
|
await MainActor.run {
|
|
if newValue {
|
|
Defaults[.appearance] = .dark
|
|
UIApplication.shared.setAppearance(.dark)
|
|
} else {
|
|
Defaults[.appearance] = Defaults[.appAppearance]
|
|
UIApplication.shared.setAppearance(Defaults[.appAppearance].style)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.asAnyCancellable()
|
|
}
|
|
}
|
|
}
|