Adding support for browsing Podcasts separately.

This commit is contained in:
Nithin Philips 2012-09-25 22:25:44 -04:00
parent 58df26fb27
commit 6c0deecb39
8 changed files with 210 additions and 6 deletions

BIN
images/podcast_16x16.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,019 B

24
index.html Normal file → Executable file
View file

@ -38,6 +38,7 @@
<div id="nav"> <div id="nav">
<ul class="tabs"> <ul class="tabs">
<li><a href="#tabLibrary" class="first" title="Library"><img src="images/headphones_gd_16x14.png" /></a></li> <li><a href="#tabLibrary" class="first" title="Library"><img src="images/headphones_gd_16x14.png" /></a></li>
<li><a href="#tabPodcasts" title="Podcasts"><img src="images/podcast_16x16.png" /></a></li>
<li><a href="#tabCurrent" title="Current Playlist"><img src="images/play_alt_gd_16x16.png" /></a></li> <li><a href="#tabCurrent" title="Current Playlist"><img src="images/play_alt_gd_16x16.png" /></a></li>
<li><a href="#tabPlaylists" title="Playlists"><img src="images/list_gd_16x14.png" /></a></li> <li><a href="#tabPlaylists" title="Playlists"><img src="images/list_gd_16x14.png" /></a></li>
<li><a href="#tabPreferences" class="last" title="Preferences"><img src="images/cog_16x16.png" /></a></li> <li><a href="#tabPreferences" class="last" title="Preferences"><img src="images/cog_16x16.png" /></a></li>
@ -142,6 +143,29 @@
</table> </table>
</div> </div>
</div> </div>
<div id="tabPodcasts" class="tabcontent">
<div class="actions floatleft">
<a href="#" class="button" id="action_RefreshPodcasts" title="Refresh Podcasts"><img src="images/reload_9x11.png" /></a>
<a href="#" class="button" id="action_DecreaseWidthPodcasts" title="Decrease Width"><img src="images/minus_8x2.png" /></a>
<a href="#" class="button" id="action_IncreaseWidthPodcasts" title="Increase Width"><img src="images/plus_8x8.png" /></a>
</div>
<div class="subactions floatleft">
</div>
<div class="clear"></div>
<div id="Podcasts" class="lgsection floatleft noselect">
<div class="loading"></div>
<div id="PodcastList" class="smsection floatleft noselect">
<div class="padder">
<ul class="simplelist"><li class="index">Podcasts</li></ul>
<ul id="ChannelsContainer" class="simplelist mainlist"></ul>
</div>
</div>
<table id="PodcastContainer" class="simplelist songlist">
<thead></thead>
<tbody></tbody>
</table>
</div>
</div>
<div id="tabPreferences" class="tabcontent"> <div id="tabPreferences" class="tabcontent">
<div class="actions floatleft"> <div class="actions floatleft">
<a href="#" class="button" id="ResetPreferences" title="Reset Preferences">Reset</a> <a href="#" class="button" id="ResetPreferences" title="Reset Preferences">Reset</a>

4
js/app.js Normal file → Executable file
View file

@ -85,6 +85,10 @@ function loadTabContent(tab) {
if (debug) { console.log("TAG PLAYLIST"); } if (debug) { console.log("TAG PLAYLIST"); }
loadPlaylists(); loadPlaylists();
break; break;
case '#tabPodcasts':
if (debug) { console.log("TAG PODCAST"); }
loadPodcasts();
break;
case '#tabPreferences': case '#tabPreferences':
break; break;
default: default:

114
js/libs/api.js Normal file → Executable file
View file

@ -688,3 +688,117 @@ function getPlaylist(id, action, appendto) {
} }
}); });
} }
function loadPodcasts(refresh) {
if (debug) { console.log("LOAD PODCASTS"); }
if (refresh) {
$('#ChannelsContainer').empty();
}
var content = $('#ChannelsContainer').html();
if (content === "") {
// Load Podcasts
$.ajax({
url: baseURL + '/getPodcasts.view?u=' + username + '&p=' + password + '&v=' + version + '&c=' + applicationName + '&f=jsonp',
method: 'GET',
dataType: 'jsonp',
timeout: 10000,
success: function (data) {
var playlists = [];
if (data["subsonic-response"].podcasts.channel.length > 0) {
podcasts = data["subsonic-response"].podcasts.channel;
} else {
podcasts[0] = data["subsonic-response"].podcasts.channel;
}
$.each(podcasts, function (i, podcast) {
var albumId = (podcast.episode === undefined || podcast.episode.length <= 0) ? "0" : podcast.episode[0].parent;
var html = "";
html += '<li id=\"' + podcast.id + '\" albumid=\"' + albumId + '\" class=\"item\">';
html += '<span>' + podcast.title + '</span>';
html += '<div class=\"floatright\"><a class=\"play\" href=\"\" title=\"Play\"></a></div>';
html += '<div class=\"floatright\"><a class=\"download\" href=\"\" title=\"Download\"></a></div>';
html += '<div class=\"floatright\"><a class=\"add\" href=\"\" title=\"Add To Current Playlist\"></a></div>';
html += '</li>';
$(html).appendTo("#ChannelsContainer");
});
}
});
}
}
function getPodcast(id, action, appendto) {
$.ajax({
url: baseURL + '/getPodcasts.view?u=' + username + '&p=' + password + '&v=' + version + '&c=' + applicationName + '&f=jsonp',
method: 'GET',
dataType: 'jsonp',
timeout: 10000,
success: function (data) {
var channels = data["subsonic-response"].podcasts.channel;
// we hope that the result is ordered by id
var channel = channels[id - 1];
if(channel === undefined || channel.id != id){
// sometimes we have to do some extra work.
for (var i = 0; i < channels.length; i++) {
if(podcasts[i].id == id)
{
channel = channels[i];
break;
}
}
}
if (channel.episode !== undefined) {
if (appendto === '#PodcastContainer tbody') {
$(appendto).empty();
var header = generatePodcastHeaderHTML();
$("#PodcastContainer thead").html(header);
}
if (action === 'autoplay') {
$(appendto).empty();
}
var children = channel.episode;
var rowcolor;
var html;
var count = children.length;
$.each(children, function (i, child) {
if(child.status == "skipped") return; // Skip podcasts that are not yet downloaded
if (i % 2 === 0) {
rowcolor = 'even';
} else {
rowcolor = 'odd';
}
var date = parseDate(child.publishDate);
var time = secondsToTime(child.duration);
html = generatePodcastHTML(rowcolor, child.streamId, child.parent, date, child.title, child.artist, child.album, child.coverArt, child.userRating, time['m'], time['s']);
$(html).appendTo(appendto);
});
updateMessage(count + ' Songs');
if (appendto === '#CurrentPlaylistContainer tbody') {
updateMessage(children.length + ' Song(s) Added');
}
if (action === 'autoplay') {
autoPlay();
}
} else {
if (appendto === '#PodcastContainer tbody') {
$(appendto).empty();
}
}
}
});
}
function parseDate(date) {
// input: "2012-09-23 20:00:00.0"
var months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
var parts = date.split(" ");
var dateParts = parts[0].split("-");
var month = parseInt(dateParts[1], 10) - 1;
var date = months[month] + " " + dateParts[2] + ", " + dateParts[0];
return date;
}

28
js/libs/generators.js Normal file → Executable file
View file

@ -57,7 +57,33 @@ function generateSongHTML(rowcolor, childid, parentid, track, title, artist, alb
html += '</tr>'; html += '</tr>';
return html; return html;
} }
function generatePodcastHeaderHTML() {
var html;
html = '<tr><th></th><th>Published</th><th>Title</th><th>Artist</th><th>Album</th><th class=\"alignright\">Time</th></tr>';
return html;
}
function generatePodcastHTML(rowcolor, childid, parentid, published, title, artist, album, coverart, rating, m, s) {
var html;
html = '<tr class=\"song ' + rowcolor + '\" childid=\"' + childid + '\" parentid=\"' + parentid + '\" userrating=\"' + rating + '\">';
html += '<td class=\"itemactions\"><a class=\"add\" href=\"\" title=\"Add To Current Playlist\"></a>';
html += '<a class=\"remove\" href=\"\" title=\"Remove\"></a>';
html += '<a class=\"play\" href=\"\" title=\"Play\"></a>';
html += '<a class=\"download\" href=\"\" title=\"Download\"></a>';
html += '</td>';
html += '<td class=\"published\">' + published + '</td>';
html += '<td class=\"title\">' + title + '</td>';
html += '<td class=\"artist\">' + artist + '</td>';
var coverartSrc;
if (coverart == undefined) {
coverartSrc = 'images/albumdefault_25.jpg';
} else {
coverartSrc = baseURL + '/getCoverArt.view?v=' + version + '&c=' + applicationName + '&f=jsonp&size=25&id=' + coverart;
}
html += '<td class=\"album\"><a href="javascript:getAlbums(\'' + parentid + '\',\'\',\'#AlbumRows\')">' + album + '<img src=\"' + coverartSrc + '\" /></a></td>';
html += '<td class=\"time\">' + m + ':' + s + '</td>';
html += '</tr>';
return html;
}
function refreshRowColor(el) { function refreshRowColor(el) {
$.each($(el + ' tr.song'), function (i) { $.each($(el + ' tr.song'), function (i) {
$(this).removeClass('even odd'); $(this).removeClass('even odd');

5
js/ui-load.js Normal file → Executable file
View file

@ -46,7 +46,7 @@ function resizeContent() {
} }
} }
var tabwidth = $('.tabcontent').width(); var tabwidth = $('.tabcontent').width();
$('#AlbumContainer, #TrackContainer, #CurrentPlaylistContainer').css({ 'width': (tabwidth - smwidth - 30) + 'px' }); $('#AlbumContainer, #TrackContainer, #PodcastContainer, #CurrentPlaylistContainer').css({ 'width': (tabwidth - smwidth - 30) + 'px' });
$('#CurrentPlaylistContainer').css({ 'width': (tabwidth - 30) + 'px' }); $('#CurrentPlaylistContainer').css({ 'width': (tabwidth - 30) + 'px' });
$('#player').css({ 'width': tabwidth + 'px' }); $('#player').css({ 'width': tabwidth + 'px' });
} }
@ -63,5 +63,6 @@ function resizeSMSection(x) {
var ulwidth = newsmwidth + 6; var ulwidth = newsmwidth + 6;
$('#AlbumContainer').css({ 'margin-left': ulwidth + 'px' }); $('#AlbumContainer').css({ 'margin-left': ulwidth + 'px' });
$('#TrackContainer').css({ 'margin-left': ulwidth + 'px' }); $('#TrackContainer').css({ 'margin-left': ulwidth + 'px' });
$('#PodcastContainer').css({ 'margin-left': ulwidth + 'px' });
} }
} }

33
js/ui-ready.js Normal file → Executable file
View file

@ -339,6 +339,14 @@
resizeSMSection(-50); resizeSMSection(-50);
return false; return false;
}); });
$('#action_IncreaseWidthPodcasts').click(function () {
resizeSMSection(50);
return false;
});
$('#action_DecreaseWidthPodcasts').click(function () {
resizeSMSection(-50);
return false;
});
$('#action_SelectAll').click(function () { $('#action_SelectAll').click(function () {
$('#Albums tr.song').each(function () { $('#Albums tr.song').each(function () {
$(this).addClass('selected'); $(this).addClass('selected');
@ -434,6 +442,29 @@
getPlaylist($(this).parent().parent().attr("id"), '', '#CurrentPlaylistContainer tbody'); getPlaylist($(this).parent().parent().attr("id"), '', '#CurrentPlaylistContainer tbody');
return false; return false;
}); });
$('#ChannelsContainer li.item').live('click', function () {
$('#AutoChannelsContainer li').removeClass('selected');
$('#ChannelsContainer li').removeClass('selected');
$(this).addClass('selected');
getPodcast($(this).attr("id"), '', '#PodcastContainer tbody');
});
$('#ChannelsContainer li.item a.play').live('click', function () {
getPodcast($(this).parent().parent().attr("id"), 'autoplay', '#CurrentPlaylistContainer tbody');
return false;
});
$('#ChannelsContainer li.item a.download').live('click', function (event) {
var itemid = $(this).parent().parent().attr('albumid');
downloadItem(itemid, 'item');
return false;
});
$('#ChannelsContainer li.item a.add').live('click', function () {
getPodcast($(this).parent().parent().attr("id"), '', '#CurrentPlaylistContainer tbody');
return false;
});
$('#action_RefreshPodcasts').click(function () {
loadPodcasts(true);
return false;
});
$('#action_RefreshPlaylists').click(function () { $('#action_RefreshPlaylists').click(function () {
loadPlaylists(true); loadPlaylists(true);
return false; return false;
@ -653,4 +684,4 @@
} }
}).disableSelection(); }).disableSelection();
}); // End document.ready }); // End document.ready

8
style/Style.css Normal file → Executable file
View file

@ -313,7 +313,7 @@ ul.mainlist li.item a.add:hover
{ {
margin: 5px 5px 5px 206px; margin: 5px 5px 5px 206px;
} }
#TrackContainer #TrackContainer, #PodcastContainer
{ {
margin: 5px 5px 5px 206px; margin: 5px 5px 5px 206px;
} }
@ -471,6 +471,10 @@ table.songlist tr.song td.track
width: 40px; width: 40px;
text-align: right; text-align: right;
} }
table.songlist tr.song td.published
{
width: 80px;
}
table.songlist tr.song td.title table.songlist tr.song td.title
{ {
} }
@ -1154,4 +1158,4 @@ fieldset
legend legend
{ {
font-size: 12px; font-size: 12px;
} }