Commits

Adam Gomaa  committed 52da8b8

Some Backbone stuff, always use fresh <audio> tags to fix issues with audioended not firing after changing src.

  • Participants
  • Parent commits d7b909a

Comments (0)

Files changed (3)

File webmusic/templates/music-body.html

-<audio src="" preload="auto" id="audio"></audio>
 <div class="left height-100">
   <div id="artists">
   </div>
   <div id="console"></div>
 </div>
 <div id="templates" style="display:none;">
+<div id="artist-template">
+  <span class="artist-name"><%= name %></span>
+  <span class="artist-counts">(<%= num_albums %>/<%= num_songs %>)</span>
+</div>
 <div id="album-template">
   <span class="album-name"><%= text %></span>
 </div>

File webmusic/templates/music.css

 {position: absolute;}
 body>.left{left:0;}
 body>.right{right:0;}
-.left{width: 67%;}
-.right{width: 33%;}
+/*.left{width: 67%;}
+.right{width: 33%;}*/
+.left{width: 75%;}
+.right{width: 25%;}
 
 #listings>div
 {
 {
     overflow:auto;
     font-family: Liberation Sans;
-    font-size: 15px;
+    font-size: 19px;
     background-color: #000;
 }
 #artists .column{position: absolute; top: 0;}

File webmusic/templates/music.js

         },
         /* This doesn't seem quite kosher. But this way I can catch
          * global keys in the normal declarative way. */
-        el: $(window),
+        el: $(window.document),
         initialize: function(){
             this._inittime = new Date();
             _.bindAll(this, "initBody", "log", "initViews",
             this.url = _music_url
             this.ajax_url = this.url + "_ajax";
             this.media_url = this.url + "getmedia/";
-            /* Currently displayed artist & album */
-            this.current_artist = null;
-            this.current_album = null;
             this.loop = null;
             this.loop_states = [null, 'song', 'album'];
             this.slider_max = 500;
             /* seconds this has run */
             return (new Date() - this._inittime) / 1000;
         },
+        mkaudio: function(){
+            $("body").find("audio").remove()
+            $("body").append("<audio></audio>");
+            this.$audio = $("audio")
+            this.$audio.attr("preload", "auto")
+            this.audio = this.$audio[0];
+
+            this.$audio.bind("canplaythrough", this.startPlayback);
+            this.$audio.bind("timeupdate", this.timeUpdate);
+            this.audio.addEventListener("ended", this.audioEnded)
+            //this.$audio.bind("ended", this.audioEnded);
+        },
         initViews: function(){
-            this.$audio = $("#audio");
-            this.audio = this.$audio[0];
+            this.mkaudio();
             this.console = new ConsoleView({app: this, el: $("#console")});
             this.controls = new ControlsView({app: this, el: $("#controls")});
             this.artists = new ArtistsView({app: this, el: $("#artists")});
             this.albums = new AlbumsView({app: this, el: $("#albums")});
             this.songs = new SongsView({app: this, el: $("#songs")});
-            $(window).bind("resize", this.onResize);
+            $(window).bind("resize", _.debounce(this.onResize, 500));
             //$(window).bind("keydown", this.handleGlobalKey);
             this.onResize();
-
-            this.$audio.bind("canplaythrough", this.startPlayback);
-            this.$audio.bind("timeupdate", this.timeUpdate);
-            this.$audio.bind("ended", this.audioEnded);
-
         },
         onResize: function(){
+            this.log("resizing");
             $("body").css("height", $(window).height());
             this.controls.resizeControls();
+            this.artists.render();
         },
         loadSong: function(song){
+            if(!this.audio.paused){
+                this.controls.playPauseClick();
+            }
             var song_text = song["title"];
             var song_path = song['path'];
             $("title").text(song_text + " - webmusic");
             var src = this.media_url + song.get("_id").$oid;
             this.log("src:" + src)
+            this.mkaudio();
             this.$audio.attr("src", src);
             this.audio.load();
         },
         startPlayback: function(){
-            this.audio.play()
+            this.audio.play();
         },
         seekRatio: function(ratio){
             this.log("seeking to: " + ratio);
             this.log = this.app.log;
             this.post = this.app.post;
         },
-    })
+    });
 
 
     var ConsoleView = AppView.extend({
         },
         initialize: function(options){
             this.constructor.__super__.initialize.apply(this, [options]);
-            _.bindAll(this, "songStart", "slideSeek", "resizeControls",
+            _.bindAll(this, "slideSeek", "resizeControls",
                       "playPauseClick", "clickResize",
                       "clickReindex",
                       "reloadArtists", "reloadCss", "reloadJs", "reloadHtml",
                       "cycleLoopStates");
             this.app.log("ControlsView initializing");
-            this.app.bind("songstart", this.songStart);
             this.$playbtn = this.$("#play-pause");
             this.$playbtn.button();
 
             this.$elapsed = this.$("#elapsed");
             this.$duration = this.$("#duration");
             this.$remaining = this.$("#remaining");
-            this.$current_song = this.$("#current-song");
 
 
             this.$slider = this.$("#slider");
             $(this.el).show();
             this.app.log("ControlsView initialization done")
         },
-        songStart: function(){
-            this.$("#current-song").text(this.app.current_song.get("name"));
-        },
         slideSeek: function(event, ui){
             var completion = ui.value / 500;
             this.app.seekRatio(completion);
 
     var ArtistsView = AppView.extend({
         events: {
-            "click .artist": "clickArtist"
+            "click": "clickArtist"
         },
         initialize: function(options){
             _.bindAll(this, "loadArtists", "render", 'artistNodes', 'clickArtist');
             });
         },
         render: function(){
+            $(this.el).empty();
             var artists_height = $(this.el).height();
             var window_height = $(window).height();
             var num_columns_wanted = Math.ceil(artists_height / window_height);
             artist_nodes.each(function(){
                 column.append(this);
                 if(column.children().last().position().top+column.children().last().height()>window_height){
-                    var node = column.children().last().detach()
+                    var node = column.children().last().detach();
                     column = newColumn();
-                    column.append(node)
+                    column.append(node);
                 }
             });
             var len_columns = this.$(".column").length;
                 $(this).width(col_width_perc + "%");
                 $(this).css("left", ((col_width_perc+margin_perc) * ii) + "%");
             });
-            //this.$(".artist").bind("click", this.clickArtist);
         },
         artistNodes: function(){
             return $(this.artists.map(function(a, i){
-                var n = $("<div></div>");
-                n.addClass("artist")
-                if(i%2){n.addClass("odd")}
-                else{n.addClass("even")}
-                n.text(a.get("name") + "(" + a.get("num_albums") + "/" + a.get("num_songs") + ")");
-                n.data("artist", a);
-                return n;
+                var view = new SingleArtistView({app: app, artist: a});
+                var el = view.render().el;
+                if(i%2){$(el).addClass("even")}
+                else{$(el).addClass("odd")}
+                return el;
             }));
         },
         clickArtist: function(event){
-            var $artist = $(event.target)
-            this.$(".artist.selected").removeClass("selected");
-            $artist.addClass("selected");
-            var artist = $artist.data("artist");
-            this.app.current_artist = artist;
-            this.post("get-albums", {artist: artist.get("_id").$oid})
+            $(event.target).closest(".artist").data("view").handleClick();;
+        }
+    });
+    var SingleArtistView = AppView.extend({
+        className: "artist",
+        initialize: function(options){
+            _.bindAll(this, "render", "handleClick")
+            this.constructor.__super__.initialize.apply(this, [options])
+            this.artist = options.artist;
+            $(this.el).data("view", this);
+        },
+        render: function(){
+            var template_context = {
+                name: this.artist.get("name"),
+                num_albums: this.artist.get("num_albums"),
+                num_songs: this.artist.get("num_songs"),
+            };
+            $(this.el).html(get_template("#artist-template")(template_context))
+            return this;
+        },
+        handleClick: function(){
+            this.app.$(".artist.selected").removeClass("selected");
+            $(this.el).addClass("selected");
+            this.post("get-albums", {artist: this.artist.get("_id").$oid})
                 .then(function(albums){app.albums.albums.reset(albums)});
         }
+
     });
     var AlbumsView = AppView.extend({
         events: {
             $(this.el).html(get_template("#song-template")(template_context));
             return this;
         }
-    })
+    });
 
     window.app = new MusicApp();
 });