nostros/frontend/Contexts/UserContext.tsx

265 lines
7.7 KiB
TypeScript
Raw Normal View History

2023-01-14 20:35:35 +00:00
import React, { useContext, useEffect, useState } from 'react'
import SInfo from 'react-native-sensitive-info'
import { RelayPoolContext } from './RelayPoolContext'
import { AppContext } from './AppContext'
2023-01-28 20:22:04 +00:00
import { getUser } from '../Functions/DatabaseFunctions/Users'
2023-03-19 18:50:50 +00:00
import { getPublicKey, nip19 } from 'nostr-tools'
2023-01-14 20:35:35 +00:00
import { dropTables } from '../Functions/DatabaseFunctions'
2023-01-16 20:06:12 +00:00
import { navigate } from '../lib/Navigation'
2023-01-21 20:32:17 +00:00
import { getNpub } from '../lib/nostr/Nip19'
2023-03-01 16:22:12 +00:00
import { getGroups } from '../Functions/DatabaseFunctions/Groups'
2023-02-25 22:10:04 +00:00
import { getList } from '../Functions/DatabaseFunctions/Lists'
import { getETags } from '../Functions/RelayFunctions/Events'
2023-02-27 11:06:45 +00:00
import { decrypt } from '../lib/nostr/Nip04'
2023-03-01 16:22:12 +00:00
import DatabaseModule from '../lib/Native/DatabaseModule'
2023-01-14 20:35:35 +00:00
export interface UserContextProps {
2023-01-18 21:54:28 +00:00
userState: 'loading' | 'access' | 'ready'
setUserState: (userState: 'loading' | 'access' | 'ready') => void
2023-01-14 20:35:35 +00:00
nPub?: string
nSec?: string
publicKey?: string
setPublicKey: (privateKey: string | undefined) => void
privateKey?: string
setPrivateKey: (privateKey: string | undefined) => void
reloadUser: () => void
2023-02-25 22:10:04 +00:00
reloadLists: () => void
2023-03-11 22:32:45 +00:00
reloadBookmarks: () => void
2023-02-27 11:06:45 +00:00
publicBookmarks: string[]
privateBookmarks: string[]
2023-02-28 12:44:17 +00:00
mutedEvents: string[]
2023-03-04 16:02:35 +00:00
mutedUsers: string[]
2023-01-14 20:35:35 +00:00
logout: () => void
2023-01-28 20:22:04 +00:00
name?: string
setName: (value: string) => void
picture?: string
setPicture: (value: string) => void
about?: string
setAbout: (value: string) => void
lnurl?: string
setLnurl: (value: string) => void
nip05?: string
setNip05: (value: string) => void
validNip05?: boolean
2023-02-19 17:39:47 +00:00
setLnAddress: (value: string) => void
lnAddress?: string
2023-01-14 20:35:35 +00:00
}
export interface UserContextProviderProps {
children: React.ReactNode
}
export const initialUserContext: UserContextProps = {
2023-01-18 21:54:28 +00:00
userState: 'loading',
setUserState: () => {},
2023-01-14 20:35:35 +00:00
setPublicKey: () => {},
setPrivateKey: () => {},
reloadUser: () => {},
2023-02-25 22:10:04 +00:00
reloadLists: () => {},
2023-03-11 22:32:45 +00:00
reloadBookmarks: () => {},
2023-01-14 20:35:35 +00:00
logout: () => {},
2023-01-28 20:22:04 +00:00
setName: () => {},
setPicture: () => {},
setAbout: () => {},
setLnurl: () => {},
2023-02-19 17:39:47 +00:00
setLnAddress: () => {},
2023-01-28 20:22:04 +00:00
setNip05: () => {},
2023-02-27 11:06:45 +00:00
publicBookmarks: [],
privateBookmarks: [],
2023-02-28 12:44:17 +00:00
mutedEvents: [],
2023-03-04 16:02:35 +00:00
mutedUsers: [],
2023-01-14 20:35:35 +00:00
}
export const UserContextProvider = ({ children }: UserContextProviderProps): JSX.Element => {
const { database, loadingDb, init } = useContext(AppContext)
2023-02-08 16:09:13 +00:00
const { relayPool, relayPoolReady } = useContext(RelayPoolContext)
2023-01-18 21:54:28 +00:00
const [userState, setUserState] = useState<'loading' | 'access' | 'ready'>('loading')
2023-01-14 20:35:35 +00:00
const [publicKey, setPublicKey] = useState<string>()
const [nPub, setNpub] = useState<string>()
const [nSec, setNsec] = useState<string>()
const [privateKey, setPrivateKey] = useState<string>()
2023-01-28 20:22:04 +00:00
const [name, setName] = useState<string>()
const [picture, setPicture] = useState<string>()
const [about, setAbout] = useState<string>()
const [lnurl, setLnurl] = useState<string>()
2023-02-19 17:39:47 +00:00
const [lnAddress, setLnAddress] = useState<string>()
2023-01-28 20:22:04 +00:00
const [nip05, setNip05] = useState<string>()
const [validNip05, setValidNip05] = useState<boolean>()
2023-02-27 11:06:45 +00:00
const [publicBookmarks, setPublicBookmarks] = useState<string[]>([])
const [privateBookmarks, setPrivateBookmarks] = useState<string[]>([])
2023-02-28 12:44:17 +00:00
const [mutedEvents, setMutedEvents] = useState<string[]>([])
2023-03-04 16:02:35 +00:00
const [mutedUsers, setMutedUsers] = useState<string[]>([])
2023-01-14 20:35:35 +00:00
const reloadUser: () => void = () => {
if (database && publicKey) {
getUser(publicKey, database).then((result) => {
2023-01-17 13:21:32 +00:00
if (result) {
2023-01-28 20:22:04 +00:00
setName(result.name)
setPicture(result.picture)
setAbout(result.about)
setLnurl(result.lnurl)
2023-02-19 17:39:47 +00:00
setLnAddress(result.ln_address)
2023-01-28 20:22:04 +00:00
setNip05(result.nip05)
setValidNip05(result.valid_nip05)
2023-01-17 13:21:32 +00:00
}
2023-01-14 20:35:35 +00:00
})
}
}
2023-03-11 22:32:45 +00:00
const decryptBookmarks: (content: string) => void = async (content) => {
if (privateKey && publicKey && content && content !== '') {
const privateJson = decrypt(privateKey, publicKey, content)
const privateList: string[][] = JSON.parse(privateJson)
setPrivateBookmarks(privateList.map((tag) => tag[1]))
}
}
const reloadBookmarks: () => void = () => {
2023-02-27 11:06:45 +00:00
if (database && publicKey && privateKey) {
2023-03-11 22:32:45 +00:00
getList(database, 10001, publicKey).then((result) => {
2023-03-04 16:02:35 +00:00
if (result) {
const eTags = getETags(result)
2023-03-11 22:32:45 +00:00
setPublicBookmarks(eTags.map((tag) => tag[1]))
decryptBookmarks(result.content)
2023-03-04 16:02:35 +00:00
}
})
2023-03-11 22:32:45 +00:00
}
}
const reloadLists: () => void = () => {
if (database && publicKey && privateKey) {
getList(database, 10000, publicKey).then((result) => {
2023-02-25 22:10:04 +00:00
if (result) {
const eTags = getETags(result)
2023-03-11 22:32:45 +00:00
setMutedUsers(eTags.map((tag) => tag[1]))
2023-02-25 22:10:04 +00:00
}
})
2023-02-28 13:02:03 +00:00
getList(database, 30001, publicKey, 'mute').then((result) => {
2023-02-28 12:44:17 +00:00
if (result) {
const eTags = getETags(result)
setMutedEvents(eTags.map((tag) => tag[1]))
}
})
2023-02-25 22:10:04 +00:00
}
}
2023-01-14 20:35:35 +00:00
const logout: () => void = () => {
if (database) {
relayPool?.unsubscribeAll()
2023-03-07 19:11:00 +00:00
relayPool?.removeAll()
2023-01-14 20:35:35 +00:00
setPrivateKey(undefined)
setPublicKey(undefined)
setNpub(undefined)
setNsec(undefined)
2023-01-28 20:22:04 +00:00
setName(undefined)
setPicture(undefined)
setAbout(undefined)
setLnurl(undefined)
2023-02-19 17:39:47 +00:00
setLnAddress(undefined)
2023-01-28 20:22:04 +00:00
setNip05(undefined)
setValidNip05(undefined)
2023-01-14 20:35:35 +00:00
dropTables(database).then(() => {
SInfo.deleteItem('privateKey', {}).then(() => {
SInfo.deleteItem('publicKey', {}).then(() => {
init()
2023-01-18 21:54:28 +00:00
setUserState('access')
2023-01-14 20:35:35 +00:00
navigate('Home', { screen: 'ProfileConnect' })
})
})
})
}
}
useEffect(() => {
if (privateKey && privateKey !== '') {
SInfo.setItem('privateKey', privateKey, {})
2023-03-19 18:50:50 +00:00
setNsec(nip19.nsecEncode(privateKey))
2023-01-23 14:32:51 +00:00
setPublicKey(getPublicKey(privateKey))
2023-01-14 20:35:35 +00:00
}
}, [privateKey])
useEffect(() => {
if (publicKey && publicKey !== '') {
SInfo.setItem('publicKey', publicKey, {})
2023-01-21 20:32:17 +00:00
setNpub(getNpub(publicKey))
2023-01-14 20:35:35 +00:00
reloadUser()
2023-02-25 22:10:04 +00:00
reloadLists()
2023-03-11 22:32:45 +00:00
reloadBookmarks()
2023-01-14 20:35:35 +00:00
}
}, [publicKey])
2023-01-18 21:54:28 +00:00
useEffect(() => {
2023-02-12 12:38:32 +00:00
if (userState === 'ready' && publicKey && relayPoolReady && database) {
getGroups(database).then((results) => {
if (results.length === 0) {
2023-03-01 16:22:12 +00:00
DatabaseModule.addGroup(
2023-02-12 13:50:32 +00:00
'8d37308d97356600f67a28039d598a52b8c4fa1b73ef6f2e7b7d40197c3afa56',
'Nostros',
'645681b9d067b1a362c4bee8ddff987d2466d49905c26cb8fec5e6fb73af5c84',
2023-03-01 16:22:12 +00:00
() => {},
2023-02-12 13:50:32 +00:00
)
2023-02-12 12:38:32 +00:00
}
})
2023-01-18 21:54:28 +00:00
navigate('Feed')
}
2023-02-08 16:09:13 +00:00
}, [userState, publicKey, relayPoolReady])
2023-01-18 21:54:28 +00:00
2023-01-14 20:35:35 +00:00
useEffect(() => {
2023-01-16 12:09:18 +00:00
if (!loadingDb) {
2023-01-14 20:35:35 +00:00
SInfo.getItem('privateKey', {}).then((privateResult) => {
if (privateResult && privateResult !== '') {
setPrivateKey(privateResult)
2023-01-18 21:54:28 +00:00
}
})
SInfo.getItem('publicKey', {}).then((publicResult) => {
if (publicResult && publicResult !== '') {
setPublicKey(publicResult)
setUserState('ready')
2023-01-14 20:35:35 +00:00
} else {
2023-01-18 21:54:28 +00:00
setUserState('access')
2023-01-14 20:35:35 +00:00
}
})
}
}, [loadingDb])
return (
<UserContext.Provider
value={{
2023-01-18 21:54:28 +00:00
userState,
setUserState,
2023-01-14 20:35:35 +00:00
nSec,
nPub,
publicKey,
setPublicKey,
privateKey,
setPrivateKey,
reloadUser,
2023-02-25 22:10:04 +00:00
reloadLists,
2023-03-11 22:32:45 +00:00
reloadBookmarks,
2023-02-27 11:06:45 +00:00
publicBookmarks,
privateBookmarks,
2023-02-28 12:44:17 +00:00
mutedEvents,
2023-01-16 12:09:18 +00:00
logout,
2023-01-28 20:22:04 +00:00
name,
setName,
picture,
setPicture,
about,
setAbout,
lnurl,
setLnurl,
nip05,
setNip05,
validNip05,
2023-02-19 17:39:47 +00:00
lnAddress,
setLnAddress,
2023-03-04 16:02:35 +00:00
mutedUsers,
2023-01-14 20:35:35 +00:00
}}
>
{children}
</UserContext.Provider>
)
}
export const UserContext = React.createContext(initialUserContext)