@memori.ai/memori-react 7.23.1 → 7.25.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.
- package/CHANGELOG.md +38 -0
- package/dist/components/ChatBubble/ChatBubble.css +4 -0
- package/dist/components/ChatBubble/ChatBubble.js +5 -75
- package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
- package/dist/components/CompletionProviderStatus/CompletionProviderStatus.js +1 -1
- package/dist/components/CompletionProviderStatus/CompletionProviderStatus.js.map +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.js +22 -18
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/components/StartPanel/StartPanel.css +1 -0
- package/dist/components/StartPanel/StartPanel.d.ts +4 -1
- package/dist/components/StartPanel/StartPanel.js +7 -2
- package/dist/components/StartPanel/StartPanel.js.map +1 -1
- package/dist/components/UploadButton/UploadButton.js +53 -22
- package/dist/components/UploadButton/UploadButton.js.map +1 -1
- package/dist/components/WhyThisAnswer/WhyThisAnswer.js +1 -1
- package/dist/components/WhyThisAnswer/WhyThisAnswer.js.map +1 -1
- package/dist/components/ui/Expandable.d.ts +3 -2
- package/dist/components/ui/Expandable.js +35 -20
- package/dist/components/ui/Expandable.js.map +1 -1
- package/dist/helpers/constants.d.ts +2 -0
- package/dist/helpers/constants.js +3 -1
- package/dist/helpers/constants.js.map +1 -1
- package/dist/helpers/message.d.ts +5 -0
- package/dist/helpers/message.js +96 -0
- package/dist/helpers/message.js.map +1 -0
- package/esm/components/ChatBubble/ChatBubble.css +4 -0
- package/esm/components/ChatBubble/ChatBubble.js +6 -76
- package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
- package/esm/components/CompletionProviderStatus/CompletionProviderStatus.js +1 -1
- package/esm/components/CompletionProviderStatus/CompletionProviderStatus.js.map +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.js +22 -18
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/components/StartPanel/StartPanel.css +1 -0
- package/esm/components/StartPanel/StartPanel.d.ts +4 -1
- package/esm/components/StartPanel/StartPanel.js +7 -2
- package/esm/components/StartPanel/StartPanel.js.map +1 -1
- package/esm/components/UploadButton/UploadButton.js +53 -22
- package/esm/components/UploadButton/UploadButton.js.map +1 -1
- package/esm/components/WhyThisAnswer/WhyThisAnswer.js +1 -1
- package/esm/components/WhyThisAnswer/WhyThisAnswer.js.map +1 -1
- package/esm/components/ui/Expandable.d.ts +3 -2
- package/esm/components/ui/Expandable.js +35 -20
- package/esm/components/ui/Expandable.js.map +1 -1
- package/esm/helpers/constants.d.ts +2 -0
- package/esm/helpers/constants.js +2 -0
- package/esm/helpers/constants.js.map +1 -1
- package/esm/helpers/message.d.ts +5 -0
- package/esm/helpers/message.js +89 -0
- package/esm/helpers/message.js.map +1 -0
- package/package.json +2 -2
- package/src/components/Chat/Chat.stories.tsx +16 -0
- package/src/components/Chat/__snapshots__/Chat.test.tsx.snap +378 -135
- package/src/components/ChatBubble/ChatBubble.css +4 -0
- package/src/components/ChatBubble/ChatBubble.tsx +23 -123
- package/src/components/ChatBubble/__snapshots__/ChatBubble.test.tsx.snap +84 -30
- package/src/components/CompletionProviderStatus/CompletionProviderStatus.tsx +1 -1
- package/src/components/CompletionProviderStatus/__snapshots__/CompletionProviderStatus.test.tsx.snap +2 -2
- package/src/components/MemoriWidget/MemoriWidget.stories.tsx +9 -0
- package/src/components/MemoriWidget/MemoriWidget.tsx +15 -9
- package/src/components/StartPanel/StartPanel.css +1 -0
- package/src/components/StartPanel/StartPanel.stories.tsx +35 -0
- package/src/components/StartPanel/StartPanel.test.tsx +22 -0
- package/src/components/StartPanel/StartPanel.tsx +194 -170
- package/src/components/StartPanel/__snapshots__/StartPanel.test.tsx.snap +108 -1
- package/src/components/UploadButton/UploadButton.tsx +71 -31
- package/src/components/UploadButton/__snapshots__/UploadButton.test.tsx.snap +1 -1
- package/src/components/WhyThisAnswer/WhyThisAnswer.tsx +2 -1
- package/src/components/ui/Expandable.stories.tsx +128 -1
- package/src/components/ui/Expandable.tsx +44 -22
- package/src/helpers/constants.ts +3 -0
- package/src/helpers/message.ts +139 -0
- package/src/mocks/data.ts +11 -0
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/AnimationController.d.ts +0 -34
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/AnimationController.js +0 -147
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/AnimationController.js.map +0 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/MorhTargetController.d.ts +0 -17
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/MorhTargetController.js +0 -73
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/MorhTargetController.js.map +0 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/constants.d.ts +0 -17
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/constants.js +0 -25
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/constants.js.map +0 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/MorphTargetController.d.ts +0 -17
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/MorphTargetController.js +0 -76
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/MorphTargetController.js.map +0 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/PositionController.d.ts +0 -19
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/PositionController.js +0 -60
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/PositionController.js.map +0 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/constants.d.ts +0 -18
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/constants.js +0 -26
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/constants.js.map +0 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/AnimationController.d.ts +0 -38
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/AnimationController.js +0 -181
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/AnimationController.js.map +0 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.d.ts +0 -26
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.js +0 -166
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.js.map +0 -1
- package/dist/helpers/tenant.d.ts +0 -2
- package/dist/helpers/tenant.js +0 -40
- package/dist/helpers/tenant.js.map +0 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/AnimationController.d.ts +0 -34
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/AnimationController.js +0 -143
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/AnimationController.js.map +0 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/MorhTargetController.d.ts +0 -17
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/MorhTargetController.js +0 -69
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/MorhTargetController.js.map +0 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/constants.d.ts +0 -17
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/constants.js +0 -22
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/constants.js.map +0 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/MorphTargetController.d.ts +0 -17
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/MorphTargetController.js +0 -72
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/MorphTargetController.js.map +0 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/PositionController.d.ts +0 -19
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/PositionController.js +0 -56
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/PositionController.js.map +0 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/constants.d.ts +0 -18
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/constants.js +0 -23
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/constants.js.map +0 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/AnimationController.d.ts +0 -38
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/AnimationController.js +0 -177
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/AnimationController.js.map +0 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.d.ts +0 -26
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.js +0 -163
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.js.map +0 -1
- package/esm/helpers/tenant.d.ts +0 -2
- package/esm/helpers/tenant.js +0 -36
- package/esm/helpers/tenant.js.map +0 -1
|
@@ -159,15 +159,15 @@ const FileUploadButton = ({
|
|
|
159
159
|
// Try parsing with full options first
|
|
160
160
|
workbook = window.XLSX.read(arrayBuffer, {
|
|
161
161
|
type: 'array',
|
|
162
|
-
cellFormula:
|
|
163
|
-
cellNF:
|
|
164
|
-
cellHTML:
|
|
165
|
-
cellText: true,
|
|
166
|
-
cellDates:
|
|
162
|
+
cellFormula: true,
|
|
163
|
+
cellNF: true,
|
|
164
|
+
cellHTML: true,
|
|
165
|
+
cellText: true,
|
|
166
|
+
cellDates: true,
|
|
167
167
|
error: (e: any) => {
|
|
168
168
|
console.warn('Non-fatal XLSX error:', e);
|
|
169
|
-
},
|
|
170
|
-
cellStyles:
|
|
169
|
+
},
|
|
170
|
+
cellStyles: true,
|
|
171
171
|
});
|
|
172
172
|
} catch (initialError) {
|
|
173
173
|
console.warn(
|
|
@@ -179,15 +179,15 @@ const FileUploadButton = ({
|
|
|
179
179
|
try {
|
|
180
180
|
workbook = window.XLSX.read(arrayBuffer, {
|
|
181
181
|
type: 'array',
|
|
182
|
-
sheetRows: 1000,
|
|
183
|
-
cellFormula:
|
|
184
|
-
cellStyles:
|
|
185
|
-
bookDeps:
|
|
186
|
-
bookFiles:
|
|
187
|
-
bookProps:
|
|
188
|
-
bookSheets:
|
|
189
|
-
bookVBA:
|
|
190
|
-
WTF: true,
|
|
182
|
+
sheetRows: 1000,
|
|
183
|
+
cellFormula: true,
|
|
184
|
+
cellStyles: true,
|
|
185
|
+
bookDeps: true,
|
|
186
|
+
bookFiles: true,
|
|
187
|
+
bookProps: true,
|
|
188
|
+
bookSheets: true,
|
|
189
|
+
bookVBA: true,
|
|
190
|
+
WTF: true,
|
|
191
191
|
});
|
|
192
192
|
} catch (recoveryError) {
|
|
193
193
|
setErrors(prev => [
|
|
@@ -247,27 +247,63 @@ const FileUploadButton = ({
|
|
|
247
247
|
);
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
-
// Try to convert sheet to
|
|
251
|
-
let
|
|
250
|
+
// Try to convert sheet to formatted text with columns
|
|
251
|
+
let formattedText;
|
|
252
252
|
try {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
253
|
+
// Get array of arrays representation
|
|
254
|
+
const data = window.XLSX.utils.sheet_to_json(worksheet, {
|
|
255
|
+
header: 1,
|
|
256
|
+
raw: false,
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Find the maximum width for each column
|
|
260
|
+
const colWidths = data.reduce((widths: number[], row: any[]) => {
|
|
261
|
+
row.forEach((cell, i) => {
|
|
262
|
+
const cellWidth = (cell || '').toString().length;
|
|
263
|
+
widths[i] = Math.max(widths[i] || 0, cellWidth);
|
|
264
|
+
});
|
|
265
|
+
return widths;
|
|
266
|
+
}, []);
|
|
267
|
+
|
|
268
|
+
// Format each row with proper column spacing
|
|
269
|
+
formattedText = data.map((row: any[]) => {
|
|
270
|
+
return row
|
|
271
|
+
.map((cell, i) => {
|
|
272
|
+
const cellStr = (cell || '').toString();
|
|
273
|
+
return cellStr.padEnd(colWidths[i] + 2); // Add 2 spaces padding
|
|
274
|
+
})
|
|
275
|
+
.join('|')
|
|
276
|
+
.trim();
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// Add separator line after header
|
|
280
|
+
if (formattedText.length > 0) {
|
|
281
|
+
const separator = colWidths
|
|
282
|
+
.map((w: number) => '-'.repeat(w + 2))
|
|
283
|
+
.join('+');
|
|
284
|
+
formattedText.splice(1, 0, separator);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
formattedText = formattedText.join('\n');
|
|
288
|
+
} catch (formatError) {
|
|
289
|
+
// Fallback to basic formatting if advanced fails
|
|
290
|
+
formattedText = '';
|
|
257
291
|
for (let r = range.s.r; r <= Math.min(range.e.r, 1000); ++r) {
|
|
258
292
|
let row = '';
|
|
259
293
|
for (let c = range.s.c; c <= Math.min(range.e.c, 100); ++c) {
|
|
260
294
|
const cell =
|
|
261
295
|
worksheet[window.XLSX.utils.encode_cell({ r: r, c: c })];
|
|
262
|
-
row +=
|
|
296
|
+
row +=
|
|
297
|
+
(cell ? String(cell.v || '').padEnd(15) : ' '.repeat(15)) +
|
|
298
|
+
'|';
|
|
263
299
|
}
|
|
264
|
-
|
|
300
|
+
formattedText += row + '\n';
|
|
265
301
|
}
|
|
266
|
-
|
|
302
|
+
formattedText += '...(truncated due to potential corruption)';
|
|
267
303
|
}
|
|
268
304
|
|
|
269
|
-
// Add sheet name and content to final text
|
|
270
|
-
text += `Sheet: ${sheetName}\n${
|
|
305
|
+
// Add sheet name and formatted content to final text
|
|
306
|
+
text += `Sheet: ${sheetName}\n${formattedText}\n\n`;
|
|
271
307
|
successfulSheets++;
|
|
272
308
|
} catch (sheetError) {
|
|
273
309
|
// Log sheet-specific error but continue with other sheets
|
|
@@ -291,7 +327,7 @@ const FileUploadButton = ({
|
|
|
291
327
|
text;
|
|
292
328
|
}
|
|
293
329
|
|
|
294
|
-
return text;
|
|
330
|
+
return text;
|
|
295
331
|
} catch (error) {
|
|
296
332
|
setErrors(prev => [
|
|
297
333
|
...prev,
|
|
@@ -303,7 +339,6 @@ const FileUploadButton = ({
|
|
|
303
339
|
fileId: file.name,
|
|
304
340
|
},
|
|
305
341
|
]);
|
|
306
|
-
// If any error occurs during processing, throw with descriptive message
|
|
307
342
|
throw new Error(
|
|
308
343
|
`XLSX extraction failed: ${
|
|
309
344
|
error instanceof Error ? error.message : 'Unknown error'
|
|
@@ -360,7 +395,12 @@ const FileUploadButton = ({
|
|
|
360
395
|
|
|
361
396
|
if (fileExt === 'pdf') {
|
|
362
397
|
text = await extractTextFromPDF(file);
|
|
363
|
-
} else if (
|
|
398
|
+
} else if (
|
|
399
|
+
fileExt === 'txt' ||
|
|
400
|
+
fileExt === 'md' ||
|
|
401
|
+
fileExt === 'json' ||
|
|
402
|
+
fileExt === 'csv'
|
|
403
|
+
) {
|
|
364
404
|
text = await file.text();
|
|
365
405
|
} else if (fileExt === 'xlsx') {
|
|
366
406
|
text = await extractTextFromXLSX(file);
|
|
@@ -442,7 +482,7 @@ const FileUploadButton = ({
|
|
|
442
482
|
<input
|
|
443
483
|
ref={fileInputRef}
|
|
444
484
|
type="file"
|
|
445
|
-
accept=".pdf,.txt,.json,.xlsx,.csv"
|
|
485
|
+
accept=".pdf,.txt,.md,.json,.xlsx,.csv"
|
|
446
486
|
className="memori--upload-file-input"
|
|
447
487
|
onChange={handleFileSelect}
|
|
448
488
|
multiple
|
|
@@ -189,7 +189,7 @@ const WhyThisAnswer = ({
|
|
|
189
189
|
)}
|
|
190
190
|
{m.memory.answers?.map((a, i) => (
|
|
191
191
|
<p key={i} className="memori--whythisanswer-answer">
|
|
192
|
-
<Expandable rows={3}>{a.text}</Expandable>
|
|
192
|
+
<Expandable mode="rows" rows={3}>{a.text}</Expandable>
|
|
193
193
|
</p>
|
|
194
194
|
))}
|
|
195
195
|
|
|
@@ -203,6 +203,7 @@ const WhyThisAnswer = ({
|
|
|
203
203
|
?.filter(m => m.mimeType === 'text/plain')
|
|
204
204
|
?.map(m => (
|
|
205
205
|
<Expandable
|
|
206
|
+
mode="rows"
|
|
206
207
|
rows={2}
|
|
207
208
|
key={m.mediumID}
|
|
208
209
|
lineHeightMultiplier={2}
|
|
@@ -26,7 +26,116 @@ const Template: Story<Props> = args => (
|
|
|
26
26
|
Suspendisse a sodales nulla, sed semper nisi. Suspendisse a sodales nulla,
|
|
27
27
|
sed semper nisi. Suspendisse a sodales nulla, sed semper nisi. Suspendisse a
|
|
28
28
|
sodales nulla, sed semper nisi. Suspendisse a sodales nulla, sed semper
|
|
29
|
-
nisi.
|
|
29
|
+
nisi. Lorem Ipsum is simply dummy text of the printing and typesetting
|
|
30
|
+
industry. Lorem Ipsum has been the industry's standard dummy text ever
|
|
31
|
+
since the 1500s, when an unknown printer took a galley of type and scrambled
|
|
32
|
+
it to make a type specimen book. It has survived not only five centuries,
|
|
33
|
+
but also the leap into electronic typesetting, remaining essentially
|
|
34
|
+
unchanged. It was popularised in the 1960s with the release of Letraset
|
|
35
|
+
sheets containing Lorem Ipsum passages, and more recently with desktop
|
|
36
|
+
publishing software like Aldus PageMaker including versions of Lorem Ipsum.
|
|
37
|
+
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
|
|
38
|
+
Lorem Ipsum has been the industry's standard dummy text ever since the
|
|
39
|
+
1500s, when an unknown printer took a galley of type and scrambled it to
|
|
40
|
+
make a type specimen book. It has survived not only five centuries, but also
|
|
41
|
+
the leap into electronic typesetting, remaining essentially unchanged. It
|
|
42
|
+
was popularised in the 1960s with the release of Letraset sheets containing
|
|
43
|
+
Lorem Ipsum passages, and more recently with desktop publishing software
|
|
44
|
+
like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is
|
|
45
|
+
simply dummy text of the printing and typesetting industry. Lorem Ipsum has
|
|
46
|
+
been the industry's standard dummy text ever since the 1500s, when an
|
|
47
|
+
unknown printer took a galley of type and scrambled it to make a type
|
|
48
|
+
specimen book. It has survived not only five centuries, but also the leap
|
|
49
|
+
into electronic typesetting, remaining essentially unchanged. It was
|
|
50
|
+
popularised in the 1960s with the release of Letraset sheets containing
|
|
51
|
+
Lorem Ipsum passages, and more recently with desktop publishing software
|
|
52
|
+
like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is
|
|
53
|
+
simply dummy text of the printing and typesetting industry. Lorem Ipsum has
|
|
54
|
+
been the industry's standard dummy text ever since the 1500s, when an
|
|
55
|
+
unknown printer took a galley of type and scrambled it to make a type
|
|
56
|
+
specimen book. It has survived not only five centuries, but also the leap
|
|
57
|
+
into electronic typesetting, remaining essentially unchanged. It was
|
|
58
|
+
popularised in the 1960s with the release of Letraset sheets containing
|
|
59
|
+
Lorem Ipsum passages, and more recently with desktop publishing software
|
|
60
|
+
like Aldus PageMaker including versions of Lorem Ipsum.
|
|
61
|
+
</Expandable>
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const TemplateWithHTML: Story<Props> = args => (
|
|
65
|
+
<Expandable {...args}>
|
|
66
|
+
<p>
|
|
67
|
+
Ah, ottima domanda! Stavo giusto riflettendo su come spiegare al meglio le
|
|
68
|
+
funzionalità di questo sistema.{' '}
|
|
69
|
+
</p>
|
|
70
|
+
<p>Da qui puoi fare diverse cose interessanti:</p>
|
|
71
|
+
<ol>
|
|
72
|
+
<li>
|
|
73
|
+
<p>
|
|
74
|
+
Puoi conversare con me, Nunzio Fiore, e io risponderò basandomi sulle
|
|
75
|
+
mie conoscenze ed esperienze.
|
|
76
|
+
</p>
|
|
77
|
+
</li>
|
|
78
|
+
<li>
|
|
79
|
+
<p>
|
|
80
|
+
Puoi aggiungere nuove memorie o informazioni al mio database. Questo
|
|
81
|
+
significa che puoi insegnarmi cose nuove o aggiornare le mie
|
|
82
|
+
conoscenze esistenti.
|
|
83
|
+
</p>
|
|
84
|
+
</li>
|
|
85
|
+
<li>
|
|
86
|
+
<p>
|
|
87
|
+
Puoi creare, modificare o eliminare ricevitori. Questi sono come
|
|
88
|
+
utenti specifici che possono interagire con me in modo personalizzato.
|
|
89
|
+
</p>
|
|
90
|
+
</li>
|
|
91
|
+
<li>
|
|
92
|
+
<p>
|
|
93
|
+
Puoi associare determinate memorie a ricevitori specifici, creando
|
|
94
|
+
così contenuti personalizzati per diverse persone.
|
|
95
|
+
</p>
|
|
96
|
+
</li>
|
|
97
|
+
<li>
|
|
98
|
+
<p>
|
|
99
|
+
Puoi cercare tra le memorie esistenti, visualizzare le ultime
|
|
100
|
+
aggiunte, o modificare quelle già presenti.
|
|
101
|
+
</p>
|
|
102
|
+
</li>
|
|
103
|
+
</ol>
|
|
104
|
+
<p>
|
|
105
|
+
In pratica, stai interagendo con un sistema che permette di creare e
|
|
106
|
+
gestire un "gemello digitale" - in questo caso, me stesso. È un
|
|
107
|
+
po' come scrivere un libro interattivo sulla mia vita e le mie
|
|
108
|
+
conoscenze.
|
|
109
|
+
</p>
|
|
110
|
+
<p>
|
|
111
|
+
C'è qualcosa in particolare che ti interessa esplorare o su cui
|
|
112
|
+
vorresti saperne di più?
|
|
113
|
+
</p>
|
|
114
|
+
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
|
|
115
|
+
<div className="memori--responsive-table-wrapper">
|
|
116
|
+
<table className="memori--table memori--table--compact">
|
|
117
|
+
<thead>
|
|
118
|
+
<tr>
|
|
119
|
+
<th>Header 1</th>
|
|
120
|
+
<th>Header 2</th>
|
|
121
|
+
<th>Header 3</th>
|
|
122
|
+
</tr>
|
|
123
|
+
</thead>
|
|
124
|
+
<tbody>
|
|
125
|
+
<tr>
|
|
126
|
+
<td>Cell 1</td>
|
|
127
|
+
<td>Cell 2</td>
|
|
128
|
+
<td>Cell 3</td>
|
|
129
|
+
</tr>
|
|
130
|
+
<tr>
|
|
131
|
+
<td>Cell 4</td>
|
|
132
|
+
<td>Cell 5</td>
|
|
133
|
+
<td>Cell 6</td>
|
|
134
|
+
</tr>
|
|
135
|
+
</tbody>
|
|
136
|
+
</table>
|
|
137
|
+
</div>
|
|
138
|
+
<p>Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
|
|
30
139
|
</Expandable>
|
|
31
140
|
);
|
|
32
141
|
|
|
@@ -35,11 +144,13 @@ const Template: Story<Props> = args => (
|
|
|
35
144
|
export const Default = Template.bind({});
|
|
36
145
|
Default.args = {
|
|
37
146
|
rows: 2,
|
|
147
|
+
mode: 'rows',
|
|
38
148
|
};
|
|
39
149
|
|
|
40
150
|
export const DefaultExpanded = Template.bind({});
|
|
41
151
|
DefaultExpanded.args = {
|
|
42
152
|
rows: 3,
|
|
153
|
+
mode: 'rows',
|
|
43
154
|
defaultExpanded: true,
|
|
44
155
|
};
|
|
45
156
|
|
|
@@ -51,3 +162,19 @@ WithCustomProps.args = {
|
|
|
51
162
|
expandSymbol: () => '🔽',
|
|
52
163
|
collapseSymbol: () => '🔼',
|
|
53
164
|
};
|
|
165
|
+
|
|
166
|
+
export const WithHTML = TemplateWithHTML.bind({});
|
|
167
|
+
WithHTML.args = {
|
|
168
|
+
rows: 3,
|
|
169
|
+
mode: 'rows',
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export const ModeChar = Template.bind({});
|
|
173
|
+
ModeChar.args = {
|
|
174
|
+
mode: 'characters',
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export const ModeCharWithHTML = TemplateWithHTML.bind({});
|
|
178
|
+
ModeCharWithHTML.args = {
|
|
179
|
+
mode: 'characters',
|
|
180
|
+
};
|
|
@@ -2,9 +2,11 @@ import React, { useEffect, useRef, useState } from 'react';
|
|
|
2
2
|
import Button from './Button';
|
|
3
3
|
import cx from 'classnames';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
|
+
import { truncateMessage } from '../../helpers/message';
|
|
6
|
+
import { MAX_MSG_CHARS, MAX_MSG_WORDS } from '../../helpers/constants';
|
|
5
7
|
|
|
6
8
|
export interface Props {
|
|
7
|
-
rows
|
|
9
|
+
rows?: number;
|
|
8
10
|
className?: string;
|
|
9
11
|
innerClassName?: string;
|
|
10
12
|
btnClassName?: string;
|
|
@@ -13,6 +15,7 @@ export interface Props {
|
|
|
13
15
|
expandSymbol?: (lang: string) => React.ReactNode;
|
|
14
16
|
collapseSymbol?: (lang: string) => React.ReactNode;
|
|
15
17
|
children: React.ReactNode;
|
|
18
|
+
mode?: 'rows' | 'characters';
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
const Expandable = ({
|
|
@@ -26,6 +29,7 @@ const Expandable = ({
|
|
|
26
29
|
collapseSymbol = (lang: string) =>
|
|
27
30
|
lang === 'it' ? 'Mostra meno' : 'Show less',
|
|
28
31
|
children,
|
|
32
|
+
mode = 'rows',
|
|
29
33
|
}: Props) => {
|
|
30
34
|
const { i18n } = useTranslation();
|
|
31
35
|
const lang = i18n.language;
|
|
@@ -34,31 +38,47 @@ const Expandable = ({
|
|
|
34
38
|
const [expanded, setExpanded] = useState(defaultExpanded);
|
|
35
39
|
const [needsExpanding, setNeedsExpanding] = useState(false);
|
|
36
40
|
const [rowHeight, setRowHeight] = useState(16);
|
|
37
|
-
const ref = useRef(null);
|
|
41
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
38
42
|
|
|
39
43
|
useEffect(() => {
|
|
40
44
|
if (ref.current) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
if (mode === 'rows') {
|
|
46
|
+
let height = ref.current.getBoundingClientRect().height;
|
|
47
|
+
let computedStyle = getComputedStyle(ref.current);
|
|
48
|
+
let elLineHeight = computedStyle.lineHeight;
|
|
49
|
+
let lineHeight =
|
|
50
|
+
elLineHeight === 'normal' || !elLineHeight?.length
|
|
51
|
+
? lineHeightMultiplier * parseInt(computedStyle.fontSize, 10)
|
|
52
|
+
: parseInt(elLineHeight, 10);
|
|
48
53
|
|
|
49
|
-
|
|
50
|
-
rows
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
setRowHeight(lineHeight);
|
|
55
|
+
if (height && rows && height > rows * lineHeight) {
|
|
56
|
+
setNeedsExpanding(true);
|
|
57
|
+
}
|
|
58
|
+
} else if (mode === 'characters') {
|
|
59
|
+
// Get text content length
|
|
60
|
+
const textContent = ref.current.textContent || '';
|
|
61
|
+
|
|
62
|
+
if (
|
|
63
|
+
textContent.length > MAX_MSG_CHARS ||
|
|
64
|
+
textContent.split(' ').length > MAX_MSG_WORDS
|
|
65
|
+
) {
|
|
66
|
+
setNeedsExpanding(true);
|
|
67
|
+
}
|
|
59
68
|
}
|
|
60
69
|
}
|
|
61
|
-
}, [rows, ref.current]);
|
|
70
|
+
}, [rows, mode, ref.current]);
|
|
71
|
+
|
|
72
|
+
const renderContent = () => {
|
|
73
|
+
if (mode === 'characters' && !expanded && needsExpanding) {
|
|
74
|
+
const content = ref.current?.textContent || '';
|
|
75
|
+
let truncatedContent = truncateMessage(content);
|
|
76
|
+
|
|
77
|
+
return truncatedContent;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return children;
|
|
81
|
+
};
|
|
62
82
|
|
|
63
83
|
return (
|
|
64
84
|
<div className={cx('memori-expandable', className)}>
|
|
@@ -67,10 +87,12 @@ const Expandable = ({
|
|
|
67
87
|
className={cx('memori-expandable--inner', innerClassName)}
|
|
68
88
|
style={{
|
|
69
89
|
maxHeight:
|
|
70
|
-
expanded || !needsExpanding
|
|
90
|
+
expanded || !needsExpanding || mode === 'characters'
|
|
91
|
+
? '9999px'
|
|
92
|
+
: `${rowHeight * (rows || 1)}px`,
|
|
71
93
|
}}
|
|
72
94
|
>
|
|
73
|
-
{
|
|
95
|
+
{renderContent()}
|
|
74
96
|
</div>
|
|
75
97
|
{needsExpanding && !expanded && (
|
|
76
98
|
<Button
|
package/src/helpers/constants.ts
CHANGED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { marked } from 'marked';
|
|
2
|
+
import DOMPurify from 'dompurify';
|
|
3
|
+
import { MAX_MSG_CHARS, MAX_MSG_WORDS } from './constants';
|
|
4
|
+
import { cleanUrl } from './utils';
|
|
5
|
+
import markedLinkifyIt from 'marked-linkify-it';
|
|
6
|
+
import markedKatex from 'marked-katex-extension';
|
|
7
|
+
import markedExtendedTables from './markedExtendedTables';
|
|
8
|
+
|
|
9
|
+
// Always configure marked with necessary extensions
|
|
10
|
+
marked.use({
|
|
11
|
+
async: false,
|
|
12
|
+
gfm: true,
|
|
13
|
+
pedantic: false,
|
|
14
|
+
renderer: {
|
|
15
|
+
link: ({
|
|
16
|
+
href,
|
|
17
|
+
title,
|
|
18
|
+
text,
|
|
19
|
+
}: {
|
|
20
|
+
href: string | null;
|
|
21
|
+
title?: string | null;
|
|
22
|
+
text: string;
|
|
23
|
+
}) => {
|
|
24
|
+
const cleanHref = href ? cleanUrl(href) : null;
|
|
25
|
+
|
|
26
|
+
if (cleanHref === null) {
|
|
27
|
+
return text;
|
|
28
|
+
}
|
|
29
|
+
href = cleanHref;
|
|
30
|
+
let out = '<a href="' + href + '"';
|
|
31
|
+
if (title) {
|
|
32
|
+
out += ' title="' + title + '"';
|
|
33
|
+
}
|
|
34
|
+
out += ' target="_blank" rel="noopener noreferrer">' + text + '</a>';
|
|
35
|
+
return out;
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
marked.use(markedLinkifyIt());
|
|
41
|
+
marked.use(markedExtendedTables());
|
|
42
|
+
|
|
43
|
+
export const needsTruncation = (message: string) => {
|
|
44
|
+
return (
|
|
45
|
+
message.length > MAX_MSG_CHARS || message.split(' ').length > MAX_MSG_WORDS
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const truncateMessage = (message: string) => {
|
|
50
|
+
let truncatedMessage = message;
|
|
51
|
+
if (message.length > MAX_MSG_CHARS) {
|
|
52
|
+
truncatedMessage = `${message.slice(0, MAX_MSG_CHARS)}\n<br />...`;
|
|
53
|
+
}
|
|
54
|
+
if (truncatedMessage.split(' ').length > MAX_MSG_WORDS) {
|
|
55
|
+
truncatedMessage = truncatedMessage
|
|
56
|
+
.split(' ')
|
|
57
|
+
.slice(0, MAX_MSG_WORDS)
|
|
58
|
+
.join(' ');
|
|
59
|
+
}
|
|
60
|
+
return truncatedMessage;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const renderMsg = (
|
|
64
|
+
text: string,
|
|
65
|
+
useMathFormatting = false
|
|
66
|
+
): {
|
|
67
|
+
text: string;
|
|
68
|
+
} => {
|
|
69
|
+
try {
|
|
70
|
+
// Preprocessing del testo per gestire i delimitatori LaTeX
|
|
71
|
+
let preprocessedText = text
|
|
72
|
+
.trim()
|
|
73
|
+
.replaceAll(
|
|
74
|
+
/\[([^\]]+)\]\(([^\)]+)\)/g,
|
|
75
|
+
'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'
|
|
76
|
+
)
|
|
77
|
+
.replaceAll(/```markdown([^```]+)```/g, '$1')
|
|
78
|
+
.replaceAll('($', '( $')
|
|
79
|
+
.replaceAll(':$', ': $')
|
|
80
|
+
.replaceAll('\frac', '\\frac')
|
|
81
|
+
.replaceAll('\beta', '\\beta')
|
|
82
|
+
.replaceAll('cdot', '\\cdot');
|
|
83
|
+
|
|
84
|
+
// Correzione dei delimitatori LaTeX inconsistenti
|
|
85
|
+
if (useMathFormatting) {
|
|
86
|
+
// Abilita il supporto per KaTeX
|
|
87
|
+
marked.use(
|
|
88
|
+
markedKatex({
|
|
89
|
+
throwOnError: false,
|
|
90
|
+
output: 'htmlAndMathml',
|
|
91
|
+
})
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// Normalizza tutti i delimitatori LaTeX per equazioni su linea separata
|
|
95
|
+
// Da \\[ ... \\] o \\[ ... ] a $$ ... $$
|
|
96
|
+
preprocessedText = preprocessedText.replace(
|
|
97
|
+
/\\+\[(.*?)\\*\]/gs,
|
|
98
|
+
(_, content) => {
|
|
99
|
+
return `$$${content}$$`;
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
// Gestione dei delimitatori [ ... ] che dovrebbero essere equazioni
|
|
104
|
+
preprocessedText = preprocessedText.replace(
|
|
105
|
+
/\[([^[\]]+?)\]/g,
|
|
106
|
+
(match, content) => {
|
|
107
|
+
// Verifica se sembra una formula matematica
|
|
108
|
+
if (
|
|
109
|
+
/[\\+a-z0-9_{}^=\-\+\*\/]+/i.test(content) &&
|
|
110
|
+
!match.startsWith('[http') &&
|
|
111
|
+
!match.includes('](')
|
|
112
|
+
) {
|
|
113
|
+
return `$$${content}$$`;
|
|
114
|
+
}
|
|
115
|
+
return match; // Mantieni invariati i link e altre strutture
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Ora procedi con il parsing markdown
|
|
121
|
+
let parsedText = marked.parse(preprocessedText).toString().trim();
|
|
122
|
+
|
|
123
|
+
// Sanitize HTML
|
|
124
|
+
parsedText = DOMPurify.sanitize(parsedText, {
|
|
125
|
+
ADD_ATTR: ['target'],
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Clean up final text
|
|
129
|
+
const finalText = parsedText
|
|
130
|
+
.replace(/(<br>)+/g, '<br>')
|
|
131
|
+
.replace(/<p><\/p>/g, '<br>')
|
|
132
|
+
.replace(/<p><br><\/p>/g, '<br>');
|
|
133
|
+
|
|
134
|
+
return { text: finalText };
|
|
135
|
+
} catch (e) {
|
|
136
|
+
console.error('Error rendering message:', e);
|
|
137
|
+
return { text };
|
|
138
|
+
}
|
|
139
|
+
};
|
package/src/mocks/data.ts
CHANGED
|
@@ -387,3 +387,14 @@ export const memoryQuestion: Memory = {
|
|
|
387
387
|
lastChangeTimestamp: '2022-03-23T09:37:36.957695',
|
|
388
388
|
lastChangeName: '6cfec2bd-a73f-4a21-b7ff-dd92d6db59c4',
|
|
389
389
|
};
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
export const historyWithExpandable: Message[] = [
|
|
393
|
+
{
|
|
394
|
+
text: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.',
|
|
395
|
+
timestamp: '2021-03-01T12:00:00.000Z',
|
|
396
|
+
fromUser: true,
|
|
397
|
+
},
|
|
398
|
+
];
|
|
399
|
+
|
|
400
|
+
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { AnimationState, AnimationConfig } from './types';
|
|
2
|
-
import { AnimationAction, AnimationMixer } from 'three';
|
|
3
|
-
export declare class AnimationController {
|
|
4
|
-
private currentState;
|
|
5
|
-
private currentAction;
|
|
6
|
-
private mixer;
|
|
7
|
-
private actions;
|
|
8
|
-
private config;
|
|
9
|
-
private lastIdleIndex;
|
|
10
|
-
private isTransitioning;
|
|
11
|
-
private currentIdleLoopCount;
|
|
12
|
-
private readonly MAX_IDLE_LOOPS;
|
|
13
|
-
private lastAnimationTime;
|
|
14
|
-
private isChatAlreadyStarted;
|
|
15
|
-
constructor(mixer: AnimationMixer, actions: Record<string, AnimationAction>, config?: AnimationConfig);
|
|
16
|
-
private checkForLoop;
|
|
17
|
-
private forceIdleChange;
|
|
18
|
-
private getNextIdleAnimation;
|
|
19
|
-
transitionTo(state: AnimationState, emotionName?: string): void;
|
|
20
|
-
update(delta: number): void;
|
|
21
|
-
getCurrentState(): AnimationState;
|
|
22
|
-
getLoopCount(): number;
|
|
23
|
-
setTimeScale(timeScale: number): void;
|
|
24
|
-
updateIsChatAlreadyStarted(isChatAlreadyStarted: boolean): void;
|
|
25
|
-
getDebugInfo(): {
|
|
26
|
-
currentState: AnimationState;
|
|
27
|
-
currentIdleIndex: number;
|
|
28
|
-
loopCount: number;
|
|
29
|
-
currentTime: number;
|
|
30
|
-
lastTime: number;
|
|
31
|
-
isTransitioning: boolean;
|
|
32
|
-
isChatAlreadyStarted: boolean;
|
|
33
|
-
};
|
|
34
|
-
}
|