diff --git a/frontend/src/pages/InboxPage.tsx b/frontend/src/pages/InboxPage.tsx index e42d960..3faeed2 100644 --- a/frontend/src/pages/InboxPage.tsx +++ b/frontend/src/pages/InboxPage.tsx @@ -1,4 +1,4 @@ -import { useState } from "react" +import { useState, useCallback } from "react" import { useNavigate } from "react-router" import { useFrappeGetDocList } from "frappe-react-sdk" import { HugeiconsIcon } from "@hugeicons/react" @@ -18,6 +18,7 @@ import { UploadDialog } from "@/components/UploadDialog" import { MoveAssetDialog } from "@/components/MoveAssetDialog" import { DeleteAssetDialog } from "@/components/DeleteAssetDialog" import { RenameAssetDialog } from "@/components/RenameAssetDialog" +import { MediaPlayerDialog } from "@/components/MediaPlayerDialog" import { useDownload } from "@/hooks/useDownload" import { UserAvatar } from "@/components/UserAvatar" import type { VMSAsset } from "@/types" @@ -35,6 +36,7 @@ export function InboxPage() { const [moveOpen, setMoveOpen] = useState(false) const [deleteOpen, setDeleteOpen] = useState(false) const [renameOpen, setRenameOpen] = useState(false) + const [previewAsset, setPreviewAsset] = useState(null) const [selected, setSelected] = useState>(new Set()) const [view, setView] = useState<"list" | "grid">("grid") const { downloadOne, downloadMany, isDownloading } = useDownload() @@ -90,6 +92,18 @@ export function InboxPage() { mutate() } + const handleAssetClick = useCallback( + (asset: VMSAsset) => { + if (asset.status !== "Ready") return + if (asset.file_type?.startsWith("video/")) { + navigate(`/review/${asset.name}`) + } else { + setPreviewAsset(asset) + } + }, + [navigate], + ) + const handleBulkDownload = () => { if (!assets) return const toDownload = assets.filter((a) => selected.has(a.name)) @@ -217,10 +231,7 @@ export function InboxPage() { key={asset.name} size="sm" className="cursor-pointer transition-shadow hover:shadow-md" - onClick={() => { - if (asset.status === "Ready") - navigate(`/review/${asset.name}`) - }} + onClick={() => handleAssetClick(asset)} >
@@ -297,10 +308,7 @@ export function InboxPage() { { - if (asset.status === "Ready") - navigate(`/review/${asset.name}`) - }} + onClick={() => handleAssetClick(asset)} >
{asset.thumbnail_url ? ( @@ -407,6 +415,13 @@ export function InboxPage() { ) : null })()} + { if (!open) setPreviewAsset(null) }} + assetName={previewAsset?.name ?? null} + fileName={previewAsset?.file_name} + fileType={previewAsset?.file_type} + />
) } diff --git a/frontend/src/pages/ProjectDetailPage.tsx b/frontend/src/pages/ProjectDetailPage.tsx index fbe396a..8a1556c 100644 --- a/frontend/src/pages/ProjectDetailPage.tsx +++ b/frontend/src/pages/ProjectDetailPage.tsx @@ -33,6 +33,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { UploadDialog } from "@/components/UploadDialog" import { DeleteAssetDialog } from "@/components/DeleteAssetDialog" import { RenameAssetDialog } from "@/components/RenameAssetDialog" +import { MediaPlayerDialog } from "@/components/MediaPlayerDialog" import { useDownload } from "@/hooks/useDownload" import { UserAvatar } from "@/components/UserAvatar" import { toast } from "sonner" @@ -51,6 +52,7 @@ export function ProjectDetailPage() { const [uploadOpen, setUploadOpen] = useState(false) const [deleteOpen, setDeleteOpen] = useState(false) const [renameOpen, setRenameOpen] = useState(false) + const [previewAsset, setPreviewAsset] = useState(null) const [view, setView] = useState<"list" | "grid">("grid") const [selected, setSelected] = useState>(new Set()) const { downloadOne, downloadMany, isDownloading } = useDownload() @@ -134,6 +136,19 @@ export function ProjectDetailPage() { downloadMany(toDownload) } + const handleAssetClick = useCallback( + (assetName: string) => { + const asset = (assets ?? []).find((a) => a.name === assetName) + if (!asset || asset.status !== "Ready") return + if (asset.file_type?.startsWith("video/")) { + navigate(`/review/${assetName}`) + } else { + setPreviewAsset(asset) + } + }, + [assets, navigate], + ) + const handleDeleteComplete = () => { setSelected(new Set()) mutateAssets() @@ -259,7 +274,7 @@ export function ProjectDetailPage() { toggleSelect={toggleSelect} toggleSelectAll={() => toggleSelectAll(assetItems)} downloadOne={downloadOne} - onPlay={(name) => navigate(`/review/${name}`)} + onPlay={handleAssetClick} onTogglePublicReview={handleTogglePublicReview} emptyMessage="No source or cut assets yet. Upload some files to get started." /> @@ -274,7 +289,7 @@ export function ProjectDetailPage() { toggleSelect={toggleSelect} toggleSelectAll={() => toggleSelectAll(exportItems)} downloadOne={downloadOne} - onPlay={(name) => navigate(`/review/${name}`)} + onPlay={handleAssetClick} onTogglePublicReview={handleTogglePublicReview} emptyMessage="No review or final exports yet. Upload exports to share with your team." /> @@ -307,6 +322,14 @@ export function ProjectDetailPage() { /> ) : null })()} + + { if (!open) setPreviewAsset(null) }} + assetName={previewAsset?.name ?? null} + fileName={previewAsset?.file_name} + fileType={previewAsset?.file_type} + />
) } diff --git a/vms/public/frontend/index.html b/vms/public/frontend/index.html index 266040b..b5e194d 100644 --- a/vms/public/frontend/index.html +++ b/vms/public/frontend/index.html @@ -5,7 +5,7 @@ BWH VMS - + diff --git a/vms/www/vms.html b/vms/www/vms.html index 266040b..b5e194d 100644 --- a/vms/www/vms.html +++ b/vms/www/vms.html @@ -5,7 +5,7 @@ BWH VMS - +