diff --git a/src/components/ha-windows-98.ts b/src/components/ha-windows-98.ts index 4f51198cda..bdc11c7abb 100644 --- a/src/components/ha-windows-98.ts +++ b/src/components/ha-windows-98.ts @@ -24,6 +24,9 @@ const STORAGE_KEY = "windows-98-position"; const DRAG_THRESHOLD = 5; const BUBBLE_TIMEOUT = 8000; const SLEEP_TIMEOUT = 30000; +const BSOD_CLICK_COUNT = 5; +const BSOD_CLICK_TIMEOUT = 3000; +const BSOD_DISMISS_DELAY = 500; @customElement("ha-windows-98") export class HaWindows98 extends SubscribeMixin(LitElement) { @@ -56,6 +59,12 @@ export class HaWindows98 extends SubscribeMixin(LitElement) { @state() private _position: { x: number; y: number } | null = null; + @state() private _showBsod = false; + + private _clickCount = 0; + + private _clickTimer?: ReturnType; + private _dragging = false; private _dragStartX = 0; @@ -97,6 +106,7 @@ export class HaWindows98 extends SubscribeMixin(LitElement) { this._revertTheme(); document.removeEventListener("pointermove", this._boundPointerMove); document.removeEventListener("pointerup", this._boundPointerUp); + document.removeEventListener("keydown", this._boundDismissBsod); } protected willUpdate(changedProps: Map): void { @@ -223,7 +233,7 @@ export class HaWindows98 extends SubscribeMixin(LitElement) { } private _onPointerDown(ev: PointerEvent): void { - if (ev.button !== 0) return; + if (ev.button !== 0 || this._showBsod) return; this._dragging = true; this._dragMoved = false; @@ -284,6 +294,20 @@ export class HaWindows98 extends SubscribeMixin(LitElement) { } private _toggleBubble(): void { + this._clickCount++; + if (this._clickTimer) { + clearTimeout(this._clickTimer); + } + this._clickTimer = setTimeout(() => { + this._clickCount = 0; + }, BSOD_CLICK_TIMEOUT); + + if (this._clickCount >= BSOD_CLICK_COUNT) { + this._clickCount = 0; + this._triggerBsod(); + return; + } + if (this._showBubble) { this._hideBubble(); } else { @@ -291,6 +315,34 @@ export class HaWindows98 extends SubscribeMixin(LitElement) { } } + private _boundDismissBsod = this._dismissBsodOnKey.bind(this); + + private _bsodReadyToDismiss = false; + + private _triggerBsod(): void { + this._hideBubble(); + this._showBsod = true; + this._bsodReadyToDismiss = false; + this._expression = "error"; + // Delay enabling dismiss so the rapid clicks that triggered the BSOD don't immediately close it + setTimeout(() => { + this._bsodReadyToDismiss = true; + document.addEventListener("keydown", this._boundDismissBsod); + }, 500); + } + + private _dismissBsod(): void { + if (!this._bsodReadyToDismiss) return; + this._showBsod = false; + this._expression = "hi"; + this._resetSleepTimer(); + document.removeEventListener("keydown", this._boundDismissBsod); + } + + private _dismissBsodOnKey(): void { + this._dismissBsod(); + } + private _showTip(): void { const tipIndex = Math.floor(Math.random() * TIP_COUNT) + 1; this._bubbleText = this.hass!.localize( @@ -344,6 +396,10 @@ export class HaWindows98 extends SubscribeMixin(LitElement) { clearTimeout(this._sleepTimer); this._sleepTimer = undefined; } + if (this._clickTimer) { + clearTimeout(this._clickTimer); + this._clickTimer = undefined; + } } protected render() { @@ -357,6 +413,28 @@ export class HaWindows98 extends SubscribeMixin(LitElement) { : `right: 16px; bottom: 16px;`; return html` + ${this._showBsod + ? html` +
+
+

Home Assistant

+

+ A fatal exception 0E has occurred at 0028:C0011E36 in VXD + HAcore(01) + 00010E36. The current automation will be + terminated. +

+

+ * Don't worry, nothing is actually broken.
+ * Your automations are still running. Probably. +

+

+ Press any key or click to continue + _ +

+
+
+ ` + : nothing}