@memori.ai/memori-react 1.0.0-alpha.21 → 1.0.0-alpha.22
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/CHANGELOG.md +12 -0
- package/dist/components/ChatInputs/ChatInputs.js +4 -1
- package/dist/components/ChatInputs/ChatInputs.js.map +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.js +156 -136
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/components/StartPanel/StartPanel.js +1 -0
- package/dist/components/StartPanel/StartPanel.js.map +1 -1
- package/esm/components/ChatInputs/ChatInputs.js +4 -1
- package/esm/components/ChatInputs/ChatInputs.js.map +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.js +156 -136
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/components/StartPanel/StartPanel.js +1 -0
- package/esm/components/StartPanel/StartPanel.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ChatInputs/ChatInputs.tsx +4 -1
- package/src/components/MemoriWidget/MemoriWidget.tsx +191 -173
- package/src/components/StartPanel/StartPanel.tsx +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
+
## [1.0.0-alpha.22](https://github.com/memori-ai/memori-react/compare/v1.0.0-alpha.21...v1.0.0-alpha.22) (2023-01-17)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* audio issues, refactor tts ([e66c83a](https://github.com/memori-ai/memori-react/commit/e66c83a35e1a98ae7e24ee532923653d9032c3f3))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Maintenance
|
|
12
|
+
|
|
13
|
+
* cleanup ([bd755c7](https://github.com/memori-ai/memori-react/commit/bd755c7de3736f4685e66076f058ff7ca6d513d2))
|
|
14
|
+
|
|
3
15
|
## [1.0.0-alpha.21](https://github.com/memori-ai/memori-react/compare/v1.0.0-alpha.20...v1.0.0-alpha.21) (2023-01-14)
|
|
4
16
|
|
|
5
17
|
|
|
@@ -17,7 +17,10 @@ const ChatInputs = ({ dialogState, instruct = false, sendOnEnter = 'click', setS
|
|
|
17
17
|
(instruct || (dialogState === null || dialogState === void 0 ? void 0 : dialogState.acceptsMedia)) && (react_1.default.createElement(UploadMenu_1.default, { attachmentsMenuOpen: attachmentsMenuOpen, setAttachmentsMenuOpen: setAttachmentsMenuOpen, authToken: authToken, disabled: !(dialogState === null || dialogState === void 0 ? void 0 : dialogState.acceptsMedia) })),
|
|
18
18
|
react_1.default.createElement(SendOnEnterMenu_1.default, { sendOnEnter: sendOnEnter, setSendOnEnter: setSendOnEnter }),
|
|
19
19
|
react_1.default.createElement(ChatTextArea_1.default, { value: userMessage, onChange: onChangeUserMessage, onPressEnter: onTextareaPressEnter, onFocus: onTextareaFocus, onBlur: onTextareaBlur, disabled: ['R2', 'R3', 'R4', 'G3', 'X3'].includes((dialogState === null || dialogState === void 0 ? void 0 : dialogState.state) || '') }),
|
|
20
|
-
react_1.default.createElement(Button_1.default, { shape: "circle", primary: !!(userMessage === null || userMessage === void 0 ? void 0 : userMessage.length), disabled: !userMessage || userMessage.length === 0, className: "memori-chat-inputs--send", onClick: () =>
|
|
20
|
+
react_1.default.createElement(Button_1.default, { shape: "circle", primary: !!(userMessage === null || userMessage === void 0 ? void 0 : userMessage.length), disabled: !userMessage || userMessage.length === 0, className: "memori-chat-inputs--send", onClick: () => {
|
|
21
|
+
sendMessage(userMessage);
|
|
22
|
+
speechSynthesis.speak(new SpeechSynthesisUtterance(''));
|
|
23
|
+
}, title: t('send') || 'Send', icon: react_1.default.createElement(Send_1.default, null) }),
|
|
21
24
|
showMicrophone && (react_1.default.createElement(Button_1.default, { className: (0, classnames_1.default)('memori-chat-inputs--mic', {
|
|
22
25
|
'memori-chat-inputs--mic--listening': listening,
|
|
23
26
|
}), title: listening
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatInputs.js","sourceRoot":"","sources":["../../../src/components/ChatInputs/ChatInputs.tsx"],"names":[],"mappings":";;;AAAA,0DAA0B;AAE1B,kFAAkD;AAClD,iGAAiE;AACjE,wFAAwD;AACxD,kEAAkC;AAClC,iDAA+C;AAC/C,oEAA4B;AAC5B,iEAAiC;AACjC,6EAA6C;AAE7C,4BAA0B;AAyB1B,MAAM,UAAU,GAAoB,CAAC,EACnC,WAAW,EACX,QAAQ,GAAG,KAAK,EAChB,WAAW,GAAG,OAAO,EACrB,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,WAAW,GAAG,EAAE,EAChB,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,cAAc,GAAG,KAAK,EACtB,SAAS,GAAG,KAAK,EACjB,cAAc,GAAG,KAAK,EACtB,SAAS,EACT,cAAc,EACd,aAAa,EACb,SAAS,GACV,EAAE,EAAE;IACH,MAAM,EAAE,CAAC,EAAE,GAAG,IAAA,8BAAc,GAAE,CAAC;IAE/B,OAAO,CACL,4CACE,EAAE,EAAC,eAAe,EAClB,SAAS,EAAC,oBAAoB,EAC9B,QAAQ,EAAE,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,MAAK,KAAK,IAAI,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,MAAK,IAAI;QAEpE,CAAC,QAAQ,KAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,YAAY,CAAA,CAAC,IAAI,CAC1C,8BAAC,oBAAU,IACT,mBAAmB,EAAE,mBAAmB,EACxC,sBAAsB,EAAE,sBAAsB,EAC9C,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,YAAY,CAAA,GACpC,CACH;QACD,8BAAC,yBAAe,IACd,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,cAAc,GAC9B;QACF,8BAAC,sBAAY,IACX,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,mBAAmB,EAC7B,YAAY,EAAE,oBAAoB,EAClC,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,CAC/C,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,KAAI,EAAE,CACzB,GACD;QACF,8BAAC,gBAAM,IACL,KAAK,EAAC,QAAQ,EACd,OAAO,EAAE,CAAC,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,MAAM,CAAA,EAC9B,QAAQ,EAAE,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAClD,SAAS,EAAC,0BAA0B,EACpC,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"ChatInputs.js","sourceRoot":"","sources":["../../../src/components/ChatInputs/ChatInputs.tsx"],"names":[],"mappings":";;;AAAA,0DAA0B;AAE1B,kFAAkD;AAClD,iGAAiE;AACjE,wFAAwD;AACxD,kEAAkC;AAClC,iDAA+C;AAC/C,oEAA4B;AAC5B,iEAAiC;AACjC,6EAA6C;AAE7C,4BAA0B;AAyB1B,MAAM,UAAU,GAAoB,CAAC,EACnC,WAAW,EACX,QAAQ,GAAG,KAAK,EAChB,WAAW,GAAG,OAAO,EACrB,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,WAAW,GAAG,EAAE,EAChB,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,cAAc,GAAG,KAAK,EACtB,SAAS,GAAG,KAAK,EACjB,cAAc,GAAG,KAAK,EACtB,SAAS,EACT,cAAc,EACd,aAAa,EACb,SAAS,GACV,EAAE,EAAE;IACH,MAAM,EAAE,CAAC,EAAE,GAAG,IAAA,8BAAc,GAAE,CAAC;IAE/B,OAAO,CACL,4CACE,EAAE,EAAC,eAAe,EAClB,SAAS,EAAC,oBAAoB,EAC9B,QAAQ,EAAE,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,MAAK,KAAK,IAAI,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,MAAK,IAAI;QAEpE,CAAC,QAAQ,KAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,YAAY,CAAA,CAAC,IAAI,CAC1C,8BAAC,oBAAU,IACT,mBAAmB,EAAE,mBAAmB,EACxC,sBAAsB,EAAE,sBAAsB,EAC9C,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,YAAY,CAAA,GACpC,CACH;QACD,8BAAC,yBAAe,IACd,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,cAAc,GAC9B;QACF,8BAAC,sBAAY,IACX,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,mBAAmB,EAC7B,YAAY,EAAE,oBAAoB,EAClC,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,CAC/C,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,KAAI,EAAE,CACzB,GACD;QACF,8BAAC,gBAAM,IACL,KAAK,EAAC,QAAQ,EACd,OAAO,EAAE,CAAC,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,MAAM,CAAA,EAC9B,QAAQ,EAAE,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAClD,SAAS,EAAC,0BAA0B,EACpC,OAAO,EAAE,GAAG,EAAE;gBACZ,WAAW,CAAC,WAAW,CAAC,CAAC;gBACzB,eAAe,CAAC,KAAK,CAAC,IAAI,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAC;YAC1D,CAAC,EACD,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,MAAM,EAC1B,IAAI,EAAE,8BAAC,cAAI,OAAG,GACd;QACD,cAAc,IAAI,CACjB,8BAAC,gBAAM,IACL,SAAS,EAAE,IAAA,oBAAE,EAAC,yBAAyB,EAAE;gBACvC,oCAAoC,EAAE,SAAS;aAChD,CAAC,EACF,KAAK,EACH,SAAS;gBACP,CAAC,CAAC,CAAC,CAAC,2CAA2C,CAAC,IAAI,WAAW;gBAC/D,CAAC,CAAC,CAAC,CAAC,kCAAkC,CAAC,IAAI,iBAAiB,EAEhE,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,CAAC,CAAC,EAAE;gBACX,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;gBACxC,IAAI,SAAS,EAAE;oBACb,aAAa,EAAE,CAAC;iBACjB;qBAAM;oBACL,SAAS,EAAE,CAAC;oBACZ,cAAc,EAAE,CAAC;iBAClB;YACH,CAAC,EACD,KAAK,EAAC,QAAQ,EACd,IAAI,EAAE,8BAAC,oBAAU,OAAG,GACpB,CACH,CACQ,CACZ,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,UAAU,CAAC"}
|
|
@@ -81,6 +81,7 @@ let recognizer;
|
|
|
81
81
|
let speechConfig;
|
|
82
82
|
let speechSynthesizer;
|
|
83
83
|
let audioDestination;
|
|
84
|
+
let audioContext;
|
|
84
85
|
const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInstruct = false, showShare = true, preview = false, embed = false, showInputs = true, showDates = false, showContextPerLine = false, showSettings = false, height = '100vh', secret, baseUrl = 'https://app.twincreator.com', apiUrl = 'https://backend.memori.ai', initialContextVars, initialQuestion, ogImage, sessionID: initialSessionID, tenant, personification, authToken, AZURE_COGNITIVE_SERVICES_TTS_KEY, onStateChange, }) => {
|
|
85
86
|
var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _t, _u, _v;
|
|
86
87
|
const { t, i18n } = (0, react_i18next_1.useTranslation)();
|
|
@@ -107,7 +108,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
107
108
|
const [showPositionDrawer, setShowPositionDrawer] = (0, react_1.useState)(false);
|
|
108
109
|
const [showSettingsDrawer, setShowSettingsDrawer] = (0, react_1.useState)(false);
|
|
109
110
|
const [muteSpeaker, setMuteSpeaker] = (0, react_1.useState)(false);
|
|
110
|
-
const [continuousSpeech, setContinuousSpeech] = (0, react_1.useState)(
|
|
111
|
+
const [continuousSpeech, setContinuousSpeech] = (0, react_1.useState)(true);
|
|
111
112
|
const [continuousSpeechTimeout, setContinuousSpeechTimeout] = (0, react_1.useState)(3);
|
|
112
113
|
const [isPlayingAudio, setIsPlayingAudio] = (0, react_1.useState)(false);
|
|
113
114
|
(0, react_1.useEffect)(() => {
|
|
@@ -115,7 +116,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
115
116
|
}, [speechSynthesizer]);
|
|
116
117
|
(0, react_1.useEffect)(() => {
|
|
117
118
|
setMuteSpeaker((0, configuration_1.getLocalConfig)('muteSpeaker', false));
|
|
118
|
-
setContinuousSpeech((0, configuration_1.getLocalConfig)('continuousSpeech',
|
|
119
|
+
setContinuousSpeech((0, configuration_1.getLocalConfig)('continuousSpeech', true));
|
|
119
120
|
setContinuousSpeechTimeout((0, configuration_1.getLocalConfig)('continuousSpeechTimeout', 3));
|
|
120
121
|
}, []);
|
|
121
122
|
const [memoriPwd, setMemoriPwd] = (0, react_1.useState)(secret);
|
|
@@ -194,6 +195,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
194
195
|
media: currentState.media,
|
|
195
196
|
fromUser: false,
|
|
196
197
|
});
|
|
198
|
+
speak(currentState.emission);
|
|
197
199
|
}
|
|
198
200
|
}
|
|
199
201
|
else {
|
|
@@ -216,6 +218,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
216
218
|
media: currentState.media,
|
|
217
219
|
fromUser: false,
|
|
218
220
|
});
|
|
221
|
+
speak(currentState.emission);
|
|
219
222
|
}
|
|
220
223
|
}
|
|
221
224
|
else {
|
|
@@ -232,28 +235,34 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
232
235
|
emission &&
|
|
233
236
|
!instruct &&
|
|
234
237
|
isMultilanguageEnabled) {
|
|
235
|
-
translateDialogState(currentState, userLang)
|
|
238
|
+
translateDialogState(currentState, userLang).then(ts => {
|
|
239
|
+
if (ts.emission) {
|
|
240
|
+
speak(ts.emission);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
236
243
|
}
|
|
237
244
|
else {
|
|
238
245
|
setCurrentDialogState({
|
|
239
246
|
...currentState,
|
|
240
247
|
emission,
|
|
241
248
|
});
|
|
242
|
-
if (emission)
|
|
249
|
+
if (emission) {
|
|
243
250
|
pushMessage({
|
|
244
251
|
text: emission,
|
|
245
252
|
media: currentState.media,
|
|
246
253
|
fromUser: false,
|
|
247
254
|
});
|
|
255
|
+
speak(emission);
|
|
256
|
+
}
|
|
248
257
|
}
|
|
249
258
|
}
|
|
250
259
|
else if (response.resultCode === 404) {
|
|
251
260
|
setHistory(h => [...h.slice(0, h.length - 1)]);
|
|
252
|
-
reopenSession(false, memoriPwd || memori.secretToken, memoriTokens, instruct && memori.giverTag ? memori.giverTag : undefined, instruct && memori.giverPIN ? memori.giverPIN : undefined, initialContextVars, initialQuestion).then(
|
|
261
|
+
reopenSession(false, memoriPwd || memori.secretToken, memoriTokens, instruct && memori.giverTag ? memori.giverTag : undefined, instruct && memori.giverPIN ? memori.giverPIN : undefined, initialContextVars, initialQuestion).then(state => {
|
|
253
262
|
console.info('session timeout');
|
|
254
|
-
if (sessionID) {
|
|
263
|
+
if (state === null || state === void 0 ? void 0 : state.sessionID) {
|
|
255
264
|
setTimeout(() => {
|
|
256
|
-
sendMessage(text, media, sessionID);
|
|
265
|
+
sendMessage(text, media, state === null || state === void 0 ? void 0 : state.sessionID);
|
|
257
266
|
}, 500);
|
|
258
267
|
}
|
|
259
268
|
});
|
|
@@ -324,7 +333,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
324
333
|
}
|
|
325
334
|
};
|
|
326
335
|
const fetchSession = async (params) => {
|
|
327
|
-
var _a
|
|
336
|
+
var _a;
|
|
328
337
|
if (memori.privacyType !== 'PUBLIC' &&
|
|
329
338
|
!memori.secretToken &&
|
|
330
339
|
!memoriPwd &&
|
|
@@ -346,50 +355,6 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
346
355
|
(session === null || session === void 0 ? void 0 : session.currentState) &&
|
|
347
356
|
session.resultCode === 0) {
|
|
348
357
|
setSessionId(session.sessionID);
|
|
349
|
-
const language = (_f = (_d = (_c = (_b = memori.culture) === null || _b === void 0 ? void 0 : _b.split('-')) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : i18n.language) !== null && _f !== void 0 ? _f : 'IT';
|
|
350
|
-
if (!instruct &&
|
|
351
|
-
isMultilanguageEnabled &&
|
|
352
|
-
userLang.toLowerCase() !== language.toLowerCase()) {
|
|
353
|
-
translateDialogState(session.currentState, userLang).then(state => {
|
|
354
|
-
if (state === null || state === void 0 ? void 0 : state.emission) {
|
|
355
|
-
history.length <= 1
|
|
356
|
-
? setHistory([
|
|
357
|
-
{
|
|
358
|
-
text: state.emission,
|
|
359
|
-
media: state.media,
|
|
360
|
-
fromUser: false,
|
|
361
|
-
initial: true,
|
|
362
|
-
},
|
|
363
|
-
])
|
|
364
|
-
: pushMessage({
|
|
365
|
-
text: state.emission,
|
|
366
|
-
media: state.media,
|
|
367
|
-
fromUser: false,
|
|
368
|
-
initial: true,
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
|
-
else {
|
|
374
|
-
setCurrentDialogState(session.currentState);
|
|
375
|
-
if (session.currentState.emission) {
|
|
376
|
-
history.length <= 1
|
|
377
|
-
? setHistory([
|
|
378
|
-
{
|
|
379
|
-
text: session.currentState.emission,
|
|
380
|
-
media: session.currentState.media,
|
|
381
|
-
fromUser: false,
|
|
382
|
-
initial: true,
|
|
383
|
-
},
|
|
384
|
-
])
|
|
385
|
-
: pushMessage({
|
|
386
|
-
text: session.currentState.emission,
|
|
387
|
-
media: session.currentState.media,
|
|
388
|
-
fromUser: false,
|
|
389
|
-
initial: true,
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
358
|
if (position)
|
|
394
359
|
applyPosition(position, session.sessionID);
|
|
395
360
|
setLoading(false);
|
|
@@ -445,7 +410,10 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
445
410
|
if (position)
|
|
446
411
|
applyPosition(position, sessionID);
|
|
447
412
|
setLoading(false);
|
|
448
|
-
return
|
|
413
|
+
return {
|
|
414
|
+
dialogState: currentState,
|
|
415
|
+
sessionID,
|
|
416
|
+
};
|
|
449
417
|
}
|
|
450
418
|
else {
|
|
451
419
|
console.error(response);
|
|
@@ -568,7 +536,11 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
568
536
|
userLang !== (i18n === null || i18n === void 0 ? void 0 : i18n.language) &&
|
|
569
537
|
emission &&
|
|
570
538
|
emission.length > 0) {
|
|
571
|
-
translateDialogState({ ...currentState, emission: emission }, userLang)
|
|
539
|
+
translateDialogState({ ...currentState, emission: emission }, userLang).then(ts => {
|
|
540
|
+
if (ts.emission) {
|
|
541
|
+
speak(ts.emission);
|
|
542
|
+
}
|
|
543
|
+
});
|
|
572
544
|
}
|
|
573
545
|
else if (emission && emission.length > 0) {
|
|
574
546
|
pushMessage({
|
|
@@ -576,6 +548,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
576
548
|
media: currentState.media,
|
|
577
549
|
fromUser: false,
|
|
578
550
|
});
|
|
551
|
+
speak(emission);
|
|
579
552
|
setCurrentDialogState(currentState);
|
|
580
553
|
}
|
|
581
554
|
}
|
|
@@ -630,39 +603,15 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
630
603
|
if ((0, utils_1.hasTouchscreen)())
|
|
631
604
|
speechConfig.speechSynthesisOutputFormat =
|
|
632
605
|
speechSdk.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3;
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
const context = new standardized_audio_context_1.AudioContext();
|
|
642
|
-
let buffer = context.createBuffer(1, 1, 22050);
|
|
643
|
-
let source = context.createBufferSource();
|
|
644
|
-
source.buffer = buffer;
|
|
645
|
-
source.connect(context.destination);
|
|
646
|
-
}
|
|
647
|
-
catch (e) {
|
|
648
|
-
console.error(e);
|
|
649
|
-
}
|
|
650
|
-
})
|
|
651
|
-
.catch((e) => {
|
|
652
|
-
console.error('error playing intro audio', e);
|
|
653
|
-
});
|
|
654
|
-
}
|
|
606
|
+
audioContext = new standardized_audio_context_1.AudioContext();
|
|
607
|
+
let buffer = audioContext.createBuffer(1, 10000, 22050);
|
|
608
|
+
let source = audioContext.createBufferSource();
|
|
609
|
+
source.buffer = buffer;
|
|
610
|
+
source.connect(audioContext.destination);
|
|
611
|
+
audioDestination = new speechSdk.SpeakerAudioDestination();
|
|
612
|
+
let audioConfig = speechSdk.AudioConfig.fromSpeakerOutput(audioDestination);
|
|
613
|
+
speechSynthesizer = new speechSdk.SpeechSynthesizer(speechConfig, audioConfig);
|
|
655
614
|
};
|
|
656
|
-
(0, react_1.useEffect)(() => {
|
|
657
|
-
return () => {
|
|
658
|
-
if (audioDestination)
|
|
659
|
-
audioDestination.pause();
|
|
660
|
-
if (speechSynthesizer) {
|
|
661
|
-
speechSynthesizer.close();
|
|
662
|
-
speechSynthesizer = null;
|
|
663
|
-
}
|
|
664
|
-
};
|
|
665
|
-
}, []);
|
|
666
615
|
const getTTSVoice = (0, react_1.useCallback)((lang) => {
|
|
667
616
|
var _a, _b, _c, _d;
|
|
668
617
|
let voice = '';
|
|
@@ -717,9 +666,11 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
717
666
|
return voice;
|
|
718
667
|
}, [memori.voiceType, i18n.language, memori.culture]);
|
|
719
668
|
const getCultureCodeByLanguage = (lang) => {
|
|
720
|
-
var _a, _b
|
|
669
|
+
var _a, _b;
|
|
721
670
|
let voice = '';
|
|
722
|
-
let voiceLang = (
|
|
671
|
+
let voiceLang = (lang ||
|
|
672
|
+
((_b = (_a = memori.culture) === null || _a === void 0 ? void 0 : _a.split('-')) === null || _b === void 0 ? void 0 : _b[0]) ||
|
|
673
|
+
i18n.language ||
|
|
723
674
|
'IT').toUpperCase();
|
|
724
675
|
switch (voiceLang) {
|
|
725
676
|
case 'IT':
|
|
@@ -786,45 +737,59 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
786
737
|
}, text);
|
|
787
738
|
return ssmlText;
|
|
788
739
|
};
|
|
789
|
-
const speak = (text
|
|
740
|
+
const speak = (text) => {
|
|
790
741
|
console.log(AZURE_COGNITIVE_SERVICES_TTS_KEY, hasUserActivatedSpeak, preview);
|
|
791
742
|
if (!AZURE_COGNITIVE_SERVICES_TTS_KEY)
|
|
792
743
|
return;
|
|
793
|
-
if (preview
|
|
744
|
+
if (preview)
|
|
794
745
|
return;
|
|
795
746
|
if (audioDestination)
|
|
796
747
|
audioDestination.pause();
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
748
|
+
let isSafari = window.navigator.userAgent.includes('Safari') &&
|
|
749
|
+
!window.navigator.userAgent.includes('Chrome');
|
|
750
|
+
let isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
|
|
751
|
+
if (isIOS && isSafari) {
|
|
752
|
+
audioContext.suspend();
|
|
800
753
|
}
|
|
801
|
-
if (
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
754
|
+
else if (audioContext.state === 'suspended') {
|
|
755
|
+
stopAudio();
|
|
756
|
+
audioContext = new standardized_audio_context_1.AudioContext();
|
|
757
|
+
let buffer = audioContext.createBuffer(1, 10000, 22050);
|
|
758
|
+
let source = audioContext.createBufferSource();
|
|
759
|
+
source.buffer = buffer;
|
|
760
|
+
source.connect(audioContext.destination);
|
|
806
761
|
}
|
|
807
|
-
|
|
762
|
+
if (!speechSynthesizer) {
|
|
763
|
+
audioDestination = new speechSdk.SpeakerAudioDestination();
|
|
764
|
+
let audioConfig = speechSdk.AudioConfig.fromSpeakerOutput(audioDestination);
|
|
765
|
+
speechSynthesizer = new speechSdk.SpeechSynthesizer(speechConfig, audioConfig);
|
|
766
|
+
}
|
|
767
|
+
if (muteSpeaker) {
|
|
768
|
+
if (continuousSpeech) {
|
|
769
|
+
setListeningTimeout();
|
|
770
|
+
}
|
|
808
771
|
return;
|
|
809
772
|
}
|
|
810
|
-
audioDestination = new speechSdk.SpeakerAudioDestination();
|
|
811
|
-
let audioConfig = speechSdk.AudioConfig.fromSpeakerOutput(audioDestination);
|
|
812
|
-
speechSynthesizer = new speechSdk.SpeechSynthesizer(speechConfig, audioConfig);
|
|
813
773
|
audioDestination.onAudioEnd = () => {
|
|
814
774
|
setIsPlayingAudio(false);
|
|
815
|
-
if (
|
|
775
|
+
if (continuousSpeech) {
|
|
816
776
|
document.dispatchEvent(new Event('endSpeakStartListen'));
|
|
817
777
|
}
|
|
818
778
|
};
|
|
819
779
|
setIsPlayingAudio(true);
|
|
820
|
-
console.log('speaking', text);
|
|
821
|
-
console.log('speechSynthesizer', speechSynthesizer);
|
|
822
|
-
console.log('audioDestination', audioDestination);
|
|
823
|
-
console.log('speechConfig', speechConfig);
|
|
824
|
-
console.log('audioConfig', audioConfig);
|
|
825
780
|
speechSynthesizer.speakSsmlAsync(`<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="https://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" xml:lang="${getCultureCodeByLanguage(userLang)}"><voice name="${getTTSVoice(userLang)}"><s>${replaceTextWithPhonemes(text, userLang.toLowerCase())}</s></voice></speak>`, result => {
|
|
826
781
|
if (result) {
|
|
782
|
+
console.log('result', result);
|
|
827
783
|
try {
|
|
784
|
+
audioContext.decodeAudioData(result.audioData, function (buffer) {
|
|
785
|
+
const source = audioContext.createBufferSource();
|
|
786
|
+
source.buffer = buffer;
|
|
787
|
+
source.connect(audioContext.destination);
|
|
788
|
+
if (history.length < 1 || (isSafari && isIOS)) {
|
|
789
|
+
source.start(0);
|
|
790
|
+
}
|
|
791
|
+
});
|
|
792
|
+
audioContext.resume();
|
|
828
793
|
if (speechSynthesizer) {
|
|
829
794
|
speechSynthesizer.close();
|
|
830
795
|
speechSynthesizer = null;
|
|
@@ -834,10 +799,14 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
834
799
|
console.error('speak error: ', e);
|
|
835
800
|
window.speechSynthesis.speak(new SpeechSynthesisUtterance(text));
|
|
836
801
|
setIsPlayingAudio(false);
|
|
802
|
+
if (speechSynthesizer) {
|
|
803
|
+
speechSynthesizer.close();
|
|
804
|
+
speechSynthesizer = null;
|
|
805
|
+
}
|
|
837
806
|
}
|
|
838
807
|
}
|
|
839
808
|
else {
|
|
840
|
-
|
|
809
|
+
audioContext.resume();
|
|
841
810
|
setIsPlayingAudio(false);
|
|
842
811
|
}
|
|
843
812
|
}, error => {
|
|
@@ -846,12 +815,20 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
846
815
|
setIsPlayingAudio(false);
|
|
847
816
|
});
|
|
848
817
|
setIsPlayingAudio(false);
|
|
818
|
+
setMemoriTyping(false);
|
|
849
819
|
};
|
|
850
820
|
const stopAudio = () => {
|
|
851
821
|
if (speechSynthesizer) {
|
|
852
822
|
speechSynthesizer.close();
|
|
853
823
|
speechSynthesizer = null;
|
|
854
824
|
}
|
|
825
|
+
if (audioContext) {
|
|
826
|
+
audioContext.close();
|
|
827
|
+
}
|
|
828
|
+
if (audioDestination) {
|
|
829
|
+
audioDestination.pause();
|
|
830
|
+
audioDestination.close();
|
|
831
|
+
}
|
|
855
832
|
};
|
|
856
833
|
(0, react_1.useEffect)(() => {
|
|
857
834
|
let textarea = document.querySelector('#chat-fieldset textarea');
|
|
@@ -890,11 +867,6 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
890
867
|
(0, react_1.useEffect)(() => {
|
|
891
868
|
resetListeningTimeout();
|
|
892
869
|
resetInteractionTimeout();
|
|
893
|
-
if ((transcript === null || transcript === void 0 ? void 0 : transcript.length) > 0) {
|
|
894
|
-
const transcriptMessage = (0, utils_1.stripDuplicates)(transcript);
|
|
895
|
-
if (transcriptMessage.length > 0)
|
|
896
|
-
setUserMessage(transcriptMessage);
|
|
897
|
-
}
|
|
898
870
|
}, [transcript]);
|
|
899
871
|
const startListening = () => {
|
|
900
872
|
console.log('start listening');
|
|
@@ -920,9 +892,14 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
920
892
|
recognizer = new speechSdk.SpeechRecognizer(speechConfig, audioConfig);
|
|
921
893
|
setListening(true);
|
|
922
894
|
recognizer.recognized = (_s, e) => {
|
|
923
|
-
var _a;
|
|
924
895
|
if (e.result.reason === speechSdk.ResultReason.RecognizedSpeech) {
|
|
925
|
-
|
|
896
|
+
let transcript = e.result.text;
|
|
897
|
+
setTranscript(transcript || '');
|
|
898
|
+
if ((transcript === null || transcript === void 0 ? void 0 : transcript.length) > 0) {
|
|
899
|
+
const transcriptMessage = (0, utils_1.stripDuplicates)(transcript);
|
|
900
|
+
if (transcriptMessage.length > 0)
|
|
901
|
+
setUserMessage(transcriptMessage);
|
|
902
|
+
}
|
|
926
903
|
}
|
|
927
904
|
else if (e.result.reason === speechSdk.ResultReason.NoMatch) {
|
|
928
905
|
console.debug('NOMATCH: Speech could not be recognized.');
|
|
@@ -976,15 +953,6 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
976
953
|
if ((currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.state) === 'Z0')
|
|
977
954
|
clearListening();
|
|
978
955
|
}, [currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.state]);
|
|
979
|
-
(0, react_1.useEffect)(() => {
|
|
980
|
-
if (hasUserActivatedSpeak &&
|
|
981
|
-
!preview &&
|
|
982
|
-
!muteSpeaker &&
|
|
983
|
-
history.length > 0 &&
|
|
984
|
-
(currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.emission)) {
|
|
985
|
-
speak(currentDialogState.emission, currentDialogState.state !== 'Z0');
|
|
986
|
-
}
|
|
987
|
-
}, [currentDialogState, hasUserActivatedSpeak]);
|
|
988
956
|
const [requestedListening, setRequestedListening] = (0, react_1.useState)(false);
|
|
989
957
|
const onEndSpeakStartListen = (0, react_1.useCallback)((_e) => {
|
|
990
958
|
if (isPlayingAudio && speechSynthesizer) {
|
|
@@ -1188,7 +1156,15 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
1188
1156
|
const sessionID = (session === null || session === void 0 ? void 0 : session.sessionID) || sessionId;
|
|
1189
1157
|
const dialogState = (session === null || session === void 0 ? void 0 : session.dialogState) || currentDialogState;
|
|
1190
1158
|
setClickedStart(true);
|
|
1191
|
-
|
|
1159
|
+
let memoriAudioElement = document.getElementById('memori-audio');
|
|
1160
|
+
let isSafari = window.navigator.userAgent.includes('Safari') &&
|
|
1161
|
+
!window.navigator.userAgent.includes('Chrome');
|
|
1162
|
+
if (memoriAudioElement && isSafari) {
|
|
1163
|
+
memoriAudioElement.muted = false;
|
|
1164
|
+
memoriAudioElement.play().catch((e) => {
|
|
1165
|
+
console.error('error playing intro audio', e);
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1192
1168
|
if ((!sessionID &&
|
|
1193
1169
|
memori.privacyType !== 'PUBLIC' &&
|
|
1194
1170
|
!memori.secretToken &&
|
|
@@ -1210,7 +1186,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
1210
1186
|
initialContextVars,
|
|
1211
1187
|
initialQuestion,
|
|
1212
1188
|
});
|
|
1213
|
-
onClickStart(session || undefined);
|
|
1189
|
+
await onClickStart(session || undefined);
|
|
1214
1190
|
return;
|
|
1215
1191
|
}
|
|
1216
1192
|
else if (initialSessionID) {
|
|
@@ -1220,7 +1196,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
1220
1196
|
setGotErrorInOpening(true);
|
|
1221
1197
|
setSessionId(undefined);
|
|
1222
1198
|
setClickedStart(false);
|
|
1223
|
-
onClickStart();
|
|
1199
|
+
await onClickStart();
|
|
1224
1200
|
return;
|
|
1225
1201
|
}
|
|
1226
1202
|
setHistory([]);
|
|
@@ -1232,7 +1208,13 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
1232
1208
|
await changeTag(memori.engineMemoriID, sessionID, '-');
|
|
1233
1209
|
const session = await changeTag(memori.engineMemoriID, sessionID, memori.giverTag, memori.giverPIN);
|
|
1234
1210
|
if (session && session.resultCode === 0) {
|
|
1235
|
-
translateDialogState(session.currentState, userLang)
|
|
1211
|
+
translateDialogState(session.currentState, userLang)
|
|
1212
|
+
.then(ts => {
|
|
1213
|
+
if (ts.emission) {
|
|
1214
|
+
speak(ts.emission);
|
|
1215
|
+
}
|
|
1216
|
+
})
|
|
1217
|
+
.finally(() => {
|
|
1236
1218
|
setHasUserActivatedSpeak(true);
|
|
1237
1219
|
});
|
|
1238
1220
|
}
|
|
@@ -1256,7 +1238,13 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
1256
1238
|
await changeTag(memori.engineMemoriID, sessionID, '-');
|
|
1257
1239
|
const session = await changeTag(memori.engineMemoriID, sessionID, personification.tag, personification.pin);
|
|
1258
1240
|
if (session && session.resultCode === 0) {
|
|
1259
|
-
translateDialogState(session.currentState, userLang)
|
|
1241
|
+
translateDialogState(session.currentState, userLang)
|
|
1242
|
+
.then(ts => {
|
|
1243
|
+
if (ts.emission) {
|
|
1244
|
+
speak(ts.emission);
|
|
1245
|
+
}
|
|
1246
|
+
})
|
|
1247
|
+
.finally(() => {
|
|
1260
1248
|
setHasUserActivatedSpeak(true);
|
|
1261
1249
|
});
|
|
1262
1250
|
}
|
|
@@ -1280,7 +1268,13 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
1280
1268
|
await changeTag(memori.engineMemoriID, sessionID, '-');
|
|
1281
1269
|
const session = await changeTag(memori.engineMemoriID, sessionID, constants_1.anonTag);
|
|
1282
1270
|
if (session && session.resultCode === 0) {
|
|
1283
|
-
translateDialogState(session.currentState, userLang)
|
|
1271
|
+
translateDialogState(session.currentState, userLang)
|
|
1272
|
+
.then(ts => {
|
|
1273
|
+
if (ts.emission) {
|
|
1274
|
+
speak(ts.emission);
|
|
1275
|
+
}
|
|
1276
|
+
})
|
|
1277
|
+
.finally(() => {
|
|
1284
1278
|
setHasUserActivatedSpeak(true);
|
|
1285
1279
|
});
|
|
1286
1280
|
}
|
|
@@ -1297,14 +1291,26 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
1297
1291
|
}
|
|
1298
1292
|
}
|
|
1299
1293
|
else {
|
|
1300
|
-
translateDialogState(currentState, userLang)
|
|
1294
|
+
translateDialogState(currentState, userLang)
|
|
1295
|
+
.then(ts => {
|
|
1296
|
+
if (ts.emission) {
|
|
1297
|
+
speak(ts.emission);
|
|
1298
|
+
}
|
|
1299
|
+
})
|
|
1300
|
+
.finally(() => {
|
|
1301
1301
|
setHasUserActivatedSpeak(true);
|
|
1302
1302
|
});
|
|
1303
1303
|
}
|
|
1304
1304
|
}
|
|
1305
1305
|
else {
|
|
1306
1306
|
setHistory([]);
|
|
1307
|
-
translateDialogState(dialogState, userLang)
|
|
1307
|
+
translateDialogState(dialogState, userLang)
|
|
1308
|
+
.then(ts => {
|
|
1309
|
+
if (ts.emission) {
|
|
1310
|
+
speak(ts.emission);
|
|
1311
|
+
}
|
|
1312
|
+
})
|
|
1313
|
+
.finally(() => {
|
|
1308
1314
|
setHasUserActivatedSpeak(true);
|
|
1309
1315
|
});
|
|
1310
1316
|
}
|
|
@@ -1340,7 +1346,19 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
1340
1346
|
observer.disconnect();
|
|
1341
1347
|
};
|
|
1342
1348
|
}, []);
|
|
1343
|
-
const header = (react_1.default.createElement(Header_1.default, { memori: memori, history: history, showShare: showShare, position: position, setShowPositionDrawer: setShowPositionDrawer, setShowSettingsDrawer: setShowSettingsDrawer, speakerMuted: muteSpeaker, setSpeakerMuted:
|
|
1349
|
+
const header = (react_1.default.createElement(Header_1.default, { memori: memori, history: history, showShare: showShare, position: position, setShowPositionDrawer: setShowPositionDrawer, setShowSettingsDrawer: setShowSettingsDrawer, speakerMuted: muteSpeaker, setSpeakerMuted: mute => {
|
|
1350
|
+
setMuteSpeaker(mute);
|
|
1351
|
+
if (mute) {
|
|
1352
|
+
stopAudio();
|
|
1353
|
+
}
|
|
1354
|
+
else {
|
|
1355
|
+
audioContext = new standardized_audio_context_1.AudioContext();
|
|
1356
|
+
let buffer = audioContext.createBuffer(1, 10000, 22050);
|
|
1357
|
+
let source = audioContext.createBufferSource();
|
|
1358
|
+
source.buffer = buffer;
|
|
1359
|
+
source.connect(audioContext.destination);
|
|
1360
|
+
}
|
|
1361
|
+
}, showSettings: showSettings, hasUserActivatedSpeak: hasUserActivatedSpeak }));
|
|
1344
1362
|
const avatar = (react_1.default.createElement(Avatar_1.default, { memori: memori, integration: integration, integrationConfig: integrationConfig, tenant: tenant, instruct: instruct, avatar3dVisible: avatar3dVisible, setAvatar3dVisible: setAvatar3dVisible, hasUserActivatedSpeak: hasUserActivatedSpeak, isPlayingAudio: isPlayingAudio, baseUrl: baseUrl }));
|
|
1345
1363
|
const startPanel = (react_1.default.createElement(StartPanel_1.default, { memori: memori, tenant: tenant, gamificationLevel: gamificationLevel, language: language, userLang: userLang, setUserLang: setUserLang, baseUrl: baseUrl, position: position, openPositionDrawer: () => setShowPositionDrawer(true), integrationConfig: integrationConfig, instruct: instruct, sessionId: sessionId, clickedStart: clickedStart, onClickStart: onClickStart, initializeTTS: initializeTTS }));
|
|
1346
1364
|
const chat = sessionId ? (react_1.default.createElement(Chat_1.default, { memori: memori, sessionID: sessionId, tenant: tenant, translateTo: isMultilanguageEnabled &&
|
|
@@ -1379,9 +1397,9 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
1379
1397
|
if (values['tokens'])
|
|
1380
1398
|
setMemoriTokens(values['tokens']);
|
|
1381
1399
|
reopenSession(!sessionId, values['password'], values['tokens'], instruct ? memori.giverTag : undefined, instruct ? memori.giverPIN : undefined, initialContextVars, initialQuestion)
|
|
1382
|
-
.then(
|
|
1400
|
+
.then(state => {
|
|
1383
1401
|
setAuthModalState(null);
|
|
1384
|
-
|
|
1402
|
+
onClickStart(state || undefined);
|
|
1385
1403
|
})
|
|
1386
1404
|
.catch(() => {
|
|
1387
1405
|
setAuthModalState(null);
|
|
@@ -1415,6 +1433,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
1415
1433
|
media: currentState.media,
|
|
1416
1434
|
fromUser: false,
|
|
1417
1435
|
});
|
|
1436
|
+
speak(currentState.emission);
|
|
1418
1437
|
}
|
|
1419
1438
|
}
|
|
1420
1439
|
else {
|
|
@@ -1453,6 +1472,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, integration, showInst
|
|
|
1453
1472
|
media: currentState.media,
|
|
1454
1473
|
fromUser: false,
|
|
1455
1474
|
});
|
|
1475
|
+
speak(currentState.emission);
|
|
1456
1476
|
}
|
|
1457
1477
|
}
|
|
1458
1478
|
else {
|