apply to exports and fix bug where play button was unclickable

This commit is contained in:
Josh Hawkins 2025-10-27 07:28:54 -05:00
parent 681d00accd
commit 93ffa7b8b8
2 changed files with 80 additions and 52 deletions

View File

@ -9,6 +9,12 @@
"desc": "Enter a new name for this export.", "desc": "Enter a new name for this export.",
"saveExport": "Save Export" "saveExport": "Save Export"
}, },
"tooltip": {
"shareExport": "Share export",
"downloadVideo": "Download video",
"editName": "Edit name",
"deleteExport": "Delete export"
},
"toast": { "toast": {
"error": { "error": {
"renameExportFailed": "Failed to rename export: {{errorMessage}}" "renameExportFailed": "Failed to rename export: {{errorMessage}}"

View File

@ -4,7 +4,6 @@ import { Button } from "../ui/button";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { isDesktop, isMobile } from "react-device-detect"; import { isDesktop, isMobile } from "react-device-detect";
import { FaDownload, FaPlay, FaShareAlt } from "react-icons/fa"; import { FaDownload, FaPlay, FaShareAlt } from "react-icons/fa";
import Chip from "../indicators/Chip";
import { Skeleton } from "../ui/skeleton"; import { Skeleton } from "../ui/skeleton";
import { import {
Dialog, Dialog,
@ -22,6 +21,8 @@ import { cn } from "@/lib/utils";
import { shareOrCopy } from "@/utils/browserUtil"; import { shareOrCopy } from "@/utils/browserUtil";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { ImageShadowOverlay } from "../overlay/ImageShadowOverlay"; import { ImageShadowOverlay } from "../overlay/ImageShadowOverlay";
import BlurredIconButton from "../button/BlurredIconButton";
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
type ExportProps = { type ExportProps = {
className: string; className: string;
@ -156,56 +157,77 @@ export default function ExportCard({
</> </>
)} )}
{hovered && ( {hovered && (
<div> <>
<div className="absolute inset-0 rounded-lg bg-black bg-opacity-60 md:rounded-2xl" /> <div className="absolute inset-0 rounded-lg bg-black bg-opacity-60 md:rounded-2xl" />
<div className="absolute right-1 top-1 flex items-center gap-2"> <div className="absolute right-3 top-2">
{!exportedRecording.in_progress && ( <div className="flex items-center justify-center gap-4">
<Chip {!exportedRecording.in_progress && (
className="cursor-pointer rounded-md bg-gray-500 bg-gradient-to-br from-gray-400 to-gray-500" <Tooltip>
onClick={() => <TooltipTrigger asChild>
shareOrCopy( <BlurredIconButton
`${baseUrl}export?id=${exportedRecording.id}`, onClick={() =>
exportedRecording.name.replaceAll("_", " "), shareOrCopy(
) `${baseUrl}export?id=${exportedRecording.id}`,
} exportedRecording.name.replaceAll("_", " "),
> )
<FaShareAlt className="size-4 text-white" /> }
</Chip> >
)} <FaShareAlt className="size-4" />
{!exportedRecording.in_progress && ( </BlurredIconButton>
<a </TooltipTrigger>
download <TooltipContent>{t("tooltip.shareExport")}</TooltipContent>
href={`${baseUrl}${exportedRecording.video_path.replace("/media/frigate/", "")}`} </Tooltip>
> )}
<Chip className="cursor-pointer rounded-md bg-gray-500 bg-gradient-to-br from-gray-400 to-gray-500"> {!exportedRecording.in_progress && (
<FaDownload className="size-4 text-white" /> <a
</Chip> download
</a> href={`${baseUrl}${exportedRecording.video_path.replace("/media/frigate/", "")}`}
)} >
{!exportedRecording.in_progress && ( <Tooltip>
<Chip <TooltipTrigger asChild>
className="cursor-pointer rounded-md bg-gray-500 bg-gradient-to-br from-gray-400 to-gray-500" <BlurredIconButton>
onClick={() => <FaDownload className="size-4" />
setEditName({ </BlurredIconButton>
original: exportedRecording.name, </TooltipTrigger>
update: undefined, <TooltipContent>
}) {t("tooltip.downloadVideo")}
} </TooltipContent>
> </Tooltip>
<MdEditSquare className="size-4 text-white" /> </a>
</Chip> )}
)} {!exportedRecording.in_progress && (
<Chip <Tooltip>
className="cursor-pointer rounded-md bg-gray-500 bg-gradient-to-br from-gray-400 to-gray-500" <TooltipTrigger asChild>
onClick={() => <BlurredIconButton
onDelete({ onClick={() =>
file: exportedRecording.id, setEditName({
exportName: exportedRecording.name, original: exportedRecording.name,
}) update: undefined,
} })
> }
<LuTrash className="size-4 fill-destructive text-destructive" /> >
</Chip> <MdEditSquare className="size-4" />
</BlurredIconButton>
</TooltipTrigger>
<TooltipContent>{t("tooltip.editName")}</TooltipContent>
</Tooltip>
)}
<Tooltip>
<TooltipTrigger asChild>
<BlurredIconButton
onClick={() =>
onDelete({
file: exportedRecording.id,
exportName: exportedRecording.name,
})
}
>
<LuTrash className="size-4 fill-destructive text-destructive hover:text-white" />
</BlurredIconButton>
</TooltipTrigger>
<TooltipContent>{t("tooltip.deleteExport")}</TooltipContent>
</Tooltip>
</div>
</div> </div>
{!exportedRecording.in_progress && ( {!exportedRecording.in_progress && (
@ -220,13 +242,13 @@ export default function ExportCard({
<FaPlay /> <FaPlay />
</Button> </Button>
)} )}
</div> </>
)} )}
{loading && ( {loading && (
<Skeleton className="absolute inset-0 aspect-video rounded-lg md:rounded-2xl" /> <Skeleton className="absolute inset-0 aspect-video rounded-lg md:rounded-2xl" />
)} )}
<ImageShadowOverlay /> <ImageShadowOverlay />
<div className="absolute bottom-2 left-3 flex h-full items-end justify-between text-white smart-capitalize"> <div className="absolute bottom-2 left-3 flex items-end text-white smart-capitalize">
{exportedRecording.name.replaceAll("_", " ")} {exportedRecording.name.replaceAll("_", " ")}
</div> </div>
</div> </div>