mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
update offline detection
This commit is contained in:
parent
c651a45dea
commit
930c8cf6d8
26 changed files with 813 additions and 784 deletions
|
@ -137,28 +137,30 @@
|
|||
}
|
||||
};
|
||||
|
||||
var streamInfo = MediaPlayer.createStreamInfo('Video', item, mediaSource, startPosition);
|
||||
var currentSrc = streamInfo.url;
|
||||
MediaPlayer.createStreamInfo('Video', item, mediaSource, startPosition).done(function (streamInfo) {
|
||||
|
||||
var audioStreamIndex = getParameterByName('AudioStreamIndex', currentSrc);
|
||||
var currentSrc = streamInfo.url;
|
||||
|
||||
if (audioStreamIndex) {
|
||||
basePlayerState.PlayState.AudioStreamIndex = parseInt(audioStreamIndex);
|
||||
}
|
||||
basePlayerState.PlayState.SubtitleStreamIndex = self.currentSubtitleStreamIndex;
|
||||
var audioStreamIndex = getParameterByName('AudioStreamIndex', currentSrc);
|
||||
|
||||
basePlayerState.PlayState.PlayMethod = getParameterByName('static', currentSrc) == 'true' ?
|
||||
'DirectStream' :
|
||||
'Transcode';
|
||||
if (audioStreamIndex) {
|
||||
basePlayerState.PlayState.AudioStreamIndex = parseInt(audioStreamIndex);
|
||||
}
|
||||
basePlayerState.PlayState.SubtitleStreamIndex = self.currentSubtitleStreamIndex;
|
||||
|
||||
basePlayerState.PlayState.LiveStreamId = getParameterByName('LiveStreamId', currentSrc);
|
||||
basePlayerState.PlayState.PlaySessionId = getParameterByName('PlaySessionId', currentSrc);
|
||||
basePlayerState.PlayState.PlayMethod = getParameterByName('static', currentSrc) == 'true' ?
|
||||
'DirectStream' :
|
||||
'Transcode';
|
||||
|
||||
basePlayerState.PlayState.MediaSourceId = mediaSource.Id;
|
||||
basePlayerState.PlayState.CanSeek = false;
|
||||
basePlayerState.NowPlayingItem = MediaPlayer.getNowPlayingItemForReporting(item, mediaSource);
|
||||
basePlayerState.PlayState.LiveStreamId = getParameterByName('LiveStreamId', currentSrc);
|
||||
basePlayerState.PlayState.PlaySessionId = getParameterByName('PlaySessionId', currentSrc);
|
||||
|
||||
deferred.resolveWith(null, [streamInfo]);
|
||||
basePlayerState.PlayState.MediaSourceId = mediaSource.Id;
|
||||
basePlayerState.PlayState.CanSeek = false;
|
||||
basePlayerState.NowPlayingItem = MediaPlayer.getNowPlayingItemForReporting(item, mediaSource);
|
||||
|
||||
deferred.resolveWith(null, [streamInfo]);
|
||||
});
|
||||
}
|
||||
|
||||
function getPlayerState(positionTicks) {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
function hideStatusBar() {
|
||||
if (options.type == 'video' && window.StatusBar) {
|
||||
StatusBar.backgroundColorByName("black");
|
||||
StatusBar.overlaysWebView(true);
|
||||
//StatusBar.overlaysWebView(true);
|
||||
StatusBar.hide();
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
|||
function showStatusBar() {
|
||||
if (options.type == 'video' && window.StatusBar) {
|
||||
StatusBar.show();
|
||||
StatusBar.overlaysWebView(false);
|
||||
//StatusBar.overlaysWebView(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -355,6 +355,11 @@
|
|||
}
|
||||
|
||||
var val = streamInfo.url;
|
||||
|
||||
if (AppInfo.isNativeApp && $.browser.safari) {
|
||||
val = val.replace('file://', '');
|
||||
}
|
||||
|
||||
requiresSettingStartTimeOnStart = false;
|
||||
var startTime = getStartTime(val);
|
||||
var playNow = false;
|
||||
|
|
|
@ -270,9 +270,26 @@
|
|||
}, delay);
|
||||
});
|
||||
|
||||
function fadeOutLeftBig(elem, iterations) {
|
||||
var keyframes = [{ opacity: '1', transform: 'none', offset: 0 },
|
||||
{ opacity: '0', transform: 'translate3d(-2000px, 0, 0)', offset: 1 }];
|
||||
var timing = { duration: 700, iterations: iterations };
|
||||
return elem.animate(keyframes, timing);
|
||||
}
|
||||
|
||||
if (!LibraryBrowser.navigateOnLibraryTabSelect()) {
|
||||
tabs.addEventListener('iron-select', function () {
|
||||
pages.selected = this.selected;
|
||||
|
||||
var selected = pages.selected;
|
||||
if (selected != null) {
|
||||
var newValue = this.selected;
|
||||
fadeOutLeftBig(pages.querySelectorAll('.pageTabContent')[selected], 1).onfinish = function () {
|
||||
pages.selected = newValue;
|
||||
};
|
||||
}
|
||||
else {
|
||||
pages.selected = this.selected;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -2362,12 +2379,12 @@
|
|||
|
||||
var syncPercent = item.SyncPercent;
|
||||
if (syncPercent) {
|
||||
return '<div class="workingSyncIndicator syncIndicator"><iron-icon icon="sync"></iron-icon></div>';
|
||||
return '<div class="syncIndicator"><iron-icon icon="sync"></iron-icon></div>';
|
||||
}
|
||||
|
||||
if (item.SyncStatus == 'Queued' || item.SyncStatus == 'Converting' || item.SyncStatus == 'ReadyToTransfer' || item.SyncStatus == 'Transferring') {
|
||||
|
||||
return '<div class="workingSyncIndicator syncIndicator"><iron-icon icon="sync"></iron-icon></div>';
|
||||
return '<div class="syncIndicator"><iron-icon icon="sync"></iron-icon></div>';
|
||||
}
|
||||
|
||||
return '';
|
||||
|
|
|
@ -617,6 +617,13 @@
|
|||
return;
|
||||
}
|
||||
|
||||
var url = 'itemdetails.html?id=' + itemId;
|
||||
if (context) {
|
||||
url += '&context=' + context;
|
||||
}
|
||||
Dashboard.navigate(url);
|
||||
return;
|
||||
|
||||
var ids = items.map(function (i) {
|
||||
return i.Id;
|
||||
});
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
var mainDrawerButton = document.querySelector('.mainDrawerButton');
|
||||
|
||||
if (mainDrawerButton) {
|
||||
if (AppInfo.isTouchPreferred) {
|
||||
if (AppInfo.isTouchPreferred || $.browser.mobile) {
|
||||
|
||||
Events.on(mainDrawerButton, 'click', openMainDrawer);
|
||||
|
||||
|
@ -178,32 +178,35 @@
|
|||
document.body.classList.add('bodyWithPopupOpen');
|
||||
}
|
||||
|
||||
var drawer = document.querySelector('.mainDrawerPanel .mainDrawer');
|
||||
var pageElem = $($.mobile.activePage)[0];
|
||||
|
||||
ConnectionManager.user(window.ApiClient).done(function (user) {
|
||||
if (requiresDrawerRefresh || requiresDashboardDrawerRefresh) {
|
||||
|
||||
if (requiresDrawerRefresh) {
|
||||
ensureDrawerStructure(drawer);
|
||||
ConnectionManager.user(window.ApiClient).done(function (user) {
|
||||
|
||||
refreshUserInfoInDrawer(user, drawer);
|
||||
refreshLibraryInfoInDrawer(user, drawer);
|
||||
refreshBottomUserInfoInDrawer(user, drawer);
|
||||
var drawer = document.querySelector('.mainDrawerPanel .mainDrawer');
|
||||
|
||||
Events.trigger(document, 'libraryMenuCreated');
|
||||
updateLibraryMenu(user.localUser);
|
||||
}
|
||||
if (requiresDrawerRefresh) {
|
||||
ensureDrawerStructure(drawer);
|
||||
|
||||
var pageElem = $($.mobile.activePage)[0];
|
||||
refreshUserInfoInDrawer(user, drawer);
|
||||
refreshLibraryInfoInDrawer(user, drawer);
|
||||
refreshBottomUserInfoInDrawer(user, drawer);
|
||||
|
||||
if (requiresDrawerRefresh || requiresDashboardDrawerRefresh) {
|
||||
refreshDashboardInfoInDrawer(pageElem, user, drawer);
|
||||
requiresDashboardDrawerRefresh = false;
|
||||
}
|
||||
Events.trigger(document, 'libraryMenuCreated');
|
||||
updateLibraryMenu(user.localUser);
|
||||
}
|
||||
|
||||
requiresDrawerRefresh = false;
|
||||
if (requiresDrawerRefresh || requiresDashboardDrawerRefresh) {
|
||||
refreshDashboardInfoInDrawer(pageElem, user, drawer);
|
||||
requiresDashboardDrawerRefresh = false;
|
||||
}
|
||||
|
||||
updateLibraryNavLinks(pageElem);
|
||||
});
|
||||
requiresDrawerRefresh = false;
|
||||
});
|
||||
}
|
||||
|
||||
updateLibraryNavLinks(pageElem);
|
||||
|
||||
document.querySelector('.mainDrawerPanel #drawer').classList.add('verticalScrollingDrawer');
|
||||
}
|
||||
|
@ -714,26 +717,33 @@
|
|||
lnkMediaFolder.classList.remove('selectedMediaFolder');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateTabLinks(page) {
|
||||
var context = getParameterByName('context');
|
||||
|
||||
if (context !== 'playlists') {
|
||||
var elems = page.querySelectorAll('.scopedLibraryViewNav a');
|
||||
|
||||
elems = page.querySelectorAll('.scopedLibraryViewNav a');
|
||||
var id = page.classList.contains('liveTvPage') || page.classList.contains('channelsPage') || page.classList.contains('metadataEditorPage') || page.classList.contains('reportsPage') || page.classList.contains('mySyncPage') || page.classList.contains('allLibraryPage') ?
|
||||
'' :
|
||||
getTopParentId() || '';
|
||||
|
||||
for (i = 0, length = elems.length; i < length; i++) {
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
|
||||
var lnk = elems[i];
|
||||
var src = lnk.href;
|
||||
for (i = 0, length = elems.length; i < length; i++) {
|
||||
|
||||
if (src.indexOf('#') != -1) {
|
||||
continue;
|
||||
}
|
||||
var lnk = elems[i];
|
||||
var src = lnk.href;
|
||||
|
||||
src = replaceQueryString(src, 'topParentId', id);
|
||||
|
||||
lnk.href = src;
|
||||
if (src.indexOf('#') != -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
src = replaceQueryString(src, 'topParentId', id);
|
||||
|
||||
lnk.href = src;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -792,7 +802,9 @@
|
|||
|
||||
var page = this;
|
||||
|
||||
requiresDashboardDrawerRefresh = true;
|
||||
if (page.classList.contains('type-interior')) {
|
||||
requiresDashboardDrawerRefresh = true;
|
||||
}
|
||||
|
||||
onPageBeforeShowDocumentReady(page);
|
||||
|
||||
|
@ -861,7 +873,12 @@
|
|||
if (AppInfo.enableBottomTabs) {
|
||||
page.classList.add('noSecondaryNavPage');
|
||||
|
||||
document.querySelector('.footer').classList.add('footerOverBottomTabs');
|
||||
if (page.classList.contains('pageWithAbsoluteTabs')) {
|
||||
document.querySelector('.footer').classList.add('footerOverBottomTabs');
|
||||
}
|
||||
else {
|
||||
document.querySelector('.footer').classList.remove('footerOverBottomTabs');
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -927,6 +944,7 @@
|
|||
// Scroll back up so in case vertical scroll was messed with
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
updateTabLinks(page);
|
||||
}
|
||||
|
||||
function initHeadRoom(elem) {
|
||||
|
|
|
@ -96,16 +96,16 @@
|
|||
function updateFilterControls(page) {
|
||||
|
||||
var query = getQuery();
|
||||
$('#chkFavorite', page).checked(query.IsFavorite == true);
|
||||
$('#chkLikes', page).checked(query.IsLiked == true);
|
||||
$('#chkDislikes', page).checked(query.IsDisliked == true);
|
||||
$('.chkFavorite', page).checked(query.IsFavorite == true);
|
||||
$('.chkLikes', page).checked(query.IsLiked == true);
|
||||
$('.chkDislikes', page).checked(query.IsDisliked == true);
|
||||
}
|
||||
|
||||
window.LiveTvPage.initChannelsTab = function (page, tabContent) {
|
||||
|
||||
var viewPanel = page.querySelector('.channelViewPanel');
|
||||
|
||||
$('#chkFavorite', viewPanel).on('change', function () {
|
||||
$('.chkFavorite', viewPanel).on('change', function () {
|
||||
|
||||
var query = getQuery();
|
||||
query.StartIndex = 0;
|
||||
|
@ -115,7 +115,7 @@
|
|||
});
|
||||
|
||||
|
||||
$('#chkLikes', viewPanel).on('change', function () {
|
||||
$('.chkLikes', viewPanel).on('change', function () {
|
||||
|
||||
var query = getQuery();
|
||||
query.StartIndex = 0;
|
||||
|
@ -124,7 +124,7 @@
|
|||
reloadItems(tabContent, viewPanel);
|
||||
});
|
||||
|
||||
$('#chkDislikes', viewPanel).on('change', function () {
|
||||
$('.chkDislikes', viewPanel).on('change', function () {
|
||||
|
||||
var query = getQuery();
|
||||
query.StartIndex = 0;
|
||||
|
|
|
@ -891,28 +891,29 @@
|
|||
|
||||
requirejs(['videorenderer'], function () {
|
||||
|
||||
var streamInfo = self.createStreamInfo('Video', item, mediaSource, startPosition);
|
||||
self.createStreamInfo('Video', item, mediaSource, startPosition).done(function (streamInfo) {
|
||||
|
||||
// Huge hack alert. Safari doesn't seem to like if the segments aren't available right away when playback starts
|
||||
// This will start the transcoding process before actually feeding the video url into the player
|
||||
if ($.browser.safari && !mediaSource.RunTimeTicks) {
|
||||
// Huge hack alert. Safari doesn't seem to like if the segments aren't available right away when playback starts
|
||||
// This will start the transcoding process before actually feeding the video url into the player
|
||||
if ($.browser.safari && !mediaSource.RunTimeTicks) {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.ajax({
|
||||
type: 'GET',
|
||||
url: streamInfo.url.replace('master.m3u8', 'live.m3u8')
|
||||
}).always(function () {
|
||||
ApiClient.ajax({
|
||||
type: 'GET',
|
||||
url: streamInfo.url.replace('master.m3u8', 'live.m3u8')
|
||||
}).always(function () {
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
||||
}).done(function () {
|
||||
}).done(function () {
|
||||
self.playVideoInternal(item, mediaSource, startPosition, streamInfo, callback);
|
||||
});
|
||||
|
||||
} else {
|
||||
self.playVideoInternal(item, mediaSource, startPosition, streamInfo, callback);
|
||||
});
|
||||
|
||||
} else {
|
||||
self.playVideoInternal(item, mediaSource, startPosition, streamInfo, callback);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -291,8 +291,6 @@
|
|||
|
||||
profile.ContainerProfiles = [];
|
||||
|
||||
var maxAudioChannels = isVlc ? '6' : '2';
|
||||
|
||||
profile.CodecProfiles = [];
|
||||
profile.CodecProfiles.push({
|
||||
Type: 'Audio',
|
||||
|
@ -303,16 +301,6 @@
|
|||
}]
|
||||
});
|
||||
|
||||
profile.CodecProfiles.push({
|
||||
Type: 'VideoAudio',
|
||||
Codec: 'mp3',
|
||||
Conditions: [{
|
||||
Condition: 'LessThanEqual',
|
||||
Property: 'AudioChannels',
|
||||
Value: maxAudioChannels
|
||||
}]
|
||||
});
|
||||
|
||||
if (!isVlc) {
|
||||
profile.CodecProfiles.push({
|
||||
Type: 'VideoAudio',
|
||||
|
@ -340,7 +328,7 @@
|
|||
{
|
||||
Condition: 'LessThanEqual',
|
||||
Property: 'AudioChannels',
|
||||
Value: maxAudioChannels
|
||||
Value: '6'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
@ -641,17 +629,18 @@
|
|||
if (validatePlaybackInfoResult(result)) {
|
||||
|
||||
self.currentMediaSource = result.MediaSources[0];
|
||||
var streamInfo = self.createStreamInfo(self.currentItem.MediaType, self.currentItem, self.currentMediaSource, ticks);
|
||||
self.createStreamInfo(self.currentItem.MediaType, self.currentItem, self.currentMediaSource, ticks).done(function (streamInfo) {
|
||||
|
||||
if (!streamInfo.url) {
|
||||
MediaController.showPlaybackInfoErrorMessage('NoCompatibleStream');
|
||||
self.stop();
|
||||
return false;
|
||||
}
|
||||
if (!streamInfo.url) {
|
||||
MediaController.showPlaybackInfoErrorMessage('NoCompatibleStream');
|
||||
self.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
self.currentSubtitleStreamIndex = subtitleStreamIndex;
|
||||
self.currentSubtitleStreamIndex = subtitleStreamIndex;
|
||||
|
||||
changeStreamToUrl(mediaRenderer, playSessionId, streamInfo, streamInfo.startTimeTicksOffset || 0);
|
||||
changeStreamToUrl(mediaRenderer, playSessionId, streamInfo, streamInfo.startTimeTicksOffset || 0);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -915,6 +904,8 @@
|
|||
|
||||
self.createStreamInfo = function (type, item, mediaSource, startPosition) {
|
||||
|
||||
var deferred = $.Deferred();
|
||||
|
||||
var mediaUrl;
|
||||
var contentType;
|
||||
var startTimeTicksOffset = 0;
|
||||
|
@ -1018,13 +1009,32 @@
|
|||
}
|
||||
}
|
||||
|
||||
return {
|
||||
var resultInfo = {
|
||||
url: mediaUrl,
|
||||
mimeType: contentType,
|
||||
startTimeTicksOffset: startTimeTicksOffset,
|
||||
startPositionInSeekParam: startPositionInSeekParam,
|
||||
playMethod: playMethod
|
||||
};
|
||||
|
||||
if (playMethod == 'DirectPlay' && mediaSource.Protocol == 'File') {
|
||||
|
||||
require(['localassetmanager'], function () {
|
||||
|
||||
LocalAssetManager.translateFilePath(resultInfo.url).done(function (path) {
|
||||
|
||||
resultInfo.url = path;
|
||||
Logger.log('LocalAssetManager.translateFilePath: path: ' + resultInfo.url + ' result: ' + path);
|
||||
deferred.resolveWith(null, [resultInfo]);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
else {
|
||||
deferred.resolveWith(null, [resultInfo]);
|
||||
}
|
||||
|
||||
return deferred.promise();
|
||||
};
|
||||
|
||||
self.lastBitrateDetect = 0;
|
||||
|
@ -1872,65 +1882,67 @@
|
|||
|
||||
function playAudioInternal(item, mediaSource, startPositionTicks) {
|
||||
|
||||
var streamInfo = self.createStreamInfo('Audio', item, mediaSource, startPositionTicks);
|
||||
var audioUrl = streamInfo.url;
|
||||
self.startTimeTicksOffset = streamInfo.startTimeTicksOffset;
|
||||
self.createStreamInfo('Audio', item, mediaSource, startPositionTicks).done(function (streamInfo) {
|
||||
|
||||
var initialVolume = self.getSavedVolume();
|
||||
var audioUrl = streamInfo.url;
|
||||
self.startTimeTicksOffset = streamInfo.startTimeTicksOffset;
|
||||
|
||||
var mediaRenderer = new AudioRenderer({
|
||||
poster: self.getPosterUrl(item)
|
||||
});
|
||||
var initialVolume = self.getSavedVolume();
|
||||
|
||||
Events.on(mediaRenderer, "volumechange.mediaplayerevent", function () {
|
||||
var mediaRenderer = new AudioRenderer({
|
||||
poster: self.getPosterUrl(item)
|
||||
});
|
||||
|
||||
Logger.log('audio element event: volumechange');
|
||||
Events.on(mediaRenderer, "volumechange.mediaplayerevent", function () {
|
||||
|
||||
self.onVolumeChanged(this);
|
||||
Logger.log('audio element event: volumechange');
|
||||
|
||||
});
|
||||
self.onVolumeChanged(this);
|
||||
|
||||
$(mediaRenderer).one("playing.mediaplayerevent", function () {
|
||||
});
|
||||
|
||||
Logger.log('audio element event: playing');
|
||||
$(mediaRenderer).one("playing.mediaplayerevent", function () {
|
||||
|
||||
// For some reason this is firing at the start, so don't bind until playback has begun
|
||||
Events.on(this, 'ended', self.onPlaybackStopped);
|
||||
Logger.log('audio element event: playing');
|
||||
|
||||
$(this).one('ended', self.playNextAfterEnded);
|
||||
// For some reason this is firing at the start, so don't bind until playback has begun
|
||||
Events.on(this, 'ended', self.onPlaybackStopped);
|
||||
|
||||
self.onPlaybackStart(this, item, mediaSource);
|
||||
$(this).one('ended', self.playNextAfterEnded);
|
||||
|
||||
}).on("pause.mediaplayerevent", function () {
|
||||
self.onPlaybackStart(this, item, mediaSource);
|
||||
|
||||
Logger.log('audio element event: pause');
|
||||
}).on("pause.mediaplayerevent", function () {
|
||||
|
||||
self.onPlaystateChange(this);
|
||||
Logger.log('audio element event: pause');
|
||||
|
||||
// In the event timeupdate isn't firing, at least we can update when this happens
|
||||
self.setCurrentTime(self.getCurrentTicks());
|
||||
self.onPlaystateChange(this);
|
||||
|
||||
}).on("playing.mediaplayerevent", function () {
|
||||
// In the event timeupdate isn't firing, at least we can update when this happens
|
||||
self.setCurrentTime(self.getCurrentTicks());
|
||||
|
||||
Logger.log('audio element event: playing');
|
||||
}).on("playing.mediaplayerevent", function () {
|
||||
|
||||
self.onPlaystateChange(this);
|
||||
Logger.log('audio element event: playing');
|
||||
|
||||
// In the event timeupdate isn't firing, at least we can update when this happens
|
||||
self.setCurrentTime(self.getCurrentTicks());
|
||||
self.onPlaystateChange(this);
|
||||
|
||||
}).on("timeupdate.mediaplayerevent", onTimeUpdate);
|
||||
// In the event timeupdate isn't firing, at least we can update when this happens
|
||||
self.setCurrentTime(self.getCurrentTicks());
|
||||
|
||||
self.currentMediaRenderer = mediaRenderer;
|
||||
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
|
||||
}).on("timeupdate.mediaplayerevent", onTimeUpdate);
|
||||
|
||||
mediaRenderer.init().done(function () {
|
||||
self.currentMediaRenderer = mediaRenderer;
|
||||
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
|
||||
|
||||
// Set volume first to avoid an audible change
|
||||
mediaRenderer.volume(initialVolume);
|
||||
mediaRenderer.init().done(function () {
|
||||
|
||||
mediaRenderer.setCurrentSrc(streamInfo, item, mediaSource);
|
||||
self.streamInfo = streamInfo;
|
||||
// Set volume first to avoid an audible change
|
||||
mediaRenderer.volume(initialVolume);
|
||||
|
||||
mediaRenderer.setCurrentSrc(streamInfo, item, mediaSource);
|
||||
self.streamInfo = streamInfo;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,39 @@
|
|||
});
|
||||
}
|
||||
|
||||
function getSyncStatusBanner(job) {
|
||||
|
||||
var opacity = '.85';
|
||||
var background = 'rgba(204,51,51,' + opacity + ')';
|
||||
var text = Globalize.translate('SyncJobStatus' + job.Status);
|
||||
|
||||
if (job.Status == 'Completed') {
|
||||
background = 'rgba(82, 181, 75, ' + opacity + ')';
|
||||
}
|
||||
else if (job.Status == 'CompletedWithError') {
|
||||
|
||||
}
|
||||
else if (job.Status == 'Queued') {
|
||||
background = 'rgba(51, 136, 204, ' + opacity + ')';
|
||||
}
|
||||
else if (job.Status == 'ReadyToTransfer') {
|
||||
background = 'rgba(51, 136, 204, ' + opacity + ')';
|
||||
}
|
||||
else if (job.Status == 'Transferring') {
|
||||
background = 'rgba(72, 0, 255, ' + opacity + ')';
|
||||
}
|
||||
else if (job.Status == 'Converting') {
|
||||
background = 'rgba(255, 106, 0, ' + opacity + ')';
|
||||
}
|
||||
|
||||
var html = '';
|
||||
html += '<div class="syncStatusBanner" data-status="' + job.Status + '" style="background-color:' + background + ';position:absolute;top:0;right:0;padding:.5em .5em; text-align:left;color: #fff; font-weight: 500; text-transform:uppercase; border-bottom-left-radius: 3px;">';
|
||||
html += text;
|
||||
html += '</div>';
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function getSyncJobHtml(page, job, cardBoxCssClass, syncJobPage) {
|
||||
|
||||
var html = '';
|
||||
|
@ -54,42 +87,23 @@
|
|||
|
||||
html += '<div class="cardImage coveredCardImage lazy" data-src="' + imgUrl + '" style="' + style + '">';
|
||||
|
||||
if (job.Progress && job.Progress < 100) {
|
||||
html += '<div class="cardFooter fullCardFooter lightCardFooter">';
|
||||
html += "<div class='cardText cardProgress'>";
|
||||
html += '<progress class="itemProgressBar" min="0" max="100" value="' + job.Progress + '"></progress>';
|
||||
html += "</div>";
|
||||
html += "</div>";
|
||||
var progress = job.Progress || 0;
|
||||
|
||||
var footerClass = 'cardFooter fullCardFooter lightCardFooter';
|
||||
|
||||
if (progress == 0 || progress >= 100) {
|
||||
footerClass += ' hide';
|
||||
}
|
||||
|
||||
html += '<div class="' + footerClass + '">';
|
||||
html += "<div class='cardText cardProgress'>";
|
||||
html += '<progress class="itemProgressBar" min="0" max="100" value="' + progress + '"></progress>';
|
||||
html += "</div>";
|
||||
html += "</div>";
|
||||
|
||||
html += "</div>";
|
||||
|
||||
var opacity = '.85';
|
||||
var background = 'rgba(204,51,51,' + opacity + ')';
|
||||
var text = Globalize.translate('SyncJobStatus' + job.Status);
|
||||
|
||||
if (job.Status == 'Completed') {
|
||||
background = 'rgba(82, 181, 75, ' + opacity + ')';
|
||||
}
|
||||
else if (job.Status == 'CompletedWithError') {
|
||||
|
||||
}
|
||||
else if (job.Status == 'Queued') {
|
||||
background = 'rgba(51, 136, 204, ' + opacity + ')';
|
||||
}
|
||||
else if (job.Status == 'ReadyToTransfer') {
|
||||
background = 'rgba(51, 136, 204, ' + opacity + ')';
|
||||
}
|
||||
else if (job.Status == 'Transferring') {
|
||||
background = 'rgba(72, 0, 255, ' + opacity + ')';
|
||||
}
|
||||
else if (job.Status == 'Converting') {
|
||||
background = 'rgba(255, 106, 0, ' + opacity + ')';
|
||||
}
|
||||
|
||||
html += '<div class="syncStatusBanner" style="background-color:' + background + ';position:absolute;top:0;right:0;padding:.5em .5em; text-align:left;color: #fff; font-weight: 500; text-transform:uppercase; border-bottom-left-radius: 3px;">';
|
||||
html += text;
|
||||
html += '</div>';
|
||||
html += getSyncStatusBanner(job);
|
||||
|
||||
// cardContent
|
||||
html += "</a>";
|
||||
|
@ -139,8 +153,17 @@
|
|||
return html;
|
||||
}
|
||||
|
||||
var lastDataLoad = 0;
|
||||
|
||||
function loadData(page, jobs) {
|
||||
|
||||
if ((new Date().getTime() - lastDataLoad) < 60000) {
|
||||
refreshData(page, jobs);
|
||||
return;
|
||||
}
|
||||
|
||||
lastDataLoad = new Date().getTime();
|
||||
|
||||
var html = '';
|
||||
var lastTargetName = '';
|
||||
|
||||
|
@ -195,6 +218,46 @@
|
|||
}
|
||||
}
|
||||
|
||||
function refreshData(page, jobs) {
|
||||
|
||||
for (var i = 0, length = jobs.length; i < length; i++) {
|
||||
|
||||
var job = jobs[i];
|
||||
refreshJob(page, job);
|
||||
}
|
||||
}
|
||||
|
||||
function refreshJob(page, job) {
|
||||
|
||||
var card = page.querySelector('.card[data-id=\'' + job.Id + '\']');
|
||||
|
||||
if (!card) {
|
||||
return;
|
||||
}
|
||||
|
||||
var banner = card.querySelector('.syncStatusBanner');
|
||||
|
||||
if (banner.getAttribute('data-status') == job.Status) {
|
||||
var elem = document.createElement('div');
|
||||
elem.innerHTML = getSyncStatusBanner(job);
|
||||
elem = elem.querySelector('.syncStatusBanner');
|
||||
elem.parentNode.removeChild(elem);
|
||||
|
||||
banner.parentNode.replaceChild(elem, banner);
|
||||
}
|
||||
|
||||
var progress = job.Progress || 0;
|
||||
var cardFooter = card.querySelector('.cardFooter');
|
||||
|
||||
if (progress == 0 || progress >= 100) {
|
||||
cardFooter.classList.add('hide');
|
||||
}
|
||||
else {
|
||||
cardFooter.classList.remove('hide');
|
||||
cardFooter.querySelector('.itemProgressBar').value = progress;
|
||||
}
|
||||
}
|
||||
|
||||
function showJobMenu(page, elem) {
|
||||
|
||||
var card = $(elem).parents('.card');
|
||||
|
@ -265,6 +328,9 @@
|
|||
|
||||
loadData(page, response.Items);
|
||||
|
||||
setTimeout(function () {
|
||||
loadData(page, response.Items);
|
||||
}, 2000);
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
||||
});
|
||||
|
@ -314,6 +380,7 @@
|
|||
$(document).on('pageshowready', ".syncActivityPage", function () {
|
||||
|
||||
var page = this;
|
||||
lastDataLoad = 0;
|
||||
|
||||
Dashboard.getPluginSecurityInfo().done(function (pluginSecurityInfo) {
|
||||
|
||||
|
|
|
@ -85,6 +85,10 @@
|
|||
}
|
||||
html += '</div>';
|
||||
|
||||
html += '<div secondary style="padding-top:5px;">';
|
||||
html += '<paper-progress class="mini" style="width:100%;" value="' + (jobItem.Progress || 0) + '"></paper-progress>';
|
||||
html += '</div>';
|
||||
|
||||
html += '</paper-item-body>';
|
||||
|
||||
if (hasActions) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue