@memori.ai/memori-react 7.8.8 → 7.9.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 (148) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/components/Avatar/Avatar.d.ts +4 -0
  3. package/dist/components/Avatar/Avatar.js +6 -6
  4. package/dist/components/Avatar/Avatar.js.map +1 -1
  5. package/dist/components/Avatar/AvatarView/AvatarComponent/avatarComponent.d.ts +3 -0
  6. package/dist/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js +3 -3
  7. package/dist/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js.map +1 -1
  8. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/AnimationController.js +1 -1
  9. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/AnimationController.js.map +1 -1
  10. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.d.ts +1 -1
  11. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js +48 -10
  12. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js.map +1 -1
  13. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/types.d.ts +4 -1
  14. package/dist/components/Avatar/AvatarView/AvatarComponent/components/MorphTargetController.d.ts +17 -0
  15. package/dist/components/Avatar/AvatarView/AvatarComponent/components/MorphTargetController.js +73 -0
  16. package/dist/components/Avatar/AvatarView/AvatarComponent/components/MorphTargetController.js.map +1 -0
  17. package/dist/components/Avatar/AvatarView/AvatarComponent/components/PositionController.d.ts +19 -0
  18. package/dist/components/Avatar/AvatarView/AvatarComponent/components/PositionController.js +60 -0
  19. package/dist/components/Avatar/AvatarView/AvatarComponent/components/PositionController.js.map +1 -0
  20. package/dist/components/Avatar/AvatarView/AvatarComponent/components/constants.d.ts +18 -0
  21. package/dist/components/Avatar/AvatarView/AvatarComponent/components/constants.js +26 -0
  22. package/dist/components/Avatar/AvatarView/AvatarComponent/components/constants.js.map +1 -0
  23. package/dist/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.d.ts +8 -7
  24. package/dist/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js +65 -78
  25. package/dist/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js.map +1 -1
  26. package/dist/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.css +99 -0
  27. package/dist/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.d.ts +12 -0
  28. package/dist/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.js +98 -0
  29. package/dist/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.js.map +1 -0
  30. package/dist/components/Avatar/AvatarView/index.d.ts +4 -1
  31. package/dist/components/Avatar/AvatarView/index.js +36 -13
  32. package/dist/components/Avatar/AvatarView/index.js.map +1 -1
  33. package/dist/components/Avatar/AvatarView/utils/hideHands.d.ts +2 -0
  34. package/dist/components/Avatar/AvatarView/utils/hideHands.js +14 -0
  35. package/dist/components/Avatar/AvatarView/utils/hideHands.js.map +1 -0
  36. package/dist/components/Chat/Chat.d.ts +1 -0
  37. package/dist/components/Chat/Chat.js +5 -2
  38. package/dist/components/Chat/Chat.js.map +1 -1
  39. package/dist/components/MemoriWidget/MemoriWidget.js +27 -4
  40. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  41. package/dist/components/SettingsDrawer/SettingsDrawer.css +4 -2
  42. package/dist/components/SettingsDrawer/SettingsDrawer.d.ts +6 -1
  43. package/dist/components/SettingsDrawer/SettingsDrawer.js +10 -4
  44. package/dist/components/SettingsDrawer/SettingsDrawer.js.map +1 -1
  45. package/dist/components/layouts/Totem.js +1 -1
  46. package/dist/components/layouts/Totem.js.map +1 -1
  47. package/dist/components/layouts/totem.css +9 -9
  48. package/dist/components/ui/Button.css +4 -0
  49. package/dist/components/ui/Button.d.ts +1 -0
  50. package/dist/components/ui/Button.js +2 -1
  51. package/dist/components/ui/Button.js.map +1 -1
  52. package/dist/components/ui/Slider.css +177 -0
  53. package/dist/components/ui/Slider.d.ts +12 -0
  54. package/dist/components/ui/Slider.js +78 -0
  55. package/dist/components/ui/Slider.js.map +1 -0
  56. package/dist/locales/en.json +11 -0
  57. package/dist/locales/it.json +11 -0
  58. package/dist/styles.css +1 -0
  59. package/esm/components/Avatar/Avatar.d.ts +4 -0
  60. package/esm/components/Avatar/Avatar.js +6 -6
  61. package/esm/components/Avatar/Avatar.js.map +1 -1
  62. package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.d.ts +3 -0
  63. package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js +3 -3
  64. package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js.map +1 -1
  65. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/AnimationController.js +1 -1
  66. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/AnimationController.js.map +1 -1
  67. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.d.ts +1 -1
  68. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js +45 -8
  69. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js.map +1 -1
  70. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/types.d.ts +4 -1
  71. package/esm/components/Avatar/AvatarView/AvatarComponent/components/MorphTargetController.d.ts +17 -0
  72. package/esm/components/Avatar/AvatarView/AvatarComponent/components/MorphTargetController.js +69 -0
  73. package/esm/components/Avatar/AvatarView/AvatarComponent/components/MorphTargetController.js.map +1 -0
  74. package/esm/components/Avatar/AvatarView/AvatarComponent/components/PositionController.d.ts +19 -0
  75. package/esm/components/Avatar/AvatarView/AvatarComponent/components/PositionController.js +56 -0
  76. package/esm/components/Avatar/AvatarView/AvatarComponent/components/PositionController.js.map +1 -0
  77. package/esm/components/Avatar/AvatarView/AvatarComponent/components/constants.d.ts +18 -0
  78. package/esm/components/Avatar/AvatarView/AvatarComponent/components/constants.js +23 -0
  79. package/esm/components/Avatar/AvatarView/AvatarComponent/components/constants.js.map +1 -0
  80. package/esm/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.d.ts +8 -7
  81. package/esm/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js +66 -80
  82. package/esm/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js.map +1 -1
  83. package/esm/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.css +99 -0
  84. package/esm/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.d.ts +12 -0
  85. package/esm/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.js +95 -0
  86. package/esm/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.js.map +1 -0
  87. package/esm/components/Avatar/AvatarView/index.d.ts +4 -1
  88. package/esm/components/Avatar/AvatarView/index.js +38 -15
  89. package/esm/components/Avatar/AvatarView/index.js.map +1 -1
  90. package/esm/components/Avatar/AvatarView/utils/hideHands.d.ts +2 -0
  91. package/esm/components/Avatar/AvatarView/utils/hideHands.js +10 -0
  92. package/esm/components/Avatar/AvatarView/utils/hideHands.js.map +1 -0
  93. package/esm/components/Chat/Chat.d.ts +1 -0
  94. package/esm/components/Chat/Chat.js +5 -2
  95. package/esm/components/Chat/Chat.js.map +1 -1
  96. package/esm/components/MemoriWidget/MemoriWidget.js +27 -4
  97. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  98. package/esm/components/SettingsDrawer/SettingsDrawer.css +4 -2
  99. package/esm/components/SettingsDrawer/SettingsDrawer.d.ts +6 -1
  100. package/esm/components/SettingsDrawer/SettingsDrawer.js +10 -4
  101. package/esm/components/SettingsDrawer/SettingsDrawer.js.map +1 -1
  102. package/esm/components/layouts/Totem.js +1 -1
  103. package/esm/components/layouts/Totem.js.map +1 -1
  104. package/esm/components/layouts/totem.css +9 -9
  105. package/esm/components/ui/Button.css +4 -0
  106. package/esm/components/ui/Button.d.ts +1 -0
  107. package/esm/components/ui/Button.js +2 -1
  108. package/esm/components/ui/Button.js.map +1 -1
  109. package/esm/components/ui/Slider.css +177 -0
  110. package/esm/components/ui/Slider.d.ts +12 -0
  111. package/esm/components/ui/Slider.js +75 -0
  112. package/esm/components/ui/Slider.js.map +1 -0
  113. package/esm/locales/en.json +11 -0
  114. package/esm/locales/it.json +11 -0
  115. package/esm/styles.css +1 -0
  116. package/package.json +3 -2
  117. package/src/components/Avatar/Avatar.test.tsx +8 -0
  118. package/src/components/Avatar/Avatar.tsx +19 -6
  119. package/src/components/Avatar/AvatarView/AvatarComponent/avatarComponent.tsx +17 -8
  120. package/src/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/AnimationController.ts +1 -1
  121. package/src/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.tsx +69 -18
  122. package/src/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/types.ts +4 -1
  123. package/src/components/Avatar/AvatarView/AvatarComponent/components/PositionController.ts +83 -0
  124. package/src/components/Avatar/AvatarView/AvatarComponent/components/{FullbodyAvatar/constants.ts → constants.ts} +2 -1
  125. package/src/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.tsx +106 -124
  126. package/src/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.css +99 -0
  127. package/src/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.tsx +187 -0
  128. package/src/components/Avatar/AvatarView/index.tsx +115 -43
  129. package/src/components/Avatar/AvatarView/utils/hideHands.ts +11 -0
  130. package/src/components/Avatar/__snapshots__/Avatar.test.tsx.snap +32 -93
  131. package/src/components/Chat/Chat.test.tsx +11 -0
  132. package/src/components/Chat/Chat.tsx +8 -1
  133. package/src/components/MemoriWidget/MemoriWidget.tsx +42 -5
  134. package/src/components/SettingsDrawer/SettingsDrawer.css +4 -2
  135. package/src/components/SettingsDrawer/SettingsDrawer.test.tsx +24 -0
  136. package/src/components/SettingsDrawer/SettingsDrawer.tsx +76 -4
  137. package/src/components/layouts/Totem.tsx +1 -1
  138. package/src/components/layouts/layouts.stories.tsx +111 -3
  139. package/src/components/layouts/totem.css +9 -9
  140. package/src/components/ui/Button.css +4 -0
  141. package/src/components/ui/Button.tsx +3 -0
  142. package/src/components/ui/Slider.css +177 -0
  143. package/src/components/ui/Slider.stories.tsx +63 -0
  144. package/src/components/ui/Slider.tsx +142 -0
  145. package/src/locales/en.json +11 -0
  146. package/src/locales/it.json +11 -0
  147. package/src/styles.css +1 -0
  148. /package/src/components/Avatar/AvatarView/AvatarComponent/components/{FullbodyAvatar/MorhTargetController.ts → MorphTargetController.ts} +0 -0
@@ -55,6 +55,7 @@ it('renders Chat unchanged', () => {
55
55
  startListening={jest.fn()}
56
56
  stopListening={jest.fn()}
57
57
  resetTranscript={jest.fn()}
58
+ setEnableFocusChatInput={jest.fn()}
58
59
  />
59
60
  );
60
61
  expect(container).toMatchSnapshot();
@@ -86,6 +87,7 @@ it('renders Chat with memori typing unchanged', () => {
86
87
  showMicrophone={false}
87
88
  listening={false}
88
89
  startListening={jest.fn()}
90
+ setEnableFocusChatInput={jest.fn()}
89
91
  memoriTyping
90
92
  />
91
93
  );
@@ -118,6 +120,7 @@ it('renders Chat with hints unchanged', () => {
118
120
  showMicrophone={false}
119
121
  listening={false}
120
122
  startListening={jest.fn()}
123
+ setEnableFocusChatInput={jest.fn()}
121
124
  />
122
125
  );
123
126
  expect(container).toMatchSnapshot();
@@ -149,6 +152,7 @@ it('renders Chat with media unchanged', () => {
149
152
  showMicrophone={false}
150
153
  listening={false}
151
154
  startListening={jest.fn()}
155
+ setEnableFocusChatInput={jest.fn()}
152
156
  />
153
157
  );
154
158
  expect(container).toMatchSnapshot();
@@ -181,6 +185,7 @@ it('renders Chat with dates unchanged', () => {
181
185
  listening={false}
182
186
  startListening={jest.fn()}
183
187
  showDates
188
+ setEnableFocusChatInput={jest.fn()}
184
189
  />
185
190
  );
186
191
  expect(container).toMatchSnapshot();
@@ -212,6 +217,7 @@ it('renders Chat with context vars unchanged', () => {
212
217
  showMicrophone={false}
213
218
  listening={false}
214
219
  startListening={jest.fn()}
220
+ setEnableFocusChatInput={jest.fn()}
215
221
  showContextPerLine
216
222
  />
217
223
  );
@@ -247,6 +253,7 @@ it('renders Chat on X3 state unchanged', () => {
247
253
  showMicrophone={false}
248
254
  listening={false}
249
255
  startListening={jest.fn()}
256
+ setEnableFocusChatInput={jest.fn()}
250
257
  showContextPerLine
251
258
  />
252
259
  );
@@ -282,6 +289,7 @@ it('renders Chat on X2a state unchanged', () => {
282
289
  showMicrophone={false}
283
290
  listening={false}
284
291
  startListening={jest.fn()}
292
+ setEnableFocusChatInput={jest.fn()}
285
293
  showContextPerLine
286
294
  />
287
295
  );
@@ -315,6 +323,7 @@ it('renders Chat with user unchanged', () => {
315
323
  startListening={jest.fn()}
316
324
  stopListening={jest.fn()}
317
325
  resetTranscript={jest.fn()}
326
+ setEnableFocusChatInput={jest.fn()}
318
327
  />
319
328
  );
320
329
  expect(container).toMatchSnapshot();
@@ -347,6 +356,7 @@ it('renders Chat with custom user avatar unchanged', () => {
347
356
  startListening={jest.fn()}
348
357
  stopListening={jest.fn()}
349
358
  resetTranscript={jest.fn()}
359
+ setEnableFocusChatInput={jest.fn()}
350
360
  />
351
361
  );
352
362
  expect(container).toMatchSnapshot();
@@ -379,6 +389,7 @@ it('renders Chat with custom user avatar as react element unchanged', () => {
379
389
  startListening={jest.fn()}
380
390
  stopListening={jest.fn()}
381
391
  resetTranscript={jest.fn()}
392
+ setEnableFocusChatInput={jest.fn()}
382
393
  />
383
394
  );
384
395
  expect(container).toMatchSnapshot();
@@ -58,6 +58,7 @@ export interface Props {
58
58
  onChangeUserMessage: (userMessage: string) => void;
59
59
  sendMessage: (msg: string) => void;
60
60
  listening?: boolean;
61
+ setEnableFocusChatInput: (enableFocusChatInput: boolean) => void;
61
62
  isPlayingAudio?: boolean;
62
63
  stopAudio: () => void;
63
64
  startListening: () => void;
@@ -104,6 +105,7 @@ const Chat: React.FC<Props> = ({
104
105
  onChangeUserMessage,
105
106
  sendMessage,
106
107
  listening,
108
+ setEnableFocusChatInput,
107
109
  isPlayingAudio,
108
110
  stopAudio,
109
111
  startListening,
@@ -130,8 +132,13 @@ const Chat: React.FC<Props> = ({
130
132
 
131
133
  const onTextareaFocus = () => {
132
134
  stopListening();
133
- if (hasTouchscreen() && window.innerWidth <= 768) {
135
+ const hasTouch = hasTouchscreen();
136
+
137
+ if (hasTouch) setEnableFocusChatInput(true);
138
+ // if the user is on mobile and had not recorded audio, add the chat-focused class to the chat wrapper
139
+ if (hasTouch && window.innerWidth <= 768) {
134
140
  document.getElementById('chat-wrapper')?.classList?.add('chat-focused');
141
+ // add the chat-focused class to the memori widget
135
142
  document
136
143
  .querySelector('.memori.memori-widget')
137
144
  ?.classList?.add('chat-focused');
@@ -457,6 +457,7 @@ const MemoriWidget = ({
457
457
  } = client;
458
458
 
459
459
  const [instruct, setInstruct] = useState(false);
460
+ const [enableFocusChatInput, setEnableFocusChatInput] = useState(true);
460
461
 
461
462
  const [loginToken, setLoginToken] = useState<string | undefined>(
462
463
  additionalInfo?.loginToken ?? authToken
@@ -544,6 +545,11 @@ const MemoriWidget = ({
544
545
  const [controlsPosition, setControlsPosition] = useState<'center' | 'bottom'>(
545
546
  'center'
546
547
  );
548
+
549
+ const [enablePositionControls, setEnablePositionControls] = useState(false);
550
+ const [avatarType, setAvatarType] = useState<'blob' | 'avatar3d' | null>(
551
+ null
552
+ );
547
553
  const [hideEmissions, setHideEmissions] = useState(false);
548
554
 
549
555
  const {
@@ -598,6 +604,7 @@ const MemoriWidget = ({
598
604
  setControlsPosition(
599
605
  getLocalConfig('controlsPosition', defaultControlsPosition)
600
606
  );
607
+ setAvatarType(getLocalConfig('avatarType', 'avatar3d'));
601
608
  setHideEmissions(getLocalConfig('hideEmissions', false));
602
609
 
603
610
  if (!additionalInfo?.loginToken && !authToken) {
@@ -1133,6 +1140,7 @@ const MemoriWidget = ({
1133
1140
  userToken ?? loginToken ?? additionalInfo?.loginToken ?? authToken,
1134
1141
  language: getCultureCodeByLanguage(userLang),
1135
1142
  referral: referral,
1143
+ timeZoneOffset: new Date().getTimezoneOffset().toString(),
1136
1144
  },
1137
1145
  });
1138
1146
  if (
@@ -1229,6 +1237,7 @@ const MemoriWidget = ({
1229
1237
  userToken ?? loginToken ?? additionalInfo?.loginToken ?? authToken,
1230
1238
  language: getCultureCodeByLanguage(userLang),
1231
1239
  referral: referral,
1240
+ timeZoneOffset: new Date().getTimezoneOffset().toString(),
1232
1241
  },
1233
1242
  });
1234
1243
 
@@ -1383,6 +1392,7 @@ const MemoriWidget = ({
1383
1392
  authToken,
1384
1393
  language: getCultureCodeByLanguage(userLang),
1385
1394
  referral: referral,
1395
+ timeZoneOffset: new Date().getTimezoneOffset().toString(),
1386
1396
  },
1387
1397
  });
1388
1398
  } else if (!!currentState) {
@@ -2106,14 +2116,28 @@ const MemoriWidget = ({
2106
2116
  }
2107
2117
  };
2108
2118
 
2119
+ const focusChatInput = () => {
2120
+ let textarea = document.querySelector(
2121
+ '#chat-fieldset textarea'
2122
+ ) as HTMLTextAreaElement | null;
2123
+ // console.log('textarea', enableFocusChatInput);
2124
+ if (textarea && enableFocusChatInput) {
2125
+ textarea.focus();
2126
+ // console.log('focused');
2127
+ } else {
2128
+ textarea?.blur();
2129
+ // console.log('blurred');
2130
+ }
2131
+ };
2132
+
2109
2133
  /**
2110
2134
  * Focus on the chat input on mount
2111
2135
  */
2112
2136
  useEffect(() => {
2113
- let textarea = document.querySelector(
2114
- '#chat-fieldset textarea'
2115
- ) as HTMLTextAreaElement | null;
2116
- if (textarea) textarea.focus();
2137
+ // focus on chat input disabled for totem layout
2138
+ if (selectedLayout !== 'TOTEM') {
2139
+ focusChatInput();
2140
+ }
2117
2141
  // eslint-disable-next-line react-hooks/exhaustive-deps
2118
2142
  }, [currentDialogState?.emission]);
2119
2143
 
@@ -2162,13 +2186,16 @@ const MemoriWidget = ({
2162
2186
  /**
2163
2187
  * Listening methods
2164
2188
  */
2165
- const startListening = () => {
2189
+ const startListening = async () => {
2166
2190
  if (!AZURE_COGNITIVE_SERVICES_TTS_KEY) return;
2167
2191
 
2168
2192
  clearListening();
2169
2193
  setTranscript('');
2170
2194
  resetTranscript();
2171
2195
 
2196
+ // remove focus on chat input if the user is on mobile
2197
+ if (hasTouchscreen()) setEnableFocusChatInput(false);
2198
+
2172
2199
  try {
2173
2200
  navigator.mediaDevices
2174
2201
  .getUserMedia({ audio: true })
@@ -2669,6 +2696,7 @@ const MemoriWidget = ({
2669
2696
  additionalInfo?.loginToken ??
2670
2697
  authToken,
2671
2698
  language: getCultureCodeByLanguage(userLang),
2699
+ timeZoneOffset: new Date().getTimezoneOffset().toString(),
2672
2700
  },
2673
2701
  });
2674
2702
 
@@ -3079,6 +3107,9 @@ const MemoriWidget = ({
3079
3107
  loading: !!memoriTyping,
3080
3108
  baseUrl,
3081
3109
  apiUrl,
3110
+ enablePositionControls,
3111
+ setEnablePositionControls,
3112
+ avatarType,
3082
3113
  };
3083
3114
 
3084
3115
  const startPanelProps: StartPanelProps = {
@@ -3163,6 +3194,7 @@ const MemoriWidget = ({
3163
3194
  stopAudio,
3164
3195
  resetTranscript,
3165
3196
  listening,
3197
+ setEnableFocusChatInput,
3166
3198
  isPlayingAudio,
3167
3199
  customMediaRenderer,
3168
3200
  user,
@@ -3378,6 +3410,11 @@ const MemoriWidget = ({
3378
3410
  setControlsPosition={setControlsPosition}
3379
3411
  hideEmissions={hideEmissions}
3380
3412
  setHideEmissions={setHideEmissions}
3413
+ avatarType={avatarType}
3414
+ setAvatarType={setAvatarType}
3415
+ enablePositionControls={enablePositionControls}
3416
+ setEnablePositionControls={setEnablePositionControls}
3417
+ isAvatar3d={!!integrationConfig?.avatarURL}
3381
3418
  additionalSettings={additionalSettings}
3382
3419
  />
3383
3420
  )}
@@ -1,7 +1,7 @@
1
1
  .memori-settings-drawer .memori-settings-drawer--field {
2
2
  display: flex;
3
3
  flex-direction: column;
4
- margin: 0.5rem 0 1.5rem;
4
+ margin: 0.5rem 0;
5
5
  }
6
6
 
7
7
  .memori-settings-drawer .memori-settings-drawer--field .memori-select--value {
@@ -9,9 +9,11 @@
9
9
  }
10
10
 
11
11
  .memori-settings-drawer--controlsposition-radio,
12
+ .memori-settings-drawer--avatarType-radio,
12
13
  .memori-settings-drawer--microphoneMode-radio {
13
14
  display: flex;
14
15
  flex-wrap: wrap;
15
16
  align-items: center;
16
17
  margin: 0.5rem 0;
17
- }
18
+ gap: 0.2rem;
19
+ }
@@ -25,6 +25,9 @@ it('renders SettingsDrawer unchanged', () => {
25
25
  setControlsPosition={jest.fn()}
26
26
  hideEmissions={false}
27
27
  setHideEmissions={jest.fn()}
28
+ avatarType="avatar3d"
29
+ setAvatarType={jest.fn()}
30
+ setEnablePositionControls={jest.fn()}
28
31
  />
29
32
  );
30
33
  expect(container).toMatchSnapshot();
@@ -43,6 +46,9 @@ it('renders SettingsDrawer open unchanged', () => {
43
46
  setControlsPosition={jest.fn()}
44
47
  hideEmissions={false}
45
48
  setHideEmissions={jest.fn()}
49
+ avatarType="avatar3d"
50
+ setAvatarType={jest.fn()}
51
+ setEnablePositionControls={jest.fn()}
46
52
  />
47
53
  );
48
54
  expect(container).toMatchSnapshot();
@@ -61,6 +67,9 @@ it('renders SettingsDrawer open with continuous speech enabled unchanged', () =>
61
67
  setControlsPosition={jest.fn()}
62
68
  hideEmissions={false}
63
69
  setHideEmissions={jest.fn()}
70
+ avatarType="avatar3d"
71
+ setAvatarType={jest.fn()}
72
+ setEnablePositionControls={jest.fn()}
64
73
  />
65
74
  );
66
75
  expect(container).toMatchSnapshot();
@@ -79,6 +88,9 @@ it('renders SettingsDrawer open with non-default continuous speech timeout uncha
79
88
  setControlsPosition={jest.fn()}
80
89
  hideEmissions={false}
81
90
  setHideEmissions={jest.fn()}
91
+ avatarType="avatar3d"
92
+ setAvatarType={jest.fn()}
93
+ setEnablePositionControls={jest.fn()}
82
94
  />
83
95
  );
84
96
  expect(container).toMatchSnapshot();
@@ -98,6 +110,9 @@ it('renders SettingsDrawer for totem layout open unchanged', () => {
98
110
  setControlsPosition={jest.fn()}
99
111
  hideEmissions={false}
100
112
  setHideEmissions={jest.fn()}
113
+ avatarType="avatar3d"
114
+ setAvatarType={jest.fn()}
115
+ setEnablePositionControls={jest.fn()}
101
116
  />
102
117
  );
103
118
  expect(container).toMatchSnapshot();
@@ -117,6 +132,9 @@ it('renders SettingsDrawer for totem layout open with controls at center unchang
117
132
  setControlsPosition={jest.fn()}
118
133
  hideEmissions={false}
119
134
  setHideEmissions={jest.fn()}
135
+ avatarType="avatar3d"
136
+ setAvatarType={jest.fn()}
137
+ setEnablePositionControls={jest.fn()}
120
138
  />
121
139
  );
122
140
  expect(container).toMatchSnapshot();
@@ -136,6 +154,9 @@ it('renders SettingsDrawer for totem layout with continuous speech and hide emis
136
154
  setControlsPosition={jest.fn()}
137
155
  hideEmissions={true}
138
156
  setHideEmissions={jest.fn()}
157
+ avatarType="avatar3d"
158
+ setAvatarType={jest.fn()}
159
+ setEnablePositionControls={jest.fn()}
139
160
  />
140
161
  );
141
162
  expect(container).toMatchSnapshot();
@@ -172,6 +193,9 @@ it('renders SettingsDrawer with additional custom settings unchanged', () => {
172
193
  hideEmissions={false}
173
194
  setHideEmissions={jest.fn()}
174
195
  additionalSettings={<AdditionalSettings />}
196
+ avatarType="avatar3d"
197
+ setAvatarType={jest.fn()}
198
+ setEnablePositionControls={jest.fn()}
175
199
  />
176
200
  );
177
201
  expect(container).toMatchSnapshot();
@@ -3,10 +3,11 @@ import { useTranslation } from 'react-i18next';
3
3
  import Checkbox from '../ui/Checkbox';
4
4
  import Select from '../ui/Select';
5
5
  import { setLocalConfig } from '../../helpers/configuration';
6
- import { RadioGroup } from '@headlessui/react';
6
+ import { RadioGroup, Switch } from '@headlessui/react';
7
7
  import Button from '../ui/Button';
8
8
  import { Props as WidgetProps } from '../MemoriWidget/MemoriWidget';
9
-
9
+ import { useState } from 'react';
10
+ import Slider from '../ui/Slider';
10
11
  export interface Props {
11
12
  open: boolean;
12
13
  layout?: WidgetProps['layout'];
@@ -20,6 +21,11 @@ export interface Props {
20
21
  hideEmissions?: boolean;
21
22
  setHideEmissions: (value: boolean) => void;
22
23
  additionalSettings?: WidgetProps['additionalSettings'];
24
+ avatarType?: 'blob' | 'avatar3d' | null;
25
+ setAvatarType: (value: 'blob' | 'avatar3d' | null) => void;
26
+ enablePositionControls?: boolean;
27
+ setEnablePositionControls: (value: boolean) => void;
28
+ isAvatar3d?: boolean;
23
29
  }
24
30
 
25
31
  const silenceSeconds = [2, 3, 5, 10, 15, 20, 30, 60];
@@ -37,6 +43,11 @@ const SettingsDrawer = ({
37
43
  hideEmissions,
38
44
  setHideEmissions,
39
45
  additionalSettings,
46
+ avatarType,
47
+ setAvatarType,
48
+ enablePositionControls,
49
+ setEnablePositionControls,
50
+ isAvatar3d,
40
51
  }: Props) => {
41
52
  const { t } = useTranslation();
42
53
 
@@ -58,7 +69,7 @@ const SettingsDrawer = ({
58
69
  value={microphoneMode}
59
70
  defaultValue={microphoneMode}
60
71
  className="memori-settings-drawer--microphoneMode-radio"
61
- onChange={value => {
72
+ onChange={(value: any) => {
62
73
  let micMode =
63
74
  value === 'CONTINUOUS' ? 'CONTINUOUS' : 'HOLD_TO_TALK';
64
75
 
@@ -117,7 +128,7 @@ const SettingsDrawer = ({
117
128
  value={controlsPosition}
118
129
  defaultValue={controlsPosition}
119
130
  className="memori-settings-drawer--controlsposition-radio"
120
- onChange={value => {
131
+ onChange={(value: any) => {
121
132
  setControlsPosition(value);
122
133
  setLocalConfig('controlsPosition', value);
123
134
  }}
@@ -144,6 +155,67 @@ const SettingsDrawer = ({
144
155
  </RadioGroup.Option>
145
156
  </RadioGroup>
146
157
  </div>
158
+
159
+ {isAvatar3d && (
160
+ <>
161
+ <div className="memori-settings-drawer--field controls">
162
+
163
+ <label
164
+ htmlFor="avatarType"
165
+ className="memori-settings-drawer-label"
166
+ >
167
+ {t('write_and_speak.avatarType') || 'Avatar type'}:
168
+ </label>
169
+ <RadioGroup
170
+ id="avatarType"
171
+ name="avatarType"
172
+ value={avatarType}
173
+ defaultValue={avatarType}
174
+ className="memori-settings-drawer--avatarType-radio"
175
+ onChange={(value: any) => {
176
+ setAvatarType && setAvatarType(value);
177
+ setLocalConfig('avatarType', value);
178
+ }}
179
+ >
180
+ <RadioGroup.Option
181
+ value="blob"
182
+ className="memori-settings-drawer--avatarType-radio-button"
183
+ >
184
+ {({ checked }) => (
185
+ <Button primary={checked} outlined={!checked}>
186
+ {t('write_and_speak.blob') || 'Blob'}
187
+ </Button>
188
+ )}
189
+ </RadioGroup.Option>
190
+ <RadioGroup.Option
191
+ value="avatar3d"
192
+ className="memori-settings-drawer--avatarType-radio-button"
193
+ >
194
+ {({ checked }) => (
195
+ <Button primary={checked} outlined={!checked}>
196
+ {t('write_and_speak.avatar3d') || 'Avatar 3D'}
197
+ </Button>
198
+ )}
199
+ </RadioGroup.Option>
200
+ </RadioGroup>
201
+ </div>
202
+
203
+ <div className="memori-settings-drawer--field">
204
+ <Checkbox
205
+ label={
206
+ t('write_and_speak.enablePositionControls') ||
207
+ 'Enable position controls'
208
+ }
209
+ name="enablePositionControls"
210
+ checked={enablePositionControls}
211
+ onChange={e => {
212
+ setEnablePositionControls(e.target.checked);
213
+ }}
214
+ />
215
+ </div>
216
+ </>
217
+ )}
218
+
147
219
  <div className="memori-settings-drawer--field">
148
220
  <Checkbox
149
221
  label={
@@ -36,7 +36,7 @@ const TotemLayout: React.FC<LayoutProps> = ({
36
36
  </div>
37
37
 
38
38
  <div className="memori-totem-layout--avatar">
39
- {Avatar && avatarProps && <Avatar {...avatarProps} />}
39
+ {Avatar && avatarProps && <Avatar {...avatarProps} isTotem />}
40
40
  </div>
41
41
 
42
42
  <div id="extension" />
@@ -90,6 +90,116 @@ FullPage.args = {
90
90
  layout: 'FULLPAGE',
91
91
  };
92
92
 
93
+ export const Totem = Template.bind({});
94
+ Totem.args = {
95
+ uiLang: 'it',
96
+ showShare: true,
97
+ showSettings: true,
98
+ // memori,
99
+ // tenant,
100
+ memori: {
101
+ memoriID: '6573844d-a7cd-47ef-9e78-840d82020c21',
102
+ name: 'Nicola',
103
+ password: null,
104
+ recoveryTokens: null,
105
+ newPassword: null,
106
+ ownerUserID: null,
107
+ ownerUserName: 'nzambello',
108
+ ownerTenantName: 'aisuru.com',
109
+ memoriConfigurationID: 'fd10bb42-98d9-4c08-8e02-2b08bd4e4975',
110
+ description:
111
+ 'Sono Nicola Zambello, sviluppatore e attivista per un web etico e sostenibile',
112
+ completionDescription: null,
113
+ engineMemoriID: '9b0a2913-d3d8-4e98-a49d-6e1c99479e1b',
114
+ isOwner: false,
115
+ isGiver: false,
116
+ isReceiver: false,
117
+ giverTag: null,
118
+ giverPIN: null,
119
+ privacyType: 'PUBLIC',
120
+ secretToken: null,
121
+ minimumNumberOfRecoveryTokens: null,
122
+ totalNumberOfRecoveryTokens: null,
123
+ sentInvitations: [],
124
+ receivedInvitations: [],
125
+ integrations: [
126
+ {
127
+ integrationID: '62de8c99-0ac2-4cbe-bd95-a39ad7dc6b32',
128
+ memoriID: '6573844d-a7cd-47ef-9e78-840d82020c21',
129
+ type: 'LANDING_EXPERIENCE',
130
+ state: 'NEW',
131
+ deviceEmails: null,
132
+ invocationText: null,
133
+ jobID: null,
134
+ customData:
135
+ '{"textColor":"#000000","buttonBgColor":"#007eb6","buttonTextColor":"#ffffff","globalBackground":"https://assets.memori.ai/api/v2/asset/cade3b9c-0437-4342-b2bd-8db9c2a3a20e.png","blurBackground":true,"innerBgColor":"light","multilanguage":true,"avatar":"readyplayerme","avatarURL":"https://assets.memori.ai/api/v2/asset/893c41df-7619-436d-9e86-fe1d406fc933.glb#1681736752156","name":"Pagina pubblica","contextVars":"ANIMALE:CANE","personTag":"☠️","personPIN":"666666","personName":"Pirata","showShare":true,"avatarFullBodyURL":"https://models.readyplayer.me/63b55751f17e295642bf07a2.glb"}',
136
+ resources: [],
137
+ publish: true,
138
+ creationTimestamp: '2022-06-13T14:44:52.833573Z',
139
+ lastChangeTimestamp: '2022-06-13T14:44:52.833573Z',
140
+ },
141
+ ],
142
+ avatarURL:
143
+ 'https://assets.memori.ai/api/v2/asset/3049582f-db5f-452c-913d-e4340d4afd0a.png',
144
+ coverURL:
145
+ 'https://assets.memori.ai/api/v2/asset/e9bb9f6d-8f34-45ab-af9e-6d630d9a51a8.png',
146
+ avatar3DURL:
147
+ 'https://assets.memori.ai/api/v2/asset/893c41df-7619-436d-9e86-fe1d406fc933.glb',
148
+ avatarOriginal3DURL:
149
+ 'https://d1a370nemizbjq.cloudfront.net/c7c80a1d-deda-4fe1-96c6-fabad0771aa2.glb',
150
+ needsPosition: false,
151
+ voiceType: 'MALE',
152
+ culture: 'it-IT',
153
+ categories: [
154
+ 'biografico',
155
+ 'tecnologia',
156
+ 'web',
157
+ 'open-source',
158
+ 'green',
159
+ 'privacy',
160
+ ],
161
+ exposed: true,
162
+ disableR2R3Loop: null,
163
+ disableR4Loop: null,
164
+ disableR5Loop: null,
165
+ enableCompletions: true,
166
+ completionModel: null,
167
+ chainingMemoriID: null,
168
+ chainingBaseURL: null,
169
+ chainingPassword: null,
170
+ contentQualityIndex: 210.8,
171
+ contentQualityIndexTimestamp: '2023-04-17T00:01:32.194744Z',
172
+ publishedInTheMetaverse: true,
173
+ metaverseEnvironment: 'apartment',
174
+ blockedUntil: null,
175
+ creationTimestamp: '2022-06-13T14:21:55.793034Z',
176
+ lastChangeTimestamp: '2023-04-15T08:15:36.403546Z',
177
+ },
178
+ integration: {
179
+ integrationID: '62de8c99-0ac2-4cbe-bd95-a39ad7dc6b32',
180
+ memoriID: '6573844d-a7cd-47ef-9e78-840d82020c21',
181
+ type: 'LANDING_EXPERIENCE',
182
+ state: 'NEW',
183
+ deviceEmails: null,
184
+ invocationText: null,
185
+ jobID: null,
186
+ publish: true,
187
+ creationTimestamp: '2022-06-13T14:44:52.833573Z',
188
+ lastChangeTimestamp: '2022-06-13T14:44:52.833573Z',
189
+ customData: JSON.stringify({
190
+ ...JSON.parse(
191
+ '{"textColor":"#000000","buttonBgColor":"#007eb6","buttonTextColor":"#ffffff","globalBackground":"https://assets.memori.ai/api/v2/asset/cade3b9c-0437-4342-b2bd-8db9c2a3a20e.png","blurBackground":true,"innerBgColor":"light","multilanguage":true,"avatar":"readyplayerme","avatarURL":"https://assets.memori.ai/api/v2/asset/893c41df-7619-436d-9e86-fe1d406fc933.glb#1681736752156","name":"Pagina pubblica","contextVars":"ANIMALE:CANE","personTag":"☠️","personPIN":"666666","personName":"Pirata","showShare":true,"avatarFullBodyURL":"https://models.readyplayer.me/63b55751f17e295642bf07a2.glb"}'
192
+ ),
193
+ avatar: 'readyplayerme-full',
194
+ avatarURL:
195
+ 'https://models.readyplayer.me/63b55751f17e295642bf07a2.glb#' +
196
+ // 'https://models.readyplayer.me/63b558263858282637c54115.glb#' +
197
+ new Date(Date.now()).getTime(),
198
+ }),
199
+ },
200
+ layout: 'TOTEM',
201
+ };
202
+
93
203
  export const ChatOnly = Template.bind({});
94
204
  ChatOnly.args = {
95
205
  uiLang: 'it',
@@ -200,7 +310,6 @@ ChatOnly.args = {
200
310
  layout: 'CHAT',
201
311
  };
202
312
 
203
-
204
313
  export const Custom = Template.bind({});
205
314
  Custom.args = {
206
315
  uiLang: 'it',
@@ -431,7 +540,6 @@ HiddenChat.args = {
431
540
  layout: 'HIDDEN_CHAT',
432
541
  };
433
542
 
434
-
435
543
  export const ZoomedFullBody = Template.bind({});
436
544
  ZoomedFullBody.args = {
437
545
  uiLang: 'it',
@@ -535,7 +643,7 @@ ZoomedFullBody.args = {
535
643
  ),
536
644
  avatar: 'readyplayerme-full',
537
645
  avatarURL:
538
- 'https://assets.memori.ai/api/v2/asset/3932bf70-e953-4e8a-b63a-f316544c283e.glb'+
646
+ 'https://assets.memori.ai/api/v2/asset/3932bf70-e953-4e8a-b63a-f316544c283e.glb' +
539
647
  new Date(Date.now()).getTime(),
540
648
  }),
541
649
  },
@@ -1,5 +1,5 @@
1
1
  .memori-widget.memori-layout-totem {
2
- height: 100vh !important;
2
+ height: 95vh !important;
3
3
  }
4
4
 
5
5
  .memori-widget.memori-layout-totem .memori--global-background.no-background-image {
@@ -95,28 +95,28 @@
95
95
  bottom: auto;
96
96
  }
97
97
 
98
- .memori-totem-layout--avatar .memori--avatar-wrapper>div {
99
- overflow: visible !important;
98
+ /* .memori-totem-layout--avatar .memori--avatar-wrapper>div {
99
+ overflow: visible !important; */
100
100
  /* width: 100% !important;
101
101
  height: 100% !important; */
102
- width: auto !important;
102
+ /* width: auto !important;
103
103
  height: 90vh !important;
104
104
  max-height: 90vh;
105
105
  border-radius: 0;
106
106
  transform: scale(1.7) translate(0px, 10vh);
107
- }
107
+ } */
108
108
 
109
- .memori-totem-layout--avatar .memori--avatar-wrapper canvas {
109
+ /* .memori-totem-layout--avatar .memori--avatar-wrapper canvas {
110
110
  width: auto !important;
111
111
  max-width: 100%;
112
112
  height: 100% !important;
113
113
  max-height: 100%;
114
- }
114
+ } */
115
115
 
116
- .memori-totem-layout--controls {
116
+ /* .memori-totem-layout--controls {
117
117
  position: relative;
118
118
  z-index: 5;
119
- }
119
+ } */
120
120
 
121
121
  .memori-totem-layout--controls .memori--start-panel,
122
122
  .memori-totem-layout--controls .memori-chat--history,
@@ -12,6 +12,10 @@
12
12
  font-size: 14px;
13
13
  transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
14
14
  }
15
+ .memori-button--active {
16
+ background: var(--memori-primary);
17
+ color: var(--memori-primary-text);
18
+ }
15
19
 
16
20
  .memori-button:hover {
17
21
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.02), 0 4px 8px rgba(0, 0, 0, 0.04);