Refactor(ToolViewScreenViewModel): Save tool detail in cache
This commit is contained in:
@@ -5,6 +5,8 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.FlowCollector
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
@@ -13,6 +15,7 @@ import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import timber.log.Timber
|
||||
import top.fatweb.oxygen.toolbox.model.Result
|
||||
import top.fatweb.oxygen.toolbox.model.tool.ToolEntity
|
||||
import top.fatweb.oxygen.toolbox.navigation.ToolViewArgs
|
||||
import top.fatweb.oxygen.toolbox.repository.tool.StoreRepository
|
||||
import top.fatweb.oxygen.toolbox.repository.tool.ToolRepository
|
||||
@@ -35,6 +38,8 @@ class ToolViewScreenViewModel @Inject constructor(
|
||||
private val toolId = toolViewArgs.toolId
|
||||
private val preview = toolViewArgs.preview
|
||||
|
||||
private val storeDetailCache = MutableStateFlow<Result<ToolEntity>?>(null)
|
||||
|
||||
|
||||
val toolViewUiState: StateFlow<ToolViewUiState> = toolViewUiState(
|
||||
savedStateHandle = savedStateHandle,
|
||||
@@ -42,7 +47,8 @@ class ToolViewScreenViewModel @Inject constructor(
|
||||
toolId = toolId,
|
||||
preview = preview,
|
||||
storeRepository = storeRepository,
|
||||
toolRepository = toolRepository
|
||||
toolRepository = toolRepository,
|
||||
storeDetailCache = storeDetailCache
|
||||
)
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
@@ -57,7 +63,8 @@ private fun toolViewUiState(
|
||||
toolId: String,
|
||||
preview: Boolean,
|
||||
storeRepository: StoreRepository,
|
||||
toolRepository: ToolRepository
|
||||
toolRepository: ToolRepository,
|
||||
storeDetailCache: MutableStateFlow<Result<ToolEntity>?>
|
||||
): Flow<ToolViewUiState> {
|
||||
val toolViewTemplate = toolRepository.toolViewTemplate
|
||||
val entityFlow =
|
||||
@@ -67,32 +74,14 @@ private fun toolViewUiState(
|
||||
combine(entityFlow, toolViewTemplate, ::Pair).collect { (entityFlow, toolViewTemplate) ->
|
||||
if (entityFlow == null) {
|
||||
savedStateHandle[IS_PREVIEW] = true
|
||||
storeRepository.detail(username, toolId).collect {
|
||||
emit(
|
||||
when (it) {
|
||||
is Result.Success -> {
|
||||
val dist = it.data.dist!!
|
||||
val base = it.data.base!!
|
||||
ToolViewUiState.Success(
|
||||
it.data.name,
|
||||
processHtml(
|
||||
toolViewTemplate = toolViewTemplate,
|
||||
distBase64 = dist,
|
||||
baseBase64 = base
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
is Result.Loading -> ToolViewUiState.Loading
|
||||
is Result.Error -> {
|
||||
Timber.e("Can not load tool", it.exception)
|
||||
|
||||
ToolViewUiState.Error
|
||||
}
|
||||
|
||||
is Result.Fail -> ToolViewUiState.Error
|
||||
}
|
||||
)
|
||||
val cachedDetail = storeDetailCache.value
|
||||
if (cachedDetail != null) {
|
||||
emitResult(result = cachedDetail, toolViewTemplate = toolViewTemplate)
|
||||
} else {
|
||||
storeRepository.detail(username, toolId).collect { result ->
|
||||
storeDetailCache.value = result
|
||||
emitResult(result = result, toolViewTemplate = toolViewTemplate)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
savedStateHandle[IS_PREVIEW] = false
|
||||
@@ -111,6 +100,36 @@ private fun toolViewUiState(
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun FlowCollector<ToolViewUiState>.emitResult(
|
||||
result: Result<ToolEntity>,
|
||||
toolViewTemplate: String
|
||||
) {
|
||||
emit(
|
||||
when (result) {
|
||||
is Result.Success -> {
|
||||
val dist = result.data.dist!!
|
||||
val base = result.data.base!!
|
||||
ToolViewUiState.Success(
|
||||
result.data.name,
|
||||
processHtml(
|
||||
toolViewTemplate = toolViewTemplate,
|
||||
distBase64 = dist,
|
||||
baseBase64 = base
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
is Result.Loading -> ToolViewUiState.Loading
|
||||
is Result.Error -> {
|
||||
Timber.e("Can not load tool", result.exception)
|
||||
ToolViewUiState.Error
|
||||
}
|
||||
|
||||
is Result.Fail -> ToolViewUiState.Error
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
sealed interface ToolViewUiState {
|
||||
data class Success(
|
||||
val toolName: String,
|
||||
|
||||
Reference in New Issue
Block a user