Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 11 additions & 26 deletions app/components/ascii-art-generator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -681,20 +681,6 @@ export function AsciiArtGenerator() {
[processFile],
)

const handleExampleScriptClick = useCallback(() => {
// Open code sidebar and load the clock example
setShowCodeSidebar(true)
const template = TEMPLATES.sin
setPendingCode(template.source.code)
updateSettings('source', template.source)
updateSettings('output', template.output)
updateSettings('export', template.export)
updateSettings('preprocessing', template.preprocessing)
updateSettings('meta', template.meta)
updateSettings('source', template.source)
updateSettings('animation', template.animation)
}, [updateSettings])

const handleTemplateChange = (template: TemplateType) => {
if (template !== 'custom' && TEMPLATES[template]) {
loadTemplate(template)
Expand Down Expand Up @@ -811,18 +797,8 @@ export function AsciiArtGenerator() {
disabled={!program}
exportSettings={settings.export}
/>
<hr />
{/* Project Management */}
<ProjectManagement
projectName={projectName}
setProjectName={setProjectName}
templateType={templateType}
settings={settings}
handleLoadProjectInput={handleLoadProjectInput}
handleTemplateChange={handleTemplateChange}
/>
</div>
<div className="flex grow items-end p-3 pb-2">
<div className="flex grow items-end p-3 pb-3">
<a
href="https://oxide.computer"
target="_blank"
Expand All @@ -834,6 +810,15 @@ export function AsciiArtGenerator() {
</a>
</div>
</div>
{/* Project Management */}
<ProjectManagement
projectName={projectName}
setProjectName={setProjectName}
templateType={templateType}
settings={settings}
handleLoadProjectInput={handleLoadProjectInput}
handleTemplateChange={handleTemplateChange}
/>
</motion.div>
</motion.div>

Expand Down Expand Up @@ -890,7 +875,7 @@ export function AsciiArtGenerator() {
animationController={animationController}
setAnimationController={setAnimationController}
isExporting={isExporting}
onExampleScriptClick={handleExampleScriptClick}
onExampleScriptClick={(template) => loadTemplate(template)}
onExampleImageClick={() =>
updateSourceAndAspectRatio(exampleImage, 'image', 'example-grad.png')
}
Expand Down
48 changes: 42 additions & 6 deletions app/components/ascii-preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,21 @@
import {
Action16Icon,
AutoRestart12Icon,
DirectionDownIcon,
DirectionRightIcon,
DocumentApi16Icon,
Folder16Icon,
Resize16Icon,
} from '@oxide/design-system/icons/react'
import useResizeObserver from '@react-hook/resize-observer'
import cn from 'classnames'
import { motion } from 'motion/react'
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
import { useHotkeys } from 'react-hotkeys-hook'

import type { createAnimation, Program } from '~/lib/animation'
import { InputButton, InputNumber } from '~/lib/ui/src'
import { TEMPLATES, type TemplateType } from '~/templates'

import AsciiAnimation from './ascii-animation'
import type { GridType } from './ascii-art-generator'
Expand All @@ -43,7 +46,7 @@ interface AsciiPreviewProps {
setAnimationController: (controller: AnimationController) => void
isExporting: boolean
onUploadClick?: () => void
onExampleScriptClick?: () => void
onExampleScriptClick?: (templateType: TemplateType) => void
onExampleImageClick?: () => void
}

Expand All @@ -54,28 +57,57 @@ const DemoCard = ({
title,
onClick,
index,
hasDropdown = false,
onDropdownChange,
}: {
icon: React.ReactNode
title: string
onClick?: () => void
index: number
hasDropdown?: boolean
onDropdownChange?: (value: string) => void
}) => (
<motion.button
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{
duration: 0.5,
delay: index * 0.1,
ease: [0.25, 0.46, 0.45, 0.94],
}}
className="flex w-[20rem] items-center rounded border p-2 text-left transition-colors bg-raise border-secondary elevation-1 hover:bg-[var(--base-neutral-100)]"
onClick={onClick}
className="group relative flex w-[20rem] items-center rounded border p-2 text-left transition-colors bg-raise border-secondary elevation-1 hover:bg-[var(--base-neutral-100)]"
>
<div className="mr-3 inline-flex items-center justify-center rounded p-2 text-accent bg-accent-secondary">
{icon}
</div>
<div className="text-default text-sans-md">{title}</div>
</motion.button>
{hasDropdown && (
<div className="absolute bottom-0 right-0 top-0 flex w-8 items-center justify-center border-l bg-raise border-secondary hover:bg-[var(--base-neutral-100)]">
<select
className="absolute h-full w-full cursor-pointer appearance-none opacity-0"
style={{ color: 'transparent' }}
onChange={(e) => onDropdownChange?.(e.target.value)}
defaultValue=""
>
<option value="" disabled>
Select script
</option>
{Object.entries(TEMPLATES)
.filter(([key]) => key !== 'custom' && key !== 'imageCode')
.map(([key, template]) => (
<option key={key} value={key}>
{template.meta.name}
</option>
))}
</select>
<DirectionDownIcon className="h-3 w-3 flex-shrink-0 text-tertiary" />
</div>
)}
<button
className={cn('absolute bottom-0 left-0 top-0', hasDropdown ? 'right-12' : 'right-0')}
onClick={onClick}
/>
</motion.div>
)

const useSize = (target: HTMLDivElement | null) => {
Expand Down Expand Up @@ -217,7 +249,11 @@ export function AsciiPreview({
index={1}
icon={<DocumentApi16Icon className="text-accent-secondary" />}
title="Run example script"
onClick={onExampleScriptClick}
hasDropdown={true}
onDropdownChange={(templateKey) =>
onExampleScriptClick?.(templateKey as TemplateType)
}
onClick={() => onExampleScriptClick?.('sin')}
/>
<DemoCard
index={2}
Expand Down
4 changes: 2 additions & 2 deletions app/components/project-management.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export function ProjectManagement({
}

return (
<Container>
<Container className="border-t py-3 border-default">
<InputSelect<TemplateType>
value={templateType}
onChange={handleTemplateChange}
Expand All @@ -91,7 +91,7 @@ export function ProjectManagement({

<div className="flex gap-2">
<InputButton variant="secondary">
Load
Load JSON
<input
type="file"
className="absolute inset-0 z-10 opacity-0"
Expand Down
Loading