const {div, li, img, h, h2, p, a, makeDOMDriver} = CycleDOM;const { run } = Cycle;
const { makeDOMDriver, h } = CycleDOM;
const { makeHTTPDriver } = CycleHTTPDriver;
const xs = xstream.default;
function intent(DOMSource) {const getRandomItem = arr => arr[Math.floor(Math.random() * arr.length)];
// Create streams for the intents that will be observed
const refreshClickStream$ = DOMSource.select('.refresh').events('click');
const close1ClickStream$ = DOMSource.select('.close1').events('click');
const close2ClickStream$ = DOMSource.select('.close2').events('click');
const close3ClickStream$ = DOMSource.select('.close3').events('click');
// Return all the streams ready to be subscribed
return {refreshClickStream$, close1ClickStream$, close2ClickStream$, close3ClickStream$};
}
function createSuggestionStream(refreshClickStream, responseStream, closeClickStream) {function intent(DOM, HTTP) {
return closeClickStream.startWith('startup click') return {
.combineLatest(responseStream, fetchBeers: HTTP.select('fetchBeers').flatten(),
function(click, listBeers) { fetchBeer: HTTP.select('fetchBeer').flatten(),
return listBeers[Math.floor(Math.random()*listBeers.length)]; refresh: DOM.select('.refresh').events('click'),
} refreshOne: DOM.select('.close').events('click')
) .map(e => {
.merge( e.preventDefault();
refreshClickStream.map(function(){ return e.target.dataset.beerNumber;
return null;
}) })
) };
.startWith(null);
}
// Update UI elements every time somethign is streamed
function renderSuggestion(suggestedBeer, selector) {
var suggestionEl = document.querySelector(selector);
if (suggestedBeer != null) {
suggestionEl.style.visibility = 'visible';
var usernameEl = suggestionEl.querySelector('.username');
usernameEl.textContent = suggestedBeer.name;
var imgEl = suggestionEl.querySelector('img');
imgEl.src = suggestedBeer.image_url;
var descriptionEl = suggestionEl.querySelector('.description');
descriptionEl.textContent = suggestedBeer.description;
}
}}
// Subscribe the observers to API resultsfunction model(actions) {
function model(refreshClickStream$, close1ClickStream$, close2ClickStream$, close3ClickStream$) { const allBeers$ = actions.fetchBeers
var requestStream = refreshClickStream$.startWith('startup click') .map(res => res.body)
.map(function() { .map(beers => [ getRandomItem(beers), getRandomItem(beers), getRandomItem(beers) ])
return 'https://api.punkapi.com/v2/beers'; .startWith([]);
}); const singleBeer$ = actions.fetchBeer
.map(res => [ getRandomItem(res.body), res.request.beerNumber ])
var responseStream = requestStream .startWith([]);
.flatMap(function(requestUrl) { return xs.combine(allBeers$, singleBeer$)
return Rx.Observable.fromPromise($.getJSON(requestUrl)); .map(([ allBeers, [ beer, beerNumber ] ]) => {
if (beer) allBeers[beerNumber - 1] = beer;
return allBeers;
}); });
var suggestion1Stream = createSuggestionStream(refreshClickStream$, responseStream, close1ClickStream$);
var suggestion2Stream = createSuggestionStream(refreshClickStream$, responseStream, close2ClickStream$);
var suggestion3Stream = createSuggestionStream(refreshClickStream$, responseStream, close3ClickStream$);
suggestion1Stream.subscribe(function(suggestedBeer) {
renderSuggestion(suggestedBeer, '.suggestion1');
});
suggestion2Stream.subscribe(function(suggestedBeer) {
renderSuggestion(suggestedBeer, '.suggestion2');
});
suggestion3Stream.subscribe(function(suggestedBeer) {
renderSuggestion(suggestedBeer, '.suggestion3');
});
return responseStream.merge(suggestion1Stream)
.merge(suggestion2Stream)
.merge(suggestion3Stream);
}}
// Render the view
function view(state$) {function view(state$) {
return state$.map(state => return state$.map(([beer1, beer2, beer3]) => h('div', [
div([ h('div.header', [
div('.info', [ h('h2', 'Brewdog\'s beer'),
p('Developed by Anderson Leite using RxJS and Cycle.js'), h('a.refresh', { attrs: { href: '#' } } , 'refresh')
p('See the 3 part blog post') ]),
h('div.containerx', [
h('div.left.box', [
h('li.suggestion1', [
renderBeer(beer1, 1)
])
]), ]),
div('.header', [ h('div.middle.box', [
h2('Brewdog\'s beer'), h('li.suggestion2', [
a('.refresh', {href: '#'}, 'refresh') renderBeer(beer2, 2)
])
]), ]),
div('.containerx', [ h('div.right.box', [
h('li.suggestion3', [
div('.left .box', [ renderBeer(beer3, 3)
h('li.suggestion1', [
div('.beer', [
img()
]),
p('.username', 'loading...'),
p('.description', 'loading...'),
a('.close .close1', {href: '#'}, 'show me other')
])
]),
div('.middle .box', [
h('li.suggestion2', [
div('.beer', [
img()
]),
p('.username', 'loading...'),
p('.description', 'loading...'),
a('.close .close2', {href: '#'}, 'show me other')
])
]),
div('.right .box', [
h('li.suggestion3', [
div('.beer', [
img()
]),
p('.username', 'loading...'),
p('.description', 'loading...'),
a('.close .close3', {href: '#'}, 'show me other')
])
]) ])
]) ])
]) ])
) ]));
}
function renderBeer(beer, beerNumber) {
return h('div', [
h('div.beer', [
h('img', { attrs: beer ? { src: beer.image_url } : null })
]),
h('p.username', beer ? beer.name : 'loading...'),
h('p.description', beer ? beer.description : 'loading...'),
h('a.close', { attrs: { 'data-beer-number': beerNumber, href: '#' } }, 'show me other')
]);
}}
function main(sources) {function main(sources) {
const {refreshClickStream$, close1ClickStream$, close2ClickStream$, close3ClickStream$} = intent(sources.DOM); const actions = intent(sources.DOM, sources.HTTP);
const state$ = model(refreshClickStream$, close1ClickStream$, close2ClickStream$, close3ClickStream$); const beersRequest$ = actions.refresh
const vtree$ = view(Rx.Observable.of('')); .startWith()
.mapTo({ url: 'https://api.punkapi.com/v2/beers', category: 'fetchBeers' });
const beerRequest$ = actions.refreshOne
.map(beerNumber => ({ url: 'https://api.punkapi.com/v2/beers', category: 'fetchBeer', beerNumber }));
const request$ = xs.merge(beersRequest$, beerRequest$);
return { return {
DOM: vtree$ DOM: view(model(actions)),
HTTP: request$
}; };
}}
const drivers = {run(main, {
DOM: makeDOMDriver('#app') DOM: makeDOMDriver('#app'),
}; HTTP: makeHTTPDriver()
});
Cycle.run(main, drivers);
original text
changed text