mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-05 19:24:39 +00:00
only single selected theme or custom background at once
This commit is contained in:
@@ -17,10 +17,11 @@ export interface Background {
|
||||
|
||||
interface BackgroundSelectorProps {
|
||||
selectedType: "background" | "theme";
|
||||
setSelectedType: (type: "background" | "theme") => void;
|
||||
isEditMode: boolean;
|
||||
}
|
||||
|
||||
export default function BackgroundSelector({ selectedType, isEditMode }: BackgroundSelectorProps) {
|
||||
export default function BackgroundSelector({ selectedType, setSelectedType, isEditMode }: BackgroundSelectorProps) {
|
||||
const [backgrounds, setBackgrounds] = useState<Background[]>([]);
|
||||
const [selectedBackground, setSelectedBackground] = useState<string | null>(localStorage.getItem('selectedBackground'));
|
||||
const [downloadedPresetIds, setDownloadedPresetIds] = useState<string[]>([]);
|
||||
@@ -75,6 +76,7 @@ export default function BackgroundSelector({ selectedType, isEditMode }: Backgro
|
||||
|
||||
const selectBackground = (fileId: string): void => {
|
||||
disableTheme();
|
||||
setSelectedType('background');
|
||||
setSelectedBackground(fileId);
|
||||
localStorage.setItem('selectedBackground', fileId);
|
||||
};
|
||||
|
||||
@@ -10,13 +10,19 @@ interface Theme {
|
||||
coverImage: JSX.Element;
|
||||
}
|
||||
|
||||
const ThemeSelector = () => {
|
||||
interface ThemeSelectorProps {
|
||||
selectedType: "background" | "theme";
|
||||
setSelectedType: (type: "background" | "theme") => void;
|
||||
isEditMode: boolean;
|
||||
}
|
||||
|
||||
const ThemeSelector = ({ selectedType, setSelectedType, isEditMode }: ThemeSelectorProps) => {
|
||||
const [themes, setThemes] = useState<Theme[]>([]);
|
||||
const [enabledThemeName, setEnabledThemeName] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
const initializeThemes = async () => {
|
||||
const downloaded = await listThemes();
|
||||
const downloaded = (await listThemes()).themes;
|
||||
|
||||
const initializedThemes = themesList.map(theme => ({
|
||||
...theme,
|
||||
@@ -31,7 +37,6 @@ const ThemeSelector = () => {
|
||||
}, []);
|
||||
|
||||
const handleThemeAction = async (themeName: string, themeURL: string) => {
|
||||
// Start loading for the selected theme.
|
||||
const startLoading = (name: string) => (
|
||||
setThemes(prevThemes => prevThemes.map(theme =>
|
||||
theme.name === name ? { ...theme, isLoading: true } : theme
|
||||
@@ -51,7 +56,7 @@ const ThemeSelector = () => {
|
||||
theme.name === name ? { ...theme, isDownloaded: true } : theme
|
||||
))
|
||||
);
|
||||
|
||||
|
||||
startLoading(themeName);
|
||||
|
||||
// Early return if theme is not found.
|
||||
@@ -60,11 +65,14 @@ const ThemeSelector = () => {
|
||||
stopLoading(themeName);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Theme: ", theme);
|
||||
|
||||
// If theme is downloaded and is the currently enabled theme, disable it.
|
||||
if (theme.isDownloaded && themeName === enabledThemeName) {
|
||||
await disableTheme();
|
||||
setEnabledThemeName('');
|
||||
setSelectedType('background');
|
||||
stopLoading(themeName);
|
||||
return;
|
||||
}
|
||||
@@ -73,6 +81,7 @@ const ThemeSelector = () => {
|
||||
if (theme.isDownloaded && themeName !== enabledThemeName) {
|
||||
await setTheme(themeName, themeURL);
|
||||
setEnabledThemeName(themeName);
|
||||
setSelectedType('theme');
|
||||
stopLoading(themeName);
|
||||
return;
|
||||
}
|
||||
@@ -81,6 +90,7 @@ const ThemeSelector = () => {
|
||||
if (!theme.isDownloaded) {
|
||||
await downloadTheme(themeName, themeURL);
|
||||
markAsDownloaded(themeName);
|
||||
setSelectedType('theme');
|
||||
setEnabledThemeName(themeName);
|
||||
}
|
||||
|
||||
@@ -94,11 +104,17 @@ const ThemeSelector = () => {
|
||||
{themes.map((theme) => (
|
||||
<button
|
||||
key={theme.name}
|
||||
className={`relative w-full h-16 flex justify-center items-center rounded-lg overflow-hidden bg-zinc-700 transition ring dark:ring-white ring-zinc-300 ${enabledThemeName == theme.name ? 'dark:ring-2 ring-4' : 'ring-0'} ${theme.isLoading ? 'cursor-not-allowed' : ''}`}
|
||||
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'}`}
|
||||
onClick={() => handleThemeAction(theme.name, theme.url)}
|
||||
disabled={theme.isLoading}
|
||||
>
|
||||
<div className={`relative transition top-0 z-10 flex justify-center w-full h-full text-white group place-items-center ${ theme.isDownloaded ? '' : 'hover:bg-black/20'}`}>
|
||||
{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"
|
||||
onClick={() => console.log("Deleted!")}>
|
||||
<div className="w-4 h-0.5 bg-white"></div>
|
||||
</div>
|
||||
)}
|
||||
<div className={`relative transition rounded-lg overflow-hidden top-0 z-10 flex justify-center w-full h-full text-white group place-items-center ${ theme.isDownloaded ? '' : 'hover:bg-black/20'}`}>
|
||||
<span className="absolute z-10 text-3xl transition opacity-0 font-IconFamily group-hover:opacity-100">
|
||||
{ theme.isDownloaded || theme.isLoading ? '' : ''}
|
||||
</span>
|
||||
@@ -109,7 +125,7 @@ const ThemeSelector = () => {
|
||||
</div> }
|
||||
|
||||
</div>
|
||||
<div className="absolute inset-0 z-0">
|
||||
<div className="absolute inset-0 z-0 overflow-hidden rounded-lg">
|
||||
{theme.coverImage}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
interface ThemeList {
|
||||
themes: string[];
|
||||
selectedTheme: string;
|
||||
}
|
||||
|
||||
export const downloadTheme = async (themeName: string, themeURL: string) => {
|
||||
@@ -34,14 +35,13 @@ export const listThemes = async () => {
|
||||
// send message to the background script
|
||||
const response: ThemeList = await chrome.runtime.sendMessage({
|
||||
type: 'currentTab',
|
||||
info: 'ListThemes',
|
||||
body: {}
|
||||
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.themes;
|
||||
return response;
|
||||
}
|
||||
|
||||
export const disableTheme = async () => {
|
||||
|
||||
@@ -1,22 +1,29 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import BackgroundSelector from '../components/BackgroundSelector';
|
||||
import ThemeSelector from '../components/ThemeSelector';
|
||||
import { listThemes } from '../hooks/ThemeManagment';
|
||||
|
||||
const Themes: FC = () => {
|
||||
const [isEditMode, setIsEditMode] = useState<boolean>(false);
|
||||
const [selectedType, setSelectedType] = useState<'background' | 'theme'>('background');
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedType('background');
|
||||
listThemes().then(themes => {
|
||||
if (themes.selectedTheme) {
|
||||
setSelectedType('theme');
|
||||
} else {
|
||||
setSelectedType('background');
|
||||
}
|
||||
});
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button className="absolute top-0 right-0 p-2 text-[0.8rem] text-blue-500" onClick={() => setIsEditMode(!isEditMode)}>
|
||||
<button className="absolute top-12 z-10 right-0 p-2 text-[0.8rem] text-blue-500" onClick={() => setIsEditMode(!isEditMode)}>
|
||||
{isEditMode ? 'Done' : 'Edit'}
|
||||
</button>
|
||||
<BackgroundSelector selectedType={selectedType} isEditMode={isEditMode} />
|
||||
<ThemeSelector selectedType={selectedType} isEditMode={isEditMode} />
|
||||
<BackgroundSelector setSelectedType={setSelectedType} selectedType={selectedType} isEditMode={isEditMode} />
|
||||
<ThemeSelector setSelectedType={setSelectedType} selectedType={selectedType} isEditMode={isEditMode} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
+1
-1
@@ -772,9 +772,9 @@ document.addEventListener(
|
||||
link.rel = "stylesheet";
|
||||
document.getElementsByTagName("html")[0].appendChild(link);
|
||||
|
||||
enableCurrentTheme();
|
||||
chrome.storage.local.get(null, function (items) {
|
||||
main(items);
|
||||
enableCurrentTheme();
|
||||
});
|
||||
}
|
||||
if (
|
||||
|
||||
+10
-4
@@ -84,9 +84,14 @@ const applyTheme = async (themeName) => {
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const listThemes = async () => {
|
||||
const themes = await localforage.keys();
|
||||
return themes.filter((key) => key.startsWith("css_")).map((key) => key.replace("css_", ""));
|
||||
console.log("Themes in IndexedDB:", themes);
|
||||
return {
|
||||
themes: themes.filter((key) => key.startsWith("css_")).map((key) => key.replace("css_", "")),
|
||||
selectedTheme: await localforage.getItem("selectedTheme")
|
||||
};
|
||||
};
|
||||
|
||||
export const downloadTheme = async (themeName, themeUrl) => {
|
||||
@@ -101,14 +106,15 @@ export const setTheme = async (themeName, themeUrl) => {
|
||||
await downloadTheme(themeName, themeUrl);
|
||||
}
|
||||
|
||||
localforage.setItem("selectedTheme", themeName);
|
||||
await localforage.setItem("selectedTheme", themeName);
|
||||
await applyTheme(themeName).catch((error) => {
|
||||
console.error(`Failed to apply theme: ${error}`);
|
||||
});
|
||||
};
|
||||
|
||||
export const enableCurrentTheme = async () => {
|
||||
const currentTheme = localforage.getItem("selectedTheme");
|
||||
console.log("Enabling current theme...");
|
||||
const currentTheme = await localforage.getItem("selectedTheme");
|
||||
|
||||
if (currentTheme) {
|
||||
console.log(`Enabling current theme: ${currentTheme}`);
|
||||
@@ -136,7 +142,7 @@ export const disableTheme = async () => {
|
||||
}
|
||||
|
||||
// Remove any applied image URLs from the root element
|
||||
const currentTheme = localforage.getItem("selectedTheme");
|
||||
const currentTheme = await localforage.getItem("selectedTheme");
|
||||
if (currentTheme) {
|
||||
const themeData = await localforage.getItem(`css_${currentTheme}`);
|
||||
if (themeData && themeData.images) {
|
||||
|
||||
@@ -14,6 +14,8 @@ export class MessageHandler {
|
||||
case "EditSidebar":
|
||||
this.editSidebar();
|
||||
break;
|
||||
|
||||
/* Theme related */
|
||||
case "SetTheme":
|
||||
console.log(request);
|
||||
setTheme(request.body.themeName, request.body.themeURL).then(() => {
|
||||
@@ -26,8 +28,8 @@ export class MessageHandler {
|
||||
});
|
||||
return true;
|
||||
case "ListThemes":
|
||||
listThemes().then((themes) => {
|
||||
sendResponse({ themes });
|
||||
listThemes().then((response) => {
|
||||
sendResponse(response);
|
||||
});
|
||||
return true;
|
||||
case "DisableTheme":
|
||||
|
||||
Reference in New Issue
Block a user