feat(ThemePreview): update to follow blob format

This commit is contained in:
SethBurkart123
2024-10-05 20:17:31 +10:00
parent 33e34a0552
commit 818ff48a0d
7 changed files with 86 additions and 91 deletions
+3
View File
@@ -38,6 +38,7 @@ import documentLoadCSS from '@/css/documentload.scss?inline'
import renderSvelte from '@/svelte-interface/main' import renderSvelte from '@/svelte-interface/main'
import Settings from '@/svelte-interface/pages/settings.svelte' import Settings from '@/svelte-interface/pages/settings.svelte'
import { settingsPopup } from './svelte-interface/hooks/SettingsPopup' import { settingsPopup } from './svelte-interface/hooks/SettingsPopup'
import { OpenThemeCreator } from './seqta/ui/ThemeCreator'
let SettingsClicked = false let SettingsClicked = false
export let MenuOptionsOpen = false export let MenuOptionsOpen = false
@@ -461,6 +462,8 @@ export async function finishLoad() {
console.error("Error during loading cleanup:", err); console.error("Error during loading cleanup:", err);
} }
OpenThemeCreator()
if (settingsState.justupdated && !document.getElementById('whatsnewbk')) { if (settingsState.justupdated && !document.getElementById('whatsnewbk')) {
OpenWhatsNewPopup(); OpenWhatsNewPopup();
} }
+6 -1
View File
@@ -1,6 +1,7 @@
import renderSvelte from "@/svelte-interface/main" import renderSvelte from "@/svelte-interface/main"
import themeCreator from "@/svelte-interface/pages/themeCreator.svelte" import themeCreator from "@/svelte-interface/pages/themeCreator.svelte"
import { unmount } from "svelte" import { unmount } from "svelte"
import { ClearThemePreview } from "./themes/UpdateThemePreview"
let themeCreatorSvelteApp: any = null let themeCreatorSvelteApp: any = null
@@ -30,7 +31,11 @@ export function OpenThemeCreator(themeID: string = "") {
const closeButton = document.createElement("button") const closeButton = document.createElement("button")
closeButton.classList.add("themeCloseButton") closeButton.classList.add("themeCloseButton")
closeButton.textContent = "×" closeButton.textContent = "×"
closeButton.addEventListener("click", CloseThemeCreator) closeButton.addEventListener("click", () => {
CloseThemeCreator()
ClearThemePreview()
})
document.body.appendChild(closeButton) document.body.appendChild(closeButton)
const resizeBar = document.createElement("div") const resizeBar = document.createElement("div")
-12
View File
@@ -1,17 +1,5 @@
import { base64toblobURL } from '@/seqta/utils/imageConversions';
export const imageData: Record<string, { url: string; variableName: string }> = {}; export const imageData: Record<string, { url: string; variableName: string }> = {};
export const UpdateImageData = (image: { id: string; base64: string }) => {
const { id, base64 } = image;
if (imageData[id]) {
imageData[id].url = base64toblobURL(base64);
const { variableName } = imageData[id];
document.documentElement.style.setProperty('--' + variableName, `url(${imageData[id].url})`);
}
};
export function applyCustomCSS(customCSS: string) { export function applyCustomCSS(customCSS: string) {
let styleElement = document.getElementById('custom-theme'); let styleElement = document.getElementById('custom-theme');
if (!styleElement) { if (!styleElement) {
+55 -45
View File
@@ -1,65 +1,75 @@
import type { CustomThemeBase64 } from '@/types/CustomThemes'; import type { LoadedCustomTheme } from '@/types/CustomThemes';
import { applyCustomCSS, imageData, removeImageFromDocument, UpdateImageData } from './Themes'; import { applyCustomCSS, removeImageFromDocument } from './Themes';
import { settingsState } from '@/seqta/utils/listeners/SettingsState'; import { settingsState } from '@/seqta/utils/listeners/SettingsState';
let previousImageVariableNames: string[] = [];
let originalColor: string | null = null;
let originalTheme: boolean | null = null;
export const UpdateThemePreview = async (updatedTheme: CustomThemeBase64 /* Omit<CustomTheme, 'CustomImages'> & { CustomImages: Omit<CustomImage, 'blob'>[] } */) => { export const UpdateThemePreview = async (updatedTheme: LoadedCustomTheme) => {
const { CustomCSS, CustomImages, defaultColour } = updatedTheme; const { CustomCSS, CustomImages, defaultColour, forceDark } = updatedTheme;
if (updatedTheme.forceDark != undefined) { // Update dark mode setting
if (updatedTheme.forceDark) { if (forceDark !== undefined) {
settingsState.DarkMode = true; // Store the original theme if it hasn't been stored yet
} else { if (originalTheme === null) {
settingsState.DarkMode = false; originalTheme = settingsState.DarkMode;
} }
settingsState.DarkMode = forceDark;
} }
// Update image data // Get the new image variable names
const currentImageIds = Object.keys(imageData); const newImageVariableNames = CustomImages.map(image => image.variableName);
const updatedImageIds = CustomImages.map((image) => image.id);
// Remove unused images from imageData and document // Remove images that are no longer present
currentImageIds.forEach((imageId) => { previousImageVariableNames.forEach(variableName => {
if (!updatedImageIds.includes(imageId)) { if (!newImageVariableNames.includes(variableName)) {
const { variableName } = imageData[imageId];
removeImageFromDocument(variableName); removeImageFromDocument(variableName);
delete imageData[imageId];
} }
}); });
// Update or add new images to imageData // Update or add new images
CustomImages.forEach((image) => { CustomImages.forEach((image: any) => {
const existingImage = imageData[image.id]; document.documentElement.style.setProperty(`--${image.variableName}`, `url(${image.url})`);
if (existingImage && existingImage.variableName !== image.variableName) {
// Remove the previous variableName from the document
removeImageFromDocument(existingImage.variableName);
// Update the variableName in imageData
imageData[image.id].variableName = image.variableName;
// Update the variableName in the document
document.documentElement.style.setProperty('--' + image.variableName, `url(${existingImage.url})`);
}
if (image.url) {
UpdateImageData({
id: image.id,
base64: image.url
});
}
imageData[image.id] = {
url: imageData[image.id]?.url || '',
variableName: image.variableName,
};
}); });
// Update the previousImageVariableNames for the next run
previousImageVariableNames = newImageVariableNames;
// Apply custom CSS // Apply custom CSS
applyCustomCSS(CustomCSS); applyCustomCSS(CustomCSS);
// Apply default color // Apply default color
if (defaultColour !== '') { if (defaultColour) {
settingsState.selectedColor = defaultColour // Store the original color if it hasn't been stored yet
if (originalColor === null) {
originalColor = settingsState.selectedColor;
}
settingsState.selectedColor = defaultColour;
} }
}; };
export const ClearThemePreview = () => {
previousImageVariableNames.forEach(variableName => {
removeImageFromDocument(variableName);
});
previousImageVariableNames = [];
let styleElement = document.getElementById('custom-theme');
if (styleElement) {
styleElement.remove();
}
// Reset the color to the original value
if (originalColor !== null) {
settingsState.selectedColor = originalColor;
originalColor = null;
}
// Reset the theme (dark/light mode) to the original value
if (originalTheme !== null) {
settingsState.DarkMode = originalTheme;
originalTheme = null;
}
}
+7 -16
View File
@@ -1,27 +1,18 @@
import localforage from 'localforage'; import localforage from 'localforage';
import type { CustomTheme, CustomThemeBase64 } from '@/types/CustomThemes'; import type { LoadedCustomTheme } from '@/types/CustomThemes';
import { disableTheme } from './disableTheme'; import { disableTheme } from './disableTheme';
export const saveTheme = async (theme: CustomThemeBase64) => { export const saveTheme = async (theme: LoadedCustomTheme) => {
try { try {
const updatedTheme: CustomTheme = {
...theme,
coverImage: theme.coverImage ? await fetch(theme.coverImage).then((res) => res.blob()) : null,
CustomImages: await Promise.all(
theme.CustomImages.map(async (image) => ({
id: image.id,
blob: await fetch(image.url).then((res) => res.blob()),
variableName: image.variableName,
}))
),
};
disableTheme(); disableTheme();
console.debug('Theme to save:', updatedTheme); console.debug('Theme to save:', theme);
await localforage.setItem(updatedTheme.id, updatedTheme); /* remove blob urls from theme */
const updatedTheme = { ...theme, CustomImages: theme.CustomImages.map((image) => ({ ...image, blob: null })) }
await localforage.setItem(theme.id, updatedTheme);
await localforage.getItem('customThemes').then((themes: unknown) => { await localforage.getItem('customThemes').then((themes: unknown) => {
const themeList = themes as string[] | null; const themeList = themes as string[] | null;
if (themeList) { if (themeList) {
+13 -4
View File
@@ -22,6 +22,9 @@
handleImageVariableChange, handleImageVariableChange,
handleCoverImageUpload handleCoverImageUpload
} from '../utils/themeImageHandlers'; } from '../utils/themeImageHandlers';
import { ClearThemePreview, UpdateThemePreview } from '@/seqta/ui/themes/UpdateThemePreview'
import { saveTheme } from '@/seqta/ui/themes/saveTheme'
import { CloseThemeCreator } from '@/seqta/ui/ThemeCreator'
const { themeID } = $props<{ themeID: string }>() const { themeID } = $props<{ themeID: string }>()
let theme = $state<LoadedCustomTheme>({ let theme = $state<LoadedCustomTheme>({
@@ -83,8 +86,16 @@
theme = await handleCoverImageUpload(event, theme); theme = await handleCoverImageUpload(event, theme);
} }
$effect(() => { function submitTheme() {
console.log('saving theme', theme)
ClearThemePreview();
saveTheme(theme);
CloseThemeCreator();
}
$effect(() => {
UpdateThemePreview(theme);
}); });
type SettingType = 'switch' | 'button' | 'slider' | 'colourPicker' | 'select' | 'codeEditor' | 'imageUpload' | 'conditional' | 'lightDarkToggle'; type SettingType = 'switch' | 'button' | 'slider' | 'colourPicker' | 'select' | 'codeEditor' | 'imageUpload' | 'conditional' | 'lightDarkToggle';
@@ -314,9 +325,7 @@
{/each} {/each}
<button <button
onclick={() => { onclick={submitTheme}
console.log(theme)
}}
class="w-full px-4 py-2 mt-3 text-[13px] dark:text-white transition rounded-xl bg-zinc-200 dark:bg-zinc-700/50"> class="w-full px-4 py-2 mt-3 text-[13px] dark:text-white transition rounded-xl bg-zinc-200 dark:bg-zinc-700/50">
Save Theme Save Theme
</button> </button>
+2 -13
View File
@@ -16,12 +16,12 @@ export type CustomTheme = {
} }
export type LoadedCustomTheme = CustomTheme & { export type LoadedCustomTheme = CustomTheme & {
CustomImages: Array<{ CustomImages: {
id: string; id: string;
blob: Blob; blob: Blob;
variableName: string; variableName: string;
url: string | null; url: string | null;
}>; }[];
coverImageUrl?: string; coverImageUrl?: string;
}; };
@@ -35,17 +35,6 @@ export type CustomImage = {
variableName: string; variableName: string;
} }
export type CustomImageBase64 = {
id: string;
url: string;
variableName: string;
}
export type CustomThemeBase64 = Omit<CustomTheme, 'CustomImages'> & {
CustomImages: CustomImageBase64[];
coverImage: string | null;
}
export type ThemeList = { export type ThemeList = {
themes: CustomTheme[]; themes: CustomTheme[];
selectedTheme: string; selectedTheme: string;