From 332e731083a289d00ec20840dd3a2ec7baf898a2 Mon Sep 17 00:00:00 2001 From: waleed Date: Sat, 2 May 2026 13:45:34 -0700 Subject: [PATCH 1/3] feat(files): zoom controls for inline mermaid and images in markdown, fit zoom upscaling --- .../components/file-viewer/preview-panel.tsx | 32 ++++++++++++++----- .../file-viewer/zoomable-preview.tsx | 2 +- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx index be5e581418f..b3c0b053887 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx @@ -462,10 +462,16 @@ function resolveSimFileUrl(src: string | undefined): string | undefined { try { const parsed = new URL(src, 'http://placeholder') if (parsed.origin !== 'http://placeholder') return src - const [, seg1, , seg3, fileId] = parsed.pathname.split('/') + const parts = parsed.pathname.split('/') + const [, seg1, , seg3, fileId] = parts if (seg1 === 'workspace' && seg3 === 'files' && fileId) { return `/api/files/view/${fileId}` } + // files/by-id/{uuid}/content — canonical VFS path used by Mothership skills; treat as embed URL + const [, s1, s2, byIdFileId, s4] = parts + if (s1 === 'files' && s2 === 'by-id' && byIdFileId && s4 === 'content') { + return `/api/files/view/${byIdFileId}` + } } catch { // not a parseable URL } @@ -476,7 +482,14 @@ const STATIC_MARKDOWN_COMPONENTS = { pre: ({ children }: { children?: React.ReactNode }) => <>{children}, 'mermaid-diagram': ({ definition }: { definition?: string }) => { const isStreaming = useContext(MermaidStreamingCtx) - return + return ( + + ) }, p: ({ children }: { children?: React.ReactNode }) => (

@@ -613,12 +626,15 @@ const STATIC_MARKDOWN_COMPONENTS = { img: ({ src, alt }: React.ImgHTMLAttributes) => { const resolvedSrc = resolveSimFileUrl(typeof src === 'string' ? src : undefined) return ( - {alt + + {alt + ) }, table: ({ children }: { children?: React.ReactNode }) => ( diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/zoomable-preview.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/zoomable-preview.tsx index bcdb3aa9e06..151b4325a8d 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/zoomable-preview.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/zoomable-preview.tsx @@ -47,7 +47,7 @@ function getFitZoom(container: Size, content: Size): number { const availableWidth = Math.max(1, container.width - FIT_PADDING) const availableHeight = Math.max(1, container.height - FIT_PADDING) - return clampZoom(Math.min(1, availableWidth / content.width, availableHeight / content.height)) + return clampZoom(Math.min(availableWidth / content.width, availableHeight / content.height)) } function clampOffset(container: Size, content: Size, offset: Offset, zoom: number): Offset { From cd5f27e4651e34d6fc36496afa79023d909644a8 Mon Sep 17 00:00:00 2001 From: waleed Date: Sat, 2 May 2026 13:50:53 -0700 Subject: [PATCH 2/3] revert(files): remove vfs url rewriting, keep zoom controls only --- .../files/components/file-viewer/preview-panel.tsx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx index b3c0b053887..d021698b928 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx @@ -462,16 +462,10 @@ function resolveSimFileUrl(src: string | undefined): string | undefined { try { const parsed = new URL(src, 'http://placeholder') if (parsed.origin !== 'http://placeholder') return src - const parts = parsed.pathname.split('/') - const [, seg1, , seg3, fileId] = parts + const [, seg1, , seg3, fileId] = parsed.pathname.split('/') if (seg1 === 'workspace' && seg3 === 'files' && fileId) { return `/api/files/view/${fileId}` } - // files/by-id/{uuid}/content — canonical VFS path used by Mothership skills; treat as embed URL - const [, s1, s2, byIdFileId, s4] = parts - if (s1 === 'files' && s2 === 'by-id' && byIdFileId && s4 === 'content') { - return `/api/files/view/${byIdFileId}` - } } catch { // not a parseable URL } From c3d815144adfa50fe451e97ae14dc0d6a2115614 Mon Sep 17 00:00:00 2001 From: waleed Date: Sat, 2 May 2026 14:11:19 -0700 Subject: [PATCH 3/3] fix(files): use actual scale for raster images, add my-4 to mermaid zoom --- .../files/components/file-viewer/preview-panel.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx index d021698b928..86da6855104 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx @@ -481,7 +481,7 @@ const STATIC_MARKDOWN_COMPONENTS = { definition={definition ?? ''} isStreaming={isStreaming} zoomable - zoomClassName='h-[420px] rounded-lg' + zoomClassName='my-4 h-[420px] rounded-lg' /> ) }, @@ -620,7 +620,7 @@ const STATIC_MARKDOWN_COMPONENTS = { img: ({ src, alt }: React.ImgHTMLAttributes) => { const resolvedSrc = resolveSimFileUrl(typeof src === 'string' ? src : undefined) return ( - +