"use client"; import { useEffect, useState } from "react"; import { ArrowUp, LoaderCircle } from "lucide-react"; import { Button } from "antd"; import { ModelPicker } from "@/components/model-picker"; import { defaultConfig, useConfigStore, useEffectiveConfig, type AiConfig } from "@/stores/use-config-store"; import { CreditSymbol, requestCreditCost } from "@/constant/credits"; import { canvasThemes } from "@/lib/canvas-theme"; import { useThemeStore } from "@/stores/use-theme-store"; import { CanvasImageSettingsPopover } from "./canvas-image-settings-popover"; import { CanvasPromptLibrary } from "./canvas-prompt-library"; import { CanvasVideoSettingsPopover } from "./canvas-video-settings-popover"; import { CanvasNodeType, type CanvasGenerationMode, type CanvasNodeData } from "../types"; export type CanvasNodeGenerationMode = CanvasGenerationMode; type CanvasNodePromptPanelProps = { node: CanvasNodeData; isRunning: boolean; onPromptChange: (nodeId: string, prompt: string) => void; onConfigChange: (nodeId: string, patch: Partial) => void; onGenerate: (nodeId: string, mode: CanvasNodeGenerationMode, prompt: string) => void; onImageSettingsOpenChange?: (open: boolean) => void; }; export function CanvasNodePromptPanel({ node, isRunning, onPromptChange, onConfigChange, onGenerate, onImageSettingsOpenChange }: CanvasNodePromptPanelProps) { const globalConfig = useEffectiveConfig(); const modelCosts = useConfigStore((state) => state.publicSettings?.modelChannel.modelCosts); const openConfigDialog = useConfigStore((state) => state.openConfigDialog); const theme = canvasThemes[useThemeStore((state) => state.theme)]; const mode = defaultMode(node.type); const config = buildNodeConfig(globalConfig, node, mode); const hasTextContent = node.type === CanvasNodeType.Text && Boolean(node.metadata?.content?.trim()); const hasImageContent = node.type === CanvasNodeType.Image && Boolean(node.metadata?.content); const isEditingExistingContent = hasTextContent || hasImageContent; const [prompt, setPrompt] = useState(isEditingExistingContent ? "" : node.metadata?.prompt || ""); const credits = requestCreditCost({ channelMode: config.channelMode, modelCosts, model: config.model, count: mode === "image" ? config.count : 1 }); useEffect(() => { setPrompt(isEditingExistingContent ? "" : node.metadata?.prompt || ""); }, [isEditingExistingContent, node.id]); const updatePrompt = (value: string) => { setPrompt(value); if (!isEditingExistingContent) onPromptChange(node.id, value); }; const submit = () => { const text = prompt.trim(); if (!text || isRunning) return; onGenerate(node.id, mode, text); setPrompt(""); }; return (
event.stopPropagation()} onPointerDown={(event) => event.stopPropagation()} onWheel={(event) => event.stopPropagation()} >