From ff94f4290e7468bfa232b3b2bf5a152e3e37cf78 Mon Sep 17 00:00:00 2001 From: user_1781515504933 Date: Fri, 2 Oct 2026 15:50:38 +0700 Subject: [PATCH] feat: add Noir Gear NOIR E1 support --- src/app/OverviewPage.tsx | 63 +++++++++++++++++------- src/app/cards/DpiCard.tsx | 4 +- src/app/cards/availability.test.ts | 28 +++++++++++ src/app/cards/availability.ts | 2 +- src/control.css | 47 ++++++++++++++++++ src/device/controller.ts | 50 ++++++++++--------- src/device/m2nex-profiles.test.ts | 21 ++++++++ src/device/m2nex-profiles.ts | 18 ++++--- src/device/noir.test.ts | 27 +++++++--- src/device/noir.ts | 17 +++++-- src/supported-devices-crosscheck.test.ts | 11 +++++ src/supported-devices-crosscheck.ts | 11 +++-- src/supported-devices-data.ts | 1 + src/ui/device-images.test.ts | 1 + src/ui/device-images.ts | 1 + 15 files changed, 234 insertions(+), 68 deletions(-) diff --git a/src/app/OverviewPage.tsx b/src/app/OverviewPage.tsx index 284a5e82..af9a47ee 100644 --- a/src/app/OverviewPage.tsx +++ b/src/app/OverviewPage.tsx @@ -15,7 +15,7 @@ import { } from "lucide-react"; import { useEffect, useRef, useState, type KeyboardEvent, type ReactNode } from "react"; import * as control from "../device/controller"; -import { isNoirKsnakeStatus, isNoirS1Status, noirBrandLabel } from "../device/noir.ts"; +import { isNoirE1Status, isNoirKsnakeStatus, isNoirS1Status, noirBrandLabel } from "../device/noir.ts"; import type { ControlSnapshot, WorkspaceTab } from "../device/types"; import { t, tp, connectionText, type I18nKey } from "../i18n"; import { Diagnostics, LogitechDetails } from "./Diagnostics"; @@ -104,6 +104,14 @@ const NOIR_S1_BUTTON_MARKER_POSITIONS: Readonly> = { + left: { x: 0.28, y: 0.2 }, + right: { x: 0.72, y: 0.2 }, + middle: { x: 0.5, y: 0.18 }, + forward: { x: 0.08, y: 0.32 }, + backward: { x: 0.08, y: 0.5 }, +}; + function m2NexButtonMarkerPosition(button: string): ButtonMarkerPosition | null { return M2_NEX_BUTTON_MARKER_POSITIONS[button.trim().toLowerCase()] ?? null; } @@ -112,6 +120,10 @@ function noirS1ButtonMarkerPosition(button: string): ButtonMarkerPosition | null return NOIR_S1_BUTTON_MARKER_POSITIONS[button.trim().toLowerCase()] ?? null; } +function noirE1ButtonMarkerPosition(button: string): ButtonMarkerPosition | null { + return NOIR_E1_BUTTON_MARKER_POSITIONS[button.trim().toLowerCase()] ?? null; +} + // Device artwork requests go straight to the documented GitHub issue form // (public/devices/README.md, .github/ISSUE_TEMPLATE/device-artwork.yml). const ARTWORK_ISSUE_URL = "https://github.com/OpenMouse-Project/openmouse/issues/new?template=device-artwork.yml"; @@ -247,12 +259,12 @@ function M2NexProfileOverview({ snapshot }: { snapshot: ControlSnapshot }): Reac >
{t(locale, "m2nex.overline")} - {t(locale, "m2nex.label")} + {status.name}