Change handler methods to async for cleanliness.

This commit is contained in:
Dermot Duffy
2023-01-24 19:36:54 -08:00
parent 5385d4d5fd
commit 962311f241
2 changed files with 58 additions and 76 deletions
+51 -68
View File
@@ -435,7 +435,7 @@ export class FrigateCardTimelineCore extends LitElement {
* Called whenever the timeline is clicked. * Called whenever the timeline is clicked.
* @param properties The properties of the timeline click event. * @param properties The properties of the timeline click event.
*/ */
protected _timelineClickHandler(properties: TimelineEventPropertiesResult): void { protected async _timelineClickHandler(properties: TimelineEventPropertiesResult): Promise<void> {
// Calls to stopEventFromActivatingCardWideActions() are included for // Calls to stopEventFromActivatingCardWideActions() are included for
// completeness. Timeline does not support card-wide events and they are // completeness. Timeline does not support card-wide events and they are
// disabled in card.ts in `_getMergedActions`. // disabled in card.ts in `_getMergedActions`.
@@ -459,13 +459,13 @@ export class FrigateCardTimelineCore extends LitElement {
return; return;
} }
let viewPromise: Promise<View | null> | null = null; let view: View | null = null;
if ( if (
this.timelineConfig?.show_recordings && this.timelineConfig?.show_recordings &&
['background', 'group-label'].includes(properties.what) ['background', 'group-label'].includes(properties.what)
) { ) {
viewPromise = createViewForRecordings( view = await createViewForRecordings(
this.hass, this.hass,
this.cameraManager, this.cameraManager,
this.cameras, this.cameras,
@@ -481,7 +481,7 @@ export class FrigateCardTimelineCore extends LitElement {
}, },
); );
} else if (this.timelineConfig?.show_recordings && properties.what === 'axis') { } else if (this.timelineConfig?.show_recordings && properties.what === 'axis') {
viewPromise = createViewForRecordings( view = await createViewForRecordings(
this.hass, this.hass,
this.cameraManager, this.cameraManager,
this.cameras, this.cameras,
@@ -498,24 +498,18 @@ export class FrigateCardTimelineCore extends LitElement {
properties.what === 'item' && properties.what === 'item' &&
this.view.query?.areRecordingQueries() this.view.query?.areRecordingQueries()
) { ) {
viewPromise = (async (): Promise<View | null> => { const eventView = await this._createViewWithEventMediaQuery(
if (!properties.item || !this.cameraManager || !this.hass) { this._createEventMediaQuerys(),
return null; {
} selectedItem: properties.item,
const view = await this._createViewWithEventMediaQuery( targetView: 'media',
this._createEventMediaQuerys(), },
{ );
selectedItem: properties.item, const results = eventView?.queryResults?.getResults();
targetView: 'media', // Specifically ensure there are _some_ results before dispatching the
}, // view change.
); if (eventView && results && results.length) {
const results = view?.queryResults?.getResults(); eventView.mergeInContext(
// Specifically ensure there are _some_ results before dispatching the
// view change.
if (!view || !results || !results.length) {
return null;
}
view.mergeInContext(
await generateMediaViewerContext( await generateMediaViewerContext(
this.hass, this.hass,
this.cameraManager, this.cameraManager,
@@ -523,18 +517,15 @@ export class FrigateCardTimelineCore extends LitElement {
properties.time, properties.time,
), ),
); );
return view; view = eventView;
})(); }
} else if ( } else if (
properties.item && properties.item &&
properties.what === 'item' && properties.what === 'item' &&
this.view.queryResults?.hasResults() this.view.queryResults?.hasResults() &&
this.view.query
) { ) {
viewPromise = (async (): Promise<View | null> => { view = this.view.evolve({
if (!this.view?.query) {
return null;
}
return this.view.evolve({
queryResults: this.view.queryResults queryResults: this.view.queryResults
?.clone() ?.clone()
.resetSelectedResult() .resetSelectedResult()
@@ -544,24 +535,18 @@ export class FrigateCardTimelineCore extends LitElement {
media.getID(this.cameras.get(media.getCameraID())) === properties.item, media.getID(this.cameras.get(media.getCameraID())) === properties.item,
), ),
}); });
})();
} }
if (viewPromise) { if (view) {
viewPromise.then((view: View | null) => { view
if (view) { // If the user is clicking something in the timeline, don't
view // subsequently shift the window (it's pretty jarring).
// If the user is clicking something in the timeline, don't .mergeInContext(this._generateTimelineContext({ noSetWindow: true }))
// subsequently shift the window (it's pretty jarring). .dispatchChangeEvent(this);
.mergeInContext(this._generateTimelineContext({ noSetWindow: true }))
.dispatchChangeEvent(this); if (this.view?.is('timeline')) {
if (this.view?.is('timeline')) { dispatchFrigateCardEvent(this, 'thumbnails:open');
dispatchFrigateCardEvent(this, 'thumbnails:open'); }
}
this._ignoreClick = false;
return;
}
});
} else if (this.view?.is('timeline')) { } else if (this.view?.is('timeline')) {
dispatchFrigateCardEvent(this, 'thumbnails:close'); dispatchFrigateCardEvent(this, 'thumbnails:close');
} }
@@ -586,39 +571,37 @@ export class FrigateCardTimelineCore extends LitElement {
* Handle a range change in the timeline. * Handle a range change in the timeline.
* @param properties vis.js provided range information. * @param properties vis.js provided range information.
*/ */
protected _timelineRangeChangedHandler(properties: { protected async _timelineRangeChangedHandler(properties: {
start: Date; start: Date;
end: Date; end: Date;
byUser: boolean; byUser: boolean;
event: Event & { additionalEvent: string }; event: Event & { additionalEvent: string };
}): void { }): Promise<void> {
if (!properties.byUser) { if (!properties.byUser) {
return; return;
} }
this._removeTargetBar(); this._removeTargetBar();
(async (): Promise<void> => { if (!this.hass || !this.cameras) {
if (!this.hass || !this.cameras) { return;
return; }
}
const prefetchedWindow = this._getPrefetchWindow(properties); const prefetchedWindow = this._getPrefetchWindow(properties);
await this._timelineSource?.refresh(this.hass, this.cameras, prefetchedWindow); await this._timelineSource?.refresh(this.hass, this.cameras, prefetchedWindow);
// Don't show event thumbnails if the user is looking at recordings, // Don't show event thumbnails if the user is looking at recordings,
// as the recording "hours" are the media, not the event // as the recording "hours" are the media, not the event
// clips/snapshots. // clips/snapshots.
if (this._timeline && this.view && !this.view.query?.areRecordingQueries()) { if (this._timeline && this.view && !this.view.query?.areRecordingQueries()) {
( (
await this._createViewWithEventMediaQuery( await this._createViewWithEventMediaQuery(
this._createEventMediaQuerys({ window: prefetchedWindow }), this._createEventMediaQuerys({ window: prefetchedWindow }),
{ {
noSetWindow: true, noSetWindow: true,
}, },
) )
)?.dispatchChangeEvent(this); )?.dispatchChangeEvent(this);
} }
})();
} }
protected _createEventMediaQuerys(options?: { protected _createEventMediaQuerys(options?: {
+7 -8
View File
@@ -1,5 +1,4 @@
// Easy: // Easy:
// - TODO: Search for references to frigate.js and see where it's being called outside of the cameraManager. Can I collapse some of those functions in?
// - TODO: Refactor thumbnailsControlSchema to all use the shortform for other thumbnail users beyond live. // - TODO: Refactor thumbnailsControlSchema to all use the shortform for other thumbnail users beyond live.
// - TODO: limit param in recordings should do something // - TODO: limit param in recordings should do something
// - TODO: Should be able to set live media to 'all' and have it work. // - TODO: Should be able to set live media to 'all' and have it work.
@@ -7,15 +6,15 @@
// - TODO: In MediaQueriesBase, do we need to generic? Just have T be a MediaQuery? // - TODO: In MediaQueriesBase, do we need to generic? Just have T be a MediaQuery?
// - TODO: Are areEventQueries and areRecordingQueries should be in a classifier to keep with the pattern used elsewhere. // - TODO: Are areEventQueries and areRecordingQueries should be in a classifier to keep with the pattern used elsewhere.
// - TODO: In the viewer @click handlers should I use this.selected instead of calling carouselScrollPrevious() // - TODO: In the viewer @click handlers should I use this.selected instead of calling carouselScrollPrevious()
// - TODO: Can _timelineClickHandler be an async method in timeline-core to improve cleanliness?
// - TODO: Can _timelineRangeChangedHandler be an async method in timeline-core to improve cleanliness?
// Medium: // Medium:
// - TODO: Callers of all async methods of data-engine need to catch errors. // - TODO: Callers of all async methods of data-engine need to catch errors.
// - TODO: Add garbage collecting of segments not present in the recording summaries anymore. // - TODO: Add garbage collecting of segments not present in the recording summaries anymore.
// - TODO: Do I need to dedup recordings? (i.e. multiple zones on same camera may need to be dedup'd somewhere before returning the view). The media getID() call may be useful for this. // - TODO: Do I need to dedup recordings? (i.e. multiple zones on same camera may need to be dedup'd somewhere before returning the view). The media getID() call may be useful for this.
// - TODO: Do a fresh media query in the viewer on snapshot click, since the first query may (e.g.) only have requested events with snapshots (which would miss an event with just a clip). // - TODO: Do a fresh media query in the viewer on snapshot click, since the first query may (e.g.) only have requested events with snapshots (which would miss an event with just a clip).
// - TODO: ts-prune https://camchenry.com/blog/deleting-dead-code-in-typescript // - TODO: Move view/ stuff into a view directory.
// - TODO: Move frigate specific view-media under the camera manager.
// - TODO: ts-prune https://camchenry.com/blog/deleting-dead-code-in-typescript
// Hard: // Hard:
// - TODO: Implement dragging the timeline seeking forward in both Frigate recordings & events. // - TODO: Implement dragging the timeline seeking forward in both Frigate recordings & events.