mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 19:54:39 +00:00
merge interface with main script
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import { Background } from "../components/BackgroundSelector";
|
||||
|
||||
export const downloadPresetBackground = async (background: Background, onProgress: (progress: number) => void): Promise<Background> => {
|
||||
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
|
||||
export const openDB = () => {
|
||||
return new Promise<IDBDatabase>((resolve, reject) => {
|
||||
const request = indexedDB.open('MyDatabase', 1);
|
||||
|
||||
request.onerror = () => reject(request.error);
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
|
||||
request.onupgradeneeded = (event) => {
|
||||
const db = (event.target as IDBOpenDBRequest).result;
|
||||
db.createObjectStore('backgrounds', { keyPath: 'id' });
|
||||
};
|
||||
});
|
||||
};
|
||||
export 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: fileId, type, blob });
|
||||
|
||||
await new Promise((res, rej) => {
|
||||
tx.oncomplete = () => res(request.result);
|
||||
tx.onerror = () => rej(tx.error);
|
||||
}).then(resolve, reject);
|
||||
|
||||
}).catch(reject);
|
||||
});
|
||||
};
|
||||
export const readAllData = async (): Promise<Background[]> => {
|
||||
const db = await openDB();
|
||||
const tx = db.transaction('backgrounds', 'readonly');
|
||||
const store = tx.objectStore('backgrounds');
|
||||
const request = store.getAll();
|
||||
|
||||
return await new Promise((resolve, reject) => {
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
import browser from 'webextension-polyfill'
|
||||
interface ThemeList {
|
||||
themes: string[];
|
||||
selectedTheme: string;
|
||||
}
|
||||
|
||||
export const downloadTheme = async (themeName: string, themeURL: string) => {
|
||||
// send message to the background script
|
||||
const response = await browser.runtime.sendMessage({
|
||||
type: 'currentTab',
|
||||
info: 'DownloadTheme',
|
||||
body: {
|
||||
themeName: themeName,
|
||||
themeURL: themeURL
|
||||
}
|
||||
});
|
||||
|
||||
console.log("Response: ", response);
|
||||
}
|
||||
|
||||
export const setTheme = async (themeName: string, themeURL: string) => {
|
||||
// send message to the background script
|
||||
const response = await browser.runtime.sendMessage({
|
||||
type: 'currentTab',
|
||||
info: 'SetTheme',
|
||||
body: {
|
||||
themeName: themeName,
|
||||
themeURL: themeURL
|
||||
}
|
||||
});
|
||||
|
||||
console.log("Response: ", response);
|
||||
}
|
||||
|
||||
export const listThemes = async () => {
|
||||
// send message to the background script
|
||||
const response: ThemeList = await browser.runtime.sendMessage({
|
||||
type: 'currentTab',
|
||||
info: 'ListThemes'
|
||||
});
|
||||
|
||||
// response.themes is an array of strings that are identical to the theme names that we loop over. Use this list to see which ones are downloaded and which ones need to see the download icon.
|
||||
console.log("Response: ", response);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export const disableTheme = async () => {
|
||||
await browser.runtime.sendMessage({
|
||||
type: 'currentTab',
|
||||
info: 'DisableTheme',
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteTheme = async (themeName: string) => {
|
||||
await browser.runtime.sendMessage({
|
||||
type: 'currentTab',
|
||||
info: 'DeleteTheme',
|
||||
body: {
|
||||
themeName: themeName
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
import browser from 'webextension-polyfill'
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { SettingsProps } from "../types/SettingsProps";
|
||||
import { MainConfig, SettingsState } from "../types/AppProps";
|
||||
|
||||
let RanOnce = false;
|
||||
let previousSettingsState: SettingsState
|
||||
|
||||
const useSettingsState = ({ settingsState, setSettingsState }: SettingsProps) => {
|
||||
useEffect(() => {
|
||||
if (RanOnce) return;
|
||||
RanOnce = true;
|
||||
|
||||
// get the current settings state
|
||||
// @ts-expect-error - TODO: Fix this
|
||||
browser.storage.local.get().then((result: MainConfig) => {
|
||||
setSettingsState({
|
||||
notificationCollector: result.notificationcollector,
|
||||
lessonAlerts: result.lessonalert,
|
||||
telemetry: result.telemetry,
|
||||
animatedBackground: result.animatedbk,
|
||||
animatedBackgroundSpeed: result.bksliderinput,
|
||||
customThemeColor: result.selectedColor,
|
||||
betterSEQTAPlus: result.onoff,
|
||||
shortcuts: result.shortcuts,
|
||||
customshortcuts: result.customshortcuts,
|
||||
transparencyEffects: result.transparencyEffects
|
||||
});
|
||||
|
||||
if (result.DarkMode) {
|
||||
document.body.classList.add('dark');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const keyToStateMap = useMemo(() => ({
|
||||
"notificationcollector": "notificationCollector",
|
||||
"lessonalert": "lessonAlerts",
|
||||
"telemetry": "telemetry",
|
||||
"animatedbk": "animatedBackground",
|
||||
"bksliderinput": "animatedBackgroundSpeed",
|
||||
"selectedColor": "customThemeColor",
|
||||
"onoff": "betterSEQTAPlus",
|
||||
"shortcuts": "shortcuts",
|
||||
"customshortcuts": "customshortcuts",
|
||||
"transparencyEffects": "transparencyEffects"
|
||||
}), []);
|
||||
|
||||
const storageChangeListener = (changes: browser.Storage.StorageChange) => {
|
||||
for (const [key, { newValue }] of Object.entries(changes)) {
|
||||
if (key === "DarkMode") {
|
||||
if (key === "DarkMode" && newValue) {
|
||||
document.body.classList.add('dark');
|
||||
} else {
|
||||
document.body.classList.remove('dark');
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error - TODO: Fix this
|
||||
const stateKey = keyToStateMap[key as keyof MainConfig];
|
||||
if (stateKey) {
|
||||
setSettingsState((prevState: SettingsState) => ({
|
||||
...prevState,
|
||||
[stateKey]: newValue
|
||||
}));
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
browser.storage.onChanged.addListener(storageChangeListener);
|
||||
return () => {
|
||||
browser.storage.onChanged.removeListener(storageChangeListener);
|
||||
};
|
||||
});
|
||||
|
||||
const setStorage = (key: keyof MainConfig, value: any) => {
|
||||
browser.storage.local.set({ [key]: value });
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (previousSettingsState) {
|
||||
for (const [key, value] of Object.entries(settingsState)) {
|
||||
// @ts-expect-error - TODO: Fix this
|
||||
const storageKey = Object.keys(keyToStateMap).find(k => keyToStateMap[k] === key);
|
||||
// @ts-expect-error - TODO: Fix this
|
||||
if (storageKey && value !== previousSettingsState[key]) {
|
||||
setStorage(storageKey as keyof MainConfig, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
previousSettingsState = settingsState;
|
||||
}, [settingsState, keyToStateMap])
|
||||
}
|
||||
|
||||
export default useSettingsState;
|
||||
Reference in New Issue
Block a user