diff --git a/apps/akasha/src/components/app-routes.tsx b/apps/akasha/src/components/app-routes.tsx index fc20fad173..ef8e964d3c 100644 --- a/apps/akasha/src/components/app-routes.tsx +++ b/apps/akasha/src/components/app-routes.tsx @@ -27,9 +27,6 @@ const AppRoutes: React.FC = props => { profileService: sdkModules.profiles.profileService, }); - const pubKey = loginState.pubKey; - const ethAddress = loginState.ethAddress; - const [loginModalState, setLoginModalState] = React.useState(false); const [reportModalOpen, setReportModalOpen] = React.useState(false); const [flagged, setFlagged] = React.useState(''); @@ -48,17 +45,17 @@ const AppRoutes: React.FC = props => { }; React.useEffect(() => { - if (pubKey) { + if (loginState.pubKey) { setLoginModalState(false); } - }, [pubKey]); + }, [loginState.pubKey]); React.useEffect(() => { - if (ethAddress && flagged.length) { + if (loginState.ethAddress && flagged.length) { setLoginModalState(false); setReportModalOpen(true); } - }, [ethAddress]); + }, [loginState.ethAddress]); const loginErrors: string | null = React.useMemo(() => { if (errorState && Object.keys(errorState).length) { @@ -79,8 +76,8 @@ const AppRoutes: React.FC = props => { = props => { void; + onReady?: (data: boolean) => void; } const useGlobalLogin = (props: UseGlobalLoginProps): void => { @@ -39,6 +41,43 @@ const useGlobalLogin = (props: UseGlobalLoginProps): void => { call.subscribe(handleLoginSubscribe, createErrorHandler('useGlobalLogin.login')); return () => call.unsubscribe(); }, []); + React.useEffect(() => { + const waitForAuthCall = props.globalChannel.pipe( + filter((payload: any) => { + return ( + payload.channelInfo.method === 'waitForAuth' && + payload.channelInfo.servicePath.includes('AUTH_SERVICE') + ); + }), + ); + + waitForAuthCall.subscribe((payload: { data: boolean }) => { + const { data } = payload; + if (props.waitForAuth) { + props.waitForAuth(data); + } + }); + return () => waitForAuthCall.unsubscribe(); + }, []); + + React.useEffect(() => { + const readyCall = props.globalChannel.pipe( + filter((payload: any) => { + return ( + payload.channelInfo.method === 'ready' && + payload.channelInfo.servicePath.includes('AUTH_SERVICE') + ); + }), + ); + + readyCall.subscribe((payload: { data: boolean }) => { + const { data } = payload; + if (props.onReady) { + props.onReady(data); + } + }); + return () => readyCall.unsubscribe(); + }, []); React.useEffect(() => { const logoutCall = props.globalChannel.pipe( diff --git a/ui/hooks/src/use-login-state.ts b/ui/hooks/src/use-login-state.ts index 5fd164d9a8..781121a629 100644 --- a/ui/hooks/src/use-login-state.ts +++ b/ui/hooks/src/use-login-state.ts @@ -24,14 +24,21 @@ export interface UseLoginState { /* logged in user's ethAddress */ ethAddress: string | null; pubKey: string | null; + /** + * check if the user is fully logged in or not + * check this flag whenever you need to make sure + * that the user login status is settled + * defaults to false + */ + currentUserCalled: boolean; + ready: boolean | null; + waitForAuth: boolean | null; } export interface UseLoginActions { /* Login */ login: (provider: EthProviders) => void; /* Logout */ logout: () => void; - /* call this before showing the profile form */ - resetUpdateStatus: () => void; } const useLoginState = (props: UseLoginProps): [UseLoginState, UseLoginActions] => { @@ -39,42 +46,61 @@ const useLoginState = (props: UseLoginProps): [UseLoginState, UseLoginActions] = const [loginState, setLoginState] = React.useState({ ethAddress: null, pubKey: null, + currentUserCalled: false, + ready: null, + waitForAuth: null, }); // this will also reset profile data useGlobalLogin({ globalChannel, onLogin: payload => - setLoginState({ + setLoginState(prev => ({ + ...prev, ethAddress: payload.ethAddress, pubKey: payload.pubKey, - }), + })), + waitForAuth: data => + setLoginState(prev => ({ + ...prev, + waitForAuth: data, + })), + onReady: data => setLoginState(prev => ({ ...prev, ready: data })), onLogout: () => { if (props.onLogout) { props.onLogout(); } - setLoginState({ + setLoginState(prev => ({ + ...prev, ethAddress: null, pubKey: null, - }); + ready: null, + })); }, onError: payload => { createErrorHandler('useLoginState.globalLogin', false, onError)(payload.error); }, }); - React.useEffect(() => { + React.useLayoutEffect(() => { // make an attempt to load the eth address from cache; if (authService) { const getDeps = authService.getCurrentUser(null); getDeps.subscribe((resp: { data: any }) => { const { data } = resp; - if (data?.ethAddress && data?.pubKey) { - setLoginState(prev => ({ + setLoginState(prev => { + if (!data) { + return { + ...prev, + currentUserCalled: true, + }; + } + return { ...prev, + currentUserCalled: true, ethAddress: data.ethAddress, pubKey: data.pubKey, - })); - } + }; + }); }, createErrorHandler('useLoginState.authService', false, onError)); } }, []); @@ -122,17 +148,6 @@ const useLoginState = (props: UseLoginProps): [UseLoginState, UseLoginActions] = }, ); }, - resetUpdateStatus() { - setLoginState(prev => ({ - ...prev, - updateStatus: { - updateComplete: false, - saving: false, - uploadingAvatar: false, - uploadingCoverImage: false, - }, - })); - }, }; return [loginState, actions]; }; diff --git a/ui/plugins/profile/src/components/profile-cards/profile-card.tsx b/ui/plugins/profile/src/components/profile-cards/profile-card.tsx index 8d59f7bb8e..3b5a978da0 100644 --- a/ui/plugins/profile/src/components/profile-cards/profile-card.tsx +++ b/ui/plugins/profile/src/components/profile-cards/profile-card.tsx @@ -222,7 +222,6 @@ export const ProfilePageCard = (props: IProfileHeaderProps & RootComponentProps) }; const showUpdateProfileModal = () => { - props.loginActions.resetUpdateStatus(); props.modalActions.show(MODAL_NAMES.PROFILE_UPDATE); };