@memori.ai/memori-react 1.2.0 → 2.0.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 (291) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/README.md +12 -2
  3. package/dist/components/AgeVerificationModal/AgeVerificationModal.d.ts +7 -0
  4. package/dist/components/AgeVerificationModal/AgeVerificationModal.js +39 -0
  5. package/dist/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -0
  6. package/dist/components/AgeVerificationModal/AgeVerificationModal.test.d.ts +1 -0
  7. package/dist/components/AgeVerificationModal/AgeVerificationModal.test.js +27 -0
  8. package/dist/components/AgeVerificationModal/AgeVerificationModal.test.js.map +1 -0
  9. package/dist/components/AttachmentLinkModal/AttachmentLinkModal.stories.d.ts +2 -2
  10. package/dist/components/AttachmentMediaModal/AttachmentMediaModal.stories.d.ts +2 -2
  11. package/dist/components/Auth/Auth.stories.d.ts +5 -5
  12. package/dist/components/Avatar/Avatar.js +2 -2
  13. package/dist/components/Avatar/Avatar.js.map +1 -1
  14. package/dist/components/Avatar/Avatar.stories.d.ts +5 -5
  15. package/dist/components/AvatarView/AvatarView.stories.d.ts +10 -10
  16. package/dist/components/AvatarView/components/fullbodyAvatar.d.ts +2 -1
  17. package/dist/components/AvatarView/components/fullbodyAvatar.js +6 -3
  18. package/dist/components/AvatarView/components/fullbodyAvatar.js.map +1 -1
  19. package/dist/components/AvatarView/components/loader.js +3 -1
  20. package/dist/components/AvatarView/components/loader.js.map +1 -1
  21. package/dist/components/AvatarView/index.d.ts +2 -1
  22. package/dist/components/AvatarView/index.js +2 -2
  23. package/dist/components/AvatarView/index.js.map +1 -1
  24. package/dist/components/AvatarView/utils/useMouthSpeaking.js +3 -1
  25. package/dist/components/AvatarView/utils/useMouthSpeaking.js.map +1 -1
  26. package/dist/components/Blob/Blob.stories.d.ts +4 -4
  27. package/dist/components/BlockedMemoriBadge/BlockedMemoriBadge.stories.d.ts +5 -5
  28. package/dist/components/ChangeMode/ChangeMode.stories.d.ts +3 -3
  29. package/dist/components/Chat/Chat.stories.d.ts +12 -12
  30. package/dist/components/ChatBubble/ChatBubble.stories.d.ts +7 -7
  31. package/dist/components/ChatInputs/ChatInputs.js +2 -1
  32. package/dist/components/ChatInputs/ChatInputs.js.map +1 -1
  33. package/dist/components/ChatInputs/ChatInputs.stories.d.ts +9 -9
  34. package/dist/components/ChatTextArea/ChatTextArea.stories.d.ts +4 -4
  35. package/dist/components/CustomGLBModelViewer/ModelViewer.stories.d.ts +2 -2
  36. package/dist/components/DateSelector/DateSelector.d.ts +9 -0
  37. package/dist/components/DateSelector/DateSelector.js +61 -0
  38. package/dist/components/DateSelector/DateSelector.js.map +1 -0
  39. package/dist/components/DateSelector/DateSelector.test.d.ts +1 -0
  40. package/dist/components/DateSelector/DateSelector.test.js +24 -0
  41. package/dist/components/DateSelector/DateSelector.test.js.map +1 -0
  42. package/dist/components/ExportHistoryButton/ExportHistoryButton.stories.d.ts +5 -5
  43. package/dist/components/FeedbackButtons/FeedbackButtons.stories.d.ts +4 -4
  44. package/dist/components/Header/Header.d.ts +1 -0
  45. package/dist/components/Header/Header.js +26 -2
  46. package/dist/components/Header/Header.js.map +1 -1
  47. package/dist/components/Header/Header.stories.d.ts +7 -7
  48. package/dist/components/ImageUpload/ImageUpload.stories.d.ts +8 -8
  49. package/dist/components/MediaWidget/LinkItemWidget.d.ts +2 -1
  50. package/dist/components/MediaWidget/LinkItemWidget.js +10 -2
  51. package/dist/components/MediaWidget/LinkItemWidget.js.map +1 -1
  52. package/dist/components/MediaWidget/LinkItemWidget.stories.d.ts +2 -2
  53. package/dist/components/MediaWidget/MediaItemWidget.d.ts +3 -1
  54. package/dist/components/MediaWidget/MediaItemWidget.js +44 -72
  55. package/dist/components/MediaWidget/MediaItemWidget.js.map +1 -1
  56. package/dist/components/MediaWidget/MediaItemWidget.stories.d.ts +3 -3
  57. package/dist/components/MediaWidget/MediaWidget.js +10 -7
  58. package/dist/components/MediaWidget/MediaWidget.js.map +1 -1
  59. package/dist/components/MediaWidget/MediaWidget.stories.d.ts +5 -5
  60. package/dist/components/MemoriWidget/MemoriWidget.d.ts +3 -2
  61. package/dist/components/MemoriWidget/MemoriWidget.js +92 -25
  62. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  63. package/dist/components/MemoriWidget/MemoriWidget.stories.d.ts +8 -8
  64. package/dist/components/PoweredBy/PoweredBy.stories.d.ts +4 -4
  65. package/dist/components/SendOnEnterMenu/SendOnEnterMenu.stories.d.ts +3 -3
  66. package/dist/components/SettingsDrawer/SettingsDrawer.d.ts +13 -0
  67. package/dist/components/SettingsDrawer/SettingsDrawer.js +27 -0
  68. package/dist/components/SettingsDrawer/SettingsDrawer.js.map +1 -0
  69. package/dist/components/SettingsDrawer/SettingsDrawer.test.d.ts +1 -0
  70. package/dist/components/SettingsDrawer/SettingsDrawer.test.js +27 -0
  71. package/dist/components/SettingsDrawer/SettingsDrawer.test.js.map +1 -0
  72. package/dist/components/ShareButton/ShareButton.stories.d.ts +4 -4
  73. package/dist/components/Snippet/Snippet.stories.d.ts +15 -15
  74. package/dist/components/StartPanel/StartPanel.d.ts +1 -1
  75. package/dist/components/StartPanel/StartPanel.js +10 -7
  76. package/dist/components/StartPanel/StartPanel.js.map +1 -1
  77. package/dist/components/StartPanel/StartPanel.stories.d.ts +6 -6
  78. package/dist/components/StartPanel/StartPanel.test.js +7 -0
  79. package/dist/components/StartPanel/StartPanel.test.js.map +1 -1
  80. package/dist/components/UploadMenu/UploadMenu.stories.d.ts +4 -4
  81. package/dist/components/icons/Refresh.d.ts +5 -0
  82. package/dist/components/icons/Refresh.js +6 -0
  83. package/dist/components/icons/Refresh.js.map +1 -0
  84. package/dist/components/icons/SelectIcon.d.ts +5 -0
  85. package/dist/components/icons/SelectIcon.js +6 -0
  86. package/dist/components/icons/SelectIcon.js.map +1 -0
  87. package/dist/components/icons/icons.stories.d.ts +2 -2
  88. package/dist/components/layouts/FullPage.d.ts +17 -0
  89. package/dist/components/layouts/FullPage.js +8 -0
  90. package/dist/components/layouts/FullPage.js.map +1 -0
  91. package/dist/components/layouts/FullPage.test.d.ts +1 -0
  92. package/dist/components/layouts/FullPage.test.js +12 -0
  93. package/dist/components/layouts/FullPage.test.js.map +1 -0
  94. package/dist/components/layouts/Totem.d.ts +17 -0
  95. package/dist/components/layouts/Totem.js +8 -0
  96. package/dist/components/layouts/Totem.js.map +1 -0
  97. package/dist/components/layouts/Totem.test.d.ts +1 -0
  98. package/dist/components/layouts/Totem.test.js +12 -0
  99. package/dist/components/layouts/Totem.test.js.map +1 -0
  100. package/dist/components/ui/Button.stories.d.ts +14 -14
  101. package/dist/components/ui/Card.stories.d.ts +7 -7
  102. package/dist/components/ui/Checkbox.d.ts +2 -0
  103. package/dist/components/ui/Checkbox.js +2 -2
  104. package/dist/components/ui/Checkbox.js.map +1 -1
  105. package/dist/components/ui/Checkbox.stories.d.ts +5 -5
  106. package/dist/components/ui/Drawer.stories.d.ts +9 -9
  107. package/dist/components/ui/Modal.stories.d.ts +9 -9
  108. package/dist/components/ui/Select.d.ts +15 -0
  109. package/dist/components/ui/Select.js +17 -0
  110. package/dist/components/ui/Select.js.map +1 -0
  111. package/dist/components/ui/Select.test.d.ts +1 -0
  112. package/dist/components/ui/Select.test.js +47 -0
  113. package/dist/components/ui/Select.test.js.map +1 -0
  114. package/dist/components/ui/Spin.stories.d.ts +4 -4
  115. package/dist/components/ui/Tooltip.stories.d.ts +6 -6
  116. package/dist/components/ui/definitions.stories.d.ts +2 -3
  117. package/dist/helpers/configuration.js +2 -0
  118. package/dist/helpers/configuration.js.map +1 -1
  119. package/dist/helpers/utils.js +1 -1
  120. package/dist/helpers/utils.js.map +1 -1
  121. package/dist/index.d.ts +2 -0
  122. package/dist/index.js +2 -2
  123. package/dist/index.js.map +1 -1
  124. package/dist/index.stories.d.ts +2 -2
  125. package/dist/locales/en.json +17 -0
  126. package/dist/locales/it.json +17 -0
  127. package/dist/mocks/data.js +5 -2
  128. package/dist/mocks/data.js.map +1 -1
  129. package/esm/components/AgeVerificationModal/AgeVerificationModal.d.ts +7 -0
  130. package/esm/components/AgeVerificationModal/AgeVerificationModal.js +36 -0
  131. package/esm/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -0
  132. package/esm/components/AgeVerificationModal/AgeVerificationModal.test.d.ts +1 -0
  133. package/esm/components/AgeVerificationModal/AgeVerificationModal.test.js +24 -0
  134. package/esm/components/AgeVerificationModal/AgeVerificationModal.test.js.map +1 -0
  135. package/esm/components/Avatar/Avatar.js +2 -2
  136. package/esm/components/Avatar/Avatar.js.map +1 -1
  137. package/esm/components/AvatarView/components/fullbodyAvatar.d.ts +2 -1
  138. package/esm/components/AvatarView/components/fullbodyAvatar.js +7 -4
  139. package/esm/components/AvatarView/components/fullbodyAvatar.js.map +1 -1
  140. package/esm/components/AvatarView/components/loader.js +2 -1
  141. package/esm/components/AvatarView/components/loader.js.map +1 -1
  142. package/esm/components/AvatarView/index.d.ts +2 -1
  143. package/esm/components/AvatarView/index.js +2 -2
  144. package/esm/components/AvatarView/index.js.map +1 -1
  145. package/esm/components/AvatarView/utils/useMouthSpeaking.js +3 -1
  146. package/esm/components/AvatarView/utils/useMouthSpeaking.js.map +1 -1
  147. package/esm/components/ChatInputs/ChatInputs.js +2 -1
  148. package/esm/components/ChatInputs/ChatInputs.js.map +1 -1
  149. package/esm/components/DateSelector/DateSelector.d.ts +9 -0
  150. package/esm/components/DateSelector/DateSelector.js +58 -0
  151. package/esm/components/DateSelector/DateSelector.js.map +1 -0
  152. package/esm/components/DateSelector/DateSelector.test.d.ts +1 -0
  153. package/esm/components/DateSelector/DateSelector.test.js +21 -0
  154. package/esm/components/DateSelector/DateSelector.test.js.map +1 -0
  155. package/esm/components/Header/Header.d.ts +1 -0
  156. package/esm/components/Header/Header.js +26 -2
  157. package/esm/components/Header/Header.js.map +1 -1
  158. package/esm/components/MediaWidget/LinkItemWidget.d.ts +2 -1
  159. package/esm/components/MediaWidget/LinkItemWidget.js +10 -2
  160. package/esm/components/MediaWidget/LinkItemWidget.js.map +1 -1
  161. package/esm/components/MediaWidget/MediaItemWidget.d.ts +3 -1
  162. package/esm/components/MediaWidget/MediaItemWidget.js +44 -72
  163. package/esm/components/MediaWidget/MediaItemWidget.js.map +1 -1
  164. package/esm/components/MediaWidget/MediaWidget.js +11 -8
  165. package/esm/components/MediaWidget/MediaWidget.js.map +1 -1
  166. package/esm/components/MemoriWidget/MemoriWidget.d.ts +3 -2
  167. package/esm/components/MemoriWidget/MemoriWidget.js +92 -25
  168. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  169. package/esm/components/SettingsDrawer/SettingsDrawer.d.ts +13 -0
  170. package/esm/components/SettingsDrawer/SettingsDrawer.js +24 -0
  171. package/esm/components/SettingsDrawer/SettingsDrawer.js.map +1 -0
  172. package/esm/components/SettingsDrawer/SettingsDrawer.test.d.ts +1 -0
  173. package/esm/components/SettingsDrawer/SettingsDrawer.test.js +24 -0
  174. package/esm/components/SettingsDrawer/SettingsDrawer.test.js.map +1 -0
  175. package/esm/components/StartPanel/StartPanel.d.ts +1 -1
  176. package/esm/components/StartPanel/StartPanel.js +10 -7
  177. package/esm/components/StartPanel/StartPanel.js.map +1 -1
  178. package/esm/components/StartPanel/StartPanel.test.js +7 -0
  179. package/esm/components/StartPanel/StartPanel.test.js.map +1 -1
  180. package/esm/components/icons/Refresh.d.ts +5 -0
  181. package/esm/components/icons/Refresh.js +4 -0
  182. package/esm/components/icons/Refresh.js.map +1 -0
  183. package/esm/components/icons/SelectIcon.d.ts +5 -0
  184. package/esm/components/icons/SelectIcon.js +4 -0
  185. package/esm/components/icons/SelectIcon.js.map +1 -0
  186. package/esm/components/layouts/FullPage.d.ts +17 -0
  187. package/esm/components/layouts/FullPage.js +5 -0
  188. package/esm/components/layouts/FullPage.js.map +1 -0
  189. package/esm/components/layouts/FullPage.test.d.ts +1 -0
  190. package/esm/components/layouts/FullPage.test.js +9 -0
  191. package/esm/components/layouts/FullPage.test.js.map +1 -0
  192. package/esm/components/layouts/Totem.d.ts +17 -0
  193. package/esm/components/layouts/Totem.js +5 -0
  194. package/esm/components/layouts/Totem.js.map +1 -0
  195. package/esm/components/layouts/Totem.test.d.ts +1 -0
  196. package/esm/components/layouts/Totem.test.js +9 -0
  197. package/esm/components/layouts/Totem.test.js.map +1 -0
  198. package/esm/components/ui/Checkbox.d.ts +2 -0
  199. package/esm/components/ui/Checkbox.js +2 -2
  200. package/esm/components/ui/Checkbox.js.map +1 -1
  201. package/esm/components/ui/Select.d.ts +15 -0
  202. package/esm/components/ui/Select.js +14 -0
  203. package/esm/components/ui/Select.js.map +1 -0
  204. package/esm/components/ui/Select.test.d.ts +1 -0
  205. package/esm/components/ui/Select.test.js +44 -0
  206. package/esm/components/ui/Select.test.js.map +1 -0
  207. package/esm/helpers/configuration.js +2 -0
  208. package/esm/helpers/configuration.js.map +1 -1
  209. package/esm/helpers/utils.js +1 -1
  210. package/esm/helpers/utils.js.map +1 -1
  211. package/esm/index.d.ts +2 -0
  212. package/esm/index.js +2 -2
  213. package/esm/index.js.map +1 -1
  214. package/esm/locales/en.json +17 -0
  215. package/esm/locales/it.json +17 -0
  216. package/esm/mocks/data.js +5 -2
  217. package/esm/mocks/data.js.map +1 -1
  218. package/package.json +20 -16
  219. package/src/components/AgeVerificationModal/AgeVerificationModal.css +63 -0
  220. package/src/components/AgeVerificationModal/AgeVerificationModal.stories.tsx +41 -0
  221. package/src/components/AgeVerificationModal/AgeVerificationModal.test.tsx +33 -0
  222. package/src/components/AgeVerificationModal/AgeVerificationModal.tsx +89 -0
  223. package/src/components/AgeVerificationModal/__snapshots__/AgeVerificationModal.test.tsx.snap +19 -0
  224. package/src/components/Avatar/Avatar.stories.tsx +20 -1
  225. package/src/components/Avatar/Avatar.tsx +2 -1
  226. package/src/components/Avatar/__snapshots__/Avatar.test.tsx.snap +2 -2
  227. package/src/components/AvatarView/AvatarView.stories.tsx +31 -0
  228. package/src/components/AvatarView/components/fullbodyAvatar.tsx +8 -6
  229. package/src/components/AvatarView/components/loader.tsx +15 -12
  230. package/src/components/AvatarView/index.tsx +4 -1
  231. package/src/components/AvatarView/utils/useMouthSpeaking.ts +3 -1
  232. package/src/components/Chat/__snapshots__/Chat.test.tsx.snap +67 -67
  233. package/src/components/ChatBubble/ChatBubble.css +1 -2
  234. package/src/components/ChatBubble/__snapshots__/ChatBubble.test.tsx.snap +4 -4
  235. package/src/components/ChatInputs/ChatInputs.css +14 -3
  236. package/src/components/ChatInputs/ChatInputs.tsx +2 -0
  237. package/src/components/ChatInputs/__snapshots__/ChatInputs.test.tsx.snap +5 -5
  238. package/src/components/DateSelector/DateSelector.css +135 -0
  239. package/src/components/DateSelector/DateSelector.stories.tsx +34 -0
  240. package/src/components/DateSelector/DateSelector.test.tsx +38 -0
  241. package/src/components/DateSelector/DateSelector.tsx +203 -0
  242. package/src/components/DateSelector/__snapshots__/DateSelector.test.tsx.snap +14938 -0
  243. package/src/components/Header/Header.stories.tsx +23 -5
  244. package/src/components/Header/Header.tsx +47 -1
  245. package/src/components/MediaWidget/LinkItemWidget.tsx +20 -1
  246. package/src/components/MediaWidget/MediaItemWidget.css +67 -0
  247. package/src/components/MediaWidget/MediaItemWidget.tsx +72 -71
  248. package/src/components/MediaWidget/MediaWidget.css +9 -0
  249. package/src/components/MediaWidget/MediaWidget.stories.tsx +8 -0
  250. package/src/components/MediaWidget/MediaWidget.tsx +44 -27
  251. package/src/components/MediaWidget/__snapshots__/MediaItemWidget.test.tsx.snap +1 -1
  252. package/src/components/MemoriWidget/MemoriWidget.css +1 -1
  253. package/src/components/MemoriWidget/MemoriWidget.stories.tsx +12 -0
  254. package/src/components/MemoriWidget/MemoriWidget.tsx +178 -33
  255. package/src/components/SettingsDrawer/SettingsDrawer.css +5 -0
  256. package/src/components/SettingsDrawer/SettingsDrawer.stories.tsx +57 -0
  257. package/src/components/SettingsDrawer/SettingsDrawer.test.tsx +61 -0
  258. package/src/components/SettingsDrawer/SettingsDrawer.tsx +108 -0
  259. package/src/components/SettingsDrawer/__snapshots__/SettingsDrawer.test.tsx.snap +19 -0
  260. package/src/components/StartPanel/StartPanel.css +8 -2
  261. package/src/components/StartPanel/StartPanel.stories.tsx +66 -2
  262. package/src/components/StartPanel/StartPanel.test.tsx +21 -0
  263. package/src/components/StartPanel/StartPanel.tsx +28 -23
  264. package/src/components/StartPanel/__snapshots__/StartPanel.test.tsx.snap +420 -67
  265. package/src/components/icons/Refresh.tsx +30 -0
  266. package/src/components/icons/SelectIcon.tsx +28 -0
  267. package/src/components/layouts/FullPage.test.tsx +17 -0
  268. package/src/components/layouts/{Default.tsx → FullPage.tsx} +2 -2
  269. package/src/components/layouts/Totem.test.tsx +17 -0
  270. package/src/components/layouts/Totem.tsx +52 -0
  271. package/src/components/layouts/__snapshots__/FullPage.test.tsx.snap +391 -0
  272. package/src/components/layouts/__snapshots__/Totem.test.tsx.snap +422 -0
  273. package/src/components/layouts/layouts.stories.tsx +155 -0
  274. package/src/components/layouts/totem.css +148 -0
  275. package/src/components/ui/Button.css +4 -0
  276. package/src/components/ui/Checkbox.tsx +6 -0
  277. package/src/components/ui/Drawer.css +24 -2
  278. package/src/components/ui/Select.css +135 -0
  279. package/src/components/ui/Select.stories.tsx +79 -0
  280. package/src/components/ui/Select.test.tsx +84 -0
  281. package/src/components/ui/Select.tsx +73 -0
  282. package/src/components/ui/Spin.css +2 -0
  283. package/src/components/ui/__snapshots__/Select.test.tsx.snap +278 -0
  284. package/src/helpers/configuration.ts +4 -2
  285. package/src/helpers/utils.ts +3 -2
  286. package/src/index.stories.tsx +41 -1
  287. package/src/index.tsx +7 -2
  288. package/src/locales/en.json +17 -0
  289. package/src/locales/it.json +17 -0
  290. package/src/mocks/data.ts +5 -2
  291. package/src/styles.css +24 -2
@@ -13,7 +13,7 @@ import {
13
13
  GamificationLevel,
14
14
  Tenant,
15
15
  Asset,
16
- } from '@memori.ai/memori-api-client/dist/types';
16
+ } from '@memori.ai/memori-api-client/src/types';
17
17
  import {
18
18
  SpeakerAudioDestination,
19
19
  SpeechConfig,
@@ -52,7 +52,8 @@ import AttachmentLinkModal from '../AttachmentLinkModal/AttachmentLinkModal';
52
52
  import PoweredBy from '../PoweredBy/PoweredBy';
53
53
 
54
54
  // Layout
55
- import DefaultLayout from '../layouts/Default';
55
+ import FullPageLayout from '../layouts/FullPage';
56
+ import TotemLayout from '../layouts/Totem';
56
57
 
57
58
  // Helpers / Utils
58
59
  import { getTranslation } from '../../helpers/translations';
@@ -61,6 +62,8 @@ import { hasTouchscreen, stripDuplicates } from '../../helpers/utils';
61
62
  import { anonTag } from '../../helpers/constants';
62
63
  import { getErrori18nKey } from '../../helpers/error';
63
64
  import { getGamificationLevel } from '../../helpers/statistics';
65
+ import AgeVerificationModal from '../AgeVerificationModal/AgeVerificationModal';
66
+ import SettingsDrawer from '../SettingsDrawer/SettingsDrawer';
64
67
 
65
68
  // Widget utilities and helpers
66
69
  const getMemoriState = (integrationId?: string): object | null => {
@@ -136,7 +139,6 @@ window.getMemoriState = getMemoriState;
136
139
  window.typeMessage = typeMessage;
137
140
 
138
141
  // Global variables
139
- const silenceSeconds = [2, 3, 5, 10, 15, 20, 30, 60];
140
142
  let recognizer: SpeechRecognizer | null;
141
143
  let speechConfig: SpeechConfig;
142
144
  let speechSynthesizer: SpeechSynthesizer | null;
@@ -148,6 +150,7 @@ export interface Props {
148
150
  memoriConfigs?: MemoriConfig[];
149
151
  memoriLang?: string;
150
152
  integration?: Integration;
153
+ layout?: 'DEFAULT' | 'FULLPAGE' | 'TOTEM';
151
154
  showShare?: boolean;
152
155
  showInstruct?: boolean;
153
156
  showInputs?: boolean;
@@ -180,6 +183,7 @@ const MemoriWidget = ({
180
183
  memoriConfigs,
181
184
  memoriLang,
182
185
  integration,
186
+ layout = 'DEFAULT',
183
187
  showInstruct = false,
184
188
  showShare = true,
185
189
  preview = false,
@@ -187,7 +191,7 @@ const MemoriWidget = ({
187
191
  showInputs = true,
188
192
  showDates = false,
189
193
  showContextPerLine = false,
190
- showSettings = false,
194
+ showSettings = true,
191
195
  height = '100vh',
192
196
  secret,
193
197
  baseUrl = 'https://app.twincreator.com',
@@ -220,7 +224,6 @@ const MemoriWidget = ({
220
224
  getSession,
221
225
  getContentQualityIndexes,
222
226
  } = client;
223
- const { uploadAsset, getUploadAssetURL, deleteAsset } = client.backend;
224
227
 
225
228
  const [instruct, setInstruct] = useState(false);
226
229
 
@@ -247,6 +250,8 @@ const MemoriWidget = ({
247
250
  const [loading, setLoading] = useState(false);
248
251
  const [memoriTyping, setMemoriTyping] = useState(false);
249
252
 
253
+ const selectedLayout = layout || integrationConfig?.layout || 'DEFAULT';
254
+
250
255
  const [hasUserActivatedSpeak, setHasUserActivatedSpeak] = useState(false);
251
256
  const [hasUserActivatedListening, setHasUserActivatedListening] =
252
257
  useState(false);
@@ -254,8 +259,11 @@ const MemoriWidget = ({
254
259
  const [showSettingsDrawer, setShowSettingsDrawer] = useState(false);
255
260
  const [muteSpeaker, setMuteSpeaker] = useState(false);
256
261
  const [continuousSpeech, setContinuousSpeech] = useState(true);
257
- const [continuousSpeechTimeout, setContinuousSpeechTimeout] = useState(3);
262
+ const [continuousSpeechTimeout, setContinuousSpeechTimeout] = useState(2);
258
263
  const [isPlayingAudio, setIsPlayingAudio] = useState(false);
264
+ const [controlsPosition, setControlsPosition] = useState<'center' | 'bottom'>(
265
+ 'center'
266
+ );
259
267
  useEffect(() => {
260
268
  setIsPlayingAudio(!!speechSynthesizer);
261
269
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -264,7 +272,8 @@ const MemoriWidget = ({
264
272
  useEffect(() => {
265
273
  setMuteSpeaker(getLocalConfig('muteSpeaker', false));
266
274
  setContinuousSpeech(getLocalConfig('continuousSpeech', true));
267
- setContinuousSpeechTimeout(getLocalConfig('continuousSpeechTimeout', 3));
275
+ setContinuousSpeechTimeout(getLocalConfig('continuousSpeechTimeout', 2));
276
+ setControlsPosition(getLocalConfig('controlsPosition', 'center'));
268
277
  }, []);
269
278
 
270
279
  /**
@@ -541,6 +550,19 @@ const MemoriWidget = ({
541
550
  return translatedState;
542
551
  };
543
552
 
553
+ /**
554
+ * Age verification
555
+ */
556
+ const minAge = memori.ageRestriction
557
+ ? memori.ageRestriction
558
+ : memori.nsfw
559
+ ? 18
560
+ : memori.enableCompletions
561
+ ? 14
562
+ : 0;
563
+ const [birthDate, setBirthDate] = useState<string | undefined>();
564
+ const [showAgeVerification, setShowAgeVerification] = useState(false);
565
+
544
566
  /**
545
567
  * Sessione
546
568
  */
@@ -570,6 +592,15 @@ const MemoriWidget = ({
570
592
  return;
571
593
  }
572
594
 
595
+ let storageBirthDate = getLocalConfig<string | undefined>(
596
+ 'birthDate',
597
+ undefined
598
+ );
599
+ if (!(birthDate || storageBirthDate) && !!minAge) {
600
+ setShowAgeVerification(true);
601
+ return;
602
+ }
603
+
573
604
  setLoading(true);
574
605
  try {
575
606
  if (!memori.giverTag && !!memori.receivedInvitations?.length) {
@@ -598,6 +629,12 @@ const MemoriWidget = ({
598
629
  dialogState: session.currentState,
599
630
  sessionID: session.sessionID,
600
631
  } as { dialogState: DialogState; sessionID: string };
632
+ } else if (
633
+ session?.resultMessage.startsWith('This Memori is aged restricted')
634
+ ) {
635
+ console.error(session);
636
+ message.error(t('underageTwinSession', { age: minAge }));
637
+ setGotErrorInOpening(true);
601
638
  } else {
602
639
  console.error(session);
603
640
  message.error(t(getErrori18nKey(session?.resultCode)));
@@ -615,10 +652,16 @@ const MemoriWidget = ({
615
652
  tag?: string,
616
653
  pin?: string,
617
654
  initialContextVars?: { [key: string]: string },
618
- initialQuestion?: string
655
+ initialQuestion?: string,
656
+ birthDate?: string
619
657
  ) => {
620
658
  setLoading(true);
621
659
  try {
660
+ let storageBirthDate = getLocalConfig<string | undefined>(
661
+ 'birthDate',
662
+ undefined
663
+ );
664
+
622
665
  const { sessionID, currentState, ...response } = await initSession({
623
666
  memoriID: memori.engineMemoriID ?? '',
624
667
  password,
@@ -627,6 +670,7 @@ const MemoriWidget = ({
627
670
  pin,
628
671
  initialContextVars,
629
672
  initialQuestion,
673
+ birthDate: birthDate || storageBirthDate || undefined,
630
674
  });
631
675
 
632
676
  if (sessionID && currentState && response.resultCode === 0) {
@@ -658,6 +702,12 @@ const MemoriWidget = ({
658
702
  dialogState: currentState,
659
703
  sessionID,
660
704
  };
705
+ } else if (
706
+ response?.resultMessage.startsWith('This Memori is aged restricted')
707
+ ) {
708
+ console.error(response);
709
+ message.error(t('underageTwinSession', { age: minAge }));
710
+ setGotErrorInOpening(true);
661
711
  } else {
662
712
  console.error(response);
663
713
  message.error(t(getErrori18nKey(response.resultCode)));
@@ -714,6 +764,11 @@ const MemoriWidget = ({
714
764
  }
715
765
  } else if ([400, 401, 403, 404, 500].includes(resultCode)) {
716
766
  console.warn('[APPCONTEXT/CHANGETAG]', resultCode);
767
+ let storageBirthDate = getLocalConfig<string | undefined>(
768
+ 'birthDate',
769
+ undefined
770
+ );
771
+
717
772
  fetchSession({
718
773
  memoriID: memori.engineMemoriID ?? '',
719
774
  password: secret || memori.secretToken,
@@ -721,6 +776,7 @@ const MemoriWidget = ({
721
776
  pin: memori.giverPIN,
722
777
  initialContextVars,
723
778
  initialQuestion,
779
+ birthDate: birthDate || storageBirthDate || undefined,
724
780
  });
725
781
  } else if (!!currentState) {
726
782
  return {
@@ -1085,6 +1141,8 @@ const MemoriWidget = ({
1085
1141
 
1086
1142
  const speak = (text: string): void => {
1087
1143
  if (!AZURE_COGNITIVE_SERVICES_TTS_KEY) return;
1144
+ stopListening();
1145
+ // stopAudio();
1088
1146
 
1089
1147
  if (preview) return;
1090
1148
  if (muteSpeaker) {
@@ -1095,10 +1153,6 @@ const MemoriWidget = ({
1095
1153
  return;
1096
1154
  }
1097
1155
 
1098
- if (listening) {
1099
- stopListening();
1100
- }
1101
-
1102
1156
  if (audioDestination) audioDestination.pause();
1103
1157
 
1104
1158
  // if (audioContext?.state === 'running') {
@@ -1180,12 +1234,10 @@ const MemoriWidget = ({
1180
1234
  audioDestination.onAudioEnd = () => {
1181
1235
  setIsPlayingAudio(false);
1182
1236
  source.disconnect();
1183
- // stopAudio();
1184
1237
 
1185
- if (continuousSpeech) {
1186
- // trigger start continuous listening if set
1187
- document.dispatchEvent(new Event('endSpeakStartListen'));
1188
- }
1238
+ // trigger start continuous listening if set
1239
+ // document.dispatchEvent(new Event('endSpeakStartListen'));
1240
+ onEndSpeakStartListen();
1189
1241
  };
1190
1242
 
1191
1243
  setIsPlayingAudio(true);
@@ -1361,6 +1413,7 @@ const MemoriWidget = ({
1361
1413
 
1362
1414
  setListening(true);
1363
1415
  recognizer.recognized = (_s, e) => {
1416
+ if (!e.result.text) return;
1364
1417
  if (e.result.reason === speechSdk.ResultReason.RecognizedSpeech) {
1365
1418
  let transcript = e.result.text;
1366
1419
  setTranscript(transcript || '');
@@ -1430,7 +1483,7 @@ const MemoriWidget = ({
1430
1483
  */
1431
1484
  const [requestedListening, setRequestedListening] = useState(false);
1432
1485
  const onEndSpeakStartListen = useCallback(
1433
- (_e: Event) => {
1486
+ (_e?: Event) => {
1434
1487
  if (isPlayingAudio && speechSynthesizer) {
1435
1488
  speechSynthesizer.close();
1436
1489
  speechSynthesizer = null;
@@ -1447,7 +1500,12 @@ const MemoriWidget = ({
1447
1500
  [continuousSpeech, hasUserActivatedListening]
1448
1501
  );
1449
1502
  useEffect(() => {
1450
- if (!isPlayingAudio && continuousSpeech && hasUserActivatedListening)
1503
+ if (
1504
+ history.length > 1 &&
1505
+ !isPlayingAudio &&
1506
+ continuousSpeech &&
1507
+ (hasUserActivatedListening || !requestedListening)
1508
+ )
1451
1509
  startListening();
1452
1510
  else if (isPlayingAudio && listening) {
1453
1511
  stopListening();
@@ -1561,7 +1619,12 @@ const MemoriWidget = ({
1561
1619
  // eslint-disable-next-line
1562
1620
  const [avatar3dVisible, setAvatar3dVisible] = useState(false);
1563
1621
  useEffect(() => {
1564
- if (window.innerWidth >= 768) setAvatar3dVisible(true);
1622
+ if (
1623
+ (window.innerWidth >= 768 && selectedLayout === 'FULLPAGE') ||
1624
+ selectedLayout !== 'FULLPAGE'
1625
+ ) {
1626
+ setAvatar3dVisible(true);
1627
+ }
1565
1628
  }, []);
1566
1629
 
1567
1630
  const [gamificationLevel, setGamificationLevel] =
@@ -1694,6 +1757,7 @@ const MemoriWidget = ({
1694
1757
 
1695
1758
  const simulateUserPrompt = (text: string, translatedText?: string) => {
1696
1759
  stopListening();
1760
+ stopAudio();
1697
1761
  sendMessage(text, undefined, undefined, false, translatedText);
1698
1762
  };
1699
1763
 
@@ -1718,6 +1782,12 @@ const MemoriWidget = ({
1718
1782
  });
1719
1783
  }
1720
1784
 
1785
+ let storageBirthDate = getLocalConfig<string | undefined>(
1786
+ 'birthDate',
1787
+ undefined
1788
+ );
1789
+ let birth = birthDate || storageBirthDate || undefined;
1790
+
1721
1791
  if (
1722
1792
  (!sessionID &&
1723
1793
  memori.privacyType !== 'PUBLIC' &&
@@ -1729,6 +1799,9 @@ const MemoriWidget = ({
1729
1799
  setAuthModalState('password');
1730
1800
  setClickedStart(false);
1731
1801
  return;
1802
+ } else if (!sessionID && !!minAge && !birth) {
1803
+ setShowAgeVerification(true);
1804
+ setClickedStart(false);
1732
1805
  } else if (!sessionID) {
1733
1806
  setClickedStart(false);
1734
1807
  setGotErrorInOpening(false);
@@ -1739,6 +1812,7 @@ const MemoriWidget = ({
1739
1812
  pin: personification?.pin,
1740
1813
  initialContextVars,
1741
1814
  initialQuestion,
1815
+ birthDate: birth,
1742
1816
  });
1743
1817
 
1744
1818
  if (session?.dialogState) {
@@ -1819,7 +1893,8 @@ const MemoriWidget = ({
1819
1893
  memori?.giverTag,
1820
1894
  memori?.giverPIN,
1821
1895
  initialContextVars,
1822
- initialQuestion
1896
+ initialQuestion,
1897
+ birth
1823
1898
  ).then(() => {
1824
1899
  setHasUserActivatedSpeak(true);
1825
1900
  });
@@ -1865,7 +1940,8 @@ const MemoriWidget = ({
1865
1940
  personification.tag,
1866
1941
  personification.pin,
1867
1942
  initialContextVars,
1868
- initialQuestion
1943
+ initialQuestion,
1944
+ birth
1869
1945
  ).then(() => {
1870
1946
  setHasUserActivatedSpeak(true);
1871
1947
  });
@@ -1911,7 +1987,8 @@ const MemoriWidget = ({
1911
1987
  undefined,
1912
1988
  undefined,
1913
1989
  initialContextVars,
1914
- initialQuestion
1990
+ initialQuestion,
1991
+ birth
1915
1992
  ).then(() => {
1916
1993
  setHasUserActivatedSpeak(true);
1917
1994
  });
@@ -2009,6 +2086,7 @@ const MemoriWidget = ({
2009
2086
  }}
2010
2087
  showSettings={showSettings}
2011
2088
  hasUserActivatedSpeak={hasUserActivatedSpeak}
2089
+ showReload={selectedLayout === 'TOTEM'}
2012
2090
  />
2013
2091
  );
2014
2092
 
@@ -2069,7 +2147,7 @@ const MemoriWidget = ({
2069
2147
  baseUrl={baseUrl}
2070
2148
  apiUrl={apiUrl}
2071
2149
  memoriTyping={memoriTyping}
2072
- history={history}
2150
+ history={layout === 'TOTEM' ? history.slice(-2) : history}
2073
2151
  authToken={loginToken}
2074
2152
  dialogState={currentDialogState}
2075
2153
  setDialogState={setCurrentDialogState}
@@ -2091,6 +2169,7 @@ const MemoriWidget = ({
2091
2169
  userMessage={userMessage}
2092
2170
  onChangeUserMessage={onChangeUserMessage}
2093
2171
  sendMessage={(msg: string) => {
2172
+ stopAudio();
2094
2173
  stopListening();
2095
2174
  sendMessage(msg);
2096
2175
  setUserMessage('');
@@ -2113,7 +2192,9 @@ const MemoriWidget = ({
2113
2192
  style={{ backgroundImage: globalBackgroundUrl }}
2114
2193
  />
2115
2194
  </div>
2116
- ) : null;
2195
+ ) : (
2196
+ <div className="memori--global-background no-background-image" />
2197
+ );
2117
2198
 
2118
2199
  const integrationStyle = integration ? (
2119
2200
  <style dangerouslySetInnerHTML={{ __html: integrationStylesheet }} />
@@ -2134,14 +2215,27 @@ const MemoriWidget = ({
2134
2215
 
2135
2216
  const poweredBy = <PoweredBy tenant={tenant} userLang={userLang} />;
2136
2217
 
2218
+ const Layout =
2219
+ selectedLayout === 'TOTEM'
2220
+ ? TotemLayout
2221
+ : selectedLayout === 'FULLPAGE'
2222
+ ? FullPageLayout
2223
+ : FullPageLayout;
2224
+
2137
2225
  return (
2138
2226
  <div
2139
- className={cx('memori', 'memori-widget', {
2140
- 'memori--preview': preview,
2141
- 'memori--embed': embed,
2142
- 'memori--with-integration': integration,
2143
- 'memori--active': hasUserActivatedSpeak,
2144
- })}
2227
+ className={cx(
2228
+ 'memori',
2229
+ 'memori-widget',
2230
+ `memori-layout-${layout.toLowerCase()}`,
2231
+ `memori-controls-${controlsPosition.toLowerCase()}`,
2232
+ {
2233
+ 'memori--preview': preview,
2234
+ 'memori--embed': embed,
2235
+ 'memori--with-integration': integration,
2236
+ 'memori--active': hasUserActivatedSpeak,
2237
+ }
2238
+ )}
2145
2239
  data-memori-name={memori?.name}
2146
2240
  data-memori-id={memori?.engineMemoriID}
2147
2241
  data-memori-secondary-id={memori?.memoriID}
@@ -2153,7 +2247,7 @@ const MemoriWidget = ({
2153
2247
  })}
2154
2248
  style={{ height }}
2155
2249
  >
2156
- <DefaultLayout
2250
+ <Layout
2157
2251
  header={header}
2158
2252
  avatar={avatar}
2159
2253
  chat={chat}
@@ -2192,7 +2286,8 @@ const MemoriWidget = ({
2192
2286
  instruct ? memori.giverTag : undefined,
2193
2287
  instruct ? memori.giverPIN : undefined,
2194
2288
  initialContextVars,
2195
- initialQuestion
2289
+ initialQuestion,
2290
+ birthDate
2196
2291
  )
2197
2292
  .then(state => {
2198
2293
  setAuthModalState(null);
@@ -2209,6 +2304,56 @@ const MemoriWidget = ({
2209
2304
  />
2210
2305
  )}
2211
2306
 
2307
+ {isClient && (
2308
+ <AgeVerificationModal
2309
+ visible={showAgeVerification}
2310
+ minAge={minAge}
2311
+ onClose={birthDate => {
2312
+ if (birthDate) {
2313
+ setBirthDate(birthDate);
2314
+
2315
+ setLocalConfig('birthDate', birthDate);
2316
+
2317
+ reopenSession(
2318
+ !sessionId,
2319
+ memori?.secretToken,
2320
+ undefined,
2321
+ instruct ? memori.giverTag : undefined,
2322
+ instruct ? memori.giverPIN : undefined,
2323
+ initialContextVars,
2324
+ initialQuestion,
2325
+ birthDate
2326
+ )
2327
+ .then(state => {
2328
+ setShowAgeVerification(false);
2329
+ onClickStart(state || undefined);
2330
+ })
2331
+ .catch(() => {
2332
+ setShowAgeVerification(false);
2333
+ setGotErrorInOpening(true);
2334
+ });
2335
+ } else {
2336
+ setShowAgeVerification(false);
2337
+ setClickedStart(false);
2338
+ }
2339
+ }}
2340
+ />
2341
+ )}
2342
+
2343
+ {showSettingsDrawer && (
2344
+ <SettingsDrawer
2345
+ layout={selectedLayout}
2346
+ open={!!showSettingsDrawer}
2347
+ onClose={() => setShowSettingsDrawer(false)}
2348
+ continuousSpeech={continuousSpeech}
2349
+ continuousSpeechTimeout={continuousSpeechTimeout}
2350
+ setContinuousSpeech={setContinuousSpeech}
2351
+ setContinuousSpeechTimeout={setContinuousSpeechTimeout}
2352
+ controlsPosition={controlsPosition}
2353
+ setControlsPosition={setControlsPosition}
2354
+ />
2355
+ )}
2356
+
2212
2357
  {sessionId && (
2213
2358
  <AttachmentLinkModal
2214
2359
  apiURL={apiUrl}
@@ -0,0 +1,5 @@
1
+ .memori-settings-drawer .memori-settings-drawer--field {
2
+ display: flex;
3
+ flex-direction: column;
4
+ margin: 0.5rem 0 1.5rem;
5
+ }
@@ -0,0 +1,57 @@
1
+ import React from 'react';
2
+ import { Meta, Story } from '@storybook/react';
3
+ import SettingsDrawer, { Props } from './SettingsDrawer';
4
+ import './SettingsDrawer.css';
5
+
6
+ const meta: Meta = {
7
+ title: 'Widget/SettingsDrawer',
8
+ component: SettingsDrawer,
9
+ argTypes: {
10
+ open: {
11
+ control: {
12
+ type: 'boolean',
13
+ },
14
+ },
15
+ },
16
+ parameters: {
17
+ controls: { expanded: true },
18
+ },
19
+ };
20
+
21
+ export default meta;
22
+
23
+ const Template: Story<Props> = args => {
24
+ const [controlsPosition, setControlsPosition] = React.useState<
25
+ 'bottom' | 'center'
26
+ >('bottom');
27
+ return (
28
+ <SettingsDrawer
29
+ {...args}
30
+ controlsPosition={controlsPosition}
31
+ setControlsPosition={setControlsPosition}
32
+ />
33
+ );
34
+ };
35
+
36
+ // By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
37
+ // https://storybook.js.org/docs/react/workflows/unit-testing
38
+ export const Default = Template.bind({});
39
+ Default.args = {
40
+ open: true,
41
+ onClose: () => {},
42
+ continuousSpeech: false,
43
+ continuousSpeechTimeout: 2,
44
+ setContinuousSpeech: () => {},
45
+ setContinuousSpeechTimeout: () => {},
46
+ };
47
+
48
+ export const WithinTotemLayout = Template.bind({});
49
+ WithinTotemLayout.args = {
50
+ layout: 'TOTEM',
51
+ open: true,
52
+ onClose: () => {},
53
+ continuousSpeech: false,
54
+ continuousSpeechTimeout: 2,
55
+ setContinuousSpeech: () => {},
56
+ setContinuousSpeechTimeout: () => {},
57
+ };
@@ -0,0 +1,61 @@
1
+ import { render } from '@testing-library/react';
2
+ import SettingsDrawer from './SettingsDrawer';
3
+
4
+ beforeEach(() => {
5
+ // @ts-ignore
6
+ window.IntersectionObserver = jest.fn(() => ({
7
+ observe: jest.fn(),
8
+ unobserve: jest.fn(),
9
+ disconnect: jest.fn(),
10
+ takeRecords: jest.fn(),
11
+ }));
12
+ });
13
+
14
+ it('renders SettingsDrawer unchanged', () => {
15
+ const { container } = render(
16
+ <SettingsDrawer
17
+ open={false}
18
+ onClose={jest.fn()}
19
+ continuousSpeech={false}
20
+ continuousSpeechTimeout={2}
21
+ setContinuousSpeech={jest.fn()}
22
+ setContinuousSpeechTimeout={jest.fn()}
23
+ controlsPosition="bottom"
24
+ setControlsPosition={jest.fn()}
25
+ />
26
+ );
27
+ expect(container).toMatchSnapshot();
28
+ });
29
+
30
+ it('renders SettingsDrawer open unchanged', () => {
31
+ const { container } = render(
32
+ <SettingsDrawer
33
+ open={true}
34
+ onClose={jest.fn()}
35
+ continuousSpeech={false}
36
+ continuousSpeechTimeout={2}
37
+ setContinuousSpeech={jest.fn()}
38
+ setContinuousSpeechTimeout={jest.fn()}
39
+ controlsPosition="bottom"
40
+ setControlsPosition={jest.fn()}
41
+ />
42
+ );
43
+ expect(container).toMatchSnapshot();
44
+ });
45
+
46
+ it('renders SettingsDrawer for totem layout open unchanged', () => {
47
+ const { container } = render(
48
+ <SettingsDrawer
49
+ layout="TOTEM"
50
+ open={true}
51
+ onClose={jest.fn()}
52
+ continuousSpeech={false}
53
+ continuousSpeechTimeout={2}
54
+ setContinuousSpeech={jest.fn()}
55
+ setContinuousSpeechTimeout={jest.fn()}
56
+ controlsPosition="bottom"
57
+ setControlsPosition={jest.fn()}
58
+ />
59
+ );
60
+ expect(container).toMatchSnapshot();
61
+ });