Skip to content

Commit eb3f7f5

Browse files
committed
feat(pptx): replace viewer with custom preview
1 parent 773720e commit eb3f7f5

51 files changed

Lines changed: 22221 additions & 329 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/sim/app/(auth)/signup/signup-form.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ function SignupFormContent({ githubAvailable, googleAvailable, isProduction }: S
271271
...(token ? { 'x-captcha-response': token } : {}),
272272
},
273273
onError: (ctx) => {
274-
logger.error('Signup error:', ctx.error)
274+
logger.warn('Signup error:', ctx.error)
275275
const errorMessage: string[] = ['Failed to create account']
276276

277277
let errorCode = 'unknown'

apps/sim/app/api/files/parse/route.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import { Buffer } from 'buffer'
1+
import { Buffer, isUtf8 } from 'buffer'
22
import { createHash } from 'crypto'
33
import fsPromises, { readFile } from 'fs/promises'
44
import path from 'path'
55
import { createLogger } from '@sim/logger'
6-
import binaryExtensionsList from 'binary-extensions'
76
import { type NextRequest, NextResponse } from 'next/server'
87
import { fileParseContract } from '@/lib/api/contracts/storage-transfer'
98
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -40,6 +39,10 @@ const logger = createLogger('FilesParseAPI')
4039
const MAX_DOWNLOAD_SIZE_BYTES = 100 * 1024 * 1024 // 100 MB
4140
const DOWNLOAD_TIMEOUT_MS = 30000 // 30 seconds
4241

42+
function isLikelyTextBuffer(fileBuffer: Buffer): boolean {
43+
return isUtf8(fileBuffer) && !fileBuffer.includes(0)
44+
}
45+
4346
interface ExecutionContext {
4447
workspaceId: string
4548
workflowId: string
@@ -863,10 +866,9 @@ function handleGenericBuffer(
863866
extension: string,
864867
fileType?: string
865868
): ParseResult {
866-
const isBinary = binaryExtensionsList.includes(extension)
867-
const content = isBinary
868-
? `[Binary ${extension.toUpperCase()} file - ${fileBuffer.length} bytes]`
869-
: fileBuffer.toString('utf-8')
869+
const content = isLikelyTextBuffer(fileBuffer)
870+
? fileBuffer.toString('utf-8')
871+
: `[Binary ${extension.toUpperCase()} file - ${fileBuffer.length} bytes]`
870872

871873
return {
872874
success: true,

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

Lines changed: 40 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
44
import { createLogger } from '@sim/logger'
5-
import { ChevronLeft, ChevronRight, ZoomIn, ZoomOut } from 'lucide-react'
65
import { pdfjs, Document as ReactPdfDocument, Page as ReactPdfPage } from 'react-pdf'
76
import 'react-pdf/dist/Page/TextLayer.css'
8-
import { Button, Skeleton } from '@/components/emcn'
7+
import { Skeleton } from '@/components/emcn'
8+
import { PreviewToolbar } from '@/app/workspace/[workspaceId]/files/components/file-viewer/preview-toolbar'
99

1010
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
1111
'pdfjs-dist/build/pdf.worker.min.mjs',
@@ -172,81 +172,44 @@ export const PdfViewerCore = memo(function PdfViewerCore({ source, filename }: P
172172
return (
173173
<div className='flex flex-1 flex-col overflow-hidden'>
174174
{pageCount > 0 && !loadError && (
175-
<div className='flex shrink-0 items-center justify-between border-[var(--border)] border-b bg-[var(--surface-1)] px-3 py-1.5'>
176-
<div className='flex items-center gap-1'>
177-
<Button
178-
variant='ghost'
179-
size='sm'
180-
onClick={() => {
181-
const prev = Math.max(1, currentPage - 1)
182-
setCurrentPage(prev)
183-
scrollToPage(prev)
184-
}}
185-
disabled={currentPage <= 1}
186-
className='h-6 w-6 p-0 text-[var(--text-icon)]'
187-
aria-label='Previous page'
188-
>
189-
<ChevronLeft className='h-[14px] w-[14px]' />
190-
</Button>
191-
<span className='min-w-[5rem] text-center text-[12px] text-[var(--text-secondary)]'>
192-
{currentPage} / {pageCount}
193-
</span>
194-
<Button
195-
variant='ghost'
196-
size='sm'
197-
onClick={() => {
198-
const next = Math.min(pageCount, currentPage + 1)
199-
setCurrentPage(next)
200-
scrollToPage(next)
201-
}}
202-
disabled={currentPage >= pageCount}
203-
className='h-6 w-6 p-0 text-[var(--text-icon)]'
204-
aria-label='Next page'
205-
>
206-
<ChevronRight className='h-[14px] w-[14px]' />
207-
</Button>
208-
</div>
209-
210-
<div className='flex items-center gap-1'>
211-
<Button
212-
variant='ghost'
213-
size='sm'
214-
onClick={() => {
215-
const c = containerRef.current
216-
applyZoomAt(
217-
Math.max(PDF_ZOOM_MIN, zoomRef.current / PDF_ZOOM_STEP),
218-
c ? c.clientWidth / 2 : 0,
219-
c ? c.clientHeight / 2 : 0
220-
)
221-
}}
222-
disabled={displayZoom <= PDF_ZOOM_MIN}
223-
className='h-6 w-6 p-0 text-[var(--text-icon)]'
224-
aria-label='Zoom out'
225-
>
226-
<ZoomOut className='h-[14px] w-[14px]' />
227-
</Button>
228-
<span className='min-w-[3rem] text-center text-[12px] text-[var(--text-secondary)]'>
229-
{Math.round(displayZoom * 100)}%
230-
</span>
231-
<Button
232-
variant='ghost'
233-
size='sm'
234-
onClick={() => {
235-
const c = containerRef.current
236-
applyZoomAt(
237-
Math.min(PDF_ZOOM_MAX, zoomRef.current * PDF_ZOOM_STEP),
238-
c ? c.clientWidth / 2 : 0,
239-
c ? c.clientHeight / 2 : 0
240-
)
241-
}}
242-
disabled={displayZoom >= PDF_ZOOM_MAX}
243-
className='h-6 w-6 p-0 text-[var(--text-icon)]'
244-
aria-label='Zoom in'
245-
>
246-
<ZoomIn className='h-[14px] w-[14px]' />
247-
</Button>
248-
</div>
249-
</div>
175+
<PreviewToolbar
176+
navigation={{
177+
current: currentPage,
178+
total: pageCount,
179+
label: 'page',
180+
onPrevious: () => {
181+
const prev = Math.max(1, currentPage - 1)
182+
setCurrentPage(prev)
183+
scrollToPage(prev)
184+
},
185+
onNext: () => {
186+
const next = Math.min(pageCount, currentPage + 1)
187+
setCurrentPage(next)
188+
scrollToPage(next)
189+
},
190+
}}
191+
zoom={{
192+
label: `${Math.round(displayZoom * 100)}%`,
193+
canZoomOut: displayZoom > PDF_ZOOM_MIN,
194+
canZoomIn: displayZoom < PDF_ZOOM_MAX,
195+
onZoomOut: () => {
196+
const c = containerRef.current
197+
applyZoomAt(
198+
Math.max(PDF_ZOOM_MIN, zoomRef.current / PDF_ZOOM_STEP),
199+
c ? c.clientWidth / 2 : 0,
200+
c ? c.clientHeight / 2 : 0
201+
)
202+
},
203+
onZoomIn: () => {
204+
const c = containerRef.current
205+
applyZoomAt(
206+
Math.min(PDF_ZOOM_MAX, zoomRef.current * PDF_ZOOM_STEP),
207+
c ? c.clientWidth / 2 : 0,
208+
c ? c.clientHeight / 2 : 0
209+
)
210+
},
211+
}}
212+
/>
250213
)}
251214

252215
<div

0 commit comments

Comments
 (0)