fix timeline jumping (#4471)
Two things changed here: The check for `positionStart`only in `onItemRangeInserted` is not always correct - we only want to jump up when something is inserted at the top, if we already are at the top. `enablePlaceholders = false` has unintended side effects - the recyclerview adapter sometimes receives an "onItemRangeRemoved" followed by an "onItemRangeInserted", instead of just "onItemRangeChanged". Together they should make sure the timelines stay were they are.
This commit is contained in:
parent
83403ebb58
commit
0483440381
|
@ -45,8 +45,7 @@ class AccountMediaViewModel @Inject constructor(
|
|||
val media = Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = LOAD_AT_ONCE,
|
||||
prefetchDistance = LOAD_AT_ONCE * 2,
|
||||
enablePlaceholders = false
|
||||
prefetchDistance = LOAD_AT_ONCE * 2
|
||||
),
|
||||
pagingSourceFactory = {
|
||||
AccountMediaPagingSource(
|
||||
|
|
|
@ -162,7 +162,8 @@ class ConversationsFragment :
|
|||
|
||||
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
||||
if (positionStart == 0 && adapter.itemCount != itemCount) {
|
||||
val firstPos = (binding.recyclerView.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()
|
||||
if (firstPos == 0 && positionStart == 0 && adapter.itemCount != itemCount) {
|
||||
binding.recyclerView.post {
|
||||
if (getView() != null) {
|
||||
binding.recyclerView.scrollBy(0, Utils.dpToPx(requireContext(), -30))
|
||||
|
|
|
@ -45,8 +45,7 @@ class ConversationsViewModel @Inject constructor(
|
|||
@OptIn(ExperimentalPagingApi::class)
|
||||
val conversationFlow = Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = 30,
|
||||
enablePlaceholders = false
|
||||
pageSize = 30
|
||||
),
|
||||
remoteMediator = ConversationsRemoteMediator(api, database, accountManager),
|
||||
pagingSourceFactory = {
|
||||
|
|
|
@ -41,8 +41,7 @@ class DomainBlocksRepository @Inject constructor(
|
|||
val domainPager = Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = PAGE_SIZE,
|
||||
initialLoadSize = PAGE_SIZE,
|
||||
enablePlaceholders = false
|
||||
initialLoadSize = PAGE_SIZE
|
||||
),
|
||||
remoteMediator = DomainBlocksRemoteMediator(api, this),
|
||||
pagingSourceFactory = factory
|
||||
|
|
|
@ -40,8 +40,7 @@ class DraftsViewModel @Inject constructor(
|
|||
|
||||
val drafts = Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = 20,
|
||||
enablePlaceholders = false
|
||||
pageSize = 20
|
||||
),
|
||||
pagingSourceFactory = {
|
||||
database.draftDao().draftsPagingSource(
|
||||
|
|
|
@ -27,8 +27,7 @@ class FollowedTagsViewModel @Inject constructor(
|
|||
@OptIn(ExperimentalPagingApi::class)
|
||||
val pager = Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = 100,
|
||||
enablePlaceholders = false
|
||||
pageSize = 100
|
||||
),
|
||||
remoteMediator = FollowedTagsRemoteMediator(api, this),
|
||||
pagingSourceFactory = {
|
||||
|
|
|
@ -229,7 +229,8 @@ class NotificationsFragment :
|
|||
|
||||
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
||||
if (positionStart == 0 && adapter.itemCount != itemCount) {
|
||||
val firstPos = (binding.recyclerView.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()
|
||||
if (firstPos == 0 && positionStart == 0 && adapter.itemCount != itemCount) {
|
||||
binding.recyclerView.post {
|
||||
if (getView() != null) {
|
||||
binding.recyclerView.scrollBy(
|
||||
|
|
|
@ -95,8 +95,7 @@ class NotificationsViewModel @Inject constructor(
|
|||
val notifications = refreshTrigger.flatMapLatest {
|
||||
Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = LOAD_AT_ONCE,
|
||||
enablePlaceholders = false
|
||||
pageSize = LOAD_AT_ONCE
|
||||
),
|
||||
remoteMediator = remoteMediator,
|
||||
pagingSourceFactory = {
|
||||
|
|
|
@ -79,8 +79,7 @@ class ReportViewModel @Inject constructor(
|
|||
initialKey = statusId,
|
||||
config = PagingConfig(
|
||||
pageSize = 20,
|
||||
initialLoadSize = 20,
|
||||
enablePlaceholders = false
|
||||
initialLoadSize = 20
|
||||
),
|
||||
pagingSourceFactory = { StatusesPagingSource(accountId, mastodonApi) }
|
||||
).flow
|
||||
|
|
|
@ -40,8 +40,7 @@ class ScheduledStatusViewModel @Inject constructor(
|
|||
val data = Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = 20,
|
||||
initialLoadSize = 20,
|
||||
enablePlaceholders = false
|
||||
initialLoadSize = 20
|
||||
),
|
||||
pagingSourceFactory = pagingSourceFactory
|
||||
).flow
|
||||
|
|
|
@ -90,8 +90,7 @@ class SearchViewModel @Inject constructor(
|
|||
val statusesFlow = Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = DEFAULT_LOAD_SIZE,
|
||||
initialLoadSize = DEFAULT_LOAD_SIZE,
|
||||
enablePlaceholders = false
|
||||
initialLoadSize = DEFAULT_LOAD_SIZE
|
||||
),
|
||||
pagingSourceFactory = statusesPagingSourceFactory
|
||||
).flow
|
||||
|
@ -100,8 +99,7 @@ class SearchViewModel @Inject constructor(
|
|||
val accountsFlow = Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = DEFAULT_LOAD_SIZE,
|
||||
initialLoadSize = DEFAULT_LOAD_SIZE,
|
||||
enablePlaceholders = false
|
||||
initialLoadSize = DEFAULT_LOAD_SIZE
|
||||
),
|
||||
pagingSourceFactory = accountsPagingSourceFactory
|
||||
).flow
|
||||
|
@ -110,8 +108,7 @@ class SearchViewModel @Inject constructor(
|
|||
val hashtagsFlow = Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = DEFAULT_LOAD_SIZE,
|
||||
initialLoadSize = DEFAULT_LOAD_SIZE,
|
||||
enablePlaceholders = false
|
||||
initialLoadSize = DEFAULT_LOAD_SIZE
|
||||
),
|
||||
pagingSourceFactory = hashtagsPagingSourceFactory
|
||||
).flow
|
||||
|
|
|
@ -252,7 +252,8 @@ class TimelineFragment :
|
|||
|
||||
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
||||
if (positionStart == 0 && adapter.itemCount != itemCount) {
|
||||
val firstPos = (binding.recyclerView.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()
|
||||
if (firstPos == 0 && positionStart == 0 && adapter.itemCount != itemCount) {
|
||||
binding.recyclerView.post {
|
||||
if (getView() != null) {
|
||||
if (isSwipeToRefreshEnabled) {
|
||||
|
|
|
@ -86,8 +86,7 @@ class CachedTimelineViewModel @Inject constructor(
|
|||
@OptIn(ExperimentalPagingApi::class)
|
||||
override val statuses = Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = LOAD_AT_ONCE,
|
||||
enablePlaceholders = false
|
||||
pageSize = LOAD_AT_ONCE
|
||||
),
|
||||
remoteMediator = CachedTimelineRemoteMediator(accountManager, api, db),
|
||||
pagingSourceFactory = {
|
||||
|
|
|
@ -88,8 +88,7 @@ class NetworkTimelineViewModel @Inject constructor(
|
|||
@OptIn(ExperimentalPagingApi::class)
|
||||
override val statuses = Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = LOAD_AT_ONCE,
|
||||
enablePlaceholders = false
|
||||
pageSize = LOAD_AT_ONCE
|
||||
),
|
||||
pagingSourceFactory = {
|
||||
NetworkTimelinePagingSource(
|
||||
|
|
|
@ -26,6 +26,7 @@ import androidx.fragment.app.viewModels
|
|||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
|
||||
|
@ -76,7 +77,8 @@ class TrendingTagsFragment :
|
|||
|
||||
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
||||
if (positionStart == 0 && adapter.itemCount != itemCount) {
|
||||
val firstPos = (binding.recyclerView.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()
|
||||
if (firstPos == 0 && positionStart == 0 && adapter.itemCount != itemCount) {
|
||||
binding.recyclerView.post {
|
||||
if (getView() != null) {
|
||||
binding.recyclerView.scrollBy(
|
||||
|
|
Loading…
Reference in New Issue