Files
scoreko-dev/src/dashboard/scoreko-dev/i18n.ts
T

278 lines
12 KiB
TypeScript

import { ref } from 'vue';
export type Locale = 'en' | 'es';
type Translations = {
menuDashboard: string;
menuPlayers: string;
menuGraphics: string;
menuSettings: string;
menuAbout: string;
settingsTitle: string;
settingsDescription: string;
settingsLanguageLabel: string;
settingsLanguageHint: string;
settingsShortcutTitle: string;
settingsShortcutDescription: string;
settingsShortcutLeftIncrementLabel: string;
settingsShortcutLeftIncrementHint: string;
settingsShortcutLeftDecrementLabel: string;
settingsShortcutLeftDecrementHint: string;
settingsShortcutRightIncrementLabel: string;
settingsShortcutRightIncrementHint: string;
settingsShortcutRightDecrementLabel: string;
settingsShortcutRightDecrementHint: string;
settingsShortcutReset: string;
languageEnglish: string;
languageSpanish: string;
scoreboardUnassigned: string;
scoreboardLeft: string;
scoreboardRight: string;
scoreboardPreview: string;
scoreboardLeftImage: string;
scoreboardRightImage: string;
scoreboardLabelCharacter: string;
scoreboardLabelPlayer: string;
scoreboardLabelTeam: string;
scoreboardLabelCountry: string;
scoreboardLabelGame: string;
aboutTitle: string;
aboutVersion: string;
aboutDescription: string;
aboutFrameworkNodeCG: string;
aboutCollaboratorsTitle: string;
aboutUpdateSystemTitle: string;
aboutUpdateSystemDescription: string;
aboutCheckUpdates: string;
aboutLatestRelease: string;
aboutPublished: string;
aboutUpdateAvailable: string;
aboutUpToDate: string;
aboutViewRelease: string;
aboutElectronNote: string;
aboutUnknownReleaseError: string;
aboutGitHubStatusError: string;
graphicsTitle: string;
graphicsDescription: string;
graphicsNoConfigured: string;
graphicsCopyUrl: string;
graphicsDragObs: string;
graphicsScoreboard: string;
graphicsCommentary: string;
graphicsSkinLabel: string;
commentaryTitle: string;
commentaryCommentator1: string;
commentaryCommentator2: string;
commentaryTwitterText: string;
bracketTitle: string;
bracketStage: string;
bracketSide: string;
bracketCustomProgress: string;
playersLabelTeam: string;
playersLabelCountry: string;
playersLabelActions: string;
playersStartggHelp: string;
playersConnectStartgg: string;
playersConnected: string;
playersUsePersonalApi: string;
playersTournament: string;
playersImportPlayers: string;
playersChallongeHelp: string;
playersConnectChallonge: string;
playersNewPlayer: string;
playersSearchPlaceholder: string;
playersImport: string;
playersExport: string;
};
const STORAGE_KEY = 'scoreko-dev.language';
const messages: Record<Locale, Translations> = {
en: {
menuDashboard: 'Dashboard',
menuPlayers: 'Players',
menuGraphics: 'Graphics',
menuSettings: 'Settings',
menuAbout: 'About',
settingsTitle: 'Settings',
settingsDescription: 'Dashboard and bundle configuration.',
settingsLanguageLabel: 'Language',
settingsLanguageHint: 'Choose the dashboard language.',
settingsShortcutTitle: 'Keyboard shortcuts',
settingsShortcutDescription: 'Configure quick keys to update the score for each side.',
settingsShortcutLeftIncrementLabel: 'P1 score +1',
settingsShortcutLeftIncrementHint: 'Increases left player score by one.',
settingsShortcutLeftDecrementLabel: 'P1 score -1',
settingsShortcutLeftDecrementHint: 'Decreases left player score by one.',
settingsShortcutRightIncrementLabel: 'P2 score +1',
settingsShortcutRightIncrementHint: 'Increases right player score by one.',
settingsShortcutRightDecrementLabel: 'P2 score -1',
settingsShortcutRightDecrementHint: 'Decreases right player score by one.',
settingsShortcutReset: 'Reset shortcuts',
languageEnglish: 'English',
languageSpanish: 'Spanish',
scoreboardUnassigned: '(Unassigned)',
scoreboardLeft: 'Left',
scoreboardRight: 'Right',
scoreboardPreview: 'preview',
scoreboardLeftImage: 'Left image',
scoreboardRightImage: 'Right image',
scoreboardLabelCharacter: 'Character',
scoreboardLabelPlayer: 'Player',
scoreboardLabelTeam: 'Team',
scoreboardLabelCountry: 'Country',
scoreboardLabelGame: 'Game',
aboutTitle: 'About',
aboutVersion: 'Version',
aboutDescription: 'Dashboard for producing fighting game overlays using NodeCG, Vue, and Quasar.',
aboutFrameworkNodeCG: 'Framework NodeCG',
aboutCollaboratorsTitle: 'Collaborators and acknowledgments',
aboutUpdateSystemTitle: 'Update system (GitHub Releases)',
aboutUpdateSystemDescription: 'This check fetches the latest release from the repository and compares it with the current version.',
aboutCheckUpdates: 'Check for updates',
aboutLatestRelease: 'Latest release',
aboutPublished: 'Published',
aboutUpdateAvailable: 'A newer version is available.',
aboutUpToDate: 'Your version is up to date with the latest release.',
aboutViewRelease: 'View release',
aboutElectronNote: 'Note for Electron: this panel only implements detection and notification. For real automatic desktop updates, you need to integrate autoUpdater into Electron\'s main process and publish signed artifacts per platform.',
aboutUnknownReleaseError: 'Unknown error while checking releases.',
aboutGitHubStatusError: 'GitHub responded with status',
graphicsTitle: 'Graphics',
graphicsDescription: 'Bundle graphics controls and status.',
graphicsNoConfigured: 'There are no graphics configured in this bundle.',
graphicsCopyUrl: 'Copy URL',
graphicsDragObs: 'Drag into OBS',
graphicsScoreboard: 'Scoreboard',
graphicsCommentary: 'Commentary',
graphicsSkinLabel: 'Skin',
commentaryTitle: 'Commentary',
commentaryCommentator1: 'Commentator #1',
commentaryCommentator2: 'Commentator #2',
commentaryTwitterText: '@Twitter / Text',
bracketTitle: 'Bracket',
bracketStage: 'Stage',
bracketSide: 'Bracket side',
bracketCustomProgress: 'Custom progress',
playersLabelTeam: 'Team',
playersLabelCountry: 'Country',
playersLabelActions: 'Actions',
playersStartggHelp: 'Connect via OAuth (recommended) or paste your personal token to load tournaments you created or administrate. If you see "Client authentication failed", verify your config uses the Client ID/Secret from a start.gg OAuth App.',
playersConnectStartgg: 'Connect with start.gg',
playersConnected: 'Connected',
playersUsePersonalApi: 'Use personal API',
playersTournament: 'Tournament',
playersImportPlayers: 'Import players',
playersChallongeHelp: 'Connect with OAuth or paste your personal token to load your Challonge tournaments and import participants.',
playersConnectChallonge: 'Connect with Challonge',
playersNewPlayer: 'New player',
playersSearchPlaceholder: 'Search...',
playersImport: 'Import',
playersExport: 'Export',
},
es: {
menuDashboard: 'Panel',
menuPlayers: 'Jugadores',
menuGraphics: 'Gráficos',
menuSettings: 'Configuración',
menuAbout: 'Acerca de',
settingsTitle: 'Configuración',
settingsDescription: 'Configuración del dashboard y del bundle.',
settingsLanguageLabel: 'Idioma',
settingsLanguageHint: 'Selecciona el idioma del dashboard.',
settingsShortcutTitle: 'Atajos de teclado',
settingsShortcutDescription: 'Configura teclas rápidas para actualizar el score de cada lado.',
settingsShortcutLeftIncrementLabel: 'Score P1 +1',
settingsShortcutLeftIncrementHint: 'Incrementa en uno el score del jugador izquierdo.',
settingsShortcutLeftDecrementLabel: 'Score P1 -1',
settingsShortcutLeftDecrementHint: 'Reduce en uno el score del jugador izquierdo.',
settingsShortcutRightIncrementLabel: 'Score P2 +1',
settingsShortcutRightIncrementHint: 'Incrementa en uno el score del jugador derecho.',
settingsShortcutRightDecrementLabel: 'Score P2 -1',
settingsShortcutRightDecrementHint: 'Reduce en uno el score del jugador derecho.',
settingsShortcutReset: 'Restablecer atajos',
languageEnglish: 'Inglés',
languageSpanish: 'Castellano',
scoreboardUnassigned: '(Sin asignar)',
scoreboardLeft: 'Izquierda',
scoreboardRight: 'Derecha',
scoreboardPreview: 'vista previa',
scoreboardLeftImage: 'Imagen izquierda',
scoreboardRightImage: 'Imagen derecha',
scoreboardLabelCharacter: 'Personaje',
scoreboardLabelPlayer: 'Jugador',
scoreboardLabelTeam: 'Equipo',
scoreboardLabelCountry: 'País',
scoreboardLabelGame: 'Juego',
aboutTitle: 'Acerca de',
aboutVersion: 'Versión',
aboutDescription: 'Dashboard para producir overlays de juegos de lucha usando NodeCG, Vue y Quasar.',
aboutFrameworkNodeCG: 'Framework NodeCG',
aboutCollaboratorsTitle: 'Colaboradores y agradecimientos',
aboutUpdateSystemTitle: 'Sistema de actualizaciones (GitHub Releases)',
aboutUpdateSystemDescription: 'Esta comprobación obtiene la última release del repositorio y la compara con la versión actual.',
aboutCheckUpdates: 'Buscar actualizaciones',
aboutLatestRelease: 'Última release',
aboutPublished: 'Publicado',
aboutUpdateAvailable: 'Hay una versión más nueva disponible.',
aboutUpToDate: 'Tu versión está actualizada con la última release.',
aboutViewRelease: 'Ver release',
aboutElectronNote: 'Nota para Electron: este panel solo implementa detección y notificación. Para actualizaciones automáticas reales de escritorio, debes integrar autoUpdater en el proceso principal de Electron y publicar artefactos firmados por plataforma.',
aboutUnknownReleaseError: 'Error desconocido al consultar releases.',
aboutGitHubStatusError: 'GitHub respondió con estado',
graphicsTitle: 'Gráficos',
graphicsDescription: 'Controles y estado de los gráficos del bundle.',
graphicsNoConfigured: 'No hay gráficos configurados en este bundle.',
graphicsCopyUrl: 'Copiar URL',
graphicsDragObs: 'Arrastrar a OBS',
graphicsScoreboard: 'Scoreboard',
graphicsCommentary: 'Comentario',
graphicsSkinLabel: 'Skin',
commentaryTitle: 'Comentario',
commentaryCommentator1: 'Comentarista #1',
commentaryCommentator2: 'Comentarista #2',
commentaryTwitterText: '@Twitter / Texto',
bracketTitle: 'Bracket',
bracketStage: 'Etapa',
bracketSide: 'Lado del bracket',
bracketCustomProgress: 'Progreso personalizado',
playersLabelTeam: 'Equipo',
playersLabelCountry: 'País',
playersLabelActions: 'Acciones',
playersStartggHelp: 'Conéctate por OAuth (recomendado) o pega tu token personal para cargar torneos que creaste o administras. Si ves "Client authentication failed", revisa que tu configuración use el Client ID/Secret de una app OAuth de start.gg.',
playersConnectStartgg: 'Conectar con start.gg',
playersConnected: 'Conectado',
playersUsePersonalApi: 'Usar API personal',
playersTournament: 'Torneo',
playersImportPlayers: 'Importar jugadores',
playersChallongeHelp: 'Conéctate con OAuth o pega tu token personal para cargar tus torneos de Challonge e importar participantes.',
playersConnectChallonge: 'Conectar con Challonge',
playersNewPlayer: 'Nuevo jugador',
playersSearchPlaceholder: 'Buscar...',
playersImport: 'Importar',
playersExport: 'Exportar',
},
};
const normalizeLocale = (value: unknown): Locale => (value === 'es' ? 'es' : 'en');
const getStoredLocale = (): Locale => {
if (typeof window === 'undefined') {
return 'en';
}
return normalizeLocale(localStorage.getItem(STORAGE_KEY));
};
export const locale = ref<Locale>(getStoredLocale());
export const setLocale = (value: Locale) => {
locale.value = normalizeLocale(value);
if (typeof window !== 'undefined') {
localStorage.setItem(STORAGE_KEY, locale.value);
}
};
export const t = (key: keyof Translations): string => messages[locale.value][key];