diff --git a/ui/src/app/app.component.ts b/ui/src/app/app.component.ts index f29326a..5e12ea6 100644 --- a/ui/src/app/app.component.ts +++ b/ui/src/app/app.component.ts @@ -1,4 +1,4 @@ -import { Component, HostListener, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable, distinctUntilChanged, map } from 'rxjs'; @@ -17,7 +17,7 @@ export type DownloadTab = 'downloading' | 'queued' | 'completed'; styleUrls: ['./app.component.sass'], standalone: false }) -export class AppComponent implements OnInit { +export class AppComponent implements OnInit, OnDestroy { formats: Format[] = Formats; qualities: Quality[]; themes: Theme[] = Themes; @@ -128,6 +128,15 @@ export class AppComponent implements OnInit { window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { if (this.activeTheme.id === 'auto') this.setTheme(this.activeTheme); }); + + // Listen in the capture phase so Escape closes the player even when the + // native video controls (shadow DOM) hold focus after seeking and would + // otherwise swallow the keydown before it bubbles to the document. + document.addEventListener('keydown', this.onPlayerKeydown, true); + } + + ngOnDestroy(): void { + document.removeEventListener('keydown', this.onPlayerKeydown, true); } // ---------- Navigation ---------- @@ -169,10 +178,11 @@ export class AppComponent implements OnInit { this.playerTitle = ''; } - @HostListener('document:keydown.escape') - onEscape(): void { - if (this.playerUrl) this.closePlayer(); - } + private onPlayerKeydown = (event: KeyboardEvent): void => { + if (event.key === 'Escape' && this.playerUrl) { + this.closePlayer(); + } + }; // ---------- Library (媒体库) ----------