Wire locale catalogs, repair mint terminology, and confirm login with a toast.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+51
-4
@@ -14,6 +14,7 @@ import { escapeHtml, iconGradient, shortNpub, truncateMiddle, wireCopyButtons }
|
||||
import { useI18n } from '../i18n/client';
|
||||
import type { Translator } from '../i18n/translate';
|
||||
import { closeModal, openModal, wireModal } from './modal';
|
||||
import { showToast, type Toast } from './toast';
|
||||
import {
|
||||
clearSession,
|
||||
connectBunker,
|
||||
@@ -310,14 +311,51 @@ function loggedInHtml(session: Session, npub: string, profile: Profile | null):
|
||||
);
|
||||
}
|
||||
|
||||
/** How long the login toast stays once it has nothing left to wait for. */
|
||||
const TOAST_SETTLED_MS = 3000;
|
||||
|
||||
/**
|
||||
* Say that the login landed, while the header cannot yet say it.
|
||||
*
|
||||
* The popup closes as soon as the signer answers, but the control it closes onto
|
||||
* still reads "Log in" until a kind 0 comes back from the relays: a round trip that
|
||||
* takes seconds on a cold cache and up to `PROFILE_TIMEOUT_MS` when a relay is dead.
|
||||
* Those seconds looked like a login that quietly failed, which is the one reading
|
||||
* that must never be available. So the toast confirms the half that is already true
|
||||
* and names what the other half is waiting on.
|
||||
*/
|
||||
function announceLogin(): Toast {
|
||||
const t = useI18n();
|
||||
return showToast({
|
||||
title: t('login.toast.loggedIn'),
|
||||
body: t('login.toast.fetchingProfile'),
|
||||
tone: 'busy',
|
||||
duration: null, // Pinned: the profile lookup below is what ends it.
|
||||
});
|
||||
}
|
||||
|
||||
/** Close the login toast out, saying who the relays turned out to name. */
|
||||
function settleLogin(toast: Toast, profile: Profile | null, t: Translator): void {
|
||||
const name = profileName(profile);
|
||||
toast.update({
|
||||
// The name is the reader's own, out of their kind 0. `showToast` sets it as text.
|
||||
body: name ? t('login.toast.profile', { name }) : t('login.toast.noProfile'),
|
||||
tone: 'done',
|
||||
duration: TOAST_SETTLED_MS,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the header for the session as it stands.
|
||||
*
|
||||
* Runs twice on a restored session: once from the cache, immediately, so the avatar
|
||||
* and name are there at first paint, and again if the relays turn up something newer.
|
||||
* Neither pass changes the control's height.
|
||||
*
|
||||
* `announce` is set only by a fresh login, never by a restore or a redraw: a toast on
|
||||
* every page arrival would be noise, and the wait it explains only exists once.
|
||||
*/
|
||||
async function renderHeader(): Promise<void> {
|
||||
async function renderHeader(announce = false): Promise<void> {
|
||||
const root = headerRoot();
|
||||
if (!root) return;
|
||||
|
||||
@@ -328,10 +366,17 @@ async function renderHeader(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
const toast = announce ? announceLogin() : null;
|
||||
|
||||
const npub = await toNpub(session.pubkey);
|
||||
const cached = await resolveProfile(session.pubkey);
|
||||
if (readSession()?.pubkey !== session.pubkey) return; // Logged out while we waited.
|
||||
if (readSession()?.pubkey !== session.pubkey) {
|
||||
// Logged out while we waited. Nothing left to confirm, so take the toast with it.
|
||||
toast?.dismiss();
|
||||
return;
|
||||
}
|
||||
root.innerHTML = loggedInHtml(session, npub, cached);
|
||||
if (toast) settleLogin(toast, cached, useI18n());
|
||||
}
|
||||
|
||||
function setMenu(open: boolean): void {
|
||||
@@ -397,8 +442,10 @@ export function initAuth(): void {
|
||||
if (wired) return;
|
||||
wired = true;
|
||||
|
||||
onSessionChange(() => {
|
||||
void renderHeader();
|
||||
onSessionChange((session) => {
|
||||
// A session arriving here is always a fresh login: it is emitted on write, and a
|
||||
// restored session is read, not written. A logout redraws without a toast.
|
||||
void renderHeader(session !== null);
|
||||
});
|
||||
|
||||
// The signer talks back through here: reconnecting, waiting, approve-in-a-window.
|
||||
|
||||
Reference in New Issue
Block a user