Skip to content

Commit 8abb884

Browse files
committed
Fix ppt load
1 parent 704d06f commit 8abb884

File tree

2 files changed

+66
-53
lines changed

2 files changed

+66
-53
lines changed

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

Lines changed: 62 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,39 @@ function ImagePreview({ file }: { file: WorkspaceFileRecord }) {
439439
)
440440
}
441441

442+
const pptxSlideCache = new Map<string, string[]>()
443+
444+
function pptxCacheKey(fileId: string, dataUpdatedAt: number): string {
445+
return `${fileId}:${dataUpdatedAt}`
446+
}
447+
448+
async function renderPptxSlides(
449+
data: Uint8Array,
450+
onSlide: (src: string, index: number) => void,
451+
cancelled: () => boolean
452+
): Promise<void> {
453+
const { PPTXViewer } = await import('pptxviewjs')
454+
if (cancelled()) return
455+
456+
const W = 1920
457+
const H = 1080
458+
459+
const canvas = document.createElement('canvas')
460+
canvas.width = W
461+
canvas.height = H
462+
const viewer = new PPTXViewer({ canvas })
463+
await viewer.loadFile(data)
464+
const count = viewer.getSlideCount()
465+
if (cancelled() || count === 0) return
466+
467+
for (let i = 0; i < count; i++) {
468+
if (cancelled()) break
469+
if (i === 0) await viewer.render()
470+
else await viewer.goToSlide(i)
471+
onSlide(canvas.toDataURL('image/jpeg', 0.85), i)
472+
}
473+
}
474+
442475
function PptxPreview({
443476
file,
444477
workspaceId,
@@ -455,11 +488,19 @@ function PptxPreview({
455488
dataUpdatedAt,
456489
} = useWorkspaceFileBinary(workspaceId, file.id, file.key)
457490

458-
const [slides, setSlides] = useState<string[]>([])
491+
const cacheKey = pptxCacheKey(file.id, dataUpdatedAt)
492+
const cached = pptxSlideCache.get(cacheKey)
493+
494+
const [slides, setSlides] = useState<string[]>(cached ?? [])
459495
const [rendering, setRendering] = useState(false)
460496
const [renderError, setRenderError] = useState<string | null>(null)
461497

462498
useEffect(() => {
499+
if (cached) {
500+
setSlides(cached)
501+
return
502+
}
503+
463504
let cancelled = false
464505

465506
async function render() {
@@ -474,61 +515,33 @@ function PptxPreview({
474515
await fn(pptx)
475516
const arrayBuffer = (await pptx.write({ outputType: 'arraybuffer' })) as ArrayBuffer
476517
if (cancelled) return
477-
const { PPTXViewer } = await import('pptxviewjs')
478518
const data = new Uint8Array(arrayBuffer)
479-
const probe = document.createElement('canvas')
480-
const probeViewer = new PPTXViewer({ canvas: probe })
481-
await probeViewer.loadFile(data)
482-
const count = probeViewer.getSlideCount()
483-
if (cancelled || count === 0) return
484-
const dpr = window.devicePixelRatio || 1
485-
const W = Math.round(1920 * dpr)
486-
const H = Math.round(1080 * dpr)
487519
const images: string[] = []
488-
for (let i = 0; i < count; i++) {
489-
if (cancelled) break
490-
const canvas = document.createElement('canvas')
491-
canvas.width = W
492-
canvas.height = H
493-
const viewer = new PPTXViewer({ canvas })
494-
await viewer.loadFile(data)
495-
if (i > 0) await viewer.goToSlide(i)
496-
else await viewer.render()
497-
images.push(canvas.toDataURL('image/png'))
498-
}
499-
if (!cancelled) setSlides(images)
520+
await renderPptxSlides(
521+
data,
522+
(src) => {
523+
images.push(src)
524+
if (!cancelled) setSlides([...images])
525+
},
526+
() => cancelled
527+
)
500528
return
501529
}
502530

503531
if (!fileData) return
504-
const { PPTXViewer } = await import('pptxviewjs')
505-
if (cancelled) return
506-
507-
const data = new Uint8Array(fileData!)
508-
const probe = document.createElement('canvas')
509-
const probeViewer = new PPTXViewer({ canvas: probe })
510-
await probeViewer.loadFile(data)
511-
const count = probeViewer.getSlideCount()
512-
if (cancelled || count === 0) return
513-
514-
const dpr = window.devicePixelRatio || 1
515-
const W = Math.round(1920 * dpr)
516-
const H = Math.round(1080 * dpr)
532+
const data = new Uint8Array(fileData)
517533
const images: string[] = []
518-
519-
for (let i = 0; i < count; i++) {
520-
if (cancelled) break
521-
const canvas = document.createElement('canvas')
522-
canvas.width = W
523-
canvas.height = H
524-
const viewer = new PPTXViewer({ canvas })
525-
await viewer.loadFile(data)
526-
if (i > 0) await viewer.goToSlide(i)
527-
else await viewer.render()
528-
images.push(canvas.toDataURL('image/png'))
534+
await renderPptxSlides(
535+
data,
536+
(src) => {
537+
images.push(src)
538+
if (!cancelled) setSlides([...images])
539+
},
540+
() => cancelled
541+
)
542+
if (!cancelled && images.length > 0) {
543+
pptxSlideCache.set(cacheKey, images)
529544
}
530-
531-
if (!cancelled) setSlides(images)
532545
} catch (err) {
533546
if (!cancelled) {
534547
const msg = err instanceof Error ? err.message : 'Failed to render presentation'
@@ -544,7 +557,7 @@ function PptxPreview({
544557
return () => {
545558
cancelled = true
546559
}
547-
}, [fileData, dataUpdatedAt, streamingContent])
560+
}, [fileData, dataUpdatedAt, streamingContent, cacheKey, cached])
548561

549562
const error = fetchError
550563
? fetchError instanceof Error

apps/sim/hooks/queries/workspace-files.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ async function fetchWorkspaceFileBinary(
106106
key: string,
107107
signal?: AbortSignal
108108
): Promise<ArrayBuffer> {
109-
const serveUrl = `/api/files/serve/${encodeURIComponent(key)}?context=workspace&t=${Date.now()}`
110-
const response = await fetch(serveUrl, { signal, cache: 'no-store' })
109+
const serveUrl = `/api/files/serve/${encodeURIComponent(key)}?context=workspace`
110+
const response = await fetch(serveUrl, { signal })
111111
if (!response.ok) throw new Error('Failed to fetch file content')
112112
return response.arrayBuffer()
113113
}
@@ -122,8 +122,8 @@ export function useWorkspaceFileBinary(workspaceId: string, fileId: string, key:
122122
queryKey: workspaceFilesKeys.content(workspaceId, fileId, 'binary'),
123123
queryFn: ({ signal }) => fetchWorkspaceFileBinary(key, signal),
124124
enabled: !!workspaceId && !!fileId && !!key,
125-
staleTime: 30 * 1000,
126-
refetchOnWindowFocus: 'always',
125+
staleTime: 5 * 60 * 1000,
126+
refetchOnWindowFocus: false,
127127
})
128128
}
129129

0 commit comments

Comments
 (0)