From c36cd02f4772b60a2f329bea2a7cf2da9ba7ed1c Mon Sep 17 00:00:00 2001 From: SethBurkart123 Date: Mon, 23 Oct 2023 14:39:22 +1100 Subject: [PATCH] add image downloading system and fix shortcuts bug --- interface/src/pages/Themes.tsx | 132 +++++++++++++++++++++++++++++---- src/SEQTA.js | 2 +- 2 files changed, 119 insertions(+), 15 deletions(-) diff --git a/interface/src/pages/Themes.tsx b/interface/src/pages/Themes.tsx index 2ca950f6..620e9cf3 100644 --- a/interface/src/pages/Themes.tsx +++ b/interface/src/pages/Themes.tsx @@ -7,8 +7,43 @@ interface Background { type: string; blob: Blob; url?: string; + previewUrl?: string; // New field + isPreset?: boolean; + isDownloaded?: boolean; } +const downloadPresetBackground = async (background: Background, onProgress: (progress: number) => void): Promise => { + const response = await fetch(background.url as string); + + const totalLength = +response.headers.get('Content-Length')!; + let receivedLength = 0; + + const reader = response.body?.getReader(); + const chunks = []; + + // eslint-disable-next-line no-constant-condition + while (true) { + const { done, value } = await reader!.read(); + + if (done) break; + + chunks.push(value!); + receivedLength += value!.length; + + onProgress(Math.ceil(receivedLength / totalLength * 100)); + } + + const blob = new Blob(chunks); + await writeData(background.id, background.type, blob); + + return { + id: background.id, + type: background.type, + blob, + url: URL.createObjectURL(blob), + }; +}; + // IndexedDB utility functions const openDB = () => { return new Promise((resolve, reject) => { @@ -55,8 +90,29 @@ const readAllData = async (): Promise => { const Themes: FC = () => { const [backgrounds, setBackgrounds] = useState([]); const [selectedBackground, setSelectedBackground] = useState(localStorage.getItem('selectedBackground')); + const [downloadedPresetIds, setDownloadedPresetIds] = useState([]); + const [downloadProgress, setDownloadProgress] = useState>({}); const [isEditMode, setIsEditMode] = useState(false); + + const presetBackgrounds = [ + { + id: 'preset-1', + type: 'image', + url: 'https://images.unsplash.com/photo-1697228428285-8c442346434a?auto=format&fit=crop&q=80&w=2070&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', + previewUrl: 'https://images.unsplash.com/photo-1697228428285-8c442346434a?auto=format&fit=crop&q=80&w=2070&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', + isPreset: true + }, + { + id: 'preset-2', + type: 'image', + url: 'https://images.unsplash.com/photo-1697359774044-35aa12ab7c91?auto=format&fit=crop&q=80&w=2375&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', + previewUrl: 'https://images.unsplash.com/photo-1697359774044-35aa12ab7c91?auto=format&fit=crop&q=80&w=2375&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', + isPreset: true + }, + // ... more preset backgrounds + ]; + const handleFileChange = async (e: ChangeEvent): Promise => { const file = e.target.files?.[0]; if (!file) return; @@ -72,9 +128,38 @@ const Themes: FC = () => { const loadBackgrounds = async (): Promise => { const data = await readAllData(); const dataWithUrls = data.map(bg => ({ ...bg, url: URL.createObjectURL(bg.blob) })); + + // Update downloaded preset IDs + setDownloadedPresetIds(data.map(bg => bg.id)); + setBackgrounds(dataWithUrls); - }; + }; +const handlePresetClick = async (bg: Background): Promise => { + if (bg.isPreset) { + // Check if already exists in IndexedDB or is currently being downloaded + const existingBackgrounds = await readAllData(); + const alreadyExists = existingBackgrounds.some(ebg => ebg.id === bg.id) || downloadProgress[bg.id] !== undefined; + + if (!alreadyExists) { + setDownloadProgress(prev => ({ ...prev, [bg.id]: 0 })); + const downloadedBg = await downloadPresetBackground(bg, progress => { + console.log(`${bg}, ${progress}`); + setDownloadProgress(prev => ({ ...prev, [bg.id]: progress })); + }); + setDownloadProgress(prev => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { [bg.id]: _, ...rest } = prev; + return rest; + }); + await writeData(downloadedBg.id, downloadedBg.type, downloadedBg.blob); + setBackgrounds(prev => [...prev, downloadedBg]); + setDownloadedPresetIds(prev => [...prev, downloadedBg.id]); + } + selectBackground(bg.id); + } +}; + const selectBackground = (fileId: string): void => { setSelectedBackground(fileId); localStorage.setItem('selectedBackground', fileId); @@ -86,20 +171,25 @@ const Themes: FC = () => { const store = tx.objectStore('backgrounds'); store.delete(fileId); setBackgrounds(prev => prev.filter(bg => bg.id !== fileId)); - }; + + // Check if the background being deleted is currently selected + if (fileId === selectedBackground) { + selectNoBackground(); // Disable the current background + } + }; const selectNoBackground = (): void => { setSelectedBackground(null); localStorage.removeItem('selectedBackground'); - }; - + }; + useEffect(() => { loadBackgrounds(); }, []); return (
-
@@ -129,6 +219,27 @@ const Themes: FC = () => { swatch
))} + {backgrounds.concat(presetBackgrounds as Background[]).filter(bg => bg.type === 'image' && bg.isPreset && !bg.isDownloaded && !downloadedPresetIds.includes(bg.id)).map(bg => ( +
handlePresetClick(bg)} + className='relative w-16 h-16 transition cursor-pointer rounded-xl'> + {bg.isPreset && downloadProgress[bg.id] !== undefined && ( +
+ )} +
+ +  + + +  + +
+ swatch +
+ ))}

Videos

@@ -152,15 +263,8 @@ const Themes: FC = () => {