diff --git a/src/svelte-interface/pages/themeCreator.svelte b/src/svelte-interface/pages/themeCreator.svelte index 8e34c041..cb9c858c 100644 --- a/src/svelte-interface/pages/themeCreator.svelte +++ b/src/svelte-interface/pages/themeCreator.svelte @@ -14,6 +14,12 @@ import ColourPicker from '../components/ColourPicker.svelte' import CodeEditor from '../components/CodeEditor.svelte' + import { + handleImageUpload, + handleRemoveImage, + handleImageVariableChange, + handleCoverImageUpload + } from '../utils/themeImageHandlers'; const { themeID } = $props<{ themeID: string }>() let theme = $state({ @@ -38,8 +44,24 @@ } }); + async function onImageUpload(event: Event) { + theme = await handleImageUpload(event, theme); + } + + function onRemoveImage(imageId: string) { + theme = handleRemoveImage(imageId, theme); + } + + function onImageVariableChange(imageId: string, variableName: string) { + theme = handleImageVariableChange(imageId, variableName, theme); + } + + async function onCoverImageUpload(event: Event) { + theme = await handleCoverImageUpload(event, theme); + } + $effect(() => { - console.log(theme) + }) type SettingType = 'switch' | 'button' | 'slider' | 'colourPicker' | 'select' | 'codeEditor'; @@ -157,5 +179,44 @@ ] as SettingItem[] as setting} {@render settingItem(setting)} {/each} + +
+
+ \ueb44 +
+ {theme.coverImage ? 'Change' : 'Add'} cover image + + {#if !theme.hideThemeName && theme.coverImage} +
{theme.name}
+ {/if} + {#if theme.coverImage} +
+ Cover + {/if} +
+ + {#each theme.CustomImages as image (image.id)} +
+
+ {image.variableName} +
+ onImageVariableChange(image.id, e.currentTarget.value)} + placeholder="CSS Variable Name" + class="flex-grow flex-[3] 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-800/50 dark:text-white" + /> + +
+ {/each} + +
+ + Add image + +
diff --git a/src/svelte-interface/utils/themeImageHandlers.ts b/src/svelte-interface/utils/themeImageHandlers.ts new file mode 100644 index 00000000..2f555f5d --- /dev/null +++ b/src/svelte-interface/utils/themeImageHandlers.ts @@ -0,0 +1,60 @@ +import type { CustomTheme } from '@/types/CustomThemes'; + +export function generateImageId(): string { + return Math.random().toString(36).substr(2, 9); +} + +export function handleImageUpload(event: Event, theme: CustomTheme): Promise | CustomTheme { + const input = event.target as HTMLInputElement; + const file = input.files?.[0]; + input.value = ''; + if (file) { + return new Promise((resolve) => { + 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}`; + resolve({ + ...theme, + CustomImages: [...theme.CustomImages, { id: imageId, blob: imageBlob, variableName }], + }); + }; + reader.readAsDataURL(file); + }); + } + return theme; +} + +export function handleRemoveImage(imageId: string, theme: CustomTheme): CustomTheme { + return { + ...theme, + CustomImages: theme.CustomImages.filter((image) => image.id !== imageId), + }; +} + +export function handleImageVariableChange(imageId: string, variableName: string, theme: CustomTheme): CustomTheme { + return { + ...theme, + CustomImages: theme.CustomImages.map((image) => + image.id === imageId ? { ...image, variableName } : image + ), + }; +} + +export function handleCoverImageUpload(event: Event, theme: CustomTheme): Promise { + const input = event.target as HTMLInputElement; + const file = input.files?.[0]; + input.value = ''; + if (file) { + return new Promise((resolve) => { + const reader = new FileReader(); + reader.onload = async () => { + const imageBlob = await fetch(reader.result as string).then(res => res.blob()); + resolve({ ...theme, coverImage: imageBlob }); + }; + reader.readAsDataURL(file); + }); + } + return Promise.resolve(theme); +} \ No newline at end of file