Files
iOS/Sources/Shared/Environment/FocusStatusWrapper.swift
Bruno Pantaleão 0008727ff3 WIP
2026-06-15 09:36:28 +02:00

103 lines
2.7 KiB
Swift

import Intents
import PromiseKit
public class FocusStateTrigger: UserDefaultsValueSync<Date> {
init() {
super.init(settingsKey: "FocusStateTriggerKey")
}
}
public class FocusStatusWrapper {
private(set) lazy var trigger = FocusStateTrigger()
public enum AuthorizationStatus: Equatable {
case notDetermined
case restricted
case denied
case authorized
init(authorizationStatus: INFocusStatusAuthorizationStatus) {
switch authorizationStatus {
case .notDetermined:
self = .notDetermined
case .restricted:
self = .restricted
case .denied:
self = .denied
case .authorized:
self = .authorized
@unknown default:
self = .denied
}
}
}
private var lastStatus: Status? {
willSet {
#if !os(macOS)
precondition(Current.isAppExtension)
#endif
}
}
public lazy var isAvailable: () -> Bool = { [weak self] in
#if !os(macOS)
if Current.isAppExtension {
return self?.lastStatus != nil
} else {
return true
}
#else
return true
#endif
}
public var authorizationStatus: () -> AuthorizationStatus = {
.init(authorizationStatus: INFocusStatusCenter.default.authorizationStatus)
}
public var requestAuthorization: () -> Guarantee<AuthorizationStatus> = {
let (promise, seal) = Guarantee<AuthorizationStatus>.pending()
INFocusStatusCenter.default.requestAuthorization { result in
seal(.init(authorizationStatus: result))
}
return promise
}
public struct Status: Equatable {
public var isFocused: Bool?
public init(focusStatus: INFocusStatus) {
self.init(
isFocused: focusStatus.isFocused
)
}
public init(isFocused: Bool?) {
self.isFocused = isFocused
}
}
public func update(fromReceived status: INFocusStatus?) {
#if !os(macOS)
precondition(Current.isAppExtension)
#endif
lastStatus = status.flatMap { Status(focusStatus: $0) }
trigger.value = Current.date()
}
public lazy var status: () -> Status = { [weak self] in
#if !os(macOS)
if Current.isAppExtension, let lastStatus = self?.lastStatus {
return lastStatus
} else {
return .init(focusStatus: INFocusStatusCenter.default.focusStatus)
}
#else
return .init(focusStatus: INFocusStatusCenter.default.focusStatus)
#endif
}
}