Feat(ToolView): Support load tool offline
This commit is contained in:
@@ -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(
|
||||||
|
|||||||
@@ -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?>
|
||||||
|
|||||||
@@ -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) }
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user