fix(spa): back button respects history; auto-redirect / → /hjem when logged in
Two related navigation fixes: 1. Back-button now uses real browser history. Sub-view "Tilbake" buttons (permalink, tag page, personvern, public list) all used to call goPublicHome() — which always sent the user to / — instead of returning to wherever they came from. Replaced with a single backToCallerOrHome() that delegates to navigate.goBack(fallback), which calls window.history.back() if there's a prior entry, else navigates to /hjem (or / when anonymous) so cold-loaded permalinks still have somewhere to go. 2. Cold-load redirect: a logged-in user landing on / probably wants their own dashboard, not the public marketing surface. After the me-probe finishes in onMount, if the initial route was 'public-home' and session.user exists, push to /hjem instead of applying the public-home route. This only runs on initial mount (not on every popstate), so browser-back from /hjem to / still works if the user explicitly navigates there. The wordmark in the nav also picks its destination by auth state now — logged-in users go to /hjem, anonymous users to /. Otherwise clicking it post-redirect would just bounce back to /hjem.
This commit is contained in:
parent
834abfdfb0
commit
443702d222
2 changed files with 46 additions and 17 deletions
|
|
@ -3,6 +3,7 @@
|
|||
import { ready } from './lib/crypto';
|
||||
import { api, ApiError } from './lib/api';
|
||||
import { session, setSessionUserOnly } from './lib/session.svelte';
|
||||
import { goBack } from './lib/navigate';
|
||||
import { logout } from './lib/auth';
|
||||
import Login from './components/Login.svelte';
|
||||
import Signup from './components/Signup.svelte';
|
||||
|
|
@ -138,7 +139,18 @@
|
|||
// No session — fine.
|
||||
}
|
||||
|
||||
applyRoute(route);
|
||||
// Cold-load redirect: a logged-in user landing on the public landing
|
||||
// probably wants their own dashboard, not the marketing-y "what is this"
|
||||
// page. We only redirect on this initial mount — not on every
|
||||
// applyRoute call — so browser-back from /hjem to / still lets the
|
||||
// explicit navigation through (no loop, and the wordmark intentionally
|
||||
// sends logged-in users to /hjem instead of / anyway).
|
||||
if (route.view === 'public-home' && session.user) {
|
||||
pushUrl('/hjem');
|
||||
view = 'home';
|
||||
} else {
|
||||
applyRoute(route);
|
||||
}
|
||||
});
|
||||
|
||||
function applyRoute(route: Route) {
|
||||
|
|
@ -164,22 +176,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
function leaveTag() {
|
||||
// Same logic as leavePersonvern — back to wherever they were.
|
||||
if (session.user) goHome();
|
||||
else goPublicHome();
|
||||
}
|
||||
|
||||
function goPersonvern() {
|
||||
pushUrl('/personvern');
|
||||
view = 'personvern';
|
||||
}
|
||||
|
||||
function leavePersonvern() {
|
||||
// Send the visitor wherever they "would have been" — landing if logged out,
|
||||
// dashboard if logged in. Either is more useful than staying on the doc page.
|
||||
if (session.user) goHome();
|
||||
else goPublicHome();
|
||||
/**
|
||||
* Back-button handler for sub-views (permalink, tag page, personvern,
|
||||
* public list). Uses real browser history so the user returns to
|
||||
* wherever they came from in the SPA — /hjem, /etiketter/foo,
|
||||
* /aktivitet/bar, anywhere. Falls back to /hjem (or / when anonymous)
|
||||
* on cold-loads where there's no prior history entry.
|
||||
*/
|
||||
function backToCallerOrHome() {
|
||||
goBack(session.user ? '/hjem' : '/');
|
||||
}
|
||||
|
||||
function onAuthed() {
|
||||
|
|
@ -207,7 +217,8 @@
|
|||
<main>
|
||||
<nav class="top">
|
||||
<h1 style="margin: 0;">
|
||||
<a href="/" onclick={(e) => { e.preventDefault(); goPublicHome(); }}
|
||||
<a href={session.user ? '/hjem' : '/'}
|
||||
onclick={(e) => { e.preventDefault(); session.user ? goHome() : goPublicHome(); }}
|
||||
style="color: inherit; text-decoration: none;">Vinterliste</a>
|
||||
</h1>
|
||||
{#if view !== 'public-list' && view !== 'permalink' && view !== 'tag'}
|
||||
|
|
@ -246,9 +257,9 @@
|
|||
{#if view === 'loading'}
|
||||
<p class="muted">Laster …</p>
|
||||
{:else if view === 'public-list'}
|
||||
<PublicList username={publicListUsername} onBack={goPublicHome} />
|
||||
<PublicList username={publicListUsername} onBack={backToCallerOrHome} />
|
||||
{:else if view === 'permalink'}
|
||||
<ActivityPermalink id={activityId} onBack={goPublicHome} />
|
||||
<ActivityPermalink id={activityId} onBack={backToCallerOrHome} />
|
||||
{:else if view === 'public-home'}
|
||||
<Home publicOnly={true} />
|
||||
{:else if view === 'login'}
|
||||
|
|
@ -276,9 +287,9 @@
|
|||
{:else if view === 'moderate-tags'}
|
||||
<ModerateTags onDone={goHome} />
|
||||
{:else if view === 'personvern'}
|
||||
<Personvern onBack={leavePersonvern} />
|
||||
<Personvern onBack={backToCallerOrHome} />
|
||||
{:else if view === 'tag'}
|
||||
<TagPage tag={tagName} onBack={leaveTag} />
|
||||
<TagPage tag={tagName} onBack={backToCallerOrHome} />
|
||||
{:else}
|
||||
<Home publicOnly={false} />
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -34,3 +34,21 @@ export function onSpaLink(e: MouseEvent, path: string): void {
|
|||
e.preventDefault();
|
||||
navigate(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* "Back" navigation for in-app back buttons. Uses real browser history
|
||||
* when there's prior history to return to (preserves the user's actual
|
||||
* path through the SPA). Falls back to navigate(fallback) on cold-loads
|
||||
* — when the user opened the URL directly in a new tab and there's no
|
||||
* prior entry to back into.
|
||||
*
|
||||
* `window.history.length` is browser-dependent but length === 1 is a
|
||||
* reliable cold-load signal: every browser counts the current entry.
|
||||
*/
|
||||
export function goBack(fallback: string): void {
|
||||
if (window.history.length > 1) {
|
||||
window.history.back();
|
||||
} else {
|
||||
navigate(fallback);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue