Last active
March 5, 2019 15:23
-
-
Save kosich/fa4eb1c0ed0cea4252be282ef8028a7f to your computer and use it in GitHub Desktop.
Pausing observable on mouse hover with event spacing example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const { rxObserver } = require('api/v0.3'); | |
| const { of, timer, fromEvent, merge, empty, interval, Subject, forkJoin } = require('rxjs'); | |
| const { startWith, switchMap, distinctUntilChanged, map, mapTo, take, tap, concatMap, ignoreElements, multicast, shareReplay } = require('rxjs/operators'); | |
| const mouse$ = new Subject(); | |
| const TIMEOUT = 50; | |
| const notifications$ = new Subject(); | |
| merge( | |
| timer(20, 170), | |
| timer(130, 280) | |
| ) | |
| .take(7) | |
| .map(v => 'M:' + v) | |
| .subscribe(notifications$); | |
| // we need to remember what was the latest mouse position | |
| // otherwise it will be reset when new msg comes in | |
| const memMouse$ = mouse$ | |
| .startWith(false) | |
| .pipe(shareReplay(1)); | |
| let currentMsgIndex = -1; | |
| const display$ = notifications$.pipe( | |
| // store current msg index | |
| map((msg,i) => { | |
| currentMsgIndex = i; | |
| return msg; | |
| }), | |
| concatMap((msg, i) => { | |
| // we listen to events from the mouse | |
| // starting with "mouse away" state (false) | |
| return memMouse$.pipe( | |
| // if mouse pos changed -- reeval timeout | |
| switchMap(value => { | |
| // do nothing on mouse in | |
| if (value) { | |
| return empty(); | |
| } | |
| // until next msg comes in -- we're tracking mouse in/out | |
| let nextMsgAwait$; | |
| if (i == currentMsgIndex) { | |
| nextMsgAwait$ = notifications$.take(1); | |
| } else { | |
| nextMsgAwait$ = of(void 0); | |
| } | |
| // if mouse is away -- wait for | |
| // - timer for TIMEOUT | |
| // - wait till new msg arrives | |
| // until then -- user can mouse in/out | |
| // to delay the next msg display | |
| return forkJoin( | |
| timer(TIMEOUT) | |
| , nextMsgAwait$ | |
| ); | |
| }), | |
| take(1), | |
| // DEBUG {{{ | |
| map(_=>Date.now()), | |
| tap(rxObserver('Mouse minding gap')), | |
| // }}} | |
| // basically ignoring everything, we need only the delay here | |
| ignoreElements(), | |
| // pushing message to the start of the stream | |
| // here | |
| // ...............(timeout)| | |
| // becomes | |
| // (msg)...................| | |
| startWith(msg) | |
| ); | |
| }) | |
| ); | |
| setTimeout(()=>{ | |
| mouse$.next(true); | |
| }, 150); | |
| setTimeout(()=>{ | |
| mouse$.next(false); | |
| }, 250); | |
| // pushing first msg directly to the display | |
| display$ | |
| .skip(1) | |
| .merge(notifications$.take(1)) | |
| .map(v=>Date.now()) | |
| .subscribe(rxObserver('Display stream')); | |
| notifications$ | |
| .subscribe(rxObserver('Notifications')); | |
| mouse$ | |
| .subscribe(rxObserver('mouse')); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
example for https://stackoverflow.com/questions/54862366/pause-notifications-stream-on-mouseover-and-resume-on-mouseout/54867651#54867651