mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
add new mirror mode
This commit is contained in:
parent
2835534c6d
commit
9f83edf9ec
18 changed files with 316 additions and 191 deletions
|
@ -106,7 +106,7 @@
|
|||
|
||||
#mediaPlayer .ui-slider-track, .nowPlayingBar .ui-slider-track {
|
||||
border-color: #2ad !important;
|
||||
height: 8px!important;
|
||||
height: 2px!important;
|
||||
}
|
||||
|
||||
#mediaPlayer .ui-slider-handle, .nowPlayingBar .ui-slider-handle {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Now playing bar */
|
||||
.nowPlayingBar {
|
||||
padding: 10px 0 14px 0;
|
||||
padding: 6px 0 14px 0;
|
||||
border-top: 2px solid green;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
|||
}
|
||||
|
||||
.nowPlayingDoubleText {
|
||||
top: 0;
|
||||
top: -3px;
|
||||
}
|
||||
|
||||
.nowPlayingImage {
|
||||
|
@ -57,7 +57,7 @@
|
|||
}
|
||||
|
||||
.nowPlayingBar .currentTime {
|
||||
top: -12px;
|
||||
top: -15px;
|
||||
}
|
||||
|
||||
.mediaSlider {
|
||||
|
@ -75,8 +75,8 @@
|
|||
width: 130px;
|
||||
}
|
||||
|
||||
#nowPlayingBar .positionSliderContainer {
|
||||
margin-top: 10px;
|
||||
#nowPlayingBar .sliderContainer {
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.volumeSliderContainer {
|
||||
|
|
|
@ -1267,6 +1267,10 @@
|
|||
castPlayer.stopMedia();
|
||||
};
|
||||
|
||||
self.displayContent = function (options) {
|
||||
|
||||
};
|
||||
|
||||
self.mute = function () {
|
||||
castPlayer.mute();
|
||||
};
|
||||
|
@ -1280,12 +1284,19 @@
|
|||
};
|
||||
|
||||
self.getTargets = function () {
|
||||
|
||||
var targets = [];
|
||||
|
||||
if (castPlayer.hasReceivers) {
|
||||
targets.push(self.getCurrentTargetInfo());
|
||||
}
|
||||
|
||||
return targets;
|
||||
|
||||
};
|
||||
|
||||
self.getCurrentTargetInfo = function () {
|
||||
|
||||
var appName = null;
|
||||
if (castPlayer.session && castPlayer.session.receiver && castPlayer.session.friendlyName) {
|
||||
appName = castPlayer.session.friendlyName;
|
||||
|
@ -1297,7 +1308,8 @@
|
|||
playerName: self.name,
|
||||
playableMediaTypes: ["Audio", "Video"],
|
||||
isLocalPlayer: false,
|
||||
appName: appName
|
||||
appName: appName,
|
||||
supportedCommands: []
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -66,18 +66,11 @@
|
|||
renderDetails(page, item);
|
||||
renderTabs(page, item);
|
||||
|
||||
if (ApiClient.isWebSocketOpen()) {
|
||||
$(page).trigger('displayingitem', [{
|
||||
|
||||
var vals = [item.Type, item.Id, item.Name];
|
||||
|
||||
var context = getParameterByName('context');
|
||||
|
||||
if (context) {
|
||||
vals.push(vals);
|
||||
}
|
||||
|
||||
ApiClient.sendWebSocketMessage("Context", vals.join('|'));
|
||||
}
|
||||
item: item,
|
||||
context: getParameterByName('context')
|
||||
}]);
|
||||
|
||||
Dashboard.getCurrentUser().done(function (user) {
|
||||
|
||||
|
|
|
@ -120,9 +120,11 @@
|
|||
|
||||
setPeopleHeader(page, item);
|
||||
|
||||
if (ApiClient.isWebSocketOpen()) {
|
||||
ApiClient.sendWebSocketMessage("Context", [item.Type, item.Id, item.Name, context].join('|'));
|
||||
}
|
||||
$(page).trigger('displayingitem', [{
|
||||
|
||||
item: item,
|
||||
context: context
|
||||
}]);
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
|
|
|
@ -93,9 +93,10 @@
|
|||
|
||||
Dashboard.setPageTitle(name);
|
||||
|
||||
if (ApiClient.isWebSocketOpen()) {
|
||||
ApiClient.sendWebSocketMessage("Context", [item.Type, item.Id, item.Name].join('|'));
|
||||
}
|
||||
$(page).trigger('displayingitem', [{
|
||||
|
||||
item: item
|
||||
}]);
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -672,7 +672,7 @@
|
|||
html += '<a data-itemid="' + item.Id + '" class="' + cssClass + '" data-mediasourcecount="' + mediaSourceCount + '" href="' + href + '">';
|
||||
|
||||
var style = "";
|
||||
|
||||
options.lazy = false;
|
||||
if (imgUrl && !options.lazy) {
|
||||
style += 'background-image:url(\'' + imgUrl + '\');';
|
||||
}
|
||||
|
|
|
@ -135,14 +135,11 @@
|
|||
|
||||
$('.userDataIcons', page).html(LibraryBrowser.getUserDataIconsHtml(item));
|
||||
|
||||
if (ApiClient.isWebSocketOpen()) {
|
||||
$(page).trigger('displayingitem', [{
|
||||
|
||||
var vals = [item.Type, item.Id, item.Name];
|
||||
|
||||
vals.push('livetv');
|
||||
|
||||
ApiClient.sendWebSocketMessage("Context", vals.join('|'));
|
||||
}
|
||||
item: item,
|
||||
context: 'livetv'
|
||||
}]);
|
||||
|
||||
Dashboard.getCurrentUser().done(function (user) {
|
||||
|
||||
|
|
|
@ -50,14 +50,11 @@
|
|||
|
||||
LiveTvHelpers.renderMiscProgramInfo($('.miscTvProgramInfo', page), item);
|
||||
|
||||
if (ApiClient.isWebSocketOpen()) {
|
||||
$(page).trigger('displayingitem', [{
|
||||
|
||||
var vals = [item.Type, item.Id, item.Name];
|
||||
|
||||
vals.push('livetv');
|
||||
|
||||
ApiClient.sendWebSocketMessage("Context", vals.join('|'));
|
||||
}
|
||||
item: item,
|
||||
context: 'livetv'
|
||||
}]);
|
||||
|
||||
if (item.TimerId) {
|
||||
$('#cancelRecordingButtonContainer', page).show();
|
||||
|
|
|
@ -55,14 +55,11 @@
|
|||
|
||||
LiveTvHelpers.renderMiscProgramInfo($('.miscTvProgramInfo', page), item);
|
||||
|
||||
if (ApiClient.isWebSocketOpen()) {
|
||||
$(page).trigger('displayingitem', [{
|
||||
|
||||
var vals = [item.Type, item.Id, item.Name];
|
||||
|
||||
vals.push('livetv');
|
||||
|
||||
ApiClient.sendWebSocketMessage("Context", vals.join('|'));
|
||||
}
|
||||
item: item,
|
||||
context: 'livetv'
|
||||
}]);
|
||||
|
||||
$('.recordingStatus', page).html('Status: ' + item.Status);
|
||||
|
||||
|
|
|
@ -1,11 +1,26 @@
|
|||
(function ($, window) {
|
||||
|
||||
var enableMirrorMode;
|
||||
var currentDisplayInfo;
|
||||
|
||||
function mirrorItem(info) {
|
||||
|
||||
var item = info.item;
|
||||
|
||||
MediaController.getCurrentPlayer().displayContent({
|
||||
|
||||
itemName: item.Name,
|
||||
itemId: item.Id,
|
||||
itemType: item.Type,
|
||||
context: info.context
|
||||
});
|
||||
}
|
||||
|
||||
function mediaController() {
|
||||
|
||||
var self = this;
|
||||
var currentPlayer;
|
||||
var currentTargetInfo;
|
||||
|
||||
var players = [];
|
||||
|
||||
self.registerPlayer = function (player) {
|
||||
|
@ -308,11 +323,11 @@
|
|||
else if (cmd.Name === 'ToggleMute') {
|
||||
localPlayer.toggleMute();
|
||||
}
|
||||
else if (msg.Data.Command === 'Fullscreen') {
|
||||
else if (cmd.Name === 'Fullscreen') {
|
||||
localPlayer.remoteFullscreen();
|
||||
}
|
||||
else if (msg.Data.Command === 'SetVolume') {
|
||||
localPlayer.setVolume(cmd.Arguments.Volume);
|
||||
else if (cmd.Name === 'SetVolume') {
|
||||
localPlayer.setVolume(parseFloat(cmd.Arguments.Volume));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -324,7 +339,9 @@
|
|||
var playerInfo = MediaController.getPlayerInfo();
|
||||
|
||||
var html = '';
|
||||
html += '<h3>Select Player:</h3>';
|
||||
html += '<form>';
|
||||
|
||||
html += '<form><h3>Select Player:</h3>';
|
||||
html += '<fieldset data-role="controlgroup" data-mini="true">';
|
||||
|
||||
for (var i = 0, length = targets.length; i < length; i++) {
|
||||
|
@ -336,7 +353,9 @@
|
|||
var isChecked = target.id == playerInfo.id;
|
||||
var checkedHtml = isChecked ? ' checked="checked"' : '';
|
||||
|
||||
html += '<input type="radio" class="radioSelectPlayerTarget" name="radioSelectPlayerTarget" data-mediatypes="' + target.playableMediaTypes.join(',') + '" data-playername="' + target.playerName + '" data-targetid="' + target.id + '" data-targetname="' + target.name + '" id="' + id + '" value="' + target.id + '"' + checkedHtml + '>';
|
||||
var mirror = (!target.isLocalPlayer && target.supportedCommands.indexOf('DisplayContent') != -1) ? 'true' : 'false';
|
||||
|
||||
html += '<input type="radio" class="radioSelectPlayerTarget" name="radioSelectPlayerTarget" data-mirror="' + mirror + '" data-mediatypes="' + target.playableMediaTypes.join(',') + '" data-playername="' + target.playerName + '" data-targetid="' + target.id + '" data-targetname="' + target.name + '" id="' + id + '" value="' + target.id + '"' + checkedHtml + '>';
|
||||
html += '<label for="' + id + '" style="font-weight:normal;">' + target.name;
|
||||
|
||||
if (target.appName) {
|
||||
|
@ -350,6 +369,11 @@
|
|||
|
||||
html += '<p class="fieldDescription">All plays will be sent to the selected player.</p>';
|
||||
|
||||
var checkedHtml = enableMirrorMode ? ' checked="checked"' : '';
|
||||
html += '<div style="margin-top:1.5em;" class="fldMirrorMode"><label for="chkEnableMirrorMode">Enable Mirror Mode</label><input type="checkbox" class="chkEnableMirrorMode" id="chkEnableMirrorMode" data-mini="true"' + checkedHtml + ' /></div>';
|
||||
|
||||
html += '</form>';
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
|
@ -374,8 +398,36 @@
|
|||
|
||||
$('.players', elem).html(getTargetsHtml(targets)).trigger('create');
|
||||
|
||||
$('.chkEnableMirrorMode', elem).on().on('change', function () {
|
||||
enableMirrorMode = this.checked;
|
||||
|
||||
if (this.checked && currentDisplayInfo) {
|
||||
|
||||
mirrorItem(currentDisplayInfo);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$('.radioSelectPlayerTarget', elem).on('change', function () {
|
||||
|
||||
var supportsMirror = this.getAttribute('data-mirror') == 'true';
|
||||
|
||||
if (supportsMirror) {
|
||||
$('.fldMirrorMode', elem).show();
|
||||
} else {
|
||||
$('.fldMirrorMode', elem).hide();
|
||||
$('.chkEnableMirrorMode', elem).checked(false).trigger('change').checkboxradio('refresh');
|
||||
}
|
||||
|
||||
}).each(function () {
|
||||
|
||||
if (this.checked) {
|
||||
$(this).trigger('change');
|
||||
}
|
||||
|
||||
}).on('change', function () {
|
||||
|
||||
var playerName = this.getAttribute('data-playername');
|
||||
var targetId = this.getAttribute('data-targetid');
|
||||
var targetName = this.getAttribute('data-targetname');
|
||||
|
@ -401,4 +453,21 @@
|
|||
});
|
||||
});
|
||||
|
||||
$(document).on('pagebeforeshow', ".page", function () {
|
||||
|
||||
var page = this;
|
||||
|
||||
currentDisplayInfo = null;
|
||||
|
||||
}).on('displayingitem', ".libraryPage", function (e, info) {
|
||||
|
||||
var page = this;
|
||||
|
||||
currentDisplayInfo = info;
|
||||
|
||||
if (enableMirrorMode) {
|
||||
mirrorItem(info);
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery, window);
|
|
@ -28,7 +28,8 @@
|
|||
id: ApiClient.deviceId(),
|
||||
playerName: self.name,
|
||||
playableMediaTypes: ['Audio', 'Video'],
|
||||
isLocalPlayer: true
|
||||
isLocalPlayer: true,
|
||||
supportedCommands: Dashboard.getSupportedRemoteCommands()
|
||||
}];
|
||||
|
||||
return targets;
|
||||
|
@ -521,19 +522,60 @@
|
|||
url = "css/images/items/detail/video.png";
|
||||
}
|
||||
|
||||
var name = state.itemName;
|
||||
|
||||
var nowPlayingTextElement = $('.nowPlayingText', mediaControls);
|
||||
var nameHtml = self.getNowPlayingNameHtml(state);
|
||||
|
||||
if (state.itemSubName) {
|
||||
name += '<br/>' + state.itemSubName;
|
||||
if (nameHtml.indexOf('<br/>') != -1) {
|
||||
nowPlayingTextElement.addClass('nowPlayingDoubleText');
|
||||
} else {
|
||||
nowPlayingTextElement.removeClass('nowPlayingDoubleText');
|
||||
}
|
||||
|
||||
$('.nowPlayingImage', mediaControls).html('<img src="' + url + '" />');
|
||||
nowPlayingTextElement.html(name);
|
||||
nowPlayingTextElement.html(nameHtml);
|
||||
};
|
||||
|
||||
self.getNowPlayingNameHtml = function (playerState) {
|
||||
|
||||
var topText = playerState.itemName;
|
||||
|
||||
if (playerState.mediaType == 'Video') {
|
||||
if (playerState.indexNumber != null) {
|
||||
topText = playerState.indexNumber + " - " + topText;
|
||||
}
|
||||
if (playerState.parentIndexNumber != null) {
|
||||
topText = playerState.parentIndexNumber + "." + topText;
|
||||
}
|
||||
}
|
||||
|
||||
var bottomText = '';
|
||||
|
||||
if (playerState.artists && playerState.artists.length) {
|
||||
bottomText = topText;
|
||||
topText = playerState.artists[0];
|
||||
}
|
||||
else if (playerState.seriesName || playerState.album) {
|
||||
bottomText = topText;
|
||||
topText = playerState.seriesName || playerState.album;
|
||||
}
|
||||
else if (playerState.productionYear) {
|
||||
bottomText = playerState.productionYear;
|
||||
}
|
||||
|
||||
return bottomText ? topText + '<br/>' + bottomText : topText;
|
||||
};
|
||||
|
||||
self.displayContent = function (options) {
|
||||
|
||||
// Handle it the same as a remote control command
|
||||
Dashboard.onBrowseCommand({
|
||||
|
||||
ItemName: options.itemName,
|
||||
ItemType: options.itemType,
|
||||
ItemId: options.itemId,
|
||||
Context: options.context
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
self.getItemsForPlayback = function (query) {
|
||||
|
@ -930,41 +972,15 @@
|
|||
state.itemId = item.Id;
|
||||
state.mediaType = item.MediaType;
|
||||
state.itemType = item.Type;
|
||||
|
||||
var itemName = '';
|
||||
var itemSubName = '';
|
||||
|
||||
var name = item.Name;
|
||||
var seriesName = '';
|
||||
|
||||
// Channel number
|
||||
if (item.Number) {
|
||||
name = item.Number + ' ' + name;
|
||||
}
|
||||
if (item.IndexNumber != null) {
|
||||
name = item.IndexNumber + " - " + name;
|
||||
}
|
||||
if (item.ParentIndexNumber != null) {
|
||||
name = item.ParentIndexNumber + "." + name;
|
||||
}
|
||||
|
||||
if (item.CurrentProgram) {
|
||||
seriesName = item.CurrentProgram.Name;
|
||||
}
|
||||
else if (item.SeriesName || item.Album) {
|
||||
seriesName = item.SeriesName || item.Album;
|
||||
}
|
||||
|
||||
if (seriesName) {
|
||||
itemName = seriesName;
|
||||
itemSubName = name;
|
||||
} else {
|
||||
itemName = name;
|
||||
}
|
||||
|
||||
if (!itemSubName && item.ProductionYear) {
|
||||
itemSubName = item.ProductionYear;
|
||||
}
|
||||
state.indexNumber = item.IndexNumber;
|
||||
state.indexNumberEnd = item.IndexNumberEnd;
|
||||
state.parentIndexNumber = item.ParentIndexNumber;
|
||||
state.productionYear = item.ProductionYear;
|
||||
state.premiereDate = item.PremiereDate;
|
||||
state.seriesName = item.SeriesName;
|
||||
state.album = item.Album;
|
||||
state.itemName = item.Name;
|
||||
state.artists = item.Artists;
|
||||
|
||||
var imageTags = item.ImageTags || {};
|
||||
|
||||
|
@ -973,6 +989,16 @@
|
|||
state.primaryImageItemId = item.Id;
|
||||
state.primaryImageTag = imageTags.Primary;
|
||||
}
|
||||
else if (item.AlbumPrimaryImageTag) {
|
||||
|
||||
state.primaryImageItemId = item.AlbumId;
|
||||
state.primaryImageTag = item.AlbumPrimaryImageTag;
|
||||
}
|
||||
else if (item.SeriesPrimaryImageTag) {
|
||||
|
||||
state.primaryImageItemId = item.SeriesId;
|
||||
state.primaryImageTag = item.SeriesPrimaryImageTag;
|
||||
}
|
||||
|
||||
if (item.BackdropImageTags && item.BackdropImageTags.length) {
|
||||
|
||||
|
@ -985,9 +1011,6 @@
|
|||
state.thumbItemId = item.Id;
|
||||
state.thumbImageTag = imageTags.Thumb;
|
||||
}
|
||||
|
||||
state.itemName = itemName;
|
||||
state.itemSubName = itemSubName;
|
||||
}
|
||||
|
||||
return state;
|
||||
|
@ -1123,6 +1146,7 @@
|
|||
return $('.mediaPlayerAudio');
|
||||
}
|
||||
|
||||
var supportsAac = document.createElement('audio').canPlayType('audio/aac').replace(/no/, '');
|
||||
function playAudio(item, mediaSource, startPositionTicks) {
|
||||
|
||||
startPositionTicks = startPositionTicks || 0;
|
||||
|
@ -1134,30 +1158,36 @@
|
|||
mediaSourceId: mediaSource.Id
|
||||
};
|
||||
|
||||
var mp3Url = ApiClient.getUrl('Audio/' + item.Id + '/stream.mp3', $.extend({}, baseParams, {
|
||||
audioCodec: 'mp3'
|
||||
}));
|
||||
|
||||
var mediaStreams = mediaSource.MediaStreams;
|
||||
|
||||
var sourceContainer = (mediaSource.Container || '').toLowerCase();
|
||||
var isStatic = false;
|
||||
var seekParam = startPositionTicks ? '#t=' + (startPositionTicks / 10000000) : '';
|
||||
|
||||
for (var i = 0, length = mediaStreams.length; i < length; i++) {
|
||||
if (sourceContainer == 'mp3' ||
|
||||
(sourceContainer == 'aac' && supportsAac)) {
|
||||
|
||||
var stream = mediaStreams[i];
|
||||
for (var i = 0, length = mediaSource.MediaStreams.length; i < length; i++) {
|
||||
|
||||
var stream = mediaSource.MediaStreams[i];
|
||||
|
||||
if (stream.Type == "Audio") {
|
||||
|
||||
var container = (mediaSource.Container || '').toLowerCase();
|
||||
// Stream statically when possible
|
||||
if (container == 'mp3' && stream.BitRate <= 256000) {
|
||||
mp3Url += "&static=true" + seekParam;
|
||||
if (stream.BitRate <= 256000) {
|
||||
isStatic = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var outputContainer = isStatic ? sourceContainer : 'mp3';
|
||||
var audioUrl = ApiClient.getUrl('Audio/' + item.Id + '/stream.' + outputContainer, $.extend({}, baseParams, {
|
||||
audioCodec: outputContainer
|
||||
}));
|
||||
|
||||
if (isStatic) {
|
||||
var seekParam = startPositionTicks ? '#t=' + (startPositionTicks / 10000000) : '';
|
||||
audioUrl += "&static=true" + seekParam;
|
||||
}
|
||||
|
||||
self.startTimeTicksOffset = isStatic ? 0 : startPositionTicks;
|
||||
|
||||
|
@ -1165,7 +1195,7 @@
|
|||
|
||||
return getAudioElement().each(function () {
|
||||
|
||||
this.src = mp3Url;
|
||||
this.src = audioUrl;
|
||||
this.volume = initialVolume;
|
||||
this.play();
|
||||
|
||||
|
|
|
@ -222,18 +222,18 @@
|
|||
updateNowPlayingInfo(state);
|
||||
}
|
||||
|
||||
var currentImgUrl;
|
||||
function updateNowPlayingInfo(state) {
|
||||
|
||||
var name = state.itemName;
|
||||
var nameHtml = MediaPlayer.getNowPlayingNameHtml(state);
|
||||
|
||||
if (state.itemSubName) {
|
||||
name += '<br/>' + state.itemSubName;
|
||||
if (nameHtml.indexOf('<br/>') != -1) {
|
||||
nowPlayingTextElement.addClass('nowPlayingDoubleText');
|
||||
} else {
|
||||
nowPlayingTextElement.removeClass('nowPlayingDoubleText');
|
||||
}
|
||||
|
||||
nowPlayingTextElement.html(name);
|
||||
nowPlayingTextElement.html(nameHtml);
|
||||
|
||||
var url;
|
||||
|
||||
|
@ -273,6 +273,12 @@
|
|||
url = "css/images/items/detail/video.png";
|
||||
}
|
||||
|
||||
if (url == currentImgUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentImgUrl = url;
|
||||
|
||||
nowPlayingImageElement.html('<img src="' + url + '" />');
|
||||
}
|
||||
|
||||
|
|
|
@ -529,6 +529,18 @@
|
|||
});
|
||||
};
|
||||
|
||||
self.displayContent = function (options) {
|
||||
|
||||
sendCommand('DisplayContent', {
|
||||
|
||||
ItemName: options.itemName,
|
||||
ItemType: options.itemType,
|
||||
ItemId: options.itemId,
|
||||
Context: options.context
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
self.getPlayerState = function () {
|
||||
|
||||
var deferred = $.Deferred();
|
||||
|
@ -615,7 +627,8 @@
|
|||
playerName: self.name,
|
||||
appName: s.Client,
|
||||
playableMediaTypes: s.PlayableMediaTypes,
|
||||
isLocalPlayer: false
|
||||
isLocalPlayer: false,
|
||||
supportedCommands: s.SupportedCommands
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -648,13 +661,17 @@
|
|||
if (item) {
|
||||
|
||||
state.itemId = item.Id;
|
||||
state.itemType = item.Type;
|
||||
state.mediaType = item.MediaType;
|
||||
state.runtimeTicks = item.RunTimeTicks;
|
||||
state.mediaSource = item.MediaSourceId;
|
||||
state.positionTicks = session.NowPlayingPositionTicks || 0;
|
||||
|
||||
state.itemType = item.Type;
|
||||
state.indexNumber = item.IndexNumber;
|
||||
state.indexNumberEnd = item.IndexNumberEnd;
|
||||
state.parentIndexNumber = item.ParentIndexNumber;
|
||||
state.productionYear = item.ProductionYear;
|
||||
state.premiereDate = item.PremiereDate;
|
||||
state.seriesName = item.SeriesName;
|
||||
state.album = item.Album;
|
||||
state.itemName = item.Name;
|
||||
state.artists = item.Artists;
|
||||
|
||||
state.primaryImageItemId = item.PrimaryImageItemId;
|
||||
state.primaryImageTag = item.PrimaryImageTag;
|
||||
|
@ -664,6 +681,10 @@
|
|||
|
||||
state.thumbItemId = item.ThumbItemId;
|
||||
state.thumbImageTag = item.ThumbImageTag;
|
||||
|
||||
state.mediaSource = item.MediaSourceId;
|
||||
state.positionTicks = session.NowPlayingPositionTicks || 0;
|
||||
state.runtimeTicks = item.RunTimeTicks;
|
||||
}
|
||||
|
||||
return state;
|
||||
|
|
|
@ -263,6 +263,8 @@ var Dashboard = {
|
|||
|
||||
var html = '<span style="margin-right: 1em;">Please refresh this page to receive new updates from the server.</span>';
|
||||
|
||||
html += '<button type="button" data-icon="refresh" onclick="$(this).buttonEnabled(false);Dashboard.reloadPage();" data-theme="b" data-inline="true" data-mini="true">Refresh</button>';
|
||||
|
||||
Dashboard.showFooterNotification({ id: "dashboardVersionWarning", html: html, forceShow: true, allowHide: false });
|
||||
},
|
||||
|
||||
|
@ -801,6 +803,16 @@ var Dashboard = {
|
|||
ApiClient.openWebSocket(webSocketUrl);
|
||||
},
|
||||
|
||||
onWebSocketOpened: function () {
|
||||
|
||||
ApiClient.reportCapabilities({
|
||||
PlayableMediaTypes: "Audio,Video",
|
||||
|
||||
SupportedCommands: Dashboard.getSupportedRemoteCommands().join(',')
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
onWebSocketMessageReceived: function (e, data) {
|
||||
|
||||
var msg = data;
|
||||
|
@ -878,10 +890,6 @@ var Dashboard = {
|
|||
}
|
||||
});
|
||||
}
|
||||
else if (msg.MessageType === "Browse") {
|
||||
|
||||
Dashboard.onBrowseCommand(msg.Data);
|
||||
}
|
||||
else if (msg.MessageType === "GeneralCommand") {
|
||||
|
||||
var cmd = msg.Data;
|
||||
|
@ -892,6 +900,9 @@ var Dashboard = {
|
|||
else if (cmd.Name === 'GoToSettings') {
|
||||
Dashboard.navigate('dashboard.html');
|
||||
}
|
||||
else if (cmd.Name === 'DisplayContent') {
|
||||
Dashboard.onBrowseCommand(cmd.Arguments);
|
||||
}
|
||||
}
|
||||
else if (msg.MessageType === "MessageCommand") {
|
||||
|
||||
|
@ -1237,6 +1248,27 @@ var Dashboard = {
|
|||
}
|
||||
|
||||
$(select).html(html).selectmenu("refresh");
|
||||
},
|
||||
|
||||
getSupportedRemoteCommands: function () {
|
||||
|
||||
// Full list
|
||||
// https://github.com/MediaBrowser/MediaBrowser/blob/master/MediaBrowser.Model/Session/GeneralCommand.cs
|
||||
return [
|
||||
"GoHome",
|
||||
"GoToSettings",
|
||||
"VolumeUp",
|
||||
"VolumeDown",
|
||||
"Mute",
|
||||
"Unmute",
|
||||
"ToggleMute",
|
||||
"SetVolume",
|
||||
"ToggleFullscreen",
|
||||
"SetAudioStreamIndex",
|
||||
"SetSubtitleStreamIndex",
|
||||
"DisplayContent"
|
||||
];
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1252,7 +1284,7 @@ else if (!IsStorageEnabled()) {
|
|||
|
||||
var ApiClient = MediaBrowser.ApiClient.create("Dashboard", window.dashboardVersion);
|
||||
|
||||
$(ApiClient).on("websocketmessage", Dashboard.onWebSocketMessageReceived);
|
||||
$(ApiClient).on("websocketopen", Dashboard.onWebSocketOpened).on("websocketmessage", Dashboard.onWebSocketMessageReceived);
|
||||
|
||||
|
||||
$(function () {
|
||||
|
|
|
@ -1,29 +1,11 @@
|
|||
var SupporterPage = {
|
||||
(function () {
|
||||
|
||||
onPageShow: function () {
|
||||
SupporterPage.load();
|
||||
},
|
||||
$(document).on('pageshow', "#supporterPage", function () {
|
||||
|
||||
onPageHide: function () {
|
||||
var page = this;
|
||||
|
||||
},
|
||||
|
||||
load: function() {
|
||||
Dashboard.showLoadingMsg();
|
||||
var page = $.mobile.activePage;
|
||||
|
||||
ApiClient.getPluginSecurityInfo().done(function (info) {
|
||||
$('#txtSupporterKey', page).val(info.SupporterKey);
|
||||
if (info.IsMBSupporter) {
|
||||
$('.supporterOnly', page).show();
|
||||
} else {
|
||||
$('.supporterOnly', page).hide();
|
||||
}
|
||||
$('#paypalReturnUrl', page).val(ApiClient.getUrl("supporterkey.html"));
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('pageshow', "#supporterPage", SupporterPage.onPageShow)
|
||||
.on('pagehide', "#supporterPage", SupporterPage.onPageHide);
|
||||
});
|
||||
|
||||
})();
|
|
@ -18,15 +18,9 @@
|
|||
</div>
|
||||
<h3>Support the Media Browser Team</h3>
|
||||
<p>
|
||||
Help ensure the continued development of this product by donating a minimum of $10 (greater amounts greatly appreciated). A portion of all donations will be contributed to other <a href="about.html">free tools</a> we depend on.
|
||||
Help ensure the continued development of this project by donating. A portion of all donations will be contributed to other <a href="about.html">free tools</a> we depend on.
|
||||
</p>
|
||||
|
||||
<p style="display: none; padding: 1em; border-radius: 5px; font-weight: normal;" class="ui-bar-a supporterOnly">
|
||||
<strong>Thank You</strong> for your past support of the Media Browser Team. Users like you make it possible for
|
||||
Media Browser to exist and keep getting better and better. You can always support us again if you feel you are getting maximum
|
||||
value from the product.
|
||||
|
||||
</p>
|
||||
<br />
|
||||
<form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr"
|
||||
method="post">
|
||||
|
|
|
@ -1728,6 +1728,16 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
|
|||
});
|
||||
};
|
||||
|
||||
self.reportCapabilities = function (options) {
|
||||
|
||||
var url = self.getUrl("Sessions/Capabilities", options);
|
||||
|
||||
return self.ajax({
|
||||
type: "POST",
|
||||
url: url
|
||||
});
|
||||
};
|
||||
|
||||
self.updateItemImageIndex = function (itemId, itemType, itemName, imageType, imageIndex, newIndex) {
|
||||
|
||||
if (!imageType) {
|
||||
|
@ -3758,24 +3768,6 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
|
|||
});
|
||||
};
|
||||
|
||||
self.sendBrowseCommand = function (sessionId, options) {
|
||||
|
||||
if (!sessionId) {
|
||||
throw new Error("null sessionId");
|
||||
}
|
||||
|
||||
if (!options) {
|
||||
throw new Error("null options");
|
||||
}
|
||||
|
||||
var url = self.getUrl("Sessions/" + sessionId + "/Viewing", options);
|
||||
|
||||
return self.ajax({
|
||||
type: "POST",
|
||||
url: url
|
||||
});
|
||||
};
|
||||
|
||||
self.sendPlayCommand = function (sessionId, options) {
|
||||
|
||||
if (!sessionId) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue