more support for episodes directly in a series folder

This commit is contained in:
Luke Pulverenti 2013-12-03 23:18:50 -05:00
parent b8c8a794f3
commit e38caab270
15 changed files with 217 additions and 65 deletions

View File

@ -66,6 +66,10 @@
border-top: 0; border-top: 0;
} }
.posterItemText + .posterItemProgress {
padding-top: 0;
}
.posterItemDefaultText { .posterItemDefaultText {
position: absolute; position: absolute;
top: 30%; top: 30%;

View File

@ -32,7 +32,7 @@
body { body {
overflow-y: scroll!important; overflow-y: scroll!important;
font-size: 90%; font-size: 13px;
} }
.textlink { .textlink {

View File

@ -11,6 +11,35 @@
<a href="livetvrecordings.html" class="ui-btn-active">Recordings</a> <a href="livetvrecordings.html" class="ui-btn-active">Recordings</a>
<a href="livetvtimers.html">Timers</a> <a href="livetvtimers.html">Timers</a>
</div> </div>
<div id="itemBackdrop" class="itemBackdrop noBackdrop">
<div class="itemBackdropContent">
<table class="detailPageContent primaryDetailPageContent">
<tr>
<td style="vertical-align: top; padding: 10px 1em 10px 0;">
<div id="itemImage" class="itemImageContainer"></div>
</td>
<td style="vertical-align: top; padding: 0;">
<p><span class="itemName inlineItemName"></span><span class="itemMiscInfo" style="display: inline;"></span></p>
<p class="itemChannelNumber"></p>
<p style="margin: 2em 0;">
<span class="userDataIcons"></span>
</p>
</td>
</tr>
</table>
</div>
</div>
<div class="ui-body-a" style="text-align: center; padding: .25em 0 .5em;">
<span id="playButtonContainer" style="display: none;">
<button id="btnPlay" type="button" data-icon="play" data-inline="true" data-mini="true">Play</button>
</span>
<span>
<button id="btnRemote" type="button" data-icon="hand-up" data-inline="true" data-mini="true">Remote</button>
</span>
<span id="deleteButtonContainer" style="display: none;">
<button id="btnDelete" type="button" data-icon="delete" data-inline="true" data-mini="true">Delete</button>
</span>
</div>
<div data-role="content"> <div data-role="content">
</div> </div>
</div> </div>

View File

@ -24,7 +24,7 @@
<th class="desktopColumn">Channel</th> <th class="desktopColumn">Channel</th>
<th>Date</th> <th>Date</th>
<th>Start</th> <th>Start</th>
<th class="tabletColumn">End</th> <th class="tabletColumn">Length</th>
<th class="tabletColumn">Status</th> <th class="tabletColumn">Status</th>
</tr> </tr>
</thead> </thead>

View File

@ -364,14 +364,34 @@
return; return;
} }
var friendly = item.Type == "Audio" ? "song" : item.Type.toLowerCase(); var promise;
ApiClient.getItems(Dashboard.getCurrentUserId(), { if (item.Type == "Season") {
AdjacentTo: item.Id, promise = ApiClient.getSeasons(item.SeriesId, {
ParentId: item.ParentId
}).done(function (result) { userId: Dashboard.getCurrentUserId(),
AdjacentTo: item.Id
});
}
else if (item.Type == "Episode") {
// Use dedicated episodes endpoint
promise = ApiClient.getEpisodes(item.SeriesId, {
seasonId: item.SeasonId,
userId: Dashboard.getCurrentUserId(),
AdjacentTo: item.Id
});
} else {
promise = ApiClient.getItems(Dashboard.getCurrentUserId(), {
AdjacentTo: item.Id,
ParentId: item.ParentId
});
}
promise.done(function (result) {
for (var i = 0, length = result.Items.length; i < length; i++) { for (var i = 0, length = result.Items.length; i < length; i++) {
@ -381,13 +401,15 @@
continue; continue;
} }
var friendlyTypeName = item.Type == "Audio" ? "song" : item.Type.toLowerCase();
if (curr.IndexNumber < item.IndexNumber) { if (curr.IndexNumber < item.IndexNumber) {
$('.lnkPreviousItem', page).removeClass('hide').attr('href', 'itemdetails.html?id=' + curr.Id).html('← Previous ' + friendly); $('.lnkPreviousItem', page).removeClass('hide').attr('href', 'itemdetails.html?id=' + curr.Id).html('← Previous ' + friendlyTypeName);
} }
else if (curr.IndexNumber > item.IndexNumber) { else if (curr.IndexNumber > item.IndexNumber) {
$('.lnkNextItem', page).removeClass('hide').attr('href', 'itemdetails.html?id=' + curr.Id).html('Next ' + friendly + ' →'); $('.lnkNextItem', page).removeClass('hide').attr('href', 'itemdetails.html?id=' + curr.Id).html('Next ' + friendlyTypeName + ' →');
} }
} }
}); });
@ -518,23 +540,12 @@
} }
else if (item.Type == "Season") { else if (item.Type == "Season") {
if (item.IndexNumber == null) { // Use dedicated episodes endpoint
promise = ApiClient.getEpisodes(item.SeriesId, {
// Use dedicated episodes endpoint seasonId: item.Id,
promise = ApiClient.getEpisodes(item.SeriesId, { userId: user.Id
});
seasonId: item.Id,
userId: user.Id
});
} else {
// Use dedicated episodes endpoint
promise = ApiClient.getEpisodes(item.SeriesId, {
season: item.IndexNumber,
userId: user.Id
});
}
} }
promise = promise || ApiClient.getItems(Dashboard.getCurrentUserId(), query); promise = promise || ApiClient.getItems(Dashboard.getCurrentUserId(), query);

View File

@ -68,7 +68,8 @@
for (var i = 0, length = result.Items.length; i < length; i++) { for (var i = 0, length = result.Items.length; i < length; i++) {
urls.push(LibraryBrowser.getImageUrl(result.Items[i], 'Primary', 0, { urls.push(LibraryBrowser.getImageUrl(result.Items[i], 'Primary', 0, {
width: 160 width: 160,
EnableImageEnhancers: false
})); }));
} }
@ -96,7 +97,8 @@
for (var i = 0, length = result.Items.length; i < length; i++) { for (var i = 0, length = result.Items.length; i < length; i++) {
urls.push(LibraryBrowser.getImageUrl(result.Items[i], 'Primary', 0, { urls.push(LibraryBrowser.getImageUrl(result.Items[i], 'Primary', 0, {
width: 160 width: 160,
EnableImageEnhancers: false
})); }));
} }
@ -124,7 +126,8 @@
for (var i = 0, length = result.Items.length; i < length; i++) { for (var i = 0, length = result.Items.length; i < length; i++) {
urls.push(LibraryBrowser.getImageUrl(result.Items[i], 'Primary', 0, { urls.push(LibraryBrowser.getImageUrl(result.Items[i], 'Primary', 0, {
width: 160 width: 160,
EnableImageEnhancers: false
})); }));
} }
@ -152,7 +155,8 @@
for (var i = 0, length = result.Items.length; i < length; i++) { for (var i = 0, length = result.Items.length; i < length; i++) {
urls.push(LibraryBrowser.getImageUrl(result.Items[i], 'Primary', 0, { urls.push(LibraryBrowser.getImageUrl(result.Items[i], 'Primary', 0, {
width: 160 width: 160,
EnableImageEnhancers: false
})); }));
} }

View File

@ -735,7 +735,7 @@
else if (item.ImageTags && item.ImageTags.Primary) { else if (item.ImageTags && item.ImageTags.Primary) {
height = 300; height = 300;
width = primaryImageAspectRatio ? parseInt(height * primaryImageAspectRatio) : null; width = primaryImageAspectRatio ? (height * primaryImageAspectRatio).toFixed(0) : null;
imgUrl = ApiClient.getImageUrl(item.Id, { imgUrl = ApiClient.getImageUrl(item.Id, {
type: "Primary", type: "Primary",
@ -748,7 +748,7 @@
else if (item.AlbumId && item.AlbumPrimaryImageTag) { else if (item.AlbumId && item.AlbumPrimaryImageTag) {
height = 300; height = 300;
width = primaryImageAspectRatio ? parseInt(height * primaryImageAspectRatio) : null; width = primaryImageAspectRatio ? (height * primaryImageAspectRatio).toFixed(0) : null;
imgUrl = ApiClient.getImageUrl(item.AlbumId, { imgUrl = ApiClient.getImageUrl(item.AlbumId, {
type: "Primary", type: "Primary",
@ -1200,7 +1200,7 @@
} }
else if (item.ParentIndexNumber && item.Type == "Episode") { else if (item.ParentIndexNumber && item.Type == "Episode") {
html.push('<a class="detailPageParentLink" href="itemdetails.html?id=' + item.ParentId + '">Season ' + item.ParentIndexNumber + '</a>'); html.push('<a class="detailPageParentLink" href="itemdetails.html?id=' + item.SeasonId + '">Season ' + item.ParentIndexNumber + '</a>');
} }
else if (item.Album && item.Type == "Audio" && (item.AlbumId || item.ParentId)) { else if (item.Album && item.Type == "Audio" && (item.AlbumId || item.ParentId)) {
html.push('<a class="detailPageParentLink" href="itemdetails.html?id=' + (item.AlbumId || item.ParentId) + '">' + item.Album + '</a>'); html.push('<a class="detailPageParentLink" href="itemdetails.html?id=' + (item.AlbumId || item.ParentId) + '">' + item.Album + '</a>');
@ -2009,20 +2009,31 @@
} }
} }
var minutes;
if (item.RunTimeTicks && item.Type != "Series") { if (item.RunTimeTicks && item.Type != "Series") {
if (item.Type == "Audio") { if (item.Type == "Audio") {
miscInfo.push(Dashboard.getDisplayTime(item.RunTimeTicks)); miscInfo.push(Dashboard.getDisplayTime(item.RunTimeTicks));
} else { } else {
var minutes = item.RunTimeTicks / 600000000; minutes = item.RunTimeTicks / 600000000;
minutes = minutes || 1; minutes = minutes || 1;
miscInfo.push(parseInt(minutes) + "min"); miscInfo.push(minutes.toFixed(0) + "min");
} }
} }
if (item.DurationMs) {
minutes = item.DurationMs / 60000;
minutes = minutes || 1;
miscInfo.push(minutes.toFixed(0) + "min");
}
if (item.OfficialRating && item.Type !== "Season" && item.Type !== "Episode") { if (item.OfficialRating && item.Type !== "Season" && item.Type !== "Episode") {
miscInfo.push(item.OfficialRating); miscInfo.push(item.OfficialRating);
} }

View File

@ -1,19 +1,99 @@
function deleteRecording(page, id) { (function ($, document, apiClient) {
Dashboard.confirm("Are you sure you wish to delete this recording?", "Confirm Recording Deletion", function (result) { var currentItem;
if (result) { function deleteRecording() {
Dashboard.showLoadingMsg(); Dashboard.confirm("Are you sure you wish to delete this recording?", "Confirm Recording Deletion", function (result) {
ApiClient.deleteLiveTvRecording(id).done(function () { if (result) {
Dashboard.alert('Recording deleted'); Dashboard.showLoadingMsg();
reload(page); ApiClient.deleteLiveTvRecording(currentItem.Id).done(function () {
});
Dashboard.alert('Recording deleted');
Dashboard.navigate('livetvrecordings.html');
});
}
});
}
function renderRecording(page, item) {
currentItem = item;
var name = item.Name;
$('#itemImage', page).html(LibraryBrowser.getDetailImageHtml(item));
Dashboard.setPageTitle(name);
$('.itemName', page).html(name);
$('.itemChannelNumber', page).html(item.Number);
$('.userDataIcons', page).html(LibraryBrowser.getUserDataIconsHtml(item));
$('.itemMiscInfo', page).html(LibraryBrowser.getMiscInfoHtml(item));
if (ApiClient.isWebSocketOpen()) {
var vals = [item.Type, item.Id, item.Name];
vals.push('livetv');
ApiClient.sendWebSocketMessage("Context", vals.join('|'));
} }
}); if (MediaPlayer.canPlay(item)) {
} $('#playButtonContainer', page).show();
} else {
$('#playButtonContainer', page).hide();
}
Dashboard.getCurrentUser().done(function (user) {
if (user.Configuration.IsAdministrator && item.LocationType !== "Offline") {
$('#deleteButtonContainer', page).show();
} else {
$('#deleteButtonContainer', page).hide();
}
});
Dashboard.hideLoadingMsg();
}
function reload(page) {
Dashboard.showLoadingMsg();
var id = getParameterByName('id');
apiClient.getLiveTvRecording(id).done(function (result) {
renderRecording(page, result);
});
}
$(document).on('pageinit', "#liveTvRecordingPage", function () {
var page = this;
$('#btnDelete', page).on('click', deleteRecording);
}).on('pagebeforeshow', "#liveTvRecordingPage", function () {
var page = this;
reload(page);
}).on('pagehide', "#liveTvRecordingPage", function () {
currentItem = null;
});
})(jQuery, document, ApiClient);

View File

@ -34,7 +34,13 @@
html += '</td>'; html += '</td>';
html += '<td>'; html += '<td>';
html += '<a href="livetvrecording.html?id=' + recording.Id + '">' + recording.Name + '</a>'; html += '<a href="livetvrecording.html?id=' + recording.Id + '">';
html += recording.Name;
if (recording.EpisodeTitle) {
html += "<br/>" + recording.EpisodeTitle;
}
html += '</a>';
html += '</td>'; html += '</td>';
html += '<td class="desktopColumn">'; html += '<td class="desktopColumn">';
@ -57,7 +63,9 @@
html += '<td>' + LiveTvHelpers.getDisplayTime(recording.StartDate) + '</td>'; html += '<td>' + LiveTvHelpers.getDisplayTime(recording.StartDate) + '</td>';
html += '<td class="tabletColumn">' + LiveTvHelpers.getDisplayTime(recording.EndDate) + '</td>'; var minutes = recording.DurationMs / 60000;
html += '<td class="tabletColumn">' + minutes.toFixed(0) + ' mins</td>';
html += '<td class="tabletColumn">' + (recording.Status || '') + '</td>'; html += '<td class="tabletColumn">' + (recording.Status || '') + '</td>';

View File

@ -38,7 +38,7 @@
html += '<th class="desktopColumn">Channel</th>'; html += '<th class="desktopColumn">Channel</th>';
html += '<th>Date</th>'; html += '<th>Date</th>';
html += '<th>Start</th>'; html += '<th>Start</th>';
html += '<th class="tabletColumn">End</th>'; html += '<th class="tabletColumn">Length</th>';
html += '<th class="tabletColumn">Status</th>'; html += '<th class="tabletColumn">Status</th>';
html += '<th class="desktopColumn">Recurring</th>'; html += '<th class="desktopColumn">Recurring</th>';
@ -78,7 +78,9 @@
html += '<td>' + LiveTvHelpers.getDisplayTime(timer.StartDate) + '</td>'; html += '<td>' + LiveTvHelpers.getDisplayTime(timer.StartDate) + '</td>';
html += '<td class="tabletColumn">' + LiveTvHelpers.getDisplayTime(timer.EndDate) + '</td>'; var minutes = timer.DurationMs / 60000;
html += '<td class="tabletColumn">' + minutes.toFixed(0) + ' mins</td>';
html += '<td class="tabletColumn">' + (timer.Status || '') + '</td>'; html += '<td class="tabletColumn">' + (timer.Status || '') + '</td>';

View File

@ -102,11 +102,11 @@
hours = 0; hours = 0;
} }
hours = parseInt(hours); hours = hours.toFixed(0);
ticks -= (hours * 36000000000); ticks -= (hours * 36000000000);
var minutes = parseInt(ticks / 600000000); var minutes = (ticks / 600000000).toFixed(0);
var suffix = "am"; var suffix = "am";

View File

@ -1100,7 +1100,7 @@ var Dashboard = {
var parts = []; var parts = [];
var hours = ticks / ticksPerHour; var hours = ticks / ticksPerHour;
hours = parseInt(hours); hours = hours.toFixed(0);
if (hours) { if (hours) {
parts.push(hours); parts.push(hours);
@ -1111,7 +1111,7 @@ var Dashboard = {
var ticksPerMinute = 600000000; var ticksPerMinute = 600000000;
var minutes = ticks / ticksPerMinute; var minutes = ticks / ticksPerMinute;
minutes = parseInt(minutes); minutes = minutes.toFixed(0);
ticks -= (minutes * ticksPerMinute); ticks -= (minutes * ticksPerMinute);
@ -1123,7 +1123,7 @@ var Dashboard = {
var ticksPerSecond = 10000000; var ticksPerSecond = 10000000;
var seconds = ticks / ticksPerSecond; var seconds = ticks / ticksPerSecond;
seconds = parseInt(seconds); seconds = seconds.toFixed(0);
if (seconds < 10) { if (seconds < 10) {
seconds = '0' + seconds; seconds = '0' + seconds;

View File

@ -9,7 +9,7 @@
SortBy: "DateCreated", SortBy: "DateCreated",
SortOrder: "Descending", SortOrder: "Descending",
IncludeItemTypes: "Episode", IncludeItemTypes: "Episode",
Limit: 8, Limit: 12,
Recursive: true, Recursive: true,
Fields: "PrimaryImageAspectRatio,SeriesInfo,UserData", Fields: "PrimaryImageAspectRatio,SeriesInfo,UserData",
Filters: "IsUnplayed", Filters: "IsUnplayed",
@ -35,7 +35,7 @@
SortOrder: "Descending", SortOrder: "Descending",
IncludeItemTypes: "Episode", IncludeItemTypes: "Episode",
Filters: "IsResumable", Filters: "IsResumable",
Limit: 8, Limit: 4,
Recursive: true, Recursive: true,
Fields: "PrimaryImageAspectRatio,SeriesInfo,UserData", Fields: "PrimaryImageAspectRatio,SeriesInfo,UserData",
ExcludeLocationTypes: "Virtual" ExcludeLocationTypes: "Virtual"

View File

@ -7,8 +7,10 @@
function getDateFormat(date) { function getDateFormat(date) {
// yyyyMMddHHmmss // yyyyMMddHHmmss
var d = date; // Convert to UTC
// http://stackoverflow.com/questions/948532/how-do-you-convert-a-javascript-date-to-utc/14610512#14610512
var d = new Date(date.getTime());
return "" + d.getFullYear() + formatDigit(d.getMonth() + 1) + formatDigit(d.getDate()) + formatDigit(d.getHours()) + formatDigit(d.getMinutes()) + formatDigit(d.getSeconds()); return "" + d.getFullYear() + formatDigit(d.getMonth() + 1) + formatDigit(d.getDate()) + formatDigit(d.getHours()) + formatDigit(d.getMinutes()) + formatDigit(d.getSeconds());
} }
@ -28,15 +30,15 @@
var missedItemsQuery = $.extend({ var missedItemsQuery = $.extend({
}, query); IsUnaired: false
}, query);
var yesterday = new Date(); var yesterday = new Date();
yesterday.setHours(23, 50, 0, 0);
yesterday.setDate(yesterday.getDate() - 1); yesterday.setDate(yesterday.getDate() - 1);
missedItemsQuery.MaxPremiereDate = getDateFormat(yesterday);
yesterday.setHours(0, 0, 0, 0); yesterday.setHours(0, 0, 0, 0);
missedItemsQuery.MinPremiereDate = getDateFormat(yesterday); missedItemsQuery.MinPremiereDate = getDateFormat(yesterday);
var unairedQuery = $.extend({ var unairedQuery = $.extend({

View File

@ -19,10 +19,6 @@
<table class="ehsContent"> <table class="ehsContent">
<tr> <tr>
<td> <td>
<h1 class="listHeader firstListHeader">Latest Episodes</h1>
<div id="recentlyAddedItems">
</div>
<div id="resumableSection" style="display: none;"> <div id="resumableSection" style="display: none;">
<h1 class="listHeader">Resume</h1> <h1 class="listHeader">Resume</h1>
@ -30,6 +26,11 @@
<div id="resumableItems"> <div id="resumableItems">
</div> </div>
</div> </div>
<h1 class="listHeader">Latest Episodes</h1>
<div id="recentlyAddedItems">
</div>
</td> </td>
</tr> </tr>
</table> </table>