summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/app.js
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/app.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/app.js20
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') {