mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-26 23:45:19 +00:00
[codex] Refactor BLE outbound scheduling and Noise queues (#1306)
* Refactor BLE transport event handling * Make image output paths unique * Keep queued Nostr read receipts alive * Refine BLE ingress fanout * Rediscover BLE service after invalidation * Extract BLE notification retry buffer * Extract BLE inbound write buffer * Extract BLE fragment assembly buffer * Tidy secure log handling from device run * Extract BLE outbound fragment scheduler * Harden app CI media tests * Redact BLE message content from logs * Extract BLE Noise session queues * Fix BLE read receipt UI updates * Allow self-authored RSR ingress replies * Harden read receipt queue test timing * Extract BLE outbound policy and incoming file storage * Avoid duplicate BLE link snapshots during send * Canonicalize Nostr relay URLs --------- Co-authored-by: jack <jackjackbits@users.noreply.github.com>
This commit is contained in:
@@ -381,12 +381,7 @@ final class GeoRelayDirectory {
|
||||
if idx == 0 && line.lowercased().contains("relay url") { continue }
|
||||
let parts = line.split(separator: ",").map { $0.trimmed }
|
||||
guard parts.count >= 3 else { continue }
|
||||
var host = parts[0]
|
||||
host = host.replacingOccurrences(of: "https://", with: "")
|
||||
host = host.replacingOccurrences(of: "http://", with: "")
|
||||
host = host.replacingOccurrences(of: "wss://", with: "")
|
||||
host = host.replacingOccurrences(of: "ws://", with: "")
|
||||
host = host.trimmingCharacters(in: CharacterSet(charactersIn: "/"))
|
||||
guard let host = NostrRelayURL.directoryAddress(parts[0]) else { continue }
|
||||
guard let lat = Double(parts[1]), let lon = Double(parts[2]) else { continue }
|
||||
result.insert(Entry(host: host, lat: lat, lon: lon))
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ final class NostrRelayManager: ObservableObject {
|
||||
"wss://offchain.pub"
|
||||
// For local testing, you can add: "ws://localhost:8080"
|
||||
]
|
||||
private static let defaultRelaySet = Set(defaultRelays)
|
||||
private static let defaultRelaySet = Set(defaultRelays.compactMap { NostrRelayURL.normalized($0) })
|
||||
|
||||
@Published private(set) var relays: [Relay] = []
|
||||
@Published private(set) var isConnected = false
|
||||
@@ -390,8 +390,7 @@ final class NostrRelayManager: ObservableObject {
|
||||
|
||||
// Target specific relays if provided; else default. Filter permanently failed relays.
|
||||
let baseUrls = relayUrls ?? Self.defaultRelays
|
||||
let candidateUrls = baseUrls.filter { !isPermanentlyFailed($0) }
|
||||
let urls = allowedRelayList(from: candidateUrls)
|
||||
let urls = allowedRelayList(from: baseUrls).filter { !isPermanentlyFailed($0) }
|
||||
let requestState = SubscriptionRequestState(messageString: messageString, relayURLs: Set(urls))
|
||||
if subscriptionRequestState[id] == requestState, subscriptionStateExists(id: id, requestState: requestState) {
|
||||
return
|
||||
@@ -474,7 +473,8 @@ final class NostrRelayManager: ObservableObject {
|
||||
private func allowedRelayList(from urls: [String]) -> [String] {
|
||||
var seen = Set<String>()
|
||||
var result: [String] = []
|
||||
for url in urls {
|
||||
for rawURL in urls {
|
||||
guard let url = NostrRelayURL.normalized(rawURL) else { continue }
|
||||
if !allowDefaultRelays && Self.defaultRelaySet.contains(url) { continue }
|
||||
if seen.insert(url).inserted {
|
||||
result.append(url)
|
||||
@@ -881,7 +881,8 @@ final class NostrRelayManager: ObservableObject {
|
||||
|
||||
/// Manually retry connection to a specific relay
|
||||
func retryConnection(to relayUrl: String) {
|
||||
guard let index = relays.firstIndex(where: { $0.url == relayUrl }) else { return }
|
||||
let normalizedRelayUrl = NostrRelayURL.normalized(relayUrl) ?? relayUrl
|
||||
guard let index = relays.firstIndex(where: { $0.url == normalizedRelayUrl }) else { return }
|
||||
|
||||
// Reset reconnection attempts
|
||||
relays[index].reconnectAttempts = 0
|
||||
@@ -889,13 +890,13 @@ final class NostrRelayManager: ObservableObject {
|
||||
relays[index].lastError = nil
|
||||
|
||||
// Disconnect if connected
|
||||
if let connection = connections[relayUrl] {
|
||||
if let connection = connections[normalizedRelayUrl] {
|
||||
connection.cancel(with: .goingAway, reason: nil)
|
||||
connections.removeValue(forKey: relayUrl)
|
||||
connections.removeValue(forKey: normalizedRelayUrl)
|
||||
}
|
||||
|
||||
// Attempt immediate reconnection
|
||||
connectToRelay(relayUrl)
|
||||
connectToRelay(normalizedRelayUrl)
|
||||
}
|
||||
|
||||
/// Get detailed status for all relays
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import Foundation
|
||||
|
||||
enum NostrRelayURL {
|
||||
static func normalized(_ rawValue: String, defaultScheme: String? = nil) -> String? {
|
||||
var value = rawValue.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard !value.isEmpty else { return nil }
|
||||
|
||||
if !value.contains("://"), let defaultScheme {
|
||||
value = "\(defaultScheme)://\(value)"
|
||||
}
|
||||
|
||||
guard var components = URLComponents(string: value),
|
||||
let rawScheme = components.scheme?.lowercased(),
|
||||
let rawHost = components.host?.lowercased(),
|
||||
!rawHost.isEmpty else {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch rawScheme {
|
||||
case "wss", "https":
|
||||
components.scheme = "wss"
|
||||
if components.port == 443 {
|
||||
components.port = nil
|
||||
}
|
||||
case "ws", "http":
|
||||
components.scheme = "ws"
|
||||
if components.port == 80 {
|
||||
components.port = nil
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
components.host = rawHost
|
||||
if components.path == "/" {
|
||||
components.path = ""
|
||||
}
|
||||
components.fragment = nil
|
||||
|
||||
return components.string
|
||||
}
|
||||
|
||||
static func directoryAddress(_ rawValue: String) -> String? {
|
||||
guard var normalized = normalized(rawValue, defaultScheme: "wss") else { return nil }
|
||||
for prefix in ["wss://", "ws://"] where normalized.hasPrefix(prefix) {
|
||||
normalized.removeFirst(prefix.count)
|
||||
break
|
||||
}
|
||||
return normalized
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user