@davi-ai/retorik-framework 4.0.3 → 5.0.0

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.
Files changed (84) hide show
  1. package/README.md +13 -0
  2. package/dist/{AttachmentDetail.637ad44f.js → AttachmentDetail.3f9c113d.js} +15 -6
  3. package/dist/AttachmentDetail.3f9c113d.js.map +1 -0
  4. package/dist/{AttachmentDetail.83788045.js → AttachmentDetail.57c5579a.js} +15 -6
  5. package/dist/AttachmentDetail.57c5579a.js.map +1 -0
  6. package/dist/{CustomView.bf84bdf3.js → CustomView.6b96f53f.js} +8 -4
  7. package/dist/CustomView.6b96f53f.js.map +1 -0
  8. package/dist/{CustomView.9930c671.js → CustomView.b32a608f.js} +8 -4
  9. package/dist/CustomView.b32a608f.js.map +1 -0
  10. package/dist/{Emergency.1e63c85f.js → Emergency.43605d14.js} +16 -7
  11. package/dist/Emergency.43605d14.js.map +1 -0
  12. package/dist/{Emergency.89b4d9ed.js → Emergency.f1287bd5.js} +16 -7
  13. package/dist/Emergency.f1287bd5.js.map +1 -0
  14. package/dist/FullScreenImage.17df27bf.js.map +1 -1
  15. package/dist/FullScreenImage.99e19e10.js.map +1 -1
  16. package/dist/{HistoryList.3b4b1ffb.js → HistoryList.c19556a7.js} +8 -2
  17. package/dist/HistoryList.c19556a7.js.map +1 -0
  18. package/dist/{HistoryList.e5c01f21.js → HistoryList.e7262d62.js} +8 -2
  19. package/dist/HistoryList.e7262d62.js.map +1 -0
  20. package/dist/{LanguageChoice.1d866cfa.js → LanguageChoice.54fae1dc.js} +19 -8
  21. package/dist/LanguageChoice.54fae1dc.js.map +1 -0
  22. package/dist/{LanguageChoice.cce361a3.js → LanguageChoice.6e8b74f6.js} +19 -8
  23. package/dist/LanguageChoice.6e8b74f6.js.map +1 -0
  24. package/dist/LittleWeatherContainer.7e41105e.js.map +1 -1
  25. package/dist/LittleWeatherContainer.ee087e22.js.map +1 -1
  26. package/dist/{MapContainer.14c28128.js → MapContainer.25c8f4b4.js} +20 -5
  27. package/dist/MapContainer.25c8f4b4.js.map +1 -0
  28. package/dist/{MapContainer.f22ad81f.js → MapContainer.d00ab5b2.js} +20 -5
  29. package/dist/MapContainer.d00ab5b2.js.map +1 -0
  30. package/dist/{NewsContainer.c0a24775.js → NewsContainer.a39630c3.js} +33 -26
  31. package/dist/NewsContainer.a39630c3.js.map +1 -0
  32. package/dist/{NewsContainer.c3331d80.js → NewsContainer.ec15c3bb.js} +33 -26
  33. package/dist/NewsContainer.ec15c3bb.js.map +1 -0
  34. package/dist/PrintingPreview.375e62b0.js.map +1 -1
  35. package/dist/PrintingPreview.c0ca7706.js.map +1 -1
  36. package/dist/RecognitionManager.c58b8a3d.js +298 -0
  37. package/dist/RecognitionManager.c58b8a3d.js.map +1 -0
  38. package/dist/RecognitionManager.cdfb39fc.js +314 -0
  39. package/dist/RecognitionManager.cdfb39fc.js.map +1 -0
  40. package/dist/SpiritEngineWrapper.21ea10d4.js.map +1 -1
  41. package/dist/SpiritEngineWrapper.39627300.js.map +1 -1
  42. package/dist/SynthesisPonyfillManager.10888d6d.js +888 -0
  43. package/dist/SynthesisPonyfillManager.10888d6d.js.map +1 -0
  44. package/dist/SynthesisPonyfillManager.f9f9a915.js +920 -0
  45. package/dist/SynthesisPonyfillManager.f9f9a915.js.map +1 -0
  46. package/dist/{ThreeJsWrapper.dd4906ff.js → ThreeJsWrapper.0285d280.js} +24 -12
  47. package/dist/ThreeJsWrapper.0285d280.js.map +1 -0
  48. package/dist/{ThreeJsWrapper.c02a077f.js → ThreeJsWrapper.ad746197.js} +24 -11
  49. package/dist/ThreeJsWrapper.ad746197.js.map +1 -0
  50. package/dist/{VeilleManager.72cf0e9c.js → VeilleManager.0b3f2454.js} +18 -17
  51. package/dist/VeilleManager.0b3f2454.js.map +1 -0
  52. package/dist/{VeilleManager.26dcadac.js → VeilleManager.340a7825.js} +18 -17
  53. package/dist/VeilleManager.340a7825.js.map +1 -0
  54. package/dist/{Weather.bb414852.js → Weather.abc13d88.js} +25 -77
  55. package/dist/Weather.abc13d88.js.map +1 -0
  56. package/dist/{Weather.ced9b467.js → Weather.b9d9f82e.js} +25 -77
  57. package/dist/Weather.b9d9f82e.js.map +1 -0
  58. package/dist/index.d.ts +22 -929
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +53286 -33038
  61. package/dist/index.js.map +1 -1
  62. package/dist/index.modern.js +51651 -31410
  63. package/dist/index.modern.js.map +1 -1
  64. package/package.json +20 -21
  65. package/dist/AttachmentDetail.637ad44f.js.map +0 -1
  66. package/dist/AttachmentDetail.83788045.js.map +0 -1
  67. package/dist/CustomView.9930c671.js.map +0 -1
  68. package/dist/CustomView.bf84bdf3.js.map +0 -1
  69. package/dist/Emergency.1e63c85f.js.map +0 -1
  70. package/dist/Emergency.89b4d9ed.js.map +0 -1
  71. package/dist/HistoryList.3b4b1ffb.js.map +0 -1
  72. package/dist/HistoryList.e5c01f21.js.map +0 -1
  73. package/dist/LanguageChoice.1d866cfa.js.map +0 -1
  74. package/dist/LanguageChoice.cce361a3.js.map +0 -1
  75. package/dist/MapContainer.14c28128.js.map +0 -1
  76. package/dist/MapContainer.f22ad81f.js.map +0 -1
  77. package/dist/NewsContainer.c0a24775.js.map +0 -1
  78. package/dist/NewsContainer.c3331d80.js.map +0 -1
  79. package/dist/ThreeJsWrapper.c02a077f.js.map +0 -1
  80. package/dist/ThreeJsWrapper.dd4906ff.js.map +0 -1
  81. package/dist/VeilleManager.26dcadac.js.map +0 -1
  82. package/dist/VeilleManager.72cf0e9c.js.map +0 -1
  83. package/dist/Weather.bb414852.js.map +0 -1
  84. package/dist/Weather.ced9b467.js.map +0 -1
@@ -0,0 +1,298 @@
1
+ import {jsx as $asYsR$jsx} from "react/jsx-runtime";
2
+ import $asYsR$react, {useState as $asYsR$useState, useRef as $asYsR$useRef, useEffect as $asYsR$useEffect} from "react";
3
+ import {createSpeechRecognitionPonyfill as $asYsR$createSpeechRecognitionPonyfill, SpeechGrammarList as $asYsR$SpeechGrammarList} from "@davi-ai/web-speech-cognitive-services-davi";
4
+ import {useDispatch as $asYsR$useDispatch, useSelector as $asYsR$useSelector} from "react-redux";
5
+
6
+
7
+ function $parcel$defineInteropFlag(a) {
8
+ Object.defineProperty(a, '__esModule', {value: true, configurable: true});
9
+ }
10
+
11
+ function $parcel$export(e, n, v, s) {
12
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
13
+ }
14
+
15
+ var $parcel$global = globalThis;
16
+ var parcelRequire = $parcel$global["parcelRequirea39d"];
17
+ var parcelRegister = parcelRequire.register;
18
+ parcelRegister("kzWGI", function(module, exports) {
19
+
20
+ $parcel$defineInteropFlag(module.exports);
21
+
22
+ $parcel$export(module.exports, "default", () => $e5415612407dd579$export$2e2bcd8739ae039);
23
+
24
+
25
+
26
+
27
+
28
+ var $8ItUL = parcelRequire("8ItUL");
29
+
30
+ var $cW5Dh = parcelRequire("cW5Dh");
31
+ const $e5415612407dd579$var$timeoutDuration = 1000;
32
+ const $e5415612407dd579$var$RecognitionManager = ()=>{
33
+ const dispatch = (0, $asYsR$useDispatch)();
34
+ const locale = (0, $asYsR$useSelector)((state)=>state.localeReducer.locale);
35
+ const mode = (0, $asYsR$useSelector)((state)=>state.speechReducer.mode);
36
+ const appAvailable = (0, $asYsR$useSelector)((state)=>state.retorikReducer.appAvailable);
37
+ const loaderClosed = (0, $asYsR$useSelector)((state)=>state.retorikReducer.loaderClosed);
38
+ const agentData = (0, $asYsR$useSelector)((state)=>state.retorikReducer.agentData);
39
+ const delay = (0, $asYsR$useSelector)((state)=>state.retorikReducer.submitDelayBeforeSendingMessage);
40
+ const speechRecognitionOptions = (0, $asYsR$useSelector)((state)=>state.retorikReducer.configuration.speechRecognitionOptions);
41
+ const ponyfillCredentials = (0, $asYsR$useSelector)((state)=>state.speechReducer.ponyfillCredentials);
42
+ const useContinuousRecognition = (0, $asYsR$useSelector)((state)=>state.speechReducer.useContinuousRecognition);
43
+ const activeRecognitionState = (0, $asYsR$useSelector)((state)=>state.speechReducer.activeRecognitionState);
44
+ const lastRecognitionInterim = (0, $asYsR$useSelector)((state)=>state.speechReducer.lastRecognitionInterim);
45
+ const speechRecognitionDynamicGrammars = (0, $asYsR$useSelector)((state)=>state.speechReducer.speechRecognitionDynamicGrammars);
46
+ const route = (0, $asYsR$useSelector)((state)=>state.viewReducer.route);
47
+ const [ponyfill, setPonyfill] = (0, $asYsR$useState)(null);
48
+ const [recognitionAllowed, setRecognitionAllowed] = (0, $asYsR$useState)(false);
49
+ const [ponyfillReady, setPonyfillReady] = (0, $asYsR$useState)(false);
50
+ const activeModeRef = (0, $asYsR$useRef)(undefined);
51
+ const timerRef = (0, $asYsR$useRef)(null);
52
+ const localeRef = (0, $asYsR$useRef)(undefined);
53
+ const getCommonAndLocalizedWakeWords = (currentLocale, agentName)=>{
54
+ let commonAndlocalizedWakeWords = [];
55
+ if (speechRecognitionOptions?.wakeWords) {
56
+ if (speechRecognitionOptions.wakeWords.common) commonAndlocalizedWakeWords = [
57
+ ...speechRecognitionOptions.wakeWords.common
58
+ ];
59
+ if (speechRecognitionOptions.wakeWords.localized) {
60
+ const localizedWakeWords = speechRecognitionOptions.wakeWords.localized[currentLocale] || [];
61
+ localizedWakeWords.length && (commonAndlocalizedWakeWords = [
62
+ ...commonAndlocalizedWakeWords,
63
+ ...localizedWakeWords
64
+ ]);
65
+ }
66
+ }
67
+ // Add agent's name to wake words
68
+ agentName && (commonAndlocalizedWakeWords = [
69
+ ...commonAndlocalizedWakeWords,
70
+ agentName
71
+ ]);
72
+ return commonAndlocalizedWakeWords;
73
+ };
74
+ const getCommonAndLocalizedGrammars = (currentLocale)=>{
75
+ let commonAndlocalizedGrammars = [];
76
+ if (speechRecognitionOptions?.grammars) {
77
+ if (speechRecognitionOptions.grammars.common) commonAndlocalizedGrammars = [
78
+ ...speechRecognitionOptions.grammars.common
79
+ ];
80
+ if (speechRecognitionOptions.grammars.localized) {
81
+ const localizedGrammars = speechRecognitionOptions.grammars.localized[currentLocale] || [];
82
+ localizedGrammars.length && (commonAndlocalizedGrammars = [
83
+ ...commonAndlocalizedGrammars,
84
+ ...localizedGrammars
85
+ ]);
86
+ }
87
+ }
88
+ return commonAndlocalizedGrammars;
89
+ };
90
+ const askPermission = ()=>{
91
+ if (recognitionAllowed) ponyfill?.speechRecognition.start();
92
+ else (0, $cW5Dh.default)().then((permission)=>{
93
+ setRecognitionAllowed(permission === (0, $8ItUL.PermissionStatus).allowed);
94
+ }).catch(console.log);
95
+ };
96
+ (0, $asYsR$useEffect)(()=>{
97
+ // Clear data on component unmount
98
+ return ()=>{
99
+ timerRef?.current && clearTimeout(timerRef.current);
100
+ ponyfill?.speechRecognition?.abort?.();
101
+ };
102
+ }, []);
103
+ (0, $asYsR$useEffect)(()=>{
104
+ recognitionAllowed && useContinuousRecognition && ponyfill?.speechRecognition.start();
105
+ }, [
106
+ recognitionAllowed
107
+ ]);
108
+ (0, $asYsR$useEffect)(()=>{
109
+ if (ponyfillCredentials && locale && agentData) {
110
+ let currentPonyfill = ponyfill;
111
+ if (locale !== localeRef.current) {
112
+ localeRef.current = locale;
113
+ // We create the ponyfill if it isn't created yet. We recreate a new one if we are using custom endpoints for speech recognition.
114
+ if (!ponyfill || ponyfillCredentials?.speechRecognitionHostnamesRecord) {
115
+ // Check if we need to use a custom endpoint from speechRecognitionHostnamesRecord
116
+ const speechRecognitionHostname = ponyfillCredentials?.speechRecognitionHostnamesRecord ? ponyfillCredentials.speechRecognitionHostnamesRecord[locale] || Object.values(ponyfillCredentials.speechRecognitionHostnamesRecord)[0] : undefined;
117
+ const options = {
118
+ autoStart: false,
119
+ continuous: useContinuousRecognition,
120
+ interimResults: true,
121
+ grammarsList: getCommonAndLocalizedGrammars(locale),
122
+ lang: locale,
123
+ passive: useContinuousRecognition,
124
+ wakeWords: getCommonAndLocalizedWakeWords(locale),
125
+ debug: false,
126
+ timerBeforeSpeechEnd: speechRecognitionOptions?.timerBeforeSpeechEnd
127
+ };
128
+ const processedCredentials = {
129
+ credentials: speechRecognitionHostname ? {
130
+ region: undefined,
131
+ subscriptionKey: ponyfillCredentials.subscriptionKey || 'mandatory_subscription_key',
132
+ speechRecognitionHostname: speechRecognitionHostname,
133
+ speechSynthesisHostname: 'mandatory_synthesis_host_name'
134
+ } : {
135
+ region: ponyfillCredentials.region,
136
+ subscriptionKey: ponyfillCredentials.subscriptionKey,
137
+ authorizationToken: ponyfillCredentials.authorizationToken
138
+ }
139
+ };
140
+ // Abort current recognition before setting the new recognition ponyfill if there is a need to
141
+ currentPonyfill?.speechRecognition?.abort?.();
142
+ currentPonyfill = (0, $asYsR$createSpeechRecognitionPonyfill)(processedCredentials, options);
143
+ } else if (currentPonyfill) {
144
+ // Set wakeworkds
145
+ currentPonyfill.speechRecognition.wakeWords = getCommonAndLocalizedWakeWords(locale, agentData?.name);
146
+ // Set language
147
+ activeRecognitionState === (0, $8ItUL.RecognitionState).Listening ? currentPonyfill?.speechRecognition.changeLanguage(locale) : currentPonyfill.speechRecognition.lang = locale;
148
+ }
149
+ }
150
+ if (currentPonyfill) {
151
+ // Set grammar list
152
+ const grammarList = new (0, $asYsR$SpeechGrammarList)();
153
+ grammarList.phrases = getCommonAndLocalizedGrammars(locale);
154
+ if (speechRecognitionDynamicGrammars.length) speechRecognitionDynamicGrammars.forEach((grammar)=>{
155
+ !grammarList.phrases.includes(grammar) && grammarList.phrases.push(grammar);
156
+ });
157
+ if (agentData?.name) {
158
+ // Add raw name
159
+ !grammarList.phrases.includes(agentData.name) && grammarList.phrases.push(agentData.name);
160
+ // Add lower-cased name
161
+ !grammarList.phrases.includes(agentData.name.toLocaleLowerCase(locale)) && grammarList.phrases.push(agentData.name.toLocaleLowerCase(locale));
162
+ }
163
+ currentPonyfill.speechRecognition.grammars = grammarList;
164
+ setPonyfill(currentPonyfill);
165
+ }
166
+ }
167
+ }, [
168
+ ponyfillCredentials,
169
+ locale,
170
+ speechRecognitionDynamicGrammars,
171
+ agentData
172
+ ]);
173
+ /**
174
+ * Abort recognition if we are not on the 'home' page
175
+ */ (0, $asYsR$useEffect)(()=>{
176
+ route !== (0, $8ItUL.Routes).Home && dispatch((0, $8ItUL.storeActions).speech.setActiveRecognitionState((0, $8ItUL.RecognitionState).Closed));
177
+ }, [
178
+ route
179
+ ]);
180
+ (0, $asYsR$useEffect)(()=>{
181
+ if (ponyfill && appAvailable && loaderClosed) {
182
+ if (ponyfill.speechRecognition) {
183
+ ponyfill.speechRecognition.onstart = ()=>{
184
+ dispatch((0, $8ItUL.storeActions).speech.setActiveRecognitionState((0, $8ItUL.RecognitionState).Listening));
185
+ };
186
+ // onend callback is called only whithout using passive speech recognition
187
+ ponyfill.speechRecognition.onend = ()=>{
188
+ activeModeRef.current !== (0, $8ItUL.RecognitionState).Closed && dispatch((0, $8ItUL.storeActions).speech.setActiveRecognitionState((0, $8ItUL.RecognitionState).Closing));
189
+ };
190
+ ponyfill.speechRecognition.onabort = ()=>{
191
+ dispatch((0, $8ItUL.storeActions).speech.setActiveRecognitionState((0, $8ItUL.RecognitionState).Closed));
192
+ };
193
+ ponyfill.speechRecognition.onwakeup = ()=>{
194
+ if (activeModeRef.current === (0, $8ItUL.RecognitionState).Closed) {
195
+ console.log('Retorik Framework > wake word found, trying to open microphone');
196
+ activeModeRef.current === (0, $8ItUL.RecognitionState).Closed && dispatch((0, $8ItUL.storeActions).speech.toggleMicrophone(false));
197
+ } else console.log('Retorik Framework > wake word found, but microphone not ready');
198
+ };
199
+ ponyfill.speechRecognition.onresult = (result)=>{
200
+ const lastMessage = result.length ? result[result.length - 1].transcript : null;
201
+ // Only get result in Active mode
202
+ if (lastMessage && activeModeRef.current === (0, $8ItUL.RecognitionState).Listening) dispatch((0, $8ItUL.storeActions).speech.setLastRecognitionInterim(lastMessage));
203
+ };
204
+ setPonyfillReady(true);
205
+ }
206
+ }
207
+ }, [
208
+ ponyfill,
209
+ appAvailable,
210
+ loaderClosed
211
+ ]);
212
+ (0, $asYsR$useEffect)(()=>{
213
+ if (ponyfillReady && mode === (0, $8ItUL.Mode).vocal) // Start passive recognition if not done yet
214
+ useContinuousRecognition && !ponyfill?.speechRecognition.started && askPermission();
215
+ }, [
216
+ mode,
217
+ ponyfillReady
218
+ ]);
219
+ const togglePassiveToActive = ()=>{
220
+ if (ponyfill?.speechRecognition.started) ponyfill.speechRecognition.toggleContinuousPassiveToActive();
221
+ else if (ponyfill) {
222
+ ponyfill.speechRecognition.passive = false;
223
+ ponyfill.speechRecognition.continuous = false;
224
+ ponyfill.speechRecognition.start();
225
+ }
226
+ };
227
+ (0, $asYsR$useEffect)(()=>{
228
+ activeModeRef.current = activeRecognitionState;
229
+ if (ponyfill?.speechRecognition && appAvailable && loaderClosed) {
230
+ timerRef?.current && clearTimeout(timerRef.current);
231
+ switch(activeRecognitionState){
232
+ // Do nothing if we are in a transition state
233
+ case (0, $8ItUL.RecognitionState).Initializing:
234
+ useContinuousRecognition ? togglePassiveToActive() : ponyfill.speechRecognition.start();
235
+ break;
236
+ case (0, $8ItUL.RecognitionState).Listening:
237
+ break;
238
+ case (0, $8ItUL.RecognitionState).Closing:
239
+ if (lastRecognitionInterim) {
240
+ if (!delay) timerRef.current = setTimeout(()=>{
241
+ dispatch((0, $8ItUL.storeActions).directline.sendMessage({
242
+ text: lastRecognitionInterim
243
+ }));
244
+ dispatch((0, $8ItUL.storeActions).speech.setActiveRecognitionState((0, $8ItUL.RecognitionState).Closed));
245
+ }, $e5415612407dd579$var$timeoutDuration);
246
+ } else dispatch((0, $8ItUL.storeActions).speech.setActiveRecognitionState((0, $8ItUL.RecognitionState).Closed));
247
+ break;
248
+ case (0, $8ItUL.RecognitionState).ForceClosing:
249
+ dispatch((0, $8ItUL.storeActions).speech.setLastRecognitionInterim(''));
250
+ // Let's abort the current recognition
251
+ ponyfill.speechRecognition.started ? ponyfill.speechRecognition.abort?.() : dispatch((0, $8ItUL.storeActions).speech.setActiveRecognitionState((0, $8ItUL.RecognitionState).Closed));
252
+ break;
253
+ case (0, $8ItUL.RecognitionState).Closed:
254
+ if (useContinuousRecognition && mode === (0, $8ItUL.Mode).vocal) timerRef.current = setTimeout(()=>{
255
+ ponyfill.speechRecognition.toggleContinuousActiveToPassive();
256
+ }, $e5415612407dd579$var$timeoutDuration);
257
+ dispatch((0, $8ItUL.storeActions).speech.setLastRecognitionInterim(''));
258
+ break;
259
+ }
260
+ }
261
+ }, [
262
+ activeRecognitionState
263
+ ]);
264
+ return /*#__PURE__*/ (0, $asYsR$jsx)((0, $asYsR$react).Fragment, {});
265
+ };
266
+ var $e5415612407dd579$export$2e2bcd8739ae039 = $e5415612407dd579$var$RecognitionManager;
267
+
268
+ });
269
+ parcelRegister("cW5Dh", function(module, exports) {
270
+
271
+ $parcel$export(module.exports, "default", () => $1c5c9ed09d1921fe$export$2e2bcd8739ae039);
272
+
273
+ var $8ItUL = parcelRequire("8ItUL");
274
+ const $1c5c9ed09d1921fe$var$getMicrophonePermission = async ()=>{
275
+ try {
276
+ return navigator.mediaDevices.getUserMedia({
277
+ audio: true
278
+ }).then((stream)=>{
279
+ return stream ? (0, $8ItUL.PermissionStatus).allowed : (0, $8ItUL.PermissionStatus).refused;
280
+ }, (reason)=>{
281
+ console.log('Retorik Framework > microphone permission refused : ', reason);
282
+ return (0, $8ItUL.PermissionStatus).refused;
283
+ }).catch((error)=>{
284
+ console.log('Retorik Framework > microphone permission refused : ', error);
285
+ return (0, $8ItUL.PermissionStatus).error;
286
+ });
287
+ } catch (error) {
288
+ console.log('Retorik Framework > microphone permission refused : ', error);
289
+ return (0, $8ItUL.PermissionStatus).error;
290
+ }
291
+ };
292
+ var $1c5c9ed09d1921fe$export$2e2bcd8739ae039 = $1c5c9ed09d1921fe$var$getMicrophonePermission;
293
+
294
+ });
295
+
296
+
297
+
298
+ //# sourceMappingURL=RecognitionManager.c58b8a3d.js.map
@@ -0,0 +1 @@
1
+ {"mappings":"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","sources":["src/components/Speech/RecognitionManager.tsx","src/utils/getMicrophonePermission.ts"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react'\r\nimport { createSpeechRecognitionPonyfill, SpeechGrammarList } from '@davi-ai/web-speech-cognitive-services-davi'\r\nimport type { PonyfillOptions, SpeechRecognitionPonyfillType, SpeechRecognitionProps, SpeechRecognitionResultList, SpeechRecognitionResultListItem } from '@davi-ai/web-speech-cognitive-services-davi'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions, Mode, PermissionStatus, RecognitionState, Routes } from '../../store'\r\nimport getMicrophonePermission from '../../utils/getMicrophonePermission'\r\n\r\nconst timeoutDuration = 1000\r\n\r\nconst RecognitionManager = (): React.JSX.Element => {\r\n const dispatch = useDispatch()\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const mode = useSelector((state: RootState) => state.speechReducer.mode)\r\n const appAvailable = useSelector((state: RootState) => state.retorikReducer.appAvailable)\r\n const loaderClosed = useSelector((state: RootState) => state.retorikReducer.loaderClosed)\r\n const agentData = useSelector((state: RootState) => state.retorikReducer.agentData)\r\n const delay = useSelector((state: RootState) => state.retorikReducer.submitDelayBeforeSendingMessage)\r\n const speechRecognitionOptions = useSelector((state: RootState) => state.retorikReducer.configuration.speechRecognitionOptions)\r\n const ponyfillCredentials = useSelector((state: RootState) => state.speechReducer.ponyfillCredentials)\r\n const useContinuousRecognition = useSelector((state: RootState) => state.speechReducer.useContinuousRecognition)\r\n const activeRecognitionState = useSelector((state: RootState) => state.speechReducer.activeRecognitionState)\r\n const lastRecognitionInterim = useSelector((state: RootState) => state.speechReducer.lastRecognitionInterim)\r\n const speechRecognitionDynamicGrammars = useSelector((state: RootState) => state.speechReducer.speechRecognitionDynamicGrammars)\r\n const route = useSelector((state: RootState) => state.viewReducer.route)\r\n\r\n const [ponyfill, setPonyfill] = useState<SpeechRecognitionPonyfillType | null>(null)\r\n const [recognitionAllowed, setRecognitionAllowed] = useState<boolean>(false)\r\n const [ponyfillReady, setPonyfillReady] = useState<boolean>(false)\r\n\r\n const activeModeRef = useRef<RecognitionState | undefined>(undefined)\r\n const timerRef = useRef<NodeJS.Timeout | null>(null)\r\n const localeRef = useRef<string | undefined>(undefined)\r\n\r\n const getCommonAndLocalizedWakeWords = (currentLocale: string, agentName?: string): Array<string> => {\r\n let commonAndlocalizedWakeWords: Array<string> = []\r\n if (speechRecognitionOptions?.wakeWords) {\r\n if (speechRecognitionOptions.wakeWords.common) {\r\n commonAndlocalizedWakeWords = [...speechRecognitionOptions.wakeWords.common]\r\n }\r\n\r\n if (speechRecognitionOptions.wakeWords.localized) {\r\n const localizedWakeWords = speechRecognitionOptions.wakeWords.localized[currentLocale] || []\r\n localizedWakeWords.length && (commonAndlocalizedWakeWords = [...commonAndlocalizedWakeWords, ...localizedWakeWords])\r\n }\r\n }\r\n\r\n // Add agent's name to wake words\r\n agentName && (commonAndlocalizedWakeWords = [...commonAndlocalizedWakeWords, agentName])\r\n\r\n return commonAndlocalizedWakeWords\r\n }\r\n\r\n const getCommonAndLocalizedGrammars = (currentLocale: string): Array<string> => {\r\n let commonAndlocalizedGrammars: Array<string> = []\r\n if (speechRecognitionOptions?.grammars) {\r\n if (speechRecognitionOptions.grammars.common) {\r\n commonAndlocalizedGrammars = [...speechRecognitionOptions.grammars.common]\r\n }\r\n\r\n if (speechRecognitionOptions.grammars.localized) {\r\n const localizedGrammars = speechRecognitionOptions.grammars.localized[currentLocale] || []\r\n localizedGrammars.length && (commonAndlocalizedGrammars = [...commonAndlocalizedGrammars, ...localizedGrammars])\r\n }\r\n }\r\n\r\n return commonAndlocalizedGrammars\r\n }\r\n\r\n const askPermission = (): void => {\r\n if (recognitionAllowed) {\r\n ponyfill?.speechRecognition.start()\r\n } else {\r\n getMicrophonePermission()\r\n .then((permission) => {\r\n setRecognitionAllowed(permission === PermissionStatus.allowed)\r\n })\r\n .catch(console.log)\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n // Clear data on component unmount\r\n return () => {\r\n timerRef?.current && clearTimeout(timerRef.current)\r\n ponyfill?.speechRecognition?.abort?.()\r\n }\r\n }, [])\r\n\r\n useEffect(() => {\r\n recognitionAllowed && useContinuousRecognition && ponyfill?.speechRecognition.start()\r\n }, [recognitionAllowed])\r\n\r\n useEffect(() => {\r\n if (ponyfillCredentials && locale && agentData) {\r\n let currentPonyfill = ponyfill\r\n if (locale !== localeRef.current) {\r\n localeRef.current = locale\r\n // We create the ponyfill if it isn't created yet. We recreate a new one if we are using custom endpoints for speech recognition.\r\n if (!ponyfill || ponyfillCredentials?.speechRecognitionHostnamesRecord) {\r\n // Check if we need to use a custom endpoint from speechRecognitionHostnamesRecord\r\n const speechRecognitionHostname = ponyfillCredentials?.speechRecognitionHostnamesRecord\r\n ? ponyfillCredentials.speechRecognitionHostnamesRecord[locale] || Object.values(ponyfillCredentials.speechRecognitionHostnamesRecord)[0]\r\n : undefined\r\n\r\n const options: SpeechRecognitionProps = {\r\n autoStart: false,\r\n continuous: useContinuousRecognition,\r\n interimResults: true,\r\n grammarsList: getCommonAndLocalizedGrammars(locale),\r\n lang: locale,\r\n passive: useContinuousRecognition,\r\n wakeWords: getCommonAndLocalizedWakeWords(locale),\r\n debug: false,\r\n timerBeforeSpeechEnd: speechRecognitionOptions?.timerBeforeSpeechEnd\r\n }\r\n\r\n const processedCredentials: PonyfillOptions = {\r\n credentials: speechRecognitionHostname\r\n ? {\r\n region: undefined,\r\n subscriptionKey: ponyfillCredentials.subscriptionKey || 'mandatory_subscription_key',\r\n speechRecognitionHostname: speechRecognitionHostname,\r\n speechSynthesisHostname: 'mandatory_synthesis_host_name'\r\n }\r\n : {\r\n region: ponyfillCredentials.region,\r\n subscriptionKey: ponyfillCredentials.subscriptionKey,\r\n authorizationToken: ponyfillCredentials.authorizationToken\r\n }\r\n }\r\n\r\n // Abort current recognition before setting the new recognition ponyfill if there is a need to\r\n currentPonyfill?.speechRecognition?.abort?.()\r\n currentPonyfill = createSpeechRecognitionPonyfill(processedCredentials, options)\r\n } else if (currentPonyfill) {\r\n // Set wakeworkds\r\n currentPonyfill.speechRecognition.wakeWords = getCommonAndLocalizedWakeWords(locale, agentData?.name)\r\n // Set language\r\n activeRecognitionState === RecognitionState.Listening ? currentPonyfill?.speechRecognition.changeLanguage(locale) : (currentPonyfill.speechRecognition.lang = locale)\r\n }\r\n }\r\n\r\n if (currentPonyfill) {\r\n // Set grammar list\r\n const grammarList = new SpeechGrammarList()\r\n grammarList.phrases = getCommonAndLocalizedGrammars(locale)\r\n if (speechRecognitionDynamicGrammars.length) {\r\n speechRecognitionDynamicGrammars.forEach((grammar) => {\r\n !grammarList.phrases.includes(grammar) && grammarList.phrases.push(grammar)\r\n })\r\n }\r\n\r\n if (agentData?.name) {\r\n // Add raw name\r\n !grammarList.phrases.includes(agentData.name) && grammarList.phrases.push(agentData.name)\r\n // Add lower-cased name\r\n !grammarList.phrases.includes(agentData.name.toLocaleLowerCase(locale)) && grammarList.phrases.push(agentData.name.toLocaleLowerCase(locale))\r\n }\r\n currentPonyfill.speechRecognition.grammars = grammarList\r\n\r\n setPonyfill(currentPonyfill)\r\n }\r\n }\r\n }, [ponyfillCredentials, locale, speechRecognitionDynamicGrammars, agentData])\r\n\r\n /**\r\n * Abort recognition if we are not on the 'home' page\r\n */\r\n useEffect(() => {\r\n route !== Routes.Home && dispatch(storeActions.speech.setActiveRecognitionState(RecognitionState.Closed))\r\n }, [route])\r\n\r\n useEffect(() => {\r\n if (ponyfill && appAvailable && loaderClosed) {\r\n if (ponyfill.speechRecognition) {\r\n ponyfill.speechRecognition.onstart = () => {\r\n dispatch(storeActions.speech.setActiveRecognitionState(RecognitionState.Listening))\r\n }\r\n\r\n // onend callback is called only whithout using passive speech recognition\r\n ponyfill.speechRecognition.onend = () => {\r\n activeModeRef.current !== RecognitionState.Closed && dispatch(storeActions.speech.setActiveRecognitionState(RecognitionState.Closing))\r\n }\r\n\r\n ponyfill.speechRecognition.onabort = () => {\r\n dispatch(storeActions.speech.setActiveRecognitionState(RecognitionState.Closed))\r\n }\r\n\r\n ponyfill.speechRecognition.onwakeup = () => {\r\n if (activeModeRef.current === RecognitionState.Closed) {\r\n console.log('Retorik Framework > wake word found, trying to open microphone')\r\n activeModeRef.current === RecognitionState.Closed && dispatch(storeActions.speech.toggleMicrophone(false))\r\n } else {\r\n console.log('Retorik Framework > wake word found, but microphone not ready')\r\n }\r\n }\r\n\r\n ponyfill.speechRecognition.onresult = (result: SpeechRecognitionResultList | Array<SpeechRecognitionResultListItem>) => {\r\n const lastMessage: string | null = result.length ? result[result.length - 1].transcript : null\r\n // Only get result in Active mode\r\n if (lastMessage && activeModeRef.current === RecognitionState.Listening) {\r\n dispatch(storeActions.speech.setLastRecognitionInterim(lastMessage))\r\n }\r\n }\r\n\r\n setPonyfillReady(true)\r\n }\r\n }\r\n }, [ponyfill, appAvailable, loaderClosed])\r\n\r\n useEffect(() => {\r\n if (ponyfillReady && mode === Mode.vocal) {\r\n // Start passive recognition if not done yet\r\n useContinuousRecognition && !ponyfill?.speechRecognition.started && askPermission()\r\n }\r\n }, [mode, ponyfillReady])\r\n\r\n const togglePassiveToActive = (): void => {\r\n if (ponyfill?.speechRecognition.started) {\r\n ponyfill.speechRecognition.toggleContinuousPassiveToActive()\r\n } else {\r\n if (ponyfill) {\r\n ponyfill.speechRecognition.passive = false\r\n ponyfill.speechRecognition.continuous = false\r\n ponyfill.speechRecognition.start()\r\n }\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n activeModeRef.current = activeRecognitionState\r\n\r\n if (ponyfill?.speechRecognition && appAvailable && loaderClosed) {\r\n timerRef?.current && clearTimeout(timerRef.current)\r\n switch (activeRecognitionState) {\r\n // Do nothing if we are in a transition state\r\n case RecognitionState.Initializing: {\r\n useContinuousRecognition ? togglePassiveToActive() : ponyfill.speechRecognition.start()\r\n break\r\n }\r\n case RecognitionState.Listening:\r\n break\r\n case RecognitionState.Closing: {\r\n if (lastRecognitionInterim) {\r\n if (!delay) {\r\n timerRef.current = setTimeout(() => {\r\n dispatch(storeActions.directline.sendMessage({ text: lastRecognitionInterim }))\r\n\r\n dispatch(storeActions.speech.setActiveRecognitionState(RecognitionState.Closed))\r\n }, timeoutDuration)\r\n }\r\n } else {\r\n dispatch(storeActions.speech.setActiveRecognitionState(RecognitionState.Closed))\r\n }\r\n break\r\n }\r\n case RecognitionState.ForceClosing: {\r\n dispatch(storeActions.speech.setLastRecognitionInterim(''))\r\n\r\n // Let's abort the current recognition\r\n ponyfill.speechRecognition.started ? ponyfill.speechRecognition.abort?.() : dispatch(storeActions.speech.setActiveRecognitionState(RecognitionState.Closed))\r\n break\r\n }\r\n case RecognitionState.Closed: {\r\n if (useContinuousRecognition && mode === Mode.vocal) {\r\n timerRef.current = setTimeout(() => {\r\n ponyfill.speechRecognition.toggleContinuousActiveToPassive()\r\n }, timeoutDuration)\r\n }\r\n dispatch(storeActions.speech.setLastRecognitionInterim(''))\r\n break\r\n }\r\n }\r\n }\r\n }, [activeRecognitionState])\r\n\r\n return <React.Fragment />\r\n}\r\n\r\nexport default RecognitionManager\r\n","import { PermissionStatus } from '../store'\r\n\r\nconst getMicrophonePermission = async (): Promise<PermissionStatus> => {\r\n try {\r\n return navigator.mediaDevices\r\n .getUserMedia({ audio: true })\r\n .then(\r\n (stream) => {\r\n return stream ? PermissionStatus.allowed : PermissionStatus.refused\r\n },\r\n (reason) => {\r\n console.log(\r\n 'Retorik Framework > microphone permission refused : ',\r\n reason\r\n )\r\n return PermissionStatus.refused\r\n }\r\n )\r\n .catch((error) => {\r\n console.log(\r\n 'Retorik Framework > microphone permission refused : ',\r\n error\r\n )\r\n return PermissionStatus.error\r\n })\r\n } catch (error) {\r\n console.log('Retorik Framework > microphone permission refused : ', error)\r\n return PermissionStatus.error\r\n }\r\n}\r\n\r\nexport default getMicrophonePermission\r\n"],"names":[],"version":3,"file":"RecognitionManager.c58b8a3d.js.map"}