Alpha done, needs testing though :)
authorAndrew Karpow <andy@ndyk.de>
Thu, 7 Nov 2013 16:40:22 +0000 (17:40 +0100)
committerAndrew Karpow <andy@ndyk.de>
Thu, 7 Nov 2013 16:40:22 +0000 (17:40 +0100)
htdocs/css/mpd.css
htdocs/index.html
htdocs/js/mpd.js
src/mpd_client.c
src/mpd_client.h

index 46244c7..0b271a5 100644 (file)
@@ -28,3 +28,14 @@ body {
        min-width: 50px;
 }
 
+.btn-group-hover .btn {
+    border-color: white;
+    background: white;
+    text-shadow: 0 1px 1px white;
+    -webkit-box-shadow: inset 0 1px 0 white;
+    -moz-box-shadow: inset 0 1px 0 white;
+    box-shadow: inset 0 1px 0 white;
+}
+.btn-group-hover {
+    opacity: 0;
+}
index 32a6ea0..eb8c102 100644 (file)
@@ -37,9 +37,9 @@
       <div class="collapse navbar-collapse">
 
         <ul id="nav_links" class="nav navbar-nav">
-          <li id="nav_playlist"><a href="#">Playlist</a></li>
-          <li id="nav_browse"><a href="#/browse/">Browse database</a></li>
-          <li id="nav_about"><a href="#/about/">About</a></li>
+          <li id="playlist"><a href="#/">Playlist</a></li>
+          <li id="browse"><a href="#/browse/">Browse database</a></li>
+          <li id="about"><a href="#/about/">About</a></li>
         </ul>
 
         <form class="navbar-form navbar-right" role="search">
           <div id="panel-heading" class="panel-heading">Playlist</div>
           <div class="panel-body">
             <h1><span id="track-icon" class="glyphicon glyphicon-play"></span><span id="currenttrack"></span></h1>
+            <h4></span><span id="album" class="text"></span>
+              <span id="artist" class="text pull-right"></span></h4>
             <p id="counter" class="text pull-right">&nbsp;&nbsp;</p>
 
             <div class="progress progress-striped active">
               <div id="progressbar" class="progress-bar navbar-left"  role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100">
               </div>
             </div>
+
           </div>
 
           <!-- Table -->
             <span class="glyphicon glyphicon-wrench"></span> Options <span class="caret"></span>
           </button>
           <ul class="dropdown-menu">
-            <li><a href="#" onclick="updateDB()"><span class="glyphicon glyphicon-refresh"></span> Update Database</a></li>
+            <li><a href="#/" onclick="updateDB();"><span class="glyphicon glyphicon-refresh"></span> Update Database</a></li>
+            <li><a href="#/" onclick="socket.send('MPD_API_RM_ALL');"><span class="glyphicon glyphicon-trash"></span> Clear queue</a></li>
           </ul>
         </div>
       </div><!-- /.col-md-2 -->
index c813fe7..6fe91df 100644 (file)
@@ -6,14 +6,10 @@ $('#volumeslider').slider().on('slide', function(event) {
        socket.send("MPD_API_SET_VOLUME,"+event.value);
 });
 
-$('#nav_links > li').on('click', function(e) {
-       //$('#nav_links > li:contains(' + History.getState().title + ')').removeClass('active');
-       //History.pushState({state:$(this).attr('id')}, $(this).text(), '?' + $(this).attr('id'));
-});
-
 var app = $.sammy(function() {
        this.before('/', function(e, data) {
                socket.send("MPD_API_GET_TRACK_INFO");
+               $('#nav_links > li').removeClass('active');
        });
 
        this.get('#/', function() {
@@ -21,7 +17,9 @@ var app = $.sammy(function() {
                $('#salamisandwich').find("tr:gt(0)").remove();
                socket.send("MPD_API_GET_PLAYLIST");
                $('#panel-heading').text("Playlist");
+               $('#playlist').addClass('active');
        });
+
        this.get(/\#\/browse\/(.*)/, function() {
                current_app = 'browse';
                $('#salamisandwich').find("tr:gt(0)").remove();
@@ -31,50 +29,26 @@ var app = $.sammy(function() {
 
                socket.send("MPD_API_GET_BROWSE,"+path);
                $('#panel-heading').text("Browse database: "+path+"");
+               $('#browse').addClass('active');
        });
-       this.get('#/about', function() {
+
+       this.get('#/about/', function() {
                current_app = 'about';
                $('#panel-heading').text("About");
-       }); 
+               $('#about').addClass('active');
+       });
+
        this.get("/", function(context) {
                context.redirect("#/");
        });
 });
 
-
-
-/*
-History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate
-
-    if(!State.data.state) {
-       //$('#' + State.data).
-    }
-
-       $('#panel-heading').text(State.title);
-       switch(State.data.state) {
-               case "nav_browse":
-                       socket.send('MPD_API_GET_BROWSE,/');
-                       break;
-               case "nav_about":
-                       break;
-               case "nav_playlist":
-               default:
-                       
-       }
-       $(this).addClass('active');
-
-    console.log(" Browser State: ");
-    console.log(State);
-       socket.send("MPD_API_GET_TRACK_INFO");
-});
-*/
 $(document).ready(function(){
        webSocketConnect();
 });
 
 
 function webSocketConnect() {
-
        if (typeof MozWebSocket != "undefined") {
                socket = new MozWebSocket(get_appropriate_ws_url(), "ympd-client");
        } else {
@@ -99,19 +73,36 @@ function webSocketConnect() {
                                case "playlist":
                                        //if(state.data.state !== 'nav_playlist')
                                        //      break;
+                                       console.log("Got Playlist...");
                                        if(current_app !== 'playlist')
                                                break;
 
+                                       $('#salamisandwich > tbody').empty();
                                        for (var song in obj.data) {
                                                var minutes = Math.floor(obj.data[song].duration / 60);
                                                var seconds = obj.data[song].duration - minutes * 60;
 
-                                               $('#salamisandwich tr:last').after(
-                                                       "<tr id=\"playlist_" + obj.data[song].id + "\"><td>" + obj.data[song].pos + "</td>" +
+                                               $('#salamisandwich > tbody').append(
+                                                       "<tr trackid=\"" + obj.data[song].id + "\"><td>" + obj.data[song].pos + "</td>" +
                                                        "<td>"+ obj.data[song].title +"</td>" + 
                                                        "<td>"+ minutes + ":" + (seconds < 10 ? '0' : '') + seconds +
-                                                       "<span class=\"glyphicon glyphicon-trash pull-right hoverhidden\"></span> </td></tr>");
+                                                       "</td></tr>");
                                        }
+
+                                       $('#salamisandwich > tbody > tr').on({
+                                               mouseover: function(){
+                                                       if($(this).children().last().has("a").length == 0)
+                                                               $(this).children().last().append(
+                                                                       "<a class=\"btn btn-xs pull-right btn-group-hover\" href=\"#/\" " +
+                                                                       "onclick=\"socket.send('MPD_API_RM_TRACK," + $(this).attr("trackid") +"'); $(this).parents('tr').remove();\">" +
+                                                                       "<span class=\"glyphicon glyphicon-trash\"></span></a>")
+                                                               .find('a').fadeTo('fast',1);
+                                               },
+                                               mouseleave: function(){
+                                                       $(this).children().last().find("a").stop().remove();
+                                               }
+                                       });
+
                                        break;
                                case "browse":
                                        //if(state.data.state !== 'nav_browse')
@@ -123,8 +114,9 @@ function webSocketConnect() {
                                        for (var item in obj.data) {
                                                switch(obj.data[item].type) {
                                                        case "directory":
-                                                               $('#salamisandwich tr:last').after(
-                                                                       "<tr><td><span class=\"glyphicon glyphicon-folder-open\"></span></td>" + 
+                                                               $('#salamisandwich > tbody').append(
+                                                                       "<tr uri=\"" + obj.data[item].dir + "\">" +
+                                                                       "<td><span class=\"glyphicon glyphicon-folder-open\"></span></td>" + 
                                                                        "<td><a href=\"#/browse/"+ obj.data[item].dir +"\">" + obj.data[item].dir +"</a></td>" + 
                                                                        "<td></td></tr>");
                                                                break;
@@ -132,15 +124,33 @@ function webSocketConnect() {
                                                                var minutes = Math.floor(obj.data[item].duration / 60);
                                                                var seconds = obj.data[item].duration - minutes * 60;
 
-                                                               $('#salamisandwich tr:last').after(
-                                                                       "<tr><td><span class=\"glyphicon glyphicon-music\"></span></td>" + 
-                                                                       "<td><a href=\"#\">" + obj.data[item].title +"</a></td>" + 
+                                                               $('#salamisandwich > tbody').append(
+                                                                       "<tr uri=\"" + obj.data[item].uri + "\">" +
+                                                                       "<td><span class=\"glyphicon glyphicon-music\"></span></td>" + 
+                                                                       "<td>" + obj.data[item].title +"</td>" + 
                                                                        "<td>"+ minutes + ":" + (seconds < 10 ? '0' : '') + seconds +"</td></tr>");
                                                                break;
+
                                                        case "playlist":
                                                                break;
                                                }
                                        }
+
+                                       $('#salamisandwich > tbody > tr').on({
+                                               mouseover: function(){
+                                                       if($(this).children().last().has("a").length == 0)
+                                                               if($(this).attr("uri").length > 0)
+                                                                       $(this).children().last().append(
+                                                                               "<a class=\"btn btn-xs pull-right btn-group-hover\" " +
+                                                                               "onclick=\"socket.send('MPD_API_ADD_TRACK," + $(this).attr("uri") +"'); $(this).parents('tr').addClass('success');\">" +
+                                                                               "<span class=\"glyphicon glyphicon-plus\"></span></a>")
+                                                                               .find('a').fadeTo('fast',1);
+                                               },
+                                               mouseleave: function(){
+                                                       $(this).children().last().find("a").stop().remove();
+                                               }
+                                       });
+
                                        $('#salamisandwich td:eq(1)').click(function(){
                                                console.log($(this).children().attr("path"));
                                                //socket.send('MPD_API_GET_BROWSE,'+;
@@ -209,7 +219,10 @@ function webSocketConnect() {
 
                                case "current_song":
                                        $('#currenttrack').text(" " + obj.data.title);
-
+                                       if(obj.data.album)
+                                               $('#album').text(obj.data.album);
+                                       if(obj.data.artist)
+                                               $('#artist').text(obj.data.artist);
                                default:
                                        break;
                        }
index 500640c..950f521 100644 (file)
@@ -103,6 +103,14 @@ int callback_ympd(struct libwebsocket_context *context,
                                mpd_send_next(conn);
                                mpd_response_finish(conn);
                        }
+                       else if(!strcmp((const char *)in, MPD_API_RM_ALL)) {
+                               mpd_run_clear(conn);
+                       }
+                       else if(!strncmp((const char *)in, MPD_API_RM_TRACK, sizeof(MPD_API_RM_TRACK)-1)) {
+                               unsigned id;
+                               if(sscanf(in, "MPD_API_RM_TRACK,%d", &id))
+                                       mpd_run_delete_id(conn, id);
+                       }
                        else if(!strncmp((const char *)in, MPD_API_TOGGLE_RANDOM, sizeof(MPD_API_TOGGLE_RANDOM)-1)) {
                                unsigned random;
                                if(sscanf(in, "MPD_API_TOGGLE_RANDOM,%d", &random))
@@ -136,6 +144,14 @@ int callback_ympd(struct libwebsocket_context *context,
                                        pss->browse_path = dir;
                                }
                        }
+                       else if(!strncmp((const char *)in, MPD_API_ADD_TRACK, sizeof(MPD_API_ADD_TRACK)-1)) {
+                               char *uri;
+                               if(sscanf(in, "MPD_API_ADD_TRACK,%m[^\t\n]", &uri) && uri != NULL) {
+                                       printf("sending '%s'\n", uri);
+                                       mpd_run_add(conn, uri);
+                                       free(uri);
+                               }
+                       }
 
                        break;
 
@@ -247,11 +263,11 @@ int mpd_put_current_song(char *buffer)
                return 0;
 
        len = snprintf(buffer, MAX_SIZE, "{\"type\": \"current_song\", \"data\":"
-               "{\"id\":%d, \"pos\":%d, \"duration\":%d, \"title\":\"%s\"}}",
-               mpd_song_get_id(song),
+               "{\"pos\":%d, \"title\":\"%s\", \"artist\":\"%s\", \"album\":\"%s\"}}",
                mpd_song_get_pos(song),
-               mpd_song_get_duration(song),
-               mpd_get_title(song)
+               mpd_get_title(song),
+               mpd_song_get_tag(song, MPD_TAG_ARTIST, 0),
+               mpd_song_get_tag(song, MPD_TAG_ALBUM, 0)
        );
        mpd_song_free(song);
        mpd_response_finish(conn);
index 1fe6313..b710230 100644 (file)
@@ -25,6 +25,8 @@ enum mpd_conn_states {
 #define MPD_API_GET_TRACK_INFO   "MPD_API_GET_TRACK_INFO"
 #define MPD_API_GET_BROWSE       "MPD_API_GET_BROWSE"
 #define MPD_API_ADD_TRACK        "MPD_API_ADD_TRACK"
+#define MPD_API_RM_TRACK         "MPD_API_RM_TRACK"
+#define MPD_API_RM_ALL           "MPD_API_RM_ALL"
 #define MPD_API_SET_VOLUME       "MPD_API_SET_VOLUME"
 #define MPD_API_SET_PAUSE        "MPD_API_SET_PAUSE"
 #define MPD_API_SET_PLAY         "MPD_API_SET_PLAY"