From cc26593881659dae1e988c85b18af10e24d4025e Mon Sep 17 00:00:00 2001 From: Breakdown <169538186+RINZE1@users.noreply.github.com> Date: Mon, 5 Oct 2026 22:27:14 +0800 Subject: [PATCH 1/2] feat: expose LunaFury controls and game profiles --- src/app/OverviewPage.tsx | 3 + src/app/cards/AdvancedCards.tsx | 44 ++++++----- src/app/cards/LunaFuryCards.tsx | 94 ++++++++++++++++++++++++ src/app/cards/availability.test.ts | 54 ++++++++++++++ src/app/cards/availability.ts | 10 +++ src/app/useBridgeProfileApplier.ts | 5 +- src/app/workspace-tabs.test.ts | 8 ++ src/app/workspace-tabs.ts | 2 +- src/device/controller.ts | 76 ++++++++++++++----- src/device/game-profile-snapshot.test.ts | 65 +++++++++++++++- src/device/game-profile-snapshot.ts | 61 ++++++++++++++- src/device/lunafury-labels.test.ts | 58 +++++++++++++++ src/device/lunafury-labels.ts | 42 +++++++++++ src/device/lunafury-profile.test.ts | 83 +++++++++++++++++++++ src/device/lunafury-profile.ts | 76 +++++++++++++++++++ src/device/traits.ts | 1 + src/i18n-ar.ts | 15 ++++ src/i18n-de.ts | 15 ++++ src/i18n-es.ts | 15 ++++ src/i18n-fr.ts | 15 ++++ src/i18n-ja.ts | 15 ++++ src/i18n-ko.ts | 15 ++++ src/i18n-pt.ts | 15 ++++ src/i18n-ru.ts | 15 ++++ src/i18n-vi.ts | 15 ++++ src/i18n-zh.ts | 15 ++++ src/i18n.ts | 15 ++++ src/supported-devices-data.ts | 2 + 28 files changed, 808 insertions(+), 41 deletions(-) create mode 100644 src/app/cards/LunaFuryCards.tsx create mode 100644 src/device/lunafury-labels.test.ts create mode 100644 src/device/lunafury-labels.ts create mode 100644 src/device/lunafury-profile.test.ts create mode 100644 src/device/lunafury-profile.ts diff --git a/src/app/OverviewPage.tsx b/src/app/OverviewPage.tsx index af9a47ee..ad27ac5c 100644 --- a/src/app/OverviewPage.tsx +++ b/src/app/OverviewPage.tsx @@ -25,6 +25,7 @@ import { Superstrike } from "./Superstrike"; import { DpiCard } from "./cards/DpiCard"; import { LightforceCard, PollingCard, SensorCard } from "./cards/PerformanceCards"; import { LightingCard } from "./cards/LightingCard"; +import { LunaFuryButtonsCard, LunaFuryWheelCard } from "./cards/LunaFuryCards"; import { MxMasterButtonsCard, MxMasterCards } from "./cards/MxMasterCards"; import { AtkButtonCard, AtkDongleCard, AtkProfileCard, AtkReceiverCard, AtkSensorCard } from "./cards/AtkCards"; import { @@ -580,6 +581,8 @@ export function Workspace({ show(has.lowPower, ["advanced"]) ? : null, show(has.finalmouse, ["advanced"]) ? : null, show(has.incott, ["advanced"]) ? : null, + show(has.lunafuryButtons, ["buttons"]) ? : null, + show(has.lunafuryWheelGuard, ["buttons"]) ? : null, device && show(has.dongleLed, ["advanced"]) ? : null, show(has.atkProfile, ["profiles"]) ? : null, device && show(has.atkReceiver, ["advanced"]) ? : null, diff --git a/src/app/cards/AdvancedCards.tsx b/src/app/cards/AdvancedCards.tsx index 96180fa7..1a8a6e41 100644 --- a/src/app/cards/AdvancedCards.tsx +++ b/src/app/cards/AdvancedCards.tsx @@ -22,6 +22,7 @@ import { teevolutionSensorModeUi } from "@openmouse/protocol/teevolution"; import type { KsnakeMacroProfile, KsnakeMacroStep } from "@openmouse/protocol/ksnake"; import { isPulsarProProtocol } from "../../device/traits"; import { isNoirKsnakeStatus } from "../../device/noir.ts"; +import { lunafurySettingLabel, lunafuryTrackingVisible } from "../../device/lunafury-labels.ts"; import * as control from "../../device/controller"; import { PULSAR_SLEEP_OPTIONS } from "../../device/controller"; import { selectableValues, sleepLabel, sleepParts, sleepTotalSeconds, valuesWithCurrent, KEYCHRON_SLEEP_MAX_HOURS, KEYCHRON_SLEEP_MAX_SECONDS, KEYCHRON_SLEEP_MIN_SECONDS } from "../../device/options"; @@ -374,16 +375,29 @@ export function ProcessingCard({ snapshot }: { snapshot: ControlSnapshot }): Rea }) : null; - const angleSnappingLabel = status.ui?.family === "atk" ? t(locale, "adv.straightLine") : t(locale, "adv.angleSnapping"); + const angleSnappingLabel = lunafurySettingLabel(status, locale, "angleSnapping") + ?? (status.ui?.family === "atk" ? t(locale, "adv.straightLine") : t(locale, "adv.angleSnapping")); // WLMouse calls the same sensor setting High-speed mode in its own tool. - const hyperLabel = status.brand === "WLMouse" ? t(locale, "adv.highSpeed") : t(locale, "adv.hyperMode"); + const hyperLabel = lunafurySettingLabel(status, locale, "hyperMode") + ?? (status.brand === "WLMouse" ? t(locale, "adv.highSpeed") : t(locale, "adv.hyperMode")); // Pulsar Pro shows the angle with the rest of its Pro-only settings. const angleTuning = isPulsarProProtocol(status) ? null : status.angleTuning; + const angleLabel = t(locale, status.brand === "LunaFury" ? "luna.sensorAngle" : "adv.angleTune"); - const performanceLabel = status.brand === "CRDRAKO" + const performanceLabel = lunafurySettingLabel(status, locale, "performanceMode") ?? (status.brand === "CRDRAKO" ? t(locale, "adv.competitive") - : status.brand === "Teevolution" ? t(locale, "adv.highestPerf") : t(locale, "adv.perfMode"); + : status.brand === "Teevolution" ? t(locale, "adv.highestPerf") : t(locale, "adv.perfMode")); + + const hyperModeControl = ( +