mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	Add download chips to search item details video and snapshot panes (#14525)
This commit is contained in:
		
							parent
							
								
									e4048be088
								
							
						
					
					
						commit
						fc59c83e16
					
				@ -4,17 +4,20 @@ import { toast } from "sonner";
 | 
			
		||||
import ActivityIndicator from "../indicators/activity-indicator";
 | 
			
		||||
import { FaDownload } from "react-icons/fa";
 | 
			
		||||
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
 | 
			
		||||
import { cn } from "@/lib/utils";
 | 
			
		||||
 | 
			
		||||
type DownloadVideoButtonProps = {
 | 
			
		||||
  source: string;
 | 
			
		||||
  camera: string;
 | 
			
		||||
  startTime: number;
 | 
			
		||||
  className?: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function DownloadVideoButton({
 | 
			
		||||
  source,
 | 
			
		||||
  camera,
 | 
			
		||||
  startTime,
 | 
			
		||||
  className,
 | 
			
		||||
}: DownloadVideoButtonProps) {
 | 
			
		||||
  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 (
 | 
			
		||||
    <div className="flex justify-center">
 | 
			
		||||
      <Button
 | 
			
		||||
@ -48,16 +44,13 @@ export function DownloadVideoButton({
 | 
			
		||||
        size="sm"
 | 
			
		||||
        aria-label="Download Video"
 | 
			
		||||
      >
 | 
			
		||||
        <a
 | 
			
		||||
          href={source}
 | 
			
		||||
          download={filename}
 | 
			
		||||
          onClick={handleDownloadStart}
 | 
			
		||||
          onBlur={handleDownloadEnd}
 | 
			
		||||
        >
 | 
			
		||||
        <a href={source} download={filename} onClick={handleDownloadStart}>
 | 
			
		||||
          {isDownloading ? (
 | 
			
		||||
            <ActivityIndicator className="size-4" />
 | 
			
		||||
          ) : (
 | 
			
		||||
            <FaDownload className="size-4 text-secondary-foreground" />
 | 
			
		||||
            <FaDownload
 | 
			
		||||
              className={cn("size-4 text-secondary-foreground", className)}
 | 
			
		||||
            />
 | 
			
		||||
          )}
 | 
			
		||||
        </a>
 | 
			
		||||
      </Button>
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,7 @@ import ActivityIndicator from "@/components/indicators/activity-indicator";
 | 
			
		||||
import {
 | 
			
		||||
  FaCheckCircle,
 | 
			
		||||
  FaChevronDown,
 | 
			
		||||
  FaDownload,
 | 
			
		||||
  FaHistory,
 | 
			
		||||
  FaImage,
 | 
			
		||||
  FaRegListAlt,
 | 
			
		||||
@ -68,6 +69,7 @@ import {
 | 
			
		||||
  PopoverTrigger,
 | 
			
		||||
} from "@/components/ui/popover";
 | 
			
		||||
import { LuInfo } from "react-icons/lu";
 | 
			
		||||
import { TooltipPortal } from "@radix-ui/react-tooltip";
 | 
			
		||||
 | 
			
		||||
const SEARCH_TABS = [
 | 
			
		||||
  "details",
 | 
			
		||||
@ -577,6 +579,7 @@ function ObjectSnapshotTab({
 | 
			
		||||
              }}
 | 
			
		||||
            >
 | 
			
		||||
              {search?.id && (
 | 
			
		||||
                <div className="relative mx-auto">
 | 
			
		||||
                  <img
 | 
			
		||||
                    ref={imgRef}
 | 
			
		||||
                    className={`mx-auto max-h-[60dvh] bg-black object-contain`}
 | 
			
		||||
@ -587,6 +590,28 @@ function ObjectSnapshotTab({
 | 
			
		||||
                      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>
 | 
			
		||||
            {search.plus_id !== "not_enabled" && search.end_time && (
 | 
			
		||||
@ -669,7 +694,7 @@ export function VideoTab({ search }: VideoTabProps) {
 | 
			
		||||
      {reviewItem && (
 | 
			
		||||
        <div
 | 
			
		||||
          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",
 | 
			
		||||
          )}
 | 
			
		||||
        >
 | 
			
		||||
@ -689,7 +714,24 @@ export function VideoTab({ search }: VideoTabProps) {
 | 
			
		||||
                <FaHistory className="size-4 text-white" />
 | 
			
		||||
              </Chip>
 | 
			
		||||
            </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>
 | 
			
		||||
        </div>
 | 
			
		||||
      )}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user