From c1f14cea2e8c5594e3281b40fd60fc4451317384 Mon Sep 17 00:00:00 2001 From: KotlinGeekDev Date: Thu, 27 Mar 2025 18:47:57 +0100 Subject: [PATCH] Use a general type to represent lists, NostrList. Make FollowSet a subclass. Rename ListType to ListVisibility. Refactor accordingly. --- .../amethyst/ui/dal/FollowSetFeedFilter.kt | 13 ++++++++- .../loggedIn/lists/CustomListsScreen.kt | 16 +++++------ .../ui/screen/loggedIn/lists/FollowSet.kt | 8 +++--- .../lists/{ListType.kt => ListVisibility.kt} | 2 +- .../ui/screen/loggedIn/lists/NostrList.kt | 26 +++++++++++++++++ .../profile/header/FollowSetsActionMenu.kt | 28 +++++++++---------- 6 files changed, 65 insertions(+), 28 deletions(-) rename amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/{ListType.kt => ListVisibility.kt} (97%) create mode 100644 amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/NostrList.kt diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FollowSetFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FollowSetFeedFilter.kt index 3453a161f..b0b3e2fec 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FollowSetFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FollowSetFeedFilter.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.dal import android.util.Log import com.vitorpamplona.amethyst.model.Account +import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.FollowSet import kotlinx.coroutines.launch import kotlin.coroutines.cancellation.CancellationException @@ -29,6 +30,8 @@ import kotlin.coroutines.cancellation.CancellationException class FollowSetFeedFilter( val account: Account, ) : FeedFilter() { + private val followSetEventPairs: MutableMap = mutableMapOf() + override fun feedKey(): String = account.userProfile().pubkeyHex override fun feed(): List { @@ -44,6 +47,14 @@ class FollowSetFeedFilter( } } } - return userFollowSets.map { account.mapNoteToFollowSet(it) } + updateFollowSetEventPairs(userFollowSets) + return followSetEventPairs.values.toList() + } + + private fun updateFollowSetEventPairs(notes: Set) { + notes.forEach { note -> + val noteAndSetPair = note to account.mapNoteToFollowSet(note) + followSetEventPairs.putIfAbsent(noteAndSetPair.first, noteAndSetPair.second) + } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/CustomListsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/CustomListsScreen.kt index 581c895ec..8d379f295 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/CustomListsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/CustomListsScreen.kt @@ -226,12 +226,12 @@ fun CustomListItem( ) } - followSet.type.let { + followSet.visibility.let { val text by derivedStateOf { when (it) { - ListType.Public -> "Public" - ListType.Private -> "Private" - ListType.Mixed -> "Mixed" + ListVisibility.Public -> "Public" + ListVisibility.Private -> "Private" + ListVisibility.Mixed -> "Mixed" } } Column( @@ -243,9 +243,9 @@ fun CustomListItem( painter = painterResource( when (it) { - ListType.Public -> R.drawable.ic_public - ListType.Private -> R.drawable.incognito - ListType.Mixed -> R.drawable.format_list_bulleted_type + ListVisibility.Public -> R.drawable.ic_public + ListVisibility.Private -> R.drawable.incognito + ListVisibility.Mixed -> R.drawable.format_list_bulleted_type }, ), contentDescription = "Icon for $text List", @@ -261,7 +261,7 @@ fun CustomListItem( private fun ListItemPreview() { val sampleFollowSet = FollowSet( - type = ListType.Mixed, + visibility = ListVisibility.Mixed, title = "Sample List Title", description = "Sample List Description", emptySet(), diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/FollowSet.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/FollowSet.kt index 164c8acaf..253424109 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/FollowSet.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/FollowSet.kt @@ -26,11 +26,11 @@ import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent @Stable data class FollowSet( - val type: ListType, + val visibility: ListVisibility, val title: String, val description: String?, val profileList: Set, -) { +) : NostrList(listVisibility = visibility, content = profileList) { companion object { fun mapEventToSet( event: PeopleListEvent, @@ -44,14 +44,14 @@ data class FollowSet( event.privateTaggedUsers(signer) { userList -> privateFollows.addAll(userList) } return if (publicFollows.isEmpty() && privateFollows.isNotEmpty()) { FollowSet( - type = ListType.Private, + visibility = ListVisibility.Private, title = listTitle, description = listDescription, profileList = privateFollows.toSet(), ) } else if (publicFollows.isNotEmpty() && privateFollows.isEmpty()) { FollowSet( - type = ListType.Public, + visibility = ListVisibility.Public, title = listTitle, description = listDescription, profileList = publicFollows.toSet(), diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/ListType.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/ListVisibility.kt similarity index 97% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/ListType.kt rename to amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/ListVisibility.kt index 32e62043d..ea2524f90 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/ListType.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/ListVisibility.kt @@ -20,7 +20,7 @@ */ package com.vitorpamplona.amethyst.ui.screen.loggedIn.lists -enum class ListType { +enum class ListVisibility { Public, Private, Mixed, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/NostrList.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/NostrList.kt new file mode 100644 index 000000000..25c079441 --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/NostrList.kt @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * 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.lists + +sealed class NostrList( + val listVisibility: ListVisibility, + val content: Collection, +) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/FollowSetsActionMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/FollowSetsActionMenu.kt index 1282a0f77..150fd8755 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/FollowSetsActionMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/FollowSetsActionMenu.kt @@ -62,7 +62,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.window.PopupProperties import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.FollowSet -import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.ListType +import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.ListVisibility import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer @@ -133,7 +133,7 @@ fun FollowSetsActionMenu( FollowSetItem( modifier = Modifier.fillMaxWidth(), listHeader = list.title, - listType = list.type, + listVisibility = list.visibility, isUserInList = list.profileList.contains(userHex), onRemoveUser = { removeUser(index) @@ -174,11 +174,11 @@ private fun DropDownMenuHeader( fun generateFollowLists(): List = List(10) { index: Int -> FollowSet( - type = + visibility = when { - index % 2 == 0 -> ListType.Private - index in listOf(3, 7, 9) -> ListType.Mixed - else -> ListType.Public + index % 2 == 0 -> ListVisibility.Private + index in listOf(3, 7, 9) -> ListVisibility.Mixed + else -> ListVisibility.Public }, title = "List No $index", description = null, @@ -190,7 +190,7 @@ fun generateFollowLists(): List = fun FollowSetItem( modifier: Modifier = Modifier, listHeader: String, - listType: ListType, + listVisibility: ListVisibility, isUserInList: Boolean, onAddUser: () -> Unit, onRemoveUser: () -> Unit, @@ -281,12 +281,12 @@ fun FollowSetItem( } } - listType.let { + listVisibility.let { val text by derivedStateOf { when (it) { - ListType.Public -> "Public" - ListType.Private -> "Private" - ListType.Mixed -> "Mixed" + ListVisibility.Public -> "Public" + ListVisibility.Private -> "Private" + ListVisibility.Mixed -> "Mixed" } } @@ -298,9 +298,9 @@ fun FollowSetItem( painter = painterResource( when (it) { - ListType.Public -> R.drawable.ic_public - ListType.Private -> R.drawable.incognito - ListType.Mixed -> R.drawable.format_list_bulleted_type + ListVisibility.Public -> R.drawable.ic_public + ListVisibility.Private -> R.drawable.incognito + ListVisibility.Mixed -> R.drawable.format_list_bulleted_type }, ), contentDescription = "Icon for $text List",