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? private var dataTask: Task? 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) } } } }