fix(notifications): a notice value is no plain string, so a translated name cannot freeze in one language

A name goes in as raw(), a translated word as its own msg(): tsc now lists every value, and the
ones that froze are said when shown — Watch later and an untitled channel in the pin and channel
notices, a Plex season's name in its removal toast (a new seasonTitleText, which seasonTitle says).
This commit is contained in:
2026-10-30 00:03:48 +01:00
parent cb8b99e0e7
commit 4a0d4b0964
37 changed files with 174 additions and 109 deletions
@@ -29,7 +29,7 @@ import { LS, useTabPersistedState } from "../../lib/storage";
import { SETTINGS_TAB_KEY, settingsTabParams } from "../../lib/settingsTab";
import { useUrlMirror } from "../../lib/useUrlMirror";
import Avatar from "../../components/ui/Avatar";
import { msg, type NotifSettings, notify } from "../../lib/notifications";
import { msg, type NotifSettings, notify, raw } from "../../lib/notifications";
import Tooltip from "../../components/ui/Tooltip";
import { Section, SwitchRow } from "../../components/ui/form";
import { Badge } from "../../components/ui/Badge";
@@ -402,7 +402,7 @@ export function SignInMethods({ me }: { me: Me }) {
await qc.invalidateQueries({ queryKey: qk.me() });
notify({
level: "success",
message: msg("settings.account.password.saved", { email: me.email }),
message: msg("settings.account.password.saved", { email: raw(me.email) }),
});
} catch (e) {
setErr(
@@ -33,7 +33,7 @@ vi.mock("../../lib/format", async (importOriginal) => ({
import type { TFunction } from "i18next";
import TakeoutImport from "./TakeoutImport";
import { msg, sayNotif, type NotifText } from "../../lib/notifications";
import { msg, type NotifText, raw, sayNotif } from "../../lib/notifications";
afterEach(() => {
cleanup();
@@ -282,7 +282,7 @@ describe("YouTube history import · while it runs", () => {
expect(mocks.notify).toHaveBeenCalledWith({
level: "error",
message: msg("settings.takeout.tooLarge", {
name: "watch-history.json",
name: raw("watch-history.json"),
limit: { bytes: 10 },
}),
});
@@ -9,7 +9,7 @@ import { StateMessage } from "../../components/ui/QueryState";
import { api, type TakeoutStatus, type TakeoutUpload } from "../../lib/api";
import type { TAKEOUT_OUTCOMES } from "../../lib/api/feed";
import { qk } from "../../lib/queryKeys";
import { msg, notify } from "../../lib/notifications";
import { msg, notify, raw } from "../../lib/notifications";
import { notifyActionError } from "../../lib/actionErrors";
import { formatDateTime, formatNumber } from "../../lib/format";
import { importBusy, invalidateImported, watchTakeout } from "./takeoutWatch";
@@ -129,7 +129,7 @@ export default function TakeoutImport() {
// Refused here, not after minutes of upload, and with the limit named.
notify({
level: "error",
message: msg("settings.takeout.tooLarge", { name: file.name, limit: { bytes: max } }),
message: msg("settings.takeout.tooLarge", { name: raw(file.name), limit: { bytes: max } }),
});
return false;
}
@@ -145,7 +145,7 @@ export default function TakeoutImport() {
notify({
level: "success",
message: msg("settings.takeout.read", {
name: file.name,
name: raw(file.name),
count: res.videos,
n: { number: res.videos },
}),