From 23a04faad89ae3138008f4b1b9a112bf944f279b Mon Sep 17 00:00:00 2001 From: enes Date: Tue, 8 Oct 2024 18:50:33 +0200 Subject: [PATCH] refactor(auth): main effect order and deps --- src/controllers/AuthController.ts | 2 +- src/layouts/Main.tsx | 207 ++++++++++++++---------------- 2 files changed, 100 insertions(+), 109 deletions(-) diff --git a/src/controllers/AuthController.ts b/src/controllers/AuthController.ts index bd8c021..6536e19 100644 --- a/src/controllers/AuthController.ts +++ b/src/controllers/AuthController.ts @@ -86,7 +86,7 @@ export class AuthController { return Promise.resolve(appPrivateRoutes.relays) } - if (store.getState().auth?.loggedIn) { + if (store.getState().auth.loggedIn) { if (!compareObjects(store.getState().relays?.map, relayMap.map)) store.dispatch(setRelayMapAction(relayMap.map)) } diff --git a/src/layouts/Main.tsx b/src/layouts/Main.tsx index 2fed6c9..9cdc549 100644 --- a/src/layouts/Main.tsx +++ b/src/layouts/Main.tsx @@ -37,8 +37,8 @@ export const MainLayout = () => { const logout = useLogout() const [isLoading, setIsLoading] = useState(true) const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState(`Loading App`) + const isLoggedIn = useAppSelector((state) => state.auth?.loggedIn) const authState = useAppSelector((state) => state.auth) - const usersAppData = useAppSelector((state) => state.userAppData) // Ref to track if `subscribeForSigits` has been called const hasSubscribed = useRef(false) @@ -72,104 +72,6 @@ export const MainLayout = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [dispatch]) - useEffect(() => { - const handleNostrAuth = (_: string, opts: NostrLoginAuthOptions) => { - if (opts.type === 'logout') { - logout() - } else { - dispatch(updateNostrLoginAuthMethod(opts.method)) - login() - } - } - - ;(async () => { - try { - const options = { - methods: ['connect', 'extension', 'local'], - noBanner: true, - onAuth: handleNostrAuth - } - await initNostrLogin(options) - console.log('Nostr-Login initialized successfully') - } catch (error) { - console.error('Failed to initialize Nostr-Login', error) - } - })() - }, [dispatch, login, logout]) - - useEffect(() => { - const metadataController = MetadataController.getInstance() - - const restoredState = loadState() - if (restoredState) { - dispatch(restoreState(restoredState)) - - const { loggedIn, loginMethod, usersPubkey } = restoredState.auth - - if (loggedIn) { - if (!loginMethod || !usersPubkey) return logout() - - 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) - }) - } else { - setIsLoading(false) - } - } else { - setIsLoading(false) - } - }, [dispatch, logout]) - - useEffect(() => { - if (authState && authState.loggedIn && usersAppData) { - const pubkey = authState.usersPubkey || authState.keyPair?.public - - if (pubkey && !hasSubscribed.current) { - // Call `subscribeForSigits` only if it hasn't been called before - // #193 disabled websocket subscribtion, until #194 is done - subscribeForSigits(pubkey) - - // Mark `subscribeForSigits` as called - hasSubscribed.current = true - } - } - }, [authState, usersAppData]) - - /** - * 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 - - if (pubkey) { - dispatch(setUserRobotImage(getRoboHashPicture(pubkey))) - } - - setIsLoading(true) - setLoadingSpinnerDesc(`Loading SIGit history...`) - getUsersAppData() - .then((appData) => { - if (appData) { - dispatch(updateUserAppData(appData)) - } - }) - .finally(() => setIsLoading(false)) - } - }, [authState, dispatch]) - useEffect(() => { // Developer login with ?nsec= (not recommended) const nsec = searchParams.get('nsec') @@ -201,15 +103,14 @@ export const MainLayout = () => { }) ) dispatch(updateLoginMethod(LoginMethod.privateKey)) - ;(async () => { - const authController = new AuthController() - await authController - .authAndGetMetadataAndRelaysMap(publickey) - .catch((err) => { - console.error('Error occurred in authentication: ' + err) - return null - }) - })() + + const authController = new AuthController() + authController + .authAndGetMetadataAndRelaysMap(publickey) + .catch((err) => { + console.error('Error occurred in authentication: ' + err) + return null + }) } catch (err) { console.error(`Error decoding the nsec. ${err}`) } @@ -217,6 +118,96 @@ export const MainLayout = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [dispatch, searchParams]) + useEffect(() => { + const handleNostrAuth = (_: string, opts: NostrLoginAuthOptions) => { + if (opts.type === 'login' || opts.type === 'signup') { + dispatch(updateNostrLoginAuthMethod(opts.method)) + login() + } + } + + // Initialize the nostr-login + initNostrLogin({ + methods: ['connect', 'extension', 'local'], + noBanner: true, + onAuth: handleNostrAuth + }).catch((error) => { + console.error('Failed to initialize Nostr-Login', error) + }) + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [dispatch]) + + useEffect(() => { + const metadataController = MetadataController.getInstance() + + const restoredState = loadState() + if (restoredState) { + dispatch(restoreState(restoredState)) + + const { loggedIn, loginMethod, usersPubkey } = restoredState.auth + + if (loggedIn) { + if (!loginMethod || !usersPubkey) return logout() + + // Update user profile metadata, old state might be outdated + 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) + }) + } else { + setIsLoading(false) + } + } else { + setIsLoading(false) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [dispatch]) + + /** + * 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 && isLoggedIn) { + const pubkey = authState.usersPubkey || authState.keyPair?.public + + if (pubkey && !hasSubscribed.current) { + // Call `subscribeForSigits` only if it hasn't been called before + // #193 disabled websocket subscribtion, until #194 is done + subscribeForSigits(pubkey) + + // Mark `subscribeForSigits` as called + hasSubscribed.current = true + } + + if (pubkey) { + dispatch(setUserRobotImage(getRoboHashPicture(pubkey))) + } + + setIsLoading(true) + setLoadingSpinnerDesc(`Loading SIGit history...`) + getUsersAppData() + .then((appData) => { + if (appData) { + dispatch(updateUserAppData(appData)) + } + }) + .finally(() => setIsLoading(false)) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [dispatch, isLoggedIn]) + if (isLoading) return const isDev = import.meta.env.MODE === 'development'