feat(i18n): enhance localization for chat and minigames
All checks were successful
Deploy to production / deploy (push) Successful in 1m51s

- Updated localization strings for chat and minigames across multiple languages, including Cebuano, German, English, Spanish, and French, to improve user experience and clarity.
- Added new translations for participant counts, user selection prompts, and game over messages, ensuring consistency and better engagement in the UI.
- Enhanced existing translations for accuracy and context, particularly in the TaxiGame component and chat functionalities.
This commit is contained in:
Torsten Schulz (local)
2026-04-17 16:38:39 +02:00
parent 3232e42251
commit 14881803df
13 changed files with 98 additions and 63 deletions

View File

@@ -42,7 +42,7 @@
<template v-if="msg.type === 'scream'">
<span class="scream-line" :style="msg.color ? { color: msg.color } : null">
<span class="user">{{ msg.user }}</span>
<span class="scream-label"> schreit:</span>
<span class="scream-label">{{ $t('chat.multichat.screamColon') }}</span>
<span class="text"> {{ (msg.text || '').toUpperCase() }}</span>
</span>
</template>
@@ -133,7 +133,7 @@
</div>
<div v-if="roomCreateValidation.range" class="room-create-error room-create-error-block">{{ roomCreateValidation.range }}</div>
<div class="room-create-preview">
{{ $t('chat.multichat.createRoom.commandPrefix') }}: <code>{{ buildRoomCreateCommandPreview() || '/cr <raumname>' }}</code>
{{ $t('chat.multichat.createRoom.commandPrefix') }}: <code>{{ buildRoomCreateCommandPreview() || $t('chat.multichat.commandPreviewFallback') }}</code>
</div>
<div class="owned-rooms-section">
<div class="owned-rooms-title">{{ $t('chat.multichat.createRoom.ownedRooms.title') }}</div>
@@ -157,11 +157,11 @@
</div>
</div>
<div class="user-list">
<div class="user-list-header">Teilnehmer ({{ usersInRoom.length }})</div>
<div class="user-list-header">{{ $t('chat.multichat.participantsWithCount', { count: usersInRoom.length }) }}</div>
<div class="user-list-items">
<div class="user-list-item" v-for="u in usersInRoom" :key="u.name"
:class="{ selected: selectedTargetUser === u.name }" @click="selectTargetUser(u.name)"
title="Klicken zum Auswählen">
:title="$t('chat.multichat.clickToSelectUser')">
<span class="user-dot"
:style="{ backgroundColor: (u.color || userColors[u.name] || '#ccc') }"></span>
<span class="user-name"

View File

@@ -1,8 +1,8 @@
{
"chat": {
"multichat": {
"title": "Multi Chat",
"eroticTitle": "Erotic chat",
"title": "Daghan nga chat",
"eroticTitle": "Erotik nga chat",
"autoscroll": "Auto scroll",
"options": "Mga kapilian",
"send": "Ipadala",
@@ -39,12 +39,16 @@
"disconnected": "Naputol ang koneksyon",
"error": "Sayop sa koneksyon"
},
"reloadRooms": "I-reload ang mga room",
"reloadRooms": "I-reload ang mga lawak",
"participantsWithCount": "Mga partisipante ({count})",
"clickToSelectUser": "I-klik aron pilion",
"screamColon": " misinggit:",
"commandPreviewFallback": "/cr <ngalan sa lawak>",
"createRoom": {
"toggleShowChat": "Ipakita ang chat",
"toggleCreateRoom": "Paghimo og room",
"title": "Paghimo og bag-ong room",
"commandPrefix": "Command",
"toggleCreateRoom": "Paghimo og lawak",
"title": "Paghimo og bag-ong lawak",
"commandPrefix": "Sugo",
"labels": {
"roomName": "Ngalan sa room",
"visibility": "Visibility",
@@ -69,7 +73,7 @@
"genderAny": "Bisan kinsa / walay limitasyon"
},
"actions": {
"create": "Paghimo og room",
"create": "Paghimo og lawak",
"reset": "I-reset"
},
"validation": {

View File

@@ -96,13 +96,13 @@
"pointsTitle": "Puntos",
"speedViolations": "Mga lapas sa speed limit",
"redLightsPassed": "Mga pulang suga nga nalapas",
"highscore": "Highscore",
"highscore": "Labing taas nga puntos",
"topPlayers": "Top 20 nga mga player",
"loadingHighscore": "Nag-load sa highscore...",
"noHighscore": "Wala pay highscore",
"pointsShort": "pts",
"backToGame": "Balik sa dula",
"minimap": "Minimap",
"minimap": "Gamay nga mapa",
"loadedPassengers": "Mga pasahero sulod sa taxi",
"waitingPassengers": "Naghulat nga mga pasahero",
"noPassengersInTaxi": "Walay pasahero sulod sa taxi",
@@ -111,6 +111,9 @@
"destination": "Padulngan",
"bonus": "Bonus",
"time": "Oras",
"unknownMap": "Wala nailhan",
"gameOverTitle": "Nahuman na ang dula!",
"gameOverMessage": "Wala na kay sakyanan. Nahuman na ang dula!\n\nImong mga resulta:\n• Mga pasahero: {passengers}\n• Puntos: {score}\n• Oras sa dula: {playTime}\n• Mapa: {map}\n\nNa-save na ang highscore!",
"crash": {
"title": "Bangga!",
"message": "Naaksidente ka! Mga crash: {crashes}"

View File

@@ -6,14 +6,14 @@
"socialnetwork": "Tigomanan",
"chats": "Mga chat",
"falukant": "Falukant",
"minigames": "Mga minigame",
"personal": "Personal",
"settings": "Mga setting",
"minigames": "Mga minidula",
"personal": "Kaugalingon",
"settings": "Mga opsyon",
"administration": "Pagdumala",
"m-chats": {
"multiChat": "Multiuser chat",
"randomChat": "Random single chat",
"eroticChat": "Erotik chat"
"multiChat": "Daghan nga chat",
"randomChat": "Usa-ka-chat nga random",
"eroticChat": "Erotik nga chat"
},
"m-socialnetwork": {
"guestbook": "Libro sa bisita",
@@ -56,7 +56,7 @@
"m-settings": {
"homepage": "Sinugdanan",
"account": "Account",
"personal": "Personal",
"personal": "Kaugalingon",
"view": "Panagway",
"flirt": "Flirt",
"interests": "Mga interes",
@@ -85,7 +85,7 @@
"mapEditor": "Editor sa mapa",
"createNPC": "Paghimo og NPC"
},
"minigames": "Mga minigame",
"minigames": "Mga minidula",
"m-minigames": {
"match3": "Mga level sa Match3",
"taxiTools": "Mga himan sa taxi"

View File

@@ -41,6 +41,10 @@
"error": "Fehler bei der Verbindung"
},
"reloadRooms": "Räume neu laden",
"participantsWithCount": "Teilnehmer ({count})",
"clickToSelectUser": "Zum Auswählen klicken",
"screamColon": " schreit:",
"commandPreviewFallback": "/cr <raumname>",
"createRoom": {
"toggleShowChat": "Chat anzeigen",
"toggleCreateRoom": "Raum anlegen",

View File

@@ -111,6 +111,9 @@
"destination": "Ziel",
"bonus": "Bonus",
"time": "Zeit",
"unknownMap": "Unbekannt",
"gameOverTitle": "Spiel beendet!",
"gameOverMessage": "Keine Fahrzeuge mehr. Spiel beendet!\n\nDeine Leistung:\n• Passagiere: {passengers}\n• Punkte: {score}\n• Spielzeit: {playTime}\n• Map: {map}\n\nHighscore wurde gespeichert!",
"crash": {
"title": "Unfall!",
"message": "Du hattest einen Unfall! Crashes: {crashes}"

View File

@@ -41,6 +41,10 @@
"error": "Connection error"
},
"reloadRooms": "Reload rooms",
"participantsWithCount": "Participants ({count})",
"clickToSelectUser": "Click to select",
"screamColon": " shouts:",
"commandPreviewFallback": "/cr <roomname>",
"createRoom": {
"toggleShowChat": "Show chat",
"toggleCreateRoom": "Create room",

View File

@@ -111,6 +111,9 @@
"destination": "Destination",
"bonus": "Bonus",
"time": "Time",
"unknownMap": "Unknown",
"gameOverTitle": "Game over!",
"gameOverMessage": "No vehicles left. Game over!\n\nYour results:\n• Passengers: {passengers}\n• Score: {score}\n• Play time: {playTime}\n• Map: {map}\n\nHighscore saved!",
"crash": {
"title": "Crash!",
"message": "You had an accident! Crashes: {crashes}"

View File

@@ -40,6 +40,10 @@
"error": "Error de conexión"
},
"reloadRooms": "Recargar salas",
"participantsWithCount": "Participantes ({count})",
"clickToSelectUser": "Clic para seleccionar",
"screamColon": " grita:",
"commandPreviewFallback": "/cr <nombre de sala>",
"createRoom": {
"toggleShowChat": "Mostrar chat",
"toggleCreateRoom": "Crear sala",

View File

@@ -111,6 +111,9 @@
"destination": "Destino",
"bonus": "Bonificación",
"time": "Tiempo",
"unknownMap": "Desconocido",
"gameOverTitle": "¡Fin del juego!",
"gameOverMessage": "No quedan vehículos. ¡Fin del juego!\n\nTus resultados:\n• Pasajeros: {passengers}\n• Puntos: {score}\n• Tiempo de juego: {playTime}\n• Mapa: {map}\n\n¡Puntuación guardada!",
"crash": {
"title": "¡Accidente!",
"message": "¡Has tenido un accidente! Choques: {crashes}"

View File

@@ -40,6 +40,10 @@
"error": "Fehler bei der Verbindung"
},
"reloadRooms": "Räume neu laden",
"participantsWithCount": "Participants ({count})",
"clickToSelectUser": "Cliquer pour sélectionner",
"screamColon": " crie :",
"commandPreviewFallback": "/cr <nom de la salle>",
"createRoom": {
"toggleShowChat": "Chat anzeigen",
"toggleCreateRoom": "Raum anlegen",

View File

@@ -111,9 +111,12 @@
"destination": "Ziel",
"bonus": "prime",
"time": "Temps",
"unknownMap": "Inconnu",
"gameOverTitle": "Partie terminée !",
"gameOverMessage": "Plus aucun véhicule. Partie terminée !\n\nTes résultats :\n• Passagers : {passengers}\n• Points : {score}\n• Temps de jeu : {playTime}\n• Carte : {map}\n\nMeilleur score enregistré !",
"crash": {
"title": "Accident!",
"message": "Vous avez eu un accident ! Crashes : {crashs}"
"message": "Vous avez eu un accident ! Crashes : {crashes}"
}
}
}

View File

@@ -14,37 +14,37 @@
<div class="game-area">
<!-- Legende (links) -->
<div class="controls-legend">
<h3>Steuerung</h3>
<h3>{{ $t('minigames.taxi.controls') }}</h3>
<div class="legend-grid">
<div class="legend-item">
<span class="legend-key"> W</span>
<span class="legend-text">Gas geben</span>
<span class="legend-text">{{ $t('minigames.taxi.accelerate') }}</span>
</div>
<div class="legend-item">
<span class="legend-key"> X</span>
<span class="legend-text">Bremsen</span>
<span class="legend-text">{{ $t('minigames.taxi.brake') }}</span>
</div>
<div class="legend-item">
<span class="legend-key"> D</span>
<span class="legend-text">Rechts lenken</span>
<span class="legend-text">{{ $t('minigames.taxi.steerRight') }}</span>
</div>
<div class="legend-item">
<span class="legend-key"> A</span>
<span class="legend-text">Links lenken</span>
<span class="legend-text">{{ $t('minigames.taxi.steerLeft') }}</span>
</div>
</div>
<!-- Ziele -->
<div class="game-objectives">
<h4>Ziele</h4>
<h4>{{ $t('minigames.taxi.goals') }}</h4>
<ul>
<li>Vermeide Kollisionen mit anderen Fahrzeugen</li>
<li>{{ $t('minigames.taxi.avoidCollisions') }}</li>
</ul>
</div>
<!-- Straßenname-Legende -->
<div class="game-objectives" v-if="streetLegend.length">
<h4>Straßennamen</h4>
<h4>{{ $t('minigames.taxi.streetNames') }}</h4>
<ul>
<li
v-for="item in streetLegend"
@@ -64,11 +64,11 @@
<!-- Tacho-Display -->
<div class="tacho-display">
<div class="tacho-speed">
<span class="lives" title="Verbleibende Fahrzeuge"> {{ vehicleCount }}</span>
<span class="fuel" title="Treibstoff"> {{ Math.round(fuel) }}%</span>
<span class="score" title="Punkte"> {{ score }}</span>
<span class="speed-violations" title="Geschwindigkeitsverstöße">📷 {{ speedViolations }}</span>
<span class="redlight-counter" title="Rote Ampeln überfahren">
<span class="lives" :title="$t('minigames.taxi.remainingVehicles')"> {{ vehicleCount }}</span>
<span class="fuel" :title="$t('minigames.taxi.fuelTitle')"> {{ Math.round(fuel) }}%</span>
<span class="score" :title="$t('minigames.taxi.pointsTitle')"> {{ score }}</span>
<span class="speed-violations" :title="$t('minigames.taxi.speedViolations')">📷 {{ speedViolations }}</span>
<span class="redlight-counter" :title="$t('minigames.taxi.redLightsPassed')">
<span class="redlight-icon">🚦</span>
<span class="redlight-value">{{ redLightViolations }}</span>
</span>
@@ -108,15 +108,15 @@
<!-- Highscore-Anzeige (als Overlay über dem Canvas) -->
<div v-if="showHighscore" class="highscore-overlay">
<div class="highscore-header">
<h2>🏆 Highscore</h2>
<div class="highscore-subtitle">Top 20 Spieler</div>
<h2>🏆 {{ $t('minigames.taxi.highscore') }}</h2>
<div class="highscore-subtitle">{{ $t('minigames.taxi.topPlayers') }}</div>
</div>
<div class="highscore-list">
<div v-if="loadingHighscore" class="loading-message">
Lade Highscore...
{{ $t('minigames.taxi.loadingHighscore') }}
</div>
<div v-else-if="highscoreList.length === 0" class="no-highscore">
Noch keine Highscores vorhanden
{{ $t('minigames.taxi.noHighscore') }}
</div>
<div v-else class="highscore-table">
<div
@@ -127,7 +127,7 @@
>
<div class="highscore-rank">{{ entry.rank }}</div>
<div class="highscore-name">{{ entry.nickname }}</div>
<div class="highscore-points">{{ entry.points }} Pkt</div>
<div class="highscore-points">{{ entry.points }} {{ $t('minigames.taxi.pointsShort') }}</div>
</div>
<div v-if="showCurrentPlayerBelow" class="highscore-separator">...</div>
<div
@@ -136,7 +136,7 @@
>
<div class="highscore-rank">{{ currentPlayerEntry.rank }}</div>
<div class="highscore-name">{{ currentPlayerEntry.nickname }}</div>
<div class="highscore-points">{{ currentPlayerEntry.points }} Pkt</div>
<div class="highscore-points">{{ currentPlayerEntry.points }} {{ $t('minigames.taxi.pointsShort') }}</div>
</div>
</div>
</div>
@@ -154,7 +154,7 @@
{{ $t('minigames.taxi.restartLevel') }}
</button>
<button @click="toggleHighscore" class="control-button">
{{ showHighscore ? 'Zurück zum Spiel' : 'Highscore' }}
{{ showHighscore ? $t('minigames.taxi.backToGame') : $t('minigames.taxi.highscore') }}
</button>
</div>
</div>
@@ -164,7 +164,7 @@
<!-- Minimap -->
<div class="minimap-card">
<div class="minimap-header">
<h3 class="minimap-title">Minimap</h3>
<h3 class="minimap-title">{{ $t('minigames.taxi.minimap') }}</h3>
<div class="map-selector">
<select v-model="selectedMapId" @change="onMapChange" class="map-select">
<option
@@ -190,19 +190,19 @@
<!-- Geladene Passagiere -->
<div class="loaded-passengers-card">
<div class="loaded-passengers-header">
<h3 class="loaded-passengers-title">Geladene Passagiere</h3>
<h3 class="loaded-passengers-title">{{ $t('minigames.taxi.loadedPassengers') }}</h3>
</div>
<div class="loaded-passengers-content">
<div v-if="loadedPassengersList.length === 0" class="no-passengers">
Keine Passagiere im Taxi
{{ $t('minigames.taxi.noPassengersInTaxi') }}
</div>
<table v-else class="passengers-table">
<thead>
<tr>
<th>Name</th>
<th>Ziel</th>
<th>Bonus</th>
<th>Zeit</th>
<th>{{ $t('minigames.taxi.name') }}</th>
<th>{{ $t('minigames.taxi.destination') }}</th>
<th>{{ $t('minigames.taxi.bonus') }}</th>
<th>{{ $t('minigames.taxi.time') }}</th>
</tr>
</thead>
<tbody>
@@ -227,11 +227,11 @@
<!-- Wartende Passagiere -->
<div class="waiting-passengers-card">
<div class="waiting-passengers-header">
<h3 class="waiting-passengers-title">Wartende Passagiere</h3>
<h3 class="waiting-passengers-title">{{ $t('minigames.taxi.waitingPassengers') }}</h3>
</div>
<div class="waiting-passengers-list">
<div v-if="waitingPassengersList.length === 0" class="no-passengers">
Keine wartenden Passagiere
{{ $t('minigames.taxi.noWaitingPassengers') }}
</div>
<table v-else>
<tr v-for="(passenger, index) in waitingPassengersList"
@@ -3047,9 +3047,8 @@ export default {
// Dialog über globale MessageDialog öffnen
this.$nextTick(() => {
// Temporär direkte Übersetzung verwenden, bis i18n-Problem gelöst ist
const crashMessage = `Du hattest einen Unfall! Crashes: ${this.crashes}`;
const crashTitle = 'Unfall!';
const crashMessage = this.$t('minigames.taxi.crash.message', { crashes: this.crashes });
const crashTitle = this.$t('minigames.taxi.crash.title');
this.$root?.$refs?.messageDialog?.open?.(crashMessage, crashTitle, {}, this.handleCrashDialogClose);
console.log('Crash-Dialog wird angezeigt:', {
@@ -3137,7 +3136,7 @@ export default {
playtime: playTime,
points: this.score,
mapId: this.currentMap ? this.currentMap.id : null,
mapName: this.currentMap ? this.currentMap.name : 'Unbekannt'
mapName: this.currentMap ? this.currentMap.name : this.$t('minigames.taxi.unknownMap')
};
const response = await apiClient.post('/api/taxi/highscores', highscoreData);
@@ -3166,14 +3165,15 @@ export default {
const playTimeMinutes = Math.floor(playTime / 60);
const playTimeSeconds = playTime % 60;
const title = 'Spiel beendet!';
const msg = `Keine Fahrzeuge mehr. Spiel beendet!\n\n` +
`Deine Leistung:\n` +
`• Passagiere: ${this.passengersDelivered}\n` +
`• Punkte: ${this.score}\n` +
`• Spielzeit: ${playTimeMinutes}:${playTimeSeconds.toString().padStart(2, '0')}\n` +
`• Map: ${this.currentMap ? this.currentMap.name : 'Unbekannt'}\n\n` +
`Highscore wurde gespeichert!`;
const mapLabel = this.currentMap ? this.currentMap.name : this.$t('minigames.taxi.unknownMap');
const playTimeStr = `${playTimeMinutes}:${playTimeSeconds.toString().padStart(2, '0')}`;
const title = this.$t('minigames.taxi.gameOverTitle');
const msg = this.$t('minigames.taxi.gameOverMessage', {
passengers: this.passengersDelivered,
score: this.score,
playTime: playTimeStr,
map: mapLabel
});
this.$root?.$refs?.messageDialog?.open?.(msg, title, {}, () => {
this.restartLevel();