@memori.ai/memori-react 2.7.2 → 2.8.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.
- package/CHANGELOG.md +14 -0
- package/README.md +49 -28
- package/dist/components/Chat/Chat.d.ts +2 -0
- package/dist/components/Chat/Chat.js +2 -2
- package/dist/components/Chat/Chat.js.map +1 -1
- package/dist/components/MediaWidget/MediaItemWidget.d.ts +3 -1
- package/dist/components/MediaWidget/MediaItemWidget.js +8 -4
- package/dist/components/MediaWidget/MediaItemWidget.js.map +1 -1
- package/dist/components/MediaWidget/MediaItemWidget.test.js +4 -0
- package/dist/components/MediaWidget/MediaItemWidget.test.js.map +1 -1
- package/dist/components/MediaWidget/MediaWidget.d.ts +2 -0
- package/dist/components/MediaWidget/MediaWidget.js +2 -2
- package/dist/components/MediaWidget/MediaWidget.js.map +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.d.ts +2 -1
- package/dist/components/MemoriWidget/MemoriWidget.js +20 -5
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/esm/components/Chat/Chat.d.ts +2 -0
- package/esm/components/Chat/Chat.js +2 -2
- package/esm/components/Chat/Chat.js.map +1 -1
- package/esm/components/MediaWidget/MediaItemWidget.d.ts +3 -1
- package/esm/components/MediaWidget/MediaItemWidget.js +8 -4
- package/esm/components/MediaWidget/MediaItemWidget.js.map +1 -1
- package/esm/components/MediaWidget/MediaItemWidget.test.js +4 -0
- package/esm/components/MediaWidget/MediaItemWidget.test.js.map +1 -1
- package/esm/components/MediaWidget/MediaWidget.d.ts +2 -0
- package/esm/components/MediaWidget/MediaWidget.js +2 -2
- package/esm/components/MediaWidget/MediaWidget.js.map +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.d.ts +2 -1
- package/esm/components/MemoriWidget/MemoriWidget.js +20 -5
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/index.d.ts +1 -0
- package/esm/index.js +2 -2
- package/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Chat/Chat.tsx +6 -1
- package/src/components/MediaWidget/MediaItemWidget.stories.tsx +25 -0
- package/src/components/MediaWidget/MediaItemWidget.test.tsx +11 -0
- package/src/components/MediaWidget/MediaItemWidget.tsx +12 -0
- package/src/components/MediaWidget/MediaWidget.tsx +4 -1
- package/src/components/MediaWidget/__snapshots__/MediaItemWidget.test.tsx.snap +12 -0
- package/src/components/MemoriWidget/MemoriWidget.stories.tsx +21 -0
- package/src/components/MemoriWidget/MemoriWidget.tsx +173 -150
- package/src/index.tsx +3 -0
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import React, { useEffect, useState } from 'react';
|
|
6
6
|
import Button from '../ui/Button';
|
|
7
7
|
import LinkItemWidget from './LinkItemWidget';
|
|
8
|
-
import MediaItemWidget from './MediaItemWidget';
|
|
8
|
+
import MediaItemWidget, { Props as MediaItemProps } from './MediaItemWidget';
|
|
9
9
|
import { Transition } from '@headlessui/react';
|
|
10
10
|
import cx from 'classnames';
|
|
11
11
|
import { useTranslation } from 'react-i18next';
|
|
@@ -19,6 +19,7 @@ export interface Props {
|
|
|
19
19
|
baseUrl?: string;
|
|
20
20
|
apiUrl?: string;
|
|
21
21
|
translateTo?: string;
|
|
22
|
+
customMediaRenderer?: MediaItemProps['customMediaRenderer'];
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
const MediaWidget: React.FC<Props> = ({
|
|
@@ -30,6 +31,7 @@ const MediaWidget: React.FC<Props> = ({
|
|
|
30
31
|
baseUrl,
|
|
31
32
|
apiUrl,
|
|
32
33
|
translateTo,
|
|
34
|
+
customMediaRenderer,
|
|
33
35
|
}: Props) => {
|
|
34
36
|
const { t } = useTranslation();
|
|
35
37
|
const [showHints, setShowHints] = useState(true);
|
|
@@ -48,6 +50,7 @@ const MediaWidget: React.FC<Props> = ({
|
|
|
48
50
|
translateTo={translateTo}
|
|
49
51
|
baseURL={baseUrl}
|
|
50
52
|
apiURL={apiUrl}
|
|
53
|
+
customMediaRenderer={customMediaRenderer}
|
|
51
54
|
/>
|
|
52
55
|
)}
|
|
53
56
|
{links?.length > 0 && <LinkItemWidget items={links} baseUrl={baseUrl} />}
|
|
@@ -151,6 +151,18 @@ exports[`renders MediaItemWidget unchanged with css snippet to show 1`] = `
|
|
|
151
151
|
</div>
|
|
152
152
|
`;
|
|
153
153
|
|
|
154
|
+
exports[`renders MediaItemWidget unchanged with custom media renderer 1`] = `
|
|
155
|
+
<div>
|
|
156
|
+
<div
|
|
157
|
+
class="memori-media-items"
|
|
158
|
+
>
|
|
159
|
+
<div
|
|
160
|
+
class="memori-media-items--grid"
|
|
161
|
+
/>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
`;
|
|
165
|
+
|
|
154
166
|
exports[`renders MediaItemWidget unchanged with img 1`] = `
|
|
155
167
|
<div>
|
|
156
168
|
<div
|
|
@@ -127,3 +127,24 @@ WithAzureSpeechKey.args = {
|
|
|
127
127
|
tenant,
|
|
128
128
|
AZURE_COGNITIVE_SERVICES_TTS_KEY: 'provide your key here',
|
|
129
129
|
};
|
|
130
|
+
|
|
131
|
+
export const WithCustomMediaRenderer = Template.bind({});
|
|
132
|
+
WithCustomMediaRenderer.args = {
|
|
133
|
+
memori,
|
|
134
|
+
tenant,
|
|
135
|
+
customMediaRenderer: (mimeType: string) => (
|
|
136
|
+
<div
|
|
137
|
+
style={{
|
|
138
|
+
width: '100%',
|
|
139
|
+
height: '100%',
|
|
140
|
+
backgroundColor: 'black',
|
|
141
|
+
color: 'white',
|
|
142
|
+
display: 'flex',
|
|
143
|
+
justifyContent: 'center',
|
|
144
|
+
alignItems: 'center',
|
|
145
|
+
}}
|
|
146
|
+
>
|
|
147
|
+
{mimeType}
|
|
148
|
+
</div>
|
|
149
|
+
),
|
|
150
|
+
};
|
|
@@ -148,6 +148,7 @@ let audioContext: IAudioContext;
|
|
|
148
148
|
|
|
149
149
|
let memoriPassword: string | undefined;
|
|
150
150
|
let speakerMuted: boolean = false;
|
|
151
|
+
let speakLanguage: string | undefined;
|
|
151
152
|
|
|
152
153
|
export interface LayoutProps {
|
|
153
154
|
Header?: typeof Header;
|
|
@@ -203,6 +204,7 @@ export interface Props {
|
|
|
203
204
|
AZURE_COGNITIVE_SERVICES_TTS_KEY?: string;
|
|
204
205
|
onStateChange?: (state?: DialogState) => void;
|
|
205
206
|
additionalInfo?: OpenSession['additionalInfo'] & { [key: string]: string };
|
|
207
|
+
customMediaRenderer?: ChatProps['customMediaRenderer'];
|
|
206
208
|
}
|
|
207
209
|
|
|
208
210
|
const MemoriWidget = ({
|
|
@@ -235,6 +237,7 @@ const MemoriWidget = ({
|
|
|
235
237
|
AZURE_COGNITIVE_SERVICES_TTS_KEY,
|
|
236
238
|
onStateChange,
|
|
237
239
|
additionalInfo,
|
|
240
|
+
customMediaRenderer,
|
|
238
241
|
}: Props) => {
|
|
239
242
|
const { t, i18n } = useTranslation();
|
|
240
243
|
|
|
@@ -271,7 +274,7 @@ const MemoriWidget = ({
|
|
|
271
274
|
multilingual !== undefined
|
|
272
275
|
? multilingual
|
|
273
276
|
: !!integrationConfig?.multilanguage;
|
|
274
|
-
const [userLang,
|
|
277
|
+
const [userLang, _setUserLang] = useState(
|
|
275
278
|
memoriLang ??
|
|
276
279
|
integrationConfig?.lang ??
|
|
277
280
|
memori?.culture?.split('-')?.[0] ??
|
|
@@ -280,6 +283,10 @@ const MemoriWidget = ({
|
|
|
280
283
|
i18n.language ??
|
|
281
284
|
'IT'
|
|
282
285
|
);
|
|
286
|
+
const setUserLang: typeof _setUserLang = lang => {
|
|
287
|
+
_setUserLang(lang);
|
|
288
|
+
speakLanguage = lang;
|
|
289
|
+
};
|
|
283
290
|
|
|
284
291
|
const [loading, setLoading] = useState(false);
|
|
285
292
|
const [memoriTyping, setMemoriTyping] = useState(false);
|
|
@@ -1141,6 +1148,13 @@ const MemoriWidget = ({
|
|
|
1141
1148
|
: 'ru-RU-SvetlanaNeural'
|
|
1142
1149
|
}`;
|
|
1143
1150
|
break;
|
|
1151
|
+
case 'PL':
|
|
1152
|
+
voice = `${
|
|
1153
|
+
memori.voiceType === 'MALE'
|
|
1154
|
+
? 'pl-PL-MarekNeural'
|
|
1155
|
+
: 'pl-PL-AgnieszkaNeural'
|
|
1156
|
+
}`;
|
|
1157
|
+
break;
|
|
1144
1158
|
default:
|
|
1145
1159
|
voice = `${
|
|
1146
1160
|
memori.voiceType === 'MALE'
|
|
@@ -1187,6 +1201,9 @@ const MemoriWidget = ({
|
|
|
1187
1201
|
case 'RU':
|
|
1188
1202
|
voice = 'ru-RU';
|
|
1189
1203
|
break;
|
|
1204
|
+
case 'PL':
|
|
1205
|
+
voice = 'pl-PL';
|
|
1206
|
+
break;
|
|
1190
1207
|
default:
|
|
1191
1208
|
voice = 'it-IT';
|
|
1192
1209
|
break;
|
|
@@ -1266,177 +1283,182 @@ const MemoriWidget = ({
|
|
|
1266
1283
|
// .replace(/qfe/gi, `<sub alias="Quota Filo Erba">QFE</sub>`)
|
|
1267
1284
|
};
|
|
1268
1285
|
|
|
1269
|
-
const speak = (
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1286
|
+
const speak = useCallback(
|
|
1287
|
+
(text: string): void => {
|
|
1288
|
+
if (!AZURE_COGNITIVE_SERVICES_TTS_KEY) return;
|
|
1289
|
+
stopListening();
|
|
1290
|
+
// stopAudio();
|
|
1273
1291
|
|
|
1274
|
-
|
|
1292
|
+
if (preview) return;
|
|
1275
1293
|
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1294
|
+
if (muteSpeaker || speakerMuted) {
|
|
1295
|
+
// trigger start continuous listening if set, see MemoriChat
|
|
1296
|
+
if (continuousSpeech) {
|
|
1297
|
+
setListeningTimeout();
|
|
1298
|
+
}
|
|
1299
|
+
return;
|
|
1280
1300
|
}
|
|
1281
|
-
return;
|
|
1282
|
-
}
|
|
1283
1301
|
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1302
|
+
if (audioDestination) audioDestination.pause();
|
|
1303
|
+
|
|
1304
|
+
// if (audioContext?.state === 'running') {
|
|
1305
|
+
// // audioContext.suspend();
|
|
1306
|
+
// // }
|
|
1307
|
+
// // if (audioContext) {
|
|
1308
|
+
// audioContext.close().then(() => {
|
|
1309
|
+
// audioContext = new AudioContext();
|
|
1310
|
+
// let buffer = audioContext.createBuffer(1, 10000, 22050);
|
|
1311
|
+
// let source = audioContext.createBufferSource();
|
|
1312
|
+
// source.buffer = buffer;
|
|
1313
|
+
// source.connect(audioContext.destination);
|
|
1314
|
+
// });
|
|
1315
|
+
// }
|
|
1316
|
+
|
|
1317
|
+
let isSafari =
|
|
1318
|
+
window.navigator.userAgent.includes('Safari') &&
|
|
1319
|
+
!window.navigator.userAgent.includes('Chrome');
|
|
1320
|
+
let isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
|
|
1321
|
+
if ((audioContext.state as string) === 'interrupted') {
|
|
1322
|
+
audioContext.resume().then(() => speak(text));
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1325
|
+
if (isIOS && isSafari) {
|
|
1326
|
+
audioContext.suspend();
|
|
1327
|
+
|
|
1328
|
+
if (isPlayingAudio) {
|
|
1329
|
+
try {
|
|
1330
|
+
if (speechSynthesizer) {
|
|
1331
|
+
speechSynthesizer.close();
|
|
1332
|
+
speechSynthesizer = null;
|
|
1333
|
+
}
|
|
1334
|
+
if (audioDestination) {
|
|
1335
|
+
audioDestination.pause();
|
|
1336
|
+
audioDestination.close();
|
|
1337
|
+
}
|
|
1338
|
+
if (audioContext) {
|
|
1339
|
+
// audioContext.close().then(() => {
|
|
1340
|
+
// audioContext = new AudioContext();
|
|
1341
|
+
// let buffer = audioContext.createBuffer(1, 10000, 22050);
|
|
1342
|
+
// let source = audioContext.createBufferSource();
|
|
1343
|
+
// source.buffer = buffer;
|
|
1344
|
+
// source.connect(audioContext.destination);
|
|
1345
|
+
// });
|
|
1346
|
+
audioContext.destination.disconnect();
|
|
1347
|
+
}
|
|
1348
|
+
} catch (e) {
|
|
1349
|
+
console.error('stopAudio error: ', e);
|
|
1329
1350
|
}
|
|
1330
|
-
} catch (e) {
|
|
1331
|
-
console.error('stopAudio error: ', e);
|
|
1332
1351
|
}
|
|
1333
1352
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
stopAudio();
|
|
1353
|
+
if (audioContext.state === 'closed') {
|
|
1354
|
+
audioContext = new AudioContext();
|
|
1355
|
+
let buffer = audioContext.createBuffer(1, 10000, 22050);
|
|
1356
|
+
let source = audioContext.createBufferSource();
|
|
1357
|
+
source.buffer = buffer;
|
|
1358
|
+
source.connect(audioContext.destination);
|
|
1359
|
+
} else if (audioContext.state === 'suspended') {
|
|
1360
|
+
stopAudio();
|
|
1343
1361
|
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1362
|
+
audioContext = new AudioContext();
|
|
1363
|
+
let buffer = audioContext.createBuffer(1, 10000, 22050);
|
|
1364
|
+
let source = audioContext.createBufferSource();
|
|
1365
|
+
source.buffer = buffer;
|
|
1366
|
+
source.connect(audioContext.destination);
|
|
1367
|
+
}
|
|
1350
1368
|
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1369
|
+
if (!speechSynthesizer) {
|
|
1370
|
+
audioDestination = new speechSdk.SpeakerAudioDestination();
|
|
1371
|
+
let audioConfig =
|
|
1372
|
+
speechSdk.AudioConfig.fromSpeakerOutput(audioDestination);
|
|
1373
|
+
speechSynthesizer = new speechSdk.SpeechSynthesizer(
|
|
1374
|
+
speechConfig,
|
|
1375
|
+
audioConfig
|
|
1376
|
+
);
|
|
1377
|
+
}
|
|
1360
1378
|
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1379
|
+
const source = audioContext.createBufferSource();
|
|
1380
|
+
source.addEventListener('ended', () => {
|
|
1381
|
+
setIsPlayingAudio(false);
|
|
1382
|
+
});
|
|
1383
|
+
audioDestination.onAudioEnd = () => {
|
|
1384
|
+
setIsPlayingAudio(false);
|
|
1385
|
+
source.disconnect();
|
|
1368
1386
|
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1387
|
+
// trigger start continuous listening if set
|
|
1388
|
+
// document.dispatchEvent(new Event('endSpeakStartListen'));
|
|
1389
|
+
onEndSpeakStartListen();
|
|
1390
|
+
};
|
|
1373
1391
|
|
|
1374
|
-
|
|
1375
|
-
`<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(
|
|
1376
|
-
userLang
|
|
1377
|
-
)}"><voice name="${getTTSVoice(userLang)}"><s>${replaceTextWithPhonemes(
|
|
1378
|
-
escapeHTML(text),
|
|
1379
|
-
userLang.toLowerCase()
|
|
1380
|
-
)}</s></voice></speak>`,
|
|
1381
|
-
result => {
|
|
1382
|
-
if (result) {
|
|
1383
|
-
setIsPlayingAudio(true);
|
|
1392
|
+
const lang = speakLanguage || userLang;
|
|
1384
1393
|
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
}
|
|
1396
|
-
});
|
|
1394
|
+
speechSynthesizer.speakSsmlAsync(
|
|
1395
|
+
`<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(
|
|
1396
|
+
lang
|
|
1397
|
+
)}"><voice name="${getTTSVoice(lang)}"><s>${replaceTextWithPhonemes(
|
|
1398
|
+
escapeHTML(text),
|
|
1399
|
+
lang.toLowerCase()
|
|
1400
|
+
)}</s></voice></speak>`,
|
|
1401
|
+
result => {
|
|
1402
|
+
if (result) {
|
|
1403
|
+
setIsPlayingAudio(true);
|
|
1397
1404
|
|
|
1398
|
-
|
|
1399
|
-
if (
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
) {
|
|
1403
|
-
source.
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1405
|
+
try {
|
|
1406
|
+
// if (audioContext.destination.context.state === 'running') {
|
|
1407
|
+
// audioContext.destination.disconnect();
|
|
1408
|
+
// }
|
|
1409
|
+
audioContext.decodeAudioData(result.audioData, function (buffer) {
|
|
1410
|
+
source.buffer = buffer;
|
|
1411
|
+
source.connect(audioContext.destination);
|
|
1412
|
+
|
|
1413
|
+
if (history.length < 1 || (isSafari && isIOS)) {
|
|
1414
|
+
source.start(0);
|
|
1415
|
+
}
|
|
1416
|
+
});
|
|
1409
1417
|
|
|
1410
|
-
|
|
1418
|
+
audioContext.onstatechange = () => {
|
|
1419
|
+
if (
|
|
1420
|
+
audioContext.state === 'suspended' ||
|
|
1421
|
+
audioContext.state === 'closed'
|
|
1422
|
+
) {
|
|
1423
|
+
source.disconnect();
|
|
1424
|
+
setIsPlayingAudio(false);
|
|
1425
|
+
} else if ((audioContext.state as string) === 'interrupted') {
|
|
1426
|
+
audioContext.resume();
|
|
1427
|
+
}
|
|
1428
|
+
};
|
|
1411
1429
|
|
|
1412
|
-
|
|
1413
|
-
speechSynthesizer.close();
|
|
1414
|
-
speechSynthesizer = null;
|
|
1415
|
-
}
|
|
1416
|
-
} catch (e) {
|
|
1417
|
-
console.error('speak error: ', e);
|
|
1418
|
-
window.speechSynthesis.speak(new SpeechSynthesisUtterance(text));
|
|
1419
|
-
setIsPlayingAudio(false);
|
|
1430
|
+
audioContext.resume();
|
|
1420
1431
|
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1432
|
+
if (speechSynthesizer) {
|
|
1433
|
+
speechSynthesizer.close();
|
|
1434
|
+
speechSynthesizer = null;
|
|
1435
|
+
}
|
|
1436
|
+
} catch (e) {
|
|
1437
|
+
console.error('speak error: ', e);
|
|
1438
|
+
window.speechSynthesis.speak(new SpeechSynthesisUtterance(text));
|
|
1439
|
+
setIsPlayingAudio(false);
|
|
1440
|
+
|
|
1441
|
+
if (speechSynthesizer) {
|
|
1442
|
+
speechSynthesizer.close();
|
|
1443
|
+
speechSynthesizer = null;
|
|
1444
|
+
}
|
|
1424
1445
|
}
|
|
1446
|
+
} else {
|
|
1447
|
+
audioContext.resume();
|
|
1448
|
+
setIsPlayingAudio(false);
|
|
1425
1449
|
}
|
|
1426
|
-
}
|
|
1427
|
-
|
|
1450
|
+
},
|
|
1451
|
+
error => {
|
|
1452
|
+
console.error('speak:', error);
|
|
1453
|
+
window.speechSynthesis.speak(new SpeechSynthesisUtterance(text));
|
|
1428
1454
|
setIsPlayingAudio(false);
|
|
1429
1455
|
}
|
|
1430
|
-
|
|
1431
|
-
error => {
|
|
1432
|
-
console.error('speak:', error);
|
|
1433
|
-
window.speechSynthesis.speak(new SpeechSynthesisUtterance(text));
|
|
1434
|
-
setIsPlayingAudio(false);
|
|
1435
|
-
}
|
|
1436
|
-
);
|
|
1456
|
+
);
|
|
1437
1457
|
|
|
1438
|
-
|
|
1439
|
-
|
|
1458
|
+
setMemoriTyping(false);
|
|
1459
|
+
},
|
|
1460
|
+
[userLang, speakerMuted]
|
|
1461
|
+
);
|
|
1440
1462
|
const stopAudio = () => {
|
|
1441
1463
|
setIsPlayingAudio(false);
|
|
1442
1464
|
try {
|
|
@@ -2312,6 +2334,7 @@ const MemoriWidget = ({
|
|
|
2312
2334
|
resetTranscript,
|
|
2313
2335
|
listening,
|
|
2314
2336
|
isPlayingAudio,
|
|
2337
|
+
customMediaRenderer,
|
|
2315
2338
|
};
|
|
2316
2339
|
|
|
2317
2340
|
const integrationBackground =
|
package/src/index.tsx
CHANGED
|
@@ -40,6 +40,7 @@ export interface Props {
|
|
|
40
40
|
AZURE_COGNITIVE_SERVICES_TTS_KEY?: string;
|
|
41
41
|
onStateChange?: (state?: DialogState) => void;
|
|
42
42
|
additionalInfo?: WidgetProps['additionalInfo'];
|
|
43
|
+
customMediaRenderer?: WidgetProps['customMediaRenderer'];
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
const getPreferredLanguages = () => {
|
|
@@ -87,6 +88,7 @@ const Memori: React.FC<Props> = ({
|
|
|
87
88
|
AZURE_COGNITIVE_SERVICES_TTS_KEY,
|
|
88
89
|
onStateChange,
|
|
89
90
|
additionalInfo,
|
|
91
|
+
customMediaRenderer,
|
|
90
92
|
}) => {
|
|
91
93
|
const [memori, setMemori] = useState<IMemori>();
|
|
92
94
|
const [speechKey, setSpeechKey] = useState<string | undefined>(
|
|
@@ -213,6 +215,7 @@ const Memori: React.FC<Props> = ({
|
|
|
213
215
|
}
|
|
214
216
|
onStateChange={onStateChange}
|
|
215
217
|
additionalInfo={additionalInfo}
|
|
218
|
+
customMediaRenderer={customMediaRenderer}
|
|
216
219
|
{...(tag && pin ? { personification: { tag, pin } } : {})}
|
|
217
220
|
/>
|
|
218
221
|
) : (
|