From 49567dcade5172cca39d7d6c0ba5bede52013592 Mon Sep 17 00:00:00 2001 From: acclorite Date: Thu, 13 Jun 2024 13:02:34 +0300 Subject: [PATCH] Fixed: Progress is not being tracked. (v1.0.1) --- .../screens/reader/ReaderScreen.kt | 22 +++-- .../screens/reader/data/ReaderViewModel.kt | 86 ++++++++++--------- 2 files changed, 62 insertions(+), 46 deletions(-) diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/ReaderScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/ReaderScreen.kt index 7fcfbdfd..1ac19562 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/ReaderScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/ReaderScreen.kt @@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.text.selection.DisableSelection import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme @@ -29,6 +30,7 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset @@ -87,6 +89,12 @@ fun ReaderScreenRoot() { val state = viewModel.state.collectAsState() val mainState = mainViewModel.state.collectAsState() + val lazyListState = rememberSaveable( + state.value.listState, + saver = LazyListState.Saver + ) { + state.value.listState + } val canScroll by remember { derivedStateOf { state.value.listState.canScrollBackward && state.value.listState.canScrollForward @@ -109,16 +117,18 @@ fun ReaderScreenRoot() { ).show() } ) - viewModel.onUpdateProgress( - onLibraryEvent = libraryViewModel::onEvent, - onHistoryEvent = historyViewModel::onEvent - ) } LaunchedEffect(canScroll) { if (!canScroll && !state.value.showMenu && !state.value.loading) { viewModel.onEvent(ReaderEvent.OnShowHideMenu(context = context)) } } + LaunchedEffect(lazyListState) { + viewModel.onUpdateProgress( + onLibraryEvent = libraryViewModel::onEvent, + onHistoryEvent = historyViewModel::onEvent + ) + } DisposableEffect(Unit) { onDispose { @@ -130,6 +140,7 @@ fun ReaderScreenRoot() { state = state, mainState = mainState, navigator = navigator, + lazyListState = lazyListState, onEvent = viewModel::onEvent, onMainEvent = mainViewModel::onEvent, onLibraryEvent = libraryViewModel::onEvent, @@ -143,6 +154,7 @@ private fun ReaderScreen( state: State, mainState: State, navigator: Navigator, + lazyListState: LazyListState, onEvent: (ReaderEvent) -> Unit, onMainEvent: (MainEvent) -> Unit, onLibraryEvent: (LibraryEvent) -> Unit, @@ -330,7 +342,7 @@ private fun ReaderScreen( } ) { toolbarHidden -> LazyColumn( - state = state.value.listState, + state = lazyListState, modifier = Modifier .fillMaxSize() .background(backgroundColor) diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderViewModel.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderViewModel.kt index 38aadc9a..f790e41b 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderViewModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/data/ReaderViewModel.kt @@ -22,6 +22,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.yield @@ -1269,51 +1270,54 @@ class ReaderViewModel @Inject constructor( } @OptIn(FlowPreview::class) - suspend fun onUpdateProgress( + fun onUpdateProgress( onLibraryEvent: (LibraryEvent) -> Unit, onHistoryEvent: (HistoryEvent) -> Unit ) { - snapshotFlow { - _state.value.listState.firstVisibleItemIndex to _state.value.listState.firstVisibleItemScrollOffset - } - .debounce(300) - .collectLatest { items -> - val listState = _state.value.listState - if ( - !_state.value.loading && - _state.value.text.isNotEmpty() && - listState.layoutInfo.totalItemsCount > 0 - ) { - val lastVisibleItemIndex = listState - .layoutInfo - .visibleItemsInfo - .last() - .index - val totalItemsCount = listState.layoutInfo.totalItemsCount - 1 - - val progress = if (items.first > 0) { - if (lastVisibleItemIndex >= totalItemsCount) { - 1f - } else { - items.first / (_state.value.text.size - 1).toFloat() - } - } else { - 0f - } - - onEvent( - ReaderEvent.OnChangeProgress( - progress = progress, - firstVisibleItemIndex = items.first, - firstVisibleItemOffset = items.second, - refreshList = { book -> - onLibraryEvent(LibraryEvent.OnUpdateBook(book)) - onHistoryEvent(HistoryEvent.OnUpdateBook(book)) - } - ) - ) - } + viewModelScope.launch { + snapshotFlow { + _state.value.listState.firstVisibleItemIndex to _state.value.listState.firstVisibleItemScrollOffset } + .distinctUntilChanged() + .debounce(300) + .collectLatest { (firstVisibleItemIndex, firstVisibleItemScrollOffset) -> + val listState = _state.value.listState + if ( + !_state.value.loading && + _state.value.text.isNotEmpty() && + listState.layoutInfo.totalItemsCount > 0 + ) { + val lastVisibleItemIndex = listState + .layoutInfo + .visibleItemsInfo + .last() + .index + val totalItemsCount = listState.layoutInfo.totalItemsCount - 1 + + val progress = if (firstVisibleItemIndex > 0) { + if (lastVisibleItemIndex >= totalItemsCount) { + 1f + } else { + firstVisibleItemIndex / (_state.value.text.size - 1).toFloat() + } + } else { + 0f + } + + onEvent( + ReaderEvent.OnChangeProgress( + progress = progress, + firstVisibleItemIndex = firstVisibleItemIndex, + firstVisibleItemOffset = firstVisibleItemScrollOffset, + refreshList = { book -> + onLibraryEvent(LibraryEvent.OnUpdateBook(book)) + onHistoryEvent(HistoryEvent.OnUpdateBook(book)) + } + ) + ) + } + } + } } private fun calculateProgress(): Float {