diff --git a/web/src/components/card/HistoryCard.tsx b/web/src/components/card/HistoryCard.tsx
index ccacefa20..114eb1976 100644
--- a/web/src/components/card/HistoryCard.tsx
+++ b/web/src/components/card/HistoryCard.tsx
@@ -47,7 +47,7 @@ export default function HistoryCard({
{formatUnixTimestampToDateTime(timeline.time, {
strftime_fmt:
- config.ui.time_format == "24hour" ? "%H:%M:%S" : "%I:%M:%S",
+ config.ui.time_format == "24hour" ? "%H:%M:%S" : "%I:%M:%S %p",
time_style: "medium",
date_style: "medium",
})}
diff --git a/web/src/components/player/PreviewThumbnailPlayer.tsx b/web/src/components/player/PreviewThumbnailPlayer.tsx
index 39f651fad..5ecd871c7 100644
--- a/web/src/components/player/PreviewThumbnailPlayer.tsx
+++ b/web/src/components/player/PreviewThumbnailPlayer.tsx
@@ -105,7 +105,10 @@ export default function PreviewThumbnailPlayer({
);
let content;
- if (!relevantPreview || !visible) {
+
+ if (relevantPreview && !visible) {
+ content =
;
+ } else if (!relevantPreview) {
if (isCurrentHour(startTs)) {
content = (
{
- Object.keys(hourlyTimeline["hours"])
- .reverse()
- .forEach((hour) => {
- const day = new Date(parseInt(hour) * 1000);
- day.setHours(0, 0, 0, 0);
- const dayKey = (day.getTime() / 1000).toString();
- const source_to_types: { [key: string]: string[] } = {};
- Object.values(hourlyTimeline["hours"][hour]).forEach((i) => {
- const time = new Date(i.timestamp * 1000);
- time.setSeconds(0);
- time.setMilliseconds(0);
- const key = `${i.source_id}-${time.getMinutes()}`;
- if (key in source_to_types) {
- source_to_types[key].push(i.class_type);
- } else {
- source_to_types[key] = [i.class_type];
- }
- });
-
- if (!Object.keys(cards).includes(dayKey)) {
- cards[dayKey] = {};
- }
- cards[dayKey][hour] = {};
- Object.values(hourlyTimeline["hours"][hour]).forEach((i) => {
- const time = new Date(i.timestamp * 1000);
- const key = `${i.camera}-${time.getMinutes()}`;
-
- // detail level for saving items
- // detail level determines which timeline items for each moment is returned
- // values can be normal, extra, or full
- // normal: return all items except active / attribute / gone / stationary / visible unless that is the only item.
- // extra: return all items except attribute / gone / visible unless that is the only item
- // full: return all items
-
- let add = true;
- if (detailLevel == "normal") {
- if (
- source_to_types[`${i.source_id}-${time.getMinutes()}`].length >
- 1 &&
- [
- "active",
- "attribute",
- "gone",
- "stationary",
- "visible",
- ].includes(i.class_type)
- ) {
- add = false;
- }
- } else if (detailLevel == "extra") {
- if (
- source_to_types[`${i.source_id}-${time.getMinutes()}`].length >
- 1 &&
- i.class_type in ["attribute", "gone", "visible"]
- ) {
- add = false;
- }
- }
-
- if (add) {
- if (key in cards[dayKey][hour]) {
- cards[dayKey][hour][key].entries.push(i);
- } else {
- cards[dayKey][hour][key] = {
- camera: i.camera,
- time: time.getTime() / 1000,
- entries: [i],
- };
- }
- }
- });
- });
- });
-
- return cards;
+ return getHourlyTimelineData(timelinePages, detailLevel);
}, [detailLevel, timelinePages]);
const isDone =
@@ -206,7 +131,10 @@ function History() {
{formatUnixTimestampToDateTime(parseInt(hour), {
- strftime_fmt: "%I:00",
+ strftime_fmt:
+ config.ui.time_format == "24hour"
+ ? "%H:00"
+ : "%I:00 %p",
time_style: "medium",
date_style: "medium",
})}
@@ -229,6 +157,7 @@ function History() {
preview.end > startTs
);
}
+
return (
{
+ Object.keys(hourlyTimeline["hours"])
+ .reverse()
+ .forEach((hour) => {
+ const day = new Date(parseInt(hour) * 1000);
+ day.setHours(0, 0, 0, 0);
+ const dayKey = (day.getTime() / 1000).toString();
+ const source_to_types: { [key: string]: string[] } = {};
+ Object.values(hourlyTimeline["hours"][hour]).forEach((i) => {
+ const time = new Date(i.timestamp * 1000);
+ time.setSeconds(0);
+ time.setMilliseconds(0);
+ const key = `${i.source_id}-${time.getMinutes()}`;
+ if (key in source_to_types) {
+ source_to_types[key].push(i.class_type);
+ } else {
+ source_to_types[key] = [i.class_type];
+ }
+ });
+
+ if (!Object.keys(cards).includes(dayKey)) {
+ cards[dayKey] = {};
+ }
+ cards[dayKey][hour] = {};
+ Object.values(hourlyTimeline["hours"][hour]).forEach((i) => {
+ const time = new Date(i.timestamp * 1000);
+ const minuteKey = `${i.camera}-${time.getMinutes()}`;
+ const uniqueKey = `${i.source_id}-${i.class_type}`;
+
+ // detail level for saving items
+ // detail level determines which timeline items for each moment is returned
+ // values can be normal, extra, or full
+ // normal: return all items except active / attribute / gone / stationary / visible unless that is the only item.
+ // extra: return all items except attribute / gone / visible unless that is the only item
+ // full: return all items
+
+ let add = true;
+ if (detailLevel == "normal") {
+ if (
+ source_to_types[`${i.source_id}-${time.getMinutes()}`].length >
+ 1 &&
+ ["active", "attribute", "gone", "stationary", "visible"].includes(
+ i.class_type
+ )
+ ) {
+ add = false;
+ }
+ } else if (detailLevel == "extra") {
+ if (
+ source_to_types[`${i.source_id}-${time.getMinutes()}`].length >
+ 1 &&
+ i.class_type in ["attribute", "gone", "visible"]
+ ) {
+ add = false;
+ }
+ }
+
+ if (add) {
+ if (minuteKey in cards[dayKey][hour]) {
+ if (
+ !cards[dayKey][hour][minuteKey].uniqueKeys.includes(
+ uniqueKey
+ ) ||
+ detailLevel == "full"
+ ) {
+ cards[dayKey][hour][minuteKey].entries.push(i);
+ cards[dayKey][hour][minuteKey].uniqueKeys.push(uniqueKey);
+ }
+ } else {
+ cards[dayKey][hour][minuteKey] = {
+ camera: i.camera,
+ time: time.getTime() / 1000,
+ entries: [i],
+ uniqueKeys: [uniqueKey],
+ };
+ }
+ }
+ });
+ });
+ });
+
+ return cards;
+}