mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
fix: building working, (lots of bugs)
This commit is contained in:
@@ -1,73 +0,0 @@
|
||||
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);
|
||||
});
|
||||
};
|
||||
@@ -1,161 +0,0 @@
|
||||
import browser from 'webextension-polyfill'
|
||||
import { CustomTheme, DownloadedTheme, ThemeList } from '../types/CustomThemes';
|
||||
import localforage from 'localforage';
|
||||
|
||||
export const setTheme = async (themeID: string) => {
|
||||
// send message to the background script
|
||||
await browser.runtime.sendMessage({
|
||||
type: 'currentTab',
|
||||
info: 'SetTheme',
|
||||
body: {
|
||||
themeID: themeID
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const getDownloadedThemes = async (): Promise<DownloadedTheme[]> => {
|
||||
// send message to the background script
|
||||
const response: DownloadedTheme[] = await new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let availableThemes = await localforage.getItem('availableThemes') as string[];
|
||||
availableThemes = Array.from(new Set(availableThemes));
|
||||
|
||||
const downloadedThemes: DownloadedTheme[] = [];
|
||||
for (let i = 0; i < availableThemes.length; i++) {
|
||||
let themeData = await localforage.getItem(availableThemes[i]) as DownloadedTheme;
|
||||
|
||||
downloadedThemes.push(themeData);
|
||||
}
|
||||
|
||||
resolve(downloadedThemes);
|
||||
} catch(error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export const listThemes = async (): Promise<ThemeList> => {
|
||||
// send message to the background script
|
||||
const response: ThemeList = await new Promise((resolve, reject) => {
|
||||
browser.runtime.sendMessage({
|
||||
type: 'currentTab',
|
||||
info: 'ListThemes'
|
||||
}).then(async (response) => {
|
||||
if (response) {
|
||||
// convert the response themes coverImage to a bloburl
|
||||
response.themes = await Promise.all(
|
||||
response.themes.map(async (theme: Omit<CustomTheme, 'CustomImages'>) => {
|
||||
if (theme.coverImage) {
|
||||
const blob = await fetch(theme.coverImage as string).then((res) => res.blob());
|
||||
theme.coverImage = URL.createObjectURL(blob);
|
||||
}
|
||||
return theme;
|
||||
})
|
||||
);
|
||||
|
||||
resolve(response);
|
||||
} else {
|
||||
reject(new Error('Failed to get response'));
|
||||
}
|
||||
}).catch((error: any) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export const disableTheme = async () => {
|
||||
await browser.runtime.sendMessage({
|
||||
type: 'currentTab',
|
||||
info: 'DisableTheme',
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteTheme = async (themeID: string) => {
|
||||
await browser.runtime.sendMessage({
|
||||
type: 'currentTab',
|
||||
info: 'DeleteTheme',
|
||||
body: {
|
||||
themeID: themeID
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const sendThemeUpdate = async (updatedTheme: CustomTheme | DownloadedTheme, saveTheme?: boolean, updateImages?: boolean, enableTheme?: boolean) => {
|
||||
saveTheme = saveTheme || false;
|
||||
enableTheme = enableTheme || false;
|
||||
|
||||
const imageDataPromises = updatedTheme.CustomImages.map(async (image) => {
|
||||
if (saveTheme || updateImages) {
|
||||
const base64 = await blobToBase64(image.blob);
|
||||
return {
|
||||
id: image.id,
|
||||
variableName: image.variableName,
|
||||
url: base64,
|
||||
};
|
||||
}
|
||||
return {
|
||||
id: image.id,
|
||||
variableName: image.variableName,
|
||||
url: ''
|
||||
};
|
||||
});
|
||||
|
||||
Promise.all(imageDataPromises).then(async (imageData) => {
|
||||
const themeData = {
|
||||
...updatedTheme,
|
||||
CustomImages: imageData,
|
||||
};
|
||||
|
||||
if (saveTheme && updatedTheme.coverImage) {
|
||||
themeData.coverImage = await blobToBase64(updatedTheme.coverImage as Blob);
|
||||
} else {
|
||||
themeData.coverImage = null;
|
||||
}
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
type: 'currentTab',
|
||||
info: 'UpdateThemePreview',
|
||||
body: themeData,
|
||||
save: saveTheme,
|
||||
enableTheme: enableTheme
|
||||
});
|
||||
|
||||
if (saveTheme) {
|
||||
browser.runtime.sendMessage({ type: 'currentTab', info: 'CloseThemeCreator' });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Helper function to convert a Blob to base64
|
||||
const blobToBase64 = (blob: Blob): Promise<string> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => {
|
||||
const base64 = reader.result as string;
|
||||
resolve(base64);
|
||||
};
|
||||
reader.onerror = (error) => {
|
||||
reject(error);
|
||||
};
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
};
|
||||
|
||||
export const enableCurrentTheme = async () => {
|
||||
await browser.runtime.sendMessage({
|
||||
type: 'currentTab',
|
||||
info: 'EnableCurrentTheme',
|
||||
});
|
||||
};
|
||||
|
||||
export const saveUpdatedTheme = async (updatedTheme: CustomTheme) => {
|
||||
await browser.runtime.sendMessage({
|
||||
type: 'currentTab',
|
||||
info: 'SaveTheme',
|
||||
body: updatedTheme,
|
||||
});
|
||||
};
|
||||
@@ -1,100 +0,0 @@
|
||||
import browser from 'webextension-polyfill'
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { SettingsProps } from "../types/SettingsProps";
|
||||
import { SettingsState } from "../types/AppProps";
|
||||
import { SettingsState as StorageSettingsState } from '../../types/storage';
|
||||
|
||||
let RanOnce = false;
|
||||
let previousSettingsState: SettingsState
|
||||
|
||||
const useSettingsState = ({ settingsState, setSettingsState }: SettingsProps) => {
|
||||
useEffect(() => {
|
||||
if (RanOnce) return;
|
||||
RanOnce = true;
|
||||
|
||||
// @ts-expect-error - TODO: Fix this
|
||||
browser.storage.local.get().then((result: StorageSettingsState) => {
|
||||
setSettingsState({
|
||||
notificationCollector: result.notificationcollector,
|
||||
lessonAlerts: result.lessonalert,
|
||||
animatedBackground: result.animatedbk,
|
||||
animatedBackgroundSpeed: result.bksliderinput,
|
||||
customThemeColor: result.selectedColor,
|
||||
betterSEQTAPlus: result.onoff,
|
||||
shortcuts: result.shortcuts,
|
||||
customshortcuts: result.customshortcuts,
|
||||
transparencyEffects: result.transparencyEffects,
|
||||
selectedTheme: result.selectedTheme,
|
||||
timeFormat: result.timeFormat,
|
||||
animations: result.animations,
|
||||
defaultPage: result.defaultPage,
|
||||
devMode: result.devMode || false
|
||||
});
|
||||
});
|
||||
});
|
||||
const keyToStateMap = useMemo(() => ({
|
||||
"notificationcollector": "notificationCollector",
|
||||
"lessonalert": "lessonAlerts",
|
||||
"animatedbk": "animatedBackground",
|
||||
"bksliderinput": "animatedBackgroundSpeed",
|
||||
"selectedColor": "customThemeColor",
|
||||
"onoff": "betterSEQTAPlus",
|
||||
"shortcuts": "shortcuts",
|
||||
"customshortcuts": "customshortcuts",
|
||||
"transparencyEffects": "transparencyEffects",
|
||||
"selectedTheme": "selectedTheme",
|
||||
"timeFormat": "timeFormat",
|
||||
"animations": "animations",
|
||||
"defaultPage": "defaultPage",
|
||||
"devMode": "devMode"
|
||||
}), []);
|
||||
|
||||
const storageChangeListener = (changes: browser.Storage.StorageChange) => {
|
||||
for (const [key, { newValue }] of Object.entries(changes)) {
|
||||
if (key === "DarkMode") {
|
||||
if (key === "DarkMode" && newValue) {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error - TODO: Fix this
|
||||
const stateKey = keyToStateMap[key as keyof StorageSettingsState];
|
||||
if (stateKey) {
|
||||
setSettingsState((prevState: SettingsState) => ({
|
||||
...prevState,
|
||||
[stateKey]: newValue
|
||||
}));
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
browser.storage.onChanged.addListener(storageChangeListener);
|
||||
return () => {
|
||||
browser.storage.onChanged.removeListener(storageChangeListener);
|
||||
};
|
||||
});
|
||||
|
||||
const setStorage = (key: keyof StorageSettingsState, 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 StorageSettingsState, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
previousSettingsState = settingsState;
|
||||
}, [settingsState, keyToStateMap])
|
||||
}
|
||||
|
||||
export default useSettingsState;
|
||||
Reference in New Issue
Block a user