@memori.ai/memori-react 2.0.10 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +74 -26
  3. package/dist/components/MediaWidget/MediaItemWidget.js +1 -12
  4. package/dist/components/MediaWidget/MediaItemWidget.js.map +1 -1
  5. package/dist/components/MemoriWidget/MemoriWidget.d.ts +17 -1
  6. package/dist/components/MemoriWidget/MemoriWidget.js +13 -7
  7. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  8. package/dist/components/SettingsDrawer/SettingsDrawer.js +2 -2
  9. package/dist/components/SettingsDrawer/SettingsDrawer.js.map +1 -1
  10. package/dist/components/layouts/FullPage.d.ts +2 -15
  11. package/dist/components/layouts/FullPage.js.map +1 -1
  12. package/dist/components/layouts/Totem.d.ts +2 -15
  13. package/dist/components/layouts/Totem.js.map +1 -1
  14. package/dist/helpers/media.js +25 -19
  15. package/dist/helpers/media.js.map +1 -1
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.js +2 -2
  18. package/dist/index.js.map +1 -1
  19. package/esm/components/MediaWidget/MediaItemWidget.js +1 -12
  20. package/esm/components/MediaWidget/MediaItemWidget.js.map +1 -1
  21. package/esm/components/MemoriWidget/MemoriWidget.d.ts +17 -1
  22. package/esm/components/MemoriWidget/MemoriWidget.js +13 -7
  23. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  24. package/esm/components/SettingsDrawer/SettingsDrawer.js +2 -2
  25. package/esm/components/SettingsDrawer/SettingsDrawer.js.map +1 -1
  26. package/esm/components/layouts/FullPage.d.ts +2 -15
  27. package/esm/components/layouts/FullPage.js.map +1 -1
  28. package/esm/components/layouts/Totem.d.ts +2 -15
  29. package/esm/components/layouts/Totem.js.map +1 -1
  30. package/esm/helpers/media.js +25 -19
  31. package/esm/helpers/media.js.map +1 -1
  32. package/esm/index.d.ts +1 -0
  33. package/esm/index.js +2 -2
  34. package/esm/index.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/components/Chat/__snapshots__/Chat.test.tsx.snap +6 -6
  37. package/src/components/MediaWidget/MediaItemWidget.tsx +1 -12
  38. package/src/components/MediaWidget/__snapshots__/MediaItemWidget.test.tsx.snap +6 -6
  39. package/src/components/MediaWidget/__snapshots__/MediaWidget.test.tsx.snap +1 -1
  40. package/src/components/MemoriWidget/MemoriWidget.tsx +30 -8
  41. package/src/components/SettingsDrawer/SettingsDrawer.tsx +11 -13
  42. package/src/components/layouts/FullPage.tsx +2 -16
  43. package/src/components/layouts/Totem.tsx +2 -16
  44. package/src/components/layouts/layouts.stories.tsx +41 -1
  45. package/src/helpers/media.ts +29 -23
  46. package/src/index.tsx +3 -0
@@ -2605,7 +2605,7 @@ exports[`renders Chat with media unchanged 1`] = `
2605
2605
  >
2606
2606
  <a
2607
2607
  class="memori-media-item--link"
2608
- href="https://picsum.photos/300/200?random=0/131165be-9d1a-42fb-a3ce-e8f86d40c88f"
2608
+ href="https://picsum.photos/300/200?random=0"
2609
2609
  rel="noopener noreferrer"
2610
2610
  target="_blank"
2611
2611
  title="Image 0"
@@ -2623,7 +2623,7 @@ exports[`renders Chat with media unchanged 1`] = `
2623
2623
  class="memori-media-item--figure"
2624
2624
  >
2625
2625
  <source
2626
- srcset="https://picsum.photos/300/200?random=0/131165be-9d1a-42fb-a3ce-e8f86d40c88f, /images/memoriAvatar.png, https://picsum.photos/300/200?random=0, "
2626
+ srcset="https://picsum.photos/300/200?random=0, https://picsum.photos/300/200?random=0, "
2627
2627
  type="image/png"
2628
2628
  />
2629
2629
  <img
@@ -2669,7 +2669,7 @@ exports[`renders Chat with media unchanged 1`] = `
2669
2669
  >
2670
2670
  <a
2671
2671
  class="memori-media-item--link"
2672
- href="https://picsum.photos/200/300?random=1/131165be-9d1a-42fb-a3ce-e8f86d40c88f"
2672
+ href="https://picsum.photos/200/300?random=1"
2673
2673
  rel="noopener noreferrer"
2674
2674
  target="_blank"
2675
2675
  title="Image 1"
@@ -2687,7 +2687,7 @@ exports[`renders Chat with media unchanged 1`] = `
2687
2687
  class="memori-media-item--figure"
2688
2688
  >
2689
2689
  <source
2690
- srcset="https://picsum.photos/200/300?random=1/131165be-9d1a-42fb-a3ce-e8f86d40c88f, /images/memoriAvatar.png, https://picsum.photos/200/300?random=1, "
2690
+ srcset="https://picsum.photos/200/300?random=1, https://picsum.photos/200/300?random=1, "
2691
2691
  type="image/png"
2692
2692
  />
2693
2693
  <img
@@ -2733,7 +2733,7 @@ exports[`renders Chat with media unchanged 1`] = `
2733
2733
  >
2734
2734
  <a
2735
2735
  class="memori-media-item--link"
2736
- href="https://picsum.photos/300/300?random=2/131165be-9d1a-42fb-a3ce-e8f86d40c88f"
2736
+ href="https://picsum.photos/300/300?random=2"
2737
2737
  rel="noopener noreferrer"
2738
2738
  target="_blank"
2739
2739
  title="Image 2"
@@ -2751,7 +2751,7 @@ exports[`renders Chat with media unchanged 1`] = `
2751
2751
  class="memori-media-item--figure"
2752
2752
  >
2753
2753
  <source
2754
- srcset="https://picsum.photos/300/300?random=2/131165be-9d1a-42fb-a3ce-e8f86d40c88f, /images/memoriAvatar.png, https://picsum.photos/300/300?random=2, "
2754
+ srcset="https://picsum.photos/300/300?random=2, https://picsum.photos/300/300?random=2, "
2755
2755
  type="image/png"
2756
2756
  />
2757
2757
  <img
@@ -78,18 +78,7 @@ export const RenderMediaItem = ({
78
78
  <picture className="memori-media-item--figure">
79
79
  {!preview && (
80
80
  <source
81
- srcSet={[
82
- url,
83
- getResourceUrl({
84
- resourceURI: item.content,
85
- sessionID,
86
- tenantID,
87
- baseURL,
88
- apiURL,
89
- }),
90
- item.url,
91
- item.content,
92
- ].join(', ')}
81
+ srcSet={[url, item.url, item.content].join(', ')}
93
82
  type={item.mimeType}
94
83
  />
95
84
  )}
@@ -182,7 +182,7 @@ exports[`renders MediaItemWidget unchanged with img 1`] = `
182
182
  class="memori-media-item--figure"
183
183
  >
184
184
  <source
185
- srcset="https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2, /images/memoriAvatar.png, https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2, "
185
+ srcset="https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2, https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2, "
186
186
  type="image/jpeg"
187
187
  />
188
188
  <img
@@ -241,7 +241,7 @@ exports[`renders MediaItemWidget unchanged with img and sessionID 1`] = `
241
241
  >
242
242
  <a
243
243
  class="memori-media-item--link"
244
- href="https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2/131165be-9d1a-42fb-a3ce-e8f86d40c88f"
244
+ href="https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2"
245
245
  rel="noopener noreferrer"
246
246
  target="_blank"
247
247
  title="Game Cover"
@@ -259,7 +259,7 @@ exports[`renders MediaItemWidget unchanged with img and sessionID 1`] = `
259
259
  class="memori-media-item--figure"
260
260
  >
261
261
  <source
262
- srcset="https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2/131165be-9d1a-42fb-a3ce-e8f86d40c88f, /images/memoriAvatar.png, https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2, "
262
+ srcset="https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2, https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2, "
263
263
  type="image/jpeg"
264
264
  />
265
265
  <img
@@ -431,7 +431,7 @@ exports[`renders MediaItemWidget with imgs in correct order (creation date) 1`]
431
431
  class="memori-media-item--figure"
432
432
  >
433
433
  <source
434
- srcset="https://memori.ai/past, /images/memoriAvatar.png, https://memori.ai/past, "
434
+ srcset="https://memori.ai/past, https://memori.ai/past, "
435
435
  type="image/jpeg"
436
436
  />
437
437
  <img
@@ -495,7 +495,7 @@ exports[`renders MediaItemWidget with imgs in correct order (creation date) 1`]
495
495
  class="memori-media-item--figure"
496
496
  >
497
497
  <source
498
- srcset="https://memori.ai/medium, /images/memoriAvatar.png, https://memori.ai/medium, "
498
+ srcset="https://memori.ai/medium, https://memori.ai/medium, "
499
499
  type="image/jpeg"
500
500
  />
501
501
  <img
@@ -559,7 +559,7 @@ exports[`renders MediaItemWidget with imgs in correct order (creation date) 1`]
559
559
  class="memori-media-item--figure"
560
560
  >
561
561
  <source
562
- srcset="https://memori.ai/now, /images/memoriAvatar.png, https://memori.ai/now, "
562
+ srcset="https://memori.ai/now, https://memori.ai/now, "
563
563
  type="image/jpeg"
564
564
  />
565
565
  <img
@@ -148,7 +148,7 @@ exports[`renders MediaWidget with media unchanged 1`] = `
148
148
  class="memori-media-item--figure"
149
149
  >
150
150
  <source
151
- srcset="https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2, /images/memoriAvatar.png, https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2, "
151
+ srcset="https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2, https://api.lorem.space/image/game?w=150&h=220&hash=8B7BCDC2, "
152
152
  type="image/jpeg"
153
153
  />
154
154
  <img
@@ -145,12 +145,28 @@ let speechSynthesizer: SpeechSynthesizer | null;
145
145
  let audioDestination: SpeakerAudioDestination;
146
146
  let audioContext: IAudioContext;
147
147
 
148
+ export interface LayoutProps {
149
+ header?: JSX.Element | null;
150
+ avatar: JSX.Element;
151
+ chat?: JSX.Element | null;
152
+ startPanel: JSX.Element;
153
+ integrationStyle?: JSX.Element | null;
154
+ integrationBackground?: JSX.Element | null;
155
+ changeMode?: JSX.Element | null;
156
+ poweredBy?: JSX.Element | null;
157
+ sessionId?: string;
158
+ hasUserActivatedSpeak?: boolean;
159
+ showInstruct?: boolean;
160
+ loading?: boolean;
161
+ }
162
+
148
163
  export interface Props {
149
164
  memori: Memori;
150
165
  memoriConfigs?: MemoriConfig[];
151
166
  memoriLang?: string;
152
167
  integration?: Integration;
153
168
  layout?: 'DEFAULT' | 'FULLPAGE' | 'TOTEM';
169
+ customLayout?: React.FC<LayoutProps>;
154
170
  showShare?: boolean;
155
171
  showInstruct?: boolean;
156
172
  showInputs?: boolean;
@@ -184,6 +200,7 @@ const MemoriWidget = ({
184
200
  memoriLang,
185
201
  integration,
186
202
  layout = 'DEFAULT',
203
+ customLayout,
187
204
  showInstruct = false,
188
205
  showShare = true,
189
206
  preview = false,
@@ -1267,6 +1284,9 @@ const MemoriWidget = ({
1267
1284
  }
1268
1285
 
1269
1286
  const source = audioContext.createBufferSource();
1287
+ source.addEventListener('ended', () => {
1288
+ setIsPlayingAudio(false);
1289
+ });
1270
1290
  audioDestination.onAudioEnd = () => {
1271
1291
  setIsPlayingAudio(false);
1272
1292
  source.disconnect();
@@ -1276,8 +1296,6 @@ const MemoriWidget = ({
1276
1296
  onEndSpeakStartListen();
1277
1297
  };
1278
1298
 
1279
- setIsPlayingAudio(true);
1280
-
1281
1299
  speechSynthesizer.speakSsmlAsync(
1282
1300
  `<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(
1283
1301
  userLang
@@ -1287,6 +1305,8 @@ const MemoriWidget = ({
1287
1305
  )}</s></voice></speak>`,
1288
1306
  result => {
1289
1307
  if (result) {
1308
+ setIsPlayingAudio(true);
1309
+
1290
1310
  try {
1291
1311
  // if (audioContext.destination.context.state === 'running') {
1292
1312
  // audioContext.destination.disconnect();
@@ -1306,6 +1326,7 @@ const MemoriWidget = ({
1306
1326
  audioContext.state === 'closed'
1307
1327
  ) {
1308
1328
  source.disconnect();
1329
+ setIsPlayingAudio(false);
1309
1330
  } else if ((audioContext.state as string) === 'interrupted') {
1310
1331
  audioContext.resume();
1311
1332
  }
@@ -2251,12 +2272,13 @@ const MemoriWidget = ({
2251
2272
 
2252
2273
  const poweredBy = <PoweredBy tenant={tenant} userLang={userLang} />;
2253
2274
 
2254
- const Layout =
2255
- selectedLayout === 'TOTEM'
2256
- ? TotemLayout
2257
- : selectedLayout === 'FULLPAGE'
2258
- ? FullPageLayout
2259
- : FullPageLayout;
2275
+ const Layout = customLayout
2276
+ ? customLayout
2277
+ : selectedLayout === 'TOTEM'
2278
+ ? TotemLayout
2279
+ : selectedLayout === 'FULLPAGE'
2280
+ ? FullPageLayout
2281
+ : FullPageLayout;
2260
2282
 
2261
2283
  return (
2262
2284
  <div
@@ -106,19 +106,17 @@ const SettingsDrawer = ({
106
106
  </RadioGroup.Option>
107
107
  </RadioGroup>
108
108
  </div>
109
- {!!continuousSpeech && (
110
- <div className="memori-settings-drawer--field">
111
- <Checkbox
112
- label={t('write_and_speak.hideEmissionsLabel')}
113
- name="hideControls"
114
- checked={hideEmissions}
115
- onChange={e => {
116
- setHideEmissions(e.target.checked);
117
- setLocalConfig('hideEmissions', e.target.checked);
118
- }}
119
- />
120
- </div>
121
- )}
109
+ <div className="memori-settings-drawer--field">
110
+ <Checkbox
111
+ label={t('write_and_speak.hideEmissionsLabel')}
112
+ name="hideControls"
113
+ checked={hideEmissions}
114
+ onChange={e => {
115
+ setHideEmissions(e.target.checked);
116
+ setLocalConfig('hideEmissions', e.target.checked);
117
+ }}
118
+ />
119
+ </div>
122
120
  </>
123
121
  )}
124
122
  </Drawer>
@@ -1,22 +1,8 @@
1
1
  import React from 'react';
2
2
  import Spin from '../ui/Spin';
3
+ import { LayoutProps } from '../MemoriWidget/MemoriWidget';
3
4
 
4
- export interface Props {
5
- header?: JSX.Element | null;
6
- avatar: JSX.Element;
7
- chat?: JSX.Element | null;
8
- startPanel: JSX.Element;
9
- integrationStyle?: JSX.Element | null;
10
- integrationBackground?: JSX.Element | null;
11
- changeMode?: JSX.Element | null;
12
- poweredBy?: JSX.Element | null;
13
- sessionId?: string;
14
- hasUserActivatedSpeak?: boolean;
15
- showInstruct?: boolean;
16
- loading?: boolean;
17
- }
18
-
19
- const FullPageLayout: React.FC<Props> = ({
5
+ const FullPageLayout: React.FC<LayoutProps> = ({
20
6
  header,
21
7
  avatar,
22
8
  chat,
@@ -1,22 +1,8 @@
1
1
  import React from 'react';
2
2
  import Spin from '../ui/Spin';
3
+ import { LayoutProps } from '../MemoriWidget/MemoriWidget';
3
4
 
4
- export interface Props {
5
- header?: JSX.Element | null;
6
- avatar: JSX.Element;
7
- chat?: JSX.Element | null;
8
- startPanel: JSX.Element;
9
- integrationStyle?: JSX.Element | null;
10
- integrationBackground?: JSX.Element | null;
11
- changeMode?: JSX.Element | null;
12
- poweredBy?: JSX.Element | null;
13
- sessionId?: string;
14
- hasUserActivatedSpeak?: boolean;
15
- showInstruct?: boolean;
16
- loading?: boolean;
17
- }
18
-
19
- const TotemLayout: React.FC<Props> = ({
5
+ const TotemLayout: React.FC<LayoutProps> = ({
20
6
  header,
21
7
  avatar,
22
8
  chat,
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import { Meta, Story } from '@storybook/react';
3
3
  import { memori, tenant, integration } from '../../mocks/data';
4
- import Memori, { Props } from '../MemoriWidget/MemoriWidget';
4
+ import Memori, { LayoutProps, Props } from '../MemoriWidget/MemoriWidget';
5
+ import Spin from '../ui/Spin';
5
6
 
6
7
  const meta: Meta = {
7
8
  title: 'General/Layouts',
@@ -21,6 +22,34 @@ const meta: Meta = {
21
22
 
22
23
  export default meta;
23
24
 
25
+ const CustomLayout: React.FC<LayoutProps> = ({
26
+ header,
27
+ avatar,
28
+ chat,
29
+ startPanel,
30
+ integrationStyle,
31
+ integrationBackground,
32
+ changeMode,
33
+ sessionId,
34
+ hasUserActivatedSpeak,
35
+ showInstruct = false,
36
+ loading = false,
37
+ poweredBy,
38
+ }) => (
39
+ <>
40
+ {integrationStyle}
41
+ {integrationBackground}
42
+
43
+ <Spin spinning={loading} className="memori-mycustom-layout">
44
+ {poweredBy}
45
+
46
+ <div className="memori-mycustom-layout--controls">
47
+ {sessionId && hasUserActivatedSpeak ? chat : startPanel}
48
+ </div>
49
+ </Spin>
50
+ </>
51
+ );
52
+
24
53
  const Template: Story<Props> = args => <Memori {...args} />;
25
54
 
26
55
  // By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
@@ -153,3 +182,14 @@ Totem.args = {
153
182
  tenant,
154
183
  layout: 'TOTEM',
155
184
  };
185
+
186
+ export const Custom = Template.bind({});
187
+ Custom.args = {
188
+ uiLang: 'it',
189
+ showShare: true,
190
+ showSettings: true,
191
+ memori,
192
+ tenant,
193
+ layout: 'FULLPAGE',
194
+ customLayout: CustomLayout,
195
+ };
@@ -17,28 +17,34 @@ export const getResourceUrl = ({
17
17
  type === 'cover'
18
18
  ? `${baseURL}/images/memoriCover.png`
19
19
  : `${baseURL}/images/memoriAvatar.png`;
20
- if (!resourceURI || resourceURI.length === 0) {
21
- return defaultUri;
22
- } else if (
23
- resourceURI.includes('memoriai/memory') &&
24
- !resourceURI.includes('memori-ai-session-id') &&
25
- sessionID
26
- ) {
27
- return `${resourceURI}?memori-ai-session-id=${sessionID}`;
28
- } else if (
29
- resourceURI.startsWith('https://') ||
30
- resourceURI.startsWith('http://')
31
- ) {
32
- return `${resourceURI}${sessionID ? `/${sessionID}` : ''}`;
33
- } else if (resourceURI.startsWith('cloud://')) {
34
- return `${
35
- apiURL?.replace(/v2/, 'v1') || ''
36
- }/CloudAsset/${resourceURI.replace('cloud://', '')}`;
37
- } else if (resourceURI.startsWith('guid://')) {
38
- return `${
39
- apiURL?.replace(/v2/, 'v1') || ''
40
- }/GuidAsset/${resourceURI.replace('guid://', '')}`;
41
- } else {
42
- return defaultUri;
20
+
21
+ try {
22
+ if (!resourceURI || resourceURI.length === 0) {
23
+ return defaultUri;
24
+ } else if (
25
+ resourceURI.includes('memoriai/memory') &&
26
+ !resourceURI.includes('memori-ai-session-id') &&
27
+ sessionID
28
+ ) {
29
+ return `${resourceURI}?memori-ai-session-id=${sessionID}`;
30
+ } else if (
31
+ (resourceURI.startsWith('https://') ||
32
+ resourceURI.startsWith('http://')) &&
33
+ new URL(resourceURI).hostname.includes('memori.ai')
34
+ ) {
35
+ return `${resourceURI}${sessionID ? `/${sessionID}` : ''}`;
36
+ } else if (resourceURI.startsWith('cloud://')) {
37
+ return `${
38
+ apiURL?.replace(/v2/, 'v1') || ''
39
+ }/CloudAsset/${resourceURI.replace('cloud://', '')}`;
40
+ } else if (resourceURI.startsWith('guid://')) {
41
+ return `${
42
+ apiURL?.replace(/v2/, 'v1') || ''
43
+ }/GuidAsset/${resourceURI.replace('guid://', '')}`;
44
+ } else {
45
+ return resourceURI || defaultUri;
46
+ }
47
+ } catch (e) {
48
+ return resourceURI || defaultUri;
43
49
  }
44
50
  };
package/src/index.tsx CHANGED
@@ -22,6 +22,7 @@ export interface Props {
22
22
  secretToken?: string;
23
23
  sessionID?: string;
24
24
  layout?: WidgetProps['layout'];
25
+ customLayout?: WidgetProps['customLayout'];
25
26
  showShare?: boolean;
26
27
  showSettings?: boolean;
27
28
  showInstruct?: boolean;
@@ -66,6 +67,7 @@ const Memori: React.FC<Props> = ({
66
67
  secretToken,
67
68
  sessionID,
68
69
  layout = 'DEFAULT',
70
+ customLayout,
69
71
  showShare = true,
70
72
  showSettings = true,
71
73
  showInstruct = false,
@@ -147,6 +149,7 @@ const Memori: React.FC<Props> = ({
147
149
  return memori ? (
148
150
  <MemoriWidget
149
151
  layout={layout}
152
+ customLayout={customLayout}
150
153
  height={height}
151
154
  baseUrl={
152
155
  baseURL ||