Add interaction and triggered conditions.
This commit is contained in:
@@ -54,6 +54,13 @@ export class CardElementManager {
|
||||
}
|
||||
|
||||
public elementConnected(): void {
|
||||
// Set initial condition state. Must be done after the element is connected to
|
||||
// allow callbacks to interact with the card.
|
||||
this._api.getInteractionManager().initialize();
|
||||
this._api.getFullscreenManager().initialize();
|
||||
this._api.getExpandManager().initialize();
|
||||
this._api.getMediaLoadedInfoManager().initialize();
|
||||
|
||||
// Whether or not the card is in panel mode on the dashboard.
|
||||
setOrRemoveAttribute(this._element, isCardInPanel(this._element), 'panel');
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
frigateConditionalSchema,
|
||||
OverrideConfigurationKey,
|
||||
RawFrigateCardConfig,
|
||||
ViewDisplayMode
|
||||
ViewDisplayMode,
|
||||
} from '../config/types';
|
||||
import { CardConditionAPI } from './types';
|
||||
|
||||
@@ -18,6 +18,8 @@ interface ConditionState {
|
||||
state?: HassEntities;
|
||||
media_loaded?: boolean;
|
||||
displayMode?: ViewDisplayMode;
|
||||
triggered?: Set<string>;
|
||||
interaction?: boolean;
|
||||
}
|
||||
|
||||
export class ConditionEvaluateRequestEvent extends Event {
|
||||
@@ -133,7 +135,7 @@ export class ConditionsManager {
|
||||
this._listeners = [
|
||||
() => this._api.getConfigManager().computeOverrideConfig(),
|
||||
() => this._api.getAutomationsManager().execute(),
|
||||
...(listener ? [listener] : [])
|
||||
...(listener ? [listener] : []),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -243,6 +245,15 @@ export class ConditionsManager {
|
||||
if (condition.display_mode) {
|
||||
result &&= !!state.displayMode && condition.display_mode === state.displayMode;
|
||||
}
|
||||
if (condition.triggered?.length) {
|
||||
result &&= condition.triggered.some((triggeredCameraID) =>
|
||||
state.triggered?.has(triggeredCameraID),
|
||||
);
|
||||
}
|
||||
if (condition.interaction !== undefined) {
|
||||
result &&=
|
||||
state.interaction !== undefined && condition.interaction === state.interaction;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@ export class ExpandManager {
|
||||
this._api = api;
|
||||
}
|
||||
|
||||
public initialize(): void {
|
||||
this._setConditionState();
|
||||
}
|
||||
|
||||
public isExpanded(): boolean {
|
||||
return this._expanded;
|
||||
}
|
||||
@@ -23,9 +27,13 @@ export class ExpandManager {
|
||||
}
|
||||
|
||||
this._expanded = expanded;
|
||||
this._api.getConditionsManager()?.setState({
|
||||
expand: expanded,
|
||||
});
|
||||
this._setConditionState();
|
||||
this._api.getCardElementManager().update();
|
||||
}
|
||||
|
||||
protected _setConditionState(): void {
|
||||
this._api.getConditionsManager()?.setState({
|
||||
expand: this._expanded,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ export class FullscreenManager {
|
||||
this._api = api;
|
||||
}
|
||||
|
||||
public initialize(): void {
|
||||
this._setConditionState();
|
||||
}
|
||||
|
||||
public connect(): void {
|
||||
if (screenfull.isEnabled) {
|
||||
screenfull.on('change', this._fullscreenHandler);
|
||||
@@ -32,12 +36,16 @@ export class FullscreenManager {
|
||||
screenfull.exit();
|
||||
}
|
||||
|
||||
protected _fullscreenHandler = (): void => {
|
||||
this._api.getExpandManager().setExpanded(false);
|
||||
|
||||
protected _setConditionState(): void {
|
||||
this._api.getConditionsManager()?.setState({
|
||||
fullscreen: this.isInFullscreen(),
|
||||
});
|
||||
}
|
||||
|
||||
protected _fullscreenHandler = (): void => {
|
||||
this._api.getExpandManager().setExpanded(false);
|
||||
|
||||
this._setConditionState();
|
||||
|
||||
// Re-render after a change to fullscreen mode to take advantage of
|
||||
// the expanded screen real-estate (vs staying in aspect-ratio locked
|
||||
|
||||
@@ -16,32 +16,37 @@ export class InteractionManager {
|
||||
this._reportInteraction();
|
||||
}, 1 * 1000);
|
||||
|
||||
public initialize(): void {
|
||||
this._api.getConditionsManager().setState({ interaction: false });
|
||||
}
|
||||
|
||||
public hasInteraction(): boolean {
|
||||
return this._timer.isRunning();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the user interaction ('screensaver') timer to reset the view to
|
||||
* default `view.timeout_seconds` after user interaction.
|
||||
* default `view.interaction_seconds` after user interaction.
|
||||
*/
|
||||
protected _reportInteraction(): void {
|
||||
this._timer.stop();
|
||||
|
||||
const timeoutSeconds = this._api.getConfigManager().getConfig()
|
||||
?.view.timeout_seconds;
|
||||
?.view.interaction_seconds;
|
||||
|
||||
if (timeoutSeconds) {
|
||||
this._api.getConditionsManager().setState({ interaction: true });
|
||||
|
||||
this._timer.start(timeoutSeconds, () => {
|
||||
if (this._isAutomatedUpdateAllowed()) {
|
||||
this._api.getViewManager().setViewDefault();
|
||||
this._api.getConditionsManager().setState({ interaction: false });
|
||||
|
||||
if (!this._api.getTriggersManager().isTriggered()) {
|
||||
if (this._api.getConfigManager().getConfig()?.view.reset_after_interaction) {
|
||||
this._api.getViewManager().setViewDefault();
|
||||
}
|
||||
this._api.getStyleManager().setLightOrDarkMode();
|
||||
}
|
||||
});
|
||||
}
|
||||
this._api.getStyleManager().setLightOrDarkMode();
|
||||
}
|
||||
|
||||
protected _isAutomatedUpdateAllowed(): boolean {
|
||||
return !this._api.getTriggersManager().isTriggered();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,10 @@ export class MediaLoadedInfoManager {
|
||||
this._api = api;
|
||||
}
|
||||
|
||||
public initialize(): void {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
public set(mediaInfo: MediaLoadedInfo): void {
|
||||
if (!isValidMediaLoadedInfo(mediaInfo)) {
|
||||
return;
|
||||
|
||||
@@ -95,6 +95,7 @@ export class TriggersManager {
|
||||
cameraID === this._api.getViewManager().getView()?.camera)
|
||||
) {
|
||||
this._triggeredCameras.set(cameraID, now);
|
||||
this._setConditionState();
|
||||
this._triggerAction(cameraID);
|
||||
}
|
||||
}
|
||||
@@ -132,6 +133,14 @@ export class TriggersManager {
|
||||
this._api.getCardElementManager().update();
|
||||
}
|
||||
|
||||
protected _setConditionState(): void {
|
||||
this._api.getConditionsManager().setState({
|
||||
triggered: this._triggeredCameras.size
|
||||
? new Set(this._triggeredCameras.keys())
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
protected _untriggerAction(cameraID: string): void {
|
||||
const action = this._api.getConfigManager().getConfig()?.view.scan.actions.untrigger;
|
||||
|
||||
@@ -140,6 +149,7 @@ export class TriggersManager {
|
||||
}
|
||||
this._triggeredCameras.delete(cameraID);
|
||||
this._deleteTimer(cameraID);
|
||||
this._setConditionState();
|
||||
|
||||
// Must update master element to remove border pulsing.
|
||||
this._api.getCardElementManager().update();
|
||||
|
||||
@@ -100,6 +100,7 @@ export interface CardDownloadAPI {
|
||||
|
||||
export interface CardElementAPI {
|
||||
getActionsManager(): ActionsManager;
|
||||
getExpandManager(): ExpandManager;
|
||||
getFullscreenManager(): FullscreenManager;
|
||||
getInteractionManager(): InteractionManager;
|
||||
getMediaLoadedInfoManager(): MediaLoadedInfoManager;
|
||||
@@ -147,6 +148,7 @@ export interface CardInitializerAPI {
|
||||
}
|
||||
|
||||
export interface CardInteractionAPI {
|
||||
getConditionsManager(): ConditionsManager;
|
||||
getConfigManager(): ConfigManager;
|
||||
getStyleManager(): StyleManager;
|
||||
getTriggersManager(): TriggersManager;
|
||||
@@ -198,6 +200,7 @@ export interface CardStyleAPI {
|
||||
|
||||
export interface CardTriggersAPI {
|
||||
getCameraManager(): CameraManager;
|
||||
getConditionsManager(): ConditionsManager;
|
||||
getCardElementManager(): CardElementManager;
|
||||
getConfigManager(): ConfigManager;
|
||||
getHASSManager(): HASSManager;
|
||||
|
||||
Reference in New Issue
Block a user