forked from Github/frigate
Improve thumbnails and live player (#9828)
* Don't show gif until event is over and fix aspect * Be more efficient about updating events * ensure previews are sorted * Don't show live view when window is not visible * Move debug camera to separate view * Improve jpg loading * Ensure still is updated on player live finish * Don't reload when window not visible * Only disconnect instead of full remove * Use start time instead of event over to determine gif
This commit is contained in:
@@ -1,22 +1,46 @@
|
||||
import { useFrigateEvents } from "@/api/ws";
|
||||
import { AnimatedEventThumbnail } from "@/components/image/AnimatedEventThumbnail";
|
||||
import LivePlayer from "@/components/player/LivePlayer";
|
||||
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { Event as FrigateEvent } from "@/types/event";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import { useMemo } from "react";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import useSWR from "swr";
|
||||
|
||||
function Live() {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
|
||||
// recent events
|
||||
|
||||
const { data: allEvents } = useSWR<FrigateEvent[]>(
|
||||
const { payload: eventUpdate } = useFrigateEvents();
|
||||
const { data: allEvents, mutate: updateEvents } = useSWR<FrigateEvent[]>(
|
||||
["events", { limit: 10 }],
|
||||
{ refreshInterval: 60000 }
|
||||
{ revalidateOnFocus: false }
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!eventUpdate) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if event is ended and was saved, update events list
|
||||
if (
|
||||
eventUpdate.type == "end" &&
|
||||
(eventUpdate.after.has_clip || eventUpdate.after.has_snapshot)
|
||||
) {
|
||||
updateEvents();
|
||||
return;
|
||||
}
|
||||
|
||||
// if event is updated and has become a saved event, update events list
|
||||
if (
|
||||
!(eventUpdate.before.has_clip || eventUpdate.before.has_snapshot) &&
|
||||
(eventUpdate.after.has_clip || eventUpdate.after.has_snapshot)
|
||||
) {
|
||||
updateEvents();
|
||||
}
|
||||
}, [eventUpdate]);
|
||||
|
||||
const events = useMemo(() => {
|
||||
if (!allEvents) {
|
||||
return [];
|
||||
@@ -40,6 +64,19 @@ function Live() {
|
||||
.sort((aConf, bConf) => aConf.ui.order - bConf.ui.order);
|
||||
}, [config]);
|
||||
|
||||
const [windowVisible, setWindowVisible] = useState(true);
|
||||
const visibilityListener = useCallback(() => {
|
||||
setWindowVisible(document.visibilityState == "visible");
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
addEventListener("visibilitychange", visibilityListener);
|
||||
|
||||
return () => {
|
||||
removeEventListener("visibilitychange", visibilityListener);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
{events && events.length > 0 && (
|
||||
@@ -62,7 +99,7 @@ function Live() {
|
||||
if (aspectRatio > 2) {
|
||||
grow = "md:col-span-2 aspect-wide";
|
||||
} else if (aspectRatio < 1) {
|
||||
grow = `md:row-span-2 aspect-[8/9] md:h-full`;
|
||||
grow = `md:row-span-2 aspect-tall md:h-full`;
|
||||
} else {
|
||||
grow = "aspect-video";
|
||||
}
|
||||
@@ -70,6 +107,7 @@ function Live() {
|
||||
<LivePlayer
|
||||
key={camera.name}
|
||||
className={`mb-2 md:mb-0 rounded-2xl bg-black ${grow}`}
|
||||
windowVisible={windowVisible}
|
||||
cameraConfig={camera}
|
||||
preferredLiveMode="mse"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user