mirror of
https://github.com/bitwarden/android.git
synced 2025-03-15 18:58:59 +03:00
Store SpecialCircumstance to SavedStateHandle (#799)
This commit is contained in:
parent
3264be998d
commit
7a163d82ed
4 changed files with 70 additions and 4 deletions
|
@ -2,6 +2,7 @@ package com.x8bit.bitwarden
|
|||
|
||||
import android.content.Intent
|
||||
import android.os.Parcelable
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.x8bit.bitwarden.data.platform.manager.SpecialCircumstanceManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.SpecialCircumstance
|
||||
|
@ -16,6 +17,8 @@ import kotlinx.coroutines.flow.update
|
|||
import kotlinx.parcelize.Parcelize
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val SPECIAL_CIRCUMSTANCE_KEY = "special-circumstance"
|
||||
|
||||
/**
|
||||
* A view model that helps launch actions for the [MainActivity].
|
||||
*/
|
||||
|
@ -24,12 +27,27 @@ class MainViewModel @Inject constructor(
|
|||
private val specialCircumstanceManager: SpecialCircumstanceManager,
|
||||
private val intentManager: IntentManager,
|
||||
settingsRepository: SettingsRepository,
|
||||
private val savedStateHandle: SavedStateHandle,
|
||||
) : BaseViewModel<MainState, Unit, MainAction>(
|
||||
MainState(
|
||||
theme = settingsRepository.appTheme,
|
||||
),
|
||||
) {
|
||||
private var specialCircumstance: SpecialCircumstance?
|
||||
get() = savedStateHandle[SPECIAL_CIRCUMSTANCE_KEY]
|
||||
set(value) {
|
||||
savedStateHandle[SPECIAL_CIRCUMSTANCE_KEY] = value
|
||||
}
|
||||
|
||||
init {
|
||||
// Immediately restore the special circumstance if we have one and then listen for changes
|
||||
specialCircumstanceManager.specialCircumstance = specialCircumstance
|
||||
|
||||
specialCircumstanceManager
|
||||
.specialCircumstanceStateFlow
|
||||
.onEach { specialCircumstance = it }
|
||||
.launchIn(viewModelScope)
|
||||
|
||||
settingsRepository
|
||||
.appThemeStateFlow
|
||||
.onEach { trySendAction(MainAction.Internal.ThemeUpdate(it)) }
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
package com.x8bit.bitwarden.data.platform.manager.model
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
/**
|
||||
* Represents a special circumstance the app may be in. These circumstances could require some kind
|
||||
* of navigation that is counter to what otherwise may happen based on the state of the app.
|
||||
*/
|
||||
sealed class SpecialCircumstance {
|
||||
sealed class SpecialCircumstance : Parcelable {
|
||||
/**
|
||||
* The app was launched in order to create/share a new Send using the given [data].
|
||||
*/
|
||||
@Parcelize
|
||||
data class ShareNewSend(
|
||||
val data: IntentManager.ShareData,
|
||||
val shouldFinishWhenComplete: Boolean,
|
||||
|
|
|
@ -2,9 +2,11 @@ package com.x8bit.bitwarden.ui.platform.manager.intent
|
|||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Parcelable
|
||||
import androidx.activity.compose.ManagedActivityResultLauncher
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.compose.runtime.Composable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
/**
|
||||
* A manager class for simplifying the handling of Android Intents within a given context.
|
||||
|
@ -74,19 +76,21 @@ interface IntentManager {
|
|||
/**
|
||||
* Represents file information.
|
||||
*/
|
||||
@Parcelize
|
||||
data class FileData(
|
||||
val fileName: String,
|
||||
val uri: Uri,
|
||||
val sizeBytes: Long,
|
||||
)
|
||||
) : Parcelable
|
||||
|
||||
/**
|
||||
* Represents data for a share request coming from outside the app.
|
||||
*/
|
||||
sealed class ShareData {
|
||||
sealed class ShareData : Parcelable {
|
||||
/**
|
||||
* The data required to create a new Text Send.
|
||||
*/
|
||||
@Parcelize
|
||||
data class TextSend(
|
||||
val subject: String?,
|
||||
val text: String,
|
||||
|
@ -95,6 +99,7 @@ interface IntentManager {
|
|||
/**
|
||||
* The data required to create a new File Send.
|
||||
*/
|
||||
@Parcelize
|
||||
data class FileSend(
|
||||
val fileData: FileData,
|
||||
) : ShareData()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.x8bit.bitwarden
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.UserState
|
||||
import com.x8bit.bitwarden.data.auth.repository.util.getCaptchaCallbackTokenResult
|
||||
|
@ -16,6 +17,7 @@ import io.mockk.mockk
|
|||
import io.mockk.verify
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertNull
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class MainViewModelTest : BaseViewModelTest() {
|
||||
|
@ -34,6 +36,38 @@ class MainViewModelTest : BaseViewModelTest() {
|
|||
private val intentManager: IntentManager = mockk {
|
||||
every { getShareDataFromIntent(any()) } returns null
|
||||
}
|
||||
private val savedStateHandle = SavedStateHandle()
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `initialization should set a saved SpecialCircumstance to the SpecialCircumstanceManager if present`() {
|
||||
assertNull(specialCircumstanceManager.specialCircumstance)
|
||||
|
||||
val specialCircumstance = mockk<SpecialCircumstance>()
|
||||
createViewModel(
|
||||
initialSpecialCircumstance = specialCircumstance,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
specialCircumstance,
|
||||
specialCircumstanceManager.specialCircumstance,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `SpecialCircumstance updates should update the SavedStateHandle`() {
|
||||
createViewModel()
|
||||
|
||||
assertNull(savedStateHandle[SPECIAL_CIRCUMSTANCE_KEY])
|
||||
|
||||
val specialCircumstance = mockk<SpecialCircumstance>()
|
||||
specialCircumstanceManager.specialCircumstance = specialCircumstance
|
||||
|
||||
assertEquals(
|
||||
specialCircumstance,
|
||||
savedStateHandle[SPECIAL_CIRCUMSTANCE_KEY],
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on AppThemeChanged should update state`() {
|
||||
|
@ -109,13 +143,19 @@ class MainViewModelTest : BaseViewModelTest() {
|
|||
)
|
||||
}
|
||||
|
||||
private fun createViewModel() = MainViewModel(
|
||||
private fun createViewModel(
|
||||
initialSpecialCircumstance: SpecialCircumstance? = null,
|
||||
) = MainViewModel(
|
||||
specialCircumstanceManager = specialCircumstanceManager,
|
||||
settingsRepository = settingsRepository,
|
||||
intentManager = intentManager,
|
||||
savedStateHandle = savedStateHandle.apply {
|
||||
set(SPECIAL_CIRCUMSTANCE_KEY, initialSpecialCircumstance)
|
||||
},
|
||||
)
|
||||
|
||||
companion object {
|
||||
private const val SPECIAL_CIRCUMSTANCE_KEY = "special-circumstance"
|
||||
private const val USER_ID = "userID"
|
||||
private val DEFAULT_USER_STATE = UserState(
|
||||
activeUserId = USER_ID,
|
||||
|
|
Loading…
Add table
Reference in a new issue