-
Notifications
You must be signed in to change notification settings - Fork 66
Expand file tree
/
Copy pathctx.tsx
More file actions
71 lines (60 loc) · 2 KB
/
ctx.tsx
File metadata and controls
71 lines (60 loc) · 2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react'
import { startLibp2p } from '../lib/libp2p'
import { ChatProvider } from './chat-ctx'
import { PixelArtProvider } from './pixel-art-ctx'
import type { Libp2p, PubSub } from '@libp2p/interface'
import type { Identify } from '@libp2p/identify'
import type { DirectMessage } from '@/lib/direct-message'
import type { DelegatedRoutingV1HttpApiClient } from '@helia/delegated-routing-v1-http-api-client'
import { Booting } from '@/components/booting'
export type Libp2pType = Libp2p<{
pubsub: PubSub
identify: Identify
directMessage: DirectMessage
delegatedRouting: DelegatedRoutingV1HttpApiClient
}>
export const libp2pContext = createContext<{ libp2p: Libp2pType }>({
// @ts-ignore to avoid having to check isn't undefined everywhere. Can't be undefined because children are conditionally rendered
libp2p: undefined,
})
interface WrapperProps {
children?: ReactNode
}
// This is needed to prevent libp2p from instantiating more than once
let loaded = false
export function AppWrapper({ children }: WrapperProps) {
const [libp2p, setLibp2p] = useState<Libp2pType | undefined>(undefined)
const [error, setError] = useState('')
useEffect(() => {
const init = async () => {
if (loaded) return
try {
loaded = true
const libp2p = await startLibp2p()
if (!libp2p) {
throw new Error('failed to start libp2p')
}
// @ts-ignore
window.libp2p = libp2p
setLibp2p(libp2p as Libp2pType)
} catch (e) {
console.error('failed to start libp2p', e)
setError(`failed to start libp2p ${e}`)
}
}
init()
}, [])
if (!libp2p) {
return <Booting error={error} />
}
return (
<libp2pContext.Provider value={{ libp2p }}>
<ChatProvider>
<PixelArtProvider>{children}</PixelArtProvider>
</ChatProvider>
</libp2pContext.Provider>
)
}
export function useLibp2pContext() {
return useContext(libp2pContext)
}