diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index ff8332b86c..ee59b7ef36 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -158,7 +158,6 @@ import com.vitorpamplona.amethyst.service.relayClient.chatDelivery.ChatDeliveryT import com.vitorpamplona.amethyst.service.relayClient.notifyCommand.model.NotifyRequestsCache import com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc.NWCPaymentFilterAssembler import com.vitorpamplona.amethyst.service.uploads.FileHeader -import com.vitorpamplona.amethyst.ui.actions.LocalCacheDao import com.vitorpamplona.amethyst.ui.actions.NewMessageTagger import com.vitorpamplona.amethyst.ui.screen.loggedIn.EventProcessor import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.concord.concordChannelLastReadRoute @@ -2432,7 +2431,7 @@ class Account( // quick reply is notified (`p`) and their reference resolves. The reply-parent author is // already tagged by each builder below, so drop it from the body mentions to avoid a // duplicate `p`. - val tagger = NewMessageTagger(text, emptyList(), emptyList(), LocalCacheDao) + val tagger = NewMessageTagger(text) tagger.run() val mentions = tagger.pTags?.mapNotNull { it.pubkeyHex.takeIf { pk -> pk != rootEvent.pubKey } }.orEmpty() val finalText = appendMediaUrls(tagger.message, imetas) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationReplyReceiver.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationReplyReceiver.kt index 5988f7b790..b2191045bf 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationReplyReceiver.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationReplyReceiver.kt @@ -30,7 +30,6 @@ import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.accountsCache.AccountCacheState -import com.vitorpamplona.amethyst.ui.actions.LocalCacheDao import com.vitorpamplona.amethyst.ui.actions.NewMessageTagger import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle import com.vitorpamplona.quartz.nip01Core.tags.people.PTag @@ -207,7 +206,7 @@ class NotificationReplyReceiver : BroadcastReceiver() { // (`p`) and linkable — the same enrichment the in-app composers do. The comment builders // already tag the reply-parent author, so drop it from the body mentions to avoid a // duplicate `p` (kind-1 doesn't auto-tag the parent, so nothing is lost there). - val tagger = NewMessageTagger(replyText, emptyList(), emptyList(), LocalCacheDao) + val tagger = NewMessageTagger(replyText) tagger.run() val mentions = tagger.pTags?.mapNotNull { pt -> pt.pubkeyHex.takeIf { it != targetEvent.pubKey } }.orEmpty() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/LocalCacheDao.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/LocalCacheDao.kt deleted file mode 100644 index a42a4e6f85..0000000000 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/LocalCacheDao.kt +++ /dev/null @@ -1,46 +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.actions - -import com.vitorpamplona.amethyst.model.AddressableNote -import com.vitorpamplona.amethyst.model.LocalCache -import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.quartz.nip01Core.core.Address -import com.vitorpamplona.quartz.nip01Core.core.HexKey - -/** - * A [Dao] backed directly by [LocalCache], for resolving `@`/`nostr:` mentions with - * [NewMessageTagger] from paths that have no `AccountViewModel` to hand — the model-layer - * send helpers ([com.vitorpamplona.amethyst.model.Account]) and the background notification - * quick-reply receiver. Mirrors `AccountViewModel`'s own Dao delegation, which is just this. - * - * Resolving an npub/nprofile to its pubkey needs no populated cache (the key is in the - * bech32 itself), so this works even in a cold `:napplet`-free receiver process where - * LocalCache hasn't been rehydrated; only note-author lookups degrade there, which is fine. - */ -object LocalCacheDao : Dao { - override suspend fun getOrCreateUser(hex: HexKey): User = LocalCache.getOrCreateUser(hex) - - override suspend fun getOrCreateNote(hex: HexKey): Note = LocalCache.getOrCreateNote(hex) - - override fun getOrCreateAddressableNote(address: Address): AddressableNote = LocalCache.getOrCreateAddressableNote(address) -} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMessageTagger.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMessageTagger.kt index 1df8b61d10..c7f1f1d2db 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMessageTagger.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMessageTagger.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.actions import androidx.compose.runtime.Immutable import com.vitorpamplona.amethyst.model.AddressableNote +import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.quartz.nip01Core.core.Address @@ -44,7 +45,10 @@ class NewMessageTagger( var message: String, var pTags: List? = null, var eTags: List? = null, - var dao: Dao, + // Defaults to a Dao whose methods read straight from LocalCache (see the interface below), + // so callers with no AccountViewModel — model-layer sends, background receivers — can just + // omit it. UI callers still pass their AccountViewModel, which resolves to the same thing. + var dao: Dao = object : Dao {}, ) { val directMentions = mutableSetOf() val directMentionsNotes = mutableSetOf() @@ -260,9 +264,9 @@ class NewMessageTagger( } interface Dao { - suspend fun getOrCreateUser(hex: String): User + suspend fun getOrCreateUser(hex: HexKey): User = LocalCache.getOrCreateUser(hex) - suspend fun getOrCreateNote(hex: String): Note + suspend fun getOrCreateNote(hex: HexKey): Note = LocalCache.getOrCreateNote(hex) - fun getOrCreateAddressableNote(address: Address): AddressableNote? + fun getOrCreateAddressableNote(address: Address): AddressableNote? = LocalCache.getOrCreateAddressableNote(address) }