Home > front end >  RXJS, How to watch mouse and keyboard and do something when when none has been used for some time?
RXJS, How to watch mouse and keyboard and do something when when none has been used for some time?

Time:02-10

I need run a function if neither the mouse has moved, nor the keyboard has been touched for 1mn.

I tried the code below but doesn't seem to work. How can I fix it? Thank you for your help.

mouseEvent$ = fromEvent(document, 'mouseMove');
keyPress$ = fromEvent(document, 'keyup');

merge(
    this.mouseEvent$.pipe(startWith(null)).pipe(switchMap(() => timer(10000, 1000))),
    this.keyPress$.pipe(startWith(null)).pipe(switchMap(() => timer(10000, 1000))),
).subscribe(() => console.log("----));

CodePudding user response:

Here's my take on this:

 const mouseMove$ = fromEvent<MouseEvent>(document, 'mousemove');
 const keyPress$ = fromEvent<KeyboardEvent>(document, 'keyup');
 const mergeBothEvents = merge(keyPress$, mouseMove$);
 const interval$ = timer(60000);
 
 mergeBothEvents
     .pipe(
       startWith('initial'),
       switchMap(() => {
         return interval$;
       })
     )
     .subscribe(() => {
       console.log('60 seconds past');
       console.log('Perform function here');
     });

A bit of inside into what's happening in the code.

fromEvent<MouseEvent> used to capture the mouse movements.

fromEvent<KeyboardEvent> used to capture the keyboard key up click event.

merge(keyPress$, mouse$) is used to merge both the observables so that they can run in parallel.

timer(60000) is used to check the time of a minute before running the required function.

In mergeBothEvents we have used to more operators startWith() and switchMap

startWith() is used for the edge-case in which if the user doesn't do anything(mouse or keyboard) when he enters the page the mergeBothEvents event won't be emitted. Thanks @MrkSef to for pointing that out.

Finally switchMap is used to cancel the previous subscription of the event when the user moves the mouse or presses the keyboard so the timer restarts from 0th second.

CodePudding user response:

The first thing to notice is that you typed mouseMove incorrectly.

Here's how I might do this:

merge(
  fromEvent(document, 'mousemove'),
  fromEvent(document, 'keyup')
).pipe(
  share(),
  startWith(null),
  debounceTime(60000),
  take(1),
  retry()
).subscribe(_ => console.log("1 Minute without input"));
  • Related