Convert the AdventureDetailScreen to flow instead of snapshot.
This commit is contained in:
parent
acb76e72cf
commit
e62b558c21
4 changed files with 106 additions and 51 deletions
|
|
@ -17,8 +17,10 @@ import com.pixelized.rplexicon.utilitary.exceptions.IncompatibleSheetStructure
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
|
@ -32,7 +34,7 @@ class AdventureRepository @Inject constructor(
|
|||
private val adventureStoryLineParser: AdventureStoryLineParser,
|
||||
private val adventureDboFactory: AdventureDboFactory,
|
||||
) {
|
||||
val adventure = database.adventureDao().let { database ->
|
||||
private val adventures = database.adventureDao().let { database ->
|
||||
combine(
|
||||
database.getBooksFlow(),
|
||||
database.getStoriesFlow(),
|
||||
|
|
@ -50,6 +52,31 @@ class AdventureRepository @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
fun bookFlow(): Flow<List<Adventure>> {
|
||||
return adventures
|
||||
}
|
||||
|
||||
fun storyFlow(
|
||||
bookTitle: String,
|
||||
): Flow<List<Adventure>> {
|
||||
return adventures.map { adventures ->
|
||||
adventures.filter { adventure ->
|
||||
adventure.bookTitle == bookTitle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun adventureFlow(
|
||||
bookTitle: String,
|
||||
adventureTitle: String,
|
||||
): Flow<Adventure?> {
|
||||
return adventures.map { adventures ->
|
||||
adventures.firstOrNull { adventure ->
|
||||
adventure.bookTitle == bookTitle && adventure.storyTitle == adventureTitle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IncompatibleSheetStructure::class, Exception::class)
|
||||
suspend fun fetchBooks() {
|
||||
val database = database.adventureDao()
|
||||
|
|
@ -177,18 +204,6 @@ class AdventureRepository @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
fun find(bookTitle: String): List<Adventure> {
|
||||
return adventure.value.filter { adventure ->
|
||||
adventure.bookTitle == bookTitle
|
||||
}
|
||||
}
|
||||
|
||||
fun find(bookTitle: String, adventureTitle: String): Adventure? {
|
||||
return adventure.value.firstOrNull { adventure ->
|
||||
adventure.bookTitle == bookTitle && adventure.storyTitle == adventureTitle
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IncompatibleSheetStructure::class, Exception::class)
|
||||
private suspend fun fetchAdventureBooks(): List<AdventureBook> {
|
||||
return googleRepository.fetch { sheet ->
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class AdventureBooksViewModel @Inject constructor(
|
|||
private val _isLoading = mutableStateOf(false)
|
||||
val isLoading: State<Boolean> get() = _isLoading
|
||||
|
||||
private val _books = adventureRepository.adventure
|
||||
private val _books = adventureRepository.bookFlow()
|
||||
.map { adventures ->
|
||||
adventures
|
||||
.map { adventure ->
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class AdventureStoriesViewModel @Inject constructor(
|
|||
argument.bookTitle
|
||||
}
|
||||
|
||||
private val _chapters = adventureRepository.adventure
|
||||
private val _chapters = adventureRepository.storyFlow(bookTitle = argument.bookTitle)
|
||||
.map { adventures ->
|
||||
adventures
|
||||
.filter { it.bookTitle == argument.bookTitle && it.documentId == argument.documentId }
|
||||
|
|
|
|||
|
|
@ -1,14 +1,22 @@
|
|||
package com.pixelized.rplexicon.ui.screens.adventure.detail
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.pixelized.rplexicon.data.model.adventure.AdventureLine.Format
|
||||
import com.pixelized.rplexicon.data.repository.adventure.AdventureRepository
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.adventureDetailArgument
|
||||
import com.pixelized.rplexicon.ui.screens.adventure.detail.AdventureLineUio.Style
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
|
|
@ -17,44 +25,76 @@ class AdventureDetailViewModel @Inject constructor(
|
|||
savedStateHandle: SavedStateHandle,
|
||||
) : ViewModel() {
|
||||
private val argument = savedStateHandle.adventureDetailArgument
|
||||
private val _detail = mutableStateOf(
|
||||
adventureRepository.find(
|
||||
bookTitle = argument.bookTitle,
|
||||
adventureTitle = argument.adventureTitle,
|
||||
)
|
||||
|
||||
private val detail = adventureRepository.adventureFlow(
|
||||
bookTitle = argument.bookTitle,
|
||||
adventureTitle = argument.adventureTitle,
|
||||
).stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.Lazily,
|
||||
initialValue = null,
|
||||
)
|
||||
|
||||
val background = derivedStateOf {
|
||||
_detail.value?.storyBackground
|
||||
}
|
||||
val background: State<Uri?>
|
||||
@Composable
|
||||
get() = remember(detail) {
|
||||
detail.map { it?.storyBackground }
|
||||
}.collectAsState(initial = null)
|
||||
|
||||
val adventure = derivedStateOf {
|
||||
_detail.value?.story?.map { line ->
|
||||
AdventureLineUio(
|
||||
text = line.text,
|
||||
style = when (line.format) {
|
||||
Format.TITLE -> Style.TITLE
|
||||
Format.SUB_TITLE -> Style.SUB_TITLE
|
||||
Format.CHAPTER -> Style.CHAPTER
|
||||
Format.PARAGRAPH -> Style.PARAGRAPH
|
||||
Format.DIALOGUE -> Style.DIALOGUE
|
||||
Format.ANNEX -> Style.ANNEX
|
||||
Format.LEGEND -> Style.LEGEND
|
||||
},
|
||||
)
|
||||
} ?: emptyList()
|
||||
}
|
||||
val adventure: State<List<AdventureLineUio>>
|
||||
@Composable
|
||||
get() = remember(detail) {
|
||||
detail
|
||||
.map { adventure ->
|
||||
adventure?.story?.map { line ->
|
||||
AdventureLineUio(
|
||||
text = line.text,
|
||||
style = when (line.format) {
|
||||
Format.TITLE -> Style.TITLE
|
||||
Format.SUB_TITLE -> Style.SUB_TITLE
|
||||
Format.CHAPTER -> Style.CHAPTER
|
||||
Format.PARAGRAPH -> Style.PARAGRAPH
|
||||
Format.DIALOGUE -> Style.DIALOGUE
|
||||
Format.ANNEX -> Style.ANNEX
|
||||
Format.LEGEND -> Style.LEGEND
|
||||
},
|
||||
)
|
||||
} ?: emptyList()
|
||||
}
|
||||
}.collectAsState(initial = emptyList())
|
||||
|
||||
private val titleCell = derivedStateOf {
|
||||
adventure.value.let { adventures ->
|
||||
adventures.firstOrNull { it.style == Style.TITLE }
|
||||
?: adventures.firstOrNull()
|
||||
private val titleCell: State<AdventureLineUio?>
|
||||
@Composable
|
||||
get() = adventure.let { state ->
|
||||
remember(state) {
|
||||
derivedStateOf {
|
||||
state.value.let { adventures ->
|
||||
adventures.firstOrNull { it.style == Style.TITLE }
|
||||
?: adventures.firstOrNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val title: State<String>
|
||||
@Composable
|
||||
get() = titleCell.let { state ->
|
||||
remember(state) {
|
||||
derivedStateOf {
|
||||
state.value?.text ?: ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val titleIndex: State<Int>
|
||||
@Composable
|
||||
get() {
|
||||
val cell = titleCell
|
||||
val adv = adventure
|
||||
return remember(cell, adv) {
|
||||
derivedStateOf {
|
||||
adv.value.indexOf(cell.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val title = derivedStateOf {
|
||||
titleCell.value?.text ?: ""
|
||||
}
|
||||
val titleIndex = derivedStateOf {
|
||||
adventure.value.indexOf(titleCell.value)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue