diff --git a/frigate/timeline.py b/frigate/timeline.py
index 927fd6845..39cb6cf03 100644
--- a/frigate/timeline.py
+++ b/frigate/timeline.py
@@ -85,12 +85,13 @@ class TimelineProcessor(threading.Thread):
"""Handle object detection."""
save = False
camera_config = self.config.cameras[camera]
+ event_id = event_data["id"]
timeline_entry = {
Timeline.timestamp: event_data["frame_time"],
Timeline.camera: camera,
Timeline.source: "tracked_object",
- Timeline.source_id: event_data["id"],
+ Timeline.source_id: event_id,
Timeline.data: {
"box": to_relative_box(
camera_config.detect.width,
@@ -107,6 +108,23 @@ class TimelineProcessor(threading.Thread):
"attribute": "",
},
}
+
+ # make sure all timeline items have a sub label
+ if prev_event_data != None and prev_event_data.get(
+ "sub_label"
+ ) != event_data.get("sub_label"):
+ # update existing timeline items to have sub label
+ sub_label = event_data["sub_label"]
+
+ if sub_label[0] not in ALL_ATTRIBUTE_LABELS:
+ if event_id in self.pre_event_cache.keys():
+ for e in self.pre_event_cache[event_id]:
+ e[Timeline.data]["sub_label"] = sub_label
+ else:
+ Timeline.update(
+ data=Timeline.data.update({"sub_label": sub_label})
+ ).where(Timeline.source_id == event_id).execute()
+
if event_type == "start":
timeline_entry[Timeline.class_type] = "visible"
save = True
@@ -129,13 +147,6 @@ class TimelineProcessor(threading.Thread):
event_data["attributes"].keys()
)[0]
save = True
- elif not prev_event_data.get("sub_label") and event_data.get("sub_label"):
- sub_label = event_data["sub_label"][0]
-
- if sub_label not in ALL_ATTRIBUTE_LABELS:
- timeline_entry[Timeline.class_type] = "sub_label"
- timeline_entry[Timeline.data]["sub_label"] = sub_label
- save = True
elif event_type == "end":
timeline_entry[Timeline.class_type] = "gone"
save = True
diff --git a/web/src/components/player/PreviewThumbnailPlayer.tsx b/web/src/components/player/PreviewThumbnailPlayer.tsx
index 267d8a404..f35ab0dcc 100644
--- a/web/src/components/player/PreviewThumbnailPlayer.tsx
+++ b/web/src/components/player/PreviewThumbnailPlayer.tsx
@@ -52,7 +52,10 @@ export default function PreviewThumbnailPlayer({
}
if (!playerRef.current) {
- setIsInitiallyVisible(true);
+ if (isHovered) {
+ setIsInitiallyVisible(true);
+ }
+
return;
}
@@ -103,7 +106,7 @@ export default function PreviewThumbnailPlayer({
{
threshold: 1.0,
root: document.getElementById("pageRoot"),
- rootMargin: "-15% 0px -15% 0px",
+ rootMargin: "-10% 0px -25% 0px",
}
);
if (node) autoPlayObserver.current.observe(node);
diff --git a/web/src/types/history.ts b/web/src/types/history.ts
index 989df3b2f..189a8d0b9 100644
--- a/web/src/types/history.ts
+++ b/web/src/types/history.ts
@@ -36,7 +36,6 @@ type Timeline = {
class_type:
| "visible"
| "gone"
- | "sub_label"
| "entered_zone"
| "attribute"
| "active"
diff --git a/web/src/utils/timelineUtil.tsx b/web/src/utils/timelineUtil.tsx
index 1820df5f5..483d63231 100644
--- a/web/src/utils/timelineUtil.tsx
+++ b/web/src/utils/timelineUtil.tsx
@@ -42,15 +42,6 @@ export function getTimelineIcon(timelineItem: Timeline) {
default:
return ;
}
- case "sub_label":
- switch (timelineItem.data.label) {
- case "person":
- return ;
- case "car":
- return ;
- default:
- return ;
- }
case "heard":
return ;
case "external":
@@ -119,8 +110,6 @@ export function getTimelineItemDescription(timelineItem: Timeline) {
}
return title;
}
- case "sub_label":
- return `${timelineItem.data.label} recognized as ${timelineItem.data.sub_label}`;
case "gone":
return `${label} left`;
case "heard":
diff --git a/web/src/views/history/DesktopTimelineView.tsx b/web/src/views/history/DesktopTimelineView.tsx
index e7acb76c0..e210aef0f 100644
--- a/web/src/views/history/DesktopTimelineView.tsx
+++ b/web/src/views/history/DesktopTimelineView.tsx
@@ -123,7 +123,7 @@ export default function DesktopTimelineView({
const timelineTime = useMemo(() => {
if (scrubbing) {
- return playerTime;
+ return selectedPlayback.range.start + playerTime;
} else {
// take a player time in seconds and convert to timestamp in timeline
let timestamp = 0;
@@ -395,11 +395,10 @@ export default function DesktopTimelineView({
setTimeToSeek(Math.round(seekTime));
}}
timechangedHandler={(data) => {
- const playbackTime = data.time.getTime() / 1000;
- playerRef.current?.currentTime(
- playbackTime - timeline.range.start
- );
setScrubbing(false);
+ const playbackTime =
+ data.time.getTime() / 1000 - timeline.range.start;
+ playerRef.current?.currentTime(playbackTime);
playerRef.current?.play();
}}
selectHandler={(data) => {