69 lines
2.1 KiB
Swift
69 lines
2.1 KiB
Swift
import CoreDomain
|
||
import CoreModel
|
||
import Observation
|
||
|
||
@MainActor
|
||
@Observable
|
||
public final class CheckinViewModel {
|
||
public private(set) var uiState: CheckinUiState = .loading
|
||
public var selectedStatus: CheckinStatus = .normal
|
||
public var submitting = false
|
||
|
||
private let checkinUseCase: CheckinUseCase
|
||
private let sessionUseCase: SessionUseCase
|
||
private var loadTask: Task<Void, Never>?
|
||
private var dataTask: Task<Void, Never>?
|
||
|
||
public init(checkinUseCase: CheckinUseCase, sessionUseCase: SessionUseCase) {
|
||
self.checkinUseCase = checkinUseCase
|
||
self.sessionUseCase = sessionUseCase
|
||
}
|
||
|
||
public func load() {
|
||
loadTask?.cancel()
|
||
loadTask = Task { [weak self] in
|
||
guard let self else { return }
|
||
do {
|
||
for try await isLoggedIn in self.sessionUseCase.observeIsLoggedIn() {
|
||
self.handleLoginState(isLoggedIn)
|
||
}
|
||
} catch is CancellationError {
|
||
} catch {
|
||
self.uiState = .error(error.localizedDescription)
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 提交打卡(对齐 android:只即时高亮选中 pill,卡片/成员靠流重新发射刷新)。
|
||
public func submit(_ status: CheckinStatus) {
|
||
guard !submitting else { return }
|
||
selectedStatus = status
|
||
submitting = true
|
||
Task { [weak self] in
|
||
guard let self else { return }
|
||
try? await self.checkinUseCase.submitCheckin(status: status)
|
||
self.submitting = false
|
||
}
|
||
}
|
||
|
||
private func handleLoginState(_ isLoggedIn: Bool) {
|
||
dataTask?.cancel()
|
||
guard isLoggedIn else {
|
||
uiState = .loggedOut
|
||
return
|
||
}
|
||
uiState = .loading
|
||
dataTask = Task { [weak self] in
|
||
guard let self else { return }
|
||
do {
|
||
for try await record in self.checkinUseCase.observeCheckin() {
|
||
self.uiState = .success(record)
|
||
}
|
||
} catch is CancellationError {
|
||
} catch {
|
||
self.uiState = .error(error.localizedDescription)
|
||
}
|
||
}
|
||
}
|
||
}
|