From 8e2caacd36bb7a27c13897650294aaa245cde8bb Mon Sep 17 00:00:00 2001 From: Chris Witterholt Date: Tue, 7 Feb 2023 17:05:38 +0100 Subject: [PATCH] Add hot keys --- src/app/app.component.ts | 42 +++++++++++++++++++++++++++++++++++++- src/app/hotkeys.service.ts | 42 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 src/app/hotkeys.service.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 60b771b..16ba597 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -11,6 +11,7 @@ import { LoginComponent } from './components/login/login.component'; import { fromEvent } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { DisplayModeSelectorComponent } from './components/display-mode-selector/display-mode-selector.component'; +import { HotKeysService } from './hotkeys.service'; // import { version } from '../../package.json'; @Component({ @@ -30,7 +31,8 @@ export class AppComponent implements OnInit { webSocketOpen = false; constructor(private pageTitleService: PageTitleService, private openlpService: OpenLPService, - private dialog: MatDialog, private bottomSheet: MatBottomSheet, private windowRef: WindowRef) { + private dialog: MatDialog, private bottomSheet: MatBottomSheet, private windowRef: WindowRef, + private hotKeysService: HotKeysService) { pageTitleService.pageTitleChanged$.subscribe(pageTitle => this.pageTitle = pageTitle); openlpService.stateChanged$.subscribe(item => this.state = item); openlpService.webSocketStateChanged$.subscribe(status => this.webSocketOpen = status === WebSocketStatus.Open); @@ -45,6 +47,44 @@ export class AppComponent implements OnInit { ngOnInit(): void { this.openlpService.retrieveSystemInformation().subscribe(res => this.showLogin = res.login_required); + this.addHotKeys(); + } + + addHotKeys(): void { + this.hotKeysService.addShortcut({ keys: 'ArrowUp' }).subscribe(_ => + this.previousSlide() + ); + this.hotKeysService.addShortcut({ keys: 'ArrowDown' }).subscribe(_ => + this.nextSlide() + ); + this.hotKeysService.addShortcut({ keys: 'PageUp' }).subscribe(_ => + this.previousSlide() + ); + this.hotKeysService.addShortcut({ keys: 'PageDown' }).subscribe(_ => + this.nextSlide() + ); + this.hotKeysService.addShortcut({ keys: 'ArrowLeft' }).subscribe(_ => + this.previousItem() + ); + this.hotKeysService.addShortcut({ keys: 'ArrowRight' }).subscribe(_ => + this.nextItem() + ); + this.hotKeysService.addShortcut({ keys: 'Space' }).subscribe(_ => + { + if (this.state.displayMode != DisplayMode.Presentation) { + this.showDisplay(); + } + } + ); + this.hotKeysService.addShortcut({ keys: 't' }).subscribe(_ => + this.state.displayMode == DisplayMode.Theme ? this.showDisplay() : this.themeDisplay() + ); + this.hotKeysService.addShortcut({ keys: 'code.Period' }).subscribe(_ => + this.state.displayMode == DisplayMode.Blank ? this.showDisplay() : this.blankDisplay() + ); + this.hotKeysService.addShortcut({ keys: 'd' }).subscribe(_ => + this.state.displayMode == DisplayMode.Desktop ? this.showDisplay() : this.desktopDisplay() + ); } get fastSwitching(): boolean { diff --git a/src/app/hotkeys.service.ts b/src/app/hotkeys.service.ts new file mode 100644 index 0000000..b1112cc --- /dev/null +++ b/src/app/hotkeys.service.ts @@ -0,0 +1,42 @@ +import { DOCUMENT } from "@angular/common"; +import { Inject, Injectable } from "@angular/core"; +import { EventManager } from "@angular/platform-browser"; +import { Observable } from "rxjs"; + +type Options = { + element: any; + keys: string; +} + +@Injectable({ providedIn: 'root' }) +export class HotKeysService { + defaults: Partial = { + element: this.document + } + + constructor(private eventManager: EventManager, @Inject(DOCUMENT) private document: Document) { + } + + addShortcut(options: Partial) { + const merged = { ...this.defaults, ...options }; + const event = `keydown.${merged.keys}`; + + return new Observable(observer => { + const handler = (e: KeyboardEvent) => { + if (document.URL.endsWith('/slides')) + { + e.preventDefault() + observer.next(e); + } + }; + + const dispose = this.eventManager.addEventListener( + merged.element, event, handler + ); + + return () => { + dispose(); + }; + }) + } +} \ No newline at end of file