@memori.ai/memori-react 8.5.1 → 8.6.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 +24 -0
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.d.ts +3 -3
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.js +2 -2
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.js.map +1 -1
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyButtonWithDropdown.js +129 -3
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyButtonWithDropdown.js.map +1 -1
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/hooks/useCopyArtifact.js +189 -26
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/hooks/useCopyArtifact.js.map +1 -1
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/utils/PDFExporter.d.ts +2 -0
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/utils/PDFExporter.js +138 -17
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/utils/PDFExporter.js.map +1 -1
- package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +17 -4
- package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +64 -21
- package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -1
- package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js +9 -4
- package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js.map +1 -1
- package/dist/components/layouts/chat.css +1 -1
- package/dist/helpers/utils.d.ts +2 -0
- package/dist/helpers/utils.js +19 -1
- package/dist/helpers/utils.js.map +1 -1
- package/dist/locales/de.json +2 -1
- package/dist/locales/en.json +2 -1
- package/dist/locales/es.json +2 -1
- package/dist/locales/fr.json +2 -1
- package/dist/locales/it.json +2 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.d.ts +3 -3
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.js +2 -2
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.js.map +1 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyButtonWithDropdown.js +129 -3
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyButtonWithDropdown.js.map +1 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/hooks/useCopyArtifact.js +188 -26
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/hooks/useCopyArtifact.js.map +1 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/utils/PDFExporter.d.ts +2 -0
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/utils/PDFExporter.js +138 -17
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/utils/PDFExporter.js.map +1 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +17 -4
- package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +64 -21
- package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js +9 -4
- package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js.map +1 -1
- package/esm/components/layouts/chat.css +1 -1
- package/esm/helpers/utils.d.ts +2 -0
- package/esm/helpers/utils.js +16 -0
- package/esm/helpers/utils.js.map +1 -1
- package/esm/locales/de.json +2 -1
- package/esm/locales/en.json +2 -1
- package/esm/locales/es.json +2 -1
- package/esm/locales/fr.json +2 -1
- package/esm/locales/it.json +2 -1
- package/package.json +1 -1
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.tsx +5 -5
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyButtonWithDropdown.tsx +141 -3
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/hooks/useCopyArtifact.ts +211 -33
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/utils/PDFExporter.ts +190 -26
- package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +17 -4
- package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.tsx +191 -180
- package/src/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.tsx +9 -4
- package/src/components/layouts/chat.css +1 -1
- package/src/helpers/utils.ts +21 -0
- package/src/locales/de.json +2 -1
- package/src/locales/en.json +2 -1
- package/src/locales/es.json +2 -1
- package/src/locales/fr.json +2 -1
- package/src/locales/it.json +2 -1
|
@@ -12,7 +12,7 @@ import Close from '../../../icons/Close';
|
|
|
12
12
|
import ArtifactActions from '../ArtifactActions/ArtifactActions';
|
|
13
13
|
import { useArtifact } from '../../context/ArtifactContext';
|
|
14
14
|
import ArtifactPreview from '../ArtifactPreview/ArtifactPreview';
|
|
15
|
-
import { ArtifactTab } from '../../types/artifact.types';
|
|
15
|
+
import { ArtifactData, ArtifactTab } from '../../types/artifact.types';
|
|
16
16
|
import cx from 'classnames';
|
|
17
17
|
import Drawer from '../../../ui/Drawer';
|
|
18
18
|
import Fullscreen from '../../../icons/Fullscreen';
|
|
@@ -27,11 +27,9 @@ import TabSwitch from './components/TabSwitch';
|
|
|
27
27
|
const ArtifactDrawer: React.FC<{ isChatLogPanel?: boolean }> = ({
|
|
28
28
|
isChatLogPanel = false,
|
|
29
29
|
}) => {
|
|
30
|
-
const { state,
|
|
30
|
+
const { state, closeArtifact, toggleFullscreen } =
|
|
31
31
|
useArtifact();
|
|
32
32
|
const { t } = useTranslation();
|
|
33
|
-
const [showHistory, setShowHistory] = useState(false);
|
|
34
|
-
const [isAnimating, setIsAnimating] = useState(false);
|
|
35
33
|
const [isMobile, setIsMobile] = useState(false);
|
|
36
34
|
|
|
37
35
|
const [activeTab, setActiveTab] = useState<ArtifactTab>('preview');
|
|
@@ -99,30 +97,6 @@ const ArtifactDrawer: React.FC<{ isChatLogPanel?: boolean }> = ({
|
|
|
99
97
|
}
|
|
100
98
|
}, [state.currentArtifact]);
|
|
101
99
|
|
|
102
|
-
/**
|
|
103
|
-
* Handle download action
|
|
104
|
-
*/
|
|
105
|
-
const handleDownload = useCallback(() => {
|
|
106
|
-
// This will be handled by the ArtifactActions component
|
|
107
|
-
console.log('Download triggered');
|
|
108
|
-
}, []);
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Handle print action
|
|
112
|
-
*/
|
|
113
|
-
const handlePrint = useCallback(() => {
|
|
114
|
-
// This will be handled by the ArtifactActions component
|
|
115
|
-
console.log('Print triggered');
|
|
116
|
-
}, []);
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Handle external open action
|
|
120
|
-
*/
|
|
121
|
-
const handleOpenExternal = useCallback(() => {
|
|
122
|
-
// This will be handled by the ArtifactActions component
|
|
123
|
-
console.log('External open triggered');
|
|
124
|
-
}, []);
|
|
125
|
-
|
|
126
100
|
/**
|
|
127
101
|
* Handle fullscreen toggle
|
|
128
102
|
*/
|
|
@@ -139,20 +113,6 @@ const ArtifactDrawer: React.FC<{ isChatLogPanel?: boolean }> = ({
|
|
|
139
113
|
closeArtifact();
|
|
140
114
|
}, [closeArtifact]);
|
|
141
115
|
|
|
142
|
-
/**
|
|
143
|
-
* Toggle history panel
|
|
144
|
-
*/
|
|
145
|
-
const toggleHistory = useCallback(() => {
|
|
146
|
-
setShowHistory(prev => !prev);
|
|
147
|
-
}, []);
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Mobile dropdown menu handlers
|
|
151
|
-
*/
|
|
152
|
-
const handleMobileOpenExternal = useCallback(() => {
|
|
153
|
-
handleOpenExternal();
|
|
154
|
-
}, [handleOpenExternal]);
|
|
155
|
-
|
|
156
116
|
if (!state.currentArtifact) {
|
|
157
117
|
return null;
|
|
158
118
|
}
|
|
@@ -166,9 +126,7 @@ const ArtifactDrawer: React.FC<{ isChatLogPanel?: boolean }> = ({
|
|
|
166
126
|
if (isChatLogPanel) {
|
|
167
127
|
return (
|
|
168
128
|
<div
|
|
169
|
-
style={
|
|
170
|
-
isChatLogPanel ? { minHeight: '75vh', maxHeight: '75vh' } : {}
|
|
171
|
-
}
|
|
129
|
+
style={{ minHeight: '75vh', maxHeight: '75vh' }}
|
|
172
130
|
className="memori-artifact-panel"
|
|
173
131
|
>
|
|
174
132
|
{children}
|
|
@@ -210,176 +168,229 @@ const ArtifactDrawer: React.FC<{ isChatLogPanel?: boolean }> = ({
|
|
|
210
168
|
[isChatLogPanel, handleClose, state.isDrawerOpen, state.isFullscreen]
|
|
211
169
|
);
|
|
212
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Get MIME type string for downloads
|
|
173
|
+
*/
|
|
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);
|
|
223
|
+
}
|
|
224
|
+
}, []);
|
|
225
|
+
|
|
213
226
|
// Render web split panel
|
|
214
227
|
return (
|
|
215
228
|
<ContentContainer>
|
|
216
229
|
{/* Header */}
|
|
217
|
-
<div
|
|
230
|
+
<div
|
|
231
|
+
className={cx('memori-artifact-drawer-container-actions', {
|
|
232
|
+
'memori-artifact-drawer-container-actions--no-preview': !hasPreview,
|
|
233
|
+
'memori-artifact-drawer-container-actions--chatlog': isChatLogPanel,
|
|
234
|
+
})}
|
|
235
|
+
>
|
|
218
236
|
{/* Desktop Actions */}
|
|
219
237
|
{!isMobile && (
|
|
220
238
|
<>
|
|
221
|
-
{/* {!isChatLogPanel && (
|
|
222
|
-
<Button
|
|
223
|
-
onClick={handleToggleFullscreen}
|
|
224
|
-
className={cx(
|
|
225
|
-
'memori-artifact-drawer-fullscreen',
|
|
226
|
-
'memori-button--circle',
|
|
227
|
-
'memori-button--icon-only'
|
|
228
|
-
)}
|
|
229
|
-
ghost
|
|
230
|
-
icon={
|
|
231
|
-
state.isFullscreen ? (
|
|
232
|
-
<Fullscreen className="memori-artifact-panel--close-icon" />
|
|
233
|
-
) : (
|
|
234
|
-
<FullscreenExit className="memori-artifact-panel--close-icon" />
|
|
235
|
-
)
|
|
236
|
-
}
|
|
237
|
-
title={
|
|
238
|
-
state.isFullscreen
|
|
239
|
-
? t('artifact.exitFullscreen') || 'Exit Fullscreen'
|
|
240
|
-
: t('artifact.fullscreen') || 'Fullscreen'
|
|
241
|
-
}
|
|
242
|
-
/>
|
|
243
|
-
)} */}
|
|
244
239
|
{/* Modern Tab Switch */}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
240
|
+
{hasPreview && (
|
|
241
|
+
<TabSwitch
|
|
242
|
+
activeTab={activeTab}
|
|
243
|
+
onTabChange={handleTabChange}
|
|
244
|
+
hasPreview={hasPreview}
|
|
245
|
+
/>
|
|
246
|
+
)}
|
|
250
247
|
<ArtifactActions
|
|
251
248
|
artifact={state.currentArtifact}
|
|
252
249
|
onCopy={handleCopy}
|
|
253
|
-
onDownload={handleDownload}
|
|
254
250
|
loading={false}
|
|
255
|
-
onPrint={handlePrint}
|
|
256
|
-
onOpenExternal={handleOpenExternal}
|
|
257
251
|
isMobile={isMobile}
|
|
258
252
|
/>
|
|
259
253
|
<Button
|
|
260
254
|
onClick={closeArtifact}
|
|
261
255
|
className={cx(
|
|
262
256
|
'memori-artifact-drawer--close',
|
|
263
|
-
'memori-button--icon-only'
|
|
257
|
+
'memori-button--icon-only',
|
|
258
|
+
{
|
|
259
|
+
'memori-artifact-drawer--close-desktop': !hasPreview,
|
|
260
|
+
}
|
|
264
261
|
)}
|
|
265
262
|
ghost
|
|
266
263
|
title={t('artifact.close') || 'Close'}
|
|
267
264
|
>
|
|
268
|
-
<Close
|
|
265
|
+
<Close className="memori-artifact-panel--close-icon" />
|
|
269
266
|
</Button>
|
|
270
267
|
</>
|
|
271
268
|
)}
|
|
272
269
|
</div>
|
|
273
270
|
|
|
274
271
|
{/* Top Right Header Section */}
|
|
275
|
-
<div
|
|
272
|
+
<div
|
|
273
|
+
className={cx('memori-artifact-drawer-top-right', {
|
|
274
|
+
'memori-artifact-drawer-top-right--no-preview': !hasPreview,
|
|
275
|
+
'memori-artifact-drawer-top-right--chatlog': isChatLogPanel,
|
|
276
|
+
})}
|
|
277
|
+
>
|
|
276
278
|
{/* Mobile Dropdown Menu */}
|
|
277
279
|
{isMobile && (
|
|
278
280
|
<>
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
as={React.Fragment}
|
|
301
|
-
enter="memori-mobile-dropdown-enter"
|
|
302
|
-
enterFrom="memori-mobile-dropdown-enter-from"
|
|
303
|
-
enterTo="memori-mobile-dropdown-enter-to"
|
|
304
|
-
leave="memori-mobile-dropdown-leave"
|
|
305
|
-
leaveFrom="memori-mobile-dropdown-leave-from"
|
|
306
|
-
leaveTo="memori-mobile-dropdown-leave-to"
|
|
307
|
-
>
|
|
308
|
-
<Menu.Items className="memori-mobile-dropdown">
|
|
309
|
-
<div className="memori-mobile-dropdown-list">
|
|
310
|
-
<Button
|
|
311
|
-
onClick={handleCopy}
|
|
312
|
-
disabled={false}
|
|
313
|
-
className="memori-artifact-action-btn"
|
|
314
|
-
ghost
|
|
315
|
-
title={t('artifact.copy') || 'Copy'}
|
|
316
|
-
>
|
|
317
|
-
<span className="memori-artifact-action-text">
|
|
318
|
-
{t('artifact.copy') || 'Copy'}
|
|
319
|
-
</span>
|
|
320
|
-
</Button>
|
|
281
|
+
{hasPreview && (
|
|
282
|
+
<TabSwitch
|
|
283
|
+
activeTab={activeTab}
|
|
284
|
+
onTabChange={handleTabChange}
|
|
285
|
+
hasPreview={hasPreview}
|
|
286
|
+
/>
|
|
287
|
+
)}
|
|
288
|
+
<Menu as="div" className="memori-mobile-actions-menu">
|
|
289
|
+
<Menu.Button as="div" className="memori-mobile-actions-trigger">
|
|
290
|
+
<Button
|
|
291
|
+
className={cx(
|
|
292
|
+
'memori-button',
|
|
293
|
+
'memori-button--more-options',
|
|
294
|
+
'memori-button--icon-only'
|
|
295
|
+
)}
|
|
296
|
+
ghost
|
|
297
|
+
title={t('artifact.actions') || 'Actions'}
|
|
298
|
+
>
|
|
299
|
+
<MenuVertical className="memori-artifact-action-icon" />
|
|
300
|
+
</Button>
|
|
301
|
+
</Menu.Button>
|
|
321
302
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
};
|
|
303
|
+
<Transition
|
|
304
|
+
as={React.Fragment}
|
|
305
|
+
enter="memori-mobile-dropdown-enter"
|
|
306
|
+
enterFrom="memori-mobile-dropdown-enter-from"
|
|
307
|
+
enterTo="memori-mobile-dropdown-enter-to"
|
|
308
|
+
leave="memori-mobile-dropdown-leave"
|
|
309
|
+
leaveFrom="memori-mobile-dropdown-leave-from"
|
|
310
|
+
leaveTo="memori-mobile-dropdown-leave-to"
|
|
311
|
+
>
|
|
312
|
+
<Menu.Items className="memori-mobile-dropdown">
|
|
313
|
+
<div className="memori-mobile-dropdown-list">
|
|
314
|
+
<Button
|
|
315
|
+
onClick={handleCopy}
|
|
316
|
+
disabled={false}
|
|
317
|
+
className="memori-artifact-action-btn"
|
|
318
|
+
ghost
|
|
319
|
+
title={t('artifact.copy') || 'Copy'}
|
|
320
|
+
>
|
|
321
|
+
<span className="memori-artifact-action-text">
|
|
322
|
+
{t('artifact.copy') || 'Copy'}
|
|
323
|
+
</span>
|
|
324
|
+
</Button>
|
|
345
325
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
326
|
+
{formats.map(format => {
|
|
327
|
+
// Get appropriate icon based on action type
|
|
328
|
+
const getIcon = () => {
|
|
329
|
+
switch (format.action) {
|
|
330
|
+
case 'copy':
|
|
331
|
+
return (
|
|
332
|
+
<Link className="memori-artifact-action-icon" />
|
|
333
|
+
);
|
|
334
|
+
case 'download':
|
|
335
|
+
return (
|
|
336
|
+
<Download className="memori-artifact-action-icon" />
|
|
337
|
+
);
|
|
338
|
+
case 'print':
|
|
339
|
+
case 'pdf':
|
|
340
|
+
return (
|
|
341
|
+
<PrintIcon className="memori-artifact-action-icon" />
|
|
342
|
+
);
|
|
343
|
+
default:
|
|
344
|
+
return (
|
|
345
|
+
<Link className="memori-artifact-action-icon" />
|
|
346
|
+
);
|
|
353
347
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
{
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
return (
|
|
351
|
+
<Button
|
|
352
|
+
key={format.id}
|
|
353
|
+
onClick={() => handleCopyFormat(format)}
|
|
354
|
+
disabled={
|
|
355
|
+
copyState.loading &&
|
|
356
|
+
copyState.activeFormat === format.id
|
|
357
|
+
}
|
|
358
|
+
className="memori-artifact-action-btn"
|
|
359
|
+
ghost
|
|
360
|
+
icon={getIcon()}
|
|
361
|
+
title={format.label}
|
|
362
|
+
>
|
|
363
|
+
<span className="memori-artifact-action-text">
|
|
364
|
+
{format.label}
|
|
365
|
+
</span>
|
|
366
|
+
</Button>
|
|
367
|
+
);
|
|
368
|
+
})}
|
|
365
369
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
{
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
370
|
+
{/* External open action (not from hook) */}
|
|
371
|
+
<Button
|
|
372
|
+
onClick={() => handleOpenExternal(state.currentArtifact ?? {
|
|
373
|
+
content: '',
|
|
374
|
+
mimeType: '',
|
|
375
|
+
title: '',
|
|
376
|
+
timestamp: new Date(),
|
|
377
|
+
size: 0,
|
|
378
|
+
id: '',
|
|
379
|
+
})}
|
|
380
|
+
disabled={false}
|
|
381
|
+
className="memori-artifact-action-btn"
|
|
382
|
+
ghost
|
|
383
|
+
icon={<Link className="memori-artifact-action-icon" />}
|
|
384
|
+
title={t('artifact.external') || 'External'}
|
|
385
|
+
>
|
|
386
|
+
<span className="memori-artifact-action-text">
|
|
387
|
+
{t('artifact.external') || 'External'}
|
|
388
|
+
</span>
|
|
389
|
+
</Button>
|
|
390
|
+
</div>
|
|
391
|
+
</Menu.Items>
|
|
392
|
+
</Transition>
|
|
393
|
+
</Menu>
|
|
383
394
|
</>
|
|
384
395
|
)}
|
|
385
396
|
|
|
@@ -25,14 +25,19 @@ const ArtifactHandler: React.FC<ArtifactHandlerProps> = ({
|
|
|
25
25
|
// Auto-open artifacts when detected in new messages
|
|
26
26
|
useEffect(() => {
|
|
27
27
|
const messageText = message.translatedText || message.text || '';
|
|
28
|
-
if (
|
|
28
|
+
if (messageText.length > 0) {
|
|
29
29
|
const artifacts = detectArtifacts(messageText);
|
|
30
30
|
|
|
31
31
|
if (artifacts.length > 0) {
|
|
32
|
-
|
|
33
|
-
openArtifact(artifacts[0]);
|
|
32
|
+
if(isChatlogPanel){
|
|
33
|
+
// openArtifact(artifacts[0]);
|
|
34
34
|
setCurrentArtifact(artifacts[0]);
|
|
35
|
-
}
|
|
35
|
+
} else {
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
openArtifact(artifacts[0]);
|
|
38
|
+
setCurrentArtifact(artifacts[0]);
|
|
39
|
+
}, 100);
|
|
40
|
+
}
|
|
36
41
|
}
|
|
37
42
|
}
|
|
38
43
|
}, [message]);
|
package/src/helpers/utils.ts
CHANGED
|
@@ -68,6 +68,27 @@ export const isAndroid = (): boolean => {
|
|
|
68
68
|
return isAndroid;
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
+
export const isSafari = (): boolean => {
|
|
72
|
+
if (typeof navigator === 'undefined') return false;
|
|
73
|
+
|
|
74
|
+
const userAgent = navigator.userAgent;
|
|
75
|
+
const isSafariUA = userAgent.includes('Safari') && !userAgent.includes('Chrome');
|
|
76
|
+
const isWebKit = 'WebKit' in window && !('Chrome' in window);
|
|
77
|
+
|
|
78
|
+
return isSafariUA || isWebKit;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const isSafariIOS = (): boolean => {
|
|
82
|
+
if (typeof navigator === 'undefined') return false;
|
|
83
|
+
|
|
84
|
+
const userAgent = navigator.userAgent;
|
|
85
|
+
return (
|
|
86
|
+
userAgent.includes('Safari') &&
|
|
87
|
+
!userAgent.includes('Chrome') &&
|
|
88
|
+
/iPad|iPhone|iPod/.test(userAgent)
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
71
92
|
export const pwdRegEx =
|
|
72
93
|
// eslint-disable-next-line no-useless-escape
|
|
73
94
|
/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$_:;|,~+=\{\}\[\]%^&*-]).{8,}$/;
|
package/src/locales/de.json
CHANGED
|
@@ -224,7 +224,8 @@
|
|
|
224
224
|
"copyWithoutSyntaxHighlighting": "Ohne Syntaxhervorhebung kopieren",
|
|
225
225
|
"copyTextContent": "Textinhalt kopieren",
|
|
226
226
|
"pdfExportNotSupported": "PDF-Export wird in diesem Browser nicht unterstützt",
|
|
227
|
-
"popupBlocked": "Popup blockiert! Bitte aktivieren Sie Popups zum Drucken."
|
|
227
|
+
"popupBlocked": "Popup blockiert! Bitte aktivieren Sie Popups zum Drucken.",
|
|
228
|
+
"safariPdfInstructions": "PDF-Export in neuem Fenster geöffnet. Bitte verwenden Sie Cmd+P (Mac) oder Strg+P (Windows) zum Drucken und als PDF speichern."
|
|
228
229
|
},
|
|
229
230
|
"upload": {
|
|
230
231
|
"loginRequired": "Login erforderlich",
|
package/src/locales/en.json
CHANGED
|
@@ -235,7 +235,8 @@
|
|
|
235
235
|
"copyWithoutSyntaxHighlighting": "Copy without syntax highlighting",
|
|
236
236
|
"copyTextContent": "Copy text content",
|
|
237
237
|
"pdfExportNotSupported": "PDF export is not supported in this browser",
|
|
238
|
-
"popupBlocked": "Popup blocked! Please enable popups to print."
|
|
238
|
+
"popupBlocked": "Popup blocked! Please enable popups to print.",
|
|
239
|
+
"safariPdfInstructions": "PDF export opened in new window. Please use Cmd+P (Mac) or Ctrl+P (Windows) to print and save as PDF."
|
|
239
240
|
},
|
|
240
241
|
"upload": {
|
|
241
242
|
"loginRequired": "Login required",
|
package/src/locales/es.json
CHANGED
|
@@ -224,7 +224,8 @@
|
|
|
224
224
|
"copyWithoutSyntaxHighlighting": "Copiar sin resaltado de sintaxis",
|
|
225
225
|
"copyTextContent": "Copiar contenido de texto",
|
|
226
226
|
"pdfExportNotSupported": "La exportación PDF no es compatible con este navegador",
|
|
227
|
-
"popupBlocked": "¡Popup bloqueado! Por favor, habilita los popups para imprimir."
|
|
227
|
+
"popupBlocked": "¡Popup bloqueado! Por favor, habilita los popups para imprimir.",
|
|
228
|
+
"safariPdfInstructions": "Exportación PDF abierta en nueva ventana. Por favor, usa Cmd+P (Mac) o Ctrl+P (Windows) para imprimir y guardar como PDF."
|
|
228
229
|
},
|
|
229
230
|
"upload": {
|
|
230
231
|
"loginRequired": "Connexion requise",
|
package/src/locales/fr.json
CHANGED
|
@@ -233,7 +233,8 @@
|
|
|
233
233
|
"copyWithoutSyntaxHighlighting": "Copier sans coloration syntaxique",
|
|
234
234
|
"copyTextContent": "Copier le contenu texte",
|
|
235
235
|
"pdfExportNotSupported": "L'exportation PDF n'est pas prise en charge dans ce navigateur",
|
|
236
|
-
"popupBlocked": "Popup bloqué ! Veuillez activer les popups pour imprimer."
|
|
236
|
+
"popupBlocked": "Popup bloqué ! Veuillez activer les popups pour imprimer.",
|
|
237
|
+
"safariPdfInstructions": "Export PDF ouvert dans une nouvelle fenêtre. Veuillez utiliser Cmd+P (Mac) ou Ctrl+P (Windows) pour imprimer et sauvegarder en PDF."
|
|
237
238
|
},
|
|
238
239
|
"upload": {
|
|
239
240
|
"loginRequired": "Connexion requise",
|
package/src/locales/it.json
CHANGED
|
@@ -238,7 +238,8 @@
|
|
|
238
238
|
"copyWithoutSyntaxHighlighting": "Copia senza evidenziazione sintassi",
|
|
239
239
|
"copyTextContent": "Copia contenuto testo",
|
|
240
240
|
"pdfExportNotSupported": "L'esportazione PDF non è supportata in questo browser",
|
|
241
|
-
"popupBlocked": "Popup bloccato! Abilita i popup per stampare."
|
|
241
|
+
"popupBlocked": "Popup bloccato! Abilita i popup per stampare.",
|
|
242
|
+
"safariPdfInstructions": "Esportazione PDF aperta in una nuova finestra. Usa Cmd+P (Mac) o Ctrl+P (Windows) per stampare e salvare come PDF."
|
|
242
243
|
|
|
243
244
|
},
|
|
244
245
|
"media": {
|