import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuPortal,
DropdownMenuSeparator,
} from "@/components/ui/dropdown-menu";
import { HiDotsHorizontal } from "react-icons/hi";
import { useApiHost } from "@/api";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { Event } from "@/types/event";
import { FrigateConfig } from "@/types/frigateConfig";
import { useCallback, useState } from "react";
import { useIsAdmin } from "@/hooks/use-is-admin";
import axios from "axios";
import { toast } from "sonner";
import { Button } from "../ui/button";
type EventMenuProps = {
event: Event;
config?: FrigateConfig;
onOpenUpload?: (e: Event) => void;
onOpenSimilarity?: (e: Event) => void;
isSelected?: boolean;
onToggleSelection?: (event: Event | undefined) => void;
};
export default function EventMenu({
event,
config,
onOpenUpload,
onOpenSimilarity,
isSelected = false,
onToggleSelection,
}: EventMenuProps) {
const apiHost = useApiHost();
const navigate = useNavigate();
const { t } = useTranslation(["views/explore", "views/replay"]);
const [isOpen, setIsOpen] = useState(false);
const isAdmin = useIsAdmin();
const [isStarting, setIsStarting] = useState(false);
const handleObjectSelect = () => {
if (isSelected) {
onToggleSelection?.(undefined);
} else {
onToggleSelection?.(event);
}
};
const handleDebugReplay = useCallback(
(event: Event) => {
setIsStarting(true);
axios
.post("debug_replay/start", {
camera: event.camera,
start_time: event.start_time,
end_time: event.end_time,
})
.then((response) => {
if (response.status === 200) {
toast.success(t("dialog.toast.success", { ns: "views/replay" }), {
position: "top-center",
});
navigate("/replay");
}
})
.catch((error) => {
const errorMessage =
error.response?.data?.message ||
error.response?.data?.detail ||
"Unknown error";
if (error.response?.status === 409) {
toast.error(
t("dialog.toast.alreadyActive", { ns: "views/replay" }),
{
position: "top-center",
closeButton: true,
dismissible: false,
action: (
),
},
);
} else {
toast.error(t("dialog.toast.error", { error: errorMessage }), {
position: "top-center",
});
}
})
.finally(() => {
setIsStarting(false);
});
},
[navigate, t],
);
return (
<>
{isSelected
? t("itemMenu.hideObjectDetails.label")
: t("itemMenu.showObjectDetails.label")}
{
navigate(`/explore?event_id=${event.id}`);
}}
>
{t("details.item.button.viewInExplore")}
{t("itemMenu.downloadSnapshot.label")}
{isAdmin &&
event.has_snapshot &&
event.plus_id == undefined &&
event.data.type == "object" &&
config?.plus?.enabled && (
{
setIsOpen(false);
onOpenUpload?.(event);
}}
>
{t("itemMenu.submitToPlus.label")}
)}
{event.has_snapshot && config?.semantic_search?.enabled && (
{
if (onOpenSimilarity) onOpenSimilarity(event);
else
navigate(
`/explore?search_type=similarity&event_id=${event.id}`,
);
}}
>
{t("itemMenu.findSimilar.label")}
)}
{event.has_clip && (
{
handleDebugReplay(event);
}}
>
{isStarting
? t("dialog.starting", { ns: "views/replay" })
: t("itemMenu.debugReplay.label")}
)}
>
);
}