2024-02-28 16:49:44 +00:00
|
|
|
import { Box } from '@mui/material'
|
|
|
|
import Container from '@mui/material/Container'
|
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-05-16 14:45:00 +00:00
|
|
|
import { restoreState, setAuthState, setMetadataEvent } from '../store/actions'
|
2024-05-17 11:35:37 +00:00
|
|
|
import {
|
|
|
|
clearAuthToken,
|
|
|
|
clearState,
|
|
|
|
getRoboHashPicture,
|
|
|
|
loadState,
|
2024-06-28 09:24:14 +00:00
|
|
|
saveNsecBunkerDelegatedKey,
|
|
|
|
subscribeForSigits
|
2024-05-17 11:35:37 +00:00
|
|
|
} from '../utils'
|
2024-04-08 12:45:51 +00:00
|
|
|
import { LoadingSpinner } from '../components/LoadingSpinner'
|
|
|
|
import { Dispatch } from '../store/store'
|
2024-05-16 14:45:00 +00:00
|
|
|
import { MetadataController, NostrController } from '../controllers'
|
2024-04-08 12:45:51 +00:00
|
|
|
import { LoginMethods } from '../store/auth/types'
|
2024-05-17 11:33:01 +00:00
|
|
|
import { setUserRobotImage } from '../store/userRobotImage/action'
|
|
|
|
import { State } from '../store/rootReducer'
|
2024-05-30 17:28:40 +00:00
|
|
|
import { Event, kinds } from 'nostr-tools'
|
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-05-17 11:33:01 +00:00
|
|
|
const authState = useSelector((state: State) => state.auth)
|
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-04-08 12:45:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setIsLoading(false)
|
2024-02-28 16:49:44 +00:00
|
|
|
}, [dispatch])
|
|
|
|
|
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-06-28 09:24:14 +00:00
|
|
|
|
|
|
|
subscribeForSigits(pubkey)
|
2024-05-17 11:33:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}, [authState])
|
|
|
|
|
2024-05-15 08:50:21 +00:00
|
|
|
if (isLoading) return <LoadingSpinner desc="Loading App" />
|
2024-04-08 12:45:51 +00:00
|
|
|
|
2024-02-28 16:49:44 +00:00
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<AppBar />
|
|
|
|
|
2024-05-15 08:50:21 +00:00
|
|
|
<Box className="main">
|
2024-02-28 16:49:44 +00:00
|
|
|
<Container
|
|
|
|
sx={{
|
2024-04-08 12:45:51 +00:00
|
|
|
position: 'relative',
|
|
|
|
maxWidth: {
|
|
|
|
xs: '550px'
|
|
|
|
}
|
2024-02-28 16:49:44 +00:00
|
|
|
}}
|
|
|
|
>
|
|
|
|
<Outlet />
|
|
|
|
</Container>
|
|
|
|
</Box>
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|