Skip to content

Commit

Permalink
fix: unsubscribe shortcuts when removed
Browse files Browse the repository at this point in the history
  • Loading branch information
ebichan38 committed Jul 18, 2021
1 parent f3c8c6e commit 1e2aba3
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
13 changes: 11 additions & 2 deletions projects/ngneat/hotkeys/src/lib/hotkeys.service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { DOCUMENT } from '@angular/common';
import { Inject, Injectable } from '@angular/core';
import { EventManager } from '@angular/platform-browser';
import { Observable, of } from 'rxjs';
import { Observable, of, Subject } from 'rxjs';

import { hostPlatform, normalizeKeys } from './utils/platform';
import { coerceArray } from './utils/array';
import { takeUntil } from 'rxjs/operators';

export type AllowInElement = 'INPUT' | 'TEXTAREA' | 'SELECT';
interface Options {
Expand All @@ -28,6 +29,7 @@ export type HotkeyCallback = (event: KeyboardEvent, keys: string, target: HTMLEl
@Injectable({ providedIn: 'root' })
export class HotkeysService {
private readonly hotkeys = new Map<string, Hotkey>();
private readonly disposers = new Map<string, Subject<void>>();
private readonly defaults: Options = {
trigger: 'keydown',
allowIn: [],
Expand Down Expand Up @@ -79,6 +81,9 @@ export class HotkeysService {
this.hotkeys.set(normalizedKeys, mergedOptions);
const event = `${mergedOptions.trigger}.${normalizedKeys}`;

const disposer = new Subject<void>();
this.disposers.set(normalizedKeys, disposer);

return new Observable(observer => {
const handler = (e: KeyboardEvent) => {
const hotkey = this.hotkeys.get(normalizedKeys);
Expand All @@ -100,9 +105,10 @@ export class HotkeysService {

return () => {
this.hotkeys.delete(normalizedKeys);
this.disposers.delete(normalizedKeys);
dispose();
};
});
}).pipe(takeUntil<KeyboardEvent>(disposer));
}

removeShortcuts(hotkeys: string | string[]): void {
Expand All @@ -113,6 +119,9 @@ export class HotkeysService {
return;
}
this.hotkeys.delete(hotkey);
const disposer = this.disposers.get(hotkey);
disposer.next();
this.disposers.delete(hotkey);
});
}

Expand Down
15 changes: 15 additions & 0 deletions projects/ngneat/hotkeys/src/lib/tests/hotkeys.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ describe('Service: Hotkeys', () => {
expect(spy).toHaveBeenCalled();
});

it('should unsubscribe shortcuts when removed', () => {
const subscription = spectator.service.addShortcut({ keys: 'meta.a' }).subscribe();
spectator.service.removeShortcuts('meta.a');
expect(subscription.closed).toBe(true);
});

it('should delete hotkey and disposer when unsubscribed', () => {
spectator.service
.addShortcut({ keys: 'meta.a' })
.subscribe()
.unsubscribe();
expect(spectator.service.getHotkeys().length).toBe(0);
expect(spectator.service['disposers'].has('meta.a')).toBe(false);
});

it('should listen to keydown', () => {
const spyFcn = createSpy('subscribe', e => {});
spectator.service.addShortcut({ keys: 'a' }).subscribe(spyFcn);
Expand Down

0 comments on commit 1e2aba3

Please sign in to comment.