Refactor(ToolViewScreenViewModel): Save tool detail in cache

This commit is contained in:
2024-09-29 15:52:12 +08:00
parent ba72ef2759
commit af3edb1d30

View File

@@ -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,