fix: show emoji-list action (not bookmark) for kind 30030 notes

Three-dots menu on an EmojiPackEvent now offers Add/Remove from my emoji
list (kind 10030) and navigates to EmojiPackSelection. The regular
Manage bookmarks row is hidden for emoji packs so they can't end up in
the bookmark list by mistake. Closes #2426.
This commit is contained in:
Claude
2026-04-20 17:58:33 +00:00
parent 2c6b8596ec
commit 8444b943f7
@@ -30,6 +30,7 @@ import androidx.compose.material.icons.outlined.CellTower
import androidx.compose.material.icons.outlined.ContentCopy import androidx.compose.material.icons.outlined.ContentCopy
import androidx.compose.material.icons.outlined.Delete import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.Edit import androidx.compose.material.icons.outlined.Edit
import androidx.compose.material.icons.outlined.EmojiEmotions
import androidx.compose.material.icons.outlined.Lock import androidx.compose.material.icons.outlined.Lock
import androidx.compose.material.icons.outlined.LockOpen import androidx.compose.material.icons.outlined.LockOpen
import androidx.compose.material.icons.outlined.PersonAdd import androidx.compose.material.icons.outlined.PersonAdd
@@ -69,8 +70,10 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.report.ReportNoteDialog import com.vitorpamplona.amethyst.ui.screen.loggedIn.report.ReportNoteDialog
import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.Size24Modifier import com.vitorpamplona.amethyst.ui.theme.Size24Modifier
import com.vitorpamplona.quartz.nip01Core.tags.aTag.isTaggedAddressableNote
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
import com.vitorpamplona.quartz.nip30CustomEmoji.pack.EmojiPackEvent
import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
@@ -114,6 +117,7 @@ data class DropDownParams(
val isLoggedUser: Boolean, val isLoggedUser: Boolean,
val isSensitive: Boolean, val isSensitive: Boolean,
val showSensitiveContent: Boolean?, val showSensitiveContent: Boolean?,
val isEmojiPackInMyList: Boolean = false,
) )
@Composable @Composable
@@ -284,14 +288,29 @@ fun NoteDropDownMenu(
} }
} }
} }
val noteBookmarkType = if (note.event is LongTextNoteEvent) stringRes(R.string.article) else stringRes(R.string.post) // Emoji packs belong in the user's emoji list (kind 10030), not the bookmark list.
M3ActionRow(icon = Icons.Outlined.BookmarkAdd, text = stringRes(R.string.manage_bookmark_label, noteBookmarkType)) { if (note.event is EmojiPackEvent) {
if (note.event is LongTextNoteEvent) { val emojiText =
nav.nav(Route.ArticleBookmarkManagement((note as AddressableNote).address)) if (state.isEmojiPackInMyList) {
} else { stringRes(R.string.remove_from_emoji_list)
nav.nav(Route.PostBookmarkManagement(note.idHex)) } else {
stringRes(R.string.add_to_emoji_list)
}
M3ActionRow(icon = Icons.Outlined.EmojiEmotions, text = emojiText) {
val address = (note as AddressableNote).address
nav.nav(Route.EmojiPackSelection(kind = EmojiPackEvent.KIND, pubKeyHex = address.pubKeyHex, dTag = address.dTag))
onDismiss()
}
} else {
val noteBookmarkType = if (note.event is LongTextNoteEvent) stringRes(R.string.article) else stringRes(R.string.post)
M3ActionRow(icon = Icons.Outlined.BookmarkAdd, text = stringRes(R.string.manage_bookmark_label, noteBookmarkType)) {
if (note.event is LongTextNoteEvent) {
nav.nav(Route.ArticleBookmarkManagement((note as AddressableNote).address))
} else {
nav.nav(Route.PostBookmarkManagement(note.idHex))
}
onDismiss()
} }
onDismiss()
} }
if (state.isPrivateBookmarkNote) { if (state.isPrivateBookmarkNote) {
M3ActionRow(icon = Icons.Outlined.LockOpen, text = stringRes(R.string.remove_from_private_bookmarks)) { M3ActionRow(icon = Icons.Outlined.LockOpen, text = stringRes(R.string.remove_from_private_bookmarks)) {
@@ -345,12 +364,20 @@ fun observeBookmarksFollowsAndAccount(
note: Note, note: Note,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
) = remember(note) { ) = remember(note) {
val noteIdForEmoji = if (note.event is EmojiPackEvent) note.idHex else null
combine( combine(
accountViewModel.account.kind3FollowList.flow, accountViewModel.account.kind3FollowList.flow,
accountViewModel.account.bookmarkState.bookmarks, accountViewModel.account.bookmarkState.bookmarks,
accountViewModel.account.pinState.pinnedEventIdSet, accountViewModel.account.pinState.pinnedEventIdSet,
accountViewModel.showSensitiveContent(), accountViewModel.showSensitiveContent(),
) { follows, bookmarks, pinnedIds, showSensitiveContent -> accountViewModel.account.emoji.getEmojiPackSelectionFlow(),
) { follows, bookmarks, pinnedIds, showSensitiveContent, emojiSelectionState ->
val isEmojiPackInMyList =
if (noteIdForEmoji != null) {
emojiSelectionState.note.event?.isTaggedAddressableNote(noteIdForEmoji) == true
} else {
false
}
DropDownParams( DropDownParams(
isFollowingAuthor = note.author?.pubkeyHex in follows.authors, isFollowingAuthor = note.author?.pubkeyHex in follows.authors,
isPrivateBookmarkNote = note in bookmarks.private, isPrivateBookmarkNote = note in bookmarks.private,
@@ -359,6 +386,7 @@ fun observeBookmarksFollowsAndAccount(
isLoggedUser = accountViewModel.isLoggedUser(note.author), isLoggedUser = accountViewModel.isLoggedUser(note.author),
isSensitive = note.event?.isSensitiveOrNSFW() ?: false, isSensitive = note.event?.isSensitiveOrNSFW() ?: false,
showSensitiveContent = showSensitiveContent, showSensitiveContent = showSensitiveContent,
isEmojiPackInMyList = isEmojiPackInMyList,
) )
}.onStart { }.onStart {
emit( emit(
@@ -370,6 +398,12 @@ fun observeBookmarksFollowsAndAccount(
isLoggedUser = accountViewModel.isLoggedUser(note.author), isLoggedUser = accountViewModel.isLoggedUser(note.author),
isSensitive = note.event?.isSensitiveOrNSFW() ?: false, isSensitive = note.event?.isSensitiveOrNSFW() ?: false,
showSensitiveContent = accountViewModel.showSensitiveContent().value, showSensitiveContent = accountViewModel.showSensitiveContent().value,
isEmojiPackInMyList =
noteIdForEmoji?.let {
accountViewModel.account.emoji
.getEmojiPackSelection()
?.isTaggedAddressableNote(it) == true
} ?: false,
), ),
) )
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)