diff --git a/src/lib/components/assets/shared/asset-preview.svelte b/src/lib/components/assets/shared/asset-preview.svelte index 15ffaaec..4721cc38 100644 --- a/src/lib/components/assets/shared/asset-preview.svelte +++ b/src/lib/components/assets/shared/asset-preview.svelte @@ -106,7 +106,7 @@ * Update the {@link loaded} state when the media is loaded. */ const checkLoaded = async () => { - if (!mediaElement) { + if (!mediaElement || !src) { return; } @@ -133,10 +133,16 @@ } loaded = true; + + // Revoke the thumbnail blob URL + if (asset && isThumbnail && src?.startsWith('blob:')) { + URL.revokeObjectURL(src); + } }; $: { void mediaElement; + void src; checkLoaded(); } diff --git a/src/lib/services/assets/index.js b/src/lib/services/assets/index.js index a2782e91..b8a76be5 100644 --- a/src/lib/services/assets/index.js +++ b/src/lib/services/assets/index.js @@ -205,11 +205,6 @@ let thumbnailDB = undefined; * @returns {Promise} Thumbnail blob URL. */ export const getAssetThumbnailURL = async (asset) => { - // Use a cached image if available - if (asset.thumbnailURL) { - return asset.thumbnailURL; - } - const isPDF = asset.name.endsWith('.pdf'); if (!(['image', 'video'].includes(asset.kind) || isPDF)) { @@ -235,12 +230,7 @@ export const getAssetThumbnailURL = async (asset) => { await thumbnailDB?.set(asset.sha, thumbnailBlob); } - const thumbnailURL = URL.createObjectURL(thumbnailBlob); - - // Cache the image as blob URL for later use - asset.thumbnailURL = thumbnailURL; - - return thumbnailURL; + return URL.createObjectURL(thumbnailBlob); }; /** diff --git a/src/lib/services/utils/media.js b/src/lib/services/utils/media.js index 64abc6d5..a487df57 100644 --- a/src/lib/services/utils/media.js +++ b/src/lib/services/utils/media.js @@ -200,12 +200,13 @@ export const renderPDF = async ( } } + const blobURL = URL.createObjectURL(blob); const canvas = new OffscreenCanvas(512, 512); const context = /** @type {OffscreenCanvasRenderingContext2D} */ (canvas.getContext('2d')); try { const pdfDocument = await pdfjs.getDocument({ - url: URL.createObjectURL(blob), + url: blobURL, isEvalSupported: false, disableAutoFetch: true, }).promise; @@ -219,6 +220,8 @@ export const renderPDF = async ( canvasContext: context, viewport: scale === 1 ? viewport : pdfPage.getViewport({ scale }), }).promise; + + URL.revokeObjectURL(blobURL); } catch { throw new Error('Failed to render PDF'); } diff --git a/src/lib/typedefs.js b/src/lib/typedefs.js index d098f1e9..fcfc5dd0 100644 --- a/src/lib/typedefs.js +++ b/src/lib/typedefs.js @@ -900,8 +900,6 @@ * @property {File} [file] - File object. Local backend only. * @property {string} [blobURL] - Blob URL for the asset. It’s a temporary URL for a remote file * being fetched or a local file being uploaded. Or `undefined` if the URL is not generated yet. - * @property {string} [thumbnailURL] - Thumbnail Blob URL for the asset. Used to cache a rendered - * thumbnail of a PDF document. * @property {string} name - File name. * @property {string} path - File path. * @property {string} sha - SHA-1 hash for the file.