From bde562b4a603dcdb13b4444cf28e3d7a12704ab3 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 29 Jul 2026 18:11:59 +0000 Subject: [PATCH] chore(concord): remove now-unused facepile helpers Delete ConcordAuthorFacepile and the ConcordChannel/RelayGroupChannel recentAuthorHexes extensions, orphaned after the channel rows dropped the recent-posters facepile. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_017x22okBh6HbiCrJN3zf5xn --- .../publicChannels/concord/ConcordFacepile.kt | 60 ------------------- .../publicChannels/concord/ConcordUnread.kt | 20 ------- .../relayGroup/RelayGroupUnread.kt | 24 -------- 3 files changed, 104 deletions(-) delete mode 100644 amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordFacepile.kt diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordFacepile.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordFacepile.kt deleted file mode 100644 index 53042dfa2e..0000000000 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordFacepile.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2025 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.chats.publicChannels.concord - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Row -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture -import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.nip01Core.core.HexKey - -/** - * A horizontal strip of the recent posters in a channel — the "who's here" cue that makes a busy - * channel feel alive. Each poster is drawn with the app's standard profile avatar - * ([ClickableUserPicture]), so it carries the same following badge (top-right) and trust-score tag - * (bottom-centre) shown everywhere else a user appears, instead of a bare cropped image. Laid out - * with a small gap rather than an overlapping stack so those badges stay readable; the newest poster - * is leftmost. Renders nothing for an empty [authorHexes], so callers can drop it in unconditionally. - */ -@Composable -fun ConcordAuthorFacepile( - authorHexes: List, - accountViewModel: AccountViewModel, - modifier: Modifier = Modifier, - avatarSize: Dp = 24.dp, - maxShown: Int = 4, -) { - if (authorHexes.isEmpty()) return - val shown = authorHexes.take(maxShown) - Row(modifier, horizontalArrangement = Arrangement.spacedBy(2.dp)) { - shown.forEach { hex -> - ClickableUserPicture( - baseUserHex = hex, - size = avatarSize, - accountViewModel = accountViewModel, - ) - } - } -} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordUnread.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordUnread.kt index 5f5b6124ef..bf94968907 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordUnread.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordUnread.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.quartz.concord.cord03Channels.ConcordChannelId -import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip22Comments.CommentEvent import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow @@ -135,22 +134,3 @@ private fun ConcordChannel.newMessagesSince( notes.count { _, note -> (note.createdAt() ?: 0L) > sinceSecs && isConcordTimelineMessage(note, account) } - -/** - * The pubkeys of the [limit] most-recent distinct posters in this channel, newest first — the - * facepile shown on a channel row. One O(notes) pass keeps each author's latest post time, so a - * chatty author counts once (at their newest message) rather than crowding out quieter voices. - */ -fun ConcordChannel.recentAuthorHexes(limit: Int): List { - val latestByAuthor = HashMap() - for (note in notes.values()) { - val author = note.author?.pubkeyHex ?: continue - val at = note.createdAt() ?: continue - val prev = latestByAuthor[author] - if (prev == null || at > prev) latestByAuthor[author] = at - } - return latestByAuthor.entries - .sortedByDescending { it.value } - .take(limit) - .map { it.key } -} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupUnread.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupUnread.kt index 11eae20dea..666dd002b0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupUnread.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupUnread.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.dal.sortedByDefaultFeedOrder import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.isMinichatReply -import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer import com.vitorpamplona.quartz.nip29RelayGroups.GroupId @@ -112,29 +111,6 @@ fun RelayGroupChannel.newestTimelineNote(account: Account): Note? = .sortedByDefaultFeedOrder() .firstOrNull() -/** - * The pubkeys of the [limit] most-recent distinct posters in this group, newest first — the facepile - * shown on a channel row. One O(notes) pass keeps each author's latest post time, so a chatty author - * counts once (at their newest message) rather than crowding out quieter voices. - */ -fun RelayGroupChannel.recentAuthorHexes( - account: Account, - limit: Int, -): List { - val latestByAuthor = HashMap() - for (note in notes.values()) { - if (!isRelayGroupTimelineMessage(note, account)) continue - val author = note.author?.pubkeyHex ?: continue - val at = note.createdAt() ?: continue - val prev = latestByAuthor[author] - if (prev == null || at > prev) latestByAuthor[author] = at - } - return latestByAuthor.entries - .sortedByDescending { it.value } - .take(limit) - .map { it.key } -} - /** Whether this group's message store holds any acceptable timeline message created after [sinceSecs]. */ private fun RelayGroupChannel.hasChatNewerThan( account: Account,