chore: merge the develop branch into master #1
@@ -278,6 +278,7 @@ class Nostr {
|
||||
when (val message = notification.message.asEnum()) {
|
||||
is RelayMessageEnum.EventMsg -> {
|
||||
val event = message.event
|
||||
val id = message.subscriptionId
|
||||
|
||||
// Prevent processing duplicate events
|
||||
if (processedEvent.contains(event.id())) continue
|
||||
@@ -299,9 +300,18 @@ class Nostr {
|
||||
}
|
||||
|
||||
if (event.kind().asStd()?.equals(KindStandard.INBOX_RELAYS) == true) {
|
||||
// Get all gift wrap events for current user
|
||||
if (isSignedByUser(event = event)) {
|
||||
getUserMessages(msgRelayList = event)
|
||||
}
|
||||
|
||||
// Connect to all msg relays for the currently active chat room
|
||||
if (id.startsWith("room-")) {
|
||||
launch {
|
||||
chatRoomAuth(event)
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the relay list for future use
|
||||
setMsgRelay(pubkey = event.author(), event = event)
|
||||
}
|
||||
@@ -525,6 +535,23 @@ class Nostr {
|
||||
setSigner(keys)
|
||||
}
|
||||
|
||||
suspend fun getAllCacheMetadata(): Map<PublicKey, Metadata> {
|
||||
try {
|
||||
val filter = Filter().kind(Kind.fromStd(KindStandard.METADATA)).limit(200u)
|
||||
val events = client?.database()?.query(filter)
|
||||
val results = mutableMapOf<PublicKey, Metadata>()
|
||||
|
||||
events?.toVec()?.forEach { event ->
|
||||
val metadata = Metadata.fromJson(event.content())
|
||||
results[event.author()] = metadata
|
||||
}
|
||||
|
||||
return results
|
||||
} catch (e: Exception) {
|
||||
throw IllegalStateException("Failed to get cache metadata: ${e.message}", e)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun fetchMetadataBatch(keys: List<PublicKey>) {
|
||||
try {
|
||||
val limit = keys.size.toULong() * 4u;
|
||||
@@ -611,7 +638,7 @@ class Nostr {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun chatRoomConnect(members: List<PublicKey>) {
|
||||
suspend fun chatRoomConnect(id: Long, members: List<PublicKey>) {
|
||||
try {
|
||||
members.forEach { member ->
|
||||
val kind = Kind.fromStd(KindStandard.INBOX_RELAYS)
|
||||
@@ -620,7 +647,8 @@ class Nostr {
|
||||
|
||||
client?.subscribe(
|
||||
target = ReqTarget.auto(listOf(filter)),
|
||||
closeOn = opts
|
||||
closeOn = opts,
|
||||
id = "room-${id}"
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
@@ -628,6 +656,18 @@ class Nostr {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun chatRoomAuth(event: Event) {
|
||||
try {
|
||||
val urls = nip17ExtractRelayList(event);
|
||||
for (url in urls) {
|
||||
client?.addRelay(url)
|
||||
client?.connectRelay(url)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throw IllegalStateException("Failed to authenticate chat room: ${e.message}", e)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun sendMessage(
|
||||
to: List<PublicKey>,
|
||||
content: String,
|
||||
@@ -694,9 +734,13 @@ class Nostr {
|
||||
)
|
||||
|
||||
if (output != null) {
|
||||
// Keep track of sent events
|
||||
sentEvents[output.id] = emptyList()
|
||||
if (rumor.id() != null) {
|
||||
rumorMap[rumor.id()!!] = output.id
|
||||
if (rumor.id() != null) rumorMap[rumor.id()!!] = output.id
|
||||
|
||||
// Collect failed outputs
|
||||
output.failed.forEach { (relayUrl, reason) ->
|
||||
println("Failed to send event to relay $relayUrl: $reason")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ class NostrViewModel(
|
||||
|
||||
init {
|
||||
startMetadataBatchProcessor()
|
||||
getCacheMetadata()
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
@@ -78,10 +79,7 @@ class NostrViewModel(
|
||||
private fun showError(message: String) {
|
||||
viewModelScope.launch {
|
||||
_errorEvents.send(message)
|
||||
|
||||
if (isCreating.value) {
|
||||
_isCreating.value = false
|
||||
}
|
||||
if (isCreating.value) _isCreating.value = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +114,17 @@ class NostrViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCacheMetadata() {
|
||||
viewModelScope.launch {
|
||||
val results = nostr.getAllCacheMetadata()
|
||||
results.forEach { (pubkey, metadata) ->
|
||||
println("Cache metadata for pubkey $pubkey: $metadata")
|
||||
updateMetadata(pubkey, metadata)
|
||||
seenPublicKeys.add(pubkey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun requestMetadata(pubkey: PublicKey) {
|
||||
if (seenPublicKeys.add(pubkey)) {
|
||||
viewModelScope.launch {
|
||||
@@ -124,6 +133,10 @@ class NostrViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateMetadata(pubkey: PublicKey, metadata: Metadata) {
|
||||
_metadataStore.getOrPut(pubkey) { MutableStateFlow(null) }.value = metadata
|
||||
}
|
||||
|
||||
fun getMetadata(pubkey: PublicKey): StateFlow<Metadata?> {
|
||||
val flow = _metadataStore.getOrPut(pubkey) { MutableStateFlow(null) }
|
||||
if (flow.value == null) {
|
||||
@@ -132,10 +145,6 @@ class NostrViewModel(
|
||||
return flow.asStateFlow()
|
||||
}
|
||||
|
||||
private fun updateMetadata(pubkey: PublicKey, metadata: Metadata) {
|
||||
_metadataStore.getOrPut(pubkey) { MutableStateFlow(null) }.value = metadata
|
||||
}
|
||||
|
||||
suspend fun login() {
|
||||
try {
|
||||
getUserSecret()
|
||||
@@ -355,7 +364,7 @@ class NostrViewModel(
|
||||
val room = getChatRoom(roomId)
|
||||
val members = room.members
|
||||
|
||||
nostr.chatRoomConnect(members.toList())
|
||||
nostr.chatRoomConnect(roomId, members.toList())
|
||||
} catch (e: Exception) {
|
||||
showError("Error: ${e.message}")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user