137 removals
86 additions
1.const {div, li, img, h, h2, p, a, makeDOMDriver} = CycleDOM;1.const { run } = Cycle;
2.const { makeDOMDriver, h } = CycleDOM;
3.const { makeHTTPDriver } = CycleHTTPDriver;
4.const xs = xstream.default;
2.5.
3.function intent(DOMSource) {6.const 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.}
13.7.
14.function createSuggestionStream(refreshClickStream, responseStream, closeClickStream) {8.function 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
30.function 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.}
42.20.
43.// Subscribe the observers to API results21.function model(actions) {
44.function 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
49.27. .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.}
75.35.
76.// Render the view
77.function view(state$) {36.function 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', [
89.54. 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.
62.function 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.}
127.72.
128.function main(sources) {73.function 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()
132.77. .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.}
137.87.
138.const drivers = {88.run(main, {
139. DOM: makeDOMDriver('#app')89. DOM: makeDOMDriver('#app'),
140.};90. HTTP: makeHTTPDriver()
141.91.});
142.Cycle.run(main, drivers);
original text
changed text