mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-05 19:28:25 +00:00
feat(desktop): WoT badges on search-result person cards
Extends the WoT trust indicator to the Search screen's person-picker results, matching the badges already shown on note-card avatars. - `UserSearchCard` (commons) gains an optional `badge: @Composable (BoxScope.() -> Unit)? = null` param, forwarded to its embedded `UserAvatar` (which has the slot from the WoT PR). Default null → no visual change for callers that don't opt in; Android search screens continue to render as before. - `SearchResultsList` (desktopApp) inlines the score-lookup gates in a small `wotBadgeFor(pubkey)` helper and passes the badge lambda at both person-result call sites (main list + expandable overflow). Same visibility rules as the note-card avatar badges: score > 0, past the 2 s startup readiness gate, and pubkey not in `LocalSpamExemptKeys` (self / already-followed).
This commit is contained in:
+7
@@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.commons.ui.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
@@ -46,12 +47,17 @@ import org.jetbrains.compose.resources.stringResource
|
||||
/**
|
||||
* A card displaying user search result with avatar, name, and nip05/pubkey.
|
||||
* Shared between Android and Desktop search screens.
|
||||
*
|
||||
* @param badge Optional overlay drawn on top of the avatar (bottom-right
|
||||
* by convention). Used by Desktop for the WoT trust-score chip; Android
|
||||
* call sites leave it null. Forwarded to [UserAvatar].
|
||||
*/
|
||||
@Composable
|
||||
fun UserSearchCard(
|
||||
user: User,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
badge: @Composable (BoxScope.() -> Unit)? = null,
|
||||
) {
|
||||
Card(
|
||||
modifier =
|
||||
@@ -73,6 +79,7 @@ fun UserSearchCard(
|
||||
pictureUrl = user.profilePicture(),
|
||||
size = 40.dp,
|
||||
contentDescription = stringResource(Res.string.accessibility_user_avatar),
|
||||
badge = badge,
|
||||
)
|
||||
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
|
||||
+34
@@ -55,12 +55,16 @@ import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbol
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
import com.vitorpamplona.amethyst.commons.moderation.LocalSpamExemptKeys
|
||||
import com.vitorpamplona.amethyst.commons.search.AdvancedSearchBarState
|
||||
import com.vitorpamplona.amethyst.commons.search.SearchSortOrder
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.UserSearchCard
|
||||
import com.vitorpamplona.amethyst.commons.wot.LocalWoTReady
|
||||
import com.vitorpamplona.amethyst.commons.wot.LocalWoTService
|
||||
import com.vitorpamplona.amethyst.desktop.cache.DesktopLocalCache
|
||||
import com.vitorpamplona.amethyst.desktop.ui.note.NoteCard
|
||||
import com.vitorpamplona.amethyst.desktop.ui.note.SpamCheckedNoteRender
|
||||
import com.vitorpamplona.amethyst.desktop.ui.note.WoTBadge
|
||||
import com.vitorpamplona.amethyst.desktop.ui.rememberDisplayData
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
|
||||
@@ -116,6 +120,7 @@ fun SearchResultsList(
|
||||
UserSearchCard(
|
||||
user = user,
|
||||
onClick = { onNavigateToProfile(user.pubkeyHex) },
|
||||
badge = wotBadgeFor(user.pubkeyHex),
|
||||
)
|
||||
}
|
||||
if (people.size > 5) {
|
||||
@@ -126,6 +131,7 @@ fun SearchResultsList(
|
||||
UserSearchCard(
|
||||
user = user,
|
||||
onClick = { onNavigateToProfile(user.pubkeyHex) },
|
||||
badge = wotBadgeFor(user.pubkeyHex),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -286,6 +292,34 @@ fun SearchResultsList(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a WoT-badge lambda for the given pubkey, or null when the
|
||||
* badge should be hidden. Same gates as [WoTBadgedAvatar]:
|
||||
* - WoT service is provided
|
||||
* - initial batch fetch has finished (or 2 s startup timeout fired)
|
||||
* - the pubkey is not exempt (self or already followed)
|
||||
* - the score is > 0
|
||||
* Inlined here (rather than wrapped in a new composable) because it's
|
||||
* only used at the two SearchResultsList person-result call sites.
|
||||
*/
|
||||
@Composable
|
||||
private fun wotBadgeFor(userHex: String): (@Composable androidx.compose.foundation.layout.BoxScope.() -> Unit)? {
|
||||
val service = LocalWoTService.current
|
||||
val ready = LocalWoTReady.current
|
||||
val exempt = LocalSpamExemptKeys.current
|
||||
val score =
|
||||
if (service != null && ready && userHex !in exempt) {
|
||||
service.scores[userHex] ?: 0
|
||||
} else {
|
||||
0
|
||||
}
|
||||
return if (score > 0) {
|
||||
{ WoTBadge(count = score, modifier = Modifier.align(Alignment.BottomEnd)) }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SortableHeader(
|
||||
title: String,
|
||||
|
||||
Reference in New Issue
Block a user