index.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. var Cycle = require('cyclejs');
  2. var Rx = Cycle.Rx;
  3. var h = Cycle.h;
  4. var about = require('./templates/about');
  5. var nav = [
  6. {partial: 'about', name: 'About'},
  7. {partial: 'chatRoom', name: 'Chat'},
  8. {partial: 'contribute', name: 'Contribute'}
  9. ];
  10. function intent(drivers) {
  11. var DOM = drivers.DOM;
  12. return {
  13. disconnect$: DOM.get('#disconnect', 'click'),
  14. username$: DOM.get('#username', 'input').map(function(ev) {
  15. return ev.target.value;
  16. }),
  17. login$: DOM.get('#login-form', 'submit').map(function(ev) {
  18. ev.preventDefault();
  19. return true;
  20. })
  21. };
  22. }
  23. function model(actions) {
  24. return {
  25. username$: actions.login$
  26. .withLatestFrom(actions.username$, function(submit, username) {
  27. return username;
  28. })
  29. .merge(actions.disconnect$.map(function() { return null; }))
  30. .startWith(null)
  31. ,
  32. route$: Rx.Observable.fromEvent(window, 'hashchange')
  33. .map(function(hashEvent) { return hashEvent.target.location.hash.replace('#', '') })
  34. .startWith(window.location.hash.replace('#', '') || 'about')
  35. }
  36. }
  37. function renderLogin(username) {
  38. var content;
  39. if(!username) {
  40. content = [ h('a.navbar-link', {href: '#chatRoom'}, ['Play!']) ];
  41. }
  42. if(username) {
  43. content = [
  44. "Logged in as "+username+" — ",
  45. h('a.navbar-link#disconnect', ['Disconnect'])
  46. ];
  47. }
  48. return h('div', {className: 'navbar-right collapse navbar-collapse'}, [
  49. h('p.navbar-text', content)
  50. ]);
  51. }
  52. function renderNav(route, username) {
  53. return (
  54. h('nav', {className: 'navbar navbar-inverse navbar-static-top', role: 'navigation'}, [
  55. h('div.container', [
  56. h('div.navbar-header', [
  57. h('span.brand.navbar-brand', ["Game 'n Chat"])
  58. ]),
  59. h('ul', {className: 'nav navbar-nav collapse navbar-collapse'}, nav.map(function(item) {
  60. var className = '';
  61. if(item.partial == route) {
  62. className = 'active';
  63. }
  64. return h('li', {className: className}, [
  65. h('a', {href: '#'+item.partial}, [ item.name ])
  66. ]);
  67. })),
  68. renderLogin(username)
  69. ]),
  70. ])
  71. )
  72. }
  73. function renderFooter() {
  74. return h('footer', [
  75. h('p', [
  76. h('a', {href: 'http://twitter.com/pleasantprog', target: '_blank'}, ['@pleasantprog'])
  77. ])
  78. ]);
  79. }
  80. function renderContainer(route) {
  81. var content = require('./templates/'+route)();
  82. return h('div.container', [
  83. h('div.content', [content]),
  84. renderFooter()
  85. ]);
  86. }
  87. function view(model) {
  88. return Rx.Observable.combineLatest(
  89. model.route$,
  90. model.username$,
  91. function(route, username) {
  92. return h('div', [
  93. renderNav(route, username),
  94. renderContainer(route)
  95. ]);
  96. }
  97. );
  98. }
  99. function main(drivers) {
  100. return { DOM: view(model(intent(drivers))) };
  101. }
  102. Cycle.run(main, {
  103. DOM: Cycle.makeDOMDriver('body')
  104. });