From b0fcfe1898ba5a7b5a740f4fafe998a050353d07 Mon Sep 17 00:00:00 2001 From: ctide Date: Fri, 10 Apr 2015 14:26:38 -0700 Subject: [PATCH] v1 --- Gemfile | 2 +- Gemfile.lock | 2 +- app/assets/javascripts/app.js | 109 ++++++++++++------ app/assets/javascripts/application.js | 1 + .../javascripts/collections/lineup_items.js | 5 +- .../components/schedule_component.js.jsx | 14 ++- app/assets/javascripts/models/lineup_item.js | 15 ++- app/views/layouts/application.html.erb | 44 +++++++ 8 files changed, 148 insertions(+), 44 deletions(-) diff --git a/Gemfile b/Gemfile index 5941dc4..94c606b 100644 --- a/Gemfile +++ b/Gemfile @@ -20,7 +20,7 @@ gem 'turbolinks' gem 'jbuilder', '~> 2.0' # bundle exec rake doc:rails generates the API under doc/api. gem 'sdoc', '~> 0.4.0', group: :doc -gem 'react-rails' +gem 'react-rails', '~> 1.0' # Use ActiveModel has_secure_password # gem 'bcrypt', '~> 3.1.7' diff --git a/Gemfile.lock b/Gemfile.lock index e897a21..2c058d5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -158,7 +158,7 @@ DEPENDENCIES jbuilder (~> 2.0) jquery-rails rails (= 4.2.0) - react-rails + react-rails (~> 1.0) sass-rails (~> 5.0) sdoc (~> 0.4.0) spring diff --git a/app/assets/javascripts/app.js b/app/assets/javascripts/app.js index 73e06e3..c340204 100644 --- a/app/assets/javascripts/app.js +++ b/app/assets/javascripts/app.js @@ -6,54 +6,95 @@ } var setupSchedule = function() { + if (localStorage['liveChannels']) { + App.Data.liveChannels = new App.Collections.LineupItems(JSON.parse(localStorage['liveChannels'])); + } else { + App.Data.liveChannels = new App.Collections.LineupItems(); + } + App.Data.channels = new App.Collections.Channels([ - {id: 1, name: 'Channel 1', url: ''}, - {id: 2, name: 'Channel 2', url: ''}, - {id: 3, name: 'Channel 3', url: ''} + {id: 1, name: 'Channel 1', videoId: '0-g994f5tS8'}, + {id: 2, name: 'Channel 2', videoId: 'D7ImOXSKFpE'}, + {id: 3, name: 'Channel 3', videoId: 'HC5sCm6Mg40'} ]) App.Data.friday = new App.Collections.LineupItems([ - {time: moment('2015-04-10 15:35 -0700'), artist: {name: 'Haerts'}, where: App.Data.channels.one()}, - {time: moment('2015-04-10 15:35 -0700'), artist: {name: 'Eagulls'}, where: App.Data.channels.two()}, - {time: moment('2015-04-10 15:35 -0700'), artist: {name: 'Cloud Nothings'}, where: App.Data.channels.three()}, - {time: moment('2015-04-10 16:10 -0700'), artist: {name: 'Reverend Horton Heat'}, where: App.Data.channels.one()}, - {time: moment('2015-04-10 16:25 -0700'), artist: {name: 'Brant Bjork and the Low Desert Punk Band'}, where: App.Data.channels.two()}, - {time: moment('2015-04-10 16:50 -0700'), artist: {name: 'George Ezra'}, where: App.Data.channels.one()}, - {time: moment('2015-04-10 17:20 -0700'), artist: {name: 'Sylvan Esso'}, where: App.Data.channels.two()}, - {time: moment('2015-04-10 16:55 -0700'), artist: {name: 'Kieza'}, where: App.Data.channels.three()}, - {time: moment('2015-04-10 17:30 -0700'), artist: {name: 'Charles Bradley and his Extraordinaires'}, where: App.Data.channels.one()}, - {time: moment('2015-04-10 18:10 -0700'), artist: {name: 'Kimbra'}, where: App.Data.channels.two()}, - {time: moment('2015-04-10 18:20 -0700'), artist: {name: 'The War on Drugs'}, where: App.Data.channels.one()}, - {time: moment('2015-04-10 19:10 -0700'), artist: {name: 'Raekwon and Ghostface Killah'}, where: App.Data.channels.two()}, - {time: moment('2015-04-10 18:45 -0700'), artist: {name: 'Hot Natured'}, where: App.Data.channels.three()}, - {time: moment('2015-04-10 19:10 -0700'), artist: {name: 'Alabama Shakes'}, where: App.Data.channels.one()}, - {time: moment('2015-04-10 20:05 -0700'), artist: {name: 'Gorgon City'}, where: App.Data.channels.two()}, - {time: moment('2015-04-10 19:40 -0700'), artist: {name: 'Keys N Krates'}, where: App.Data.channels.three()}, - {time: moment('2015-04-10 20:20 -0700'), artist: {name: 'Interpol'}, where: App.Data.channels.one()}, - {time: moment('2015-04-10 20:50 -0700'), artist: {name: 'Azealia Banks'}, where: App.Data.channels.two()}, - {time: moment('2015-04-10 20:30 -0700'), artist: {name: 'DJ Snake'}, where: App.Data.channels.three()}, - {time: moment('2015-04-10 21:15 -0700'), artist: {name: 'Tame Impala'}, where: App.Data.channels.one()}, - {time: moment('2015-04-10 21:35 -0700'), artist: {name: 'Nero'}, where: App.Data.channels.two()}, - {time: moment('2015-04-10 21:30 -0700'), artist: {name: 'R3hab (Part 1)'}, where: App.Data.channels.three()}, - {time: moment('2015-04-10 22:30 -0700'), artist: {name: 'Lykke Li'}, where: App.Data.channels.two()}, - {time: moment('2015-04-10 22:00 -0700'), artist: {name: 'Porter Robinson'}, where: App.Data.channels.three()}, - {time: moment('2015-04-10 23:20 -0700'), artist: {name: 'Ride'}, where: App.Data.channels.two()}, - {time: moment('2015-04-10 23:00 -0700'), artist: {name: 'R3hab (Part 2)'}, where: App.Data.channels.three()}, - {time: moment('2015-04-11 00:05 -0700'), artist: {name: 'Todd Terje and the Olsens'}, where: App.Data.channels.two()}, - {time: moment('2015-04-10 23:35 -0700'), artist: {name: 'Alesso'}, where: App.Data.channels.three()}, - ]); + {id: 1, time: moment('2015-04-10 15:35 -0700'), artist: {name: 'Haerts'}, channel: App.Data.channels.one()}, + {id: 2, time: moment('2015-04-10 15:35 -0700'), artist: {name: 'Eagulls'}, channel: App.Data.channels.two()}, + {id: 3, time: moment('2015-04-10 15:35 -0700'), artist: {name: 'Cloud Nothings'}, channel: App.Data.channels.three()}, + {id: 4, time: moment('2015-04-10 16:10 -0700'), artist: {name: 'Reverend Horton Heat'}, channel: App.Data.channels.one()}, + {id: 5, time: moment('2015-04-10 16:25 -0700'), artist: {name: 'Brant Bjork and the Low Desert Punk Band'}, channel: App.Data.channels.two()}, + {id: 6, time: moment('2015-04-10 16:50 -0700'), artist: {name: 'George Ezra'}, channel: App.Data.channels.one()}, + {id: 7, time: moment('2015-04-10 17:20 -0700'), artist: {name: 'Sylvan Esso'}, channel: App.Data.channels.two()}, + {id: 8, time: moment('2015-04-10 16:55 -0700'), artist: {name: 'Kieza'}, channel: App.Data.channels.three()}, + {id: 9, time: moment('2015-04-10 17:30 -0700'), artist: {name: 'Charles Bradley and his Extraordinaires'}, channel: App.Data.channels.one()}, + {id: 10, time: moment('2015-04-10 18:10 -0700'), artist: {name: 'Kimbra'}, channel: App.Data.channels.two()}, + {id: 11, time: moment('2015-04-10 18:20 -0700'), artist: {name: 'The War on Drugs'}, channel: App.Data.channels.one()}, + {id: 12, time: moment('2015-04-10 19:10 -0700'), artist: {name: 'Raekwon and Ghostface Killah'}, channel: App.Data.channels.two()}, + {id: 13, time: moment('2015-04-10 18:45 -0700'), artist: {name: 'Hot Natured'}, channel: App.Data.channels.three()}, + {id: 14, time: moment('2015-04-10 19:10 -0700'), artist: {name: 'Alabama Shakes'}, channel: App.Data.channels.one()}, + {id: 15, time: moment('2015-04-10 20:05 -0700'), artist: {name: 'Gorgon City'}, channel: App.Data.channels.two()}, + {id: 16, time: moment('2015-04-10 19:40 -0700'), artist: {name: 'Keys N Krates'}, channel: App.Data.channels.three()}, + {id: 17, time: moment('2015-04-10 20:20 -0700'), artist: {name: 'Interpol'}, channel: App.Data.channels.one()}, + {id: 18, time: moment('2015-04-10 20:50 -0700'), artist: {name: 'Azealia Banks'}, channel: App.Data.channels.two()}, + {id: 19, time: moment('2015-04-10 20:30 -0700'), artist: {name: 'DJ Snake'}, channel: App.Data.channels.three()}, + {id: 20, time: moment('2015-04-10 21:15 -0700'), artist: {name: 'Tame Impala'}, channel: App.Data.channels.one()}, + {id: 21, time: moment('2015-04-10 21:35 -0700'), artist: {name: 'Nero'}, channel: App.Data.channels.two()}, + {id: 22, time: moment('2015-04-10 21:30 -0700'), artist: {name: 'R3hab (Part 1)'}, channel: App.Data.channels.three()}, + {id: 23, time: moment('2015-04-10 22:30 -0700'), artist: {name: 'Lykke Li'}, channel: App.Data.channels.two()}, + {id: 24, time: moment('2015-04-10 22:00 -0700'), artist: {name: 'Porter Robinson'}, channel: App.Data.channels.three()}, + {id: 25, time: moment('2015-04-10 23:20 -0700'), artist: {name: 'Ride'}, channel: App.Data.channels.two()}, + {id: 26, time: moment('2015-04-10 23:00 -0700'), artist: {name: 'R3hab (Part 2)'}, channel: App.Data.channels.three()}, + {id: 27, time: moment('2015-04-11 00:05 -0700'), artist: {name: 'Todd Terje and the Olsens'}, channel: App.Data.channels.two()}, + {id: 28, time: moment('2015-04-10 23:35 -0700'), artist: {name: 'Alesso'}, channel: App.Data.channels.three()}, + ], {parse: true}); } window.App = { init: function() { App.Router = new Router(); + setupSchedule(); setupViews(); Backbone.history.start({ pushState: true, root: '/' }); + App.Dispatcher.on('enableChannel', function(lineupItem) { + App.Data.liveChannels.add(lineupItem); + }); + App.Dispatcher.on('disableChannel', function(lineupItem) { + App.Data.liveChannels.remove(lineupItem); + }); + App.Data.liveChannels.on('add remove', function() { + localStorage['liveChannels'] = JSON.stringify(App.Data.liveChannels.toJSON()); + if (App.Data.nextTimeout) { + clearTimeout(App.Data.nextTimeout); + } + App.updatePlayer(); + }); }, - Data: { - }, + Data: {}, Models: {}, Collections: {}, + updatePlayer: function() { + var active = App.Data.liveChannels.filter(function(lineupItem) { + return lineupItem.get('time') <= moment(); + }).pop(); + + if (active) { + var videoId = active.get('channel').get('videoId'); + if (App.Data.videoId != videoId) { + App.Data.videoId = videoId; + player.loadVideoById(videoId); + } + } + + var nextUp = App.Data.liveChannels.filter(function(lineupItem) { + return lineupItem.get('time') > moment(); + }).shift(); + + if (nextUp) { + var timeDiff = nextUp.get('time') - new moment(); + App.Data.nextTimeout = setTimeout(App.updatePlayer, timeDiff); + } + }, Dispatcher: _.clone(Backbone.Events) } diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 94a52fb..8285566 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -14,6 +14,7 @@ //= require underscore //= require backbone //= require react +//= require moment //= require jquery_ujs //= require turbolinks //= require react.backbone diff --git a/app/assets/javascripts/collections/lineup_items.js b/app/assets/javascripts/collections/lineup_items.js index 73c8f05..10f26b5 100644 --- a/app/assets/javascripts/collections/lineup_items.js +++ b/app/assets/javascripts/collections/lineup_items.js @@ -1 +1,4 @@ -App.Collections.LineupItems = Backbone.Collection.extend({}); +App.Collections.LineupItems = Backbone.Collection.extend({ + comparator: 'time', + model: App.Models.LineupItem +}); diff --git a/app/assets/javascripts/components/schedule_component.js.jsx b/app/assets/javascripts/components/schedule_component.js.jsx index 167d4dd..d20fb7a 100644 --- a/app/assets/javascripts/components/schedule_component.js.jsx +++ b/app/assets/javascripts/components/schedule_component.js.jsx @@ -1,8 +1,8 @@ var ScheduleComponent = React.createBackboneClass({ - var lineItems = this.getCollection().map(function(lineItem) { - return - }); render: function() { + var lineItems = this.getCollection().map(function(lineItem) { + return + }); return ( { lineItems } @@ -13,17 +13,19 @@ var ScheduleComponent = React.createBackboneClass({ var LineupItemComponent = React.createBackboneClass({ getInitialState: function() { - { val: false } + return { val: !!App.Data.liveChannels.findWhere({id: this.getModel().get('id')}) } }, toggleState: function() { this.setState({val: !this.state.val}); + this.getModel().toggleState(); }, render: function() { + console.log(this.state.val); return ( - + - + ) } diff --git a/app/assets/javascripts/models/lineup_item.js b/app/assets/javascripts/models/lineup_item.js index 77fe128..54f2a9b 100644 --- a/app/assets/javascripts/models/lineup_item.js +++ b/app/assets/javascripts/models/lineup_item.js @@ -1 +1,14 @@ -App.Models.LineupItem = Backbone.Model.extend({}); +App.Models.LineupItem = Backbone.Model.extend({ + parse: function(data) { + this.artist = new App.Models.Artist(data.artist); + return _.omit(data, 'artist'); + }, + toggleState: function() { + this.set('enabled', !this.get('enabled')); + if (this.get('enabled')) { + App.Dispatcher.trigger('enableChannel', this); + } else { + App.Dispatcher.trigger('disableChannel', this); + } + } +}); diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index d17effb..da4e66c 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -8,8 +8,52 @@ +
+
+
{ this.getModel().get('time').format('h:mm a') }{ this.getModel().get('name') }{ this.getModel().artist.get('name') }