/9-final-no-server/public/js/Tunes.js
JavaScript | 347 lines | 279 code | 65 blank | 3 comment | 17 complexity | 58994e42457c0fb6e32249ffbef1a145 MD5 | raw file
- (function($) {
- window.Album = Backbone.Model.extend({
- isFirstTrack: function(index) {
- return index == 0;
- },
- isLastTrack: function(index) {
- return index >= this.get('tracks').length - 1;
- },
- trackUrlAtIndex: function(index) {
- if (this.get('tracks').length >= index) {
- return this.get('tracks')[index].url;
- }
- return null;
- }
- });
- window.Albums = Backbone.Collection.extend({
- model: Album,
- url: "/albums"
- });
- window.Playlist = Albums.extend({
- isFirstAlbum: function(index) {
- return (index == 0)
- },
-
- isLastAlbum: function(index) {
- return (index == (this.models.length - 1))
- }
- });
- window.Player = Backbone.Model.extend({
- defaults: {
- 'currentAlbumIndex': 0,
- 'currentTrackIndex': 0,
- 'state': 'stop'
- },
-
- initialize: function() {
- this.playlist = new Playlist();
- },
-
- play: function() {
- this.set({'state': 'play'});
- this.trigger('change:currentTrackIndex');
- this.logCurrentAlbumAndTrack();
- },
- pause: function() {
- this.set({'state': 'pause'});
- },
- isPlaying: function() {
- return (this.get('state') == 'play');
- },
-
- isStopped: function() {
- return (!this.isPlaying());
- },
- currentAlbum: function() {
- return this.playlist.at(this.get('currentAlbumIndex'));
- },
- currentTrackUrl: function() {
- var album = this.currentAlbum();
- return album.trackUrlAtIndex(this.get('currentTrackIndex'));
- },
- nextTrack: function() {
- var currentTrackIndex = this.get('currentTrackIndex'),
- currentAlbumIndex = this.get('currentAlbumIndex');
- if (this.currentAlbum().isLastTrack(currentTrackIndex)) {
- if (this.playlist.isLastAlbum(currentAlbumIndex)) {
- this.set({'currentAlbumIndex': 0});
- this.set({'currentTrackIndex': 0});
- } else {
- this.set({'currentAlbumIndex': currentAlbumIndex + 1});
- this.set({'currentTrackIndex': 0});
- }
- } else {
- this.set({'currentTrackIndex': currentTrackIndex + 1});
- }
- this.logCurrentAlbumAndTrack();
- },
- prevTrack: function() {
- var currentTrackIndex = this.get('currentTrackIndex'),
- currentAlbumIndex = this.get('currentAlbumIndex'),
- lastModelIndex = 0;
- if (this.currentAlbum().isFirstTrack(currentTrackIndex)) {
- if (this.playlist.isFirstAlbum(currentAlbumIndex)) {
- lastModelIndex = this.playlist.models.length - 1;
- this.set({'currentAlbumIndex': lastModelIndex});
- } else {
- this.set({'currentAlbumIndex': currentAlbumIndex - 1});
- }
- // In either case, go to last track on album
- var lastTrackIndex =
- this.currentAlbum().get('tracks').length - 1;
- this.set({'currentTrackIndex': lastTrackIndex});
- } else {
- this.set({'currentTrackIndex': currentTrackIndex - 1});
- }
- this.logCurrentAlbumAndTrack();
- },
-
- logCurrentAlbumAndTrack: function() {
- console.log("Player " +
- this.get('currentAlbumIndex') + ':' +
- this.get('currentTrackIndex'), this);
- }
-
- });
- window.library = new Albums();
- window.player = new Player();
- window.AlbumView = Backbone.View.extend({
- template: "#album-template",
- tag: 'li',
- className: 'album',
- initialize: function() {
- _.bindAll(this, 'render');
- this.initializeTemplate();
- },
-
- initializeTemplate: function() {
- this.template = _.template($(this.template).html());
- },
- render: function() {
- $(this.el).html(this.template(this.model.toJSON()));
- return this;
- }
- });
- window.PlaylistAlbumView = AlbumView.extend({
- events: {
- 'click .queue.remove': 'removeFromPlaylist'
- },
- initialize: function() {
- _.bindAll(this, 'render',
- 'updateState',
- 'updateTrack',
- 'remove');
- this.initializeTemplate();
- this.player = this.options.player;
- this.player.bind('change:state', this.updateState);
- this.player.bind('change:currentTrackIndex', this.updateTrack);
- this.model.bind('remove', this.remove);
- },
- render: function() {
- $(this.el).html(this.template(this.model.toJSON()));
- this.updateTrack();
- return this;
- },
- updateState: function() {
- var isAlbumCurrent = (this.player.currentAlbum() === this.model);
- $(this.el).toggleClass('current', isAlbumCurrent);
- },
- updateTrack: function() {
- var isAlbumCurrent = (this.player.currentAlbum() === this.model);
- if (isAlbumCurrent) {
- var currentTrackIndex = this.player.get('currentTrackIndex');
- this.$("li").each(function(index, el) {
- $(el).toggleClass('current', index == currentTrackIndex);
- });
- }
- this.updateState();
- },
- removeFromPlaylist: function() {
- this.options.playlist.remove(this.model);
- }
- });
- window.LibraryAlbumView = AlbumView.extend({
- events: {
- 'click .queue.add': 'select'
- },
- select: function() {
- this.collection.trigger('select', this.model);
- }
- });
- window.PlaylistView = Backbone.View.extend({
- tag: 'section',
- className: 'playlist',
- events: {
- 'click .play': 'play',
- 'click .pause': 'pause',
- 'click .next': 'nextTrack',
- 'click .prev': 'prevTrack'
- },
- initialize: function() {
- _.bindAll(this, 'render',
- 'renderAlbum',
- 'updateTrack',
- 'queueAlbum');
- this.template = _.template($("#playlist-template").html());
- this.collection.bind('reset', this.render);
- this.collection.bind('add', this.renderAlbum);
- // TODO: May need to bind to currentAlbumIndex too
- this.player = this.options.player;
- this.player.bind('change:currentTrackIndex', this.updateTrack);
- this.createAudio();
- this.library = this.options.library;
- this.library.bind('select', this.queueAlbum);
- },
- createAudio: function() {
- this.audio = new Audio();
- },
- render: function() {
- $(this.el).html(this.template(this.player.toJSON()));
- this.collection.each(this.renderAlbum);
- this.$("button.play").toggle(this.player.isStopped());
- this.$("button.pause").toggle(this.player.isPlaying());
- return this;
- },
- renderAlbum: function(album) {
- var view = new PlaylistAlbumView({
- model: album,
- player: this.player,
- playlist: this.collection
- });
- this.$("ul").append(view.render().el);
- },
- updateTrack: function() {
- this.audio.src = this.player.currentTrackUrl();
- if (this.player.get('state') == 'play') { this.audio.play(); }
- },
- queueAlbum: function(album) {
- this.collection.add(album);
- },
- play: function() {
- this.player.play();
- this.audio.play();
- this.$("button.play").hide();
- this.$("button.pause").show();
- },
- pause: function() {
- this.player.pause();
- this.audio.pause();
- this.$("button.pause").hide();
- this.$("button.play").show();
- },
- nextTrack: function() {
- this.player.nextTrack();
- },
- prevTrack: function() {
- this.player.prevTrack();
- }
- });
- window.LibraryView = Backbone.View.extend({
- tagName: 'section',
- className: 'library',
- initialize: function() {
- _.bindAll(this, 'render');
- this.template = _.template($('#library-template').html());
- this.collection.bind('reset', this.render);
- },
- render: function() {
- var $albums,
- collection = this.collection;
- $(this.el).html(this.template({}));
- $albums = this.$(".albums");
- this.collection.each(function(album) {
- var view = new LibraryAlbumView({ model: album,
- collection: collection });
- $albums.append(view.render().el);
- });
- return this;
- }
- });
- window.BackboneTunes = Backbone.Router.extend({
- routes: {
- '': 'home',
- 'blank': 'blank'
- },
- initialize: function() {
- this.playlistView = new PlaylistView({
- collection: window.player.playlist,
- player: window.player,
- library: window.library });
- this.libraryView = new LibraryView({
- collection: window.library });
- },
- home: function() {
- $('#container').empty();
- $("#container").append(this.playlistView.render().el);
- $("#container").append(this.libraryView.render().el);
- },
- blank: function() {
- $('#container').empty();
- $('#container').text('blank');
- }
- });
- $(document).ready(function() {
- window.App = new BackboneTunes();
- Backbone.history.start({pushState: true});
- window.App.home();
- });
- })(jQuery);
- // vim:sw=4:ts=4:expandtab