Adding support for browsing Podcasts separately.
This commit is contained in:
parent
58df26fb27
commit
6c0deecb39
8 changed files with 210 additions and 6 deletions
BIN
images/podcast_16x16.png
Executable file
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
24
index.html
Normal file → Executable file
|
@ -38,6 +38,7 @@
|
|||
<div id="nav">
|
||||
<ul class="tabs">
|
||||
<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="#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>
|
||||
|
@ -142,6 +143,29 @@
|
|||
</table>
|
||||
</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 class="actions floatleft">
|
||||
<a href="#" class="button" id="ResetPreferences" title="Reset Preferences">Reset</a>
|
||||
|
|
4
js/app.js
Normal file → Executable file
4
js/app.js
Normal file → Executable file
|
@ -85,6 +85,10 @@ function loadTabContent(tab) {
|
|||
if (debug) { console.log("TAG PLAYLIST"); }
|
||||
loadPlaylists();
|
||||
break;
|
||||
case '#tabPodcasts':
|
||||
if (debug) { console.log("TAG PODCAST"); }
|
||||
loadPodcasts();
|
||||
break;
|
||||
case '#tabPreferences':
|
||||
break;
|
||||
default:
|
||||
|
|
114
js/libs/api.js
Normal file → Executable file
114
js/libs/api.js
Normal file → Executable 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
28
js/libs/generators.js
Normal file → Executable file
|
@ -57,7 +57,33 @@ function generateSongHTML(rowcolor, childid, parentid, track, title, artist, alb
|
|||
html += '</tr>';
|
||||
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) {
|
||||
$.each($(el + ' tr.song'), function (i) {
|
||||
$(this).removeClass('even odd');
|
||||
|
|
3
js/ui-load.js
Normal file → Executable file
3
js/ui-load.js
Normal file → Executable file
|
@ -46,7 +46,7 @@ function resizeContent() {
|
|||
}
|
||||
}
|
||||
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' });
|
||||
$('#player').css({ 'width': tabwidth + 'px' });
|
||||
}
|
||||
|
@ -63,5 +63,6 @@ function resizeSMSection(x) {
|
|||
var ulwidth = newsmwidth + 6;
|
||||
$('#AlbumContainer').css({ 'margin-left': ulwidth + 'px' });
|
||||
$('#TrackContainer').css({ 'margin-left': ulwidth + 'px' });
|
||||
$('#PodcastContainer').css({ 'margin-left': ulwidth + 'px' });
|
||||
}
|
||||
}
|
31
js/ui-ready.js
Normal file → Executable file
31
js/ui-ready.js
Normal file → Executable file
|
@ -339,6 +339,14 @@
|
|||
resizeSMSection(-50);
|
||||
return false;
|
||||
});
|
||||
$('#action_IncreaseWidthPodcasts').click(function () {
|
||||
resizeSMSection(50);
|
||||
return false;
|
||||
});
|
||||
$('#action_DecreaseWidthPodcasts').click(function () {
|
||||
resizeSMSection(-50);
|
||||
return false;
|
||||
});
|
||||
$('#action_SelectAll').click(function () {
|
||||
$('#Albums tr.song').each(function () {
|
||||
$(this).addClass('selected');
|
||||
|
@ -434,6 +442,29 @@
|
|||
getPlaylist($(this).parent().parent().attr("id"), '', '#CurrentPlaylistContainer tbody');
|
||||
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 () {
|
||||
loadPlaylists(true);
|
||||
return false;
|
||||
|
|
6
style/Style.css
Normal file → Executable file
6
style/Style.css
Normal file → Executable file
|
@ -313,7 +313,7 @@ ul.mainlist li.item a.add:hover
|
|||
{
|
||||
margin: 5px 5px 5px 206px;
|
||||
}
|
||||
#TrackContainer
|
||||
#TrackContainer, #PodcastContainer
|
||||
{
|
||||
margin: 5px 5px 5px 206px;
|
||||
}
|
||||
|
@ -471,6 +471,10 @@ table.songlist tr.song td.track
|
|||
width: 40px;
|
||||
text-align: right;
|
||||
}
|
||||
table.songlist tr.song td.published
|
||||
{
|
||||
width: 80px;
|
||||
}
|
||||
table.songlist tr.song td.title
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue