Save the user's reading position in the home timeline (#3614)

- Add a field to AccountEntity to hold the reading position
- Provide a method to save in the viewmodel to save the position
- Save the position when TimelineFragment pauses

Does not restore the position yet.
This commit is contained in:
Nik Clayton 2023-05-08 13:57:17 +02:00 committed by GitHub
commit 367240a612
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 1050 additions and 5 deletions

View file

@ -77,7 +77,6 @@ import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import java.io.IOException
@ -578,6 +577,17 @@ class TimelineFragment :
private var talkBackWasEnabled = false
override fun onPause() {
super.onPause()
(binding.recyclerView.layoutManager as? LinearLayoutManager)?.findFirstVisibleItemPosition()?.let { position ->
if (position != RecyclerView.NO_POSITION) {
adapter.snapshot().getOrNull(position)?.id?.let { statusId ->
viewModel.saveReadingPosition(statusId)
}
}
}
}
override fun onResume() {
super.onResume()
val a11yManager =

View file

@ -289,6 +289,14 @@ class CachedTimelineViewModel @Inject constructor(
}
}
override fun saveReadingPosition(statusId: String) {
accountManager.activeAccount?.let { account ->
Log.d(TAG, "Saving position at: $statusId")
account.lastVisibleHomeTimelineStatusId = statusId
accountManager.saveAccount(account)
}
}
override suspend fun invalidate() {
// invalidating when we don't have statuses yet can cause empty timelines because it cancels the network load
if (db.timelineDao().getStatusCount(accountManager.activeAccount!!.id) > 0) {
@ -297,6 +305,7 @@ class CachedTimelineViewModel @Inject constructor(
}
companion object {
private const val TAG = "CachedTimelineViewModel"
private const val MAX_STATUSES_IN_CACHE = 1000
}
}

View file

@ -255,6 +255,10 @@ class NetworkTimelineViewModel @Inject constructor(
}
}
override fun saveReadingPosition(statusId: String) {
/** Does nothing for non-cached timelines */
}
override suspend fun invalidate() {
currentSource?.invalidate()
}

View file

@ -182,6 +182,9 @@ abstract class TimelineViewModel(
abstract fun clearWarning(status: StatusViewData.Concrete)
/** Saves the user's reading position so it can be restored later */
abstract fun saveReadingPosition(statusId: String)
/** Triggered when currently displayed data must be reloaded. */
protected abstract suspend fun invalidate()