mirror of
https://github.com/bitwarden/android.git
synced 2026-03-11 20:54:58 -05:00
Migrate DataStateExtensions to core module
Move `DataStateExtensions` to the `core` module. - Deleted `DataStateExtensions.kt` from `authenticator` and `app` modules. - Updated all imports. - Added `junit5` and `kotlinx.coroutines.test` test implementation to `core` module.
This commit is contained in:
@@ -23,13 +23,13 @@ import com.bitwarden.authenticator.data.platform.manager.imports.model.ImportDat
|
||||
import com.bitwarden.authenticator.data.platform.manager.imports.model.ImportFileFormat
|
||||
import com.bitwarden.authenticator.data.platform.manager.model.FlagKey
|
||||
import com.bitwarden.authenticator.data.platform.repository.SettingsRepository
|
||||
import com.bitwarden.core.data.repository.model.DataState
|
||||
import com.bitwarden.authenticator.data.platform.repository.util.map
|
||||
import com.bitwarden.authenticator.ui.platform.feature.settings.export.model.ExportVaultFormat
|
||||
import com.bitwarden.authenticator.ui.platform.manager.intent.IntentManager
|
||||
import com.bitwarden.authenticatorbridge.manager.AuthenticatorBridgeManager
|
||||
import com.bitwarden.authenticatorbridge.manager.model.AccountSyncState
|
||||
import com.bitwarden.core.data.repository.model.DataState
|
||||
import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow
|
||||
import com.bitwarden.core.data.repository.util.map
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
package com.bitwarden.authenticator.data.platform.repository.util
|
||||
|
||||
import com.bitwarden.core.data.repository.model.DataState
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.transformWhile
|
||||
|
||||
/**
|
||||
* Maps the data inside a [DataState] with the given [transform].
|
||||
*/
|
||||
inline fun <T : Any?, R : Any?> DataState<T>.map(
|
||||
transform: (T) -> R,
|
||||
): DataState<R> = when (this) {
|
||||
is DataState.Loaded -> DataState.Loaded(transform(data))
|
||||
is DataState.Loading -> DataState.Loading
|
||||
is DataState.Pending -> DataState.Pending(transform(data))
|
||||
is DataState.Error -> DataState.Error(error, data?.let(transform))
|
||||
is DataState.NoNetwork -> DataState.NoNetwork(data?.let(transform))
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits all values of a [DataState] [Flow] until it emits a [DataState.Loaded].
|
||||
*/
|
||||
fun <T : Any?> Flow<DataState<T>>.takeUntilLoaded(): Flow<DataState<T>> = transformWhile {
|
||||
emit(it)
|
||||
it !is DataState.Loaded
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines the [dataState1] and [dataState2] [DataState]s together using the provided [transform].
|
||||
*
|
||||
* This function will internally manage the final `DataState` type that is returned. This is done
|
||||
* by prioritizing each if the states in this order:
|
||||
*
|
||||
* - [DataState.Error]
|
||||
* - [DataState.NoNetwork]
|
||||
* - [DataState.Loading]
|
||||
* - [DataState.Pending]
|
||||
* - [DataState.Loaded]
|
||||
*
|
||||
* This priority order ensures that the total state is accurately reflecting the underlying states.
|
||||
* If one of the `DataState`s has a higher priority than the other, the output will be the highest
|
||||
* priority. For example, if one `DataState` is `DataState.Loaded` and another is `DataState.Error`
|
||||
* then the returned `DataState` will be `DataState.Error`.
|
||||
*
|
||||
* The payload of the final `DataState` be created by the `transform` lambda which will be invoked
|
||||
* whenever the payloads of both `dataState1` and `dataState2` are not null. In the scenario where
|
||||
* one or both payloads are null, the resulting `DataState` will have a null payload.
|
||||
*/
|
||||
fun <T1, T2, R> combineDataStates(
|
||||
dataState1: DataState<T1>,
|
||||
dataState2: DataState<T2>,
|
||||
transform: (t1: T1, t2: T2) -> R,
|
||||
): DataState<R> {
|
||||
// Wraps the `transform` lambda to allow null data to be passed in. If either of the passed in
|
||||
// values are null, the regular transform will not be invoked and null is returned.
|
||||
val nullableTransform: (T1?, T2?) -> R? = { t1, t2 ->
|
||||
if (t1 != null && t2 != null) transform(t1, t2) else null
|
||||
}
|
||||
return when {
|
||||
// Error states have highest priority, fail fast.
|
||||
dataState1 is DataState.Error -> {
|
||||
DataState.Error(
|
||||
error = dataState1.error,
|
||||
data = nullableTransform(dataState1.data, dataState2.data),
|
||||
)
|
||||
}
|
||||
|
||||
dataState2 is DataState.Error -> {
|
||||
DataState.Error(
|
||||
error = dataState2.error,
|
||||
data = nullableTransform(dataState1.data, dataState2.data),
|
||||
)
|
||||
}
|
||||
|
||||
dataState1 is DataState.NoNetwork || dataState2 is DataState.NoNetwork -> {
|
||||
DataState.NoNetwork(nullableTransform(dataState1.data, dataState2.data))
|
||||
}
|
||||
|
||||
// Something is still loading, we will wait for all the data.
|
||||
dataState1 is DataState.Loading || dataState2 is DataState.Loading -> DataState.Loading
|
||||
|
||||
// Pending state for everything while any one piece of data is updating.
|
||||
dataState1 is DataState.Pending || dataState2 is DataState.Pending -> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
DataState.Pending(transform(dataState1.data as T1, dataState2.data as T2))
|
||||
}
|
||||
|
||||
// Both states are Loaded and have data
|
||||
else -> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
DataState.Loaded(transform(dataState1.data as T1, dataState2.data as T2))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,6 @@ import com.bitwarden.authenticator.data.authenticator.datasource.disk.entity.Aut
|
||||
import com.bitwarden.authenticator.data.authenticator.datasource.disk.entity.AuthenticatorItemType
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.AuthenticatorRepository
|
||||
import com.bitwarden.authenticator.data.authenticator.repository.model.CreateItemResult
|
||||
import com.bitwarden.core.data.repository.model.DataState
|
||||
import com.bitwarden.authenticator.data.platform.repository.util.takeUntilLoaded
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.edititem.AuthenticatorRefreshPeriodOption.entries
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.edititem.EditItemState.Companion.MAX_ALLOWED_CODE_DIGITS
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.edititem.EditItemState.Companion.MIN_ALLOWED_CODE_DIGITS
|
||||
import com.bitwarden.authenticator.ui.authenticator.feature.edititem.model.EditItemData
|
||||
@@ -22,6 +19,8 @@ import com.bitwarden.authenticator.ui.platform.base.util.Text
|
||||
import com.bitwarden.authenticator.ui.platform.base.util.asText
|
||||
import com.bitwarden.authenticator.ui.platform.base.util.concat
|
||||
import com.bitwarden.authenticator.ui.platform.base.util.isBase32
|
||||
import com.bitwarden.core.data.repository.model.DataState
|
||||
import com.bitwarden.core.data.repository.util.takeUntilLoaded
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
Reference in New Issue
Block a user