CurrentRelaysProvider.tsx raw
1 import client from '@/services/client.service'
2 import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'
3
4 type TCurrentRelaysContext = {
5 relayUrls: string[]
6 addRelayUrls: (urls: string[]) => void
7 removeRelayUrls: (urls: string[]) => void
8 }
9
10 const CurrentRelaysContext = createContext<TCurrentRelaysContext | undefined>(undefined)
11
12 export const useCurrentRelays = () => {
13 const context = useContext(CurrentRelaysContext)
14 if (!context) {
15 throw new Error('useCurrentRelays must be used within a CurrentRelaysProvider')
16 }
17 return context
18 }
19
20 export function CurrentRelaysProvider({ children }: { children: React.ReactNode }) {
21 const [relayRefCount, setRelayRefCount] = useState<Record<string, number>>({})
22 const relayUrls = useMemo(() => Object.keys(relayRefCount), [relayRefCount])
23
24 useEffect(() => {
25 client.currentRelays = relayUrls
26 }, [relayUrls])
27
28 const addRelayUrls = useCallback((urls: string[]) => {
29 setRelayRefCount((prev) => {
30 const newCounts = { ...prev }
31 urls.forEach((url) => {
32 newCounts[url] = (newCounts[url] || 0) + 1
33 })
34 return newCounts
35 })
36 }, [])
37
38 const removeRelayUrls = useCallback((urls: string[]) => {
39 setRelayRefCount((prev) => {
40 const newCounts = { ...prev }
41 urls.forEach((url) => {
42 if (newCounts[url]) {
43 newCounts[url] -= 1
44 if (newCounts[url] <= 0) {
45 delete newCounts[url]
46 }
47 }
48 })
49 return newCounts
50 })
51 }, [])
52
53 return (
54 <CurrentRelaysContext.Provider value={{ relayUrls, addRelayUrls, removeRelayUrls }}>
55 {children}
56 </CurrentRelaysContext.Provider>
57 )
58 }
59