mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
made backgrounds and themes independant of each other
This commit is contained in:
@@ -2,7 +2,6 @@ import { ChangeEvent, memo, useEffect, useState } from "react";
|
|||||||
import { downloadPresetBackground, openDB, readAllData, writeData } from "../hooks/BackgroundDataLoader";
|
import { downloadPresetBackground, openDB, readAllData, writeData } from "../hooks/BackgroundDataLoader";
|
||||||
import presetBackgrounds from "../assets/presetBackgrounds";
|
import presetBackgrounds from "../assets/presetBackgrounds";
|
||||||
import "./BackgroundSelector.css";
|
import "./BackgroundSelector.css";
|
||||||
import { disableTheme } from "../hooks/ThemeManagment";
|
|
||||||
import browser from "webextension-polyfill";
|
import browser from "webextension-polyfill";
|
||||||
|
|
||||||
// Custom Types and Interfaces
|
// Custom Types and Interfaces
|
||||||
@@ -17,9 +16,8 @@ export interface Background {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface BackgroundSelectorProps {
|
interface BackgroundSelectorProps {
|
||||||
selectedType: "background" | "theme";
|
|
||||||
setSelectedType: (type: "background" | "theme") => void;
|
|
||||||
isEditMode: boolean;
|
isEditMode: boolean;
|
||||||
|
disableTheme: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function GetTheme() {
|
async function GetTheme() {
|
||||||
@@ -31,7 +29,7 @@ async function SetTheme(theme: string) {
|
|||||||
await browser.storage.local.set({ theme });
|
await browser.storage.local.set({ theme });
|
||||||
}
|
}
|
||||||
|
|
||||||
function BackgroundSelector({ selectedType, setSelectedType, isEditMode }: BackgroundSelectorProps) {
|
function BackgroundSelector({ isEditMode, disableTheme }: BackgroundSelectorProps) {
|
||||||
const [backgrounds, setBackgrounds] = useState<Background[]>([]);
|
const [backgrounds, setBackgrounds] = useState<Background[]>([]);
|
||||||
const [selectedBackground, setSelectedBackground] = useState<string | null>();
|
const [selectedBackground, setSelectedBackground] = useState<string | null>();
|
||||||
const [downloadedPresetIds, setDownloadedPresetIds] = useState<string[]>([]);
|
const [downloadedPresetIds, setDownloadedPresetIds] = useState<string[]>([]);
|
||||||
@@ -106,13 +104,11 @@ function BackgroundSelector({ selectedType, setSelectedType, isEditMode }: Backg
|
|||||||
};
|
};
|
||||||
|
|
||||||
const selectBackground = (fileId: string): void => {
|
const selectBackground = (fileId: string): void => {
|
||||||
if (selectedType == 'background' && selectedBackground == fileId) {
|
if (selectedBackground == fileId) {
|
||||||
selectNoBackground();
|
selectNoBackground();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
disableTheme();
|
|
||||||
setSelectedType('background');
|
|
||||||
setSelectedBackground(fileId);
|
setSelectedBackground(fileId);
|
||||||
SetTheme(fileId);
|
SetTheme(fileId);
|
||||||
};
|
};
|
||||||
@@ -131,8 +127,6 @@ function BackgroundSelector({ selectedType, setSelectedType, isEditMode }: Backg
|
|||||||
};
|
};
|
||||||
|
|
||||||
const selectNoBackground = (): void => {
|
const selectNoBackground = (): void => {
|
||||||
setSelectedType('background');
|
|
||||||
disableTheme();
|
|
||||||
setSelectedBackground(null);
|
setSelectedBackground(null);
|
||||||
SetTheme('');
|
SetTheme('');
|
||||||
};
|
};
|
||||||
@@ -146,9 +140,10 @@ function BackgroundSelector({ selectedType, setSelectedType, isEditMode }: Backg
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
disabled={selectedBackground == null && selectedType != 'theme' ? true : false}
|
disabled={selectedBackground == null ? true : false}
|
||||||
className={`w-full px-4 py-2 mb-4 dark:text-white transition ${selectedBackground == null && selectedType != 'theme' ? 'dark:bg-zinc-900 bg-zinc-100' : 'bg-blue-500 text-white'} rounded`} onClick={() => selectNoBackground()}>
|
className={`w-full px-4 py-2 mb-4 dark:text-white transition ${selectedBackground == null ? 'dark:bg-zinc-900 bg-zinc-100' : 'bg-blue-500 text-white'} rounded`}
|
||||||
{selectedBackground == null && selectedType != 'theme' ? 'No Background' : 'Remove Background'}
|
onClick={() => { disableTheme(), selectNoBackground() }}>
|
||||||
|
{selectedBackground == null ? 'No Theme' : 'Remove Theme'}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{BackgroundsBlocked && (
|
{BackgroundsBlocked && (
|
||||||
@@ -173,7 +168,7 @@ function BackgroundSelector({ selectedType, setSelectedType, isEditMode }: Backg
|
|||||||
{backgrounds.filter(bg => bg.type === 'image').map(bg => (
|
{backgrounds.filter(bg => bg.type === 'image').map(bg => (
|
||||||
<div key={bg.id}
|
<div key={bg.id}
|
||||||
onClick={() => selectBackground(bg.id)}
|
onClick={() => selectBackground(bg.id)}
|
||||||
className={`relative w-16 h-16 cursor-pointer rounded-xl transition ring dark:ring-white ring-zinc-300 ${isEditMode ? 'animate-shake' : ''} ${selectedBackground === bg.id && selectedType === "background" ? 'dark:ring-2 ring-4' : 'ring-0'}`}>
|
className={`relative w-16 h-16 cursor-pointer rounded-xl transition ring dark:ring-white ring-zinc-300 ${isEditMode ? 'animate-shake' : ''} ${selectedBackground === bg.id ? 'dark:ring-2 ring-4' : 'ring-0'}`}>
|
||||||
{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={() => deleteBackground(bg.id)}>
|
onClick={() => deleteBackground(bg.id)}>
|
||||||
@@ -202,7 +197,7 @@ function BackgroundSelector({ selectedType, setSelectedType, isEditMode }: Backg
|
|||||||
</div>
|
</div>
|
||||||
<img
|
<img
|
||||||
className="absolute top-0 object-cover w-full h-full rounded-xl"
|
className="absolute top-0 object-cover w-full h-full rounded-xl"
|
||||||
src={bg.isPreset ? bg.previewUrl : bg.url} // Use preview for preset backgrounds
|
src={bg.isPreset ? bg.previewUrl : bg.url}
|
||||||
alt="swatch" />
|
alt="swatch" />
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
@@ -219,7 +214,7 @@ function BackgroundSelector({ selectedType, setSelectedType, isEditMode }: Backg
|
|||||||
<input type="file" accept='image/*, video/*' onChange={handleFileChange} className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" />
|
<input type="file" accept='image/*, video/*' onChange={handleFileChange} className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" />
|
||||||
</div>
|
</div>
|
||||||
{backgrounds.filter(bg => bg.type === 'video').map(bg => (
|
{backgrounds.filter(bg => bg.type === 'video').map(bg => (
|
||||||
<div key={bg.id} onClick={() => selectBackground(bg.id)} className={`relative w-16 h-16 cursor-pointer rounded-xl transition ring dark:ring-white ring-zinc-300 ${isEditMode ? 'animate-shake' : ''} ${selectedBackground === bg.id && selectedType === "background" ? 'dark:ring-2 ring-4' : 'ring-0'}`}>
|
<div key={bg.id} onClick={() => selectBackground(bg.id)} className={`relative w-16 h-16 cursor-pointer rounded-xl transition ring dark:ring-white ring-zinc-300 ${isEditMode ? 'animate-shake' : ''} ${selectedBackground === bg.id ? 'dark:ring-2 ring-4' : 'ring-0'}`}>
|
||||||
{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={() => deleteBackground(bg.id)}>
|
onClick={() => deleteBackground(bg.id)}>
|
||||||
|
|||||||
@@ -1,29 +1,25 @@
|
|||||||
import React, { useEffect, useState, useCallback } from 'react';
|
import React, { useEffect, useState, useCallback, forwardRef, useImperativeHandle, ForwardRefExoticComponent, RefAttributes } from 'react';
|
||||||
import { listThemes, deleteTheme, setTheme, disableTheme } from '../hooks/ThemeManagment';
|
import { listThemes, deleteTheme, setTheme, disableTheme } from '../hooks/ThemeManagment';
|
||||||
import { ThemeCover } from './ThemeCover';
|
import { ThemeCover } from './ThemeCover';
|
||||||
import Browser from 'webextension-polyfill';
|
import Browser from 'webextension-polyfill';
|
||||||
import { CustomTheme } from '../types/CustomThemes';
|
import { CustomTheme } from '../types/CustomThemes';
|
||||||
|
|
||||||
interface ThemeSelectorProps {
|
interface ThemeSelectorProps {
|
||||||
setSelectedType: React.Dispatch<React.SetStateAction<'background' | 'theme'>>;
|
|
||||||
selectedType: 'background' | 'theme';
|
|
||||||
isEditMode: boolean;
|
isEditMode: boolean;
|
||||||
|
ref: React.Ref<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ThemeSelector: React.FC<ThemeSelectorProps> = ({
|
const ThemeSelector: ForwardRefExoticComponent<Omit<ThemeSelectorProps, "ref"> & RefAttributes<any>> = forwardRef(({ isEditMode = false }, ref) => {
|
||||||
setSelectedType,
|
|
||||||
selectedType,
|
|
||||||
isEditMode,
|
|
||||||
}) => {
|
|
||||||
const [themes, setThemes] = useState<Omit<CustomTheme, 'CustomImages'>[]>([]);
|
const [themes, setThemes] = useState<Omit<CustomTheme, 'CustomImages'>[]>([]);
|
||||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||||
const [selectedThemeId, setSelectedThemeId] = useState<string | null>(null);
|
const [selectedThemeId, setSelectedThemeId] = useState<string | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useImperativeHandle(ref, () => ({
|
||||||
if (selectedType === 'background') {
|
disableTheme: async () => {
|
||||||
|
await disableTheme();
|
||||||
setSelectedThemeId(null);
|
setSelectedThemeId(null);
|
||||||
}
|
}
|
||||||
}, [selectedType]);
|
}));
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchThemes = async () => {
|
const fetchThemes = async () => {
|
||||||
@@ -49,17 +45,15 @@ const ThemeSelector: React.FC<ThemeSelectorProps> = ({
|
|||||||
if (themeId === selectedThemeId) {
|
if (themeId === selectedThemeId) {
|
||||||
await disableTheme();
|
await disableTheme();
|
||||||
setSelectedThemeId(null);
|
setSelectedThemeId(null);
|
||||||
setSelectedType('background');
|
|
||||||
} else {
|
} else {
|
||||||
const selectedTheme = themes.find((theme) => theme.id === themeId);
|
const selectedTheme = themes.find((theme) => theme.id === themeId);
|
||||||
if (selectedTheme) {
|
if (selectedTheme) {
|
||||||
await setTheme(selectedTheme.id);
|
await setTheme(selectedTheme.id);
|
||||||
setSelectedThemeId(themeId);
|
setSelectedThemeId(themeId);
|
||||||
setSelectedType('theme');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[selectedThemeId, themes, setSelectedType]
|
[selectedThemeId, themes]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleThemeDelete = useCallback(
|
const handleThemeDelete = useCallback(
|
||||||
@@ -69,13 +63,12 @@ const ThemeSelector: React.FC<ThemeSelectorProps> = ({
|
|||||||
setThemes((prevThemes) => prevThemes.filter((theme) => theme.id !== themeId));
|
setThemes((prevThemes) => prevThemes.filter((theme) => theme.id !== themeId));
|
||||||
if (themeId === selectedThemeId) {
|
if (themeId === selectedThemeId) {
|
||||||
setSelectedThemeId(null);
|
setSelectedThemeId(null);
|
||||||
setSelectedType('background');
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error deleting theme:', error);
|
console.error('Error deleting theme:', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[selectedThemeId, setSelectedType]
|
[selectedThemeId]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
@@ -83,9 +76,9 @@ const ThemeSelector: React.FC<ThemeSelectorProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="my-2">
|
<div className="my-3">
|
||||||
<h2 className="pb-2 text-lg font-bold">Themes</h2>
|
<h2 className="pb-2 text-lg font-bold">Themes</h2>
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-2">
|
||||||
{themes.map((theme) => (
|
{themes.map((theme) => (
|
||||||
<ThemeCover
|
<ThemeCover
|
||||||
key={theme.id}
|
key={theme.id}
|
||||||
@@ -107,6 +100,6 @@ const ThemeSelector: React.FC<ThemeSelectorProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
export default ThemeSelector;
|
export default ThemeSelector;
|
||||||
@@ -1,29 +1,23 @@
|
|||||||
import { FC, useEffect, useState } from 'react';
|
import { FC, createRef, useState } from 'react';
|
||||||
import BackgroundSelector from '../../components/BackgroundSelector';
|
import BackgroundSelector from '../../components/BackgroundSelector';
|
||||||
import ThemeSelector from '../../components/ThemeSelector';
|
import ThemeSelector from '../../components/ThemeSelector';
|
||||||
import { listThemes } from '../../hooks/ThemeManagment';
|
|
||||||
|
|
||||||
const Themes: FC = () => {
|
const Themes: FC = () => {
|
||||||
const [isEditMode, setIsEditMode] = useState<boolean>(false);
|
const [isEditMode, setIsEditMode] = useState<boolean>(false);
|
||||||
const [selectedType, setSelectedType] = useState<'background' | 'theme'>('background');
|
const themeSelectorRef = createRef();
|
||||||
|
|
||||||
|
const disableTheme = async () => {
|
||||||
|
themeSelectorRef?.current?.disableTheme();
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
listThemes().then(themes => {
|
|
||||||
if (themes?.selectedTheme) {
|
|
||||||
setSelectedType('theme');
|
|
||||||
} else {
|
|
||||||
setSelectedType('background');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="px-0.5">
|
<div className="px-0.5">
|
||||||
<button className="absolute top-12 z-20 right-0 p-2 text-[0.8rem] text-blue-500" onClick={() => setIsEditMode(!isEditMode)}>
|
<button className="absolute top-12 z-20 right-0 p-2 text-[0.8rem] text-blue-500" onClick={() => setIsEditMode(!isEditMode)}>
|
||||||
{isEditMode ? 'Done' : 'Edit'}
|
{isEditMode ? 'Done' : 'Edit'}
|
||||||
</button>
|
</button>
|
||||||
<BackgroundSelector setSelectedType={setSelectedType} selectedType={selectedType} isEditMode={isEditMode} />
|
<BackgroundSelector disableTheme={disableTheme} isEditMode={isEditMode} />
|
||||||
<ThemeSelector selectedType={selectedType} setSelectedType={setSelectedType} isEditMode={isEditMode} />
|
<ThemeSelector ref={themeSelectorRef} isEditMode={isEditMode} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user