'Recreate contextmenu event in RxJS

I want to recreate the contextmenu event from touch events in RxJS because iOS does not support the contextmenu event on touch.

In plain language, this observable should emit when:

  • the touchstart event occurred
  • for 2000ms (basically long-press)
  • followed by touchend

It should not emit when:

  • the touchend occurs in less than 2000ms
  • the touchstart event is followed by touchmove event

I can't figure out how to skip if the touchend occurs sooner or if the touchstart is followed by touchmove. This is what I've so far:

const touchStart$ = fromEvent<TouchEvent>(this.el.nativeElement, "touchstart");
const touchEnd$ = fromEvent<TouchEvent>(this.el.nativeElement, "touchend");
const touchMove$ = fromEvent<TouchEvent>(this.el.nativeElement, "touchmove");
const contextmenu$ = touchStart$.pipe(
      switchMap(event => touchEnd$.pipe(mapTo(event))),
      switchMap(event => timer(2000).pipe(mapTo(event), takeUntil(merge(touchEnd$, touchMove$))))
);

contextmenu$.subscribe($event => {
      console.log("CONTEXTMENU EVENT HAPPENED");
});


Solution 1:[1]

I came up with a possible solution:

const touchStart$ = fromEvent<TouchEvent>(this.el.nativeElement, "touchstart");
const touchEnd$ = fromEvent<TouchEvent>(this.el.nativeElement, "touchend");
const touchMove$ = fromEvent<TouchEvent>(this.el.nativeElement, "touchmove");
const contextmenu$ = touchStart$.pipe(
    switchMap(event =>
        timer(2000).pipe(
           mapTo(event),
           takeUntil(merge(touchMove$, touchEnd$)),
           switchMap(event => touchEnd$.pipe(mapTo(event), takeUntil(touchMove$)))
        )
    )
);

contextmenu$.subscribe($event => {
    console.log("CONTEXT MENU EVENT HAPPENED");
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Runtime Terror