diff --git a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ThreadDualAxisChartAssemblerTest.kt b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ThreadDualAxisChartAssemblerTest.kt index dea5d5d39..347c5f035 100644 --- a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ThreadDualAxisChartAssemblerTest.kt +++ b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ThreadDualAxisChartAssemblerTest.kt @@ -22,13 +22,13 @@ package com.vitorpamplona.amethyst import androidx.test.ext.junit.runners.AndroidJUnit4 import com.fasterxml.jackson.module.kotlin.readValue +import com.vitorpamplona.amethyst.commons.viewmodels.thread.ThreadFeedFilter import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.AccountSettings import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.service.location.LocationState import com.vitorpamplona.amethyst.service.okhttp.OkHttpWebSocket import com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc.NWCPaymentFilterAssembler -import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.dal.ThreadFeedFilter import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair import com.vitorpamplona.quartz.nip01Core.crypto.verify @@ -174,7 +174,7 @@ class ThreadDualAxisChartAssemblerTest { null, ) - val filter = ThreadFeedFilter(account, naddr.toTag()) + val filter = ThreadFeedFilter(account, naddr.toTag(), LocalCache) val calculatedFeed = filter.feed() val expectedOrder = diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 5b24119a6..e2171228c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -1662,7 +1662,7 @@ class Account( fun isHidden(userHex: String): Boolean = hiddenUsers.flow.value.isUserHidden(userHex) - fun followingKeySet(): Set = kind3FollowList.flow.value.authors + override fun followingKeySet(): Set = kind3FollowList.flow.value.authors fun isAcceptable(user: User): Boolean { if (userProfile().pubkeyHex == user.pubkeyHex) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/dal/ThreadFeedViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/dal/ThreadFeedViewModel.kt index 5c408f2f1..52155155f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/dal/ThreadFeedViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/dal/ThreadFeedViewModel.kt @@ -22,13 +22,14 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.dal import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import com.vitorpamplona.amethyst.commons.viewmodels.thread.ThreadFeedFilter import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache class ThreadFeedViewModel( account: Account, noteId: String, -) : com.vitorpamplona.amethyst.commons.viewmodels.thread.LevelFeedViewModel(ThreadFeedFilter(account, noteId), LocalCache) { +) : com.vitorpamplona.amethyst.commons.viewmodels.thread.LevelFeedViewModel(ThreadFeedFilter(account, noteId, LocalCache), LocalCache) { class Factory( val account: Account, val noteId: String, diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/IAccount.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/IAccount.kt index 2b2a4510e..7460b925a 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/IAccount.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/IAccount.kt @@ -81,4 +81,7 @@ interface IAccount { val hiddenWordsCase: List val hiddenUsersHashCodes: Set val spammersHashCodes: Set + + /** Set of followed user pubkeys (for feed ordering/highlighting) */ + fun followingKeySet(): Set } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/dal/ThreadFeedFilter.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/viewmodels/thread/ThreadFeedFilter.kt similarity index 73% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/dal/ThreadFeedFilter.kt rename to commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/viewmodels/thread/ThreadFeedFilter.kt index ec0fd2ed7..4f96bc0e6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/dal/ThreadFeedFilter.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/viewmodels/thread/ThreadFeedFilter.kt @@ -18,35 +18,46 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.dal +package com.vitorpamplona.amethyst.commons.viewmodels.thread import androidx.compose.runtime.Immutable +import com.vitorpamplona.amethyst.commons.model.IAccount import com.vitorpamplona.amethyst.commons.model.LevelSignature +import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.ThreadAssembler import com.vitorpamplona.amethyst.commons.model.ThreadLevelCalculator -import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.model.LocalCache -import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.ui.dal.FeedFilter +import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider +import com.vitorpamplona.amethyst.commons.ui.feeds.FeedFilter import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.collections.immutable.toImmutableSet +/** + * Filter for assembling and sorting thread feeds. + * + * This filter uses ThreadAssembler to find all notes in a thread and + * ThreadLevelCalculator to sort them by reply level and relevance. + * + * @param account The current user's account (provides user profile and following set) + * @param noteId The root note ID of the thread to display + * @param cacheProvider The cache provider for accessing notes + */ @Immutable class ThreadFeedFilter( - val account: Account, + val account: IAccount, private val noteId: String, + private val cacheProvider: ICacheProvider, ) : FeedFilter() { override fun feedKey(): String = noteId override fun feed(): List { val cachedSignatures: MutableMap = mutableMapOf() - val followingKeySet = account.kind3FollowList.flow.value.authors - val eventsToWatch = ThreadAssembler(LocalCache).findThreadFor(noteId) ?: return emptyList() + val followingKeySet = account.followingKeySet() + val eventsToWatch = ThreadAssembler(cacheProvider).findThreadFor(noteId) ?: return emptyList() // Filter out drafts made by other accounts on device val filteredEvents = eventsToWatch.allNotes - .filter { !it.isDraft() || (it.author?.pubkeyHex == account.userProfile().pubkeyHex) } + .filter { !it.isDraft() || (it.author?.pubkeyHex == account.pubKey) } .toImmutableSet() val filteredThreadInfo = ThreadAssembler.ThreadInfo(eventsToWatch.root, filteredEvents)