mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-15 07:35:27 +03:00
add export preview dialog
This commit is contained in:
parent
238e489f55
commit
caa70b3e50
@ -2,6 +2,7 @@ import { useCallback, useMemo, useState } from "react";
|
|||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
DialogFooter,
|
DialogFooter,
|
||||||
DialogHeader,
|
DialogHeader,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
@ -22,10 +23,13 @@ import { FrigateConfig } from "@/types/frigateConfig";
|
|||||||
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
|
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
|
||||||
import { TimezoneAwareCalendar } from "./ReviewActivityCalendar";
|
import { TimezoneAwareCalendar } from "./ReviewActivityCalendar";
|
||||||
import { SelectSeparator } from "../ui/select";
|
import { SelectSeparator } from "../ui/select";
|
||||||
import { isDesktop, isIOS } from "react-device-detect";
|
import { isDesktop, isIOS, isMobile } from "react-device-detect";
|
||||||
import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer";
|
import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer";
|
||||||
import SaveExportOverlay from "./SaveExportOverlay";
|
import SaveExportOverlay from "./SaveExportOverlay";
|
||||||
import { getUTCOffset } from "@/utils/dateUtil";
|
import { getUTCOffset } from "@/utils/dateUtil";
|
||||||
|
import { baseUrl } from "@/api/baseUrl";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import { GenericVideoPlayer } from "../player/GenericVideoPlayer";
|
||||||
|
|
||||||
const EXPORT_OPTIONS = [
|
const EXPORT_OPTIONS = [
|
||||||
"1",
|
"1",
|
||||||
@ -44,8 +48,10 @@ type ExportDialogProps = {
|
|||||||
currentTime: number;
|
currentTime: number;
|
||||||
range?: TimeRange;
|
range?: TimeRange;
|
||||||
mode: ExportMode;
|
mode: ExportMode;
|
||||||
|
showPreview: boolean;
|
||||||
setRange: (range: TimeRange | undefined) => void;
|
setRange: (range: TimeRange | undefined) => void;
|
||||||
setMode: (mode: ExportMode) => void;
|
setMode: (mode: ExportMode) => void;
|
||||||
|
setShowPreview: (showPreview: boolean) => void;
|
||||||
};
|
};
|
||||||
export default function ExportDialog({
|
export default function ExportDialog({
|
||||||
camera,
|
camera,
|
||||||
@ -53,10 +59,13 @@ export default function ExportDialog({
|
|||||||
currentTime,
|
currentTime,
|
||||||
range,
|
range,
|
||||||
mode,
|
mode,
|
||||||
|
showPreview,
|
||||||
setRange,
|
setRange,
|
||||||
setMode,
|
setMode,
|
||||||
|
setShowPreview,
|
||||||
}: ExportDialogProps) {
|
}: ExportDialogProps) {
|
||||||
const [name, setName] = useState("");
|
const [name, setName] = useState("");
|
||||||
|
|
||||||
const onStartExport = useCallback(() => {
|
const onStartExport = useCallback(() => {
|
||||||
if (!range) {
|
if (!range) {
|
||||||
toast.error("No valid time range selected", { position: "top-center" });
|
toast.error("No valid time range selected", { position: "top-center" });
|
||||||
@ -109,9 +118,16 @@ export default function ExportDialog({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<ExportPreviewDialog
|
||||||
|
camera={camera}
|
||||||
|
range={range}
|
||||||
|
showPreview={showPreview}
|
||||||
|
setShowPreview={setShowPreview}
|
||||||
|
/>
|
||||||
<SaveExportOverlay
|
<SaveExportOverlay
|
||||||
className="pointer-events-none absolute left-1/2 top-8 z-50 -translate-x-1/2"
|
className="pointer-events-none absolute left-1/2 top-8 z-50 -translate-x-1/2"
|
||||||
show={mode == "timeline"}
|
show={mode == "timeline"}
|
||||||
|
onPreview={() => setShowPreview(true)}
|
||||||
onSave={() => onStartExport()}
|
onSave={() => onStartExport()}
|
||||||
onCancel={() => setMode("none")}
|
onCancel={() => setMode("none")}
|
||||||
/>
|
/>
|
||||||
@ -525,3 +541,44 @@ function CustomTimeSelector({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ExportPreviewDialogProps = {
|
||||||
|
camera: string;
|
||||||
|
range?: TimeRange;
|
||||||
|
showPreview: boolean;
|
||||||
|
setShowPreview: (showPreview: boolean) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function ExportPreviewDialog({
|
||||||
|
camera,
|
||||||
|
range,
|
||||||
|
showPreview,
|
||||||
|
setShowPreview,
|
||||||
|
}: ExportPreviewDialogProps) {
|
||||||
|
if (!range) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const source = `${baseUrl}vod/${camera}/start/${range.after}/end/${range.before}/index.m3u8`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={showPreview} onOpenChange={setShowPreview}>
|
||||||
|
<DialogContent
|
||||||
|
className={cn(
|
||||||
|
"scrollbar-container overflow-y-auto",
|
||||||
|
isDesktop &&
|
||||||
|
"max-h-[95dvh] sm:max-w-xl md:max-w-4xl lg:max-w-4xl xl:max-w-7xl",
|
||||||
|
isMobile && "px-4",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Preview Export</DialogTitle>
|
||||||
|
<DialogDescription className="sr-only">
|
||||||
|
Preview Export
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<GenericVideoPlayer source={source} />
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user