From 3a40da1dbee7bd7d7b5c562a5adb52e42f4d4b74 Mon Sep 17 00:00:00 2001 From: magnolia-fan Date: Wed, 13 Apr 2011 01:19:53 +0400 Subject: [PATCH] Huge player update. Closes #36, closes #33. #37 is almost done --- app/views/layouts/application.html.erb | 18 +-- public/images/player/pause.svg | 1 - public/images/player/playlist.svg | 10 ++ public/images/player/shuffle.svg | 41 +++++++ public/javascripts/jquery-rand.min.js | 15 +++ public/javascripts/jquery.jscrollpane.min.js | 11 ++ public/javascripts/jquery.mousewheel.js | 78 +++++++++++++ public/javascripts/player.js | 72 +++++++++--- public/stylesheets/jquery.jscrollpane.css | 113 +++++++++++++++++++ public/stylesheets/player.css | 81 +++++++++---- 10 files changed, 391 insertions(+), 49 deletions(-) create mode 100644 public/images/player/playlist.svg create mode 100644 public/images/player/shuffle.svg create mode 100644 public/javascripts/jquery-rand.min.js create mode 100644 public/javascripts/jquery.jscrollpane.min.js create mode 100644 public/javascripts/jquery.mousewheel.js create mode 100644 public/stylesheets/jquery.jscrollpane.css diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index c9c9f85..27b943a 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -13,28 +13,28 @@
- -
play
- - + +
ply
+ +
0:00
No track
-
+
0:00
+
shu
+
rep
+
pls
-
-
    -
+
    <%= yield %> - add
    diff --git a/public/images/player/pause.svg b/public/images/player/pause.svg index 7b8119d..99b791a 100644 --- a/public/images/player/pause.svg +++ b/public/images/player/pause.svg @@ -1,5 +1,4 @@ - diff --git a/public/images/player/playlist.svg b/public/images/player/playlist.svg new file mode 100644 index 0000000..696f99a --- /dev/null +++ b/public/images/player/playlist.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/public/images/player/shuffle.svg b/public/images/player/shuffle.svg new file mode 100644 index 0000000..4f1e016 --- /dev/null +++ b/public/images/player/shuffle.svg @@ -0,0 +1,41 @@ + + + + + + + + + \ No newline at end of file diff --git a/public/javascripts/jquery-rand.min.js b/public/javascripts/jquery-rand.min.js new file mode 100644 index 0000000..090c30e --- /dev/null +++ b/public/javascripts/jquery-rand.min.js @@ -0,0 +1,15 @@ +/* +* jQuery.fn.rand(); +* +* Return a random, but defined numbers of elements from a jQuery Object. +* $('element').rand(); // returns one element from the jQuery Object. +* $('element').rand(4); // returns four elements from the jQuery Object. +* +* Version 0.8.5 +* www.labs.skengdon.com/rand +* www.labs.skengdon.com/rand/js/rand.min.js +* +* And: +* http://phpjs.org/functions/array_rand:332 +*/ +;(function($){$.fn.rand=function(number){var array_rand=function(input,num_req){var indexes=[];var ticks=num_req||1;var checkDuplicate=function(input,value){var exist=false,index=0;while(indexthis.length)number=this.length;var numbers=array_rand(this,number);var $return=[];for(var i=0;i').css("padding",aJ).append(E.children());an=b('
    ').css({width:al+"px",height:w+"px"}).append(Z).appendTo(E)}else{E.css("width","");aQ=aA.stickToBottom&&L();aM=aA.stickToRight&&C();aL=E.innerWidth()+g!=al||E.outerHeight()!=w;if(aL){al=E.innerWidth()+g;w=E.innerHeight();an.css({width:al+"px",height:w+"px"})}if(!aL&&M==U&&Z.outerHeight()==aa){E.width(al);return}M=U;Z.css("width","");E.width(al);an.find(">.jspVerticalBar,>.jspHorizontalBar").remove().end()}if(aU.contentWidth){U=aU.contentWidth}else{aS=Z.clone(false,false).css("position","absolute");aT=b('
    ').append(aS);b("body").append(aT);U=Math.max(Z.outerWidth(),aS.outerWidth());aT.remove()}aa=Z.outerHeight();z=U/al;r=aa/w;aB=r>1;aG=z>1;if(!(aG||aB)){E.removeClass("jspScrollable");Z.css({top:0,width:an.width()-g});o();F();S();x();aj()}else{E.addClass("jspScrollable");aN=aA.maintainPosition&&(J||ab);if(aN){aP=aE();aO=aC()}aH();A();G();if(aN){O(aM?(U-al):aP,false);N(aQ?(aa-w):aO,false)}K();ah();ap();if(aA.enableKeyboardNavigation){T()}if(aA.clickOnTrack){q()}D();if(aA.hijackInternalLinks){n()}}if(aA.autoReinitialise&&!ax){ax=setInterval(function(){au(aA)},aA.autoReinitialiseDelay)}else{if(!aA.autoReinitialise&&ax){clearInterval(ax)}}aK&&E.scrollTop(0)&&N(aK,false);aR&&E.scrollLeft(0)&&O(aR,false);E.trigger("jsp-initialised",[aG||aB])}function aH(){if(aB){an.append(b('
    ').append(b('
    '),b('
    ').append(b('
    ').append(b('
    '),b('
    '))),b('
    ')));V=an.find(">.jspVerticalBar");ar=V.find(">.jspTrack");aw=ar.find(">.jspDrag");if(aA.showArrows){at=b('').bind("mousedown.jsp",aF(0,-1)).bind("click.jsp",aD);ag=b('').bind("mousedown.jsp",aF(0,1)).bind("click.jsp",aD);if(aA.arrowScrollOnHover){at.bind("mouseover.jsp",aF(0,-1,at));ag.bind("mouseover.jsp",aF(0,1,ag))}am(ar,aA.verticalArrowPositions,at,ag)}u=w;an.find(">.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow").each(function(){u-=b(this).outerHeight()});aw.hover(function(){aw.addClass("jspHover")},function(){aw.removeClass("jspHover")}).bind("mousedown.jsp",function(aK){b("html").bind("dragstart.jsp selectstart.jsp",aD);aw.addClass("jspActive");var s=aK.pageY-aw.position().top;b("html").bind("mousemove.jsp",function(aL){W(aL.pageY-s,false)}).bind("mouseup.jsp mouseleave.jsp",ay);return false});p()}}function p(){ar.height(u+"px");J=0;Y=aA.verticalGutter+ar.outerWidth();Z.width(al-Y-g);try{if(V.position().left===0){Z.css("margin-left",Y+"px")}}catch(s){}}function A(){if(aG){an.append(b('
    ').append(b('
    '),b('
    ').append(b('
    ').append(b('
    '),b('
    '))),b('
    ')));ao=an.find(">.jspHorizontalBar");H=ao.find(">.jspTrack");i=H.find(">.jspDrag");if(aA.showArrows){az=b('').bind("mousedown.jsp",aF(-1,0)).bind("click.jsp",aD); +y=b('').bind("mousedown.jsp",aF(1,0)).bind("click.jsp",aD);if(aA.arrowScrollOnHover){az.bind("mouseover.jsp",aF(-1,0,az));y.bind("mouseover.jsp",aF(1,0,y))}am(H,aA.horizontalArrowPositions,az,y)}i.hover(function(){i.addClass("jspHover")},function(){i.removeClass("jspHover")}).bind("mousedown.jsp",function(aK){b("html").bind("dragstart.jsp selectstart.jsp",aD);i.addClass("jspActive");var s=aK.pageX-i.position().left;b("html").bind("mousemove.jsp",function(aL){X(aL.pageX-s,false)}).bind("mouseup.jsp mouseleave.jsp",ay);return false});m=an.innerWidth();ai()}}function ai(){an.find(">.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow").each(function(){m-=b(this).outerWidth()});H.width(m+"px");ab=0}function G(){if(aG&&aB){var aK=H.outerHeight(),s=ar.outerWidth();u-=aK;b(ao).find(">.jspCap:visible,>.jspArrow").each(function(){m+=b(this).outerWidth()});m-=s;w-=s;al-=aK;H.parent().append(b('
    ').css("width",aK+"px"));p();ai()}if(aG){Z.width((an.outerWidth()-g)+"px")}aa=Z.outerHeight();r=aa/w;if(aG){av=Math.ceil(1/z*m);if(av>aA.horizontalDragMaxWidth){av=aA.horizontalDragMaxWidth}else{if(avaA.verticalDragMaxHeight){B=aA.verticalDragMaxHeight}else{if(BaU){R.scrollByY(-aR)}else{W(aU)}}else{if(aO>0){if(J+aSaU){R.scrollByX(-aR)}else{X(aU)}}else{if(aO>0){if(ab+aSj){s=j}}if(aK===c){aK=aA.animateScroll}if(aK){R.animate(aw,"top",s,ae)}else{aw.css("top",s);ae(s)}}function ae(aK){if(aK===c){aK=aw.position().top}an.scrollTop(0);J=aK;var aN=J===0,aL=J==j,aM=aK/j,s=-aM*(aa-w);if(ak!=aN||aI!=aL){ak=aN;aI=aL;E.trigger("jsp-arrow-change",[ak,aI,Q,l])}v(aN,aL);Z.css("top",s);E.trigger("jsp-scroll-y",[-s,aN,aL]).trigger("scroll")}function X(aK,s){if(!aG){return +}if(aK<0){aK=0}else{if(aK>k){aK=k}}if(s===c){s=aA.animateScroll}if(s){R.animate(i,"left",aK,af)}else{i.css("left",aK);af(aK)}}function af(aK){if(aK===c){aK=i.position().left}an.scrollTop(0);ab=aK;var aN=ab===0,aM=ab==k,aL=aK/k,s=-aL*(U-al);if(Q!=aN||l!=aM){Q=aN;l=aM;E.trigger("jsp-arrow-change",[ak,aI,Q,l])}t(aN,aM);Z.css("left",s);E.trigger("jsp-scroll-x",[-s,aN,aM]).trigger("scroll")}function v(aK,s){if(aA.showArrows){at[aK?"addClass":"removeClass"]("jspDisabled");ag[s?"addClass":"removeClass"]("jspDisabled")}}function t(aK,s){if(aA.showArrows){az[aK?"addClass":"removeClass"]("jspDisabled");y[s?"addClass":"removeClass"]("jspDisabled")}}function N(s,aK){var aL=s/(aa-w);W(aL*j,aK)}function O(aK,s){var aL=aK/(U-al);X(aL*k,s)}function ac(aX,aS,aL){var aP,aM,aN,s=0,aW=0,aK,aR,aQ,aU,aT,aV;try{aP=b(aX)}catch(aO){return}aM=aP.outerHeight();aN=aP.outerWidth();an.scrollTop(0);an.scrollLeft(0);while(!aP.is(".jspPane")){s+=aP.position().top;aW+=aP.position().left;aP=aP.offsetParent();if(/^body|html$/i.test(aP[0].nodeName)){return}}aK=aC();aQ=aK+w;if(saQ){aT=s-w+aM+aA.verticalGutter}}if(aT){N(aT,aL)}aR=aE();aU=aR+al;if(aWaU){aV=aW-al+aN+aA.horizontalGutter}}if(aV){O(aV,aL)}}function aE(){return -Z.position().left}function aC(){return -Z.position().top}function L(){var s=aa-w;return(s>20)&&(s-aC()<10)}function C(){var s=U-al;return(s>20)&&(s-aE()<10)}function ah(){an.unbind(ad).bind(ad,function(aN,aO,aM,aK){var aL=ab,s=J;R.scrollBy(aM*aA.mouseWheelSpeed,-aK*aA.mouseWheelSpeed,false);return aL==ab&&s==J})}function o(){an.unbind(ad)}function aD(){return false}function K(){Z.find(":input,a").unbind("focus.jsp").bind("focus.jsp",function(s){ac(s.target,false)})}function F(){Z.find(":input,a").unbind("focus.jsp")}function T(){var s,aK,aM=[];aG&&aM.push(ao[0]);aB&&aM.push(V[0]);Z.focus(function(){E.focus()});E.attr("tabindex",0).unbind("keydown.jsp keypress.jsp").bind("keydown.jsp",function(aP){if(aP.target!==this&&!(aM.length&&b(aP.target).closest(aM).length)){return}var aO=ab,aN=J;switch(aP.keyCode){case 40:case 38:case 34:case 32:case 33:case 39:case 37:s=aP.keyCode;aL();break;case 35:N(aa-w);s=null;break;case 36:N(0);s=null;break}aK=aP.keyCode==s&&aO!=ab||aN!=J;return !aK}).bind("keypress.jsp",function(aN){if(aN.keyCode==s){aL()}return !aK});if(aA.hideFocus){E.css("outline","none");if("hideFocus" in an[0]){E.attr("hideFocus",true)}}else{E.css("outline","");if("hideFocus" in an[0]){E.attr("hideFocus",false)}}function aL(){var aO=ab,aN=J;switch(s){case 40:R.scrollByY(aA.keyboardSpeed,false);break;case 38:R.scrollByY(-aA.keyboardSpeed,false);break;case 34:case 32:R.scrollByY(w*aA.scrollPagePercent,false);break;case 33:R.scrollByY(-w*aA.scrollPagePercent,false);break;case 39:R.scrollByX(aA.keyboardSpeed,false);break;case 37:R.scrollByX(-aA.keyboardSpeed,false);break}aK=aO!=ab||aN!=J;return aK}}function S(){E.attr("tabindex","-1").removeAttr("tabindex").unbind("keydown.jsp keypress.jsp")}function D(){if(location.hash&&location.hash.length>1){var aL,aK;try{aL=b(location.hash)}catch(s){return}if(aL.length&&Z.find(location.hash)){if(an.scrollTop()===0){aK=setInterval(function(){if(an.scrollTop()>0){ac(location.hash,true);b(document).scrollTop(an.position().top);clearInterval(aK)}},50)}else{ac(location.hash,true);b(document).scrollTop(an.position().top)}}}}function aj(){b("a.jspHijack").unbind("click.jsp-hijack").removeClass("jspHijack")}function n(){aj();b("a[href^=#]").addClass("jspHijack").bind("click.jsp-hijack",function(){var s=this.href.split("#"),aK;if(s.length>1){aK=s[1];if(aK.length>0&&Z.find("#"+aK).length>0){ac("#"+aK,true);return false}}})}function ap(){var aL,aK,aN,aM,aO,s=false;an.unbind("touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick").bind("touchstart.jsp",function(aP){var aQ=aP.originalEvent.touches[0];aL=aE();aK=aC();aN=aQ.pageX;aM=aQ.pageY;aO=false;s=true}).bind("touchmove.jsp",function(aS){if(!s){return}var aR=aS.originalEvent.touches[0],aQ=ab,aP=J; +R.scrollTo(aL+aN-aR.pageX,aK+aM-aR.pageY);aO=aO||Math.abs(aN-aR.pageX)>5||Math.abs(aM-aR.pageY)>5;return aQ==ab&&aP==J}).bind("touchend.jsp",function(aP){s=false}).bind("click.jsp-touchclick",function(aP){if(aO){aO=false;return false}})}function h(){var s=aC(),aK=aE();E.removeClass("jspScrollable").unbind(".jsp");E.replaceWith(aq.append(Z.children()));aq.scrollTop(s);aq.scrollLeft(aK)}b.extend(R,{reinitialise:function(aK){aK=b.extend({},aA,aK);au(aK)},scrollToElement:function(aL,aK,s){ac(aL,aK,s)},scrollTo:function(aL,s,aK){O(aL,aK);N(s,aK)},scrollToX:function(aK,s){O(aK,s)},scrollToY:function(s,aK){N(s,aK)},scrollToPercentX:function(aK,s){O(aK*(U-al),s)},scrollToPercentY:function(aK,s){N(aK*(aa-w),s)},scrollBy:function(aK,s,aL){R.scrollByX(aK,aL);R.scrollByY(s,aL)},scrollByX:function(s,aL){var aK=aE()+s,aM=aK/(U-al);X(aM*k,aL)},scrollByY:function(s,aL){var aK=aC()+s,aM=aK/(aa-w);W(aM*j,aL)},positionDragX:function(s,aK){X(s,aK)},positionDragY:function(aK,s){X(aK,s)},animate:function(aK,aN,s,aM){var aL={};aL[aN]=s;aK.animate(aL,{duration:aA.animateDuration,ease:aA.animateEase,queue:false,step:aM})},getContentPositionX:function(){return aE()},getContentPositionY:function(){return aC()},getContentWidth:function(){return U},getContentHeight:function(){return aa},getPercentScrolledX:function(){return aE()/(U-al)},getPercentScrolledY:function(){return aC()/(aa-w)},getIsScrollableH:function(){return aG},getIsScrollableV:function(){return aB},getContentPane:function(){return Z},scrollToBottom:function(s){W(j,s)},hijackInternalLinks:function(){n()},destroy:function(){h()}});au(P)}f=b.extend({},b.fn.jScrollPane.defaults,f);b.each(["mouseWheelSpeed","arrowButtonSpeed","trackClickSpeed","keyboardSpeed"],function(){f[this]=f[this]||f.speed});var e;this.each(function(){var g=b(this),h=g.data("jsp");if(h){h.reinitialise(f)}else{h=new d(g,f);g.data("jsp",h)}e=e?e.add(g):g});return e};b.fn.jScrollPane.defaults={showArrows:false,maintainPosition:true,stickToBottom:false,stickToRight:false,clickOnTrack:true,autoReinitialise:false,autoReinitialiseDelay:500,verticalDragMinHeight:0,verticalDragMaxHeight:99999,horizontalDragMinWidth:0,horizontalDragMaxWidth:99999,contentWidth:c,animateScroll:false,animateDuration:300,animateEase:"linear",hijackInternalLinks:false,verticalGutter:4,horizontalGutter:4,mouseWheelSpeed:0,arrowButtonSpeed:0,arrowRepeatFreq:50,arrowScrollOnHover:false,trackClickSpeed:0,trackClickRepeatFreq:70,verticalArrowPositions:"split",horizontalArrowPositions:"split",enableKeyboardNavigation:true,hideFocus:false,keyboardSpeed:0,initialDelay:300,speed:30,scrollPagePercent:0.8}})(jQuery,this); \ No newline at end of file diff --git a/public/javascripts/jquery.mousewheel.js b/public/javascripts/jquery.mousewheel.js new file mode 100644 index 0000000..b793241 --- /dev/null +++ b/public/javascripts/jquery.mousewheel.js @@ -0,0 +1,78 @@ +/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net) + * Licensed under the MIT License (LICENSE.txt). + * + * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. + * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. + * Thanks to: Seamus Leahy for adding deltaX and deltaY + * + * Version: 3.0.4 + * + * Requires: 1.2.2+ + */ + +(function($) { + +var types = ['DOMMouseScroll', 'mousewheel']; + +$.event.special.mousewheel = { + setup: function() { + if ( this.addEventListener ) { + for ( var i=types.length; i; ) { + this.addEventListener( types[--i], handler, false ); + } + } else { + this.onmousewheel = handler; + } + }, + + teardown: function() { + if ( this.removeEventListener ) { + for ( var i=types.length; i; ) { + this.removeEventListener( types[--i], handler, false ); + } + } else { + this.onmousewheel = null; + } + } +}; + +$.fn.extend({ + mousewheel: function(fn) { + return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); + }, + + unmousewheel: function(fn) { + return this.unbind("mousewheel", fn); + } +}); + + +function handler(event) { + var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0; + event = $.event.fix(orgEvent); + event.type = "mousewheel"; + + // Old school scrollwheel delta + if ( event.wheelDelta ) { delta = event.wheelDelta/120; } + if ( event.detail ) { delta = -event.detail/3; } + + // New school multidimensional scroll (touchpads) deltas + deltaY = delta; + + // Gecko + if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { + deltaY = 0; + deltaX = -1*delta; + } + + // Webkit + if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; } + if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; } + + // Add event and delta to the front of the arguments + args.unshift(event, delta, deltaX, deltaY); + + return $.event.handle.apply(this, args); +} + +})(jQuery); \ No newline at end of file diff --git a/public/javascripts/player.js b/public/javascripts/player.js index df82813..f8cc0d2 100644 --- a/public/javascripts/player.js +++ b/public/javascripts/player.js @@ -1,6 +1,17 @@ var audio; var utid; $(function(){ + $.extend($.fn.disableTextSelect = function() { + return this.each(function(){ + if ($.browser.mozilla) {//Firefox + $(this).css('MozUserSelect','none'); + } else if ($.browser.msie) {//IE + $(this).bind('selectstart',function(){return false;}); + } else {//Opera, etc. + $(this).mousedown(function(){return false;}); + } + }); + }); audio = document.getElementsByTagName('audio')[0]; $('#player .play').click(function(){ if (! audio.src) return; @@ -8,14 +19,13 @@ $(function(){ utid = window.setTimeout(updatePlayer, 100); $('#player .pause').show(); $('#player .play').hide(); - }) + }).disableTextSelect(); $('#player .pause').click(function(){ audio.pause(); clearTimeout(utid); $('#player .pause').hide(); $('#player .play').show(); - }) - + }).disableTextSelect(); $('.tracks .play').click(function(){ addToPlaylist( $('h1.artist').html(), @@ -24,9 +34,20 @@ $(function(){ $(this).parent().attr('id') ); }) - $('#playlist .show-button').click(function(){ - $('#playlist ul').toggle(); + $('#player .prev').click(function(){ + playPrev(); + }).disableTextSelect(); + $('#player .next').click(function(){ + playNext(); + }).disableTextSelect(); + $('#player .shuffle, #player .repeat').click(function(){ + $(this).toggleClass('on'); + }).disableTextSelect(); + $('#player .playlist').click(function(){ + $('#playlist').toggle(); + //$('#playlist').data('jsp').reinitialise(); }) + $('#playlist').hide(); }) function updatePlayer() { duration = audio.duration; @@ -36,10 +57,10 @@ function updatePlayer() { } loaded = 0; if ((audio.buffered != undefined) && (audio.buffered.length != 0)) { - loaded = Math.round((audio.buffered.end(0) / audio.duration) * 730); + loaded = Math.round((audio.buffered.end(0) / audio.duration) * 390); $('#player .time-played').html(formatTime(cur_time)); $('#player .time-left').html(formatTime(duration - cur_time)); - progress = Math.round((cur_time / duration) * 730); + progress = Math.round((cur_time / duration) * 390); $('#player .progress-loaded').css('width', loaded +'px') $('#player .progress-point').css('margin-left', progress +'px') } @@ -58,25 +79,46 @@ function playTrack(artist, track, id) { $('#player .time-left').html('0:00'); $('#player .progress-loaded').css('width', 0 +'px') $('#player .progress-point').css('margin-left', 0 +'px') - $('#playlist li').removeClass('now-playing'); - $('#playlist li[data-id="'+ id +'"]').addClass('now-playing'); $('#player .play').trigger('click'); } -function playNext() { - $('#playlist ul li.now-playing').next().trigger('click'); +function playPrev() { + if ($('#playlist ul.list li').length == 0) return false; + if ($('#playlist ul.list li.now-playing').prev().length == 0) { + $('#playlist ul.list li:last').dblclick(); + } else { + $('#playlist ul.list li.now-playing').prev().dblclick(); + } +} +function playNext(auto) { + if ($('#playlist ul.list li').length == 0) return false; + if ($('#player .shuffle').hasClass('on')) { + $('#playlist ul.list li').rand().dblclick(); + } + if ($('#playlist ul.list li.now-playing').next().length == 0) { + $('#playlist ul.list li:first').dblclick(); + } else { + $('#playlist ul.list li.now-playing').next().dblclick(); + } } function addToPlaylist(artist, track, length, id) { - $('#playlist ul').append($( + $('#playlist ul.list').append($( '
  • '+ ''+ artist +' — '+ ''+ track +''+ ''+ formatTime(length) +''+ '
  • ' )); - $('#playlist ul li[data-id="'+ id +'"]').click(function(){ + $('#playlist ul.list li').disableTextSelect(); + $('#playlist ul.list li[data-id="'+ id +'"]').dblclick(function(){ playTrack(artist, track, id); + $('#playlist li').removeClass('now-playing'); + $(this).addClass('now-playing'); }) - if ($('#playlist ul li').length == 1) { - playTrack(artist, track, id); + if ($('#playlist ul.list li').length == 1) { + $('#playlist ul.list li:first').dblclick(); } + if ($('#playlist ul.list li').length > 6) { + $('#playlist').jScrollPane(); + } + } diff --git a/public/stylesheets/jquery.jscrollpane.css b/public/stylesheets/jquery.jscrollpane.css new file mode 100644 index 0000000..07cf64f --- /dev/null +++ b/public/stylesheets/jquery.jscrollpane.css @@ -0,0 +1,113 @@ +/* + * CSS Styles that are needed by jScrollPane for it to operate correctly. + * + * Include this stylesheet in your site or copy and paste the styles below into your stylesheet - jScrollPane + * may not operate correctly without them. + */ + +.jspContainer +{ + overflow: hidden; + position: relative; +} + +.jspPane +{ + position: absolute; +} + +.jspVerticalBar +{ + position: absolute; + top: 0; + right: 0; + width: 10px; + height: 100%; + background: red; +} + +.jspHorizontalBar +{ + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 16px; + background: red; +} + +.jspVerticalBar *, +.jspHorizontalBar * +{ + margin: 0; + padding: 0; +} + +.jspCap +{ + display: none; +} + +.jspHorizontalBar .jspCap +{ + float: left; +} + +.jspTrack +{ + background: #111; + position: relative; +} + +.jspDrag +{ + background: #555; + position: relative; + top: 0; + left: 0; + cursor: default; +} + +.jspHorizontalBar .jspTrack, +.jspHorizontalBar .jspDrag +{ + float: left; + height: 100%; +} + + +.jspArrow.jspDisabled +{ + cursor: default; + background: #80808d; +} + +.jspVerticalBar .jspArrow +{ + height: 16px; +} + +.jspHorizontalBar .jspArrow +{ + width: 16px; + float: left; + height: 100%; +} + +.jspVerticalBar .jspArrow:focus +{ + outline: none; +} + +.jspCorner +{ + background: #eeeef4; + float: left; + height: 100%; +} + +/* Yuk! CSS Hack for IE6 3 pixel bug :( */ +* html .jspCorner +{ + margin: 0 -3px 0 0; +} \ No newline at end of file diff --git a/public/stylesheets/player.css b/public/stylesheets/player.css index 8f2fe8f..d788768 100644 --- a/public/stylesheets/player.css +++ b/public/stylesheets/player.css @@ -1,10 +1,10 @@ #player { position: fixed; - width: 1000px; + width: 750px; height: 50px; left: 50%; top: 0; - margin-left: -500px; + margin-left: -375px; background-color: #000; font-size: 12px; } @@ -50,7 +50,7 @@ margin-left: 20px; } #player .next { - margin-right: 20px; + margin-right: 6px; } #player .time-played, #player .time-left { float: left; @@ -65,11 +65,11 @@ float: left; margin-top: 25px; height: 25px; - width: 740px; + width: 400px; } #player .track-title { float: left; - width: 730px; + width: 390px; height: 25px; margin-left: 5px; margin-top: -25px; @@ -80,7 +80,7 @@ float: left; margin: 11px 5px; background-color: #013; - width: 730px; + width: 390px; height: 3px; } #player .progress-loaded { @@ -100,41 +100,74 @@ border-radius: 6px; cursor: pointer; } + #player .shuffle, #player .repeat, #player .playlist { + float: left; + cursor: pointer; + } + #player .shuffle { + margin: 17px 0 0 0; + } + #player .shuffle img { + width: 20px; + } + #player .repeat { + margin: 17px 0 0 15px; + } + #player .repeat img { + width: 20px; + } + #player .playlist { + margin: 12px 0 0 15px; + } + #player .playlist img { + width: 20px; + } + #player .shuffle, #player .repeat { + opacity: 0.5; + -moz-opacity: 0.5; + -khtml-opacity: 0.5; + -webkit-opacity: 0.5; + filter:alpha(opacity=50); + } + #player .shuffle.on, #player .repeat.on { + opacity: 1; + -moz-opacity: 1; + -khtml-opacity: 1; + -webkit-opacity: 1; + filter:alpha(opacity=100); + } #playlist { position: fixed; top: 50px; left: 50%; - width: 1000px; - margin-left: -500px; + width: 750px; + margin-left: -375px; background-color: #000; - opacity: 60; - -moz-opacity: 60; - -khtml-opacity: 60; - -webkit-opacity: 60; + opacity: 0.9; + -moz-opacity: 0.9; + -khtml-opacity: 0.9; + -webkit-opacity: 0.9; + filter:alpha(opacity=90); + overflow-y: auto; + max-height: 10em; } - #playlist .show-button { - width: 100%; - height: 10px; - background-color: #222; - cursor: pointer; - } + #playlist ul { margin: 0.2em 0.3em; padding: 0; - max-height: 10em; - overflow-y: scroll; + position: relative; } #playlist ul li { margin: 0; - padding: 0.2em 0; + padding: 0.4em 0; display: block; width: 100%; - font-size: 0.8em; + font-size: 0.75em; color: #FFF; } #playlist ul li:hover { - background-color: #222; - cursor: pointer; + background-color: #050505; + cursor: default; } #playlist ul li.now-playing { background-color: #013;