diff --git a/docs/configuration/performance.md b/docs/configuration/performance.md index 4fb87857..b29728ea 100644 --- a/docs/configuration/performance.md +++ b/docs/configuration/performance.md @@ -25,6 +25,7 @@ performance: | Option | Default | Description | | ---------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `animated_progress_indicator` | `true` | Will show the animated progress indicator 'spinners' when `true`. | +| `card_loading_indicator` | `true` | Will show the card loading indicator (spinner & version number) when `true`. | | `media_chunk_size` | `50` | How many media items to fetch and render at a time (e.g. thumbnails under a live view, or number of snapshots to load in the media viewer). This may only make partial sense in some contexts (e.g. the 'infinite gallery' is still infinite, it just loads thumbnails this many items at a time) or not at all (e.g. the timeline will show the number of events dictated by the time span the user navigates to). | | `max_simultaneous_engine_requests` | _Infinity_ | How many camera engine requests to allow occur in parallel. Setting lower values will slow the card down since more requests will run in sequence, but it will increase the chances of positive cache hit rates and reduce the chances of overwhelming the backend. | @@ -59,6 +60,7 @@ For low end devices, the `low-performance` profile will adjust card defaults to performance: features: animated_progress_indicator: true + card_loading_indicator: true media_chunk_size: 50 max_simultaneous_engine_requests: 100 style: diff --git a/src/card.ts b/src/card.ts index f993804f..5ce39029 100644 --- a/src/card.ts +++ b/src/card.ts @@ -348,9 +348,9 @@ class FrigateCard extends LitElement { const actions = this._controller.getActionsManager().getMergedActions(); const cameraManager = this._controller.getCameraManager(); - const showLoadingSpinner = - this._config?.performance?.features.animated_progress_indicator !== false && - !this._controller.getInitializationManager().wasEverInitialized() && + + const showLoading = + this._config?.performance?.features.card_loading_indicator !== false && !this._controller.getMessageManager().hasMessage(); // Caution: Keep the main div and the menu next to one another in order to @@ -380,7 +380,11 @@ class FrigateCard extends LitElement { } @frigate-card:focus=${() => this.focus()} > - ${showLoadingSpinner ? html`` : ''} + ${showLoading + ? html`` + : ''} ${this._renderMenuStatusContainer('top')} ${this._renderMenuStatusContainer('overlay')}
diff --git a/src/components/loading.ts b/src/components/loading.ts index d55f9e41..d3e5142a 100644 --- a/src/components/loading.ts +++ b/src/components/loading.ts @@ -1,12 +1,14 @@ import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit'; import { customElement } from 'lit/decorators.js'; import loadingStyle from '../scss/loading.scss'; +import { getReleaseVersion } from '../utils/diagnostics'; import './icon'; @customElement('frigate-card-loading') export class FrigateCardLoading extends LitElement { protected render(): TemplateResult { - return html``; + return html`${getReleaseVersion(true)}`; } static get styles(): CSSResultGroup { diff --git a/src/config/profiles/low-performance.ts b/src/config/profiles/low-performance.ts index 8eac77d8..773dbb95 100644 --- a/src/config/profiles/low-performance.ts +++ b/src/config/profiles/low-performance.ts @@ -34,6 +34,7 @@ import { CONF_MENU_BUTTONS_MEDIA_PLAYER, CONF_MENU_BUTTONS_TIMELINE, CONF_MENU_STYLE, + CONF_PERFORMANCE_FEATURES_CARD_LOADING_INDICATOR, CONF_PERFORMANCE_FEATURES_ANIMATED_PROGRESS_INDICATOR, CONF_PERFORMANCE_FEATURES_MAX_SIMULTANEOUS_ENGINE_REQUESTS, CONF_PERFORMANCE_FEATURES_MEDIA_CHUNK_SIZE, @@ -118,6 +119,7 @@ export const LOW_PERFORMANCE_PROFILE = { // Disable all optional performance related features. [CONF_PERFORMANCE_FEATURES_ANIMATED_PROGRESS_INDICATOR]: false, + [CONF_PERFORMANCE_FEATURES_CARD_LOADING_INDICATOR]: false, // Load fewer media items by default. [CONF_PERFORMANCE_FEATURES_MEDIA_CHUNK_SIZE]: 10, diff --git a/src/config/types.ts b/src/config/types.ts index 6e3efbed..3b058162 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -1995,6 +1995,7 @@ const automationsSchema = automationSchema.array(); const performanceConfigDefault = { features: { animated_progress_indicator: true, + card_loading_indicator: true, media_chunk_size: MEDIA_CHUNK_SIZE_DEFAULT, }, style: { @@ -2010,6 +2011,9 @@ export const performanceConfigSchema = z animated_progress_indicator: z .boolean() .default(performanceConfigDefault.features.animated_progress_indicator), + card_loading_indicator: z + .boolean() + .default(performanceConfigDefault.features.card_loading_indicator), media_chunk_size: z .number() .min(0) diff --git a/src/const.ts b/src/const.ts index 62c7116d..adfb8fb9 100644 --- a/src/const.ts +++ b/src/const.ts @@ -366,6 +366,7 @@ export const CONF_OVERRIDES = 'overrides' as const; const CONF_PERFORMANCE = 'performance' as const; export const CONF_PERFORMANCE_FEATURES_ANIMATED_PROGRESS_INDICATOR = `${CONF_PERFORMANCE}.features.animated_progress_indicator`; +export const CONF_PERFORMANCE_FEATURES_CARD_LOADING_INDICATOR = `${CONF_PERFORMANCE}.features.card_loading_indicator`; export const CONF_PERFORMANCE_FEATURES_MEDIA_CHUNK_SIZE = `${CONF_PERFORMANCE}.features.media_chunk_size`; export const CONF_PERFORMANCE_FEATURES_MAX_SIMULTANEOUS_ENGINE_REQUESTS = `${CONF_PERFORMANCE}.features.max_simultaneous_engine_requests`; export const CONF_PERFORMANCE_PROFILE = `${CONF_PERFORMANCE}.profile`; diff --git a/src/editor.ts b/src/editor.ts index 5e718926..5e7095be 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -177,6 +177,7 @@ import { CONF_MENU_POSITION, CONF_MENU_STYLE, CONF_PERFORMANCE_FEATURES_ANIMATED_PROGRESS_INDICATOR, + CONF_PERFORMANCE_FEATURES_CARD_LOADING_INDICATOR, CONF_PERFORMANCE_FEATURES_MAX_SIMULTANEOUS_ENGINE_REQUESTS, CONF_PERFORMANCE_FEATURES_MEDIA_CHUNK_SIZE, CONF_PERFORMANCE_PROFILE, @@ -2965,6 +2966,10 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor 'config.performance.features.editor_label', 'mdi:feature-search', html` + ${this._renderSwitch( + CONF_PERFORMANCE_FEATURES_CARD_LOADING_INDICATOR, + this._defaults.performance.features.card_loading_indicator, + )} ${this._renderSwitch( CONF_PERFORMANCE_FEATURES_ANIMATED_PROGRESS_INDICATOR, this._defaults.performance.features.animated_progress_indicator, diff --git a/src/localize/languages/ca.json b/src/localize/languages/ca.json index 1ffba635..cfdf4b9a 100644 --- a/src/localize/languages/ca.json +++ b/src/localize/languages/ca.json @@ -435,6 +435,7 @@ "performance": { "features": { "animated_progress_indicator": "Indicador animat del progrés", + "card_loading_indicator": "", "editor_label": "Opcions de característiques", "max_simultaneous_engine_requests": "", "media_chunk_size": "Mida del fragment multimèdia" @@ -511,8 +512,8 @@ "theme": { "themes": { "dark": "", - "ha": "", "editor_label": "", + "ha": "", "light": "", "traditional": "" } diff --git a/src/localize/languages/en.json b/src/localize/languages/en.json index 2472387c..9af3274a 100644 --- a/src/localize/languages/en.json +++ b/src/localize/languages/en.json @@ -435,6 +435,7 @@ "performance": { "features": { "animated_progress_indicator": "Animated Progress Indicator", + "card_loading_indicator": "Card Loading Indicator", "editor_label": "Feature Options", "max_simultaneous_engine_requests": "Max simultaneous camera engine requests", "media_chunk_size": "Media chunk size" diff --git a/src/localize/languages/fr.json b/src/localize/languages/fr.json index 2ace6383..cce9380f 100644 --- a/src/localize/languages/fr.json +++ b/src/localize/languages/fr.json @@ -435,6 +435,7 @@ "performance": { "features": { "animated_progress_indicator": "Indicateur de progression animé", + "card_loading_indicator": "", "editor_label": "Options de fonctionnalités", "max_simultaneous_engine_requests": "Nombre maximal de requêtes simultanées au moteur de caméra", "media_chunk_size": "Taille du morceau de média" @@ -511,8 +512,8 @@ "theme": { "themes": { "dark": "", - "ha": "", "editor_label": "", + "ha": "", "light": "", "traditional": "" } diff --git a/src/localize/languages/it.json b/src/localize/languages/it.json index 64d1b606..e92b642c 100644 --- a/src/localize/languages/it.json +++ b/src/localize/languages/it.json @@ -435,6 +435,7 @@ "performance": { "features": { "animated_progress_indicator": "Indicatore di avanzamento animato", + "card_loading_indicator": "", "editor_label": "Opzioni funzionalità", "max_simultaneous_engine_requests": "", "media_chunk_size": "Dimensione del blocco multimediale" @@ -511,8 +512,8 @@ "theme": { "themes": { "dark": "", - "ha": "", "editor_label": "", + "ha": "", "light": "", "traditional": "" } diff --git a/src/localize/languages/pt-BR.json b/src/localize/languages/pt-BR.json index ac96b25f..f73349a4 100644 --- a/src/localize/languages/pt-BR.json +++ b/src/localize/languages/pt-BR.json @@ -435,6 +435,7 @@ "performance": { "features": { "animated_progress_indicator": "Indicador de Carregamento Animado", + "card_loading_indicator": "", "editor_label": "Opções de recursos", "max_simultaneous_engine_requests": "", "media_chunk_size": "Tamanho do bloco de mídia" @@ -511,8 +512,8 @@ "theme": { "themes": { "dark": "", - "ha": "", "editor_label": "", + "ha": "", "light": "", "traditional": "" } diff --git a/src/localize/languages/pt-PT.json b/src/localize/languages/pt-PT.json index 6e52dd73..c0ca36b9 100644 --- a/src/localize/languages/pt-PT.json +++ b/src/localize/languages/pt-PT.json @@ -435,6 +435,7 @@ "performance": { "features": { "animated_progress_indicator": "Animação na barra de progresso", + "card_loading_indicator": "", "editor_label": "Editor de etiquetas", "max_simultaneous_engine_requests": "", "media_chunk_size": "Tamanho do ficheiro" @@ -511,8 +512,8 @@ "theme": { "themes": { "dark": "", - "ha": "", "editor_label": "", + "ha": "", "light": "", "traditional": "" } diff --git a/src/scss/loading.scss b/src/scss/loading.scss index 090ddbe1..8db11741 100644 --- a/src/scss/loading.scss +++ b/src/scss/loading.scss @@ -3,14 +3,26 @@ height: intrinsic; display: flex; + flex-direction: column; justify-content: center; align-items: center; pointer-events: none; + + background-color: var(--frigate-card-loading-background-color); + color: var(--frigate-card-loading-foreground-color); + + transition: opacity 1.5s ease-in; + opacity: 1; +} + +:host([loaded]) { + opacity: 0; } frigate-card-icon { - height: 50%; + margin-bottom: 20px; + height: 25%; width: auto; animation: rotate 8s linear infinite; } @@ -23,3 +35,7 @@ frigate-card-icon { transform: rotate(360deg); } } + +span { + font-size: x-large; +} diff --git a/src/scss/themes/base.scss b/src/scss/themes/base.scss index 200ec8bd..c334a170 100644 --- a/src/scss/themes/base.scss +++ b/src/scss/themes/base.scss @@ -124,4 +124,13 @@ --frigate-card-timeline-divider-color: var(--frigate-card-divider-color); --frigate-card-timeline-target-bar-color: var(--frigate-card-active-color); + + /******************* + * Loading Indicator + *******************/ + + --frigate-card-loading-background-color: var( + --frigate-card-control-background-transparent + ); + --frigate-card-loading-foreground-color: var(--frigate-card-control-foreground); } diff --git a/src/utils/diagnostics.ts b/src/utils/diagnostics.ts index a3ab2a4c..1a51a6c2 100644 --- a/src/utils/diagnostics.ts +++ b/src/utils/diagnostics.ts @@ -20,7 +20,7 @@ interface IntegrationDiagnostics { version?: string; } -export const getReleaseVersion = (): string => { +export const getReleaseVersion = (short?: boolean): string => { const releaseVersion = '__FRIGATE_CARD_RELEASE_VERSION__'; /* istanbul ignore if: depends on rollup substitution -- @preserve */ @@ -30,7 +30,7 @@ export const getReleaseVersion = (): string => { /* istanbul ignore if: depends on rollup substitution -- @preserve */ if ((releaseVersion as unknown) === 'dev') { - return `${releaseVersion}+${pkg['gitAbbrevHash']} (${pkg['buildDate']})`; + return `${releaseVersion}+${pkg['gitAbbrevHash']}${short ? '' : ` (${pkg['buildDate']})`}`; } return releaseVersion; diff --git a/tests/card-controller/config/config-manager.test.ts b/tests/card-controller/config/config-manager.test.ts index 5be228c1..c9020f6d 100644 --- a/tests/card-controller/config/config-manager.test.ts +++ b/tests/card-controller/config/config-manager.test.ts @@ -158,6 +158,7 @@ describe('ConfigManager', () => { performance: { features: { animated_progress_indicator: true, + card_loading_indicator: true, media_chunk_size: 50, }, style: { diff --git a/tests/config/profiles/low-performance.test.ts b/tests/config/profiles/low-performance.test.ts index bad67efa..ece5088b 100644 --- a/tests/config/profiles/low-performance.test.ts +++ b/tests/config/profiles/low-performance.test.ts @@ -42,6 +42,7 @@ it('should contain expected defaults', () => { 'menu.buttons.timeline.enabled': false, 'menu.style': 'outside', 'performance.features.animated_progress_indicator': false, + 'performance.features.card_loading_indicator': false, 'performance.features.max_simultaneous_engine_requests': 1, 'performance.features.media_chunk_size': 10, 'performance.style.border_radius': false, diff --git a/tests/config/types.test.ts b/tests/config/types.test.ts index 8c553a2a..d9c8a154 100644 --- a/tests/config/types.test.ts +++ b/tests/config/types.test.ts @@ -278,6 +278,7 @@ describe('config defaults', () => { performance: { features: { animated_progress_indicator: true, + card_loading_indicator: true, media_chunk_size: 50, }, style: {