diff --git a/web/app.react.js b/web/app.react.js --- a/web/app.react.js +++ b/web/app.react.js @@ -37,6 +37,7 @@ import { initOpaque } from './crypto/opaque-utils.js'; import electron from './electron.js'; import InputStateContainer from './input/input-state-container.react.js'; +import InviteLinkHandler from './invite-links/invite-link-handler.react.js'; import LoadingIndicator from './loading-indicator.react.js'; import { MenuProvider } from './menu-provider.react.js'; import UpdateModalHandler from './modals/update-modal.react.js'; @@ -169,6 +170,7 @@ + {content} {this.props.modals} diff --git a/web/invite-links/invite-link-handler.react.js b/web/invite-links/invite-link-handler.react.js new file mode 100644 --- /dev/null +++ b/web/invite-links/invite-link-handler.react.js @@ -0,0 +1,63 @@ +// @flow + +import * as React from 'react'; +import { useDispatch } from 'react-redux'; + +import { + verifyInviteLink, + verifyInviteLinkActionTypes, +} from 'lib/actions/link-actions.js'; +import { useModalContext } from 'lib/components/modal-provider.react.js'; +import { isLoggedIn } from 'lib/selectors/user-selectors.js'; +import { + useDispatchActionPromise, + useServerCall, +} from 'lib/utils/action-utils.js'; + +import AcceptInviteModal from './accept-invite-modal.react.js'; +import { updateNavInfoActionType } from '../redux/action-types.js'; +import { useSelector } from '../redux/redux-utils.js'; + +function InviteLinkHandler(): null { + const inviteSecret = useSelector(state => state.navInfo.inviteSecret); + const loggedIn = useSelector(isLoggedIn); + + const dispatchActionPromise = useDispatchActionPromise(); + const dispatch = useDispatch(); + const validateLink = useServerCall(verifyInviteLink); + const { pushModal } = useModalContext(); + React.useEffect(() => { + if (!inviteSecret || !loggedIn) { + return; + } + dispatch({ + type: updateNavInfoActionType, + payload: { inviteSecret: null }, + }); + const validateLinkPromise = validateLink({ secret: inviteSecret }); + dispatchActionPromise(verifyInviteLinkActionTypes, validateLinkPromise); + (async () => { + const result = await validateLinkPromise; + if (result.status === 'already_joined') { + return; + } + pushModal( + , + ); + })(); + }, [ + dispatch, + dispatchActionPromise, + inviteSecret, + loggedIn, + pushModal, + validateLink, + ]); + + return null; +} + +export default InviteLinkHandler;