feat: Escape ends calls (#2488)

This commit is contained in:
Dermot Duffy
2026-06-30 17:45:13 -07:00
committed by dermotduffy
parent 9b750953ae
commit 881ba51e9f
2 changed files with 29 additions and 3 deletions
+18
View File
@@ -49,6 +49,16 @@ export class AdvancedCameraCardCallControls extends LitElement {
@state()
private _exiting = false;
public connectedCallback(): void {
super.connectedCallback();
window.addEventListener('keydown', this._handleKeyDown);
}
public disconnectedCallback(): void {
window.removeEventListener('keydown', this._handleKeyDown);
super.disconnectedCallback();
}
protected willUpdate(changedProps: PropertyValues): void {
if (changedProps.has('buttonSize') && this.buttonSize) {
this.style.setProperty(
@@ -113,6 +123,14 @@ export class AdvancedCameraCardCallControls extends LitElement {
</div>`;
}
private _handleKeyDown = (ev: KeyboardEvent): void => {
if (this.active && ev.key === 'Escape') {
dispatchActionExecutionRequest(this, { actions: createCallEndAction() });
ev.stopPropagation();
ev.preventDefault();
}
};
private _handleAnimationEnd = (ev: AnimationEvent): void => {
if (hasPopOutAnimationEnded(ev)) {
this._exiting = false;
+11 -3
View File
@@ -24,13 +24,17 @@ export class AdvancedCameraCardNotification extends LitElement {
super.connectedCallback();
window.addEventListener('click', this._handleOutsideInteraction);
window.addEventListener('focusin', this._handleOutsideInteraction);
window.addEventListener('keydown', this._handleKeyDown);
// Escape is claimed in the capture phase: the popup is a modal surface and
// must consume Escape before non-modal background controls (e.g. the call
// controls) that also listen on `window`.
window.addEventListener('keydown', this._handleKeyDown, { capture: true });
}
public disconnectedCallback(): void {
window.removeEventListener('click', this._handleOutsideInteraction);
window.removeEventListener('focusin', this._handleOutsideInteraction);
window.removeEventListener('keydown', this._handleKeyDown);
window.removeEventListener('keydown', this._handleKeyDown, { capture: true });
super.disconnectedCallback();
}
@@ -95,7 +99,11 @@ export class AdvancedCameraCardNotification extends LitElement {
private _handleKeyDown = (ev: KeyboardEvent): void => {
if (ev.key === 'Escape') {
this._dismiss();
ev.stopPropagation();
// `stopImmediatePropagation()` (not `stopPropagation()`) is required to
// block sibling `window` listeners -- `stopPropagation()` only stops
// propagation to other targets, not other listeners on `window` itself.
ev.stopImmediatePropagation();
ev.preventDefault();
}
};