-137 Removals
+86 Additions
1const {div, li, img, h, h2, p, a, makeDOMDriver} = CycleDOM;1const { run } = Cycle;
2const { makeDOMDriver, h } = CycleDOM;
3const { makeHTTPDriver } = CycleHTTPDriver;
4const xs = xstream.default;
25
3function intent(DOMSource) {6const getRandomItem = arr => arr[Math.floor(Math.random() * arr.length)];
4 // Create streams for the intents that will be observed
5 const refreshClickStream$ = DOMSource.select('.refresh').events('click');
6 const close1ClickStream$ = DOMSource.select('.close1').events('click');
7 const close2ClickStream$ = DOMSource.select('.close2').events('click');
8 const close3ClickStream$ = DOMSource.select('.close3').events('click');
9
10 // Return all the streams ready to be subscribed
11 return {refreshClickStream$, close1ClickStream$, close2ClickStream$, close3ClickStream$};
12}
137
14function createSuggestionStream(refreshClickStream, responseStream, closeClickStream) {8function intent(DOM, HTTP) {
15 return closeClickStream.startWith('startup click')9 return {
16 .combineLatest(responseStream,10 fetchBeers: HTTP.select('fetchBeers').flatten(),
17 function(click, listBeers) {11 fetchBeer: HTTP.select('fetchBeer').flatten(),
18 return listBeers[Math.floor(Math.random()*listBeers.length)];12 refresh: DOM.select('.refresh').events('click'),
19 }13 refreshOne: DOM.select('.close').events('click')
20 )14 .map(e => {
21 .merge(15 e.preventDefault();
22 refreshClickStream.map(function(){16 return e.target.dataset.beerNumber;
23 return null;
24 })17 })
25 )18 };
26 .startWith(null);
27}
28
29// Update UI elements every time somethign is streamed
30function renderSuggestion(suggestedBeer, selector) {
31 var suggestionEl = document.querySelector(selector);
32 if (suggestedBeer != null) {
33 suggestionEl.style.visibility = 'visible';
34 var usernameEl = suggestionEl.querySelector('.username');
35 usernameEl.textContent = suggestedBeer.name;
36 var imgEl = suggestionEl.querySelector('img');
37 imgEl.src = suggestedBeer.image_url;
38 var descriptionEl = suggestionEl.querySelector('.description');
39 descriptionEl.textContent = suggestedBeer.description;
40 }
41}19}
4220
43// Subscribe the observers to API results21function model(actions) {
44function model(refreshClickStream$, close1ClickStream$, close2ClickStream$, close3ClickStream$) {22 const allBeers$ = actions.fetchBeers
45 var requestStream = refreshClickStream$.startWith('startup click')23 .map(res => res.body)
46 .map(function() {24 .map(beers => [ getRandomItem(beers), getRandomItem(beers), getRandomItem(beers) ])
47 return 'https://api.punkapi.com/v2/beers';25 .startWith([]);
48 });26 const singleBeer$ = actions.fetchBeer
4927 .map(res => [ getRandomItem(res.body), res.request.beerNumber ])
50 var responseStream = requestStream28 .startWith([]);
51 .flatMap(function(requestUrl) {29 return xs.combine(allBeers$, singleBeer$)
52 return Rx.Observable.fromPromise($.getJSON(requestUrl));30 .map(([ allBeers, [ beer, beerNumber ] ]) => {
31 if (beer) allBeers[beerNumber - 1] = beer;
32 return allBeers;
53 });33 });
54
55 var suggestion1Stream = createSuggestionStream(refreshClickStream$, responseStream, close1ClickStream$);
56 var suggestion2Stream = createSuggestionStream(refreshClickStream$, responseStream, close2ClickStream$);
57 var suggestion3Stream = createSuggestionStream(refreshClickStream$, responseStream, close3ClickStream$);
58
59 suggestion1Stream.subscribe(function(suggestedBeer) {
60 renderSuggestion(suggestedBeer, '.suggestion1');
61 });
62
63 suggestion2Stream.subscribe(function(suggestedBeer) {
64 renderSuggestion(suggestedBeer, '.suggestion2');
65 });
66
67 suggestion3Stream.subscribe(function(suggestedBeer) {
68 renderSuggestion(suggestedBeer, '.suggestion3');
69 });
70
71 return responseStream.merge(suggestion1Stream)
72 .merge(suggestion2Stream)
73 .merge(suggestion3Stream);
74}34}
7535
76// Render the view
77function view(state$) {36function view(state$) {
78 return state$.map(state =>37 return state$.map(([beer1, beer2, beer3]) => h('div', [
79 div([38 h('div.header', [
80 div('.info', [39 h('h2', 'Brewdog\'s beer'),
81 p('Developed by Anderson Leite using RxJS and Cycle.js'),40 h('a.refresh', { attrs: { href: '#' } } , 'refresh')
82 p('See the 3 part blog post')41 ]),
42 h('div.containerx', [
43 h('div.left.box', [
44 h('li.suggestion1', [
45 renderBeer(beer1, 1)
46 ])
83 ]),47 ]),
84 div('.header', [48 h('div.middle.box', [
85 h2('Brewdog\'s beer'),49 h('li.suggestion2', [
86 a('.refresh', {href: '#'}, 'refresh')50 renderBeer(beer2, 2)
51 ])
87 ]),52 ]),
88 div('.containerx', [53 h('div.right.box', [
8954 h('li.suggestion3', [
90 div('.left .box', [55 renderBeer(beer3, 3)
91 h('li.suggestion1', [
92 div('.beer', [
93 img()
94 ]),
95 p('.username', 'loading...'),
96 p('.description', 'loading...'),
97 a('.close .close1', {href: '#'}, 'show me other')
98 ])
99 ]),
100
101 div('.middle .box', [
102 h('li.suggestion2', [
103 div('.beer', [
104 img()
105 ]),
106 p('.username', 'loading...'),
107 p('.description', 'loading...'),
108 a('.close .close2', {href: '#'}, 'show me other')
109 ])
110 ]),
111
112 div('.right .box', [
113 h('li.suggestion3', [
114 div('.beer', [
115 img()
116 ]),
117 p('.username', 'loading...'),
118 p('.description', 'loading...'),
119 a('.close .close3', {href: '#'}, 'show me other')
120 ])
121 ])56 ])
122
123 ])57 ])
124 ])58 ])
125 )59 ]));
60}
61
62function renderBeer(beer, beerNumber) {
63 return h('div', [
64 h('div.beer', [
65 h('img', { attrs: beer ? { src: beer.image_url } : null })
66 ]),
67 h('p.username', beer ? beer.name : 'loading...'),
68 h('p.description', beer ? beer.description : 'loading...'),
69 h('a.close', { attrs: { 'data-beer-number': beerNumber, href: '#' } }, 'show me other')
70 ]);
126}71}
12772
128function main(sources) {73function main(sources) {
129 const {refreshClickStream$, close1ClickStream$, close2ClickStream$, close3ClickStream$} = intent(sources.DOM);74 const actions = intent(sources.DOM, sources.HTTP);
130 const state$ = model(refreshClickStream$, close1ClickStream$, close2ClickStream$, close3ClickStream$);75 const beersRequest$ = actions.refresh
131 const vtree$ = view(Rx.Observable.of(''));76 .startWith()
13277 .mapTo({ url: 'https://api.punkapi.com/v2/beers', category: 'fetchBeers' });
78 const beerRequest$ = actions.refreshOne
79 .map(beerNumber => ({ url: 'https://api.punkapi.com/v2/beers', category: 'fetchBeer', beerNumber }));
80 const request$ = xs.merge(beersRequest$, beerRequest$);
81
133 return {82 return {
134 DOM: vtree$83 DOM: view(model(actions)),
84 HTTP: request$
135 };85 };
136}86}
13787
138const drivers = {88run(main, {
139 DOM: makeDOMDriver('#app')89 DOM: makeDOMDriver('#app'),
140};90 HTTP: makeHTTPDriver()
14191});
142Cycle.run(main, drivers);
Editor
Original Text
Changed Text
Recommended videos