import React, { useContext, useEffect, useState } from 'react' import { getPublickey } from '../lib/nostr/Bip' import SInfo from 'react-native-sensitive-info' import { RelayPoolContext } from './RelayPoolContext' import { AppContext } from './AppContext' import { getContactsCount, getFollowersCount, getUser, User, } from '../Functions/DatabaseFunctions/Users' import { dropTables } from '../Functions/DatabaseFunctions' import { navigate } from '../lib/Navigation' import { npubEncode, nsecEncode } from 'nostr-tools/nip19' export interface UserContextProps { userState: 'loading' | 'access' | 'ready' setUserState: (userState: 'loading' | 'access' | 'ready') => void nPub?: string nSec?: string publicKey?: string setPublicKey: (privateKey: string | undefined) => void privateKey?: string setPrivateKey: (privateKey: string | undefined) => void setUser: (user: User) => void user?: User contactsCount: number followersCount: number setContantsCount: (count: number) => void setFollowersCount: (count: number) => void reloadUser: () => void logout: () => void } export interface UserContextProviderProps { children: React.ReactNode } export const initialUserContext: UserContextProps = { userState: 'loading', setUserState: () => {}, setPublicKey: () => {}, setPrivateKey: () => {}, setUser: () => {}, reloadUser: () => {}, logout: () => {}, setContantsCount: () => {}, setFollowersCount: () => {}, contactsCount: 0, followersCount: 0, } export const UserContextProvider = ({ children }: UserContextProviderProps): JSX.Element => { const { database, loadingDb, init } = useContext(AppContext) const { relayPool } = useContext(RelayPoolContext) const [userState, setUserState] = useState<'loading' | 'access' | 'ready'>('loading') const [publicKey, setPublicKey] = useState() const [nPub, setNpub] = useState() const [nSec, setNsec] = useState() const [privateKey, setPrivateKey] = useState() const [user, setUser] = React.useState() const [contactsCount, setContantsCount] = React.useState(0) const [followersCount, setFollowersCount] = React.useState(0) const reloadUser: () => void = () => { if (database && publicKey) { getUser(publicKey, database).then((result) => { if (result) { setUser(result) } else { setUser({ id: publicKey, }) } }) getContactsCount(database).then(setContantsCount) getFollowersCount(database).then(setFollowersCount) } } const logout: () => void = () => { if (database) { relayPool?.unsubscribeAll() setPrivateKey(undefined) setPublicKey(undefined) setNpub(undefined) setNsec(undefined) setUser(undefined) dropTables(database).then(() => { SInfo.deleteItem('privateKey', {}).then(() => { SInfo.deleteItem('publicKey', {}).then(() => { init() setUserState('access') navigate('Home', { screen: 'ProfileConnect' }) }) }) }) } } useEffect(() => { if (privateKey && privateKey !== '') { SInfo.setItem('privateKey', privateKey, {}) setNsec(nsecEncode(privateKey)) const publicKey: string = getPublickey(privateKey) setPublicKey(publicKey) } }, [privateKey]) useEffect(() => { if (publicKey && publicKey !== '') { SInfo.setItem('publicKey', publicKey, {}) setNpub(npubEncode(publicKey)) reloadUser() } }, [publicKey]) useEffect(() => { if (userState === 'ready' && publicKey) { navigate('Feed') } }, [userState, publicKey]) useEffect(() => { if (!loadingDb) { SInfo.getItem('privateKey', {}).then((privateResult) => { if (privateResult && privateResult !== '') { setPrivateKey(privateResult) } }) SInfo.getItem('publicKey', {}).then((publicResult) => { if (publicResult && publicResult !== '') { setPublicKey(publicResult) setUserState('ready') } else { setUserState('access') } }) } }, [loadingDb]) return ( {children} ) } export const UserContext = React.createContext(initialUserContext)