Status Update
Comments
[Deleted User] <[Deleted User]> #2
network fraud
[Deleted User] <[Deleted User]> #3
Any update when this will be release or any alpha version ?
or any update on below ticket
ku...@gmail.com <ku...@gmail.com> #4
Hello!
I tried this out on a sample which removes items through the solution given
ViewModel:
val pager = Pager(
config = config,
pagingSourceFactory = {
PagingSource(
initialKey,
prevKey,
nextKey,
getItems
)
}
).flow
private var _removedItemsFlow = MutableStateFlow(mutableListOf<String>())
private val removedItemsFlow: Flow<MutableList<String>> get() = _removedItemsFlow
val pagingData: Flow<PagingData<String>>
get() = pager.pagingData
.combine(removedItemsFlow) { pagingData, removed ->
pagingData.filter { it !in removed }
}
.cachedIn(clientScope)
fun removeItem(item: String) {
var removedItems = _removedItemsFlow.value
removedItems.add(item)
_removedItemsFlow.value = removedItems
}
Activity/Fragment
private val pagingDataAdapter by lazy {
SamplePagingDataAdapter {
viewModel.removeItem(it)
}
}
viewModel.pagingData
.onEach { pagingDataAdapter.submitData(it) }
.launchIn(lifecycleScope)
The problem is it doesn't update the list when I update the removedItems
list even if I call viewModel.removeItem(item)
so I tried to refresh the list everytime I remove:
private val pagingDataAdapter by lazy {
SamplePagingDataAdapter {
viewModel.removeItem(it)
refresh()
}
}
private fun refresh() {
pagingDataAdapter.refresh()
}
This works however:
-
If I remove all items from page one, the whole list becomes empty. I'm guessing because there's no page one, it wasn't able to load the next?
-
If I remove an item from page 2 and above, the whole list refreshes and I'm back to page 1. Really bad if I'm at page 10 then I have to scroll over again.
I'm guessing refresh isn't the way to do this. Have I missed anything? Thanks in advance!
au...@gmail.com <au...@gmail.com> #5
Do I understand correctly that most modern DBaaS's(Firestore, MongoDB Realm) auto-sync functionality is not supported currently? (datasource can't push updates)
And this ticket covers functionality required for PagedList v3 to enable that with most DBaaS? Or separate issue needs to be created?
du...@google.com <du...@google.com> #6
PagingData.filtering in a .combine not pushing updates seems to be a separate bug from db updates automatically invalidating PagingSource.
For PagingSource backed by MongoDB / Realm, you'll need to make sure to call PagingSource.invalidate() when the db is updated.
Each PagingSource instance is meant to represent a snapshot of the backing dataset and should be invalidated whenever that changes.
cc...@google.com <cc...@google.com> #7
Re #4, 1) - filed
cc...@google.com <cc...@google.com> #8
Also, note in #4 that your combine is performed before the caching step, which I think means you'll be re-starting collection every time the filter changes, and thus losing currently fetched state. (If that's the problem, perhaps a good argument for an immediate cachedIn() by default)
Can you add a .cachedIn() before that, and let us know if that works?
val pagingData: Flow<PagingData<String>>
get() = pager.pagingData
.cachedIn(clientScope) // cache data as it's loaded
.combine(removedItemsFlow) { pagingData, removed ->
pagingData.filter { it !in removed }
}
.cachedIn(clientScope) // cache filtered data, so new subscribers don't need to re-filter
au...@gmail.com <au...@gmail.com> #9
For PagingSource backed by MongoDB / Realm, you'll need to make sure to call PagingSource.invalidate() when the db is updated.
I mean a lot of DBaaS has APIs for paging which return stream of items for each page. e.g.
- For page1 result from FirebaseDataSource is
Flow<List<Item>>
- For page2 result from FirebaseDataSource is
Flow<List<Item>>
- etc.
From my understanding PagingSource.invalidate()
invalidates and refetches all items?
ku...@gmail.com <ku...@gmail.com> #10
Re #8
Thanks! I tried out your suggestion but unfortunately, it didn't work. I just starred the issue you mentioned on #7. I hope it gets fixed soon!
du...@google.com <du...@google.com> #11
I mean a lot of DBaaS has APIs for paging which return stream of items for each page. e.g. Firebase
For page1 result from FirebaseDataSource is Flow<List<Item>> For page2 result from FirebaseDataSource is Flow<List<Item>> etc. From my understanding PagingSource.invalidate() invalidates and refetches all items?
Correct, PagingSource.invalidate() refetches all items, but you'll want to reload the page the user is at to update that page of items anyway.
You'll want to implement PagingSource.getRefreshKey to tell PagingSource how to resume from user's current scroll position.
ku...@gmail.com <ku...@gmail.com> #12
I've fixed #4.2 from the comment of #11 to implement PagingSource.getRefreshKey. Thanks for that! Now, it doesn't go to the start on every refresh however, I've been encountering this weird issue. The refresh is alternating between two pages if two pages are shown in the list. Any idea why this is happening? I've attached some screen recordings and the code.
Here's my PagingSource:
class PagingSource<K : Any, V : Any>(
...
...
private val nextKey: (List<V>, K) -> K?,
...
) : androidx.paging.PagingSource<K, V>() {
override val jumpingSupported = true
override val keyReuseSupported = true
@OptIn(ExperimentalPagingApi::class)
override fun getRefreshKey(state: PagingState<K, V>): K? {
return state.anchorPosition?.let { position ->
state.closestPageToPosition(position)?.let { page ->
// Trying to load the current page
// No way to get current page so just use prevKey and get the nextKey
page.prevKey?.let {
nextKey(page.data, it)
}
}
}
}
...
}
du...@google.com <du...@google.com> #13
Re: #12
What does your model and DiffUtil.ItemCallback look like? I don't think entire pages should be flashing like that. Also, what does your PagingConfig look like?
ku...@gmail.com <ku...@gmail.com> #14
Config is just a PagingConfig(pageSize = 15, enablePlaceholders = false)
and the DiffUtil.ItemCallback
is just for a String
so it's using oldItem == newItem
for both areItemsTheSame
and areContentsTheSame
du...@google.com <du...@google.com> #15
Thanks - if you're able to share a repro project I'm happy to check it out and take a closer look.
ku...@gmail.com <ku...@gmail.com> #16
Thanks, too. I'm trying to implement it in the sample on my kurt/paging-3.0
branch.
cc...@google.com <cc...@google.com> #17
Re-#9 and streams of items for each page - I've filed a separate bug for supporting each page as a stream -
Will keep this bug about modifying data after it is loaded at the PagingData/UI level, and split off the question of self-updating pages/items at the PagingSource level into the other bug (since the implementations would be very different).
Description
The immediate goal is to support async modifications (such as removing or updating an item due to a network signal). This will be much simpler with the new event/stream-based architecture internally, as well as support for in-memory caching.
We'll also consider synchronous modifications, for use cases like modifying an event locally in response to a modification in list UI (e.g. starring or upvoting an item). The difficulty there is that any new stream objects go through async DiffUtil.