diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/app.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/app.js | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/app.js b/packages/meshbay-hub/src/meshbay_hub/static/app.js index fbfb942..a757e61 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/app.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/app.js @@ -1,3 +1,6 @@ +// First, on purpose: loading it takes an invitation link out of the address +// before anything else here can read, log or route on it (invite-link.js). +import { clearPending, loadPending } from './invite-link.js'; import { html, render, useState, useEffect, useLayoutEffect, useCallback, useRef, createContext, useContext, @@ -29,6 +32,7 @@ import { ProfilePage } from './profile-page.js'; import { ExplorePage } from './explore-page.js'; import { GroupName } from './group-name.js'; import { FirstRunPage, LoginPage, RegisterPage, ResetPasswordPage } from './auth-page.js'; +import { InvitePage, JoinByLink } from './invite-page.js'; // ── Constants ──────────────────────────────────────────────────────────────── @@ -536,6 +540,7 @@ function HomePage({ groups, notifications, onMarkRead, onPurge, allowPublicGroup <h2>${t('home.welcome')}</h2> <${NotificationFeed} notifications=${notifications} onMarkRead=${onMarkRead} onPurge=${onPurge} /> + <${JoinByLink} hubOrigin=${platform.hubOrigin()} /> <p class="page-message"> ${t('home.no_groups')} ${' '}${allowPublicGroups @@ -568,6 +573,7 @@ function HomePage({ groups, notifications, onMarkRead, onPurge, allowPublicGroup </a> `)} </div> + <${JoinByLink} hubOrigin=${platform.hubOrigin()} /> </div> `; } @@ -680,7 +686,8 @@ function App() { // flow signs in half-way and still has its progress and result to show. const onAuthForm = route === '/login' || route === '/register'; useEffect(() => { - if (user && onAuthForm) window.location.replace('#/'); + // An invitation waiting in this tab is where a sign-in was headed. + if (user && onAuthForm) window.location.replace(loadPending() ? '#/invite' : '#/'); }, [user, onAuthForm]); // A desktop build with a remembered device signs in without asking. Null // until it has tried, so nothing renders a sign-in form the user is about to @@ -1091,6 +1098,8 @@ function App() { // Revoked on the hub too, so a copy of the refresh token is worth // nothing. Read before the next line clears it. logoutOnHub(); + // An invitation belongs to whoever was about to use it, not to the tab. + clearPending(); setAuth(null); setUser(null); setGroups([]); @@ -1136,6 +1145,15 @@ function App() { : route === '/reset' ? html`<${ResetPasswordPage} onLogin=${authCtx.login} />` : html`<${LoginPage} onLogin=${authCtx.login} />`; + } else if (route === '/invite') { + // Signed in or not: signed out, it explains and sends to register or sign + // in; signed in, it asks the hub what the ticket is for. + page = html`<${InvitePage} user=${user} onJoined=${async () => { + try { + const data = await hubFetch('/v1/groups/mine', { token: user.token }); + setGroups(data.groups || []); + } catch { /* the group page fetches what it needs */ } + }} />`; } else if (!user) { page = html`<${LoginPage} onLogin=${authCtx.login} />`; } else if (route === '/search') { |