Skip to content

Instantly share code, notes, and snippets.

@seiyria
Created January 3, 2021 18:03
Show Gist options
  • Select an option

  • Save seiyria/6fd0482ab5e03a898bac40242cad268c to your computer and use it in GitHub Desktop.

Select an option

Save seiyria/6fd0482ab5e03a898bac40242cad268c to your computer and use it in GitHub Desktop.

Revisions

  1. seiyria created this gist Jan 3, 2021.
    64 changes: 64 additions & 0 deletions longpress.directive.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,64 @@
    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);
    }
    }