Skip to content

Instantly share code, notes, and snippets.

@seiyria
Created January 3, 2021 18:03
Show Gist options
  • Save seiyria/6fd0482ab5e03a898bac40242cad268c to your computer and use it in GitHub Desktop.
Save seiyria/6fd0482ab5e03a898bac40242cad268c to your computer and use it in GitHub Desktop.
import { Directive, EventEmitter, HostListener, Input, OnDestroy, Output } from '@angular/core';
import { combineLatest, interval, Observable, Subject } from 'rxjs';
import { filter, first, map, takeUntil } from 'rxjs/operators';
@Directive({
selector: '[appLongPress]'
})
export class LongPressDirective implements OnDestroy {
@Input() public longPress = 500;
@Output() public release: EventEmitter<MouseEvent> = new EventEmitter();
public mouseups$ = new Subject();
public mousedowns$ = new Subject();
public destroys$ = new Subject();
private initClick(): void {
const interval$ = this.interval$()
.pipe(
takeUntil(this.mouseups$)
);
combineLatest([this.mousedowns$, interval$])
.pipe(first())
.subscribe((val) => {
this.release.emit(val[0] as MouseEvent);
});
}
public ngOnDestroy(): void {
this.destroys$.next();
this.destroys$.unsubscribe();
}
public interval$(): Observable<number> {
return interval()
.pipe(
map(i => i * 10),
filter(i => i >= this.longPress)
);
}
@HostListener('touchstart', ['$event'])
public onTouchStart(event: MouseEvent): void {
this.initClick();
this.mousedowns$.next(event);
}
@HostListener('touchend', ['$event'])
public onTouchEnd(event: MouseEvent): void {
this.mouseups$.next(event);
}
@HostListener('mousedown', ['$event'])
public onMouseDown(event: MouseEvent): void {
this.initClick();
this.mousedowns$.next(event);
}
@HostListener('mouseup', ['$event'])
public onMouseUp(event: MouseEvent): void {
this.mouseups$.next(event);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment