import { useLazyQuery } from "@apollo/client" ; import React , { PropsWithChildren , useState , useRef } from "react" ; import { Qu_user } from "../queries/user" ; import type { WalletManager } from "../services/Wallet" ; import { ConnectedUser } from "../types/entities/User" ; import { useClientAsyncEffect , useClientEffect } from "../utils/hookts" ; interface UserContextType { autoConnectChecked : boolean ; user : ConnectedUser | null ; walletManager : WalletManager | null ; connect : ( ) => Promise < void > ; disconnect : ( ) => void ; } const defaultCtx = { autoConnectChecked : false , user : null , walletManager : null , connect : ( ) => new Promise ( r => r ( ) ) , disconnect : ( ) => { } } ; export const UserContext = React . createContext < UserContextType > ( defaultCtx ) ; export function UserProvider ( { children } ) { const [ context , setContext ] = useState < UserContextType > ( defaultCtx ) ; const ctxRef = useRef < UserContextType > ( context ) ; const [ getUser , { data : userData } ] = useLazyQuery ( Qu_user , { fetchPolicy : "no-cache" } ) ; useClientEffect ( ( ) => { ctxRef . current = context ; } , [ context ] ) ; useClientEffect ( ( ) => { if ( userData && userData . user ) { setContext ( { ... context , user : userData . user } ) ; } } , [ userData ] ) ; const connect = ( ) => new Promise < void > ( async ( resolve , reject ) => { const ctx = ctxRef . current ; if ( ctx . walletManager ) { const pkh = await ctx . walletManager . connect ( ) ; if ( pkh ) { const nCtx = { ... ctx } ; nCtx . user = { id : pkh } ; setContext ( nCtx ) ; getUser ( { variables : { id : pkh } } ) ; resolve ( ) ; } else { reject ( ) ; } } else { reject ( ) ; } } ) ; const disconnect = async ( ) => { const ctx = ctxRef . current ; if ( ctx . walletManager ) { await ctx . walletManager . disconnect ( ) ; setContext ( { ... ctx , user : null } ) ; } } ; useClientAsyncEffect ( async ( isMounted ) => { const initCtx = { ... defaultCtx , connect , disconnect , } ; const { WalletManager } = await import ( "../services/Wallet" ) ; const manager = new WalletManager ( ) ; initCtx . walletManager = manager ; const pkh = await manager . connectFromStorage ( ) ; if ( pkh ) { initCtx . user = { id : pkh } ; getUser ( { variables : { id : pkh } } ) ; } initCtx . autoConnectChecked = true ; setContext ( initCtx ) ; } , [ ] ) ; return ( < UserContext . Provider value = { context } > { children } < /UserContext.Provider>); }