Fix thumbnails for recordings.

This commit is contained in:
Dermot Duffy
2022-09-22 17:44:43 -07:00
parent eb88c6e0e0
commit f11822fc87
4 changed files with 63 additions and 40 deletions
+6 -5
View File
@@ -175,19 +175,20 @@ export class FrigateCardSurround extends LitElement {
) => {
const child: FrigateBrowseMediaSource | null =
ev.detail.target?.children?.[ev.detail.childIndex] ?? null;
// Send the view change from the source of the tap event, so the
// view change will be caught by the handler above (to close the drawer).
if (child) {
this.view
?.evolve({
view: this.view.is('recording') ? 'recording' : 'media',
target: ev.detail.target,
childIndex: ev.detail.childIndex,
context: null,
...(child?.frigate?.cameraID && {
camera: child?.frigate?.cameraID,
...(child.frigate?.cameraID && {
camera: child.frigate?.cameraID,
}),
})
.removeContext('timeline')
// Send the view change from the source of the tap event, so
// the view change will be caught by the handler above (to
// close the drawer).
.dispatchChangeEvent(ev.composedPath()[0]);
}
}}
+3
View File
@@ -303,6 +303,9 @@ export class FrigateCardThumbnail extends LitElement {
.removeContext('timeline')
.dispatchChangeEvent(this);
} else if (recording) {
// Specifically reset the media target/childIndex, as we cannot
// 'select' an hour in the timeline rather we set the window to
// matching values.
this.view
?.evolve({
view: 'timeline',
+49 -30
View File
@@ -40,6 +40,7 @@ import {
FrigateBrowseMediaSource,
frigateCardConfigDefaults,
FrigateEvent,
FrigateRecording,
TimelineCoreConfig,
} from '../types';
import { stopEventFromActivatingCardWideActions } from '../utils/action';
@@ -65,7 +66,7 @@ import {
} from '../utils/timeline-data-manager';
import { View } from '../view';
import { dispatchMessageEvent } from './message.js';
import "./thumbnail.js";
import './thumbnail.js';
interface FrigateCardGroupData {
id: string;
@@ -557,7 +558,7 @@ export class FrigateCardTimelineCore extends LitElement {
childIndex: childIndex,
}),
})
.mergeInContext({ ...this._generateTimelineContext(true), ...context })
.mergeInContext({ ...this._generateTimelineContext(), ...context })
.dispatchChangeEvent(this);
}
}
@@ -567,7 +568,7 @@ export class FrigateCardTimelineCore extends LitElement {
* seek times into each media item).
* @param children The media children.
* @param targetTime The target time.
* @returns
* @returns The ViewContext.
*/
protected _generateMediaViewerContextForChildren(
children: FrigateBrowseMediaSource[],
@@ -696,9 +697,9 @@ export class FrigateCardTimelineCore extends LitElement {
childIndex = thumbnails.childIndex;
if (thumbnails.target?.children?.length) {
context = this._generateMediaViewerContextForChildren(
thumbnails.target.children,
properties.time,
);
thumbnails.target.children,
properties.time,
);
}
}
} else {
@@ -771,7 +772,7 @@ export class FrigateCardTimelineCore extends LitElement {
target: thumbnails?.target ?? null,
childIndex: thumbnails?.childIndex ?? null,
})
.mergeInContext(this._generateTimelineContext(true))
.mergeInContext(this._generateTimelineContext())
.dispatchChangeEvent(this);
}
});
@@ -874,6 +875,15 @@ export class FrigateCardTimelineCore extends LitElement {
];
}
/**
* Given a recording get the start/end window.
* @param recording The FrigateRecording to consider.
* @returns A tuple of start/end date.
*/
protected _getStartEndFromRecording(recording: FrigateRecording): [Date, Date] {
return [fromUnixTime(recording.start_time), fromUnixTime(recording.end_time)];
}
/**
* Get the configured window length in seconds.
*/
@@ -1004,8 +1014,12 @@ export class FrigateCardTimelineCore extends LitElement {
}
const event = this.view?.media?.frigate?.event;
const recording = this.view?.media?.frigate?.recording;
const [windowStart, windowEnd] = event
? this._getStartEndFromEvent(event)
: recording
? this._getStartEndFromRecording(recording)
: this._getStartEnd();
let fetched = false;
@@ -1042,33 +1056,40 @@ export class FrigateCardTimelineCore extends LitElement {
this.timelineDataManager?.rewriteItem(event.id);
}
let contextWindow: TimelineWindow | null = null;
if (!this._pointerHeld) {
// Regenerate the thumbnails after the selection, to allow the new selection
// to be in the generated view.
const context = this.view.context?.timeline;
const timelineWindow = this._timeline.getWindow();
if (context?.window) {
if (!isEqual(context.window, timelineWindow)) {
this._timeline.setWindow(context.window.start, context.window.end);
}
} else if (event) {
const eventStart = new Date(event.start_time * 1000);
const eventEnd = event.end_time ? new Date(event.end_time * 1000) : 0;
// If there's a set context window, always move to it.
if (context?.window && !isEqual(context.window, timelineWindow)) {
contextWindow = {start: context.window.start, end: context.window.end};
} else if (event || recording) {
const source = event ?? recording as FrigateEvent | FrigateRecording;
const start = fromUnixTime(source.start_time);
const end = source.end_time ? fromUnixTime(source.end_time) : 0;
// If there's an event or recording outside the current window, move to it.
if (
eventStart < timelineWindow.start ||
eventStart > timelineWindow.end ||
(eventEnd &&
(eventEnd < timelineWindow.start || eventEnd > timelineWindow.end))
start < timelineWindow.start ||
start > timelineWindow.end ||
(end &&
(end < timelineWindow.start || end > timelineWindow.end))
) {
this._timeline.setWindow(windowStart, windowEnd);
contextWindow = {start: windowStart, end: windowEnd};
}
} else {
this._timeline.setWindow(windowStart, windowEnd);
// Otherwise just the default window.
contextWindow = {start: windowStart, end: windowEnd};
}
}
if (contextWindow) {
this._timeline.setWindow(contextWindow.start, contextWindow.end);
}
// Only generate thumbnails if an actual fetch occurred, to avoid getting
// stuck in a loop (the subsequent fetches will not actually fetch since the
// data will have been cached).
@@ -1078,15 +1099,17 @@ export class FrigateCardTimelineCore extends LitElement {
// -> Thumbnails generated
// -> New view dispatched (to load thumbnails into outer carousel).
// -> New view received ... [loop]
if ((fetched || !this.view.context?.timeline?.generatedThumbnails) && !this.mini) {
//
// Also don't generate thumbnails in mini-timelines (they will already have
// been generated), or if the media child is a recording.
if ((fetched || !this.view.context?.timeline?.generatedThumbnails) && !this.mini && !recording) {
const thumbnails = this._generateThumbnails();
this.view
?.evolve({
target: thumbnails?.target ?? null,
childIndex: thumbnails?.childIndex ?? null,
})
.mergeInContext(this._generateTimelineContext(false))
.mergeInContext(this._generateTimelineContext(contextWindow))
.dispatchChangeEvent(this);
}
}
@@ -1097,16 +1120,12 @@ export class FrigateCardTimelineCore extends LitElement {
* the window is preserved if it is already in the context.
* @returns The TimelineViewContext object.
*/
protected _generateTimelineContext(addWindow: boolean): ViewContext {
const currentContext = this.view?.context?.timeline;
protected _generateTimelineContext(window?: TimelineWindow | null): ViewContext {
const newContext: TimelineViewContext = {
generatedThumbnails: true,
};
if (addWindow && this._timeline) {
newContext.window = this._timeline.getWindow();
} else if (currentContext?.window) {
newContext.window = currentContext.window;
if (this._timeline) {
newContext.window = window ? window : this._timeline.getWindow();
}
if (this.timelineDataManager?.lastFetchDate) {
newContext.dateFetch = this.timelineDataManager.lastFetchDate;
+5 -5
View File
@@ -161,11 +161,11 @@
"thumbnails": {
"mode": "Media Viewer thumbnails mode",
"modes": {
"above": "Thumbnails above the media",
"below": "Thumbnails below the media",
"left": "Thumbnails in a drawer left of the media",
"above": "Thumbnails above",
"below": "Thumbnails below",
"left": "Thumbnails in a drawer to the left",
"none": "No thumbnails",
"right": "Thumbnails in a drawer right of the media"
"right": "Thumbnails in a drawer to the right"
},
"show_details": "Show details with thumbnails",
"show_favorite_control": "Show favorite control on thumbnails",
@@ -372,7 +372,7 @@
"thumbnail": {
"no_thumbnail": "No thumbnail available",
"retain_indefinitely": "Event will be indefinitely retained",
"timeline": "See event in timeline"
"timeline": "See event/recording in timeline"
},
"timeline": {
"lock": "Lock timeline to a single event",