fix: prevent unwanted list jumping during paging refresh

Fixes #347

Fixes SDP-34
This commit is contained in:
Harsh Shandilya 2022-12-20 22:47:53 +05:30
parent f6064616b0
commit 7b593806eb
No known key found for this signature in database
4 changed files with 24 additions and 9 deletions

View file

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix a case where collapsing the parent of an already collapsed comment caused it to become expanded - Fix a case where collapsing the parent of an already collapsed comment caused it to become expanded
- Tweak progress bar UI to use a linear indicator - Tweak progress bar UI to use a linear indicator
- Allow app bar to hide when scrolling down - Allow app bar to hide when scrolling down
- Fix bug where refreshing a list of posts caused it to jump around multiple times
## [1.14.0] - 2022-12-12 ## [1.14.0] - 2022-12-12

View file

@ -27,13 +27,14 @@ constructor(
) : PagingSource<Int, LobstersPost>() { ) : PagingSource<Int, LobstersPost>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, LobstersPost> { override suspend fun load(params: LoadParams<Int>): LoadResult<Int, LobstersPost> {
val page = params.key ?: 1 val page = params.key ?: STARTING_PAGE_INDEX
return when (val result = withContext(ioDispatcher) { remoteFetcher.getItemsAtPage(page) }) { return when (val result = withContext(ioDispatcher) { remoteFetcher.getItemsAtPage(page) }) {
is Success -> is Success ->
LoadResult.Page( LoadResult.Page(
itemsBefore = (page - 1) * PAGE_SIZE,
data = result.value, data = result.value,
prevKey = if (page == 1) null else page - 1, prevKey = if (page == STARTING_PAGE_INDEX) null else page - 1,
nextKey = page.plus(1) nextKey = page + 1,
) )
is Failure.NetworkFailure -> LoadResult.Error(result.error) is Failure.NetworkFailure -> LoadResult.Error(result.error)
is Failure.UnknownFailure -> LoadResult.Error(result.error) is Failure.UnknownFailure -> LoadResult.Error(result.error)
@ -42,12 +43,19 @@ constructor(
} }
} }
override fun getRefreshKey(state: PagingState<Int, LobstersPost>): Int { override fun getRefreshKey(state: PagingState<Int, LobstersPost>): Int? {
return state.pages.size + 1 return state.anchorPosition?.let { anchorPosition ->
(anchorPosition / PAGE_SIZE).coerceAtLeast(STARTING_PAGE_INDEX)
}
} }
@AssistedFactory @AssistedFactory
interface Factory { interface Factory {
fun create(remoteFetcher: RemoteFetcher<LobstersPost>): LobstersPagingSource fun create(remoteFetcher: RemoteFetcher<LobstersPost>): LobstersPagingSource
} }
companion object {
const val PAGE_SIZE = 25
const val STARTING_PAGE_INDEX = 1
}
} }

View file

@ -57,7 +57,7 @@ fun NetworkPosts(
LazyColumn( LazyColumn(
state = listState, state = listState,
) { ) {
items(lazyPagingItems) { item -> items(items = lazyPagingItems, key = { it.shortId }) { item ->
if (item != null) { if (item != null) {
val dbModel = item.toDbModel() val dbModel = item.toDbModel()
ListItem( ListItem(
@ -70,7 +70,7 @@ fun NetworkPosts(
} }
} }
if (lazyPagingItems.loadState.append == LoadState.Loading) { if (lazyPagingItems.loadState.append == LoadState.Loading) {
item { item(key = "progressbar") {
ProgressBar( ProgressBar(
modifier = modifier =
Modifier.fillMaxWidth() Modifier.fillMaxWidth()

View file

@ -15,6 +15,8 @@ import com.slack.eithernet.ApiResult.Failure
import com.slack.eithernet.ApiResult.Success import com.slack.eithernet.ApiResult.Success
import dev.msfjarvis.claw.android.injection.IODispatcher import dev.msfjarvis.claw.android.injection.IODispatcher
import dev.msfjarvis.claw.android.paging.LobstersPagingSource import dev.msfjarvis.claw.android.paging.LobstersPagingSource
import dev.msfjarvis.claw.android.paging.LobstersPagingSource.Companion.PAGE_SIZE
import dev.msfjarvis.claw.android.paging.LobstersPagingSource.Companion.STARTING_PAGE_INDEX
import dev.msfjarvis.claw.android.ui.toLocalDateTime import dev.msfjarvis.claw.android.ui.toLocalDateTime
import dev.msfjarvis.claw.api.LobstersApi import dev.msfjarvis.claw.api.LobstersApi
import dev.msfjarvis.claw.database.local.SavedPost import dev.msfjarvis.claw.database.local.SavedPost
@ -38,9 +40,13 @@ constructor(
@IODispatcher private val ioDispatcher: CoroutineDispatcher, @IODispatcher private val ioDispatcher: CoroutineDispatcher,
) : ViewModel() { ) : ViewModel() {
private val hottestPostsPager = private val hottestPostsPager =
Pager(PagingConfig(pageSize = 20)) { pagingSourceFactory.create(api::getHottestPosts) } Pager(PagingConfig(pageSize = PAGE_SIZE), initialKey = STARTING_PAGE_INDEX) {
pagingSourceFactory.create(api::getHottestPosts)
}
private val newestPostsPager = private val newestPostsPager =
Pager(PagingConfig(pageSize = 20)) { pagingSourceFactory.create(api::getHottestPosts) } Pager(PagingConfig(pageSize = PAGE_SIZE), initialKey = STARTING_PAGE_INDEX) {
pagingSourceFactory.create(api::getHottestPosts)
}
val hottestPosts val hottestPosts
get() = hottestPostsPager.flow get() = hottestPostsPager.flow