Skip to content

Commit

Permalink
v1
Browse files Browse the repository at this point in the history
  • Loading branch information
ctide committed Apr 10, 2015
1 parent 5c67b61 commit b0fcfe1
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 44 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
109 changes: 75 additions & 34 deletions app/assets/javascripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
1 change: 1 addition & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
//= require underscore
//= require backbone
//= require react
//= require moment
//= require jquery_ujs
//= require turbolinks
//= require react.backbone
Expand Down
5 changes: 4 additions & 1 deletion app/assets/javascripts/collections/lineup_items.js
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
App.Collections.LineupItems = Backbone.Collection.extend({});
App.Collections.LineupItems = Backbone.Collection.extend({
comparator: 'time',
model: App.Models.LineupItem
});
14 changes: 8 additions & 6 deletions app/assets/javascripts/components/schedule_component.js.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
var ScheduleComponent = React.createBackboneClass({
var lineItems = this.getCollection().map(function(lineItem) {
return <LineupItemComponent model={ lineItem }/>
});
render: function() {
var lineItems = this.getCollection().map(function(lineItem) {
return <LineupItemComponent model={ lineItem }/>
});
return (
<table className='schedule'>
{ lineItems }
Expand All @@ -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 (
<tr className='line-item'>
<td className='checkbox'><input type='checkbox' onChange={this.toggleState} value={this.state.val}></input></td>
<td className='checkbox'><input type='checkbox' onChange={this.toggleState} checked={this.state.val}></input></td>
<td className='time'>{ this.getModel().get('time').format('h:mm a') }</td>
<td className='artist'>{ this.getModel().get('name') }</td>
<td className='artist'>{ this.getModel().artist.get('name') }</td>
</tr>
)
}
Expand Down
15 changes: 14 additions & 1 deletion app/assets/javascripts/models/lineup_item.js
Original file line number Diff line number Diff line change
@@ -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);
}
}
});
44 changes: 44 additions & 0 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,52 @@
</head>
<body>

<div id='player'>
</div>
<div class='contents'>
</div>

</body>
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');

tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'TLknyzCPtZQ',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}

// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}

// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</html>

0 comments on commit b0fcfe1

Please sign in to comment.