fix: Don't run the query string actions until after initialization (#1579)
This commit is contained in:
@@ -2,9 +2,9 @@ import { LitElement, ReactiveControllerHost } from 'lit';
|
||||
import { ActionEventTarget } from '../action-handler-directive';
|
||||
import { setOrRemoveAttribute } from '../utils/basic';
|
||||
import { isCardInPanel } from '../utils/ha';
|
||||
import { ActionExecutionRequestEventTarget } from './actions/utils/execution-request';
|
||||
import { InitializationAspect } from './initialization-manager';
|
||||
import { CardElementAPI } from './types';
|
||||
import { ActionExecutionRequestEventTarget } from './actions/utils/execution-request';
|
||||
|
||||
export type ScrollCallback = () => void;
|
||||
export type MenuToggleCallback = () => void;
|
||||
@@ -120,16 +120,19 @@ export class CardElementManager {
|
||||
// See: https://github.com/home-assistant/frontend/blob/273992c8e9c3062c6e49481b6d7d688a07067232/src/common/navigate.ts#L43
|
||||
window.addEventListener(
|
||||
'location-changed',
|
||||
this._api.getQueryStringManager().executeAll,
|
||||
this._api.getQueryStringManager().requestExecution,
|
||||
);
|
||||
|
||||
// Listen for history state changes (i.e. user using the browser
|
||||
// back/forward controls).
|
||||
window.addEventListener('popstate', this._api.getQueryStringManager().executeAll);
|
||||
window.addEventListener(
|
||||
'popstate',
|
||||
this._api.getQueryStringManager().requestExecution,
|
||||
);
|
||||
|
||||
// Manually call the location change handler as the card will be
|
||||
// Manually request query string execute as the card will be
|
||||
// disconnected/reconnected when dashboard 'tab' changes happen within HA.
|
||||
this._api.getQueryStringManager().executeAll();
|
||||
this._api.getQueryStringManager().requestExecution();
|
||||
|
||||
// Make sure reconnections call the initialization code.
|
||||
this._element.requestUpdate();
|
||||
@@ -180,8 +183,11 @@ export class CardElementManager {
|
||||
|
||||
window.removeEventListener(
|
||||
'location-changed',
|
||||
this._api.getQueryStringManager().executeAll,
|
||||
this._api.getQueryStringManager().requestExecution,
|
||||
);
|
||||
window.removeEventListener(
|
||||
'popstate',
|
||||
this._api.getQueryStringManager().requestExecution,
|
||||
);
|
||||
window.removeEventListener('popstate', this._api.getQueryStringManager().executeAll);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,27 +14,27 @@ interface QueryStringViewIntent {
|
||||
|
||||
export class QueryStringManager {
|
||||
protected _api: CardQueryStringAPI;
|
||||
protected _shouldRun = true;
|
||||
|
||||
constructor(api: CardQueryStringAPI) {
|
||||
this._api = api;
|
||||
}
|
||||
|
||||
public hasViewRelatedActions(): boolean {
|
||||
return !!this._calculateIntent().view;
|
||||
public hasViewRelatedActionsToRun(): boolean {
|
||||
return !!this._calculateIntent().view && this._shouldRun;
|
||||
}
|
||||
|
||||
public executeNonViewRelated = async (): Promise<void> => {
|
||||
await this._executeNonViewRelated(this._calculateIntent());
|
||||
public requestExecution = (): void => {
|
||||
this._shouldRun = true;
|
||||
this._api.getCardElementManager().update();
|
||||
};
|
||||
|
||||
public executeViewRelated = async (): Promise<void> => {
|
||||
await this._executeViewRelated(this._calculateIntent());
|
||||
};
|
||||
|
||||
public executeAll = async (): Promise<void> => {
|
||||
const intent = this._calculateIntent();
|
||||
await this._executeViewRelated(intent);
|
||||
await this._executeNonViewRelated(intent);
|
||||
public executeIfNecessary = async (): Promise<void> => {
|
||||
if (this._shouldRun) {
|
||||
this._shouldRun = false;
|
||||
await this._executeViewRelated(this._calculateIntent());
|
||||
await this._executeNonViewRelated(this._calculateIntent());
|
||||
}
|
||||
};
|
||||
|
||||
protected async _executeViewRelated(intent: QueryStringViewIntent): Promise<void> {
|
||||
@@ -63,15 +63,9 @@ export class QueryStringManager {
|
||||
}
|
||||
|
||||
protected async _executeNonViewRelated(intent: QueryStringViewIntent): Promise<void> {
|
||||
if (
|
||||
// Only execute non-view actions when the card has rendered at least once.
|
||||
!this._api.getCardElementManager().hasUpdated() ||
|
||||
!intent.other?.length
|
||||
) {
|
||||
return;
|
||||
if (intent.other) {
|
||||
await this._api.getActionsManager().executeActions(intent.other);
|
||||
}
|
||||
|
||||
await this._api.getActionsManager().executeActions(intent.other);
|
||||
}
|
||||
|
||||
protected _calculateIntent(): QueryStringViewIntent {
|
||||
|
||||
@@ -134,18 +134,11 @@ export class ViewManager implements ViewManagerInterface {
|
||||
}
|
||||
|
||||
public initialize = async (): Promise<boolean> => {
|
||||
// Set a view on initial load. However, if the query string contains a view
|
||||
// related action, we don't set any view here and allow that content to be
|
||||
// triggered by the firstUpdated() call that runs query string actions. To
|
||||
// do otherwise may cause a race condition between the default view and the
|
||||
// querystring view, see:
|
||||
// https://github.com/dermotduffy/frigate-hass-card/issues/1200
|
||||
const hasViewRelatedActions = this._api
|
||||
.getQueryStringManager()
|
||||
.hasViewRelatedActions();
|
||||
if (hasViewRelatedActions) {
|
||||
await this._api.getQueryStringManager().executeViewRelated();
|
||||
} else {
|
||||
// If the query string contains a view related action, we don't set any view
|
||||
// here and allow that action to be triggered by the next call of to execute
|
||||
// query actions (called at least once per render cycle).
|
||||
// Related: https://github.com/dermotduffy/frigate-hass-card/issues/1200
|
||||
if (!this._api.getQueryStringManager().hasViewRelatedActionsToRun()) {
|
||||
await this.setViewDefaultWithNewQuery({ failSafe: true });
|
||||
}
|
||||
return true;
|
||||
|
||||
+4
-3
@@ -302,9 +302,10 @@ class FrigateCard extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
protected firstUpdated(): void {
|
||||
// Execute query string actions after first render is complete.
|
||||
this._controller.getQueryStringManager().executeNonViewRelated();
|
||||
protected updated(): void {
|
||||
if (this._controller.getInitializationManager().isInitializedMandatory()) {
|
||||
this._controller.getQueryStringManager().executeIfNecessary();
|
||||
}
|
||||
}
|
||||
|
||||
protected _renderInDialogIfNecessary(contents: TemplateResult): TemplateResult | void {
|
||||
|
||||
Reference in New Issue
Block a user