Dynamic relayUrls (#14)

* core: fix dependency array for connectToRelays cb and useEffect

* core: update relays connexion on relayUrls update

* core: connect and disconnect only when required
This commit is contained in:
Louis Aussedat 2023-03-25 21:57:49 +01:00 committed by GitHub
parent b3a2e69718
commit 7ab57708ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -55,43 +55,71 @@ export function NostrProvider({
}) { }) {
const [isLoading, setIsLoading] = useState(true) const [isLoading, setIsLoading] = useState(true)
const [connectedRelays, setConnectedRelays] = useState<Relay[]>([]) const [connectedRelays, setConnectedRelays] = useState<Relay[]>([])
const [relays, setRelays] = useState<Relay[]>([])
const relayUrlsRef = useRef<string[]>([])
let onConnectCallback: null | OnConnectFunc = null let onConnectCallback: null | OnConnectFunc = null
let onDisconnectCallback: null | OnDisconnectFunc = null let onDisconnectCallback: null | OnDisconnectFunc = null
const isFirstRender = useRef(true) const disconnectToRelays = useCallback(
(relayUrls: string[]) => {
const connectToRelays = useCallback(() => { relayUrls.forEach(async (relayUrl) => {
relayUrls.forEach(async (relayUrl) => { await relays.find((relay) => relay.url === relayUrl)?.close()
const relay = relayInit(relayUrl) setRelays((prev) => prev.filter((r) => r.url !== relayUrl))
relay.connect()
relay.on("connect", () => {
log(debug, "info", `✅ nostr (${relayUrl}): Connected!`)
setIsLoading(false)
onConnectCallback?.(relay)
setConnectedRelays((prev) => uniqBy([...prev, relay], "url"))
}) })
},
[relays],
)
relay.on("disconnect", () => { const connectToRelays = useCallback(
log(debug, "warn", `🚪 nostr (${relayUrl}): Connection closed.`) (relayUrls: string[]) => {
onDisconnectCallback?.(relay) relayUrls.forEach(async (relayUrl) => {
setConnectedRelays((prev) => prev.filter((r) => r.url !== relayUrl)) const relay = relayInit(relayUrl)
})
relay.on("error", () => { if (connectedRelays.findIndex((r) => r.url === relayUrl) >= 0) {
log(debug, "error", `❌ nostr (${relayUrl}): Connection error!`) // already connected, skip
return
}
setRelays((prev) => uniqBy([...prev, relay], "url"))
relay.connect()
relay.on("connect", () => {
log(debug, "info", `✅ nostr (${relayUrl}): Connected!`)
setIsLoading(false)
onConnectCallback?.(relay)
setConnectedRelays((prev) => uniqBy([...prev, relay], "url"))
})
relay.on("disconnect", () => {
log(debug, "warn", `🚪 nostr (${relayUrl}): Connection closed.`)
onDisconnectCallback?.(relay)
setConnectedRelays((prev) => prev.filter((r) => r.url !== relayUrl))
})
relay.on("error", () => {
log(debug, "error", `❌ nostr (${relayUrl}): Connection error!`)
})
}) })
}) },
}, []) [connectedRelays, debug, onConnectCallback, onDisconnectCallback],
)
useEffect(() => { useEffect(() => {
// Make sure we only start the relays once (even in strict-mode) if (relayUrlsRef.current === relayUrls) {
if (isFirstRender.current) { // relayUrls isn't updated, skip
isFirstRender.current = false return
connectToRelays()
} }
}, [])
const relayUrlsToDisconnect = relayUrlsRef.current.filter(
(relayUrl) => !relayUrls.includes(relayUrl),
)
disconnectToRelays(relayUrlsToDisconnect)
connectToRelays(relayUrls)
relayUrlsRef.current = relayUrls
}, [relayUrls, connectToRelays, disconnectToRelays])
const publish = (event: NostrEvent) => { const publish = (event: NostrEvent) => {
return connectedRelays.map((relay) => { return connectedRelays.map((relay) => {