From 2e609fd85891d7f8363750d44de7a7deb328dfb7 Mon Sep 17 00:00:00 2001 From: FloPinguin <25036848+FloPinguin@users.noreply.github.com> Date: Sat, 31 Jan 2026 22:52:58 +0100 Subject: [PATCH] =?UTF-8?q?Move=20betrayal=20button,=20remove=20betrayal?= =?UTF-8?q?=20confirmation=20=F0=9F=94=A7=20(#3076)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description: - Move betrayal button to the boat-sending-button-location (you can't send boats to allies) to prevent missclicks - Remove betrayal confirmation image ## 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: FloPinguin --- resources/images/CheckmarkIconWhite.svg | 3 -- .../graphics/layers/RadialMenuElements.ts | 32 ++------------ .../graphics/RadialMenuElements.test.ts | 1 + tests/radialMenuElements.test.ts | 42 +------------------ 4 files changed, 7 insertions(+), 71 deletions(-) delete mode 100644 resources/images/CheckmarkIconWhite.svg diff --git a/resources/images/CheckmarkIconWhite.svg b/resources/images/CheckmarkIconWhite.svg deleted file mode 100644 index ef1abfe12..000000000 --- a/resources/images/CheckmarkIconWhite.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/client/graphics/layers/RadialMenuElements.ts b/src/client/graphics/layers/RadialMenuElements.ts index 4ee7e5924..aeafdf8a1 100644 --- a/src/client/graphics/layers/RadialMenuElements.ts +++ b/src/client/graphics/layers/RadialMenuElements.ts @@ -17,7 +17,6 @@ import allianceIcon from "/images/AllianceIconWhite.svg?url"; import boatIcon from "/images/BoatIconWhite.svg?url"; import buildIcon from "/images/BuildIconWhite.svg?url"; import chatIcon from "/images/ChatIconWhite.svg?url"; -import checkmarkIcon from "/images/CheckmarkIconWhite.svg?url"; import donateGoldIcon from "/images/DonateGoldIconWhite.svg?url"; import donateTroopIcon from "/images/DonateTroopIconWhite.svg?url"; import emojiIcon from "/images/EmojiIconWhite.svg?url"; @@ -219,15 +218,6 @@ const allyBreakElement: MenuElement = { !!params.playerActions?.interaction?.canBreakAlliance, color: COLORS.breakAlly, icon: traitorIcon, - subMenu: () => [allyBreakCancelElement, allyBreakConfirmElement], -}; - -const allyBreakConfirmElement: MenuElement = { - id: "ally_break_confirm", - name: "confirm", - disabled: () => false, - color: COLORS.breakAlly, - icon: checkmarkIcon, action: (params: MenuElementParams) => { params.playerActionHandler.handleBreakAlliance( params.myPlayer, @@ -237,17 +227,6 @@ const allyBreakConfirmElement: MenuElement = { }, }; -const allyBreakCancelElement: MenuElement = { - id: "ally_break_cancel", - name: "cancel", - disabled: () => false, - color: COLORS.info, - icon: xIcon, - action: (params: MenuElementParams) => { - params.closeMenu(); - }, -}; - // eslint-disable-next-line @typescript-eslint/no-unused-vars const allyDonateGoldElement: MenuElement = { id: "ally_donate_gold", @@ -638,10 +617,7 @@ export const rootMenuElement: MenuElement = { icon: infoIcon, color: COLORS.info, subMenu: (params: MenuElementParams) => { - let ally = allyRequestElement; - if (params.selected?.isAlliedWith(params.myPlayer)) { - ally = allyBreakElement; - } + const isAllied = params.selected?.isAlliedWith(params.myPlayer); const tileOwner = params.game.owner(params.tile); const isOwnTerritory = @@ -651,10 +627,10 @@ export const rootMenuElement: MenuElement = { const menuItems: (MenuElement | null)[] = [ infoMenuElement, ...(isOwnTerritory - ? [deleteUnitElement, ally, buildMenuElement] + ? [deleteUnitElement, allyRequestElement, buildMenuElement] : [ - boatMenuElement, - ally, + isAllied ? allyBreakElement : boatMenuElement, + allyRequestElement, isFriendlyTarget(params) && !isDisconnectedTarget(params) ? donateGoldRadialElement : attackMenuElement, diff --git a/tests/client/graphics/RadialMenuElements.test.ts b/tests/client/graphics/RadialMenuElements.test.ts index 739672637..e1162f4eb 100644 --- a/tests/client/graphics/RadialMenuElements.test.ts +++ b/tests/client/graphics/RadialMenuElements.test.ts @@ -341,6 +341,7 @@ describe("RadialMenuElements", () => { isPlayer: vi.fn(() => true), } as unknown as PlayerView; mockParams.selected = allyPlayer; + mockGame.owner = vi.fn(() => allyPlayer); const subMenu = rootMenuElement.subMenu!(mockParams); const allyMenu = subMenu.find((item) => item.id === "ally_break"); diff --git a/tests/radialMenuElements.test.ts b/tests/radialMenuElements.test.ts index a95e6be05..15a8885fc 100644 --- a/tests/radialMenuElements.test.ts +++ b/tests/radialMenuElements.test.ts @@ -75,12 +75,6 @@ const makeParams = (opts?: Partial): MenuElementParams => { const findAllyBreak = (items: any[]) => items.find((i) => i && i.id === "ally_break"); -const findAllyBreakConfirm = (items: any[]) => - items.find((i) => i && i.id === "ally_break_confirm"); - -const findAllyBreakCancel = (items: any[]) => - items.find((i) => i && i.id === "ally_break_cancel"); - describe("RadialMenuElements ally break", () => { test("shows break option with correct color when allied", () => { const params = makeParams(); @@ -91,29 +85,12 @@ describe("RadialMenuElements ally break", () => { expect(ally.color).toBe(COLORS.breakAlly); }); - test("break option opens confirmation submenu", () => { + test("break action calls handleBreakAlliance and closes menu", () => { const params = makeParams(); const items = rootMenuElement.subMenu!(params); const ally = findAllyBreak(items)!; - expect(ally.subMenu).toBeDefined(); - const subMenuItems = ally.subMenu!(params); - expect(subMenuItems.length).toBe(2); - - const confirmItem = findAllyBreakConfirm(subMenuItems); - const cancelItem = findAllyBreakCancel(subMenuItems); - expect(confirmItem).toBeTruthy(); - expect(cancelItem).toBeTruthy(); - }); - - test("confirm action calls handleBreakAlliance and closes menu", () => { - const params = makeParams(); - const items = rootMenuElement.subMenu!(params); - const ally = findAllyBreak(items)!; - const subMenuItems = ally.subMenu!(params); - const confirmItem = findAllyBreakConfirm(subMenuItems)!; - - confirmItem.action!(params); + ally.action!(params); expect(params.playerActionHandler.handleBreakAlliance).toHaveBeenCalledWith( params.myPlayer, @@ -121,19 +98,4 @@ describe("RadialMenuElements ally break", () => { ); expect(params.closeMenu).toHaveBeenCalled(); }); - - test("cancel action closes menu without breaking alliance", () => { - const params = makeParams(); - const items = rootMenuElement.subMenu!(params); - const ally = findAllyBreak(items)!; - const subMenuItems = ally.subMenu!(params); - const cancelItem = findAllyBreakCancel(subMenuItems)!; - - cancelItem.action!(params); - - expect( - params.playerActionHandler.handleBreakAlliance, - ).not.toHaveBeenCalled(); - expect(params.closeMenu).toHaveBeenCalled(); - }); });