2024-07-05 08:38:04 +00:00
|
|
|
import { Event, kinds } from 'nostr-tools'
|
2024-04-08 12:45:51 +00:00
|
|
|
import { useEffect, useState } from 'react'
|
2024-05-17 11:33:01 +00:00
|
|
|
import { useDispatch, useSelector } from 'react-redux'
|
2024-02-28 16:49:44 +00:00
|
|
|
import { Outlet } from 'react-router-dom'
|
|
|
|
import { AppBar } from '../components/AppBar/AppBar'
|
2024-07-05 08:38:04 +00:00
|
|
|
import { LoadingSpinner } from '../components/LoadingSpinner'
|
|
|
|
import { MetadataController, NostrController } from '../controllers'
|
|
|
|
import {
|
|
|
|
restoreState,
|
|
|
|
setAuthState,
|
|
|
|
setMetadataEvent,
|
|
|
|
updateUserAppData
|
|
|
|
} from '../store/actions'
|
|
|
|
import { LoginMethods } from '../store/auth/types'
|
|
|
|
import { State } from '../store/rootReducer'
|
|
|
|
import { Dispatch } from '../store/store'
|
|
|
|
import { setUserRobotImage } from '../store/userRobotImage/action'
|
2024-05-17 11:35:37 +00:00
|
|
|
import {
|
|
|
|
clearAuthToken,
|
|
|
|
clearState,
|
|
|
|
getRoboHashPicture,
|
2024-07-05 08:38:04 +00:00
|
|
|
getUsersAppData,
|
2024-05-17 11:35:37 +00:00
|
|
|
loadState,
|
2024-06-28 09:24:14 +00:00
|
|
|
saveNsecBunkerDelegatedKey,
|
|
|
|
subscribeForSigits
|
2024-05-17 11:35:37 +00:00
|
|
|
} from '../utils'
|
2024-07-05 08:38:04 +00:00
|
|
|
import { useAppSelector } from '../hooks'
|
|
|
|
import { SubCloser } from 'nostr-tools/abstract-pool'
|
2024-07-25 13:05:47 +00:00
|
|
|
import styles from './style.module.scss'
|
|
|
|
import { Footer } from '../components/Footer/Footer'
|
2024-05-16 14:45:00 +00:00
|
|
|
|
2024-02-28 16:49:44 +00:00
|
|
|
export const MainLayout = () => {
|
2024-04-08 12:45:51 +00:00
|
|
|
const dispatch: Dispatch = useDispatch()
|
|
|
|
const [isLoading, setIsLoading] = useState(true)
|
2024-07-05 08:38:04 +00:00
|
|
|
const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState(`Loading App`)
|
2024-05-17 11:33:01 +00:00
|
|
|
const authState = useSelector((state: State) => state.auth)
|
2024-07-05 08:38:04 +00:00
|
|
|
const usersAppData = useAppSelector((state) => state.userAppData)
|
2024-02-28 16:49:44 +00:00
|
|
|
|
|
|
|
useEffect(() => {
|
2024-05-30 17:28:40 +00:00
|
|
|
const metadataController = new MetadataController()
|
|
|
|
|
2024-04-08 12:45:51 +00:00
|
|
|
const logout = () => {
|
|
|
|
dispatch(
|
|
|
|
setAuthState({
|
2024-05-16 14:45:00 +00:00
|
|
|
keyPair: undefined,
|
2024-04-08 12:45:51 +00:00
|
|
|
loggedIn: false,
|
|
|
|
usersPubkey: undefined,
|
|
|
|
loginMethod: undefined,
|
|
|
|
nsecBunkerPubkey: undefined
|
|
|
|
})
|
|
|
|
)
|
|
|
|
|
2024-05-17 08:59:03 +00:00
|
|
|
dispatch(setMetadataEvent(metadataController.getEmptyMetadataEvent()))
|
2024-05-16 14:45:00 +00:00
|
|
|
|
2024-04-08 12:45:51 +00:00
|
|
|
// clear authToken saved in local storage
|
|
|
|
clearAuthToken()
|
2024-05-16 14:45:00 +00:00
|
|
|
clearState()
|
2024-04-08 12:45:51 +00:00
|
|
|
|
|
|
|
// update nsecBunker delegated key
|
|
|
|
const newDelegatedKey =
|
|
|
|
NostrController.getInstance().generateDelegatedKey()
|
|
|
|
saveNsecBunkerDelegatedKey(newDelegatedKey)
|
|
|
|
}
|
|
|
|
|
2024-02-28 16:49:44 +00:00
|
|
|
const restoredState = loadState()
|
2024-04-08 12:45:51 +00:00
|
|
|
if (restoredState) {
|
|
|
|
dispatch(restoreState(restoredState))
|
|
|
|
|
|
|
|
const { loggedIn, loginMethod, usersPubkey, nsecBunkerRelays } =
|
|
|
|
restoredState.auth
|
|
|
|
|
|
|
|
if (loggedIn) {
|
|
|
|
if (!loginMethod || !usersPubkey) return logout()
|
|
|
|
|
|
|
|
if (loginMethod === LoginMethods.nsecBunker) {
|
|
|
|
if (!nsecBunkerRelays) return logout()
|
|
|
|
|
|
|
|
const nostrController = NostrController.getInstance()
|
|
|
|
nostrController.nsecBunkerInit(nsecBunkerRelays).then(() => {
|
|
|
|
nostrController.createNsecBunkerSigner(usersPubkey)
|
|
|
|
})
|
|
|
|
}
|
2024-05-30 17:28:40 +00:00
|
|
|
|
|
|
|
const handleMetadataEvent = (event: Event) => {
|
|
|
|
dispatch(setMetadataEvent(event))
|
|
|
|
}
|
|
|
|
|
|
|
|
metadataController.on(usersPubkey, (kind: number, event: Event) => {
|
|
|
|
if (kind === kinds.Metadata) {
|
|
|
|
handleMetadataEvent(event)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
metadataController.findMetadata(usersPubkey).then((metadataEvent) => {
|
|
|
|
if (metadataEvent) handleMetadataEvent(metadataEvent)
|
|
|
|
})
|
2024-07-05 08:38:04 +00:00
|
|
|
} else {
|
|
|
|
setIsLoading(false)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
setIsLoading(false)
|
|
|
|
}
|
|
|
|
}, [dispatch])
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
let subCloser: SubCloser | null = null
|
|
|
|
|
|
|
|
if (authState.loggedIn && usersAppData) {
|
|
|
|
const pubkey = authState.usersPubkey || authState.keyPair?.public
|
|
|
|
|
|
|
|
if (pubkey) {
|
|
|
|
subscribeForSigits(pubkey).then((res) => {
|
|
|
|
subCloser = res || null
|
|
|
|
})
|
2024-04-08 12:45:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-05 08:38:04 +00:00
|
|
|
return () => {
|
|
|
|
if (subCloser) {
|
|
|
|
subCloser.close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, [authState, usersAppData])
|
2024-02-28 16:49:44 +00:00
|
|
|
|
2024-05-17 11:33:01 +00:00
|
|
|
/**
|
|
|
|
* When authState change user logged in / or app reloaded
|
|
|
|
* we set robohash avatar in the global state based on user npub
|
|
|
|
* so that avatar will be consistent across the app when kind 0 is empty
|
|
|
|
*/
|
|
|
|
useEffect(() => {
|
|
|
|
if (authState && authState.loggedIn) {
|
|
|
|
const pubkey = authState.usersPubkey || authState.keyPair?.public
|
2024-05-17 11:35:37 +00:00
|
|
|
|
2024-05-17 11:33:01 +00:00
|
|
|
if (pubkey) {
|
2024-05-17 11:35:37 +00:00
|
|
|
dispatch(setUserRobotImage(getRoboHashPicture(pubkey)))
|
2024-05-17 11:33:01 +00:00
|
|
|
}
|
2024-07-08 09:27:09 +00:00
|
|
|
|
|
|
|
setIsLoading(true)
|
2024-07-30 14:25:36 +00:00
|
|
|
setLoadingSpinnerDesc(`Loading SIGit History`)
|
2024-07-08 09:27:09 +00:00
|
|
|
getUsersAppData()
|
|
|
|
.then((appData) => {
|
|
|
|
if (appData) {
|
|
|
|
dispatch(updateUserAppData(appData))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.finally(() => setIsLoading(false))
|
2024-05-17 11:33:01 +00:00
|
|
|
}
|
|
|
|
}, [authState])
|
|
|
|
|
2024-07-05 08:38:04 +00:00
|
|
|
if (isLoading) return <LoadingSpinner desc={loadingSpinnerDesc} />
|
2024-04-08 12:45:51 +00:00
|
|
|
|
2024-02-28 16:49:44 +00:00
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<AppBar />
|
2024-07-25 13:05:47 +00:00
|
|
|
<main className={styles.main}>
|
|
|
|
<Outlet />
|
|
|
|
</main>
|
|
|
|
<Footer />
|
2024-02-28 16:49:44 +00:00
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|