diff --git a/docs/configuration/performance.md b/docs/configuration/performance.md
index f0597905..4fb87857 100644
--- a/docs/configuration/performance.md
+++ b/docs/configuration/performance.md
@@ -24,7 +24,7 @@ performance:
| Option | Default | Description |
| ---------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `animated_progress_indicator` | `true` | Will show the animated progress indicator 'spinner' when `true` or a simple loading icon when `false`. |
+| `animated_progress_indicator` | `true` | Will show the animated progress indicator 'spinners' 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. |
diff --git a/src/card-controller/initialization-manager.ts b/src/card-controller/initialization-manager.ts
index 127f69bb..15239d63 100644
--- a/src/card-controller/initialization-manager.ts
+++ b/src/card-controller/initialization-manager.ts
@@ -31,12 +31,17 @@ export class InitializationManager {
// initialization" (above) are followed.
protected _initializationQueue = new PQueue({ concurrency: 1 });
protected _initializer: Initializer;
+ protected _everInitialized = false;
constructor(api: CardInitializerAPI, initializer?: Initializer) {
this._api = api;
this._initializer = initializer ?? new Initializer();
}
+ public wasEverInitialized(): boolean {
+ return this._everInitialized;
+ }
+
public isInitializedMandatory(): boolean {
const config = this._api.getConfigManager().getConfig();
if (!config) {
@@ -113,6 +118,7 @@ export class InitializationManager {
return;
}
+ this._everInitialized = true;
this._api.getCardElementManager().update();
}
diff --git a/src/card.ts b/src/card.ts
index 57321d83..0ac95d60 100644
--- a/src/card.ts
+++ b/src/card.ts
@@ -12,6 +12,7 @@ import { CardController } from './card-controller/controller';
import { MenuButtonController } from './components-lib/menu-button-controller';
import './components/elements.js';
import { FrigateCardElements } from './components/elements.js';
+import './components/loading.js';
import './components/menu.js';
import { FrigateCardMenu } from './components/menu.js';
import './components/message.js';
@@ -183,7 +184,6 @@ class FrigateCard extends LitElement {
if (!this._controller.getInitializationManager().isInitializedMandatory()) {
this._controller.getInitializationManager().initializeMandatory();
- return false;
}
return true;
}
@@ -338,6 +338,11 @@ class FrigateCard extends LitElement {
const actions = this._controller.getActionsManager().getMergedActions();
const cameraManager = this._controller.getCameraManager();
+ const renderLoadingSpinner =
+ this._config?.performance?.features.animated_progress_indicator !== false;
+ const showLoadingSpinner =
+ !this._controller.getInitializationManager().wasEverInitialized() &&
+ !this._controller.getMessageManager().hasMessage();
// Caution: Keep the main div and the menu next to one another in order to
// ensure the hover menu styling continues to work.
@@ -366,35 +371,35 @@ class FrigateCard extends LitElement {
}
@frigate-card:focus=${() => this.focus()}
>
+ ${renderLoadingSpinner
+ ? html`