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:
parent
0c02dd18bf
commit
367240a612
7 changed files with 1050 additions and 5 deletions
1001
app/schemas/com.keylesspalace.tusky.db.AppDatabase/49.json
Normal file
1001
app/schemas/com.keylesspalace.tusky.db.AppDatabase/49.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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 =
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -82,7 +82,13 @@ data class AccountEntity(
|
|||
var pushPubKey: String = "",
|
||||
var pushPrivKey: String = "",
|
||||
var pushAuth: String = "",
|
||||
var pushServerKey: String = ""
|
||||
var pushServerKey: String = "",
|
||||
|
||||
/**
|
||||
* ID of the status at the top of the visible list in the home timeline when the
|
||||
* user navigated away.
|
||||
*/
|
||||
var lastVisibleHomeTimelineStatusId: String? = null
|
||||
) {
|
||||
|
||||
val identifier: String
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package com.keylesspalace.tusky.db;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.AutoMigration;
|
||||
import androidx.room.Database;
|
||||
import androidx.room.RoomDatabase;
|
||||
import androidx.room.migration.Migration;
|
||||
|
@ -29,9 +30,20 @@ import java.io.File;
|
|||
/**
|
||||
* DB version & declare DAO
|
||||
*/
|
||||
@Database(entities = { DraftEntity.class, AccountEntity.class, InstanceEntity.class, TimelineStatusEntity.class,
|
||||
TimelineAccountEntity.class, ConversationEntity.class
|
||||
}, version = 48)
|
||||
@Database(
|
||||
entities = {
|
||||
DraftEntity.class,
|
||||
AccountEntity.class,
|
||||
InstanceEntity.class,
|
||||
TimelineStatusEntity.class,
|
||||
TimelineAccountEntity.class,
|
||||
ConversationEntity.class
|
||||
},
|
||||
version = 49,
|
||||
autoMigrations = {
|
||||
@AutoMigration(from = 48, to = 49)
|
||||
}
|
||||
)
|
||||
public abstract class AppDatabase extends RoomDatabase {
|
||||
|
||||
public abstract AccountDao accountDao();
|
||||
|
|
Loading…
Reference in a new issue