Improve graph using pandas (#9234)

* Ensure viewport is always full screen

* Protect against hour with no cards and ensure data is consistent

* Reduce grouped up image refreshes

* Include current hour and fix scrubbing bugginess

* Scroll initially selected timeline in to view

* Expand timelne class type

* Use poster image for preview on video player instead of using separate image view

* Fix available streaming modes

* Incrase timing for grouping timline items

* Fix audio activity listener

* Fix player not switching views correctly

* Use player time to convert to timeline time

* Update sub labels for previous timeline items

* Show mini timeline bar for non selected items

* Rewrite desktop timeline to use separate dynamic video player component

* Extend improvements to mobile as well

* Improve time formatting

* Fix scroll

* Fix no preview case

* Mobile fixes

* Audio toggle fixes

* More fixes for mobile

* Improve scaling of graph motion activity

* Add keyboard shortcut hook and support shortcuts for playback page

* Fix sizing of dialog

* Improve height scaling of dialog

* simplify and fix layout system for timeline

* Fix timeilne items not working

* Implement basic Frigate+ submitting from timeline
This commit is contained in:
Nicolas Mowen
2024-01-31 05:29:18 -07:00
committed by Blake Blackshear
parent 9c4b69191b
commit af3f6dadcb
28 changed files with 1379 additions and 852 deletions

View File

@@ -1,11 +1,15 @@
import { useCallback, useEffect, useState } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { AspectRatio } from "../ui/aspect-ratio";
import CameraImage from "./CameraImage";
import { LuEar } from "react-icons/lu";
import { CameraConfig } from "@/types/frigateConfig";
import { TbUserScan } from "react-icons/tb";
import { MdLeakAdd } from "react-icons/md";
import { useFrigateEvents, useMotionActivity } from "@/api/ws";
import {
useAudioActivity,
useFrigateEvents,
useMotionActivity,
} from "@/api/ws";
type DynamicCameraImageProps = {
camera: CameraConfig;
@@ -21,10 +25,14 @@ export default function DynamicCameraImage({
}: DynamicCameraImageProps) {
const [key, setKey] = useState(Date.now());
const [activeObjects, setActiveObjects] = useState<string[]>([]);
const hasActiveObjects = useMemo(
() => activeObjects.length > 0,
[activeObjects]
);
const { payload: detectingMotion } = useMotionActivity(camera.name);
const { payload: event } = useFrigateEvents();
const { payload: audioRms } = useMotionActivity(camera.name);
const { payload: audioRms } = useAudioActivity(camera.name);
useEffect(() => {
if (!event) {
@@ -50,7 +58,6 @@ export default function DynamicCameraImage({
if (eventIndex == -1) {
const newActiveObjects = [...activeObjects, event.after.id];
setActiveObjects(newActiveObjects);
setKey(Date.now());
}
}
}
@@ -58,8 +65,9 @@ export default function DynamicCameraImage({
const handleLoad = useCallback(() => {
const loadTime = Date.now() - key;
const loadInterval =
activeObjects.length > 0 ? INTERVAL_ACTIVE_MS : INTERVAL_INACTIVE_MS;
const loadInterval = hasActiveObjects
? INTERVAL_ACTIVE_MS
: INTERVAL_INACTIVE_MS;
setTimeout(
() => {
@@ -67,7 +75,7 @@ export default function DynamicCameraImage({
},
loadTime > loadInterval ? 1 : loadInterval
);
}, [activeObjects, key]);
}, [key]);
return (
<AspectRatio
@@ -91,7 +99,7 @@ export default function DynamicCameraImage({
activeObjects.length > 0 ? "text-object" : "text-gray-600"
}`}
/>
{camera.audio.enabled && (
{camera.audio.enabled_in_config && (
<LuEar
className={`${
parseInt(audioRms) >= camera.audio.min_volume