@memori.ai/memori-react 2.9.2 → 2.10.1

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 (32) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/components/ChatBubble/ChatBubble.js +31 -31
  3. package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
  4. package/dist/components/MemoriWidget/MemoriWidget.d.ts +16 -1
  5. package/dist/components/MemoriWidget/MemoriWidget.js +242 -226
  6. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  7. package/dist/components/StartPanel/StartPanel.js +6 -1
  8. package/dist/components/StartPanel/StartPanel.js.map +1 -1
  9. package/dist/helpers/utils.d.ts +1 -0
  10. package/dist/helpers/utils.js +5 -1
  11. package/dist/helpers/utils.js.map +1 -1
  12. package/dist/helpers/utils.test.js +12 -0
  13. package/dist/helpers/utils.test.js.map +1 -1
  14. package/esm/components/ChatBubble/ChatBubble.js +31 -31
  15. package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
  16. package/esm/components/MemoriWidget/MemoriWidget.d.ts +16 -1
  17. package/esm/components/MemoriWidget/MemoriWidget.js +243 -227
  18. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  19. package/esm/components/StartPanel/StartPanel.js +6 -1
  20. package/esm/components/StartPanel/StartPanel.js.map +1 -1
  21. package/esm/helpers/utils.d.ts +1 -0
  22. package/esm/helpers/utils.js +3 -0
  23. package/esm/helpers/utils.js.map +1 -1
  24. package/esm/helpers/utils.test.js +13 -1
  25. package/esm/helpers/utils.test.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/components/ChatBubble/ChatBubble.tsx +1 -1
  28. package/src/components/ChatBubble/__snapshots__/ChatBubble.test.tsx.snap +0 -3
  29. package/src/components/MemoriWidget/MemoriWidget.tsx +353 -292
  30. package/src/components/StartPanel/StartPanel.tsx +8 -3
  31. package/src/helpers/utils.test.ts +15 -1
  32. package/src/helpers/utils.ts +4 -0
@@ -20,7 +20,7 @@ import TotemLayout from '../layouts/Totem';
20
20
  import ChatLayout from '../layouts/Chat';
21
21
  import { getTranslation } from '../../helpers/translations';
22
22
  import { setLocalConfig, getLocalConfig } from '../../helpers/configuration';
23
- import { hasTouchscreen, stripDuplicates } from '../../helpers/utils';
23
+ import { hasTouchscreen, stripDuplicates, stripEmojis, } from '../../helpers/utils';
24
24
  import { anonTag } from '../../helpers/constants';
25
25
  import { getErrori18nKey } from '../../helpers/error';
26
26
  import { getGamificationLevel } from '../../helpers/statistics';
@@ -43,41 +43,20 @@ const getMemoriState = (integrationId) => {
43
43
  let dialogState = JSON.parse(engineState);
44
44
  return dialogState;
45
45
  };
46
- function setNativeValue(element, value) {
47
- var _a, _b, _c, _d;
48
- const valueSetter = (_b = (_a = Object === null || Object === void 0 ? void 0 : Object.getOwnPropertyDescriptor) === null || _a === void 0 ? void 0 : _a.call(Object, element, 'value')) === null || _b === void 0 ? void 0 : _b.set;
49
- const prototype = Object.getPrototypeOf(element);
50
- const prototypeValueSetter = (_d = (_c = Object === null || Object === void 0 ? void 0 : Object.getOwnPropertyDescriptor) === null || _c === void 0 ? void 0 : _c.call(Object, prototype, 'value')) === null || _d === void 0 ? void 0 : _d.set;
51
- if (prototypeValueSetter &&
52
- valueSetter &&
53
- valueSetter !== prototypeValueSetter) {
54
- prototypeValueSetter.call(element, value);
55
- }
56
- else if (valueSetter) {
57
- valueSetter.call(element, value);
58
- }
59
- }
60
- const typeMessage = (message) => {
61
- var _a, _b;
62
- let textarea = document.querySelector('fieldset#chat-fieldset textarea') ||
63
- ((_b = (_a = document
64
- .querySelector('memori-client')) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('fieldset#chat-fieldset textarea'));
65
- if (!textarea)
66
- return;
67
- setNativeValue(textarea, message);
68
- textarea.dispatchEvent(new Event('input', { bubbles: true }));
69
- setTimeout(() => {
70
- var _a, _b;
71
- let sendButton = document.querySelector('button.memori-chat-inputs--send') ||
72
- ((_b = (_a = document
73
- .querySelector('memori-client')) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('button.memori-chat-inputs--send'));
74
- if (!sendButton)
75
- return;
76
- sendButton.click();
77
- }, 100);
46
+ const typeMessage = (message, waitForPrevious = true, hidden = false) => {
47
+ const e = new CustomEvent('MemoriTextEntered', {
48
+ detail: {
49
+ text: message,
50
+ waitForPrevious,
51
+ hidden,
52
+ },
53
+ });
54
+ document.dispatchEvent(e);
78
55
  };
56
+ const typeMessageHidden = (message, waitForPrevious = true) => typeMessage(message, waitForPrevious, true);
79
57
  window.getMemoriState = getMemoriState;
80
58
  window.typeMessage = typeMessage;
59
+ window.typeMessageHidden = typeMessageHidden;
81
60
  let recognizer;
82
61
  let speechConfig;
83
62
  let speechSynthesizer;
@@ -85,6 +64,7 @@ let audioDestination;
85
64
  let audioContext;
86
65
  let memoriPassword;
87
66
  let speakerMuted = false;
67
+ let memoriSpeaking = false;
88
68
  const MemoriWidget = ({ memori, memoriConfigs, memoriLang, multilingual, integration, layout = 'DEFAULT', customLayout, showInstruct = false, showShare, preview = false, embed = false, showInputs = true, showDates = false, showContextPerLine = false, showSettings = true, 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, additionalInfo, additionalSettings, customMediaRenderer, }) => {
89
69
  var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _t, _u, _v, _w, _x, _y;
90
70
  const { t, i18n } = useTranslation();
@@ -120,6 +100,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, multilingual, integra
120
100
  const [hideEmissions, setHideEmissions] = useState(false);
121
101
  useEffect(() => {
122
102
  setIsPlayingAudio(!!speechSynthesizer);
103
+ memoriSpeaking = !!speechSynthesizer;
123
104
  }, [speechSynthesizer]);
124
105
  useEffect(() => {
125
106
  let defaultControlsPosition = 'bottom';
@@ -166,199 +147,6 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, multilingual, integra
166
147
  _setPosition(venue);
167
148
  applyPosition(venue);
168
149
  };
169
- const [userMessage, setUserMessage] = useState('');
170
- const onChangeUserMessage = (value) => {
171
- if (!value || value === '\n' || value.trim() === '') {
172
- setUserMessage('');
173
- resetInteractionTimeout();
174
- return;
175
- }
176
- setUserMessage(value);
177
- clearInteractionTimeout();
178
- };
179
- const [listening, setListening] = useState(false);
180
- const [history, setHistory] = useState([]);
181
- const pushMessage = (message) => {
182
- setHistory(history => [...history, { ...message }]);
183
- };
184
- const sendMessage = async (text, media, newSessionId, translate = true, translatedText) => {
185
- var _a, _b, _c, _d, _f;
186
- if (!sessionId || !(text === null || text === void 0 ? void 0 : text.length))
187
- return;
188
- pushMessage({
189
- text: text,
190
- translatedText,
191
- fromUser: true,
192
- media: media !== null && media !== void 0 ? media : [],
193
- initial: !!newSessionId,
194
- });
195
- setMemoriTyping(true);
196
- const language = (_d = (_c = (_b = (_a = memori.culture) === null || _a === void 0 ? void 0 : _a.split('-')) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : i18n.language) !== null && _d !== void 0 ? _d : 'IT';
197
- let msg = text;
198
- if (translate &&
199
- !instruct &&
200
- isMultilanguageEnabled &&
201
- userLang.toUpperCase() !== language.toUpperCase()) {
202
- const translation = await getTranslation(text, language, userLang, baseUrl);
203
- msg = translation.text;
204
- }
205
- const { currentState, ...response } = await postTextEnteredEvent({
206
- sessionId: newSessionId !== null && newSessionId !== void 0 ? newSessionId : sessionId,
207
- text: msg,
208
- });
209
- if (response.resultCode === 0 && currentState) {
210
- const emission = (_f = currentState.emission) !== null && _f !== void 0 ? _f : currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.emission;
211
- if (currentState.state === 'X4' && memori.giverTag) {
212
- const { currentState, ...resp } = await postTagChangedEvent(sessionId, memori.giverTag);
213
- if (resp.resultCode === 0) {
214
- setCurrentDialogState(currentState);
215
- if (currentState.emission) {
216
- pushMessage({
217
- text: currentState.emission,
218
- media: currentState.media,
219
- fromUser: false,
220
- });
221
- speak(currentState.emission);
222
- }
223
- }
224
- else {
225
- console.error(response, resp);
226
- message.error(t(getErrori18nKey(resp.resultCode)));
227
- }
228
- }
229
- else if (currentState.state === 'X2d' && memori.giverTag) {
230
- const { currentState, ...resp } = await postTextEnteredEvent({
231
- sessionId: newSessionId !== null && newSessionId !== void 0 ? newSessionId : sessionId,
232
- text: Math.random().toString().substring(2, 8),
233
- });
234
- if (resp.resultCode === 0) {
235
- const { currentState, ...resp } = await postTagChangedEvent(sessionId, memori.giverTag);
236
- if (resp.resultCode === 0) {
237
- setCurrentDialogState(currentState);
238
- if (currentState.emission) {
239
- pushMessage({
240
- text: currentState.emission,
241
- media: currentState.media,
242
- fromUser: false,
243
- });
244
- speak(currentState.emission);
245
- }
246
- }
247
- else {
248
- console.error(response, resp);
249
- message.error(t(getErrori18nKey(resp.resultCode)));
250
- }
251
- }
252
- else {
253
- console.error(response, resp);
254
- message.error(t(getErrori18nKey(resp.resultCode)));
255
- }
256
- }
257
- else if (userLang.toLowerCase() !== language.toLowerCase() &&
258
- emission &&
259
- !instruct &&
260
- isMultilanguageEnabled) {
261
- translateDialogState(currentState, userLang).then(ts => {
262
- if (ts.emission) {
263
- speak(ts.emission);
264
- }
265
- });
266
- }
267
- else {
268
- setCurrentDialogState({
269
- ...currentState,
270
- emission,
271
- });
272
- if (emission) {
273
- pushMessage({
274
- text: emission,
275
- media: currentState.media,
276
- fromUser: false,
277
- generatedByAI: !!currentState.completion,
278
- });
279
- speak(emission);
280
- }
281
- }
282
- }
283
- else if (response.resultCode === 404) {
284
- setHistory(h => [...h.slice(0, h.length - 1)]);
285
- reopenSession(false, memoriPwd || memori.secretToken, memoriTokens, instruct && memori.giverTag ? memori.giverTag : undefined, instruct && memori.giverPIN ? memori.giverPIN : undefined, initialContextVars, initialQuestion).then(state => {
286
- console.info('session timeout');
287
- if (state === null || state === void 0 ? void 0 : state.sessionID) {
288
- setTimeout(() => {
289
- sendMessage(text, media, state === null || state === void 0 ? void 0 : state.sessionID);
290
- }, 500);
291
- }
292
- });
293
- }
294
- setMemoriTyping(false);
295
- };
296
- const translateDialogState = async (state, userLang) => {
297
- var _a, _b, _c, _d, _f, _g, _h;
298
- const language = (_d = (_c = (_b = (_a = memori.culture) === null || _a === void 0 ? void 0 : _a.split('-')) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : i18n.language) !== null && _d !== void 0 ? _d : 'IT';
299
- const emission = (_f = state.emission) !== null && _f !== void 0 ? _f : currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.emission;
300
- let translatedState = { ...state };
301
- let translatedMsg = null;
302
- if (!emission ||
303
- instruct ||
304
- language.toUpperCase() === userLang.toUpperCase() ||
305
- !isMultilanguageEnabled) {
306
- translatedState = { ...state, emission };
307
- if (emission) {
308
- translatedMsg = {
309
- text: emission,
310
- media: state.media,
311
- fromUser: false,
312
- };
313
- }
314
- }
315
- else {
316
- const t = await getTranslation(emission, userLang, language, baseUrl);
317
- if (state.hints && state.hints.length > 0) {
318
- const translatedHints = await Promise.all(((_g = state.hints) !== null && _g !== void 0 ? _g : []).map(async (hint) => {
319
- var _a;
320
- const tHint = await getTranslation(hint, userLang, language, baseUrl);
321
- return {
322
- text: (_a = tHint === null || tHint === void 0 ? void 0 : tHint.text) !== null && _a !== void 0 ? _a : hint,
323
- originalText: hint,
324
- };
325
- }));
326
- translatedState = {
327
- ...state,
328
- emission: t.text,
329
- translatedHints,
330
- };
331
- }
332
- else {
333
- translatedState = {
334
- ...state,
335
- emission: t.text,
336
- hints: (_h = state.hints) !== null && _h !== void 0 ? _h : (state.state === 'G1' ? currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.hints : []),
337
- };
338
- }
339
- if (t.text.length > 0)
340
- translatedMsg = {
341
- text: t.text,
342
- media: state.media,
343
- fromUser: false,
344
- generatedByAI: !!state.completion,
345
- };
346
- }
347
- setCurrentDialogState(translatedState);
348
- if (translatedMsg) {
349
- pushMessage(translatedMsg);
350
- }
351
- return translatedState;
352
- };
353
- const minAge = memori.ageRestriction
354
- ? memori.ageRestriction
355
- : memori.nsfw
356
- ? 18
357
- : memori.enableCompletions
358
- ? 14
359
- : 0;
360
- const [birthDate, setBirthDate] = useState();
361
- const [showAgeVerification, setShowAgeVerification] = useState(false);
362
150
  const [sessionId, setSessionId] = useState(initialSessionID);
363
151
  const [currentDialogState, _setCurrentDialogState] = useState();
364
152
  const setCurrentDialogState = (state) => {
@@ -607,6 +395,201 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, multilingual, integra
607
395
  restoreGiverTag();
608
396
  };
609
397
  }, []);
398
+ const [userMessage, setUserMessage] = useState('');
399
+ const onChangeUserMessage = (value) => {
400
+ if (!value || value === '\n' || value.trim() === '') {
401
+ setUserMessage('');
402
+ resetInteractionTimeout();
403
+ return;
404
+ }
405
+ setUserMessage(value);
406
+ clearInteractionTimeout();
407
+ };
408
+ const [listening, setListening] = useState(false);
409
+ const [history, setHistory] = useState([]);
410
+ const pushMessage = (message) => {
411
+ setHistory(history => [...history, { ...message }]);
412
+ };
413
+ const sendMessage = useCallback(async (text, media, newSessionId, translate = true, translatedText, hidden = false) => {
414
+ var _a, _b, _c, _d, _f;
415
+ const sessionID = newSessionId || sessionId;
416
+ if (!sessionID || !(text === null || text === void 0 ? void 0 : text.length))
417
+ return;
418
+ if (!hidden)
419
+ pushMessage({
420
+ text: text,
421
+ translatedText,
422
+ fromUser: true,
423
+ media: media !== null && media !== void 0 ? media : [],
424
+ initial: !!newSessionId,
425
+ });
426
+ setMemoriTyping(true);
427
+ const language = (_d = (_c = (_b = (_a = memori.culture) === null || _a === void 0 ? void 0 : _a.split('-')) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : i18n.language) !== null && _d !== void 0 ? _d : 'IT';
428
+ let msg = text;
429
+ if (translate &&
430
+ !instruct &&
431
+ isMultilanguageEnabled &&
432
+ userLang.toUpperCase() !== language.toUpperCase()) {
433
+ const translation = await getTranslation(text, language, userLang, baseUrl);
434
+ msg = translation.text;
435
+ }
436
+ const { currentState, ...response } = await postTextEnteredEvent({
437
+ sessionId: sessionID,
438
+ text: msg,
439
+ });
440
+ if (response.resultCode === 0 && currentState) {
441
+ const emission = (_f = currentState.emission) !== null && _f !== void 0 ? _f : currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.emission;
442
+ if (currentState.state === 'X4' && memori.giverTag) {
443
+ const { currentState, ...resp } = await postTagChangedEvent(sessionID, memori.giverTag);
444
+ if (resp.resultCode === 0) {
445
+ setCurrentDialogState(currentState);
446
+ if (currentState.emission) {
447
+ pushMessage({
448
+ text: currentState.emission,
449
+ media: currentState.media,
450
+ fromUser: false,
451
+ });
452
+ speak(currentState.emission);
453
+ }
454
+ }
455
+ else {
456
+ console.error(response, resp);
457
+ message.error(t(getErrori18nKey(resp.resultCode)));
458
+ }
459
+ }
460
+ else if (currentState.state === 'X2d' && memori.giverTag) {
461
+ const { currentState, ...resp } = await postTextEnteredEvent({
462
+ sessionId: sessionID,
463
+ text: Math.random().toString().substring(2, 8),
464
+ });
465
+ if (resp.resultCode === 0) {
466
+ const { currentState, ...resp } = await postTagChangedEvent(sessionID, memori.giverTag);
467
+ if (resp.resultCode === 0) {
468
+ setCurrentDialogState(currentState);
469
+ if (currentState.emission) {
470
+ pushMessage({
471
+ text: currentState.emission,
472
+ media: currentState.media,
473
+ fromUser: false,
474
+ });
475
+ speak(currentState.emission);
476
+ }
477
+ }
478
+ else {
479
+ console.error(response, resp);
480
+ message.error(t(getErrori18nKey(resp.resultCode)));
481
+ }
482
+ }
483
+ else {
484
+ console.error(response, resp);
485
+ message.error(t(getErrori18nKey(resp.resultCode)));
486
+ }
487
+ }
488
+ else if (userLang.toLowerCase() !== language.toLowerCase() &&
489
+ emission &&
490
+ !instruct &&
491
+ isMultilanguageEnabled) {
492
+ translateDialogState(currentState, userLang).then(ts => {
493
+ if (ts.emission) {
494
+ speak(ts.emission);
495
+ }
496
+ });
497
+ }
498
+ else {
499
+ setCurrentDialogState({
500
+ ...currentState,
501
+ emission,
502
+ });
503
+ if (emission) {
504
+ pushMessage({
505
+ text: emission,
506
+ media: currentState.media,
507
+ fromUser: false,
508
+ generatedByAI: !!currentState.completion,
509
+ });
510
+ speak(emission);
511
+ }
512
+ }
513
+ }
514
+ else if (response.resultCode === 404) {
515
+ setHistory(h => [...h.slice(0, h.length - 1)]);
516
+ reopenSession(false, memoriPwd || memori.secretToken, memoriTokens, instruct && memori.giverTag ? memori.giverTag : undefined, instruct && memori.giverPIN ? memori.giverPIN : undefined, initialContextVars, initialQuestion).then(state => {
517
+ console.info('session timeout');
518
+ if (state === null || state === void 0 ? void 0 : state.sessionID) {
519
+ setTimeout(() => {
520
+ sendMessage(text, media, state === null || state === void 0 ? void 0 : state.sessionID);
521
+ }, 500);
522
+ }
523
+ });
524
+ }
525
+ setMemoriTyping(false);
526
+ }, [sessionId]);
527
+ const translateDialogState = async (state, userLang) => {
528
+ var _a, _b, _c, _d, _f, _g, _h;
529
+ const language = (_d = (_c = (_b = (_a = memori.culture) === null || _a === void 0 ? void 0 : _a.split('-')) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : i18n.language) !== null && _d !== void 0 ? _d : 'IT';
530
+ const emission = (_f = state.emission) !== null && _f !== void 0 ? _f : currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.emission;
531
+ let translatedState = { ...state };
532
+ let translatedMsg = null;
533
+ if (!emission ||
534
+ instruct ||
535
+ language.toUpperCase() === userLang.toUpperCase() ||
536
+ !isMultilanguageEnabled) {
537
+ translatedState = { ...state, emission };
538
+ if (emission) {
539
+ translatedMsg = {
540
+ text: emission,
541
+ media: state.media,
542
+ fromUser: false,
543
+ };
544
+ }
545
+ }
546
+ else {
547
+ const t = await getTranslation(emission, userLang, language, baseUrl);
548
+ if (state.hints && state.hints.length > 0) {
549
+ const translatedHints = await Promise.all(((_g = state.hints) !== null && _g !== void 0 ? _g : []).map(async (hint) => {
550
+ var _a;
551
+ const tHint = await getTranslation(hint, userLang, language, baseUrl);
552
+ return {
553
+ text: (_a = tHint === null || tHint === void 0 ? void 0 : tHint.text) !== null && _a !== void 0 ? _a : hint,
554
+ originalText: hint,
555
+ };
556
+ }));
557
+ translatedState = {
558
+ ...state,
559
+ emission: t.text,
560
+ translatedHints,
561
+ };
562
+ }
563
+ else {
564
+ translatedState = {
565
+ ...state,
566
+ emission: t.text,
567
+ hints: (_h = state.hints) !== null && _h !== void 0 ? _h : (state.state === 'G1' ? currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.hints : []),
568
+ };
569
+ }
570
+ if (t.text.length > 0)
571
+ translatedMsg = {
572
+ text: t.text,
573
+ media: state.media,
574
+ fromUser: false,
575
+ generatedByAI: !!state.completion,
576
+ };
577
+ }
578
+ setCurrentDialogState(translatedState);
579
+ if (translatedMsg) {
580
+ pushMessage(translatedMsg);
581
+ }
582
+ return translatedState;
583
+ };
584
+ const minAge = memori.ageRestriction
585
+ ? memori.ageRestriction
586
+ : memori.nsfw
587
+ ? 18
588
+ : memori.enableCompletions
589
+ ? 14
590
+ : 0;
591
+ const [birthDate, setBirthDate] = useState();
592
+ const [showAgeVerification, setShowAgeVerification] = useState(false);
610
593
  const [userInteractionTimeout, setUserInteractionTimeout] = useState();
611
594
  const timeoutRef = useRef();
612
595
  const clearInteractionTimeout = () => {
@@ -876,6 +859,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, multilingual, integra
876
859
  if (preview)
877
860
  return;
878
861
  if (muteSpeaker || speakerMuted) {
862
+ memoriSpeaking = false;
879
863
  if (continuousSpeech) {
880
864
  setListeningTimeout();
881
865
  }
@@ -894,6 +878,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, multilingual, integra
894
878
  audioContext.suspend();
895
879
  if (isPlayingAudio) {
896
880
  try {
881
+ memoriSpeaking = false;
897
882
  if (speechSynthesizer) {
898
883
  speechSynthesizer.close();
899
884
  speechSynthesizer = null;
@@ -934,15 +919,18 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, multilingual, integra
934
919
  const source = audioContext.createBufferSource();
935
920
  source.addEventListener('ended', () => {
936
921
  setIsPlayingAudio(false);
922
+ memoriSpeaking = false;
937
923
  });
938
924
  audioDestination.onAudioEnd = () => {
939
925
  setIsPlayingAudio(false);
926
+ memoriSpeaking = false;
940
927
  source.disconnect();
941
928
  onEndSpeakStartListen();
942
929
  };
943
- 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(escapeHTML(text), userLang.toLowerCase())}</s></voice></speak>`, result => {
930
+ 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(escapeHTML(stripEmojis(text)), userLang.toLowerCase())}</s></voice></speak>`, result => {
944
931
  if (result) {
945
932
  setIsPlayingAudio(true);
933
+ memoriSpeaking = true;
946
934
  try {
947
935
  audioContext.decodeAudioData(result.audioData, function (buffer) {
948
936
  source.buffer = buffer;
@@ -956,6 +944,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, multilingual, integra
956
944
  audioContext.state === 'closed') {
957
945
  source.disconnect();
958
946
  setIsPlayingAudio(false);
947
+ memoriSpeaking = false;
959
948
  }
960
949
  else if (audioContext.state === 'interrupted') {
961
950
  audioContext.resume();
@@ -971,6 +960,7 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, multilingual, integra
971
960
  console.error('speak error: ', e);
972
961
  window.speechSynthesis.speak(new SpeechSynthesisUtterance(text));
973
962
  setIsPlayingAudio(false);
963
+ memoriSpeaking = false;
974
964
  if (speechSynthesizer) {
975
965
  speechSynthesizer.close();
976
966
  speechSynthesizer = null;
@@ -980,16 +970,19 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, multilingual, integra
980
970
  else {
981
971
  audioContext.resume();
982
972
  setIsPlayingAudio(false);
973
+ memoriSpeaking = false;
983
974
  }
984
975
  }, error => {
985
976
  console.error('speak:', error);
986
977
  window.speechSynthesis.speak(new SpeechSynthesisUtterance(text));
987
978
  setIsPlayingAudio(false);
979
+ memoriSpeaking = false;
988
980
  });
989
981
  setMemoriTyping(false);
990
982
  };
991
983
  const stopAudio = () => {
992
984
  setIsPlayingAudio(false);
985
+ memoriSpeaking = false;
993
986
  try {
994
987
  if (speechSynthesizer) {
995
988
  speechSynthesizer.close();
@@ -1346,6 +1339,29 @@ const MemoriWidget = ({ memori, memoriConfigs, memoriLang, multilingual, integra
1346
1339
  stopAudio();
1347
1340
  sendMessage(text, undefined, undefined, false, translatedText);
1348
1341
  };
1342
+ const memoriTextEnteredHandler = useCallback((e) => {
1343
+ var _a;
1344
+ const { text, waitForPrevious, hidden } = e.detail;
1345
+ const sessionID = sessionId || ((_a = window.getMemoriState()) === null || _a === void 0 ? void 0 : _a.sessionID);
1346
+ if (text) {
1347
+ if (waitForPrevious &&
1348
+ !speakerMuted &&
1349
+ (memoriSpeaking || memoriTyping)) {
1350
+ setTimeout(() => {
1351
+ memoriTextEnteredHandler(e);
1352
+ }, 1000);
1353
+ }
1354
+ else {
1355
+ sendMessage(text, undefined, sessionID, undefined, undefined, hidden);
1356
+ }
1357
+ }
1358
+ }, [sessionId, isPlayingAudio, memoriTyping]);
1359
+ useEffect(() => {
1360
+ document.addEventListener('MemoriTextEntered', memoriTextEnteredHandler);
1361
+ return () => {
1362
+ document.removeEventListener('MemoriTextEntered', memoriTextEnteredHandler);
1363
+ };
1364
+ }, []);
1349
1365
  const onClickStart = useCallback(async (session) => {
1350
1366
  const sessionID = (session === null || session === void 0 ? void 0 : session.sessionID) || sessionId;
1351
1367
  const dialogState = (session === null || session === void 0 ? void 0 : session.dialogState) || currentDialogState;