@effectnode/media 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/effectnode-media +2 -0
- package/dist/backend/index.d.ts +8 -0
- package/dist/backend/index.js +13 -0
- package/dist/backend/movie-backend/agent/agent-backend.d.ts +16 -0
- package/dist/backend/movie-backend/agent/agent-backend.js +703 -0
- package/dist/backend/movie-backend/agent/storyprompt.d.ts +1 -0
- package/dist/backend/movie-backend/agent/storyprompt.js +90 -0
- package/dist/backend/movie-backend/agent/tools/edit-image.d.ts +3 -0
- package/dist/backend/movie-backend/agent/tools/edit-image.js +192 -0
- package/dist/backend/movie-backend/agent/tools/get-time.d.ts +3 -0
- package/dist/backend/movie-backend/agent/tools/get-time.js +7 -0
- package/dist/backend/movie-backend/agent/tools/grep-files.d.ts +3 -0
- package/dist/backend/movie-backend/agent/tools/grep-files.js +59 -0
- package/dist/backend/movie-backend/agent/tools/image-to-video-generation.d.ts +3 -0
- package/dist/backend/movie-backend/agent/tools/image-to-video-generation.js +160 -0
- package/dist/backend/movie-backend/agent/tools/index.d.ts +7 -0
- package/dist/backend/movie-backend/agent/tools/index.js +59 -0
- package/dist/backend/movie-backend/agent/tools/list-files.d.ts +3 -0
- package/dist/backend/movie-backend/agent/tools/list-files.js +17 -0
- package/dist/backend/movie-backend/agent/tools/read-file.d.ts +3 -0
- package/dist/backend/movie-backend/agent/tools/read-file.js +28 -0
- package/dist/backend/movie-backend/agent/tools/remove-file.d.ts +3 -0
- package/dist/backend/movie-backend/agent/tools/remove-file.js +22 -0
- package/dist/backend/movie-backend/agent/tools/rename-file.d.ts +3 -0
- package/dist/backend/movie-backend/agent/tools/rename-file.js +37 -0
- package/dist/backend/movie-backend/agent/tools/show-image.d.ts +3 -0
- package/dist/backend/movie-backend/agent/tools/show-image.js +28 -0
- package/dist/backend/movie-backend/agent/tools/stitch-videos.d.ts +3 -0
- package/dist/backend/movie-backend/agent/tools/stitch-videos.js +96 -0
- package/dist/backend/movie-backend/agent/tools/text-to-video-generation.d.ts +3 -0
- package/dist/backend/movie-backend/agent/tools/text-to-video-generation.js +125 -0
- package/dist/backend/movie-backend/agent/tools/types.d.ts +15 -0
- package/dist/backend/movie-backend/agent/tools/types.js +1 -0
- package/dist/backend/movie-backend/agent/tools/update-file.d.ts +3 -0
- package/dist/backend/movie-backend/agent/tools/update-file.js +27 -0
- package/dist/backend/movie-backend/agent/tools/write-file.d.ts +3 -0
- package/dist/backend/movie-backend/agent/tools/write-file.js +26 -0
- package/dist/backend/movie-backend/agent/workspace.d.ts +25 -0
- package/dist/backend/movie-backend/agent/workspace.js +124 -0
- package/dist/backend/movie-backend/core.d.ts +4 -0
- package/dist/backend/movie-backend/core.js +1167 -0
- package/dist/backend/movie-backend/generation-queue.d.ts +24 -0
- package/dist/backend/movie-backend/generation-queue.js +766 -0
- package/dist/backend/movie-backend/process.d.ts +21 -0
- package/dist/backend/movie-backend/process.js +98 -0
- package/dist/backend/movie-backend/render-media.d.ts +48 -0
- package/dist/backend/movie-backend/render-media.js +3311 -0
- package/dist/backend/routes/health.d.ts +1 -0
- package/dist/backend/routes/health.js +9 -0
- package/dist/backend/routes/index.d.ts +1 -0
- package/dist/backend/routes/index.js +11 -0
- package/dist/backend/routes/media.d.ts +1 -0
- package/dist/backend/routes/media.js +13 -0
- package/dist/backend/routes/projects.d.ts +8 -0
- package/dist/backend/routes/projects.js +68 -0
- package/dist/backend/routes/voice.d.ts +1 -0
- package/dist/backend/routes/voice.js +39 -0
- package/dist/backend/routes.d.ts +1 -0
- package/dist/backend/routes.js +20 -0
- package/dist/backend/server.d.ts +1 -0
- package/dist/backend/server.js +23 -0
- package/dist/backend/workspace.d.ts +5 -0
- package/dist/backend/workspace.js +27 -0
- package/dist/backend/ws/index.d.ts +3 -0
- package/dist/backend/ws/index.js +27 -0
- package/dist/backend/ws/messages.d.ts +8 -0
- package/dist/backend/ws/messages.js +21 -0
- package/dist/backend/ws.d.ts +3 -0
- package/dist/backend/ws.js +29 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +80 -0
- package/frontend/index.html +22 -0
- package/frontend/public/ffmpeg/ffmpeg-core.js +16 -0
- package/frontend/public/ffmpeg/ffmpeg-core.wasm +0 -0
- package/frontend/src/index.css +46 -0
- package/frontend/src/main.tsx +13 -0
- package/frontend/src/movie-app/AppRouter.tsx +14 -0
- package/frontend/src/movie-app/MediaStudio.tsx +9 -0
- package/frontend/src/movie-app/SetupPage.tsx +293 -0
- package/frontend/src/movie-app/components/AgentWorkspace.tsx +574 -0
- package/frontend/src/movie-app/components/ChatUI/ChatUI.tsx +655 -0
- package/frontend/src/movie-app/components/ChatUI/MarkdownMessage.tsx +267 -0
- package/frontend/src/movie-app/components/EditorTabs/AgentTab.tsx +61 -0
- package/frontend/src/movie-app/components/EditorTabs/BatchImageToVideoTab.tsx +927 -0
- package/frontend/src/movie-app/components/EditorTabs/BatchVideoTab.tsx +777 -0
- package/frontend/src/movie-app/components/EditorTabs/BatchVoiceVideoTab.tsx +913 -0
- package/frontend/src/movie-app/components/EditorTabs/CharacterSheet.tsx +234 -0
- package/frontend/src/movie-app/components/EditorTabs/CharactersTab.tsx +664 -0
- package/frontend/src/movie-app/components/EditorTabs/CropTool.tsx +251 -0
- package/frontend/src/movie-app/components/EditorTabs/ExtendVideoTab.tsx +305 -0
- package/frontend/src/movie-app/components/EditorTabs/ExtractImageTab.tsx +249 -0
- package/frontend/src/movie-app/components/EditorTabs/FastImageEditTab.tsx +555 -0
- package/frontend/src/movie-app/components/EditorTabs/GenerateVideoTab.tsx +722 -0
- package/frontend/src/movie-app/components/EditorTabs/LlmServerTab.tsx +40 -0
- package/frontend/src/movie-app/components/EditorTabs/MlxVlmServerPanel.tsx +490 -0
- package/frontend/src/movie-app/components/EditorTabs/MovieStudioTab.tsx +938 -0
- package/frontend/src/movie-app/components/EditorTabs/ReferencesToVideoTab.tsx +881 -0
- package/frontend/src/movie-app/components/EditorTabs/SceneVisualTab.tsx +267 -0
- package/frontend/src/movie-app/components/EditorTabs/StoryWriterTab.tsx +51 -0
- package/frontend/src/movie-app/components/EditorTabs/TaskQueuePanel.tsx +246 -0
- package/frontend/src/movie-app/components/EditorTabs/TerminalLogPanel.tsx +49 -0
- package/frontend/src/movie-app/components/EditorTabs/TextToImageTab.tsx +574 -0
- package/frontend/src/movie-app/components/EditorTabs/VoiceChatPanel.tsx +320 -0
- package/frontend/src/movie-app/components/ProjectEditorPage.tsx +636 -0
- package/frontend/src/movie-app/components/ProjectManager.tsx +381 -0
- package/frontend/src/movie-app/index.css +46 -0
- package/frontend/src/movie-app/index.html +16 -0
- package/frontend/src/movie-app/lambobo.png +0 -0
- package/frontend/src/movie-app/lib/batchImageToVideoStorage.ts +69 -0
- package/frontend/src/movie-app/lib/batchVideoStorage.ts +68 -0
- package/frontend/src/movie-app/lib/batchVoiceStorage.ts +75 -0
- package/frontend/src/movie-app/lib/ffmpeg.ts +42 -0
- package/frontend/src/movie-app/lib/referencesToVideoStorage.ts +64 -0
- package/frontend/src/movie-app/lib/textToImageStorage.ts +61 -0
- package/frontend/src/movie-app/public/ffmpeg/ffmpeg-core.js +16 -0
- package/frontend/src/movie-app/public/ffmpeg/ffmpeg-core.wasm +0 -0
- package/frontend/src/movie-app/stores/batchImageToVideoStore.ts +736 -0
- package/frontend/src/movie-app/stores/batchVideoStore.ts +670 -0
- package/frontend/src/movie-app/stores/batchVoiceStore.ts +990 -0
- package/frontend/src/movie-app/stores/characterStore.ts +109 -0
- package/frontend/src/movie-app/stores/chatStore.ts +459 -0
- package/frontend/src/movie-app/stores/generationStore.ts +2140 -0
- package/frontend/src/movie-app/stores/logStore.ts +25 -0
- package/frontend/src/movie-app/stores/movieStudioStore.ts +709 -0
- package/frontend/src/movie-app/stores/projectStore.ts +124 -0
- package/frontend/src/movie-app/stores/queueStore.ts +214 -0
- package/frontend/src/movie-app/stores/referencesToVideoStore.ts +467 -0
- package/frontend/src/movie-app/stores/sceneVisualStore.ts +251 -0
- package/frontend/src/movie-app/stores/voiceChatStore.ts +170 -0
- package/frontend/src/movie-app/stores/workspaceStore.ts +158 -0
- package/frontend/src/vite-env.d.ts +1 -0
- package/frontend/tsconfig.json +19 -0
- package/package.json +65 -0
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { useParams, useNavigate } from "react-router-dom";
|
|
3
|
+
import { useProjectStore, type Project } from "../stores/projectStore";
|
|
4
|
+
import { useGenerationStore } from "../stores/generationStore";
|
|
5
|
+
import ExtendVideoTab from "./EditorTabs/ExtendVideoTab";
|
|
6
|
+
import FastImageEditTab from "./EditorTabs/FastImageEditTab";
|
|
7
|
+
import MovieStudioTab from "./EditorTabs/MovieStudioTab";
|
|
8
|
+
import GenerateVideoTab from "./EditorTabs/GenerateVideoTab";
|
|
9
|
+
import AgentTab from "./EditorTabs/AgentTab";
|
|
10
|
+
import StoryWriterTab from "./EditorTabs/StoryWriterTab";
|
|
11
|
+
import CharactersTab from "./EditorTabs/CharactersTab";
|
|
12
|
+
import ExtractImageTab from "./EditorTabs/ExtractImageTab";
|
|
13
|
+
import SceneVisualTab from "./EditorTabs/SceneVisualTab";
|
|
14
|
+
import TextToImageTab from "./EditorTabs/TextToImageTab";
|
|
15
|
+
import ReferencesToVideoTab from "./EditorTabs/ReferencesToVideoTab";
|
|
16
|
+
import BatchVideoTab from "./EditorTabs/BatchVideoTab";
|
|
17
|
+
import BatchImageToVideoTab from "./EditorTabs/BatchImageToVideoTab";
|
|
18
|
+
import BatchVoiceVideoTab from "./EditorTabs/BatchVoiceVideoTab";
|
|
19
|
+
import LlmServerTab from "./EditorTabs/LlmServerTab";
|
|
20
|
+
|
|
21
|
+
export default function ProjectEditorPage() {
|
|
22
|
+
const { id } = useParams<{ id: string }>();
|
|
23
|
+
const navigate = useNavigate();
|
|
24
|
+
const { projects, fetchProjects } = useProjectStore();
|
|
25
|
+
const [project, setProject] = useState<Project | null>(null);
|
|
26
|
+
|
|
27
|
+
// Zustand generation store
|
|
28
|
+
const store = useGenerationStore();
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (projects.length === 0) {
|
|
32
|
+
fetchProjects();
|
|
33
|
+
}
|
|
34
|
+
}, []);
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
const found = projects.find((p) => p.id === id) || null;
|
|
38
|
+
setProject(found);
|
|
39
|
+
}, [id, projects]);
|
|
40
|
+
|
|
41
|
+
// Fetch project images and videos on mount
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (id) {
|
|
44
|
+
store.fetchProjectImages(id);
|
|
45
|
+
store.fetchProjectVideos(id);
|
|
46
|
+
}
|
|
47
|
+
}, [id]);
|
|
48
|
+
|
|
49
|
+
// Poll the LLM server status so the tab label light stays accurate
|
|
50
|
+
// regardless of which tab is active.
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
store.checkAgentStatus();
|
|
53
|
+
store.checkServerOnline();
|
|
54
|
+
const interval = setInterval(() => {
|
|
55
|
+
store.checkServerOnline();
|
|
56
|
+
}, 3000);
|
|
57
|
+
return () => clearInterval(interval);
|
|
58
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
59
|
+
}, []);
|
|
60
|
+
|
|
61
|
+
// ========== SVG Icons ==========
|
|
62
|
+
|
|
63
|
+
const BackIcon = (
|
|
64
|
+
<svg
|
|
65
|
+
width="16"
|
|
66
|
+
height="16"
|
|
67
|
+
viewBox="0 0 24 24"
|
|
68
|
+
fill="none"
|
|
69
|
+
stroke="currentColor"
|
|
70
|
+
strokeWidth="2"
|
|
71
|
+
>
|
|
72
|
+
<line x1="19" y1="12" x2="5" y2="12" />
|
|
73
|
+
<polyline points="12 19 5 12 12 5" />
|
|
74
|
+
</svg>
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const VideoIcon = (
|
|
78
|
+
<svg
|
|
79
|
+
width="18"
|
|
80
|
+
height="18"
|
|
81
|
+
viewBox="0 0 24 24"
|
|
82
|
+
fill="none"
|
|
83
|
+
stroke="currentColor"
|
|
84
|
+
strokeWidth="2"
|
|
85
|
+
>
|
|
86
|
+
<polygon points="23 7 16 12 23 17 23 7" />
|
|
87
|
+
<rect x="1" y="5" width="15" height="14" rx="2" ry="2" />
|
|
88
|
+
</svg>
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const ExtendIcon = (
|
|
92
|
+
<svg
|
|
93
|
+
width="18"
|
|
94
|
+
height="18"
|
|
95
|
+
viewBox="0 0 24 24"
|
|
96
|
+
fill="none"
|
|
97
|
+
stroke="currentColor"
|
|
98
|
+
strokeWidth="2"
|
|
99
|
+
strokeLinecap="round"
|
|
100
|
+
strokeLinejoin="round"
|
|
101
|
+
>
|
|
102
|
+
<polygon points="23 7 16 12 23 17 23 7" />
|
|
103
|
+
<rect x="1" y="5" width="15" height="14" rx="2" ry="2" />
|
|
104
|
+
<line x1="5" y1="12" x2="11" y2="12" />
|
|
105
|
+
<line x1="8" y1="9" x2="8" y2="15" />
|
|
106
|
+
</svg>
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const FastImageEditIcon = (
|
|
110
|
+
<svg
|
|
111
|
+
width="18"
|
|
112
|
+
height="18"
|
|
113
|
+
viewBox="0 0 24 24"
|
|
114
|
+
fill="none"
|
|
115
|
+
stroke="currentColor"
|
|
116
|
+
strokeWidth="2"
|
|
117
|
+
strokeLinecap="round"
|
|
118
|
+
strokeLinejoin="round"
|
|
119
|
+
>
|
|
120
|
+
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
|
|
121
|
+
</svg>
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
const MovieStudioIcon = (
|
|
125
|
+
<svg
|
|
126
|
+
width="18"
|
|
127
|
+
height="18"
|
|
128
|
+
viewBox="0 0 24 24"
|
|
129
|
+
fill="none"
|
|
130
|
+
stroke="currentColor"
|
|
131
|
+
strokeWidth="2"
|
|
132
|
+
strokeLinecap="round"
|
|
133
|
+
strokeLinejoin="round"
|
|
134
|
+
>
|
|
135
|
+
<path d="M20.2 6 3 11l-.9-2.4c-.3-1.1.3-2.2 1.3-2.5l13.5-4c1.1-.3 2.2.3 2.5 1.3Z" />
|
|
136
|
+
<path d="m6.2 5.3 3.1 3.9" />
|
|
137
|
+
<path d="m12.4 3.4 3.1 4" />
|
|
138
|
+
<path d="M3 11h18v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z" />
|
|
139
|
+
</svg>
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
const AgentIcon = (
|
|
143
|
+
<svg
|
|
144
|
+
width="18"
|
|
145
|
+
height="18"
|
|
146
|
+
viewBox="0 0 24 24"
|
|
147
|
+
fill="none"
|
|
148
|
+
stroke="currentColor"
|
|
149
|
+
strokeWidth="2"
|
|
150
|
+
strokeLinecap="round"
|
|
151
|
+
strokeLinejoin="round"
|
|
152
|
+
>
|
|
153
|
+
<rect x="4" y="4" width="16" height="16" rx="2" />
|
|
154
|
+
<circle cx="9" cy="9" r="1" />
|
|
155
|
+
<circle cx="15" cy="9" r="1" />
|
|
156
|
+
<line x1="9" y1="14" x2="15" y2="14" />
|
|
157
|
+
</svg>
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
const StoryWriterIcon = (
|
|
161
|
+
<svg
|
|
162
|
+
width="18"
|
|
163
|
+
height="18"
|
|
164
|
+
viewBox="0 0 24 24"
|
|
165
|
+
fill="none"
|
|
166
|
+
stroke="currentColor"
|
|
167
|
+
strokeWidth="2"
|
|
168
|
+
strokeLinecap="round"
|
|
169
|
+
strokeLinejoin="round"
|
|
170
|
+
>
|
|
171
|
+
<path d="M12 20h9" />
|
|
172
|
+
<path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" />
|
|
173
|
+
</svg>
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
const CharacterIcon = (
|
|
177
|
+
<svg
|
|
178
|
+
width="18"
|
|
179
|
+
height="18"
|
|
180
|
+
viewBox="0 0 24 24"
|
|
181
|
+
fill="none"
|
|
182
|
+
stroke="currentColor"
|
|
183
|
+
strokeWidth="2"
|
|
184
|
+
strokeLinecap="round"
|
|
185
|
+
strokeLinejoin="round"
|
|
186
|
+
>
|
|
187
|
+
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
|
|
188
|
+
<circle cx="12" cy="7" r="4" />
|
|
189
|
+
</svg>
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
const ExtractIcon = (
|
|
193
|
+
<svg
|
|
194
|
+
width="18"
|
|
195
|
+
height="18"
|
|
196
|
+
viewBox="0 0 24 24"
|
|
197
|
+
fill="none"
|
|
198
|
+
stroke="currentColor"
|
|
199
|
+
strokeWidth="2"
|
|
200
|
+
strokeLinecap="round"
|
|
201
|
+
strokeLinejoin="round"
|
|
202
|
+
>
|
|
203
|
+
<path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z" />
|
|
204
|
+
<circle cx="12" cy="13" r="4" />
|
|
205
|
+
</svg>
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
const SceneVisualIcon = (
|
|
209
|
+
<svg
|
|
210
|
+
width="18"
|
|
211
|
+
height="18"
|
|
212
|
+
viewBox="0 0 24 24"
|
|
213
|
+
fill="none"
|
|
214
|
+
stroke="currentColor"
|
|
215
|
+
strokeWidth="2"
|
|
216
|
+
strokeLinecap="round"
|
|
217
|
+
strokeLinejoin="round"
|
|
218
|
+
>
|
|
219
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
|
|
220
|
+
<circle cx="8.5" cy="8.5" r="1.5" />
|
|
221
|
+
<polyline points="21 15 16 10 5 21" />
|
|
222
|
+
</svg>
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
const TextToImageIcon = (
|
|
226
|
+
<svg
|
|
227
|
+
width="18"
|
|
228
|
+
height="18"
|
|
229
|
+
viewBox="0 0 24 24"
|
|
230
|
+
fill="none"
|
|
231
|
+
stroke="currentColor"
|
|
232
|
+
strokeWidth="2"
|
|
233
|
+
strokeLinecap="round"
|
|
234
|
+
strokeLinejoin="round"
|
|
235
|
+
>
|
|
236
|
+
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
|
|
237
|
+
</svg>
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
const ReferencesToVideoIcon = (
|
|
241
|
+
<svg
|
|
242
|
+
width="18"
|
|
243
|
+
height="18"
|
|
244
|
+
viewBox="0 0 24 24"
|
|
245
|
+
fill="none"
|
|
246
|
+
stroke="currentColor"
|
|
247
|
+
strokeWidth="2"
|
|
248
|
+
strokeLinecap="round"
|
|
249
|
+
strokeLinejoin="round"
|
|
250
|
+
>
|
|
251
|
+
<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20" />
|
|
252
|
+
<path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" />
|
|
253
|
+
</svg>
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
const BatchVideoIcon = (
|
|
257
|
+
<svg
|
|
258
|
+
width="18"
|
|
259
|
+
height="18"
|
|
260
|
+
viewBox="0 0 24 24"
|
|
261
|
+
fill="none"
|
|
262
|
+
stroke="currentColor"
|
|
263
|
+
strokeWidth="2"
|
|
264
|
+
strokeLinecap="round"
|
|
265
|
+
strokeLinejoin="round"
|
|
266
|
+
>
|
|
267
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
|
|
268
|
+
<line x1="3" y1="9" x2="21" y2="9" />
|
|
269
|
+
<line x1="3" y1="15" x2="21" y2="15" />
|
|
270
|
+
<line x1="9" y1="3" x2="9" y2="21" />
|
|
271
|
+
</svg>
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
const BatchVoiceIcon = (
|
|
275
|
+
<svg
|
|
276
|
+
width="18"
|
|
277
|
+
height="18"
|
|
278
|
+
viewBox="0 0 24 24"
|
|
279
|
+
fill="none"
|
|
280
|
+
stroke="currentColor"
|
|
281
|
+
strokeWidth="2"
|
|
282
|
+
strokeLinecap="round"
|
|
283
|
+
strokeLinejoin="round"
|
|
284
|
+
>
|
|
285
|
+
<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" />
|
|
286
|
+
<path d="M19 10v2a7 7 0 0 1-14 0v-2" />
|
|
287
|
+
<line x1="12" y1="19" x2="12" y2="23" />
|
|
288
|
+
</svg>
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
const BatchImageToVideoIcon = (
|
|
292
|
+
<svg
|
|
293
|
+
width="18"
|
|
294
|
+
height="18"
|
|
295
|
+
viewBox="0 0 24 24"
|
|
296
|
+
fill="none"
|
|
297
|
+
stroke="currentColor"
|
|
298
|
+
strokeWidth="2"
|
|
299
|
+
strokeLinecap="round"
|
|
300
|
+
strokeLinejoin="round"
|
|
301
|
+
>
|
|
302
|
+
<polygon points="12 2 2 7 12 12 22 7 12 2" />
|
|
303
|
+
<polyline points="2 17 12 22 22 17" />
|
|
304
|
+
<polyline points="2 12 12 17 22 12" />
|
|
305
|
+
</svg>
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
const ServerIcon = (
|
|
309
|
+
<svg
|
|
310
|
+
width="18"
|
|
311
|
+
height="18"
|
|
312
|
+
viewBox="0 0 24 24"
|
|
313
|
+
fill="none"
|
|
314
|
+
stroke="currentColor"
|
|
315
|
+
strokeWidth="2"
|
|
316
|
+
strokeLinecap="round"
|
|
317
|
+
strokeLinejoin="round"
|
|
318
|
+
>
|
|
319
|
+
<rect x="2" y="2" width="20" height="8" rx="2" ry="2" />
|
|
320
|
+
<rect x="2" y="14" width="20" height="8" rx="2" ry="2" />
|
|
321
|
+
<line x1="6" y1="6" x2="6.01" y2="6" />
|
|
322
|
+
<line x1="6" y1="18" x2="6.01" y2="18" />
|
|
323
|
+
</svg>
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
const ServerStatusLight = () => (
|
|
327
|
+
<span
|
|
328
|
+
className={`w-2.5 h-2.5 rounded-full ${
|
|
329
|
+
store.agent.serverOnline === true
|
|
330
|
+
? "bg-emerald-500 shadow-[0_0_6px_2px_rgba(16,185,129,0.5)]"
|
|
331
|
+
: store.agent.serverOnline === false
|
|
332
|
+
? "bg-red-500 shadow-[0_0_6px_2px_rgba(239,68,68,0.5)]"
|
|
333
|
+
: "bg-tiffany-500"
|
|
334
|
+
}`}
|
|
335
|
+
/>
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
// ========== Loading / Not Found ==========
|
|
339
|
+
|
|
340
|
+
if (!project) {
|
|
341
|
+
return (
|
|
342
|
+
<div className="flex flex-col items-center justify-center h-screen bg-ink-50">
|
|
343
|
+
<div className="w-16 h-16 bg-ink-100 rounded-3xl flex items-center justify-center mb-4">
|
|
344
|
+
<svg
|
|
345
|
+
width="28"
|
|
346
|
+
height="28"
|
|
347
|
+
viewBox="0 0 24 24"
|
|
348
|
+
fill="none"
|
|
349
|
+
stroke="#81d8d0"
|
|
350
|
+
strokeWidth="1.5"
|
|
351
|
+
>
|
|
352
|
+
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
|
|
353
|
+
</svg>
|
|
354
|
+
</div>
|
|
355
|
+
<p className="text-sm font-medium text-ink-800 mb-3">
|
|
356
|
+
Project not found
|
|
357
|
+
</p>
|
|
358
|
+
<button
|
|
359
|
+
onClick={() => navigate("/app")}
|
|
360
|
+
className="flex items-center gap-1.5 px-4 py-2 bg-ink-100 hover:bg-ink-300 text-ink-700 text-sm font-medium rounded-2xl transition-colors"
|
|
361
|
+
>
|
|
362
|
+
{BackIcon}
|
|
363
|
+
Back to Projects
|
|
364
|
+
</button>
|
|
365
|
+
</div>
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return (
|
|
370
|
+
<div className="flex flex-col h-screen bg-ink-50">
|
|
371
|
+
{/* Top bar */}
|
|
372
|
+
<div className="flex items-center gap-6 px-8 py-5 bg-white border-b border-ink-200 mb-8">
|
|
373
|
+
<button
|
|
374
|
+
onClick={() => {
|
|
375
|
+
store.resetAll();
|
|
376
|
+
navigate("/app");
|
|
377
|
+
}}
|
|
378
|
+
className="flex items-center gap-1.5 px-3 py-1.5 bg-ink-50 hover:bg-ink-200 text-ink-700 text-sm font-medium rounded-2xl transition-colors border border-ink-200/60"
|
|
379
|
+
>
|
|
380
|
+
{BackIcon}
|
|
381
|
+
Back
|
|
382
|
+
</button>
|
|
383
|
+
<div className="flex-1">
|
|
384
|
+
<h1 className="text-lg font-semibold text-ink-900 tracking-tight">
|
|
385
|
+
{project.name}
|
|
386
|
+
</h1>
|
|
387
|
+
{project.description && (
|
|
388
|
+
<p className="text-xs text-ink-600/60 mt-0.5">
|
|
389
|
+
{project.description}
|
|
390
|
+
</p>
|
|
391
|
+
)}
|
|
392
|
+
</div>
|
|
393
|
+
</div>
|
|
394
|
+
|
|
395
|
+
{/* Content */}
|
|
396
|
+
<div className="flex-1 px-8 pb-8">
|
|
397
|
+
<div className="bg-white border border-ink-200 rounded-3xl shadow-card p-8 min-h-full">
|
|
398
|
+
{/* ========== TAB BAR ========== */}
|
|
399
|
+
<div className="flex items-center gap-1.5 border-b border-ink-200 pb-5 mb-4 flex-wrap">
|
|
400
|
+
<button
|
|
401
|
+
onClick={() => store.setActiveTab("movieStudio")}
|
|
402
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
403
|
+
store.activeTab === "movieStudio"
|
|
404
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
405
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
406
|
+
}`}
|
|
407
|
+
>
|
|
408
|
+
{MovieStudioIcon}
|
|
409
|
+
Movie Studio
|
|
410
|
+
</button>
|
|
411
|
+
<button
|
|
412
|
+
onClick={() => store.setActiveTab("video")}
|
|
413
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
414
|
+
store.activeTab === "video"
|
|
415
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
416
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
417
|
+
}`}
|
|
418
|
+
>
|
|
419
|
+
{VideoIcon}
|
|
420
|
+
Generate Avatar ideo
|
|
421
|
+
</button>
|
|
422
|
+
<button
|
|
423
|
+
onClick={() => store.setActiveTab("extend")}
|
|
424
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
425
|
+
store.activeTab === "extend"
|
|
426
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
427
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
428
|
+
}`}
|
|
429
|
+
>
|
|
430
|
+
{ExtendIcon}
|
|
431
|
+
Extend Video
|
|
432
|
+
</button>
|
|
433
|
+
<button
|
|
434
|
+
onClick={() => store.setActiveTab("fastImageEdit")}
|
|
435
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
436
|
+
store.activeTab === "fastImageEdit"
|
|
437
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
438
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
439
|
+
}`}
|
|
440
|
+
>
|
|
441
|
+
{FastImageEditIcon}
|
|
442
|
+
Fast Image Edit
|
|
443
|
+
</button>
|
|
444
|
+
<button
|
|
445
|
+
onClick={() => store.setActiveTab("agent")}
|
|
446
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
447
|
+
store.activeTab === "agent"
|
|
448
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
449
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
450
|
+
}`}
|
|
451
|
+
>
|
|
452
|
+
{AgentIcon}
|
|
453
|
+
Agent
|
|
454
|
+
</button>
|
|
455
|
+
<button
|
|
456
|
+
onClick={() => store.setActiveTab("storyWriter")}
|
|
457
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
458
|
+
store.activeTab === "storyWriter"
|
|
459
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
460
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
461
|
+
}`}
|
|
462
|
+
>
|
|
463
|
+
{StoryWriterIcon}
|
|
464
|
+
Story Writer
|
|
465
|
+
</button>
|
|
466
|
+
<button
|
|
467
|
+
onClick={() => store.setActiveTab("characters")}
|
|
468
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
469
|
+
store.activeTab === "characters"
|
|
470
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
471
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
472
|
+
}`}
|
|
473
|
+
>
|
|
474
|
+
{CharacterIcon}
|
|
475
|
+
Characters
|
|
476
|
+
</button>
|
|
477
|
+
<button
|
|
478
|
+
onClick={() => store.setActiveTab("extract")}
|
|
479
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
480
|
+
store.activeTab === "extract"
|
|
481
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
482
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
483
|
+
}`}
|
|
484
|
+
>
|
|
485
|
+
{ExtractIcon}
|
|
486
|
+
Extract Image
|
|
487
|
+
</button>
|
|
488
|
+
<button
|
|
489
|
+
onClick={() => store.setActiveTab("sceneVisual")}
|
|
490
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
491
|
+
store.activeTab === "sceneVisual"
|
|
492
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
493
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
494
|
+
}`}
|
|
495
|
+
>
|
|
496
|
+
{SceneVisualIcon}
|
|
497
|
+
Scene Visual
|
|
498
|
+
</button>
|
|
499
|
+
<button
|
|
500
|
+
onClick={() => store.setActiveTab("textToImage")}
|
|
501
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
502
|
+
store.activeTab === "textToImage"
|
|
503
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
504
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
505
|
+
}`}
|
|
506
|
+
>
|
|
507
|
+
{TextToImageIcon}
|
|
508
|
+
Text-to-Image
|
|
509
|
+
</button>
|
|
510
|
+
<button
|
|
511
|
+
onClick={() => store.setActiveTab("referencesToVideo")}
|
|
512
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
513
|
+
store.activeTab === "referencesToVideo"
|
|
514
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
515
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
516
|
+
}`}
|
|
517
|
+
>
|
|
518
|
+
{ReferencesToVideoIcon}
|
|
519
|
+
References to Video
|
|
520
|
+
</button>
|
|
521
|
+
<button
|
|
522
|
+
onClick={() => store.setActiveTab("batchVideo")}
|
|
523
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
524
|
+
store.activeTab === "batchVideo"
|
|
525
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
526
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
527
|
+
}`}
|
|
528
|
+
>
|
|
529
|
+
{BatchVideoIcon}
|
|
530
|
+
Batch Video
|
|
531
|
+
</button>
|
|
532
|
+
<button
|
|
533
|
+
onClick={() => store.setActiveTab("batchImageToVideo")}
|
|
534
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
535
|
+
store.activeTab === "batchImageToVideo"
|
|
536
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
537
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
538
|
+
}`}
|
|
539
|
+
>
|
|
540
|
+
{BatchImageToVideoIcon}
|
|
541
|
+
Batch Image to Video
|
|
542
|
+
</button>
|
|
543
|
+
<button
|
|
544
|
+
onClick={() => store.setActiveTab("batchVoice")}
|
|
545
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
546
|
+
store.activeTab === "batchVoice"
|
|
547
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
548
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
549
|
+
}`}
|
|
550
|
+
>
|
|
551
|
+
{BatchVoiceIcon}
|
|
552
|
+
Batch Videos with Voice Over
|
|
553
|
+
</button>
|
|
554
|
+
<button
|
|
555
|
+
onClick={() => store.setActiveTab("llmServer")}
|
|
556
|
+
className={`flex items-center gap-2 px-5 py-2.5 text-sm font-medium rounded-2xl transition-all ${
|
|
557
|
+
store.activeTab === "llmServer"
|
|
558
|
+
? "bg-tiffany-500/10 text-tiffany-700 shadow-glow-sm"
|
|
559
|
+
: "text-ink-600 hover:bg-ink-100 hover:text-ink-800"
|
|
560
|
+
}`}
|
|
561
|
+
>
|
|
562
|
+
{ServerIcon}
|
|
563
|
+
LLM Server
|
|
564
|
+
<ServerStatusLight />
|
|
565
|
+
</button>
|
|
566
|
+
</div>
|
|
567
|
+
|
|
568
|
+
{/* ========== MOVIE STUDIO PANEL ========== */}
|
|
569
|
+
{store.activeTab === "movieStudio" && (
|
|
570
|
+
<MovieStudioTab projectId={id!} />
|
|
571
|
+
)}
|
|
572
|
+
|
|
573
|
+
{/* ========== FAST IMAGE EDIT PANEL ========== */}
|
|
574
|
+
{store.activeTab === "fastImageEdit" && (
|
|
575
|
+
<FastImageEditTab projectId={id!} />
|
|
576
|
+
)}
|
|
577
|
+
|
|
578
|
+
{/* ========== VIDEO GENERATION PANEL ========== */}
|
|
579
|
+
{store.activeTab === "video" && <GenerateVideoTab projectId={id!} />}
|
|
580
|
+
|
|
581
|
+
{/* ========== EXTEND VIDEO PANEL ========== */}
|
|
582
|
+
{store.activeTab === "extend" && <ExtendVideoTab projectId={id!} />}
|
|
583
|
+
|
|
584
|
+
{/* ========== AGENT PANEL ========== */}
|
|
585
|
+
{store.activeTab === "agent" && <AgentTab projectId={id!} />}
|
|
586
|
+
|
|
587
|
+
{/* ========== STORY WRITER PANEL ========== */}
|
|
588
|
+
{store.activeTab === "storyWriter" && (
|
|
589
|
+
<StoryWriterTab projectId={id!} />
|
|
590
|
+
)}
|
|
591
|
+
|
|
592
|
+
{/* ========== CHARACTERS PANEL ========== */}
|
|
593
|
+
{store.activeTab === "characters" && (
|
|
594
|
+
<CharactersTab projectId={id!} />
|
|
595
|
+
)}
|
|
596
|
+
|
|
597
|
+
{/* ========== EXTRACT IMAGE PANEL ========== */}
|
|
598
|
+
{store.activeTab === "extract" && <ExtractImageTab projectId={id!} />}
|
|
599
|
+
|
|
600
|
+
{/* ========== SCENE VISUAL PANEL ========== */}
|
|
601
|
+
{store.activeTab === "sceneVisual" && (
|
|
602
|
+
<SceneVisualTab projectId={id!} />
|
|
603
|
+
)}
|
|
604
|
+
|
|
605
|
+
{/* ========== TEXT-TO-IMAGE PANEL ========== */}
|
|
606
|
+
{store.activeTab === "textToImage" && (
|
|
607
|
+
<TextToImageTab projectId={id!} />
|
|
608
|
+
)}
|
|
609
|
+
|
|
610
|
+
{/* ========== REFERENCES TO VIDEO PANEL ========== */}
|
|
611
|
+
{store.activeTab === "referencesToVideo" && (
|
|
612
|
+
<ReferencesToVideoTab projectId={id!} />
|
|
613
|
+
)}
|
|
614
|
+
|
|
615
|
+
{/* ========== BATCH VIDEO PANEL ========== */}
|
|
616
|
+
{store.activeTab === "batchVideo" && (
|
|
617
|
+
<BatchVideoTab projectId={id!} />
|
|
618
|
+
)}
|
|
619
|
+
|
|
620
|
+
{/* ========== BATCH IMAGE TO VIDEO PANEL ========== */}
|
|
621
|
+
{store.activeTab === "batchImageToVideo" && (
|
|
622
|
+
<BatchImageToVideoTab projectId={id!} />
|
|
623
|
+
)}
|
|
624
|
+
|
|
625
|
+
{/* ========== BATCH VOICE VIDEO PANEL ========== */}
|
|
626
|
+
{store.activeTab === "batchVoice" && (
|
|
627
|
+
<BatchVoiceVideoTab projectId={id!} />
|
|
628
|
+
)}
|
|
629
|
+
|
|
630
|
+
{/* ========== LLM SERVER PANEL ========== */}
|
|
631
|
+
{store.activeTab === "llmServer" && <LlmServerTab />}
|
|
632
|
+
</div>
|
|
633
|
+
</div>
|
|
634
|
+
</div>
|
|
635
|
+
);
|
|
636
|
+
}
|