feat: mark conversation participants with an 'In this chat' chip in mention suggestions

Renders a small chip on suggestion rows whose pubkey is in the
suggestion state's priorityPubkeys set, unless the caller supplies
its own trailingContent. Priority keys only reorder and label the
users that already matched the search — they never inject results.
This commit is contained in:
Claude
2026-06-10 17:40:52 +00:00
parent b79ab1214c
commit 6f79779885
2 changed files with 33 additions and 1 deletions
@@ -25,13 +25,16 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -43,6 +46,7 @@ import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.model.nip05DnsIdentifiers.Nip05State
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.User
@@ -52,6 +56,7 @@ import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture
import com.vitorpamplona.amethyst.ui.note.ObserveAndRenderNIP05VerifiedSymbol
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.Font14SP
import com.vitorpamplona.amethyst.ui.theme.NIP05IconSize
@@ -116,13 +121,23 @@ fun WatchResponses(
val suggestions by userSuggestions.results.collectAsStateWithLifecycle(emptyList())
if (suggestions.isNotEmpty()) {
// Snapshot once per result list, not per row.
val priority = remember(suggestions) { userSuggestions.priorityPubkeys() }
LazyColumn(
contentPadding = PaddingValues(top = 10.dp),
modifier = modifier,
state = listState,
) {
itemsIndexed(suggestions, key = { _, item -> item.pubkeyHex }) { _, item ->
UserLine(item, accountViewModel, trailingContent) { onSelect(item) }
val trailing =
trailingContent
?: if (item.pubkeyHex in priority) {
{ InThisChatChip() }
} else {
null
}
UserLine(item, accountViewModel, trailing) { onSelect(item) }
HorizontalDivider(
thickness = DividerThickness,
)
@@ -133,6 +148,22 @@ fun WatchResponses(
}
}
@Composable
private fun InThisChatChip() {
Surface(
shape = RoundedCornerShape(12.dp),
color = MaterialTheme.colorScheme.surfaceVariant,
) {
Text(
text = stringRes(R.string.user_suggestion_in_this_chat),
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 1,
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
)
}
}
@Composable
fun UserLine(
baseUser: User,
+1
View File
@@ -214,6 +214,7 @@
<string name="voice_anonymize_description">Alters your voice pitch. Note: basic pitch changes can potentially be reversed by determined listeners.</string>
<string name="user_does_not_have_a_lightning_address_setup_to_receive_sats">User does not have a lightning address set up to receive sats</string>
<string name="reply_here">"reply here… "</string>
<string name="user_suggestion_in_this_chat">In this chat</string>
<string name="copies_the_note_id_to_the_clipboard_for_sharing">Copies the Note ID to the clipboard for sharing in Nostr</string>
<string name="copy_channel_id_note_to_the_clipboard">Copy Channel ID (Note) to the Clipboard</string>
<string name="edits_the_channel_metadata">Edits the Channel Metadata</string>