|
|
@ -22,6 +22,11 @@ import { useShowHandleLabels } from "@/hooks/useShowHandleLabels"; |
|
|
import { HandleLabel } from "./HandleLabel"; |
|
|
import { HandleLabel } from "./HandleLabel"; |
|
|
import { useI18n } from "@/i18n"; |
|
|
import { useI18n } from "@/i18n"; |
|
|
import { createGeminiLegacyImageModel, createNewApiWGDefaultImageModel } from "@/store/utils/defaultImageModel"; |
|
|
import { createGeminiLegacyImageModel, createNewApiWGDefaultImageModel } from "@/store/utils/defaultImageModel"; |
|
|
|
|
|
import { |
|
|
|
|
|
isBrowserFileSystemPath, |
|
|
|
|
|
joinBrowserFileSystemPath, |
|
|
|
|
|
loadBrowserGenerationFile, |
|
|
|
|
|
} from "@/utils/browserFileSystem"; |
|
|
|
|
|
|
|
|
/** Reorder items so they read column-first in a row-based CSS grid. |
|
|
/** Reorder items so they read column-first in a row-based CSS grid. |
|
|
* e.g. [1,2,3,4,5,6,7,8] with 2 cols → [1,5,2,6,3,7,4,8] */ |
|
|
* e.g. [1,2,3,4,5,6,7,8] with 2 cols → [1,5,2,6,3,7,4,8] */ |
|
|
@ -65,6 +70,7 @@ export function GenerateImageNode({ id, data, selected }: NodeProps<NanoBananaNo |
|
|
const adaptiveOutputImage = useAdaptiveImageSrc(data.outputImage, id); |
|
|
const adaptiveOutputImage = useAdaptiveImageSrc(data.outputImage, id); |
|
|
const updateNodeData = useWorkflowStore((state) => state.updateNodeData); |
|
|
const updateNodeData = useWorkflowStore((state) => state.updateNodeData); |
|
|
const generationsPath = useWorkflowStore((state) => state.generationsPath); |
|
|
const generationsPath = useWorkflowStore((state) => state.generationsPath); |
|
|
|
|
|
const saveDirectoryPath = useWorkflowStore((state) => state.saveDirectoryPath); |
|
|
// Use stable selector for API keys to prevent unnecessary re-fetches
|
|
|
// Use stable selector for API keys to prevent unnecessary re-fetches
|
|
|
const { newApiWGApiKey, newApiWGBaseUrl, replicateApiKey, falApiKey, kieApiKey, replicateEnabled, kieEnabled } = useProviderApiKeys(); |
|
|
const { newApiWGApiKey, newApiWGBaseUrl, replicateApiKey, falApiKey, kieApiKey, replicateEnabled, kieEnabled } = useProviderApiKeys(); |
|
|
const [isLoadingCarouselImage, setIsLoadingCarouselImage] = useState(false); |
|
|
const [isLoadingCarouselImage, setIsLoadingCarouselImage] = useState(false); |
|
|
@ -334,17 +340,26 @@ export function GenerateImageNode({ id, data, selected }: NodeProps<NanoBananaNo |
|
|
}, [id, regenerateNode]); |
|
|
}, [id, regenerateNode]); |
|
|
|
|
|
|
|
|
const loadImageById = useCallback(async (imageId: string) => { |
|
|
const loadImageById = useCallback(async (imageId: string) => { |
|
|
if (!generationsPath) { |
|
|
const effectiveGenerationsPath = generationsPath |
|
|
|
|
|
?? (isBrowserFileSystemPath(saveDirectoryPath) |
|
|
|
|
|
? joinBrowserFileSystemPath(saveDirectoryPath, "generations") |
|
|
|
|
|
: null); |
|
|
|
|
|
|
|
|
|
|
|
if (!effectiveGenerationsPath) { |
|
|
console.error("Generations path not configured"); |
|
|
console.error("Generations path not configured"); |
|
|
return null; |
|
|
return null; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
|
|
|
if (isBrowserFileSystemPath(effectiveGenerationsPath)) { |
|
|
|
|
|
return await loadBrowserGenerationFile(effectiveGenerationsPath, imageId); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
const response = await fetch("/api/load-generation", { |
|
|
const response = await fetch("/api/load-generation", { |
|
|
method: "POST", |
|
|
method: "POST", |
|
|
headers: { "Content-Type": "application/json" }, |
|
|
headers: { "Content-Type": "application/json" }, |
|
|
body: JSON.stringify({ |
|
|
body: JSON.stringify({ |
|
|
directoryPath: generationsPath, |
|
|
directoryPath: effectiveGenerationsPath, |
|
|
imageId, |
|
|
imageId, |
|
|
}), |
|
|
}), |
|
|
}); |
|
|
}); |
|
|
@ -360,7 +375,7 @@ export function GenerateImageNode({ id, data, selected }: NodeProps<NanoBananaNo |
|
|
console.warn("Error loading image:", error); |
|
|
console.warn("Error loading image:", error); |
|
|
return null; |
|
|
return null; |
|
|
} |
|
|
} |
|
|
}, [generationsPath]); |
|
|
}, [generationsPath, saveDirectoryPath]); |
|
|
|
|
|
|
|
|
const handleCarouselPrevious = useCallback(async () => { |
|
|
const handleCarouselPrevious = useCallback(async () => { |
|
|
const history = nodeData.imageHistory || []; |
|
|
const history = nodeData.imageHistory || []; |
|
|
|