diff --git a/public/assets/my.js b/public/assets/my.js index 043627a..b455f92 100644 --- a/public/assets/my.js +++ b/public/assets/my.js @@ -523,12 +523,18 @@ if ($('mcFinish')) $('mcFinish').hidden = !walletOnly; if (!signedIn) return; if ($('adminLink')) $('adminLink').hidden = !me.isAdmin; // admin portal link, only for ADMIN_EMAIL - // arrived from an invite page: run onboarding once (username, welcome tour, login ad) + // REQUIRED first step (Marty, 2026-09-12): no username, nothing else. The modal cannot be + // skipped or dismissed; it resolves only when a username is saved, then the area renders. + if (!me.username) { + if (!render.gating) { render.gating = true; showOnboard(true).then(() => { render.gating = false; render(); }); } + return; + } + // arrived from an invite page: run the welcome tour and login ad once if (/[?&]welcome=1/.test(location.search) && !render.welcomed) { render.welcomed = true; history.replaceState(null, '', '/my' + (location.hash || '')); (async () => { - try { if (!me.username) await showOnboard(); if (!(await showGauntlet())) await showLoginAd(); } catch (e) {} + try { if (!(await showGauntlet())) await showLoginAd(); } catch (e) {} await render(); })(); } @@ -1771,15 +1777,23 @@ })); })(); - // new-member onboarding: choose a username, optionally a bio (both skippable) - function showOnboard() { + // new-member onboarding: choose a username (required), optionally a bio. + // required=true: no skip, no backdrop dismiss, prefilled suggestion, resolves only after a save. + function showOnboard(required) { return new Promise(resolve => { const m = $('onboardModal'); if (!m) return resolve(); m.hidden = false; $('obErr').hidden = true; + $('obSkip').hidden = !!required; + if (required && !$('obUsername').value) { + fetch('/api/my/username-suggest').then(r => r.json()).then(r => { if (r.suggest && !$('obUsername').value) { $('obUsername').value = r.suggest; $('obUsername').select(); } }).catch(() => {}); + } + setTimeout(() => $('obUsername').focus(), 50); const done = () => { m.hidden = true; resolve(); }; - $('obSkip').onclick = done; + $('obSkip').onclick = required ? null : done; + $('obUsername').onkeydown = e => { if (e.key === 'Enter') { e.preventDefault(); $('obSave').click(); } }; $('obSave').onclick = async () => { const u = $('obUsername').value.trim(); + if (required && !u) { $('obErr').hidden = false; $('obErr').textContent = 'Pick a username to continue.'; return; } try { if (u) await api('/api/my/profile', { username: u }); const bio = $('obBio').value.trim(); diff --git a/public/my.html b/public/my.html index 2e716c2..1044511 100644 --- a/public/my.html +++ b/public/my.html @@ -98,15 +98,15 @@