diff options
-rwxr-xr-x | app.py | 2 | ||||
-rw-r--r-- | static/index.html | 64 | ||||
-rw-r--r-- | static/init.js | 37 | ||||
-rw-r--r-- | static/playlist.js | 5 | ||||
-rw-r--r-- | static/style.css | 31 | ||||
-rw-r--r-- | static/templates.js | 19 |
6 files changed, 95 insertions, 63 deletions
@@ -73,7 +73,7 @@ class JSONApplication(object): try: session = db.Session() r = db.Track.search(session, *l, **d) - results = [x.dict() for x in r] + results = [self.format_track(x) for x in r] finally: session.close() diff --git a/static/index.html b/static/index.html index b2bb27e..8520468 100644 --- a/static/index.html +++ b/static/index.html @@ -27,30 +27,58 @@ </div> <div id="tabs"> <ul> - <li><a href="#directory-tab">Directories</a></li> - <li><a href="#playlist-tab">Playlist</a></li> - <li><a href="#search-tab">Search</a></li> + <li><a href="#playlist-tab" accesskey="p"><span class="accessor">P</span>laylist</a></li> + <li><a href="#search-tab" accesskey="s"><span class="accessor">S</span>earch</a></li> + <li><a href="#directory-tab" accesskey="d"><span class="accessor">D</span>irectories</a></li> </ul> - <div id="directory-tab"> - <ul id="directory-list"> - </ul> - </div> <div id="playlist-tab"> - <table id="playlist"> - <thead> - <tr> - <th>Name</th> - <th> </th> - </tr> - </thead> - <tbody> - </tbody> + <table class="track-table"> + <thead> + <tr> + <th>Title</th> + <th>Artist</th> + <th>Album</th> + <th> </th> + </tr> + </thead> + <tbody id="playlist"> + </tbody> </table> </div> <div id="search-tab"> <input type="text" id="search_box" /> - <ul id="search-results"> - </ul> + <span> + <input type="button" id="search-add" value="Add selected" /> + </span> + <table class="track-table"> + <thead> + <tr> + <th>Title</th> + <th>Artist</th> + <th>Album</th> + </tr> + </thead> + <tbody id="search-results"> + <tr> + <td colspan="3" style="font-style: italic">Use the search box above to find music.</td> + </tr> + </tbody> + </table> + </div> + <div id="directory-tab"> + <table id="directory-table" class="track-table"> + <thead> + <tr> + <th>Title</th> + <th>Artist</th> + <th>Album</th> + </tr> + </thead> + <tbody id="directory-list"> + <tr> + </tr> + </tbody> + </table> </div> </div> </div> diff --git a/static/init.js b/static/init.js index 2ef7c9b..901aa1a 100644 --- a/static/init.js +++ b/static/init.js @@ -28,21 +28,19 @@ function load_directory(dir_id, dir_item) { var dir_list = $('#directory-list'); dir_list.html(''); if(dir_item && dir_item.parent) { - dir_list.append($('<li></li>') - .addClass('dir') + dir_list.append($('<tr></tr>').append($('<td></td>').attr('colspan', 3) .append($('<a></a>') + .addClass('dir') .attr('href', '#') .text('..') .click(function() { load_directory(dir_item.parent.id, dir_item.parent); return false; }) - ) + )) ); } $.each(data, function(i, item) { - if(item.type == "track") - item.nocache = !item.cache; var el = $(templates.directory_item(item)); var id = el.attr('id'); if(item.type == "track") { @@ -66,15 +64,18 @@ function search_results(data) { var results = $('#search-results'); results.empty(); $.each(data, function(i, track) { - var li = $(templates.directory_item(track)); - console.log(li); - $(li, 'a').click(function() { - console.log('clicked'); - playlist.add(track); - return false; - }); - results.append(li); + var item = $(templates.directory_item(track)); + item.data('track', track); + results.append(item); + }); + results.selectable({ + filter: 'tr', + stop: function(event, ui) { + $('#search-add').prop('disabled', results.children().length == 0); + return true; + } }); + $('#search-add').prop('disabled', true); } $(document).ready(function() { @@ -99,7 +100,15 @@ $(document).ready(function() { $('#search_box').keypress(function(event) { if(event.keyCode == 13) { var val = $(this).val(); - $.get('/json/search?q=' + escape(val), search_results, 'json'); + $.get('/json/search?q=' + encodeURIComponent(val), search_results, 'json'); } }); + $('#search-add').click(function(event) { + var tracks = $('#search-results tr.ui-selected'); + console.log(tracks); + tracks.each(function(i, item) { + var track = $(item).data('track'); + playlist.add(track); + }); + }).prop('disabled', true); }); diff --git a/static/playlist.js b/static/playlist.js index 45a4a07..70149b3 100644 --- a/static/playlist.js +++ b/static/playlist.js @@ -51,12 +51,9 @@ $(function(){ addOne: function(item) { var view = new PlaylistItemView({model: item}); var el = view.render().el; - if(item.attributes.nocache) - $(el).addClass('nocache'); $('#playlist').append(el); - if(item.attributes.cache !== undefined || item.attributes.nocache !== undefined) { + if(item.attributes.cache !== undefined) { delete item.attributes.cache; - delete item.attributes.nocache; item.save(); } }, diff --git a/static/style.css b/static/style.css index 3aab5aa..34579f7 100644 --- a/static/style.css +++ b/static/style.css @@ -1,19 +1,24 @@ * { padding: 0; margin: 0; } .ui-tabs-nav li a { font-size: small; } #progress { margin: .5em 1em; width: 300px; } -#directory-list, #playlist, #search-results { font-size: small; } -#directory-list a, #playlist a, #search-results a { color: inherit; text-decoration: inherit; } -#directory-list a:hover, #playlist a:hover, #search-results a:hover { text-decoration: underline; } -#directory-list .dir, #directory-list .track, #playlist a.play, #search-results .track { background-repeat: no-repeat; padding-left: 20px; } -#directory-list .dir { background-image: url('/static/icons/folder.png'); } -#directory-list .track, #search-results .track { background-image: url('/static/icons/music.png'); } -#directory-list .nocache, #playlist .nocache a.play { background-image: url('/static/icons/music_nocache.png'); } -#directory-list, #search-results { list-style-type: none; } +#tabs { font-size: 100%; } +.accessor { text-decoration: underline; } + +.track-table { width: 100%; } +.track-table tr:nth-child(odd) td { background: #eee; } +.track-table tr:nth-child(even) td { background: #ddd; } +.track-table tr.ui-selected td { background-color: #fea; } +.track-table tr:hover td { background-color: #fbb; } + +.track-table a { color: inherit; text-decoration: inherit; background-repeat: no-repeat; padding-left: 20px; display: block; } +.track-table a:hover { text-decoration: underline; } +.track-table .dir { background-image: url('/static/icons/folder.png'); } +.track-table .track { background-image: url('/static/icons/music.png'); } +.track-table .track.nocache { background-image: url('/static/icons/music_nocache.png'); } + #playlist .playing a.play { background-image: url('/static/icons/music_playing.png'); } #playlist .loading a.play { background-image: url('/static/icons/loading.gif'); } -#playlist { border-collapse: collapse; background: white; width: 100%; } -#playlist tr td:first-child { width: 100%; } -#playlist td { padding: .3em; background: white; border: 1px solid #ddd; border-width: 0 1px; } -#playlist tr:last-child td { border-bottom-width: 1px; } -#playlist th { background: #ddd; text-align: left; padding: .5em; } +#playlist tr td.track-buttons { width: 1em; } + +#search_box { border: 1px solid #888; border-radius: 10px; padding: 0 .3em; } #search-results { margin-top: 1em; } diff --git a/static/templates.js b/static/templates.js index f1d6bed..d0e7057 100644 --- a/static/templates.js +++ b/static/templates.js @@ -3,21 +3,14 @@ Handlebars.registerHelper('trackname', function() { if(!item.metadata) return item.name; - var s = ''; if(item.metadata.title) - s = item.metadata.title; - if(item.metadata.artist) { - if(s.length) { - s = ' - ' + s; - s = item.metadata.artist + s; - } - } - if(!s.length) - s = item.name; - return s; + return item.metadata.title; + else + return item.name; }); var templates = new (function Templates() { - this.directory_item = Handlebars.compile('<li id="{{type}}-{{id}}" class="{{type}}{{#if nocache}} nocache{{/if}}"><a href="#">{{trackname}}</a>'); - this.playlist_item = Handlebars.compile('<td><a href="#" class="play">{{trackname}}</a></td><td><a href="#" class="delete"><img src="/static/icons/delete.png" alt="Delete" title="Delete" /></a></td>'); + this.directory_item = Handlebars.compile('<tr id="{{type}}-{{id}}"><td><a href="#" class="{{type}}{{#unless cache}} nocache{{/unless}}">{{trackname}}</a></td><td>{{metadata.artist}}</td><td>{{metadata.album}}</td></tr>'); + // The playlist automatically adds a tr tag. + this.playlist_item = Handlebars.compile('<td><a href="#" class="play">{{trackname}}</a></td><td><a href="#">{{metadata.artist}}</a></td><td><a href="#">{{metadata.album}}</a></td><td class="track-buttons"><a href="#" class="delete"><img src="/static/icons/delete.png" alt="Delete" title="Delete" /></a></td>'); })(); |