422 lines
17 KiB
TypeScript
422 lines
17 KiB
TypeScript
|
|
import { useCallback, useMemo } from "react";
|
||
|
|
|
||
|
|
type Locale = "en" | "fr";
|
||
|
|
|
||
|
|
const translations = {
|
||
|
|
en: {
|
||
|
|
"app.name": "Negopoly Bank",
|
||
|
|
"common.loading": "Loading...",
|
||
|
|
"common.notice": "Notice:",
|
||
|
|
"common.reset": "Reset",
|
||
|
|
"common.guest": "Guest",
|
||
|
|
"common.dummy": "Dummy",
|
||
|
|
"common.player": "Player",
|
||
|
|
"common.banker": "Banker",
|
||
|
|
"common.bank": "Bank",
|
||
|
|
"common.online": "online",
|
||
|
|
"common.offline": "Offline",
|
||
|
|
"common.name": "Name",
|
||
|
|
"common.startingBalance": "Starting balance",
|
||
|
|
"common.selectPlayer": "Select player",
|
||
|
|
"common.reason": "Reason",
|
||
|
|
"common.amount": "Amount",
|
||
|
|
"common.note": "Note",
|
||
|
|
"common.noReason": "No reason provided",
|
||
|
|
"common.from": "From",
|
||
|
|
"common.to": "To",
|
||
|
|
"common.apply": "Apply",
|
||
|
|
"common.force": "Force",
|
||
|
|
"common.trigger": "Trigger",
|
||
|
|
"common.send": "Send",
|
||
|
|
"common.download": "Download",
|
||
|
|
"common.load": "Load",
|
||
|
|
"common.save": "Save",
|
||
|
|
"common.transactions": "Transactions",
|
||
|
|
"common.noActivity": "No activity yet.",
|
||
|
|
"common.connecting": "Connecting to session {id}...",
|
||
|
|
"common.sessionLive": "Session {code} · live",
|
||
|
|
"common.continue": "Continue",
|
||
|
|
"tabs.dashboard": "Dashboard",
|
||
|
|
"tabs.tools": "Tools",
|
||
|
|
"tabs.home": "Home",
|
||
|
|
"tabs.transfers": "Transfers",
|
||
|
|
"tabs.chat": "Chat",
|
||
|
|
"entry.tagline": "Open a lobby or join the city.",
|
||
|
|
"entry.liveSessions": "Live sessions",
|
||
|
|
"entry.bankerControlled": "Banker controlled",
|
||
|
|
"entry.createTitle": "Create a session",
|
||
|
|
"entry.createSubtitle": "Become the banker and control the flow of money.",
|
||
|
|
"entry.bankerName": "Banker name",
|
||
|
|
"entry.openVault": "Open the vault",
|
||
|
|
"entry.joinTitle": "Join a session",
|
||
|
|
"entry.joinSubtitle": "Enter a session code to continue.",
|
||
|
|
"entry.sessionCode": "Session code",
|
||
|
|
"entry.codePlaceholder": "Enter code",
|
||
|
|
"entry.newPlayerLabel": "Create a new player",
|
||
|
|
"entry.playerName": "Player name",
|
||
|
|
"entry.joinAsNew": "Join as new player",
|
||
|
|
"entry.takeoverTitle": "Take over a dummy",
|
||
|
|
"entry.alreadyConnected": "You are already connected to this session.",
|
||
|
|
"entry.selectDummy": "Select dummy",
|
||
|
|
"entry.yourNameOptional": "Your name (optional)",
|
||
|
|
"entry.requestTakeover": "Request takeover",
|
||
|
|
"entry.noDummies": "No dummies available to take over yet.",
|
||
|
|
"entry.changeCode": "Change code",
|
||
|
|
"entry.alert.enterCode": "Enter a session code",
|
||
|
|
"entry.alert.sessionNotFound": "Session not found",
|
||
|
|
"entry.alert.selectDummy": "Select a dummy player",
|
||
|
|
"lobby.title": "Negopoly Lobby",
|
||
|
|
"lobby.sessionLabel": "Session {id}",
|
||
|
|
"lobby.joinTitle": "Join this lobby",
|
||
|
|
"lobby.loadingInfo": "Loading session info...",
|
||
|
|
"lobby.waitingState": "Waiting for the lobby state.",
|
||
|
|
"lobby.header": "Lobby · Session {code}",
|
||
|
|
"lobby.statusLine": "Status: {status} · {count} players",
|
||
|
|
"lobby.roster": "Lobby roster",
|
||
|
|
"lobby.startGame": "Start the game",
|
||
|
|
"lobby.waitingBanker": "Waiting for the banker to start the game.",
|
||
|
|
"lobby.sessionClosed": "Session closed.",
|
||
|
|
"lobby.inviteQr": "Invite QR",
|
||
|
|
"lobby.scanToJoin": "Scan to join this lobby instantly.",
|
||
|
|
"lobby.addDummyTitle": "Add dummy player",
|
||
|
|
"lobby.addDummySubtitle":
|
||
|
|
"Create a player for someone without the app. Dummies can be taken over later.",
|
||
|
|
"lobby.enterDummyName": "Enter a dummy name",
|
||
|
|
"lobby.addDummyButton": "Add dummy",
|
||
|
|
"lobby.errorLoadInfo": "Unable to load session info",
|
||
|
|
"banker.consoleTitle": "Banker Console",
|
||
|
|
"banker.controlsTitle": "Banker controls",
|
||
|
|
"banker.tools.playersTab": "Players",
|
||
|
|
"banker.tools.adminTab": "Admin",
|
||
|
|
"banker.playersTitle": "Players",
|
||
|
|
"banker.playerOverview": "Player overview",
|
||
|
|
"banker.noPlayers": "No players yet.",
|
||
|
|
"banker.adminControls": "Session controls",
|
||
|
|
"banker.adjustBalance": "Adjust balance",
|
||
|
|
"banker.adjustAmountPlaceholder": "+/- amount",
|
||
|
|
"banker.forceTransfer": "Force transfer",
|
||
|
|
"banker.createDummy": "Create dummy",
|
||
|
|
"banker.dummyName": "Dummy name",
|
||
|
|
"banker.addDummy": "Add dummy",
|
||
|
|
"banker.blackout": "EMP",
|
||
|
|
"banker.blackoutToggle": "Toggle EMP",
|
||
|
|
"banker.blackoutEnable": "Enable EMP",
|
||
|
|
"banker.blackoutDisable": "Disable EMP",
|
||
|
|
"banker.blackoutReason": "EMP reason",
|
||
|
|
"banker.endSession": "End session",
|
||
|
|
"banker.takeoverApprovals": "Takeover approvals",
|
||
|
|
"banker.wants": "Wants {name}",
|
||
|
|
"banker.approve": "Approve",
|
||
|
|
"banker.stateTitle": "GameState",
|
||
|
|
"banker.stateSubtitle": "Export, import, or resume a session from a saved snapshot.",
|
||
|
|
"banker.downloadState": "Download current GameState",
|
||
|
|
"banker.loadFromFile": "Load GameState from file",
|
||
|
|
"banker.loadFromStorage": "Load from browser storage",
|
||
|
|
"banker.stateDownloaded": "GameState downloaded.",
|
||
|
|
"banker.stateDownloadError": "Unable to download GameState.",
|
||
|
|
"banker.stateLoaded": "GameState loaded.",
|
||
|
|
"banker.stateLoadError": "Unable to load GameState.",
|
||
|
|
"banker.stateLoadInvalid": "Invalid GameState file.",
|
||
|
|
"banker.autosaveTitle": "AutoSave",
|
||
|
|
"banker.autosaveSubtitle": "Keep rolling backups in this browser.",
|
||
|
|
"banker.autosaveToggle": "Enable AutoSave",
|
||
|
|
"banker.autosaveEnabled": "AutoSave is enabled",
|
||
|
|
"banker.autosaveInterval": "Minutes between saves",
|
||
|
|
"banker.autosaveMinutes": "e.g. 3",
|
||
|
|
"banker.autosaveKeep": "Snapshots to keep",
|
||
|
|
"banker.autosaveCount": "e.g. 5",
|
||
|
|
"banker.autosaveNow": "Save now",
|
||
|
|
"banker.autosaveSaved": "AutoSave captured.",
|
||
|
|
"banker.autosaveFailed": "AutoSave failed.",
|
||
|
|
"banker.noAutosaves": "No autosaves yet.",
|
||
|
|
"banker.savedAt": "Saved {time}",
|
||
|
|
"player.deskTitle": "Player Desk",
|
||
|
|
"player.quickTransfer": "Quick transfer",
|
||
|
|
"player.sendTo": "Send to",
|
||
|
|
"player.noteOptional": "Note (optional)",
|
||
|
|
"player.notePlaceholder": "For what?",
|
||
|
|
"player.sendFunds": "Send funds",
|
||
|
|
"transfers.error": "Choose a player and a valid amount.",
|
||
|
|
"player.lastUpdated": "Last updated {time}",
|
||
|
|
"home.balance": "Balance",
|
||
|
|
"blackout.title": "EMP",
|
||
|
|
"blackout.defaultReason": "EMP in effect",
|
||
|
|
"blackout.active": "EMP active",
|
||
|
|
"chat.title": "Chats",
|
||
|
|
"chat.global": "Global chat",
|
||
|
|
"chat.conversationCount": "{count} conversations",
|
||
|
|
"chat.conversationCountOne": "1 conversation",
|
||
|
|
"chat.searchPlaceholder": "Search chats",
|
||
|
|
"chat.newTitle": "New chat",
|
||
|
|
"chat.newSubtitle": "Start a direct or group conversation",
|
||
|
|
"chat.direct": "Direct",
|
||
|
|
"chat.group": "Group",
|
||
|
|
"chat.groupName": "Group name",
|
||
|
|
"chat.groupPlaceholder": "e.g. Negotiators",
|
||
|
|
"chat.choosePlayers": "Choose players",
|
||
|
|
"chat.noPlayers": "No other players available yet.",
|
||
|
|
"chat.back": "Back",
|
||
|
|
"chat.backChats": "Chats",
|
||
|
|
"chat.noMessages": "No messages yet.",
|
||
|
|
"chat.startConversation": "Start the conversation.",
|
||
|
|
"chat.messagePlaceholder": "Message",
|
||
|
|
"chat.startChat": "Start chat",
|
||
|
|
"chat.everyone": "Everyone in the session",
|
||
|
|
"chat.directMessage": "Direct message",
|
||
|
|
"chat.memberCount": "{count} members",
|
||
|
|
"chat.memberCountOne": "1 member",
|
||
|
|
"chat.error.direct": "Choose one person to start a direct chat.",
|
||
|
|
"chat.error.groupName": "Give the group a name.",
|
||
|
|
"chat.error.member": "Select at least one member.",
|
||
|
|
"transaction.transfer": "Transfer",
|
||
|
|
"transaction.banker_adjust": "Banker adjustment",
|
||
|
|
"transaction.banker_force_transfer": "Forced transfer",
|
||
|
|
"status.lobby": "Lobby",
|
||
|
|
"status.active": "Active",
|
||
|
|
"status.ended": "Ended",
|
||
|
|
"connection.idle": "idle",
|
||
|
|
"connection.connecting": "connecting",
|
||
|
|
"connection.open": "connected",
|
||
|
|
"connection.error": "error",
|
||
|
|
"error.parseResponse": "Unable to parse server response",
|
||
|
|
"error.createSession": "Unable to create session",
|
||
|
|
"error.joinSession": "Unable to join session",
|
||
|
|
"error.connectionNotReady": "Connection not ready",
|
||
|
|
},
|
||
|
|
fr: {
|
||
|
|
"app.name": "Banque Negopoly",
|
||
|
|
"common.loading": "Chargement...",
|
||
|
|
"common.notice": "Info :",
|
||
|
|
"common.reset": "Réinitialiser",
|
||
|
|
"common.guest": "Invité",
|
||
|
|
"common.dummy": "Dummy",
|
||
|
|
"common.player": "Joueur",
|
||
|
|
"common.banker": "Banquier",
|
||
|
|
"common.bank": "Banque",
|
||
|
|
"common.online": "en ligne",
|
||
|
|
"common.offline": "Hors ligne",
|
||
|
|
"common.name": "Nom",
|
||
|
|
"common.startingBalance": "Solde de départ",
|
||
|
|
"common.selectPlayer": "Choisir un joueur",
|
||
|
|
"common.reason": "Raison",
|
||
|
|
"common.amount": "Montant",
|
||
|
|
"common.note": "Note",
|
||
|
|
"common.noReason": "Aucune raison fournie",
|
||
|
|
"common.from": "De",
|
||
|
|
"common.to": "À",
|
||
|
|
"common.apply": "Appliquer",
|
||
|
|
"common.force": "Forcer",
|
||
|
|
"common.trigger": "Déclencher",
|
||
|
|
"common.send": "Envoyer",
|
||
|
|
"common.download": "Télécharger",
|
||
|
|
"common.load": "Charger",
|
||
|
|
"common.save": "Enregistrer",
|
||
|
|
"common.transactions": "Transactions",
|
||
|
|
"common.noActivity": "Aucune activité.",
|
||
|
|
"common.connecting": "Connexion à la session {id}...",
|
||
|
|
"common.sessionLive": "Session {code} · en direct",
|
||
|
|
"common.continue": "Continuer",
|
||
|
|
"tabs.dashboard": "Tableau",
|
||
|
|
"tabs.tools": "Outils",
|
||
|
|
"tabs.home": "Accueil",
|
||
|
|
"tabs.transfers": "Transferts",
|
||
|
|
"tabs.chat": "Chat",
|
||
|
|
"entry.tagline": "Ouvrez un lobby ou rejoignez la ville.",
|
||
|
|
"entry.liveSessions": "Sessions en direct",
|
||
|
|
"entry.bankerControlled": "Contrôlé par le banquier",
|
||
|
|
"entry.createTitle": "Créer une session",
|
||
|
|
"entry.createSubtitle": "Devenez banquier et contrôlez le flux d'argent.",
|
||
|
|
"entry.bankerName": "Nom du banquier",
|
||
|
|
"entry.openVault": "Ouvrir le coffre",
|
||
|
|
"entry.joinTitle": "Rejoindre une session",
|
||
|
|
"entry.joinSubtitle": "Entrez un code pour continuer.",
|
||
|
|
"entry.sessionCode": "Code de session",
|
||
|
|
"entry.codePlaceholder": "Entrez le code",
|
||
|
|
"entry.newPlayerLabel": "Créer un nouveau joueur",
|
||
|
|
"entry.playerName": "Nom du joueur",
|
||
|
|
"entry.joinAsNew": "Rejoindre comme nouveau joueur",
|
||
|
|
"entry.takeoverTitle": "Reprendre un dummy",
|
||
|
|
"entry.alreadyConnected": "Vous êtes déjà connecté à cette session.",
|
||
|
|
"entry.selectDummy": "Choisir un dummy",
|
||
|
|
"entry.yourNameOptional": "Votre nom (optionnel)",
|
||
|
|
"entry.requestTakeover": "Demander la reprise",
|
||
|
|
"entry.noDummies": "Aucun dummy disponible pour le moment.",
|
||
|
|
"entry.changeCode": "Changer de code",
|
||
|
|
"entry.alert.enterCode": "Entrez un code de session",
|
||
|
|
"entry.alert.sessionNotFound": "Session introuvable",
|
||
|
|
"entry.alert.selectDummy": "Sélectionnez un dummy",
|
||
|
|
"lobby.title": "Lobby Negopoly",
|
||
|
|
"lobby.sessionLabel": "Session {id}",
|
||
|
|
"lobby.joinTitle": "Rejoindre ce lobby",
|
||
|
|
"lobby.loadingInfo": "Chargement des infos de session...",
|
||
|
|
"lobby.waitingState": "En attente de l'état du lobby.",
|
||
|
|
"lobby.header": "Lobby · Session {code}",
|
||
|
|
"lobby.statusLine": "Statut : {status} · {count} joueurs",
|
||
|
|
"lobby.roster": "Liste des joueurs",
|
||
|
|
"lobby.startGame": "Démarrer la partie",
|
||
|
|
"lobby.waitingBanker": "En attente du banquier pour démarrer.",
|
||
|
|
"lobby.sessionClosed": "Session terminée.",
|
||
|
|
"lobby.inviteQr": "QR d'invitation",
|
||
|
|
"lobby.scanToJoin": "Scannez pour rejoindre instantanément.",
|
||
|
|
"lobby.addDummyTitle": "Ajouter un dummy",
|
||
|
|
"lobby.addDummySubtitle":
|
||
|
|
"Créez un joueur pour quelqu'un sans l'application. Les dummies peuvent être repris.",
|
||
|
|
"lobby.enterDummyName": "Entrez un nom de dummy",
|
||
|
|
"lobby.addDummyButton": "Ajouter un dummy",
|
||
|
|
"lobby.errorLoadInfo": "Impossible de charger les infos de session",
|
||
|
|
"banker.consoleTitle": "Console banquier",
|
||
|
|
"banker.controlsTitle": "Contrôles banquier",
|
||
|
|
"banker.tools.playersTab": "Joueurs",
|
||
|
|
"banker.tools.adminTab": "Admin",
|
||
|
|
"banker.playersTitle": "Joueurs",
|
||
|
|
"banker.playerOverview": "Vue joueur",
|
||
|
|
"banker.noPlayers": "Pas encore de joueurs.",
|
||
|
|
"banker.adminControls": "Contrôles de session",
|
||
|
|
"banker.adjustBalance": "Ajuster le solde",
|
||
|
|
"banker.adjustAmountPlaceholder": "Montant +/-",
|
||
|
|
"banker.forceTransfer": "Forcer un transfert",
|
||
|
|
"banker.createDummy": "Créer un dummy",
|
||
|
|
"banker.dummyName": "Nom du dummy",
|
||
|
|
"banker.addDummy": "Ajouter un dummy",
|
||
|
|
"banker.blackout": "EMP",
|
||
|
|
"banker.blackoutToggle": "Basculer l'EMP",
|
||
|
|
"banker.blackoutEnable": "Activer l'EMP",
|
||
|
|
"banker.blackoutDisable": "Désactiver l'EMP",
|
||
|
|
"banker.blackoutReason": "Raison de l'EMP",
|
||
|
|
"banker.endSession": "Terminer la session",
|
||
|
|
"banker.takeoverApprovals": "Approbations de reprise",
|
||
|
|
"banker.wants": "Veut {name}",
|
||
|
|
"banker.approve": "Approuver",
|
||
|
|
"banker.stateTitle": "État de partie",
|
||
|
|
"banker.stateSubtitle": "Exportez, importez ou reprenez une partie depuis une sauvegarde.",
|
||
|
|
"banker.downloadState": "Télécharger l'état actuel",
|
||
|
|
"banker.loadFromFile": "Charger un état depuis un fichier",
|
||
|
|
"banker.loadFromStorage": "Charger depuis le navigateur",
|
||
|
|
"banker.stateDownloaded": "État téléchargé.",
|
||
|
|
"banker.stateDownloadError": "Impossible de télécharger l'état.",
|
||
|
|
"banker.stateLoaded": "État chargé.",
|
||
|
|
"banker.stateLoadError": "Impossible de charger l'état.",
|
||
|
|
"banker.stateLoadInvalid": "Fichier d'état invalide.",
|
||
|
|
"banker.autosaveTitle": "AutoSave",
|
||
|
|
"banker.autosaveSubtitle": "Conservez des sauvegardes dans ce navigateur.",
|
||
|
|
"banker.autosaveToggle": "Activer AutoSave",
|
||
|
|
"banker.autosaveEnabled": "AutoSave activé",
|
||
|
|
"banker.autosaveInterval": "Minutes entre sauvegardes",
|
||
|
|
"banker.autosaveMinutes": "ex. 3",
|
||
|
|
"banker.autosaveKeep": "Sauvegardes à conserver",
|
||
|
|
"banker.autosaveCount": "ex. 5",
|
||
|
|
"banker.autosaveNow": "Sauvegarder maintenant",
|
||
|
|
"banker.autosaveSaved": "Sauvegarde effectuée.",
|
||
|
|
"banker.autosaveFailed": "Échec de la sauvegarde.",
|
||
|
|
"banker.noAutosaves": "Aucune sauvegarde.",
|
||
|
|
"banker.savedAt": "Sauvé {time}",
|
||
|
|
"player.deskTitle": "Bureau joueur",
|
||
|
|
"player.quickTransfer": "Transfert rapide",
|
||
|
|
"player.sendTo": "Envoyer à",
|
||
|
|
"player.noteOptional": "Note (optionnel)",
|
||
|
|
"player.notePlaceholder": "Pour quoi ?",
|
||
|
|
"player.sendFunds": "Envoyer les fonds",
|
||
|
|
"transfers.error": "Choisissez un joueur et un montant valide.",
|
||
|
|
"player.lastUpdated": "Mis à jour {time}",
|
||
|
|
"home.balance": "Solde",
|
||
|
|
"blackout.title": "EMP",
|
||
|
|
"blackout.defaultReason": "EMP en cours",
|
||
|
|
"blackout.active": "EMP actif",
|
||
|
|
"chat.title": "Chats",
|
||
|
|
"chat.global": "Chat global",
|
||
|
|
"chat.conversationCount": "{count} conversations",
|
||
|
|
"chat.conversationCountOne": "1 conversation",
|
||
|
|
"chat.searchPlaceholder": "Rechercher un chat",
|
||
|
|
"chat.newTitle": "Nouveau chat",
|
||
|
|
"chat.newSubtitle": "Démarrer une conversation directe ou de groupe",
|
||
|
|
"chat.direct": "Direct",
|
||
|
|
"chat.group": "Groupe",
|
||
|
|
"chat.groupName": "Nom du groupe",
|
||
|
|
"chat.groupPlaceholder": "ex. Négociateurs",
|
||
|
|
"chat.choosePlayers": "Choisir des joueurs",
|
||
|
|
"chat.noPlayers": "Aucun autre joueur disponible.",
|
||
|
|
"chat.back": "Retour",
|
||
|
|
"chat.backChats": "Chats",
|
||
|
|
"chat.noMessages": "Aucun message.",
|
||
|
|
"chat.startConversation": "Démarrez la conversation.",
|
||
|
|
"chat.messagePlaceholder": "Message",
|
||
|
|
"chat.startChat": "Démarrer le chat",
|
||
|
|
"chat.everyone": "Tout le monde dans la session",
|
||
|
|
"chat.directMessage": "Message direct",
|
||
|
|
"chat.memberCount": "{count} membres",
|
||
|
|
"chat.memberCountOne": "1 membre",
|
||
|
|
"chat.error.direct": "Choisissez une personne pour un chat direct.",
|
||
|
|
"chat.error.groupName": "Donnez un nom au groupe.",
|
||
|
|
"chat.error.member": "Sélectionnez au moins un membre.",
|
||
|
|
"transaction.transfer": "Transfert",
|
||
|
|
"transaction.banker_adjust": "Ajustement banquier",
|
||
|
|
"transaction.banker_force_transfer": "Transfert forcé",
|
||
|
|
"status.lobby": "Lobby",
|
||
|
|
"status.active": "Active",
|
||
|
|
"status.ended": "Terminée",
|
||
|
|
"connection.idle": "inactif",
|
||
|
|
"connection.connecting": "connexion",
|
||
|
|
"connection.open": "connecté",
|
||
|
|
"connection.error": "erreur",
|
||
|
|
"error.parseResponse": "Impossible de lire la réponse du serveur",
|
||
|
|
"error.createSession": "Impossible de créer la session",
|
||
|
|
"error.joinSession": "Impossible de rejoindre la session",
|
||
|
|
"error.connectionNotReady": "Connexion non prête",
|
||
|
|
},
|
||
|
|
} as const;
|
||
|
|
|
||
|
|
type I18nKey = keyof typeof translations.en;
|
||
|
|
|
||
|
|
export function getLocale(): Locale {
|
||
|
|
if (typeof navigator !== "undefined") {
|
||
|
|
const raw = (navigator.languages?.[0] ?? navigator.language ?? "en").toLowerCase();
|
||
|
|
return raw.startsWith("fr") ? "fr" : "en";
|
||
|
|
}
|
||
|
|
return "en";
|
||
|
|
}
|
||
|
|
|
||
|
|
function translate(locale: Locale, key: I18nKey, vars?: Record<string, string | number>) {
|
||
|
|
const table = translations[locale] ?? translations.en;
|
||
|
|
let template = table[key] ?? translations.en[key] ?? key;
|
||
|
|
if (vars) {
|
||
|
|
Object.entries(vars).forEach(([name, value]) => {
|
||
|
|
template = template.replace(new RegExp(`\\{${name}\\}`, "g"), String(value));
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return template;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useI18n() {
|
||
|
|
const locale = useMemo(getLocale, []);
|
||
|
|
const t = useCallback(
|
||
|
|
(key: I18nKey, vars?: Record<string, string | number>) => translate(locale, key, vars),
|
||
|
|
[locale],
|
||
|
|
);
|
||
|
|
return { t, locale };
|
||
|
|
}
|
||
|
|
|
||
|
|
export function tStatic(key: I18nKey, vars?: Record<string, string | number>) {
|
||
|
|
return translate(getLocale(), key, vars);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function formatTransactionKind(
|
||
|
|
kind: "transfer" | "banker_adjust" | "banker_force_transfer",
|
||
|
|
t: (key: I18nKey) => string,
|
||
|
|
) {
|
||
|
|
return t(`transaction.${kind}` as I18nKey);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function formatStatus(
|
||
|
|
status: "lobby" | "active" | "ended",
|
||
|
|
t: (key: I18nKey) => string,
|
||
|
|
) {
|
||
|
|
return t(`status.${status}` as I18nKey);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function formatConnectionState(
|
||
|
|
state: "idle" | "connecting" | "open" | "error",
|
||
|
|
t: (key: I18nKey) => string,
|
||
|
|
) {
|
||
|
|
return t(`connection.${state}` as I18nKey);
|
||
|
|
}
|