A pure move (git mv, history kept): 333 files leave components/, which now holds only the platform layer (ui/) and the legal pages. The shell is the frame (App, header, nav rail, palette, boot); each page lives in modules/<page>/ with its rail, store and tests; what several pages share sits in features/<name>/; the shared-link page is watch/. Domain-free helpers went straight to ui/ (ViewSwitcher, FilterRail, the confirm dialog, the language switcher, the copy rows). Every relative specifier was rewritten (imports, dynamic imports, vi.mock, new URL), and the contract tests that scan sources now scan the whole app source, not only components/ — each glob was counted before and after so none went green over fewer files. The locale-format rule matched `/src/components/` only, so the move would have taken ~300 files out from under its i18n-singleton check; it now covers every folder that holds components, with a test per folder.
101 lines
4.1 KiB
TypeScript
101 lines
4.1 KiB
TypeScript
// The public /watch page's own strings. The page is opened by whoever got the link, signed out and
|
|
// with no app language preference, so it reads the browser's language against this small dict
|
|
// instead of loading the app's i18n (every locale of every area — half of what the page weighed).
|
|
|
|
const STR = {
|
|
en: {
|
|
loading: "Loading…",
|
|
gone: "This link is no longer available.",
|
|
goneHint: "It may have expired or been revoked by the owner.",
|
|
passwordTitle: "This video is password-protected",
|
|
passwordPlaceholder: "Enter password",
|
|
watch: "Watch",
|
|
wrong: "Wrong password.",
|
|
download: "Download",
|
|
file: "File",
|
|
links: "Links",
|
|
brand: "Shared via Siftlode",
|
|
repeat: "Repeat",
|
|
failed: "Couldn't load this link.",
|
|
failedHint: "Check your connection and try again.",
|
|
preparing: "This video is being prepared.",
|
|
preparingHint: "Try again in a few minutes.",
|
|
retry: "Try again",
|
|
tooMany: "Too many attempts. Try again in a few minutes.",
|
|
unlockFailed: "Couldn't check the password. Try again.",
|
|
crashTitle: "Something went wrong.",
|
|
crashHint: "Reload the page to try again.",
|
|
reload: "Reload",
|
|
passwordTitleFolder: "This folder is password-protected",
|
|
folderEmpty: "This folder is empty.",
|
|
play: "Play",
|
|
files: (n: number) => (n === 1 ? "1 file" : `${n} files`),
|
|
},
|
|
hu: {
|
|
loading: "Betöltés…",
|
|
gone: "Ez a link már nem elérhető.",
|
|
goneHint: "Lehet, hogy lejárt, vagy a tulajdonos visszavonta.",
|
|
passwordTitle: "Ez a videó jelszóval védett",
|
|
passwordPlaceholder: "Add meg a jelszót",
|
|
watch: "Megnézem",
|
|
wrong: "Hibás jelszó.",
|
|
download: "Letöltés",
|
|
file: "Fájl",
|
|
links: "Linkek",
|
|
brand: "Megosztva a Siftlode-dal",
|
|
repeat: "Ismétlés",
|
|
failed: "Nem sikerült betölteni a linket.",
|
|
failedHint: "Ellenőrizd a kapcsolatot, és próbáld újra.",
|
|
preparing: "A videó előkészítése folyamatban.",
|
|
preparingHint: "Próbáld újra néhány perc múlva.",
|
|
retry: "Újrapróbálás",
|
|
tooMany: "Túl sok próbálkozás. Próbáld újra pár perc múlva.",
|
|
unlockFailed: "Nem sikerült ellenőrizni a jelszót. Próbáld újra.",
|
|
crashTitle: "Valami hiba történt.",
|
|
crashHint: "Töltsd újra az oldalt, és próbáld újra.",
|
|
reload: "Újratöltés",
|
|
passwordTitleFolder: "Ez a mappa jelszóval védett",
|
|
folderEmpty: "Ez a mappa üres.",
|
|
play: "Lejátszás",
|
|
files: (n: number) => `${n} fájl`,
|
|
},
|
|
de: {
|
|
loading: "Wird geladen…",
|
|
gone: "Dieser Link ist nicht mehr verfügbar.",
|
|
goneHint: "Er ist möglicherweise abgelaufen oder wurde widerrufen.",
|
|
passwordTitle: "Dieses Video ist passwortgeschützt",
|
|
passwordPlaceholder: "Passwort eingeben",
|
|
watch: "Ansehen",
|
|
wrong: "Falsches Passwort.",
|
|
download: "Herunterladen",
|
|
file: "Datei",
|
|
links: "Links",
|
|
brand: "Geteilt über Siftlode",
|
|
repeat: "Wiederholen",
|
|
failed: "Der Link konnte nicht geladen werden.",
|
|
failedHint: "Prüfe deine Verbindung und versuche es erneut.",
|
|
preparing: "Dieses Video wird gerade vorbereitet.",
|
|
preparingHint: "Versuche es in ein paar Minuten erneut.",
|
|
retry: "Erneut versuchen",
|
|
tooMany: "Zu viele Versuche. Versuche es in ein paar Minuten erneut.",
|
|
unlockFailed: "Das Passwort konnte nicht geprüft werden. Versuche es erneut.",
|
|
crashTitle: "Etwas ist schiefgelaufen.",
|
|
crashHint: "Lade die Seite neu und versuche es erneut.",
|
|
reload: "Neu laden",
|
|
passwordTitleFolder: "Dieser Ordner ist passwortgeschützt",
|
|
folderEmpty: "Dieser Ordner ist leer.",
|
|
play: "Abspielen",
|
|
files: (n: number) => (n === 1 ? "1 Datei" : `${n} Dateien`),
|
|
},
|
|
} as const;
|
|
|
|
export const lang =
|
|
((navigator.language || "en").slice(0, 2) as keyof typeof STR) in STR
|
|
? ((navigator.language || "en").slice(0, 2) as keyof typeof STR)
|
|
: "en";
|
|
export const T = STR[lang];
|
|
|
|
// The document says the language its text is in: a screen reader picks its voice by it, and the
|
|
// browser offers to translate by it. watch.html can only ship one; this page picks its own.
|
|
document.documentElement.lang = lang;
|