mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-05 19:24:39 +00:00
added theme deletion
This commit is contained in:
@@ -95,6 +95,7 @@ export default function BackgroundSelector({ selectedType, setSelectedType, isEd
|
|||||||
};
|
};
|
||||||
|
|
||||||
const selectNoBackground = (): void => {
|
const selectNoBackground = (): void => {
|
||||||
|
setSelectedType('background');
|
||||||
disableTheme();
|
disableTheme();
|
||||||
setSelectedBackground(null);
|
setSelectedBackground(null);
|
||||||
localStorage.removeItem('selectedBackground');
|
localStorage.removeItem('selectedBackground');
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import themesList from '../assets/themes';
|
import themesList from '../assets/themes';
|
||||||
import { listThemes, disableTheme, downloadTheme, setTheme } from "../hooks/ThemeManagment";
|
import { listThemes, disableTheme, downloadTheme, setTheme, deleteTheme } from "../hooks/ThemeManagment";
|
||||||
|
|
||||||
interface Theme {
|
interface Theme {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -30,12 +30,38 @@ const ThemeSelector = ({ selectedType, setSelectedType, isEditMode }: ThemeSelec
|
|||||||
isLoading: false
|
isLoading: false
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
initializedThemes.sort((a, b) => Number(b.isDownloaded) - Number(a.isDownloaded));
|
||||||
|
|
||||||
setThemes(initializedThemes);
|
setThemes(initializedThemes);
|
||||||
};
|
};
|
||||||
|
|
||||||
initializeThemes();
|
initializeThemes();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleDeleteTheme = async (themeName: string) => {
|
||||||
|
await deleteTheme(themeName);
|
||||||
|
setThemes(prevThemes => {
|
||||||
|
// Update the theme's isDownloaded property to false
|
||||||
|
const updatedThemes = prevThemes.map(theme => {
|
||||||
|
if (theme.name === themeName) {
|
||||||
|
return { ...theme, isDownloaded: false };
|
||||||
|
}
|
||||||
|
return theme;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sort themes so non-downloaded ones appear last
|
||||||
|
updatedThemes.sort((a, b) => Number(b.isDownloaded) - Number(a.isDownloaded));
|
||||||
|
|
||||||
|
return updatedThemes;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reset the enabled theme name if the deleted theme was the currently enabled one
|
||||||
|
if (enabledThemeName === themeName) {
|
||||||
|
setEnabledThemeName('');
|
||||||
|
setSelectedType('background');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleThemeAction = async (themeName: string, themeURL: string) => {
|
const handleThemeAction = async (themeName: string, themeURL: string) => {
|
||||||
const startLoading = (name: string) => (
|
const startLoading = (name: string) => (
|
||||||
setThemes(prevThemes => prevThemes.map(theme =>
|
setThemes(prevThemes => prevThemes.map(theme =>
|
||||||
@@ -103,9 +129,12 @@ const ThemeSelector = ({ selectedType, setSelectedType, isEditMode }: ThemeSelec
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="my-2">
|
<div className="my-2">
|
||||||
<h2 className="pb-2 text-lg font-bold">Themes</h2>
|
{(isEditMode ? themes.some(theme => theme.isDownloaded) : themes.length > 0) && (
|
||||||
|
<h2 className="pb-2 text-lg font-bold">Themes</h2>)}
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
{themes.map((theme) => (
|
{themes
|
||||||
|
.filter(theme => !isEditMode || theme.isDownloaded) // Only show downloaded themes in edit mode
|
||||||
|
.map((theme) => (
|
||||||
<button
|
<button
|
||||||
key={theme.name}
|
key={theme.name}
|
||||||
className={`relative w-full h-16 flex justify-center items-center rounded-lg bg-zinc-700 transition ring dark:ring-white ring-zinc-300 ${enabledThemeName == theme.name && selectedType == "theme" ? 'dark:ring-2 ring-4' : 'ring-0'}`}
|
className={`relative w-full h-16 flex justify-center items-center rounded-lg bg-zinc-700 transition ring dark:ring-white ring-zinc-300 ${enabledThemeName == theme.name && selectedType == "theme" ? 'dark:ring-2 ring-4' : 'ring-0'}`}
|
||||||
@@ -114,7 +143,7 @@ const ThemeSelector = ({ selectedType, setSelectedType, isEditMode }: ThemeSelec
|
|||||||
>
|
>
|
||||||
{isEditMode && (
|
{isEditMode && (
|
||||||
<div className="absolute top-0 right-0 z-10 flex w-6 h-6 p-2 text-white translate-x-1/2 -translate-y-1/2 bg-red-600 rounded-full place-items-center"
|
<div className="absolute top-0 right-0 z-10 flex w-6 h-6 p-2 text-white translate-x-1/2 -translate-y-1/2 bg-red-600 rounded-full place-items-center"
|
||||||
onClick={() => console.log("Deleted!")}>
|
onClick={(e) => { e.stopPropagation(); handleDeleteTheme(theme.name); }}>
|
||||||
<div className="w-4 h-0.5 bg-white"></div>
|
<div className="w-4 h-0.5 bg-white"></div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -50,3 +50,13 @@ export const disableTheme = async () => {
|
|||||||
info: 'DisableTheme',
|
info: 'DisableTheme',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const deleteTheme = async (themeName: string) => {
|
||||||
|
await chrome.runtime.sendMessage({
|
||||||
|
type: 'currentTab',
|
||||||
|
info: 'DeleteTheme',
|
||||||
|
body: {
|
||||||
|
themeName: themeName
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
+24
-22
@@ -47,33 +47,26 @@ const saveToIndexedDB = async (theme, themeName) => {
|
|||||||
|
|
||||||
// Apply theme from storage via localForage to document
|
// Apply theme from storage via localForage to document
|
||||||
const applyTheme = async (themeName) => {
|
const applyTheme = async (themeName) => {
|
||||||
// Remove previous theme's style if it exists
|
|
||||||
if (currentThemeStyle) {
|
|
||||||
document.head.removeChild(currentThemeStyle);
|
|
||||||
currentThemeStyle = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove previous theme's class if it exists
|
|
||||||
if (currentThemeClass) {
|
|
||||||
document.body.classList.remove(currentThemeClass);
|
|
||||||
currentThemeClass = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const { css, className, images } = await localforage.getItem(`css_${themeName}`);
|
const { css, className, images } = await localforage.getItem(`css_${themeName}`);
|
||||||
|
|
||||||
// Apply CSS
|
const newStyle = document.createElement("style");
|
||||||
const style = document.createElement("style");
|
newStyle.innerHTML = css;
|
||||||
style.innerHTML = css;
|
document.head.appendChild(newStyle);
|
||||||
document.head.appendChild(style);
|
|
||||||
currentThemeStyle = style; // Keep track of the new style element
|
|
||||||
|
|
||||||
// Apply className
|
if (window.currentThemeStyle) {
|
||||||
if (className) {
|
document.head.removeChild(window.currentThemeStyle);
|
||||||
document.body.classList.add(className);
|
}
|
||||||
currentThemeClass = className; // Keep track of the new class
|
|
||||||
|
window.currentThemeStyle = newStyle;
|
||||||
|
|
||||||
|
if (window.currentThemeClass) {
|
||||||
|
document.body.classList.remove(window.currentThemeClass);
|
||||||
|
}
|
||||||
|
if (className) {
|
||||||
|
document.body.classList.add(className);
|
||||||
|
window.currentThemeClass = className;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply images
|
|
||||||
if (images) {
|
if (images) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
Object.keys(images).map(async (cssVar) => {
|
Object.keys(images).map(async (cssVar) => {
|
||||||
@@ -101,6 +94,15 @@ export const downloadTheme = async (themeName, themeUrl) => {
|
|||||||
console.log(`Theme ${themeName} saved to IndexedDB`);
|
console.log(`Theme ${themeName} saved to IndexedDB`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const deleteTheme = async (themeName) => {
|
||||||
|
console.log(`Deleting theme ${themeName}...`);
|
||||||
|
await localforage.removeItem(`css_${themeName}`);
|
||||||
|
await Promise.all(
|
||||||
|
(await localforage.keys()).filter((key) => key.startsWith(`images_${themeName}`)).map((key) => localforage.removeItem(key))
|
||||||
|
);
|
||||||
|
console.log(`Theme ${themeName} deleted.`);
|
||||||
|
}
|
||||||
|
|
||||||
export const setTheme = async (themeName, themeUrl) => {
|
export const setTheme = async (themeName, themeUrl) => {
|
||||||
if (!(await themeExistsInDB(themeName))) {
|
if (!(await themeExistsInDB(themeName))) {
|
||||||
await downloadTheme(themeName, themeUrl);
|
await downloadTheme(themeName, themeUrl);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* global chrome */
|
/* global chrome */
|
||||||
|
|
||||||
import { MenuOptionsOpen, OpenMenuOptions, closeSettings } from "../../SEQTA.js";
|
import { MenuOptionsOpen, OpenMenuOptions, closeSettings } from "../../SEQTA.js";
|
||||||
import { disableTheme, downloadTheme, listThemes, setTheme } from "../ui/Themes.js";
|
import { deleteTheme, disableTheme, downloadTheme, listThemes, setTheme } from "../ui/Themes.js";
|
||||||
|
|
||||||
export class MessageHandler {
|
export class MessageHandler {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -37,6 +37,11 @@ export class MessageHandler {
|
|||||||
sendResponse({ status: "success" });
|
sendResponse({ status: "success" });
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
case "DeleteTheme":
|
||||||
|
deleteTheme(request.body.themeName).then(() => {
|
||||||
|
sendResponse({ status: "success" });
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.log("Unknown request info:", request.info);
|
console.log("Unknown request info:", request.info);
|
||||||
|
|||||||
Reference in New Issue
Block a user