From 815f1de67b71d83f8c15721d6d9b3074f5fdf450 Mon Sep 17 00:00:00 2001 From: Evan Date: Fri, 6 Mar 2026 18:32:01 -0800 Subject: [PATCH] Update control panel UI (#3357) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Relates to #2260 ## Description: Inspired by https://github.com/openfrontio/OpenFrontIO/pull/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 Screenshot 2026-03-06 at 2 06 34 PM Screenshot 2026-03-06 at 2 06 55 PM Screenshot 2026-03-06 at 4 11 20 PM Screenshot 2026-03-06 at 4 11 32 PM ## 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> --- index.html | 29 +- src/client/graphics/layers/AttacksDisplay.ts | 12 +- src/client/graphics/layers/ControlPanel.ts | 334 +++++++++---------- src/client/graphics/layers/EventsDisplay.ts | 10 +- src/client/graphics/layers/UnitDisplay.ts | 168 +++++----- 5 files changed, 274 insertions(+), 279 deletions(-) diff --git a/index.html b/index.html index 90f2e229b..c5d47ffa5 100644 --- a/index.html +++ b/index.html @@ -264,23 +264,37 @@
+
+
- - + +
+ + +
+ +
@@ -290,7 +304,6 @@ -
diff --git a/src/client/graphics/layers/AttacksDisplay.ts b/src/client/graphics/layers/AttacksDisplay.ts index f77411e55..88e0f4c15 100644 --- a/src/client/graphics/layers/AttacksDisplay.ts +++ b/src/client/graphics/layers/AttacksDisplay.ts @@ -221,7 +221,7 @@ export class AttacksDisplay extends LitElement implements Layer { return this.incomingAttacks.map( (attack) => html`
${this.renderButton({ content: html` html`
${this.renderButton({ content: html` html`
${this.renderButton({ content: html` html`
${this.renderButton({ content: html`${this.renderBoatIcon(boat)} @@ -403,7 +403,7 @@ export class AttacksDisplay extends LitElement implements Layer { return this.incomingBoats.map( (boat) => html`
${this.renderButton({ content: html`${this.renderBoatIcon(boat)} @@ -441,7 +441,7 @@ export class AttacksDisplay extends LitElement implements Layer { return html`
${this.renderOutgoingAttacks()} ${this.renderOutgoingLandAttacks()} ${this.renderBoats()} ${this.renderIncomingAttacks()} diff --git a/src/client/graphics/layers/ControlPanel.ts b/src/client/graphics/layers/ControlPanel.ts index 8aeb8d415..5210a1995 100644 --- a/src/client/graphics/layers/ControlPanel.ts +++ b/src/client/graphics/layers/ControlPanel.ts @@ -40,9 +40,6 @@ export class ControlPanel extends LitElement implements Layer { @state() private _attackingTroops: number = 0; - @state() - private _touchDragging = false; - private _troopRateIsIncreasing: boolean = true; private _lastTroopIncreaseRate: number; @@ -127,73 +124,13 @@ export class ControlPanel extends LitElement implements Layer { this.requestUpdate(); } - private _outsideTouchHandler: ((ev: Event) => void) | null = null; - - private handleAttackTouchStart(e: TouchEvent) { - e.preventDefault(); - e.stopPropagation(); - - if (this._touchDragging) { - this.closeAttackBar(); - return; - } - - this._touchDragging = true; - - setTimeout(() => { - this._outsideTouchHandler = () => { - this.closeAttackBar(); - }; - document.addEventListener("touchstart", this._outsideTouchHandler); - }, 0); - } - - private closeAttackBar() { - this._touchDragging = false; - if (this._outsideTouchHandler) { - document.removeEventListener("touchstart", this._outsideTouchHandler); - this._outsideTouchHandler = null; - } - } - - private handleBarTouch(e: TouchEvent) { - e.preventDefault(); - e.stopPropagation(); - - this.setRatioFromTouch(e.touches[0]); - - const onMove = (ev: TouchEvent) => { - ev.preventDefault(); - this.setRatioFromTouch(ev.touches[0]); - }; - - const onEnd = () => { - document.removeEventListener("touchmove", onMove); - document.removeEventListener("touchend", onEnd); - }; - - document.addEventListener("touchmove", onMove, { passive: false }); - document.addEventListener("touchend", onEnd); - } - - private setRatioFromTouch(touch: Touch) { - const barEl = this.querySelector(".attack-drag-bar"); - if (!barEl) return; - - const rect = barEl.getBoundingClientRect(); - const ratio = (rect.bottom - touch.clientY) / (rect.bottom - rect.top); - this.attackRatio = - Math.round(Math.max(1, Math.min(100, ratio * 100))) / 100; - this.onAttackRatioChange(this.attackRatio); - } - private handleRatioSliderInput(e: Event) { const value = Number((e.target as HTMLInputElement).value); this.attackRatio = value / 100; this.onAttackRatioChange(this.attackRatio); } - private renderTroopBar() { + private calculateTroopBar(): { greenPercent: number; orangePercent: number } { const base = Math.max(this._maxTroops, 1); const greenPercentRaw = (this._troops / base) * 100; const orangePercentRaw = (this._attackingTroops / base) * 100; @@ -204,9 +141,14 @@ export class ControlPanel extends LitElement implements Layer { Math.min(100 - greenPercent, orangePercentRaw), ); + return { greenPercent, orangePercent }; + } + + private renderMobileTroopBar() { + const { greenPercent, orangePercent } = this.calculateTroopBar(); return html`
${greenPercent > 0 @@ -223,7 +165,7 @@ export class ControlPanel extends LitElement implements Layer { : ""}