Published
Edited
Feb 26, 2021
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
index = {
const { fromEvent, merge, NEVER, timer } = Rx;
const { map, tap, takeWhile, switchMap,
withLatestFrom, share, mapTo,
switchMapTo, filter, sample } = Rx.operators;
const { startBtn, pauseBtn, resetBtn } = inputs;
const { body, timerDisplay } = outputs;
const { latestTimer$, initialDuration$ } = state;

const { save$ } = durationSelectorM;

const backgroundImage$ = timer(0, 60000).pipe(
switchMapTo(imageUrl$)
);
backgroundImage$.subscribe((imageUrl) => {body.style.backgroundImage = `url(${imageUrl})`});

// observable creation from inputs
const start$ = fromEvent(startBtn, 'click').pipe(mapTo(1));
const pause$ = fromEvent(pauseBtn, 'click');
const reset$ = fromEvent(resetBtn, 'click');

// timer management functionality

const stopTimer$ = merge(pause$, reset$).pipe(mapTo(0));

const countdown = () => timer(0, 1000).pipe(
withLatestFrom(latestTimer$),
map(([i, lastValue]) => lastValue - i),
takeWhile(secs => secs >= 0),
)

const timer$ = merge(start$, stopTimer$).pipe(
switchMap((val) => val ? countdown() : NEVER),
share()
)

const pausedTimerValue$ = timer$.pipe(sample(pause$))

const resetTimerValue$ = merge(reset$, save$).pipe(
withLatestFrom(initialDuration$),
map(([e, duration]) => duration)
);

merge(pausedTimerValue$, resetTimerValue$).subscribe(latestTimer$);

const timerDisplayFormatter = ms =>
`${Math.floor(ms / 60)}:${(ms % 60).toLocaleString('en-US', { minimumIntegerDigits: 2 })}`;

const resetTimerDisplay$ = resetTimerValue$.pipe(map(timerDisplayFormatter));

const timerDisplay$ = timer$.pipe(map(timerDisplayFormatter));

const updateTimerDisplay = timer => timerDisplay.innerHTML = timer;

resetTimerDisplay$.subscribe(updateTimerDisplay);

timerDisplay$.subscribe(updateTimerDisplay);

timer$.pipe(filter(val => val === 0)).subscribe(() => {alert(`you're done!`)});
}
Insert cell
state = {
const { BehaviorSubject } = Rx;
const latestTimer$ = new BehaviorSubject(1500);
const initialDuration$ = new BehaviorSubject(1500);
return { latestTimer$, initialDuration$ }
}
Insert cell
outputs = {
const body = widget.bodyEl;
const durationSelector = widget.durationSelectorEL;
const timerDisplay = widget.timerEl;
return { body, durationSelector, timerDisplay }
}
Insert cell
durationSelectorM = {
const { fromEvent, of } = Rx;
const { map, share, flatMap } = Rx.operators;
const { settingsBtn, setDurationBtn, minutesInput } = inputs;
const { durationSelector } = outputs;
const { latestTimer$, initialDuration$ } = state;

// observable creation from inputs
const showSettings$ = fromEvent(settingsBtn, 'click');
const inputValue$ = of(minutesInput);
const save$ = fromEvent(setDurationBtn, 'click').pipe(share());

// settings show functionality
showSettings$.subscribe(() => { durationSelector.style.visibility = 'visible'});

// get input section
const durationInSeconds$ = save$.pipe(
flatMap(e => inputValue$),
map(input => input.value * 60)
);

durationInSeconds$.subscribe(initialDuration$);

save$.subscribe(() => { durationSelector.style.visibility = 'hidden'});
return { save$ }
}
Insert cell
imageUrl$ = Rx.Observable.create((observer) => {
fetch('https://source.unsplash.com/collection/540518/1600x900')
.then(res => {
if (res.ok) {
observer.next(res.url);
}
})
});
Insert cell
inputs = {
const startBtn = widget.startEl;
const pauseBtn = widget.pauseEl;
const resetBtn = widget.restartEl;

const settingsBtn = widget.settingsEl;
const setDurationBtn = widget.setDurationEl;
const minutesInput = widget.inputMinutesEl;

return { startBtn, pauseBtn, resetBtn, settingsBtn, setDurationBtn, minutesInput }
}
Insert cell
faStyle({regular: true, solid: true, brands: true})
Insert cell
import { fas, style as faStyle } from "@airbornemint/fontawesome"
Insert cell
import {collapsedCSS} from "@j-f1/css-template-tag"
Insert cell
Rx = require('rxjs@6.2.1/bundles/rxjs.umd.js')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more