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 import top.fatweb.oxygen.toolbox.model.tool.ToolEntity
interface StoreRepository { interface StoreRepository {
val toolViewTemplate: Flow<String>
suspend fun getStore(searchValue: String, currentPage: Int): Flow<PagingData<ToolEntity>> suspend fun getStore(searchValue: String, currentPage: Int): Flow<PagingData<ToolEntity>>
fun detail( fun detail(

View File

@@ -4,6 +4,8 @@ import kotlinx.coroutines.flow.Flow
import top.fatweb.oxygen.toolbox.model.tool.ToolEntity import top.fatweb.oxygen.toolbox.model.tool.ToolEntity
interface ToolRepository { interface ToolRepository {
val toolViewTemplate: Flow<String>
fun getAllToolsStream(): Flow<List<ToolEntity>> fun getAllToolsStream(): Flow<List<ToolEntity>>
fun getToolById(id: Long): Flow<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.Flow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import top.fatweb.oxygen.toolbox.data.network.OxygenNetworkDataSource 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.Result
import top.fatweb.oxygen.toolbox.model.asExternalModel import top.fatweb.oxygen.toolbox.model.asExternalModel
import top.fatweb.oxygen.toolbox.model.tool.ToolEntity import top.fatweb.oxygen.toolbox.model.tool.ToolEntity
@@ -20,13 +19,13 @@ import javax.inject.Inject
private const val PAGE_SIZE = 20 private const val PAGE_SIZE = 20
internal class NetworkStoreRepository @Inject constructor( internal class NetworkStoreRepository @Inject constructor(
private val oxygenNetworkDataSource: OxygenNetworkDataSource, private val oxygenNetworkDataSource: OxygenNetworkDataSource
private val toolDataSource: ToolDataSource
) : StoreRepository { ) : 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( Pager(
config = PagingConfig(PAGE_SIZE), config = PagingConfig(PAGE_SIZE),
pagingSourceFactory = { ToolStorePagingSource(oxygenNetworkDataSource, searchValue) } pagingSourceFactory = { ToolStorePagingSource(oxygenNetworkDataSource, searchValue) }

View File

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

View File

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