import styles from "./sd-panel.module.scss"; import React from "react"; import { Select } from "@/app/components/ui-lib"; import { IconButton } from "@/app/components/button"; import Locale from "@/app/locales"; import { useSdStore } from "@/app/store/sd"; import clsx from "clsx"; export const params = [ { name: Locale.SdPanel.Prompt, value: "prompt", type: "textarea", placeholder: Locale.SdPanel.PleaseInput(Locale.SdPanel.Prompt), required: true, }, { name: Locale.SdPanel.ModelVersion, value: "model", type: "select", default: "sd3-medium", support: ["sd3"], options: [ { name: "SD3 Medium", value: "sd3-medium" }, { name: "SD3 Large", value: "sd3-large" }, { name: "SD3 Large Turbo", value: "sd3-large-turbo" }, ], }, { name: Locale.SdPanel.NegativePrompt, value: "negative_prompt", type: "textarea", placeholder: Locale.SdPanel.PleaseInput(Locale.SdPanel.NegativePrompt), }, { name: Locale.SdPanel.AspectRatio, value: "aspect_ratio", type: "select", default: "1:1", options: [ { name: "1:1", value: "1:1" }, { name: "16:9", value: "16:9" }, { name: "21:9", value: "21:9" }, { name: "2:3", value: "2:3" }, { name: "3:2", value: "3:2" }, { name: "4:5", value: "4:5" }, { name: "5:4", value: "5:4" }, { name: "9:16", value: "9:16" }, { name: "9:21", value: "9:21" }, ], }, { name: Locale.SdPanel.ImageStyle, value: "style", type: "select", default: "3d-model", support: ["core"], options: [ { name: Locale.SdPanel.Styles.D3Model, value: "3d-model" }, { name: Locale.SdPanel.Styles.AnalogFilm, value: "analog-film" }, { name: Locale.SdPanel.Styles.Anime, value: "anime" }, { name: Locale.SdPanel.Styles.Cinematic, value: "cinematic" }, { name: Locale.SdPanel.Styles.ComicBook, value: "comic-book" }, { name: Locale.SdPanel.Styles.DigitalArt, value: "digital-art" }, { name: Locale.SdPanel.Styles.Enhance, value: "enhance" }, { name: Locale.SdPanel.Styles.FantasyArt, value: "fantasy-art" }, { name: Locale.SdPanel.Styles.Isometric, value: "isometric" }, { name: Locale.SdPanel.Styles.LineArt, value: "line-art" }, { name: Locale.SdPanel.Styles.LowPoly, value: "low-poly" }, { name: Locale.SdPanel.Styles.ModelingCompound, value: "modeling-compound", }, { name: Locale.SdPanel.Styles.NeonPunk, value: "neon-punk" }, { name: Locale.SdPanel.Styles.Origami, value: "origami" }, { name: Locale.SdPanel.Styles.Photographic, value: "photographic" }, { name: Locale.SdPanel.Styles.PixelArt, value: "pixel-art" }, { name: Locale.SdPanel.Styles.TileTexture, value: "tile-texture" }, ], }, { name: "Seed", value: "seed", type: "number", default: 0, min: 0, max: 4294967294, }, { name: Locale.SdPanel.OutFormat, value: "output_format", type: "select", default: "png", options: [ { name: "PNG", value: "png" }, { name: "JPEG", value: "jpeg" }, { name: "WebP", value: "webp" }, ], }, ]; const sdCommonParams = (model: string, data: any) => { return params.filter((item) => { return !(item.support && !item.support.includes(model)); }); }; export const models = [ { name: "Stable Image Ultra", value: "ultra", params: (data: any) => sdCommonParams("ultra", data), }, { name: "Stable Image Core", value: "core", params: (data: any) => sdCommonParams("core", data), }, { name: "Stable Diffusion 3", value: "sd3", params: (data: any) => { return sdCommonParams("sd3", data).filter((item) => { return !( data.model === "sd3-large-turbo" && item.value == "negative_prompt" ); }); }, }, ]; export function ControlParamItem(props: { title: string; subTitle?: string; required?: boolean; children?: JSX.Element | JSX.Element[]; className?: string; }) { return (
{props.title} {props.required && *}
{props.children} {props.subTitle && (
{props.subTitle}
)}
); } export function ControlParam(props: { columns: any[]; data: any; onChange: (field: string, val: any) => void; }) { return ( <> {props.columns?.map((item) => { let element: null | JSX.Element; switch (item.type) { case "textarea": element = ( ); break; case "select": element = ( ); break; case "number": element = ( { props.onChange(item.value, parseInt(e.currentTarget.value)); }} /> ); break; default: element = ( { props.onChange(item.value, e.currentTarget.value); }} /> ); } return
{element}
; })} ); } export const getModelParamBasicData = ( columns: any[], data: any, clearText?: boolean, ) => { const newParams: any = {}; columns.forEach((item: any) => { if (clearText && ["text", "textarea", "number"].includes(item.type)) { newParams[item.value] = item.default || ""; } else { // @ts-ignore newParams[item.value] = data[item.value] || item.default || ""; } }); return newParams; }; export const getParams = (model: any, params: any) => { return models.find((m) => m.value === model.value)?.params(params) || []; }; export function SdPanel() { const sdStore = useSdStore(); const currentModel = sdStore.currentModel; const setCurrentModel = sdStore.setCurrentModel; const params = sdStore.currentParams; const setParams = sdStore.setCurrentParams; const handleValueChange = (field: string, val: any) => { setParams({ ...params, [field]: val, }); }; const handleModelChange = (model: any) => { setCurrentModel(model); setParams(getModelParamBasicData(model.params({}), params)); }; return ( <>
{models.map((item) => { return ( handleModelChange(item)} /> ); })}
); }