Spaces:
Sleeping
Sleeping
| "use client" | |
| import { useState } from "react" | |
| import { | |
| Select, | |
| SelectContent, | |
| SelectItem, | |
| SelectTrigger, | |
| SelectValue, | |
| } from "@/components/ui/select" | |
| import { Label } from "@/components/ui/label" | |
| import { cn } from "@/lib/utils" | |
| import { FontName, fontList, fonts } from "@/lib/fonts" | |
| import { Input } from "@/components/ui/input" | |
| import { defaultPreset, getPreset, presets } from "@/app/engine/presets" | |
| import { useStore } from "@/app/store" | |
| import { Button } from "@/components/ui/button" | |
| export function TopMenu() { | |
| const font = useStore(state => state.font) | |
| const setFont = useStore(state => state.setFont) | |
| const preset = useStore(state => state.preset) | |
| const setPreset = useStore(state => state.setPreset) | |
| const prompt = useStore(state => state.prompt) | |
| const setPrompt = useStore(state => state.setPrompt) | |
| const isGeneratingStory = useStore(state => state.isGeneratingStory) | |
| const atLeastOnePanelIsBusy = useStore(state => state.atLeastOnePanelIsBusy) | |
| const isBusy = isGeneratingStory || atLeastOnePanelIsBusy | |
| const [draft, setDraft] = useState("") | |
| return ( | |
| <div className={cn( | |
| `print:hidden`, | |
| `z-10 fixed top-0 left-0 right-0`, | |
| `flex flex-col md:flex-row w-full justify-between items-center`, | |
| `backdrop-blur-xl`, | |
| `transition-all duration-200 ease-in-out`, | |
| `px-2 py-2 border-b-1 border-gray-50 dark:border-gray-50`, | |
| `bg-stone-900/70 dark:bg-stone-900/70 text-gray-50 dark:text-gray-50`, | |
| `space-y-2 md:space-y-0 md:space-x-3 lg:space-x-6` | |
| )}> | |
| <div className="flex flex-row space-x-6 md:space-x-3"> | |
| <div className={cn( | |
| `transition-all duration-200 ease-in-out`, | |
| `flex flex-row items-center justify-start space-x-3 font-mono w-1/2 md:w-auto` | |
| )}> | |
| <Label className="flex text-sm md:w-24">Preset:</Label> | |
| <Select | |
| defaultValue={defaultPreset} | |
| onValueChange={(value) => { setPreset(getPreset(value as FontName)) }} | |
| disabled={isBusy} | |
| > | |
| <SelectTrigger className="flex-grow"> | |
| <SelectValue className="text-sm" placeholder="Type" /> | |
| </SelectTrigger> | |
| <SelectContent> | |
| {Object.entries(presets).map(([key, preset]) => | |
| <SelectItem key={key} value={key}>{preset.label}</SelectItem> | |
| )} | |
| </SelectContent> | |
| </Select> | |
| </div> | |
| <div className={cn( | |
| `transition-all duration-200 ease-in-out`, | |
| `flex flex-row items-center space-x-3 font-mono w-1/2 md:w-auto md:hidden` | |
| )}> | |
| <Label className="flex text-sm md:w-24">Font:</Label> | |
| <Select | |
| defaultValue={fontList.includes(preset.font) ? preset.font : "cartoonist"} | |
| onValueChange={(value) => { setFont(value as FontName) }} | |
| disabled={atLeastOnePanelIsBusy} | |
| > | |
| <SelectTrigger className="flex-grow"> | |
| <SelectValue className="text-sm" placeholder="Type" /> | |
| </SelectTrigger> | |
| <SelectContent> | |
| {Object.keys(fonts) | |
| .map((font) => | |
| <SelectItem | |
| key={font} | |
| value={font}>{ | |
| font | |
| }</SelectItem> | |
| )} | |
| </SelectContent> | |
| </Select> | |
| </div> | |
| </div> | |
| <div className={cn( | |
| `transition-all duration-200 ease-in-out`, | |
| `flex flex-row flex-grow items-center space-x-3 font-mono w-full md:w-auto` | |
| )}> | |
| <Input | |
| placeholder="Story" | |
| className="w-full bg-neutral-300 text-neutral-800 dark:bg-neutral-300 dark:text-neutral-800" | |
| // disabled={atLeastOnePanelIsBusy} | |
| onChange={(e) => { | |
| setDraft(e.target.value) | |
| }} | |
| onKeyDown={({ key }) => { | |
| if (isBusy) { | |
| return | |
| } | |
| if (key === 'Enter') { | |
| if (draft.trim() !== prompt.trim()) { | |
| setPrompt(draft.trim()) | |
| } | |
| } | |
| }} | |
| value={draft} | |
| /> | |
| <Button | |
| onClick={() => { | |
| if (isBusy) { | |
| return | |
| } | |
| if (draft.trim() !== prompt.trim()) { | |
| setPrompt(draft.trim()) | |
| } | |
| }} | |
| disabled={!draft?.trim().length || isBusy} | |
| > | |
| Generate | |
| </Button> | |
| </div> | |
| <div className={cn( | |
| `transition-all duration-200 ease-in-out`, | |
| `hidden md:flex flex-row items-center space-x-3 font-mono w-full md:w-auto` | |
| )}> | |
| <Label className="flex text-sm w-24">Font:</Label> | |
| <Select | |
| defaultValue={fontList.includes(preset.font) ? preset.font : "actionman"} | |
| onValueChange={(value) => { setFont(value as FontName) }} | |
| // disabled={isBusy} | |
| disabled={true} | |
| > | |
| <SelectTrigger className="flex-grow"> | |
| <SelectValue className="text-sm" placeholder="Type" /> | |
| </SelectTrigger> | |
| <SelectContent> | |
| {Object.keys(fonts) | |
| .map((font) => | |
| <SelectItem | |
| key={font} | |
| value={font}>{ | |
| font | |
| }</SelectItem> | |
| )} | |
| </SelectContent> | |
| </Select> | |
| </div> | |
| </div> | |
| ) | |
| } |