From 6184e7edc92783456eaee7891197348175ceea6d Mon Sep 17 00:00:00 2001 From: mukherja04 Date: Wed, 5 Nov 2025 14:58:05 -0600 Subject: [PATCH 1/3] Added ScribeAR Server connection snackbar --- package-lock.json | 351 ++++++++++++++++++ src/App.tsx | 59 ++- .../api/scribearServer/scribearRecognizer.tsx | 24 +- src/components/navbars/topbar/api/pickApi.tsx | 2 +- 4 files changed, 427 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 838a59b..b4bfcd8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3784,6 +3784,314 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz", + "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz", + "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz", + "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz", + "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz", + "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz", + "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz", + "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz", + "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz", + "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz", + "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz", + "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz", + "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz", + "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz", + "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz", + "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz", + "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz", + "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz", + "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "peer": true + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz", + "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz", + "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz", + "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz", + "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, "node_modules/@rushstack/eslint-patch": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.4.tgz", @@ -13188,6 +13496,49 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" }, + "node_modules/meyda/node_modules/rollup": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", + "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.5", + "@rollup/rollup-android-arm64": "4.52.5", + "@rollup/rollup-darwin-arm64": "4.52.5", + "@rollup/rollup-darwin-x64": "4.52.5", + "@rollup/rollup-freebsd-arm64": "4.52.5", + "@rollup/rollup-freebsd-x64": "4.52.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", + "@rollup/rollup-linux-arm-musleabihf": "4.52.5", + "@rollup/rollup-linux-arm64-gnu": "4.52.5", + "@rollup/rollup-linux-arm64-musl": "4.52.5", + "@rollup/rollup-linux-loong64-gnu": "4.52.5", + "@rollup/rollup-linux-ppc64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-musl": "4.52.5", + "@rollup/rollup-linux-s390x-gnu": "4.52.5", + "@rollup/rollup-linux-x64-gnu": "4.52.5", + "@rollup/rollup-linux-x64-musl": "4.52.5", + "@rollup/rollup-openharmony-arm64": "4.52.5", + "@rollup/rollup-win32-arm64-msvc": "4.52.5", + "@rollup/rollup-win32-ia32-msvc": "4.52.5", + "@rollup/rollup-win32-x64-gnu": "4.52.5", + "@rollup/rollup-win32-x64-msvc": "4.52.5", + "fsevents": "~2.3.2" + } + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", diff --git a/src/App.tsx b/src/App.tsx index 0f3a7c3..9c05b1f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,22 +1,67 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import Desktop from './mode/Desktop'; import WhisperFrame from './mode/WhisperFrame'; -import { useSelector} from 'react-redux'; -import { RootState, DisplayStatus } from './react-redux&middleware/redux/typesImports'; +import { useSelector } from 'react-redux'; +import { RootState, DisplayStatus, STATUS } from './react-redux&middleware/redux/typesImports'; +import Snackbar from '@mui/material/Snackbar'; +import Alert from '@mui/material/Alert'; import './App.css'; function App() { const display = useSelector((state: RootState) => { return state.DisplayReducer as DisplayStatus; - }); + }); + + const scribearStatus = useSelector((state: RootState) => state.APIStatusReducer?.scribearServerStatus as number); + + const [snackbarOpen, setSnackbarOpen] = useState(false); + const [snackbarMsg, setSnackbarMsg] = useState(''); + const [snackbarSeverity, setSnackbarSeverity] = useState<'error' | 'warning' | 'info' | 'success'>('info'); + + useEffect(() => { + // Show a visible snackbar when ScribeAR server experiences error or disconnects + if (scribearStatus === STATUS.ERROR) { + setSnackbarMsg('ScribeAR Server error: connection problem'); + setSnackbarSeverity('error'); + setSnackbarOpen(true); + } else if (scribearStatus === STATUS.UNAVAILABLE) { + setSnackbarMsg('ScribeAR Server disconnected'); + setSnackbarSeverity('warning'); + setSnackbarOpen(true); + } else if (scribearStatus === STATUS.AVAILABLE || scribearStatus === STATUS.TRANSCRIBING) { + // Optionally notify successful connection briefly + setSnackbarMsg('ScribeAR Server connected'); + setSnackbarSeverity('success'); + setSnackbarOpen(true); + // auto-close success after short time handled by Snackbar props + } + // else if (scribearStatus === STATUS.TRANSCRIBING) { + // // keep transcribing as info; close any earlier error + // setSnackbarMsg('ScribeAR Server connected'); + // setSnackbarSeverity('success'); + // setSnackbarOpen(true); + // } + }, [scribearStatus]); + + const handleClose = (_event?: React.SyntheticEvent | Event, reason?: string) => { + if (reason === 'clickaway') return; + setSnackbarOpen(false); + }; + return ( -
-
- +
+
+
+ + + + {snackbarMsg} + +
); } diff --git a/src/components/api/scribearServer/scribearRecognizer.tsx b/src/components/api/scribearServer/scribearRecognizer.tsx index 2a77003..560b56b 100644 --- a/src/components/api/scribearServer/scribearRecognizer.tsx +++ b/src/components/api/scribearServer/scribearRecognizer.tsx @@ -1,6 +1,6 @@ import { Recognizer } from '../recognizer'; import { TranscriptBlock } from '../../../react-redux&middleware/redux/types/TranscriptTypes'; -import { ScribearServerStatus } from '../../../react-redux&middleware/redux/typesImports'; +import { ScribearServerStatus, STATUS } from '../../../react-redux&middleware/redux/typesImports'; import RecordRTC, { StereoAudioRecorder } from 'recordrtc'; import { store } from '../../../store' import { setModelOptions, setSelectedModel } from '../../../react-redux&middleware/redux/reducers/modelSelectionReducers'; @@ -88,6 +88,12 @@ export class ScribearRecognizer implements Recognizer { sourceToken: this.scribearServerStatus.scribearServerKey, sessionToken: this.scribearServerStatus.scribearServerSessionToken, })); + // Notify UI that the socket is open/available + try { + store.dispatch({ type: 'CHANGE_API_STATUS', payload: { scribearServerStatus: STATUS.AVAILABLE } }); + } catch (e) { + console.warn('Failed to dispatch API status AVAILABLE', e); + } } const inProgressBlock = new TranscriptBlock(); @@ -103,6 +109,12 @@ export class ScribearRecognizer implements Recognizer { if (this.selectedModelOption) { this.socket?.send(JSON.stringify(this.selectedModelOption)); this.ready = true; + // Client has informed server which model to use — consider the connection active/ready + try { + store.dispatch({ type: 'CHANGE_API_STATUS', payload: { scribearServerStatus: STATUS.TRANSCRIBING } }); + } catch (e) { + console.warn('Failed to dispatch API status TRANSCRIBING', e); + } } return; } @@ -127,12 +139,22 @@ export class ScribearRecognizer implements Recognizer { this.socket.onerror = (event) => { const error = new Error("WebSocket error"); console.error("WebSocket error event:", event); + try { + store.dispatch({ type: 'CHANGE_API_STATUS', payload: { scribearServerStatus: STATUS.ERROR } }); + } catch (e) { + console.warn('Failed to dispatch API status ERROR', e); + } this.errorCallback?.(error); }; this.socket.onclose = (event) => { console.warn(`WebSocket closed: code=${event.code}, reason=${event.reason}`); this.socket = null; + try { + store.dispatch({ type: 'CHANGE_API_STATUS', payload: { scribearServerStatus: STATUS.UNAVAILABLE } }); + } catch (e) { + console.warn('Failed to dispatch API status UNAVAILABLE', e); + } if (event.code !== 1000) { // 1000 = normal closure const error = new Error(`WebSocket closed unexpectedly: code=${event.code}`); this.errorCallback?.(error); diff --git a/src/components/navbars/topbar/api/pickApi.tsx b/src/components/navbars/topbar/api/pickApi.tsx index bba360f..6a597ce 100644 --- a/src/components/navbars/topbar/api/pickApi.tsx +++ b/src/components/navbars/topbar/api/pickApi.tsx @@ -176,7 +176,7 @@ export default function PickApi() { copyStatus.azureConvoStatus = STATUS.AVAILABLE; copyStatus.whisperStatus = STATUS.AVAILABLE; copyStatus.streamTextStatus = STATUS.AVAILABLE; - copyStatus.scribearServerStatus= STATUS.AVAILABLE; + // NOTE: do not reset scribearServerStatus here — keep the last known server state copyStatus.playbackStatus = STATUS.AVAILABLE; let apiName = ''; From 3c7d74c5b7f067ae18d3a5a093c9278421261a70 Mon Sep 17 00:00:00 2001 From: mukherja04 Date: Wed, 5 Nov 2025 15:55:03 -0600 Subject: [PATCH 2/3] Distinguished server disconnection with API key error --- src/App.tsx | 12 +++--------- .../api/scribearServer/scribearRecognizer.tsx | 9 ++++++++- src/components/navbars/topbar/api/pickApi.tsx | 13 +++++++------ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 9c05b1f..2a1be4e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,15 +15,16 @@ function App() { }); const scribearStatus = useSelector((state: RootState) => state.APIStatusReducer?.scribearServerStatus as number); + const scribearMessage = useSelector((state: RootState) => (state.APIStatusReducer as any)?.scribearServerMessage as string | undefined); const [snackbarOpen, setSnackbarOpen] = useState(false); const [snackbarMsg, setSnackbarMsg] = useState(''); const [snackbarSeverity, setSnackbarSeverity] = useState<'error' | 'warning' | 'info' | 'success'>('info'); useEffect(() => { - // Show a visible snackbar when ScribeAR server experiences error or disconnects + // Show a visible snackbar when ScribeAR server connects, sends error, or disconnects if (scribearStatus === STATUS.ERROR) { - setSnackbarMsg('ScribeAR Server error: connection problem'); + setSnackbarMsg(scribearMessage ?? 'ScribeAR Server error: connection problem'); setSnackbarSeverity('error'); setSnackbarOpen(true); } else if (scribearStatus === STATUS.UNAVAILABLE) { @@ -31,18 +32,11 @@ function App() { setSnackbarSeverity('warning'); setSnackbarOpen(true); } else if (scribearStatus === STATUS.AVAILABLE || scribearStatus === STATUS.TRANSCRIBING) { - // Optionally notify successful connection briefly setSnackbarMsg('ScribeAR Server connected'); setSnackbarSeverity('success'); setSnackbarOpen(true); // auto-close success after short time handled by Snackbar props } - // else if (scribearStatus === STATUS.TRANSCRIBING) { - // // keep transcribing as info; close any earlier error - // setSnackbarMsg('ScribeAR Server connected'); - // setSnackbarSeverity('success'); - // setSnackbarOpen(true); - // } }, [scribearStatus]); const handleClose = (_event?: React.SyntheticEvent | Event, reason?: string) => { diff --git a/src/components/api/scribearServer/scribearRecognizer.tsx b/src/components/api/scribearServer/scribearRecognizer.tsx index 560b56b..931293c 100644 --- a/src/components/api/scribearServer/scribearRecognizer.tsx +++ b/src/components/api/scribearServer/scribearRecognizer.tsx @@ -155,10 +155,17 @@ export class ScribearRecognizer implements Recognizer { } catch (e) { console.warn('Failed to dispatch API status UNAVAILABLE', e); } - if (event.code !== 1000) { // 1000 = normal closure + if (event.code == 3000) { // API key error + try { + store.dispatch({ type: 'CHANGE_API_STATUS', payload: { scribearServerStatus: STATUS.ERROR, scribearServerMessage: 'ScribeAR Server rejected credentials (invalid API key/token)' } }); + } catch (e) { + console.warn('Failed to dispatch API status for code 3000', e); + } + } else if (event.code !== 1000) { // 1000 = normal closure const error = new Error(`WebSocket closed unexpectedly: code=${event.code}`); this.errorCallback?.(error); } + }; } diff --git a/src/components/navbars/topbar/api/pickApi.tsx b/src/components/navbars/topbar/api/pickApi.tsx index 6a597ce..d9c90bd 100644 --- a/src/components/navbars/topbar/api/pickApi.tsx +++ b/src/components/navbars/topbar/api/pickApi.tsx @@ -171,13 +171,14 @@ export default function PickApi() { copyStatus.currentApi = api; // reset all - copyStatus.azureTranslStatus = STATUS.AVAILABLE; - copyStatus.webspeechStatus = STATUS.AVAILABLE; - copyStatus.azureConvoStatus = STATUS.AVAILABLE; - copyStatus.whisperStatus = STATUS.AVAILABLE; - copyStatus.streamTextStatus = STATUS.AVAILABLE; + copyStatus.azureTranslStatus = STATUS.AVAILABLE; + copyStatus.webspeechStatus = STATUS.AVAILABLE; + copyStatus.azureConvoStatus = STATUS.AVAILABLE; + copyStatus.whisperStatus = STATUS.AVAILABLE; + copyStatus.streamTextStatus = STATUS.AVAILABLE; + copyStatus.scribearServerStatus = STATUS.NULL; // NOTE: do not reset scribearServerStatus here — keep the last known server state - copyStatus.playbackStatus = STATUS.AVAILABLE; + copyStatus.playbackStatus = STATUS.AVAILABLE; let apiName = ''; if (api === API.AZURE_TRANSLATION) { From 78b27fe3f363d0dd80a19f76a4ec500aedc6b856 Mon Sep 17 00:00:00 2001 From: mukherja04 Date: Wed, 5 Nov 2025 16:33:38 -0600 Subject: [PATCH 3/3] Fixed transcription model bug --- src/components/navbars/topbar/api/pickApi.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/navbars/topbar/api/pickApi.tsx b/src/components/navbars/topbar/api/pickApi.tsx index d9c90bd..7056c47 100644 --- a/src/components/navbars/topbar/api/pickApi.tsx +++ b/src/components/navbars/topbar/api/pickApi.tsx @@ -176,7 +176,6 @@ export default function PickApi() { copyStatus.azureConvoStatus = STATUS.AVAILABLE; copyStatus.whisperStatus = STATUS.AVAILABLE; copyStatus.streamTextStatus = STATUS.AVAILABLE; - copyStatus.scribearServerStatus = STATUS.NULL; // NOTE: do not reset scribearServerStatus here — keep the last known server state copyStatus.playbackStatus = STATUS.AVAILABLE;