diff --git a/src/lib/chrome.test.ts b/src/lib/chrome.test.ts index c952aff..f711935 100644 --- a/src/lib/chrome.test.ts +++ b/src/lib/chrome.test.ts @@ -1,13 +1,19 @@ import { describe, expect, it } from 'vitest'; -import { isImmersive } from './chrome'; +import { hidesFooter, isImmersive } from './chrome'; describe('immersive pages', () => { - it('skips the site chrome on /start and the book reader only', () => { - expect(isImmersive('/start')).toBe(true); - expect(isImmersive('/start/')).toBe(true); + it('skips the site chrome on the book reader only', () => { + expect(isImmersive('/start')).toBe(false); expect(isImmersive('/trackers/books/12/read')).toBe(true); expect(isImmersive('/')).toBe(false); expect(isImmersive('/starter')).toBe(false); expect(isImmersive('/trackers/books/12')).toBe(false); }); + + it('shows the header but no footer on /start', () => { + expect(hidesFooter('/start')).toBe(true); + expect(hidesFooter('/start/')).toBe(true); + expect(hidesFooter('/starter')).toBe(false); + expect(hidesFooter('/')).toBe(false); + }); }); diff --git a/src/lib/chrome.ts b/src/lib/chrome.ts index 5861086..7ad0738 100644 --- a/src/lib/chrome.ts +++ b/src/lib/chrome.ts @@ -1,10 +1,15 @@ /** - * Full-screen pages that render without the site header and footer: the /start new-tab - * dashboard and the book reader. They also skip loading the header's JS (icons, menus, - * the mobile Sheet): src/routes/+layout.ts only imports SiteChrome for other pages. + * Full-screen pages that render without the site header and footer (the book reader). They + * also skip loading the header's JS (icons, menus, the mobile Sheet): src/routes/+layout.ts + * only imports SiteChrome for other pages. */ export function isImmersive(pathname: string): boolean { - return /^\/start\/?$/.test(pathname) || /^\/trackers\/books\/\d+\/read\/?$/.test(pathname); + return /^\/trackers\/books\/\d+\/read\/?$/.test(pathname); +} + +/** Pages that show the site header but no footer: the /start new-tab dashboard. */ +export function hidesFooter(pathname: string): boolean { + return /^\/start\/?$/.test(pathname); } /** True when a keyboard shortcut should not fire because the user is typing. */ diff --git a/src/lib/components/SiteChrome.svelte b/src/lib/components/SiteChrome.svelte index 8d7ec88..3d5ffbf 100644 --- a/src/lib/components/SiteChrome.svelte +++ b/src/lib/components/SiteChrome.svelte @@ -2,7 +2,7 @@ import { onMount, type Snippet } from 'svelte'; import { resolve } from '$app/paths'; import logo from '#lib/assets/brand/favicon-32x32.png?url'; - import { isTyping } from '#lib/chrome.js'; + import { hidesFooter, isTyping } from '#lib/chrome.js'; import { page } from '$app/state'; import CopyButton from '#lib/components/CopyButton.svelte'; import ProjectIcon from '#lib/components/ProjectIcon.svelte'; @@ -36,6 +36,7 @@ version: string; }; let { data, children }: { data: ChromeData; children: Snippet } = $props(); + const showFooter = $derived(!hidesFooter(page.url.pathname)); let menuOpen = $state(false); // Which header dropdown is open (desktop): '/projects', '/trackers' or none. let openMenu = $state(null); @@ -266,7 +267,7 @@ {#if data.isOwner} +
+
+ stan runge {data.version.slice(0, 7)} - {/each} - {#each copyLinks as item (item.label)}{/each} - -
- + source +
+ + + + {/if}