- Implemented ComfyGenerateRequest type and associated functions for generating images using various architectures and modes. - Added functions for listing generation options and handling image uploads. - Created workflows for different generation modes including SDXL, Z-Image, Z-Image Turbo, and Anima. - Introduced GenerationJobStatus component to display the status of ongoing generation jobs. - Developed MaskControls for managing mask operations and displaying mask analysis. - Created palette items for tool selection, layer management, and generation settings.
58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
import { useCallback, useEffect, useRef } from "react";
|
|
import type { AppStore } from "@editor/store";
|
|
import { importImageAsLayer } from "@operations/import/importImage";
|
|
import { decodeBrowserImageFile } from "@platform/browser/imageFiles";
|
|
|
|
export function useImageImport(store: AppStore) {
|
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
|
|
const importFile = useCallback(
|
|
async (file: File) => {
|
|
const image = await decodeBrowserImageFile(file);
|
|
if (image) importImageAsLayer(store, image);
|
|
},
|
|
[store],
|
|
);
|
|
|
|
const openFilePicker = useCallback(() => inputRef.current?.click(), []);
|
|
|
|
useEffect(() => {
|
|
const handleKeyDown = (event: KeyboardEvent) => {
|
|
if (event.defaultPrevented || event.key.toLowerCase() !== "o" || (!event.metaKey && !event.ctrlKey)) return;
|
|
event.preventDefault();
|
|
openFilePicker();
|
|
};
|
|
|
|
const handlePaste = (event: ClipboardEvent) => {
|
|
const file = [...(event.clipboardData?.files ?? [])].find((candidate) => candidate.type.startsWith("image/"));
|
|
if (!file) return;
|
|
|
|
event.preventDefault();
|
|
void importFile(file);
|
|
};
|
|
|
|
window.addEventListener("keydown", handleKeyDown);
|
|
window.addEventListener("paste", handlePaste);
|
|
return () => {
|
|
window.removeEventListener("keydown", handleKeyDown);
|
|
window.removeEventListener("paste", handlePaste);
|
|
};
|
|
}, [importFile, openFilePicker]);
|
|
|
|
const input = (
|
|
<input
|
|
ref={inputRef}
|
|
type="file"
|
|
accept="image/*"
|
|
className="hidden"
|
|
onChange={(event) => {
|
|
const file = event.currentTarget.files?.[0];
|
|
event.currentTarget.value = "";
|
|
if (file) void importFile(file);
|
|
}}
|
|
/>
|
|
);
|
|
|
|
return { input, openFilePicker, importFile };
|
|
}
|