From 14246339b0471225aad43019e5fd45d87c6eff2b Mon Sep 17 00:00:00 2001 From: silberengel Date: Wed, 16 Jul 2025 19:21:30 +0200 Subject: [PATCH] fallback to npub, when Amber session breaks --- src/lib/components/LoginMenu.svelte | 64 +++++++++++++++++++++++------ src/lib/stores/userStore.ts | 3 ++ src/routes/+layout.ts | 37 ++++++++++++++--- 3 files changed, 85 insertions(+), 19 deletions(-) diff --git a/src/lib/components/LoginMenu.svelte b/src/lib/components/LoginMenu.svelte index c5a037a..a1fa14e 100644 --- a/src/lib/components/LoginMenu.svelte +++ b/src/lib/components/LoginMenu.svelte @@ -17,17 +17,39 @@ let loginButtonRef: HTMLElement | undefined = $state(); let resultTimeout: ReturnType | null = null; let profileAvatarId = 'profile-avatar-btn'; - let showAmberReconnect = $state(false); + let showAmberFallback = $state(false); + let fallbackCheckInterval: ReturnType | null = null; onMount(() => { - if (localStorage.getItem('alexandria/amber/reconnect') === '1') { - showAmberReconnect = true; + if (localStorage.getItem('alexandria/amber/fallback') === '1') { + console.log('LoginMenu: Found fallback flag on mount, showing modal'); + showAmberFallback = true; } }); // Subscribe to userStore let user = $state(get(userStore)); - userStore.subscribe(val => user = val); + userStore.subscribe(val => { + user = val; + // Check for fallback flag when user state changes to signed in + if (val.signedIn && localStorage.getItem('alexandria/amber/fallback') === '1' && !showAmberFallback) { + console.log('LoginMenu: User signed in and fallback flag found, showing modal'); + showAmberFallback = true; + } + + // Set up periodic check when user is signed in + if (val.signedIn && !fallbackCheckInterval) { + fallbackCheckInterval = setInterval(() => { + if (localStorage.getItem('alexandria/amber/fallback') === '1' && !showAmberFallback) { + console.log('LoginMenu: Found fallback flag during periodic check, showing modal'); + showAmberFallback = true; + } + }, 500); // Check every 500ms + } else if (!val.signedIn && fallbackCheckInterval) { + clearInterval(fallbackCheckInterval); + fallbackCheckInterval = null; + } + }); // Generate QR code const generateQrCode = async (text: string): Promise => { @@ -122,16 +144,21 @@ const handleLogout = () => { localStorage.removeItem('amber/nsec'); - localStorage.removeItem('alexandria/amber/reconnect'); + localStorage.removeItem('alexandria/amber/fallback'); logoutUser(); }; function handleAmberReconnect() { - showAmberReconnect = false; - localStorage.removeItem('alexandria/amber/reconnect'); + showAmberFallback = false; + localStorage.removeItem('alexandria/amber/fallback'); handleAmberLogin(); } + function handleAmberFallbackDismiss() { + showAmberFallback = false; + localStorage.removeItem('alexandria/amber/fallback'); + } + function shortenNpub(long: string | undefined) { if (!long) return ''; return long.slice(0, 8) + '…' + long.slice(-4); @@ -237,6 +264,17 @@ {user.npub ? shortenNpub(user.npub) : 'Unknown'} +
  • + {#if user.loginMethod === 'extension'} + Logged in with extension + {:else if user.loginMethod === 'amber'} + Logged in with Amber + {:else if user.loginMethod === 'npub'} + Logged in with npub + {:else} + Unknown login method + {/if} +
  • diff --git a/src/lib/stores/userStore.ts b/src/lib/stores/userStore.ts index 3e3d77f..69e628b 100644 --- a/src/lib/stores/userStore.ts +++ b/src/lib/stores/userStore.ts @@ -272,6 +272,9 @@ export function logoutUser() { localStorage.removeItem(key); }); + // Clear Amber-specific flags + localStorage.removeItem('alexandria/amber/fallback'); + // Set a flag to prevent auto-login on next page load localStorage.setItem('alexandria/logout/flag', 'true'); diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts index 4744b85..df15c76 100644 --- a/src/routes/+layout.ts +++ b/src/routes/+layout.ts @@ -49,15 +49,40 @@ export const load: LayoutLoad = () => { await loginWithAmber(amberSigner, user); console.log('Amber session restored.'); } catch (err) { - // If reconnection fails, show a non-blocking prompt (handled in LoginMenu UI) - console.warn('Amber session could not be restored. Prompting user to reconnect.'); - // Optionally, set a flag in localStorage or a Svelte store to show a reconnect banner/modal - localStorage.setItem('alexandria/amber/reconnect', '1'); + // If reconnection fails, automatically fallback to npub-only mode + console.warn('Amber session could not be restored. Falling back to npub-only mode.'); + try { + // Set the flag first, before login + localStorage.setItem('alexandria/amber/fallback', '1'); + console.log('Set fallback flag in localStorage'); + + // Small delay to ensure flag is set + await new Promise(resolve => setTimeout(resolve, 100)); + + await loginWithNpub(pubkey); + console.log('Successfully fell back to npub-only mode.'); + } catch (fallbackErr) { + console.error('Failed to fallback to npub-only mode:', fallbackErr); + } } }); } else { - // No session data, prompt user to reconnect (handled in LoginMenu UI) - localStorage.setItem('alexandria/amber/reconnect', '1'); + // No session data, automatically fallback to npub-only mode + console.log('No Amber session data found. Falling back to npub-only mode.'); + + // Set the flag first, before login + localStorage.setItem('alexandria/amber/fallback', '1'); + console.log('Set fallback flag in localStorage'); + + // Small delay to ensure flag is set + setTimeout(async () => { + try { + await loginWithNpub(pubkey); + console.log('Successfully fell back to npub-only mode.'); + } catch (fallbackErr) { + console.error('Failed to fallback to npub-only mode:', fallbackErr); + } + }, 100); } } else if (loginMethod === 'npub') { console.log('Restoring npub login...');