From 0039f4c155674333a28620c557a015ac93794d4b Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 4 Jan 2026 17:25:56 +0200 Subject: [PATCH] feat(pdfjs): replace blob instead of creating a new revision every time --- apps/client/src/widgets/react/hooks.tsx | 8 +++++--- apps/client/src/widgets/type_widgets/file/Pdf.tsx | 3 ++- apps/server/src/routes/api/files.ts | 4 +++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx index 17efcc275f..d0031fe071 100644 --- a/apps/client/src/widgets/react/hooks.tsx +++ b/apps/client/src/widgets/react/hooks.tsx @@ -170,7 +170,7 @@ export function useEditorSpacedUpdate({ note, noteType, noteContext, getData, on return spacedUpdate; } -export function useBlobEditorSpacedUpdate({ note, noteType, noteContext, getData, onContentChange, dataSaved, updateInterval }: { +export function useBlobEditorSpacedUpdate({ note, noteType, noteContext, getData, onContentChange, dataSaved, updateInterval, replaceWithoutRevision }: { noteType: NoteType; note: FNote, noteContext: NoteContext | null | undefined, @@ -178,6 +178,8 @@ export function useBlobEditorSpacedUpdate({ note, noteType, noteContext, getData onContentChange: (newBlob: FBlob) => void, dataSaved?: (savedData: Blob) => void, updateInterval?: number; + /** If set to true, then the blob is replaced directly without saving a revision before. */ + replaceWithoutRevision?: boolean; }) { const parentComponent = useContext(ParentComponent); const blob = useNoteBlob(note, parentComponent?.componentId); @@ -190,10 +192,10 @@ export function useBlobEditorSpacedUpdate({ note, noteType, noteContext, getData if (data === undefined || note.type !== noteType) return; protected_session_holder.touchProtectedSessionIfNecessary(note); - await server.upload(`notes/${note.noteId}/file`, new File([ data ], note.title, { type: note.mime }), parentComponent?.componentId); + await server.upload(`notes/${note.noteId}/file?replace=${replaceWithoutRevision ? "1" : "0"}`, new File([ data ], note.title, { type: note.mime }), parentComponent?.componentId); dataSaved?.(data); }; - }, [ note, getData, dataSaved, noteType, parentComponent ]); + }, [ note, getData, dataSaved, noteType, parentComponent, replaceWithoutRevision ]); const stateCallback = useCallback((state) => { noteContext?.setContextData("saveState", { state diff --git a/apps/client/src/widgets/type_widgets/file/Pdf.tsx b/apps/client/src/widgets/type_widgets/file/Pdf.tsx index d7a09b35a4..7acbc6d6cf 100644 --- a/apps/client/src/widgets/type_widgets/file/Pdf.tsx +++ b/apps/client/src/widgets/type_widgets/file/Pdf.tsx @@ -43,7 +43,8 @@ export default function PdfPreview({ note, blob, componentId, noteContext }: { if (iframeRef.current?.contentWindow) { iframeRef.current.contentWindow.location.reload(); } - } + }, + replaceWithoutRevision: true }); useEffect(() => { diff --git a/apps/server/src/routes/api/files.ts b/apps/server/src/routes/api/files.ts index 5be826fba6..4a6e17382b 100644 --- a/apps/server/src/routes/api/files.ts +++ b/apps/server/src/routes/api/files.ts @@ -28,7 +28,9 @@ function updateFile(req: Request) { }; } - note.saveRevision(); + if (req.query.replace !== "1") { + note.saveRevision(); + } note.mime = file.mimetype.toLowerCase(); note.save();