package com.x8bit.bitwarden import android.content.Intent import android.os.Parcelable import androidx.lifecycle.viewModelScope import com.x8bit.bitwarden.data.auth.repository.AuthRepository import com.x8bit.bitwarden.data.auth.repository.util.getCaptchaCallbackTokenResult import com.x8bit.bitwarden.data.platform.repository.SettingsRepository import com.x8bit.bitwarden.ui.platform.base.BaseViewModel import com.x8bit.bitwarden.ui.platform.feature.settings.appearance.model.AppTheme import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.update import kotlinx.parcelize.Parcelize import javax.inject.Inject /** * A view model that helps launch actions for the [MainActivity]. */ @HiltViewModel class MainViewModel @Inject constructor( private val authRepository: AuthRepository, settingsRepository: SettingsRepository, ) : BaseViewModel( MainState( theme = settingsRepository.appTheme, ), ) { init { settingsRepository .appThemeStateFlow .onEach { trySendAction(MainAction.Internal.ThemeUpdate(it)) } .launchIn(viewModelScope) } override fun handleAction(action: MainAction) { when (action) { is MainAction.Internal.ThemeUpdate -> handleAppThemeUpdated(action) is MainAction.ReceiveNewIntent -> handleNewIntentReceived(action) } } private fun handleAppThemeUpdated(action: MainAction.Internal.ThemeUpdate) { mutableStateFlow.update { it.copy(theme = action.theme) } } private fun handleNewIntentReceived(action: MainAction.ReceiveNewIntent) { val captchaCallbackTokenResult = action.intent.getCaptchaCallbackTokenResult() when { captchaCallbackTokenResult != null -> { authRepository.setCaptchaCallbackTokenResult( tokenResult = captchaCallbackTokenResult, ) } else -> Unit } } } /** * Models state for the [MainActivity]. */ @Parcelize data class MainState( val theme: AppTheme, ) : Parcelable /** * Models actions for the [MainActivity]. */ sealed class MainAction { /** * Receive Intent by the application. */ data class ReceiveNewIntent(val intent: Intent) : MainAction() /** * Actions for internal use by the ViewModel. */ sealed class Internal : MainAction() { /** * Indicates that the app theme has changed. */ data class ThemeUpdate( val theme: AppTheme, ) : Internal() } }