Reader gets chapter-aware chevrons + a persistent app frame + distraction-free focus mode. - Single-mode chevrons (and ArrowLeft/Right + j/k) advance pages within the chapter and fall through to the adjacent chapter at the boundaries. Last page of last chapter / first page of first chapter disables the chevron and silent-no-ops on the keypress. - Continuous-mode gets a fixed bottom bar with prev/next chapter buttons; arrows + j/k jump chapters directly. - `?page=N` and `?page=last` URL query lets the prev-chapter jump land on the previous chapter's last page. - Layout header is fixed at the top; reader nav is sticky just below it; both stay visible while scrolling so reading settings are always reachable. - New "Focus" toggle in the reader nav hides the layout header, reader nav, and bottom chapter bar with smooth 220ms slide animations. Exit via Esc or a small floating Minimize2 button at the top-right (low resting opacity, full on hover). Reset on reader unmount so it doesn't leak to other pages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
34 lines
1.0 KiB
TypeScript
34 lines
1.0 KiB
TypeScript
/**
|
|
* Cross-component flag for the reader's "hide all chrome" view.
|
|
*
|
|
* The reader page toggles this; the root layout reads it to hide the
|
|
* top app navbar; the reader itself reads it to hide its own nav bar
|
|
* and bottom chapter bar. CSS handles the slide animations via a
|
|
* `data-reader-fullscreen` attribute on `<html>` so the entire frame
|
|
* (layout chrome included) stays synchronised.
|
|
*
|
|
* Always reset on reader unmount — letting the flag leak across
|
|
* navigation would orphan a hidden app navbar on other pages.
|
|
*/
|
|
let active = $state(false);
|
|
|
|
export const readerFullscreen = {
|
|
get value() {
|
|
return active;
|
|
},
|
|
set value(v: boolean) {
|
|
active = v;
|
|
if (typeof document !== 'undefined') {
|
|
if (v) document.documentElement.dataset.readerFullscreen = 'true';
|
|
else delete document.documentElement.dataset.readerFullscreen;
|
|
}
|
|
},
|
|
toggle() {
|
|
this.value = !active;
|
|
},
|
|
/** Force off — call from the reader's onDestroy. */
|
|
reset() {
|
|
this.value = false;
|
|
}
|
|
};
|