diff --git a/apps/clients/chooser/src/App.tsx b/apps/clients/chooser/src/App.tsx
index 3e786a4..f0d7c23 100644
--- a/apps/clients/chooser/src/App.tsx
+++ b/apps/clients/chooser/src/App.tsx
@@ -11,7 +11,7 @@ import superjson from "superjson";
import { ClientNotFound } from "@sora-vp/ui/client-not-found";
-import { KeyboardWebsocketProvider } from "./context/keyboard-websocket";
+import { HardwareWebsocketProvider } from "./context/hardware-websocket";
import { env } from "./env";
const router = createBrowserRouter([
@@ -78,13 +78,13 @@ export default function App() {
return (
-
+
-
+
);
diff --git a/apps/clients/chooser/src/components/scanner/index.tsx b/apps/clients/chooser/src/components/scanner/index.tsx
index b16bbf5..c4a0f13 100644
--- a/apps/clients/chooser/src/components/scanner/index.tsx
+++ b/apps/clients/chooser/src/components/scanner/index.tsx
@@ -1,5 +1,5 @@
import { useCallback, useEffect, useState } from "react";
-import { useKeyboardWebsocket } from "@/context/keyboard-websocket";
+import { useHardwareWebsocket } from "@/context/hardware-websocket";
import { useParticipant } from "@/context/participant-context";
import { api } from "@/utils/api";
import { Navigate } from "react-router-dom";
@@ -10,24 +10,21 @@ import { MainScanner } from "./main-scanner";
export function ScannerComponent() {
const { qrId, setQRCode } = useParticipant();
- const { wsEnabled, lastMessage, setLastMessage } = useKeyboardWebsocket();
+ const { subscribe } = useHardwareWebsocket();
const [isQrInvalid, setInvalidQr] = useState(false);
const participantAttended =
api.clientConsumer.checkParticipantAttended.useMutation({
onSuccess() {
- setLastMessage(null);
-
setQRCode(participantAttended.variables!);
},
});
useEffect(() => {
- if (wsEnabled && lastMessage) {
- // Precheck before consuming command
- if (lastMessage.startsWith("SORA-KEYBIND-")) {
- const actualCommand = lastMessage.replace("SORA-KEYBIND-", "");
+ const unsubHardware = subscribe((message) => {
+ if (message.startsWith("SORA-KEYBIND-")) {
+ const actualCommand = message.replace("SORA-KEYBIND-", "");
switch (actualCommand) {
case "RELOAD": {
@@ -37,8 +34,12 @@ export function ScannerComponent() {
}
}
}
- }
- }, [isQrInvalid, participantAttended.isError, wsEnabled, lastMessage]);
+ });
+
+ return () => {
+ unsubHardware();
+ };
+ }, [isQrInvalid, participantAttended.isError]);
const setIsQrValid = useCallback(
(invalid: boolean) => setInvalidQr(invalid),
diff --git a/apps/clients/chooser/src/context/keyboard-websocket.tsx b/apps/clients/chooser/src/context/hardware-websocket.tsx
similarity index 54%
rename from apps/clients/chooser/src/context/keyboard-websocket.tsx
rename to apps/clients/chooser/src/context/hardware-websocket.tsx
index 5823240..073aa2c 100644
--- a/apps/clients/chooser/src/context/keyboard-websocket.tsx
+++ b/apps/clients/chooser/src/context/hardware-websocket.tsx
@@ -3,8 +3,7 @@ import {
useCallback,
useContext,
useEffect,
- useMemo,
- useState,
+ useRef,
} from "react";
import { defaultWSPortAtom, enableWSConnectionAtom } from "@/utils/atom";
import { useAtomValue } from "jotai";
@@ -12,28 +11,31 @@ import useWebSocket, { ReadyState } from "react-use-websocket";
import { toast } from "@sora-vp/ui/toast";
-export interface IKeyboardWebsocket {
+export type THardwareWebsocketCallback = (message: string) => void;
+
+export interface IHardwareWebsocket {
wsEnabled: boolean;
- lastMessage: string | null;
- setLastMessage: (msg: string | null) => void;
+ subscribe(callbacK: THardwareWebsocketCallback): () => void;
}
-export const KeyboardWebsocketContext = createContext(
- {} as IKeyboardWebsocket,
+export const HardwareWebsocketContext = createContext(
+ {} as IHardwareWebsocket,
);
-export const KeyboardWebsocketProvider = ({
+export const HardwareWebsocketProvider = ({
children,
}: {
children: React.ReactNode;
}) => {
- const [lastMessage, setLastMessageState] =
- useState(null);
+ const currentSubscriberIdRef = useRef(0);
+ const subscribersRef = useRef