mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
@@ -10,6 +10,8 @@ import {
|
||||
} from "lucide-react";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { AssetPickerSheet } from "../../AssetPickerSheet";
|
||||
import { useAssetPreviewSrc } from "@/hooks/useAssetPreviewSrc";
|
||||
import { MediaFallback } from "@/components/generic/MediaFallback";
|
||||
|
||||
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -25,6 +27,15 @@ const fmtTime = (s) => {
|
||||
export function VideoBlock({ content, onUpdate, readOnly = false }) {
|
||||
const [pickerOpen, setPickerOpen] = useState(false);
|
||||
|
||||
// content.url is redacted (null) server-side for S3 assets — see
|
||||
// redactS3Url() in controllers/admin/assets.controller.js. Re-resolve
|
||||
// through media.util.js instead of trusting the persisted url/thumbnail.
|
||||
const { src, thumbnailUrl, loading } = useAssetPreviewSrc(
|
||||
{ asset_id: content?.asset_id, storage_provider: content?.storage_provider, file_url: content?.url, thumbnail_url: content?.thumbnail_url },
|
||||
{ scope: "admin" },
|
||||
);
|
||||
const poster = thumbnailUrl ?? content?.thumbnail_url ?? undefined;
|
||||
|
||||
const vidRef = useRef(null);
|
||||
const [playing, setPlaying] = useState(false);
|
||||
const [progress, setProgress] = useState(0);
|
||||
@@ -41,7 +52,7 @@ export function VideoBlock({ content, onUpdate, readOnly = false }) {
|
||||
setCurrentTime(0);
|
||||
setTotalDuration(0);
|
||||
setOverlayVisible(true);
|
||||
}, [content.url]);
|
||||
}, [src]);
|
||||
|
||||
// ── Video event listeners ─────────────────────────────────────────────────
|
||||
|
||||
@@ -65,7 +76,7 @@ export function VideoBlock({ content, onUpdate, readOnly = false }) {
|
||||
v.removeEventListener("loadedmetadata", onLoaded);
|
||||
v.removeEventListener("ended", onEnded);
|
||||
};
|
||||
}, [content.url]);
|
||||
}, [src]);
|
||||
|
||||
// ── Controls ──────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -126,11 +137,12 @@ export function VideoBlock({ content, onUpdate, readOnly = false }) {
|
||||
//
|
||||
const handleSelect = (asset) => {
|
||||
onUpdate({
|
||||
asset_id: asset.asset_id,
|
||||
url: asset.file_url,
|
||||
thumbnail_url: asset.thumbnail_url ?? null,
|
||||
title: asset.display_name,
|
||||
tag: asset.extension?.toUpperCase() ?? "",
|
||||
asset_id: asset.asset_id,
|
||||
storage_provider: asset.storage_provider ?? null,
|
||||
url: asset.file_url,
|
||||
thumbnail_url: asset.thumbnail_url ?? null,
|
||||
title: asset.display_name,
|
||||
tag: asset.extension?.toUpperCase() ?? "",
|
||||
});
|
||||
setPlaying(false);
|
||||
setProgress(0);
|
||||
@@ -145,7 +157,9 @@ export function VideoBlock({ content, onUpdate, readOnly = false }) {
|
||||
<div className="space-y-3">
|
||||
{!readOnly && <Label>Video</Label>}
|
||||
|
||||
{content.url ? (
|
||||
{loading ? (
|
||||
<MediaFallback className="w-full aspect-video rounded-lg" />
|
||||
) : src ? (
|
||||
<div className="rounded-lg overflow-hidden bg-card">
|
||||
|
||||
{/* ── Video area ── */}
|
||||
@@ -157,8 +171,8 @@ export function VideoBlock({ content, onUpdate, readOnly = false }) {
|
||||
>
|
||||
<video
|
||||
ref={vidRef}
|
||||
src={content.url}
|
||||
poster={content.thumbnail_url ?? undefined}
|
||||
src={src}
|
||||
poster={poster}
|
||||
preload="metadata"
|
||||
playsInline
|
||||
className="w-full h-full object-cover"
|
||||
|
||||
Reference in New Issue
Block a user