mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
custom themes: auto remove unused css variables
This commit is contained in:
@@ -26,7 +26,7 @@ export default function ThemeCreator() {
|
|||||||
reader.onload = () => {
|
reader.onload = () => {
|
||||||
const imageUrl = reader.result as string;
|
const imageUrl = reader.result as string;
|
||||||
const imageId = generateImageId();
|
const imageId = generateImageId();
|
||||||
const variableName = `--custom-image-${theme.CustomImages.length}`;
|
const variableName = `custom-image-${theme.CustomImages.length}`;
|
||||||
const updatedTheme = {
|
const updatedTheme = {
|
||||||
...theme,
|
...theme,
|
||||||
CustomImages: [...theme.CustomImages, { id: imageId, url: imageUrl, variableName }],
|
CustomImages: [...theme.CustomImages, { id: imageId, url: imageUrl, variableName }],
|
||||||
@@ -57,9 +57,11 @@ export default function ThemeCreator() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function CodeUpdate(value: string) {
|
function CodeUpdate(value: string) {
|
||||||
const updatedTheme = { ...theme, CustomCSS: value };
|
setTheme((prevTheme) => ({
|
||||||
setTheme(updatedTheme);
|
...prevTheme,
|
||||||
}
|
CustomCSS: value,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
sendThemeUpdate(theme);
|
sendThemeUpdate(theme);
|
||||||
@@ -113,25 +115,29 @@ export default function ThemeCreator() {
|
|||||||
|
|
||||||
<div className='h-4'></div>
|
<div className='h-4'></div>
|
||||||
|
|
||||||
<Accordion defaultOpened title='Custom Images'>
|
{theme.CustomImages.map((image, index) => (
|
||||||
{theme.CustomImages.map((image, index) => (
|
<div key={image.id} className="flex items-center p-2 mb-4 bg-white rounded-lg shadow dark:bg-zinc-900">
|
||||||
<div key={image.id}>
|
<div className="flex-grow mr-4">
|
||||||
<img src={image.url} alt={`Custom Image ${index + 1}`} />
|
<img src={image.url} alt={`Custom Image ${index + 1}`} className="object-contain w-auto rounded max-h-32" />
|
||||||
<input
|
|
||||||
type='text'
|
|
||||||
value={image.variableName}
|
|
||||||
onChange={(e) => handleImageVariableChange(image.id, e.target.value)}
|
|
||||||
placeholder='CSS Variable Name'
|
|
||||||
/>
|
|
||||||
<button onClick={() => handleRemoveImage(image.id)}>Remove</button>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
<input
|
||||||
<input
|
type="text"
|
||||||
type='file'
|
value={image.variableName}
|
||||||
accept='image/*'
|
onChange={(e) => handleImageVariableChange(image.id, e.target.value)}
|
||||||
onChange={handleImageUpload}
|
placeholder="CSS Variable Name"
|
||||||
/>
|
className="flex-grow w-full p-2 transition-all duration-300 rounded-lg focus:outline-none ring-0 focus:ring-1 ring-zinc-100 dark:ring-zinc-700 dark:bg-zinc-900 dark:text-white"
|
||||||
</Accordion>
|
/>
|
||||||
|
<button onClick={() => handleRemoveImage(image.id)} className="px-4 py-2 ml-4 text-sm text-white transition bg-red-500 rounded hover:bg-red-600 dark:text-white">
|
||||||
|
Remove
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<input
|
||||||
|
type='file'
|
||||||
|
accept='image/*'
|
||||||
|
onChange={handleImageUpload}
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
<div className='h-4'></div>
|
<div className='h-4'></div>
|
||||||
|
|||||||
+53
-25
@@ -161,51 +161,80 @@ export const disableTheme = async () => {
|
|||||||
localforage.removeItem('selectedTheme');
|
localforage.removeItem('selectedTheme');
|
||||||
};
|
};
|
||||||
|
|
||||||
let imageData: CustomImage[] = [];
|
const imageData: Record<string, { url: string; variableName: string }> = {};
|
||||||
let previousTheme: CustomTheme = null;
|
|
||||||
|
|
||||||
export const UpdateThemePreview = async (updatedTheme: CustomTheme) => {
|
export const UpdateThemePreview = async (updatedTheme: CustomTheme) => {
|
||||||
console.log(updatedTheme)
|
console.log(updatedTheme);
|
||||||
|
|
||||||
if (updatedTheme.CustomImages.length !== imageData.length) {
|
|
||||||
updatedTheme.CustomImages.forEach((image) => {
|
|
||||||
updateImage(image.id, image.url);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const { CustomCSS, CustomImages, defaultColour } = updatedTheme;
|
const { CustomCSS, CustomImages, defaultColour } = updatedTheme;
|
||||||
|
|
||||||
|
// Update image data
|
||||||
|
const currentImageIds = Object.keys(imageData);
|
||||||
|
const updatedImageIds = CustomImages.map((image) => image.id);
|
||||||
|
|
||||||
|
// Remove unused images from imageData and document
|
||||||
|
currentImageIds.forEach((imageId) => {
|
||||||
|
if (!updatedImageIds.includes(imageId)) {
|
||||||
|
const { variableName } = imageData[imageId];
|
||||||
|
removeImageFromDocument(variableName);
|
||||||
|
delete imageData[imageId];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update or add new images to imageData
|
||||||
|
CustomImages.forEach((image) => {
|
||||||
|
const existingImage = imageData[image.id];
|
||||||
|
|
||||||
|
if (existingImage && existingImage.variableName !== image.variableName) {
|
||||||
|
// Remove the previous variableName from the document
|
||||||
|
removeImageFromDocument(existingImage.variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
imageData[image.id] = {
|
||||||
|
url: updateImage(image),
|
||||||
|
variableName: image.variableName,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
// Apply custom CSS
|
// Apply custom CSS
|
||||||
let styleElement = document.getElementById('theme-preview-styles');
|
applyCustomCSS(CustomCSS);
|
||||||
if (!styleElement) {
|
|
||||||
styleElement = document.createElement('style');
|
|
||||||
styleElement.id = 'theme-preview-styles';
|
|
||||||
document.head.appendChild(styleElement);
|
|
||||||
}
|
|
||||||
styleElement.textContent = CustomCSS;
|
|
||||||
|
|
||||||
// Apply default color
|
// Apply default color
|
||||||
if (defaultColour !== '') {
|
if (defaultColour !== '') {
|
||||||
browser.storage.local.set({ selectedColor: defaultColour });
|
browser.storage.local.set({ selectedColor: defaultColour });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply custom images
|
||||||
CustomImages.forEach((image) => {
|
CustomImages.forEach((image) => {
|
||||||
// @ts-expect-error - not sure why its yelling at me :(
|
const imageUrl = imageData[image.id]?.url;
|
||||||
const imageUrl = imageData[image.id];
|
|
||||||
if (imageUrl) {
|
if (imageUrl) {
|
||||||
document.documentElement.style.setProperty(image.variableName, `url(${imageUrl})`);
|
document.documentElement.style.setProperty('--' + image.variableName, `url(${imageUrl})`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function applyCustomCSS(customCSS: string) {
|
||||||
|
let styleElement = document.getElementById('theme-preview-styles');
|
||||||
|
if (!styleElement) {
|
||||||
|
styleElement = document.createElement('style');
|
||||||
|
styleElement.id = 'theme-preview-styles';
|
||||||
|
document.head.appendChild(styleElement);
|
||||||
|
}
|
||||||
|
styleElement.textContent = customCSS;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateImage(imageId: string, imageDataURI: string) {
|
function removeImageFromDocument(variableName: string) {
|
||||||
|
document.documentElement.style.removeProperty('--' + variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateImage(image: CustomImage) {
|
||||||
// Extract base64 data from the data URI
|
// Extract base64 data from the data URI
|
||||||
const base64Index = imageDataURI.indexOf(',') + 1;
|
const base64Index = image.url.indexOf(',') + 1;
|
||||||
const imageBase64 = imageDataURI.substring(base64Index);
|
const imageBase64 = image.url.substring(base64Index);
|
||||||
|
|
||||||
// Convert base64 to blob
|
// Convert base64 to blob
|
||||||
const byteCharacters = atob(imageBase64);
|
const byteCharacters = atob(imageBase64);
|
||||||
const byteNumbers = new Array(byteCharacters.length);
|
const byteNumbers = new Uint8Array(byteCharacters.length);
|
||||||
for (let i = 0; i < byteCharacters.length; i++) {
|
for (let i = 0; i < byteCharacters.length; i++) {
|
||||||
byteNumbers[i] = byteCharacters.charCodeAt(i);
|
byteNumbers[i] = byteCharacters.charCodeAt(i);
|
||||||
}
|
}
|
||||||
@@ -215,6 +244,5 @@ export function updateImage(imageId: string, imageDataURI: string) {
|
|||||||
// Convert blob to blob URL
|
// Convert blob to blob URL
|
||||||
const imageUrl = URL.createObjectURL(blob);
|
const imageUrl = URL.createObjectURL(blob);
|
||||||
|
|
||||||
// @ts-expect-error - same problem 😭
|
return imageUrl;
|
||||||
imageData[imageId] = imageUrl;
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user