diff --git a/src/components/Elements/ShareModal/ShareModal.jsx b/src/components/Elements/ShareModal/ShareModal.jsx index 2491e82b..8a673585 100644 --- a/src/components/Elements/ShareModal/ShareModal.jsx +++ b/src/components/Elements/ShareModal/ShareModal.jsx @@ -127,4 +127,4 @@ function ShareModal({ modalClose, data }) { const MemoizedSharemodal = memo(ShareModal); -export { MemoizedSharemodal as default, MemoizedSharemodal as ShareModal }; +export { MemoizedSharemodal as default, MemoizedSharemodal as ShareModal }; \ No newline at end of file diff --git a/src/features/background/api/videoCheck.js b/src/features/background/api/videoCheck.js index 8b6d44fa..8510b419 100644 --- a/src/features/background/api/videoCheck.js +++ b/src/features/background/api/videoCheck.js @@ -1,13 +1,19 @@ /** - * If the URL starts with `data:video/` or ends with `.mp4`, `.webm`, or `.ogg`, then it's a video. - * @param url - The URL of the file to be checked. - * @returns A function that takes a url and returns a boolean. + * Checks if the given URL or MIME type represents a video file. + * Supports both URLs (data:video/, .mp4, .webm, .ogg) and MIME types (video/mp4, video/webm, video/ogg). + * @param urlOrMimeType - The URL or MIME type to check. + * @returns true if it's a video, false otherwise. */ -export default function videoCheck(url) { +export default function videoCheck(urlOrMimeType) { + if (!urlOrMimeType) { + return false; + } + return ( - url.startsWith('data:video/') || - url.endsWith('.mp4') || - url.endsWith('.webm') || - url.endsWith('.ogg') + urlOrMimeType.startsWith('data:video/') || + urlOrMimeType.startsWith('video/') || + urlOrMimeType.endsWith('.mp4') || + urlOrMimeType.endsWith('.webm') || + urlOrMimeType.endsWith('.ogg') ); } diff --git a/src/features/background/options/Custom.jsx b/src/features/background/options/Custom.jsx index 200f99dc..f5f9201a 100644 --- a/src/features/background/options/Custom.jsx +++ b/src/features/background/options/Custom.jsx @@ -33,6 +33,7 @@ import { calculateStorageSize, calculateTotalStorageSize, formatBytes, + extractVideoThumbnail, } from 'utils/imageMetadata'; import { generateBlurHashDataUrl } from '../api/blurHash'; @@ -132,6 +133,7 @@ const CustomSettings = memo(() => { fileSize: metadata.fileSize, folder: metadata.folder || '', blurHash: metadata.blurHash, + thumbnail: metadata.thumbnail || null, }; await addBackground(backgroundData); @@ -189,17 +191,37 @@ const CustomSettings = memo(() => { const reader = new FileReader(); return new Promise((resolve, reject) => { - reader.onloadend = () => { - resolve({ - dataUrl: reader.result, - metadata: { - name: getFileName(file, customBackground.length), - dimensions: null, - fileSize: file.size, - folder: folderName, - blurHash: null, - }, - }); + reader.onloadend = async () => { + try { + // Extract thumbnail and dimensions from video + const { thumbnail, dimensions } = await extractVideoThumbnail(reader.result); + + resolve({ + dataUrl: reader.result, + metadata: { + name: getFileName(file, customBackground.length), + dimensions, + fileSize: file.size, + folder: folderName, + blurHash: null, + thumbnail, + }, + }); + } catch (error) { + console.warn('Could not extract video thumbnail:', error); + // Fallback to no thumbnail if extraction fails + resolve({ + dataUrl: reader.result, + metadata: { + name: getFileName(file, customBackground.length), + dimensions: null, + fileSize: file.size, + folder: folderName, + blurHash: null, + thumbnail: null, + }, + }); + } }; reader.onerror = reject; reader.readAsDataURL(file); @@ -625,7 +647,7 @@ const CustomSettings = memo(() => { )} - · + {customBackground.length > 0 && ·} {selectedImages.size > 0 ? ( <> {selectedImages.size} selected @@ -757,9 +779,39 @@ const CustomSettings = memo(() => { ) : null; })()} {isVideo ? ( -