mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
fix(colourPicker): saving presets list at incorrect times
This commit is contained in:
@@ -52,6 +52,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@bedframe/cli": "^0.0.85",
|
||||
"@codemirror/lang-css": "^6.3.0",
|
||||
"@codemirror/lang-less": "^6.0.2",
|
||||
"@million/lint": "latest",
|
||||
"@sveltejs/vite-plugin-svelte": "4.0.0-next.7",
|
||||
@@ -70,6 +71,7 @@
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"classnames": "^2.5.1",
|
||||
"codemirror": "^6.0.1",
|
||||
"color": "^4.2.3",
|
||||
"dompurify": "^3.1.6",
|
||||
"idb": "^8.0.0",
|
||||
|
||||
@@ -1,4 +1,70 @@
|
||||
<script lang="ts">
|
||||
import { EditorState } from '@codemirror/state';
|
||||
import { highlightSelectionMatches } from '@codemirror/search';
|
||||
import { indentWithTab, history, defaultKeymap, historyKeymap } from '@codemirror/commands';
|
||||
import { foldGutter, indentOnInput, indentUnit, bracketMatching, foldKeymap, syntaxHighlighting, defaultHighlightStyle } from '@codemirror/language';
|
||||
import { closeBrackets, autocompletion, closeBracketsKeymap, completionKeymap } from '@codemirror/autocomplete';
|
||||
import { lineNumbers, highlightActiveLineGutter, highlightSpecialChars, drawSelection, rectangularSelection, crosshairCursor, highlightActiveLine, keymap, EditorView } from '@codemirror/view'; // dropCursor
|
||||
|
||||
// Theme
|
||||
import { oneDark } from "@codemirror/theme-one-dark";
|
||||
|
||||
// Language
|
||||
import { css } from "@codemirror/lang-css";
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
function createEditorState(initialContents: string, options = {}) {
|
||||
let extensions = [
|
||||
/* lineNumbers(),
|
||||
highlightActiveLineGutter(),
|
||||
highlightSpecialChars(),
|
||||
history(),
|
||||
foldGutter(),
|
||||
drawSelection(),
|
||||
indentUnit.of(" "),
|
||||
EditorState.allowMultipleSelections.of(true),
|
||||
indentOnInput(),
|
||||
bracketMatching(),
|
||||
closeBrackets(),
|
||||
autocompletion(),
|
||||
rectangularSelection(),
|
||||
crosshairCursor(),
|
||||
highlightActiveLine(),
|
||||
highlightSelectionMatches(),
|
||||
keymap.of([
|
||||
indentWithTab,
|
||||
...closeBracketsKeymap,
|
||||
...defaultKeymap,
|
||||
...historyKeymap,
|
||||
...foldKeymap,
|
||||
...completionKeymap,
|
||||
]), */
|
||||
css(),
|
||||
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
|
||||
];
|
||||
|
||||
/* if (options.oneDark)
|
||||
extensions.push(oneDark); */
|
||||
|
||||
return EditorState.create({
|
||||
doc: initialContents,
|
||||
extensions
|
||||
});
|
||||
}
|
||||
|
||||
function createEditorView(state: any, parent: HTMLElement) {
|
||||
return new EditorView({ state, parent });
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
const editor = document.querySelector('#cm-target');
|
||||
if (editor) {
|
||||
const state = createEditorState('body {\n color: red;\n}');
|
||||
const view = createEditorView(state, editor as HTMLElement);
|
||||
|
||||
console.log(view)
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div>Code Editor Here</div>
|
||||
<div id="cm-target"></div>
|
||||
|
||||
@@ -5,16 +5,18 @@
|
||||
import { animate, spring } from 'motion';
|
||||
import { delay } from '@/seqta/utils/delay.ts'
|
||||
|
||||
const { hidePicker, standalone = false } = $props<{
|
||||
const { hidePicker, standalone = false, savePresets = true } = $props<{
|
||||
hidePicker?: () => void,
|
||||
standalone?: boolean
|
||||
standalone?: boolean,
|
||||
savePresets?: boolean
|
||||
}>();
|
||||
|
||||
let background: HTMLDivElement;
|
||||
let content: HTMLDivElement;
|
||||
let background = $state<HTMLDivElement | null>(null);
|
||||
let content = $state<HTMLDivElement | null>(null);
|
||||
|
||||
const closePicker = async () => {
|
||||
if (standalone) return;
|
||||
if (!background || !content) return;
|
||||
|
||||
animate(
|
||||
content,
|
||||
@@ -34,6 +36,7 @@
|
||||
|
||||
onMount(() => {
|
||||
if (standalone) return;
|
||||
if (!background || !content) return;
|
||||
|
||||
animate(
|
||||
background,
|
||||
@@ -69,7 +72,7 @@
|
||||
|
||||
{#if standalone}
|
||||
<div class="h-auto rounded-xl overflow-clip">
|
||||
<ReactAdapter el={ColourPicker} />
|
||||
<ReactAdapter savePresets={savePresets} el={ColourPicker} />
|
||||
</div>
|
||||
{:else}
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
@@ -83,7 +86,7 @@
|
||||
bind:this={content}
|
||||
class="h-auto p-4 bg-white border shadow-lg cursor-auto rounded-xl dark:bg-zinc-800 border-zinc-100 dark:border-zinc-700"
|
||||
>
|
||||
<ReactAdapter el={ColourPicker} />
|
||||
<ReactAdapter savePresets={savePresets} el={ColourPicker} />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import ColorPicker from "react-best-gradient-color-picker"
|
||||
import React, { useEffect, useState } from "react"
|
||||
import React, { useEffect, useState, useRef } from "react"
|
||||
import { settingsState } from "@/seqta/utils/listeners/SettingsState.ts"
|
||||
|
||||
const defaultPresets = [
|
||||
@@ -35,13 +35,23 @@ export default function Picker({
|
||||
customState,
|
||||
savePresets = true,
|
||||
}: PickerProps) {
|
||||
const [customThemeColor, setCustomThemeColor] = useState<string | null>(
|
||||
() => customState ?? settingsState.selectedColor ?? null
|
||||
)
|
||||
const [presets, setPresets] = useState<string[]>(() => {
|
||||
const savedPresets = localStorage.getItem("colorPickerPresets")
|
||||
return savedPresets ? JSON.parse(savedPresets) : defaultPresets
|
||||
})
|
||||
const [customThemeColor, setCustomThemeColor] = useState<string | null>()
|
||||
const [presets, setPresets] = useState<string[]>()
|
||||
|
||||
const latestValuesRef = useRef({ customThemeColor, customOnChange, savePresets, presets });
|
||||
|
||||
useEffect(() => {
|
||||
if (customState !== undefined) {
|
||||
setCustomThemeColor(customState)
|
||||
} else {
|
||||
setCustomThemeColor(settingsState.selectedColor ?? null)
|
||||
}
|
||||
|
||||
if (presets === undefined) {
|
||||
const savedPresets = localStorage.getItem("colorPickerPresets")
|
||||
setPresets(savedPresets ? JSON.parse(savedPresets) : defaultPresets)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (customState !== undefined) {
|
||||
@@ -50,32 +60,34 @@ export default function Picker({
|
||||
}, [customState])
|
||||
|
||||
useEffect(() => {
|
||||
if (customThemeColor && !customOnChange && savePresets) {
|
||||
return () => {
|
||||
// Check if the selected color is already in the presets
|
||||
const existingIndex = presets.indexOf(customThemeColor)
|
||||
latestValuesRef.current = { customThemeColor, customOnChange, savePresets, presets };
|
||||
}, [customThemeColor, customOnChange, savePresets, presets]);
|
||||
|
||||
let updatedPresets
|
||||
if (existingIndex > -1) {
|
||||
// If the color exists, move it to the front
|
||||
updatedPresets = [
|
||||
customThemeColor,
|
||||
...presets.slice(0, existingIndex),
|
||||
...presets.slice(existingIndex + 1),
|
||||
]
|
||||
} else {
|
||||
// If the color is new, add it to the front and slice the array
|
||||
updatedPresets = [customThemeColor, ...presets].slice(0, 18)
|
||||
}
|
||||
|
||||
setPresets(updatedPresets)
|
||||
localStorage.setItem(
|
||||
"colorPickerPresets",
|
||||
JSON.stringify(updatedPresets),
|
||||
)
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
const { customThemeColor, customOnChange, savePresets, presets } = latestValuesRef.current;
|
||||
if (!(customThemeColor && !customOnChange && savePresets)) return;
|
||||
|
||||
// Only proceed if presets are different (avoid unnecessary updates)
|
||||
const existingIndex = presets.indexOf(customThemeColor);
|
||||
let updatedPresets;
|
||||
|
||||
if (existingIndex === 0) {
|
||||
// No need to update if the selected color is already the first element
|
||||
return;
|
||||
} else if (existingIndex > -1) {
|
||||
updatedPresets = [
|
||||
customThemeColor,
|
||||
...presets.slice(0, existingIndex),
|
||||
...presets.slice(existingIndex + 1),
|
||||
];
|
||||
} else {
|
||||
updatedPresets = [customThemeColor, ...presets].slice(0, 18);
|
||||
}
|
||||
|
||||
localStorage.setItem("colorPickerPresets", JSON.stringify(updatedPresets));
|
||||
}
|
||||
}, [customThemeColor, customOnChange, savePresets, presets])
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (customThemeColor && !customOnChange) {
|
||||
|
||||
@@ -74,16 +74,16 @@
|
||||
{:else if item.type === 'slider'}
|
||||
<Slider {...(item.props as SliderProps)} />
|
||||
{:else if item.type === 'colourPicker'}
|
||||
<ColourPicker standalone={true} {...(item.props)} />
|
||||
<ColourPicker savePresets={false} standalone={true} {...(item.props)} />
|
||||
{:else if item.type === 'codeEditor'}
|
||||
<CodeEditor {...(item.props as CodeEditorProps)} />
|
||||
<CodeEditor /> <!-- {/*...(item.props as CodeEditorProps)*/} -->
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
<div class='h-screen overflow-y-scroll {$settingsState.DarkMode && "dark"} '>
|
||||
<div class='w-full min-h-screen bg-zinc-100 dark:bg-zinc-800 flex flex-col p-2 dark:text-white'>
|
||||
<div class='flex flex-col w-full min-h-screen p-2 bg-zinc-100 dark:bg-zinc-800 dark:text-white'>
|
||||
<h1 class='text-xl font-semibold'>Theme Creator</h1>
|
||||
<a href='https://betterseqta.gitbook.io/betterseqta-docs' target='_blank' class='text-sm font-light text-zinc-500 dark:text-zinc-400'>
|
||||
<span class='no-underline font-IconFamily pr-0.5'>{'\ueb44'}</span>
|
||||
|
||||
Reference in New Issue
Block a user