Skip to content

UI overhaul: split/classic layouts, control panel, events, attacks…#3359

Open
hkio120 wants to merge 1 commit intoopenfrontio:mainfrom
hkio120:pr-ui-global
Open

UI overhaul: split/classic layouts, control panel, events, attacks…#3359
hkio120 wants to merge 1 commit intoopenfrontio:mainfrom
hkio120:pr-ui-global

Conversation

@hkio120
Copy link
Contributor

@hkio120 hkio120 commented Mar 5, 2026

Summary
This PR introduces a full in-game UI rework focused on layout flexibility, clearer information hierarchy, and improved readability during combat-heavy gameplay.
What’s New (vs main)

  1. Dual in-game layout system
    • Added a switchable in-game layout:
    ◦ Layout: Split
    ◦ Layout: Classic
    • Added persistent layout setting.
    • Updated panel placement logic (control panel, attacks display, side event panels) for each layout.
    Files:
    • index.html
    • src/client/graphics/GameRenderer.ts
  2. Independent control panel style switch
    • Added a second toggle to switch control panel style independently of layout:
    ◦ Panel: Split
    ◦ Panel: Classic
    • Added persistent panel-style setting.
    • Enables mixed combinations (e.g. classic layout + split panel).
    Files:
    • index.html
    • src/client/graphics/layers/ControlPanel.ts
  3. Control panel redesign and info flow
    • Reworked control panel rendering for both styles.
    • Improved spacing/alignment for troops, attack ratio, gold, and economy info.
    • Added/adjusted gold-per-minute visibility where needed by mode.
    Files:
    • src/client/graphics/layers/ControlPanel.ts
  4. Unit display integration
    • Better integration of unit display with panel layout.
    • Size/spacing refinements for unit icons and fit behavior.
    Files:
    • src/client/graphics/layers/UnitDisplay.ts
    • index.html
  5. Events/chat panel restructuring
    • Added mode-based event display routing (trades, right, alliance_requests, etc.).
    • Improved filtering to reduce noisy messages.
    • Separated alliance request flow from general event stream where relevant.
    Files:
    • src/client/graphics/layers/EventsDisplay.ts
    • index.html
  6. Attacks display compaction and positioning
    • Made attacks display more compact/readable.
    • Improved vertical positioning relative to control panel, especially in classic layout.
    Files:
    • src/client/graphics/layers/AttacksDisplay.ts
    • index.html
  7. Mini hover
    • Added mini-hover overlay toggle and behavior refinements.
    Files:
    • src/client/graphics/layers/PlayerInfoOverlay.ts
    • index.html
  8. Localization updates
    • Added missing i18n entries used by new/updated event messages (including conquest gold messages) to avoid raw key rendering.
    Files:
    • resources/lang/en.json
    • resources/lang/fr.json
    Why
    These changes improve:
    • player customization of UI setup,
    • combat readability,
    • event signal-to-noise ratio,
    • consistency across in-game overlays.
    Testing
    Manual in-game verification performed for:
    • all Layout x Panel combinations,
    • control panel / attacks display alignment,
    • events panel routing and filtering,
    • mini-hover toggle and rendering,
    • translation rendering for updated event messages.

I DIDNT TESTED ON MOBILE !

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
  • 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

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

HulKiora

@hkio120 hkio120 requested review from a team as code owners March 5, 2026 21:06
@hkio120 hkio120 changed the title UI overhaul: split/classic layouts, control panel, events, attacks, a… UI overhaul: split/classic layouts, control panel, events, attacks… Mar 5, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 5, 2026

Walkthrough

This PR introduces a layout switching system for the game UI with multiple display modes, new DOM elements for classic/split layouts, comprehensive localization updates, enhanced graphics layers with mode-based filtering, and client-side state persistence via localStorage.

Changes

Cohort / File(s) Summary
Layout and DOM Structure
index.html
Reorganizes in-game layout with new classic/split layout support, introduces left control panel and right events column, adds persistent UI control buttons for layout/style toggles, and injects client-side script for localStorage-based state management and CSS class switching.
Localization
resources/lang/en.json, resources/lang/fr.json
Adds extensive new UI keys for modals, overlays, and controls; updates event display labels and authentication flow; removes obsolete keys; French translation adds two new conquest-related event messages.
Graphics Renderer Core
src/client/graphics/GameRenderer.ts
Refactors initialization to support multiple EventsDisplay instances via query loop, spreads collected displays into layer composition, and assigns UIState to PlayerInfoOverlay.
Attacks Display and Layout
src/client/graphics/layers/AttacksDisplay.ts
Restructures incoming/outgoing attack blocks into responsive two-column grid; reduces icon sizes, simplifies utility classes, updates text sizing (text-xs lg:text-sm), and adjusts container spacing with new gap and margin rules.
Control Panel and Income System
src/client/graphics/layers/ControlPanel.ts
Introduces income-per-minute tracking with rolling 60-second window, adds optimal regen/troop calculations using ternary-search logic, implements touch-drag attack ratio UI, refactors rendering into classic/standard layouts, and persists attack ratio changes via UIState and localStorage.
Events Display with Mode Filtering
src/client/graphics/layers/EventsDisplay.ts
Adds mode system (all/trades/alerts/social/right/alliance_requests) with category-based visibility filtering, extends GameEvent with unitType and messageKey fields, refactors alliance request UI with action buttons and mode-aware styling, and updates event categorization logic.
Player Info Overlay and Hover System
src/client/graphics/layers/PlayerInfoOverlay.ts
Introduces compact hover overlay rendering, adds troop bar coloring based on optimal regen point, implements hover state tracking and coordinate updates, refactors layout to support collapsible details, adds attack/troop preview calculations, and integrates UIState for state-aware rendering.
Unit Display with Hover Tooltip
src/client/graphics/layers/UnitDisplay.ts
Adds shared hover tooltip displaying unit type, hotkey, description, and cost; tracks hovered structure and hotkey; refactors container styling, adjusts icon dimensions (w-[20px] h-[20px]), and introduces visual dividers between unit groups.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

Layouts shift from left to right, ✨
Modes filter events just right,
Income streams flow smooth and true,
Hover tooltips fresh and new,
Storage keeps your choices bright,
UI dance in pixel light! 🎮

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately summarizes the main change: a comprehensive UI overhaul covering split/classic layouts, control panel redesign, and event panel restructuring.
Description check ✅ Passed The PR description is well-organized and directly related to the changeset, detailing all major features, affected files, testing approach, and author contact information.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
resources/lang/en.json (1)

8-25: ⚠️ Potential issue | 🟠 Major

Restore removed common keys still used by UI.

common.paste and common.enabled are still referenced in join-lobby flows, so their removal from the common block causes missing translation output at runtime.

🩹 Suggested key restoration
   "common": {
     "close": "Close",
     "copy": "Copy",
+    "paste": "Paste",
     "back": "Back",
     "available": "Available",
@@
     "target_dead_note": "You can't send resources to an eliminated player.",
     "none": "None",
+    "enabled": "Enabled",
     "copied": "Copied!",
     "click_to_copy": "Click to copy"
   },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@resources/lang/en.json` around lines 8 - 25, Restore the missing translation
keys under the common block by re-adding "paste" and "enabled" (i.e.,
common.paste and common.enabled) with appropriate English strings (for example
"Paste" and "Enabled") so join-lobby flows can resolve translations; update the
resources/lang/en.json common object to include these keys alongside existing
entries and ensure JSON syntax remains valid (commas, quoting) after insertion.
🧹 Nitpick comments (4)
src/client/graphics/layers/UnitDisplay.ts (1)

281-287: Remove dead template output and duplicate class token.

Line 281 renders an empty template (hovered ? html\` : null) with no visible effect, and rounded-sm` is duplicated in the class string on Lines 285 and 287.

♻️ Proposed cleanup
-        ${hovered ? html`` : null}
         <div
           class="${this.canBuild(unitType)
             ? ""
-            : "opacity-40"} border border-slate-500 rounded-sm pr-1 pb-0.5 flex items-center gap-1 cursor-pointer
+            : "opacity-40"} border border-slate-500 pr-1 pb-0.5 flex items-center gap-1 cursor-pointer
              ${selected ? "hover:bg-gray-400/10" : "hover:bg-gray-800"}
              rounded-sm text-white text-xs ${selected ? "bg-slate-400/20" : ""}"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/client/graphics/layers/UnitDisplay.ts` around lines 281 - 287, In
UnitDisplay.ts (in the render template where hovered, selected, and
canBuild(unitType) are used) remove the dead template expression "hovered ?
html`` : null" and deduplicate the "rounded-sm" class token in the big class
string (used alongside the conditional from canBuild(unitType) and selected) so
the markup no longer outputs an empty template and the class attribute contains
"rounded-sm" only once; keep the rest of the conditional class logic
(opacity-40, hover:bg-*, bg-slate-400/20, text-white, text-xs, border classes)
intact.
src/client/graphics/layers/PlayerInfoOverlay.ts (1)

113-123: Gate reactive cursor updates to when compact hover is actually used.

Lines 114-115 update reactive state on every mouse move before the throttle branch, which can cause unnecessary re-renders on a very hot path.

⚡ Suggested gating
   private onMouseEvent(event: MouseMoveEvent) {
-    this.hoverScreenX = event.x;
-    this.hoverScreenY = event.y;
+    const shouldTrackPointer =
+      this._isInfoVisible &&
+      this.player !== null &&
+      this.unit === null &&
+      this.isDesktopViewport() &&
+      this.isMiniHoverOverlayEnabled();
+    if (shouldTrackPointer) {
+      this.hoverScreenX = event.x;
+      this.hoverScreenY = event.y;
+    }

     const now = Date.now();
     if (now - this.lastMouseUpdate < 100) {
       return;
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/client/graphics/layers/PlayerInfoOverlay.ts` around lines 113 - 123, The
code updates hoverScreenX/hoverScreenY every mouse move before throttling;
change onMouseEvent so it first checks whether compact hover mode is active
(e.g. a flag/method like this.isCompactHoverEnabled or this.compactHoverEnabled)
and only then performs the reactive assignments and throttling logic; keep the
Date.now() throttle using lastMouseUpdate and call this.maybeShow(x,y) as
before, but move hoverScreenX/hoverScreenY assignments to occur inside the
compact-hover branch after the throttle check so non-compact cursor movement
does not trigger reactive updates.
src/client/graphics/layers/ControlPanel.ts (2)

624-644: Extract touch drag overlay into a helper method.

This block (lines 624-644) is nearly identical to lines 732-752 in render(). Extracting it to a private method like renderTouchDragOverlay() would reduce duplication and simplify both render paths.

♻️ Proposed extraction
+  private renderTouchDragOverlay() {
+    if (!this._touchDragging) return "";
+    return html`
+      <div
+        class="absolute bottom-full right-0 flex flex-col items-center pointer-events-auto z-[10000] bg-gray-800/70 backdrop-blur-xs rounded-tl-lg sm:rounded-lg p-2 w-12"
+        style="height: 50vh;"
+        `@touchstart`=${(e: TouchEvent) => this.handleBarTouch(e)}
+      >
+        <span class="text-red-400 text-sm font-bold mb-1" translate="no"
+          >${(this.attackRatio * 100).toFixed(0)}%</span
+        >
+        <div
+          class="attack-drag-bar flex-1 w-3 bg-white/20 rounded-full relative overflow-hidden"
+        >
+          <div
+            class="absolute bottom-0 w-full bg-red-500 rounded-full"
+            style="height: ${this.attackRatio * 100}%"
+          ></div>
+        </div>
+      </div>
+    `;
+  }

Then replace both occurrences with ${this.renderTouchDragOverlay()}.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/client/graphics/layers/ControlPanel.ts` around lines 624 - 644, The
touch-drag overlay HTML is duplicated in render(); extract it into a private
helper like renderTouchDragOverlay() that returns the same template and uses the
same bindings (_touchDragging, attackRatio, handleBarTouch), then replace both
duplicated inline blocks in render() with ${this.renderTouchDragOverlay()} so
both paths reuse the single method and remove the duplicated markup.

52-52: Unused state property regenPct.

This property is declared but never read or written anywhere in the file. Remove it or wire it up if it was intended for something.

🧹 Proposed fix
-  `@state`() private regenPct: number = 0;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/client/graphics/layers/ControlPanel.ts` at line 52, The property
decorated as `@state`() private regenPct: number = 0 in the ControlPanel class is
unused; remove this unused state field or implement its intended usage. Locate
the ControlPanel class in ControlPanel.ts, delete the regenPct declaration if
not needed, or if it should reflect some UI state, connect it to the
corresponding update logic (e.g., update it inside methods that compute regen
percentage or bind it to the template/render function) and ensure any references
use this.regenPct consistently; also remove any unused imports triggered by this
change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@index.html`:
- Around line 384-401: The three control buttons (ids layout-switch-button,
mini-hover-toggle-button, control-panel-style-button) currently hardcode English
labels in HTML and are later updated in JS (around the code that updates them at
~417-453); change both the static HTML text and all JS updates to use the app's
established i18n mechanism (the same translation function/utility used
elsewhere) and reference new translation keys (e.g., controls.layout.split,
controls.miniHover.on, controls.panel.split) instead of literal strings so the
labels render localized text for all locales; ensure keys are added to locale
files and the JS that toggles/changes labels calls the translation function
rather than setting raw English text.

In `@resources/lang/en.json`:
- Around line 869-871: The locale entries "slider_tooltip", "aria_slider", and
"capacity_note" use double-brace placeholders (e.g., "{{percent}}") which is
inconsistent with the project's single-brace convention; update those keys to
use single braces (e.g., "{percent}") and also change the other occurrence
referenced at line 877 to single-brace placeholders so all locale interpolations
use the same "{...}" format.

In `@resources/lang/fr.json`:
- Around line 721-722: Revert the direct edits to resources/lang/fr.json for the
keys "received_gold_from_conquest" and "conquered_no_gold" (remove those two
added/changed entries) and instead add these translation updates via the
dedicated translation workflow: create or include them in a translation PR
titled "mls" authored by Aotumori (or submit the source strings in en.json if
missing) so that only the dedicated translation PR updates non-English locale
files.

In `@src/client/graphics/layers/EventsDisplay.ts`:
- Around line 955-957: The static mode headers "Alliance Requests" and "Trade
Information" in the EventsDisplay component are hardcoded; replace them with the
component's i18n translation calls (use the same translate function used
elsewhere in this file, e.g., t(...) or i18n.t(...)) and reference new keys like
events.allianceRequests and events.tradeInformation so the headers are localized
consistently with the rest of the component (update both occurrences that render
those header divs).

---

Outside diff comments:
In `@resources/lang/en.json`:
- Around line 8-25: Restore the missing translation keys under the common block
by re-adding "paste" and "enabled" (i.e., common.paste and common.enabled) with
appropriate English strings (for example "Paste" and "Enabled") so join-lobby
flows can resolve translations; update the resources/lang/en.json common object
to include these keys alongside existing entries and ensure JSON syntax remains
valid (commas, quoting) after insertion.

---

Nitpick comments:
In `@src/client/graphics/layers/ControlPanel.ts`:
- Around line 624-644: The touch-drag overlay HTML is duplicated in render();
extract it into a private helper like renderTouchDragOverlay() that returns the
same template and uses the same bindings (_touchDragging, attackRatio,
handleBarTouch), then replace both duplicated inline blocks in render() with
${this.renderTouchDragOverlay()} so both paths reuse the single method and
remove the duplicated markup.
- Line 52: The property decorated as `@state`() private regenPct: number = 0 in
the ControlPanel class is unused; remove this unused state field or implement
its intended usage. Locate the ControlPanel class in ControlPanel.ts, delete the
regenPct declaration if not needed, or if it should reflect some UI state,
connect it to the corresponding update logic (e.g., update it inside methods
that compute regen percentage or bind it to the template/render function) and
ensure any references use this.regenPct consistently; also remove any unused
imports triggered by this change.

In `@src/client/graphics/layers/PlayerInfoOverlay.ts`:
- Around line 113-123: The code updates hoverScreenX/hoverScreenY every mouse
move before throttling; change onMouseEvent so it first checks whether compact
hover mode is active (e.g. a flag/method like this.isCompactHoverEnabled or
this.compactHoverEnabled) and only then performs the reactive assignments and
throttling logic; keep the Date.now() throttle using lastMouseUpdate and call
this.maybeShow(x,y) as before, but move hoverScreenX/hoverScreenY assignments to
occur inside the compact-hover branch after the throttle check so non-compact
cursor movement does not trigger reactive updates.

In `@src/client/graphics/layers/UnitDisplay.ts`:
- Around line 281-287: In UnitDisplay.ts (in the render template where hovered,
selected, and canBuild(unitType) are used) remove the dead template expression
"hovered ? html`` : null" and deduplicate the "rounded-sm" class token in the
big class string (used alongside the conditional from canBuild(unitType) and
selected) so the markup no longer outputs an empty template and the class
attribute contains "rounded-sm" only once; keep the rest of the conditional
class logic (opacity-40, hover:bg-*, bg-slate-400/20, text-white, text-xs,
border classes) intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6b53ab94-67d1-4b0d-bda1-55c5fd5c5a64

📥 Commits

Reviewing files that changed from the base of the PR and between b3c01d4 and 3c14267.

📒 Files selected for processing (9)
  • index.html
  • resources/lang/en.json
  • resources/lang/fr.json
  • src/client/graphics/GameRenderer.ts
  • src/client/graphics/layers/AttacksDisplay.ts
  • src/client/graphics/layers/ControlPanel.ts
  • src/client/graphics/layers/EventsDisplay.ts
  • src/client/graphics/layers/PlayerInfoOverlay.ts
  • src/client/graphics/layers/UnitDisplay.ts

Comment on lines +384 to +401
<button
id="layout-switch-button"
class="px-3 py-1.5 rounded-md bg-gray-900/80 border border-white/20 text-white text-xs lg:text-sm hover:bg-gray-800/90 transition-colors"
>
Layout: Split
</button>
<button
id="mini-hover-toggle-button"
class="px-3 py-1.5 rounded-md bg-gray-900/80 border border-white/20 text-white text-xs lg:text-sm hover:bg-gray-800/90 transition-colors"
>
Mini Hover: On
</button>
<button
id="control-panel-style-button"
class="px-3 py-1.5 rounded-md bg-gray-900/80 border border-white/20 text-white text-xs lg:text-sm hover:bg-gray-800/90 transition-colors"
>
Panel: Split
</button>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

New layout-control labels are not localized.

Texts set on Lines 384-401 and updated in JS on Lines 417-453 are hardcoded in English. In other locales, these controls will still show English strings. Please route them through translation keys like the rest of the UI.

Also applies to: 417-453

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@index.html` around lines 384 - 401, The three control buttons (ids
layout-switch-button, mini-hover-toggle-button, control-panel-style-button)
currently hardcode English labels in HTML and are later updated in JS (around
the code that updates them at ~417-453); change both the static HTML text and
all JS updates to use the app's established i18n mechanism (the same translation
function/utility used elsewhere) and reference new translation keys (e.g.,
controls.layout.split, controls.miniHover.on, controls.panel.split) instead of
literal strings so the labels render localized text for all locales; ensure keys
are added to locale files and the JS that toggles/changes labels calls the
translation function rather than setting raw English text.

Comment on lines +869 to +871
"slider_tooltip": "{{percent}}% • {{amount}}",
"aria_slider": "Troops slider",
"capacity_note": "Receiver can accept only {amount} right now."
"capacity_note": "Receiver can accept only {{amount}} right now."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use consistent single-brace placeholders in tooltips.

Lines 869-871 and 877 use {{...}}, but existing locale placeholders use {...}. This inconsistency can break interpolation and show raw braces to users.

🩹 Placeholder consistency fix
-    "slider_tooltip": "{{percent}}% • {{amount}}",
+    "slider_tooltip": "{percent}% • {amount}",
@@
-    "capacity_note": "Receiver can accept only {{amount}} right now."
+    "capacity_note": "Receiver can accept only {amount} right now."
@@
-    "slider_tooltip": "{{percent}}% • {{amount}}"
+    "slider_tooltip": "{percent}% • {amount}"

Also applies to: 877-877

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@resources/lang/en.json` around lines 869 - 871, The locale entries
"slider_tooltip", "aria_slider", and "capacity_note" use double-brace
placeholders (e.g., "{{percent}}") which is inconsistent with the project's
single-brace convention; update those keys to use single braces (e.g.,
"{percent}") and also change the other occurrence referenced at line 877 to
single-brace placeholders so all locale interpolations use the same "{...}"
format.

Comment on lines +721 to +722
"received_gold_from_conquest": "{gold} ors reçu en conquérant {name}",
"conquered_no_gold": "{name} a été conquis, mais il n'y avait aucun or à récupérer",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Move fr.json updates to the dedicated translation flow.

Adding keys in resources/lang/fr.json on Lines 721-722 should be done in the dedicated translation PR process, not in a regular feature PR.

Based on learnings: In OpenFrontIO, translation files in resources/lang/*.json (except en.json) should not be updated in regular PRs. Only dedicated translation PRs titled "mls" and made by Aotumori should update non-English locale files.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@resources/lang/fr.json` around lines 721 - 722, Revert the direct edits to
resources/lang/fr.json for the keys "received_gold_from_conquest" and
"conquered_no_gold" (remove those two added/changed entries) and instead add
these translation updates via the dedicated translation workflow: create or
include them in a translation PR titled "mls" authored by Aotumori (or submit
the source strings in en.json if missing) so that only the dedicated translation
PR updates non-English locale files.

Comment on lines +955 to +957
<div class="text-[11px] uppercase tracking-wide text-gray-300 mb-1">
Alliance Requests
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Mode headers are hardcoded instead of translated.

Alliance Requests and Trade Information (Lines 955-957, 1041-1049) should use translation keys to match the rest of this component’s i18n behavior.

Also applies to: 1041-1049

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/client/graphics/layers/EventsDisplay.ts` around lines 955 - 957, The
static mode headers "Alliance Requests" and "Trade Information" in the
EventsDisplay component are hardcoded; replace them with the component's i18n
translation calls (use the same translate function used elsewhere in this file,
e.g., t(...) or i18n.t(...)) and reference new keys like events.allianceRequests
and events.tradeInformation so the headers are localized consistently with the
rest of the component (update both occurrences that render those header divs).

@github-project-automation github-project-automation bot moved this from Triage to Development in OpenFront Release Management Mar 5, 2026
@evanpelle evanpelle mentioned this pull request Mar 6, 2026
4 tasks
evanpelle added a commit that referenced this pull request Mar 7, 2026
Relates to #2260

## Description:

Inspired by #3359

This PR centers the control panel and combines it with the units
display. The reasoning is that the control panel contains the most
critical info so it should be in the center of the screen. Combining it
with the units display reduces the number of UI components on screen.

Also made the attack ratio bar persistent on mobile

<img width="618" height="216" alt="Screenshot 2026-03-06 at 2 06 34 PM"
src="https://github.com/user-attachments/assets/34b041c1-d78b-46b5-a7ab-f2a44145a7e2"
/>


<img width="941" height="343" alt="Screenshot 2026-03-06 at 2 06 55 PM"
src="https://github.com/user-attachments/assets/1e3b026c-8eb2-407c-be38-0e71e1ae426c"
/>

<img width="562" height="228" alt="Screenshot 2026-03-06 at 4 11 20 PM"
src="https://github.com/user-attachments/assets/56eac49f-c8a4-4ac1-a60a-f1bcb2fad2d0"
/>

<img width="939" height="357" alt="Screenshot 2026-03-06 at 4 11 32 PM"
src="https://github.com/user-attachments/assets/eb5591d5-3cc2-4182-944b-3a4b0b76852a"
/>


## 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

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

evan

Co-authored-by: hkio120 <111693579+hkio120@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Development

Development

Successfully merging this pull request may close these issues.

1 participant