1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

stub out web client media controller

This commit is contained in:
Luke Pulverenti 2014-03-29 11:40:32 -04:00
parent 8842110e54
commit 355c3dcb42
21 changed files with 399 additions and 1061 deletions

View file

@ -165,7 +165,7 @@
/****************************************/ /****************************************/
@media all and (max-width: 1200px), all and (max-height: 720px) { @media all and (max-width: 1200px), all and (max-height: 720px) {
#mediaPlayer .chaptersButton, #mediaPlayer .audioTracksButton, #mediaPlayer .sendMediaButton { #mediaPlayer .chaptersButton, #mediaPlayer .audioTracksButton {
display: none!important; display: none!important;
} }
@ -179,7 +179,7 @@
} }
@media all and (max-width: 960px), all and (max-height: 550px) { @media all and (max-width: 960px), all and (max-height: 550px) {
#mediaPlayer .nowPlayingBarImage, #mediaPlayer .qualityButton, #mediaPlayer .audioTracksButton, #mediaPlayer .chaptersButton, #mediaPlayer .sendMediaButton { #mediaPlayer .nowPlayingBarImage, #mediaPlayer .qualityButton, #mediaPlayer .audioTracksButton, #mediaPlayer .chaptersButton {
display: none!important; display: none!important;
} }
@ -193,7 +193,7 @@
} }
@media all and (max-width: 800px), all and (max-height: 460px) { @media all and (max-width: 800px), all and (max-height: 460px) {
#mediaPlayer .muteButton, #mediaPlayer .unmuteButton, #mediaPlayer .nowPlayingMediaInfo, #mediaPlayer .sendMediaButton { #mediaPlayer .muteButton, #mediaPlayer .unmuteButton, #mediaPlayer .nowPlayingMediaInfo {
display: none!important; display: none!important;
} }

View file

@ -135,7 +135,7 @@ input[type="range"]::-ms-fill-upper {
} }
@media all and (max-width: 600px) { @media all and (max-width: 600px) {
.chaptersButton, .audioTracksButton, .sendMediaButton { .chaptersButton, .audioTracksButton {
display: none!important; display: none!important;
} }

View file

@ -120,11 +120,13 @@
</div> </div>
<div class="profileTab tabDirectPlayProfiles"> <div class="profileTab tabDirectPlayProfiles">
<p>Add direct play profiles to indicate what formats the device can handle natively.</p> <p>Add direct play profiles to indicate which formats the device can handle natively.</p>
<button class="btnAddDirectPlayProfile" type="button" data-mini="true" data-icon="plus">New</button>
<br />
<div class="directPlayProfiles"></div> <div class="directPlayProfiles"></div>
</div> </div>
<div class="profileTab tabTranscodingProfiles"> <div class="profileTab tabTranscodingProfiles">
<p>Add transcoding profiles to indicate what formats should be used when transcoding is required.</p> <p>Add transcoding profiles to indicate which formats should be used when transcoding is required.</p>
<div class="transcodingProfiles"></div> <div class="transcodingProfiles"></div>
</div> </div>
<div class="profileTab tabContainerProfiles"> <div class="profileTab tabContainerProfiles">

View file

@ -145,9 +145,6 @@
<span id="playButtonContainer" style="display: none;"> <span id="playButtonContainer" style="display: none;">
<button id="btnPlay" type="button" data-icon="play" data-inline="true" data-mini="true">Play</button> <button id="btnPlay" type="button" data-icon="play" data-inline="true" data-mini="true">Play</button>
</span> </span>
<span>
<button id="btnRemote" type="button" data-icon="wireless" data-inline="true" data-mini="true">Remote</button>
</span>
<span id="editButtonContainer" style="display: none;"> <span id="editButtonContainer" style="display: none;">
<a id="btnEdit" data-role="button" data-icon="edit" data-inline="true" data-mini="true" href="#">Edit</a> <a id="btnEdit" data-role="button" data-icon="edit" data-inline="true" data-mini="true" href="#">Edit</a>
</span> </span>

View file

@ -131,9 +131,6 @@
<span id="playExternalButtonContainer" style="display: none;"> <span id="playExternalButtonContainer" style="display: none;">
<a id="btnPlayExternal" data-role="button" data-icon="play" data-inline="true" data-mini="true" href="#" target="_blank">Play</a> <a id="btnPlayExternal" data-role="button" data-icon="play" data-inline="true" data-mini="true" href="#" target="_blank">Play</a>
</span> </span>
<span id="remoteButtonContainer" style="display: none;">
<button id="btnRemote" type="button" data-icon="wireless" data-inline="true" data-mini="true">Remote</button>
</span>
<span id="editButtonContainer" style="display: none;"> <span id="editButtonContainer" style="display: none;">
<a id="btnEdit" data-role="button" data-icon="edit" data-inline="true" data-mini="true" href="#">Edit</a> <a id="btnEdit" data-role="button" data-icon="edit" data-inline="true" data-mini="true" href="#">Edit</a>
</span> </span>

View file

@ -30,9 +30,6 @@
<span id="playButtonContainer" style="display: none;"> <span id="playButtonContainer" style="display: none;">
<button id="btnPlay" type="button" data-icon="play" data-inline="true" data-mini="true">Play</button> <button id="btnPlay" type="button" data-icon="play" data-inline="true" data-mini="true">Play</button>
</span> </span>
<span>
<button id="btnRemote" type="button" data-icon="wireless" data-inline="true" data-mini="true">Remote</button>
</span>
<span id="editButtonContainer" style="display: none;"> <span id="editButtonContainer" style="display: none;">
<button id="btnEdit" type="button" data-icon="edit" data-inline="true" data-mini="true">Edit</button> <button id="btnEdit" type="button" data-icon="edit" data-inline="true" data-mini="true">Edit</button>
</span> </span>

View file

@ -47,9 +47,6 @@
<span id="recordButtonContainer" style="display: none;"> <span id="recordButtonContainer" style="display: none;">
<button id="btnRecord" type="button" data-icon="video" data-inline="true" data-mini="true">Record</button> <button id="btnRecord" type="button" data-icon="video" data-inline="true" data-mini="true">Record</button>
</span> </span>
<span>
<button id="btnRemote" type="button" data-icon="wireless" data-inline="true" data-mini="true">Remote</button>
</span>
</div> </div>
<div data-role="content"> <div data-role="content">
<div class="detailPageContent"> <div class="detailPageContent">

View file

@ -41,9 +41,6 @@
<span id="playButtonContainer" style="display: none;"> <span id="playButtonContainer" style="display: none;">
<button id="btnPlay" type="button" data-icon="play" data-inline="true" data-mini="true">Play</button> <button id="btnPlay" type="button" data-icon="play" data-inline="true" data-mini="true">Play</button>
</span> </span>
<span>
<button id="btnRemote" type="button" data-icon="wireless" data-inline="true" data-mini="true">Remote</button>
</span>
<span id="deleteButtonContainer" style="display: none;"> <span id="deleteButtonContainer" style="display: none;">
<button id="btnDelete" type="button" data-icon="delete" data-inline="true" data-mini="true">Delete</button> <button id="btnDelete" type="button" data-icon="delete" data-inline="true" data-mini="true">Delete</button>
</span> </span>

View file

@ -67,7 +67,7 @@
} }
function renderSubProfiles(page, profile) { function renderSubProfiles(page, profile) {
renderDirectPlayProfiles(page, profile.DirectPlayProfiles); renderDirectPlayProfiles(page, profile.DirectPlayProfiles);
renderTranscodingProfiles(page, profile.TranscodingProfiles); renderTranscodingProfiles(page, profile.TranscodingProfiles);
renderContainerProfiles(page, profile.ContainerProfiles); renderContainerProfiles(page, profile.ContainerProfiles);
@ -75,10 +75,11 @@
renderMediaProfiles(page, profile.MediaProfiles); renderMediaProfiles(page, profile.MediaProfiles);
} }
function editDirectPlayProfile(page, directPlayProfile, isNew) { function editDirectPlayProfile(page, directPlayProfile) {
isSubProfileNew = directPlayProfile == null;
directPlayProfile = directPlayProfile || {};
currentSubProfile = directPlayProfile; currentSubProfile = directPlayProfile;
isSubProfileNew = isNew;
var popup = $('#popupEditDirectPlayProfile', page).popup('open'); var popup = $('#popupEditDirectPlayProfile', page).popup('open');
@ -94,16 +95,16 @@
currentSubProfile.Container = $('#txtDirectPlayContainer', page).val(); currentSubProfile.Container = $('#txtDirectPlayContainer', page).val();
currentSubProfile.AudioCodec = $('#txtDirectPlayAudioCodec', page).val(); currentSubProfile.AudioCodec = $('#txtDirectPlayAudioCodec', page).val();
currentSubProfile.VideoCodec = $('#txtDirectPlayVideoCodec', page).val(); currentSubProfile.VideoCodec = $('#txtDirectPlayVideoCodec', page).val();
if (isSubProfileNew) { if (isSubProfileNew) {
currentProfile.DirectPlayProfiles.push(currentSubProfile); currentProfile.DirectPlayProfiles.push(currentSubProfile);
} }
renderSubProfiles(page, currentProfile); renderSubProfiles(page, currentProfile);
currentSubProfile = null; currentSubProfile = null;
$('#popupEditDirectPlayProfile', page).popup('close'); $('#popupEditDirectPlayProfile', page).popup('close');
} }
@ -432,7 +433,7 @@
}).done(function () { }).done(function () {
Dashboard.navigate('dlnaprofiles.html'); Dashboard.alert('Settings saved.');
}); });
} else { } else {
@ -503,6 +504,12 @@
}); });
$('.btnAddDirectPlayProfile', page).on('click', function () {
editDirectPlayProfile(page);
});
}).on('pageshow', "#dlnaProfilePage", function () { }).on('pageshow', "#dlnaProfilePage", function () {
var page = this; var page = this;

View file

@ -81,7 +81,7 @@
Dashboard.getCurrentUser().done(function (user) { Dashboard.getCurrentUser().done(function (user) {
if (MediaPlayer.canPlay(item, user)) { if (MediaController.canPlay(item)) {
$('#playButtonContainer', page).show(); $('#playButtonContainer', page).show();
} else { } else {
$('#playButtonContainer', page).hide(); $('#playButtonContainer', page).hide();
@ -518,12 +518,7 @@
$('#btnPlay', page).on('click', function () { $('#btnPlay', page).on('click', function () {
var userdata = currentItem.UserData || {}; var userdata = currentItem.UserData || {};
LibraryBrowser.showPlayMenu(this, currentItem.Name, currentItem.Type, "Audio", userdata.PlaybackPositionTicks); LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, false, "Audio", userdata.PlaybackPositionTicks);
});
$('#btnRemote', page).on('click', function () {
RemoteControl.showMenuForItem({ item: currentItem, context: getParameterByName('context') || '' });
}); });
}).on('pageshow', "#itemByNameDetailPage", function () { }).on('pageshow', "#itemByNameDetailPage", function () {

View file

@ -29,8 +29,6 @@
renderDetails(page, item, context); renderDetails(page, item, context);
LibraryBrowser.renderDetailPageBackdrop(page, item); LibraryBrowser.renderDetailPageBackdrop(page, item);
$("#remoteButtonContainer", page).show();
if (user.Configuration.IsAdministrator) { if (user.Configuration.IsAdministrator) {
$('#editButtonContainer', page).show(); $('#editButtonContainer', page).show();
@ -38,21 +36,18 @@
$('#editButtonContainer', page).hide(); $('#editButtonContainer', page).hide();
} }
if (MediaPlayer.canPlay(item, user)) { var externalPlayUrl = getExternalPlayUrl(item);
$('#btnPlayExternal', page).attr('href', externalPlayUrl || '#');
var url = MediaPlayer.getPlayUrl(item); if (externalPlayUrl) {
$('#playExternalButtonContainer', page).show();
if (url) { $('#playButtonContainer', page).hide();
$('#playExternalButtonContainer', page).show(); }
$('#playButtonContainer', page).hide(); else if (MediaController.canPlay(item)) {
} else { $('#playButtonContainer', page).show();
$('#playButtonContainer', page).show(); $('#playExternalButtonContainer', page).hide();
$('#playExternalButtonContainer', page).hide(); }
} else {
$('#btnPlayExternal', page).attr('href', url || '#');
} else {
$('#playButtonContainer', page).hide(); $('#playButtonContainer', page).hide();
$('#playExternalButtonContainer', page).hide(); $('#playExternalButtonContainer', page).hide();
} }
@ -124,6 +119,22 @@
$('#btnEdit', page).attr('href', "edititemmetadata.html?id=" + id); $('#btnEdit', page).attr('href', "edititemmetadata.html?id=" + id);
} }
function getExternalPlayUrl(item) {
if (item.GameSystem == "Nintendo" && item.MediaType == "Game" && item.ProviderIds.NesBox && item.ProviderIds.NesBoxRom) {
return "http://nesbox.com/game/" + item.ProviderIds.NesBox + '/rom/' + item.ProviderIds.NesBoxRom;
}
if (item.GameSystem == "Super Nintendo" && item.MediaType == "Game" && item.ProviderIds.NesBox && item.ProviderIds.NesBoxRom) {
return "http://snesbox.com/game/" + item.ProviderIds.NesBox + '/rom/' + item.ProviderIds.NesBoxRom;
}
return null;
};
function setPeopleHeader(page, item) { function setPeopleHeader(page, item) {
if (item.Type == "Audio" || item.Type == "MusicAlbum" || item.MediaType == "Book" || item.MediaType == "Photo") { if (item.Type == "Audio" || item.Type == "MusicAlbum" || item.MediaType == "Book" || item.MediaType == "Photo") {
@ -1107,7 +1118,7 @@
attributes.push(createAttribute("Layout", stream.ChannelLayout)); attributes.push(createAttribute("Layout", stream.ChannelLayout));
} }
else if (stream.Channels) { else if (stream.Channels) {
attributes.push(createAttribute("Channels", stream.Channels + ' ch')); attributes.push(createAttribute("Channels", stream.Channels + ' ch'));
} }
if (stream.BitRate && stream.Codec != "mjpeg") { if (stream.BitRate && stream.Codec != "mjpeg") {
@ -1138,7 +1149,7 @@
if (version.Path) { if (version.Path) {
html += '<br/><span class="mediaInfoLabel">Path</span><span class="mediaInfoAttribute">' + version.Path + '</span>'; html += '<br/><span class="mediaInfoLabel">Path</span><span class="mediaInfoAttribute">' + version.Path + '</span>';
} }
return html; return html;
} }
@ -1162,7 +1173,7 @@
var href = "itemdetails.html?id=" + item.Id; var href = "itemdetails.html?id=" + item.Id;
var onclick = item.PlayAccess == 'Full' ? ' onclick="MediaPlayer.playById(\'' + item.Id + '\'); return false;"' : ""; var onclick = item.PlayAccess == 'Full' ? ' onclick="MediaController.play(\'' + item.Id + '\'); return false;"' : "";
html += '<a class="' + cssClass + '" href="' + href + '"' + onclick + '>'; html += '<a class="' + cssClass + '" href="' + href + '"' + onclick + '>';
@ -1286,7 +1297,10 @@
function play(startPosition) { function play(startPosition) {
MediaPlayer.play([currentItem], startPosition); MediaController.play({
items: [currentItem],
startPositionTicks: startPosition
});
} }
function splitVersions(page) { function splitVersions(page) {
@ -1317,7 +1331,7 @@
ApiClient.getLocalTrailers(Dashboard.getCurrentUserId(), currentItem.Id).done(function (trailers) { ApiClient.getLocalTrailers(Dashboard.getCurrentUserId(), currentItem.Id).done(function (trailers) {
MediaPlayer.play(trailers); MediaController.play({ items: trailers });
}); });
} }
@ -1335,7 +1349,7 @@
mediaType = "Audio"; mediaType = "Audio";
} }
LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, mediaType, userdata.PlaybackPositionTicks); LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, currentItem.IsFolder, mediaType, userdata.PlaybackPositionTicks);
}); });
$('#btnPlayTrailer', page).on('click', function () { $('#btnPlayTrailer', page).on('click', function () {
@ -1347,19 +1361,6 @@
ApiClient.markPlayed(Dashboard.getCurrentUserId(), currentItem.Id, new Date()); ApiClient.markPlayed(Dashboard.getCurrentUserId(), currentItem.Id, new Date());
}); });
$('#btnRemote', page).on('click', function () {
RemoteControl.showMenuForItem({
item: currentItem,
context: getContext(currentItem),
themeSongs: $('#themeSongsCollapsible:visible', page).length > 0,
themeVideos: $('#themeVideosCollapsible:visible', page).length > 0
});
});
$('.btnSplitVersions', page).on('click', function () { $('.btnSplitVersions', page).on('click', function () {
splitVersions(page); splitVersions(page);

View file

@ -211,7 +211,7 @@
html += '<td class="detailTableButtonsCell">'; html += '<td class="detailTableButtonsCell">';
html += '<button class="btnPlay" data-icon="play" type="button" data-iconpos="notext" onclick="LibraryBrowser.showPlayMenu(this, \'' + item.Id + '\', \'Audio\', \'Audio\');" data-inline="true" title="Play">Play</button>'; html += '<button class="btnPlay" data-icon="play" type="button" data-iconpos="notext" onclick="LibraryBrowser.showPlayMenu(this, \'' + item.Id + '\', \'Audio\', \'Audio\');" data-inline="true" title="Play">Play</button>';
html += '<button class="btnQueue" data-icon="plus" type="button" data-iconpos="notext" onclick="MediaPlayer.queue(\'' + item.Id + '\');" data-inline="true" title="Queue">Queue</button>'; html += '<button class="btnQueue" data-icon="plus" type="button" data-iconpos="notext" onclick="MediaController.queue(\'' + item.Id + '\');" data-inline="true" title="Queue">Queue</button>';
html += '</td>'; html += '</td>';
var num = item.IndexNumber; var num = item.IndexNumber;
@ -287,12 +287,12 @@
return html; return html;
}, },
showPlayMenu: function (positionTo, itemId, itemType, mediaType, resumePositionTicks) { showPlayMenu: function (positionTo, itemId, itemType, isFolder, mediaType, resumePositionTicks) {
var isPlaying = MediaPlayer.isPlaying(); var isPlaying = MediaPlayer.isPlaying();
if (!isPlaying && !resumePositionTicks && mediaType != "Audio") { if (!isPlaying && !resumePositionTicks && mediaType != "Audio" && !isFolder) {
MediaPlayer.playById(itemId); MediaController.play(itemId);
return; return;
} }
@ -303,38 +303,22 @@
html += '<ul data-role="listview" style="min-width: 150px;">'; html += '<ul data-role="listview" style="min-width: 150px;">';
html += '<li data-role="list-divider" data-theme="b">Play Menu</li>'; html += '<li data-role="list-divider" data-theme="b">Play Menu</li>';
if (itemType == "MusicArtist") { html += '<li><a href="#" onclick="MediaController.play(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Play</a></li>';
html += '<li><a href="#" onclick="MediaPlayer.playArtist(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Play</a></li>';
} else if (itemType != "MusicGenre") { if (itemType == "Audio" || itemType == "MusicAlbum" || itemType == "MusicArtist" || itemType == "MusicGenre") {
html += '<li><a href="#" onclick="MediaPlayer.playById(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Play</a></li>'; html += '<li><a href="#" onclick="MediaController.instantMix(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Instant Mix</a></li>';
} }
if (itemType == "Audio") { if (isFolder || itemType == "MusicArtist" || itemType == "MusicGenre") {
html += '<li><a href="#" onclick="MediaPlayer.playInstantMixFromSong(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Instant Mix</a></li>'; html += '<li><a href="#" onclick="MediaController.shuffle(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Shuffle</a></li>';
}
else if (itemType == "MusicAlbum") {
html += '<li><a href="#" onclick="MediaPlayer.playInstantMixFromAlbum(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Instant Mix</a></li>';
html += '<li><a href="#" onclick="MediaPlayer.shuffleFolder(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Shuffle</a></li>';
}
else if (itemType == "MusicArtist") {
html += '<li><a href="#" onclick="MediaPlayer.playInstantMixFromArtist(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Instant Mix</a></li>';
html += '<li><a href="#" onclick="MediaPlayer.shuffleArtist(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Shuffle</a></li>';
}
else if (itemType == "MusicGenre") {
html += '<li><a href="#" onclick="MediaPlayer.playInstantMixFromMusicGenre(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Instant Mix</a></li>';
html += '<li><a href="#" onclick="MediaPlayer.shuffleMusicGenre(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Shuffle</a></li>';
} }
if (resumePositionTicks) { if (resumePositionTicks) {
html += '<li><a href="#" onclick="MediaPlayer.playById(\'' + itemId + '\', ' + resumePositionTicks + ');LibraryBrowser.closePlayMenu();">Resume</a></li>'; html += '<li><a href="#" onclick="MediaController.play({ids:[\'' + itemId + '\'],startPositionTicks:' + resumePositionTicks + '});LibraryBrowser.closePlayMenu();">Resume</a></li>';
} }
if (isPlaying) { if (MediaController.canQueueMediaType(mediaType)) {
if (itemType == "MusicArtist") { html += '<li><a href="#" onclick="MediaController.queue(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Queue</a></li>';
html += '<li><a href="#" onclick="MediaPlayer.queueArtist(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Queue</a></li>';
} else if (itemType != "MusicGenre") {
html += '<li><a href="#" onclick="MediaPlayer.queue(\'' + itemId + '\');LibraryBrowser.closePlayMenu();">Queue</a></li>';
}
} }
html += '</ul>'; html += '</ul>';

View file

@ -102,16 +102,16 @@
var buttonCount = 0; var buttonCount = 0;
if (MediaPlayer.canPlay(item, currentUser)) { if (MediaController.canPlay(item)) {
var resumePosition = (item.UserData || {}).PlaybackPositionTicks || 0; var resumePosition = (item.UserData || {}).PlaybackPositionTicks || 0;
var onPlayClick = 'LibraryBrowser.showPlayMenu(this, \'' + item.Id + '\', \'' + item.Type + '\', \'' + item.MediaType + '\', ' + resumePosition + ');return false;'; var onPlayClick = 'LibraryBrowser.showPlayMenu(this, \'' + item.Id + '\', \'' + item.Type + '\', ' + item.IsFolder + ', \'' + item.MediaType + '\', ' + resumePosition + ');return false;';
html += '<button type="button" data-mini="true" data-inline="true" data-icon="play" data-iconpos="notext" title="Play" onclick="' + onPlayClick + '" style="' + buttonMargin + '">Play</button>'; html += '<button type="button" data-mini="true" data-inline="true" data-icon="play" data-iconpos="notext" title="Play" onclick="' + onPlayClick + '" style="' + buttonMargin + '">Play</button>';
buttonCount++; buttonCount++;
if (item.MediaType == "Audio" || item.Type == "MusicAlbum") { if (item.MediaType == "Audio" || item.Type == "MusicAlbum") {
html += '<button type="button" data-mini="true" data-inline="true" data-icon="plus" data-iconpos="notext" title="Queue" onclick="MediaPlayer.queue(\'' + item.Id + '\');return false;" style="' + buttonMargin + '">Queue</button>'; html += '<button type="button" data-mini="true" data-inline="true" data-icon="plus" data-iconpos="notext" title="Queue" onclick="MediaController.queue(\'' + item.Id + '\');return false;" style="' + buttonMargin + '">Queue</button>';
buttonCount++; buttonCount++;
} }
} }
@ -126,10 +126,6 @@
buttonCount++; buttonCount++;
} }
if (!isPortrait || buttonCount < 3) {
html += '<button type="button" data-mini="true" data-inline="true" data-icon="wireless" data-iconpos="notext" title="Remote" class="btnRemoteControl" data-itemid="' + item.Id + '" style="' + buttonMargin + '">Remote</button>';
}
html += '</div>'; html += '</div>';
html += '</div>'; html += '</div>';
@ -142,22 +138,7 @@
var id = this.getAttribute('data-itemid'); var id = this.getAttribute('data-itemid');
ApiClient.getLocalTrailers(Dashboard.getCurrentUserId(), id).done(function (trailers) { ApiClient.getLocalTrailers(Dashboard.getCurrentUserId(), id).done(function (trailers) {
MediaPlayer.play(trailers); MediaController.play({ items: trailers });
});
return false;
}
function onRemoteControlButtonClick() {
var id = this.getAttribute('data-itemid');
ApiClient.getItem(Dashboard.getCurrentUserId(), id).done(function (item) {
RemoteControl.showMenuForItem({
item: item
});
}); });
return false; return false;
@ -248,7 +229,6 @@
innerElem.html(getOverlayHtml(item, user, elem)).trigger('create'); innerElem.html(getOverlayHtml(item, user, elem)).trigger('create');
$('.btnPlayTrailer', innerElem).on('click', onTrailerButtonClick); $('.btnPlayTrailer', innerElem).on('click', onTrailerButtonClick);
$('.btnRemoteControl', innerElem).on('click', onRemoteControlButtonClick);
}); });
innerElem.show().each(function () { innerElem.show().each(function () {

View file

@ -146,7 +146,7 @@
Dashboard.getCurrentUser().done(function (user) { Dashboard.getCurrentUser().done(function (user) {
if (MediaPlayer.canPlay(item, user)) { if (MediaController.canPlay(item)) {
$('#playButtonContainer', page).show(); $('#playButtonContainer', page).show();
} else { } else {
$('#playButtonContainer', page).hide(); $('#playButtonContainer', page).hide();
@ -296,12 +296,7 @@
$('#btnPlay', page).on('click', function () { $('#btnPlay', page).on('click', function () {
var userdata = currentItem.UserData || {}; var userdata = currentItem.UserData || {};
LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, currentItem.MediaType, userdata.PlaybackPositionTicks); LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, false, currentItem.MediaType, userdata.PlaybackPositionTicks);
});
$('#btnRemote', page).on('click', function () {
RemoteControl.showMenuForItem({ item: currentItem, context: 'livetv' });
}); });
$('#btnEdit', page).on('click', function () { $('#btnEdit', page).on('click', function () {

View file

@ -114,7 +114,7 @@
ApiClient.getLiveTvChannel(currentItem.ChannelId, Dashboard.getCurrentUserId()).done(function (channel) { ApiClient.getLiveTvChannel(currentItem.ChannelId, Dashboard.getCurrentUserId()).done(function (channel) {
var userdata = channel.UserData || {}; var userdata = channel.UserData || {};
LibraryBrowser.showPlayMenu(this, channel.Id, channel.Type, channel.MediaType, userdata.PlaybackPositionTicks); LibraryBrowser.showPlayMenu(this, channel.Id, channel.Type, false, channel.MediaType, userdata.PlaybackPositionTicks);
}); });
}); });
@ -123,15 +123,6 @@
deleteTimer(page, currentItem.TimerId); deleteTimer(page, currentItem.TimerId);
}); });
$('#btnRemote', page).on('click', function () {
RemoteControl.showMenuForItem({
item: currentItem,
context: 'livetv'
});
});
}).on('pageshow', "#liveTvProgramPage", function () { }).on('pageshow', "#liveTvProgramPage", function () {
var page = this; var page = this;

View file

@ -27,7 +27,7 @@
var mediaType = currentItem.MediaType; var mediaType = currentItem.MediaType;
LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, mediaType, userdata.PlaybackPositionTicks); LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, false, mediaType, userdata.PlaybackPositionTicks);
} }
function renderRecording(page, item) { function renderRecording(page, item) {
@ -68,7 +68,7 @@
Dashboard.getCurrentUser().done(function (user) { Dashboard.getCurrentUser().done(function (user) {
if (MediaPlayer.canPlay(item, user)) { if (MediaController.canPlay(item)) {
$('#playButtonContainer', page).show(); $('#playButtonContainer', page).show();
} else { } else {
$('#playButtonContainer', page).hide(); $('#playButtonContainer', page).hide();
@ -107,15 +107,6 @@
$('#btnDelete', page).on('click', deleteRecording); $('#btnDelete', page).on('click', deleteRecording);
$('#btnPlay', page).on('click', play); $('#btnPlay', page).on('click', play);
$('#btnRemote', page).on('click', function () {
RemoteControl.showMenuForItem({
item: currentItem,
context: 'livetv'
});
});
}).on('pagebeforeshow', "#liveTvRecordingPage", function () { }).on('pagebeforeshow', "#liveTvRecordingPage", function () {
var page = this; var page = this;

View file

@ -0,0 +1,145 @@
(function ($, window) {
function mediaController() {
var self = this;
var currentPlayer;
var players = [];
self.registerPlayer = function (player) {
players.push(player);
if (!currentPlayer) {
currentPlayer = player;
}
};
self.play = function (options) {
if (typeof (options) === 'string') {
options = { ids: [options] };
}
currentPlayer.play(options);
};
self.shuffle = function (id) {
currentPlayer.shuffle(id);
};
self.instantMix = function (id) {
currentPlayer.instantMix(id);
};
self.queue = function (options) {
if (typeof (options) === 'string') {
options = { ids: [options] };
}
currentPlayer.queue(options);
};
self.queueNext = function (options) {
if (typeof (options) === 'string') {
options = { ids: [options] };
}
currentPlayer.queueNext(options);
};
self.canPlay = function (item) {
if (item.PlayAccess != 'Full') {
return false;
}
if (item.LocationType == "Virtual" || item.IsPlaceHolder) {
return false;
}
if (item.IsFolder || item.Type == "MusicGenre") {
return true;
}
return currentPlayer.canPlayMediaType(item.MediaType);
};
self.canQueueMediaType = function (mediaType) {
return currentPlayer.canQueueMediaType(mediaType);
};
self.isPlaying = function () {
return currentPlayer.isPlaying();
};
self.getLocalPlayer = function () {
return currentPlayer.isLocalPlayer ?
currentPlayer :
players.filter(function (p) {
return p.isLocalPlayer;
})[0];
};
}
window.MediaController = new mediaController();
function onWebSocketMessageReceived() {
var msg = data;
var localPlayer = msg.MessageType === "Play" || msg.MessageType === "Play" ?
MediaController.getLocalPlayer() :
null;
if (msg.MessageType === "Play") {
if (msg.Data.PlayCommand == "PlayNext") {
localPlayer.queueNext({ ids: msg.Data.ItemIds });
}
else if (msg.Data.PlayCommand == "PlayLast") {
localPlayer.queue({ ids: msg.Data.ItemIds });
}
else {
localPlayer.play({ ids: msg.Data.ItemIds, startPositionTicks: msg.Data.StartPositionTicks });
}
}
else if (msg.MessageType === "Playstate") {
if (msg.Data.Command === 'Stop') {
localPlayer.stop();
}
else if (msg.Data.Command === 'Pause') {
localPlayer.pause();
}
else if (msg.Data.Command === 'Unpause') {
localPlayer.unpause();
}
else if (msg.Data.Command === 'Seek') {
localPlayer.seek(msg.Data.SeekPositionTicks);
}
else if (msg.Data.Command === 'NextTrack') {
localPlayer.nextTrack();
}
else if (msg.Data.Command === 'PreviousTrack') {
localPlayer.previousTrack();
}
else if (msg.Data.Command === 'Fullscreen') {
localPlayer.remoteFullscreen();
}
}
}
$(ApiClient).on("websocketmessage", onWebSocketMessageReceived);
})(jQuery, window);

View file

@ -453,8 +453,6 @@
html += "</div>"; html += "</div>";
} }
html += '<div style="padding: 5px;"><a data-role="button" data-icon="gear" href="usersettings.html?userid=' + Dashboard.getCurrentUserId() + '" data-mini="true" data-theme="a">Preferences</a></div>';
return html; return html;
}; };
@ -528,8 +526,6 @@
html += "</div>"; html += "</div>";
} }
html += '<div style="padding: 5px;"><a data-role="button" data-icon="gear" href="usersettings.html?userid=' + Dashboard.getCurrentUserId() + '" data-mini="true" data-theme="a">Preferences</a></div>';
return html; return html;
}; };

View file

@ -13,15 +13,18 @@
var canClientSeek; var canClientSeek;
var currentPlaylistIndex = 0; var currentPlaylistIndex = 0;
self.currentTimeElement; self.currentTimeElement = null;
self.unmuteButton; self.unmuteButton = null;
self.muteButton; self.muteButton = null;
self.positionSlider; self.positionSlider = null;
self.isPositionSliderActive; self.isPositionSliderActive = null;
self.volumeSlider; self.volumeSlider = null;
self.startTimeTicksOffset; self.startTimeTicksOffset = null;
self.playlist = []; self.playlist = [];
self.isLocalPlayer = true;
self.updateCanClientSeek = function (elem) { self.updateCanClientSeek = function (elem) {
var duration = elem.duration; var duration = elem.duration;
canClientSeek = duration && !isNaN(duration) && duration != Number.POSITIVE_INFINITY && duration != Number.NEGATIVE_INFINITY; canClientSeek = duration && !isNaN(duration) && duration != Number.POSITIVE_INFINITY && duration != Number.NEGATIVE_INFINITY;
@ -275,7 +278,7 @@
audioBitrate: audioBitrate, audioBitrate: audioBitrate,
videoBitrate: videoBitrate videoBitrate: videoBitrate
}; };
if (params.videoCodec == 'h264') { if (params.videoCodec == 'h264') {
params.profile = 'baseline'; params.profile = 'baseline';
params.level = '3'; params.level = '3';
@ -284,46 +287,6 @@
return params; return params;
}; };
self.canPlay = function (item, user) {
if (item.PlayAccess != 'Full') {
return false;
}
if (item.LocationType == "Virtual" || item.IsPlaceHolder) {
return false;
}
if (item.Type == "MusicAlbum" || item.Type == "MusicArtist" || item.Type == "MusicGenre") {
return true;
}
if (item.GameSystem == "Nintendo" && item.MediaType == "Game" && item.ProviderIds.NesBox && item.ProviderIds.NesBoxRom) {
return true;
}
if (item.GameSystem == "Super Nintendo" && item.MediaType == "Game" && item.ProviderIds.NesBox && item.ProviderIds.NesBoxRom) {
return true;
}
return self.canPlayMediaType(item.MediaType);
};
self.getPlayUrl = function (item) {
if (item.GameSystem == "Nintendo" && item.MediaType == "Game" && item.ProviderIds.NesBox && item.ProviderIds.NesBoxRom) {
return "http://nesbox.com/game/" + item.ProviderIds.NesBox + '/rom/' + item.ProviderIds.NesBoxRom;
}
if (item.GameSystem == "Super Nintendo" && item.MediaType == "Game" && item.ProviderIds.NesBox && item.ProviderIds.NesBoxRom) {
return "http://snesbox.com/game/" + item.ProviderIds.NesBox + '/rom/' + item.ProviderIds.NesBoxRom;
}
return null;
};
self.canPlayMediaType = function (mediaType) { self.canPlayMediaType = function (mediaType) {
if (mediaType === "Video") { if (mediaType === "Video") {
@ -337,84 +300,45 @@
return false; return false;
}; };
self.play = function (items, startPosition) { self.canQueueMediaType = function (mediaType) {
return currentItem && currentItem.MediaType == mediaType;
};
self.play = function (options) {
Dashboard.getCurrentUser().done(function (user) { Dashboard.getCurrentUser().done(function (user) {
var item = items[0]; if (options.items) {
var videoType = (item.VideoType || "").toLowerCase(); self.playInternal(options.items[0], options.startPositionTicks, user);
var expirementalText = "This feature is experimental. It may not work at all with some titles. Do you wish to continue?"; self.playlist = options.items;
currentPlaylistIndex = 0;
if (videoType == "dvd") { } else {
self.playWithWarning(items, startPosition, user, "dvdstreamconfirmed", "Dvd Folder Streaming", expirementalText); self.getItemsForPlayback({
return;
}
else if (videoType == "bluray") {
self.playWithWarning(items, startPosition, user, "bluraystreamconfirmed", "Blu-ray Folder Streaming", expirementalText); Ids: options.ids.join(',')
return;
}
else if (videoType == "iso") {
var isoType = (item.IsoType || "").toLowerCase(); }).done(function (result) {
if (isoType == "dvd") { options.items = result.Items;
self.playWithWarning(items, startPosition, user, "dvdisostreamconfirmed", "Dvd Iso Streaming", expirementalText); self.playInternal(options.items[0], options.startPositionTicks, user);
return;
}
else if (isoType == "bluray") {
self.playWithWarning(items, startPosition, user, "blurayisostreamconfirmed", "Blu-ray Iso Streaming", expirementalText); self.playlist = options.items;
return; currentPlaylistIndex = 0;
}
}
self.playInternal(items[0], startPosition, user); });
self.onPlaybackStarted(items);
});
};
self.playWithWarning = function (items, startPosition, user, localStorageKeyName, header, text) {
// Increment this version when changes are made and we want users to see the prompts again
var warningVersion = "2";
localStorageKeyName += new Date().getMonth() + warningVersion;
if (localStorage.getItem(localStorageKeyName) == "1") {
self.playInternal(items[0], startPosition, user);
self.onPlaybackStarted(items);
return;
}
Dashboard.confirm(text, header, function (result) {
if (result) {
localStorage.setItem(localStorageKeyName, "1");
self.playInternal(items[0], startPosition, user);
self.onPlaybackStarted(items);
} }
}); });
}; };
self.onPlaybackStarted = function (items) { self.getBitrateSetting = function () {
self.playlist = items;
currentPlaylistIndex = 0;
};
self.getBitrateSetting = function() {
return parseInt(localStorage.getItem('preferredVideoBitrate') || '') || 1500000; return parseInt(localStorage.getItem('preferredVideoBitrate') || '') || 1500000;
}; };
@ -569,163 +493,11 @@
query.Limit = query.Limit || 100; query.Limit = query.Limit || 100;
query.Fields = getItemFields; query.Fields = getItemFields;
query.ExcludeLocationTypes = "Virtual";
return ApiClient.getItems(userId, query); return ApiClient.getItems(userId, query);
}; };
self.playById = function (id, startPositionTicks) {
ApiClient.getItem(Dashboard.getCurrentUserId(), id).done(function (item) {
if (item.IsFolder) {
self.getItemsForPlayback({
ParentId: id,
Recursive: true,
SortBy: "SortName"
}).done(function (result) {
self.play(result.Items, startPositionTicks);
});
} else {
self.play([item], startPositionTicks);
}
});
};
self.playInstantMixFromSong = function (id) {
ApiClient.getInstantMixFromSong(id, {
UserId: Dashboard.getCurrentUserId(),
Fields: getItemFields,
Limit: 50
}).done(function (result) {
self.play(result.Items);
});
};
self.playInstantMixFromAlbum = function (id) {
ApiClient.getInstantMixFromAlbum(id, {
UserId: Dashboard.getCurrentUserId(),
Fields: getItemFields,
Limit: 50
}).done(function (result) {
self.play(result.Items);
});
};
self.playInstantMixFromArtist = function (name) {
ApiClient.getInstantMixFromArtist(name, {
UserId: Dashboard.getCurrentUserId(),
Fields: getItemFields,
Limit: 50
}).done(function (result) {
self.play(result.Items);
});
};
self.playInstantMixFromMusicGenre = function (name) {
ApiClient.getInstantMixFromMusicGenre(name, {
UserId: Dashboard.getCurrentUserId(),
Fields: getItemFields,
Limit: 50
}).done(function (result) {
self.play(result.Items);
});
};
self.playArtist = function (artist) {
self.getItemsForPlayback({
Artists: artist,
Recursive: true,
SortBy: "Album,SortName",
IncludeItemTypes: "Audio"
}).done(function (result) {
self.play(result.Items);
});
};
self.shuffleArtist = function (artist) {
self.getItemsForPlayback({
Artists: artist,
Recursive: true,
SortBy: "Random",
IncludeItemTypes: "Audio"
}).done(function (result) {
self.play(result.Items);
});
};
self.shuffleMusicGenre = function (genre) {
self.getItemsForPlayback({
Genres: genre,
Recursive: true,
SortBy: "Random",
IncludeItemTypes: "Audio"
}).done(function (result) {
self.play(result.Items);
});
};
self.shuffleFolder = function (id) {
self.getItemsForPlayback({
ParentId: id,
Recursive: true,
SortBy: "Random"
}).done(function (result) {
self.play(result.Items);
});
};
self.removeFromPlaylist = function (index) { self.removeFromPlaylist = function (index) {
self.playlist.remove(index); self.playlist.remove(index);
@ -797,51 +569,66 @@
} }
}; };
self.queue = function (id) { self.queue = function (options) {
if (!currentMediaElement) { if (!currentMediaElement) {
self.playById(id); self.play(options);
return; return;
} }
ApiClient.getItem(Dashboard.getCurrentUserId(), id).done(function (item) { Dashboard.getCurrentUser().done(function (user) {
if (item.IsFolder) { if (options.items) {
self.queueItems(options.items);
} else {
self.getItemsForPlayback({ self.getItemsForPlayback({
ParentId: id, Ids: options.ids.join(',')
Recursive: true,
SortBy: "SortName"
}).done(function (result) { }).done(function (result) {
self.queueItems(result.Items); options.items = result.Items;
self.queueItems(options.items);
}); });
} else {
self.queueItems([item]);
} }
}); });
}; };
self.queueArtist = function (artist) { self.queueNext = function (options) {
self.getItemsForPlayback({ if (!currentMediaElement) {
self.play(options);
return;
}
Artists: artist, Dashboard.getCurrentUser().done(function (user) {
Recursive: true,
SortBy: "Album,SortName",
IncludeItemTypes: "Audio"
}).done(function (result) { if (options.items) {
self.queueItems(result.Items); self.queueItemsNext(options.items);
} else {
self.getItemsForPlayback({
Ids: options.ids.join(',')
}).done(function (result) {
options.items = result.Items;
self.queueItemsNext(options.items);
});
}
}); });
}; };
self.pause = function () { self.pause = function () {
@ -905,6 +692,108 @@
} }
}; };
self.shuffle = function (id) {
var userId = Dashboard.getCurrentUserId();
ApiClient.getItem(userId, id).done(function (item) {
var query = {
UserId: userId,
Fields: getItemFields,
Limit: 50,
Filters: "IsNotFolder",
Recursive: true,
SortBy: "Random"
};
if (item.IsFolder) {
query.ParentId = id;
}
else if (item.Type == "MusicArtist") {
query.MediaTypes = "Audio";
query.Artists = item.Name;
}
else if (item.Type == "MusicGenre") {
query.MediaTypes = "Audio";
query.Genres = item.Name;
} else {
return;
}
self.getItemsForPlayback(query).done(function (result) {
self.play({ items: result.Items });
});
});
};
self.instantMix = function (id) {
var userId = Dashboard.getCurrentUserId();
ApiClient.getItem(userId, id).done(function (item) {
var promise;
if (item.Type == "MusicArtist") {
promise = ApiClient.getInstantMixFromArtist(name, {
UserId: Dashboard.getCurrentUserId(),
Fields: getItemFields,
Limit: 50
});
}
else if (item.Type == "MusicGenre") {
promise = ApiClient.getInstantMixFromMusicGenre(name, {
UserId: Dashboard.getCurrentUserId(),
Fields: getItemFields,
Limit: 50
});
}
else if (item.Type == "MusicAlbum") {
promise = ApiClient.getInstantMixFromAlbum(id, {
UserId: Dashboard.getCurrentUserId(),
Fields: getItemFields,
Limit: 50
});
}
else if (item.Type == "Audio") {
promise = ApiClient.getInstantMixFromSong(id, {
UserId: Dashboard.getCurrentUserId(),
Fields: getItemFields,
Limit: 50
});
}
else {
return;
}
promise.done(function (result) {
self.play({ items: result.Items });
});
});
};
self.stop = function () { self.stop = function () {
var elem = currentMediaElement; var elem = currentMediaElement;
@ -933,14 +822,6 @@
return currentMediaElement; return currentMediaElement;
}; };
self.showSendMediaMenu = function () {
RemoteControl.showMenuForItem({
item: currentItem
});
};
self.bindPositionSlider = function () { self.bindPositionSlider = function () {
self.positionSlider.on('slidestart', function (e) { self.positionSlider.on('slidestart', function (e) {
@ -1220,4 +1101,7 @@
window.MediaPlayer = new mediaPlayer(); window.MediaPlayer = new mediaPlayer();
window.MediaController.registerPlayer(window.MediaPlayer);
})(document, setTimeout, clearTimeout, screen, localStorage, $, setInterval, window); })(document, setTimeout, clearTimeout, screen, localStorage, $, setInterval, window);

View file

@ -1,570 +1,5 @@
(function (window, document, $) { (function (window, document, $) {
function sendPlayFolderCommand(item, sessionId, popup) {
ApiClient.getItems(Dashboard.getCurrentUserId(), {
ParentId: item.Id,
Filters: "IsNotFolder",
SortBy: "SortName",
Recursive: true,
Limit: 100
}).done(function (result) {
ApiClient.sendPlayCommand(sessionId, {
ItemIds: result.Items.map(function (i) {
return i.Id;
}).join(','),
PlayCommand: $('#fldPlayCommand', popup).val()
});
popup.popup("close");
});
}
function sendPlayArtistCommand(item, sessionId, popup) {
ApiClient.getItems(Dashboard.getCurrentUserId(), {
Artists: item.Name,
SortBy: "SortName",
IncludeItemTypes: "Audio",
Recursive: true,
Limit: 100
}).done(function (result) {
ApiClient.sendPlayCommand(sessionId, {
ItemIds: result.Items.map(function (i) {
return i.Id;
}).join(','),
PlayCommand: $('#fldPlayCommand', popup).val()
});
popup.popup("close");
});
}
function showMenuForItem(options, sessionsPromise) {
var playFromRendered;
var trailersRendered;
var specialFeaturesRendered;
var themeVideosRendered;
var themeSongsRendered;
var item = options.item;
var html = '<div data-role="popup" class="remoteControlFlyout" data-transition="slidedown" data-theme="a">';
html += '<a href="#" data-rel="back" data-role="button" data-icon="delete" data-iconpos="notext" class="ui-btn-right" data-theme="b">Close</a>';
html += '<div class="ui-bar-b" style="text-align:center;">';
html += '<div style="margin:.5em 0;">Remote Control</div>';
html += '</div>';
html += '<div style="padding: 1em;">';
html += '<form id="sendToForm">';
html += '<input type="hidden" value="PlayNow" id="fldPlayCommand" />';
html += '<div class="sessionsPopupContent">';
html += '<div class="circle"></div><div class="circle1"></div>';
html += '</div>';
html += '<p style="text-align:center;margin:.75em 0 0;">';
html += '<span id="playButtonContainer" style="display:none;"><button onclick="$(\'#fldPlayCommand\').val(\'PlayNow\');" type="submit" data-icon="play" data-mini="true" data-inline="true">Play</button></span>';
html += '<span id="resumeButtonContainer" style="display:none;"><button onclick="$(\'#fldPlayCommand\').val(\'Resume\');" type="submit" data-icon="play" data-mini="true" data-inline="true">Resume</button></span>';
html += '<span id="queueButtonContainer" style="display:none;"><button onclick="$(\'#fldPlayCommand\').val(\'PlayLast\');" type="submit" data-icon="plus" data-mini="true" data-inline="true">Queue</button></span>';
html += '<span id="browseButtonContainer" style="display:none;"><button onclick="$(\'#fldPlayCommand\').val(\'Browse\');" type="submit" data-icon="eye" data-mini="true" data-inline="true">View</button></span>';
html += '</p>';
html += '</form></div>';
html += '</div>';
$(document.body).append(html);
var popup = $('.remoteControlFlyout').popup({ history: false, tolerance: 0, corners: false }).trigger('create').popup("open").on("popupafterclose", function () {
if (ApiClient.isWebSocketOpen()) {
ApiClient.sendWebSocketMessage("SessionsStop");
}
$(ApiClient).off("websocketmessage.remotecontrol");
$(this).off("popupafterclose").remove();
$('.remoteControlFlyout').popup("destroy").remove();
});
popup.on('click', '.trSession', function () {
$('input', this).checked(true);
}).on('click', '.trSelectPlayTime', function () {
$('input', this).checked(true);
}).on('click', '.trItem', function () {
$('input', this).checked(true);
});
$('#sendToForm', popup).on('submit', function () {
var checkboxes = $('.chkClient', popup);
if (!checkboxes.length) {
$('.remoteControlFlyout').popup("close");
return false;
}
checkboxes = $('.chkClient:checked', popup);
if (!checkboxes.length) {
Dashboard.alert('Please select a device to control.');
return false;
}
var sessionIds = [];
checkboxes.parents('.trSession').each(function () {
sessionIds.push(this.getAttribute('data-sessionid'));
});
var command = $('#selectCommand', popup).val();
var promise;
var showRemoteControlMenuAfterCommand = true;
if (command == "Play") {
if (item.IsFolder) {
sendPlayFolderCommand(item, sessionIds[0], popup);
return false;
}
if (item.Type == "MusicArtist") {
sendPlayArtistCommand(item, sessionIds[0], popup);
return false;
}
var playCommand = $('#fldPlayCommand', popup).val();
if (playCommand == "Resume") {
promise = ApiClient.sendPlayCommand(sessionIds[0], {
ItemIds: [item.Id].join(','),
PlayCommand: 'PlayNow',
StartPositionTicks: item.UserData.PlaybackPositionTicks
});
}
else if (playCommand == "Browse") {
promise = ApiClient.sendBrowseCommand(sessionIds[0], {
ItemId: item.Id,
ItemName: item.Name,
ItemType: item.Type,
Context: options.context
});
showRemoteControlMenuAfterCommand = false;
}
else {
promise = ApiClient.sendPlayCommand(sessionIds[0], {
ItemIds: [item.Id].join(','),
PlayCommand: playCommand
});
}
}
else if (command == "PlayFromChapter") {
var checkedChapter = $('.chkSelectPlayTime:checked', popup);
var ticks = checkedChapter.length ? checkedChapter.parents('.trSelectPlayTime').attr('data-ticks') : 0;
promise = ApiClient.sendPlayCommand(sessionIds[0], {
ItemIds: [item.Id].join(','),
PlayCommand: $('#fldPlayCommand', popup).val(),
StartPositionTicks: ticks
});
}
else if (command == "Trailer" || command == "SpecialFeature" || command == "ThemeSong" || command == "ThemeVideo") {
var id = $('.chkSelectItem:checked', popup).parents('.trItem').attr('data-id');
if (!id) {
Dashboard.alert('Please select an item.');
return false;
}
promise = ApiClient.sendPlayCommand(sessionIds[0], {
ItemIds: [id].join(','),
PlayCommand: $('#fldPlayCommand', popup).val()
});
}
promise.done(function () {
popup.popup("close");
if (showRemoteControlMenuAfterCommand) {
RemoteControl.showMenu();
}
});
return false;
});
var elem = $('.sessionsPopupContent');
sessionsPromise.done(function (sessions) {
var deviceId = ApiClient.deviceId();
// don't display the current session
sessions = sessions.filter(function (s) {
return s.DeviceId != deviceId;
});
renderSessionsInPlayMenu(sessions, options, elem, popup);
if (ApiClient.isWebSocketOpen()) {
ApiClient.sendWebSocketMessage("SessionsStart", "1000,1000");
$(ApiClient).on("websocketmessage.remotecontrol", function (e, msg) {
if (msg.MessageType === "Sessions") {
updateSessionsInPlayMenu(msg.Data, elem);
}
});
}
$('#selectCommand', popup).on('change', function () {
var playFromMenu = $('.playFromMenu', popup).hide();
var trailersElem = $('.trailers', popup).hide();
var specialFeaturesElem = $('.specialFeatures', popup).hide();
var themeSongsElem = $('.themeSongs', popup).hide();
var themeVideosElem = $('.themeVideos', popup).hide();
var playButtonContainer = $('#playButtonContainer', popup).hide();
var queueButtonContainer = $('#queueButtonContainer', popup).hide();
var resumeButtonContainer = $('#resumeButtonContainer', popup).hide();
var browseButtonContainer = $('#browseButtonContainer', popup).hide();
var value = this.value;
if (value == "Play") {
browseButtonContainer.show();
if (item.Type != 'Person' && item.Type != 'Genre' && item.Type != 'Studio' && item.Type != 'GameGenre' && item.Type != 'MusicGenre' && item.LocationType != 'Virtual') {
playButtonContainer.show();
queueButtonContainer.show();
}
if (!item.IsFolder && item.UserData && item.UserData.PlaybackPositionTicks) {
resumeButtonContainer.show();
}
}
else if (value == "Trailer") {
trailersElem.show();
playButtonContainer.show();
queueButtonContainer.show();
if (!trailersRendered) {
trailersRendered = true;
ApiClient.getLocalTrailers(Dashboard.getCurrentUserId(), item.Id).done(function (trailers) {
renderVideos(trailersElem, trailers, 'Trailers');
popup.popup("reposition", { tolerance: 0 });
});
}
}
else if (value == "SpecialFeature") {
specialFeaturesElem.show();
playButtonContainer.show();
queueButtonContainer.show();
if (!specialFeaturesRendered) {
specialFeaturesRendered = true;
ApiClient.getSpecialFeatures(Dashboard.getCurrentUserId(), item.Id).done(function (videos) {
renderVideos(specialFeaturesElem, videos, 'Special Features');
popup.popup("reposition", { tolerance: 0 });
});
}
}
else if (value == "ThemeSong") {
themeSongsElem.show();
playButtonContainer.show();
queueButtonContainer.show();
if (!themeSongsRendered) {
themeSongsRendered = true;
ApiClient.getThemeSongs(Dashboard.getCurrentUserId(), item.Id).done(function (result) {
renderVideos(themeSongsElem, result.Items, 'Theme Songs');
$('.remoteControlFlyout').popup("reposition", { tolerance: 0 });
});
}
}
else if (value == "ThemeVideo") {
themeVideosElem.show();
playButtonContainer.show();
queueButtonContainer.show();
if (!themeVideosRendered) {
themeVideosRendered = true;
ApiClient.getThemeVideos(Dashboard.getCurrentUserId(), item.Id).done(function (result) {
renderVideos(themeVideosElem, result.Items, 'Theme Videos');
popup.popup("reposition", { tolerance: 0 });
});
}
}
}).trigger('change');
});
}
function renderSessionsInPlayMenu(sessions, options, elem, popup) {
if (!sessions.length) {
elem.html('<p>There are currently no available media browser sessions to control.</p>');
$('.remoteControlFlyout').popup("reposition", {});
return;
}
var item = options.item;
var html = '';
html += '<div style="margin-top:0;">';
html += '<select id="selectCommand" data-mini="true">';
// Default for virtual & IBN types
var playLabel = 'View';
if (item.LocationType != "Virtual") {
if (item.IsFolder) {
playLabel = "Play All";
}
else if (item.MediaType == "Video") {
playLabel = "Play from beginning";
}
else if (item.MediaType) {
playLabel = "Play";
}
}
html += '<option value="Play" selected>' + playLabel + '</label>';
if (item.LocalTrailerCount) {
html += '<option value="Trailer">Play trailer</label>';
}
if (item.SpecialFeatureCount) {
html += '<option value="SpecialFeature">Play special feature</label>';
}
if (options.themeSongs) {
html += '<option value="ThemeSong">Play theme song</label>';
}
if (options.themeVideos) {
html += '<option value="ThemeVideo">Play theme video</label>';
}
html += '</select>';
html += '</div>';
html += '<div class="playFromMenu" style="display:none;"></div>';
html += '<div class="trailers" style="display:none;"></div>';
html += '<div class="specialFeatures" style="display:none;"></div>';
html += '<div class="themeSongs" style="display:none;"></div>';
html += '<div class="themeVideos" style="display:none;"></div>';
html += '<h4 style="margin: 1em 0 .5em;">Select Device</h4>';
html += '<table class="tblRemoteControl">';
html += '<thead><tr>';
html += '<th></th>';
html += '<th>Device</th>';
html += '</tr></thead>';
html += '<tbody>';
for (var i = 0, length = sessions.length; i < length; i++) {
var session = sessions[i];
html += '<tr class="trSession" data-queue="' + session.QueueableMediaTypes.join(',') + '" data-sessionid="' + session.Id + '">';
html += '<td class="tdSelectSession"></td>';
html += '<td>' + session.DeviceName;
if (session.UserName) {
html += ' - ' + session.UserName;
}
html += '</td>';
html += '</tr>';
}
html += '</tbody>';
html += '</table>';
html += '</div>';
elem.html(html).trigger('create');
$('.tdSelectSession', elem).html('<input type="radio" class="chkClient" name="chkClient" />');
$('.chkClient:first', elem).checked(true);
}
function getSessionNowPlayingTime(session) {
var html = '';
if (session.NowPlayingItem) {
html += Dashboard.getDisplayTime(session.NowPlayingPositionTicks || 0);
if (session.NowPlayingItem.RunTimeTicks) {
html += " / ";
html += Dashboard.getDisplayTime(session.NowPlayingItem.RunTimeTicks);
}
}
return html;
}
function updateSessionsInPlayMenu(sessions, elem) {
for (var i = 0, length = sessions.length; i < length; i++) {
var session = sessions[i];
var sessionElem = $('.trSession[data-sessionid=' + session.Id + ']', elem);
$('.tdUserName', sessionElem).html(session.UserName || '');
$('.tdNowPlayingTime', sessionElem).html(getSessionNowPlayingTime(session));
$('.tdNowPlayingName', sessionElem).html(session.NowPlayingItem ? session.NowPlayingItem.Name : '');
}
}
function renderVideos(elem, videos, header) {
var html = '';
html += '<h4 style="margin: 1em 0 .5em;">' + header + '</h4>';
html += '<div class="playMenuOptions">';
html += '<table class="tblRemoteControl tblRemoteControlNoHeader">';
html += '<tbody>';
for (var i = 0, length = videos.length; i < length; i++) {
var video = videos[i];
html += '<tr class="trItem" data-id="' + video.Id + '">';
html += '<td class="tdSelectItem"></td>';
html += '<td class="tdRemoteControlImage">';
var imgUrl;
if (video.ImageTags && video.ImageTags.Primary) {
imgUrl = ApiClient.getImageUrl(video.Id, {
maxheight: 80,
tag: video.ImageTags.Primary,
type: "Primary"
});
html += '<img src="' + imgUrl + '" />';
}
html += '</td>';
html += '<td>' + video.Name;
if (video.RunTimeTicks) {
html += '<br/>' + Dashboard.getDisplayTime(video.RunTimeTicks);
}
html += '</td>';
html += '</tr>';
}
html += '</tbody>';
html += '</table>';
html += '</div>';
elem.html(html);
$('.tdSelectItem', elem).html('<input type="radio" class="chkSelectItem" name="chkSelectItem" />');
$('.chkSelectItem:first', elem).checked(true);
}
function showMenu(sessions, options) { function showMenu(sessions, options) {
var html = '<div data-role="popup" data-transition="slidedown" class="remoteControlFlyout" data-theme="a">'; var html = '<div data-role="popup" data-transition="slidedown" class="remoteControlFlyout" data-theme="a">';
@ -965,10 +400,6 @@
ControllableByUserId: Dashboard.getCurrentUserId() ControllableByUserId: Dashboard.getCurrentUserId()
}; };
self.showMenuForItem = function (options) {
showMenuForItem(options, ApiClient.getSessions(sessionQuery));
};
self.showMenu = function (options) { self.showMenu = function (options) {
ApiClient.getSessions(sessionQuery).done(function (sessions) { ApiClient.getSessions(sessionQuery).done(function (sessions) {

View file

@ -882,51 +882,6 @@ var Dashboard = {
Dashboard.onBrowseCommand(msg.Data); Dashboard.onBrowseCommand(msg.Data);
} }
else if (msg.MessageType === "Play") {
MediaPlayer.getItemsForPlayback({
Ids: msg.Data.ItemIds.join(',')
}).done(function (result) {
if (msg.Data.PlayCommand == "PlayNext") {
MediaPlayer.queueItemsNext(result.Items);
}
else if (msg.Data.PlayCommand == "PlayLast") {
MediaPlayer.queueItems(result.Items);
}
else {
MediaPlayer.play(result.Items, msg.Data.StartPositionTicks);
}
});
}
else if (msg.MessageType === "Playstate") {
if (msg.Data.Command === 'Stop') {
MediaPlayer.stop();
}
else if (msg.Data.Command === 'Pause') {
MediaPlayer.pause();
}
else if (msg.Data.Command === 'Unpause') {
MediaPlayer.unpause();
}
else if (msg.Data.Command === 'Seek') {
MediaPlayer.seek(msg.Data.SeekPositionTicks);
}
else if (msg.Data.Command === 'NextTrack') {
MediaPlayer.nextTrack();
}
else if (msg.Data.Command === 'PreviousTrack') {
MediaPlayer.previousTrack();
}
else if (msg.Data.Command === 'Fullscreen') {
MediaPlayer.remoteFullscreen();
}
}
else if (msg.MessageType === "SystemCommand") { else if (msg.MessageType === "SystemCommand") {
if (msg.Data === 'GoHome') { if (msg.Data === 'GoHome') {
@ -1365,8 +1320,6 @@ $(function () {
videoPlayerHtml += '<button onclick="MediaPlayer.showChaptersFlyout();" id="video-chaptersButton" class="mediaButton chaptersButton" title="Scenes" type="button" data-icon="video" data-iconpos="notext" data-inline="true">Scenes</button>'; videoPlayerHtml += '<button onclick="MediaPlayer.showChaptersFlyout();" id="video-chaptersButton" class="mediaButton chaptersButton" title="Scenes" type="button" data-icon="video" data-iconpos="notext" data-inline="true">Scenes</button>';
videoPlayerHtml += '<div class="mediaFlyoutContainer"><div id="video-chaptersFlyout" style="display:none;" class="mediaPlayerFlyout chaptersFlyout"></div></div>'; videoPlayerHtml += '<div class="mediaFlyoutContainer"><div id="video-chaptersFlyout" style="display:none;" class="mediaPlayerFlyout chaptersFlyout"></div></div>';
videoPlayerHtml += '<button onclick="MediaPlayer.showSendMediaMenu();" id="video-sendMediaButton" class="mediaButton sendMediaButton" title="Remote" type="button" data-icon="wireless" data-iconpos="notext" data-inline="true">Remote</button>';
videoPlayerHtml += '<button onclick="MediaPlayer.toggleVideoPlayerMenu();" id="video-videoPlayerMenuButton" class="mediaButton videoPlayerMenuButton" title="Menu" type="button" data-icon="bars" data-iconpos="notext" data-inline="true">Menu</button>'; videoPlayerHtml += '<button onclick="MediaPlayer.toggleVideoPlayerMenu();" id="video-videoPlayerMenuButton" class="mediaButton videoPlayerMenuButton" title="Menu" type="button" data-icon="bars" data-iconpos="notext" data-inline="true">Menu</button>';
videoPlayerHtml += '</div>'; // videoControls videoPlayerHtml += '</div>'; // videoControls
@ -1422,8 +1375,6 @@ $(function () {
footerHtml += '<button onclick="MediaPlayer.toggleFullscreen();" id="fullscreenButton" class="mediaButton fullscreenButton" title="Fullscreen" type="button" data-icon="action" data-iconpos="notext" data-inline="true">Fullscreen</button>'; footerHtml += '<button onclick="MediaPlayer.toggleFullscreen();" id="fullscreenButton" class="mediaButton fullscreenButton" title="Fullscreen" type="button" data-icon="action" data-iconpos="notext" data-inline="true">Fullscreen</button>';
footerHtml += '<button onclick="MediaPlayer.showSendMediaMenu();" id="sendMediaButton" class="mediaButton sendMediaButton" title="Remote" type="button" data-icon="wireless" data-iconpos="notext" data-inline="true">Remote</button>';
footerHtml += '</div>'; footerHtml += '</div>';
footerHtml += '<div id="footerNotifications"></div>'; footerHtml += '<div id="footerNotifications"></div>';