diff --git a/CHANGELOG.md b/CHANGELOG.md index d16ee987..512496b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 - Tweak progress bar UI to use a linear indicator - 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 diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/paging/LobstersPagingSource.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/paging/LobstersPagingSource.kt index 0cc5a939..0a7fa21f 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/paging/LobstersPagingSource.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/paging/LobstersPagingSource.kt @@ -27,13 +27,14 @@ constructor( ) : PagingSource() { override suspend fun load(params: LoadParams): LoadResult { - val page = params.key ?: 1 + val page = params.key ?: STARTING_PAGE_INDEX return when (val result = withContext(ioDispatcher) { remoteFetcher.getItemsAtPage(page) }) { is Success -> LoadResult.Page( + itemsBefore = (page - 1) * PAGE_SIZE, data = result.value, - prevKey = if (page == 1) null else page - 1, - nextKey = page.plus(1) + prevKey = if (page == STARTING_PAGE_INDEX) null else page - 1, + nextKey = page + 1, ) is Failure.NetworkFailure -> LoadResult.Error(result.error) is Failure.UnknownFailure -> LoadResult.Error(result.error) @@ -42,12 +43,19 @@ constructor( } } - override fun getRefreshKey(state: PagingState): Int { - return state.pages.size + 1 + override fun getRefreshKey(state: PagingState): Int? { + return state.anchorPosition?.let { anchorPosition -> + (anchorPosition / PAGE_SIZE).coerceAtLeast(STARTING_PAGE_INDEX) + } } @AssistedFactory interface Factory { fun create(remoteFetcher: RemoteFetcher): LobstersPagingSource } + + companion object { + const val PAGE_SIZE = 25 + const val STARTING_PAGE_INDEX = 1 + } } diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/lists/NetworkPosts.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/lists/NetworkPosts.kt index c76bb351..87832248 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/lists/NetworkPosts.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/lists/NetworkPosts.kt @@ -57,7 +57,7 @@ fun NetworkPosts( LazyColumn( state = listState, ) { - items(lazyPagingItems) { item -> + items(items = lazyPagingItems, key = { it.shortId }) { item -> if (item != null) { val dbModel = item.toDbModel() ListItem( @@ -70,7 +70,7 @@ fun NetworkPosts( } } if (lazyPagingItems.loadState.append == LoadState.Loading) { - item { + item(key = "progressbar") { ProgressBar( modifier = Modifier.fillMaxWidth() diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/viewmodel/ClawViewModel.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/viewmodel/ClawViewModel.kt index cb6f5261..ead6b8ed 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/viewmodel/ClawViewModel.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/viewmodel/ClawViewModel.kt @@ -15,6 +15,8 @@ import com.slack.eithernet.ApiResult.Failure import com.slack.eithernet.ApiResult.Success import dev.msfjarvis.claw.android.injection.IODispatcher 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.api.LobstersApi import dev.msfjarvis.claw.database.local.SavedPost @@ -38,9 +40,13 @@ constructor( @IODispatcher private val ioDispatcher: CoroutineDispatcher, ) : ViewModel() { 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 = - Pager(PagingConfig(pageSize = 20)) { pagingSourceFactory.create(api::getHottestPosts) } + Pager(PagingConfig(pageSize = PAGE_SIZE), initialKey = STARTING_PAGE_INDEX) { + pagingSourceFactory.create(api::getHottestPosts) + } val hottestPosts get() = hottestPostsPager.flow