Untitled diff

Created Diff never expires
127 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
142 lines
76 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
91 lines
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 results
function 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);