@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
|
@@ -31,7 +31,7 @@ import React, {
|
|
|
31
31
|
} from 'react';
|
|
32
32
|
import { useTranslation } from 'react-i18next';
|
|
33
33
|
import memoriApiClient from '@memori.ai/memori-api-client';
|
|
34
|
-
import { AudioContext } from 'standardized-audio-context';
|
|
34
|
+
import { AudioContext, IAudioContext } from 'standardized-audio-context';
|
|
35
35
|
import * as speechSdk from 'microsoft-cognitiveservices-speech-sdk';
|
|
36
36
|
import cx from 'classnames';
|
|
37
37
|
|
|
@@ -143,6 +143,7 @@ let recognizer: SpeechRecognizer | null;
|
|
|
143
143
|
let speechConfig: SpeechConfig;
|
|
144
144
|
let speechSynthesizer: SpeechSynthesizer | null;
|
|
145
145
|
let audioDestination: SpeakerAudioDestination;
|
|
146
|
+
let audioContext: IAudioContext;
|
|
146
147
|
|
|
147
148
|
export interface Props {
|
|
148
149
|
memori: Memori;
|
|
@@ -254,7 +255,7 @@ const MemoriWidget = ({
|
|
|
254
255
|
const [showPositionDrawer, setShowPositionDrawer] = useState(false);
|
|
255
256
|
const [showSettingsDrawer, setShowSettingsDrawer] = useState(false);
|
|
256
257
|
const [muteSpeaker, setMuteSpeaker] = useState(false);
|
|
257
|
-
const [continuousSpeech, setContinuousSpeech] = useState(
|
|
258
|
+
const [continuousSpeech, setContinuousSpeech] = useState(true);
|
|
258
259
|
const [continuousSpeechTimeout, setContinuousSpeechTimeout] = useState(3);
|
|
259
260
|
const [isPlayingAudio, setIsPlayingAudio] = useState(false);
|
|
260
261
|
useEffect(() => {
|
|
@@ -264,7 +265,7 @@ const MemoriWidget = ({
|
|
|
264
265
|
|
|
265
266
|
useEffect(() => {
|
|
266
267
|
setMuteSpeaker(getLocalConfig('muteSpeaker', false));
|
|
267
|
-
setContinuousSpeech(getLocalConfig('continuousSpeech',
|
|
268
|
+
setContinuousSpeech(getLocalConfig('continuousSpeech', true));
|
|
268
269
|
setContinuousSpeechTimeout(getLocalConfig('continuousSpeechTimeout', 3));
|
|
269
270
|
}, []);
|
|
270
271
|
|
|
@@ -379,6 +380,7 @@ const MemoriWidget = ({
|
|
|
379
380
|
media: currentState.media,
|
|
380
381
|
fromUser: false,
|
|
381
382
|
});
|
|
383
|
+
speak(currentState.emission);
|
|
382
384
|
}
|
|
383
385
|
} else {
|
|
384
386
|
console.error(response, resp);
|
|
@@ -405,6 +407,7 @@ const MemoriWidget = ({
|
|
|
405
407
|
media: currentState.media,
|
|
406
408
|
fromUser: false,
|
|
407
409
|
});
|
|
410
|
+
speak(currentState.emission);
|
|
408
411
|
}
|
|
409
412
|
} else {
|
|
410
413
|
console.error(response, resp);
|
|
@@ -420,19 +423,25 @@ const MemoriWidget = ({
|
|
|
420
423
|
!instruct &&
|
|
421
424
|
isMultilanguageEnabled
|
|
422
425
|
) {
|
|
423
|
-
translateDialogState(currentState, userLang)
|
|
426
|
+
translateDialogState(currentState, userLang).then(ts => {
|
|
427
|
+
if (ts.emission) {
|
|
428
|
+
speak(ts.emission);
|
|
429
|
+
}
|
|
430
|
+
});
|
|
424
431
|
} else {
|
|
425
432
|
setCurrentDialogState({
|
|
426
433
|
...currentState,
|
|
427
434
|
emission,
|
|
428
435
|
});
|
|
429
436
|
|
|
430
|
-
if (emission)
|
|
437
|
+
if (emission) {
|
|
431
438
|
pushMessage({
|
|
432
439
|
text: emission,
|
|
433
440
|
media: currentState.media,
|
|
434
441
|
fromUser: false,
|
|
435
442
|
});
|
|
443
|
+
speak(emission);
|
|
444
|
+
}
|
|
436
445
|
}
|
|
437
446
|
} else if (response.resultCode === 404) {
|
|
438
447
|
// remove last sent message, will set it as initial
|
|
@@ -447,15 +456,16 @@ const MemoriWidget = ({
|
|
|
447
456
|
instruct && memori.giverPIN ? memori.giverPIN : undefined,
|
|
448
457
|
initialContextVars,
|
|
449
458
|
initialQuestion
|
|
450
|
-
).then(
|
|
459
|
+
).then(state => {
|
|
451
460
|
console.info('session timeout');
|
|
452
|
-
if (sessionID) {
|
|
461
|
+
if (state?.sessionID) {
|
|
453
462
|
setTimeout(() => {
|
|
454
|
-
sendMessage(text, media, sessionID);
|
|
463
|
+
sendMessage(text, media, state?.sessionID);
|
|
455
464
|
}, 500);
|
|
456
465
|
}
|
|
457
466
|
});
|
|
458
467
|
}
|
|
468
|
+
|
|
459
469
|
setMemoriTyping(false);
|
|
460
470
|
};
|
|
461
471
|
|
|
@@ -577,53 +587,6 @@ const MemoriWidget = ({
|
|
|
577
587
|
session.resultCode === 0
|
|
578
588
|
) {
|
|
579
589
|
setSessionId(session.sessionID);
|
|
580
|
-
const language =
|
|
581
|
-
memori.culture?.split('-')?.[0] ?? i18n.language ?? 'IT';
|
|
582
|
-
|
|
583
|
-
if (
|
|
584
|
-
!instruct &&
|
|
585
|
-
isMultilanguageEnabled &&
|
|
586
|
-
userLang.toLowerCase() !== language.toLowerCase()
|
|
587
|
-
) {
|
|
588
|
-
translateDialogState(session.currentState, userLang).then(state => {
|
|
589
|
-
if (state?.emission) {
|
|
590
|
-
history.length <= 1
|
|
591
|
-
? setHistory([
|
|
592
|
-
{
|
|
593
|
-
text: state.emission,
|
|
594
|
-
media: state.media,
|
|
595
|
-
fromUser: false,
|
|
596
|
-
initial: true,
|
|
597
|
-
},
|
|
598
|
-
])
|
|
599
|
-
: pushMessage({
|
|
600
|
-
text: state.emission,
|
|
601
|
-
media: state.media,
|
|
602
|
-
fromUser: false,
|
|
603
|
-
initial: true,
|
|
604
|
-
});
|
|
605
|
-
}
|
|
606
|
-
});
|
|
607
|
-
} else {
|
|
608
|
-
setCurrentDialogState(session.currentState);
|
|
609
|
-
if (session.currentState.emission) {
|
|
610
|
-
history.length <= 1
|
|
611
|
-
? setHistory([
|
|
612
|
-
{
|
|
613
|
-
text: session.currentState.emission,
|
|
614
|
-
media: session.currentState.media,
|
|
615
|
-
fromUser: false,
|
|
616
|
-
initial: true,
|
|
617
|
-
},
|
|
618
|
-
])
|
|
619
|
-
: pushMessage({
|
|
620
|
-
text: session.currentState.emission,
|
|
621
|
-
media: session.currentState.media,
|
|
622
|
-
fromUser: false,
|
|
623
|
-
initial: true,
|
|
624
|
-
});
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
590
|
|
|
628
591
|
if (position) applyPosition(position, session.sessionID);
|
|
629
592
|
|
|
@@ -688,7 +651,10 @@ const MemoriWidget = ({
|
|
|
688
651
|
if (position) applyPosition(position, sessionID);
|
|
689
652
|
|
|
690
653
|
setLoading(false);
|
|
691
|
-
return
|
|
654
|
+
return {
|
|
655
|
+
dialogState: currentState,
|
|
656
|
+
sessionID,
|
|
657
|
+
};
|
|
692
658
|
} else {
|
|
693
659
|
console.error(response);
|
|
694
660
|
message.error(t(getErrori18nKey(response.resultCode)));
|
|
@@ -721,7 +687,6 @@ const MemoriWidget = ({
|
|
|
721
687
|
|
|
722
688
|
if (resultCode === 0) {
|
|
723
689
|
let textResult = 0;
|
|
724
|
-
// console.debug('[APPCONTEXT/CHANGETAG]', currentState);
|
|
725
690
|
if (
|
|
726
691
|
tag !== anonTag &&
|
|
727
692
|
pin &&
|
|
@@ -846,13 +811,18 @@ const MemoriWidget = ({
|
|
|
846
811
|
translateDialogState(
|
|
847
812
|
{ ...currentState, emission: emission },
|
|
848
813
|
userLang
|
|
849
|
-
)
|
|
814
|
+
).then(ts => {
|
|
815
|
+
if (ts.emission) {
|
|
816
|
+
speak(ts.emission);
|
|
817
|
+
}
|
|
818
|
+
});
|
|
850
819
|
} else if (emission && emission.length > 0) {
|
|
851
820
|
pushMessage({
|
|
852
821
|
text: emission,
|
|
853
822
|
media: currentState.media,
|
|
854
823
|
fromUser: false,
|
|
855
824
|
});
|
|
825
|
+
speak(emission);
|
|
856
826
|
setCurrentDialogState(currentState);
|
|
857
827
|
}
|
|
858
828
|
}
|
|
@@ -916,40 +886,19 @@ const MemoriWidget = ({
|
|
|
916
886
|
speechConfig.speechSynthesisOutputFormat =
|
|
917
887
|
speechSdk.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3;
|
|
918
888
|
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
let source = context.createBufferSource();
|
|
932
|
-
source.buffer = buffer;
|
|
933
|
-
source.connect(context.destination);
|
|
934
|
-
} catch (e) {
|
|
935
|
-
console.error(e);
|
|
936
|
-
}
|
|
937
|
-
})
|
|
938
|
-
.catch((e: any) => {
|
|
939
|
-
console.error('error playing intro audio', e);
|
|
940
|
-
});
|
|
941
|
-
}
|
|
889
|
+
audioContext = new AudioContext();
|
|
890
|
+
let buffer = audioContext.createBuffer(1, 10000, 22050);
|
|
891
|
+
let source = audioContext.createBufferSource();
|
|
892
|
+
source.buffer = buffer;
|
|
893
|
+
source.connect(audioContext.destination);
|
|
894
|
+
|
|
895
|
+
audioDestination = new speechSdk.SpeakerAudioDestination();
|
|
896
|
+
let audioConfig = speechSdk.AudioConfig.fromSpeakerOutput(audioDestination);
|
|
897
|
+
speechSynthesizer = new speechSdk.SpeechSynthesizer(
|
|
898
|
+
speechConfig,
|
|
899
|
+
audioConfig
|
|
900
|
+
);
|
|
942
901
|
};
|
|
943
|
-
useEffect(() => {
|
|
944
|
-
return () => {
|
|
945
|
-
if (audioDestination) audioDestination.pause();
|
|
946
|
-
if (speechSynthesizer) {
|
|
947
|
-
speechSynthesizer.close();
|
|
948
|
-
speechSynthesizer = null;
|
|
949
|
-
}
|
|
950
|
-
};
|
|
951
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
952
|
-
}, []);
|
|
953
902
|
|
|
954
903
|
const getTTSVoice = useCallback(
|
|
955
904
|
(lang?: string): string => {
|
|
@@ -1032,8 +981,12 @@ const MemoriWidget = ({
|
|
|
1032
981
|
|
|
1033
982
|
const getCultureCodeByLanguage = (lang?: string): string => {
|
|
1034
983
|
let voice = '';
|
|
1035
|
-
let voiceLang = (
|
|
1036
|
-
|
|
984
|
+
let voiceLang = (
|
|
985
|
+
lang ||
|
|
986
|
+
memori.culture?.split('-')?.[0] ||
|
|
987
|
+
i18n.language ||
|
|
988
|
+
'IT'
|
|
989
|
+
).toUpperCase();
|
|
1037
990
|
switch (voiceLang) {
|
|
1038
991
|
case 'IT':
|
|
1039
992
|
voice = 'it-IT';
|
|
@@ -1121,7 +1074,7 @@ const MemoriWidget = ({
|
|
|
1121
1074
|
// .replace(/qfe/gi, `<sub alias="Quota Filo Erba">QFE</sub>`)
|
|
1122
1075
|
};
|
|
1123
1076
|
|
|
1124
|
-
const speak = (text: string
|
|
1077
|
+
const speak = (text: string): void => {
|
|
1125
1078
|
console.log(
|
|
1126
1079
|
AZURE_COGNITIVE_SERVICES_TTS_KEY,
|
|
1127
1080
|
hasUserActivatedSpeak,
|
|
@@ -1129,59 +1082,54 @@ const MemoriWidget = ({
|
|
|
1129
1082
|
);
|
|
1130
1083
|
if (!AZURE_COGNITIVE_SERVICES_TTS_KEY) return;
|
|
1131
1084
|
|
|
1132
|
-
if (preview
|
|
1085
|
+
if (preview) return;
|
|
1086
|
+
|
|
1133
1087
|
if (audioDestination) audioDestination.pause();
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1088
|
+
|
|
1089
|
+
let isSafari =
|
|
1090
|
+
window.navigator.userAgent.includes('Safari') &&
|
|
1091
|
+
!window.navigator.userAgent.includes('Chrome');
|
|
1092
|
+
let isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
|
|
1093
|
+
if (isIOS && isSafari) {
|
|
1094
|
+
audioContext.suspend();
|
|
1095
|
+
} else if (audioContext.state === 'suspended') {
|
|
1096
|
+
stopAudio();
|
|
1097
|
+
audioContext = new AudioContext();
|
|
1098
|
+
let buffer = audioContext.createBuffer(1, 10000, 22050);
|
|
1099
|
+
let source = audioContext.createBufferSource();
|
|
1100
|
+
source.buffer = buffer;
|
|
1101
|
+
source.connect(audioContext.destination);
|
|
1137
1102
|
}
|
|
1138
1103
|
|
|
1139
|
-
if (
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1104
|
+
if (!speechSynthesizer) {
|
|
1105
|
+
audioDestination = new speechSdk.SpeakerAudioDestination();
|
|
1106
|
+
let audioConfig =
|
|
1107
|
+
speechSdk.AudioConfig.fromSpeakerOutput(audioDestination);
|
|
1108
|
+
speechSynthesizer = new speechSdk.SpeechSynthesizer(
|
|
1109
|
+
speechConfig,
|
|
1110
|
+
audioConfig
|
|
1111
|
+
);
|
|
1147
1112
|
}
|
|
1148
1113
|
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1114
|
+
if (muteSpeaker) {
|
|
1115
|
+
// trigger start continuous listening if set, see MemoriChat
|
|
1116
|
+
if (continuousSpeech) {
|
|
1117
|
+
setListeningTimeout();
|
|
1118
|
+
}
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1155
1121
|
|
|
1156
1122
|
audioDestination.onAudioEnd = () => {
|
|
1157
1123
|
setIsPlayingAudio(false);
|
|
1158
1124
|
|
|
1159
|
-
if (
|
|
1160
|
-
// trigger start continuous listening if set
|
|
1125
|
+
if (continuousSpeech) {
|
|
1126
|
+
// trigger start continuous listening if set
|
|
1161
1127
|
document.dispatchEvent(new Event('endSpeakStartListen'));
|
|
1162
1128
|
}
|
|
1163
1129
|
};
|
|
1164
1130
|
|
|
1165
|
-
// speechSynthesizer.visemeReceived = function (s, e) {
|
|
1166
|
-
// window.console.log(
|
|
1167
|
-
// '(Viseme), Audio offset: ' +
|
|
1168
|
-
// e.audioOffset / 10000 +
|
|
1169
|
-
// 'ms. Viseme ID: ' +
|
|
1170
|
-
// e.visemeId,
|
|
1171
|
-
// e,
|
|
1172
|
-
// );
|
|
1173
|
-
|
|
1174
|
-
// // `Animation` is an xml string for SVG or a json string for blend shapes
|
|
1175
|
-
// // var animation = e.Animation;
|
|
1176
|
-
// };
|
|
1177
|
-
|
|
1178
1131
|
setIsPlayingAudio(true);
|
|
1179
|
-
|
|
1180
|
-
console.log('speechSynthesizer', speechSynthesizer);
|
|
1181
|
-
console.log('audioDestination', audioDestination);
|
|
1182
|
-
console.log('speechConfig', speechConfig);
|
|
1183
|
-
console.log('audioConfig', audioConfig);
|
|
1184
|
-
// window.speechSynthesis.speak(new SpeechSynthesisUtterance(text));
|
|
1132
|
+
|
|
1185
1133
|
speechSynthesizer.speakSsmlAsync(
|
|
1186
1134
|
`<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(
|
|
1187
1135
|
userLang
|
|
@@ -1191,7 +1139,19 @@ const MemoriWidget = ({
|
|
|
1191
1139
|
)}</s></voice></speak>`,
|
|
1192
1140
|
result => {
|
|
1193
1141
|
if (result) {
|
|
1142
|
+
console.log('result', result);
|
|
1194
1143
|
try {
|
|
1144
|
+
audioContext.decodeAudioData(result.audioData, function (buffer) {
|
|
1145
|
+
const source = audioContext.createBufferSource();
|
|
1146
|
+
source.buffer = buffer;
|
|
1147
|
+
source.connect(audioContext.destination);
|
|
1148
|
+
|
|
1149
|
+
if (history.length < 1 || (isSafari && isIOS)) {
|
|
1150
|
+
source.start(0);
|
|
1151
|
+
}
|
|
1152
|
+
});
|
|
1153
|
+
audioContext.resume();
|
|
1154
|
+
|
|
1195
1155
|
if (speechSynthesizer) {
|
|
1196
1156
|
speechSynthesizer.close();
|
|
1197
1157
|
speechSynthesizer = null;
|
|
@@ -1200,9 +1160,14 @@ const MemoriWidget = ({
|
|
|
1200
1160
|
console.error('speak error: ', e);
|
|
1201
1161
|
window.speechSynthesis.speak(new SpeechSynthesisUtterance(text));
|
|
1202
1162
|
setIsPlayingAudio(false);
|
|
1163
|
+
|
|
1164
|
+
if (speechSynthesizer) {
|
|
1165
|
+
speechSynthesizer.close();
|
|
1166
|
+
speechSynthesizer = null;
|
|
1167
|
+
}
|
|
1203
1168
|
}
|
|
1204
1169
|
} else {
|
|
1205
|
-
|
|
1170
|
+
audioContext.resume();
|
|
1206
1171
|
setIsPlayingAudio(false);
|
|
1207
1172
|
}
|
|
1208
1173
|
},
|
|
@@ -1214,12 +1179,20 @@ const MemoriWidget = ({
|
|
|
1214
1179
|
);
|
|
1215
1180
|
|
|
1216
1181
|
setIsPlayingAudio(false);
|
|
1182
|
+
setMemoriTyping(false);
|
|
1217
1183
|
};
|
|
1218
1184
|
const stopAudio = () => {
|
|
1219
1185
|
if (speechSynthesizer) {
|
|
1220
1186
|
speechSynthesizer.close();
|
|
1221
1187
|
speechSynthesizer = null;
|
|
1222
1188
|
}
|
|
1189
|
+
if (audioContext) {
|
|
1190
|
+
audioContext.close();
|
|
1191
|
+
}
|
|
1192
|
+
if (audioDestination) {
|
|
1193
|
+
audioDestination.pause();
|
|
1194
|
+
audioDestination.close();
|
|
1195
|
+
}
|
|
1223
1196
|
};
|
|
1224
1197
|
|
|
1225
1198
|
/**
|
|
@@ -1271,10 +1244,7 @@ const MemoriWidget = ({
|
|
|
1271
1244
|
useEffect(() => {
|
|
1272
1245
|
resetListeningTimeout();
|
|
1273
1246
|
resetInteractionTimeout();
|
|
1274
|
-
|
|
1275
|
-
const transcriptMessage = stripDuplicates(transcript);
|
|
1276
|
-
if (transcriptMessage.length > 0) setUserMessage(transcriptMessage);
|
|
1277
|
-
}
|
|
1247
|
+
|
|
1278
1248
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1279
1249
|
}, [transcript]);
|
|
1280
1250
|
|
|
@@ -1317,7 +1287,13 @@ const MemoriWidget = ({
|
|
|
1317
1287
|
setListening(true);
|
|
1318
1288
|
recognizer.recognized = (_s, e) => {
|
|
1319
1289
|
if (e.result.reason === speechSdk.ResultReason.RecognizedSpeech) {
|
|
1320
|
-
|
|
1290
|
+
let transcript = e.result.text;
|
|
1291
|
+
setTranscript(transcript || '');
|
|
1292
|
+
if (transcript?.length > 0) {
|
|
1293
|
+
const transcriptMessage = stripDuplicates(transcript);
|
|
1294
|
+
if (transcriptMessage.length > 0)
|
|
1295
|
+
setUserMessage(transcriptMessage);
|
|
1296
|
+
}
|
|
1321
1297
|
} else if (e.result.reason === speechSdk.ResultReason.NoMatch) {
|
|
1322
1298
|
console.debug('NOMATCH: Speech could not be recognized.');
|
|
1323
1299
|
}
|
|
@@ -1374,19 +1350,6 @@ const MemoriWidget = ({
|
|
|
1374
1350
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1375
1351
|
}, [currentDialogState?.state]);
|
|
1376
1352
|
|
|
1377
|
-
useEffect(() => {
|
|
1378
|
-
if (
|
|
1379
|
-
hasUserActivatedSpeak &&
|
|
1380
|
-
!preview &&
|
|
1381
|
-
!muteSpeaker &&
|
|
1382
|
-
history.length > 0 &&
|
|
1383
|
-
currentDialogState?.emission
|
|
1384
|
-
) {
|
|
1385
|
-
speak(currentDialogState.emission, currentDialogState.state !== 'Z0');
|
|
1386
|
-
}
|
|
1387
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1388
|
-
}, [currentDialogState, hasUserActivatedSpeak]);
|
|
1389
|
-
|
|
1390
1353
|
/**
|
|
1391
1354
|
* Speech recognition event handlers
|
|
1392
1355
|
*/
|
|
@@ -1658,7 +1621,19 @@ const MemoriWidget = ({
|
|
|
1658
1621
|
const sessionID = session?.sessionID || sessionId;
|
|
1659
1622
|
const dialogState = session?.dialogState || currentDialogState;
|
|
1660
1623
|
setClickedStart(true);
|
|
1661
|
-
|
|
1624
|
+
|
|
1625
|
+
let memoriAudioElement = document.getElementById(
|
|
1626
|
+
'memori-audio'
|
|
1627
|
+
) as HTMLAudioElement;
|
|
1628
|
+
let isSafari =
|
|
1629
|
+
window.navigator.userAgent.includes('Safari') &&
|
|
1630
|
+
!window.navigator.userAgent.includes('Chrome');
|
|
1631
|
+
if (memoriAudioElement && isSafari) {
|
|
1632
|
+
memoriAudioElement.muted = false;
|
|
1633
|
+
memoriAudioElement.play().catch((e: any) => {
|
|
1634
|
+
console.error('error playing intro audio', e);
|
|
1635
|
+
});
|
|
1636
|
+
}
|
|
1662
1637
|
|
|
1663
1638
|
if (
|
|
1664
1639
|
(!sessionID &&
|
|
@@ -1682,7 +1657,7 @@ const MemoriWidget = ({
|
|
|
1682
1657
|
initialContextVars,
|
|
1683
1658
|
initialQuestion,
|
|
1684
1659
|
});
|
|
1685
|
-
onClickStart(session || undefined);
|
|
1660
|
+
await onClickStart(session || undefined);
|
|
1686
1661
|
return;
|
|
1687
1662
|
} else if (initialSessionID) {
|
|
1688
1663
|
// check if session is valid and not expired
|
|
@@ -1692,7 +1667,7 @@ const MemoriWidget = ({
|
|
|
1692
1667
|
setGotErrorInOpening(true);
|
|
1693
1668
|
setSessionId(undefined);
|
|
1694
1669
|
setClickedStart(false);
|
|
1695
|
-
onClickStart();
|
|
1670
|
+
await onClickStart();
|
|
1696
1671
|
return;
|
|
1697
1672
|
}
|
|
1698
1673
|
|
|
@@ -1722,9 +1697,15 @@ const MemoriWidget = ({
|
|
|
1722
1697
|
);
|
|
1723
1698
|
|
|
1724
1699
|
if (session && session.resultCode === 0) {
|
|
1725
|
-
translateDialogState(session.currentState, userLang)
|
|
1726
|
-
|
|
1727
|
-
|
|
1700
|
+
translateDialogState(session.currentState, userLang)
|
|
1701
|
+
.then(ts => {
|
|
1702
|
+
if (ts.emission) {
|
|
1703
|
+
speak(ts.emission);
|
|
1704
|
+
}
|
|
1705
|
+
})
|
|
1706
|
+
.finally(() => {
|
|
1707
|
+
setHasUserActivatedSpeak(true);
|
|
1708
|
+
});
|
|
1728
1709
|
} else {
|
|
1729
1710
|
console.error('session #1', session);
|
|
1730
1711
|
throw new Error('No session');
|
|
@@ -1762,9 +1743,15 @@ const MemoriWidget = ({
|
|
|
1762
1743
|
);
|
|
1763
1744
|
|
|
1764
1745
|
if (session && session.resultCode === 0) {
|
|
1765
|
-
translateDialogState(session.currentState, userLang)
|
|
1766
|
-
|
|
1767
|
-
|
|
1746
|
+
translateDialogState(session.currentState, userLang)
|
|
1747
|
+
.then(ts => {
|
|
1748
|
+
if (ts.emission) {
|
|
1749
|
+
speak(ts.emission);
|
|
1750
|
+
}
|
|
1751
|
+
})
|
|
1752
|
+
.finally(() => {
|
|
1753
|
+
setHasUserActivatedSpeak(true);
|
|
1754
|
+
});
|
|
1768
1755
|
} else {
|
|
1769
1756
|
console.error('session #4', session);
|
|
1770
1757
|
throw new Error('No session');
|
|
@@ -1802,9 +1789,15 @@ const MemoriWidget = ({
|
|
|
1802
1789
|
);
|
|
1803
1790
|
|
|
1804
1791
|
if (session && session.resultCode === 0) {
|
|
1805
|
-
translateDialogState(session.currentState, userLang)
|
|
1806
|
-
|
|
1807
|
-
|
|
1792
|
+
translateDialogState(session.currentState, userLang)
|
|
1793
|
+
.then(ts => {
|
|
1794
|
+
if (ts.emission) {
|
|
1795
|
+
speak(ts.emission);
|
|
1796
|
+
}
|
|
1797
|
+
})
|
|
1798
|
+
.finally(() => {
|
|
1799
|
+
setHasUserActivatedSpeak(true);
|
|
1800
|
+
});
|
|
1808
1801
|
} else {
|
|
1809
1802
|
console.error('session #7', session);
|
|
1810
1803
|
throw new Error('No session');
|
|
@@ -1825,18 +1818,30 @@ const MemoriWidget = ({
|
|
|
1825
1818
|
}
|
|
1826
1819
|
} else {
|
|
1827
1820
|
// no need to change tag
|
|
1828
|
-
translateDialogState(currentState, userLang)
|
|
1829
|
-
|
|
1830
|
-
|
|
1821
|
+
translateDialogState(currentState, userLang)
|
|
1822
|
+
.then(ts => {
|
|
1823
|
+
if (ts.emission) {
|
|
1824
|
+
speak(ts.emission);
|
|
1825
|
+
}
|
|
1826
|
+
})
|
|
1827
|
+
.finally(() => {
|
|
1828
|
+
setHasUserActivatedSpeak(true);
|
|
1829
|
+
});
|
|
1831
1830
|
}
|
|
1832
1831
|
} else {
|
|
1833
1832
|
// reset history
|
|
1834
1833
|
setHistory([]);
|
|
1835
1834
|
|
|
1836
1835
|
// everything is fine, just translate dialog state and activate chat
|
|
1837
|
-
translateDialogState(dialogState!, userLang)
|
|
1838
|
-
|
|
1839
|
-
|
|
1836
|
+
translateDialogState(dialogState!, userLang)
|
|
1837
|
+
.then(ts => {
|
|
1838
|
+
if (ts.emission) {
|
|
1839
|
+
speak(ts.emission);
|
|
1840
|
+
}
|
|
1841
|
+
})
|
|
1842
|
+
.finally(() => {
|
|
1843
|
+
setHasUserActivatedSpeak(true);
|
|
1844
|
+
});
|
|
1840
1845
|
}
|
|
1841
1846
|
};
|
|
1842
1847
|
|
|
@@ -1890,7 +1895,18 @@ const MemoriWidget = ({
|
|
|
1890
1895
|
setShowPositionDrawer={setShowPositionDrawer}
|
|
1891
1896
|
setShowSettingsDrawer={setShowSettingsDrawer}
|
|
1892
1897
|
speakerMuted={muteSpeaker}
|
|
1893
|
-
setSpeakerMuted={
|
|
1898
|
+
setSpeakerMuted={mute => {
|
|
1899
|
+
setMuteSpeaker(mute);
|
|
1900
|
+
if (mute) {
|
|
1901
|
+
stopAudio();
|
|
1902
|
+
} else {
|
|
1903
|
+
audioContext = new AudioContext();
|
|
1904
|
+
let buffer = audioContext.createBuffer(1, 10000, 22050);
|
|
1905
|
+
let source = audioContext.createBufferSource();
|
|
1906
|
+
source.buffer = buffer;
|
|
1907
|
+
source.connect(audioContext.destination);
|
|
1908
|
+
}
|
|
1909
|
+
}}
|
|
1894
1910
|
showSettings={showSettings}
|
|
1895
1911
|
hasUserActivatedSpeak={hasUserActivatedSpeak}
|
|
1896
1912
|
/>
|
|
@@ -2070,9 +2086,9 @@ const MemoriWidget = ({
|
|
|
2070
2086
|
initialContextVars,
|
|
2071
2087
|
initialQuestion
|
|
2072
2088
|
)
|
|
2073
|
-
.then(
|
|
2089
|
+
.then(state => {
|
|
2074
2090
|
setAuthModalState(null);
|
|
2075
|
-
|
|
2091
|
+
onClickStart(state || undefined);
|
|
2076
2092
|
})
|
|
2077
2093
|
.catch(() => {
|
|
2078
2094
|
setAuthModalState(null);
|
|
@@ -2119,6 +2135,7 @@ const MemoriWidget = ({
|
|
|
2119
2135
|
media: currentState.media,
|
|
2120
2136
|
fromUser: false,
|
|
2121
2137
|
});
|
|
2138
|
+
speak(currentState.emission);
|
|
2122
2139
|
}
|
|
2123
2140
|
} else {
|
|
2124
2141
|
console.error(resp, currentState, medium);
|
|
@@ -2174,6 +2191,7 @@ const MemoriWidget = ({
|
|
|
2174
2191
|
media: currentState.media,
|
|
2175
2192
|
fromUser: false,
|
|
2176
2193
|
});
|
|
2194
|
+
speak(currentState.emission);
|
|
2177
2195
|
}
|
|
2178
2196
|
} else {
|
|
2179
2197
|
console.error(resp, currentState, medium);
|
|
@@ -213,6 +213,9 @@ const StartPanel: React.FC<Props> = ({
|
|
|
213
213
|
disabled={!!memori.blockedUntil && !memori.isGiver}
|
|
214
214
|
loading={clickedStart}
|
|
215
215
|
onClick={_e => {
|
|
216
|
+
speechSynthesis.speak(
|
|
217
|
+
new SpeechSynthesisUtterance('') // This is needed to enable the speech synthesis on iOS
|
|
218
|
+
);
|
|
216
219
|
if (initializeTTS) initializeTTS();
|
|
217
220
|
if (onClickStart) onClickStart();
|
|
218
221
|
}}
|