From 58c93e0ccece9ac82f83f78f7fb25662d5a49be1 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Mon, 19 Jun 2023 14:30:15 -0400 Subject: [PATCH] - Redesign feed invalidations to account for changes in the follow list - Redesign scroll to the top implementation to avoid using arguments in the navigator. --- .../ui/dal/BookmarkPrivateFeedFilter.kt | 4 + .../ui/dal/BookmarkPublicFeedFilter.kt | 3 + .../amethyst/ui/dal/ChannelFeedFilter.kt | 5 + .../amethyst/ui/dal/ChatroomFeedFilter.kt | 4 + .../ui/dal/ChatroomListKnownFeedFilter.kt | 4 + .../ui/dal/ChatroomListNewFeedFilter.kt | 4 + .../amethyst/ui/dal/FeedFilter.kt | 5 + .../amethyst/ui/dal/GlobalFeedFilter.kt | 4 + .../amethyst/ui/dal/HashtagFeedFilter.kt | 4 + .../ui/dal/HiddenAccountsFeedFilter.kt | 3 + .../ui/dal/HomeConversationsFeedFilter.kt | 5 + .../ui/dal/HomeNewThreadFeedFilter.kt | 4 + .../amethyst/ui/dal/NotificationFeedFilter.kt | 4 + .../amethyst/ui/dal/PeopleListFeedFilter.kt | 4 + .../amethyst/ui/dal/ThreadFeedFilter.kt | 4 + ...UserProfileAppRecommendationsFeedFilter.kt | 4 + .../ui/dal/UserProfileBookmarksFeedFilter.kt | 4 + .../dal/UserProfileConversationsFeedFilter.kt | 4 + .../ui/dal/UserProfileFollowersFeedFilter.kt | 3 + .../ui/dal/UserProfileFollowsFeedFilter.kt | 4 + .../ui/dal/UserProfileNewThreadFeedFilter.kt | 4 + .../ui/dal/UserProfileReportsFeedFilter.kt | 4 + .../ui/dal/UserProfileZapsFeedFilter.kt | 5 + .../amethyst/ui/dal/VideoFeedFilter.kt | 4 + .../amethyst/ui/navigation/AppNavigation.kt | 91 +++++++------------ .../amethyst/ui/navigation/Routes.kt | 16 ++-- .../amethyst/ui/screen/CardFeedViewModel.kt | 24 +++-- .../amethyst/ui/screen/FeedView.kt | 15 ++- .../amethyst/ui/screen/FeedViewModel.kt | 25 ++--- .../ui/screen/loggedIn/BookmarkListScreen.kt | 14 ++- .../ui/screen/loggedIn/HashtagScreen.kt | 7 +- .../amethyst/ui/screen/loggedIn/HomeScreen.kt | 12 +-- .../amethyst/ui/screen/loggedIn/MainScreen.kt | 52 +++++++---- .../ui/screen/loggedIn/NotificationScreen.kt | 11 +-- .../ui/screen/loggedIn/ProfileScreen.kt | 32 ++++++- .../ui/screen/loggedIn/SearchScreen.kt | 8 +- .../ui/screen/loggedIn/VideoScreen.kt | 21 ++--- 37 files changed, 275 insertions(+), 150 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/BookmarkPrivateFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/BookmarkPrivateFeedFilter.kt index 49cb27fbb..8e8b12dca 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/BookmarkPrivateFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/BookmarkPrivateFeedFilter.kt @@ -7,6 +7,10 @@ import com.vitorpamplona.amethyst.model.Note object BookmarkPrivateFeedFilter : FeedFilter() { lateinit var account: Account + override fun feedKey(): String { + return account.userProfile().latestBookmarkList?.id ?: "" + } + override fun feed(): List { val privKey = account.loggedIn.privKey ?: return emptyList() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/BookmarkPublicFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/BookmarkPublicFeedFilter.kt index 779be607e..775e48bdc 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/BookmarkPublicFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/BookmarkPublicFeedFilter.kt @@ -7,6 +7,9 @@ import com.vitorpamplona.amethyst.model.Note object BookmarkPublicFeedFilter : FeedFilter() { lateinit var account: Account + override fun feedKey(): String { + return BookmarkPrivateFeedFilter.account.userProfile().latestBookmarkList?.id ?: "" + } override fun feed(): List { val bookmarks = account.userProfile().latestBookmarkList diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChannelFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChannelFeedFilter.kt index 8908b1f48..4f3493e67 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChannelFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChannelFeedFilter.kt @@ -5,6 +5,11 @@ import com.vitorpamplona.amethyst.model.Channel import com.vitorpamplona.amethyst.model.Note class ChannelFeedFilter(val channel: Channel, val account: Account) : AdditiveFeedFilter() { + + override fun feedKey(): String { + return channel.idHex + } + // returns the last Note of each user. override fun feed(): List { return channel.notes diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomFeedFilter.kt index 600f4173c..0235ca3ae 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomFeedFilter.kt @@ -6,6 +6,10 @@ import com.vitorpamplona.amethyst.model.User class ChatroomFeedFilter(val withUser: User, val account: Account) : AdditiveFeedFilter() { // returns the last Note of each user. + override fun feedKey(): String { + return withUser.pubkeyHex + } + override fun feed(): List { val messages = account .userProfile() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt index ff3a112f0..5ec4c8735 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListKnownFeedFilter.kt @@ -11,6 +11,10 @@ import kotlin.time.measureTimedValue class ChatroomListKnownFeedFilter(val account: Account) : AdditiveFeedFilter() { + override fun feedKey(): String { + return account.userProfile().pubkeyHex + } + // returns the last Note of each user. override fun feed(): List { val me = account.userProfile() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListNewFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListNewFeedFilter.kt index cad55b4a2..09ce59398 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListNewFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ChatroomListNewFeedFilter.kt @@ -10,6 +10,10 @@ import kotlin.time.measureTimedValue class ChatroomListNewFeedFilter(val account: Account) : AdditiveFeedFilter() { + override fun feedKey(): String { + return account.userProfile().pubkeyHex + } + // returns the last Note of each user. override fun feed(): List { val me = account.userProfile() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/FeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/FeedFilter.kt index e07d8475f..c216d8501 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/FeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/FeedFilter.kt @@ -18,6 +18,11 @@ abstract class FeedFilter { return feed.take(1000) } + /** + * Returns a string that serves as the key to invalidate the list if it changes. + */ + abstract fun feedKey(): String + abstract fun feed(): List } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/GlobalFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/GlobalFeedFilter.kt index 130b04df6..ebbe5cb63 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/GlobalFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/GlobalFeedFilter.kt @@ -7,6 +7,10 @@ import com.vitorpamplona.amethyst.service.model.* class GlobalFeedFilter(val account: Account) : AdditiveFeedFilter() { + override fun feedKey(): String { + return account.userProfile().pubkeyHex + } + override fun feed(): List { val notes = innerApplyFilter(LocalCache.notes.values) val longFormNotes = innerApplyFilter(LocalCache.addressables.values) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HashtagFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HashtagFeedFilter.kt index 5f5106c84..dbf22f15e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HashtagFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HashtagFeedFilter.kt @@ -12,6 +12,10 @@ object HashtagFeedFilter : AdditiveFeedFilter() { lateinit var account: Account var tag: String? = null + override fun feedKey(): String { + return account.userProfile().pubkeyHex + "-" + tag + } + fun loadHashtag(account: Account, tag: String?) { this.account = account this.tag = tag diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HiddenAccountsFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HiddenAccountsFeedFilter.kt index e63cc809d..59c58f1cf 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HiddenAccountsFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HiddenAccountsFeedFilter.kt @@ -5,6 +5,9 @@ import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.User class HiddenAccountsFeedFilter(val account: Account) : FeedFilter() { + override fun feedKey(): String { + return account.userProfile().pubkeyHex + "-" + HashtagFeedFilter.tag + } override fun feed(): List { return (account.hiddenUsers + account.transientHiddenUsers) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeConversationsFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeConversationsFeedFilter.kt index de3b54ab0..390969169 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeConversationsFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeConversationsFeedFilter.kt @@ -7,6 +7,11 @@ import com.vitorpamplona.amethyst.service.model.PollNoteEvent import com.vitorpamplona.amethyst.service.model.TextNoteEvent class HomeConversationsFeedFilter(val account: Account) : AdditiveFeedFilter() { + + override fun feedKey(): String { + return account.userProfile().pubkeyHex + "-" + account.defaultHomeFollowList + } + override fun feed(): List { return sort(innerApplyFilter(LocalCache.notes.values)) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeNewThreadFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeNewThreadFeedFilter.kt index e8b5861d1..cc4e9e0a5 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeNewThreadFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/HomeNewThreadFeedFilter.kt @@ -12,6 +12,10 @@ import com.vitorpamplona.amethyst.service.model.RepostEvent import com.vitorpamplona.amethyst.service.model.TextNoteEvent class HomeNewThreadFeedFilter(val account: Account) : AdditiveFeedFilter() { + override fun feedKey(): String { + return account.userProfile().pubkeyHex + "-" + account.defaultHomeFollowList + } + override fun feed(): List { val notes = innerApplyFilter(LocalCache.notes.values) val longFormNotes = innerApplyFilter(LocalCache.addressables.values) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt index 8ab920e5c..8b303e718 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/NotificationFeedFilter.kt @@ -8,6 +8,10 @@ import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.service.model.* class NotificationFeedFilter(val account: Account) : AdditiveFeedFilter() { + override fun feedKey(): String { + return account.userProfile().pubkeyHex + "-" + account.defaultNotificationFollowList + } + override fun feed(): List { return sort(innerApplyFilter(LocalCache.notes.values)) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/PeopleListFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/PeopleListFeedFilter.kt index 46bf82fe9..e8f741dbd 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/PeopleListFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/PeopleListFeedFilter.kt @@ -8,6 +8,10 @@ import com.vitorpamplona.amethyst.service.model.PeopleListEvent object PeopleListFeedFilter : FeedFilter() { lateinit var account: Account + override fun feedKey(): String { + return account.userProfile().pubkeyHex + } + override fun feed(): List { val privKey = account.loggedIn.privKey ?: return emptyList() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ThreadFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ThreadFeedFilter.kt index 3a6883f52..1612d85cb 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ThreadFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/ThreadFeedFilter.kt @@ -7,6 +7,10 @@ import com.vitorpamplona.amethyst.model.ThreadAssembler @Immutable class ThreadFeedFilter(val noteId: String) : FeedFilter() { + override fun feedKey(): String { + return noteId + } + override fun feed(): List { val cachedSignatures: MutableMap = mutableMapOf() val eventsToWatch = ThreadAssembler().findThreadFor(noteId) ?: emptySet() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt index 4f4d4f71b..9c14828de 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt @@ -6,6 +6,10 @@ import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.model.AppRecommendationEvent class UserProfileAppRecommendationsFeedFilter(val user: User) : FeedFilter() { + override fun feedKey(): String { + return user.pubkeyHex + } + override fun feed(): List { val recommendations = LocalCache.addressables.values.filter { (it.event as? AppRecommendationEvent)?.pubKey == user.pubkeyHex diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileBookmarksFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileBookmarksFeedFilter.kt index 837b77f12..884b5e622 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileBookmarksFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileBookmarksFeedFilter.kt @@ -9,6 +9,10 @@ object UserProfileBookmarksFeedFilter : FeedFilter() { lateinit var account: Account var user: User? = null + override fun feedKey(): String { + return account.userProfile().pubkeyHex + "-" + user?.pubkeyHex + } + fun loadUserProfile(accountLoggedIn: Account, user: User?) { account = accountLoggedIn this.user = user diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileConversationsFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileConversationsFeedFilter.kt index 8d8f559c2..c7996b985 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileConversationsFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileConversationsFeedFilter.kt @@ -8,6 +8,10 @@ object UserProfileConversationsFeedFilter : FeedFilter() { var account: Account? = null var user: User? = null + override fun feedKey(): String { + return account?.userProfile()?.pubkeyHex + "-" + user?.pubkeyHex + } + fun loadUserProfile(accountLoggedIn: Account, user: User?) { account = accountLoggedIn this.user = user diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowersFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowersFeedFilter.kt index ebbf340f4..1f46bbcb1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowersFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowersFeedFilter.kt @@ -6,6 +6,9 @@ import com.vitorpamplona.amethyst.model.User class UserProfileFollowersFeedFilter(val user: User, val account: Account) : FeedFilter() { + override fun feedKey(): String { + return account.userProfile().pubkeyHex + "-" + user.pubkeyHex + } override fun feed(): List { return LocalCache.users.values.filter { it.isFollowing(user) && !account.isHidden(it) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowsFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowsFeedFilter.kt index 4e07939f3..49af3d25e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowsFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileFollowsFeedFilter.kt @@ -7,6 +7,10 @@ import com.vitorpamplona.amethyst.service.model.ContactListEvent class UserProfileFollowsFeedFilter(val user: User, val account: Account) : FeedFilter() { + override fun feedKey(): String { + return account.userProfile()?.pubkeyHex + "-" + user.pubkeyHex + } + val cache: MutableMap> = mutableMapOf() override fun feed(): List { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileNewThreadFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileNewThreadFeedFilter.kt index 36505b4ae..86e97a3ae 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileNewThreadFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileNewThreadFeedFilter.kt @@ -12,6 +12,10 @@ object UserProfileNewThreadFeedFilter : FeedFilter() { var account: Account? = null var user: User? = null + override fun feedKey(): String { + return account?.userProfile()?.pubkeyHex + "-" + user?.pubkeyHex + } + fun loadUserProfile(accountLoggedIn: Account, user: User) { account = accountLoggedIn this.user = user diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileReportsFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileReportsFeedFilter.kt index 981b1b505..920988d3b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileReportsFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileReportsFeedFilter.kt @@ -8,6 +8,10 @@ import com.vitorpamplona.amethyst.service.model.ReportEvent object UserProfileReportsFeedFilter : FeedFilter() { var user: User? = null + override fun feedKey(): String { + return user?.pubkeyHex ?: "" + } + fun loadUserProfile(user: User?) { this.user = user } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileZapsFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileZapsFeedFilter.kt index e73b3f0d6..ce2ab86f0 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileZapsFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileZapsFeedFilter.kt @@ -5,6 +5,11 @@ import com.vitorpamplona.amethyst.service.model.zaps.UserZaps import com.vitorpamplona.amethyst.ui.screen.ZapReqResponse class UserProfileZapsFeedFilter(val user: User) : FeedFilter() { + + override fun feedKey(): String { + return user.pubkeyHex + } + override fun feed(): List { return UserZaps.forProfileFeed(user.zaps) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/VideoFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/VideoFeedFilter.kt index 64634b8b4..c47f1e2a7 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/VideoFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/VideoFeedFilter.kt @@ -7,6 +7,10 @@ import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.service.model.* class VideoFeedFilter(val account: Account) : AdditiveFeedFilter() { + override fun feedKey(): String { + return account.userProfile().pubkeyHex + "-" + account.defaultStoriesFollowList + } + override fun feed(): List { val notes = innerApplyFilter(LocalCache.notes.values) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt index 0d5aa5a2b..d72aa2b06 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt @@ -60,51 +60,10 @@ fun AppNavigation( } NavHost(navController, startDestination = Route.Home.route) { - Route.Video.let { route -> - composable(route.route, route.arguments, content = { - val scrollToTop = it.arguments?.getBoolean("scrollToTop") ?: false - - if (scrollToTop) { - videoFeedViewModel.sendToTop() - it.arguments?.remove("scrollToTop") - } - - VideoScreen( - videoFeedView = videoFeedViewModel, - accountViewModel = accountViewModel, - nav = nav - ) - }) - } - - Route.Search.let { route -> - composable(route.route, route.arguments, content = { - val scrollToTop = it.arguments?.getBoolean("scrollToTop") ?: false - - if (scrollToTop) { - searchFeedViewModel.sendToTop() - it.arguments?.remove("scrollToTop") - } - - SearchScreen( - searchFeedViewModel = searchFeedViewModel, - accountViewModel = accountViewModel, - nav = nav - ) - }) - } - Route.Home.let { route -> composable(route.route, route.arguments, content = { it -> - val scrollToTop = it.arguments?.getBoolean("scrollToTop") ?: false val nip47 = it.arguments?.getString("nip47") - if (scrollToTop) { - homeFeedViewModel.sendToTop() - repliesFeedViewModel.sendToTop() - it.arguments?.remove("scrollToTop") - } - HomeScreen( homeFeedViewModel = homeFeedViewModel, repliesFeedViewModel = repliesFeedViewModel, @@ -124,25 +83,6 @@ fun AppNavigation( }) } - Route.Notification.let { route -> - composable(route.route, route.arguments, content = { - val scrollToTop = it.arguments?.getBoolean("scrollToTop") ?: false - - if (scrollToTop) { - notifFeedViewModel.clear() - notifFeedViewModel.invalidateDataAndSendToTop() - it.arguments?.remove("scrollToTop") - } - - NotificationScreen( - notifFeedViewModel = notifFeedViewModel, - userReactionsStatsModel = userReactionsStatsModel, - accountViewModel = accountViewModel, - nav = nav - ) - }) - } - composable( Route.Message.route, content = { @@ -155,6 +95,37 @@ fun AppNavigation( } ) + Route.Video.let { route -> + composable(route.route, route.arguments, content = { + VideoScreen( + videoFeedView = videoFeedViewModel, + accountViewModel = accountViewModel, + nav = nav + ) + }) + } + + Route.Search.let { route -> + composable(route.route, route.arguments, content = { + SearchScreen( + searchFeedViewModel = searchFeedViewModel, + accountViewModel = accountViewModel, + nav = nav + ) + }) + } + + Route.Notification.let { route -> + composable(route.route, route.arguments, content = { + NotificationScreen( + notifFeedViewModel = notifFeedViewModel, + userReactionsStatsModel = userReactionsStatsModel, + accountViewModel = accountViewModel, + nav = nav + ) + }) + } + composable(Route.BlockedUsers.route, content = { HiddenUsersScreen(accountViewModel, nav) }) composable(Route.Bookmarks.route, content = { BookmarkListScreen(accountViewModel, nav) }) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt index 8dd69563e..740afc737 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt @@ -33,31 +33,27 @@ sealed class Route( get() = route.substringBefore("?") object Home : Route( - route = "Home?scrollToTop={scrollToTop}&nip47={nip47}", + route = "Home?nip47={nip47}", icon = R.drawable.ic_home, arguments = listOf( - navArgument("scrollToTop") { type = NavType.BoolType; defaultValue = false }, navArgument("nip47") { type = NavType.StringType; nullable = true; defaultValue = null } ).toImmutableList(), hasNewItems = { accountViewModel, newNotes -> HomeLatestItem.hasNewItems(accountViewModel, newNotes) } ) object Search : Route( - route = "Search?scrollToTop={scrollToTop}", - icon = R.drawable.ic_globe, - arguments = listOf(navArgument("scrollToTop") { type = NavType.BoolType; defaultValue = false }).toImmutableList() + route = "Search", + icon = R.drawable.ic_globe ) object Video : Route( - route = "Video?scrollToTop={scrollToTop}", - icon = R.drawable.ic_video, - arguments = listOf(navArgument("scrollToTop") { type = NavType.BoolType; defaultValue = false }).toImmutableList() + route = "Video", + icon = R.drawable.ic_video ) object Notification : Route( - route = "Notification?scrollToTop={scrollToTop}", + route = "Notification", icon = R.drawable.ic_notifications, - arguments = listOf(navArgument("scrollToTop") { type = NavType.BoolType; defaultValue = false }).toImmutableList(), hasNewItems = { accountViewModel, newNotes -> NotificationLatestItem.hasNewItems(accountViewModel, newNotes) } ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt index aec5b2a38..b98221e57 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt @@ -56,6 +56,8 @@ open class CardFeedViewModel(val localFilter: FeedFilter) : ViewModel() { val scrollToTop = _scrollToTop.asStateFlow() var scrolltoTopPending = false + private var lastFeedKey: String? = null + fun sendToTop() { if (scrolltoTopPending) return @@ -84,6 +86,7 @@ open class CardFeedViewModel(val localFilter: FeedFilter) : ViewModel() { checkNotInMainThread() val notes = localFilter.feed() + lastFeedKey = localFilter.feedKey() val thisAccount = (localFilter as? NotificationFeedFilter)?.account val lastNotesCopy = if (thisAccount == lastAccount) lastNotes else null @@ -233,6 +236,8 @@ open class CardFeedViewModel(val localFilter: FeedFilter) : ViewModel() { val lastNotesCopy = if (thisAccount == lastAccount) lastNotes else null if (lastNotesCopy != null && localFilter is AdditiveFeedFilter && oldNotesState is CardFeedState.Loaded) { + lastFeedKey = localFilter.feedKey() + val filteredNewList = localFilter.applyFilter(newItems) if (filteredNewList.isEmpty()) return @@ -279,15 +284,18 @@ open class CardFeedViewModel(val localFilter: FeedFilter) : ViewModel() { } @OptIn(ExperimentalTime::class) - fun invalidateDataAndSendToTop(ignoreIfDoing: Boolean = false) { - bundler.invalidate(ignoreIfDoing) { - // adds the time to perform the refresh into this delay - // holding off new updates in case of heavy refresh routines. - val (value, elapsed) = measureTimedValue { - refreshSuspended() - sendToTop() + fun checkKeysInvalidateDataAndSendToTop() { + if (lastFeedKey != localFilter.feedKey()) { + clear() + bundler.invalidate(false) { + // adds the time to perform the refresh into this delay + // holding off new updates in case of heavy refresh routines. + val (value, elapsed) = measureTimedValue { + refreshSuspended() + sendToTop() + } + Log.d("Time", "${this.javaClass.simpleName} Card update $elapsed") } - Log.d("Time", "${this.javaClass.simpleName} Card update $elapsed") } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt index fd755f815..221776e6a 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt @@ -40,14 +40,13 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel fun RefresheableFeedView( viewModel: FeedViewModel, routeForLastRead: String?, - accountViewModel: AccountViewModel, - nav: (String) -> Unit, - + enablePullRefresh: Boolean = true, scrollStateKey: String? = null, - enablePullRefresh: Boolean = true + accountViewModel: AccountViewModel, + nav: (String) -> Unit ) { RefresheableView(viewModel, enablePullRefresh) { - SaveableFeedState(viewModel, accountViewModel, nav, routeForLastRead, scrollStateKey) + SaveableFeedState(viewModel, routeForLastRead, scrollStateKey, accountViewModel, nav) } } @@ -82,10 +81,10 @@ fun RefresheableView( @Composable private fun SaveableFeedState( viewModel: FeedViewModel, - accountViewModel: AccountViewModel, - nav: (String) -> Unit, routeForLastRead: String?, - scrollStateKey: String? = null + scrollStateKey: String? = null, + accountViewModel: AccountViewModel, + nav: (String) -> Unit ) { SaveableFeedState(viewModel, scrollStateKey) { listState -> RenderFeed(viewModel, accountViewModel, listState, nav, routeForLastRead) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt index 09b2fb3f1..5d502ae63 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt @@ -138,6 +138,8 @@ abstract class FeedViewModel(val localFilter: FeedFilter) : ViewModel(), I val scrollToTop = _scrollToTop.asStateFlow() var scrolltoTopPending = false + private var lastFeedKey: String? = null + fun sendToTop() { if (scrolltoTopPending) return @@ -151,10 +153,6 @@ abstract class FeedViewModel(val localFilter: FeedFilter) : ViewModel(), I scrolltoTopPending = false } - fun newListFromDataSource(): ImmutableList { - return localFilter.loadTop().toImmutableList() - } - private fun refresh() { val scope = CoroutineScope(Job() + Dispatchers.Default) scope.launch { @@ -165,7 +163,8 @@ abstract class FeedViewModel(val localFilter: FeedFilter) : ViewModel(), I fun refreshSuspended() { checkNotInMainThread() - val notes = newListFromDataSource() + val notes = localFilter.loadTop().toImmutableList() + lastFeedKey = localFilter.feedKey() val oldNotesState = _feedContent.value if (oldNotesState is FeedState.Loaded) { @@ -197,11 +196,13 @@ abstract class FeedViewModel(val localFilter: FeedFilter) : ViewModel(), I if (localFilter is AdditiveFeedFilter) { if (oldNotesState is FeedState.Loaded) { val newList = localFilter.updateListWith(oldNotesState.feed.value, newItems.toSet()).toImmutableList() + lastFeedKey = localFilter.feedKey() if (!equalImmutableLists(newList, oldNotesState.feed.value)) { updateFeed(newList) } } else if (oldNotesState is FeedState.Empty) { val newList = localFilter.updateListWith(emptyList(), newItems.toSet()).toImmutableList() + lastFeedKey = localFilter.feedKey() if (newList.isNotEmpty()) { updateFeed(newList) } @@ -226,12 +227,14 @@ abstract class FeedViewModel(val localFilter: FeedFilter) : ViewModel(), I } } - fun invalidateDataAndSendToTop(ignoreIfDoing: Boolean = false) { - bundler.invalidate(ignoreIfDoing) { - // adds the time to perform the refresh into this delay - // holding off new updates in case of heavy refresh routines. - refreshSuspended() - sendToTop() + fun checkKeysInvalidateDataAndSendToTop() { + if (lastFeedKey != localFilter.feedKey()) { + bundler.invalidate(false) { + // adds the time to perform the refresh into this delay + // holding off new updates in case of heavy refresh routines. + refreshSuspended() + sendToTop() + } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/BookmarkListScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/BookmarkListScreen.kt index ef8d6064b..8bea955cc 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/BookmarkListScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/BookmarkListScreen.kt @@ -73,8 +73,18 @@ fun BookmarkListScreen(accountViewModel: AccountViewModel, nav: (String) -> Unit } HorizontalPager(pageCount = 2, state = pagerState) { page -> when (page) { - 0 -> RefresheableFeedView(privateFeedViewModel, null, accountViewModel, nav) - 1 -> RefresheableFeedView(publicFeedViewModel, null, accountViewModel, nav) + 0 -> RefresheableFeedView( + privateFeedViewModel, + null, + accountViewModel = accountViewModel, + nav = nav + ) + 1 -> RefresheableFeedView( + publicFeedViewModel, + null, + accountViewModel = accountViewModel, + nav = nav + ) } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HashtagScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HashtagScreen.kt index f3f6a2fdc..ae2e29faa 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HashtagScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HashtagScreen.kt @@ -73,7 +73,12 @@ fun HashtagScreen(tag: String?, accountViewModel: AccountViewModel, nav: (String modifier = Modifier.padding(vertical = 0.dp) ) { HashtagHeader(tag, accountViewModel) - RefresheableFeedView(feedViewModel, null, accountViewModel, nav) + RefresheableFeedView( + feedViewModel, + null, + accountViewModel = accountViewModel, + nav = nav + ) } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt index d37ec12a0..316768847 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt @@ -123,10 +123,10 @@ private fun HomePages( HorizontalPager(pageCount = 2, state = pagerState) { page -> RefresheableFeedView( viewModel = tabs[page].viewModel, - accountViewModel = accountViewModel, - nav = nav, routeForLastRead = tabs[page].routeForLastRead, - scrollStateKey = tabs[page].scrollStateKey + scrollStateKey = tabs[page].scrollStateKey, + accountViewModel = accountViewModel, + nav = nav ) } } @@ -143,16 +143,14 @@ fun WatchAccountForHomeScreen( LaunchedEffect(accountViewModel, accountState?.account?.defaultHomeFollowList) { launch(Dispatchers.IO) { NostrHomeDataSource.invalidateFilters() - homeFeedViewModel.invalidateDataAndSendToTop(true) - repliesFeedViewModel.invalidateDataAndSendToTop(true) + homeFeedViewModel.checkKeysInvalidateDataAndSendToTop() + repliesFeedViewModel.checkKeysInvalidateDataAndSendToTop() } } LaunchedEffect(followState) { launch(Dispatchers.IO) { NostrHomeDataSource.invalidateFilters() - homeFeedViewModel.invalidateData(true) - repliesFeedViewModel.invalidateData(true) } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/MainScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/MainScreen.kt index 7b3dc7da4..0c3ca2db5 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/MainScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/MainScreen.kt @@ -73,23 +73,6 @@ fun MainScreen(accountViewModel: AccountViewModel, accountStateViewModel: Accoun } } - val navBottomRow = remember(navController) { - { route: Route, selected: Boolean -> - if (!selected) { - navController.navigate(route.base) { - popUpTo(Route.Home.route) - launchSingleTop = true - } - } else { - val newRoute = route.route.replace("{scrollToTop}", "true") - navController.navigate(newRoute) { - popUpTo(Route.Home.route) - launchSingleTop = true - } - } - } - } - val followLists: FollowListViewModel = viewModel( key = accountViewModel.userProfile().pubkeyHex + "FollowListViewModel", factory = FollowListViewModel.Factory(accountViewModel.account) @@ -136,6 +119,41 @@ fun MainScreen(accountViewModel: AccountViewModel, accountStateViewModel: Accoun factory = NostrChatroomListNewFeedViewModel.Factory(accountViewModel.account) ) + val navBottomRow = remember(navController) { + { route: Route, selected: Boolean -> + if (!selected) { + navController.navigate(route.base) { + popUpTo(Route.Home.route) + launchSingleTop = true + } + } else { + // deals with scroll to top here to avoid passing as parameter + // and having to deal with all recompositions with scroll to top true + when (route.base) { + Route.Home.base -> { + homeFeedViewModel.sendToTop() + repliesFeedViewModel.sendToTop() + } + Route.Search.base -> { + searchFeedViewModel.sendToTop() + } + Route.Video.base -> { + videoFeedViewModel.sendToTop() + } + Route.Notification.base -> { + notifFeedViewModel.clear() + notifFeedViewModel.sendToTop() + } + } + + navController.navigate(route.route) { + popUpTo(route.route) + launchSingleTop = true + } + } + } + } + ModalBottomSheetLayout( sheetState = sheetState, sheetContent = { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt index e918a46eb..075cf9b0d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt @@ -102,16 +102,9 @@ fun WatchAccountForNotifications( ) { val accountState by accountViewModel.accountLiveData.observeAsState() - var firstTime by remember(accountViewModel) { mutableStateOf(true) } - LaunchedEffect(accountViewModel, accountState?.account?.defaultNotificationFollowList) { - if (firstTime) { - firstTime = false - } else { - NostrAccountDataSource.invalidateFilters() - notifFeedViewModel.clear() - notifFeedViewModel.invalidateDataAndSendToTop(true) - } + NostrAccountDataSource.invalidateFilters() + notifFeedViewModel.checkKeysInvalidateDataAndSendToTop() } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt index 613457042..be9194142 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt @@ -1130,7 +1130,13 @@ fun TabNotesNewThreads(accountViewModel: AccountViewModel, nav: (String) -> Unit Column( modifier = Modifier.padding(vertical = 0.dp) ) { - RefresheableFeedView(feedViewModel, null, accountViewModel, nav, enablePullRefresh = false) + RefresheableFeedView( + feedViewModel, + null, + enablePullRefresh = false, + accountViewModel = accountViewModel, + nav = nav + ) } } } @@ -1147,7 +1153,13 @@ fun TabNotesConversations(accountViewModel: AccountViewModel, nav: (String) -> U Column( modifier = Modifier.padding(vertical = 0.dp) ) { - RefresheableFeedView(feedViewModel, null, accountViewModel, nav, enablePullRefresh = false) + RefresheableFeedView( + feedViewModel, + null, + enablePullRefresh = false, + accountViewModel = accountViewModel, + nav = nav + ) } } } @@ -1164,7 +1176,13 @@ fun TabBookmarks(baseUser: User, accountViewModel: AccountViewModel, nav: (Strin Column( modifier = Modifier.padding(vertical = 0.dp) ) { - RefresheableFeedView(feedViewModel, null, accountViewModel, nav, enablePullRefresh = false) + RefresheableFeedView( + feedViewModel, + null, + enablePullRefresh = false, + accountViewModel = accountViewModel, + nav = nav + ) } } } @@ -1246,7 +1264,13 @@ fun TabReports(baseUser: User, accountViewModel: AccountViewModel, nav: (String) Column(Modifier.fillMaxHeight()) { Column() { - RefresheableFeedView(feedViewModel, null, accountViewModel, nav, enablePullRefresh = false) + RefresheableFeedView( + feedViewModel, + null, + enablePullRefresh = false, + accountViewModel = accountViewModel, + nav = nav + ) } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt index 7ac61cc93..03be1d952 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt @@ -138,7 +138,13 @@ fun SearchScreen( modifier = Modifier.padding(vertical = 0.dp) ) { SearchBar(searchBarViewModel, accountViewModel, nav) - RefresheableFeedView(searchFeedViewModel, null, accountViewModel, nav, ScrollStateKeys.GLOBAL_SCREEN) + RefresheableFeedView( + searchFeedViewModel, + null, + scrollStateKey = ScrollStateKeys.GLOBAL_SCREEN, + accountViewModel = accountViewModel, + nav = nav + ) } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/VideoScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/VideoScreen.kt index 030c62a22..66a3f41d7 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/VideoScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/VideoScreen.kt @@ -127,7 +127,12 @@ fun VideoScreen( Column( modifier = Modifier.padding(vertical = 0.dp) ) { - SaveableFeedState(videoFeedView, accountViewModel, nav, ScrollStateKeys.VIDEO_SCREEN) + SaveableFeedState( + videoFeedView = videoFeedView, + accountViewModel = accountViewModel, + nav = nav, + scrollStateKey = ScrollStateKeys.VIDEO_SCREEN + ) } } } @@ -135,17 +140,10 @@ fun VideoScreen( @Composable fun WatchAccountForVideoScreen(videoFeedView: NostrVideoFeedViewModel, accountViewModel: AccountViewModel) { val accountState by accountViewModel.accountLiveData.observeAsState() - val account = remember(accountState) { accountState?.account } ?: return - var firstTime by remember(accountViewModel) { mutableStateOf(true) } - - LaunchedEffect(accountViewModel, account.defaultStoriesFollowList) { - if (firstTime) { - firstTime = false - } else { - NostrVideoDataSource.resetFilters() - videoFeedView.invalidateDataAndSendToTop(true) - } + LaunchedEffect(accountViewModel, accountState?.account?.defaultStoriesFollowList) { + NostrVideoDataSource.resetFilters() + videoFeedView.checkKeysInvalidateDataAndSendToTop() } } @@ -155,7 +153,6 @@ private fun SaveableFeedState( videoFeedView: NostrVideoFeedViewModel, accountViewModel: AccountViewModel, nav: (String) -> Unit, - routeForLastRead: String?, scrollStateKey: String? = null ) { val pagerState = if (scrollStateKey != null) {