diff --git a/lib/hooks/invite-links.js b/lib/hooks/invite-links.js --- a/lib/hooks/invite-links.js +++ b/lib/hooks/invite-links.js @@ -126,10 +126,6 @@ ); } -const joinThreadLoadingStatusSelector = createLoadingStatusSelector( - joinThreadActionTypes, -); - export type LinkStatus = 'invalid' | 'valid' | 'timed_out' | 'already_joined'; const inviteLinkTexts: { @@ -163,6 +159,7 @@ +keyserverOverride: ?KeyserverOverride, +calendarQuery: () => CalendarQuery, +closeModal: () => mixed, + +linkStatus: LinkStatus, +setLinkStatus: SetState, +navigateToThread: ThreadInfo => mixed, }; @@ -176,6 +173,7 @@ keyserverOverride, calendarQuery, closeModal, + linkStatus, setLinkStatus, navigateToThread, } = params; @@ -211,6 +209,13 @@ } }; }, []); + const [step, setStep] = React.useState< + | 'inactive' + | 'add_keyserver' + | 'auth_to_keyserver' + | 'join_community' + | 'finished', + >('inactive'); const createJoinPromise = React.useCallback(() => { return new Promise((resolve, reject) => { @@ -247,14 +252,20 @@ reject: rejectAndClearTimeout, communityID, }); + setStep('add_keyserver'); }); }, [communityID, keyserverID, setLinkStatus]); React.useEffect(() => { void (async () => { - if (!ongoingJoinData || isKeyserverKnown) { + if (!ongoingJoinData || step !== 'add_keyserver') { return; } + if (isKeyserverKnown) { + setStep('auth_to_keyserver'); + return; + } + const isValid = await isKeyserverURLValid(); if (!isValid || !keyserverURL) { setLinkStatus('invalid'); @@ -274,17 +285,23 @@ dispatch, isKeyserverKnown, isKeyserverURLValid, - ongoingJoinData, keyserverID, keyserverURL, + ongoingJoinData, setLinkStatus, + step, ]); + React.useEffect(() => { + if (step === 'auth_to_keyserver' && ongoingJoinData && isAuthenticated) { + setStep('join_community'); + } + }, [isAuthenticated, ongoingJoinData, step]); + const dispatchActionPromise = useDispatchActionPromise(); - const [joined, setJoined] = React.useState(false); React.useEffect(() => { void (async () => { - if (!ongoingJoinData || !isAuthenticated) { + if (!ongoingJoinData || step !== 'join_community') { return; } const threadID = ongoingJoinData.communityID; @@ -305,7 +322,7 @@ try { await joinThreadPromise; - setJoined(true); + setStep('finished'); ongoingJoinData.resolve(); } catch (e) { setLinkStatus(status => (status === 'valid' ? 'invalid' : status)); @@ -319,14 +336,14 @@ callJoinThread, dispatchActionPromise, inviteSecret, - isAuthenticated, ongoingJoinData, setLinkStatus, + step, ]); const threadInfos = useSelector(threadInfoSelector); React.useEffect(() => { - if (!joined) { + if (step !== 'finished') { return; } const threadID = verificationResponse.community?.id; @@ -336,14 +353,19 @@ } navigateToThread(threadInfos[threadID]); }, [ - joined, - navigateToThread, closeModal, + navigateToThread, + step, threadInfos, verificationResponse.community?.id, ]); - const joinLoadingStatus = useSelector(joinThreadLoadingStatusSelector); + let joinLoadingStatus: LoadingStatus = 'inactive'; + if (linkStatus === 'invalid' || linkStatus === 'timed_out') { + joinLoadingStatus = 'error'; + } else if (step !== 'inactive' && step !== 'finished') { + joinLoadingStatus = 'loading'; + } return React.useMemo( () => ({ diff --git a/native/navigation/invite-link-modal.react.js b/native/navigation/invite-link-modal.react.js --- a/native/navigation/invite-link-modal.react.js +++ b/native/navigation/invite-link-modal.react.js @@ -65,6 +65,7 @@ keyserverOverride, calendarQuery, closeModal: props.navigation.goBack, + linkStatus, setLinkStatus, navigateToThread, }); diff --git a/web/invite-links/accept-invite-modal.react.js b/web/invite-links/accept-invite-modal.react.js --- a/web/invite-links/accept-invite-modal.react.js +++ b/web/invite-links/accept-invite-modal.react.js @@ -58,6 +58,7 @@ keyserverOverride, calendarQuery, closeModal: popModal, + linkStatus, setLinkStatus, navigateToThread, });