only single selected theme or custom background at once

This commit is contained in:
SethBurkart123
2023-11-02 19:05:37 +11:00
parent 7b0fc29461
commit e332977e08
7 changed files with 55 additions and 22 deletions
@@ -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);
};
+22 -6
View File
@@ -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
@@ -61,10 +66,13 @@ const ThemeSelector = () => {
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>
+3 -3
View File
@@ -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 () => {
+10 -3
View File
@@ -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(() => {
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
View File
@@ -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
View File
@@ -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) {
+4 -2
View File
@@ -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":