import { IconButton } from '@/app/components/button'; import { Select } from '@/app/components/ui-lib'; import Locale from '@/app/locales'; import { useSdStore } from '@/app/store/sd'; import clsx from 'clsx'; import React from 'react'; import styles from './sd-panel.module.scss'; 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' }, ], }, ]; function 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, Number.parseInt(e.currentTarget.value)); }} /> ); break; default: element = ( { props.onChange(item.value, e.currentTarget.value); }} /> ); } return
{element}
; })} ); } export function 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 function 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)} /> ); })}
); }