From 680740031445d2c86c23cc44ea1f7d498483f8bb Mon Sep 17 00:00:00 2001 From: Nick Mowen Date: Sat, 30 Dec 2023 11:03:43 -0700 Subject: [PATCH] Break apart mobile and desktop timeline views --- web/src/views/history/HistoryTimelineView.tsx | 226 +++++++++++++++++- 1 file changed, 216 insertions(+), 10 deletions(-) diff --git a/web/src/views/history/HistoryTimelineView.tsx b/web/src/views/history/HistoryTimelineView.tsx index a892f8e9d..3dc7370a7 100644 --- a/web/src/views/history/HistoryTimelineView.tsx +++ b/web/src/views/history/HistoryTimelineView.tsx @@ -11,7 +11,13 @@ import { getTimelineIcon, } from "@/utils/timelineUtil"; import { renderToStaticMarkup } from "react-dom/server"; -import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import React, { + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from "react"; import useSWR from "swr"; import Player from "video.js/dist/types/player"; @@ -177,6 +183,83 @@ export default function HistoryTimelineView({ return ; } + if (isMobile) { + return ( + + ); + } + + return ( + + ); +} + +type DesktopViewProps = { + config: FrigateConfig; + playerRef: React.MutableRefObject; + previewRef: React.MutableRefObject; + playback: TimelinePlayback; + playbackUri: string; + playbackTimes: { start: number; end: number }; + timelineTime: number; + hasRelevantPreview: boolean; + scrubbing: boolean; + focusedItem: Timeline | undefined; + setFocusedItem: (item: Timeline | undefined) => void; + setSeeking: (seeking: boolean) => void; + onSelectItem: ({ items }: { items: number[] }) => void; + onScrubTime: ({ time }: { time: Date }) => void; + onStopScrubbing: ({ time }: { time: Date }) => void; +}; +function DesktopView({ + config, + playerRef, + previewRef, + playback, + playbackUri, + playbackTimes, + timelineTime, + hasRelevantPreview, + scrubbing, + focusedItem, + setFocusedItem, + setSeeking, + onSelectItem, + onScrubTime, + onStopScrubbing, +}: DesktopViewProps) { return (
<> @@ -254,18 +337,141 @@ export default function HistoryTimelineView({ : [] } options={{ - ...(isMobile && { - start: new Date( - Math.max(playbackTimes.start, timelineTime - 300) * 1000 - ), - end: new Date( - Math.min(playbackTimes.end, timelineTime + 300) * 1000 - ), - }), snap: null, min: new Date(playbackTimes.start * 1000), max: new Date(playbackTimes.end * 1000), - timeAxis: isMobile ? { scale: "minute", step: 5 } : {}, + }} + timechangeHandler={onScrubTime} + timechangedHandler={onStopScrubbing} + selectHandler={onSelectItem} + /> + )} +
+ + ); +} + +type MobileViewProps = { + config: FrigateConfig; + playerRef: React.MutableRefObject; + previewRef: React.MutableRefObject; + playback: TimelinePlayback; + playbackUri: string; + playbackTimes: { start: number; end: number }; + timelineTime: number; + hasRelevantPreview: boolean; + scrubbing: boolean; + focusedItem: Timeline | undefined; + setFocusedItem: (item: Timeline | undefined) => void; + setSeeking: (seeking: boolean) => void; + onSelectItem: ({ items }: { items: number[] }) => void; + onScrubTime: ({ time }: { time: Date }) => void; + onStopScrubbing: ({ time }: { time: Date }) => void; +}; +function MobileView({ + config, + playerRef, + previewRef, + playback, + playbackUri, + playbackTimes, + timelineTime, + hasRelevantPreview, + scrubbing, + focusedItem, + setFocusedItem, + setSeeking, + onSelectItem, + onScrubTime, + onStopScrubbing, +}: MobileViewProps) { + return ( +
+ <> +
+ { + playerRef.current = player; + player.currentTime(timelineTime - playbackTimes.start); + player.on("playing", () => { + setFocusedItem(undefined); + }); + }} + onDispose={() => { + playerRef.current = undefined; + }} + > + {config && focusedItem ? ( + + ) : undefined} + +
+ {hasRelevantPreview && ( +
+ { + previewRef.current = player; + player.on("seeked", () => setSeeking(false)); + }} + onDispose={() => { + previewRef.current = undefined; + }} + /> +
+ )} + +
+ {playback != undefined && ( +