From 9e24b2b4fcfe7828bb87aaf0508f3550bd443267 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sun, 11 Oct 2026 16:18:04 -0400 Subject: [PATCH] refactor: every count in the web app is said by one plural(), with the viewer's thousands separator; a source guard names any hand-written copy (M505 #5642) Co-Authored-By: Claude Opus 5.5 --- web/src/lib/admin/queues.ts | 3 +- web/src/lib/api/client.ts | 3 +- web/src/lib/components/ActiveSessions.svelte | 7 +-- .../lib/components/NetworkSettingsCard.svelte | 6 +-- web/src/lib/components/PlaylistCard.svelte | 3 +- web/src/lib/components/QueueList.svelte | 3 +- .../ReacquisitionSettingsCard.svelte | 4 +- .../lib/components/ReleaseProfilesCard.svelte | 3 +- web/src/lib/components/WantCandidates.svelte | 5 +- .../lib/components/wanted/DownloadList.svelte | 3 +- .../lib/components/wanted/FollowList.svelte | 3 +- .../components/wanted/UnmatchedList.svelte | 6 +-- web/src/lib/components/wanted/WantList.svelte | 9 ++-- web/src/lib/utils/plural.test.ts | 53 +++++++++++++++++++ web/src/lib/utils/plural.ts | 7 +++ web/src/routes/admin/+page.svelte | 6 +-- web/src/routes/admin/requests/+page.svelte | 7 +-- web/src/routes/admin/users/+page.svelte | 5 +- web/src/routes/albums/[id]/+page.svelte | 3 +- web/src/routes/artists/[id]/+page.svelte | 3 +- web/src/routes/collection/+layout.svelte | 7 +-- .../routes/collection/duplicates/+page.svelte | 19 +++---- .../routes/collection/missing/+page.svelte | 7 +-- .../routes/collection/reports/+page.svelte | 2 +- .../collection/suspect-sources/+page.svelte | 7 +-- web/src/routes/library/albums/+page.svelte | 3 +- web/src/routes/library/artists/+page.svelte | 3 +- web/src/routes/library/genres/+page.svelte | 5 +- web/src/routes/library/years/+page.svelte | 5 +- web/src/routes/playlists/[id]/+page.svelte | 3 +- web/src/routes/requests/+page.svelte | 7 +-- web/src/routes/search/albums/+page.svelte | 3 +- web/src/routes/search/artists/+page.svelte | 3 +- web/src/routes/search/tracks/+page.svelte | 3 +- 34 files changed, 144 insertions(+), 75 deletions(-) create mode 100644 web/src/lib/utils/plural.test.ts create mode 100644 web/src/lib/utils/plural.ts diff --git a/web/src/lib/admin/queues.ts b/web/src/lib/admin/queues.ts index f8d6149e..767831a7 100644 --- a/web/src/lib/admin/queues.ts +++ b/web/src/lib/admin/queues.ts @@ -1,3 +1,4 @@ +import { plural } from '#lib/utils/plural.js'; import type { AdminQueue, AdminSummary } from '#lib/api/types.js'; // The queues that wait on an admin (#5605), in the order the Overview lists @@ -30,5 +31,5 @@ export function countOf(summary: AdminSummary | undefined, key: QueueKey): numbe } export function queueLabel(def: QueueDef, n: number): string { - return `${n} ${n === 1 ? def.one : def.many}`; + return plural(n, def.one, def.many); } diff --git a/web/src/lib/api/client.ts b/web/src/lib/api/client.ts index 2e623394..6b9beb48 100644 --- a/web/src/lib/api/client.ts +++ b/web/src/lib/api/client.ts @@ -1,3 +1,4 @@ +import { plural } from '#lib/utils/plural.js'; export type ApiError = { code: string; message: string; @@ -18,7 +19,7 @@ export function rateLimitMessage(err: unknown): string | null { const secs = apiErr.retryAfter; if (!secs || secs <= 0) return 'Too many attempts. Try again in a few minutes.'; const mins = Math.ceil(secs / 60); - return `Too many attempts. Try again in ${mins} minute${mins === 1 ? '' : 's'}.`; + return `Too many attempts. Try again in ${plural(mins, 'minute', 'minutes')}.`; } export type User = { diff --git a/web/src/lib/components/ActiveSessions.svelte b/web/src/lib/components/ActiveSessions.svelte index 674c1d93..82ee5cd2 100644 --- a/web/src/lib/components/ActiveSessions.svelte +++ b/web/src/lib/components/ActiveSessions.svelte @@ -1,4 +1,5 @@ {#if unmatched.isPending} @@ -89,7 +89,7 @@ {u.title} -
{u.artist} · {tracks(u.tracks)}
+
{u.artist} · {plural(u.tracks, 'track', 'tracks')}

{u.detail}

@@ -131,7 +131,7 @@
{u.title}
- {u.artist} · {tracks(u.tracks)} · left off {relativeTime(u.decided_at)} + {u.artist} · {plural(u.tracks, 'track', 'tracks')} · left off {relativeTime(u.decided_at)}