Browse Source

Remember image generate node settings

handoff-20260429-1057
Shrimbly 7 months ago
parent
commit
c71e1ba68d
  1. 18
      src/components/nodes/NanoBananaNode.tsx
  2. 44
      src/store/workflowStore.ts

18
src/components/nodes/NanoBananaNode.tsx

@ -3,7 +3,7 @@
import { useCallback } from "react";
import { Handle, Position, NodeProps, Node } from "@xyflow/react";
import { BaseNode } from "./BaseNode";
import { useWorkflowStore } from "@/store/workflowStore";
import { useWorkflowStore, saveNanoBananaDefaults } from "@/store/workflowStore";
import { NanoBananaNodeData, AspectRatio, Resolution, ModelType } from "@/types";
// All 10 aspect ratios supported by both models
@ -25,28 +25,36 @@ export function NanoBananaNode({ id, data, selected }: NodeProps<NanoBananaNodeT
const handleAspectRatioChange = useCallback(
(e: React.ChangeEvent<HTMLSelectElement>) => {
updateNodeData(id, { aspectRatio: e.target.value as AspectRatio });
const aspectRatio = e.target.value as AspectRatio;
updateNodeData(id, { aspectRatio });
saveNanoBananaDefaults({ aspectRatio });
},
[id, updateNodeData]
);
const handleResolutionChange = useCallback(
(e: React.ChangeEvent<HTMLSelectElement>) => {
updateNodeData(id, { resolution: e.target.value as Resolution });
const resolution = e.target.value as Resolution;
updateNodeData(id, { resolution });
saveNanoBananaDefaults({ resolution });
},
[id, updateNodeData]
);
const handleModelChange = useCallback(
(e: React.ChangeEvent<HTMLSelectElement>) => {
updateNodeData(id, { model: e.target.value as ModelType });
const model = e.target.value as ModelType;
updateNodeData(id, { model });
saveNanoBananaDefaults({ model });
},
[id, updateNodeData]
);
const handleGoogleSearchToggle = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
updateNodeData(id, { useGoogleSearch: e.target.checked });
const useGoogleSearch = e.target.checked;
updateNodeData(id, { useGoogleSearch });
saveNanoBananaDefaults({ useGoogleSearch });
},
[id, updateNodeData]
);

44
src/store/workflowStore.ts

@ -145,18 +145,20 @@ const createDefaultNodeData = (type: NodeType): WorkflowNodeData => {
return {
prompt: "",
} as PromptNodeData;
case "nanoBanana":
case "nanoBanana": {
const defaults = loadNanoBananaDefaults();
return {
inputImages: [],
inputPrompt: null,
outputImage: null,
aspectRatio: "1:1",
resolution: "1K",
model: "nano-banana-pro",
useGoogleSearch: false,
aspectRatio: defaults.aspectRatio,
resolution: defaults.resolution,
model: defaults.model,
useGoogleSearch: defaults.useGoogleSearch,
status: "idle",
error: null,
} as NanoBananaNodeData;
}
case "llmGenerate":
return {
inputPrompt: null,
@ -214,6 +216,38 @@ const GROUP_COLOR_ORDER: GroupColor[] = [
// localStorage helpers for auto-save configs
const STORAGE_KEY = "node-banana-workflow-configs";
// localStorage helpers for NanoBanana sticky settings
const NANO_BANANA_DEFAULTS_KEY = "node-banana-nanoBanana-defaults";
interface NanoBananaDefaults {
aspectRatio: string;
resolution: string;
model: string;
useGoogleSearch: boolean;
}
const loadNanoBananaDefaults = (): NanoBananaDefaults => {
if (typeof window === "undefined") {
return { aspectRatio: "1:1", resolution: "1K", model: "nano-banana-pro", useGoogleSearch: false };
}
const stored = localStorage.getItem(NANO_BANANA_DEFAULTS_KEY);
if (stored) {
try {
return JSON.parse(stored);
} catch {
return { aspectRatio: "1:1", resolution: "1K", model: "nano-banana-pro", useGoogleSearch: false };
}
}
return { aspectRatio: "1:1", resolution: "1K", model: "nano-banana-pro", useGoogleSearch: false };
};
export const saveNanoBananaDefaults = (settings: Partial<NanoBananaDefaults>) => {
if (typeof window === "undefined") return;
const current = loadNanoBananaDefaults();
const updated = { ...current, ...settings };
localStorage.setItem(NANO_BANANA_DEFAULTS_KEY, JSON.stringify(updated));
};
const generateWorkflowId = () =>
`wf_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

Loading…
Cancel
Save