🛠️ Better refreshList delays

* Fixed visual issue with EmptyPlaceholder being shown when it should not be
This commit is contained in:
Acclorite 2024-12-28 13:25:33 +02:00
parent 4864aae9ab
commit fad7292b34
7 changed files with 52 additions and 53 deletions

View file

@ -224,8 +224,8 @@ class BookInfoModel @Inject constructor(
) )
} }
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
HistoryScreen.refreshListChannel.trySend(Unit) HistoryScreen.refreshListChannel.trySend(0)
if (_state.value.editTitle) { if (_state.value.editTitle) {
onEvent(BookInfoEvent.OnEditTitleMode(false)) onEvent(BookInfoEvent.OnEditTitleMode(false))
@ -302,8 +302,8 @@ class BookInfoModel @Inject constructor(
) )
} }
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
HistoryScreen.refreshListChannel.trySend(Unit) HistoryScreen.refreshListChannel.trySend(0)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
event.context.getString(R.string.cover_image_changed) event.context.getString(R.string.cover_image_changed)
@ -347,8 +347,8 @@ class BookInfoModel @Inject constructor(
.showToast(context = event.context) .showToast(context = event.context)
} }
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
HistoryScreen.refreshListChannel.trySend(Unit) HistoryScreen.refreshListChannel.trySend(0)
} }
} }
@ -372,8 +372,8 @@ class BookInfoModel @Inject constructor(
) )
} }
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
HistoryScreen.refreshListChannel.trySend(Unit) HistoryScreen.refreshListChannel.trySend(0)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
event.context.getString(R.string.cover_image_deleted) event.context.getString(R.string.cover_image_deleted)
@ -437,8 +437,8 @@ class BookInfoModel @Inject constructor(
deleteBooks.execute(listOf(_state.value.book)) deleteBooks.execute(listOf(_state.value.book))
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
HistoryScreen.refreshListChannel.trySend(Unit) HistoryScreen.refreshListChannel.trySend(0)
BrowseScreen.refreshListChannel.trySend(Unit) BrowseScreen.refreshListChannel.trySend(Unit)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
@ -476,13 +476,13 @@ class BookInfoModel @Inject constructor(
} }
updateBook.execute(_state.value.book) updateBook.execute(_state.value.book)
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
LibraryScreen.scrollToPageCompositionChannel.trySend( LibraryScreen.scrollToPageCompositionChannel.trySend(
Category.entries.dropLastWhile { Category.entries.dropLastWhile {
it != event.category it != event.category
}.size - 1 }.size - 1
) )
HistoryScreen.refreshListChannel.trySend(Unit) HistoryScreen.refreshListChannel.trySend(0)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
event.context.getString(R.string.book_moved) event.context.getString(R.string.book_moved)
@ -717,8 +717,8 @@ class BookInfoModel @Inject constructor(
) )
} }
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
HistoryScreen.refreshListChannel.trySend(Unit) HistoryScreen.refreshListChannel.trySend(0)
onEvent( onEvent(
BookInfoEvent.OnShowSnackbar( BookInfoEvent.OnShowSnackbar(

View file

@ -12,13 +12,11 @@ import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.shouldShowRationale import com.google.accompanist.permissions.shouldShowRationale
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -41,7 +39,6 @@ import java.io.File
import javax.inject.Inject import javax.inject.Inject
import kotlin.collections.map import kotlin.collections.map
@OptIn(FlowPreview::class)
@HiltViewModel @HiltViewModel
class BrowseModel @Inject constructor( class BrowseModel @Inject constructor(
private val getFilesFromDevice: GetFilesFromDevice, private val getFilesFromDevice: GetFilesFromDevice,
@ -60,7 +57,7 @@ class BrowseModel @Inject constructor(
/* Observe channel - - - - - - - - - - - */ /* Observe channel - - - - - - - - - - - */
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
BrowseScreen.refreshListChannel.receiveAsFlow().debounce(200).collectLatest { BrowseScreen.refreshListChannel.receiveAsFlow().collectLatest {
onEvent(BrowseEvent.OnRefreshList(showIndicator = false, hideSearch = false)) onEvent(BrowseEvent.OnRefreshList(showIndicator = false, hideSearch = false))
} }
} }
@ -532,7 +529,7 @@ class BrowseModel @Inject constructor(
return@launch return@launch
} }
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
LibraryScreen.scrollToPageCompositionChannel.trySend(0) LibraryScreen.scrollToPageCompositionChannel.trySend(0)
event.navigateToLibrary() event.navigateToLibrary()

View file

@ -5,13 +5,11 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -35,7 +33,6 @@ import javax.inject.Inject
import kotlin.collections.component1 import kotlin.collections.component1
import kotlin.collections.component2 import kotlin.collections.component2
@OptIn(FlowPreview::class)
@HiltViewModel @HiltViewModel
class HistoryModel @Inject constructor( class HistoryModel @Inject constructor(
private val getHistory: GetHistory, private val getHistory: GetHistory,
@ -60,13 +57,15 @@ class HistoryModel @Inject constructor(
/* Observe channel - - - - - - - - - - - */ /* Observe channel - - - - - - - - - - - */
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
HistoryScreen.refreshListChannel.receiveAsFlow().debounce(200).collectLatest { HistoryScreen.refreshListChannel.receiveAsFlow().collectLatest {
delay(it)
yield()
onEvent(HistoryEvent.OnRefreshList(showIndicator = false, hideSearch = false)) onEvent(HistoryEvent.OnRefreshList(showIndicator = false, hideSearch = false))
} }
} }
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
HistoryScreen.insertHistoryChannel.receiveAsFlow().debounce(200) HistoryScreen.insertHistoryChannel.receiveAsFlow().collectLatest {
.collectLatest {
insertHistory.execute( insertHistory.execute(
History( History(
bookId = it, bookId = it,
@ -75,8 +74,11 @@ class HistoryModel @Inject constructor(
) )
) )
delay(500)
yield()
getHistoryFromDatabase() getHistoryFromDatabase()
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
} }
} }
/* - - - - - - - - - - - - - - - - - - - */ /* - - - - - - - - - - - - - - - - - - - */
@ -172,7 +174,7 @@ class HistoryModel @Inject constructor(
getHistoryFromDatabase() getHistoryFromDatabase()
_state.update { it.copy(isRefreshing = false) } _state.update { it.copy(isRefreshing = false) }
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
deleteHistoryEntry?.cancel() deleteHistoryEntry?.cancel()
event.snackbarState.currentSnackbarData?.dismiss() event.snackbarState.currentSnackbarData?.dismiss()
@ -195,7 +197,7 @@ class HistoryModel @Inject constructor(
SnackbarResult.Dismissed -> Unit SnackbarResult.Dismissed -> Unit
SnackbarResult.ActionPerformed -> { SnackbarResult.ActionPerformed -> {
insertHistory.execute(event.history) insertHistory.execute(event.history)
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
_state.update { it.copy(isRefreshing = true) } _state.update { it.copy(isRefreshing = true) }
getHistoryFromDatabase() getHistoryFromDatabase()
@ -224,7 +226,7 @@ class HistoryModel @Inject constructor(
} }
deleteWholeHistory.execute() deleteWholeHistory.execute()
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
getHistoryFromDatabase("") getHistoryFromDatabase("")
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {

View file

@ -30,7 +30,7 @@ object HistoryScreen : Screen, Parcelable {
const val DELETE_WHOLE_HISTORY_DIALOG = "delete_whole_history_dialog" const val DELETE_WHOLE_HISTORY_DIALOG = "delete_whole_history_dialog"
@IgnoredOnParcel @IgnoredOnParcel
val refreshListChannel: Channel<Unit> = Channel(Channel.CONFLATED) val refreshListChannel: Channel<Long> = Channel(Channel.CONFLATED)
@IgnoredOnParcel @IgnoredOnParcel
val insertHistoryChannel: Channel<Int> = Channel(Channel.CONFLATED) val insertHistoryChannel: Channel<Int> = Channel(Channel.CONFLATED)

View file

@ -4,13 +4,11 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -27,7 +25,6 @@ import ua.acclorite.book_story.ui.browse.BrowseScreen
import ua.acclorite.book_story.ui.history.HistoryScreen import ua.acclorite.book_story.ui.history.HistoryScreen
import javax.inject.Inject import javax.inject.Inject
@OptIn(FlowPreview::class)
@HiltViewModel @HiltViewModel
class LibraryModel @Inject constructor( class LibraryModel @Inject constructor(
private val getBooks: GetBooks, private val getBooks: GetBooks,
@ -45,7 +42,10 @@ class LibraryModel @Inject constructor(
/* Observe channel - - - - - - - - - - - */ /* Observe channel - - - - - - - - - - - */
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
LibraryScreen.refreshListChannel.receiveAsFlow().debounce(200).collectLatest { LibraryScreen.refreshListChannel.receiveAsFlow().collectLatest {
delay(it)
yield()
onEvent(LibraryEvent.OnRefreshList(showIndicator = false, hideSearch = false)) onEvent(LibraryEvent.OnRefreshList(showIndicator = false, hideSearch = false))
} }
} }
@ -197,7 +197,7 @@ class LibraryModel @Inject constructor(
) )
} }
HistoryScreen.refreshListChannel.trySend(Unit) HistoryScreen.refreshListChannel.trySend(0)
LibraryScreen.scrollToPageCompositionChannel.trySend( LibraryScreen.scrollToPageCompositionChannel.trySend(
event.categories.dropLastWhile { event.categories.dropLastWhile {
it.category != event.selectedCategory it.category != event.selectedCategory
@ -237,7 +237,7 @@ class LibraryModel @Inject constructor(
) )
} }
HistoryScreen.refreshListChannel.trySend(Unit) HistoryScreen.refreshListChannel.trySend(0)
BrowseScreen.refreshListChannel.trySend(Unit) BrowseScreen.refreshListChannel.trySend(Unit)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {

View file

@ -40,7 +40,7 @@ object LibraryScreen : Screen, Parcelable {
const val DELETE_DIALOG = "delete_dialog" const val DELETE_DIALOG = "delete_dialog"
@IgnoredOnParcel @IgnoredOnParcel
val refreshListChannel: Channel<Unit> = Channel(Channel.CONFLATED) val refreshListChannel: Channel<Long> = Channel(Channel.CONFLATED)
@IgnoredOnParcel @IgnoredOnParcel
val scrollToPageCompositionChannel: Channel<Int> = Channel(Channel.CONFLATED) val scrollToPageCompositionChannel: Channel<Int> = Channel(Channel.CONFLATED)

View file

@ -89,8 +89,8 @@ class ReaderModel @Inject constructor(
updateBook.execute(_state.value.book) updateBook.execute(_state.value.book)
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
HistoryScreen.refreshListChannel.trySend(Unit) HistoryScreen.refreshListChannel.trySend(0)
launch { launch {
snapshotFlow { snapshotFlow {
@ -170,8 +170,8 @@ class ReaderModel @Inject constructor(
updateBook.execute(_state.value.book) updateBook.execute(_state.value.book)
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(300)
HistoryScreen.refreshListChannel.trySend(Unit) HistoryScreen.refreshListChannel.trySend(300)
} }
} }
@ -251,8 +251,8 @@ class ReaderModel @Inject constructor(
updateBook.execute(_state.value.book) updateBook.execute(_state.value.book)
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
HistoryScreen.refreshListChannel.trySend(Unit) HistoryScreen.refreshListChannel.trySend(0)
} }
WindowCompat.getInsetsController( WindowCompat.getInsetsController(
@ -599,8 +599,8 @@ class ReaderModel @Inject constructor(
updateBook.execute(_state.value.book) updateBook.execute(_state.value.book)
LibraryScreen.refreshListChannel.trySend(Unit) LibraryScreen.refreshListChannel.trySend(0)
HistoryScreen.refreshListChannel.trySend(Unit) HistoryScreen.refreshListChannel.trySend(0)
} }
} }
} }