mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-09-19 04:59:59 +00:00
Cancel pending publications when custom relays are removed
This commit is contained in:
parent
f41e844298
commit
994d40b46b
@ -79,6 +79,11 @@ internal class NostrPendingEventQueue(
|
||||
}
|
||||
}
|
||||
|
||||
fun removeRelay(relayUrl: String) = synchronized(lock) {
|
||||
entries.forEach { it.pendingRelayUrls.remove(relayUrl) }
|
||||
entries.removeAll { it.pendingRelayUrls.isEmpty() }
|
||||
}
|
||||
|
||||
fun removeLiveLocationEvents() {
|
||||
synchronized(lock) {
|
||||
entries.removeAll { it.liveLocationToken != null }
|
||||
|
||||
@ -83,6 +83,7 @@ class NostrRelayManager private constructor() {
|
||||
private val _customRelays = MutableStateFlow<List<String>>(emptyList())
|
||||
val customRelays: StateFlow<List<String>> = _customRelays.asStateFlow()
|
||||
private var customRelaysLoaded = false
|
||||
private val removedCustomRelayUrls = java.util.concurrent.ConcurrentHashMap.newKeySet<String>()
|
||||
|
||||
@Synchronized
|
||||
private fun loadCustomRelays(context: android.content.Context) {
|
||||
@ -101,6 +102,7 @@ class NostrRelayManager private constructor() {
|
||||
if (url in defaultRelays()) return true
|
||||
if (_customRelays.value.size >= 20) return false
|
||||
val previousDefaults = defaultRelays().toSet()
|
||||
removedCustomRelayUrls.remove(url)
|
||||
_customRelays.value = _customRelays.value + url
|
||||
persistCustomRelays()
|
||||
nonLiveRelayUrls.add(url)
|
||||
@ -116,6 +118,8 @@ class NostrRelayManager private constructor() {
|
||||
@Synchronized
|
||||
fun removeCustomRelay(url: String) {
|
||||
if (url !in _customRelays.value) return
|
||||
removedCustomRelayUrls.add(url)
|
||||
messageQueue.removeRelay(url)
|
||||
_customRelays.value = _customRelays.value - url
|
||||
persistCustomRelays()
|
||||
activeSubscriptions.replaceAll { _, subscription ->
|
||||
@ -930,7 +934,7 @@ class NostrRelayManager private constructor() {
|
||||
urlString: String,
|
||||
liveLocationToken: Long? = null
|
||||
) {
|
||||
if (!desiredConnected.get()) return
|
||||
if (!desiredConnected.get() || urlString in removedCustomRelayUrls) return
|
||||
val connectionToken = liveLocationToken
|
||||
?.takeIf { urlString !in nonLiveRelayUrls }
|
||||
if (!isNetworkActionAllowed(connectionToken)) return
|
||||
@ -945,6 +949,7 @@ class NostrRelayManager private constructor() {
|
||||
.build()
|
||||
|
||||
val started = runNetworkAction(connectionToken) {
|
||||
if (urlString in removedCustomRelayUrls) return@runNetworkAction
|
||||
val webSocket = httpClient.newWebSocket(
|
||||
request,
|
||||
RelayWebSocketListener(urlString, connectionToken)
|
||||
@ -952,7 +957,7 @@ class NostrRelayManager private constructor() {
|
||||
val existing = connections.putIfAbsent(urlString, webSocket)
|
||||
when {
|
||||
existing != null -> webSocket.close(1000, "Duplicate connection")
|
||||
!desiredConnected.get() -> {
|
||||
!desiredConnected.get() || urlString in removedCustomRelayUrls -> {
|
||||
connections.remove(urlString, webSocket)
|
||||
webSocket.close(1000, "Connection no longer desired")
|
||||
}
|
||||
@ -973,14 +978,14 @@ class NostrRelayManager private constructor() {
|
||||
liveLocationToken: Long? = null,
|
||||
publicationAllowed: () -> Boolean = { true }
|
||||
): Boolean {
|
||||
if (!publicationAllowed() || !isNetworkActionAllowed(liveLocationToken)) return false
|
||||
if (!publicationAllowed() || relayUrl in removedCustomRelayUrls || !isNetworkActionAllowed(liveLocationToken)) return false
|
||||
return try {
|
||||
val request = NostrRequest.Event(event)
|
||||
val message = gson.toJson(request, NostrRequest::class.java)
|
||||
|
||||
var success = false
|
||||
runNetworkAction(liveLocationToken) {
|
||||
if (publicationAllowed()) success = webSocket.send(message)
|
||||
if (publicationAllowed() && relayUrl !in removedCustomRelayUrls) success = webSocket.send(message)
|
||||
}
|
||||
if (success) {
|
||||
// Update relay stats
|
||||
@ -1238,7 +1243,7 @@ class NostrRelayManager private constructor() {
|
||||
) : WebSocketListener() {
|
||||
|
||||
override fun onOpen(webSocket: WebSocket, response: Response) {
|
||||
if (!desiredConnected.get() ||
|
||||
if (!desiredConnected.get() || relayUrl in removedCustomRelayUrls ||
|
||||
connections[relayUrl] !== webSocket ||
|
||||
!isNetworkActionAllowed(liveLocationToken)
|
||||
) {
|
||||
|
||||
@ -82,6 +82,17 @@ class NostrPendingEventQueueTest {
|
||||
assertEquals(0, queue.size())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `removing a relay drops its pending work without losing other deliveries`() {
|
||||
val queue = NostrPendingEventQueue(4)
|
||||
queue.enqueue(event("shared"), listOf("removed", "retained"), null)
|
||||
queue.enqueue(event("removed-only"), listOf("removed"), null)
|
||||
queue.removeRelay("removed")
|
||||
assertEquals(0, queue.pendingForRelay("removed").size)
|
||||
assertEquals(listOf("shared"), queue.pendingForRelay("retained").map { it.event.content })
|
||||
assertEquals(1, queue.size())
|
||||
}
|
||||
|
||||
private fun event(content: String): NostrEvent {
|
||||
val privateKey = "0".repeat(63) + "1"
|
||||
return NostrEvent(
|
||||
|
||||
@ -116,8 +116,8 @@ Physical Mesh Lab and Android-to-iOS interoperability are required separately:
|
||||
- One-time-prekey races and consumption persistence, plus iOS vectors on both
|
||||
real clients. Static screenshots cannot establish any of these properties.
|
||||
|
||||
The updated panic-help sentence falls back to English where previous translations
|
||||
still promised immediate erasure; those stale claims are removed. Full locale coverage, accessibility review and the physical matrix remain
|
||||
The updated panic-help sentence uses the English resource fallback until translated.
|
||||
Full locale coverage, accessibility review and the physical matrix remain
|
||||
release work. Manual-channel Nostr board publication still obeys the existing
|
||||
location-note privacy gate; this integration does not weaken it to force a
|
||||
successful publish. No claim is made that this large integration is ready to
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user