guide.coffee 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #
  2. # Config
  3. #
  4. #FETCH_URL = 'http://www.tvgids.nl/json/lists/programs.php'
  5. FETCH_URL = 'programs.php'
  6. HOUR_WIDTH = 200
  7. SCROLL_MULTIPLIER = HOUR_WIDTH
  8. #
  9. # Utils
  10. #
  11. seconds_today = (time) -> (time - (new Date()).setHours(0, 0, 0, 0)) / 1000
  12. time2px = (seconds) -> HOUR_WIDTH / 3600 * seconds
  13. zeropad = (digit) -> if digit < 10 then '0' + digit else String(digit)
  14. format_time = (time) ->
  15. date = new Date(time)
  16. zeropad(date.getHours()) + ':' + zeropad(date.getMinutes())
  17. #
  18. # Models & collections
  19. #
  20. Channel = Backbone.Model.extend(
  21. defaults: ->
  22. id: null
  23. name: 'Some channel'
  24. visible: true
  25. programs: []
  26. )
  27. Program = Backbone.Model.extend(
  28. defaults: ->
  29. title: 'Some program'
  30. genre: ''
  31. sort: ''
  32. start: 0
  33. end: 0
  34. #article_id: null
  35. #article_title: null
  36. )
  37. ChannelList = Backbone.Collection.extend(
  38. model: Channel
  39. comparator: 'id'
  40. initialize: (models, options) ->
  41. #_.each(CHANNELS, (props, id) => @add(_.extend({id: id}, props)))
  42. @fetchVisible()
  43. #@fetchPrograms(0)
  44. fetch: ->
  45. @reset(CHANNELS.slice(0,3))
  46. @reset(CHANNELS)
  47. #$.getJSON('channels.php', (data) => @reset(data))
  48. fetchVisible: ->
  49. visible = if localStorage.hasOwnProperty('channels') \
  50. then localStorage.getItem('channels').split(',') else @pluck('id')
  51. @setVisible(visible)
  52. saveVisible: ->
  53. selected = (c.id for c in @channels if c.visible)
  54. localStorage.setItem('channels', selected.join(','))
  55. setVisible: (visible, save=false) ->
  56. for id in visible
  57. @findWhere(id: id).set(visible: true)
  58. for id in _.difference(@pluck('id'), visible)
  59. @findWhere(id: id).set(visible: false)
  60. @saveVisible() if save
  61. fetchPrograms: (day) ->
  62. $.getJSON(
  63. FETCH_URL
  64. channels: @pluck('id').join(','), day: day
  65. (channels) ->
  66. _.each channels, (programs, id) ->
  67. channel = Channels.findWhere(id: id)
  68. channel.set('programs', (
  69. new Program(
  70. title: p.titel
  71. genre: p.genre
  72. sort: p.soort
  73. start: Date.parse(p.datum_start)
  74. end: Date.parse(p.datum_end)
  75. #article_id: p.artikel_id
  76. #article_title: p.artikel_titel
  77. ) for p in programs
  78. ))
  79. )
  80. )
  81. #
  82. # Views
  83. #
  84. ChannelView = Backbone.View.extend(
  85. tagName: 'div'
  86. className: 'channel'
  87. #template: _.template($('#channel-template').html())
  88. initialize: ->
  89. @listenTo(@model, 'change:programs', @render)
  90. @listenTo(@model, 'change:visible', @toggleVisible)
  91. #@$el.text(@model.get('title'))
  92. render: ->
  93. @$el.empty()
  94. _.each @model.get('programs'), (program) =>
  95. view = new ProgramView(model: program)
  96. view.render()
  97. @$el.append(view.el)
  98. toggleVisible: ->
  99. @$el.toggle(@model.get('visible'))
  100. )
  101. ProgramView = Backbone.View.extend(
  102. tagName: 'div'
  103. className: 'program'
  104. initialize: ->
  105. @$el.text(@model.get('title'))
  106. from = format_time(@model.get('start'))
  107. to = format_time(@model.get('end'))
  108. @$el.attr('title', @model.get('title') + " (#{from} - #{to})")
  109. left = time2px(Math.max(0, seconds_today(@model.get('start'))))
  110. width = time2px(seconds_today(@model.get('end'))) - left
  111. @$el.css(
  112. left: left + 'px'
  113. width: (width - 10) + 'px'
  114. )
  115. render: ->
  116. if @model.get('start') <= Date.now()
  117. if @model.get('end') < Date.now()
  118. @$el.removeClass('current').addClass('past')
  119. else
  120. @$el.addClass('current')
  121. )
  122. AppView = Backbone.View.extend(
  123. el: $('#guide')
  124. events:
  125. 'click #yesterday': -> @loadDay(-1)
  126. 'click #today': -> @loadDay(0)
  127. 'click #tomorrow': -> @loadDay(1)
  128. initialize: ->
  129. @updateIndicator()
  130. @listenTo(Channels, 'reset', @addChannels)
  131. Channels.fetch()
  132. @listenTo(Settings, 'change:day', @fetchPrograms)
  133. setInterval((=> @updateIndicator()), 3600000 / HOUR_WIDTH)
  134. addChannels: () ->
  135. Channels.each((channel) ->
  136. view = new ChannelView(model: channel)
  137. view.render()
  138. @$('.channels').append(view.el)
  139. , @)
  140. @fetchPrograms()
  141. loadDay: (day) ->
  142. Settings.set(day: day)
  143. @$('.navbar .active').removeClass('active')
  144. $(@$('.navbar .navitem')[day + 1]).addClass('active')
  145. updateIndicator: ->
  146. @$('.indicator').css('left', time2px(seconds_today(Date.now())) + 'px')
  147. fetchPrograms: ->
  148. Channels.fetchPrograms(Settings.get('day'))
  149. )
  150. #
  151. # Main
  152. #
  153. Settings = new (Backbone.Model.extend(
  154. defaults: ->
  155. day: 0
  156. ))()
  157. Channels = new ChannelList()
  158. App = new AppView()