mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-10 03:51:25 +00:00
pipe model info to inpainting editor
This commit is contained in:
1 parent
fbf914e24e
commit
80c9173a5e
6 files changed
+78
-28
No files matched your search
@@ -24,16 +24,30 @@ import { EditPaintSurface } from "./EditPaintSurface";
|
||||
import { normalizeCanvas } from "../../Helpers/CanvasHelpers";
|
||||
import { BaseImageSelector, BaseSelectorImage } from "./BaseImageSelector";
|
||||
import DrawToolControlBar from "./DrawToolControlBar";
|
||||
import { imageEditorModels, ModelCategory, ModelSelector, useModelSelectorStore } from "@storyteller/ui-model-selector";
|
||||
import { ModelInfo } from "@storyteller/model-list";
|
||||
|
||||
const PageEdit = () => {
|
||||
//useStateSceneLoader();
|
||||
const { selectedModels } = useModelSelectorStore();
|
||||
|
||||
const selectedModel =
|
||||
selectedModels[ModelCategory.Canvas2D] ||
|
||||
imageEditorModels[0]?.label;
|
||||
|
||||
const selectedModelInfo: ModelInfo | undefined =
|
||||
imageEditorModels.find(
|
||||
(m) => m.label === selectedModel,
|
||||
)?.modelInfo;
|
||||
|
||||
// State for canvas dimensions
|
||||
const canvasWidth = useRef<number>(1024);
|
||||
const canvasHeight = useRef<number>(1024);
|
||||
|
||||
// Add new state to track if user is selecting
|
||||
const [isSelecting, setIsSelecting] = useState<boolean>(false);
|
||||
const [selectedModel, setSelectedModel] = useState<string>("GPT-4o");
|
||||
//const [selectedModel, setSelectedModel] = useState<string>("GPT-4o");
|
||||
|
||||
// Create refs for stage and image
|
||||
const stageRef = useRef<Konva.Stage>({} as Konva.Stage);
|
||||
const leftPanelRef = useRef<Konva.Layer>({} as Konva.Layer);
|
||||
@@ -42,6 +56,7 @@ const PageEdit = () => {
|
||||
const [isEnqueuing, setIsEnqueuing] = useState<boolean>(false);
|
||||
const [generationCount, setGenerationCount] = useState<number>(1);
|
||||
|
||||
|
||||
// Use the Zustand store
|
||||
const store = useEditStore();
|
||||
|
||||
@@ -115,27 +130,6 @@ const PageEdit = () => {
|
||||
};
|
||||
}, [store]);
|
||||
|
||||
const modelList: PopoverItem[] = [
|
||||
{
|
||||
label: "GPT-4o",
|
||||
icon: <FontAwesomeIcon icon={faImage} className="h-4 w-4" />,
|
||||
selected: selectedModel === "GPT-4o",
|
||||
description: "High quality model",
|
||||
badges: [{ label: "2 min.", icon: <FontAwesomeIcon icon={faClock} /> }],
|
||||
},
|
||||
{
|
||||
label: "FLUX.1 Kontext",
|
||||
icon: <FontAwesomeIcon icon={faImage} className="h-4 w-4" />,
|
||||
selected: selectedModel === "FLUX.1 Kontext",
|
||||
description: "Fast and high-quality model",
|
||||
badges: [{ label: "20 sec.", icon: <FontAwesomeIcon icon={faClock} /> }],
|
||||
},
|
||||
];
|
||||
|
||||
const handleModelSelect = (item: PopoverItem) => {
|
||||
setSelectedModel(item.label);
|
||||
};
|
||||
|
||||
const onFitPressed = async () => {
|
||||
// Get the stage and its container dimensions
|
||||
const stage = stageRef.current;
|
||||
@@ -263,6 +257,7 @@ const PageEdit = () => {
|
||||
}`}
|
||||
>
|
||||
<PromptEditor
|
||||
modelInfo={selectedModelInfo}
|
||||
onModeChange={(mode: string) => {
|
||||
store.setActiveTool(mode as ActiveEditTool);
|
||||
}}
|
||||
@@ -328,10 +323,9 @@ const PageEdit = () => {
|
||||
</ContextMenuContainer>
|
||||
</div>
|
||||
<div className="absolute bottom-6 left-6 z-20 flex items-center gap-2">
|
||||
<PopoverMenu
|
||||
items={modelList}
|
||||
onSelect={handleModelSelect}
|
||||
mode="hoverSelect"
|
||||
<ModelSelector
|
||||
items={imageEditorModels}
|
||||
category={ModelCategory.ImageEditor}
|
||||
panelTitle="Select Model"
|
||||
panelClassName="min-w-[280px]"
|
||||
buttonClassName="bg-transparent p-0 text-lg hover:bg-transparent text-white/80 hover:text-white"
|
||||
|
||||
@@ -3,4 +3,7 @@ export enum ModelCategory {
|
||||
ImageToVideo = "image-to-video",
|
||||
Canvas2D = "2d-canvas",
|
||||
Editor3D = "3d-editor",
|
||||
|
||||
// The "inpainting + outpainting + text" image editor
|
||||
ImageEditor = "image-editor",
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
getCreatorIcon,
|
||||
getModelsByCategory,
|
||||
getInstructiveImageEditModels,
|
||||
getEditorModels,
|
||||
} from "@storyteller/model-list";
|
||||
|
||||
export type ModelList = Omit<PopoverItem, "selected">[];
|
||||
@@ -35,6 +36,9 @@ const imageModels = getModelsByCategory("image");
|
||||
const videoModels = getModelsByCategory("video");
|
||||
const instructiveModels = getInstructiveImageEditModels();
|
||||
|
||||
// Models for the editor page (not 2d canvas, the inpaint/outpaint editor)
|
||||
const imageEditModels = getEditorModels();
|
||||
|
||||
export const allModels = {
|
||||
video: buildItems(
|
||||
videoModels as any,
|
||||
@@ -48,9 +52,15 @@ export const allModels = {
|
||||
instructiveModels as any,
|
||||
<FontAwesomeIcon icon={faImage} className="h-4 w-4" />
|
||||
),
|
||||
imageEditorModels: buildItems(
|
||||
imageEditModels as any,
|
||||
<FontAwesomeIcon icon={faImage} className="h-4 w-4" />
|
||||
),
|
||||
};
|
||||
|
||||
export const videoGenerationModels: ModelList = allModels.video;
|
||||
export const imageGenerationModels: ModelList = allModels.image;
|
||||
export const instructiveImageEditModels: ModelList =
|
||||
allModels.instructiveImageEdits;
|
||||
|
||||
export const imageEditorModels: ModelList = allModels.imageEditorModels;
|
||||
@@ -63,6 +63,7 @@ export const PromptBoxEdit = ({
|
||||
// Build generation count options based on selected model
|
||||
useEffect(() => {
|
||||
const caps = getCapabilitiesForModel(modelInfo);
|
||||
console.log(">>> caps", caps)
|
||||
const items: PopoverItem[] = Array.from(
|
||||
{ length: caps.maxGenerationCount },
|
||||
(_, i) => i + 1
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
export enum ModelTag {
|
||||
// Models that show up in the 2D and 3D editors
|
||||
InstructiveEdit = "instructiveEdit",
|
||||
|
||||
// Models that show up in the inpainting editor and that use masking.
|
||||
MaskedInpainting = "maskedInpainting",
|
||||
|
||||
// Models that show up in the inpainting editor, but that do not use masking.
|
||||
NonMaskedInpainting = "nonMaskedInpainting",
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ModelCreator } from "./ModelCreator.js";
|
||||
import { ModelInfo } from "./ModelInfo.js";
|
||||
import { ModelTag } from "./ModelTag.js";
|
||||
|
||||
export type ModelCategory = "image" | "video";
|
||||
|
||||
@@ -11,7 +12,7 @@ export interface ModelConfig {
|
||||
category: ModelCategory;
|
||||
info: ModelInfo;
|
||||
capabilities: ModelCapabilities;
|
||||
tags?: string[]; // optional tags, e.g. ["instructiveEdit"] - for filtering
|
||||
tags?: (ModelTag|string)[]; // optional tags, e.g. ["instructiveEdit"] - for filtering
|
||||
}
|
||||
|
||||
const mc = ModelCreator;
|
||||
@@ -130,7 +131,23 @@ export const ALL_MODELS: ModelConfig[] = [
|
||||
description: "Fast and high-quality model",
|
||||
badges: [{ label: "20 sec." }],
|
||||
capabilities: { maxGenerationCount: 4 },
|
||||
tags: ["instructiveEdit"],
|
||||
tags: [
|
||||
ModelTag.InstructiveEdit,
|
||||
ModelTag.NonMaskedInpainting,
|
||||
],
|
||||
}),
|
||||
cfg({
|
||||
id: "flux_pro_inpaint",
|
||||
category: "image",
|
||||
info: {
|
||||
name: "Flux Pro 1 (Inpainting)",
|
||||
tauri_id: "flux_pro_1",
|
||||
creator: mc.BlackForestLabs,
|
||||
},
|
||||
description: "Fast and high-quality model",
|
||||
badges: [{ label: "20 sec." }],
|
||||
capabilities: { maxGenerationCount: 4 },
|
||||
tags: [ModelTag.MaskedInpainting],
|
||||
}),
|
||||
|
||||
//////////////////////////////
|
||||
@@ -204,6 +221,20 @@ export const getInstructiveImageEditModels = (): ModelConfig[] =>
|
||||
(m) => m.category === "image" && m.tags?.includes("instructiveEdit")
|
||||
);
|
||||
|
||||
export const getMaskedInpaintModels = (): ModelConfig[] =>
|
||||
ALL_MODELS.filter(
|
||||
(m) => m.category === "image" && m.tags?.includes(ModelTag.MaskedInpainting)
|
||||
);
|
||||
|
||||
// Models for the editor page
|
||||
export const getEditorModels = (): ModelConfig[] =>
|
||||
ALL_MODELS.filter(
|
||||
(m) => m.category === "image" && (
|
||||
m.tags?.includes(ModelTag.MaskedInpainting)
|
||||
|| m.tags?.includes(ModelTag.NonMaskedInpainting)
|
||||
)
|
||||
);
|
||||
|
||||
export const lookupModelByTauriId = (
|
||||
tauriId: string
|
||||
): ModelConfig | undefined =>
|
||||
|
||||
Reference in new issue
Block a user