Skip to content

Commit cdbe2e4

Browse files
committed
feat(files): zoom controls for inline mermaid and images in markdown, fit zoom upscaling
1 parent a251e45 commit cdbe2e4

2 files changed

Lines changed: 25 additions & 9 deletions

File tree

apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -473,10 +473,16 @@ function resolveSimFileUrl(src: string | undefined): string | undefined {
473473
try {
474474
const parsed = new URL(src, 'http://placeholder')
475475
if (parsed.origin !== 'http://placeholder') return src
476-
const [, seg1, , seg3, fileId] = parsed.pathname.split('/')
476+
const parts = parsed.pathname.split('/')
477+
const [, seg1, , seg3, fileId] = parts
477478
if (seg1 === 'workspace' && seg3 === 'files' && fileId) {
478479
return `/api/files/view/${fileId}`
479480
}
481+
// files/by-id/{uuid}/content — canonical VFS path used by Mothership skills; treat as embed URL
482+
const [, s1, s2, byIdFileId, s4] = parts
483+
if (s1 === 'files' && s2 === 'by-id' && byIdFileId && s4 === 'content') {
484+
return `/api/files/view/${byIdFileId}`
485+
}
480486
} catch {
481487
// not a parseable URL
482488
}
@@ -495,7 +501,14 @@ const STATIC_MARKDOWN_COMPONENTS = {
495501
),
496502
'mermaid-diagram': ({ definition }: { definition?: string }) => {
497503
const isStreaming = useContext(MermaidStreamingCtx)
498-
return <MermaidDiagram definition={definition ?? ''} isStreaming={isStreaming} />
504+
return (
505+
<MermaidDiagram
506+
definition={definition ?? ''}
507+
isStreaming={isStreaming}
508+
zoomable
509+
zoomClassName='h-[420px] rounded-lg'
510+
/>
511+
)
499512
},
500513
p: ({ children }: { children?: React.ReactNode }) => (
501514
<p className='mb-3 break-words text-[14px] text-[var(--text-primary)] leading-[1.6] last:mb-0'>
@@ -619,12 +632,15 @@ const STATIC_MARKDOWN_COMPONENTS = {
619632
img: ({ src, alt }: React.ImgHTMLAttributes<HTMLImageElement>) => {
620633
const resolvedSrc = resolveSimFileUrl(typeof src === 'string' ? src : undefined)
621634
return (
622-
<img
623-
src={resolvedSrc}
624-
alt={alt ?? ''}
625-
className='my-3 max-w-full rounded-md'
626-
loading='lazy'
627-
/>
635+
<ZoomablePreview className='my-3 h-[360px] rounded-md' initialScale='fit'>
636+
<img
637+
src={resolvedSrc}
638+
alt={alt ?? ''}
639+
className='max-h-full max-w-full select-none object-contain'
640+
draggable={false}
641+
loading='lazy'
642+
/>
643+
</ZoomablePreview>
628644
)
629645
},
630646
table: ({ children }: { children?: React.ReactNode }) => (

apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/zoomable-preview.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ function getFitZoom(container: Size, content: Size): number {
4747

4848
const availableWidth = Math.max(1, container.width - FIT_PADDING)
4949
const availableHeight = Math.max(1, container.height - FIT_PADDING)
50-
return clampZoom(Math.min(1, availableWidth / content.width, availableHeight / content.height))
50+
return clampZoom(Math.min(availableWidth / content.width, availableHeight / content.height))
5151
}
5252

5353
function clampOffset(container: Size, content: Size, offset: Offset, zoom: number): Offset {

0 commit comments

Comments
 (0)