@twick/studio 0.15.26 → 0.15.28
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/dist/components/container/emoji-panel-container.d.ts +3 -0
- package/dist/components/panel/captions-panel.d.ts +5 -42
- package/dist/components/panel/emoji-panel.d.ts +8 -0
- package/dist/components/properties/caption-prop.d.ts +1 -1
- package/dist/components/properties/color-filter-props.d.ts +3 -0
- package/dist/components/properties/generate-captions.d.ts +3 -2
- package/dist/helpers/emoji-catalog.d.ts +9 -0
- package/dist/helpers/generate-captions.service.d.ts +4 -4
- package/dist/hooks/use-captions-panel.d.ts +4 -8
- package/dist/hooks/use-generate-captions.d.ts +2 -2
- package/dist/index.d.ts +6 -3
- package/dist/index.js +467 -192
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +460 -188
- package/dist/index.mjs.map +1 -1
- package/dist/studio.css +55 -0
- package/dist/types/index.d.ts +9 -1
- package/package.json +15 -15
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ const react = require("react");
|
|
|
8
8
|
const timeline = require("@twick/timeline");
|
|
9
9
|
const VideoEditor = require("@twick/video-editor");
|
|
10
10
|
const livePlayer = require("@twick/live-player");
|
|
11
|
+
const mediaUtils = require("@twick/media-utils");
|
|
11
12
|
/**
|
|
12
13
|
* @license lucide-react v0.511.0 - ISC
|
|
13
14
|
*
|
|
@@ -113,103 +114,103 @@ const createLucideIcon = (iconName, iconNode) => {
|
|
|
113
114
|
* This source code is licensed under the ISC license.
|
|
114
115
|
* See the LICENSE file in the root directory of this source tree.
|
|
115
116
|
*/
|
|
116
|
-
const __iconNode$
|
|
117
|
+
const __iconNode$C = [
|
|
117
118
|
["path", { d: "M17 12H7", key: "16if0g" }],
|
|
118
119
|
["path", { d: "M19 18H5", key: "18s9l3" }],
|
|
119
120
|
["path", { d: "M21 6H3", key: "1jwq7v" }]
|
|
120
121
|
];
|
|
121
|
-
const AlignCenter = createLucideIcon("align-center", __iconNode$
|
|
122
|
+
const AlignCenter = createLucideIcon("align-center", __iconNode$C);
|
|
122
123
|
/**
|
|
123
124
|
* @license lucide-react v0.511.0 - ISC
|
|
124
125
|
*
|
|
125
126
|
* This source code is licensed under the ISC license.
|
|
126
127
|
* See the LICENSE file in the root directory of this source tree.
|
|
127
128
|
*/
|
|
128
|
-
const __iconNode$
|
|
129
|
+
const __iconNode$B = [
|
|
129
130
|
["path", { d: "M15 12H3", key: "6jk70r" }],
|
|
130
131
|
["path", { d: "M17 18H3", key: "1amg6g" }],
|
|
131
132
|
["path", { d: "M21 6H3", key: "1jwq7v" }]
|
|
132
133
|
];
|
|
133
|
-
const AlignLeft = createLucideIcon("align-left", __iconNode$
|
|
134
|
+
const AlignLeft = createLucideIcon("align-left", __iconNode$B);
|
|
134
135
|
/**
|
|
135
136
|
* @license lucide-react v0.511.0 - ISC
|
|
136
137
|
*
|
|
137
138
|
* This source code is licensed under the ISC license.
|
|
138
139
|
* See the LICENSE file in the root directory of this source tree.
|
|
139
140
|
*/
|
|
140
|
-
const __iconNode$
|
|
141
|
+
const __iconNode$A = [
|
|
141
142
|
["path", { d: "M21 12H9", key: "dn1m92" }],
|
|
142
143
|
["path", { d: "M21 18H7", key: "1ygte8" }],
|
|
143
144
|
["path", { d: "M21 6H3", key: "1jwq7v" }]
|
|
144
145
|
];
|
|
145
|
-
const AlignRight = createLucideIcon("align-right", __iconNode$
|
|
146
|
+
const AlignRight = createLucideIcon("align-right", __iconNode$A);
|
|
146
147
|
/**
|
|
147
148
|
* @license lucide-react v0.511.0 - ISC
|
|
148
149
|
*
|
|
149
150
|
* This source code is licensed under the ISC license.
|
|
150
151
|
* See the LICENSE file in the root directory of this source tree.
|
|
151
152
|
*/
|
|
152
|
-
const __iconNode$
|
|
153
|
+
const __iconNode$z = [
|
|
153
154
|
[
|
|
154
155
|
"path",
|
|
155
156
|
{ d: "M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8", key: "mg9rjx" }
|
|
156
157
|
]
|
|
157
158
|
];
|
|
158
|
-
const Bold = createLucideIcon("bold", __iconNode$
|
|
159
|
+
const Bold = createLucideIcon("bold", __iconNode$z);
|
|
159
160
|
/**
|
|
160
161
|
* @license lucide-react v0.511.0 - ISC
|
|
161
162
|
*
|
|
162
163
|
* This source code is licensed under the ISC license.
|
|
163
164
|
* See the LICENSE file in the root directory of this source tree.
|
|
164
165
|
*/
|
|
165
|
-
const __iconNode$
|
|
166
|
-
const ChevronDown = createLucideIcon("chevron-down", __iconNode$
|
|
166
|
+
const __iconNode$y = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
|
|
167
|
+
const ChevronDown = createLucideIcon("chevron-down", __iconNode$y);
|
|
167
168
|
/**
|
|
168
169
|
* @license lucide-react v0.511.0 - ISC
|
|
169
170
|
*
|
|
170
171
|
* This source code is licensed under the ISC license.
|
|
171
172
|
* See the LICENSE file in the root directory of this source tree.
|
|
172
173
|
*/
|
|
173
|
-
const __iconNode$
|
|
174
|
-
const ChevronRight = createLucideIcon("chevron-right", __iconNode$
|
|
174
|
+
const __iconNode$x = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
|
|
175
|
+
const ChevronRight = createLucideIcon("chevron-right", __iconNode$x);
|
|
175
176
|
/**
|
|
176
177
|
* @license lucide-react v0.511.0 - ISC
|
|
177
178
|
*
|
|
178
179
|
* This source code is licensed under the ISC license.
|
|
179
180
|
* See the LICENSE file in the root directory of this source tree.
|
|
180
181
|
*/
|
|
181
|
-
const __iconNode$
|
|
182
|
+
const __iconNode$w = [
|
|
182
183
|
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
183
184
|
["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
|
|
184
185
|
];
|
|
185
|
-
const CircleCheck = createLucideIcon("circle-check", __iconNode$
|
|
186
|
+
const CircleCheck = createLucideIcon("circle-check", __iconNode$w);
|
|
186
187
|
/**
|
|
187
188
|
* @license lucide-react v0.511.0 - ISC
|
|
188
189
|
*
|
|
189
190
|
* This source code is licensed under the ISC license.
|
|
190
191
|
* See the LICENSE file in the root directory of this source tree.
|
|
191
192
|
*/
|
|
192
|
-
const __iconNode$
|
|
193
|
+
const __iconNode$v = [
|
|
193
194
|
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
194
195
|
["path", { d: "m15 9-6 6", key: "1uzhvr" }],
|
|
195
196
|
["path", { d: "m9 9 6 6", key: "z0biqf" }]
|
|
196
197
|
];
|
|
197
|
-
const CircleX = createLucideIcon("circle-x", __iconNode$
|
|
198
|
+
const CircleX = createLucideIcon("circle-x", __iconNode$v);
|
|
198
199
|
/**
|
|
199
200
|
* @license lucide-react v0.511.0 - ISC
|
|
200
201
|
*
|
|
201
202
|
* This source code is licensed under the ISC license.
|
|
202
203
|
* See the LICENSE file in the root directory of this source tree.
|
|
203
204
|
*/
|
|
204
|
-
const __iconNode$
|
|
205
|
-
const Circle = createLucideIcon("circle", __iconNode$
|
|
205
|
+
const __iconNode$u = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]];
|
|
206
|
+
const Circle = createLucideIcon("circle", __iconNode$u);
|
|
206
207
|
/**
|
|
207
208
|
* @license lucide-react v0.511.0 - ISC
|
|
208
209
|
*
|
|
209
210
|
* This source code is licensed under the ISC license.
|
|
210
211
|
* See the LICENSE file in the root directory of this source tree.
|
|
211
212
|
*/
|
|
212
|
-
const __iconNode$
|
|
213
|
+
const __iconNode$t = [
|
|
213
214
|
[
|
|
214
215
|
"path",
|
|
215
216
|
{ 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", key: "1tn4o7" }
|
|
@@ -218,102 +219,118 @@ const __iconNode$r = [
|
|
|
218
219
|
["path", { d: "m12.4 3.4 3.1 4", key: "6hsd6n" }],
|
|
219
220
|
["path", { d: "M3 11h18v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z", key: "ltgou9" }]
|
|
220
221
|
];
|
|
221
|
-
const Clapperboard = createLucideIcon("clapperboard", __iconNode$
|
|
222
|
+
const Clapperboard = createLucideIcon("clapperboard", __iconNode$t);
|
|
222
223
|
/**
|
|
223
224
|
* @license lucide-react v0.511.0 - ISC
|
|
224
225
|
*
|
|
225
226
|
* This source code is licensed under the ISC license.
|
|
226
227
|
* See the LICENSE file in the root directory of this source tree.
|
|
227
228
|
*/
|
|
228
|
-
const __iconNode$
|
|
229
|
+
const __iconNode$s = [
|
|
229
230
|
["path", { d: "M12 15V3", key: "m9g1x1" }],
|
|
230
231
|
["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
|
|
231
232
|
["path", { d: "m7 10 5 5 5-5", key: "brsn70" }]
|
|
232
233
|
];
|
|
233
|
-
const Download = createLucideIcon("download", __iconNode$
|
|
234
|
+
const Download = createLucideIcon("download", __iconNode$s);
|
|
234
235
|
/**
|
|
235
236
|
* @license lucide-react v0.511.0 - ISC
|
|
236
237
|
*
|
|
237
238
|
* This source code is licensed under the ISC license.
|
|
238
239
|
* See the LICENSE file in the root directory of this source tree.
|
|
239
240
|
*/
|
|
240
|
-
const __iconNode$
|
|
241
|
+
const __iconNode$r = [
|
|
241
242
|
["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
|
|
242
243
|
["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }]
|
|
243
244
|
];
|
|
244
|
-
const File = createLucideIcon("file", __iconNode$
|
|
245
|
+
const File = createLucideIcon("file", __iconNode$r);
|
|
245
246
|
/**
|
|
246
247
|
* @license lucide-react v0.511.0 - ISC
|
|
247
248
|
*
|
|
248
249
|
* This source code is licensed under the ISC license.
|
|
249
250
|
* See the LICENSE file in the root directory of this source tree.
|
|
250
251
|
*/
|
|
251
|
-
const __iconNode$
|
|
252
|
+
const __iconNode$q = [
|
|
253
|
+
[
|
|
254
|
+
"path",
|
|
255
|
+
{
|
|
256
|
+
d: "M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z",
|
|
257
|
+
key: "sc7q7i"
|
|
258
|
+
}
|
|
259
|
+
]
|
|
260
|
+
];
|
|
261
|
+
const Funnel = createLucideIcon("funnel", __iconNode$q);
|
|
262
|
+
/**
|
|
263
|
+
* @license lucide-react v0.511.0 - ISC
|
|
264
|
+
*
|
|
265
|
+
* This source code is licensed under the ISC license.
|
|
266
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
267
|
+
*/
|
|
268
|
+
const __iconNode$p = [
|
|
252
269
|
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
|
|
253
270
|
["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
|
|
254
271
|
["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
|
|
255
272
|
];
|
|
256
|
-
const Image = createLucideIcon("image", __iconNode$
|
|
273
|
+
const Image$1 = createLucideIcon("image", __iconNode$p);
|
|
257
274
|
/**
|
|
258
275
|
* @license lucide-react v0.511.0 - ISC
|
|
259
276
|
*
|
|
260
277
|
* This source code is licensed under the ISC license.
|
|
261
278
|
* See the LICENSE file in the root directory of this source tree.
|
|
262
279
|
*/
|
|
263
|
-
const __iconNode$
|
|
280
|
+
const __iconNode$o = [
|
|
264
281
|
["line", { x1: "19", x2: "10", y1: "4", y2: "4", key: "15jd3p" }],
|
|
265
282
|
["line", { x1: "14", x2: "5", y1: "20", y2: "20", key: "bu0au3" }],
|
|
266
283
|
["line", { x1: "15", x2: "9", y1: "4", y2: "20", key: "uljnxc" }]
|
|
267
284
|
];
|
|
268
|
-
const Italic = createLucideIcon("italic", __iconNode$
|
|
285
|
+
const Italic = createLucideIcon("italic", __iconNode$o);
|
|
269
286
|
/**
|
|
270
287
|
* @license lucide-react v0.511.0 - ISC
|
|
271
288
|
*
|
|
272
289
|
* This source code is licensed under the ISC license.
|
|
273
290
|
* See the LICENSE file in the root directory of this source tree.
|
|
274
291
|
*/
|
|
275
|
-
const __iconNode$
|
|
276
|
-
const LoaderCircle = createLucideIcon("loader-circle", __iconNode$
|
|
292
|
+
const __iconNode$n = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
|
|
293
|
+
const LoaderCircle = createLucideIcon("loader-circle", __iconNode$n);
|
|
277
294
|
/**
|
|
278
295
|
* @license lucide-react v0.511.0 - ISC
|
|
279
296
|
*
|
|
280
297
|
* This source code is licensed under the ISC license.
|
|
281
298
|
* See the LICENSE file in the root directory of this source tree.
|
|
282
299
|
*/
|
|
283
|
-
const __iconNode$
|
|
300
|
+
const __iconNode$m = [
|
|
284
301
|
["path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z", key: "1lielz" }]
|
|
285
302
|
];
|
|
286
|
-
const MessageSquare = createLucideIcon("message-square", __iconNode$
|
|
303
|
+
const MessageSquare = createLucideIcon("message-square", __iconNode$m);
|
|
287
304
|
/**
|
|
288
305
|
* @license lucide-react v0.511.0 - ISC
|
|
289
306
|
*
|
|
290
307
|
* This source code is licensed under the ISC license.
|
|
291
308
|
* See the LICENSE file in the root directory of this source tree.
|
|
292
309
|
*/
|
|
293
|
-
const __iconNode$
|
|
310
|
+
const __iconNode$l = [
|
|
294
311
|
["circle", { cx: "8", cy: "18", r: "4", key: "1fc0mg" }],
|
|
295
312
|
["path", { d: "M12 18V2l7 4", key: "g04rme" }]
|
|
296
313
|
];
|
|
297
|
-
const Music2 = createLucideIcon("music-2", __iconNode$
|
|
314
|
+
const Music2 = createLucideIcon("music-2", __iconNode$l);
|
|
298
315
|
/**
|
|
299
316
|
* @license lucide-react v0.511.0 - ISC
|
|
300
317
|
*
|
|
301
318
|
* This source code is licensed under the ISC license.
|
|
302
319
|
* See the LICENSE file in the root directory of this source tree.
|
|
303
320
|
*/
|
|
304
|
-
const __iconNode$
|
|
321
|
+
const __iconNode$k = [
|
|
305
322
|
["path", { d: "M9 18V5l12-2v13", key: "1jmyc2" }],
|
|
306
323
|
["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }],
|
|
307
324
|
["circle", { cx: "18", cy: "16", r: "3", key: "1hluhg" }]
|
|
308
325
|
];
|
|
309
|
-
const Music = createLucideIcon("music", __iconNode$
|
|
326
|
+
const Music = createLucideIcon("music", __iconNode$k);
|
|
310
327
|
/**
|
|
311
328
|
* @license lucide-react v0.511.0 - ISC
|
|
312
329
|
*
|
|
313
330
|
* This source code is licensed under the ISC license.
|
|
314
331
|
* See the LICENSE file in the root directory of this source tree.
|
|
315
332
|
*/
|
|
316
|
-
const __iconNode$
|
|
333
|
+
const __iconNode$j = [
|
|
317
334
|
[
|
|
318
335
|
"path",
|
|
319
336
|
{
|
|
@@ -326,64 +343,64 @@ const __iconNode$i = [
|
|
|
326
343
|
["circle", { cx: "6.5", cy: "12.5", r: ".5", fill: "currentColor", key: "qy21gx" }],
|
|
327
344
|
["circle", { cx: "8.5", cy: "7.5", r: ".5", fill: "currentColor", key: "fotxhn" }]
|
|
328
345
|
];
|
|
329
|
-
const Palette = createLucideIcon("palette", __iconNode$
|
|
346
|
+
const Palette = createLucideIcon("palette", __iconNode$j);
|
|
330
347
|
/**
|
|
331
348
|
* @license lucide-react v0.511.0 - ISC
|
|
332
349
|
*
|
|
333
350
|
* This source code is licensed under the ISC license.
|
|
334
351
|
* See the LICENSE file in the root directory of this source tree.
|
|
335
352
|
*/
|
|
336
|
-
const __iconNode$
|
|
353
|
+
const __iconNode$i = [
|
|
337
354
|
["rect", { x: "14", y: "4", width: "4", height: "16", rx: "1", key: "zuxfzm" }],
|
|
338
355
|
["rect", { x: "6", y: "4", width: "4", height: "16", rx: "1", key: "1okwgv" }]
|
|
339
356
|
];
|
|
340
|
-
const Pause = createLucideIcon("pause", __iconNode$
|
|
357
|
+
const Pause = createLucideIcon("pause", __iconNode$i);
|
|
341
358
|
/**
|
|
342
359
|
* @license lucide-react v0.511.0 - ISC
|
|
343
360
|
*
|
|
344
361
|
* This source code is licensed under the ISC license.
|
|
345
362
|
* See the LICENSE file in the root directory of this source tree.
|
|
346
363
|
*/
|
|
347
|
-
const __iconNode$
|
|
348
|
-
const Play = createLucideIcon("play", __iconNode$
|
|
364
|
+
const __iconNode$h = [["polygon", { points: "6 3 20 12 6 21 6 3", key: "1oa8hb" }]];
|
|
365
|
+
const Play = createLucideIcon("play", __iconNode$h);
|
|
349
366
|
/**
|
|
350
367
|
* @license lucide-react v0.511.0 - ISC
|
|
351
368
|
*
|
|
352
369
|
* This source code is licensed under the ISC license.
|
|
353
370
|
* See the LICENSE file in the root directory of this source tree.
|
|
354
371
|
*/
|
|
355
|
-
const __iconNode$
|
|
372
|
+
const __iconNode$g = [
|
|
356
373
|
["path", { d: "M5 12h14", key: "1ays0h" }],
|
|
357
374
|
["path", { d: "M12 5v14", key: "s699le" }]
|
|
358
375
|
];
|
|
359
|
-
const Plus = createLucideIcon("plus", __iconNode$
|
|
376
|
+
const Plus = createLucideIcon("plus", __iconNode$g);
|
|
360
377
|
/**
|
|
361
378
|
* @license lucide-react v0.511.0 - ISC
|
|
362
379
|
*
|
|
363
380
|
* This source code is licensed under the ISC license.
|
|
364
381
|
* See the LICENSE file in the root directory of this source tree.
|
|
365
382
|
*/
|
|
366
|
-
const __iconNode$
|
|
383
|
+
const __iconNode$f = [
|
|
367
384
|
["rect", { width: "20", height: "12", x: "2", y: "6", rx: "2", key: "9lu3g6" }]
|
|
368
385
|
];
|
|
369
|
-
const RectangleHorizontal = createLucideIcon("rectangle-horizontal", __iconNode$
|
|
386
|
+
const RectangleHorizontal = createLucideIcon("rectangle-horizontal", __iconNode$f);
|
|
370
387
|
/**
|
|
371
388
|
* @license lucide-react v0.511.0 - ISC
|
|
372
389
|
*
|
|
373
390
|
* This source code is licensed under the ISC license.
|
|
374
391
|
* See the LICENSE file in the root directory of this source tree.
|
|
375
392
|
*/
|
|
376
|
-
const __iconNode$
|
|
393
|
+
const __iconNode$e = [
|
|
377
394
|
["rect", { width: "12", height: "20", x: "6", y: "2", rx: "2", key: "1oxtiu" }]
|
|
378
395
|
];
|
|
379
|
-
const RectangleVertical = createLucideIcon("rectangle-vertical", __iconNode$
|
|
396
|
+
const RectangleVertical = createLucideIcon("rectangle-vertical", __iconNode$e);
|
|
380
397
|
/**
|
|
381
398
|
* @license lucide-react v0.511.0 - ISC
|
|
382
399
|
*
|
|
383
400
|
* This source code is licensed under the ISC license.
|
|
384
401
|
* See the LICENSE file in the root directory of this source tree.
|
|
385
402
|
*/
|
|
386
|
-
const __iconNode$
|
|
403
|
+
const __iconNode$d = [
|
|
387
404
|
[
|
|
388
405
|
"path",
|
|
389
406
|
{
|
|
@@ -396,14 +413,14 @@ const __iconNode$c = [
|
|
|
396
413
|
["path", { d: "m8.5 6.5 2-2", key: "vc6u1g" }],
|
|
397
414
|
["path", { d: "m17.5 15.5 2-2", key: "wo5hmg" }]
|
|
398
415
|
];
|
|
399
|
-
const Ruler = createLucideIcon("ruler", __iconNode$
|
|
416
|
+
const Ruler = createLucideIcon("ruler", __iconNode$d);
|
|
400
417
|
/**
|
|
401
418
|
* @license lucide-react v0.511.0 - ISC
|
|
402
419
|
*
|
|
403
420
|
* This source code is licensed under the ISC license.
|
|
404
421
|
* See the LICENSE file in the root directory of this source tree.
|
|
405
422
|
*/
|
|
406
|
-
const __iconNode$
|
|
423
|
+
const __iconNode$c = [
|
|
407
424
|
[
|
|
408
425
|
"path",
|
|
409
426
|
{
|
|
@@ -414,32 +431,45 @@ const __iconNode$b = [
|
|
|
414
431
|
["path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7", key: "1ydtos" }],
|
|
415
432
|
["path", { d: "M7 3v4a1 1 0 0 0 1 1h7", key: "t51u73" }]
|
|
416
433
|
];
|
|
417
|
-
const Save = createLucideIcon("save", __iconNode$
|
|
434
|
+
const Save = createLucideIcon("save", __iconNode$c);
|
|
418
435
|
/**
|
|
419
436
|
* @license lucide-react v0.511.0 - ISC
|
|
420
437
|
*
|
|
421
438
|
* This source code is licensed under the ISC license.
|
|
422
439
|
* See the LICENSE file in the root directory of this source tree.
|
|
423
440
|
*/
|
|
424
|
-
const __iconNode$
|
|
441
|
+
const __iconNode$b = [
|
|
425
442
|
["circle", { cx: "6", cy: "6", r: "3", key: "1lh9wr" }],
|
|
426
443
|
["path", { d: "M8.12 8.12 12 12", key: "1alkpv" }],
|
|
427
444
|
["path", { d: "M20 4 8.12 15.88", key: "xgtan2" }],
|
|
428
445
|
["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }],
|
|
429
446
|
["path", { d: "M14.8 14.8 20 20", key: "ptml3r" }]
|
|
430
447
|
];
|
|
431
|
-
const Scissors = createLucideIcon("scissors", __iconNode$
|
|
448
|
+
const Scissors = createLucideIcon("scissors", __iconNode$b);
|
|
432
449
|
/**
|
|
433
450
|
* @license lucide-react v0.511.0 - ISC
|
|
434
451
|
*
|
|
435
452
|
* This source code is licensed under the ISC license.
|
|
436
453
|
* See the LICENSE file in the root directory of this source tree.
|
|
437
454
|
*/
|
|
438
|
-
const __iconNode$
|
|
455
|
+
const __iconNode$a = [
|
|
439
456
|
["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
|
|
440
457
|
["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
|
|
441
458
|
];
|
|
442
|
-
const Search = createLucideIcon("search", __iconNode$
|
|
459
|
+
const Search = createLucideIcon("search", __iconNode$a);
|
|
460
|
+
/**
|
|
461
|
+
* @license lucide-react v0.511.0 - ISC
|
|
462
|
+
*
|
|
463
|
+
* This source code is licensed under the ISC license.
|
|
464
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
465
|
+
*/
|
|
466
|
+
const __iconNode$9 = [
|
|
467
|
+
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
468
|
+
["path", { d: "M8 14s1.5 2 4 2 4-2 4-2", key: "1y1vjs" }],
|
|
469
|
+
["line", { x1: "9", x2: "9.01", y1: "9", y2: "9", key: "yxxnd0" }],
|
|
470
|
+
["line", { x1: "15", x2: "15.01", y1: "9", y2: "9", key: "1p4y9e" }]
|
|
471
|
+
];
|
|
472
|
+
const Smile = createLucideIcon("smile", __iconNode$9);
|
|
443
473
|
/**
|
|
444
474
|
* @license lucide-react v0.511.0 - ISC
|
|
445
475
|
*
|
|
@@ -591,6 +621,7 @@ const defaultToolCategories = [
|
|
|
591
621
|
{ id: "image", name: "Image", icon: "Image", description: "Add an image element" },
|
|
592
622
|
{ id: "audio", name: "Audio", icon: "Audio", description: "Add an audio element" },
|
|
593
623
|
{ id: "text", name: "Text", icon: "Type", description: "Add text elements" },
|
|
624
|
+
{ id: "emoji", name: "Emoji", icon: "Smile", description: "Add emoji stickers" },
|
|
594
625
|
{ id: "text-style", name: "Text Style", icon: "Type", description: "Apply text style presets" },
|
|
595
626
|
{ id: "effect", name: "Effect", icon: "Wand2", description: "Apply GL video effects" },
|
|
596
627
|
{ id: "shape", name: "Shape", icon: "Square", description: "Add lines, arrows, boxes, and circles" },
|
|
@@ -610,7 +641,7 @@ const getIcon = (iconName) => {
|
|
|
610
641
|
case "Square":
|
|
611
642
|
return Square;
|
|
612
643
|
case "Image":
|
|
613
|
-
return Image;
|
|
644
|
+
return Image$1;
|
|
614
645
|
case "Video":
|
|
615
646
|
return Video;
|
|
616
647
|
case "Audio":
|
|
@@ -625,6 +656,8 @@ const getIcon = (iconName) => {
|
|
|
625
656
|
return WandSparkles;
|
|
626
657
|
case "File":
|
|
627
658
|
return File;
|
|
659
|
+
case "Smile":
|
|
660
|
+
return Smile;
|
|
628
661
|
default:
|
|
629
662
|
return Plus;
|
|
630
663
|
}
|
|
@@ -2999,6 +3032,155 @@ function TextPanelContainer(props) {
|
|
|
2999
3032
|
const textPanelProps = useTextPanel(props);
|
|
3000
3033
|
return /* @__PURE__ */ jsxRuntime.jsx(TextPanel, { ...textPanelProps });
|
|
3001
3034
|
}
|
|
3035
|
+
const SUPPORTED_EMOJIS = [
|
|
3036
|
+
{ emoji: "😀", category: "Smileys" },
|
|
3037
|
+
{ emoji: "😁", category: "Smileys" },
|
|
3038
|
+
{ emoji: "😂", category: "Smileys" },
|
|
3039
|
+
{ emoji: "🤣", category: "Smileys" },
|
|
3040
|
+
{ emoji: "😍", category: "Smileys" },
|
|
3041
|
+
{ emoji: "🤩", category: "Smileys" },
|
|
3042
|
+
{ emoji: "😎", category: "Smileys" },
|
|
3043
|
+
{ emoji: "🥳", category: "Smileys" },
|
|
3044
|
+
{ emoji: "🤯", category: "Smileys" },
|
|
3045
|
+
{ emoji: "🤔", category: "Smileys" },
|
|
3046
|
+
{ emoji: "😅", category: "Smileys" },
|
|
3047
|
+
{ emoji: "😮", category: "Smileys" },
|
|
3048
|
+
{ emoji: "🥹", category: "Smileys" },
|
|
3049
|
+
{ emoji: "🔥", category: "Symbols" },
|
|
3050
|
+
{ emoji: "✨", category: "Symbols" },
|
|
3051
|
+
{ emoji: "⭐", category: "Symbols" },
|
|
3052
|
+
{ emoji: "💥", category: "Symbols" },
|
|
3053
|
+
{ emoji: "💯", category: "Symbols" },
|
|
3054
|
+
{ emoji: "✅", category: "Symbols" },
|
|
3055
|
+
{ emoji: "❌", category: "Symbols" },
|
|
3056
|
+
{ emoji: "⚡", category: "Symbols" },
|
|
3057
|
+
{ emoji: "❤️", category: "Symbols" },
|
|
3058
|
+
{ emoji: "🏆", category: "Objects" },
|
|
3059
|
+
{ emoji: "💡", category: "Objects" },
|
|
3060
|
+
{ emoji: "📈", category: "Objects" },
|
|
3061
|
+
{ emoji: "📣", category: "Objects" },
|
|
3062
|
+
{ emoji: "🧠", category: "Objects" },
|
|
3063
|
+
{ emoji: "👀", category: "Objects" },
|
|
3064
|
+
{ emoji: "🤖", category: "Objects" },
|
|
3065
|
+
{ emoji: "👍", category: "Hands" },
|
|
3066
|
+
{ emoji: "👏", category: "Hands" },
|
|
3067
|
+
{ emoji: "🙌", category: "Hands" },
|
|
3068
|
+
{ emoji: "🤝", category: "Hands" },
|
|
3069
|
+
{ emoji: "🙏", category: "Hands" },
|
|
3070
|
+
{ emoji: "🚀", category: "Media" },
|
|
3071
|
+
{ emoji: "🎯", category: "Media" },
|
|
3072
|
+
{ emoji: "🎉", category: "Media" },
|
|
3073
|
+
{ emoji: "🎬", category: "Media" },
|
|
3074
|
+
{ emoji: "🎥", category: "Media" },
|
|
3075
|
+
{ emoji: "🎧", category: "Media" }
|
|
3076
|
+
];
|
|
3077
|
+
const CDN_BASE = "https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72";
|
|
3078
|
+
function toCodePointString(emoji) {
|
|
3079
|
+
return Array.from(emoji).map((char) => {
|
|
3080
|
+
var _a;
|
|
3081
|
+
return (_a = char.codePointAt(0)) == null ? void 0 : _a.toString(16);
|
|
3082
|
+
}).filter(Boolean).join("-");
|
|
3083
|
+
}
|
|
3084
|
+
const EMOJI_CATEGORIES = [
|
|
3085
|
+
"All",
|
|
3086
|
+
"Smileys",
|
|
3087
|
+
"Symbols",
|
|
3088
|
+
"Objects",
|
|
3089
|
+
"Hands",
|
|
3090
|
+
"Media"
|
|
3091
|
+
];
|
|
3092
|
+
const EMOJI_CATALOG = SUPPORTED_EMOJIS.map(
|
|
3093
|
+
({ emoji, category }) => ({
|
|
3094
|
+
emoji,
|
|
3095
|
+
category,
|
|
3096
|
+
label: emoji,
|
|
3097
|
+
imageUrl: `${CDN_BASE}/${toCodePointString(emoji)}.png`
|
|
3098
|
+
})
|
|
3099
|
+
);
|
|
3100
|
+
function EmojiPanel({ items, onItemSelect }) {
|
|
3101
|
+
const [searchQuery, setSearchQuery] = react.useState("");
|
|
3102
|
+
const [activeCategory, setActiveCategory] = react.useState("All");
|
|
3103
|
+
const filteredItems = react.useMemo(() => {
|
|
3104
|
+
const query = searchQuery.trim().toLowerCase();
|
|
3105
|
+
return items.filter((item) => {
|
|
3106
|
+
const categoryMatch = activeCategory === "All" ? true : item.category === activeCategory;
|
|
3107
|
+
if (!categoryMatch) return false;
|
|
3108
|
+
if (!query) return true;
|
|
3109
|
+
return item.emoji.includes(query) || item.label.toLowerCase().includes(query) || item.category.toLowerCase().includes(query);
|
|
3110
|
+
});
|
|
3111
|
+
}, [items, searchQuery, activeCategory]);
|
|
3112
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel-container", children: [
|
|
3113
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-title", children: "Emoji Stickers" }),
|
|
3114
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-section", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3115
|
+
"input",
|
|
3116
|
+
{
|
|
3117
|
+
type: "text",
|
|
3118
|
+
placeholder: "Search emoji...",
|
|
3119
|
+
value: searchQuery,
|
|
3120
|
+
onChange: (e) => setSearchQuery(e.target.value),
|
|
3121
|
+
className: "input-dark"
|
|
3122
|
+
}
|
|
3123
|
+
) }),
|
|
3124
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "emoji-categories", children: EMOJI_CATEGORIES.map((category) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3125
|
+
"button",
|
|
3126
|
+
{
|
|
3127
|
+
type: "button",
|
|
3128
|
+
className: `emoji-category-chip ${activeCategory === category ? "emoji-category-chip-active" : ""}`,
|
|
3129
|
+
onClick: () => setActiveCategory(category),
|
|
3130
|
+
children: category
|
|
3131
|
+
},
|
|
3132
|
+
category
|
|
3133
|
+
)) }),
|
|
3134
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "emoji-grid", children: filteredItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3135
|
+
"button",
|
|
3136
|
+
{
|
|
3137
|
+
type: "button",
|
|
3138
|
+
className: "emoji-item",
|
|
3139
|
+
title: item.label,
|
|
3140
|
+
onClick: () => onItemSelect(item),
|
|
3141
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3142
|
+
"img",
|
|
3143
|
+
{
|
|
3144
|
+
src: item.imageUrl,
|
|
3145
|
+
alt: item.label,
|
|
3146
|
+
className: "emoji-item-image",
|
|
3147
|
+
loading: "lazy"
|
|
3148
|
+
}
|
|
3149
|
+
)
|
|
3150
|
+
},
|
|
3151
|
+
`${item.emoji}-${item.imageUrl}`
|
|
3152
|
+
)) }),
|
|
3153
|
+
filteredItems.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "empty-state", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "empty-state-content", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "empty-state-text", children: "No emoji found" }) }) })
|
|
3154
|
+
] });
|
|
3155
|
+
}
|
|
3156
|
+
function EmojiPanelContainer({ addElement, videoResolution }) {
|
|
3157
|
+
const emojiFallbackFont = "Poppins, Noto Color Emoji, Apple Color Emoji, Segoe UI Emoji, sans-serif";
|
|
3158
|
+
const canLoadEmojiImage = async (url) => new Promise((resolve) => {
|
|
3159
|
+
let settled = false;
|
|
3160
|
+
const done = (value) => {
|
|
3161
|
+
if (settled) return;
|
|
3162
|
+
settled = true;
|
|
3163
|
+
resolve(value);
|
|
3164
|
+
};
|
|
3165
|
+
const img = new Image();
|
|
3166
|
+
img.onload = () => done(true);
|
|
3167
|
+
img.onerror = () => done(false);
|
|
3168
|
+
img.src = url;
|
|
3169
|
+
window.setTimeout(() => done(false), 3e3);
|
|
3170
|
+
});
|
|
3171
|
+
const handleSelection = async (item) => {
|
|
3172
|
+
if (!addElement) return;
|
|
3173
|
+
const canUseImage = await canLoadEmojiImage(item.imageUrl);
|
|
3174
|
+
if (canUseImage) {
|
|
3175
|
+
const element = new timeline.EmojiElement(item.emoji, item.imageUrl, videoResolution).setName(`Emoji ${item.emoji}`).setEnd(5);
|
|
3176
|
+
await addElement(element);
|
|
3177
|
+
return;
|
|
3178
|
+
}
|
|
3179
|
+
const fallbackText = new timeline.TextElement(item.emoji).setName(`Emoji ${item.emoji} (fallback)`).setFontFamily(emojiFallbackFont).setFontSize(Math.round(videoResolution.height * 0.12)).setFill("#FFFFFF").setLineWidth(0).setEnd(5);
|
|
3180
|
+
await addElement(fallbackText);
|
|
3181
|
+
};
|
|
3182
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EmojiPanel, { items: EMOJI_CATALOG, onItemSelect: handleSelection });
|
|
3183
|
+
}
|
|
3002
3184
|
const TEXT_STYLE_PRESETS = [
|
|
3003
3185
|
// Utility / captions
|
|
3004
3186
|
{
|
|
@@ -4724,7 +4906,15 @@ function CaptionsPanel({
|
|
|
4724
4906
|
children: [
|
|
4725
4907
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "captions-panel-item-header", children: [
|
|
4726
4908
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "captions-panel-time captions-panel-time-start", children: formatTime(caption.s) }),
|
|
4727
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "captions-panel-time captions-panel-time-end", children: formatTime(caption.e) })
|
|
4909
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "captions-panel-time captions-panel-time-end", children: formatTime(caption.e) }),
|
|
4910
|
+
caption.isCustom ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4911
|
+
"span",
|
|
4912
|
+
{
|
|
4913
|
+
className: "captions-panel-custom",
|
|
4914
|
+
title: "This caption overrides track defaults",
|
|
4915
|
+
children: "Custom"
|
|
4916
|
+
}
|
|
4917
|
+
) : null
|
|
4728
4918
|
] }),
|
|
4729
4919
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "captions-panel-item-body", children: [
|
|
4730
4920
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4893,11 +5083,15 @@ const useCaptionsPanel = () => {
|
|
|
4893
5083
|
}
|
|
4894
5084
|
captionsTrack.current = editorCaptionsTrack;
|
|
4895
5085
|
setCaptions(
|
|
4896
|
-
editorCaptionsTrack.getElements().map((element) =>
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
5086
|
+
editorCaptionsTrack.getElements().map((element) => {
|
|
5087
|
+
var _a;
|
|
5088
|
+
return {
|
|
5089
|
+
s: element.getStart(),
|
|
5090
|
+
e: element.getEnd(),
|
|
5091
|
+
t: element.getText(),
|
|
5092
|
+
isCustom: ((_a = element.getProps()) == null ? void 0 : _a.useTrackDefaults) === false
|
|
5093
|
+
};
|
|
5094
|
+
})
|
|
4901
5095
|
);
|
|
4902
5096
|
};
|
|
4903
5097
|
react.useEffect(() => {
|
|
@@ -4911,14 +5105,13 @@ const useCaptionsPanel = () => {
|
|
|
4911
5105
|
capStyle: timeline.CAPTION_STYLE.WORD_BG_HIGHLIGHT,
|
|
4912
5106
|
...CAPTION_PROPS[timeline.CAPTION_STYLE.WORD_BG_HIGHLIGHT],
|
|
4913
5107
|
x: 0,
|
|
4914
|
-
y: 200
|
|
4915
|
-
applyToAll: true
|
|
5108
|
+
y: 200
|
|
4916
5109
|
};
|
|
4917
5110
|
(_a = captionsTrack.current) == null ? void 0 : _a.setProps(props);
|
|
4918
5111
|
}
|
|
4919
5112
|
};
|
|
4920
5113
|
const addCaption = () => {
|
|
4921
|
-
const newCaption = { s: 0, e: 0, t: "New Caption" };
|
|
5114
|
+
const newCaption = { s: 0, e: 0, t: "New Caption", isCustom: false };
|
|
4922
5115
|
if (captions.length > 0) {
|
|
4923
5116
|
newCaption.s = captions[captions.length - 1].e;
|
|
4924
5117
|
}
|
|
@@ -5811,6 +6004,16 @@ const ElementPanelContainer = ({
|
|
|
5811
6004
|
updateElement
|
|
5812
6005
|
}
|
|
5813
6006
|
);
|
|
6007
|
+
case "emoji":
|
|
6008
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6009
|
+
EmojiPanelContainer,
|
|
6010
|
+
{
|
|
6011
|
+
selectedElement,
|
|
6012
|
+
videoResolution,
|
|
6013
|
+
addElement: addNewElement,
|
|
6014
|
+
updateElement
|
|
6015
|
+
}
|
|
6016
|
+
);
|
|
5814
6017
|
case "text-style":
|
|
5815
6018
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5816
6019
|
TextStylePanelContainer,
|
|
@@ -6496,8 +6699,10 @@ const DEFAULT_COLOR_META = {
|
|
|
6496
6699
|
const CAPTION_FONTS = Object.values(VideoEditor.AVAILABLE_TEXT_FONTS);
|
|
6497
6700
|
function CaptionPropPanel({
|
|
6498
6701
|
selectedElement,
|
|
6499
|
-
updateElement
|
|
6702
|
+
updateElement,
|
|
6703
|
+
setApplyPropsToAllCaption
|
|
6500
6704
|
}) {
|
|
6705
|
+
var _a;
|
|
6501
6706
|
const { editor, changeLog } = timeline.useTimelineContext();
|
|
6502
6707
|
const captionRef = react.useRef(null);
|
|
6503
6708
|
const [capStyle, setCapStyle] = react.useState(
|
|
@@ -6515,16 +6720,14 @@ function CaptionPropPanel({
|
|
|
6515
6720
|
const [useOutline, setUseOutline] = react.useState(true);
|
|
6516
6721
|
const track = selectedElement instanceof timeline.CaptionElement ? editor.getTrackById(selectedElement.getTrackId()) : null;
|
|
6517
6722
|
const trackProps = (track == null ? void 0 : track.getProps()) ?? {};
|
|
6518
|
-
const
|
|
6519
|
-
const
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
const rawNextColors = updates.colors ?? colors;
|
|
6527
|
-
let effectiveColors = { ...rawNextColors };
|
|
6723
|
+
const elementProps = ((_a = selectedElement == null ? void 0 : selectedElement.getProps) == null ? void 0 : _a.call(selectedElement)) ?? {};
|
|
6724
|
+
const useTrackDefaults = (elementProps == null ? void 0 : elementProps.useTrackDefaults) ?? true;
|
|
6725
|
+
const getEffectiveColors = ({
|
|
6726
|
+
nextColors,
|
|
6727
|
+
highlightEnabled,
|
|
6728
|
+
outlineEnabled
|
|
6729
|
+
}) => {
|
|
6730
|
+
let effectiveColors = { ...nextColors };
|
|
6528
6731
|
if (!highlightEnabled) {
|
|
6529
6732
|
const { highlight, ...rest } = effectiveColors;
|
|
6530
6733
|
effectiveColors = rest;
|
|
@@ -6533,26 +6736,73 @@ function CaptionPropPanel({
|
|
|
6533
6736
|
const { outlineColor, ...rest } = effectiveColors;
|
|
6534
6737
|
effectiveColors = rest;
|
|
6535
6738
|
}
|
|
6536
|
-
|
|
6739
|
+
return effectiveColors;
|
|
6740
|
+
};
|
|
6741
|
+
const handleUseTrackDefaultsChange = (enabled) => {
|
|
6742
|
+
const captionElement = selectedElement;
|
|
6743
|
+
if (!captionElement) return;
|
|
6744
|
+
const prev = captionElement.getProps() ?? {};
|
|
6745
|
+
const next = { ...prev, useTrackDefaults: enabled };
|
|
6746
|
+
if (enabled) {
|
|
6747
|
+
const keysToClear = [
|
|
6748
|
+
"capStyle",
|
|
6749
|
+
"x",
|
|
6750
|
+
"y",
|
|
6751
|
+
"width",
|
|
6752
|
+
"maxWidth",
|
|
6753
|
+
"textAlign",
|
|
6754
|
+
"rotation",
|
|
6755
|
+
"opacity",
|
|
6756
|
+
"colors",
|
|
6757
|
+
"font",
|
|
6758
|
+
"lineWidth",
|
|
6759
|
+
"rectProps",
|
|
6760
|
+
"shadowColor",
|
|
6761
|
+
"shadowBlur",
|
|
6762
|
+
"shadowOffset",
|
|
6763
|
+
"fill",
|
|
6764
|
+
"stroke"
|
|
6765
|
+
];
|
|
6766
|
+
for (const k of keysToClear) {
|
|
6767
|
+
delete next[k];
|
|
6768
|
+
}
|
|
6769
|
+
}
|
|
6770
|
+
captionElement.setProps(next);
|
|
6771
|
+
updateElement == null ? void 0 : updateElement(captionElement);
|
|
6772
|
+
setApplyPropsToAllCaption == null ? void 0 : setApplyPropsToAllCaption(enabled);
|
|
6773
|
+
};
|
|
6774
|
+
const handleUpdateCaption = (updates) => {
|
|
6775
|
+
const captionElement = selectedElement;
|
|
6776
|
+
if (!captionElement) return;
|
|
6777
|
+
const nextFontSize = updates.fontSize ?? fontSize;
|
|
6778
|
+
const geometry = timeline.computeCaptionGeometry(nextFontSize, updates.style ?? (capStyle == null ? void 0 : capStyle.value) ?? "");
|
|
6779
|
+
const highlightEnabled = updates.useHighlightOverride ?? useHighlight;
|
|
6780
|
+
const outlineEnabled = updates.useOutlineOverride ?? useOutline;
|
|
6781
|
+
const rawNextColors = updates.colors ?? colors;
|
|
6782
|
+
const effectiveColors = getEffectiveColors({
|
|
6783
|
+
nextColors: rawNextColors,
|
|
6784
|
+
highlightEnabled,
|
|
6785
|
+
outlineEnabled
|
|
6786
|
+
});
|
|
6787
|
+
if (useTrackDefaults && track) {
|
|
6537
6788
|
const nextFont = {
|
|
6538
6789
|
size: nextFontSize,
|
|
6539
6790
|
family: updates.fontFamily ?? fontFamily
|
|
6540
6791
|
};
|
|
6541
6792
|
const nextColors = effectiveColors;
|
|
6542
6793
|
const nextCapStyle = updates.style ?? (capStyle == null ? void 0 : capStyle.value);
|
|
6543
|
-
track.
|
|
6544
|
-
...trackProps,
|
|
6794
|
+
editor.updateTrackProps(track.getId(), {
|
|
6545
6795
|
capStyle: nextCapStyle,
|
|
6546
6796
|
font: { ...(trackProps == null ? void 0 : trackProps.font) ?? {}, ...nextFont },
|
|
6547
6797
|
colors: nextColors,
|
|
6548
6798
|
lineWidth: geometry.lineWidth,
|
|
6549
6799
|
rectProps: geometry.rectProps
|
|
6550
6800
|
});
|
|
6551
|
-
editor.refresh();
|
|
6552
6801
|
} else {
|
|
6553
|
-
const
|
|
6802
|
+
const elementProps2 = captionElement.getProps() ?? {};
|
|
6554
6803
|
captionElement.setProps({
|
|
6555
|
-
...
|
|
6804
|
+
...elementProps2,
|
|
6805
|
+
useTrackDefaults: false,
|
|
6556
6806
|
capStyle: updates.style ?? (capStyle == null ? void 0 : capStyle.value),
|
|
6557
6807
|
font: {
|
|
6558
6808
|
size: nextFontSize,
|
|
@@ -6565,20 +6815,29 @@ function CaptionPropPanel({
|
|
|
6565
6815
|
}
|
|
6566
6816
|
};
|
|
6567
6817
|
react.useEffect(() => {
|
|
6568
|
-
var _a, _b;
|
|
6569
6818
|
const captionElement = selectedElement;
|
|
6570
6819
|
if (captionElement) {
|
|
6571
6820
|
if (captionRef.current) {
|
|
6572
6821
|
captionRef.current.value = captionElement == null ? void 0 : captionElement.getText();
|
|
6573
6822
|
}
|
|
6574
|
-
const
|
|
6575
|
-
const
|
|
6823
|
+
const elementProps2 = captionElement.getProps() ?? {};
|
|
6824
|
+
const elementUseTrackDefaults = (elementProps2 == null ? void 0 : elementProps2.useTrackDefaults) ?? true;
|
|
6825
|
+
const resolvedCapStyle = elementUseTrackDefaults ? trackProps == null ? void 0 : trackProps.capStyle : (elementProps2 == null ? void 0 : elementProps2.capStyle) ?? (trackProps == null ? void 0 : trackProps.capStyle);
|
|
6826
|
+
const resolvedFont = elementUseTrackDefaults ? trackProps == null ? void 0 : trackProps.font : {
|
|
6827
|
+
...(trackProps == null ? void 0 : trackProps.font) ?? {},
|
|
6828
|
+
...(elementProps2 == null ? void 0 : elementProps2.font) ?? {}
|
|
6829
|
+
};
|
|
6830
|
+
const resolvedColors = elementUseTrackDefaults ? trackProps == null ? void 0 : trackProps.colors : {
|
|
6831
|
+
...(trackProps == null ? void 0 : trackProps.colors) ?? {},
|
|
6832
|
+
...(elementProps2 == null ? void 0 : elementProps2.colors) ?? {}
|
|
6833
|
+
};
|
|
6834
|
+
const _capStyle = resolvedCapStyle;
|
|
6576
6835
|
if (_capStyle && _capStyle in timeline.CAPTION_STYLE_OPTIONS) {
|
|
6577
6836
|
setCapStyle(timeline.CAPTION_STYLE_OPTIONS[_capStyle]);
|
|
6578
6837
|
}
|
|
6579
|
-
setFontSize((
|
|
6580
|
-
setFontFamily((
|
|
6581
|
-
const c =
|
|
6838
|
+
setFontSize((resolvedFont == null ? void 0 : resolvedFont.size) ?? CAPTION_FONT.size);
|
|
6839
|
+
setFontFamily((resolvedFont == null ? void 0 : resolvedFont.family) ?? CAPTION_FONT.family);
|
|
6840
|
+
const c = resolvedColors;
|
|
6582
6841
|
setColors({
|
|
6583
6842
|
text: (c == null ? void 0 : c.text) ?? CAPTION_COLOR.text,
|
|
6584
6843
|
highlight: (c == null ? void 0 : c.highlight) ?? CAPTION_COLOR.highlight,
|
|
@@ -6588,7 +6847,7 @@ function CaptionPropPanel({
|
|
|
6588
6847
|
setUseHighlight((c == null ? void 0 : c.highlight) != null);
|
|
6589
6848
|
setUseOutline((c == null ? void 0 : c.outlineColor) != null);
|
|
6590
6849
|
}
|
|
6591
|
-
}, [selectedElement,
|
|
6850
|
+
}, [selectedElement, track, changeLog]);
|
|
6592
6851
|
if (!(selectedElement instanceof timeline.CaptionElement)) {
|
|
6593
6852
|
return null;
|
|
6594
6853
|
}
|
|
@@ -6642,6 +6901,18 @@ function CaptionPropPanel({
|
|
|
6642
6901
|
] }, key);
|
|
6643
6902
|
};
|
|
6644
6903
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel-container", children: [
|
|
6904
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-section", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "checkbox-control", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "checkbox-label", children: [
|
|
6905
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6906
|
+
"input",
|
|
6907
|
+
{
|
|
6908
|
+
type: "checkbox",
|
|
6909
|
+
checked: useTrackDefaults,
|
|
6910
|
+
onChange: (e) => handleUseTrackDefaultsChange(e.target.checked),
|
|
6911
|
+
className: "checkbox-purple"
|
|
6912
|
+
}
|
|
6913
|
+
),
|
|
6914
|
+
"Use track defaults"
|
|
6915
|
+
] }) }) }),
|
|
6645
6916
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel-section", children: [
|
|
6646
6917
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "label-dark", children: "Caption Style" }),
|
|
6647
6918
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6845,92 +7116,82 @@ function PlaybackPropsPanel({
|
|
|
6845
7116
|
)
|
|
6846
7117
|
] });
|
|
6847
7118
|
}
|
|
6848
|
-
const
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
if (!response.ok) throw new Error(`Failed to fetch source: ${response.status}`);
|
|
6868
|
-
const arrayBuffer = await response.arrayBuffer();
|
|
6869
|
-
return decodeAudioData(arrayBuffer);
|
|
7119
|
+
const NONE_VALUE = "none";
|
|
7120
|
+
const FILTER_LABELS = {
|
|
7121
|
+
[NONE_VALUE]: "None",
|
|
7122
|
+
[mediaUtils.COLOR_FILTERS.SATURATED]: "Saturated",
|
|
7123
|
+
[mediaUtils.COLOR_FILTERS.BRIGHT]: "Bright",
|
|
7124
|
+
[mediaUtils.COLOR_FILTERS.VIBRANT]: "Vibrant",
|
|
7125
|
+
[mediaUtils.COLOR_FILTERS.RETRO]: "Retro",
|
|
7126
|
+
[mediaUtils.COLOR_FILTERS.BLACK_WHITE]: "Black & white",
|
|
7127
|
+
[mediaUtils.COLOR_FILTERS.SEPIA]: "Sepia",
|
|
7128
|
+
[mediaUtils.COLOR_FILTERS.COOL]: "Cool",
|
|
7129
|
+
[mediaUtils.COLOR_FILTERS.WARM]: "Warm",
|
|
7130
|
+
[mediaUtils.COLOR_FILTERS.CINEMATIC]: "Cinematic",
|
|
7131
|
+
[mediaUtils.COLOR_FILTERS.SOFT_GLOW]: "Soft glow",
|
|
7132
|
+
[mediaUtils.COLOR_FILTERS.MOODY]: "Moody",
|
|
7133
|
+
[mediaUtils.COLOR_FILTERS.DREAMY]: "Dreamy",
|
|
7134
|
+
[mediaUtils.COLOR_FILTERS.INVERTED]: "Inverted",
|
|
7135
|
+
[mediaUtils.COLOR_FILTERS.VINTAGE]: "Vintage",
|
|
7136
|
+
[mediaUtils.COLOR_FILTERS.DRAMATIC]: "Dramatic",
|
|
7137
|
+
[mediaUtils.COLOR_FILTERS.FADED]: "Faded"
|
|
6870
7138
|
};
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
)
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
7139
|
+
function isMediaFilterElement(el) {
|
|
7140
|
+
return el instanceof timeline.VideoElement || el instanceof timeline.ImageElement;
|
|
7141
|
+
}
|
|
7142
|
+
function ColorFilterPropsPanel({
|
|
7143
|
+
selectedElement,
|
|
7144
|
+
updateElement
|
|
7145
|
+
}) {
|
|
7146
|
+
const mediaEl = isMediaFilterElement(selectedElement) ? selectedElement : null;
|
|
7147
|
+
const options = react.useMemo(() => {
|
|
7148
|
+
const entries = Object.values(mediaUtils.COLOR_FILTERS).map(
|
|
7149
|
+
(value) => ({
|
|
7150
|
+
value,
|
|
7151
|
+
label: FILTER_LABELS[value] ?? value
|
|
7152
|
+
})
|
|
7153
|
+
);
|
|
7154
|
+
return [{ value: NONE_VALUE, label: FILTER_LABELS[NONE_VALUE] }, ...entries];
|
|
7155
|
+
}, []);
|
|
7156
|
+
const elementProps = (mediaEl == null ? void 0 : mediaEl.getProps()) ?? {};
|
|
7157
|
+
const mediaFilter = elementProps.mediaFilter ?? NONE_VALUE;
|
|
7158
|
+
const handleFilterChange = (value) => {
|
|
7159
|
+
if (!mediaEl || !updateElement) return;
|
|
7160
|
+
const allowed = Object.values(mediaUtils.COLOR_FILTERS);
|
|
7161
|
+
const next = value === NONE_VALUE ? NONE_VALUE : allowed.includes(value) ? value : NONE_VALUE;
|
|
7162
|
+
updateElement(
|
|
7163
|
+
mediaEl.setProps({
|
|
7164
|
+
...elementProps,
|
|
7165
|
+
mediaFilter: next
|
|
7166
|
+
})
|
|
7167
|
+
);
|
|
7168
|
+
};
|
|
7169
|
+
const [isOpen, setIsOpen] = react.useState(false);
|
|
7170
|
+
if (!mediaEl) {
|
|
7171
|
+
return null;
|
|
6885
7172
|
}
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
7173
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel-container", children: [
|
|
7174
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-title", children: "Look" }),
|
|
7175
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7176
|
+
AccordionItem,
|
|
7177
|
+
{
|
|
7178
|
+
title: "Color filter",
|
|
7179
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Funnel, { className: "icon-sm" }),
|
|
7180
|
+
isOpen,
|
|
7181
|
+
onToggle: () => setIsOpen((open) => !open),
|
|
7182
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "properties-group", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "property-section", children: /* @__PURE__ */ jsxRuntime.jsx(PropertyRow, { label: "Preset", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7183
|
+
"select",
|
|
7184
|
+
{
|
|
7185
|
+
value: options.some((o) => o.value === mediaFilter) ? mediaFilter : NONE_VALUE,
|
|
7186
|
+
onChange: (e) => handleFilterChange(e.target.value),
|
|
7187
|
+
className: "select-dark w-full",
|
|
7188
|
+
children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.value, children: opt.label }, opt.value))
|
|
7189
|
+
}
|
|
7190
|
+
) }) }) })
|
|
6893
7191
|
}
|
|
6894
|
-
|
|
6895
|
-
}
|
|
6896
|
-
|
|
6897
|
-
};
|
|
6898
|
-
const loadFile = (accept) => {
|
|
6899
|
-
return new Promise((resolve, reject) => {
|
|
6900
|
-
try {
|
|
6901
|
-
const input = document.createElement("input");
|
|
6902
|
-
input.type = "file";
|
|
6903
|
-
input.accept = accept;
|
|
6904
|
-
input.style.display = "none";
|
|
6905
|
-
document.body.appendChild(input);
|
|
6906
|
-
const cleanup = () => {
|
|
6907
|
-
input.value = "";
|
|
6908
|
-
document.body.removeChild(input);
|
|
6909
|
-
};
|
|
6910
|
-
input.onchange = () => {
|
|
6911
|
-
const file = input.files && input.files[0];
|
|
6912
|
-
cleanup();
|
|
6913
|
-
if (!file) {
|
|
6914
|
-
reject(new Error("No file selected"));
|
|
6915
|
-
return;
|
|
6916
|
-
}
|
|
6917
|
-
resolve(file);
|
|
6918
|
-
};
|
|
6919
|
-
input.click();
|
|
6920
|
-
} catch (error) {
|
|
6921
|
-
reject(error);
|
|
6922
|
-
}
|
|
6923
|
-
});
|
|
6924
|
-
};
|
|
6925
|
-
const saveAsFile = (content, type, name) => {
|
|
6926
|
-
const blob = typeof content === "string" ? new Blob([content], { type }) : content;
|
|
6927
|
-
const url = URL.createObjectURL(blob);
|
|
6928
|
-
const a = document.createElement("a");
|
|
6929
|
-
a.href = url;
|
|
6930
|
-
a.download = name;
|
|
6931
|
-
a.click();
|
|
6932
|
-
URL.revokeObjectURL(url);
|
|
6933
|
-
};
|
|
7192
|
+
)
|
|
7193
|
+
] });
|
|
7194
|
+
}
|
|
6934
7195
|
function GenerateCaptionsPanel({
|
|
6935
7196
|
selectedElement,
|
|
6936
7197
|
addCaptionsToTimeline,
|
|
@@ -6944,7 +7205,7 @@ function GenerateCaptionsPanel({
|
|
|
6944
7205
|
const [pollingStatus, setPollingStatus] = react.useState("idle");
|
|
6945
7206
|
const [errorMessage, setErrorMessage] = react.useState(null);
|
|
6946
7207
|
const [selectedLanguage, setSelectedLanguage] = react.useState("auto");
|
|
6947
|
-
const [
|
|
7208
|
+
const [phraseLength, setPhraseLength] = react.useState("medium");
|
|
6948
7209
|
const pollingIntervalRef = react.useRef(null);
|
|
6949
7210
|
const currentReqIdRef = react.useRef(null);
|
|
6950
7211
|
react.useEffect(() => {
|
|
@@ -7009,7 +7270,7 @@ function GenerateCaptionsPanel({
|
|
|
7009
7270
|
const reqId = await onGenerateCaptions(
|
|
7010
7271
|
videoElement,
|
|
7011
7272
|
language,
|
|
7012
|
-
|
|
7273
|
+
phraseLength
|
|
7013
7274
|
);
|
|
7014
7275
|
if (!reqId) {
|
|
7015
7276
|
setPollingStatus("error");
|
|
@@ -7034,7 +7295,7 @@ function GenerateCaptionsPanel({
|
|
|
7034
7295
|
const videoUrl = videoElement.getSrc();
|
|
7035
7296
|
if (videoUrl) {
|
|
7036
7297
|
try {
|
|
7037
|
-
const hasAudioTrack = await hasAudio(videoUrl);
|
|
7298
|
+
const hasAudioTrack = await mediaUtils.hasAudio(videoUrl);
|
|
7038
7299
|
setContainsAudio(hasAudioTrack);
|
|
7039
7300
|
} catch (error) {
|
|
7040
7301
|
console.error("Error checking audio:", error);
|
|
@@ -7094,18 +7355,19 @@ function GenerateCaptionsPanel({
|
|
|
7094
7355
|
)
|
|
7095
7356
|
] }),
|
|
7096
7357
|
!isLoading && containsAudio === true && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel-section", children: [
|
|
7097
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "label-dark", htmlFor: "caption-
|
|
7098
|
-
/* @__PURE__ */ jsxRuntime.
|
|
7358
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "label-dark", htmlFor: "caption-phrase-length", children: "Caption length" }),
|
|
7359
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7099
7360
|
"select",
|
|
7100
7361
|
{
|
|
7101
|
-
id: "caption-
|
|
7362
|
+
id: "caption-phrase-length",
|
|
7102
7363
|
className: "select-dark",
|
|
7103
|
-
value:
|
|
7104
|
-
onChange: (e) =>
|
|
7105
|
-
children:
|
|
7106
|
-
|
|
7107
|
-
|
|
7108
|
-
|
|
7364
|
+
value: phraseLength,
|
|
7365
|
+
onChange: (e) => setPhraseLength(e.target.value),
|
|
7366
|
+
children: [
|
|
7367
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "short", children: "Short" }),
|
|
7368
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "medium", children: "Medium" }),
|
|
7369
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "long", children: "Long" })
|
|
7370
|
+
]
|
|
7109
7371
|
}
|
|
7110
7372
|
)
|
|
7111
7373
|
] }),
|
|
@@ -7502,6 +7764,7 @@ function PropertiesPanelContainer({
|
|
|
7502
7764
|
selectedElement && !(selectedElement instanceof timeline.CaptionElement) && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: (() => {
|
|
7503
7765
|
const isText = selectedElement instanceof timeline.TextElement;
|
|
7504
7766
|
const isVideo = selectedElement instanceof timeline.VideoElement;
|
|
7767
|
+
const isImage = selectedElement instanceof timeline.ImageElement;
|
|
7505
7768
|
const isAudio = selectedElement instanceof timeline.AudioElement;
|
|
7506
7769
|
const isAnnotation = selectedElement instanceof timeline.ArrowElement || selectedElement instanceof timeline.LineElement || selectedElement instanceof timeline.RectElement || selectedElement instanceof timeline.CircleElement;
|
|
7507
7770
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -7533,6 +7796,13 @@ function PropertiesPanelContainer({
|
|
|
7533
7796
|
updateElement
|
|
7534
7797
|
}
|
|
7535
7798
|
),
|
|
7799
|
+
(isVideo || isImage) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7800
|
+
ColorFilterPropsPanel,
|
|
7801
|
+
{
|
|
7802
|
+
selectedElement,
|
|
7803
|
+
updateElement
|
|
7804
|
+
}
|
|
7805
|
+
),
|
|
7536
7806
|
isText && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7537
7807
|
TextEffects,
|
|
7538
7808
|
{
|
|
@@ -7580,7 +7850,7 @@ const useStudioOperation = (studioConfig) => {
|
|
|
7580
7850
|
if (studioConfig == null ? void 0 : studioConfig.loadProject) {
|
|
7581
7851
|
project = await studioConfig.loadProject();
|
|
7582
7852
|
} else {
|
|
7583
|
-
const file = await loadFile("application/json");
|
|
7853
|
+
const file = await mediaUtils.loadFile("application/json");
|
|
7584
7854
|
const text = await file.text();
|
|
7585
7855
|
setProjectName(file.name);
|
|
7586
7856
|
project = JSON.parse(text);
|
|
@@ -7600,7 +7870,7 @@ const useStudioOperation = (studioConfig) => {
|
|
|
7600
7870
|
if ((studioConfig == null ? void 0 : studioConfig.saveProject) && present) {
|
|
7601
7871
|
await studioConfig.saveProject(present, fileName);
|
|
7602
7872
|
} else {
|
|
7603
|
-
const file = await saveAsFile(
|
|
7873
|
+
const file = await mediaUtils.saveAsFile(
|
|
7604
7874
|
JSON.stringify(present),
|
|
7605
7875
|
"application/json",
|
|
7606
7876
|
fileName
|
|
@@ -7630,19 +7900,19 @@ const useStudioOperation = (studioConfig) => {
|
|
|
7630
7900
|
const languages = timeline.getCaptionLanguages(present);
|
|
7631
7901
|
if (languages.length <= 1) {
|
|
7632
7902
|
const content = format === "srt" ? timeline.exportCaptionsAsSRT(present, languages[0]) : timeline.exportCaptionsAsVTT(present, languages[0]);
|
|
7633
|
-
await saveAsFile(content, "text/plain", `${baseName}.${format}`);
|
|
7903
|
+
await mediaUtils.saveAsFile(content, "text/plain", `${baseName}.${format}`);
|
|
7634
7904
|
return;
|
|
7635
7905
|
}
|
|
7636
7906
|
for (const language of languages) {
|
|
7637
7907
|
const content = format === "srt" ? timeline.exportCaptionsAsSRT(present, language) : timeline.exportCaptionsAsVTT(present, language);
|
|
7638
|
-
await saveAsFile(content, "text/plain", `${baseName}.${language}.${format}`);
|
|
7908
|
+
await mediaUtils.saveAsFile(content, "text/plain", `${baseName}.${language}.${format}`);
|
|
7639
7909
|
}
|
|
7640
7910
|
};
|
|
7641
7911
|
const onExportChapters = async (format) => {
|
|
7642
7912
|
if (!present) return;
|
|
7643
7913
|
const content = format === "youtube" ? timeline.exportChaptersAsYouTube(present) : timeline.exportChaptersAsJSON(present);
|
|
7644
7914
|
const fileName = `${(projectName || "chapters").replace(/\.json$/i, "")}.${format === "youtube" ? "txt" : "json"}`;
|
|
7645
|
-
await saveAsFile(content, "text/plain", fileName);
|
|
7915
|
+
await mediaUtils.saveAsFile(content, "text/plain", fileName);
|
|
7646
7916
|
};
|
|
7647
7917
|
const addCaptionsToTimeline = (captions) => {
|
|
7648
7918
|
var _a;
|
|
@@ -7776,14 +8046,14 @@ function TwickStudio({ studioConfig }) {
|
|
|
7776
8046
|
const useGenerateCaptions = (studioConfig) => {
|
|
7777
8047
|
var _a;
|
|
7778
8048
|
const { editor, present } = timeline.useTimelineContext();
|
|
7779
|
-
const onGenerateCaptions = async (videoElement, language,
|
|
8049
|
+
const onGenerateCaptions = async (videoElement, language, phraseLength) => {
|
|
7780
8050
|
if (studioConfig == null ? void 0 : studioConfig.captionGenerationService) {
|
|
7781
8051
|
const service = studioConfig.captionGenerationService;
|
|
7782
8052
|
const reqId = await service.generateCaptions(
|
|
7783
8053
|
videoElement,
|
|
7784
8054
|
present,
|
|
7785
8055
|
language,
|
|
7786
|
-
|
|
8056
|
+
phraseLength
|
|
7787
8057
|
);
|
|
7788
8058
|
return reqId;
|
|
7789
8059
|
}
|
|
@@ -8147,6 +8417,10 @@ Object.defineProperty(exports, "ElementValidator", {
|
|
|
8147
8417
|
enumerable: true,
|
|
8148
8418
|
get: () => timeline.ElementValidator
|
|
8149
8419
|
});
|
|
8420
|
+
Object.defineProperty(exports, "EmojiElement", {
|
|
8421
|
+
enumerable: true,
|
|
8422
|
+
get: () => timeline.EmojiElement
|
|
8423
|
+
});
|
|
8150
8424
|
Object.defineProperty(exports, "INITIAL_TIMELINE_DATA", {
|
|
8151
8425
|
enumerable: true,
|
|
8152
8426
|
get: () => timeline.INITIAL_TIMELINE_DATA
|
|
@@ -8311,6 +8585,7 @@ exports.DEFAULT_PROJECT_TEMPLATES = DEFAULT_PROJECT_TEMPLATES;
|
|
|
8311
8585
|
exports.DEFAULT_STUDIO_CONFIG = DEFAULT_STUDIO_CONFIG;
|
|
8312
8586
|
exports.DEMO_STUDIO_CONFIG = DEMO_STUDIO_CONFIG;
|
|
8313
8587
|
exports.EDU_STUDIO_CONFIG = EDU_STUDIO_CONFIG;
|
|
8588
|
+
exports.EmojiPanel = EmojiPanel;
|
|
8314
8589
|
exports.ImagePanel = ImagePanel;
|
|
8315
8590
|
exports.MARKETING_STUDIO_CONFIG = MARKETING_STUDIO_CONFIG;
|
|
8316
8591
|
exports.RecordPanel = RecordPanel;
|