diff --git a/README.md b/README.md index 26fe77b..a0ac9eb 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,10 @@ subscription records and nothing else. Account controls live in the popup header: a Sign in button when signed out, and your avatar and handle when signed in, opening a menu with Switch account and Sign out. The Sign in button expands into the handle form and then -submits it — it is the form's only button. A session that ends on its own +submits it — it is the form's only button. Switch account opens that same +form without signing you out: the current login stays valid until the +replacement sign-in completes, and only then is it revoked. Abandoning the +switch leaves you signed in as before. A session that ends on its own (expired or remotely revoked refresh token) is flagged once in that panel, so being signed out always has an explanation. diff --git a/src/popup/popup.ts b/src/popup/popup.ts index d75c461..f45b4d7 100644 --- a/src/popup/popup.ts +++ b/src/popup/popup.ts @@ -117,13 +117,15 @@ async function loadState(refresh: boolean) { } function renderAccount() { - $('signin-open').hidden = !!session $('account-btn').hidden = !session if (!session) { $('account-menu').hidden = true + $('signin-open').hidden = false return } - setSigninPanel(false) + // Keep the panel as it is: a profile refresh landing mid-switch must not + // close the form under the user. + setSigninPanel(!$('signin-panel').hidden) $('account-handle').textContent = `@${session.handle ?? session.did}` const img = $('account-avatar') const url = session.avatarUrl @@ -142,12 +144,16 @@ function renderAccount() { /** * The header Sign in button is the panel's only button: it expands into the * handle form, and once open it submits it. Everything that hides the panel - * must go through here so the button's state stays truthful. + * must go through here so the button's state stays truthful. While signed in + * the button appears only with the panel (the switch-account flow), so the + * form always has its submit button. */ function setSigninPanel(open: boolean) { + const opening = open && $('signin-panel').hidden $('signin-panel').hidden = !open + $('signin-open').hidden = !!session && !open $('signin-open').setAttribute('aria-expanded', String(open)) - if (open) $('handle-input').focus() + if (opening) $('handle-input').focus() } function openSigninPanel() { @@ -447,13 +453,12 @@ $('signin-form').addEventListener('submit', async (e) => { }) wireTypeaheadSubmit($('handle-input'), $('signin-form')) -$('switch-account').addEventListener('click', async (e) => { +// Just a shortcut into the sign-in form: the current login stays usable, and +// the worker revokes it only once the replacement sign-in completes +// (src/signin.ts). Closing the popup or the consent window changes nothing. +$('switch-account').addEventListener('click', (e) => { e.stopPropagation() - await invalidateSubsCache() - await signOut() - session = undefined - renderAccount() - render() + $('account-menu').hidden = true openSigninPanel() })