BookInfoScreen: Canceling BookInfoViewModel.onEvent + Resetting BookInfoState when exiting screen.
This commit is contained in:
parent
d6de5bc521
commit
4f521bcd1e
2 changed files with 714 additions and 679 deletions
|
|
@ -37,6 +37,7 @@ import androidx.compose.material3.SnackbarHostState
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.collectAsState
|
||||
|
|
@ -92,6 +93,12 @@ fun BookInfoScreenRoot(screen: Screen.BookInfo) {
|
|||
)
|
||||
}
|
||||
|
||||
DisposableEffect(Unit) {
|
||||
onDispose {
|
||||
viewModel.clearViewModel()
|
||||
}
|
||||
}
|
||||
|
||||
BookInfoScreen(
|
||||
state = state,
|
||||
onNavigate = { navigator.it() },
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
@file:Suppress("LABEL_NAME_CLASH")
|
||||
|
||||
package ua.acclorite.book_story.presentation.screens.book_info.data
|
||||
|
||||
import android.content.ClipData
|
||||
|
|
@ -11,6 +13,7 @@ import androidx.lifecycle.viewModelScope
|
|||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
|
@ -56,10 +59,13 @@ class BookInfoViewModel @Inject constructor(
|
|||
private val _state = MutableStateFlow(BookInfoState())
|
||||
val state = _state.asStateFlow()
|
||||
|
||||
private var job: Job? = null
|
||||
private var job2: Job? = null
|
||||
private var eventJob = SupervisorJob()
|
||||
|
||||
private var snackBarJob: Job? = null
|
||||
private var updateJob: Job? = null
|
||||
|
||||
fun onEvent(event: BookInfoEvent) {
|
||||
viewModelScope.launch(eventJob + Dispatchers.Main) {
|
||||
when (event) {
|
||||
is BookInfoEvent.OnShowHideChangeCoverBottomSheet -> {
|
||||
_state.update {
|
||||
|
|
@ -70,7 +76,7 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnChangeCover -> {
|
||||
viewModelScope.launch {
|
||||
launch {
|
||||
val image = event.context.contentResolver?.openInputStream(event.uri)?.use {
|
||||
BitmapFactory.decodeStream(it)
|
||||
} ?: return@launch
|
||||
|
|
@ -97,7 +103,7 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnDeleteCover -> {
|
||||
viewModelScope.launch {
|
||||
launch {
|
||||
if (_state.value.book.coverImage == null) {
|
||||
return@launch
|
||||
}
|
||||
|
|
@ -120,7 +126,7 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnCheckCoverReset -> {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
launch(Dispatchers.IO) {
|
||||
_state.update {
|
||||
it.copy(
|
||||
canResetCover = canResetCover.execute(_state.value.book.id)
|
||||
|
|
@ -130,7 +136,7 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnResetCoverImage -> {
|
||||
viewModelScope.launch {
|
||||
launch {
|
||||
val result = resetCoverImage.execute(_state.value.book.id)
|
||||
|
||||
if (!result) {
|
||||
|
|
@ -158,7 +164,7 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnShowHideEditTitle -> {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
launch(Dispatchers.IO) {
|
||||
val shouldHide = _state.value.editTitle
|
||||
|
||||
if (!shouldHide) {
|
||||
|
|
@ -198,7 +204,7 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnShowHideEditAuthor -> {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
launch(Dispatchers.IO) {
|
||||
val shouldHide = _state.value.editAuthor
|
||||
|
||||
if (!shouldHide) {
|
||||
|
|
@ -238,7 +244,7 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnShowHideEditDescription -> {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
launch(Dispatchers.IO) {
|
||||
val shouldHide = _state.value.editDescription
|
||||
|
||||
if (!shouldHide) {
|
||||
|
|
@ -278,7 +284,7 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnUpdateData -> {
|
||||
viewModelScope.launch {
|
||||
launch {
|
||||
val title = _state.value.titleValue.trim().replace("\n", "")
|
||||
val author = _state.value.authorValue.trim().replace("\n", "")
|
||||
val description = _state.value.descriptionValue.trim().replace("\n", "")
|
||||
|
|
@ -332,7 +338,7 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnDeleteBook -> {
|
||||
viewModelScope.launch {
|
||||
launch {
|
||||
_state.update {
|
||||
it.copy(
|
||||
showDeleteDialog = false
|
||||
|
|
@ -365,7 +371,7 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnMoveBook -> {
|
||||
viewModelScope.launch {
|
||||
launch {
|
||||
_state.update {
|
||||
it.copy(
|
||||
showMoveDialog = false
|
||||
|
|
@ -416,12 +422,12 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnShowSnackbar -> {
|
||||
viewModelScope.launch {
|
||||
job?.cancel()
|
||||
launch {
|
||||
snackBarJob?.cancel()
|
||||
event.snackbarState.currentSnackbarData?.dismiss()
|
||||
|
||||
if (event.durationMillis > 0) {
|
||||
job = viewModelScope.launch(Dispatchers.IO) {
|
||||
snackBarJob = launch(Dispatchers.IO) {
|
||||
yield()
|
||||
delay(event.durationMillis)
|
||||
yield()
|
||||
|
|
@ -444,11 +450,11 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnLoadUpdate -> {
|
||||
onEvent(BookInfoEvent.OnCancelUpdate)
|
||||
|
||||
job2 = viewModelScope.launch(Dispatchers.IO) {
|
||||
updateJob?.cancel()
|
||||
updateJob = launch(Dispatchers.IO) {
|
||||
_state.update {
|
||||
it.copy(
|
||||
showConfirmUpdateDialog = false,
|
||||
isLoadingUpdate = true,
|
||||
editTitle = false,
|
||||
editAuthor = false,
|
||||
|
|
@ -606,7 +612,7 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnConfirmUpdate -> {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
launch(Dispatchers.IO) {
|
||||
_state.update {
|
||||
it.copy(
|
||||
isRefreshing = true,
|
||||
|
|
@ -769,7 +775,8 @@ class BookInfoViewModel @Inject constructor(
|
|||
|
||||
is BookInfoEvent.OnCancelUpdate -> {
|
||||
_state.update {
|
||||
job2?.cancel()
|
||||
updateJob?.cancel()
|
||||
|
||||
it.copy(
|
||||
showConfirmUpdateDialog = false,
|
||||
isLoadingUpdate = false
|
||||
|
|
@ -778,7 +785,7 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is BookInfoEvent.OnNavigateToReaderScreen -> {
|
||||
viewModelScope.launch {
|
||||
launch {
|
||||
onEvent(BookInfoEvent.OnCancelUpdate)
|
||||
_state.value.book.id.let {
|
||||
insertHistory.execute(
|
||||
|
|
@ -800,9 +807,10 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun init(screen: Screen.BookInfo, onNavigate: OnNavigate) {
|
||||
viewModelScope.launch {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val book = getBookById.execute(screen.bookId)
|
||||
|
||||
if (book == null) {
|
||||
|
|
@ -817,7 +825,27 @@ class BookInfoViewModel @Inject constructor(
|
|||
book = book
|
||||
)
|
||||
}
|
||||
clear()
|
||||
|
||||
onEvent(BookInfoEvent.OnCheckCoverReset)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun clear() {
|
||||
eventJob.cancel()
|
||||
eventJob.join()
|
||||
eventJob = SupervisorJob()
|
||||
}
|
||||
|
||||
fun clearViewModel() {
|
||||
viewModelScope.launch(Dispatchers.Main) {
|
||||
_state.update {
|
||||
BookInfoState()
|
||||
}
|
||||
|
||||
eventJob.cancel()
|
||||
eventJob.join()
|
||||
eventJob = SupervisorJob()
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue