mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-07 11:45:24 +03:00
Show all timelines for day
This commit is contained in:
parent
cd4882d1e0
commit
c879c353af
@ -101,3 +101,26 @@ export function getHourlyTimelineData(
|
|||||||
|
|
||||||
return cards;
|
return cards;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getTimelineHoursForDay(timestamp: number) {
|
||||||
|
const now = new Date();
|
||||||
|
const data = [];
|
||||||
|
const startDay = new Date(timestamp * 1000);
|
||||||
|
startDay.setHours(0, 0, 0, 0);
|
||||||
|
let start = startDay.getTime() / 1000;
|
||||||
|
let end = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
startDay.setHours(startDay.getHours() + 1);
|
||||||
|
|
||||||
|
if (startDay > now) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = startDay.getTime() / 1000;
|
||||||
|
data.push({ start, end });
|
||||||
|
start = startDay.getTime() / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.reverse();
|
||||||
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import React, {
|
|||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import Player from "video.js/dist/types/player";
|
import Player from "video.js/dist/types/player";
|
||||||
import TimelineItemCard from "@/components/card/TimelineItemCard";
|
import TimelineItemCard from "@/components/card/TimelineItemCard";
|
||||||
|
import { getTimelineHoursForDay } from "@/utils/historyUtil";
|
||||||
|
|
||||||
type HistoryTimelineViewProps = {
|
type HistoryTimelineViewProps = {
|
||||||
playback: TimelinePlayback;
|
playback: TimelinePlayback;
|
||||||
@ -255,6 +256,9 @@ function DesktopView({
|
|||||||
onScrubTime,
|
onScrubTime,
|
||||||
onStopScrubbing,
|
onStopScrubbing,
|
||||||
}: DesktopViewProps) {
|
}: DesktopViewProps) {
|
||||||
|
const timelineStack =
|
||||||
|
playback == undefined ? [] : getTimelineHoursForDay(timelineTime);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
@ -297,32 +301,32 @@ function DesktopView({
|
|||||||
</VideoPlayer>
|
</VideoPlayer>
|
||||||
</div>
|
</div>
|
||||||
{hasRelevantPreview && (
|
{hasRelevantPreview && (
|
||||||
<div className={`w-full ${scrubbing ? "visible" : "hidden"}`}>
|
<div className={`w-full ${scrubbing ? "visible" : "hidden"}`}>
|
||||||
<VideoPlayer
|
<VideoPlayer
|
||||||
options={{
|
options={{
|
||||||
preload: "auto",
|
preload: "auto",
|
||||||
autoplay: false,
|
autoplay: false,
|
||||||
controls: false,
|
controls: false,
|
||||||
muted: true,
|
muted: true,
|
||||||
loadingSpinner: false,
|
loadingSpinner: false,
|
||||||
sources: [
|
sources: [
|
||||||
{
|
{
|
||||||
src: `${playback.relevantPreview?.src}`,
|
src: `${playback.relevantPreview?.src}`,
|
||||||
type: "video/mp4",
|
type: "video/mp4",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}}
|
}}
|
||||||
seekOptions={{}}
|
seekOptions={{}}
|
||||||
onReady={(player) => {
|
onReady={(player) => {
|
||||||
previewRef.current = player;
|
previewRef.current = player;
|
||||||
player.on("seeked", () => setSeeking(false));
|
player.on("seeked", () => setSeeking(false));
|
||||||
}}
|
}}
|
||||||
onDispose={() => {
|
onDispose={() => {
|
||||||
previewRef.current = undefined;
|
previewRef.current = undefined;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
<div className="px-2 h-[608px] overflow-auto">
|
<div className="px-2 h-[608px] overflow-auto">
|
||||||
@ -338,34 +342,42 @@ function DesktopView({
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="m-1">
|
<div className="m-1 max-h-96 overflow-auto">
|
||||||
{playback != undefined && (
|
{timelineStack.map((range) => {
|
||||||
<ActivityScrubber
|
const isSelected = timelineTime > range.start && timelineTime < range.end;
|
||||||
items={[]}
|
|
||||||
timeBars={
|
return (
|
||||||
hasRelevantPreview
|
<div className={`${isSelected ? "border border-primary" : ""}`}>
|
||||||
? [{ time: new Date(timelineTime * 1000), id: "playback" }]
|
<ActivityScrubber
|
||||||
: []
|
key={range.start}
|
||||||
}
|
items={[]}
|
||||||
options={{
|
timeBars={
|
||||||
snap: null,
|
hasRelevantPreview
|
||||||
min: new Date(playbackTimes.start * 1000),
|
? [{ time: new Date(timelineTime * 1000), id: "playback" }]
|
||||||
max: new Date(playbackTimes.end * 1000),
|
: []
|
||||||
}}
|
|
||||||
timechangeHandler={onScrubTime}
|
|
||||||
timechangedHandler={onStopScrubbing}
|
|
||||||
selectHandler={(data) => {
|
|
||||||
if (data.items.length > 0) {
|
|
||||||
const selected = data.items[0];
|
|
||||||
onSelectItem(
|
|
||||||
playback.timelineItems.find(
|
|
||||||
(timeline) => timeline.timestamp == selected
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}}
|
options={{
|
||||||
/>
|
snap: null,
|
||||||
)}
|
min: new Date(range.start * 1000),
|
||||||
|
max: new Date(range.end * 1000),
|
||||||
|
zoomable: false,
|
||||||
|
}}
|
||||||
|
timechangeHandler={onScrubTime}
|
||||||
|
timechangedHandler={onStopScrubbing}
|
||||||
|
selectHandler={(data) => {
|
||||||
|
if (data.items.length > 0) {
|
||||||
|
const selected = data.items[0];
|
||||||
|
onSelectItem(
|
||||||
|
playback.timelineItems.find(
|
||||||
|
(timeline) => timeline.timestamp == selected
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user