54 lines
1.4 KiB
Swift
54 lines
1.4 KiB
Swift
import Foundation
|
|
|
|
public enum AppLifecycleState: Equatable, Sendable {
|
|
case foreground
|
|
case background
|
|
}
|
|
|
|
public struct ScopedSessionEvent: Equatable, Sendable {
|
|
public var accountId: String
|
|
public var generation: Int
|
|
public var event: SessionEvent
|
|
|
|
public init(accountId: String, generation: Int, event: SessionEvent) {
|
|
self.accountId = accountId
|
|
self.generation = generation
|
|
self.event = event
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
public final class SessionLifecycleCoordinator: ObservableObject {
|
|
@Published public private(set) var lifecycleState: AppLifecycleState = .foreground
|
|
@Published public private(set) var activeAccountId: String
|
|
@Published public private(set) var generation = 0
|
|
|
|
public init(activeAccountId: String) {
|
|
self.activeAccountId = activeAccountId
|
|
}
|
|
|
|
public var shouldPollEvents: Bool {
|
|
lifecycleState == .foreground
|
|
}
|
|
|
|
public func enterBackground() {
|
|
lifecycleState = .background
|
|
}
|
|
|
|
public func enterForeground() {
|
|
lifecycleState = .foreground
|
|
}
|
|
|
|
public func switchAccount(to accountId: String) {
|
|
guard accountId != activeAccountId else {
|
|
return
|
|
}
|
|
activeAccountId = accountId
|
|
generation += 1
|
|
}
|
|
|
|
public func accepts(_ event: ScopedSessionEvent) -> Bool {
|
|
event.accountId == activeAccountId && event.generation == generation
|
|
}
|
|
}
|