import i18n from "./index"; // The translation KEY a piece of on-screen text is, or null (E22 S5 click capture). // // A click is logged by what the control IS, and its visible label is the most telling part — but a // label can be the user's own content (a video title, a tag, a channel name), which the log must not // carry. Text that is exactly one of the app's own translated strings is app copy, not user content, // so it can be logged — as its ENGLISH wording, whatever the UI language: the same click reads the // same in every log, and nothing a user typed comes out of it (a user's tag that happens to equal a // string of ours is logged as our string, which says nothing about the user). Not as a key: one // wording is often several keys ("Diagnostics" is a settings tab AND a config group), so a key would // name a control the user may never have touched. Interpolated strings (`{{n}} items`) never match. let index: Map | null = null; const normalize = (text: string) => text.replace(/\s+/g, " ").trim(); /** Every app string (any language) → its English wording. */ function build(): Map { const map = new Map(); const resources = i18n.options.resources ?? {}; const english = (path: string[]): string | null => { let node: unknown = resources.en?.translation; for (const key of path) node = (node as Record | undefined)?.[key]; return typeof node === "string" ? normalize(node) : null; }; const walk = (node: unknown, path: string[]) => { if (typeof node === "string") { const text = normalize(node); const en = english(path); if (en && text.length >= 2 && !text.includes("{{") && !map.has(text)) map.set(text, en); } else if (node && typeof node === "object") { for (const [k, v] of Object.entries(node)) walk(v, [...path, k]); } }; for (const lang of Object.keys(resources)) walk(resources[lang]?.translation, []); return map; } export function appCopyOf(text: string | null | undefined): string | null { if (!text) return null; index ??= build(); return index.get(normalize(text)) ?? null; }