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
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 com.mikepenz.iconics.utils.sizeDp
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.rxjava3.core.Observable
|
import io.reactivex.rxjava3.core.Observable
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
@ -578,6 +577,17 @@ class TimelineFragment :
|
||||||
|
|
||||||
private var talkBackWasEnabled = false
|
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() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
val a11yManager =
|
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() {
|
override suspend fun invalidate() {
|
||||||
// invalidating when we don't have statuses yet can cause empty timelines because it cancels the network load
|
// 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) {
|
if (db.timelineDao().getStatusCount(accountManager.activeAccount!!.id) > 0) {
|
||||||
|
@ -297,6 +305,7 @@ class CachedTimelineViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val TAG = "CachedTimelineViewModel"
|
||||||
private const val MAX_STATUSES_IN_CACHE = 1000
|
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() {
|
override suspend fun invalidate() {
|
||||||
currentSource?.invalidate()
|
currentSource?.invalidate()
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,6 +182,9 @@ abstract class TimelineViewModel(
|
||||||
|
|
||||||
abstract fun clearWarning(status: StatusViewData.Concrete)
|
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. */
|
/** Triggered when currently displayed data must be reloaded. */
|
||||||
protected abstract suspend fun invalidate()
|
protected abstract suspend fun invalidate()
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,13 @@ data class AccountEntity(
|
||||||
var pushPubKey: String = "",
|
var pushPubKey: String = "",
|
||||||
var pushPrivKey: String = "",
|
var pushPrivKey: String = "",
|
||||||
var pushAuth: 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
|
val identifier: String
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package com.keylesspalace.tusky.db;
|
package com.keylesspalace.tusky.db;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.room.AutoMigration;
|
||||||
import androidx.room.Database;
|
import androidx.room.Database;
|
||||||
import androidx.room.RoomDatabase;
|
import androidx.room.RoomDatabase;
|
||||||
import androidx.room.migration.Migration;
|
import androidx.room.migration.Migration;
|
||||||
|
@ -29,9 +30,20 @@ import java.io.File;
|
||||||
/**
|
/**
|
||||||
* DB version & declare DAO
|
* DB version & declare DAO
|
||||||
*/
|
*/
|
||||||
@Database(entities = { DraftEntity.class, AccountEntity.class, InstanceEntity.class, TimelineStatusEntity.class,
|
@Database(
|
||||||
TimelineAccountEntity.class, ConversationEntity.class
|
entities = {
|
||||||
}, version = 48)
|
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 class AppDatabase extends RoomDatabase {
|
||||||
|
|
||||||
public abstract AccountDao accountDao();
|
public abstract AccountDao accountDao();
|
||||||
|
|
Loading…
Reference in New Issue