Feat(ToolView): Support load tool offline

This commit is contained in:
2024-08-12 16:01:19 +08:00
parent 454108d871
commit a3800bfad6
5 changed files with 58 additions and 35 deletions

View File

@@ -6,8 +6,6 @@ import top.fatweb.oxygen.toolbox.model.Result
import top.fatweb.oxygen.toolbox.model.tool.ToolEntity
interface StoreRepository {
val toolViewTemplate: Flow<String>
suspend fun getStore(searchValue: String, currentPage: Int): Flow<PagingData<ToolEntity>>
fun detail(

View File

@@ -4,6 +4,8 @@ import kotlinx.coroutines.flow.Flow
import top.fatweb.oxygen.toolbox.model.tool.ToolEntity
interface ToolRepository {
val toolViewTemplate: Flow<String>
fun getAllToolsStream(): Flow<List<ToolEntity>>
fun getToolById(id: Long): Flow<ToolEntity?>

View File

@@ -6,7 +6,6 @@ import androidx.paging.PagingData
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import top.fatweb.oxygen.toolbox.data.network.OxygenNetworkDataSource
import top.fatweb.oxygen.toolbox.data.tool.ToolDataSource
import top.fatweb.oxygen.toolbox.model.Result
import top.fatweb.oxygen.toolbox.model.asExternalModel
import top.fatweb.oxygen.toolbox.model.tool.ToolEntity
@@ -20,13 +19,13 @@ import javax.inject.Inject
private const val PAGE_SIZE = 20
internal class NetworkStoreRepository @Inject constructor(
private val oxygenNetworkDataSource: OxygenNetworkDataSource,
private val toolDataSource: ToolDataSource
private val oxygenNetworkDataSource: OxygenNetworkDataSource
) : StoreRepository {
override val toolViewTemplate: Flow<String>
get() = toolDataSource.toolViewTemplate
override suspend fun getStore(searchValue: String, currentPage: Int): Flow<PagingData<ToolEntity>> =
override suspend fun getStore(
searchValue: String,
currentPage: Int
): Flow<PagingData<ToolEntity>> =
Pager(
config = PagingConfig(PAGE_SIZE),
pagingSourceFactory = { ToolStorePagingSource(oxygenNetworkDataSource, searchValue) }

View File

@@ -1,14 +1,19 @@
package top.fatweb.oxygen.toolbox.repository.tool.impl
import kotlinx.coroutines.flow.Flow
import top.fatweb.oxygen.toolbox.data.tool.ToolDataSource
import top.fatweb.oxygen.toolbox.data.tool.dao.ToolDao
import top.fatweb.oxygen.toolbox.model.tool.ToolEntity
import top.fatweb.oxygen.toolbox.repository.tool.ToolRepository
import javax.inject.Inject
class OfflineToolRepository @Inject constructor(
private val toolDataSource: ToolDataSource,
private val toolDao: ToolDao
) : ToolRepository {
override val toolViewTemplate: Flow<String>
get() = toolDataSource.toolViewTemplate
override fun getAllToolsStream(): Flow<List<ToolEntity>> =
toolDao.selectAllTools()

View File

@@ -9,11 +9,12 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.stateIn
import top.fatweb.oxygen.toolbox.model.Result
import top.fatweb.oxygen.toolbox.navigation.ToolViewArgs
import top.fatweb.oxygen.toolbox.repository.tool.StoreRepository
import top.fatweb.oxygen.toolbox.repository.tool.ToolRepository
import top.fatweb.oxygen.toolbox.util.decodeToStringWithZip
import javax.inject.Inject
import kotlin.io.encoding.Base64
@@ -23,6 +24,7 @@ import kotlin.time.Duration.Companion.seconds
@HiltViewModel
class ToolViewScreenViewModel @Inject constructor(
storeRepository: StoreRepository,
toolRepository: ToolRepository,
savedStateHandle: SavedStateHandle
) : ViewModel() {
private val toolViewArgs = ToolViewArgs(savedStateHandle)
@@ -32,7 +34,8 @@ class ToolViewScreenViewModel @Inject constructor(
val toolViewUiState: StateFlow<ToolViewUiState> = toolViewUiState(
username = username,
toolId = toolId,
storeRepository = storeRepository
storeRepository = storeRepository,
toolRepository = toolRepository
)
.stateIn(
scope = viewModelScope,
@@ -44,19 +47,21 @@ class ToolViewScreenViewModel @Inject constructor(
private fun toolViewUiState(
username: String,
toolId: String,
storeRepository: StoreRepository
storeRepository: StoreRepository,
toolRepository: ToolRepository
): Flow<ToolViewUiState> {
val result = storeRepository.detail(
username = username,
toolId = toolId
)
val toolViewTemplate = storeRepository.toolViewTemplate
val toolViewTemplate = toolRepository.toolViewTemplate
val entityFlow = toolRepository.getToolByUsernameAndToolId(username, toolId)
return combine(result, toolViewTemplate, ::Pair).map { (result, toolViewTemplate) ->
when (result) {
return flow {
combine(entityFlow, toolViewTemplate, ::Pair).collect { (entityFlow, toolViewTemplate) ->
if (entityFlow == null) {
storeRepository.detail(username, toolId).collect {
emit(
when (it) {
is Result.Success -> {
val dist = result.data.dist!!
val base = result.data.base!!
val dist = it.data.dist!!
val base = it.data.base!!
ToolViewUiState.Success(
processHtml(
toolViewTemplate = toolViewTemplate,
@@ -68,13 +73,27 @@ private fun toolViewUiState(
is Result.Loading -> ToolViewUiState.Loading
is Result.Error -> {
Log.e("TAG", "toolViewUiState: can not load tool", result.exception)
Log.e("TAG", "toolViewUiState: can not load tool", it.exception)
ToolViewUiState.Error
}
is Result.Fail -> ToolViewUiState.Error
}
)
}
} else {
emit(
ToolViewUiState.Success(
processHtml(
toolViewTemplate = toolViewTemplate,
distBase64 = entityFlow.dist!!,
baseBase64 = entityFlow.base!!
)
)
)
}
}
}
}