Improve desktop timeline view (#9150)

* Break apart mobile and desktop timeline views

* Set aspect ratio for player correctly

* more modest default width

* Add timeline item card

* Get video player to fit

* get layout going

* More work on youtube view

* Get video scaling working

* Better dialog sizes

* Show all timelines for day

* Add full day of timelines

* Improve hooks

* Fix previews

* Separate mobile and desktop views and don't rerender

* cleanup

* Optimizations and improvements

* make preview dates more efficient

* Remove seekbar and use timeline as seekbar

* Improve background and scrubbing
This commit is contained in:
Nicolas Mowen
2024-01-01 09:37:07 -06:00
committed by Blake Blackshear
parent 0ee81c7526
commit 160e331035
10 changed files with 663 additions and 88 deletions

View File

@@ -1,5 +1,5 @@
import strftime from 'strftime';
import { fromUnixTime, intervalToDuration, formatDuration } from 'date-fns';
import strftime from "strftime";
import { fromUnixTime, intervalToDuration, formatDuration } from "date-fns";
export const longToDate = (long: number): Date => new Date(long * 1000);
export const epochToLong = (date: number): number => date / 1000;
export const dateToLong = (date: Date): number => epochToLong(date.getTime());
@@ -276,3 +276,12 @@ const getUTCOffset = (date: Date, timezone: string): number => {
return (target.getTime() - utcDate.getTime()) / 60 / 1000;
};
export function getRangeForTimestamp(timestamp: number) {
const date = new Date(timestamp * 1000);
date.setMinutes(0, 0, 0);
const start = date.getTime() / 1000;
date.setHours(date.getHours() + 1);
const end = date.getTime() / 1000;
return { start, end };
}

View File

@@ -4,7 +4,7 @@ const GROUP_SECONDS = 60;
export function getHourlyTimelineData(
timelinePages: HourlyTimeline[],
detailLevel: string
) {
): CardsData {
const cards: CardsData = {};
timelinePages.forEach((hourlyTimeline) => {
Object.keys(hourlyTimeline["hours"])
@@ -101,3 +101,83 @@ export function getHourlyTimelineData(
return cards;
}
export function getTimelineHoursForDay(
camera: string,
cards: CardsData,
allPreviews: Preview[],
timestamp: number
): TimelinePlayback[] {
const now = new Date();
const data: TimelinePlayback[] = [];
const startDay = new Date(timestamp * 1000);
startDay.setHours(23, 59, 59, 999);
const dayEnd = startDay.getTime() / 1000;
startDay.setHours(0, 0, 0, 0);
let start = startDay.getTime() / 1000;
let end = 0;
const relevantPreviews = allPreviews.filter((preview) => {
return (
preview.camera == camera &&
preview.start >= start &&
Math.floor(preview.end - 1) <= dayEnd
);
});
const dayIdx = Object.keys(cards).find((day) => {
if (parseInt(day) > start) {
return false;
}
return true;
});
if (dayIdx == undefined) {
return [];
}
const day = cards[dayIdx];
for (let i = 0; i < 24; i++) {
startDay.setHours(startDay.getHours() + 1);
if (startDay > now) {
break;
}
end = startDay.getTime() / 1000;
const hour = Object.values(day).find((cards) => {
if (
Object.values(cards)[0].time < start ||
Object.values(cards)[0].time > end
) {
return false;
}
return true;
});
const timelineItems: Timeline[] = hour
? Object.values(hour).flatMap((card) => {
if (card.camera == camera) {
return card.entries;
}
return [];
})
: [];
const relevantPreview = relevantPreviews.find(
(preview) =>
Math.round(preview.start) >= start && Math.floor(preview.end) <= end
);
data.push({
camera,
range: { start, end },
timelineItems,
relevantPreview,
});
start = startDay.getTime() / 1000;
}
return data.reverse();
}