Add localization support for game events, settings, and UI text elements (#1372)

## Description:

This PR adds missing translations for various UI components, including
game events and settings. No visual changes were made, so screenshots
are not required. All user-facing text has been properly localized and
added to the en.json file.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

## Please put your Discord username so you can be contacted if a bug or
regression is found:

pierogi69

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
Tomasz
2025-07-08 21:39:28 +02:00
committed by GitHub
parent 2cbe34ed79
commit 4ed4c7e507
6 changed files with 135 additions and 51 deletions
+40 -21
View File
@@ -412,16 +412,18 @@ export class EventsDisplay extends LitElement implements Layer {
) as PlayerView;
this.addEvent({
description: `${requestor.name()} requests an alliance!`,
description: translateText("events_display.request_alliance", {
name: requestor.name(),
}),
buttons: [
{
text: "Focus",
text: translateText("events_display.focus"),
className: "btn-gray",
action: () => this.eventBus.emit(new GoToPlayerEvent(requestor)),
preventClose: true,
},
{
text: "Accept",
text: translateText("events_display.accept_alliance"),
className: "btn",
action: () =>
this.eventBus.emit(
@@ -429,7 +431,7 @@ export class EventsDisplay extends LitElement implements Layer {
),
},
{
text: "Reject",
text: translateText("events_display.reject_alliance"),
className: "btn-info",
action: () =>
this.eventBus.emit(
@@ -461,9 +463,12 @@ export class EventsDisplay extends LitElement implements Layer {
) as PlayerView;
this.addEvent({
description: `${recipient.name()} ${
update.accepted ? "accepted" : "rejected"
} your alliance request`,
description: translateText("events_display.alliance_request_status", {
name: recipient.name(),
status: update.accepted
? translateText("events_display.alliance_accepted")
: translateText("events_display.alliance_rejected"),
}),
type: update.accepted
? MessageType.ALLIANCE_ACCEPTED
: MessageType.ALLIANCE_REJECTED,
@@ -489,12 +494,18 @@ export class EventsDisplay extends LitElement implements Layer {
this.game.config().traitorDuration() * 0.1,
);
const durationText =
traitorDuration === 1 ? "1 second" : `${traitorDuration} seconds`;
traitorDuration === 1
? translateText("events_display.duration_second")
: translateText("events_display.duration_seconds_plural", {
seconds: traitorDuration,
});
this.addEvent({
description:
`You broke your alliance with ${betrayed.name()}, making you a TRAITOR ` +
`(${malusPercent}% defense debuff for ${durationText})`,
description: translateText("events_display.betrayal_description", {
name: betrayed.name(),
malusPercent: malusPercent,
durationText: durationText,
}),
type: MessageType.ALLIANCE_BROKEN,
highlight: true,
createdAt: this.game.ticks(),
@@ -503,14 +514,16 @@ export class EventsDisplay extends LitElement implements Layer {
} else if (betrayed === myPlayer) {
const buttons = [
{
text: "Focus",
text: translateText("events_display.focus"),
className: "btn-gray",
action: () => this.eventBus.emit(new GoToPlayerEvent(traitor)),
preventClose: true,
},
];
this.addEvent({
description: `${traitor.name()} broke their alliance with you`,
description: translateText("events_display.betrayed_you", {
name: traitor.name(),
}),
type: MessageType.ALLIANCE_BROKEN,
highlight: true,
createdAt: this.game.ticks(),
@@ -535,7 +548,9 @@ export class EventsDisplay extends LitElement implements Layer {
if (!other || !myPlayer.isAlive() || !other.isAlive()) return;
this.addEvent({
description: `Your alliance with ${other.name()} expired`,
description: translateText("events_display.alliance_expired", {
name: other.name(),
}),
type: MessageType.ALLIANCE_EXPIRED,
highlight: true,
createdAt: this.game.ticks(),
@@ -551,7 +566,10 @@ export class EventsDisplay extends LitElement implements Layer {
const target = this.game.playerBySmallID(event.targetID) as PlayerView;
this.addEvent({
description: `${other.name()} requests you attack ${target.name()}`,
description: translateText("events_display.attack_request", {
name: other.name(),
target: target.name(),
}),
type: MessageType.ATTACK_REQUEST,
highlight: true,
createdAt: this.game.ticks(),
@@ -599,7 +617,7 @@ export class EventsDisplay extends LitElement implements Layer {
if (recipient === myPlayer) {
this.addEvent({
description: `${sender.displayName()}:${update.emoji.message}`,
description: `${sender.displayName()}: ${update.emoji.message}`,
unsafeDescription: true,
type: MessageType.CHAT,
highlight: true,
@@ -608,9 +626,10 @@ export class EventsDisplay extends LitElement implements Layer {
});
} else if (sender === myPlayer && recipient !== AllPlayers) {
this.addEvent({
description: `Sent ${(recipient as PlayerView).displayName()}: ${
update.emoji.message
}`,
description: translateText("events_display.sent_emoji", {
name: (recipient as PlayerView).displayName(),
emoji: update.emoji.message,
}),
unsafeDescription: true,
type: MessageType.CHAT,
highlight: true,
@@ -746,7 +765,7 @@ export class EventsDisplay extends LitElement implements Layer {
<div class="inline-flex items-center gap-1">
${this.renderButton({
content: html`${renderTroops(landAttack.troops)}
Wilderness`,
${translateText("help_modal.ui_wilderness")}`,
className: "text-left text-gray-400",
translate: false,
})}
@@ -953,7 +972,7 @@ export class EventsDisplay extends LitElement implements Layer {
>`
: ""}
${this.renderButton({
content: "Hide",
content: translateText("leaderboard.hide"),
onClick: this.toggleHidden,
className:
"text-white cursor-pointer pointer-events-auto",
@@ -11,6 +11,7 @@ import { GameType } from "../../../core/game/Game";
import { GameUpdateType } from "../../../core/game/GameUpdates";
import { GameView } from "../../../core/game/GameView";
import { PauseGameEvent } from "../../Transport";
import { translateText } from "../../Utils";
import { Layer } from "./Layer";
import { ShowReplayPanelEvent } from "./ReplayPanel";
import { ShowSettingsModalEvent } from "./SettingsModal";
@@ -86,7 +87,9 @@ export class GameRightSidebar extends LitElement implements Layer {
private onExitButtonClick() {
const isAlive = this.game.myPlayer()?.isAlive();
if (isAlive) {
const isConfirmed = confirm("Are you sure you want to exit the game?");
const isConfirmed = confirm(
translateText("help_modal.exit_confirmation"),
);
if (!isConfirmed) return;
}
// redirect to the home page
+4 -1
View File
@@ -7,6 +7,7 @@ import { GameView } from "../../../core/game/GameView";
import { UserSettings } from "../../../core/game/UserSettings";
import { AlternateViewEvent, RefreshGraphicsEvent } from "../../InputHandler";
import { PauseGameEvent } from "../../Transport";
import { translateText } from "../../Utils";
import { Layer } from "./Layer";
const button = ({
@@ -74,7 +75,9 @@ export class OptionsMenu extends LitElement implements Layer {
private onExitButtonClick() {
const isAlive = this.game.myPlayer()?.isAlive();
if (isAlive) {
const isConfirmed = confirm("Are you sure you want to exit the game?");
const isConfirmed = confirm(
translateText("help_modal.exit_confirmation"),
);
if (!isConfirmed) return;
}
// redirect to the home page
+4 -1
View File
@@ -74,7 +74,10 @@ export class ReplayPanel extends LitElement implements Layer {
${this.renderSpeedButton(ReplaySpeedMultiplier.slow, "×0.5")}
${this.renderSpeedButton(ReplaySpeedMultiplier.normal, "×1")}
${this.renderSpeedButton(ReplaySpeedMultiplier.fast, "×2")}
${this.renderSpeedButton(ReplaySpeedMultiplier.fastest, "max")}
${this.renderSpeedButton(
ReplaySpeedMultiplier.fastest,
translateText("replay_panel.fastest_game_speed"),
)}
</div>
</div>
`;
+46 -24
View File
@@ -8,10 +8,10 @@ import mouseIcon from "../../../../resources/images/MouseIconWhite.svg";
import ninjaIcon from "../../../../resources/images/NinjaIconWhite.svg";
import settingsIcon from "../../../../resources/images/SettingIconWhite.svg";
import treeIcon from "../../../../resources/images/TreeIconWhite.svg";
import { translateText } from "../../../client/Utils";
import { EventBus } from "../../../core/EventBus";
import { UserSettings } from "../../../core/game/UserSettings";
import { AlternateViewEvent, RefreshGraphicsEvent } from "../../InputHandler";
import { translateText } from "../../Utils";
import { Layer } from "./Layer";
export class ShowSettingsModalEvent {
@@ -143,7 +143,9 @@ export class SettingsModal extends LitElement implements Layer {
height="24"
style="vertical-align: middle;"
/>
<h2 class="text-xl font-semibold text-white">Settings</h2>
<h2 class="text-xl font-semibold text-white">
${translateText("user_setting.tab_basic")}
</h2>
</div>
<button
class="text-slate-400 hover:text-white text-2xl font-bold leading-none"
@@ -160,15 +162,19 @@ export class SettingsModal extends LitElement implements Layer {
>
<img src=${treeIcon} alt="treeIcon" width="20" height="20" />
<div class="flex-1">
<div class="font-medium">Toggle Terrain</div>
<div class="font-medium">
${translateText("user_setting.toggle_terrain")}
</div>
<div class="text-sm text-slate-400">
${this.alternateView
? "Terrain view enabled"
: "Terrain view disabled"}
? translateText("user_setting.terrain_enabled")
: translateText("user_setting.terrain_disabled")}
</div>
</div>
<div class="text-sm text-slate-400">
${this.alternateView ? "On" : "Off"}
${this.alternateView
? translateText("user_setting.on")
: translateText("user_setting.off")}
</div>
</button>
@@ -183,12 +189,14 @@ export class SettingsModal extends LitElement implements Layer {
</div>
<div class="text-sm text-slate-400">
${this.userSettings.emojis()
? "Emojis are visible"
: "Emojis are hidden"}
? translateText("user_setting.emojis_visible")
: translateText("user_setting.emojis_hidden")}
</div>
</div>
<div class="text-sm text-slate-400">
${this.userSettings.emojis() ? "On" : "Off"}
${this.userSettings.emojis()
? translateText("user_setting.on")
: translateText("user_setting.off")}
</div>
</button>
@@ -208,12 +216,14 @@ export class SettingsModal extends LitElement implements Layer {
</div>
<div class="text-sm text-slate-400">
${this.userSettings.darkMode()
? "Dark mode enabled"
: "Light mode enabled"}
? translateText("user_setting.dark_mode_enabled")
: translateText("user_setting.light_mode_enabled")}
</div>
</div>
<div class="text-sm text-slate-400">
${this.userSettings.darkMode() ? "On" : "Off"}
${this.userSettings.darkMode()
? translateText("user_setting.on")
: translateText("user_setting.off")}
</div>
</button>
@@ -233,12 +243,14 @@ export class SettingsModal extends LitElement implements Layer {
</div>
<div class="text-sm text-slate-400">
${this.userSettings.fxLayer()
? "Special effects enabled"
: "Special effects disabled"}
? translateText("user_setting.special_effects_enabled")
: translateText("user_setting.special_effects_disabled")}
</div>
</div>
<div class="text-sm text-slate-400">
${this.userSettings.fxLayer() ? "On" : "Off"}
${this.userSettings.fxLayer()
? translateText("user_setting.on")
: translateText("user_setting.off")}
</div>
</button>
@@ -253,12 +265,14 @@ export class SettingsModal extends LitElement implements Layer {
</div>
<div class="text-sm text-slate-400">
${this.userSettings.anonymousNames()
? "Anonymous names enabled"
: "Real names shown"}
? translateText("user_setting.anonymous_names_enabled")
: translateText("user_setting.real_names_shown")}
</div>
</div>
<div class="text-sm text-slate-400">
${this.userSettings.anonymousNames() ? "On" : "Off"}
${this.userSettings.anonymousNames()
? translateText("user_setting.on")
: translateText("user_setting.off")}
</div>
</button>
@@ -268,15 +282,19 @@ export class SettingsModal extends LitElement implements Layer {
>
<img src=${mouseIcon} alt="mouseIcon" width="20" height="20" />
<div class="flex-1">
<div class="font-medium">Left Click Menu</div>
<div class="font-medium">
${translateText("user_setting.left_click_menu")}
</div>
<div class="text-sm text-slate-400">
${this.userSettings.leftClickOpensMenu()
? "Left click opens menu"
: "Right click opens menu"}
? translateText("user_setting.left_click_opens_menu")
: translateText("user_setting.right_click_opens_menu")}
</div>
</div>
<div class="text-sm text-slate-400">
${this.userSettings.leftClickOpensMenu() ? "On" : "Off"}
${this.userSettings.leftClickOpensMenu()
? translateText("user_setting.on")
: translateText("user_setting.off")}
</div>
</button>
@@ -287,8 +305,12 @@ export class SettingsModal extends LitElement implements Layer {
>
<img src=${exitIcon} alt="exitIcon" width="20" height="20" />
<div class="flex-1">
<div class="font-medium">Exit Game</div>
<div class="text-sm text-slate-400">Return to main menu</div>
<div class="font-medium">
${translateText("user_setting.exit_game_label")}
</div>
<div class="text-sm text-slate-400">
${translateText("user_setting.exit_game_info")}
</div>
</div>
</button>
</div>