From 65579ffc18a16a2ea191126dae3dffd0e9eb6421 Mon Sep 17 00:00:00 2001 From: nrobi144 Date: Fri, 24 Jul 2026 11:55:36 +0300 Subject: [PATCH] feat(desktop): log moderation publishes (report/mute) + surface zero-relay sends Report/mute actions published silently with no feedback. Add a DesktopModeration logger: every report/mute logs kind+id+relay-count on publish, WARNs when there are 0 connected relays (so a dropped publish is visible instead of silent), and signing/publish failures are caught + logged (were swallowed by the launching scope). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../amethyst/desktop/model/DesktopIAccount.kt | 64 ++++++++++++++----- 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/model/DesktopIAccount.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/model/DesktopIAccount.kt index b49f4d1f7a..5c83476af8 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/model/DesktopIAccount.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/model/DesktopIAccount.kt @@ -73,6 +73,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.withPermit import java.util.concurrent.ConcurrentHashMap +import java.util.logging.Logger /** * Desktop implementation of IAccount. @@ -407,17 +408,22 @@ class DesktopIAccount( add: Boolean, ) { if (!isWriteable()) return - val current = hiddenUsersState.currentMuteList() - val event = - when { - !add -> if (current != null) MuteListEvent.remove(current, tag, signer) else return - current == null -> MuteListEvent.create(tag, isPrivate, signer) - else -> MuteListEvent.add(current, tag, isPrivate, signer) - } - // Optimistic local apply so enforcement + the management screens update - // immediately, then fan out to relays. - localCache.justConsumeMyOwnEvent(event) - relayManager.broadcastToAll(event) + try { + val current = hiddenUsersState.currentMuteList() + val event = + when { + !add -> if (current != null) MuteListEvent.remove(current, tag, signer) else return + current == null -> MuteListEvent.create(tag, isPrivate, signer) + else -> MuteListEvent.add(current, tag, isPrivate, signer) + } + // Optimistic local apply so enforcement + the management screens update + // immediately, then fan out to relays. + localCache.justConsumeMyOwnEvent(event) + publishModeration(event, if (add) "mute+" else "mute-") + } catch (e: Exception) { + moderationLog.warning("[Moderation] mute list update failed: ${e.message}") + throw e + } } /** Publish a NIP-56 (kind 1984) report about a note. */ @@ -437,8 +443,13 @@ class DesktopIAccount( comment: String = "", ) { if (!isWriteable()) return - val signed = signer.sign(ReportEvent.build(reportedEvent, type, comment)) - relayManager.broadcastToAll(signed) + try { + val signed = signer.sign(ReportEvent.build(reportedEvent, type, comment)) + publishModeration(signed, "report(${type.code})") + } catch (e: Exception) { + moderationLog.warning("[Moderation] report failed: ${e.message}") + throw e + } } /** Publish a NIP-56 (kind 1984) report about a user. */ @@ -448,8 +459,30 @@ class DesktopIAccount( comment: String = "", ) { if (!isWriteable()) return - val signed = signer.sign(ReportEvent.build(userPubKeyHex, type, comment)) - relayManager.broadcastToAll(signed) + try { + val signed = signer.sign(ReportEvent.build(userPubKeyHex, type, comment)) + publishModeration(signed, "report-user(${type.code})") + } catch (e: Exception) { + moderationLog.warning("[Moderation] user report failed: ${e.message}") + throw e + } + } + + /** + * Broadcast a moderation event and log the outcome — including the relay + * count, so a publish to zero connected relays is visible rather than silent. + */ + private fun publishModeration( + event: Event, + action: String, + ) { + val relayCount = relayManager.connectedRelays.value.size + relayManager.broadcastToAll(event) + if (relayCount == 0) { + moderationLog.warning("[Moderation] $action kind=${event.kind} id=${event.id.take(8)} → 0 connected relays (not delivered)") + } else { + moderationLog.info("[Moderation] $action kind=${event.kind} id=${event.id.take(8)} → $relayCount relays") + } } private fun addEventToChatroom( @@ -466,5 +499,6 @@ class DesktopIAccount( companion object { const val CLIENT_TAG_NAME = "Amethyst" + private val moderationLog: Logger = Logger.getLogger("DesktopModeration") } }