Fix thumbnails for recordings.
This commit is contained in:
@@ -175,19 +175,20 @@ export class FrigateCardSurround extends LitElement {
|
|||||||
) => {
|
) => {
|
||||||
const child: FrigateBrowseMediaSource | null =
|
const child: FrigateBrowseMediaSource | null =
|
||||||
ev.detail.target?.children?.[ev.detail.childIndex] ?? 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) {
|
if (child) {
|
||||||
this.view
|
this.view
|
||||||
?.evolve({
|
?.evolve({
|
||||||
view: this.view.is('recording') ? 'recording' : 'media',
|
view: this.view.is('recording') ? 'recording' : 'media',
|
||||||
target: ev.detail.target,
|
target: ev.detail.target,
|
||||||
childIndex: ev.detail.childIndex,
|
childIndex: ev.detail.childIndex,
|
||||||
context: null,
|
...(child.frigate?.cameraID && {
|
||||||
...(child?.frigate?.cameraID && {
|
camera: 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]);
|
.dispatchChangeEvent(ev.composedPath()[0]);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -303,6 +303,9 @@ export class FrigateCardThumbnail extends LitElement {
|
|||||||
.removeContext('timeline')
|
.removeContext('timeline')
|
||||||
.dispatchChangeEvent(this);
|
.dispatchChangeEvent(this);
|
||||||
} else if (recording) {
|
} 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
|
this.view
|
||||||
?.evolve({
|
?.evolve({
|
||||||
view: 'timeline',
|
view: 'timeline',
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import {
|
|||||||
FrigateBrowseMediaSource,
|
FrigateBrowseMediaSource,
|
||||||
frigateCardConfigDefaults,
|
frigateCardConfigDefaults,
|
||||||
FrigateEvent,
|
FrigateEvent,
|
||||||
|
FrigateRecording,
|
||||||
TimelineCoreConfig,
|
TimelineCoreConfig,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { stopEventFromActivatingCardWideActions } from '../utils/action';
|
import { stopEventFromActivatingCardWideActions } from '../utils/action';
|
||||||
@@ -65,7 +66,7 @@ import {
|
|||||||
} from '../utils/timeline-data-manager';
|
} from '../utils/timeline-data-manager';
|
||||||
import { View } from '../view';
|
import { View } from '../view';
|
||||||
import { dispatchMessageEvent } from './message.js';
|
import { dispatchMessageEvent } from './message.js';
|
||||||
import "./thumbnail.js";
|
import './thumbnail.js';
|
||||||
|
|
||||||
interface FrigateCardGroupData {
|
interface FrigateCardGroupData {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -557,7 +558,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
childIndex: childIndex,
|
childIndex: childIndex,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
.mergeInContext({ ...this._generateTimelineContext(true), ...context })
|
.mergeInContext({ ...this._generateTimelineContext(), ...context })
|
||||||
.dispatchChangeEvent(this);
|
.dispatchChangeEvent(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -567,7 +568,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
* seek times into each media item).
|
* seek times into each media item).
|
||||||
* @param children The media children.
|
* @param children The media children.
|
||||||
* @param targetTime The target time.
|
* @param targetTime The target time.
|
||||||
* @returns
|
* @returns The ViewContext.
|
||||||
*/
|
*/
|
||||||
protected _generateMediaViewerContextForChildren(
|
protected _generateMediaViewerContextForChildren(
|
||||||
children: FrigateBrowseMediaSource[],
|
children: FrigateBrowseMediaSource[],
|
||||||
@@ -771,7 +772,7 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
target: thumbnails?.target ?? null,
|
target: thumbnails?.target ?? null,
|
||||||
childIndex: thumbnails?.childIndex ?? null,
|
childIndex: thumbnails?.childIndex ?? null,
|
||||||
})
|
})
|
||||||
.mergeInContext(this._generateTimelineContext(true))
|
.mergeInContext(this._generateTimelineContext())
|
||||||
.dispatchChangeEvent(this);
|
.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.
|
* Get the configured window length in seconds.
|
||||||
*/
|
*/
|
||||||
@@ -1004,8 +1014,12 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const event = this.view?.media?.frigate?.event;
|
const event = this.view?.media?.frigate?.event;
|
||||||
|
const recording = this.view?.media?.frigate?.recording;
|
||||||
|
|
||||||
const [windowStart, windowEnd] = event
|
const [windowStart, windowEnd] = event
|
||||||
? this._getStartEndFromEvent(event)
|
? this._getStartEndFromEvent(event)
|
||||||
|
: recording
|
||||||
|
? this._getStartEndFromRecording(recording)
|
||||||
: this._getStartEnd();
|
: this._getStartEnd();
|
||||||
|
|
||||||
let fetched = false;
|
let fetched = false;
|
||||||
@@ -1042,33 +1056,40 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
this.timelineDataManager?.rewriteItem(event.id);
|
this.timelineDataManager?.rewriteItem(event.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let contextWindow: TimelineWindow | null = null;
|
||||||
if (!this._pointerHeld) {
|
if (!this._pointerHeld) {
|
||||||
// Regenerate the thumbnails after the selection, to allow the new selection
|
// Regenerate the thumbnails after the selection, to allow the new selection
|
||||||
// to be in the generated view.
|
// to be in the generated view.
|
||||||
const context = this.view.context?.timeline;
|
const context = this.view.context?.timeline;
|
||||||
const timelineWindow = this._timeline.getWindow();
|
const timelineWindow = this._timeline.getWindow();
|
||||||
|
|
||||||
if (context?.window) {
|
// If there's a set context window, always move to it.
|
||||||
if (!isEqual(context.window, timelineWindow)) {
|
if (context?.window && !isEqual(context.window, timelineWindow)) {
|
||||||
this._timeline.setWindow(context.window.start, context.window.end);
|
contextWindow = {start: context.window.start, end: context.window.end};
|
||||||
}
|
} else if (event || recording) {
|
||||||
} else if (event) {
|
const source = event ?? recording as FrigateEvent | FrigateRecording;
|
||||||
const eventStart = new Date(event.start_time * 1000);
|
const start = fromUnixTime(source.start_time);
|
||||||
const eventEnd = event.end_time ? new Date(event.end_time * 1000) : 0;
|
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 (
|
if (
|
||||||
eventStart < timelineWindow.start ||
|
start < timelineWindow.start ||
|
||||||
eventStart > timelineWindow.end ||
|
start > timelineWindow.end ||
|
||||||
(eventEnd &&
|
(end &&
|
||||||
(eventEnd < timelineWindow.start || eventEnd > timelineWindow.end))
|
(end < timelineWindow.start || end > timelineWindow.end))
|
||||||
) {
|
) {
|
||||||
this._timeline.setWindow(windowStart, windowEnd);
|
contextWindow = {start: windowStart, end: windowEnd};
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
// Only generate thumbnails if an actual fetch occurred, to avoid getting
|
||||||
// stuck in a loop (the subsequent fetches will not actually fetch since the
|
// stuck in a loop (the subsequent fetches will not actually fetch since the
|
||||||
// data will have been cached).
|
// data will have been cached).
|
||||||
@@ -1078,15 +1099,17 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
// -> Thumbnails generated
|
// -> Thumbnails generated
|
||||||
// -> New view dispatched (to load thumbnails into outer carousel).
|
// -> New view dispatched (to load thumbnails into outer carousel).
|
||||||
// -> New view received ... [loop]
|
// -> 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();
|
const thumbnails = this._generateThumbnails();
|
||||||
this.view
|
this.view
|
||||||
?.evolve({
|
?.evolve({
|
||||||
target: thumbnails?.target ?? null,
|
target: thumbnails?.target ?? null,
|
||||||
childIndex: thumbnails?.childIndex ?? null,
|
childIndex: thumbnails?.childIndex ?? null,
|
||||||
})
|
})
|
||||||
.mergeInContext(this._generateTimelineContext(false))
|
.mergeInContext(this._generateTimelineContext(contextWindow))
|
||||||
.dispatchChangeEvent(this);
|
.dispatchChangeEvent(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1097,16 +1120,12 @@ export class FrigateCardTimelineCore extends LitElement {
|
|||||||
* the window is preserved if it is already in the context.
|
* the window is preserved if it is already in the context.
|
||||||
* @returns The TimelineViewContext object.
|
* @returns The TimelineViewContext object.
|
||||||
*/
|
*/
|
||||||
protected _generateTimelineContext(addWindow: boolean): ViewContext {
|
protected _generateTimelineContext(window?: TimelineWindow | null): ViewContext {
|
||||||
const currentContext = this.view?.context?.timeline;
|
|
||||||
const newContext: TimelineViewContext = {
|
const newContext: TimelineViewContext = {
|
||||||
generatedThumbnails: true,
|
generatedThumbnails: true,
|
||||||
};
|
};
|
||||||
|
if (this._timeline) {
|
||||||
if (addWindow && this._timeline) {
|
newContext.window = window ? window : this._timeline.getWindow();
|
||||||
newContext.window = this._timeline.getWindow();
|
|
||||||
} else if (currentContext?.window) {
|
|
||||||
newContext.window = currentContext.window;
|
|
||||||
}
|
}
|
||||||
if (this.timelineDataManager?.lastFetchDate) {
|
if (this.timelineDataManager?.lastFetchDate) {
|
||||||
newContext.dateFetch = this.timelineDataManager.lastFetchDate;
|
newContext.dateFetch = this.timelineDataManager.lastFetchDate;
|
||||||
|
|||||||
@@ -161,11 +161,11 @@
|
|||||||
"thumbnails": {
|
"thumbnails": {
|
||||||
"mode": "Media Viewer thumbnails mode",
|
"mode": "Media Viewer thumbnails mode",
|
||||||
"modes": {
|
"modes": {
|
||||||
"above": "Thumbnails above the media",
|
"above": "Thumbnails above",
|
||||||
"below": "Thumbnails below the media",
|
"below": "Thumbnails below",
|
||||||
"left": "Thumbnails in a drawer left of the media",
|
"left": "Thumbnails in a drawer to the left",
|
||||||
"none": "No thumbnails",
|
"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_details": "Show details with thumbnails",
|
||||||
"show_favorite_control": "Show favorite control on thumbnails",
|
"show_favorite_control": "Show favorite control on thumbnails",
|
||||||
@@ -372,7 +372,7 @@
|
|||||||
"thumbnail": {
|
"thumbnail": {
|
||||||
"no_thumbnail": "No thumbnail available",
|
"no_thumbnail": "No thumbnail available",
|
||||||
"retain_indefinitely": "Event will be indefinitely retained",
|
"retain_indefinitely": "Event will be indefinitely retained",
|
||||||
"timeline": "See event in timeline"
|
"timeline": "See event/recording in timeline"
|
||||||
},
|
},
|
||||||
"timeline": {
|
"timeline": {
|
||||||
"lock": "Lock timeline to a single event",
|
"lock": "Lock timeline to a single event",
|
||||||
|
|||||||
Reference in New Issue
Block a user