Add download chips to search item details video and snapshot panes (#14525)

This commit is contained in:
Josh Hawkins 2024-10-22 22:09:57 -05:00 committed by GitHub
parent e4048be088
commit fc59c83e16
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 61 additions and 26 deletions

View File

@ -4,17 +4,20 @@ import { toast } from "sonner";
import ActivityIndicator from "../indicators/activity-indicator"; import ActivityIndicator from "../indicators/activity-indicator";
import { FaDownload } from "react-icons/fa"; import { FaDownload } from "react-icons/fa";
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil"; import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
import { cn } from "@/lib/utils";
type DownloadVideoButtonProps = { type DownloadVideoButtonProps = {
source: string; source: string;
camera: string; camera: string;
startTime: number; startTime: number;
className?: string;
}; };
export function DownloadVideoButton({ export function DownloadVideoButton({
source, source,
camera, camera,
startTime, startTime,
className,
}: DownloadVideoButtonProps) { }: DownloadVideoButtonProps) {
const [isDownloading, setIsDownloading] = useState(false); const [isDownloading, setIsDownloading] = useState(false);
@ -32,13 +35,6 @@ export function DownloadVideoButton({
}); });
}; };
const handleDownloadEnd = () => {
setIsDownloading(false);
toast.success("Download completed successfully.", {
position: "top-center",
});
};
return ( return (
<div className="flex justify-center"> <div className="flex justify-center">
<Button <Button
@ -48,16 +44,13 @@ export function DownloadVideoButton({
size="sm" size="sm"
aria-label="Download Video" aria-label="Download Video"
> >
<a <a href={source} download={filename} onClick={handleDownloadStart}>
href={source}
download={filename}
onClick={handleDownloadStart}
onBlur={handleDownloadEnd}
>
{isDownloading ? ( {isDownloading ? (
<ActivityIndicator className="size-4" /> <ActivityIndicator className="size-4" />
) : ( ) : (
<FaDownload className="size-4 text-secondary-foreground" /> <FaDownload
className={cn("size-4 text-secondary-foreground", className)}
/>
)} )}
</a> </a>
</Button> </Button>

View File

@ -27,6 +27,7 @@ import ActivityIndicator from "@/components/indicators/activity-indicator";
import { import {
FaCheckCircle, FaCheckCircle,
FaChevronDown, FaChevronDown,
FaDownload,
FaHistory, FaHistory,
FaImage, FaImage,
FaRegListAlt, FaRegListAlt,
@ -68,6 +69,7 @@ import {
PopoverTrigger, PopoverTrigger,
} from "@/components/ui/popover"; } from "@/components/ui/popover";
import { LuInfo } from "react-icons/lu"; import { LuInfo } from "react-icons/lu";
import { TooltipPortal } from "@radix-ui/react-tooltip";
const SEARCH_TABS = [ const SEARCH_TABS = [
"details", "details",
@ -577,16 +579,39 @@ function ObjectSnapshotTab({
}} }}
> >
{search?.id && ( {search?.id && (
<img <div className="relative mx-auto">
ref={imgRef} <img
className={`mx-auto max-h-[60dvh] bg-black object-contain`} ref={imgRef}
src={`${baseUrl}api/events/${search?.id}/snapshot.jpg`} className={`mx-auto max-h-[60dvh] bg-black object-contain`}
alt={`${search?.label}`} src={`${baseUrl}api/events/${search?.id}/snapshot.jpg`}
loading={isSafari ? "eager" : "lazy"} alt={`${search?.label}`}
onLoad={() => { loading={isSafari ? "eager" : "lazy"}
onImgLoad(); onLoad={() => {
}} onImgLoad();
/> }}
/>
<div
className={cn(
"absolute right-1 top-1 flex items-center gap-2",
)}
>
<Tooltip>
<TooltipTrigger asChild>
<a
download
href={`${baseUrl}api/events/${search?.id}/snapshot.jpg`}
>
<Chip className="cursor-pointer rounded-md bg-gray-500 bg-gradient-to-br from-gray-400 to-gray-500">
<FaDownload className="size-4 text-white" />
</Chip>
</a>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent>Download</TooltipContent>
</TooltipPortal>
</Tooltip>
</div>
</div>
)} )}
</TransformComponent> </TransformComponent>
{search.plus_id !== "not_enabled" && search.end_time && ( {search.plus_id !== "not_enabled" && search.end_time && (
@ -669,7 +694,7 @@ export function VideoTab({ search }: VideoTabProps) {
{reviewItem && ( {reviewItem && (
<div <div
className={cn( className={cn(
"absolute top-2 z-10 flex items-center", "absolute top-2 z-10 flex items-center gap-2",
isIOS ? "right-8" : "right-2", isIOS ? "right-8" : "right-2",
)} )}
> >
@ -689,7 +714,24 @@ export function VideoTab({ search }: VideoTabProps) {
<FaHistory className="size-4 text-white" /> <FaHistory className="size-4 text-white" />
</Chip> </Chip>
</TooltipTrigger> </TooltipTrigger>
<TooltipContent side="left">View in History</TooltipContent> <TooltipPortal>
<TooltipContent>View in History</TooltipContent>
</TooltipPortal>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<a
download
href={`${baseUrl}api/${search.camera}/start/${search.start_time}/end/${endTime}/clip.mp4`}
>
<Chip className="cursor-pointer rounded-md bg-gray-500 bg-gradient-to-br from-gray-400 to-gray-500">
<FaDownload className="size-4 text-white" />
</Chip>
</a>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent>Download</TooltipContent>
</TooltipPortal>
</Tooltip> </Tooltip>
</div> </div>
)} )}