diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 8e84dee15..86e0cb618 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -2161,17 +2161,6 @@ class Account( return LocalCache.getOrCreateAddressableNote(aTag) } - fun getFileServersNote(): AddressableNote { - val aTag = - ATag( - FileServersEvent.KIND, - userProfile().pubkeyHex, - "", - null, - ) - return LocalCache.getOrCreateAddressableNote(aTag) - } - fun getBlockList(): PeopleListEvent? { return getBlockListNote().event as? PeopleListEvent } @@ -2180,10 +2169,6 @@ class Account( return getMuteListNote().event as? MuteListEvent } - fun getFileServersList(): FileServersEvent? { - return getFileServersNote().event as? FileServersEvent - } - fun hideWord(word: String) { val muteList = getMuteList() @@ -2688,10 +2673,7 @@ class Account( fun saveSearchRelayList(searchRelays: List) { if (!isWriteable()) return - val relayListForSearch = - LocalCache.getOrCreateAddressableNote( - SearchRelayListEvent.createAddressATag(signer.pubKey), - ).event as? SearchRelayListEvent + val relayListForSearch = getSearchRelayList() if (relayListForSearch != null && relayListForSearch.tags.isNotEmpty()) { SearchRelayListEvent.updateRelayList( @@ -2730,10 +2712,7 @@ class Account( fun sendNip65RelayList(relays: List) { if (!isWriteable()) return - val nip65RelayList = - LocalCache.getOrCreateAddressableNote( - AdvertisedRelayListEvent.createAddressATag(signer.pubKey), - ).event as? AdvertisedRelayListEvent + val nip65RelayList = getNIP65RelayList() if (nip65RelayList != null) { AdvertisedRelayListEvent.updateRelayList( @@ -2755,6 +2734,43 @@ class Account( } } + fun getFileServersList(): FileServersEvent? { + return getFileServersNote().event as? FileServersEvent + } + + fun getFileServersListFlow(): StateFlow { + return getFileServersNote().flow().metadata.stateFlow + } + + fun getFileServersNote(): AddressableNote { + return LocalCache.getOrCreateAddressableNote(FileServersEvent.createAddressATag(userProfile().pubkeyHex)) + } + + fun sendFileServersList(servers: List) { + if (!isWriteable()) return + + val serverList = getFileServersList() + + if (serverList != null && serverList.tags.isNotEmpty()) { + FileServersEvent.updateRelayList( + earlierVersion = serverList, + relays = servers, + signer = signer, + ) { + Client.send(it) + LocalCache.justConsume(it, null) + } + } else { + FileServersEvent.createFromScratch( + relays = servers, + signer = signer, + ) { + Client.send(it) + LocalCache.justConsume(it, null) + } + } + } + fun setHideDeleteRequestDialog() { hideDeleteRequestDialog = true saveable.invalidateData() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt index b63052cb2..d7dfc7268 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt @@ -45,6 +45,7 @@ import com.vitorpamplona.quartz.events.DraftEvent import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent import com.vitorpamplona.quartz.events.Event import com.vitorpamplona.quartz.events.EventInterface +import com.vitorpamplona.quartz.events.FileServersEvent import com.vitorpamplona.quartz.events.GenericRepostEvent import com.vitorpamplona.quartz.events.GiftWrapEvent import com.vitorpamplona.quartz.events.GitIssueEvent @@ -123,6 +124,7 @@ object NostrAccountDataSource : NostrDataSource("AccountData") { AdvertisedRelayListEvent.KIND, ChatMessageRelayListEvent.KIND, SearchRelayListEvent.KIND, + FileServersEvent.KIND, MuteListEvent.KIND, PeopleListEvent.KIND, ), diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileServersEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/FileServersEvent.kt index a2825b805..2bdbcab03 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileServersEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/FileServersEvent.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.quartz.events import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.encoders.ATag import com.vitorpamplona.quartz.encoders.HexKey import com.vitorpamplona.quartz.signers.NostrSigner import com.vitorpamplona.quartz.utils.TimeUtils @@ -36,24 +37,68 @@ class FileServersEvent( ) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) { override fun dTag() = FIXED_D_TAG + fun servers(): List { + return tags.mapNotNull { + if (it.size > 1 && it[0] == "relay") { + it[1] + } else { + null + } + } + } + companion object { const val KIND = 10096 const val FIXED_D_TAG = "" const val ALT = "File servers used by the author" - fun create( - listOfServers: List, + fun createAddressATag(pubKey: HexKey): ATag { + return ATag(KIND, pubKey, FIXED_D_TAG, null) + } + + fun createAddressTag(pubKey: HexKey): String { + return ATag.assembleATag(KIND, pubKey, FIXED_D_TAG) + } + + fun createTagArray(servers: List): Array> { + return servers.map { + arrayOf("server", it) + }.plusElement(arrayOf("alt", "Relay list to use for Search")).toTypedArray() + } + + fun updateRelayList( + earlierVersion: FileServersEvent, + relays: List, signer: NostrSigner, createdAt: Long = TimeUtils.now(), onReady: (FileServersEvent) -> Unit, ) { - val msg = "" - val tags = mutableListOf>() + val tags = + earlierVersion.tags.filter { it[0] != "server" }.plus( + relays.map { + arrayOf("server", it) + }, + ).toTypedArray() - listOfServers.forEach { tags.add(arrayOf("server", it)) } - tags.add(arrayOf("alt", ALT)) + signer.sign(createdAt, KIND, tags, earlierVersion.content, onReady) + } - signer.sign(createdAt, KIND, tags.toTypedArray(), msg, onReady) + fun createFromScratch( + relays: List, + signer: NostrSigner, + createdAt: Long = TimeUtils.now(), + onReady: (FileServersEvent) -> Unit, + ) { + create(relays, signer, createdAt, onReady) + } + + fun create( + servers: List, + signer: NostrSigner, + createdAt: Long = TimeUtils.now(), + onReady: (FileServersEvent) -> Unit, + ) { + signer.sign(createdAt, KIND, createTagArray(servers), "", onReady) } } }