fix: preserve backdrop continuity during summary recovery (#490)

Issue: #490
User-Visible: yes
This commit is contained in:
Sergey Matyunin
2026-09-09 00:10:16 +03:00
parent 87f19941a3
commit 01c653a4c6
47 changed files with 384 additions and 333 deletions
+12
View File
@@ -49,6 +49,14 @@ export interface SummaryPanelHost extends Node {
_layoutRev: number;
_cfgContentFingerprint: string;
_regSignature: string;
_signer: {
prepareImage(hass: SummaryHass | undefined, href: string): Promise<boolean>;
};
_continuity: {
readonly hasCompleteFrame: boolean;
readonly state: string;
note(event: string): void;
};
_writesPending: number;
_writeChain: Promise<void>;
_kiosk: boolean;
@@ -73,10 +81,14 @@ export interface SummaryPanelHost extends Node {
}): Promise<boolean>;
_sendConfigCandidate(candidate: ServerConfig): Promise<void>;
_getAuthoritativeConfig(): Promise<AuthoritativeConfigResponse>;
_candidateBackdrop(config: ServerConfig | null): string;
_scheduleLoadRetry(force?: boolean): void;
_beginContinuityCandidate(reason: string, dataReady: boolean): number;
_adoptStructuralResponses(response: AuthoritativeConfigResponse): { configChanged: boolean };
_syncDecorAssets(config: ServerConfig | null): Promise<void>;
_adoptInitialSpace(models: SpaceModel[], authoritative?: boolean): unknown;
_maybeRebuildDevices(): void;
_resumePendingNavMode(): boolean;
_restoreZoom(): void;
_reloadConfigOnly(force?: boolean): Promise<void>;
_cacheSnapshot(): void;
+14
View File
@@ -440,10 +440,24 @@ export class LoadedSummaryPanelRuntime {
const authoritative = await this.host._getAuthoritativeConfig();
const confirmed = confirmedSummaryPanelWriteRecovery(authoritative, draft);
if (!confirmed) throw writeError;
const configChanged = contentFingerprint(confirmed.config)
!== (this.host._cfgContentFingerprint || contentFingerprint(this.host._serverCfg));
if (configChanged && !await this.host._signer.prepareImage(
this.host.hass, this.host._candidateBackdrop(confirmed.config),
)) {
this.host._continuity.note('asset-failed');
this.host._scheduleLoadRetry(true);
throw writeError;
}
if (configChanged && this.host._continuity.hasCompleteFrame
&& this.host._continuity.state === 'steady') {
this.host._beginContinuityCandidate('summary-recovery', true);
}
const visibleSpace = this.host._space;
this.host._adoptStructuralResponses(authoritative);
void this.host._syncDecorAssets(confirmed.config).catch(() => undefined);
this.host._adoptInitialSpace(this.host._model, true);
this.host._resumePendingNavMode();
this.host._cacheSnapshot();
if (this.host._space !== visibleSpace) this.host._restoreZoom();
this.host._regSignature = '';