|
|
@@ -1,110 +1,110 @@
|
|
|
import styles from "./sd-panel.module.scss";
|
|
|
-import React, { useState } from "react";
|
|
|
-import { Select, showToast } from "@/app/components/ui-lib";
|
|
|
+import React from "react";
|
|
|
+import { Select } from "@/app/components/ui-lib";
|
|
|
import { IconButton } from "@/app/components/button";
|
|
|
import Locale from "@/app/locales";
|
|
|
-import { nanoid } from "nanoid";
|
|
|
-import { StoreKey } from "@/app/constant";
|
|
|
import { useSdStore } from "@/app/store/sd";
|
|
|
|
|
|
+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 [
|
|
|
- {
|
|
|
- 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",
|
|
|
- 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" },
|
|
|
- ],
|
|
|
- },
|
|
|
- ].filter((item) => {
|
|
|
+ return params.filter((item) => {
|
|
|
return !(item.support && !item.support.includes(model));
|
|
|
});
|
|
|
};
|
|
|
|
|
|
-const models = [
|
|
|
+export const models = [
|
|
|
{
|
|
|
name: "Stable Image Ultra",
|
|
|
value: "ultra",
|
|
|
@@ -162,7 +162,7 @@ export function ControlParam(props: {
|
|
|
}) {
|
|
|
return (
|
|
|
<>
|
|
|
- {props.columns.map((item) => {
|
|
|
+ {props.columns?.map((item) => {
|
|
|
let element: null | JSX.Element;
|
|
|
switch (item.type) {
|
|
|
case "textarea":
|
|
|
@@ -251,7 +251,7 @@ export function ControlParam(props: {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
-const getModelParamBasicData = (
|
|
|
+export const getModelParamBasicData = (
|
|
|
columns: any[],
|
|
|
data: any,
|
|
|
clearText?: boolean,
|
|
|
@@ -268,47 +268,28 @@ const getModelParamBasicData = (
|
|
|
return newParams;
|
|
|
};
|
|
|
|
|
|
+export const getParams = (model: any, params: any) => {
|
|
|
+ return models.find((m) => m.value === model.value)?.params(params) || [];
|
|
|
+};
|
|
|
+
|
|
|
export function SdPanel() {
|
|
|
- const [currentModel, setCurrentModel] = useState(models[0]);
|
|
|
- const [params, setParams] = useState(
|
|
|
- getModelParamBasicData(currentModel.params({}), {}),
|
|
|
- );
|
|
|
+ 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((prevParams: any) => ({
|
|
|
- ...prevParams,
|
|
|
+ setParams({
|
|
|
+ ...params,
|
|
|
[field]: val,
|
|
|
- }));
|
|
|
+ });
|
|
|
};
|
|
|
const handleModelChange = (model: any) => {
|
|
|
setCurrentModel(model);
|
|
|
setParams(getModelParamBasicData(model.params({}), params));
|
|
|
};
|
|
|
- const sdStore = useSdStore();
|
|
|
- const handleSubmit = () => {
|
|
|
- const columns = currentModel.params(params);
|
|
|
- const reqParams: any = {};
|
|
|
- for (let i = 0; i < columns.length; i++) {
|
|
|
- const item = columns[i];
|
|
|
- reqParams[item.value] = params[item.value] ?? null;
|
|
|
- if (item.required) {
|
|
|
- if (!reqParams[item.value]) {
|
|
|
- showToast(Locale.SdPanel.ParamIsRequired(item.name));
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- let data: any = {
|
|
|
- model: currentModel.value,
|
|
|
- model_name: currentModel.name,
|
|
|
- status: "wait",
|
|
|
- params: reqParams,
|
|
|
- created_at: new Date().toLocaleString(),
|
|
|
- img_data: "",
|
|
|
- };
|
|
|
- sdStore.sendTask(data, () => {
|
|
|
- setParams(getModelParamBasicData(columns, params, true));
|
|
|
- });
|
|
|
- };
|
|
|
+
|
|
|
return (
|
|
|
<>
|
|
|
<ControlParamItem title={Locale.SdPanel.AIModel}>
|
|
|
@@ -327,17 +308,10 @@ export function SdPanel() {
|
|
|
</div>
|
|
|
</ControlParamItem>
|
|
|
<ControlParam
|
|
|
- columns={currentModel.params(params) as any[]}
|
|
|
+ columns={getParams?.(currentModel, params) as any[]}
|
|
|
data={params}
|
|
|
onChange={handleValueChange}
|
|
|
></ControlParam>
|
|
|
- <IconButton
|
|
|
- text={Locale.SdPanel.Submit}
|
|
|
- type="primary"
|
|
|
- style={{ marginTop: "20px" }}
|
|
|
- shadow
|
|
|
- onClick={handleSubmit}
|
|
|
- ></IconButton>
|
|
|
</>
|
|
|
);
|
|
|
}
|