diff options
| author | Fuwn <[email protected]> | 2026-05-24 13:22:34 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-05-24 13:22:34 +0000 |
| commit | 56a7a7851b09cb30a5cd543c8cb4f926109b4290 (patch) | |
| tree | a620f908405fa48fd601580c5a48432831ec5c33 /src/lib/Tools/Wrapped | |
| parent | fix(layout): preserve list panel when clicking action buttons in summary (diff) | |
| download | due.moe-56a7a7851b09cb30a5cd543c8cb4f926109b4290.tar.xz due.moe-56a7a7851b09cb30a5cd543c8cb4f926109b4290.zip | |
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.
Diffstat (limited to 'src/lib/Tools/Wrapped')
| -rw-r--r-- | src/lib/Tools/Wrapped/Tool.svelte | 141 |
1 files changed, 80 insertions, 61 deletions
diff --git a/src/lib/Tools/Wrapped/Tool.svelte b/src/lib/Tools/Wrapped/Tool.svelte index b04bc5f6..b7d67cb0 100644 --- a/src/lib/Tools/Wrapped/Tool.svelte +++ b/src/lib/Tools/Wrapped/Tool.svelte @@ -2,6 +2,7 @@ import Spacer from "$lib/Layout/Spacer.svelte"; import "./wrapped.css"; import userIdentity from "$stores/identity"; +import locale from "$stores/locale"; import type { AniListAuthorisation } from "$lib/Data/AniList/identity"; import { onMount } from "svelte"; import { @@ -214,33 +215,36 @@ $: { updateWidth(); } $: genreTagTitle = (() => { + const w = $locale().tools.wrapped; switch (genreTagsSort) { case SortOptions.SCORE: - return "Highest Rated"; + return w?.highestRated ?? "Highest Rated"; case SortOptions.MINUTES_WATCHED: - return "Most Watched"; + return w?.mostWatched ?? "Most Watched"; case SortOptions.COUNT: - return "Most Common"; + return w?.mostCommon ?? "Most Common"; } })(); $: animeMostTitle = (() => { + const w = $locale().tools.wrapped; switch (mediaSort) { case SortOptions.SCORE: - return "Highest Rated"; + return w?.highestRated ?? "Highest Rated"; case SortOptions.MINUTES_WATCHED: - return "Most Watched"; + return w?.mostWatched ?? "Most Watched"; case SortOptions.COUNT: - return "Most Common"; + return w?.mostCommon ?? "Most Common"; } })(); $: mangaMostTitle = (() => { + const w = $locale().tools.wrapped; switch (mediaSort) { case SortOptions.SCORE: - return "Highest Rated"; + return w?.highestRated ?? "Highest Rated"; case SortOptions.MINUTES_WATCHED: - return "Most Read"; + return w?.mostRead ?? "Most Read"; case SortOptions.COUNT: - return "Most Common"; + return w?.mostCommon ?? "Most Common"; } })(); @@ -829,12 +833,12 @@ const pruneFullYear = async () => { {#if shouldFetchData} {#key fetchKey} {#await selectedYear !== currentYear || useFullActivityHistory || new Date().getMonth() <= 6 ? fullActivityHistory(user, $userIdentity, selectedYear, disableLoopingActivityCounter) : getActivityHistory($userIdentity)} - <Message message="Loading activity history ..." /> + <Message message={$locale().tools.wrapped?.loadingActivityHistory} /> <Skeleton count={2} /> {:then activities} {#await wrapped(user, $userIdentity, selectedYear, false, disableLoopingActivityCounter)} - <Message message="Loading user data ..." /> + <Message message={$locale().tools.wrapped?.loadingUserData} /> <Skeleton count={2} /> {:then wrapped} @@ -920,9 +924,8 @@ const pruneFullYear = async () => { > {#if useFullActivityHistory} <p> - With <b>many</b> activities, it may take multiple attempts to obtain all of your activity - history from AniList. If this occurs, wait one minute and try again to continue populating - your local activity history database. + {$locale().tools.wrapped?.multiAttemptPrefix}<b>many</b>{$locale().tools.wrapped + ?.multiAttemptSuffix} </p> {/if} </RateLimitedError> @@ -970,7 +973,7 @@ const pruneFullYear = async () => { id="watermark" data-umami-event="Load Wrapped Data" > - Click load data! + {$locale().tools.wrapped?.clickLoadData} </a> </div> </div> @@ -985,7 +988,7 @@ const pruneFullYear = async () => { <Spacer /> <blockquote style="margin: 0 0 0 1.5rem;"> - Click on the image to download, or right click and select "Save Image As...". + {$locale().tools.wrapped?.saveImageInstruction} </blockquote> {/if} </div> @@ -995,66 +998,73 @@ const pruneFullYear = async () => { {/if} <div id="options" class="card"> - <button onclick={screenshot} data-umami-event="Generate Wrapped"> Generate image </button> + <button onclick={screenshot} data-umami-event="Generate Wrapped" + >{$locale().tools.wrapped?.generateImage}</button + > {#if !shouldFetchData} - <button onclick={triggerFetch} data-umami-event="Load Wrapped Data"> Load data </button> + <button onclick={triggerFetch} data-umami-event="Load Wrapped Data" + >{$locale().tools.wrapped?.loadData}</button + > {:else if needsRefetch} <button onclick={triggerFetch} data-umami-event="Refetch Wrapped Data"> - Reload data + {$locale().tools.wrapped?.reloadData} </button> {/if} <details class="no-shadow" open> - <summary>Display</summary> + <summary>{$locale().tools.wrapped?.display}</summary> - <input type="checkbox" bind:checked={watermark} /> Show watermark<br /> - <input type="checkbox" bind:checked={transparency} /> Enable background transparency<br /> + <input type="checkbox" bind:checked={watermark} /> + {$locale().tools.wrapped?.showWatermark}<br /> + <input type="checkbox" bind:checked={transparency} /> + {$locale().tools.wrapped?.bgTransparency}<br /> <input type="checkbox" bind:checked={lightMode} /> - Enable light mode<br /> + {$locale().tools.wrapped?.lightMode}<br /> <input type="checkbox" bind:checked={topGenresTags} /> - Show top genres and tags<br /> + {$locale().tools.wrapped?.showGenresTags}<br /> <input type="checkbox" bind:checked={disableActivityHistory} disabled={selectedYear !== currentYear} /> - Hide activity history<br /> - <input type="checkbox" bind:checked={highestRatedMediaPercentage} /> Show highest rated - media percentages<br /> - <input type="checkbox" bind:checked={highestRatedGenreTagPercentage} /> Show highest rated - genre and tag percentages<br /> - <input type="checkbox" bind:checked={includeOngoingMediaFromPreviousYears} /> Show ongoing - media from previous years<br /> + {$locale().tools.wrapped?.hideActivityHistory}<br /> + <input type="checkbox" bind:checked={highestRatedMediaPercentage} /> + {$locale().tools.wrapped?.showRatedPercentages}<br /> + <input type="checkbox" bind:checked={highestRatedGenreTagPercentage} /> + {$locale().tools.wrapped?.showGenreTagPercentages}<br /> + <input type="checkbox" bind:checked={includeOngoingMediaFromPreviousYears} /> + {$locale().tools.wrapped?.showOngoingPrevious}<br /> <select bind:value={activityHistoryPosition}> - <option value="TOP">Above Top Row</option> - <option value="BELOW_TOP">Below Top Row</option> - <option value="ORIGINAL">Bottom</option> + <option value="TOP">{$locale().tools.wrapped?.aboveTopRow}</option> + <option value="BELOW_TOP">{$locale().tools.wrapped?.belowTopRow}</option> + <option value="ORIGINAL">{$locale().tools.wrapped?.bottom}</option> </select> - Activity history position<br /> + {$locale().tools.wrapped?.activityHistoryPosition}<br /> <select bind:value={highestRatedCount}> {#each [3, 4, 5, 6, 7, 8, 9, 10] as count} <option value={count}>{count}</option> {/each} </select> - Highest rated media count<br /> + {$locale().tools.wrapped?.highestRatedCount}<br /> <select bind:value={genreTagCount}> {#each [3, 4, 5, 6, 7, 8, 9, 10] as count} <option value={count}>{count}</option> {/each} </select> - Highest genre and tag count<br /> - <button onclick={updateWidth}>Find best fit</button> + {$locale().tools.wrapped?.highestGenreTagCount}<br /> + <button onclick={updateWidth}>{$locale().tools.wrapped?.findBestFit}</button> <button onclick={() => (width -= 25)}>-25px</button> <button onclick={() => (width += 25)}>+25px</button> - Width adjustment<br /> + {$locale().tools.wrapped?.widthAdjustment}<br /> </details> <details class="no-shadow" open> - <summary>Calculation</summary> + <summary>{$locale().tools.wrapped?.calculation}</summary> <input type="checkbox" bind:checked={useFullActivityHistory} disabled={needsRefetch} /> - Enable full-year activity<button class="smaller-button" onclick={pruneFullYear} - >Refresh data</button + {$locale().tools.wrapped?.enableFullYear}<button + class="smaller-button" + onclick={pruneFullYear}>{$locale().tools.wrapped?.refreshData}</button > <br /> <select bind:value={selectedYear} disabled={needsRefetch}> @@ -1064,7 +1074,7 @@ const pruneFullYear = async () => { </option> {/each} </select> - Calculate for year<br /> + {$locale().tools.wrapped?.calculateForYear}<br /> <input type="date" bind:value={startDateFilter} @@ -1076,7 +1086,7 @@ const pruneFullYear = async () => { update(); }} /> - Start date filter<br /> + {$locale().tools.wrapped?.startDateFilter}<br /> <input type="date" bind:value={endDateFilter} @@ -1088,25 +1098,30 @@ const pruneFullYear = async () => { update(); }} /> - End date filter<br /> + {$locale().tools.wrapped?.endDateFilter}<br /> <select bind:value={mediaSort}> <option value={SortOptions.SCORE}>Score</option> <option value={SortOptions.MINUTES_WATCHED}>Minutes Watched/Read</option> </select> - Anime and manga sort<br /> + {$locale().tools.wrapped?.animeMangaSort}<br /> <select bind:value={genreTagsSort}> <option value={SortOptions.SCORE}>Score</option> <option value={SortOptions.MINUTES_WATCHED}>Minutes Watched/Read</option> <option value={SortOptions.COUNT}>Count</option> </select> - Genre and tag sort<br /> - <input type="checkbox" bind:checked={includeMusic} /> Include music<br /> - <input type="checkbox" bind:checked={includeRepeats} /> Include rewatches & rereads<br /> - <input type="checkbox" bind:checked={includeSpecials} /> Include specials<br /> - <input type="checkbox" bind:checked={includeOVAs} /> Include OVAs<br /> - <input type="checkbox" bind:checked={includeMovies} /> Include movies<br /> - <input type="checkbox" bind:checked={excludeUnratedUnwatched} /> Excluded unrated & - unwatched<br /> + {$locale().tools.wrapped?.genreTagSort}<br /> + <input type="checkbox" bind:checked={includeMusic} /> + {$locale().tools.wrapped?.includeMusic}<br /> + <input type="checkbox" bind:checked={includeRepeats} /> + {$locale().tools.wrapped?.includeRewatches}<br /> + <input type="checkbox" bind:checked={includeSpecials} /> + {$locale().tools.wrapped?.includeSpecials}<br /> + <input type="checkbox" bind:checked={includeOVAs} /> + {$locale().tools.wrapped?.includeOvas}<br /> + <input type="checkbox" bind:checked={includeMovies} /> + {$locale().tools.wrapped?.includeMovies}<br /> + <input type="checkbox" bind:checked={excludeUnratedUnwatched} /> + {$locale().tools.wrapped?.excludeUnrated}<br /> <input type="text" bind:value={excludedKeywordsInput} @@ -1114,29 +1129,33 @@ const pruneFullYear = async () => { e.key === 'Enter' && submitExcludedKeywords(); }} /> - Excluded keywords - <button onclick={submitExcludedKeywords} title="Or click your Enter key" use:tooltip> - Submit + {$locale().tools.wrapped?.excludedKeywords} + <button + onclick={submitExcludedKeywords} + title={$locale().tools.input?.pressEnter} + use:tooltip + > + {$locale().tools.wrapped?.submit} </button> <br /> - <SettingHint>Comma separated list (e.g., "My Hero, Kaguya")</SettingHint> + <SettingHint>{$locale().tools.wrapped?.excludedHint}</SettingHint> </details> <details class="no-shadow" open> - <summary>Advanced</summary> + <summary>{$locale().tools.wrapped?.advanced}</summary> <input type="checkbox" bind:checked={disableLoopingActivityCounter} disabled={needsRefetch} /> - Disable detailed activity information + {$locale().tools.wrapped?.disableDetailedActivity} </details> </div> </div> </div> {:else} - <Message message="Loading user ..." /> + <Message message={$locale().tools.wrapped?.loadingUser} /> <Skeleton count={2} /> {/if} |