@flamingo-stack/openframe-frontend-core 0.0.269 → 0.0.270
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/{chunk-TOQH27ZP.js → chunk-37OJ53QH.js} +2 -2
- package/dist/{chunk-FEIRH7ER.cjs → chunk-3H5TSZMU.cjs} +25 -25
- package/dist/{chunk-FEIRH7ER.cjs.map → chunk-3H5TSZMU.cjs.map} +1 -1
- package/dist/{chunk-HQGGXT2T.js → chunk-EMRSIP4Q.js} +2 -2
- package/dist/{chunk-NM7J44WP.cjs → chunk-JIJEVSCC.cjs} +30 -30
- package/dist/{chunk-NM7J44WP.cjs.map → chunk-JIJEVSCC.cjs.map} +1 -1
- package/dist/{chunk-QDA2XVFP.cjs → chunk-N3OPJQYI.cjs} +54 -22
- package/dist/chunk-N3OPJQYI.cjs.map +1 -0
- package/dist/{chunk-TZEHP5IW.cjs → chunk-NDSCF6LB.cjs} +11 -11
- package/dist/{chunk-TZEHP5IW.cjs.map → chunk-NDSCF6LB.cjs.map} +1 -1
- package/dist/{chunk-ALCUDWKJ.js → chunk-RM7ZT3UU.js} +162 -130
- package/dist/{chunk-ALCUDWKJ.js.map → chunk-RM7ZT3UU.js.map} +1 -1
- package/dist/{chunk-DATYABIL.js → chunk-XOKXFW77.js} +2 -2
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/features/video-source-selector.d.ts +11 -1
- package/dist/components/features/video-source-selector.d.ts.map +1 -1
- package/dist/components/index.cjs +47 -47
- package/dist/components/index.js +3 -3
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/tickets/index.cjs +53 -53
- package/dist/components/tickets/index.js +3 -3
- package/dist/components/ui/index.cjs +2 -2
- package/dist/components/ui/index.js +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/features/video-source-selector.tsx +83 -18
- package/dist/chunk-QDA2XVFP.cjs.map +0 -1
- /package/dist/{chunk-TOQH27ZP.js.map → chunk-37OJ53QH.js.map} +0 -0
- /package/dist/{chunk-HQGGXT2T.js.map → chunk-EMRSIP4Q.js.map} +0 -0
- /package/dist/{chunk-DATYABIL.js.map → chunk-XOKXFW77.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import React, { useState, useCallback } from 'react';
|
|
4
|
-
import { Upload, Sparkles, X, Video } from 'lucide-react';
|
|
3
|
+
import React, { useState, useCallback, useEffect } from 'react';
|
|
4
|
+
import { Upload, Sparkles, X, Video, Loader2 } from 'lucide-react';
|
|
5
5
|
import { Button } from '../ui/button';
|
|
6
6
|
import { Input } from '../ui/input';
|
|
7
7
|
import { Label } from '../ui/label';
|
|
@@ -47,6 +47,16 @@ export interface VideoSourceSelectorProps {
|
|
|
47
47
|
onDelete: () => void;
|
|
48
48
|
isAIGenerated?: boolean;
|
|
49
49
|
}>;
|
|
50
|
+
/**
|
|
51
|
+
* Optional: resolve the uploaded video URL before it's handed to the DEFAULT
|
|
52
|
+
* `<video>` preview (no-op when a `VideoPreviewComponent` is supplied — that
|
|
53
|
+
* component owns its own rendering). Lets a consumer swap a URL that a native
|
|
54
|
+
* `<video>` can't play — e.g. a Mux HLS manifest (`stream.mux.com/{id}.m3u8`),
|
|
55
|
+
* which Chrome/Firefox/Edge can't play natively — for a playable MP4. Without
|
|
56
|
+
* it the URL is used as-is (backward compatible). A rejected resolve degrades
|
|
57
|
+
* gracefully to the original URL.
|
|
58
|
+
*/
|
|
59
|
+
resolveVideoUrl?: (url: string) => Promise<string>;
|
|
50
60
|
/** Optional: Upload progress bar component */
|
|
51
61
|
UploadProgressComponent?: React.ComponentType<{
|
|
52
62
|
progress: number;
|
|
@@ -84,6 +94,7 @@ export function VideoSourceSelector({
|
|
|
84
94
|
uploadEmptyText = 'No video uploaded yet. Click "Upload Video" to add one.',
|
|
85
95
|
disabled = false,
|
|
86
96
|
VideoPreviewComponent,
|
|
97
|
+
resolveVideoUrl,
|
|
87
98
|
UploadProgressComponent,
|
|
88
99
|
title = 'Video',
|
|
89
100
|
showTitle = true,
|
|
@@ -247,22 +258,13 @@ export function VideoSourceSelector({
|
|
|
247
258
|
isAIGenerated={isAIGenerated}
|
|
248
259
|
/>
|
|
249
260
|
) : (
|
|
250
|
-
// Default simple preview
|
|
251
|
-
<
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
<button
|
|
258
|
-
type="button"
|
|
259
|
-
onClick={handleDeleteVideo}
|
|
260
|
-
className="absolute top-2 right-2 p-1.5 bg-black/60 hover:bg-black/80 rounded-full transition-colors"
|
|
261
|
-
disabled={disabled}
|
|
262
|
-
>
|
|
263
|
-
<X className="h-4 w-4 text-white" />
|
|
264
|
-
</button>
|
|
265
|
-
</div>
|
|
261
|
+
// Default simple preview (resolver-aware — see DefaultVideoPreview)
|
|
262
|
+
<DefaultVideoPreview
|
|
263
|
+
videoUrl={mainVideoUrl}
|
|
264
|
+
resolveVideoUrl={resolveVideoUrl}
|
|
265
|
+
onDelete={handleDeleteVideo}
|
|
266
|
+
disabled={disabled}
|
|
267
|
+
/>
|
|
266
268
|
)
|
|
267
269
|
) : (
|
|
268
270
|
<p className="text-sm text-ods-text-secondary italic">
|
|
@@ -275,4 +277,67 @@ export function VideoSourceSelector({
|
|
|
275
277
|
);
|
|
276
278
|
}
|
|
277
279
|
|
|
280
|
+
interface DefaultVideoPreviewProps {
|
|
281
|
+
/** Uploaded video URL (possibly an HLS manifest a native `<video>` can't play). */
|
|
282
|
+
videoUrl: string;
|
|
283
|
+
/** Optional resolver → playable MP4 URL; omit for as-is (backward-compatible) behaviour. */
|
|
284
|
+
resolveVideoUrl?: (url: string) => Promise<string>;
|
|
285
|
+
onDelete: () => void;
|
|
286
|
+
disabled?: boolean;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Default `<video>` preview for {@link VideoSourceSelector} when no
|
|
291
|
+
* `VideoPreviewComponent` is supplied. When `resolveVideoUrl` is provided the URL
|
|
292
|
+
* is resolved (e.g. Mux HLS → MP4) before it reaches the native `<video>`, which
|
|
293
|
+
* can't play HLS on Chrome/Firefox/Edge; a rejected resolve degrades to the
|
|
294
|
+
* original URL. Without a resolver the URL is used synchronously, unchanged.
|
|
295
|
+
*/
|
|
296
|
+
function DefaultVideoPreview({ videoUrl, resolveVideoUrl, onDelete, disabled }: DefaultVideoPreviewProps) {
|
|
297
|
+
// `undefined` only while an async resolve is in flight (first paint); otherwise
|
|
298
|
+
// the (possibly resolved) URL. Synchronous passthrough when there's no resolver.
|
|
299
|
+
const [resolvedUrl, setResolvedUrl] = useState<string | undefined>(
|
|
300
|
+
resolveVideoUrl ? undefined : videoUrl,
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
useEffect(() => {
|
|
304
|
+
if (!resolveVideoUrl) {
|
|
305
|
+
setResolvedUrl(videoUrl);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
// Guard against a late resolve overwriting a newer URL / unmounted preview.
|
|
309
|
+
let active = true;
|
|
310
|
+
setResolvedUrl(undefined);
|
|
311
|
+
resolveVideoUrl(videoUrl)
|
|
312
|
+
.then((url) => { if (active) setResolvedUrl(url); })
|
|
313
|
+
.catch(() => { if (active) setResolvedUrl(videoUrl); });
|
|
314
|
+
return () => { active = false; };
|
|
315
|
+
}, [videoUrl, resolveVideoUrl]);
|
|
316
|
+
|
|
317
|
+
return (
|
|
318
|
+
<div className="relative rounded-lg border border-ods-border overflow-hidden">
|
|
319
|
+
{resolvedUrl === undefined ? (
|
|
320
|
+
<div className="w-full h-[200px] flex items-center justify-center bg-black">
|
|
321
|
+
<Loader2 className="h-6 w-6 animate-spin text-ods-accent" />
|
|
322
|
+
</div>
|
|
323
|
+
) : (
|
|
324
|
+
<video
|
|
325
|
+
src={resolvedUrl}
|
|
326
|
+
className="w-full h-auto max-h-[300px] object-contain bg-black"
|
|
327
|
+
controls
|
|
328
|
+
/>
|
|
329
|
+
)}
|
|
330
|
+
<button
|
|
331
|
+
type="button"
|
|
332
|
+
onClick={onDelete}
|
|
333
|
+
aria-label="Delete video"
|
|
334
|
+
className="absolute top-2 right-2 p-1.5 bg-black/60 hover:bg-black/80 rounded-full transition-colors"
|
|
335
|
+
disabled={disabled}
|
|
336
|
+
>
|
|
337
|
+
<X className="h-4 w-4 text-white" />
|
|
338
|
+
</button>
|
|
339
|
+
</div>
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
|
|
278
343
|
export default VideoSourceSelector;
|