import CodeEditor from '../components/CodeEditor'; import { useEffect, useState } from 'react'; import ColorPicker from 'react-best-gradient-color-picker'; import Accordion from '../components/Accordian'; import Switch from '../components/Switch'; import { sendThemeUpdate } from '../hooks/ThemeManagment'; import { PlusIcon, XMarkIcon } from '@heroicons/react/24/outline'; import { v4 as uuidv4 } from 'uuid'; import { CustomTheme, CustomThemeBase64 } from '../types/CustomThemes'; import browser from 'webextension-polyfill'; function ThemeCreator() { // default settings for new themes const [theme, setTheme] = useState({ id: uuidv4(), name: '', description: '', defaultColour: '', CanChangeColour: true, allowBackgrounds: true, CustomCSS: '', CustomImages: [], coverImage: null, isEditable: true, hideThemeName: false, }); useEffect(() => { const getTheme = async (themeID: string) => { const theme = await browser.runtime.sendMessage({ type: 'currentTab', info: 'GetTheme', body: { themeID: themeID, } }) as CustomThemeBase64 | undefined; if (theme) { // base64toblob to convert it to a blob url const CustomImages = theme.CustomImages.map((image) => { const base64Index = image.url.indexOf(',') + 1; const imageBase64 = image.url.substring(base64Index); // Convert base64 to blob const byteCharacters = atob(imageBase64); const byteNumbers = new Uint8Array(byteCharacters.length); for (let i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); const blob = new Blob([byteArray], { type: 'image/png' }); return { id: image.id, blob: blob, variableName: image.variableName, }; }); const coverImageBase64 = theme.coverImage; let coverImageBlob = null; if (coverImageBase64) { const base64Index = coverImageBase64.indexOf(',') + 1; const imageBase64 = coverImageBase64.substring(base64Index); // Convert base64 to blob const byteCharacters = atob(imageBase64); const byteNumbers = new Uint8Array(byteCharacters.length); for (let i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); coverImageBlob = new Blob([byteArray], { type: 'image/png' }); } setTheme({ ...theme, CustomImages, coverImage: coverImageBlob }); sendThemeUpdate({ ...theme, CustomImages: CustomImages, }, false, true); } }; // get ThemeID from URL params const urlParams = new URLSearchParams(window.location.search); const themeID = urlParams.get('themeID'); if (themeID) { getTheme(themeID); } }, []); const generateImageId = () => { return Math.random().toString(36).substr(2, 9); }; const handleImageUpload = (event: React.ChangeEvent) => { const file = event.target.files?.[0]; event.target.value = ''; if (file) { const reader = new FileReader(); reader.onload = async () => { const imageBlob = await fetch(reader.result as string).then(res => res.blob()); const imageId = generateImageId(); const variableName = `custom-image-${theme.CustomImages.length}`; const updatedTheme = { ...theme, CustomImages: [...theme.CustomImages, { id: imageId, blob: imageBlob, variableName }], }; setTheme(updatedTheme); sendThemeUpdate(updatedTheme, false, true); }; reader.readAsDataURL(file); } }; const handleRemoveImage = (imageId: string) => { const updatedTheme = { ...theme, CustomImages: theme.CustomImages.filter((image) => image.id !== imageId), }; setTheme(updatedTheme); }; const handleImageVariableChange = (imageId: string, variableName: string) => { const updatedTheme = { ...theme, CustomImages: theme.CustomImages.map((image) => image.id === imageId ? { ...image, variableName } : image ), }; setTheme(updatedTheme); }; function CodeUpdate(value: string) { setTheme((prevTheme) => ({ ...prevTheme, CustomCSS: value, })); } const saveTheme = async () => { sendThemeUpdate(theme, true) }; useEffect(() => { sendThemeUpdate(theme); }, [theme]); return (

Theme Creator

Theme Name
setTheme({ ...theme, name: e.target.value })} className='w-full p-2 mb-4 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' />
Description (optional)