@omniloy/sofia-sdk 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/legacy/webcomponents.es.js +915 -125
- package/dist/legacy/webcomponents.umd.js +915 -125
- package/dist/react/index.css +39 -12
- package/dist/react/index.es.js +948 -123
- package/dist/webcomponents.es.js +893 -111
- package/dist/webcomponents.umd.js +893 -111
- package/package.json +1 -1
package/dist/react/index.es.js
CHANGED
|
@@ -4313,7 +4313,7 @@ const {
|
|
|
4313
4313
|
mergeConfig: mergeConfig$1,
|
|
4314
4314
|
} = axios;
|
|
4315
4315
|
|
|
4316
|
-
const version$2 = "1.0.
|
|
4316
|
+
const version$2 = "1.0.4";
|
|
4317
4317
|
|
|
4318
4318
|
const handleApiError$1 = async (error) => {
|
|
4319
4319
|
return Promise.reject(error);
|
|
@@ -4928,6 +4928,23 @@ const ar = {
|
|
|
4928
4928
|
"Disable field": "تعطيل الحقل",
|
|
4929
4929
|
"Enable field": "تمكين الحقل",
|
|
4930
4930
|
"Customize field prompt": "تخصيص أمر الحقل",
|
|
4931
|
+
"Microphone disconnected": "تم فصل الميكروفون",
|
|
4932
|
+
"The microphone was disconnected during recording": "تم فصل الميكروفون أثناء التسجيل",
|
|
4933
|
+
"Microphone reconnected": "تم إعادة توصيل الميكروفون",
|
|
4934
|
+
"The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.": "تم فصل الميكروفون لفترة وجيزة. قد يكون جزء من التسجيل بعد \"{lastPhrase}\" قد فُقد.",
|
|
4935
|
+
"The microphone was briefly disconnected. Part of the recording may have been lost.": "تم فصل الميكروفون لفترة وجيزة. قد يكون جزء من التسجيل قد فُقد.",
|
|
4936
|
+
"Recording interrupted": "تم إيقاف التسجيل",
|
|
4937
|
+
"The server closed the session unexpectedly. Please start recording again.": "أغلق الخادم الجلسة بشكل غير متوقع. يرجى بدء التسجيل مرة أخرى.",
|
|
4938
|
+
"Microphone changed": "تم تغيير الميكروفون",
|
|
4939
|
+
"Your selected microphone was unavailable. Recording continues with the default microphone.": "الميكروفون الذي اخترته غير متاح. يستمر التسجيل باستخدام الميكروفون الافتراضي.",
|
|
4940
|
+
"No microphone available": "لا يوجد ميكروفون متاح",
|
|
4941
|
+
"Connect a microphone and try again.": "قم بتوصيل ميكروفون وحاول مرة أخرى.",
|
|
4942
|
+
"Connection lost": "انقطع الاتصال",
|
|
4943
|
+
"Internet connection was lost during recording. Audio may not reach the server until the connection is restored.": "انقطع اتصال الإنترنت أثناء التسجيل. قد لا يصل الصوت إلى الخادم حتى يتم استعادة الاتصال.",
|
|
4944
|
+
"Connection restored": "تم استعادة الاتصال",
|
|
4945
|
+
"Internet connection has been restored. Recording continues normally.": "تم استعادة اتصال الإنترنت. يستمر التسجيل بشكل طبيعي.",
|
|
4946
|
+
"Slow connection": "اتصال بطيء",
|
|
4947
|
+
"Your internet connection appears to be slow. Some audio may be delayed.": "يبدو أن اتصالك بالإنترنت بطيء. قد يتأخر بعض الصوت.",
|
|
4931
4948
|
};
|
|
4932
4949
|
|
|
4933
4950
|
const Add$b = "Afegir";
|
|
@@ -5204,6 +5221,23 @@ const ca = {
|
|
|
5204
5221
|
"Disable field": "Desactivar camp",
|
|
5205
5222
|
"Enable field": "Activar camp",
|
|
5206
5223
|
"Customize field prompt": "Personalitzar prompt del camp",
|
|
5224
|
+
"Microphone disconnected": "Micròfon desconnectat",
|
|
5225
|
+
"The microphone was disconnected during recording": "El micròfon s'ha desconnectat durant la gravació",
|
|
5226
|
+
"Microphone reconnected": "Micròfon reconnectat",
|
|
5227
|
+
"The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.": "El micròfon s'ha desconnectat breument. Part de la gravació després de \"{lastPhrase}\" pot haver-se perdut.",
|
|
5228
|
+
"The microphone was briefly disconnected. Part of the recording may have been lost.": "El micròfon s'ha desconnectat breument. Part de la gravació pot haver-se perdut.",
|
|
5229
|
+
"Recording interrupted": "Gravació interrompuda",
|
|
5230
|
+
"The server closed the session unexpectedly. Please start recording again.": "El servidor ha tancat la sessió inesperadament. Si us plau, inicia la gravació de nou.",
|
|
5231
|
+
"Microphone changed": "Micròfon canviat",
|
|
5232
|
+
"Your selected microphone was unavailable. Recording continues with the default microphone.": "El micròfon seleccionat no estava disponible. La gravació continua amb el micròfon per defecte.",
|
|
5233
|
+
"No microphone available": "No hi ha cap micròfon disponible",
|
|
5234
|
+
"Connect a microphone and try again.": "Connecta un micròfon i torna-ho a provar.",
|
|
5235
|
+
"Connection lost": "Connexió perduda",
|
|
5236
|
+
"Internet connection was lost during recording. Audio may not reach the server until the connection is restored.": "S'ha perdut la connexió a Internet durant la gravació. L'àudio podria no arribar al servidor fins que es restableixi la connexió.",
|
|
5237
|
+
"Connection restored": "Connexió restablerta",
|
|
5238
|
+
"Internet connection has been restored. Recording continues normally.": "La connexió a Internet s'ha restablert. La gravació continua normalment.",
|
|
5239
|
+
"Slow connection": "Connexió lenta",
|
|
5240
|
+
"Your internet connection appears to be slow. Some audio may be delayed.": "La teva connexió a Internet sembla lenta. Part de l'àudio podria retardar-se.",
|
|
5207
5241
|
};
|
|
5208
5242
|
|
|
5209
5243
|
const Add$a = "Afegir";
|
|
@@ -5480,6 +5514,23 @@ const ca_valencia = {
|
|
|
5480
5514
|
"Disable field": "Desactivar camp",
|
|
5481
5515
|
"Enable field": "Activar camp",
|
|
5482
5516
|
"Customize field prompt": "Personalitzar prompt del camp",
|
|
5517
|
+
"Microphone disconnected": "Micròfon desconnectat",
|
|
5518
|
+
"The microphone was disconnected during recording": "El micròfon s'ha desconnectat durant la gravació",
|
|
5519
|
+
"Microphone reconnected": "Micròfon reconnectat",
|
|
5520
|
+
"The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.": "El micròfon s'ha desconnectat breument. Part de la gravació després de \"{lastPhrase}\" pot haver-se perdut.",
|
|
5521
|
+
"The microphone was briefly disconnected. Part of the recording may have been lost.": "El micròfon s'ha desconnectat breument. Part de la gravació pot haver-se perdut.",
|
|
5522
|
+
"Recording interrupted": "Gravació interrompuda",
|
|
5523
|
+
"The server closed the session unexpectedly. Please start recording again.": "El servidor ha tancat la sessió inesperadament. Per favor, inicia la gravació de nou.",
|
|
5524
|
+
"Microphone changed": "Micròfon canviat",
|
|
5525
|
+
"Your selected microphone was unavailable. Recording continues with the default microphone.": "El micròfon seleccionat no estava disponible. La gravació continua amb el micròfon per defecte.",
|
|
5526
|
+
"No microphone available": "No hi ha cap micròfon disponible",
|
|
5527
|
+
"Connect a microphone and try again.": "Connecta un micròfon i torna-ho a provar.",
|
|
5528
|
+
"Connection lost": "Connexió perduda",
|
|
5529
|
+
"Internet connection was lost during recording. Audio may not reach the server until the connection is restored.": "S'ha perdut la connexió a Internet durant la gravació. L'àudio podria no arribar al servidor fins que es restableixi la connexió.",
|
|
5530
|
+
"Connection restored": "Connexió restablerta",
|
|
5531
|
+
"Internet connection has been restored. Recording continues normally.": "La connexió a Internet s'ha restablert. La gravació continua normalment.",
|
|
5532
|
+
"Slow connection": "Connexió lenta",
|
|
5533
|
+
"Your internet connection appears to be slow. Some audio may be delayed.": "La teva connexió a Internet sembla lenta. Part de l'àudio podria retardar-se.",
|
|
5483
5534
|
};
|
|
5484
5535
|
|
|
5485
5536
|
const Add$9 = "Přidat";
|
|
@@ -5756,6 +5807,23 @@ const cs = {
|
|
|
5756
5807
|
"Disable field": "Zakázat pole",
|
|
5757
5808
|
"Enable field": "Povolit pole",
|
|
5758
5809
|
"Customize field prompt": "Přizpůsobit prompt pole",
|
|
5810
|
+
"Microphone disconnected": "Mikrofon odpojen",
|
|
5811
|
+
"The microphone was disconnected during recording": "Mikrofon byl odpojen během nahrávání",
|
|
5812
|
+
"Microphone reconnected": "Mikrofon znovu připojen",
|
|
5813
|
+
"The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.": "Mikrofon byl krátce odpojen. Část nahrávky po \"{lastPhrase}\" mohla být ztracena.",
|
|
5814
|
+
"The microphone was briefly disconnected. Part of the recording may have been lost.": "Mikrofon byl krátce odpojen. Část nahrávky mohla být ztracena.",
|
|
5815
|
+
"Recording interrupted": "Nahrávání přerušeno",
|
|
5816
|
+
"The server closed the session unexpectedly. Please start recording again.": "Server neočekávaně ukončil relaci. Zahajte nahrávání znovu.",
|
|
5817
|
+
"Microphone changed": "Mikrofon změněn",
|
|
5818
|
+
"Your selected microphone was unavailable. Recording continues with the default microphone.": "Vybraný mikrofon nebyl dostupný. Nahrávání pokračuje s výchozím mikrofonem.",
|
|
5819
|
+
"No microphone available": "Žádný mikrofon není k dispozici",
|
|
5820
|
+
"Connect a microphone and try again.": "Připojte mikrofon a zkuste to znovu.",
|
|
5821
|
+
"Connection lost": "Spojení ztraceno",
|
|
5822
|
+
"Internet connection was lost during recording. Audio may not reach the server until the connection is restored.": "Během nahrávání bylo ztraceno internetové připojení. Zvuk nemusí dorazit na server, dokud nebude připojení obnoveno.",
|
|
5823
|
+
"Connection restored": "Spojení obnoveno",
|
|
5824
|
+
"Internet connection has been restored. Recording continues normally.": "Internetové připojení bylo obnoveno. Nahrávání pokračuje normálně.",
|
|
5825
|
+
"Slow connection": "Pomalé připojení",
|
|
5826
|
+
"Your internet connection appears to be slow. Some audio may be delayed.": "Vaše internetové připojení se zdá být pomalé. Část zvuku může být zpožděna.",
|
|
5759
5827
|
};
|
|
5760
5828
|
|
|
5761
5829
|
const Add$8 = "Add";
|
|
@@ -6032,6 +6100,23 @@ const en_GB = {
|
|
|
6032
6100
|
"Disable field": "Disable field",
|
|
6033
6101
|
"Enable field": "Enable field",
|
|
6034
6102
|
"Customize field prompt": "Customise field prompt",
|
|
6103
|
+
"Microphone disconnected": "Microphone disconnected",
|
|
6104
|
+
"The microphone was disconnected during recording": "The microphone was disconnected during recording",
|
|
6105
|
+
"Microphone reconnected": "Microphone reconnected",
|
|
6106
|
+
"The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.": "The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.",
|
|
6107
|
+
"The microphone was briefly disconnected. Part of the recording may have been lost.": "The microphone was briefly disconnected. Part of the recording may have been lost.",
|
|
6108
|
+
"Recording interrupted": "Recording interrupted",
|
|
6109
|
+
"The server closed the session unexpectedly. Please start recording again.": "The server closed the session unexpectedly. Please start recording again.",
|
|
6110
|
+
"Microphone changed": "Microphone changed",
|
|
6111
|
+
"Your selected microphone was unavailable. Recording continues with the default microphone.": "Your selected microphone was unavailable. Recording continues with the default microphone.",
|
|
6112
|
+
"No microphone available": "No microphone available",
|
|
6113
|
+
"Connect a microphone and try again.": "Connect a microphone and try again.",
|
|
6114
|
+
"Connection lost": "Connection lost",
|
|
6115
|
+
"Internet connection was lost during recording. Audio may not reach the server until the connection is restored.": "Internet connection was lost during recording. Audio may not reach the server until the connection is restored.",
|
|
6116
|
+
"Connection restored": "Connection restored",
|
|
6117
|
+
"Internet connection has been restored. Recording continues normally.": "Internet connection has been restored. Recording continues normally.",
|
|
6118
|
+
"Slow connection": "Slow connection",
|
|
6119
|
+
"Your internet connection appears to be slow. Some audio may be delayed.": "Your internet connection appears to be slow. Some audio may be delayed.",
|
|
6035
6120
|
};
|
|
6036
6121
|
|
|
6037
6122
|
const Add$7 = "Add";
|
|
@@ -6308,6 +6393,23 @@ const en_US = {
|
|
|
6308
6393
|
"Disable field": "Disable field",
|
|
6309
6394
|
"Enable field": "Enable field",
|
|
6310
6395
|
"Customize field prompt": "Customize field prompt",
|
|
6396
|
+
"Microphone disconnected": "Microphone disconnected",
|
|
6397
|
+
"The microphone was disconnected during recording": "The microphone was disconnected during recording",
|
|
6398
|
+
"Microphone reconnected": "Microphone reconnected",
|
|
6399
|
+
"The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.": "The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.",
|
|
6400
|
+
"The microphone was briefly disconnected. Part of the recording may have been lost.": "The microphone was briefly disconnected. Part of the recording may have been lost.",
|
|
6401
|
+
"Recording interrupted": "Recording interrupted",
|
|
6402
|
+
"The server closed the session unexpectedly. Please start recording again.": "The server closed the session unexpectedly. Please start recording again.",
|
|
6403
|
+
"Microphone changed": "Microphone changed",
|
|
6404
|
+
"Your selected microphone was unavailable. Recording continues with the default microphone.": "Your selected microphone was unavailable. Recording continues with the default microphone.",
|
|
6405
|
+
"No microphone available": "No microphone available",
|
|
6406
|
+
"Connect a microphone and try again.": "Connect a microphone and try again.",
|
|
6407
|
+
"Connection lost": "Connection lost",
|
|
6408
|
+
"Internet connection was lost during recording. Audio may not reach the server until the connection is restored.": "Internet connection was lost during recording. Audio may not reach the server until the connection is restored.",
|
|
6409
|
+
"Connection restored": "Connection restored",
|
|
6410
|
+
"Internet connection has been restored. Recording continues normally.": "Internet connection has been restored. Recording continues normally.",
|
|
6411
|
+
"Slow connection": "Slow connection",
|
|
6412
|
+
"Your internet connection appears to be slow. Some audio may be delayed.": "Your internet connection appears to be slow. Some audio may be delayed.",
|
|
6311
6413
|
};
|
|
6312
6414
|
|
|
6313
6415
|
const Add$6 = "Añadir";
|
|
@@ -6584,6 +6686,23 @@ const es = {
|
|
|
6584
6686
|
"Disable field": "Desactivar campo",
|
|
6585
6687
|
"Enable field": "Activar campo",
|
|
6586
6688
|
"Customize field prompt": "Personalizar prompt del campo",
|
|
6689
|
+
"Microphone disconnected": "Micrófono desconectado",
|
|
6690
|
+
"The microphone was disconnected during recording": "El micrófono se desconectó durante la grabación",
|
|
6691
|
+
"Microphone reconnected": "Micrófono reconectado",
|
|
6692
|
+
"The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.": "El micrófono se desconectó brevemente. Parte de la grabación después de \"{lastPhrase}\" puede haberse perdido.",
|
|
6693
|
+
"The microphone was briefly disconnected. Part of the recording may have been lost.": "El micrófono se desconectó brevemente. Parte de la grabación puede haberse perdido.",
|
|
6694
|
+
"Recording interrupted": "Grabación interrumpida",
|
|
6695
|
+
"The server closed the session unexpectedly. Please start recording again.": "El servidor cerró la sesión inesperadamente. Vuelve a iniciar la grabación.",
|
|
6696
|
+
"Microphone changed": "Micrófono cambiado",
|
|
6697
|
+
"Your selected microphone was unavailable. Recording continues with the default microphone.": "El micrófono seleccionado no estaba disponible. La grabación continúa con el micrófono predeterminado.",
|
|
6698
|
+
"No microphone available": "No hay ningún micrófono disponible",
|
|
6699
|
+
"Connect a microphone and try again.": "Conecta un micrófono e inténtalo de nuevo.",
|
|
6700
|
+
"Connection lost": "Conexión perdida",
|
|
6701
|
+
"Internet connection was lost during recording. Audio may not reach the server until the connection is restored.": "Se perdió la conexión a internet durante la grabación. El audio podría no llegar al servidor hasta que se restablezca la conexión.",
|
|
6702
|
+
"Connection restored": "Conexión restablecida",
|
|
6703
|
+
"Internet connection has been restored. Recording continues normally.": "La conexión a internet se ha restablecido. La grabación continúa normalmente.",
|
|
6704
|
+
"Slow connection": "Conexión lenta",
|
|
6705
|
+
"Your internet connection appears to be slow. Some audio may be delayed.": "Tu conexión a internet parece ser lenta. Parte del audio podría retrasarse.",
|
|
6587
6706
|
};
|
|
6588
6707
|
|
|
6589
6708
|
const Add$5 = "Ajouter";
|
|
@@ -6860,6 +6979,23 @@ const fr = {
|
|
|
6860
6979
|
"Disable field": "Désactiver le champ",
|
|
6861
6980
|
"Enable field": "Activer le champ",
|
|
6862
6981
|
"Customize field prompt": "Personnaliser le prompt du champ",
|
|
6982
|
+
"Microphone disconnected": "Microphone déconnecté",
|
|
6983
|
+
"The microphone was disconnected during recording": "Le microphone a été déconnecté pendant l'enregistrement",
|
|
6984
|
+
"Microphone reconnected": "Microphone reconnecté",
|
|
6985
|
+
"The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.": "Le microphone a été brièvement déconnecté. Une partie de l'enregistrement après \"{lastPhrase}\" a pu être perdue.",
|
|
6986
|
+
"The microphone was briefly disconnected. Part of the recording may have been lost.": "Le microphone a été brièvement déconnecté. Une partie de l'enregistrement a pu être perdue.",
|
|
6987
|
+
"Recording interrupted": "Enregistrement interrompu",
|
|
6988
|
+
"The server closed the session unexpectedly. Please start recording again.": "Le serveur a fermé la session de manière inattendue. Veuillez relancer l'enregistrement.",
|
|
6989
|
+
"Microphone changed": "Microphone modifié",
|
|
6990
|
+
"Your selected microphone was unavailable. Recording continues with the default microphone.": "Le microphone sélectionné n'était pas disponible. L'enregistrement continue avec le microphone par défaut.",
|
|
6991
|
+
"No microphone available": "Aucun microphone disponible",
|
|
6992
|
+
"Connect a microphone and try again.": "Connectez un microphone et réessayez.",
|
|
6993
|
+
"Connection lost": "Connexion perdue",
|
|
6994
|
+
"Internet connection was lost during recording. Audio may not reach the server until the connection is restored.": "La connexion Internet a été perdue pendant l'enregistrement. L'audio pourrait ne pas atteindre le serveur tant que la connexion n'est pas rétablie.",
|
|
6995
|
+
"Connection restored": "Connexion rétablie",
|
|
6996
|
+
"Internet connection has been restored. Recording continues normally.": "La connexion Internet a été rétablie. L'enregistrement continue normalement.",
|
|
6997
|
+
"Slow connection": "Connexion lente",
|
|
6998
|
+
"Your internet connection appears to be slow. Some audio may be delayed.": "Votre connexion Internet semble lente. Une partie de l'audio pourrait être retardée.",
|
|
6863
6999
|
};
|
|
6864
7000
|
|
|
6865
7001
|
const Add$4 = "जोड़ें";
|
|
@@ -7118,6 +7254,23 @@ const hi = {
|
|
|
7118
7254
|
"Disable field": "फ़ील्ड अक्षम करें",
|
|
7119
7255
|
"Enable field": "फ़ील्ड सक्षम करें",
|
|
7120
7256
|
"Customize field prompt": "फ़ील्ड प्रॉम्प्ट अनुकूलित करें",
|
|
7257
|
+
"Microphone disconnected": "माइक्रोफ़ोन डिस्कनेक्ट हो गया",
|
|
7258
|
+
"The microphone was disconnected during recording": "रिकॉर्डिंग के दौरान माइक्रोफ़ोन डिस्कनेक्ट हो गया",
|
|
7259
|
+
"Microphone reconnected": "माइक्रोफ़ोन फिर से कनेक्ट हो गया",
|
|
7260
|
+
"The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.": "माइक्रोफ़ोन कुछ समय के लिए डिस्कनेक्ट हो गया था। \"{lastPhrase}\" के बाद की रिकॉर्डिंग का कुछ हिस्सा खो गया हो सकता है।",
|
|
7261
|
+
"The microphone was briefly disconnected. Part of the recording may have been lost.": "माइक्रोफ़ोन कुछ समय के लिए डिस्कनेक्ट हो गया था। रिकॉर्डिंग का कुछ हिस्सा खो गया हो सकता है।",
|
|
7262
|
+
"Recording interrupted": "रिकॉर्डिंग बाधित हुई",
|
|
7263
|
+
"The server closed the session unexpectedly. Please start recording again.": "सर्वर ने सत्र अप्रत्याशित रूप से बंद कर दिया। कृपया रिकॉर्डिंग फिर से शुरू करें।",
|
|
7264
|
+
"Microphone changed": "माइक्रोफ़ोन बदल गया",
|
|
7265
|
+
"Your selected microphone was unavailable. Recording continues with the default microphone.": "आपका चुना गया माइक्रोफ़ोन उपलब्ध नहीं था। रिकॉर्डिंग डिफ़ॉल्ट माइक्रोफ़ोन के साथ जारी है।",
|
|
7266
|
+
"No microphone available": "कोई माइक्रोफ़ोन उपलब्ध नहीं है",
|
|
7267
|
+
"Connect a microphone and try again.": "माइक्रोफ़ोन कनेक्ट करें और पुनः प्रयास करें।",
|
|
7268
|
+
"Connection lost": "कनेक्शन टूट गया",
|
|
7269
|
+
"Internet connection was lost during recording. Audio may not reach the server until the connection is restored.": "रिकॉर्डिंग के दौरान इंटरनेट कनेक्शन टूट गया। कनेक्शन बहाल होने तक ऑडियो सर्वर तक नहीं पहुँच सकता।",
|
|
7270
|
+
"Connection restored": "कनेक्शन बहाल हो गया",
|
|
7271
|
+
"Internet connection has been restored. Recording continues normally.": "इंटरनेट कनेक्शन बहाल हो गया है। रिकॉर्डिंग सामान्य रूप से जारी है।",
|
|
7272
|
+
"Slow connection": "धीमा कनेक्शन",
|
|
7273
|
+
"Your internet connection appears to be slow. Some audio may be delayed.": "आपका इंटरनेट कनेक्शन धीमा लग रहा है। कुछ ऑडियो में देरी हो सकती है।",
|
|
7121
7274
|
};
|
|
7122
7275
|
|
|
7123
7276
|
const Add$3 = "Tambahkan";
|
|
@@ -7375,6 +7528,23 @@ const id = {
|
|
|
7375
7528
|
"Disable field": "Nonaktifkan bidang",
|
|
7376
7529
|
"Enable field": "Aktifkan bidang",
|
|
7377
7530
|
"Customize field prompt": "Sesuaikan prompt bidang",
|
|
7531
|
+
"Microphone disconnected": "Mikrofon terputus",
|
|
7532
|
+
"The microphone was disconnected during recording": "Mikrofon terputus saat merekam",
|
|
7533
|
+
"Microphone reconnected": "Mikrofon tersambung kembali",
|
|
7534
|
+
"The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.": "Mikrofon sempat terputus. Sebagian rekaman setelah \"{lastPhrase}\" mungkin hilang.",
|
|
7535
|
+
"The microphone was briefly disconnected. Part of the recording may have been lost.": "Mikrofon sempat terputus. Sebagian rekaman mungkin hilang.",
|
|
7536
|
+
"Recording interrupted": "Rekaman terganggu",
|
|
7537
|
+
"The server closed the session unexpectedly. Please start recording again.": "Server menutup sesi secara tak terduga. Silakan mulai merekam lagi.",
|
|
7538
|
+
"Microphone changed": "Mikrofon berubah",
|
|
7539
|
+
"Your selected microphone was unavailable. Recording continues with the default microphone.": "Mikrofon yang Anda pilih tidak tersedia. Rekaman berlanjut dengan mikrofon default.",
|
|
7540
|
+
"No microphone available": "Tidak ada mikrofon yang tersedia",
|
|
7541
|
+
"Connect a microphone and try again.": "Sambungkan mikrofon dan coba lagi.",
|
|
7542
|
+
"Connection lost": "Koneksi terputus",
|
|
7543
|
+
"Internet connection was lost during recording. Audio may not reach the server until the connection is restored.": "Koneksi internet terputus saat merekam. Audio mungkin tidak sampai ke server hingga koneksi dipulihkan.",
|
|
7544
|
+
"Connection restored": "Koneksi dipulihkan",
|
|
7545
|
+
"Internet connection has been restored. Recording continues normally.": "Koneksi internet telah dipulihkan. Perekaman berlanjut secara normal.",
|
|
7546
|
+
"Slow connection": "Koneksi lambat",
|
|
7547
|
+
"Your internet connection appears to be slow. Some audio may be delayed.": "Koneksi internet Anda tampak lambat. Sebagian audio mungkin tertunda.",
|
|
7378
7548
|
};
|
|
7379
7549
|
|
|
7380
7550
|
const Add$2 = "ਸ਼ਾਮਲ ਕਰੋ";
|
|
@@ -7651,6 +7821,23 @@ const pa = {
|
|
|
7651
7821
|
"Disable field": "ਫੀਲਡ ਬੰਦ ਕਰੋ",
|
|
7652
7822
|
"Enable field": "ਫੀਲਡ ਚਾਲੂ ਕਰੋ",
|
|
7653
7823
|
"Customize field prompt": "ਫੀਲਡ ਪ੍ਰੋਂਪਟ ਕਸਟਮਾਈਜ਼ ਕਰੋ",
|
|
7824
|
+
"Microphone disconnected": "ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਡਿਸਕਨੈਕਟ ਹੋ ਗਿਆ",
|
|
7825
|
+
"The microphone was disconnected during recording": "ਰਿਕਾਰਡਿੰਗ ਦੌਰਾਨ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਡਿਸਕਨੈਕਟ ਹੋ ਗਿਆ",
|
|
7826
|
+
"Microphone reconnected": "ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਦੁਬਾਰਾ ਕਨੈਕਟ ਹੋ ਗਿਆ",
|
|
7827
|
+
"The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.": "ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਥੋੜ੍ਹੇ ਸਮੇਂ ਲਈ ਡਿਸਕਨੈਕਟ ਹੋ ਗਿਆ ਸੀ। \"{lastPhrase}\" ਤੋਂ ਬਾਅਦ ਦੀ ਰਿਕਾਰਡਿੰਗ ਦਾ ਕੁਝ ਹਿੱਸਾ ਗੁਆਚ ਗਿਆ ਹੋ ਸਕਦਾ ਹੈ।",
|
|
7828
|
+
"The microphone was briefly disconnected. Part of the recording may have been lost.": "ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਥੋੜ੍ਹੇ ਸਮੇਂ ਲਈ ਡਿਸਕਨੈਕਟ ਹੋ ਗਿਆ ਸੀ। ਰਿਕਾਰਡਿੰਗ ਦਾ ਕੁਝ ਹਿੱਸਾ ਗੁਆਚ ਗਿਆ ਹੋ ਸਕਦਾ ਹੈ।",
|
|
7829
|
+
"Recording interrupted": "ਰਿਕਾਰਡਿੰਗ ਵਿੱਚ ਰੁਕਾਵਟ",
|
|
7830
|
+
"The server closed the session unexpectedly. Please start recording again.": "ਸਰਵਰ ਨੇ ਸੈਸ਼ਨ ਅਚਾਨਕ ਬੰਦ ਕਰ ਦਿੱਤਾ। ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਰਿਕਾਰਡਿੰਗ ਸ਼ੁਰੂ ਕਰੋ।",
|
|
7831
|
+
"Microphone changed": "ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਬਦਲ ਗਿਆ",
|
|
7832
|
+
"Your selected microphone was unavailable. Recording continues with the default microphone.": "ਤੁਹਾਡਾ ਚੁਣਿਆ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਉਪਲਬਧ ਨਹੀਂ ਸੀ। ਰਿਕਾਰਡਿੰਗ ਡਿਫ਼ਾਲਟ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨਾਲ ਜਾਰੀ ਹੈ।",
|
|
7833
|
+
"No microphone available": "ਕੋਈ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਉਪਲਬਧ ਨਹੀਂ ਹੈ",
|
|
7834
|
+
"Connect a microphone and try again.": "ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਜੋੜੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।",
|
|
7835
|
+
"Connection lost": "ਕਨੈਕਸ਼ਨ ਟੁੱਟ ਗਿਆ",
|
|
7836
|
+
"Internet connection was lost during recording. Audio may not reach the server until the connection is restored.": "ਰਿਕਾਰਡਿੰਗ ਦੌਰਾਨ ਇੰਟਰਨੈਟ ਕਨੈਕਸ਼ਨ ਟੁੱਟ ਗਿਆ। ਕਨੈਕਸ਼ਨ ਬਹਾਲ ਹੋਣ ਤੱਕ ਆਡੀਓ ਸਰਵਰ ਤੱਕ ਨਹੀਂ ਪਹੁੰਚ ਸਕਦਾ।",
|
|
7837
|
+
"Connection restored": "ਕਨੈਕਸ਼ਨ ਬਹਾਲ ਹੋ ਗਿਆ",
|
|
7838
|
+
"Internet connection has been restored. Recording continues normally.": "ਇੰਟਰਨੈਟ ਕਨੈਕਸ਼ਨ ਬਹਾਲ ਹੋ ਗਿਆ ਹੈ। ਰਿਕਾਰਡਿੰਗ ਆਮ ਤੌਰ 'ਤੇ ਜਾਰੀ ਹੈ।",
|
|
7839
|
+
"Slow connection": "ਹੌਲੀ ਕਨੈਕਸ਼ਨ",
|
|
7840
|
+
"Your internet connection appears to be slow. Some audio may be delayed.": "ਤੁਹਾਡਾ ਇੰਟਰਨੈਟ ਕਨੈਕਸ਼ਨ ਹੌਲੀ ਲੱਗ ਰਿਹਾ ਹੈ। ਕੁਝ ਆਡੀਓ ਵਿੱਚ ਦੇਰੀ ਹੋ ਸਕਦੀ ਹੈ।",
|
|
7654
7841
|
};
|
|
7655
7842
|
|
|
7656
7843
|
const Add$1 = "Lägg till";
|
|
@@ -7927,6 +8114,23 @@ const sv = {
|
|
|
7927
8114
|
"Disable field": "Inaktivera fält",
|
|
7928
8115
|
"Enable field": "Aktivera fält",
|
|
7929
8116
|
"Customize field prompt": "Anpassa fältprompt",
|
|
8117
|
+
"Microphone disconnected": "Mikrofon frånkopplad",
|
|
8118
|
+
"The microphone was disconnected during recording": "Mikrofonen kopplades från under inspelningen",
|
|
8119
|
+
"Microphone reconnected": "Mikrofon återansluten",
|
|
8120
|
+
"The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.": "Mikrofonen kopplades kortvarigt från. Delar av inspelningen efter \"{lastPhrase}\" kan ha gått förlorade.",
|
|
8121
|
+
"The microphone was briefly disconnected. Part of the recording may have been lost.": "Mikrofonen kopplades kortvarigt från. Delar av inspelningen kan ha gått förlorade.",
|
|
8122
|
+
"Recording interrupted": "Inspelning avbruten",
|
|
8123
|
+
"The server closed the session unexpectedly. Please start recording again.": "Servern stängde sessionen oväntat. Starta inspelningen igen.",
|
|
8124
|
+
"Microphone changed": "Mikrofon ändrad",
|
|
8125
|
+
"Your selected microphone was unavailable. Recording continues with the default microphone.": "Den valda mikrofonen var inte tillgänglig. Inspelningen fortsätter med standardmikrofonen.",
|
|
8126
|
+
"No microphone available": "Ingen mikrofon tillgänglig",
|
|
8127
|
+
"Connect a microphone and try again.": "Anslut en mikrofon och försök igen.",
|
|
8128
|
+
"Connection lost": "Anslutning förlorad",
|
|
8129
|
+
"Internet connection was lost during recording. Audio may not reach the server until the connection is restored.": "Internetanslutningen förlorades under inspelningen. Ljud kanske inte når servern förrän anslutningen har återställts.",
|
|
8130
|
+
"Connection restored": "Anslutning återställd",
|
|
8131
|
+
"Internet connection has been restored. Recording continues normally.": "Internetanslutningen har återställts. Inspelningen fortsätter normalt.",
|
|
8132
|
+
"Slow connection": "Långsam anslutning",
|
|
8133
|
+
"Your internet connection appears to be slow. Some audio may be delayed.": "Din internetanslutning verkar vara långsam. Visst ljud kan fördröjas.",
|
|
7930
8134
|
};
|
|
7931
8135
|
|
|
7932
8136
|
const Add = "شامل کریں";
|
|
@@ -8203,6 +8407,23 @@ const ur = {
|
|
|
8203
8407
|
"Disable field": "فیلڈ غیر فعال کریں",
|
|
8204
8408
|
"Enable field": "فیلڈ فعال کریں",
|
|
8205
8409
|
"Customize field prompt": "فیلڈ پرامپٹ حسب ضرورت بنائیں",
|
|
8410
|
+
"Microphone disconnected": "مائیکروفون منقطع ہو گیا",
|
|
8411
|
+
"The microphone was disconnected during recording": "ریکارڈنگ کے دوران مائیکروفون منقطع ہو گیا",
|
|
8412
|
+
"Microphone reconnected": "مائیکروفون دوبارہ جوڑ دیا گیا",
|
|
8413
|
+
"The microphone was briefly disconnected. Part of the recording after \"{lastPhrase}\" may have been lost.": "مائیکروفون مختصر وقت کے لیے منقطع ہو گیا تھا۔ \"{lastPhrase}\" کے بعد ریکارڈنگ کا کچھ حصہ ضائع ہو سکتا ہے۔",
|
|
8414
|
+
"The microphone was briefly disconnected. Part of the recording may have been lost.": "مائیکروفون مختصر وقت کے لیے منقطع ہو گیا تھا۔ ریکارڈنگ کا کچھ حصہ ضائع ہو سکتا ہے۔",
|
|
8415
|
+
"Recording interrupted": "ریکارڈنگ میں رکاوٹ",
|
|
8416
|
+
"The server closed the session unexpectedly. Please start recording again.": "سرور نے سیشن غیر متوقع طور پر بند کر دیا۔ براہ کرم دوبارہ ریکارڈنگ شروع کریں۔",
|
|
8417
|
+
"Microphone changed": "مائیکروفون تبدیل ہو گیا",
|
|
8418
|
+
"Your selected microphone was unavailable. Recording continues with the default microphone.": "آپ کا منتخب کردہ مائیکروفون دستیاب نہیں تھا۔ ریکارڈنگ پہلے سے طے شدہ مائیکروفون کے ساتھ جاری ہے۔",
|
|
8419
|
+
"No microphone available": "کوئی مائیکروفون دستیاب نہیں",
|
|
8420
|
+
"Connect a microphone and try again.": "مائیکروفون جوڑیں اور دوبارہ کوشش کریں۔",
|
|
8421
|
+
"Connection lost": "کنکشن ٹوٹ گیا",
|
|
8422
|
+
"Internet connection was lost during recording. Audio may not reach the server until the connection is restored.": "ریکارڈنگ کے دوران انٹرنیٹ کنکشن ٹوٹ گیا۔ کنکشن بحال ہونے تک آڈیو سرور تک نہیں پہنچ سکتا۔",
|
|
8423
|
+
"Connection restored": "کنکشن بحال ہو گیا",
|
|
8424
|
+
"Internet connection has been restored. Recording continues normally.": "انٹرنیٹ کنکشن بحال ہو گیا ہے۔ ریکارڈنگ معمول کے مطابق جاری ہے۔",
|
|
8425
|
+
"Slow connection": "سست کنکشن",
|
|
8426
|
+
"Your internet connection appears to be slow. Some audio may be delayed.": "آپ کا انٹرنیٹ کنکشن سست لگ رہا ہے۔ کچھ آڈیو میں تاخیر ہو سکتی ہے۔",
|
|
8206
8427
|
};
|
|
8207
8428
|
|
|
8208
8429
|
var LanguageCode = /* @__PURE__ */ ((LanguageCode2) => {
|
|
@@ -15433,6 +15654,8 @@ const initialState$1 = {
|
|
|
15433
15654
|
audioContext: null,
|
|
15434
15655
|
processor: null,
|
|
15435
15656
|
source: null,
|
|
15657
|
+
processorStream: null,
|
|
15658
|
+
processorSocket: null,
|
|
15436
15659
|
isServerReady: false,
|
|
15437
15660
|
uuid: "",
|
|
15438
15661
|
isActive: false,
|
|
@@ -15805,18 +16028,19 @@ const AudioRecorderApi = {
|
|
|
15805
16028
|
}
|
|
15806
16029
|
},
|
|
15807
16030
|
record: (socket, uuid, language) => {
|
|
15808
|
-
|
|
15809
|
-
|
|
15810
|
-
|
|
15811
|
-
|
|
15812
|
-
|
|
15813
|
-
|
|
15814
|
-
|
|
15815
|
-
|
|
15816
|
-
|
|
15817
|
-
|
|
15818
|
-
|
|
15819
|
-
}
|
|
16031
|
+
const config = JSON.stringify({
|
|
16032
|
+
uid: uuid,
|
|
16033
|
+
language,
|
|
16034
|
+
task: "transcribe",
|
|
16035
|
+
model: "medium",
|
|
16036
|
+
medical_practice: "medical",
|
|
16037
|
+
use_vad: true
|
|
16038
|
+
});
|
|
16039
|
+
if (socket.readyState === WebSocket.OPEN) {
|
|
16040
|
+
socket.send(config);
|
|
16041
|
+
return;
|
|
16042
|
+
}
|
|
16043
|
+
socket.addEventListener("open", () => socket.send(config), { once: true });
|
|
15820
16044
|
},
|
|
15821
16045
|
recordFinal: (socket) => {
|
|
15822
16046
|
socket.send(
|
|
@@ -15907,8 +16131,13 @@ const useWebSocketConnection = ({
|
|
|
15907
16131
|
currentSocketRef,
|
|
15908
16132
|
preconnectedSocketRef,
|
|
15909
16133
|
onConsumePreconnectedSocket,
|
|
15910
|
-
addSegments
|
|
16134
|
+
addSegments,
|
|
16135
|
+
onUnexpectedClose
|
|
15911
16136
|
}) => {
|
|
16137
|
+
const onUnexpectedCloseRef = React.useRef(onUnexpectedClose);
|
|
16138
|
+
React.useEffect(() => {
|
|
16139
|
+
onUnexpectedCloseRef.current = onUnexpectedClose;
|
|
16140
|
+
}, [onUnexpectedClose]);
|
|
15912
16141
|
const addSegmentsRef = React.useRef(addSegments);
|
|
15913
16142
|
React.useEffect(() => {
|
|
15914
16143
|
addSegmentsRef.current = addSegments;
|
|
@@ -16026,12 +16255,14 @@ const useWebSocketConnection = ({
|
|
|
16026
16255
|
);
|
|
16027
16256
|
return;
|
|
16028
16257
|
}
|
|
16029
|
-
|
|
16258
|
+
const isUnexpected = event.code !== 1e3 && event.code !== 1005;
|
|
16259
|
+
if (isUnexpected) {
|
|
16030
16260
|
if (event.code === 1006) {
|
|
16031
16261
|
logger.webSocketError(
|
|
16032
16262
|
"WSS URL is unreachable. Please verify your wssurl property points to a valid WebSocket endpoint."
|
|
16033
16263
|
);
|
|
16034
16264
|
}
|
|
16265
|
+
onUnexpectedCloseRef.current?.(event);
|
|
16035
16266
|
}
|
|
16036
16267
|
setState((prev) => ({
|
|
16037
16268
|
...prev,
|
|
@@ -16123,6 +16354,7 @@ const useWebSocketConnection = ({
|
|
|
16123
16354
|
logger.webSocketError(
|
|
16124
16355
|
`WebSocket closed unexpectedly (code: ${event.code})`
|
|
16125
16356
|
);
|
|
16357
|
+
onUnexpectedCloseRef.current?.(event);
|
|
16126
16358
|
}
|
|
16127
16359
|
setState((prev) => ({
|
|
16128
16360
|
...prev,
|
|
@@ -16182,34 +16414,72 @@ const useWebSocketConnection = ({
|
|
|
16182
16414
|
return { startRecording };
|
|
16183
16415
|
};
|
|
16184
16416
|
|
|
16185
|
-
const
|
|
16417
|
+
const INITIAL_RECONNECT_DELAY = 3e3;
|
|
16418
|
+
const MAX_RECONNECT_DELAY = 6e4;
|
|
16419
|
+
const MAX_RECONNECT_ATTEMPTS = 5;
|
|
16420
|
+
const NON_RETRYABLE_CLOSE_CODES = /* @__PURE__ */ new Set([1e3, 1008, 1011]);
|
|
16186
16421
|
const useWebSocketPreconnect = ({
|
|
16187
16422
|
wssUrl,
|
|
16188
|
-
enabled = true
|
|
16423
|
+
enabled = true,
|
|
16424
|
+
isRecordingActive = false
|
|
16189
16425
|
}) => {
|
|
16190
16426
|
const [socket, setSocket] = React.useState(null);
|
|
16191
16427
|
const [status, setStatus] = React.useState("disconnected");
|
|
16192
16428
|
const reconnectTimeoutRef = React.useRef(null);
|
|
16193
16429
|
const mountedRef = React.useRef(true);
|
|
16430
|
+
const reconnectAttemptsRef = React.useRef(0);
|
|
16431
|
+
const socketRef = React.useRef(null);
|
|
16432
|
+
const isRecordingActiveRef = React.useRef(isRecordingActive);
|
|
16433
|
+
React.useEffect(() => {
|
|
16434
|
+
isRecordingActiveRef.current = isRecordingActive;
|
|
16435
|
+
}, [isRecordingActive]);
|
|
16194
16436
|
const clearTimers = React.useCallback(() => {
|
|
16195
16437
|
if (reconnectTimeoutRef.current) {
|
|
16196
16438
|
clearTimeout(reconnectTimeoutRef.current);
|
|
16197
16439
|
reconnectTimeoutRef.current = null;
|
|
16198
16440
|
}
|
|
16199
16441
|
}, []);
|
|
16442
|
+
const getBackoffDelay = React.useCallback((attempt) => {
|
|
16443
|
+
const exponential = INITIAL_RECONNECT_DELAY * Math.pow(2, attempt);
|
|
16444
|
+
return Math.min(exponential, MAX_RECONNECT_DELAY);
|
|
16445
|
+
}, []);
|
|
16200
16446
|
const connect = React.useCallback(() => {
|
|
16201
16447
|
if (!wssUrl || !enabled || !mountedRef.current) return;
|
|
16202
16448
|
clearTimers();
|
|
16203
16449
|
setStatus("connecting");
|
|
16450
|
+
const scheduleRetry = (reason) => {
|
|
16451
|
+
if (!mountedRef.current || !enabled) return;
|
|
16452
|
+
if (isRecordingActiveRef.current) return;
|
|
16453
|
+
const attempt = reconnectAttemptsRef.current;
|
|
16454
|
+
if (attempt >= MAX_RECONNECT_ATTEMPTS) {
|
|
16455
|
+
logger.webSocketError(
|
|
16456
|
+
`WebSocket preconnect gave up after ${attempt} attempts (${reason})`
|
|
16457
|
+
);
|
|
16458
|
+
setStatus("paused");
|
|
16459
|
+
return;
|
|
16460
|
+
}
|
|
16461
|
+
const delay = getBackoffDelay(attempt);
|
|
16462
|
+
reconnectAttemptsRef.current = attempt + 1;
|
|
16463
|
+
logger.info(
|
|
16464
|
+
`WebSocket ${reason}, retry ${attempt + 1}/${MAX_RECONNECT_ATTEMPTS} in ${delay}ms`
|
|
16465
|
+
);
|
|
16466
|
+
reconnectTimeoutRef.current = setTimeout(() => {
|
|
16467
|
+
if (mountedRef.current && enabled && !isRecordingActiveRef.current) {
|
|
16468
|
+
connect();
|
|
16469
|
+
}
|
|
16470
|
+
}, delay);
|
|
16471
|
+
};
|
|
16204
16472
|
try {
|
|
16205
16473
|
const newSocket = new WebSocket(wssUrl);
|
|
16206
16474
|
newSocket.binaryType = "arraybuffer";
|
|
16475
|
+
socketRef.current = newSocket;
|
|
16207
16476
|
newSocket.onopen = () => {
|
|
16208
|
-
if (!mountedRef.current) {
|
|
16477
|
+
if (!mountedRef.current || socketRef.current !== newSocket) {
|
|
16209
16478
|
newSocket.close();
|
|
16210
16479
|
return;
|
|
16211
16480
|
}
|
|
16212
16481
|
logger.info("WebSocket pre-connected successfully");
|
|
16482
|
+
reconnectAttemptsRef.current = 0;
|
|
16213
16483
|
setSocket(newSocket);
|
|
16214
16484
|
setStatus("connected");
|
|
16215
16485
|
};
|
|
@@ -16218,61 +16488,56 @@ const useWebSocketPreconnect = ({
|
|
|
16218
16488
|
};
|
|
16219
16489
|
newSocket.onclose = (event) => {
|
|
16220
16490
|
if (!mountedRef.current) return;
|
|
16491
|
+
if (socketRef.current !== newSocket && socketRef.current !== null)
|
|
16492
|
+
return;
|
|
16221
16493
|
clearTimers();
|
|
16494
|
+
socketRef.current = null;
|
|
16222
16495
|
setSocket(null);
|
|
16223
16496
|
setStatus("disconnected");
|
|
16224
|
-
if (enabled)
|
|
16497
|
+
if (!enabled) return;
|
|
16498
|
+
if (NON_RETRYABLE_CLOSE_CODES.has(event.code)) {
|
|
16225
16499
|
logger.info(
|
|
16226
|
-
`WebSocket closed (code: ${event.code})
|
|
16500
|
+
`WebSocket closed cleanly (code: ${event.code}); pausing preconnect until next user action`
|
|
16227
16501
|
);
|
|
16228
|
-
|
|
16229
|
-
if (mountedRef.current && enabled) {
|
|
16230
|
-
connect();
|
|
16231
|
-
}
|
|
16232
|
-
}, RECONNECT_DELAY);
|
|
16502
|
+
return;
|
|
16233
16503
|
}
|
|
16504
|
+
scheduleRetry(`closed (code: ${event.code})`);
|
|
16234
16505
|
};
|
|
16235
16506
|
} catch (error) {
|
|
16236
16507
|
logger.webSocketError("Failed to create pre-connection:", error);
|
|
16237
16508
|
setStatus("disconnected");
|
|
16238
|
-
|
|
16239
|
-
reconnectTimeoutRef.current = setTimeout(() => {
|
|
16240
|
-
if (mountedRef.current && enabled) {
|
|
16241
|
-
connect();
|
|
16242
|
-
}
|
|
16243
|
-
}, RECONNECT_DELAY);
|
|
16244
|
-
}
|
|
16509
|
+
scheduleRetry("creation error");
|
|
16245
16510
|
}
|
|
16246
|
-
}, [wssUrl, enabled, clearTimers]);
|
|
16511
|
+
}, [wssUrl, enabled, clearTimers, getBackoffDelay]);
|
|
16247
16512
|
const reconnect = React.useCallback(() => {
|
|
16248
|
-
|
|
16249
|
-
|
|
16513
|
+
reconnectAttemptsRef.current = 0;
|
|
16514
|
+
if (socketRef.current) {
|
|
16515
|
+
socketRef.current.close(1e3, "Manual reconnect");
|
|
16516
|
+
socketRef.current = null;
|
|
16250
16517
|
}
|
|
16251
16518
|
connect();
|
|
16252
|
-
}, [
|
|
16519
|
+
}, [connect]);
|
|
16253
16520
|
const consumeSocket = React.useCallback(() => {
|
|
16254
16521
|
setSocket(null);
|
|
16255
16522
|
setStatus("disconnected");
|
|
16523
|
+
reconnectAttemptsRef.current = 0;
|
|
16256
16524
|
clearTimers();
|
|
16257
|
-
|
|
16258
|
-
|
|
16259
|
-
connect();
|
|
16260
|
-
}
|
|
16261
|
-
}, RECONNECT_DELAY);
|
|
16262
|
-
}, [enabled, connect, clearTimers]);
|
|
16525
|
+
socketRef.current = null;
|
|
16526
|
+
}, [clearTimers]);
|
|
16263
16527
|
React.useEffect(() => {
|
|
16264
16528
|
mountedRef.current = true;
|
|
16265
|
-
if (enabled && wssUrl) {
|
|
16529
|
+
if (enabled && wssUrl && !isRecordingActive) {
|
|
16266
16530
|
connect();
|
|
16267
16531
|
}
|
|
16268
16532
|
return () => {
|
|
16269
16533
|
mountedRef.current = false;
|
|
16270
16534
|
clearTimers();
|
|
16271
|
-
if (
|
|
16272
|
-
|
|
16535
|
+
if (socketRef.current) {
|
|
16536
|
+
socketRef.current.close(1e3, "Preconnect cleanup");
|
|
16537
|
+
socketRef.current = null;
|
|
16273
16538
|
}
|
|
16274
16539
|
};
|
|
16275
|
-
}, [enabled, wssUrl]);
|
|
16540
|
+
}, [enabled, wssUrl, isRecordingActive]);
|
|
16276
16541
|
return {
|
|
16277
16542
|
socket,
|
|
16278
16543
|
status,
|
|
@@ -16461,13 +16726,7 @@ var ToastVariation = /* @__PURE__ */ ((ToastVariation2) => {
|
|
|
16461
16726
|
ToastVariation2["danger"] = "danger";
|
|
16462
16727
|
return ToastVariation2;
|
|
16463
16728
|
})(ToastVariation || {});
|
|
16464
|
-
const
|
|
16465
|
-
title: "",
|
|
16466
|
-
message: "",
|
|
16467
|
-
visible: false,
|
|
16468
|
-
variation: "default" /* default */,
|
|
16469
|
-
duration: 3e3
|
|
16470
|
-
};
|
|
16729
|
+
const MAX_TOASTS = 3;
|
|
16471
16730
|
const showErrorToast = (setToastState, formatMessage) => {
|
|
16472
16731
|
setToastState({
|
|
16473
16732
|
variation: "danger" /* danger */,
|
|
@@ -16500,11 +16759,15 @@ const handleMicros = async (setState) => {
|
|
|
16500
16759
|
...prevState,
|
|
16501
16760
|
devices: mics.map(({ deviceId, label }) => ({ deviceId, label }))
|
|
16502
16761
|
}));
|
|
16503
|
-
if (mics.length
|
|
16504
|
-
|
|
16762
|
+
if (mics.length === 0) return;
|
|
16763
|
+
setState((prevState) => {
|
|
16764
|
+
const currentIsValid = !!prevState.selectedDevice && prevState.selectedDevice !== "no-permission" && prevState.selectedDevice !== "no-devices" && prevState.selectedDevice !== "error" && mics.some((m) => m.deviceId === prevState.selectedDevice);
|
|
16765
|
+
if (currentIsValid) return prevState;
|
|
16766
|
+
return {
|
|
16505
16767
|
...prevState,
|
|
16506
16768
|
selectedDevice: mics[0].deviceId
|
|
16507
|
-
}
|
|
16769
|
+
};
|
|
16770
|
+
});
|
|
16508
16771
|
};
|
|
16509
16772
|
const getMicros = async (setHasPermission, setOptions, setDevices, icon, setToastState, microText, notFoundText, errorText, toastText) => {
|
|
16510
16773
|
try {
|
|
@@ -16568,6 +16831,18 @@ const requestMicrophonePermission = async (permission, setState, action, setToas
|
|
|
16568
16831
|
}
|
|
16569
16832
|
} else action();
|
|
16570
16833
|
};
|
|
16834
|
+
const isNoMicrophoneError = (error) => {
|
|
16835
|
+
if (!(error instanceof DOMException)) return false;
|
|
16836
|
+
return error.name === "NotFoundError" || error.name === "OverconstrainedError" || error.name === "NotReadableError" || error.name === "AbortError";
|
|
16837
|
+
};
|
|
16838
|
+
const setNoMicrophoneToast = (setToastState, title, message) => {
|
|
16839
|
+
setToastState({
|
|
16840
|
+
variation: ToastVariation.danger,
|
|
16841
|
+
title,
|
|
16842
|
+
message,
|
|
16843
|
+
visible: true
|
|
16844
|
+
});
|
|
16845
|
+
};
|
|
16571
16846
|
const setDeniedPermissionToast = (setToastState, text) => {
|
|
16572
16847
|
setToastState({
|
|
16573
16848
|
variation: ToastVariation.danger,
|
|
@@ -16611,7 +16886,8 @@ const useRecordingActions = ({
|
|
|
16611
16886
|
appointmentData,
|
|
16612
16887
|
actions,
|
|
16613
16888
|
refs,
|
|
16614
|
-
toastText
|
|
16889
|
+
toastText,
|
|
16890
|
+
noMicToast
|
|
16615
16891
|
}) => {
|
|
16616
16892
|
const { stream, audioContext, animationFrameId, uuid, seconds } = recordingState;
|
|
16617
16893
|
const {
|
|
@@ -16788,9 +17064,18 @@ const useRecordingActions = ({
|
|
|
16788
17064
|
const newStream = await getMediaStream(selectedDevice);
|
|
16789
17065
|
setStream(newStream);
|
|
16790
17066
|
getMicrophones(newStream);
|
|
16791
|
-
} catch {
|
|
16792
|
-
|
|
16793
|
-
|
|
17067
|
+
} catch (error) {
|
|
17068
|
+
if (isNoMicrophoneError(error)) {
|
|
17069
|
+
setNoMicrophoneToast(
|
|
17070
|
+
setToastState,
|
|
17071
|
+
noMicToast.title,
|
|
17072
|
+
noMicToast.message
|
|
17073
|
+
);
|
|
17074
|
+
logger.audioError("No microphone available:", error);
|
|
17075
|
+
} else {
|
|
17076
|
+
setDeniedPermissionToast(setToastState, toastText);
|
|
17077
|
+
logger.audioError("Microphone access denied.", error);
|
|
17078
|
+
}
|
|
16794
17079
|
}
|
|
16795
17080
|
}
|
|
16796
17081
|
}, [
|
|
@@ -16801,6 +17086,7 @@ const useRecordingActions = ({
|
|
|
16801
17086
|
getMicrophones,
|
|
16802
17087
|
setToastState,
|
|
16803
17088
|
toastText,
|
|
17089
|
+
noMicToast,
|
|
16804
17090
|
setStream,
|
|
16805
17091
|
isStoppingRef,
|
|
16806
17092
|
prepareForNewRecording
|
|
@@ -16811,13 +17097,18 @@ const useRecordingActions = ({
|
|
|
16811
17097
|
};
|
|
16812
17098
|
};
|
|
16813
17099
|
|
|
17100
|
+
const SILENCE_THRESHOLD = 1e-4;
|
|
17101
|
+
const SILENCE_FRAMES_LIMIT = 30;
|
|
17102
|
+
const NO_SEND_WATCHDOG_MS = 8e3;
|
|
17103
|
+
const NO_SEND_WATCHDOG_CHECK_MS = 1e3;
|
|
16814
17104
|
const useAudioProcessor = ({
|
|
16815
17105
|
stream,
|
|
16816
17106
|
socket,
|
|
16817
17107
|
isServerReady,
|
|
16818
17108
|
enabled,
|
|
16819
17109
|
connectionLoading,
|
|
16820
|
-
setAudioContext
|
|
17110
|
+
setAudioContext,
|
|
17111
|
+
onDeviceLost
|
|
16821
17112
|
}) => {
|
|
16822
17113
|
const processorRef = React.useRef(null);
|
|
16823
17114
|
const sourceRef = React.useRef(null);
|
|
@@ -16826,9 +17117,16 @@ const useAudioProcessor = ({
|
|
|
16826
17117
|
React.useEffect(() => {
|
|
16827
17118
|
isServerReadyRef.current = isServerReady;
|
|
16828
17119
|
}, [isServerReady]);
|
|
17120
|
+
const onDeviceLostRef = React.useRef(onDeviceLost);
|
|
17121
|
+
React.useEffect(() => {
|
|
17122
|
+
onDeviceLostRef.current = onDeviceLost;
|
|
17123
|
+
}, [onDeviceLost]);
|
|
17124
|
+
const consecutiveSilentFramesRef = React.useRef(0);
|
|
17125
|
+
const deviceLostFiredRef = React.useRef(false);
|
|
17126
|
+
const lastSendAtRef = React.useRef(0);
|
|
16829
17127
|
React.useEffect(() => {
|
|
16830
17128
|
const session = getSessionState();
|
|
16831
|
-
if (session.processor && session.source && session.audioContext && session.
|
|
17129
|
+
if (session.processor && session.source && session.audioContext && session.processorStream === stream && session.processorSocket === socket) {
|
|
16832
17130
|
processorRef.current = session.processor;
|
|
16833
17131
|
sourceRef.current = session.source;
|
|
16834
17132
|
audioContextRef.current = session.audioContext;
|
|
@@ -16852,12 +17150,40 @@ const useAudioProcessor = ({
|
|
|
16852
17150
|
}
|
|
16853
17151
|
audioContextRef.current = null;
|
|
16854
17152
|
}
|
|
16855
|
-
updateSessionState({
|
|
17153
|
+
updateSessionState({
|
|
17154
|
+
processor: null,
|
|
17155
|
+
source: null,
|
|
17156
|
+
processorStream: null,
|
|
17157
|
+
processorSocket: null
|
|
17158
|
+
});
|
|
16856
17159
|
if (!stream || !enabled || connectionLoading) return;
|
|
17160
|
+
const audioTracks = stream.getAudioTracks();
|
|
17161
|
+
const handleTrackEnded = () => {
|
|
17162
|
+
if (deviceLostFiredRef.current) return;
|
|
17163
|
+
deviceLostFiredRef.current = true;
|
|
17164
|
+
logger.warn("Audio track ended — microphone disconnected");
|
|
17165
|
+
onDeviceLostRef.current?.();
|
|
17166
|
+
};
|
|
17167
|
+
const handleTrackMute = () => {
|
|
17168
|
+
logger.warn("Audio track muted — possible transient device glitch");
|
|
17169
|
+
};
|
|
17170
|
+
const handleTrackUnmute = () => {
|
|
17171
|
+
logger.info("Audio track unmuted — device recovered");
|
|
17172
|
+
consecutiveSilentFramesRef.current = 0;
|
|
17173
|
+
deviceLostFiredRef.current = false;
|
|
17174
|
+
};
|
|
16857
17175
|
try {
|
|
16858
17176
|
const audioContext = new AudioContext();
|
|
16859
17177
|
audioContextRef.current = audioContext;
|
|
16860
17178
|
setAudioContext(audioContext);
|
|
17179
|
+
if (audioContext.state === "suspended") {
|
|
17180
|
+
logger.warn(
|
|
17181
|
+
"AudioContext started suspended — calling resume(). This usually means the browser did not consider the current execution context a user gesture."
|
|
17182
|
+
);
|
|
17183
|
+
audioContext.resume().catch(
|
|
17184
|
+
(err) => logger.audioError("Failed to resume AudioContext:", err)
|
|
17185
|
+
);
|
|
17186
|
+
}
|
|
16861
17187
|
const source = audioContext.createMediaStreamSource(stream);
|
|
16862
17188
|
sourceRef.current = source;
|
|
16863
17189
|
const analyser = audioContext.createAnalyser();
|
|
@@ -16868,28 +17194,68 @@ const useAudioProcessor = ({
|
|
|
16868
17194
|
source.connect(analyser);
|
|
16869
17195
|
const processor = audioContext.createScriptProcessor(4096, 1, 1);
|
|
16870
17196
|
processorRef.current = processor;
|
|
17197
|
+
consecutiveSilentFramesRef.current = 0;
|
|
17198
|
+
deviceLostFiredRef.current = false;
|
|
17199
|
+
lastSendAtRef.current = Date.now();
|
|
16871
17200
|
processor.onaudioprocess = (event) => {
|
|
16872
17201
|
if (!isServerReadyRef.current || !socket) return;
|
|
17202
|
+
if (deviceLostFiredRef.current) return;
|
|
16873
17203
|
const input = event.inputBuffer.getChannelData(0);
|
|
17204
|
+
let isSilent = true;
|
|
17205
|
+
for (let i = 0; i < input.length; i++) {
|
|
17206
|
+
if (Math.abs(input[i]) > SILENCE_THRESHOLD) {
|
|
17207
|
+
isSilent = false;
|
|
17208
|
+
break;
|
|
17209
|
+
}
|
|
17210
|
+
}
|
|
17211
|
+
if (isSilent) {
|
|
17212
|
+
consecutiveSilentFramesRef.current++;
|
|
17213
|
+
if (consecutiveSilentFramesRef.current >= SILENCE_FRAMES_LIMIT && !deviceLostFiredRef.current) {
|
|
17214
|
+
deviceLostFiredRef.current = true;
|
|
17215
|
+
logger.warn(
|
|
17216
|
+
`Detected ${SILENCE_FRAMES_LIMIT} consecutive silent frames — microphone may be disconnected`
|
|
17217
|
+
);
|
|
17218
|
+
onDeviceLostRef.current?.();
|
|
17219
|
+
return;
|
|
17220
|
+
}
|
|
17221
|
+
} else {
|
|
17222
|
+
consecutiveSilentFramesRef.current = 0;
|
|
17223
|
+
}
|
|
16874
17224
|
if (socket.readyState === WebSocket.OPEN) {
|
|
16875
17225
|
const audioData16kHz = resampleTo16kHZ(
|
|
16876
17226
|
input,
|
|
16877
17227
|
audioContext.sampleRate
|
|
16878
17228
|
);
|
|
16879
17229
|
socket.send(audioData16kHz);
|
|
17230
|
+
lastSendAtRef.current = Date.now();
|
|
16880
17231
|
}
|
|
16881
17232
|
};
|
|
17233
|
+
audioTracks.forEach((t) => {
|
|
17234
|
+
t.addEventListener("ended", handleTrackEnded);
|
|
17235
|
+
t.addEventListener("mute", handleTrackMute);
|
|
17236
|
+
t.addEventListener("unmute", handleTrackUnmute);
|
|
17237
|
+
});
|
|
16882
17238
|
source.connect(processor);
|
|
16883
17239
|
processor.connect(audioContext.destination);
|
|
16884
17240
|
const gain = audioContext.createGain();
|
|
16885
17241
|
gain.gain.value = 1e-3;
|
|
16886
17242
|
analyser.connect(gain);
|
|
16887
17243
|
gain.connect(audioContext.destination);
|
|
16888
|
-
updateSessionState({
|
|
17244
|
+
updateSessionState({
|
|
17245
|
+
processor,
|
|
17246
|
+
source,
|
|
17247
|
+
processorStream: stream,
|
|
17248
|
+
processorSocket: socket
|
|
17249
|
+
});
|
|
16889
17250
|
} catch (error) {
|
|
16890
17251
|
logger.audioError("Error setting up audio context:", error);
|
|
16891
17252
|
}
|
|
16892
17253
|
return () => {
|
|
17254
|
+
audioTracks.forEach((t) => {
|
|
17255
|
+
t.removeEventListener("ended", handleTrackEnded);
|
|
17256
|
+
t.removeEventListener("mute", handleTrackMute);
|
|
17257
|
+
t.removeEventListener("unmute", handleTrackUnmute);
|
|
17258
|
+
});
|
|
16893
17259
|
const current = getSessionState();
|
|
16894
17260
|
if (current.processor === processorRef.current && current.source === sourceRef.current && current.isActive) {
|
|
16895
17261
|
return;
|
|
@@ -16902,9 +17268,31 @@ const useAudioProcessor = ({
|
|
|
16902
17268
|
sourceRef.current.disconnect();
|
|
16903
17269
|
sourceRef.current = null;
|
|
16904
17270
|
}
|
|
16905
|
-
updateSessionState({
|
|
17271
|
+
updateSessionState({
|
|
17272
|
+
processor: null,
|
|
17273
|
+
source: null,
|
|
17274
|
+
processorStream: null,
|
|
17275
|
+
processorSocket: null
|
|
17276
|
+
});
|
|
16906
17277
|
};
|
|
16907
17278
|
}, [stream, socket, enabled, connectionLoading, setAudioContext]);
|
|
17279
|
+
React.useEffect(() => {
|
|
17280
|
+
if (!enabled || connectionLoading || !socket || !isServerReady) return;
|
|
17281
|
+
lastSendAtRef.current = Date.now();
|
|
17282
|
+
const interval = setInterval(() => {
|
|
17283
|
+
if (deviceLostFiredRef.current) return;
|
|
17284
|
+
if (socket.readyState !== WebSocket.OPEN) return;
|
|
17285
|
+
const sinceLastSend = Date.now() - lastSendAtRef.current;
|
|
17286
|
+
if (sinceLastSend > NO_SEND_WATCHDOG_MS) {
|
|
17287
|
+
deviceLostFiredRef.current = true;
|
|
17288
|
+
logger.warn(
|
|
17289
|
+
`No audio sent to server for ${sinceLastSend}ms — microphone input appears stuck`
|
|
17290
|
+
);
|
|
17291
|
+
onDeviceLostRef.current?.();
|
|
17292
|
+
}
|
|
17293
|
+
}, NO_SEND_WATCHDOG_CHECK_MS);
|
|
17294
|
+
return () => clearInterval(interval);
|
|
17295
|
+
}, [enabled, connectionLoading, socket, isServerReady]);
|
|
16908
17296
|
const cleanup = React.useCallback(() => {
|
|
16909
17297
|
if (processorRef.current) {
|
|
16910
17298
|
processorRef.current.disconnect();
|
|
@@ -16914,7 +17302,12 @@ const useAudioProcessor = ({
|
|
|
16914
17302
|
sourceRef.current.disconnect();
|
|
16915
17303
|
sourceRef.current = null;
|
|
16916
17304
|
}
|
|
16917
|
-
updateSessionState({
|
|
17305
|
+
updateSessionState({
|
|
17306
|
+
processor: null,
|
|
17307
|
+
source: null,
|
|
17308
|
+
processorStream: null,
|
|
17309
|
+
processorSocket: null
|
|
17310
|
+
});
|
|
16918
17311
|
if (audioContextRef.current) {
|
|
16919
17312
|
try {
|
|
16920
17313
|
if (audioContextRef.current.state !== "closed") {
|
|
@@ -16949,6 +17342,19 @@ const useAudioRecording = (options = {}) => {
|
|
|
16949
17342
|
const toastText = formatMessage({
|
|
16950
17343
|
id: "Please enable the microphone or reset the permissions"
|
|
16951
17344
|
});
|
|
17345
|
+
const noMicToast = React.useMemo(
|
|
17346
|
+
() => ({
|
|
17347
|
+
title: formatMessage({
|
|
17348
|
+
id: "No microphone available",
|
|
17349
|
+
defaultMessage: "No microphone available"
|
|
17350
|
+
}),
|
|
17351
|
+
message: formatMessage({
|
|
17352
|
+
id: "Connect a microphone and try again.",
|
|
17353
|
+
defaultMessage: "Connect a microphone and try again."
|
|
17354
|
+
})
|
|
17355
|
+
}),
|
|
17356
|
+
[formatMessage]
|
|
17357
|
+
);
|
|
16952
17358
|
const isCurrentlyRecording = enabled && !connectionLoading;
|
|
16953
17359
|
const state = useAudioRecordingState(appointmentData, isCurrentlyRecording);
|
|
16954
17360
|
const {
|
|
@@ -16970,7 +17376,8 @@ const useAudioRecording = (options = {}) => {
|
|
|
16970
17376
|
]);
|
|
16971
17377
|
const { socket: preconnectedSocket, consumeSocket } = useWebSocketPreconnect({
|
|
16972
17378
|
wssUrl,
|
|
16973
|
-
enabled: !!wssUrl
|
|
17379
|
+
enabled: !!wssUrl && permission === "granted",
|
|
17380
|
+
isRecordingActive: isCurrentlyRecording
|
|
16974
17381
|
});
|
|
16975
17382
|
const preconnectedSocketRef = React.useRef(null);
|
|
16976
17383
|
React.useEffect(() => {
|
|
@@ -16986,6 +17393,10 @@ const useAudioRecording = (options = {}) => {
|
|
|
16986
17393
|
React.useEffect(() => {
|
|
16987
17394
|
segmentsRef.current = segments;
|
|
16988
17395
|
}, [segments]);
|
|
17396
|
+
const handleServerCloseRef = React.useRef(null);
|
|
17397
|
+
const handleUnexpectedClose = React.useCallback((event) => {
|
|
17398
|
+
handleServerCloseRef.current?.(event);
|
|
17399
|
+
}, []);
|
|
16989
17400
|
const { startRecording } = useWebSocketConnection({
|
|
16990
17401
|
wssUrl,
|
|
16991
17402
|
language,
|
|
@@ -16998,19 +17409,26 @@ const useAudioRecording = (options = {}) => {
|
|
|
16998
17409
|
currentSocketRef,
|
|
16999
17410
|
preconnectedSocketRef,
|
|
17000
17411
|
onConsumePreconnectedSocket: consumeSocket,
|
|
17001
|
-
addSegments
|
|
17412
|
+
addSegments,
|
|
17413
|
+
onUnexpectedClose: handleUnexpectedClose
|
|
17002
17414
|
});
|
|
17003
17415
|
const { cleanupPromise } = useAudioRecordingCleanup();
|
|
17416
|
+
const stopOnDeviceLostRef = React.useRef(null);
|
|
17417
|
+
const handleDeviceLost = React.useCallback(() => {
|
|
17418
|
+
stopOnDeviceLostRef.current?.();
|
|
17419
|
+
}, []);
|
|
17004
17420
|
const { cleanup: audioProcessorCleanup } = useAudioProcessor({
|
|
17005
17421
|
stream: state.stream,
|
|
17006
17422
|
socket: state.socket,
|
|
17007
17423
|
isServerReady: state.isServerReady,
|
|
17008
17424
|
enabled,
|
|
17009
17425
|
connectionLoading,
|
|
17010
|
-
setAudioContext: state.setAudioContext
|
|
17426
|
+
setAudioContext: state.setAudioContext,
|
|
17427
|
+
onDeviceLost: handleDeviceLost
|
|
17011
17428
|
});
|
|
17012
|
-
const { handleToggleRecording } = useRecordingActions({
|
|
17429
|
+
const { handleToggleRecording, stopCapture } = useRecordingActions({
|
|
17013
17430
|
recordingState: {
|
|
17431
|
+
socket: state.socket,
|
|
17014
17432
|
stream: state.stream,
|
|
17015
17433
|
audioContext: state.audioContext,
|
|
17016
17434
|
animationFrameId: state.animationFrameId,
|
|
@@ -17044,8 +17462,322 @@ const useAudioRecording = (options = {}) => {
|
|
|
17044
17462
|
currentSocketRef,
|
|
17045
17463
|
segmentsRef
|
|
17046
17464
|
},
|
|
17047
|
-
toastText
|
|
17465
|
+
toastText,
|
|
17466
|
+
noMicToast
|
|
17048
17467
|
});
|
|
17468
|
+
const micDisconnectedText = formatMessage({
|
|
17469
|
+
id: "Microphone disconnected",
|
|
17470
|
+
defaultMessage: "Microphone disconnected"
|
|
17471
|
+
});
|
|
17472
|
+
const micDisconnectedMessage = formatMessage({
|
|
17473
|
+
id: "The microphone was disconnected during recording",
|
|
17474
|
+
defaultMessage: "The microphone was disconnected during recording"
|
|
17475
|
+
});
|
|
17476
|
+
const micReconnectedText = formatMessage({
|
|
17477
|
+
id: "Microphone reconnected",
|
|
17478
|
+
defaultMessage: "Microphone reconnected"
|
|
17479
|
+
});
|
|
17480
|
+
const recordingInterruptedText = formatMessage({
|
|
17481
|
+
id: "Recording interrupted",
|
|
17482
|
+
defaultMessage: "Recording interrupted"
|
|
17483
|
+
});
|
|
17484
|
+
const recordingInterruptedMessage = formatMessage({
|
|
17485
|
+
id: "The server closed the session unexpectedly. Please start recording again.",
|
|
17486
|
+
defaultMessage: "The server closed the session unexpectedly. Please start recording again."
|
|
17487
|
+
});
|
|
17488
|
+
const micFallbackText = formatMessage({
|
|
17489
|
+
id: "Microphone changed",
|
|
17490
|
+
defaultMessage: "Microphone changed"
|
|
17491
|
+
});
|
|
17492
|
+
const micFallbackMessage = formatMessage({
|
|
17493
|
+
id: "Your selected microphone was unavailable. Recording continues with the default microphone.",
|
|
17494
|
+
defaultMessage: "Your selected microphone was unavailable. Recording continues with the default microphone."
|
|
17495
|
+
});
|
|
17496
|
+
React.useEffect(() => {
|
|
17497
|
+
handleServerCloseRef.current = (event) => {
|
|
17498
|
+
if (state.isStoppingRef.current) return;
|
|
17499
|
+
logger.warn(
|
|
17500
|
+
`Server closed WebSocket unexpectedly (code: ${event.code}) — stopping session`
|
|
17501
|
+
);
|
|
17502
|
+
stopCapture();
|
|
17503
|
+
setToastState({
|
|
17504
|
+
variation: ToastVariation.danger,
|
|
17505
|
+
title: recordingInterruptedText,
|
|
17506
|
+
message: recordingInterruptedMessage,
|
|
17507
|
+
visible: true,
|
|
17508
|
+
duration: 0
|
|
17509
|
+
});
|
|
17510
|
+
};
|
|
17511
|
+
}, [
|
|
17512
|
+
stopCapture,
|
|
17513
|
+
state.isStoppingRef,
|
|
17514
|
+
setToastState,
|
|
17515
|
+
recordingInterruptedText,
|
|
17516
|
+
recordingInterruptedMessage
|
|
17517
|
+
]);
|
|
17518
|
+
const selectedDeviceRef = React.useRef(selectedDevice);
|
|
17519
|
+
React.useEffect(() => {
|
|
17520
|
+
selectedDeviceRef.current = selectedDevice;
|
|
17521
|
+
}, [selectedDevice]);
|
|
17522
|
+
const lastRecoveryAtRef = React.useRef(0);
|
|
17523
|
+
const RECOVERY_LOOP_GUARD_MS = 1e4;
|
|
17524
|
+
const didFallbackRef = React.useRef(false);
|
|
17525
|
+
const prevIsRecordingRef = React.useRef(false);
|
|
17526
|
+
React.useEffect(() => {
|
|
17527
|
+
if (isCurrentlyRecording && !prevIsRecordingRef.current) {
|
|
17528
|
+
didFallbackRef.current = false;
|
|
17529
|
+
}
|
|
17530
|
+
prevIsRecordingRef.current = isCurrentlyRecording;
|
|
17531
|
+
}, [isCurrentlyRecording]);
|
|
17532
|
+
React.useEffect(() => {
|
|
17533
|
+
stopOnDeviceLostRef.current = async () => {
|
|
17534
|
+
if (state.isStoppingRef.current) return;
|
|
17535
|
+
if (Date.now() - lastRecoveryAtRef.current < RECOVERY_LOOP_GUARD_MS) {
|
|
17536
|
+
if (!didFallbackRef.current) {
|
|
17537
|
+
logger.warn(
|
|
17538
|
+
"Ghost device detected — attempting to switch to a different microphone before giving up"
|
|
17539
|
+
);
|
|
17540
|
+
try {
|
|
17541
|
+
const fallbackStream = await getMediaStream(null);
|
|
17542
|
+
if (state.isStoppingRef.current) {
|
|
17543
|
+
fallbackStream.getTracks().forEach((t) => t.stop());
|
|
17544
|
+
return;
|
|
17545
|
+
}
|
|
17546
|
+
const fallbackDeviceId = fallbackStream.getAudioTracks()[0]?.getSettings().deviceId;
|
|
17547
|
+
const currentStreamDeviceId = state.stream?.getAudioTracks()[0]?.getSettings().deviceId;
|
|
17548
|
+
if (fallbackDeviceId && fallbackDeviceId !== currentStreamDeviceId) {
|
|
17549
|
+
logger.info(
|
|
17550
|
+
`Switched to fallback microphone (${fallbackDeviceId}) after ghost on ${currentStreamDeviceId}`
|
|
17551
|
+
);
|
|
17552
|
+
didFallbackRef.current = true;
|
|
17553
|
+
lastRecoveryAtRef.current = Date.now();
|
|
17554
|
+
state.setStream(fallbackStream);
|
|
17555
|
+
setToastState({
|
|
17556
|
+
variation: ToastVariation.danger,
|
|
17557
|
+
title: micFallbackText,
|
|
17558
|
+
message: micFallbackMessage,
|
|
17559
|
+
visible: true,
|
|
17560
|
+
duration: 0
|
|
17561
|
+
});
|
|
17562
|
+
return;
|
|
17563
|
+
}
|
|
17564
|
+
fallbackStream.getTracks().forEach((t) => t.stop());
|
|
17565
|
+
logger.warn(
|
|
17566
|
+
"Fallback getMediaStream returned the same ghost device — no alternative available"
|
|
17567
|
+
);
|
|
17568
|
+
} catch (error) {
|
|
17569
|
+
logger.warn(
|
|
17570
|
+
"Fallback getMediaStream failed — no alternative available",
|
|
17571
|
+
error
|
|
17572
|
+
);
|
|
17573
|
+
}
|
|
17574
|
+
} else {
|
|
17575
|
+
logger.warn(
|
|
17576
|
+
"Ghost device detected on the fallback too — stopping recording"
|
|
17577
|
+
);
|
|
17578
|
+
}
|
|
17579
|
+
stopCapture();
|
|
17580
|
+
setToastState({
|
|
17581
|
+
variation: ToastVariation.danger,
|
|
17582
|
+
title: micDisconnectedText,
|
|
17583
|
+
message: micDisconnectedMessage,
|
|
17584
|
+
visible: true,
|
|
17585
|
+
duration: 0
|
|
17586
|
+
});
|
|
17587
|
+
return;
|
|
17588
|
+
}
|
|
17589
|
+
const currentSegments = segmentsRef.current;
|
|
17590
|
+
let lastPhrase = "";
|
|
17591
|
+
for (let i = currentSegments.length - 1; i >= 0; i--) {
|
|
17592
|
+
const texts = currentSegments[i].text;
|
|
17593
|
+
if (texts?.length) {
|
|
17594
|
+
const last = texts[texts.length - 1];
|
|
17595
|
+
if (last?.text) {
|
|
17596
|
+
lastPhrase = last.text.length > 60 ? last.text.substring(0, 60) + "…" : last.text;
|
|
17597
|
+
break;
|
|
17598
|
+
}
|
|
17599
|
+
}
|
|
17600
|
+
}
|
|
17601
|
+
const MAX_RETRIES = 3;
|
|
17602
|
+
const RETRY_DELAY = 2e3;
|
|
17603
|
+
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
17604
|
+
await sleep(RETRY_DELAY);
|
|
17605
|
+
if (state.isStoppingRef.current) return;
|
|
17606
|
+
try {
|
|
17607
|
+
const requestedDevice = selectedDeviceRef.current;
|
|
17608
|
+
const newStream = await getMediaStream(requestedDevice);
|
|
17609
|
+
if (state.isStoppingRef.current) {
|
|
17610
|
+
newStream.getTracks().forEach((t) => t.stop());
|
|
17611
|
+
return;
|
|
17612
|
+
}
|
|
17613
|
+
const actualDeviceId = newStream.getAudioTracks()[0]?.getSettings().deviceId;
|
|
17614
|
+
const usedFallback = !!requestedDevice && requestedDevice !== "no-permission" && requestedDevice !== "no-devices" && requestedDevice !== "error" && !!actualDeviceId && actualDeviceId !== requestedDevice;
|
|
17615
|
+
if (usedFallback) {
|
|
17616
|
+
logger.warn(
|
|
17617
|
+
`Selected microphone (${requestedDevice}) unavailable — recording continues with fallback device (${actualDeviceId})`
|
|
17618
|
+
);
|
|
17619
|
+
} else {
|
|
17620
|
+
logger.info(`Microphone recovered after ${attempt + 1} attempt(s)`);
|
|
17621
|
+
}
|
|
17622
|
+
lastRecoveryAtRef.current = Date.now();
|
|
17623
|
+
state.setStream(newStream);
|
|
17624
|
+
if (usedFallback) {
|
|
17625
|
+
setToastState({
|
|
17626
|
+
variation: ToastVariation.danger,
|
|
17627
|
+
title: micFallbackText,
|
|
17628
|
+
message: micFallbackMessage,
|
|
17629
|
+
visible: true,
|
|
17630
|
+
duration: 0
|
|
17631
|
+
});
|
|
17632
|
+
}
|
|
17633
|
+
const reconnectedMessage = lastPhrase ? formatMessage(
|
|
17634
|
+
{
|
|
17635
|
+
id: 'The microphone was briefly disconnected. Part of the recording after "{lastPhrase}" may have been lost.',
|
|
17636
|
+
defaultMessage: 'The microphone was briefly disconnected. Part of the recording after "{lastPhrase}" may have been lost.'
|
|
17637
|
+
},
|
|
17638
|
+
{ lastPhrase }
|
|
17639
|
+
) : formatMessage({
|
|
17640
|
+
id: "The microphone was briefly disconnected. Part of the recording may have been lost.",
|
|
17641
|
+
defaultMessage: "The microphone was briefly disconnected. Part of the recording may have been lost."
|
|
17642
|
+
});
|
|
17643
|
+
setToastState({
|
|
17644
|
+
variation: ToastVariation.default,
|
|
17645
|
+
title: micReconnectedText,
|
|
17646
|
+
message: reconnectedMessage,
|
|
17647
|
+
visible: true,
|
|
17648
|
+
duration: 0
|
|
17649
|
+
});
|
|
17650
|
+
return;
|
|
17651
|
+
} catch {
|
|
17652
|
+
logger.debug(
|
|
17653
|
+
`Microphone recovery attempt ${attempt + 1}/${MAX_RETRIES} failed`
|
|
17654
|
+
);
|
|
17655
|
+
}
|
|
17656
|
+
}
|
|
17657
|
+
if (state.isStoppingRef.current) return;
|
|
17658
|
+
stopCapture();
|
|
17659
|
+
setToastState({
|
|
17660
|
+
variation: ToastVariation.danger,
|
|
17661
|
+
title: micDisconnectedText,
|
|
17662
|
+
message: micDisconnectedMessage,
|
|
17663
|
+
visible: true,
|
|
17664
|
+
duration: 0
|
|
17665
|
+
});
|
|
17666
|
+
};
|
|
17667
|
+
}, [
|
|
17668
|
+
setToastState,
|
|
17669
|
+
micDisconnectedText,
|
|
17670
|
+
micDisconnectedMessage,
|
|
17671
|
+
micReconnectedText,
|
|
17672
|
+
micFallbackText,
|
|
17673
|
+
micFallbackMessage,
|
|
17674
|
+
formatMessage,
|
|
17675
|
+
segmentsRef,
|
|
17676
|
+
state.isStoppingRef,
|
|
17677
|
+
state.setStream,
|
|
17678
|
+
state.stream,
|
|
17679
|
+
stopCapture
|
|
17680
|
+
]);
|
|
17681
|
+
const connectionLostText = formatMessage({
|
|
17682
|
+
id: "Connection lost",
|
|
17683
|
+
defaultMessage: "Connection lost"
|
|
17684
|
+
});
|
|
17685
|
+
const connectionLostMessage = formatMessage({
|
|
17686
|
+
id: "Internet connection was lost during recording. Audio may not reach the server until the connection is restored.",
|
|
17687
|
+
defaultMessage: "Internet connection was lost during recording. Audio may not reach the server until the connection is restored."
|
|
17688
|
+
});
|
|
17689
|
+
const connectionRestoredText = formatMessage({
|
|
17690
|
+
id: "Connection restored",
|
|
17691
|
+
defaultMessage: "Connection restored"
|
|
17692
|
+
});
|
|
17693
|
+
const connectionRestoredMessage = formatMessage({
|
|
17694
|
+
id: "Internet connection has been restored. Recording continues normally.",
|
|
17695
|
+
defaultMessage: "Internet connection has been restored. Recording continues normally."
|
|
17696
|
+
});
|
|
17697
|
+
const slowConnectionText = formatMessage({
|
|
17698
|
+
id: "Slow connection",
|
|
17699
|
+
defaultMessage: "Slow connection"
|
|
17700
|
+
});
|
|
17701
|
+
const slowConnectionMessage = formatMessage({
|
|
17702
|
+
id: "Your internet connection appears to be slow. Some audio may be delayed.",
|
|
17703
|
+
defaultMessage: "Your internet connection appears to be slow. Some audio may be delayed."
|
|
17704
|
+
});
|
|
17705
|
+
React.useEffect(() => {
|
|
17706
|
+
if (!isCurrentlyRecording) return;
|
|
17707
|
+
const handleOffline = () => {
|
|
17708
|
+
logger.warn("Network offline detected during recording");
|
|
17709
|
+
setToastState({
|
|
17710
|
+
variation: ToastVariation.danger,
|
|
17711
|
+
title: connectionLostText,
|
|
17712
|
+
message: connectionLostMessage,
|
|
17713
|
+
visible: true,
|
|
17714
|
+
duration: 0
|
|
17715
|
+
});
|
|
17716
|
+
};
|
|
17717
|
+
const handleOnline = () => {
|
|
17718
|
+
logger.info("Network back online during recording");
|
|
17719
|
+
setToastState({
|
|
17720
|
+
variation: ToastVariation.default,
|
|
17721
|
+
title: connectionRestoredText,
|
|
17722
|
+
message: connectionRestoredMessage,
|
|
17723
|
+
visible: true,
|
|
17724
|
+
duration: 0
|
|
17725
|
+
});
|
|
17726
|
+
};
|
|
17727
|
+
window.addEventListener("offline", handleOffline);
|
|
17728
|
+
window.addEventListener("online", handleOnline);
|
|
17729
|
+
return () => {
|
|
17730
|
+
window.removeEventListener("offline", handleOffline);
|
|
17731
|
+
window.removeEventListener("online", handleOnline);
|
|
17732
|
+
};
|
|
17733
|
+
}, [
|
|
17734
|
+
isCurrentlyRecording,
|
|
17735
|
+
setToastState,
|
|
17736
|
+
connectionLostText,
|
|
17737
|
+
connectionLostMessage,
|
|
17738
|
+
connectionRestoredText,
|
|
17739
|
+
connectionRestoredMessage
|
|
17740
|
+
]);
|
|
17741
|
+
React.useEffect(() => {
|
|
17742
|
+
if (!isCurrentlyRecording || !state.socket) return;
|
|
17743
|
+
const GROWING_TICKS_LIMIT = 5;
|
|
17744
|
+
const MIN_BUFFER = 5e3;
|
|
17745
|
+
let prevBuffered = 0;
|
|
17746
|
+
let growingTicks = 0;
|
|
17747
|
+
let warned = false;
|
|
17748
|
+
const interval = setInterval(() => {
|
|
17749
|
+
if (!state.socket || state.socket.readyState !== WebSocket.OPEN) return;
|
|
17750
|
+
if (!navigator.onLine) return;
|
|
17751
|
+
const current = state.socket.bufferedAmount;
|
|
17752
|
+
if (current > prevBuffered && current > MIN_BUFFER) {
|
|
17753
|
+
growingTicks++;
|
|
17754
|
+
if (growingTicks >= GROWING_TICKS_LIMIT && !warned) {
|
|
17755
|
+
warned = true;
|
|
17756
|
+
logger.warn(
|
|
17757
|
+
`WebSocket buffer growing for ${growingTicks}s (${current} bytes) — slow connection`
|
|
17758
|
+
);
|
|
17759
|
+
setToastState({
|
|
17760
|
+
variation: ToastVariation.danger,
|
|
17761
|
+
title: slowConnectionText,
|
|
17762
|
+
message: slowConnectionMessage,
|
|
17763
|
+
visible: true,
|
|
17764
|
+
duration: 5e3
|
|
17765
|
+
});
|
|
17766
|
+
}
|
|
17767
|
+
} else {
|
|
17768
|
+
growingTicks = 0;
|
|
17769
|
+
warned = false;
|
|
17770
|
+
}
|
|
17771
|
+
prevBuffered = current;
|
|
17772
|
+
}, 1e3);
|
|
17773
|
+
return () => clearInterval(interval);
|
|
17774
|
+
}, [
|
|
17775
|
+
isCurrentlyRecording,
|
|
17776
|
+
state.socket,
|
|
17777
|
+
setToastState,
|
|
17778
|
+
slowConnectionText,
|
|
17779
|
+
slowConnectionMessage
|
|
17780
|
+
]);
|
|
17049
17781
|
const isDisabled = disabled || connectionLoading || chatMicrophoneActive;
|
|
17050
17782
|
return {
|
|
17051
17783
|
stream: state.stream,
|
|
@@ -26478,7 +27210,7 @@ class PromptCache {
|
|
|
26478
27210
|
const promptCacheSingleton = new PromptCache();
|
|
26479
27211
|
|
|
26480
27212
|
// Update using pnpm bump-version
|
|
26481
|
-
const __version__ = "0.5.
|
|
27213
|
+
const __version__ = "0.5.19";
|
|
26482
27214
|
|
|
26483
27215
|
// Inlined from https://github.com/flexdinesh/browser-or-node
|
|
26484
27216
|
let globalEnv;
|
|
@@ -29407,6 +30139,24 @@ class Client {
|
|
|
29407
30139
|
}
|
|
29408
30140
|
return outputs;
|
|
29409
30141
|
}
|
|
30142
|
+
/**
|
|
30143
|
+
* Filter content from new_token events to prevent streaming LLM output
|
|
30144
|
+
* from being uploaded via events.
|
|
30145
|
+
*/
|
|
30146
|
+
_filterNewTokenEvents(events) {
|
|
30147
|
+
if (!events || events.length === 0) {
|
|
30148
|
+
return events;
|
|
30149
|
+
}
|
|
30150
|
+
return events.map((event) => {
|
|
30151
|
+
if (event.name === "new_token") {
|
|
30152
|
+
// Remove the kwargs containing the token data
|
|
30153
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
30154
|
+
const { kwargs: _, ...rest } = event;
|
|
30155
|
+
return rest;
|
|
30156
|
+
}
|
|
30157
|
+
return event;
|
|
30158
|
+
});
|
|
30159
|
+
}
|
|
29410
30160
|
async prepareRunCreateOrUpdateInputs(run) {
|
|
29411
30161
|
const runParams = { ...run };
|
|
29412
30162
|
if (runParams.inputs !== undefined) {
|
|
@@ -29415,6 +30165,9 @@ class Client {
|
|
|
29415
30165
|
if (runParams.outputs !== undefined) {
|
|
29416
30166
|
runParams.outputs = await this.processOutputs(runParams.outputs);
|
|
29417
30167
|
}
|
|
30168
|
+
if (runParams.events !== undefined) {
|
|
30169
|
+
runParams.events = this._filterNewTokenEvents(runParams.events);
|
|
30170
|
+
}
|
|
29418
30171
|
return runParams;
|
|
29419
30172
|
}
|
|
29420
30173
|
async _getResponse(path, queryParams) {
|
|
@@ -30259,6 +31012,9 @@ class Client {
|
|
|
30259
31012
|
if (run.outputs) {
|
|
30260
31013
|
run.outputs = await this.processOutputs(run.outputs);
|
|
30261
31014
|
}
|
|
31015
|
+
if (run.events) {
|
|
31016
|
+
run.events = this._filterNewTokenEvents(run.events);
|
|
31017
|
+
}
|
|
30262
31018
|
// TODO: Untangle types
|
|
30263
31019
|
const data = { ...run, id: runId };
|
|
30264
31020
|
if (!this._filterForSampling([data], true).length) {
|
|
@@ -141426,8 +142182,21 @@ const MicrophoneButton = ({
|
|
|
141426
142182
|
getMicrophones(newStream);
|
|
141427
142183
|
} catch (error) {
|
|
141428
142184
|
logger.audioError("Microphone error:", error);
|
|
141429
|
-
|
|
141430
|
-
|
|
142185
|
+
if (isNoMicrophoneError(error)) {
|
|
142186
|
+
setNoMicrophoneToast(
|
|
142187
|
+
setToastState,
|
|
142188
|
+
formatMessage({
|
|
142189
|
+
id: "No microphone available",
|
|
142190
|
+
defaultMessage: "No microphone available"
|
|
142191
|
+
}),
|
|
142192
|
+
formatMessage({
|
|
142193
|
+
id: "Connect a microphone and try again.",
|
|
142194
|
+
defaultMessage: "Connect a microphone and try again."
|
|
142195
|
+
})
|
|
142196
|
+
);
|
|
142197
|
+
} else {
|
|
142198
|
+
setDeniedPermissionToast(setToastState, toastText);
|
|
142199
|
+
}
|
|
141431
142200
|
}
|
|
141432
142201
|
}
|
|
141433
142202
|
};
|
|
@@ -142910,30 +143679,52 @@ const Chat$1 = () => {
|
|
|
142910
143679
|
return /* @__PURE__ */ jsx$2(ChatView, {});
|
|
142911
143680
|
};
|
|
142912
143681
|
|
|
142913
|
-
const
|
|
142914
|
-
const { message, visible, setToastState, title, variation, duration } = useToastContext();
|
|
143682
|
+
const ToastItem = ({ toast, id, removeToast }) => {
|
|
142915
143683
|
const [show, setShow] = React.useState(false);
|
|
143684
|
+
const dismiss = React.useCallback(() => {
|
|
143685
|
+
setShow(false);
|
|
143686
|
+
setTimeout(() => removeToast(id), 300);
|
|
143687
|
+
}, [removeToast, id]);
|
|
142916
143688
|
React.useEffect(() => {
|
|
142917
|
-
|
|
142918
|
-
|
|
142919
|
-
const
|
|
142920
|
-
|
|
142921
|
-
|
|
142922
|
-
|
|
142923
|
-
|
|
143689
|
+
const showTimer = setTimeout(() => setShow(true), 10);
|
|
143690
|
+
if (toast.duration && toast.duration > 0) {
|
|
143691
|
+
const dismissTimer = setTimeout(dismiss, toast.duration);
|
|
143692
|
+
return () => {
|
|
143693
|
+
clearTimeout(showTimer);
|
|
143694
|
+
clearTimeout(dismissTimer);
|
|
143695
|
+
};
|
|
142924
143696
|
}
|
|
142925
|
-
|
|
142926
|
-
|
|
143697
|
+
return () => clearTimeout(showTimer);
|
|
143698
|
+
}, [toast.duration, dismiss]);
|
|
143699
|
+
const isPersistent = toast.duration === 0;
|
|
143700
|
+
return /* @__PURE__ */ jsxs(
|
|
142927
143701
|
"div",
|
|
142928
143702
|
{
|
|
142929
|
-
|
|
142930
|
-
|
|
142931
|
-
|
|
142932
|
-
/* @__PURE__ */
|
|
142933
|
-
|
|
143703
|
+
role: "alert",
|
|
143704
|
+
className: `omniscribe_toast-item ${toast.variation === ToastVariation.danger ? "omniscribe_toast-item-danger" : "omniscribe_toast-item-black"} ${show ? "omniscribe_toast-item-show" : "omniscribe_toast-item-hide"}`,
|
|
143705
|
+
children: [
|
|
143706
|
+
/* @__PURE__ */ jsxs("div", { className: "omniscribe_toast-subcontainer", children: [
|
|
143707
|
+
/* @__PURE__ */ jsx$2("span", { className: "omniscribe_toast-title", children: toast.title }),
|
|
143708
|
+
/* @__PURE__ */ jsx$2("span", { className: "omniscribe_toast-msg", children: toast.message })
|
|
143709
|
+
] }),
|
|
143710
|
+
isPersistent && /* @__PURE__ */ jsx$2(
|
|
143711
|
+
"button",
|
|
143712
|
+
{
|
|
143713
|
+
className: "omniscribe_toast-close",
|
|
143714
|
+
onClick: dismiss,
|
|
143715
|
+
"aria-label": "Close",
|
|
143716
|
+
children: "✕"
|
|
143717
|
+
}
|
|
143718
|
+
)
|
|
143719
|
+
]
|
|
142934
143720
|
}
|
|
142935
143721
|
);
|
|
142936
143722
|
};
|
|
143723
|
+
const Toast = () => {
|
|
143724
|
+
const { toasts, removeToast } = useToastContext();
|
|
143725
|
+
if (toasts.length === 0) return null;
|
|
143726
|
+
return /* @__PURE__ */ jsx$2("div", { className: "omniscribe_toast-stack", "aria-live": "polite", children: toasts.map((t) => /* @__PURE__ */ jsx$2(ToastItem, { toast: t, id: t.id, removeToast }, t.id)) });
|
|
143727
|
+
};
|
|
142937
143728
|
|
|
142938
143729
|
const ArrowIcon = ({
|
|
142939
143730
|
className,
|
|
@@ -145259,7 +146050,6 @@ const AppSkeleton = () => {
|
|
|
145259
146050
|
const WIDTH = "650px";
|
|
145260
146051
|
const HEIGHT = "665px";
|
|
145261
146052
|
const App = () => {
|
|
145262
|
-
const toast = useToastContext();
|
|
145263
146053
|
const { isLoading: isSettingsLoading } = useSettingsContext();
|
|
145264
146054
|
const [isChat, setIsChat] = React.useState(true);
|
|
145265
146055
|
const [showConfig, setShowConfig] = React.useState(false);
|
|
@@ -145297,47 +146087,72 @@ const App = () => {
|
|
|
145297
146087
|
}
|
|
145298
146088
|
),
|
|
145299
146089
|
renderContent(),
|
|
145300
|
-
|
|
146090
|
+
/* @__PURE__ */ jsx$2(Toast, {})
|
|
145301
146091
|
] }) });
|
|
145302
146092
|
};
|
|
145303
146093
|
|
|
146094
|
+
let nextId = 0;
|
|
145304
146095
|
const ToastProvider = ({
|
|
145305
146096
|
toast,
|
|
145306
146097
|
children
|
|
145307
146098
|
}) => {
|
|
145308
|
-
const [
|
|
145309
|
-
|
|
145310
|
-
|
|
145311
|
-
|
|
145312
|
-
|
|
145313
|
-
|
|
145314
|
-
|
|
146099
|
+
const [toasts, setToasts] = React.useState([]);
|
|
146100
|
+
const addToast = React.useCallback((t) => {
|
|
146101
|
+
if (!t.visible) return;
|
|
146102
|
+
setToasts((prev) => {
|
|
146103
|
+
const isDupe = prev.some(
|
|
146104
|
+
(existing) => existing.title === t.title && existing.message === t.message
|
|
146105
|
+
);
|
|
146106
|
+
if (isDupe && t.duration !== 0) {
|
|
146107
|
+
return prev;
|
|
146108
|
+
}
|
|
146109
|
+
const base = isDupe ? prev.filter(
|
|
146110
|
+
(existing) => !(existing.title === t.title && existing.message === t.message)
|
|
146111
|
+
) : prev;
|
|
146112
|
+
const id = String(++nextId);
|
|
146113
|
+
const next = [...base, { duration: 3e3, ...t, id }];
|
|
146114
|
+
return next.length > MAX_TOASTS ? next.slice(-MAX_TOASTS) : next;
|
|
146115
|
+
});
|
|
146116
|
+
}, []);
|
|
146117
|
+
const removeToast = React.useCallback((id) => {
|
|
146118
|
+
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
146119
|
+
}, []);
|
|
146120
|
+
const setToastState = React.useCallback(
|
|
146121
|
+
(action) => {
|
|
146122
|
+
if (action.visible) {
|
|
146123
|
+
addToast(action);
|
|
146124
|
+
}
|
|
146125
|
+
},
|
|
146126
|
+
[addToast]
|
|
146127
|
+
);
|
|
145315
146128
|
React.useEffect(() => {
|
|
145316
146129
|
if (toast) {
|
|
145317
|
-
|
|
145318
|
-
|
|
145319
|
-
|
|
145320
|
-
|
|
145321
|
-
|
|
145322
|
-
|
|
145323
|
-
|
|
145324
|
-
|
|
145325
|
-
|
|
145326
|
-
|
|
145327
|
-
|
|
145328
|
-
|
|
145329
|
-
|
|
145330
|
-
|
|
145331
|
-
visible,
|
|
145332
|
-
title,
|
|
145333
|
-
message,
|
|
145334
|
-
variation,
|
|
145335
|
-
duration,
|
|
145336
|
-
setToastState
|
|
145337
|
-
},
|
|
145338
|
-
children
|
|
146130
|
+
try {
|
|
146131
|
+
const parsed = typeof toast === "string" ? JSON.parse(toast) : toast;
|
|
146132
|
+
if (parsed.visible) {
|
|
146133
|
+
addToast({
|
|
146134
|
+
title: parsed.title ?? "",
|
|
146135
|
+
message: parsed.message ?? "",
|
|
146136
|
+
visible: true,
|
|
146137
|
+
variation: parsed.variation ?? ToastVariation.default,
|
|
146138
|
+
duration: parsed.duration ?? 3e3
|
|
146139
|
+
});
|
|
146140
|
+
}
|
|
146141
|
+
} catch {
|
|
146142
|
+
logger.warn("ToastProvider: invalid JSON in toast prop");
|
|
146143
|
+
}
|
|
145339
146144
|
}
|
|
146145
|
+
}, [toast, addToast]);
|
|
146146
|
+
const contextValue = React.useMemo(
|
|
146147
|
+
() => ({
|
|
146148
|
+
toasts,
|
|
146149
|
+
addToast,
|
|
146150
|
+
removeToast,
|
|
146151
|
+
setToastState
|
|
146152
|
+
}),
|
|
146153
|
+
[toasts, addToast, removeToast, setToastState]
|
|
145340
146154
|
);
|
|
146155
|
+
return /* @__PURE__ */ jsx$2(ToastContext.Provider, { value: contextValue, children });
|
|
145341
146156
|
};
|
|
145342
146157
|
|
|
145343
146158
|
const TranscriptorProvider = ({
|
|
@@ -146277,6 +147092,16 @@ function ProcessingThreadsProvider({
|
|
|
146277
147092
|
return /* @__PURE__ */ jsx$2(ProcessingThreadsContext.Provider, { value, children });
|
|
146278
147093
|
}
|
|
146279
147094
|
|
|
147095
|
+
const appendClientVersion = (url) => {
|
|
147096
|
+
if (!url) return url;
|
|
147097
|
+
try {
|
|
147098
|
+
const parsed = new URL(url);
|
|
147099
|
+
parsed.searchParams.set("client_version", version$2);
|
|
147100
|
+
return parsed.toString();
|
|
147101
|
+
} catch {
|
|
147102
|
+
return url;
|
|
147103
|
+
}
|
|
147104
|
+
};
|
|
146280
147105
|
const ApiConfigProvider = ({
|
|
146281
147106
|
children,
|
|
146282
147107
|
clientBaseUrl,
|
|
@@ -146288,7 +147113,7 @@ const ApiConfigProvider = ({
|
|
|
146288
147113
|
}) => {
|
|
146289
147114
|
const [{ baseUrl, langGraphBaseUrl, apiKey, wssUrl }, setConfig] = React.useState({
|
|
146290
147115
|
baseUrl: clientBaseUrl,
|
|
146291
|
-
wssUrl: clientWssUrl,
|
|
147116
|
+
wssUrl: appendClientVersion(clientWssUrl),
|
|
146292
147117
|
langGraphBaseUrl: clientBaseUrl + "/lang-graph/",
|
|
146293
147118
|
apiKey: clientApiKey
|
|
146294
147119
|
});
|
|
@@ -146299,7 +147124,7 @@ const ApiConfigProvider = ({
|
|
|
146299
147124
|
if (clientBaseUrl && clientApiKey) {
|
|
146300
147125
|
setConfig({
|
|
146301
147126
|
baseUrl: clientBaseUrl,
|
|
146302
|
-
wssUrl: clientWssUrl,
|
|
147127
|
+
wssUrl: appendClientVersion(clientWssUrl),
|
|
146303
147128
|
langGraphBaseUrl: clientBaseUrl + "/lang-graph/",
|
|
146304
147129
|
apiKey: clientApiKey
|
|
146305
147130
|
});
|