diff --git a/src/components/nodes/GenerateAudioNode.tsx b/src/components/nodes/GenerateAudioNode.tsx
index f0290671..5bf5d90d 100644
--- a/src/components/nodes/GenerateAudioNode.tsx
+++ b/src/components/nodes/GenerateAudioNode.tsx
@@ -12,37 +12,6 @@ import { ProviderModel, ModelCapability } from "@/lib/providers/types";
import { ModelSearchDialog } from "@/components/modals/ModelSearchDialog";
import { useAudioVisualization } from "@/hooks/useAudioVisualization";
-// Provider badge component
-function ProviderBadge({ provider }: { provider: ProviderType }) {
- const providerName = provider === "kie" ? "Kie.ai" : provider === "replicate" ? "Replicate" : provider === "wavespeed" ? "WaveSpeed" : "fal.ai";
-
- return (
-
- {provider === "kie" ? (
-
- ) : provider === "replicate" ? (
-
- ) : provider === "wavespeed" ? (
-
- ) : (
-
- )}
-
- );
-}
-
// Audio generation capabilities
const AUDIO_CAPABILITIES: ModelCapability[] = ["text-to-audio"];
@@ -105,34 +74,40 @@ export function GenerateAudioNode({ id, data, selected }: NodeProps {
- if (nodeData.outputAudio && !audioRef.current) {
- const audio = new Audio(nodeData.outputAudio);
- audioRef.current = audio;
+ if (!nodeData.outputAudio) {
+ if (audioRef.current) {
+ audioRef.current.pause();
+ audioRef.current = null;
+ }
+ setIsPlaying(false);
+ setCurrentTime(0);
+ return;
+ }
- const handleEnded = () => {
- setIsPlaying(false);
- setCurrentTime(0);
- };
- const handleTimeUpdate = () => {
- setCurrentTime(audio.currentTime);
- };
+ // Clean up previous audio element
+ if (audioRef.current) {
+ audioRef.current.pause();
+ }
- audio.addEventListener("ended", handleEnded);
- audio.addEventListener("timeupdate", handleTimeUpdate);
+ const audio = new Audio(nodeData.outputAudio);
+ audioRef.current = audio;
- return () => {
- audio.removeEventListener("ended", handleEnded);
- audio.removeEventListener("timeupdate", handleTimeUpdate);
- audio.pause();
- audioRef.current = null;
- };
- }
+ const handleEnded = () => {
+ setIsPlaying(false);
+ setCurrentTime(0);
+ };
+ const handleTimeUpdate = () => {
+ setCurrentTime(audio.currentTime);
+ };
+
+ audio.addEventListener("ended", handleEnded);
+ audio.addEventListener("timeupdate", handleTimeUpdate);
return () => {
- if (audioRef.current) {
- audioRef.current.pause();
- audioRef.current = null;
- }
+ audio.removeEventListener("ended", handleEnded);
+ audio.removeEventListener("timeupdate", handleTimeUpdate);
+ audio.pause();
+ audioRef.current = null;
};
}, [nodeData.outputAudio]);
diff --git a/src/components/nodes/GenerateImageNode.tsx b/src/components/nodes/GenerateImageNode.tsx
index 686afe93..6fcddc2e 100644
--- a/src/components/nodes/GenerateImageNode.tsx
+++ b/src/components/nodes/GenerateImageNode.tsx
@@ -12,41 +12,7 @@ import { ProviderModel, ModelCapability } from "@/lib/providers/types";
import { ModelSearchDialog } from "@/components/modals/ModelSearchDialog";
import { useToast } from "@/components/Toast";
import { getImageDimensions, calculateNodeSizePreservingHeight } from "@/utils/nodeDimensions";
-
-// Provider badge component - shows provider icon for all providers
-function ProviderBadge({ provider }: { provider: ProviderType }) {
- const providerName = provider === "gemini" ? "Gemini" : provider === "replicate" ? "Replicate" : provider === "kie" ? "Kie.ai" : provider === "wavespeed" ? "WaveSpeed" : "fal.ai";
-
- return (
-
- {provider === "gemini" ? (
-
- ) : provider === "replicate" ? (
-
- ) : provider === "kie" ? (
-
- ) : provider === "wavespeed" ? (
-
- ) : (
-
- )}
-
- );
-}
+import { ProviderBadge } from "./ProviderBadge";
// All 10 aspect ratios supported by both models
const ASPECT_RATIOS: AspectRatio[] = ["1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9"];
diff --git a/src/components/nodes/GenerateVideoNode.tsx b/src/components/nodes/GenerateVideoNode.tsx
index 19f71b99..6eef7ac2 100644
--- a/src/components/nodes/GenerateVideoNode.tsx
+++ b/src/components/nodes/GenerateVideoNode.tsx
@@ -12,41 +12,7 @@ import { ProviderModel, ModelCapability } from "@/lib/providers/types";
import { ModelSearchDialog } from "@/components/modals/ModelSearchDialog";
import { useToast } from "@/components/Toast";
import { getVideoDimensions, calculateNodeSizePreservingHeight } from "@/utils/nodeDimensions";
-
-// Provider badge component - shows provider icon for all providers
-function ProviderBadge({ provider }: { provider: ProviderType }) {
- const providerName = provider === "gemini" ? "Gemini" : provider === "replicate" ? "Replicate" : provider === "kie" ? "Kie.ai" : provider === "wavespeed" ? "WaveSpeed" : "fal.ai";
-
- return (
-
- {provider === "gemini" ? (
-
- ) : provider === "replicate" ? (
-
- ) : provider === "kie" ? (
-
- ) : provider === "wavespeed" ? (
-
- ) : (
-
- )}
-
- );
-}
+import { ProviderBadge } from "./ProviderBadge";
// Video generation capabilities
const VIDEO_CAPABILITIES: ModelCapability[] = ["text-to-video", "image-to-video"];
diff --git a/src/components/nodes/ProviderBadge.tsx b/src/components/nodes/ProviderBadge.tsx
new file mode 100644
index 00000000..af165f55
--- /dev/null
+++ b/src/components/nodes/ProviderBadge.tsx
@@ -0,0 +1,37 @@
+import React from "react";
+import { ProviderType } from "@/types";
+
+/** Provider badge component - shows provider icon for all providers */
+export function ProviderBadge({ provider }: { provider: ProviderType }) {
+ const providerName = provider === "gemini" ? "Gemini" : provider === "replicate" ? "Replicate" : provider === "kie" ? "Kie.ai" : provider === "wavespeed" ? "WaveSpeed" : "fal.ai";
+
+ return (
+
+ {provider === "gemini" ? (
+
+ ) : provider === "replicate" ? (
+
+ ) : provider === "kie" ? (
+
+ ) : provider === "wavespeed" ? (
+
+ ) : (
+
+ )}
+
+ );
+}