)}
- {!playingBack &&
- (review.severity == "alert" || review.severity == "detection") && (
-
- {review.data.objects.map((object) => {
- return getIconForLabel(object, "w-3 h-3 text-white");
- })}
- {review.data.audio.map((audio) => {
- return getIconForLabel(audio, "w-3 h-3 text-white");
- })}
- {review.data.sub_labels?.map((sub) => {
- return getIconForSubLabel(sub, "w-3 h-3 text-white");
- })}
-
- )}
+ {(review.severity == "alert" || review.severity == "detection") && (
+
+ {review.data.objects.map((object) => {
+ return getIconForLabel(object, "w-3 h-3 text-white");
+ })}
+ {review.data.audio.map((audio) => {
+ return getIconForLabel(audio, "w-3 h-3 text-white");
+ })}
+ {review.data.sub_labels?.map((sub) => {
+ return getIconForSubLabel(sub, "w-3 h-3 text-white");
+ })}
+
+ )}
{!playingBack && (
-
+
{config &&
formatUnixTimestampToDateTime(review.start_time, {
strftime_fmt:
@@ -184,6 +185,26 @@ function PreviewContent({
setProgress,
setReviewed,
}: PreviewContentProps) {
+ // manual playback
+ // safari is incapable of playing at a speed > 2x
+ // so manual seeking is required on iOS
+
+ const [manualPlayback, setManualPlayback] = useState(false);
+ useEffect(() => {
+ if (!manualPlayback || !playerRef.current) {
+ return;
+ }
+
+ const intervalId: NodeJS.Timeout = setInterval(() => {
+ if (playerRef.current) {
+ playerRef.current.currentTime(playerRef.current.currentTime()!! + 1);
+ }
+ }, 125);
+ return () => clearInterval(intervalId);
+ }, [manualPlayback, playerRef]);
+
+ // preview
+
if (relevantPreview && playback) {
return (
{
- if (!setProgress || playerRef.current?.paused()) {
+ if (!setProgress) {
return;
}
@@ -242,6 +269,7 @@ function PreviewContent({
if (playerPercent > 100) {
playerRef.current?.pause();
+ setManualPlayback(false);
setProgress(100.0);
} else {
setProgress(playerPercent);
diff --git a/web/src/views/events/DesktopEventView.tsx b/web/src/views/events/DesktopEventView.tsx
index 78e42e450..ddf3c0aea 100644
--- a/web/src/views/events/DesktopEventView.tsx
+++ b/web/src/views/events/DesktopEventView.tsx
@@ -116,6 +116,16 @@ export default function DesktopEventView() {
[reviewPages]
);
+ const currentItems = useMemo(() => {
+ const current = reviewItems[severity];
+
+ if (!current || current.length == 0) {
+ return null;
+ }
+
+ return current;
+ }, [reviewItems, severity]);
+
// review interaction
const pagingObserver = useRef();
@@ -244,8 +254,6 @@ export default function DesktopEventView() {
return ;
}
- console.log("end of the timeline is " + after + " vs " + (Math.floor(Date.now() / 1000) + 2 * 60 * 60))
-
return (
@@ -303,68 +311,57 @@ export default function DesktopEventView() {
ref={contentRef}
className="absolute left-0 top-12 bottom-0 right-28 flex flex-wrap content-start gap-2 overflow-y-auto no-scrollbar"
>
- {reviewItems[severity]?.map((value, segIdx) => {
- const lastRow = segIdx == reviewItems[severity].length - 1;
- const relevantPreview = Object.values(allPreviews || []).find(
- (preview) =>
- preview.camera == value.camera &&
- preview.start < value.start_time &&
- preview.end > value.end_time
- );
+ {currentItems ? (
+ currentItems.map((value, segIdx) => {
+ const lastRow = segIdx == reviewItems[severity].length - 1;
+ const relevantPreview = Object.values(allPreviews || []).find(
+ (preview) =>
+ preview.camera == value.camera &&
+ preview.start < value.start_time &&
+ preview.end > value.end_time
+ );
- return (
-
-
-
setReviewed(value.id)}
- />
+ return (
+
+
+
setReviewed(value.id)}
+ />
+
+ {lastRow && !isDone &&
}
- {lastRow && !isDone && }
-
- );
- })}
+ );
+ })
+ ) : (
+
+ )}
- {after != 0 && ()}
+ {after != 0 && (
+
+ )}
);
}
-/**
- *
- */
-
function ReviewCalendarButton() {
const disabledDates = useMemo(() => {
const tomorrow = new Date();
diff --git a/web/src/views/events/MobileEventView.tsx b/web/src/views/events/MobileEventView.tsx
index eb4c9fb29..c48d5f4b0 100644
--- a/web/src/views/events/MobileEventView.tsx
+++ b/web/src/views/events/MobileEventView.tsx
@@ -106,6 +106,16 @@ export default function MobileEventView() {
[reviewPages]
);
+ const currentItems = useMemo(() => {
+ const current = reviewItems[severity];
+
+ if (!current || current.length == 0) {
+ return null;
+ }
+
+ return current;
+ }, [reviewItems, severity]);
+
// review interaction
const pagingObserver = useRef
();
@@ -278,33 +288,37 @@ export default function MobileEventView() {
ref={contentRef}
className="w-full h-full grid grid-cols-1 sm:grid-cols-2 mt-2 gap-2 overflow-y-auto"
>
- {reviewItems[severity]?.map((value, segIdx) => {
- const lastRow = segIdx == reviewItems[severity].length - 1;
- const relevantPreview = Object.values(allPreviews || []).find(
- (preview) =>
- preview.camera == value.camera &&
- preview.start < value.start_time &&
- preview.end > value.end_time
- );
+ {currentItems ? (
+ currentItems.map((value, segIdx) => {
+ const lastRow = segIdx == reviewItems[severity].length - 1;
+ const relevantPreview = Object.values(allPreviews || []).find(
+ (preview) =>
+ preview.camera == value.camera &&
+ preview.start < value.start_time &&
+ preview.end > value.end_time
+ );
- return (
-
-
-
setReviewed(value.id)}
- />
+ return (
+
+
+
setReviewed(value.id)}
+ />
+
+ {lastRow && !isDone &&
}
- {lastRow && !isDone && }
-
- );
- })}
+ );
+ })
+ ) : (
+
+ )}
>
);