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