Browse Source

fallback to npub, when Amber session breaks

master
silberengel 8 months ago
parent
commit
14246339b0
  1. 64
      src/lib/components/LoginMenu.svelte
  2. 3
      src/lib/stores/userStore.ts
  3. 37
      src/routes/+layout.ts

64
src/lib/components/LoginMenu.svelte

@ -17,17 +17,39 @@
let loginButtonRef: HTMLElement | undefined = $state(); let loginButtonRef: HTMLElement | undefined = $state();
let resultTimeout: ReturnType<typeof setTimeout> | null = null; let resultTimeout: ReturnType<typeof setTimeout> | null = null;
let profileAvatarId = 'profile-avatar-btn'; let profileAvatarId = 'profile-avatar-btn';
let showAmberReconnect = $state(false); let showAmberFallback = $state(false);
let fallbackCheckInterval: ReturnType<typeof setInterval> | null = null;
onMount(() => { onMount(() => {
if (localStorage.getItem('alexandria/amber/reconnect') === '1') { if (localStorage.getItem('alexandria/amber/fallback') === '1') {
showAmberReconnect = true; console.log('LoginMenu: Found fallback flag on mount, showing modal');
showAmberFallback = true;
} }
}); });
// Subscribe to userStore // Subscribe to userStore
let user = $state(get(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 // Generate QR code
const generateQrCode = async (text: string): Promise<string> => { const generateQrCode = async (text: string): Promise<string> => {
@ -122,16 +144,21 @@
const handleLogout = () => { const handleLogout = () => {
localStorage.removeItem('amber/nsec'); localStorage.removeItem('amber/nsec');
localStorage.removeItem('alexandria/amber/reconnect'); localStorage.removeItem('alexandria/amber/fallback');
logoutUser(); logoutUser();
}; };
function handleAmberReconnect() { function handleAmberReconnect() {
showAmberReconnect = false; showAmberFallback = false;
localStorage.removeItem('alexandria/amber/reconnect'); localStorage.removeItem('alexandria/amber/fallback');
handleAmberLogin(); handleAmberLogin();
} }
function handleAmberFallbackDismiss() {
showAmberFallback = false;
localStorage.removeItem('alexandria/amber/fallback');
}
function shortenNpub(long: string | undefined) { function shortenNpub(long: string | undefined) {
if (!long) return ''; if (!long) return '';
return long.slice(0, 8) + '…' + long.slice(-4); return long.slice(0, 8) + '…' + long.slice(-4);
@ -237,6 +264,17 @@
{user.npub ? shortenNpub(user.npub) : 'Unknown'} {user.npub ? shortenNpub(user.npub) : 'Unknown'}
</button> </button>
</li> </li>
<li class="text-xs text-gray-500">
{#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}
</li>
<li> <li>
<button <button
id='sign-out-button' id='sign-out-button'
@ -305,14 +343,14 @@
</div> </div>
{/if} {/if}
{#if showAmberReconnect} {#if showAmberFallback}
<div class="fixed inset-0 bg-black bg-opacity-40 flex items-center justify-center z-50"> <div class="fixed inset-0 bg-black bg-opacity-40 flex items-center justify-center z-50">
<div class="bg-white rounded-lg p-6 max-w-md w-full mx-4 shadow-lg border border-primary-300"> <div class="bg-white rounded-lg p-6 max-w-md w-full mx-4 shadow-lg border border-primary-300">
<div class="text-center"> <div class="text-center">
<h2 class="text-lg font-semibold text-gray-900 mb-4">Reconnect Amber Wallet</h2> <h2 class="text-lg font-semibold text-gray-900 mb-4">Amber Session Restored</h2>
<p class="text-sm text-gray-600 mb-4"> <p class="text-sm text-gray-600 mb-4">
Your Amber wallet session could not be restored automatically.<br/> Your Amber wallet session could not be restored automatically, so you've been switched to read-only mode.<br/>
Please reconnect your Amber wallet to continue. You can still browse and read content, but you'll need to reconnect Amber to publish or comment.
</p> </p>
<button <button
class="mt-4 bg-primary-600 hover:bg-primary-700 text-white px-4 py-2 rounded text-sm font-medium transition-colors" class="mt-4 bg-primary-600 hover:bg-primary-700 text-white px-4 py-2 rounded text-sm font-medium transition-colors"
@ -322,9 +360,9 @@
</button> </button>
<button <button
class="mt-2 ml-4 bg-gray-300 hover:bg-gray-400 text-gray-800 px-4 py-2 rounded text-sm font-medium transition-colors" class="mt-2 ml-4 bg-gray-300 hover:bg-gray-400 text-gray-800 px-4 py-2 rounded text-sm font-medium transition-colors"
onclick={() => { showAmberReconnect = false; localStorage.removeItem('alexandria/amber/reconnect'); }} onclick={handleAmberFallbackDismiss}
> >
Cancel Continue in Read-Only Mode
</button> </button>
</div> </div>
</div> </div>

3
src/lib/stores/userStore.ts

@ -272,6 +272,9 @@ export function logoutUser() {
localStorage.removeItem(key); localStorage.removeItem(key);
}); });
// Clear Amber-specific flags
localStorage.removeItem('alexandria/amber/fallback');
// Set a flag to prevent auto-login on next page load // Set a flag to prevent auto-login on next page load
localStorage.setItem('alexandria/logout/flag', 'true'); localStorage.setItem('alexandria/logout/flag', 'true');

37
src/routes/+layout.ts

@ -49,15 +49,40 @@ export const load: LayoutLoad = () => {
await loginWithAmber(amberSigner, user); await loginWithAmber(amberSigner, user);
console.log('Amber session restored.'); console.log('Amber session restored.');
} catch (err) { } catch (err) {
// If reconnection fails, show a non-blocking prompt (handled in LoginMenu UI) // If reconnection fails, automatically fallback to npub-only mode
console.warn('Amber session could not be restored. Prompting user to reconnect.'); console.warn('Amber session could not be restored. Falling back to npub-only mode.');
// Optionally, set a flag in localStorage or a Svelte store to show a reconnect banner/modal try {
localStorage.setItem('alexandria/amber/reconnect', '1'); // 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 { } else {
// No session data, prompt user to reconnect (handled in LoginMenu UI) // No session data, automatically fallback to npub-only mode
localStorage.setItem('alexandria/amber/reconnect', '1'); 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') { } else if (loginMethod === 'npub') {
console.log('Restoring npub login...'); console.log('Restoring npub login...');

Loading…
Cancel
Save