Add cheaper progress indicator.
This commit is contained in:
+12
-1
@@ -67,6 +67,7 @@ import {
|
||||
MenuButton,
|
||||
Message,
|
||||
RawFrigateCardConfig,
|
||||
CardWideConfig,
|
||||
} from './types.js';
|
||||
import {
|
||||
convertActionToFrigateCardCustomAction,
|
||||
@@ -166,6 +167,9 @@ export class FrigateCard extends LitElement {
|
||||
protected _config!: FrigateCardConfig;
|
||||
protected _rawConfig?: RawFrigateCardConfig;
|
||||
|
||||
@state()
|
||||
protected _cardWideConfig?: CardWideConfig;
|
||||
|
||||
@state()
|
||||
protected _overriddenConfig?: FrigateCardConfig;
|
||||
|
||||
@@ -976,6 +980,10 @@ export class FrigateCard extends LitElement {
|
||||
|
||||
this._rawConfig = inputConfig;
|
||||
this._config = config;
|
||||
this._cardWideConfig = {
|
||||
performance: config.performance,
|
||||
};
|
||||
|
||||
this._overriddenConfig = undefined;
|
||||
this._cameras = undefined;
|
||||
this._view = undefined;
|
||||
@@ -1919,7 +1927,7 @@ export class FrigateCard extends LitElement {
|
||||
this._changeView({ resetMessage: false });
|
||||
return this._render();
|
||||
})(),
|
||||
renderProgressIndicator(),
|
||||
renderProgressIndicator({cardWideConfig: this._cardWideConfig}),
|
||||
)
|
||||
: // Always want to call render even if there's a message, to
|
||||
// ensure live preload is always present (even if not displayed).
|
||||
@@ -1989,6 +1997,7 @@ export class FrigateCard extends LitElement {
|
||||
.cameras=${this._cameras}
|
||||
.galleryConfig=${this._getConfig().event_gallery}
|
||||
.dataManager=${this._dataManager}
|
||||
.cardWideConfig=${this._cardWideConfig}
|
||||
>
|
||||
</frigate-card-gallery>`
|
||||
: ``}
|
||||
@@ -2000,6 +2009,7 @@ export class FrigateCard extends LitElement {
|
||||
.viewerConfig=${this._getConfig().media_viewer}
|
||||
.resolvedMediaCache=${this._resolvedMediaCache}
|
||||
.dataManager=${this._dataManager}
|
||||
.cardWideConfig=${this._cardWideConfig}
|
||||
>
|
||||
</frigate-card-viewer>`
|
||||
: ``}
|
||||
@@ -2031,6 +2041,7 @@ export class FrigateCard extends LitElement {
|
||||
.liveOverrides=${getOverridesByKey(this._getConfig().overrides, 'live')}
|
||||
.cameras=${this._cameras}
|
||||
.dataManager=${this._dataManager}
|
||||
.cardWideConfig=${this._cardWideConfig}
|
||||
class="${classMap(liveClasses)}"
|
||||
>
|
||||
</frigate-card-live>
|
||||
|
||||
@@ -11,6 +11,7 @@ import { customElement, property } from 'lit/decorators.js';
|
||||
import galleryStyle from '../scss/gallery.scss';
|
||||
import {
|
||||
CameraConfig,
|
||||
CardWideConfig,
|
||||
ExtendedHomeAssistant,
|
||||
frigateCardConfigDefaults,
|
||||
GalleryConfig,
|
||||
@@ -46,6 +47,9 @@ export class FrigateCardGallery extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public dataManager?: DataManager;
|
||||
|
||||
@property({ attribute: false })
|
||||
public cardWideConfig?: CardWideConfig;
|
||||
|
||||
/**
|
||||
* Master render method.
|
||||
* @returns A rendered template.
|
||||
@@ -96,7 +100,7 @@ export class FrigateCardGallery extends LitElement {
|
||||
browseMediaQueryParameters,
|
||||
);
|
||||
}
|
||||
return renderProgressIndicator();
|
||||
return renderProgressIndicator({cardWideConfig: this.cardWideConfig});
|
||||
}
|
||||
|
||||
return html`
|
||||
|
||||
+33
-4
@@ -27,6 +27,7 @@ import liveCarouselStyle from '../scss/live-carousel.scss';
|
||||
import liveProviderStyle from '../scss/live-provider.scss';
|
||||
import {
|
||||
CameraConfig,
|
||||
CardWideConfig,
|
||||
ExtendedHomeAssistant,
|
||||
frigateCardConfigDefaults,
|
||||
FrigateCardError,
|
||||
@@ -99,6 +100,9 @@ export class FrigateCardLive extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public dataManager?: DataManager;
|
||||
|
||||
@property({ attribute: false })
|
||||
public cardWideConfig?: CardWideConfig;
|
||||
|
||||
// Whether or not the live view is currently in the background (i.e. preloaded
|
||||
// but not visible)
|
||||
@state()
|
||||
@@ -250,6 +254,7 @@ export class FrigateCardLive extends LitElement {
|
||||
.inBackground=${this._inBackground}
|
||||
.conditionState=${this.conditionState}
|
||||
.liveOverrides=${this.liveOverrides}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
>
|
||||
</frigate-card-live-carousel>
|
||||
</frigate-card-surround>`,
|
||||
@@ -290,6 +295,9 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public conditionState?: ConditionState;
|
||||
|
||||
@property({ attribute: false })
|
||||
public cardWideConfig?: CardWideConfig;
|
||||
|
||||
// Index between camera name and slide number.
|
||||
protected _cameraToSlide: Record<string, number> = {};
|
||||
protected _refMediaCarousel: Ref<FrigateCardMediaCarousel> = createRef();
|
||||
@@ -520,6 +528,7 @@ export class FrigateCardLiveCarousel extends LitElement {
|
||||
.label=${getCameraTitle(this.hass, cameraConfig)}
|
||||
.liveConfig=${config}
|
||||
.hass=${this.hass}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
@frigate-card:media:loaded=${(ev: CustomEvent<MediaLoadedInfo>) => {
|
||||
wrapMediaLoadedEventForCarousel(slideIndex, ev);
|
||||
}}
|
||||
@@ -667,6 +676,9 @@ export class FrigateCardLiveProvider extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public label = '';
|
||||
|
||||
@property({ attribute: false })
|
||||
public cardWideConfig?: CardWideConfig;
|
||||
|
||||
@state()
|
||||
protected _isVideoMediaLoaded = false;
|
||||
|
||||
@@ -819,6 +831,7 @@ export class FrigateCardLiveProvider extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
.webRTCConfig=${this.liveConfig.webrtc_card}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
@frigate-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
>
|
||||
</frigate-card-live-webrtc-card>`
|
||||
@@ -828,6 +841,7 @@ export class FrigateCardLiveProvider extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.cameraConfig=${this.cameraConfig}
|
||||
.jsmpegConfig=${this.liveConfig.jsmpeg}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
@frigate-card:media:loaded=${this._videoMediaShowHandler.bind(this)}
|
||||
>
|
||||
</frigate-card-live-jsmpeg>`}
|
||||
@@ -950,6 +964,9 @@ export class FrigateCardLiveWebRTCCard extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public cameraConfig?: CameraConfig;
|
||||
|
||||
@property({ attribute: false })
|
||||
public cardWideConfig?: CardWideConfig;
|
||||
|
||||
protected hass?: HomeAssistant;
|
||||
|
||||
// A task to await the load of the WebRTC component.
|
||||
@@ -1079,9 +1096,13 @@ export class FrigateCardLiveWebRTCCard extends LitElement {
|
||||
// Use a task to allow us to asynchronously wait for the WebRTC card to
|
||||
// load, but yet still have the card load be followed by the updated()
|
||||
// lifecycle callback (unlike just using `until`).
|
||||
return renderTask(this, this._webrtcTask, render, () =>
|
||||
renderProgressIndicator(localize('error.webrtc_card_waiting')),
|
||||
);
|
||||
return renderTask(this, this._webrtcTask, render, {
|
||||
inProgressFunc: () =>
|
||||
renderProgressIndicator({
|
||||
message: localize('error.webrtc_card_waiting'),
|
||||
cardWideConfig: this.cardWideConfig,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1121,6 +1142,9 @@ export class FrigateCardLiveJSMPEG extends LitElement {
|
||||
@property({ attribute: false, hasChanged: contentsChanged })
|
||||
public jsmpegConfig?: JSMPEGConfig;
|
||||
|
||||
@property({ attribute: false })
|
||||
public cardWideConfig?: CardWideConfig;
|
||||
|
||||
protected hass?: ExtendedHomeAssistant;
|
||||
|
||||
protected _jsmpegCanvasElement?: HTMLCanvasElement;
|
||||
@@ -1327,7 +1351,12 @@ export class FrigateCardLiveJSMPEG extends LitElement {
|
||||
}
|
||||
return html`${this._jsmpegCanvasElement}`;
|
||||
};
|
||||
return html`${until(_render(), renderProgressIndicator())}`;
|
||||
return html`${until(
|
||||
_render(),
|
||||
renderProgressIndicator({
|
||||
cardWideConfig: this.cardWideConfig,
|
||||
}),
|
||||
)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@ import { classMap } from 'lit/directives/class-map.js';
|
||||
import { TROUBLESHOOTING_URL } from '../const.js';
|
||||
import { localize } from '../localize/localize.js';
|
||||
import messageStyle from '../scss/message.scss';
|
||||
import { FrigateCardError, Message, MessageType } from '../types.js';
|
||||
import { CardWideConfig, FrigateCardError, Message, MessageType } from '../types.js';
|
||||
import { dispatchFrigateCardEvent } from '../utils/basic.js';
|
||||
|
||||
@customElement('frigate-card-message')
|
||||
@@ -82,11 +82,14 @@ export class FrigateCardProgressIndicator extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public message: string | TemplateResult = '';
|
||||
|
||||
@property({ attribute: false })
|
||||
public animated = false;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html` <div class="message vertical">
|
||||
<span>
|
||||
<ha-circular-progress active="true" size="large"> </ha-circular-progress>
|
||||
</span>
|
||||
${this.animated
|
||||
? html`<ha-circular-progress active="true" size="large"> </ha-circular-progress>`
|
||||
: html`<ha-icon icon="mdi:timer-sand"></ha-icon>`}
|
||||
${this.message ? html`<span>${this.message}</span>` : html``}
|
||||
</div>`;
|
||||
}
|
||||
@@ -112,9 +115,15 @@ export function renderMessage(message: Message): TemplateResult {
|
||||
return html``;
|
||||
}
|
||||
|
||||
export function renderProgressIndicator(message?: string): TemplateResult {
|
||||
export function renderProgressIndicator(options?: {
|
||||
message?: string;
|
||||
cardWideConfig?: CardWideConfig;
|
||||
}): TemplateResult {
|
||||
return html`
|
||||
<frigate-card-progress-indicator .message=${message || ''}>
|
||||
<frigate-card-progress-indicator
|
||||
.message=${options?.message || ''}
|
||||
.animated=${options?.cardWideConfig?.performance?.profile !== 'low'}
|
||||
>
|
||||
</frigate-card-progress-indicator>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ export class FrigateCardNextPreviousControl extends LitElement {
|
||||
aria-label="${this.label}"
|
||||
/>`
|
||||
: html``,
|
||||
() => html`<div class=${classMap(classes)}></div>`,
|
||||
{ inProgressFunc: () => html`<div class=${classMap(classes)}></div>` },
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ export class FrigateCardThumbnailFeatureEvent extends LitElement {
|
||||
this._embedThumbnailTask,
|
||||
(embeddedThumbnail: string | null) =>
|
||||
embeddedThumbnail ? html`<img src="${embeddedThumbnail}" />` : html``,
|
||||
() => imageOff,
|
||||
{inProgressFunc: () => imageOff},
|
||||
)
|
||||
: imageOff} `;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
BrowseMediaNeighbors,
|
||||
BrowseMediaQueryParameters,
|
||||
CameraConfig,
|
||||
CardWideConfig,
|
||||
ExtendedHomeAssistant,
|
||||
FrigateBrowseMediaSource,
|
||||
frigateCardConfigDefaults,
|
||||
@@ -97,6 +98,9 @@ export class FrigateCardViewer extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public dataManager?: DataManager;
|
||||
|
||||
@property({ attribute: false })
|
||||
public cardWideConfig?: CardWideConfig;
|
||||
|
||||
/**
|
||||
* Master render method.
|
||||
* @returns A rendered template.
|
||||
@@ -151,7 +155,7 @@ export class FrigateCardViewer extends LitElement {
|
||||
}),
|
||||
);
|
||||
}
|
||||
return renderProgressIndicator();
|
||||
return renderProgressIndicator({ cardWideConfig: this.cardWideConfig });
|
||||
}
|
||||
|
||||
return html` <frigate-card-surround
|
||||
@@ -169,6 +173,7 @@ export class FrigateCardViewer extends LitElement {
|
||||
.viewerConfig=${this.viewerConfig}
|
||||
.browseMediaQueryParameters=${browseMediaQueryParameters}
|
||||
.resolvedMediaCache=${this.resolvedMediaCache}
|
||||
.cardWideConfig=${this.cardWideConfig}
|
||||
>
|
||||
</frigate-card-viewer-carousel>
|
||||
</frigate-card-surround>`;
|
||||
@@ -206,6 +211,9 @@ export class FrigateCardViewerCarousel extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public resolvedMediaCache?: ResolvedMediaCache;
|
||||
|
||||
@property({ attribute: false })
|
||||
public cardWideConfig?: CardWideConfig;
|
||||
|
||||
protected _refMediaCarousel: Ref<FrigateCardMediaCarousel> = createRef();
|
||||
|
||||
// Mapping of slide # to FrigateBrowseMediaSource child #.
|
||||
@@ -645,7 +653,9 @@ export class FrigateCardViewerCarousel extends LitElement {
|
||||
// If lazy loading is not enabled, wait for the media resolver task to
|
||||
// complete and show a progress indictator until this.
|
||||
if (!this.viewerConfig?.lazy_load && !this._isMediaFullyResolved()) {
|
||||
return renderTask(this, this._mediaResolutionTask, this._render.bind(this));
|
||||
return renderTask(this, this._mediaResolutionTask, this._render.bind(this), {
|
||||
cardWideConfig: this.cardWideConfig,
|
||||
});
|
||||
}
|
||||
return this._render();
|
||||
}
|
||||
|
||||
+1
-3
@@ -1,7 +1,6 @@
|
||||
// TODO: Change defaults themselves?
|
||||
// TODO: Camera auto-dep detection
|
||||
// TODO: CSS
|
||||
// TODO: Renderprogress
|
||||
// TODO: Don't pump out conditionStates based on state?
|
||||
|
||||
import { deepRemoveDefaults } from './utils/zod.js';
|
||||
import {
|
||||
@@ -16,7 +15,6 @@ import {
|
||||
CONF_EVENT_GALLERY_CONTROLS_THUMBNAILS_SHOW_FAVORITE_CONTROL,
|
||||
CONF_EVENT_GALLERY_CONTROLS_THUMBNAILS_SHOW_TIMELINE_CONTROL,
|
||||
CONF_LIVE_AUTO_MUTE,
|
||||
CONF_LIVE_AUTO_PLAY,
|
||||
CONF_LIVE_CONTROLS_THUMBNAILS_MODE,
|
||||
CONF_LIVE_CONTROLS_THUMBNAILS_SHOW_DETAILS,
|
||||
CONF_LIVE_CONTROLS_THUMBNAILS_SHOW_FAVORITE_CONTROL,
|
||||
|
||||
@@ -54,6 +54,10 @@ div.message div.icon {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.message ha-icon, ha-circular-progress {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.dotdotdot:after {
|
||||
@keyframes dots {
|
||||
0%,
|
||||
|
||||
+12
-3
@@ -4,6 +4,7 @@ import {
|
||||
dispatchFrigateCardErrorEvent,
|
||||
renderProgressIndicator,
|
||||
} from '../components/message';
|
||||
import { CardWideConfig } from '../types';
|
||||
import { errorToConsole } from './basic';
|
||||
|
||||
/**
|
||||
@@ -18,11 +19,19 @@ export const renderTask = <R>(
|
||||
host: EventTarget,
|
||||
task: Task<unknown[], R>,
|
||||
completeFunc: (result: R) => TemplateResult | void,
|
||||
inProgressFunc?: () => TemplateResult | void,
|
||||
options?: {
|
||||
cardWideConfig?: CardWideConfig;
|
||||
inProgressFunc?: () => TemplateResult | void;
|
||||
},
|
||||
): TemplateResult => {
|
||||
const progressConfig = {
|
||||
...(options?.cardWideConfig && { cardWideConfig: options.cardWideConfig }),
|
||||
};
|
||||
return html` ${task.render({
|
||||
initial: () => inProgressFunc?.() ?? renderProgressIndicator(),
|
||||
pending: () => inProgressFunc?.() ?? renderProgressIndicator(),
|
||||
initial: () =>
|
||||
options?.inProgressFunc?.() ?? renderProgressIndicator(progressConfig),
|
||||
pending: () =>
|
||||
options?.inProgressFunc?.() ?? renderProgressIndicator(progressConfig),
|
||||
error: (e: unknown) => {
|
||||
errorToConsole(e as Error);
|
||||
dispatchFrigateCardErrorEvent(host, e as Error);
|
||||
|
||||
Reference in New Issue
Block a user