diff --git a/interface/src/pages/Themes.tsx b/interface/src/pages/Themes.tsx index 2f670e43..40a174f7 100644 --- a/interface/src/pages/Themes.tsx +++ b/interface/src/pages/Themes.tsx @@ -1,4 +1,12 @@ -import React, { useState, useEffect } from 'react'; +import { useState, useEffect, ChangeEvent, FC } from 'react'; + +// Custom Types and Interfaces +interface Background { + id: string; + type: string; + blob: Blob; + url?: string; +} // IndexedDB utility functions const openDB = () => { @@ -15,12 +23,12 @@ const openDB = () => { }); }; -const writeData = async (type: string, blob: Blob) => { +const writeData = async (fileId: string, type: string, blob: Blob) => { return new Promise((resolve, reject) => { openDB().then(async db => { const tx = db.transaction('backgrounds', 'readwrite'); const store = tx.objectStore('backgrounds'); - const request = store.put({ id: 'customBackground', type, blob }); + const request = store.put({ id: fileId, type, blob }); await new Promise((res, rej) => { tx.oncomplete = () => res(request.result); @@ -31,11 +39,11 @@ const writeData = async (type: string, blob: Blob) => { }); }; -const readData = async () => { +const readAllData = async (): Promise => { const db = await openDB(); const tx = db.transaction('backgrounds', 'readonly'); const store = tx.objectStore('backgrounds'); - const request = store.get('customBackground'); + const request = store.getAll(); return await new Promise((resolve, reject) => { request.onsuccess = () => resolve(request.result); @@ -43,65 +51,69 @@ const readData = async () => { }); }; -const Themes: React.FC = () => { - const [imageSrc, setImageSrc] = useState(null); - const [videoSrc, setVideoSrc] = useState(null); +const Themes: FC = () => { + const [backgrounds, setBackgrounds] = useState([]); + const [selectedBackground, setSelectedBackground] = useState(localStorage.getItem('selectedBackground')); - const handleFileChange = async (e: React.ChangeEvent) => { + const handleFileChange = async (e: ChangeEvent): Promise => { const file = e.target.files?.[0]; if (!file) return; + const fileId = `${Date.now()}-${file.name}`; const fileType = file.type.split('/')[0]; const blob = new Blob([file], { type: file.type }); - // Save blob to IndexedDB - await writeData(fileType, blob); + await writeData(fileId, fileType, blob); + setBackgrounds(prev => [...prev, { id: fileId, type: fileType, blob, url: URL.createObjectURL(blob) }]); + }; - // For displaying purpose - const url = URL.createObjectURL(blob); - if (fileType === 'image') { - setVideoSrc(null); - setImageSrc(url); - } else if (fileType === 'video') { - setImageSrc(null); - setVideoSrc(url); - } + const loadBackgrounds = async (): Promise => { + const data = await readAllData(); + const dataWithUrls = data.map(bg => ({ ...bg, url: URL.createObjectURL(bg.blob) })); + setBackgrounds(dataWithUrls); + }; + + const selectBackground = (fileId: string): void => { + setSelectedBackground(fileId); + localStorage.setItem('selectedBackground', fileId); }; useEffect(() => { - (async () => { - const data = await readData(); - const url = URL.createObjectURL(data.blob); - if (data?.type === 'image') { - setImageSrc(url); - } else if (data?.type === 'video') { - setVideoSrc(url); - } - })(); + loadBackgrounds(); }, []); return ( -
-
-

Custom Background

-
+
+

Upload a Background

+ - - {imageSrc && Uploaded content} - {videoSrc &&
); }; diff --git a/public/backgrounds/background.html b/public/backgrounds/background.html index 76b94f20..3a5b5203 100644 --- a/public/backgrounds/background.html +++ b/public/backgrounds/background.html @@ -8,6 +8,27 @@ body { margin: 0 !important; } + + video, img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + + object-fit: cover; + + animation: fade 0.2s ease-in-out; + } + + @keyframes fade { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } diff --git a/public/backgrounds/background.js b/public/backgrounds/background.js index 53385a44..75e13601 100644 --- a/public/backgrounds/background.js +++ b/public/backgrounds/background.js @@ -13,12 +13,18 @@ const openDB = () => { }); }; -// Read data from IndexedDB +// Modified Read Data from IndexedDB const readData = async () => { + const selectedBackground = localStorage.getItem("selectedBackground"); + if (!selectedBackground) { + console.log("No selected background in local storage."); + return null; + } + const db = await openDB(); const tx = db.transaction("backgrounds", "readonly"); const store = tx.objectStore("backgrounds"); - const request = store.get("customBackground"); + const request = store.get(selectedBackground); return await new Promise((resolve, reject) => { request.onsuccess = () => resolve(request.result); @@ -26,8 +32,8 @@ const readData = async () => { }); }; -// Main function to run on page load -const main = async () => { +// Function to update the background +const updateBackground = async () => { try { const data = await readData(); if (!data) { @@ -37,6 +43,7 @@ const main = async () => { const url = URL.createObjectURL(data.blob); const container = document.getElementById("media-container"); + container.innerHTML = ""; // Clear previous background if (data.type === "image") { const imgElement = document.createElement("img"); @@ -56,5 +63,17 @@ const main = async () => { } }; +// Main function to run on page load +const main = async () => { + await updateBackground(); // Initial background update + + // Listen for changes to local storage + window.addEventListener("storage", async (event) => { + if (event.key === "selectedBackground") { + await updateBackground(); // Update background if 'selectedBackground' changes + } + }); +}; + // Run the main function when the document is ready document.addEventListener("DOMContentLoaded", main); diff --git a/src/seqta/ui/ImageBackgrounds.js b/src/seqta/ui/ImageBackgrounds.js index e2fbd3e6..41b78435 100644 --- a/src/seqta/ui/ImageBackgrounds.js +++ b/src/seqta/ui/ImageBackgrounds.js @@ -12,73 +12,4 @@ export async function appendBackgroundToUI() { background.setAttribute("excludeDarkCheck", "true"); background.src = chrome.runtime.getURL("backgrounds/background.html"); parent.appendChild(background); - - /* const response = await new Promise((resolve, reject) => { - console.log("Sending message to background script..."); - chrome.runtime.sendMessage({ type: "IndexedDB", action: "read", fileName: "customBackground" }, (response) => { - if (chrome.runtime.lastError) { - console.error("Error from background script:", chrome.runtime.lastError); - return reject(chrome.runtime.lastError); - } - console.log("Received response from background script:", response); - resolve(response); - }); - }); - - let data = response.data; // response.data is the image Data URL - - // Extract the pure base64 string from the Data URL - const base64Marker = ";base64,"; - const base64Index = data.indexOf(base64Marker) + base64Marker.length; - const base64 = data.substring(base64Index); - - let type = response.type; // response.type is the image type [ video | image ] - - if (base64) { - console.log("Data exists, proceeding..."); - - const mount = document.getElementById("container"); - - // Convert base64 to ArrayBuffer - console.log("Converting base64 to ArrayBuffer..."); - const byteCharacters = atob(base64); - const byteNumbers = Array.from(byteCharacters).map(char => char.charCodeAt(0)); - const byteArray = new Uint8Array(byteNumbers); - - // Create blob - console.log("Creating blob..."); - const blob = new Blob([byteArray], { type: type === "video" ? "video/mp4" : "image/jpeg" }); - - // Create blob URL - console.log("Creating blob URL..."); - const blobUrl = URL.createObjectURL(blob); - - let backgroundElement; - - if (type === "video") { - console.log("Appending video element..."); - backgroundElement = document.createElement("video"); - backgroundElement.src = blobUrl; - backgroundElement.autoplay = true; - backgroundElement.loop = true; - backgroundElement.muted = true; - - // Revoke blob URL to free memory - backgroundElement.addEventListener("ended", () => { - console.log("Video ended, revoking blob URL..."); - URL.revokeObjectURL(blobUrl); - }); - } else { - console.log("Appending image element..."); - backgroundElement = document.createElement("img"); - backgroundElement.src = blobUrl; - backgroundElement.alt = "Custom Background"; - backgroundElement.classList.add("imageBackground"); - } - - console.log("Appending background element to the DOM..."); - mount.appendChild(backgroundElement); - } else { - console.warn("No data received. Background not appended."); - } */ }