diff --git a/playgrounds/app/src/components/Editor.tsx b/playgrounds/app/src/components/Editor.tsx index dadbff5..688f3ef 100644 --- a/playgrounds/app/src/components/Editor.tsx +++ b/playgrounds/app/src/components/Editor.tsx @@ -40,10 +40,18 @@ import { DialogHeader, DialogTitle, } from '~/components/ui/dialog' -import { createMemo, createResource, createSignal, onCleanup, Setter, Show } from 'solid-js' +import { + createEffect, + createMemo, + createResource, + createSignal, + onCleanup, + Setter, + Show, +} from 'solid-js' import { createHighlighter, bundledThemes, bundledLanguages } from 'shiki' import { ShikiMagicMove } from 'shiki-magic-move/solid' -import { AnimationFrameConfig } from '~/types' +import { AnimationFrameConfig, SnippetSettings } from '~/types' import { authFetch } from '~/lib/utils' import { useNavigate } from '@solidjs/router' import { authToken } from '~/lib/store' @@ -51,6 +59,7 @@ import { toast } from 'solid-sonner' import { Separator } from './ui/separator' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select' import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from './ui/accordion' +import { SetStoreFunction } from 'solid-js/store' const animationSeconds = 1 const animationFPS = 30 @@ -78,46 +87,8 @@ const bgTypeOptions: SelectOption[] = [ interface EditorProps { snippetId?: string - startCode: string - setStartCode: Setter - endCode: string - setEndCode: Setter - snippetWidth: number - setSnippetWidth: Setter - yPadding: number - setYPadding: Setter - xPadding: number - setXPadding: Setter - shadowEnabled: boolean - setShadowEnabled: Setter - shadowOffsetY: number - setShadowOffsetY: Setter - shadowBlur: number - setShadowBlur: Setter - shadowColor: string - setShadowColor: Setter - shadowOpacity: number - setShadowOpacity: Setter - bgType: 'solid' | 'linearGradient' - setBgType: Setter<'solid' | 'linearGradient'> - bgColor: string - setBgColor: Setter - bgGradientColorStart: string - setBgGradientColorStart: Setter - bgGradientColorEnd: string - setBgGradientColorEnd: Setter - bgGradientDirection: number - setBgGradientDirection: Setter - fontSize: number - setFontSize: Setter - fontFamily: string - setFontFamily: Setter - language: string - setLanguage: Setter - theme: string - setTheme: Setter - // TODO: If the app grows, this logic should be surfaced to the top level route - title?: string + snippetSettings: SnippetSettings + setSnippetSettings: SetStoreFunction } export default function Editor(props: EditorProps) { @@ -130,14 +101,14 @@ export default function Editor(props: EditorProps) { width: number height: number }>() - const [code, setCode] = createSignal(props.startCode) - const [hiddenCode, setHiddenCode] = createSignal(props.startCode) + const [code, setCode] = createSignal(props.snippetSettings.codeLeft) + const [hiddenCode, setHiddenCode] = createSignal(props.snippetSettings.codeLeft) const [isResizing, setIsResizing] = createSignal(false) const [isLooping, setIsLooping] = createSignal(true) const [isGenerating, setIsGenerating] = createSignal(false) const [gifDataUrl, setGifDataUrl] = createSignal('') const [isShowingGifDialog, setIsShowingGifDialog] = createSignal(false) - const [title, setTitle] = createSignal(props.title) + const [title, setTitle] = createSignal(props.snippetSettings.title) const [isSaving, setIsSaving] = createSignal(false) const [highlighter] = createResource(async () => { @@ -149,18 +120,23 @@ export default function Editor(props: EditorProps) { return newHighlighter }) + createEffect(() => { + setCode(props.snippetSettings.codeLeft) + setHiddenCode(props.snippetSettings.codeLeft) + }) + const intervalId = setInterval(() => { if ( selectedTab() === 'output' && - props.startCode !== '' && - props.endCode !== '' && + props.snippetSettings.codeLeft !== '' && + props.snippetSettings.codeRight !== '' && !isResizing() && isLooping() ) { if (toggled()) { - setCode(props.startCode) + setCode(props.snippetSettings.codeLeft) } else { - setCode(props.endCode) + setCode(props.snippetSettings.codeRight) } setToggled(!toggled()) } @@ -173,7 +149,7 @@ export default function Editor(props: EditorProps) { document.body.addEventListener('mousemove', e => { if (isResizing()) { const deltaX = e.movementX - props.setSnippetWidth(props.snippetWidth + deltaX) + props.setSnippetSettings('snippetWidth', props.snippetSettings.snippetWidth + deltaX) } }) @@ -229,25 +205,25 @@ export default function Editor(props: EditorProps) { maxContainerDimensions()?.height || 100, { layout: { - yPadding: props.yPadding, - xPadding: props.xPadding, + yPadding: props.snippetSettings.yPadding, + xPadding: props.snippetSettings.xPadding, }, shadow: { - shadowEnabled: props.shadowEnabled, - shadowOffsetY: props.shadowOffsetY, - shadowBlur: props.shadowBlur, - shadowColor: props.shadowColor, - shadowOpacity: props.shadowOpacity, + shadowEnabled: props.snippetSettings.shadowEnabled, + shadowOffsetY: props.snippetSettings.shadowOffsetY, + shadowBlur: props.snippetSettings.shadowBlur, + shadowColor: props.snippetSettings.shadowColor, + shadowOpacity: props.snippetSettings.shadowOpacity, }, styling: { fontSize, fontFamily, snippetBackgroundColor: backgroundColor, - backgroundColor: props.bgColor, - backgroundType: props.bgType, - backgroundGradientColorStart: props.bgGradientColorStart, - backgroundGradientColorEnd: props.bgGradientColorEnd, - backgroundGradientDirection: props.bgGradientDirection, + backgroundColor: props.snippetSettings.bgColor, + backgroundType: props.snippetSettings.bgType, + backgroundGradientColorStart: props.snippetSettings.bgGradientColorStart, + backgroundGradientColorEnd: props.snippetSettings.bgGradientColorEnd, + backgroundGradientDirection: props.snippetSettings.bgGradientDirection, }, }, ) @@ -280,9 +256,9 @@ export default function Editor(props: EditorProps) { props.setSnippetSettings('theme', newTheme || '')} placeholder="Search a theme..." itemComponent={props => ( @@ -303,9 +279,9 @@ export default function Editor(props: EditorProps) { props.setSnippetSettings('language', newLanguage || '')} placeholder="Search a Language..." itemComponent={props => ( @@ -340,18 +316,28 @@ export default function Editor(props: EditorProps) { id="bg-type" - value={bgTypeOptions.find(option => option.value === props.bgType)} + value={bgTypeOptions.find( + option => option.value === props.snippetSettings.bgType, + )} optionValue="value" optionTextValue="label" onChange={newType => - newType && props.setBgType(newType.value as 'solid' | 'linearGradient') + newType && + props.setSnippetSettings( + 'bgType', + newType.value as 'solid' | 'linearGradient', + ) } options={bgTypeOptions} itemComponent={props => ( {props.item.rawValue.label} )} > - + > {state => state.selectedOption()?.label} @@ -360,7 +346,7 @@ export default function Editor(props: EditorProps) { - {props.bgType === 'linearGradient' && ( + {props.snippetSettings.bgType === 'linearGradient' && ( <>
@@ -384,18 +370,18 @@ export default function Editor(props: EditorProps) { id="bg-color-input-grad-end" class="h-6 w-6 rounded" type="color" - value={props.bgGradientColorEnd} + value={props.snippetSettings.bgGradientColorEnd} onInput={e => { - props.setBgGradientColorEnd(e.target.value) + props.setSnippetSettings('bgGradientColorEnd', e.target.value) }} /> { - props.setBgGradientDirection(e[0]) + props.setSnippetSettings('bgGradientDirection', e[0]) }} >
@@ -413,7 +399,7 @@ export default function Editor(props: EditorProps) { )} - {props.bgType === 'solid' && ( + {props.snippetSettings.bgType === 'solid' && (
@@ -438,11 +424,11 @@ export default function Editor(props: EditorProps) {
{ - props.setSnippetWidth(e[0]) + props.setSnippetSettings('snippetWidth', e[0]) }} >
@@ -459,11 +445,11 @@ export default function Editor(props: EditorProps) { { - props.setYPadding(e[0]) + props.setSnippetSettings('yPadding', e[0]) }} >
@@ -480,11 +466,11 @@ export default function Editor(props: EditorProps) { { - props.setXPadding(e[0]) + props.setSnippetSettings('xPadding', e[0]) }} >
@@ -510,15 +496,23 @@ export default function Editor(props: EditorProps) {
{ - props.setShadowEnabled(!props.shadowEnabled) + props.setSnippetSettings( + 'shadowEnabled', + !props.snippetSettings.shadowEnabled, + ) }} />
@@ -532,18 +526,18 @@ export default function Editor(props: EditorProps) { id="shadow-color-input" class="h-6 w-6 rounded" type="color" - value={props.shadowColor} - onInput={e => props.setShadowColor(e.target.value)} + value={props.snippetSettings.shadowColor} + onInput={e => props.setSnippetSettings('shadowColor', e.target.value)} />
{ - props.setShadowOpacity(e[0]) + props.setSnippetSettings('shadowOpacity', e[0]) }} >
@@ -558,11 +552,11 @@ export default function Editor(props: EditorProps) {
{ - props.setShadowOffsetY(e[0]) + props.setSnippetSettings('shadowOffsetY', e[0]) }} >
@@ -580,11 +574,11 @@ export default function Editor(props: EditorProps) {
{ - props.setShadowBlur(e[0]) + props.setSnippetSettings('shadowBlur', e[0]) }} >
@@ -613,10 +607,14 @@ export default function Editor(props: EditorProps) { id="font-family" - value={supportedFontFamilies.find(option => option.name === props.fontFamily)} + value={supportedFontFamilies.find( + option => option.name === props.snippetSettings.fontFamily, + )} optionValue="name" optionTextValue="name" - onChange={newFamily => newFamily && props.setFontFamily(newFamily.name)} + onChange={newFamily => + newFamily && props.setSnippetSettings('fontFamily', newFamily.name) + } options={supportedFontFamilies} itemComponent={props => ( {props.item.rawValue.name} @@ -625,7 +623,7 @@ export default function Editor(props: EditorProps) { > {state => state.selectedOption()?.name} @@ -636,11 +634,11 @@ export default function Editor(props: EditorProps) {
{ - props.setFontSize(e[0]) + props.setSnippetSettings('fontSize', e[0]) }} >
@@ -681,7 +679,10 @@ export default function Editor(props: EditorProps) { onClick={() => { setSelectedTab('output') }} - disabled={props.startCode === '' || props.endCode === ''} + disabled={ + props.snippetSettings.codeLeft === '' || + props.snippetSettings.codeRight === '' + } > Next @@ -691,8 +692,8 @@ export default function Editor(props: EditorProps) {
props.setSnippetSettings('codeLeft', newCodeLeft)} > Start Code @@ -700,8 +701,8 @@ export default function Editor(props: EditorProps) { props.setSnippetSettings('codeRight', newEndCode)} > End Code @@ -719,13 +720,13 @@ export default function Editor(props: EditorProps) { disabled={isGenerating()} onClick={async () => { setIsGenerating(true) - setHiddenCode(props.endCode) + setHiddenCode(props.snippetSettings.codeRight) setTimeout(async () => { const dataUrl = await generateGifDataUrl()() setGifDataUrl(dataUrl) setIsGenerating(false) setIsShowingGifDialog(true) - setHiddenCode(props.startCode) + setHiddenCode(props.snippetSettings.codeLeft) }, 1000) }} > @@ -747,14 +748,14 @@ export default function Editor(props: EditorProps) { id="styled-snippet" class="flex flex-row items-center justify-center overflow-hidden" style={{ - ...(props.bgType === 'linearGradient' + ...(props.snippetSettings.bgType === 'linearGradient' ? { - background: `linear-gradient(${props.bgGradientDirection}deg, ${props.bgGradientColorStart}, ${props.bgGradientColorEnd})`, + background: `linear-gradient(${props.snippetSettings.bgGradientDirection}deg, ${props.snippetSettings.bgGradientColorStart}, ${props.snippetSettings.bgGradientColorEnd})`, } : { - background: props.bgColor, + background: props.snippetSettings.bgColor, }), - padding: `${props.yPadding}px ${props.xPadding}px`, + padding: `${props.snippetSettings.yPadding}px ${props.snippetSettings.xPadding}px`, }} >
@@ -764,20 +765,22 @@ export default function Editor(props: EditorProps) {