@memori.ai/memori-react 8.10.1 → 8.12.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 (177) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/dist/components/AgeVerificationModal/AgeVerificationModal.css +41 -14
  3. package/dist/components/AgeVerificationModal/AgeVerificationModal.js +2 -2
  4. package/dist/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -1
  5. package/dist/components/Auth/Auth.js +36 -8
  6. package/dist/components/Auth/Auth.js.map +1 -1
  7. package/dist/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.css +2 -2
  8. package/dist/components/Chat/Chat.js +2 -2
  9. package/dist/components/Chat/Chat.js.map +1 -1
  10. package/dist/components/ChatBubble/ChatBubble.css +81 -13
  11. package/dist/components/ChatBubble/ChatBubble.js +86 -19
  12. package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
  13. package/dist/components/ChatHistoryDrawer/ChatHistory.css +5 -1
  14. package/dist/components/ChatInputs/ChatInputs.d.ts +1 -0
  15. package/dist/components/ChatInputs/ChatInputs.js +8 -3
  16. package/dist/components/ChatInputs/ChatInputs.js.map +1 -1
  17. package/dist/components/DateSelector/DateSelector.css +125 -104
  18. package/dist/components/DateSelector/DateSelector.d.ts +1 -1
  19. package/dist/components/DateSelector/DateSelector.js +110 -52
  20. package/dist/components/DateSelector/DateSelector.js.map +1 -1
  21. package/dist/components/Header/Header.js +1 -1
  22. package/dist/components/Header/Header.js.map +1 -1
  23. package/dist/components/LoginDrawer/LoginDrawer.css +37 -5
  24. package/dist/components/LoginDrawer/LoginDrawer.d.ts +1 -2
  25. package/dist/components/LoginDrawer/LoginDrawer.js +2 -9
  26. package/dist/components/LoginDrawer/LoginDrawer.js.map +1 -1
  27. package/dist/components/MediaWidget/MediaItemWidget.js +40 -5
  28. package/dist/components/MediaWidget/MediaItemWidget.js.map +1 -1
  29. package/dist/components/MediaWidget/MediaWidget.css +4 -0
  30. package/dist/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.js +1 -1
  31. package/dist/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.js.map +1 -1
  32. package/dist/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyButtonWithDropdown.js +1 -1
  33. package/dist/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyButtonWithDropdown.js.map +1 -1
  34. package/dist/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyMenuItem.js +3 -0
  35. package/dist/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyMenuItem.js.map +1 -1
  36. package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +2 -2
  37. package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -1
  38. package/dist/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.css +16 -7
  39. package/dist/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.js +6 -4
  40. package/dist/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.js.map +1 -1
  41. package/dist/components/MemoriWidget/MemoriWidget.js +69 -25
  42. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  43. package/dist/components/UploadButton/UploadButton.js +2 -0
  44. package/dist/components/UploadButton/UploadButton.js.map +1 -1
  45. package/dist/components/UploadButton/UploadImages/UploadImages.js +2 -2
  46. package/dist/components/UploadButton/UploadImages/UploadImages.js.map +1 -1
  47. package/dist/components/ui/Drawer.css +8 -0
  48. package/dist/components/ui/Drawer.d.ts +2 -0
  49. package/dist/components/ui/Drawer.js +2 -2
  50. package/dist/components/ui/Drawer.js.map +1 -1
  51. package/dist/components/ui/Tooltip.css +49 -1
  52. package/dist/components/ui/Tooltip.d.ts +1 -1
  53. package/dist/locales/de.json +6 -1
  54. package/dist/locales/en.json +9 -1
  55. package/dist/locales/es.json +6 -1
  56. package/dist/locales/fr.json +5 -1
  57. package/dist/locales/it.json +8 -1
  58. package/dist/styles.css +3 -2
  59. package/esm/components/AgeVerificationModal/AgeVerificationModal.css +41 -14
  60. package/esm/components/AgeVerificationModal/AgeVerificationModal.js +2 -2
  61. package/esm/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -1
  62. package/esm/components/Auth/Auth.js +36 -8
  63. package/esm/components/Auth/Auth.js.map +1 -1
  64. package/esm/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.css +2 -2
  65. package/esm/components/Chat/Chat.js +2 -2
  66. package/esm/components/Chat/Chat.js.map +1 -1
  67. package/esm/components/ChatBubble/ChatBubble.css +81 -13
  68. package/esm/components/ChatBubble/ChatBubble.js +87 -20
  69. package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
  70. package/esm/components/ChatHistoryDrawer/ChatHistory.css +5 -1
  71. package/esm/components/ChatInputs/ChatInputs.d.ts +1 -0
  72. package/esm/components/ChatInputs/ChatInputs.js +8 -3
  73. package/esm/components/ChatInputs/ChatInputs.js.map +1 -1
  74. package/esm/components/DateSelector/DateSelector.css +125 -104
  75. package/esm/components/DateSelector/DateSelector.d.ts +1 -1
  76. package/esm/components/DateSelector/DateSelector.js +111 -52
  77. package/esm/components/DateSelector/DateSelector.js.map +1 -1
  78. package/esm/components/Header/Header.js +1 -1
  79. package/esm/components/Header/Header.js.map +1 -1
  80. package/esm/components/LoginDrawer/LoginDrawer.css +37 -5
  81. package/esm/components/LoginDrawer/LoginDrawer.d.ts +1 -2
  82. package/esm/components/LoginDrawer/LoginDrawer.js +2 -9
  83. package/esm/components/LoginDrawer/LoginDrawer.js.map +1 -1
  84. package/esm/components/MediaWidget/MediaItemWidget.js +40 -5
  85. package/esm/components/MediaWidget/MediaItemWidget.js.map +1 -1
  86. package/esm/components/MediaWidget/MediaWidget.css +4 -0
  87. package/esm/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.js +1 -1
  88. package/esm/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.js.map +1 -1
  89. package/esm/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyButtonWithDropdown.js +1 -1
  90. package/esm/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyButtonWithDropdown.js.map +1 -1
  91. package/esm/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyMenuItem.js +3 -0
  92. package/esm/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyMenuItem.js.map +1 -1
  93. package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +2 -2
  94. package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -1
  95. package/esm/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.css +16 -7
  96. package/esm/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.js +6 -4
  97. package/esm/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.js.map +1 -1
  98. package/esm/components/MemoriWidget/MemoriWidget.js +69 -25
  99. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  100. package/esm/components/UploadButton/UploadButton.js +2 -0
  101. package/esm/components/UploadButton/UploadButton.js.map +1 -1
  102. package/esm/components/UploadButton/UploadImages/UploadImages.js +2 -2
  103. package/esm/components/UploadButton/UploadImages/UploadImages.js.map +1 -1
  104. package/esm/components/ui/Drawer.css +8 -0
  105. package/esm/components/ui/Drawer.d.ts +2 -0
  106. package/esm/components/ui/Drawer.js +2 -2
  107. package/esm/components/ui/Drawer.js.map +1 -1
  108. package/esm/components/ui/Tooltip.css +49 -1
  109. package/esm/components/ui/Tooltip.d.ts +1 -1
  110. package/esm/locales/de.json +6 -1
  111. package/esm/locales/en.json +9 -1
  112. package/esm/locales/es.json +6 -1
  113. package/esm/locales/fr.json +5 -1
  114. package/esm/locales/it.json +8 -1
  115. package/esm/styles.css +3 -2
  116. package/package.json +2 -2
  117. package/src/components/AgeVerificationModal/AgeVerificationModal.css +41 -14
  118. package/src/components/AgeVerificationModal/AgeVerificationModal.tsx +3 -1
  119. package/src/components/Auth/Auth.tsx +55 -11
  120. package/src/components/Avatar/Avatar.stories.tsx +3 -0
  121. package/src/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.css +2 -2
  122. package/src/components/Chat/Chat.stories.tsx +16 -2
  123. package/src/components/Chat/Chat.tsx +2 -1
  124. package/src/components/Chat/__snapshots__/Chat.test.tsx.snap +1036 -36
  125. package/src/components/ChatBubble/ChatBubble.css +81 -13
  126. package/src/components/ChatBubble/ChatBubble.stories.tsx +16 -2
  127. package/src/components/ChatBubble/ChatBubble.test.tsx +17 -0
  128. package/src/components/ChatBubble/ChatBubble.tsx +144 -31
  129. package/src/components/ChatBubble/__snapshots__/ChatBubble.test.tsx.snap +304 -8
  130. package/src/components/ChatHistoryDrawer/ChatHistory.css +5 -1
  131. package/src/components/ChatInputs/ChatInputs.tsx +14 -1
  132. package/src/components/DateSelector/DateSelector.css +125 -104
  133. package/src/components/DateSelector/DateSelector.stories.tsx +1 -1
  134. package/src/components/DateSelector/DateSelector.test.tsx +137 -23
  135. package/src/components/DateSelector/DateSelector.tsx +203 -177
  136. package/src/components/Header/Header.stories.tsx +5 -1
  137. package/src/components/Header/Header.tsx +1 -1
  138. package/src/components/Header/__snapshots__/Header.test.tsx.snap +1 -1
  139. package/src/components/LoginDrawer/LoginDrawer.css +37 -5
  140. package/src/components/LoginDrawer/LoginDrawer.stories.tsx +0 -1
  141. package/src/components/LoginDrawer/LoginDrawer.test.tsx +0 -1
  142. package/src/components/LoginDrawer/LoginDrawer.tsx +0 -19
  143. package/src/components/MediaWidget/MediaItemWidget.stories.tsx +69 -0
  144. package/src/components/MediaWidget/MediaItemWidget.tsx +66 -18
  145. package/src/components/MediaWidget/MediaWidget.css +4 -0
  146. package/src/components/MediaWidget/__snapshots__/MediaItemWidget.test.tsx.snap +10 -10
  147. package/src/components/MediaWidget/__snapshots__/MediaWidget.test.tsx.snap +2 -2
  148. package/src/components/MemoriArtifactSystem/ArtifactDrawer.stories.tsx +996 -204
  149. package/src/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.tsx +2 -2
  150. package/src/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyButtonWithDropdown.tsx +1 -1
  151. package/src/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyMenuItem.tsx +3 -0
  152. package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.tsx +56 -54
  153. package/src/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.css +16 -7
  154. package/src/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.tsx +12 -3
  155. package/src/components/MemoriWidget/MemoriWidget.stories.tsx +6 -3
  156. package/src/components/MemoriWidget/MemoriWidget.tsx +123 -48
  157. package/src/components/UploadButton/UploadButton.tsx +2 -0
  158. package/src/components/UploadButton/UploadImages/UploadImages.tsx +3 -2
  159. package/src/components/layouts/FullBody/FullBody.stories.tsx +110 -0
  160. package/src/components/layouts/Totem/Totem.stories.tsx +131 -0
  161. package/src/components/layouts/ZoomedFullBody/ZoomedFullBody.stories.tsx +131 -0
  162. package/src/components/layouts/layouts.stories.tsx +55 -508
  163. package/src/components/ui/Drawer.css +8 -0
  164. package/src/components/ui/Drawer.tsx +16 -12
  165. package/src/components/ui/Tooltip.css +49 -1
  166. package/src/components/ui/Tooltip.tsx +1 -1
  167. package/src/index.stories.tsx +13 -320
  168. package/src/locales/de.json +6 -1
  169. package/src/locales/en.json +9 -1
  170. package/src/locales/es.json +6 -1
  171. package/src/locales/fr.json +5 -1
  172. package/src/locales/it.json +8 -1
  173. package/src/mocks/data.ts +4 -2
  174. package/src/styles.css +3 -2
  175. package/src/components/SignupForm/SignupForm.test.tsx +0 -40
  176. package/src/components/SignupForm/SignupForm.tsx +0 -457
  177. package/src/components/SignupForm/__snapshots__/SignupForm.test.tsx.snap +0 -247
@@ -215,7 +215,7 @@ const ArtifactActions: React.FC<{
215
215
  <Button
216
216
  onClick={handlePrint}
217
217
  disabled={loading}
218
- className="memori-artifact-action-btn"
218
+ className="memori-artifact-action-btn memori-artifact-action-btn--print"
219
219
  ghost
220
220
  icon={<PrintIcon className="memori-artifact-action-icon" />}
221
221
  title={t('artifact.print') || 'Print'}
@@ -228,7 +228,7 @@ const ArtifactActions: React.FC<{
228
228
  <Button
229
229
  onClick={handleOpenExternal}
230
230
  disabled={loading}
231
- className="memori-artifact-action-btn"
231
+ className="memori-artifact-action-btn memori-artifact-action-btn--external"
232
232
  ghost
233
233
  icon={<Link className="memori-artifact-action-icon" />}
234
234
  title={t('artifact.external') || 'External'}
@@ -374,7 +374,7 @@ const CopyButtonWithDropdown: React.FC<CopyButtonWithDropdownProps> = ({
374
374
  onClick={handleCopyClick}
375
375
  disabled={disabled || loading || copyState.loading}
376
376
  className={cx(
377
- 'memori-copy-button memori-copy-button--main',
377
+ 'memori-copy-button memori-copy-button--main ',
378
378
  {
379
379
  'memori-copy-button--success': copyState.success,
380
380
  'memori-copy-button--error': copyState.error,
@@ -54,6 +54,9 @@ const CopyMenuItem: React.FC<CopyMenuItemProps & { active?: boolean }> = ({
54
54
  'memori-copy-menu-item--pdf': format.action === 'pdf',
55
55
  'memori-copy-menu-item--print': format.action === 'print',
56
56
  'memori-copy-menu-item--active': active,
57
+ 'memori-copy-menu-item--external': format.action === 'link',
58
+ 'memori-copy-menu-item--copy': format.action === 'copy',
59
+ 'memori-copy-menu-item--download': format.action === 'download',
57
60
  })}
58
61
  onClick={handleClick}
59
62
  disabled={disabled || loading}
@@ -148,6 +148,8 @@ const ArtifactDrawer: React.FC<{ isChatLogPanel?: boolean }> = ({
148
148
  widthLg="50%"
149
149
  closable={false}
150
150
  animated={true}
151
+ enterDuration={isMobile ? 'duration-500' : 'duration-300'}
152
+ leaveDuration={isMobile ? 'duration-400' : 'duration-200'}
151
153
  showBackdrop={false}
152
154
  preventBackdropClose={true}
153
155
  confirmDialogTitle={
@@ -158,70 +160,70 @@ const ArtifactDrawer: React.FC<{ isChatLogPanel?: boolean }> = ({
158
160
  t('artifact.confirmDialogMessage') ||
159
161
  'This action cannot be undone.'
160
162
  }
161
- // className="memori-artifact-panel"
163
+ // className="memori-artifact-panel"
162
164
  >
163
165
  {children}
164
166
  </Drawer>
165
167
  );
166
168
  }
167
169
  },
168
- [isChatLogPanel, handleClose, state.isDrawerOpen, state.isFullscreen]
170
+ [isChatLogPanel, handleClose, state.isDrawerOpen, state.isFullscreen, isMobile]
169
171
  );
170
172
 
171
- /**
172
- * Get MIME type string for downloads
173
+ /**
174
+ * Get MIME type string for downloads
175
+ */
176
+ const getMimeTypeString = useCallback((mimeType: string): string => {
177
+ const mimeTypes: Record<string, string> = {
178
+ html: 'text/html',
179
+ json: 'application/json',
180
+ markdown: 'text/markdown',
181
+ css: 'text/css',
182
+ javascript: 'text/javascript',
183
+ typescript: 'text/typescript',
184
+ svg: 'image/svg+xml',
185
+ xml: 'text/xml',
186
+ text: 'text/plain',
187
+ python: 'text/x-python',
188
+ java: 'text/x-java',
189
+ cpp: 'text/x-c++',
190
+ csharp: 'text/x-csharp',
191
+ php: 'text/x-php',
192
+ ruby: 'text/x-ruby',
193
+ go: 'text/x-go',
194
+ rust: 'text/x-rust',
195
+ yaml: 'text/yaml',
196
+ sql: 'text/x-sql',
197
+ };
198
+ return mimeTypes[mimeType] || 'text/plain';
199
+ }, []);
200
+
201
+ /**
202
+ * Handle external open action
173
203
  */
174
- const getMimeTypeString = useCallback((mimeType: string): string => {
175
- const mimeTypes: Record<string, string> = {
176
- html: 'text/html',
177
- json: 'application/json',
178
- markdown: 'text/markdown',
179
- css: 'text/css',
180
- javascript: 'text/javascript',
181
- typescript: 'text/typescript',
182
- svg: 'image/svg+xml',
183
- xml: 'text/xml',
184
- text: 'text/plain',
185
- python: 'text/x-python',
186
- java: 'text/x-java',
187
- cpp: 'text/x-c++',
188
- csharp: 'text/x-csharp',
189
- php: 'text/x-php',
190
- ruby: 'text/x-ruby',
191
- go: 'text/x-go',
192
- rust: 'text/x-rust',
193
- yaml: 'text/yaml',
194
- sql: 'text/x-sql',
195
- };
196
- return mimeTypes[mimeType] || 'text/plain';
197
- }, []);
198
-
199
- /**
200
- * Handle external open action
201
- */
202
- const handleOpenExternal = useCallback((artifact: ArtifactData) => {
203
- try {
204
- const mimeType = getMimeTypeString(artifact.mimeType);
205
- const blob = new Blob([artifact.content], { type: mimeType });
206
- const url = URL.createObjectURL(blob);
207
-
208
- const externalWindow = window.open(url, '_blank');
209
- if (!externalWindow) {
210
- alert(
211
- 'Popup blocked! Please enable popups to open the artifact in a new window.'
212
- );
213
- return;
214
- }
215
-
216
- // Cleanup URL after a delay
217
- setTimeout(() => {
218
- URL.revokeObjectURL(url);
219
- }, 60000);
220
-
221
- } catch (error) {
222
- console.error('External open failed:', error);
204
+ const handleOpenExternal = useCallback((artifact: ArtifactData) => {
205
+ try {
206
+ const mimeType = getMimeTypeString(artifact.mimeType);
207
+ const blob = new Blob([artifact.content], { type: mimeType });
208
+ const url = URL.createObjectURL(blob);
209
+
210
+ const externalWindow = window.open(url, '_blank');
211
+ if (!externalWindow) {
212
+ alert(
213
+ 'Popup blocked! Please enable popups to open the artifact in a new window.'
214
+ );
215
+ return;
223
216
  }
224
- }, []);
217
+
218
+ // Cleanup URL after a delay
219
+ setTimeout(() => {
220
+ URL.revokeObjectURL(url);
221
+ }, 60000);
222
+
223
+ } catch (error) {
224
+ console.error('External open failed:', error);
225
+ }
226
+ }, []);
225
227
 
226
228
  // Render web split panel
227
229
  return (
@@ -42,11 +42,6 @@
42
42
  white-space: nowrap;
43
43
  }
44
44
 
45
- /* .memori-artifact-tab:hover:not(.memori-artifact-tab--active) {
46
- background: rgba(0, 123, 255, 0.05);
47
- color: var(--memori-text-color, #333);
48
- } */
49
-
50
45
  .memori-artifact-tab--active, .memori-artifact-tab:hover, .memori-artifact-tab:active, .memori-artifact-tab:focus {
51
46
  background: var(--memori-chat-bubble-bg, #fff);
52
47
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
@@ -101,8 +96,11 @@
101
96
  /* Preview Content */
102
97
  .memori-artifact-preview-content {
103
98
  position: relative;
99
+ display: flex;
104
100
  overflow: hidden;
101
+ min-height: 0;
105
102
  flex: 1;
103
+ flex-direction: column;
106
104
  /* border: 1px solid var(--memori-button-border-color, #e9ecef); */
107
105
  border-radius: var(--memori-border-radius, 6px);
108
106
  /* margin: 1rem; */
@@ -110,14 +108,25 @@
110
108
  background: var(--memori-chat-bubble-bg, #fff);
111
109
  }
112
110
 
111
+ .memori-artifact-preview-iframe {
112
+ overflow: auto;
113
+ width: 100%;
114
+ height: 100%;
115
+ min-height: 0;
116
+ flex: 1;
117
+ border: none;
118
+ border-radius: var(--memori-border-radius, 6px);
119
+ }
120
+
113
121
  /* Markdown Preview */
114
122
  .memori-artifact-preview-markdown {
115
- height: 100%;
123
+ min-height: 0;
124
+ flex: 1;
116
125
  padding: 1rem;
117
126
  color: var(--memori-text-color, #333);
118
127
  font-family: var(--memori-font-family);
119
128
  line-height: 1.6;
120
- overflow-y: scroll;
129
+ overflow-y: auto;
121
130
  }
122
131
 
123
132
  .memori-artifact-preview-markdown h1,
@@ -28,6 +28,7 @@ const ArtifactPreview: React.FC<{
28
28
  case 'html':
29
29
  return (
30
30
  <iframe
31
+ className="memori-artifact-preview-iframe"
31
32
  srcDoc={artifact.content}
32
33
  style={{
33
34
  width: '100%',
@@ -36,6 +37,7 @@ const ArtifactPreview: React.FC<{
36
37
  borderRadius: '6px',
37
38
  }}
38
39
  title={`${artifact.title} Preview`}
40
+ scrolling="auto"
39
41
  />
40
42
  );
41
43
 
@@ -48,9 +50,16 @@ const ArtifactPreview: React.FC<{
48
50
  }}
49
51
  />
50
52
  );
51
-
53
+
52
54
  default:
53
- return null;
55
+ return (
56
+ <div
57
+ className="memori-artifact-preview-text"
58
+ dangerouslySetInnerHTML={{
59
+ __html: artifact.content,
60
+ }}
61
+ />
62
+ );
54
63
  }
55
64
  }, [artifact]);
56
65
 
@@ -110,7 +119,7 @@ const ArtifactPreview: React.FC<{
110
119
  );
111
120
 
112
121
  const hasPreview =
113
- artifact.mimeType === 'html' || artifact.mimeType === 'markdown';
122
+ artifact.mimeType === 'html' || artifact.mimeType === 'markdown' || artifact.mimeType === 'svg';
114
123
 
115
124
  return (
116
125
  <div className="memori-artifact-preview">
@@ -6,6 +6,7 @@ import MemoriWidget, { Props } from './MemoriWidget';
6
6
 
7
7
  import './MemoriWidget.css';
8
8
  import { VisemeProvider } from '../../context/visemeContext';
9
+ import { ArtifactProvider } from '../MemoriArtifactSystem/context/ArtifactContext';
9
10
 
10
11
  const meta: Meta = {
11
12
  title: 'Widget/Default',
@@ -37,9 +38,11 @@ export default meta;
37
38
 
38
39
  const Template: Story<Props> = args => (
39
40
  <I18nWrapper>
40
- <VisemeProvider>
41
- <MemoriWidget {...args} />
42
- </VisemeProvider>
41
+ <ArtifactProvider>
42
+ <VisemeProvider>
43
+ <MemoriWidget {...args} />
44
+ </VisemeProvider>
45
+ </ArtifactProvider>
43
46
  </I18nWrapper>
44
47
  );
45
48
  // By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
@@ -323,14 +323,18 @@ declare global {
323
323
  typeBatchMessages: typeof typeBatchMessages;
324
324
  MemoriArtifactAPI?: {
325
325
  openArtifact: (artifact: ArtifactData) => void;
326
- createAndOpenArtifact: (content: string, mimeType?: string, title?: string) => void;
326
+ createAndOpenArtifact: (
327
+ content: string,
328
+ mimeType?: string,
329
+ title?: string
330
+ ) => void;
327
331
  createFromOutputElement: (outputElement: HTMLOutputElement) => string;
328
332
  closeArtifact: () => void;
329
333
  toggleFullscreen: () => void;
330
- getState: () => {
331
- currentArtifact: ArtifactData | null;
332
- isDrawerOpen: boolean;
333
- isFullscreen: boolean
334
+ getState: () => {
335
+ currentArtifact: ArtifactData | null;
336
+ isDrawerOpen: boolean;
337
+ isFullscreen: boolean;
334
338
  };
335
339
  };
336
340
  }
@@ -915,7 +919,7 @@ const MemoriWidget = ({
915
919
  setHistory(h => [...h.slice(0, h.length - 1)]);
916
920
 
917
921
  reopenSession(
918
- false,
922
+ true,
919
923
  memoriPwd || memori.secretToken,
920
924
  memoriTokens,
921
925
  undefined,
@@ -926,7 +930,12 @@ const MemoriWidget = ({
926
930
  ROUTE: window.location.pathname?.split('/')?.pop() || '',
927
931
  ...(initialContextVars || {}),
928
932
  },
929
- initialQuestion
933
+ initialQuestion,
934
+ undefined,
935
+ undefined,
936
+ undefined,
937
+ undefined,
938
+ true // isSessionExpired
930
939
  ).then(state => {
931
940
  console.info('session timeout');
932
941
  if (state?.sessionID) {
@@ -1283,9 +1292,13 @@ const MemoriWidget = ({
1283
1292
  tag: params.tag ?? personification?.tag,
1284
1293
  pin: params.pin ?? personification?.pin,
1285
1294
  additionalInfo: {
1286
- ...(additionalInfo || {}),
1295
+ ...(params.additionalInfo || additionalInfo || {}),
1287
1296
  loginToken:
1288
- userToken ?? loginToken ?? additionalInfo?.loginToken ?? authToken,
1297
+ userToken ??
1298
+ loginToken ??
1299
+ params.additionalInfo?.loginToken ??
1300
+ additionalInfo?.loginToken ??
1301
+ authToken,
1289
1302
  language: getCultureCodeByLanguage(userLang),
1290
1303
  referral: referral,
1291
1304
  timeZoneOffset: new Date().getTimezoneOffset().toString(),
@@ -1379,18 +1392,12 @@ const MemoriWidget = ({
1379
1392
  pin?: string,
1380
1393
  initialContextVars?: { [key: string]: string },
1381
1394
  initialQuestion?: string,
1382
- birthDate?: string
1395
+ birthDate?: string,
1396
+ additionalInfoProp?: { [key: string]: string | undefined },
1397
+ continueFromChatLogID?: string,
1398
+ continueFromSessionID?: string,
1399
+ isSessionExpired?: boolean
1383
1400
  ) => {
1384
- // console.log('[REOPEN_SESSION] Starting reopenSession with params:', {
1385
- // updateDialogState,
1386
- // hasPassword: !!password,
1387
- // hasRecoveryTokens: !!recoveryTokens,
1388
- // tag,
1389
- // hasPin: !!pin,
1390
- // initialContextVars,
1391
- // initialQuestion,
1392
- // hasBirthDate: !!birthDate
1393
- // });
1394
1401
 
1395
1402
  // Set loading state while reopening session
1396
1403
  setLoading(true);
@@ -1444,6 +1451,8 @@ const MemoriWidget = ({
1444
1451
  recoveryTokens: recoveryTokens || memoriTokens,
1445
1452
  tag: tag ?? personification?.tag,
1446
1453
  pin: pin ?? personification?.pin,
1454
+ continueFromChatLogID: continueFromChatLogID,
1455
+ continueFromSessionID: continueFromSessionID,
1447
1456
  initialContextVars: {
1448
1457
  LANG: userLang,
1449
1458
  PATHNAME: window.location.pathname,
@@ -1453,9 +1462,13 @@ const MemoriWidget = ({
1453
1462
  initialQuestion,
1454
1463
  birthDate: userBirthDate,
1455
1464
  additionalInfo: {
1456
- ...(additionalInfo || {}),
1465
+ ...(additionalInfoProp || additionalInfo || {}),
1457
1466
  loginToken:
1458
- userToken ?? loginToken ?? additionalInfo?.loginToken ?? authToken,
1467
+ userToken ??
1468
+ loginToken ??
1469
+ additionalInfoProp?.loginToken ??
1470
+ additionalInfo?.loginToken ??
1471
+ authToken,
1459
1472
  language: getCultureCodeByLanguage(userLang),
1460
1473
  referral: referral,
1461
1474
  timeZoneOffset: new Date().getTimezoneOffset().toString(),
@@ -1464,7 +1477,7 @@ const MemoriWidget = ({
1464
1477
 
1465
1478
  // Handle successful session initialization
1466
1479
  if (sessionID && currentState && response.resultCode === 0) {
1467
- // console.log('[REOPEN_SESSION] Session initialized successfully:', sessionID);
1480
+ console.log('[REOPEN_SESSION] Session initialized successfully:', sessionID);
1468
1481
  setSessionId(sessionID);
1469
1482
 
1470
1483
  // Update dialog state and history if requested
@@ -1473,7 +1486,13 @@ const MemoriWidget = ({
1473
1486
  setCurrentDialogState(currentState);
1474
1487
 
1475
1488
  if (currentState.emission) {
1476
- // console.log('[REOPEN_SESSION] Processing emission:', currentState.emission);
1489
+ console.log('[REOPEN_SESSION] Processing emission:', currentState.emission);
1490
+ // Determine initial status message based on context
1491
+ // Show status message only if session expired and there's existing history
1492
+ const initialStatus = isSessionExpired && history.length > 1
1493
+ ? 'Session Expired, reopening session'
1494
+ : (history.length <= 1 ? true : undefined);
1495
+
1477
1496
  // Set initial message or append to existing history
1478
1497
  history.length <= 1
1479
1498
  ? setHistory([
@@ -1482,7 +1501,7 @@ const MemoriWidget = ({
1482
1501
  emitter: currentState.emitter,
1483
1502
  media: currentState.emittedMedia ?? currentState.media,
1484
1503
  fromUser: false,
1485
- initial: true,
1504
+ initial: (initialStatus === true ? true : (initialStatus || undefined)) as any,
1486
1505
  contextVars: currentState.contextVars,
1487
1506
  date: currentState.currentDate,
1488
1507
  placeName: currentState.currentPlaceName,
@@ -1498,7 +1517,7 @@ const MemoriWidget = ({
1498
1517
  emitter: currentState.emitter,
1499
1518
  media: currentState.emittedMedia ?? currentState.media,
1500
1519
  fromUser: false,
1501
- initial: true,
1520
+ initial: (initialStatus === true ? true : (initialStatus || undefined)) as any,
1502
1521
  contextVars: currentState.contextVars,
1503
1522
  date: currentState.currentDate,
1504
1523
  placeName: currentState.currentPlaceName,
@@ -2551,6 +2570,7 @@ const MemoriWidget = ({
2551
2570
  // No tag changes needed
2552
2571
  else {
2553
2572
  try {
2573
+ //This is the session id of the session that was opened before the current session
2554
2574
  const { chatLogs } = await getSessionChatLogs(
2555
2575
  sessionID!,
2556
2576
  sessionID!
@@ -3049,16 +3069,21 @@ const MemoriWidget = ({
3049
3069
  loading={loading}
3050
3070
  />
3051
3071
 
3052
- <ArtifactAPIBridge pushMessage={(message: Message) => {
3053
- setHistory(history => {
3054
- if (!history.length) return history;
3055
- const lastMessage = history[history.length - 1];
3056
- if (!lastMessage || lastMessage.fromUser) return history;
3057
- // Create a new message object with the updated text
3058
- const updatedLastMessage = { ...lastMessage, text: lastMessage.text + message.text };
3059
- return [...history.slice(0, -1), updatedLastMessage];
3060
- });
3061
- }} />
3072
+ <ArtifactAPIBridge
3073
+ pushMessage={(message: Message) => {
3074
+ setHistory(history => {
3075
+ if (!history.length) return history;
3076
+ const lastMessage = history[history.length - 1];
3077
+ if (!lastMessage || lastMessage.fromUser) return history;
3078
+ // Create a new message object with the updated text
3079
+ const updatedLastMessage = {
3080
+ ...lastMessage,
3081
+ text: lastMessage.text + message.text,
3082
+ };
3083
+ return [...history.slice(0, -1), updatedLastMessage];
3084
+ });
3085
+ }}
3086
+ />
3062
3087
 
3063
3088
  <audio
3064
3089
  id="memori-audio"
@@ -3073,12 +3098,12 @@ const MemoriWidget = ({
3073
3098
  openModal={!!authModalState}
3074
3099
  setPwdOrTokens={setAuthModalState}
3075
3100
  showTokens={memori.privacyType === 'SECRET'}
3076
- onFinish={async (values: any) => {
3101
+ onFinish={(values: any) => {
3077
3102
  if (values['password']) setMemoriPwd(values['password']);
3078
3103
  if (values['password']) memoriPassword = values['password'];
3079
3104
  if (values['tokens']) setMemoriTokens(values['tokens']);
3080
3105
 
3081
- reopenSession(
3106
+ return reopenSession(
3082
3107
  !sessionId,
3083
3108
  values['password'],
3084
3109
  values['tokens'],
@@ -3096,6 +3121,10 @@ const MemoriWidget = ({
3096
3121
  birthDate
3097
3122
  )
3098
3123
  .then(state => {
3124
+ if (!state?.sessionID) {
3125
+ throw new Error('AUTH_FAILED');
3126
+ }
3127
+
3099
3128
  setAuthModalState(null);
3100
3129
  // If we got a valid state from reopenSession, don't call onClickStart again
3101
3130
  // to avoid duplicate snippet execution
@@ -3103,12 +3132,14 @@ const MemoriWidget = ({
3103
3132
  setHasUserActivatedSpeak(true);
3104
3133
  } else {
3105
3134
  // Only call onClickStart if reopenSession didn't return a valid state
3106
- onClickStart(state || undefined);
3135
+ onClickStart(state);
3107
3136
  }
3108
3137
  })
3109
- .catch(() => {
3110
- setAuthModalState(null);
3111
- setGotErrorInOpening(true);
3138
+ .catch(error => {
3139
+ if (!(error instanceof Error) || error.message !== 'AUTH_FAILED') {
3140
+ setGotErrorInOpening(true);
3141
+ }
3142
+ throw error;
3112
3143
  });
3113
3144
  }}
3114
3145
  minimumNumberOfRecoveryTokens={
@@ -3254,16 +3285,60 @@ const MemoriWidget = ({
3254
3285
  loginToken={loginToken}
3255
3286
  onClose={() => setShowLoginDrawer(false)}
3256
3287
  onLogin={(user, token) => {
3257
- setUser(user);
3258
- setLoginToken(token);
3259
- userToken = token;
3260
- setShowLoginDrawer(false);
3261
- setLocalConfig('loginToken', token);
3288
+ //The user is logged in, so we need to set open a new session with the new token
3289
+ reopenSession(
3290
+ false,
3291
+ memoriPassword || memoriPwd || memori?.secretToken,
3292
+ [],
3293
+ personification?.tag,
3294
+ personification?.pin,
3295
+ {
3296
+ LANG: userLang,
3297
+ PATHNAME: window.location.pathname?.toUpperCase(),
3298
+ ROUTE:
3299
+ window.location.pathname?.split('/')?.pop()?.toUpperCase() ||
3300
+ '',
3301
+ ...(initialContextVars || {}),
3302
+ },
3303
+ undefined, // Don't send initialQuestion after login, only show the login status chip
3304
+ birthDate,
3305
+ { loginToken: token } as any,
3306
+ undefined,
3307
+ sessionId
3308
+ ).then(state => {
3309
+ setShowLoginDrawer(false);
3310
+ setUser(user);
3311
+ setLoginToken(token);
3312
+ userToken = token;
3313
+ setLocalConfig('loginToken', token);
3314
+ // Push a message with initial status to show status message when a new session is created after login
3315
+ if (state?.sessionID && state.sessionID !== sessionId && state?.dialogState) {
3316
+ // Push a message with initial status message showing successful login
3317
+ // Only show the chip component, not the emission text
3318
+ const username = user?.userName || t('login.user');
3319
+ pushMessage({
3320
+ text: '', // Empty text so only the chip is visible
3321
+ emitter: state.dialogState.emitter,
3322
+ media: state.dialogState.emittedMedia ?? state.dialogState.media ?? [],
3323
+ fromUser: false,
3324
+ initial: t('login.successfullyLoggedIn', { username }) as any,
3325
+ contextVars: state.dialogState.contextVars,
3326
+ date: state.dialogState.currentDate,
3327
+ placeName: state.dialogState.currentPlaceName,
3328
+ placeLatitude: state.dialogState.currentLatitude,
3329
+ placeLongitude: state.dialogState.currentLongitude,
3330
+ placeUncertaintyKm: state.dialogState.currentUncertaintyKm,
3331
+ tag: state.dialogState.currentTag,
3332
+ memoryTags: state.dialogState.memoryTags,
3333
+ });
3334
+ // Update the dialog state so the UI reflects the new session
3335
+ setCurrentDialogState(state.dialogState);
3336
+ }
3337
+ });
3262
3338
  }}
3263
3339
  setUser={setUser}
3264
3340
  onLogout={() => {
3265
3341
  if (!loginToken) return;
3266
-
3267
3342
  client.backend.pwlUserLogout(loginToken).then(() => {
3268
3343
  setShowLoginDrawer(false);
3269
3344
  setUser(undefined);
@@ -376,6 +376,7 @@ ${file.content}
376
376
  <div
377
377
  className={cx('memori--upload-menu-item', {
378
378
  'memori--upload-menu-item--disabled': hasReachedDocumentLimit,
379
+ 'memori--upload-menu-item--document': true,
379
380
  })}
380
381
  onClick={handleDocumentClick}
381
382
  title={
@@ -408,6 +409,7 @@ ${file.content}
408
409
  className={cx('memori--upload-menu-item', {
409
410
  'memori--upload-menu-item--disabled':
410
411
  !isMediaAccepted || hasReachedImageLimit,
412
+ 'memori--upload-menu-item--image': true,
411
413
  })}
412
414
  onClick={handleImageClick}
413
415
  title={
@@ -149,7 +149,8 @@ const UploadImages: React.FC<UploadImagesProps> = ({
149
149
  response = await backend.uploadAsset(
150
150
  selectedFile.name,
151
151
  fileDataUrl,
152
- authToken
152
+ authToken,
153
+ memoriID
153
154
  );
154
155
  } else if (memoriID && sessionID && backend?.uploadAssetUnlogged) {
155
156
  response = await backend.uploadAssetUnlogged(
@@ -341,7 +342,7 @@ const UploadImages: React.FC<UploadImagesProps> = ({
341
342
  <Button
342
343
  onClick={handleTitleSubmit}
343
344
  disabled={!selectedFile || !imageTitle.trim()}
344
- className="memori-button memori-button--primary"
345
+ className="memori-button memori-button--primary memori-button--image-confirm"
345
346
  >
346
347
  {t('confirm') ?? 'Confirm'}
347
348
  </Button>