From a723e56b4ce392d2b11d28f2745279aa825a2ee1 Mon Sep 17 00:00:00 2001 From: memdmp Date: Mon, 21 Jul 2025 22:53:11 +0200 Subject: feat: initial commit --- src/routes/(app)/+layout.svelte | 10 + src/routes/(app)/+server.ts | 5 + src/routes/(app)/fahrplan/+page.svelte | 524 +++++++++++++++++++++ src/routes/+layout.svelte | 7 + src/routes/_lang/+page.svelte | 17 + src/routes/train-ico/[type]/[[line]]/+page.svelte | 13 + src/routes/train-ico/[type]/[[line]]/+page.ts | 1 + .../train-ico/[type]/[[line]]/.svg/+server.ts | 23 + 8 files changed, 600 insertions(+) create mode 100644 src/routes/(app)/+layout.svelte create mode 100644 src/routes/(app)/+server.ts create mode 100644 src/routes/(app)/fahrplan/+page.svelte create mode 100644 src/routes/+layout.svelte create mode 100644 src/routes/_lang/+page.svelte create mode 100644 src/routes/train-ico/[type]/[[line]]/+page.svelte create mode 100644 src/routes/train-ico/[type]/[[line]]/+page.ts create mode 100644 src/routes/train-ico/[type]/[[line]]/.svg/+server.ts (limited to 'src/routes') diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte new file mode 100644 index 0000000..f560b02 --- /dev/null +++ b/src/routes/(app)/+layout.svelte @@ -0,0 +1,10 @@ + + +
+ {@render children()} +
diff --git a/src/routes/(app)/+server.ts b/src/routes/(app)/+server.ts new file mode 100644 index 0000000..904739f --- /dev/null +++ b/src/routes/(app)/+server.ts @@ -0,0 +1,5 @@ +import { redirect } from '@sveltejs/kit'; + +export const GET = () => { + throw redirect(307, '/fahrplan/'); +}; diff --git a/src/routes/(app)/fahrplan/+page.svelte b/src/routes/(app)/fahrplan/+page.svelte new file mode 100644 index 0000000..6d36513 --- /dev/null +++ b/src/routes/(app)/fahrplan/+page.svelte @@ -0,0 +1,524 @@ + + + + + + + + +
+ +
+ (searchFieldFocused = true)} + onblur={() => { + searchFieldFocused = false; + if (renderedObjectIdName) searchQuery = renderedObjectIdName; + }} + onkeydown={(e) => { + const resultIdx = Math.max( + Math.min(searchSuggestionIdx, searchResults.length - 1), + 0 + ); + let dir = 1; + switch (e.key) { + case 'Enter': + case 'Return': { + const result = searchResults[resultIdx]; + if (result) { + objectId = result.id; + objectIdName = result.name; + searchQuery = result.name; + e.currentTarget.blur(); + pushHistory(); + setTimeout(() => refetchResultsLoop(true), 10); + } + break; + } + case 'ArrowUp': + dir = -1; + // fall through + case 'ArrowDown': { + if (searchResults.length !== 0) { + e.preventDefault(); + searchSuggestionIdx = + dir === -1 && resultIdx % 1 !== 0 + ? Math.floor(resultIdx) + : Math.floor(resultIdx + dir); + if (searchSuggestionIdx < 0) + searchSuggestionIdx = searchResults.length - 1; + else if (searchSuggestionIdx >= searchResults.length) + searchSuggestionIdx = 0; + } + break; + } + } + }} + /> +
+ {#if searchFieldFocused && searchResults.length !== 0} +
+ {#each searchResults as result, idx} + + +
{ + searchSuggestionIdx = idx; + }} + onmouseleave={() => { + searchSuggestionIdx = idx + 0.000001; + }} + onmousedown={(e) => { + e.preventDefault(); // prevent early unfocusing + }} + onclick={(e) => { + objectId = result.id; + objectIdName = result.name; + searchQuery = result.name; + pushHistory(); + if (searchField) { + setTimeout(() => { + searchField?.blur(); + }, 10); + searchField.value = result.name; + setTimeout(() => refetchResultsLoop(true), 10); + } + }} + > + {result.name} + {[ + result.areas.find((v) => v.default)?.name, + result.type.charAt(0).toUpperCase() + + result.type.substring(1).toLowerCase(), + ] + .filter((v) => v) + .join(', ')} +
+ {/each} +
+ {/if} +
+
+
+
+ {#if progressKind === 'fetch'} +
+ {:else if progressKind === 'waiting'} +
+ {/if} +
+
+
+ { + searchQuery = q; + searchField?.focus(); + }} + /> +
+
+
+
+ + + diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..3153e95 --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,7 @@ + + +{@render children()} diff --git a/src/routes/_lang/+page.svelte b/src/routes/_lang/+page.svelte new file mode 100644 index 0000000..619f97f --- /dev/null +++ b/src/routes/_lang/+page.svelte @@ -0,0 +1,17 @@ + + + +

{m.locale_page_informational_message()}

+
+ + +
+ + this page is temporary +
diff --git a/src/routes/train-ico/[type]/[[line]]/+page.svelte b/src/routes/train-ico/[type]/[[line]]/+page.svelte new file mode 100644 index 0000000..915f57b --- /dev/null +++ b/src/routes/train-ico/[type]/[[line]]/+page.svelte @@ -0,0 +1,13 @@ + + + diff --git a/src/routes/train-ico/[type]/[[line]]/+page.ts b/src/routes/train-ico/[type]/[[line]]/+page.ts new file mode 100644 index 0000000..3eeed27 --- /dev/null +++ b/src/routes/train-ico/[type]/[[line]]/+page.ts @@ -0,0 +1 @@ +export const load = ({ params }) => ({ params }); diff --git a/src/routes/train-ico/[type]/[[line]]/.svg/+server.ts b/src/routes/train-ico/[type]/[[line]]/.svg/+server.ts new file mode 100644 index 0000000..0120348 --- /dev/null +++ b/src/routes/train-ico/[type]/[[line]]/.svg/+server.ts @@ -0,0 +1,23 @@ +import LineGlyph from '$lib/assets/LineGlyph.svelte'; +import { render } from 'svelte/server'; +import { optimize } from 'svgo'; +export const GET = ({ params }) => { + return new Response( + optimize(` +${render(LineGlyph, { + props: { + kind: `${params.type}${params.line}`, + type: `${params.type}`, + line: params.line, + }, +}).body.replace( + '