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/Tools/Tracker/Tool.svelte | 34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

(limited to 'src/lib/Tools/Tracker/Tool.svelte')

diff --git a/src/lib/Tools/Tracker/Tool.svelte b/src/lib/Tools/Tracker/Tool.svelte
index 8f7a3197..b495522a 100644
--- a/src/lib/Tools/Tracker/Tool.svelte
+++ b/src/lib/Tools/Tracker/Tool.svelte
@@ -4,6 +4,8 @@ import { v6 as uuidv6 } from "uuid";
 import { database, type TrackerEntry } from "$lib/Database/IDB/tracker";
 import { onMount } from "svelte";
 import Message from "$lib/Loading/Message.svelte";
+import locale from "$stores/locale";
+import { get } from "svelte/store";
 
 let url = "";
 let title = "";
@@ -34,15 +36,19 @@ const adjustEntry = (id: string, to: number) => {
 
 const addEntry = async (url: string, title: string, progress: number) => {
 	if (!url || !title) {
-		error = "URL and title are required fields";
+		error =
+			get(locale)().tools.tracker?.urlTitleRequired ??
+			"URL and title are required fields";
 
 		return;
 	}
 
 	if (listAccess.some((entry) => entry.url === url)) {
-		error =
-			"Entry with URL already exists: " +
-			listAccess.find((entry) => entry.url === url)?.title;
+		const existing = listAccess.find((entry) => entry.url === url)?.title;
+
+		error = (
+			get(locale)().tools.tracker?.entryExists ?? "Entry with URL already exists: {url}"
+		).replace("{url}", existing ?? "");
 
 		return;
 	}
@@ -55,7 +61,9 @@ const addEntry = async (url: string, title: string, progress: number) => {
 const deleteEntry = async (id: string) => {
 	if (confirmDelete !== 1) {
 		confirmDelete = 1;
-		error = "Click again to confirm deletion";
+		error =
+			get(locale)().tools.tracker?.confirmDelete ??
+			"Click again to confirm deletion";
 
 		return;
 	}
@@ -73,10 +81,16 @@ const deleteEntry = async (id: string) => {
     <p><b>Error</b>: {error}</p>
   {/if}
 
-  <input type="url" placeholder="URL" bind:value={url} />
-  <input type="text" placeholder="Title" bind:value={title} />
-  <input type="number" placeholder="Progress (defaults to 0)" bind:value={progress} />
-  <button class="button-lined" onclick={() => addEntry(url, title, progress)}> Add </button>
+  <input type="url" placeholder={$locale().tools.tracker?.urlPlaceholder} bind:value={url} />
+  <input type="text" placeholder={$locale().tools.tracker?.titlePlaceholder} bind:value={title} />
+  <input
+    type="number"
+    placeholder={$locale().tools.tracker?.progressPlaceholder}
+    bind:value={progress}
+  />
+  <button class="button-lined" onclick={() => addEntry(url, title, progress)}
+    >{$locale().common?.add}</button
+  >
 
   <Spacer />
 
@@ -120,7 +134,7 @@ const deleteEntry = async (id: string) => {
                 +
               </button>
               <span class="opaque">|</span>
-              <button onclick={() => deleteEntry(entry.id)}>Remove</button>
+              <button onclick={() => deleteEntry(entry.id)}>{$locale().common?.remove}</button>
             </span>
           </div>
         </li>
-- 
cgit v1.2.3

