From 56a7a7851b09cb30a5cd543c8cb4f926109b4290 Mon Sep 17 00:00:00 2001
From: Fuwn <contact@fuwn.net>
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/lib/CommandPalette/CommandPalette.svelte | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

(limited to 'src/lib/CommandPalette/CommandPalette.svelte')

diff --git a/src/lib/CommandPalette/CommandPalette.svelte b/src/lib/CommandPalette/CommandPalette.svelte
index b68d468d..04eabff9 100644
--- a/src/lib/CommandPalette/CommandPalette.svelte
+++ b/src/lib/CommandPalette/CommandPalette.svelte
@@ -3,6 +3,7 @@ import { onMount } from "svelte";
 import { fly, fade } from "svelte/transition";
 import { flip } from "svelte/animate";
 import type { CommandPaletteAction } from "./actions";
+import locale from "$stores/locale";
 
 export let items: CommandPaletteAction[] = [];
 export let open = false;
@@ -176,7 +177,7 @@ const handleGlobalKey = (e: KeyboardEvent) => {
     class="dropdown {open ? 'fade-in' : 'fade-out'}"
     role="dialog"
     aria-modal="true"
-    aria-label="Command palette"
+    aria-label={$locale().commandPalette?.ariaLabel}
   >
     <div class="dropdown-content card card-small card-glass">
       <input
@@ -184,8 +185,8 @@ const handleGlobalKey = (e: KeyboardEvent) => {
         bind:value={search}
         class="command-input"
         type="text"
-        placeholder="Search"
-        aria-label="Search commands"
+        placeholder={$locale().commandPalette?.placeholder}
+        aria-label={$locale().commandPalette?.searchCommands}
         autocomplete="off"
         spellcheck="false"
         role="combobox"
@@ -196,7 +197,12 @@ const handleGlobalKey = (e: KeyboardEvent) => {
         onkeydown={handleKey}
       />
 
-      <div class="results-container" role="listbox" id={listboxId} aria-label="Commands">
+      <div
+        class="results-container"
+        role="listbox"
+        id={listboxId}
+        aria-label={$locale().commandPalette?.commands}
+      >
         {#each filtered as item, i (item.id || item.url)}
           <a
             id={optionDomId(i)}
@@ -220,7 +226,7 @@ const handleGlobalKey = (e: KeyboardEvent) => {
 
         {#if filtered.length === 0 && search !== ''}
           <div class="no-results opaque" role="status" in:fade={{ duration: 150 }}>
-            No results found
+            {$locale().commandPalette?.noResults}
           </div>
         {/if}
       </div>
-- 
cgit v1.2.3

