From 56a7a7851b09cb30a5cd543c8cb4f926109b4290 Mon Sep 17 00:00:00 2001 From: Fuwn Date: Sun, 24 May 2026 13:22:34 +0000 Subject: refactor(locale): move hardcoded UI strings into english locale Adds optional namespaces (common, errors, commandPalette, headTitle, notifications, schedule, events, home, reader, routes, badgePreview, badgeWall) and extends existing ones (settings.*, lists.*, tools.*, user.*, hololive.*) on the Locale interface. New fields are optional so japanese.ts can omit them; svelte-i18n's fallbackLocale handles the runtime miss. HeadTitle gains an optional routeKey prop for type-safe lookup. defaultActions becomes a factory so the command palette re-reads locale on language toggle. The existing JP feedback translation in routes/settings is preserved via japanese.ts. Out of scope (kept hardcoded): service-worker.ts, app.html, Landing*.svelte, tools.ts registry, Easter Event 2025 pages. --- src/routes/+error.svelte | 5 +- src/routes/+layout.svelte | 10 ++- src/routes/completed/+page.svelte | 4 +- src/routes/events/+page.svelte | 7 +- src/routes/events/group/[group]/+page.svelte | 23 +++--- src/routes/events/groups/+page.svelte | 11 +-- src/routes/girls/+page.svelte | 13 ++-- src/routes/girls/[language]/+page.svelte | 5 +- src/routes/hololive/[[stream]]/+page.svelte | 14 ++-- src/routes/reader/+page.svelte | 16 +++-- src/routes/schedule/+page.svelte | 9 +-- src/routes/settings/+page.svelte | 30 +++----- src/routes/tools/+page.svelte | 7 +- src/routes/tools/[tool]/+page.svelte | 7 +- src/routes/updates/+page.svelte | 11 +-- src/routes/user/+page.svelte | 2 +- src/routes/user/[user]/+page.svelte | 45 +++++++----- src/routes/user/[user]/badges/+page.svelte | 103 +++++++++++++++------------ 18 files changed, 173 insertions(+), 149 deletions(-) (limited to 'src/routes') diff --git a/src/routes/+error.svelte b/src/routes/+error.svelte index 71482ffb..a67cdbbf 100644 --- a/src/routes/+error.svelte +++ b/src/routes/+error.svelte @@ -2,6 +2,7 @@ import { page } from "$app/stores"; import { closest } from "$lib/Error/path"; import Popup from "$lib/Layout/Popup.svelte"; +import locale from "$stores/locale"; $: suggestion = closest($page.url.pathname.replace("/", ""), [ "birthdays", @@ -18,11 +19,11 @@ $: suggestion = closest($page.url.pathname.replace("/", ""), [

- {$page.url.pathname} not found + {$page.url.pathname} {$locale().errors?.routeNotFound}

- Did you mean "{suggestion.charAt(0).toUpperCase() + suggestion.slice(1)} (isMenuOpen = !isMenuOpen)} @@ -434,7 +434,11 @@ $: { {:else if data.user} - Avatar + {$locale().navigation.avatar} {/if} diff --git a/src/routes/completed/+page.svelte b/src/routes/completed/+page.svelte index bcad912b..3720bf60 100644 --- a/src/routes/completed/+page.svelte +++ b/src/routes/completed/+page.svelte @@ -64,14 +64,14 @@ onMount(async () => { onDestroy(() => removeHeightObserver?.()); - + {#if LastActivityComponent} {/if} {#if data.user === undefined} -
Please log in to view completed media.
+
{$locale().errors?.completedLoginPrompt}
diff --git a/src/routes/events/+page.svelte b/src/routes/events/+page.svelte index 88a3da9e..0474852b 100644 --- a/src/routes/events/+page.svelte +++ b/src/routes/events/+page.svelte @@ -4,13 +4,14 @@ import Event from "$lib/Events/Event.svelte"; import Message from "$lib/Loading/Message.svelte"; import root from "$lib/Utility/root"; +import locale from "$stores/locale"; {#await fetch(root(`/api/events`))} - + {:then eventsResponse} {#await eventsResponse.json()} - + {:then events} {#if events} {#each events as rawEvent, i} @@ -22,6 +23,6 @@ import root from "$lib/Utility/root"; {/each} {/if} {:catch} - Error parsing events. + {$locale().events?.errorParsingEvents} {/await} {/await} diff --git a/src/routes/events/group/[group]/+page.svelte b/src/routes/events/group/[group]/+page.svelte index c02c1b51..34db0fae 100644 --- a/src/routes/events/group/[group]/+page.svelte +++ b/src/routes/events/group/[group]/+page.svelte @@ -7,6 +7,7 @@ import root from "$lib/Utility/root"; import { onMount } from "svelte"; import Group from "$lib/Events/Group.svelte"; import Event from "$lib/Events/Event.svelte"; +import locale from "$stores/locale"; import type { PageData } from "./$types"; export let data: PageData; @@ -23,16 +24,16 @@ const asEvent = (event: unknown) => event as EventType; {#await groupsResponse} - + {:then group} {#if group} {#await group.json()} - + {:then json} {#if json === null} - This group may not exist. Please - location.reload()}>try again later. + {$locale().events?.groupNotExistPrefix} + location.reload()}>{$locale().common?.tryAgain}{$locale().events?.groupNotExistSuffix} {:else} {@const group = asGroup(json)} @@ -42,13 +43,13 @@ const asEvent = (event: unknown) => event as EventType;
- Events + {$locale().events?.summary} {#await fetch(root(`/api/events?group=${data.group}`))} - + {:then eventsResponse} {#await eventsResponse.json()} - + {:then events} {#if events} {#each events as rawEvent, i} @@ -60,17 +61,17 @@ const asEvent = (event: unknown) => event as EventType; {/each} {/if} {:catch} - Error parsing events. + {$locale().events?.errorParsingEvents} {/await} {/await}
{/if} {:catch} - Error parsing group. + {$locale().events?.errorParsingGroup} {/await} {:else} - + {/if} {:catch} - Error loading group. + {$locale().events?.errorLoadingGroup} {/await} diff --git a/src/routes/events/groups/+page.svelte b/src/routes/events/groups/+page.svelte index b6181ad8..198c637b 100644 --- a/src/routes/events/groups/+page.svelte +++ b/src/routes/events/groups/+page.svelte @@ -5,6 +5,7 @@ import Message from "$lib/Loading/Message.svelte"; import root from "$lib/Utility/root"; import { onMount } from "svelte"; import Group from "$lib/Events/Group.svelte"; +import locale from "$stores/locale"; let groupsResponse: Promise; @@ -16,11 +17,11 @@ const asGroup = (group: unknown) => group as GroupType; {#await groupsResponse} - + {:then groups} {#if groups} {#await groups.json()} - + {:then json} {#each json as rawGroup, i} {@const group = asGroup(rawGroup)} @@ -34,11 +35,11 @@ const asGroup = (group: unknown) => group as GroupType; {/if} {/each} {:catch} - Error parsing groups. + {$locale().events?.errorParsingGroups} {/await} {:else} - + {/if} {:catch} - Error loading groups. + {$locale().events?.errorLoadingGroups} {/await} diff --git a/src/routes/girls/+page.svelte b/src/routes/girls/+page.svelte index bbe57ac9..e45dad4d 100644 --- a/src/routes/girls/+page.svelte +++ b/src/routes/girls/+page.svelte @@ -5,28 +5,29 @@ import HeadTitle from "$lib/Home/HeadTitle.svelte"; import Message from "$lib/Loading/Message.svelte"; import Skeleton from "$lib/Loading/Skeleton.svelte"; import root from "$lib/Utility/root"; +import locale from "$stores/locale"; import "$styles/girls.scss"; - +
{#await Senpy.getRandomImage()} - + {:then randomImage} {/await}
- The Senpy Club | Anime Girls Holding Programming Books + {$locale().routes?.girlsIntroLeft} | {$locale().routes?.girlsIntroRight} @@ -69,10 +70,10 @@ import "$styles/girls.scss";
- Languages + {$locale().routes?.girlsLanguages} {#await Senpy.getLanguages()} - + {#await Senpy.getImages(data.language)} - + {:then images} @@ -18,7 +19,7 @@ export let data: PageData; {#each images as image}
- An anime girl holding a programming book + {$locale().routes?.girlsSingleAlt}
{/each} diff --git a/src/routes/hololive/[[stream]]/+page.svelte b/src/routes/hololive/[[stream]]/+page.svelte index 573c16aa..250ce22a 100644 --- a/src/routes/hololive/[[stream]]/+page.svelte +++ b/src/routes/hololive/[[stream]]/+page.svelte @@ -49,16 +49,16 @@ const getPinnedStreams = () => { }; - + {#await schedulePromise} - + {:then scheduleResponse} {#if scheduleResponse} {#await scheduleResponse.text()} - + {:then untypedSchedule} @@ -68,17 +68,17 @@ const getPinnedStreams = () => { {:catch} {$locale().hololive.parseError} - location.reload()}>Try again? + location.reload()}>{$locale().hololive.tryAgainQuestion} {/await} {:else} - + {/if} {:catch} - {$locale().hololive.loadError} Please - location.reload()}>try again later. + {$locale().hololive.loadError} {$locale().hololive.pleasePrefix} + location.reload()}>{$locale().common?.tryAgain} {$locale().hololive.laterSuffix} {/await} diff --git a/src/routes/reader/+page.svelte b/src/routes/reader/+page.svelte index b6cce066..f279a58e 100644 --- a/src/routes/reader/+page.svelte +++ b/src/routes/reader/+page.svelte @@ -10,16 +10,22 @@ import { Resource, } from "$lib/Reader/resource"; import InputTemplate from "$lib/Tools/InputTemplate.svelte"; +import locale from "$stores/locale"; let submission = ""; $: resourceIdentity = identify(submission); - + {#if resourceIdentity} {#await fetchResource(submission)} - + {:then response} {#if response.ok} {#await decodeResource(response, submission) then data} @@ -32,12 +38,12 @@ $: resourceIdentity = identify(submission); {error} {/await} {:else} - Failed to fetch data + {$locale().reader?.fetchFailed} {/if} {:catch} - An unknown error has occurred. + {$locale().reader?.unknownError} {/await} {:else} - Invalid URL + {$locale().reader?.invalidUrl} {/if} diff --git a/src/routes/schedule/+page.svelte b/src/routes/schedule/+page.svelte index 139f333e..9dcda20a 100644 --- a/src/routes/schedule/+page.svelte +++ b/src/routes/schedule/+page.svelte @@ -13,6 +13,7 @@ import Days from "$lib/Schedule/Days.svelte"; import Skeleton from "$lib/Loading/Skeleton.svelte"; import Message from "$lib/Loading/Message.svelte"; import subsPlease from "$stores/subsPlease"; +import locale from "$stores/locale"; import type { PageData } from "./$types"; export let data: PageData; @@ -33,7 +34,7 @@ onMount(async () => { }); - + {#if !$subsPlease} - + {:else} {#await scheduledMediaPromise} - + {:then scheduledMedia} @@ -76,7 +77,7 @@ onMount(async () => {
{:else} - + {/if} diff --git a/src/routes/settings/+page.svelte b/src/routes/settings/+page.svelte index 054a126b..f9a2ee87 100644 --- a/src/routes/settings/+page.svelte +++ b/src/routes/settings/+page.svelte @@ -10,7 +10,6 @@ import Cache from "$lib/Settings/Categories/Cache.svelte"; import Category from "$lib/Settings/Category.svelte"; import tooltip from "$lib/Tooltip/tooltip"; import locale from "$stores/locale.js"; -import settings from "$stores/settings"; import LogInRestricted from "$lib/Error/LogInRestricted.svelte"; import SettingSync from "$lib/Settings/Categories/SettingSync.svelte"; import RssFeeds from "$lib/Settings/Categories/RSSFeeds.svelte"; @@ -28,28 +27,17 @@ export let data: PageData; // }; - +
- {#if $settings.displayLanguage == 'en'} - Have feedback or suggestions? Send a private message to - @fuwn - on AniList! - {:else if $settings.displayLanguage == 'ja'} - フィードバックや提案はありますか?AniListで - @fuwn - にDMを送ってください! - {/if} + {$locale().routes?.settingsFeedbackPrefix} + @fuwn + {$locale().routes?.settingsFeedbackSuffix} {#if shadowHidden} - + {/if} {#if editMode && isOwner} @@ -784,7 +786,7 @@ const shadowHideBadge = () => { ? dateToInputTime(databaseTimeToDate(selectedBadge.time)) : ''} /> - Must be full date and time, defaults to now if any fields empty + {$locale().badgeWall?.page?.dateTimeHint} @@ -827,13 +829,17 @@ const shadowHideBadge = () => { ({ - name: hidden ? 'Hidden' : 'Shown', + name: hidden + ? ($locale().badgeWall?.page?.hidden ?? 'Hidden') + : ($locale().badgeWall?.page?.shown ?? 'Shown'), url: '#', onClick: () => { const hiddenInput = document.querySelector('input[name="hidden"]'); if (hiddenInput instanceof HTMLInputElement) - hiddenInput.value = hidden ? 'Hidden' : 'Shown'; + hiddenInput.value = hidden + ? ($locale().badgeWall?.page?.hidden ?? 'Hidden') + : ($locale().badgeWall?.page?.shown ?? 'Shown'); } }))} header={false} @@ -842,16 +848,16 @@ const shadowHideBadge = () => { @@ -879,9 +885,11 @@ const shadowHideBadge = () => { {#if loadQueryParameter === 'none'}
- Notice: - {ungroupedBadges.length} badges have been loaded successfully, but they are not being displayed - due to your preferences (load=none). + {$locale().badgeWall?.page?.notice} + {$locale({ + values: { count: ungroupedBadges.length } + }).badgeWall?.page?.loadNoneNoticePrefix}load=none{$locale().badgeWall + ?.page?.loadNoneNoticeSuffix}
{:else} { {#if authorised} {/if} @@ -1026,13 +1036,13 @@ const shadowHideBadge = () => { {/if} (migrateMode = false)} show={migrateMode}> - Migrate Category + {$locale().badgeWall?.page?.migrateCategory} { /> - Leave category empty to migrate all to or from uncategorised. + {$locale().badgeWall?.page?.migrateAllHint} @@ -1060,29 +1070,28 @@ const shadowHideBadge = () => { {$locale().user.badges.importMode.cancel} (hideMode = false)} show={hideMode}> - Hide Category + {$locale().badgeWall?.page?.hideCategory} - If the majority of the badges in a category are shown, the category will be hidden, and vice - versa. + {$locale().badgeWall?.page?.hideVisibilityHint} - Leave category field empty to hide all. + {$locale().badgeWall?.page?.hideAllHint} @@ -1096,6 +1105,6 @@ const shadowHideBadge = () => { {$locale().user.badges.importMode.cancel} {$locale().badgeWall?.page?.toggleVisibility} -- cgit v1.2.3