feat(settings): add background selector

This commit is contained in:
sethburkart123
2024-09-08 19:33:47 +10:00
parent f0bdbbb14f
commit c3cb2937c9
16 changed files with 420 additions and 165 deletions
+95 -4
View File
@@ -1,13 +1,104 @@
import browser from 'webextension-polyfill';
import { getDataById, isIndexedDBSupported } from '@/svelte-interface/hooks/BackgroundDataLoader';
export async function appendBackgroundToUI() {
const parent = document.getElementById('container');
// embed background.html
const background = document.createElement('iframe');
// embed background.html - old method
/* const background = document.createElement('iframe');
background.id = 'background';
background.classList.add('imageBackground');
background.setAttribute('excludeDarkCheck', 'true');
background.src = browser.runtime.getURL('seqta/ui/background/background.html');
parent!.appendChild(background);
parent!.appendChild(background); */
if (!parent) return;
const backgroundContainer = document.createElement('div');
backgroundContainer.classList.add('imageBackground');
backgroundContainer.setAttribute('excludeDarkCheck', 'true');
const mediaContainer = document.createElement('div');
mediaContainer.id = 'media-container';
backgroundContainer.appendChild(mediaContainer);
parent.appendChild(backgroundContainer);
// Add styles
const style = document.createElement('style');
style.textContent = `
#media-container {
width: 100%;
height: 100%;
}
#media-container video, #media-container img {
width: 100%;
height: 100%;
object-fit: cover;
}
`;
document.head.appendChild(style);
// Load and display the background
await loadBackground();
}
export async function loadBackground() {
if (!isIndexedDBSupported()) {
console.error("IndexedDB is not supported. Unable to load background.");
return;
}
try {
const selectedBackgroundId = localStorage.getItem('selectedBackground');
if (!selectedBackgroundId) {
const backgroundContainer = document.querySelector('.imageBackground');
if (backgroundContainer) {
backgroundContainer.remove();
}
return;
};
const background = await getDataById(selectedBackgroundId);
if (!background) return;
let backgroundContainer = document.querySelector('.imageBackground');
if (!backgroundContainer) {
backgroundContainer = document.createElement('div');
backgroundContainer.classList.add('imageBackground');
backgroundContainer.setAttribute('excludeDarkCheck', 'true');
const parent = document.getElementById('container');
if (parent) {
parent.appendChild(backgroundContainer);
}
}
let mediaContainer = document.getElementById('media-container');
if (!mediaContainer) {
mediaContainer = document.createElement('div');
mediaContainer.id = 'media-container';
backgroundContainer.appendChild(mediaContainer);
};
mediaContainer = document.getElementById('media-container');
if (!mediaContainer) return;
mediaContainer.innerHTML = '';
const mediaElement = background.type === 'video'
? document.createElement('video')
: document.createElement('img');
mediaElement.src = URL.createObjectURL(background.blob);
mediaElement.classList.add('background');
if (mediaElement instanceof HTMLVideoElement) {
mediaElement.loop = true;
mediaElement.muted = true;
mediaElement.autoplay = true;
}
mediaContainer.appendChild(mediaElement);
} catch (error) {
console.error('Error loading background:', error);
}
}
-29
View File
@@ -1,29 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Background Fetcher</title>
<style>
body {
margin: 0 !important;
}
video, img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
</style>
</head>
<body>
<!-- Container for the media -->
<div id="media-container"></div>
<script type="module" src="./background.ts"></script>
</body>
</html>
-115
View File
@@ -1,115 +0,0 @@
interface Data {
blob: Blob;
type: 'image' | 'video';
}
interface DatabaseEventTarget extends EventTarget {
result: IDBDatabase;
}
interface DatabaseEvent extends Event {
target: DatabaseEventTarget;
}
const openDB = (): Promise<IDBDatabase> => {
return new Promise((resolve, reject) => {
const request = indexedDB.open('MyDatabase', 1);
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
request.onupgradeneeded = (event: IDBVersionChangeEvent) => {
// @ts-expect-error - The event type is not recognized by TypeScript
event?.target?.result.createObjectStore('backgrounds', { keyPath: 'id' });
};
});
};
const readData = async (): Promise<Data | null> => {
const selectedBackground = localStorage.getItem('selectedBackground');
//const selectedBackground = localStorage.getItem('selectedBackground');
if (!selectedBackground || selectedBackground === '') {
return null;
}
const db = await openDB();
const tx = db.transaction('backgrounds', 'readonly');
const store = tx.objectStore('backgrounds');
const request = store.get(selectedBackground);
return new Promise((resolve, reject) => {
request.onsuccess = () => resolve(request.result as Data);
request.onerror = () => reject(request.error);
});
};
const updateBackground = async (): Promise<void> => {
try {
const data = await readData();
if (!data) {
const container = document.getElementById('media-container');
const currentMedia = container?.querySelector('.current-media');
if (currentMedia) {
currentMedia.remove();
}
return;
}
const url = URL.createObjectURL(data.blob);
const container = document.getElementById('media-container');
// Create new element and set properties
let newElement;
if (data.type === 'image') {
newElement = document.createElement('img');
newElement.src = url;
newElement.alt = 'Uploaded content';
} else if (data.type === 'video') {
newElement = document.createElement('video');
newElement.src = url;
newElement.autoplay = true;
newElement.loop = true;
newElement.muted = true;
}
// Mark the old element for removal
const oldElement = container?.querySelector('.current-media');
if (oldElement) {
oldElement.classList.remove('current-media');
oldElement.classList.add('old-media');
}
// Add the new element and mark it as current
newElement?.classList.add('current-media');
container?.appendChild(newElement as Node);
// Delay removal of old element
setTimeout(() => {
const oldMedia = container?.querySelector('.old-media');
if (oldMedia) {
oldMedia.remove();
}
}, 100); // 0.1 second delay
} catch (error) {
console.error('An error occurred:', error);
}
};
// Main function to run on page load
const main = async (): Promise<void> => {
await updateBackground();
// Listen for changes to local storage
try {
window.addEventListener('storage', async (event) => {
if (event.key === 'selectedBackground') {
await updateBackground();
}
});
} catch (error) {
console.error('An error occurred:', error);
}
};
main()