import { baseUrl } from "@/api/baseUrl"; import ExportCard from "@/components/card/ExportCard"; import VideoPlayer from "@/components/player/VideoPlayer"; import { AlertDialog, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { Button } from "@/components/ui/button"; import { Calendar } from "@/components/ui/calendar"; import { Card } from "@/components/ui/card"; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { DropdownMenuRadioGroup, DropdownMenuTrigger, DropdownMenu, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuRadioItem, } from "@/components/ui/dropdown-menu"; import Heading from "@/components/ui/heading"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { FrigateConfig } from "@/types/frigateConfig"; import axios from "axios"; import { format } from "date-fns"; import { useCallback, useState } from "react"; import { DateRange } from "react-day-picker"; import useSWR from "swr"; type ExportItem = { name: string; }; function Export() { const { data: config } = useSWR("config"); const { data: exports, mutate } = useSWR( "exports/", (url: string) => axios({ baseURL: baseUrl, url }).then((res) => res.data) ); // Export States const [camera, setCamera] = useState(); const [playback, setPlayback] = useState(); const [message, setMessage] = useState({ text: "", error: false }); const currentDate = new Date(); currentDate.setHours(0, 0, 0, 0); const [date, setDate] = useState({ from: currentDate, }); const [startTime, setStartTime] = useState("00:00:00"); const [endTime, setEndTime] = useState("23:59:59"); const [selectedClip, setSelectedClip] = useState(); const [deleteClip, setDeleteClip] = useState(); const onHandleExport = () => { if (camera == "select") { setMessage({ text: "A camera needs to be selected.", error: true }); return; } if (playback == "select") { setMessage({ text: "A playback factor needs to be selected.", error: true, }); return; } if (!date?.from || !startTime || !endTime) { setMessage({ text: "A start and end time needs to be selected", error: true, }); return; } const startDate = new Date(date.from.getTime()); const [startHour, startMin, startSec] = startTime.split(":"); startDate.setHours( parseInt(startHour), parseInt(startMin), parseInt(startSec), 0 ); const start = startDate.getTime() / 1000; const endDate = new Date((date.to || date.from).getTime()); const [endHour, endMin, endSec] = endTime.split(":"); endDate.setHours(parseInt(endHour), parseInt(endMin), parseInt(endSec), 0); const end = endDate.getTime() / 1000; if (end <= start) { setMessage({ text: "The end time must be after the start time.", error: true, }); return; } axios .post(`export/${camera}/start/${start}/end/${end}`, { playback }) .then((response) => { if (response.status == 200) { setMessage({ text: "Successfully started export. View the file in the /exports folder.", error: false, }); } mutate(); }) .catch((error) => { if (error.response?.data?.message) { setMessage({ text: `Failed to start export: ${error.response.data.message}`, error: true, }); } else { setMessage({ text: `Failed to start export: ${error.message}`, error: true, }); } }); }; const onHandleDelete = useCallback(() => { if (!deleteClip) { return; } axios.delete(`export/${deleteClip}`).then((response) => { if (response.status == 200) { setDeleteClip(undefined); mutate(); } }); }, [deleteClip]); return ( <> Export {message.text && (
{message.text}
)} setDeleteClip(undefined)} > Delete Export Confirm deletion of {deleteClip}. Cancel setSelectedClip(undefined)} > Playback
Select A Camera {Object.keys(config?.cameras || {}).map((item) => ( {item.replaceAll("_", " ")} ))}
Select A Playback Factor Realtime Timelapse
setStartTime(e.target.value)} /> setEndTime(e.target.value)} />
{exports && ( Exports {Object.values(exports).map((item) => ( setSelectedClip(file)} onDelete={(file) => setDeleteClip(file)} /> ))} )}
); } export default Export;