Gertie2013 commited on
Commit
b62229e
·
verified ·
1 Parent(s): 91e9aba

Delete index.tsx

Browse files
Files changed (1) hide show
  1. index.tsx +0 -314
index.tsx DELETED
@@ -1,314 +0,0 @@
1
- import { useState, useEffect } from "react";
2
- import type { VoiceType } from "../lib/types";
3
-
4
- interface LibraryItem {
5
- id: string;
6
- title: string;
7
- duration: number;
8
- voice: VoiceType;
9
- blobUrl?: string;
10
- }
11
-
12
- export default function Home() {
13
- const [stylePrompt, setStylePrompt] = useState("");
14
- const [lyricPrompt, setLyricPrompt] = useState("");
15
- const [voice, setVoice] = useState<VoiceType>("Random");
16
- const [durationSeconds, setDurationSeconds] = useState<number | undefined>(undefined);
17
- const [isGenerating, setIsGenerating] = useState(false);
18
- const [result, setResult] = useState<any>(null);
19
- const [library, setLibrary] = useState<LibraryItem[]>([]);
20
- const [selectedTrackId, setSelectedTrackId] = useState<string | null>(null);
21
- const [editOperation, setEditOperation] = useState<"cover" | "extend" | "swap_vocal" | "crop">("cover");
22
- const [editResult, setEditResult] = useState<any>(null);
23
-
24
- useEffect(() => {
25
- const loadLibrary = async () => {
26
- try {
27
- const res = await fetch("/api/library");
28
- const json = await res.json();
29
- if (Array.isArray(json.items)) {
30
- setLibrary(json.items);
31
- }
32
- } catch {
33
- // silent library load failure
34
- }
35
- };
36
- loadLibrary();
37
- }, []);
38
-
39
- const handleGenerate = async () => {
40
- setIsGenerating(true);
41
- setResult(null);
42
-
43
- const duration =
44
- typeof durationSeconds === "number"
45
- ? durationSeconds
46
- : undefined; // randomizer handled server-side
47
-
48
- try {
49
- // ensure this never fails by guarding inputs and catching errors
50
- let t = await fetch("/api/generate", {
51
- method: "POST",
52
- headers: {
53
- "Content-Type": "application/json",
54
- Accept: "application/json",
55
- },
56
- body: JSON.stringify({
57
- stylePrompt,
58
- lyricPrompt: lyricPrompt || undefined,
59
- voice,
60
- durationSeconds: duration,
61
- }),
62
- });
63
-
64
- if (!t.ok) {
65
- const err = await t.json().catch(() => ({}));
66
- setResult({ error: err.error || "Generation failed", details: err.details });
67
- } else {
68
- const json = await t.json();
69
- setResult(json);
70
-
71
- const id = crypto.randomUUID();
72
- const item: LibraryItem = {
73
- id,
74
- title: stylePrompt || "Untitled",
75
- duration: json.duration,
76
- voice,
77
- };
78
-
79
- setLibrary((prev) => [...prev, item]);
80
-
81
- try {
82
- await fetch("/api/library", {
83
- method: "POST",
84
- headers: {
85
- "Content-Type": "application/json",
86
- Accept: "application/json",
87
- },
88
- body: JSON.stringify(item),
89
- });
90
- } catch {
91
- // library persistence failure is non-fatal
92
- }
93
- }
94
- } catch (e: any) {
95
- setResult({
96
- error: "Unexpected client error during generation",
97
- details: e?.message ?? "Unknown error",
98
- });
99
- } finally {
100
- setIsGenerating(false);
101
- }
102
- };
103
-
104
- const handleEdit = async () => {
105
- if (!selectedTrackId) return;
106
-
107
- try {
108
- const res = await fetch("/api/edit", {
109
- method: "POST",
110
- headers: {
111
- "Content-Type": "application/json",
112
- Accept: "application/json",
113
- },
114
- body: JSON.stringify({
115
- operation: editOperation,
116
- trackId: selectedTrackId,
117
- params: {},
118
- }),
119
- });
120
-
121
- const json = await res.json();
122
- setEditResult(json);
123
- } catch (e: any) {
124
- setEditResult({
125
- error: "Unexpected client error during editing",
126
- details: e?.message ?? "Unknown error",
127
- });
128
- }
129
- };
130
-
131
- const handleImport = async (event: React.ChangeEvent<HTMLInputElement>) => {
132
- const file = event.target.files?.[0];
133
- if (!file) return;
134
-
135
- const ext = file.name.split(".").pop()?.toLowerCase();
136
- if (!["mp3", "wav"].includes(ext || "")) {
137
- alert("Only MP3/WAV files are supported.");
138
- return;
139
- }
140
-
141
- const blobUrl = URL.createObjectURL(file);
142
- const id = crypto.randomUUID();
143
-
144
- const item: LibraryItem = {
145
- id,
146
- title: file.name,
147
- duration: 0,
148
- voice: "Random",
149
- blobUrl,
150
- };
151
-
152
- setLibrary((prev) => [...prev, item]);
153
-
154
- try {
155
- await fetch("/api/library", {
156
- method: "POST",
157
- headers: {
158
- "Content-Type": "application/json",
159
- Accept: "application/json",
160
- },
161
- body: JSON.stringify(item),
162
- });
163
- } catch {
164
- // non-fatal
165
- }
166
- };
167
-
168
- const handleExport = async (item: LibraryItem) => {
169
- if (!item.blobUrl) {
170
- alert("No audio blob available for export.");
171
- return;
172
- }
173
- const a = document.createElement("a");
174
- a.href = item.blobUrl;
175
- a.download = `${item.title || "track"}.wav`;
176
- a.click();
177
- };
178
-
179
- return (
180
- <main style={{ padding: 24, fontFamily: "system-ui" }}>
181
- <h1>ACE-Step Riffusion Studio</h1>
182
- <section style={{ marginBottom: 24 }}>
183
- <h2>Generate song</h2>
184
- <div>
185
- <label>
186
- Style prompt:
187
- <textarea
188
- value={stylePrompt}
189
- onChange={(e) => setStylePrompt(e.target.value)}
190
- rows={3}
191
- style={{ width: "100%" }}
192
- />
193
- </label>
194
- </div>
195
- <div>
196
- <label>
197
- Lyrics (optional):
198
- <textarea
199
- value={lyricPrompt}
200
- onChange={(e) => setLyricPrompt(e.target.value)}
201
- rows={3}
202
- style={{ width: "100%" }}
203
- />
204
- </label>
205
- </div>
206
- <div>
207
- <label>
208
- Voice:
209
- <select value={voice} onChange={(e) => setVoice(e.target.value as VoiceType)}>
210
- <option value="Random">Random</option>
211
- <option value="Male">Male</option>
212
- <option value="Female">Female</option>
213
- </select>
214
- </label>
215
- </div>
216
- <div>
217
- <label>
218
- Duration (30–240s, leave empty for random):
219
- <input
220
- type="number"
221
- min={30}
222
- max={240}
223
- value={durationSeconds ?? ""}
224
- onChange={(e) =>
225
- setDurationSeconds(
226
- e.target.value ? Math.min(240, Math.max(30, Number(e.target.value))) : undefined
227
- )
228
- }
229
- />
230
- </label>
231
- </div>
232
- <button onClick={handleGenerate} disabled={isGenerating || !stylePrompt}>
233
- {isGenerating ? "Generating..." : "Generate"}
234
- </button>
235
- {result && (
236
- <pre style={{ marginTop: 12, background: "#111", color: "#eee", padding: 12 }}>
237
- {JSON.stringify(result, null, 2)}
238
- </pre>
239
- )}
240
- </section>
241
- <section style={{ marginBottom: 24 }}>
242
- <h2>Editing suite (DreamVAE)</h2>
243
- <div>
244
- <label>
245
- Operation:
246
- <select
247
- value={editOperation}
248
- onChange={(e) =>
249
- setEditOperation(e.target.value as "cover" | "extend" | "swap_vocal" | "crop")
250
- }
251
- >
252
- <option value="cover">Musical cover maker</option>
253
- <option value="extend">Song extender</option>
254
- <option value="swap_vocal">Vocal swapper</option>
255
- <option value="crop">Cropping mechanism</option>
256
- </select>
257
- </label>
258
- </div>
259
- <div>
260
- <label>
261
- Track:
262
- <select
263
- value={selectedTrackId ?? ""}
264
- onChange={(e) => setSelectedTrackId(e.target.value || null)}
265
- >
266
- <option value="">Select track</option>
267
- {library.map((item) => (
268
- <option key={item.id} value={item.id}>
269
- {item.title}
270
- </option>
271
- ))}
272
- </select>
273
- </label>
274
- </div>
275
- <button onClick={handleEdit} disabled={!selectedTrackId}>
276
- Apply edit
277
- </button>
278
- {editResult && (
279
- <pre style={{ marginTop: 12, background: "#111", color: "#eee", padding: 12 }}>
280
- {JSON.stringify(editResult, null, 2)}
281
- </pre>
282
- )}
283
- </section>
284
- <section style={{ marginBottom: 24 }}>
285
- <h2>Import / Export</h2>
286
- <div>
287
- <label>
288
- Import MP3/WAV:
289
- <input type="file" accept=".mp3,.wav" onChange={handleImport} />
290
- </label>
291
- </div>
292
- <div style={{ marginTop: 12 }}>
293
- <h3>Library</h3>
294
- {library.length === 0 && <p>No tracks yet.</p>}
295
- <ul>
296
- {library.map((item) => (
297
- <li key={item.id} style={{ marginBottom: 8 }}>
298
- <strong>{item.title}</strong> ({item.voice}, {item.duration || 0}s)
299
- {item.blobUrl && (
300
- <>
301
- {" "}
302
- <button onClick={() => handleExport(item)}>Export</button>
303
- {" "}
304
- <audio controls src={item.blobUrl} />
305
- </>
306
- )}
307
- </li>
308
- ))}
309
- </ul>
310
- </div>
311
- </section>
312
- </main>
313
- );
314
- }