export const createThumbnail = async (file: File): Promise => { if (!file.type.startsWith('image/') && !file.type.startsWith('video/')) return null return new Promise((resolve, reject) => { const reader = new FileReader() reader.onload = function (event) { const thumbnailURL = event.target?.result as string if (file.type.startsWith('image/')) { const img = new Image() img.onload = function () { const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') if (!ctx) return resolve(null) const thumbnailWidth = 200 const scaleFactor = thumbnailWidth / img.width const thumbnailHeight = img.height * scaleFactor canvas.width = thumbnailWidth canvas.height = thumbnailHeight ctx.drawImage(img, 0, 0, thumbnailWidth, thumbnailHeight) const thumbnailDataURL = canvas.toDataURL('image/png') resolve(thumbnailDataURL) } img.onerror = function () { console.error('Error loading image') reject(null) } img.src = thumbnailURL } else if (file.type.startsWith('video/')) { const video = document.createElement('video') video.onloadedmetadata = function () { video.currentTime = 1 } video.onseeked = function () { const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') if (!ctx) return resolve(null) const thumbnailWidth = 200 const scaleFactor = thumbnailWidth / video.videoWidth const thumbnailHeight = video.videoHeight * scaleFactor canvas.width = thumbnailWidth canvas.height = thumbnailHeight ctx.drawImage(video, 0, 0, thumbnailWidth, thumbnailHeight) const thumbnailDataURL = canvas.toDataURL('image/png') resolve(thumbnailDataURL) } video.onerror = function () { console.error('Error loading video') reject(null) } video.src = thumbnailURL } else { resolve(null) } } reader.onerror = function () { console.error('Error reading file') reject(null) } reader.readAsDataURL(file) }) } export async function isURLExpired(url?: string) { if (!url) return { isExpired: false, status: 0, error: 'URL is empty' } try { const response = await fetch(url, { method: 'GET', headers: { Range: 'bytes=0-0', // Request only the first byte }, cache: 'no-store', }) return { isExpired: response.status === 403, status: response.status, } } catch (error) { return { isExpired: true, status: 0, error: error.message, } } }