mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-15 15:45:27 +03:00
117 lines
3.5 KiB
TypeScript
117 lines
3.5 KiB
TypeScript
|
|
import { useState } from "react";
|
||
|
|
import TimeAgo from "../dynamic/TimeAgo";
|
||
|
|
import useSWR from "swr";
|
||
|
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||
|
|
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
||
|
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
|
||
|
|
import ActivityIndicator from "../indicators/activity-indicator";
|
||
|
|
import { SearchResult } from "@/types/search";
|
||
|
|
import {
|
||
|
|
DropdownMenu,
|
||
|
|
DropdownMenuContent,
|
||
|
|
DropdownMenuItem,
|
||
|
|
DropdownMenuTrigger,
|
||
|
|
} from "@/components/ui/dropdown-menu";
|
||
|
|
import {
|
||
|
|
LuActivity,
|
||
|
|
LuCamera,
|
||
|
|
LuDownload,
|
||
|
|
LuMoreVertical,
|
||
|
|
LuSearch,
|
||
|
|
LuTrash2,
|
||
|
|
} from "react-icons/lu";
|
||
|
|
import FrigatePlusIcon from "@/components/icons/FrigatePlusIcon";
|
||
|
|
import { FrigatePlusDialog } from "../overlay/dialog/FrigatePlusDialog";
|
||
|
|
import { Event } from "@/types/event";
|
||
|
|
|
||
|
|
type SearchThumbnailProps = {
|
||
|
|
searchResult: SearchResult;
|
||
|
|
};
|
||
|
|
|
||
|
|
export default function SearchThumbnailFooter({
|
||
|
|
searchResult,
|
||
|
|
}: SearchThumbnailProps) {
|
||
|
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||
|
|
|
||
|
|
// interactions
|
||
|
|
|
||
|
|
const [showFrigatePlus, setShowFrigatePlus] = useState(false);
|
||
|
|
|
||
|
|
// date
|
||
|
|
|
||
|
|
const formattedDate = useFormattedTimestamp(
|
||
|
|
searchResult.start_time,
|
||
|
|
config?.ui.time_format == "24hour" ? "%b %-d, %H:%M" : "%b %-d, %I:%M %p",
|
||
|
|
config?.ui.timezone,
|
||
|
|
);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<>
|
||
|
|
<FrigatePlusDialog
|
||
|
|
upload={
|
||
|
|
showFrigatePlus ? (searchResult as unknown as Event) : undefined
|
||
|
|
}
|
||
|
|
onClose={() => setShowFrigatePlus(false)}
|
||
|
|
onEventUploaded={() => {}}
|
||
|
|
/>
|
||
|
|
|
||
|
|
<div className="flex flex-col items-start">
|
||
|
|
{searchResult.end_time ? (
|
||
|
|
<TimeAgo time={searchResult.start_time * 1000} dense />
|
||
|
|
) : (
|
||
|
|
<div>
|
||
|
|
<ActivityIndicator size={24} />
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
{formattedDate}
|
||
|
|
</div>
|
||
|
|
<div className="flex flex-row items-center justify-end gap-4">
|
||
|
|
{config?.plus?.enabled &&
|
||
|
|
searchResult.has_snapshot &&
|
||
|
|
searchResult.end_time && (
|
||
|
|
<Tooltip>
|
||
|
|
<TooltipTrigger asChild>
|
||
|
|
<FrigatePlusIcon
|
||
|
|
className="size-5 cursor-pointer text-white"
|
||
|
|
onClick={() => setShowFrigatePlus(true)}
|
||
|
|
/>
|
||
|
|
</TooltipTrigger>
|
||
|
|
<TooltipContent>Submit to Frigate+</TooltipContent>
|
||
|
|
</Tooltip>
|
||
|
|
)}
|
||
|
|
|
||
|
|
<Tooltip>
|
||
|
|
<TooltipTrigger asChild>
|
||
|
|
<LuSearch className="size-5 cursor-pointer text-white" />
|
||
|
|
</TooltipTrigger>
|
||
|
|
<TooltipContent>Find similar</TooltipContent>
|
||
|
|
</Tooltip>
|
||
|
|
|
||
|
|
<DropdownMenu>
|
||
|
|
<DropdownMenuTrigger>
|
||
|
|
<LuMoreVertical className="size-5 cursor-pointer text-white" />
|
||
|
|
</DropdownMenuTrigger>
|
||
|
|
<DropdownMenuContent>
|
||
|
|
<DropdownMenuItem>
|
||
|
|
<LuDownload className="mr-2 size-4" />
|
||
|
|
<span>Download video</span>
|
||
|
|
</DropdownMenuItem>
|
||
|
|
<DropdownMenuItem>
|
||
|
|
<LuCamera className="mr-2 size-4" />
|
||
|
|
<span>Download snapshot</span>
|
||
|
|
</DropdownMenuItem>
|
||
|
|
<DropdownMenuItem>
|
||
|
|
<LuActivity className="mr-2 size-4" />
|
||
|
|
<span>View object lifecycle</span>
|
||
|
|
</DropdownMenuItem>
|
||
|
|
<DropdownMenuItem>
|
||
|
|
<LuTrash2 className="mr-2 size-4" />
|
||
|
|
<span>Delete</span>
|
||
|
|
</DropdownMenuItem>
|
||
|
|
</DropdownMenuContent>
|
||
|
|
</DropdownMenu>
|
||
|
|
</div>
|
||
|
|
</>
|
||
|
|
);
|
||
|
|
}
|