mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Unminify using 1.5.323
Repo with tag: https://github.com/MediaBrowser/emby-webcomponents/tree/1.5.323
This commit is contained in:
parent
4678528d00
commit
de6ac33ec1
289 changed files with 78483 additions and 54701 deletions
|
@ -1,28 +1,63 @@
|
|||
define([], function() {
|
||||
"use strict";
|
||||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function supportsHtmlMediaAutoplay() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var timeout, elem = document.createElement("video"),
|
||||
elemStyle = elem.style;
|
||||
if (!("autoplay" in elem)) return void reject();
|
||||
elemStyle.position = "absolute", elemStyle.height = 0, elemStyle.width = 0, elem.setAttribute("autoplay", "autoplay"), elem.style.display = "none", document.body.appendChild(elem);
|
||||
var testAutoplay = function(arg) {
|
||||
clearTimeout(timeout), elem.removeEventListener("playing", testAutoplay), elem.removeEventListener("play", testAutoplay);
|
||||
var supported = arg && "playing" === arg.type || arg && "play" === arg.type || 0 !== elem.currentTime;
|
||||
elem.parentNode.removeChild(elem), supported ? resolve() : reject()
|
||||
};
|
||||
elem.addEventListener("play", testAutoplay), elem.addEventListener("playing", testAutoplay);
|
||||
try {
|
||||
elem.src = "data:video/mp4;base64,AAAAHGZ0eXBtcDQyAAAAAG1wNDJpc29tYXZjMQAAAz5tb292AAAAbG12aGQAAAAAzaNacc2jWnEAAV+QAAFfkAABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAGGlvZHMAAAAAEICAgAcAT////3//AAACQ3RyYWsAAABcdGtoZAAAAAHNo1pxzaNacQAAAAEAAAAAAAFfkAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAEAAAABAAAAAAAd9tZGlhAAAAIG1kaGQAAAAAzaNacc2jWnEAAV+QAAFfkFXEAAAAAAAhaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAAAAAAGWbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAABVnN0YmwAAACpc3RzZAAAAAAAAAABAAAAmWF2YzEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAEAAQAEgAAABIAAAAAAAAAAEOSlZUL0FWQyBDb2RpbmcAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAxYXZjQwH0AAr/4QAZZ/QACq609NQYBBkAAAMAAQAAAwAKjxImoAEABWjOAa8gAAAAEmNvbHJuY2xjAAYAAQAGAAAAGHN0dHMAAAAAAAAAAQAAAAUAAEZQAAAAKHN0c3oAAAAAAAAAAAAAAAUAAAIqAAAACAAAAAgAAAAIAAAACAAAAChzdHNjAAAAAAAAAAIAAAABAAAABAAAAAEAAAACAAAAAQAAAAEAAAAYc3RjbwAAAAAAAAACAAADYgAABaQAAAAUc3RzcwAAAAAAAAABAAAAAQAAABFzZHRwAAAAAAREREREAAAAb3VkdGEAAABnbWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcgAAAAAAAAAAAAAAAAAAAAA6aWxzdAAAADKpdG9vAAAAKmRhdGEAAAABAAAAAEhhbmRCcmFrZSAwLjkuOCAyMDEyMDcxODAwAAACUm1kYXQAAAHkBgX/4NxF6b3m2Ui3lizYINkj7u94MjY0IC0gY29yZSAxMjAgLSBILjI2NC9NUEVHLTQgQVZDIGNvZGVjIC0gQ29weWxlZnQgMjAwMy0yMDExIC0gaHR0cDovL3d3dy52aWRlb2xhbi5vcmcveDI2NC5odG1sIC0gb3B0aW9uczogY2FiYWM9MCByZWY9MSBkZWJsb2NrPTE6MDowIGFuYWx5c2U9MHgxOjAgbWU9ZXNhIHN1Ym1lPTkgcHN5PTAgbWl4ZWRfcmVmPTAgbWVfcmFuZ2U9NCBjaHJvbWFfbWU9MSB0cmVsbGlzPTAgOHg4ZGN0PTAgY3FtPTAgZGVhZHpvbmU9MjEsMTEgZmFzdF9wc2tpcD0wIGNocm9tYV9xcF9vZmZzZXQ9MCB0aHJlYWRzPTYgc2xpY2VkX3RocmVhZHM9MCBucj0wIGRlY2ltYXRlPTEgaW50ZXJsYWNlZD0wIGJsdXJheV9jb21wYXQ9MCBjb25zdHJhaW5lZF9pbnRyYT0wIGJmcmFtZXM9MCB3ZWlnaHRwPTAga2V5aW50PTUwIGtleWludF9taW49NSBzY2VuZWN1dD00MCBpbnRyYV9yZWZyZXNoPTAgcmM9Y3FwIG1idHJlZT0wIHFwPTAAgAAAAD5liISscR8A+E4ACAACFoAAITAAAgsAAPgYCoKgoC+L4vi+KAvi+L4YfAEAACMzgABF9AAEUGUgABDJiXnf4AAAAARBmiKUAAAABEGaQpQAAAAEQZpilAAAAARBmoKU";
|
||||
var promise = elem.play();
|
||||
promise && promise.catch && promise.catch(reject), timeout = setTimeout(testAutoplay, 500)
|
||||
} catch (e) {
|
||||
return void reject()
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
var timeout;
|
||||
var elem = document.createElement('video');
|
||||
var elemStyle = elem.style;
|
||||
//skip the test if video itself, or the autoplay
|
||||
//element on it isn't supported
|
||||
if (!('autoplay' in elem)) {
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
})
|
||||
elemStyle.position = 'absolute';
|
||||
elemStyle.height = 0;
|
||||
elemStyle.width = 0;
|
||||
|
||||
elem.setAttribute('autoplay', 'autoplay');
|
||||
elem.style.display = 'none';
|
||||
document.body.appendChild(elem);
|
||||
|
||||
var testAutoplay = function (arg) {
|
||||
clearTimeout(timeout);
|
||||
elem.removeEventListener('playing', testAutoplay);
|
||||
elem.removeEventListener('play', testAutoplay);
|
||||
var supported = (arg && arg.type === 'playing') || (arg && arg.type === 'play') || elem.currentTime !== 0;
|
||||
elem.parentNode.removeChild(elem);
|
||||
|
||||
if (supported) {
|
||||
resolve();
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
};
|
||||
|
||||
// play needed for firefox
|
||||
elem.addEventListener('play', testAutoplay);
|
||||
elem.addEventListener('playing', testAutoplay);
|
||||
|
||||
try {
|
||||
elem.src = 'data:video/mp4;base64,AAAAHGZ0eXBtcDQyAAAAAG1wNDJpc29tYXZjMQAAAz5tb292AAAAbG12aGQAAAAAzaNacc2jWnEAAV+QAAFfkAABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAGGlvZHMAAAAAEICAgAcAT////3//AAACQ3RyYWsAAABcdGtoZAAAAAHNo1pxzaNacQAAAAEAAAAAAAFfkAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAEAAAABAAAAAAAd9tZGlhAAAAIG1kaGQAAAAAzaNacc2jWnEAAV+QAAFfkFXEAAAAAAAhaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAAAAAAGWbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAABVnN0YmwAAACpc3RzZAAAAAAAAAABAAAAmWF2YzEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAEAAQAEgAAABIAAAAAAAAAAEOSlZUL0FWQyBDb2RpbmcAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAxYXZjQwH0AAr/4QAZZ/QACq609NQYBBkAAAMAAQAAAwAKjxImoAEABWjOAa8gAAAAEmNvbHJuY2xjAAYAAQAGAAAAGHN0dHMAAAAAAAAAAQAAAAUAAEZQAAAAKHN0c3oAAAAAAAAAAAAAAAUAAAIqAAAACAAAAAgAAAAIAAAACAAAAChzdHNjAAAAAAAAAAIAAAABAAAABAAAAAEAAAACAAAAAQAAAAEAAAAYc3RjbwAAAAAAAAACAAADYgAABaQAAAAUc3RzcwAAAAAAAAABAAAAAQAAABFzZHRwAAAAAAREREREAAAAb3VkdGEAAABnbWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcgAAAAAAAAAAAAAAAAAAAAA6aWxzdAAAADKpdG9vAAAAKmRhdGEAAAABAAAAAEhhbmRCcmFrZSAwLjkuOCAyMDEyMDcxODAwAAACUm1kYXQAAAHkBgX/4NxF6b3m2Ui3lizYINkj7u94MjY0IC0gY29yZSAxMjAgLSBILjI2NC9NUEVHLTQgQVZDIGNvZGVjIC0gQ29weWxlZnQgMjAwMy0yMDExIC0gaHR0cDovL3d3dy52aWRlb2xhbi5vcmcveDI2NC5odG1sIC0gb3B0aW9uczogY2FiYWM9MCByZWY9MSBkZWJsb2NrPTE6MDowIGFuYWx5c2U9MHgxOjAgbWU9ZXNhIHN1Ym1lPTkgcHN5PTAgbWl4ZWRfcmVmPTAgbWVfcmFuZ2U9NCBjaHJvbWFfbWU9MSB0cmVsbGlzPTAgOHg4ZGN0PTAgY3FtPTAgZGVhZHpvbmU9MjEsMTEgZmFzdF9wc2tpcD0wIGNocm9tYV9xcF9vZmZzZXQ9MCB0aHJlYWRzPTYgc2xpY2VkX3RocmVhZHM9MCBucj0wIGRlY2ltYXRlPTEgaW50ZXJsYWNlZD0wIGJsdXJheV9jb21wYXQ9MCBjb25zdHJhaW5lZF9pbnRyYT0wIGJmcmFtZXM9MCB3ZWlnaHRwPTAga2V5aW50PTUwIGtleWludF9taW49NSBzY2VuZWN1dD00MCBpbnRyYV9yZWZyZXNoPTAgcmM9Y3FwIG1idHJlZT0wIHFwPTAAgAAAAD5liISscR8A+E4ACAACFoAAITAAAgsAAPgYCoKgoC+L4vi+KAvi+L4YfAEAACMzgABF9AAEUGUgABDJiXnf4AAAAARBmiKUAAAABEGaQpQAAAAEQZpilAAAAARBmoKU';
|
||||
var promise = elem.play();
|
||||
if (promise && promise.catch) {
|
||||
promise.catch(reject);
|
||||
}
|
||||
|
||||
timeout = setTimeout(testAutoplay, 500);
|
||||
}
|
||||
|
||||
catch (e) {
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
supportsHtmlMediaAutoplay: supportsHtmlMediaAutoplay
|
||||
}
|
||||
};
|
||||
});
|
|
@ -1,63 +1,165 @@
|
|||
define(["events", "playbackManager", "dom", "browser", "css!./iconosd", "material-icons"], function(events, playbackManager, dom, browser) {
|
||||
"use strict";
|
||||
define(['events', 'playbackManager', 'dom', 'browser', 'css!./iconosd', 'material-icons'], function (events, playbackManager, dom, browser) {
|
||||
'use strict';
|
||||
|
||||
var currentPlayer;
|
||||
var osdElement;
|
||||
var iconElement;
|
||||
var progressElement;
|
||||
|
||||
var enableAnimation;
|
||||
|
||||
function getOsdElementHtml() {
|
||||
var html = "";
|
||||
return html += '<i class="md-icon iconOsdIcon"></i>', html += '<div class="iconOsdProgressOuter"><div class="iconOsdProgressInner brightnessOsdProgressInner"></div></div>'
|
||||
var html = '';
|
||||
|
||||
html += '<i class="md-icon iconOsdIcon"></i>';
|
||||
|
||||
html += '<div class="iconOsdProgressOuter"><div class="iconOsdProgressInner brightnessOsdProgressInner"></div></div>';
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function ensureOsdElement() {
|
||||
|
||||
var elem = osdElement;
|
||||
elem || (enableAnimation = browser.supportsCssAnimation(), elem = document.createElement("div"), elem.classList.add("hide"), elem.classList.add("iconOsd"), elem.classList.add("iconOsd-hidden"), elem.classList.add("brightnessOsd"), elem.innerHTML = getOsdElementHtml(), iconElement = elem.querySelector("i"), progressElement = elem.querySelector(".iconOsdProgressInner"), document.body.appendChild(elem), osdElement = elem)
|
||||
if (!elem) {
|
||||
|
||||
enableAnimation = browser.supportsCssAnimation();
|
||||
|
||||
elem = document.createElement('div');
|
||||
elem.classList.add('hide');
|
||||
elem.classList.add('iconOsd');
|
||||
elem.classList.add('iconOsd-hidden');
|
||||
elem.classList.add('brightnessOsd');
|
||||
elem.innerHTML = getOsdElementHtml();
|
||||
|
||||
iconElement = elem.querySelector('i');
|
||||
progressElement = elem.querySelector('.iconOsdProgressInner');
|
||||
|
||||
document.body.appendChild(elem);
|
||||
osdElement = elem;
|
||||
}
|
||||
}
|
||||
|
||||
function onHideComplete() {
|
||||
this.classList.add("hide")
|
||||
this.classList.add('hide');
|
||||
}
|
||||
|
||||
var hideTimeout;
|
||||
function showOsd() {
|
||||
|
||||
clearHideTimeout();
|
||||
|
||||
var elem = osdElement;
|
||||
|
||||
dom.removeEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
|
||||
once: !0
|
||||
}), elem.classList.remove("hide"), elem.offsetWidth, requestAnimationFrame(function() {
|
||||
elem.classList.remove("iconOsd-hidden"), hideTimeout = setTimeout(hideOsd, 3e3)
|
||||
})
|
||||
once: true
|
||||
});
|
||||
|
||||
elem.classList.remove('hide');
|
||||
|
||||
// trigger reflow
|
||||
void elem.offsetWidth;
|
||||
|
||||
requestAnimationFrame(function () {
|
||||
elem.classList.remove('iconOsd-hidden');
|
||||
|
||||
hideTimeout = setTimeout(hideOsd, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
function clearHideTimeout() {
|
||||
hideTimeout && (clearTimeout(hideTimeout), hideTimeout = null)
|
||||
if (hideTimeout) {
|
||||
clearTimeout(hideTimeout);
|
||||
hideTimeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
function hideOsd() {
|
||||
|
||||
clearHideTimeout();
|
||||
|
||||
var elem = osdElement;
|
||||
elem && (enableAnimation ? (elem.offsetWidth, requestAnimationFrame(function() {
|
||||
elem.classList.add("iconOsd-hidden"), dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
|
||||
once: !0
|
||||
})
|
||||
})) : onHideComplete.call(elem))
|
||||
if (elem) {
|
||||
|
||||
if (enableAnimation) {
|
||||
// trigger reflow
|
||||
void elem.offsetWidth;
|
||||
|
||||
requestAnimationFrame(function () {
|
||||
elem.classList.add('iconOsd-hidden');
|
||||
|
||||
dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
|
||||
once: true
|
||||
});
|
||||
});
|
||||
} else {
|
||||
onHideComplete.call(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateElementsFromPlayer(brightness) {
|
||||
iconElement && (iconElement.innerHTML = brightness >= 80 ? "" : brightness >= 20 ? "" : ""), progressElement && (progressElement.style.width = (brightness || 0) + "%")
|
||||
|
||||
if (iconElement) {
|
||||
if (brightness >= 80) {
|
||||
iconElement.innerHTML = '';
|
||||
}
|
||||
else if (brightness >= 20) {
|
||||
iconElement.innerHTML = '';
|
||||
} else {
|
||||
iconElement.innerHTML = '';
|
||||
}
|
||||
}
|
||||
if (progressElement) {
|
||||
progressElement.style.width = (brightness || 0) + '%';
|
||||
}
|
||||
}
|
||||
|
||||
function releaseCurrentPlayer() {
|
||||
|
||||
var player = currentPlayer;
|
||||
player && (events.off(player, "brightnesschange", onBrightnessChanged), events.off(player, "playbackstop", hideOsd), currentPlayer = null)
|
||||
|
||||
if (player) {
|
||||
events.off(player, 'brightnesschange', onBrightnessChanged);
|
||||
events.off(player, 'playbackstop', hideOsd);
|
||||
currentPlayer = null;
|
||||
}
|
||||
}
|
||||
|
||||
function onBrightnessChanged(e) {
|
||||
|
||||
var player = this;
|
||||
ensureOsdElement(), updateElementsFromPlayer(playbackManager.getBrightness(player)), showOsd()
|
||||
|
||||
ensureOsdElement();
|
||||
|
||||
updateElementsFromPlayer(playbackManager.getBrightness(player));
|
||||
|
||||
showOsd();
|
||||
}
|
||||
|
||||
function bindToPlayer(player) {
|
||||
player !== currentPlayer && (releaseCurrentPlayer(), currentPlayer = player, player && (hideOsd(), events.on(player, "brightnesschange", onBrightnessChanged), events.on(player, "playbackstop", hideOsd)))
|
||||
|
||||
if (player === currentPlayer) {
|
||||
return;
|
||||
}
|
||||
|
||||
releaseCurrentPlayer();
|
||||
|
||||
currentPlayer = player;
|
||||
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
|
||||
hideOsd();
|
||||
events.on(player, 'brightnesschange', onBrightnessChanged);
|
||||
events.on(player, 'playbackstop', hideOsd);
|
||||
}
|
||||
var currentPlayer, osdElement, iconElement, progressElement, enableAnimation, hideTimeout;
|
||||
events.on(playbackManager, "playerchange", function() {
|
||||
bindToPlayer(playbackManager.getCurrentPlayer())
|
||||
}), bindToPlayer(playbackManager.getCurrentPlayer())
|
||||
|
||||
events.on(playbackManager, 'playerchange', function () {
|
||||
bindToPlayer(playbackManager.getCurrentPlayer());
|
||||
});
|
||||
|
||||
bindToPlayer(playbackManager.getCurrentPlayer());
|
||||
|
||||
});
|
|
@ -1,41 +1,97 @@
|
|||
define(["connectionManager", "globalize", "userSettings", "apphost"], function(connectionManager, globalize, userSettings, appHost) {
|
||||
define(['connectionManager', 'globalize', 'userSettings', 'apphost'], function (connectionManager, globalize, userSettings, appHost) {
|
||||
"use strict";
|
||||
|
||||
function getRequirePromise(deps) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
require(deps, resolve);
|
||||
});
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/6117814/get-week-of-year-in-javascript-like-in-php
|
||||
function getWeek(date) {
|
||||
var d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())),
|
||||
dayNum = d.getUTCDay() || 7;
|
||||
var d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
|
||||
var dayNum = d.getUTCDay() || 7;
|
||||
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
|
||||
var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
|
||||
return Math.ceil(((d - yearStart) / 864e5 + 1) / 7)
|
||||
return Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
|
||||
}
|
||||
|
||||
function showMessage(text, userSettingsKey, appHostFeature) {
|
||||
if (appHost.supports(appHostFeature)) return Promise.resolve();
|
||||
var now = new Date;
|
||||
return userSettingsKey += now.getFullYear() + "-w" + getWeek(now), "1" === userSettings.get(userSettingsKey, !1) ? Promise.resolve() : new Promise(function(resolve, reject) {
|
||||
userSettings.set(userSettingsKey, "1", !1), require(["alert"], function(alert) {
|
||||
return alert(text).then(resolve, resolve)
|
||||
})
|
||||
})
|
||||
|
||||
if (appHost.supports(appHostFeature)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
var now = new Date();
|
||||
|
||||
userSettingsKey += now.getFullYear() + '-w' + getWeek(now);
|
||||
|
||||
if (userSettings.get(userSettingsKey, false) === '1') {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
userSettings.set(userSettingsKey, '1', false);
|
||||
|
||||
require(['alert'], function (alert) {
|
||||
|
||||
return alert(text).then(resolve, resolve);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function showBlurayMessage() {
|
||||
return showMessage("Playback of Bluray folders in this app is experimental. Some titles may not work at all. For a better experience, consider converting to mkv video files, or use an Jellyfin app with native Bluray folder support.", "blurayexpirementalinfo", "nativeblurayplayback")
|
||||
|
||||
var message =
|
||||
'Playback of Bluray folders in this app is experimental. Some titles may not work at all. For a better experience, consider converting to mkv video files, or use an Emby app with native Bluray folder support.';
|
||||
return showMessage(message, 'blurayexpirementalinfo', 'nativeblurayplayback');
|
||||
}
|
||||
|
||||
function showDvdMessage() {
|
||||
return showMessage("Playback of Dvd folders in this app is experimental. Some titles may not work at all. For a better experience, consider converting to mkv video files, or use an Jellyfin app with native Dvd folder support.", "dvdexpirementalinfo", "nativedvdplayback")
|
||||
|
||||
var message =
|
||||
'Playback of Dvd folders in this app is experimental. Some titles may not work at all. For a better experience, consider converting to mkv video files, or use an Emby app with native Dvd folder support.';
|
||||
return showMessage(message, 'dvdexpirementalinfo', 'nativedvdplayback');
|
||||
}
|
||||
|
||||
function showIsoMessage() {
|
||||
return showMessage("Playback of ISO files in this app is experimental. Some titles may not work at all. For a better experience, consider converting to mkv video files, or use an Jellyfin app with native ISO support.", "isoexpirementalinfo", "nativeisoplayback")
|
||||
|
||||
var message =
|
||||
'Playback of ISO files in this app is experimental. Some titles may not work at all. For a better experience, consider converting to mkv video files, or use an Emby app with native ISO support.';
|
||||
return showMessage(message, 'isoexpirementalinfo', 'nativeisoplayback');
|
||||
}
|
||||
|
||||
function ExpirementalPlaybackWarnings() {
|
||||
this.name = "Experimental playback warnings", this.type = "preplayintercept", this.id = "expirementalplaybackwarnings"
|
||||
|
||||
this.name = 'Experimental playback warnings';
|
||||
this.type = 'preplayintercept';
|
||||
this.id = 'expirementalplaybackwarnings';
|
||||
}
|
||||
return ExpirementalPlaybackWarnings.prototype.intercept = function(options) {
|
||||
|
||||
ExpirementalPlaybackWarnings.prototype.intercept = function (options) {
|
||||
|
||||
var item = options.item;
|
||||
return item ? "Iso" === item.VideoType ? showIsoMessage() : "BluRay" === item.VideoType ? showBlurayMessage() : "Dvd" === item.VideoType ? showDvdMessage() : Promise.resolve() : Promise.resolve()
|
||||
}, ExpirementalPlaybackWarnings
|
||||
});
|
||||
if (!item) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (item.VideoType === 'Iso') {
|
||||
return showIsoMessage();
|
||||
}
|
||||
|
||||
if (item.VideoType === 'BluRay') {
|
||||
return showBlurayMessage();
|
||||
}
|
||||
|
||||
if (item.VideoType === 'Dvd') {
|
||||
return showDvdMessage();
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
return ExpirementalPlaybackWarnings;
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
.iconOsd {
|
||||
.iconOsd {
|
||||
position: fixed;
|
||||
top: 7%;
|
||||
right: 3%;
|
||||
|
@ -8,38 +8,33 @@
|
|||
padding: 1em;
|
||||
color: #fff;
|
||||
backdrop-filter: blur(5px);
|
||||
-webkit-border-radius: .25em;
|
||||
border-radius: .25em;
|
||||
-webkit-transition: opacity .2s ease-out;
|
||||
-o-transition: opacity .2s ease-out;
|
||||
transition: opacity .2s ease-out
|
||||
transition: opacity 200ms ease-out;
|
||||
}
|
||||
|
||||
.iconOsd-hidden {
|
||||
opacity: 0
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.iconOsdIcon {
|
||||
font-size: 320%;
|
||||
display: block;
|
||||
margin: .25em .7em
|
||||
margin: .25em .7em;
|
||||
}
|
||||
|
||||
.iconOsdProgressOuter {
|
||||
margin: 1.5em .25em 1em;
|
||||
height: .35em;
|
||||
background: #222;
|
||||
-webkit-border-radius: .25em;
|
||||
border-radius: .25em
|
||||
border-radius: .25em;
|
||||
}
|
||||
|
||||
.iconOsdProgressInner {
|
||||
background: #00a4dc;
|
||||
background: #52B54B;
|
||||
height: 100%;
|
||||
-webkit-border-radius: .25em;
|
||||
border-radius: .25em
|
||||
border-radius: .25em;
|
||||
}
|
||||
|
||||
.brightnessOsdProgressInner {
|
||||
background: #FF9800
|
||||
}
|
||||
background: #FF9800;
|
||||
}
|
||||
|
|
|
@ -1,54 +1,136 @@
|
|||
define(["playbackManager", "nowPlayingHelper", "events", "connectionManager"], function(playbackManager, nowPlayingHelper, events, connectionManager) {
|
||||
define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], function (playbackManager, nowPlayingHelper, events, connectionManager) {
|
||||
"use strict";
|
||||
|
||||
// Reports media playback to the device for lock screen control
|
||||
|
||||
var currentPlayer;
|
||||
var lastUpdateTime = 0;
|
||||
|
||||
function seriesImageUrl(item, options) {
|
||||
if ("Episode" !== item.Type) return null;
|
||||
if (options = options || {}, options.type = options.type || "Primary", "Primary" === options.type && item.SeriesPrimaryImageTag) return options.tag = item.SeriesPrimaryImageTag, connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options);
|
||||
if ("Thumb" === options.type) {
|
||||
if (item.SeriesThumbImageTag) return options.tag = item.SeriesThumbImageTag, connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options);
|
||||
if (item.ParentThumbImageTag) return options.tag = item.ParentThumbImageTag, connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.ParentThumbItemId, options)
|
||||
|
||||
if (item.Type !== 'Episode') {
|
||||
return null;
|
||||
}
|
||||
return null
|
||||
|
||||
options = options || {};
|
||||
options.type = options.type || "Primary";
|
||||
|
||||
if (options.type === 'Primary') {
|
||||
|
||||
if (item.SeriesPrimaryImageTag) {
|
||||
|
||||
options.tag = item.SeriesPrimaryImageTag;
|
||||
|
||||
return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.type === 'Thumb') {
|
||||
|
||||
if (item.SeriesThumbImageTag) {
|
||||
|
||||
options.tag = item.SeriesThumbImageTag;
|
||||
|
||||
return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options);
|
||||
}
|
||||
if (item.ParentThumbImageTag) {
|
||||
|
||||
options.tag = item.ParentThumbImageTag;
|
||||
|
||||
return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.ParentThumbItemId, options);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function imageUrl(item, options) {
|
||||
return options = options || {}, options.type = options.type || "Primary", item.ImageTags && item.ImageTags[options.type] ? (options.tag = item.ImageTags[options.type], connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.Id, options)) : item.AlbumId && item.AlbumPrimaryImageTag ? (options.tag = item.AlbumPrimaryImageTag, connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.AlbumId, options)) : null
|
||||
|
||||
options = options || {};
|
||||
options.type = options.type || "Primary";
|
||||
|
||||
if (item.ImageTags && item.ImageTags[options.type]) {
|
||||
|
||||
options.tag = item.ImageTags[options.type];
|
||||
return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.Id, options);
|
||||
}
|
||||
|
||||
if (item.AlbumId && item.AlbumPrimaryImageTag) {
|
||||
|
||||
options.tag = item.AlbumPrimaryImageTag;
|
||||
return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.AlbumId, options);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function pushImageUrl(item, height, list) {
|
||||
|
||||
var imageOptions = {
|
||||
height: height
|
||||
},
|
||||
url = seriesImageUrl(item, imageOptions) || imageUrl(item, imageOptions);
|
||||
url && list.push({
|
||||
src: url,
|
||||
sizes: height + "x" + height
|
||||
})
|
||||
height: height
|
||||
};
|
||||
|
||||
var url = seriesImageUrl(item, imageOptions) || imageUrl(item, imageOptions);
|
||||
if (url) {
|
||||
list.push({ src: url, sizes: height + 'x' + height });
|
||||
}
|
||||
}
|
||||
|
||||
function getImageUrls(item) {
|
||||
|
||||
var list = [];
|
||||
return pushImageUrl(item, 96, list), pushImageUrl(item, 128, list), pushImageUrl(item, 192, list), pushImageUrl(item, 256, list), pushImageUrl(item, 384, list), pushImageUrl(item, 512, list), list
|
||||
|
||||
pushImageUrl(item, 96, list);
|
||||
pushImageUrl(item, 128, list);
|
||||
pushImageUrl(item, 192, list);
|
||||
pushImageUrl(item, 256, list);
|
||||
pushImageUrl(item, 384, list);
|
||||
pushImageUrl(item, 512, list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
function updatePlayerState(player, state, eventName) {
|
||||
|
||||
var item = state.NowPlayingItem;
|
||||
if (!item) return void hideMediaControls();
|
||||
var playState = state.PlayState || {},
|
||||
parts = nowPlayingHelper.getNowPlayingNames(item),
|
||||
artist = 1 === parts.length ? "" : parts[0].text,
|
||||
title = parts[parts.length - 1].text;
|
||||
if ("Video" === item.MediaType && parts.length > 1) {
|
||||
var temp = artist;
|
||||
artist = title, title = temp
|
||||
|
||||
if (!item) {
|
||||
hideMediaControls();
|
||||
return;
|
||||
}
|
||||
|
||||
var playState = state.PlayState || {};
|
||||
|
||||
var parts = nowPlayingHelper.getNowPlayingNames(item);
|
||||
|
||||
var artist = parts.length === 1 ? '' : parts[0].text;
|
||||
var title = parts[parts.length - 1].text;
|
||||
|
||||
var isVideo = item.MediaType === 'Video';
|
||||
|
||||
// Switch these two around for video
|
||||
if (isVideo && parts.length > 1) {
|
||||
var temp = artist;
|
||||
artist = title;
|
||||
title = temp;
|
||||
}
|
||||
|
||||
var albumArtist;
|
||||
item.AlbumArtists && item.AlbumArtists[0] && (albumArtist = item.AlbumArtists[0].Name);
|
||||
var album = item.Album || "",
|
||||
itemId = item.Id,
|
||||
duration = parseInt(item.RunTimeTicks ? item.RunTimeTicks / 1e4 : 0),
|
||||
currentTime = parseInt(playState.PositionTicks ? playState.PositionTicks / 1e4 : 0),
|
||||
isPaused = playState.IsPaused || !1;
|
||||
|
||||
if (item.AlbumArtists && item.AlbumArtists[0]) {
|
||||
albumArtist = item.AlbumArtists[0].Name;
|
||||
}
|
||||
|
||||
var album = item.Album || '';
|
||||
var itemId = item.Id;
|
||||
|
||||
// Convert to ms
|
||||
var duration = parseInt(item.RunTimeTicks ? (item.RunTimeTicks / 10000) : 0);
|
||||
var currentTime = parseInt(playState.PositionTicks ? (playState.PositionTicks / 10000) : 0);
|
||||
|
||||
var isPaused = playState.IsPaused || false;
|
||||
var canSeek = playState.CanSeek || false;
|
||||
|
||||
navigator.mediaSession.metadata = new MediaMetadata({
|
||||
title: title,
|
||||
artist: artist,
|
||||
|
@ -60,58 +142,111 @@ define(["playbackManager", "nowPlayingHelper", "events", "connectionManager"], f
|
|||
paused: isPaused,
|
||||
itemId: itemId,
|
||||
mediaType: item.MediaType
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function onGeneralEvent(e) {
|
||||
|
||||
var player = this;
|
||||
updatePlayerState(player, playbackManager.getPlayerState(player), e.type)
|
||||
var state = playbackManager.getPlayerState(player);
|
||||
|
||||
updatePlayerState(player, state, e.type);
|
||||
}
|
||||
|
||||
function onStateChanged(e, state) {
|
||||
updatePlayerState(this, state, "statechange")
|
||||
|
||||
var player = this;
|
||||
updatePlayerState(player, state, 'statechange');
|
||||
}
|
||||
|
||||
function onPlaybackStart(e, state) {
|
||||
updatePlayerState(this, state, e.type)
|
||||
|
||||
var player = this;
|
||||
|
||||
updatePlayerState(player, state, e.type);
|
||||
}
|
||||
|
||||
function onPlaybackStopped(e, state) {
|
||||
hideMediaControls()
|
||||
|
||||
var player = this;
|
||||
|
||||
hideMediaControls();
|
||||
}
|
||||
|
||||
function releaseCurrentPlayer() {
|
||||
currentPlayer && (events.off(currentPlayer, "playbackstart", onPlaybackStart), events.off(currentPlayer, "playbackstop", onPlaybackStopped), events.off(currentPlayer, "unpause", onGeneralEvent), events.off(currentPlayer, "pause", onGeneralEvent), events.off(currentPlayer, "statechange", onStateChanged), events.off(currentPlayer, "timeupdate", onGeneralEvent), currentPlayer = null, hideMediaControls())
|
||||
}
|
||||
|
||||
function hideMediaControls() {
|
||||
navigator.mediaSession.metadata = null
|
||||
}
|
||||
if (currentPlayer) {
|
||||
|
||||
function bindToPlayer(player) {
|
||||
if (releaseCurrentPlayer(), player) {
|
||||
currentPlayer = player;
|
||||
updatePlayerState(player, playbackManager.getPlayerState(player), "init"), events.on(currentPlayer, "playbackstart", onPlaybackStart), events.on(currentPlayer, "playbackstop", onPlaybackStopped), events.on(currentPlayer, "unpause", onGeneralEvent), events.on(currentPlayer, "pause", onGeneralEvent), events.on(currentPlayer, "statechange", onStateChanged), events.on(currentPlayer, "timeupdate", onGeneralEvent)
|
||||
events.off(currentPlayer, 'playbackstart', onPlaybackStart);
|
||||
events.off(currentPlayer, 'playbackstop', onPlaybackStopped);
|
||||
events.off(currentPlayer, 'unpause', onGeneralEvent);
|
||||
events.off(currentPlayer, 'pause', onGeneralEvent);
|
||||
events.off(currentPlayer, 'statechange', onStateChanged);
|
||||
events.off(currentPlayer, 'timeupdate', onGeneralEvent);
|
||||
|
||||
currentPlayer = null;
|
||||
|
||||
hideMediaControls();
|
||||
}
|
||||
}
|
||||
|
||||
function execute(name) {
|
||||
playbackManager[name](currentPlayer)
|
||||
function hideMediaControls() {
|
||||
navigator.mediaSession.metadata = null;
|
||||
}
|
||||
var currentPlayer;
|
||||
navigator.mediaSession.setActionHandler("previoustrack", function() {
|
||||
execute("previousTrack")
|
||||
}), navigator.mediaSession.setActionHandler("nexttrack", function() {
|
||||
execute("nextTrack")
|
||||
}), navigator.mediaSession.setActionHandler("play", function() {
|
||||
execute("unpause")
|
||||
}), navigator.mediaSession.setActionHandler("pause", function() {
|
||||
execute("pause")
|
||||
}), navigator.mediaSession.setActionHandler("seekbackward", function() {
|
||||
execute("rewind")
|
||||
}), navigator.mediaSession.setActionHandler("seekforward", function() {
|
||||
execute("fastForward")
|
||||
}), events.on(playbackManager, "playerchange", function() {
|
||||
bindToPlayer(playbackManager.getCurrentPlayer())
|
||||
}), bindToPlayer(playbackManager.getCurrentPlayer())
|
||||
|
||||
function bindToPlayer(player) {
|
||||
|
||||
releaseCurrentPlayer();
|
||||
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentPlayer = player;
|
||||
|
||||
var state = playbackManager.getPlayerState(player);
|
||||
updatePlayerState(player, state, 'init');
|
||||
|
||||
events.on(currentPlayer, 'playbackstart', onPlaybackStart);
|
||||
events.on(currentPlayer, 'playbackstop', onPlaybackStopped);
|
||||
events.on(currentPlayer, 'unpause', onGeneralEvent);
|
||||
events.on(currentPlayer, 'pause', onGeneralEvent);
|
||||
events.on(currentPlayer, 'statechange', onStateChanged);
|
||||
events.on(currentPlayer, 'timeupdate', onGeneralEvent);
|
||||
}
|
||||
|
||||
function execute(name) {
|
||||
playbackManager[name](currentPlayer);
|
||||
}
|
||||
|
||||
navigator.mediaSession.setActionHandler('previoustrack', function () {
|
||||
execute('previousTrack');
|
||||
});
|
||||
|
||||
navigator.mediaSession.setActionHandler('nexttrack', function () {
|
||||
execute('nextTrack');
|
||||
});
|
||||
|
||||
navigator.mediaSession.setActionHandler('play', function () {
|
||||
execute('unpause');
|
||||
});
|
||||
|
||||
navigator.mediaSession.setActionHandler('pause', function () {
|
||||
execute('pause');
|
||||
});
|
||||
|
||||
navigator.mediaSession.setActionHandler('seekbackward', function () {
|
||||
execute('rewind');
|
||||
});
|
||||
|
||||
navigator.mediaSession.setActionHandler('seekforward', function () {
|
||||
execute('fastForward');
|
||||
});
|
||||
|
||||
events.on(playbackManager, 'playerchange', function () {
|
||||
|
||||
bindToPlayer(playbackManager.getCurrentPlayer());
|
||||
});
|
||||
|
||||
bindToPlayer(playbackManager.getCurrentPlayer());
|
||||
});
|
|
@ -1,40 +1,88 @@
|
|||
define([], function() {
|
||||
"use strict";
|
||||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function getNowPlayingNames(nowPlayingItem, includeNonNameInfo) {
|
||||
var topItem = nowPlayingItem,
|
||||
bottomItem = null,
|
||||
topText = nowPlayingItem.Name;
|
||||
nowPlayingItem.AlbumId && "Audio" === nowPlayingItem.MediaType && (topItem = {
|
||||
Id: nowPlayingItem.AlbumId,
|
||||
Name: nowPlayingItem.Album,
|
||||
Type: "MusicAlbum",
|
||||
IsFolder: !0
|
||||
}), "Video" === nowPlayingItem.MediaType && (null != nowPlayingItem.IndexNumber && (topText = nowPlayingItem.IndexNumber + " - " + topText), null != nowPlayingItem.ParentIndexNumber && (topText = nowPlayingItem.ParentIndexNumber + "." + topText));
|
||||
var bottomText = "";
|
||||
nowPlayingItem.ArtistItems && nowPlayingItem.ArtistItems.length ? (bottomItem = {
|
||||
Id: nowPlayingItem.ArtistItems[0].Id,
|
||||
Name: nowPlayingItem.ArtistItems[0].Name,
|
||||
Type: "MusicArtist",
|
||||
IsFolder: !0
|
||||
}, bottomText = nowPlayingItem.ArtistItems.map(function(a) {
|
||||
return a.Name
|
||||
}).join(", ")) : nowPlayingItem.Artists && nowPlayingItem.Artists.length ? bottomText = nowPlayingItem.Artists.join(", ") : nowPlayingItem.SeriesName || nowPlayingItem.Album ? (bottomText = topText, topText = nowPlayingItem.SeriesName || nowPlayingItem.Album, bottomItem = topItem, topItem = nowPlayingItem.SeriesId ? {
|
||||
Id: nowPlayingItem.SeriesId,
|
||||
Name: nowPlayingItem.SeriesName,
|
||||
Type: "Series",
|
||||
IsFolder: !0
|
||||
} : null) : nowPlayingItem.ProductionYear && !1 !== includeNonNameInfo && (bottomText = nowPlayingItem.ProductionYear);
|
||||
|
||||
var topItem = nowPlayingItem;
|
||||
var bottomItem = null;
|
||||
var topText = nowPlayingItem.Name;
|
||||
|
||||
if (nowPlayingItem.AlbumId && nowPlayingItem.MediaType === 'Audio') {
|
||||
topItem = {
|
||||
Id: nowPlayingItem.AlbumId,
|
||||
Name: nowPlayingItem.Album,
|
||||
Type: 'MusicAlbum',
|
||||
IsFolder: true
|
||||
};
|
||||
}
|
||||
|
||||
if (nowPlayingItem.MediaType === 'Video') {
|
||||
if (nowPlayingItem.IndexNumber != null) {
|
||||
topText = nowPlayingItem.IndexNumber + " - " + topText;
|
||||
}
|
||||
if (nowPlayingItem.ParentIndexNumber != null) {
|
||||
topText = nowPlayingItem.ParentIndexNumber + "." + topText;
|
||||
}
|
||||
}
|
||||
|
||||
var bottomText = '';
|
||||
|
||||
if (nowPlayingItem.ArtistItems && nowPlayingItem.ArtistItems.length) {
|
||||
|
||||
bottomItem = {
|
||||
Id: nowPlayingItem.ArtistItems[0].Id,
|
||||
Name: nowPlayingItem.ArtistItems[0].Name,
|
||||
Type: 'MusicArtist',
|
||||
IsFolder: true
|
||||
};
|
||||
|
||||
bottomText = nowPlayingItem.ArtistItems.map(function (a) {
|
||||
return a.Name;
|
||||
}).join(', ');
|
||||
|
||||
} else if (nowPlayingItem.Artists && nowPlayingItem.Artists.length) {
|
||||
|
||||
bottomText = nowPlayingItem.Artists.join(', ');
|
||||
}
|
||||
else if (nowPlayingItem.SeriesName || nowPlayingItem.Album) {
|
||||
bottomText = topText;
|
||||
topText = nowPlayingItem.SeriesName || nowPlayingItem.Album;
|
||||
|
||||
bottomItem = topItem;
|
||||
|
||||
if (nowPlayingItem.SeriesId) {
|
||||
topItem = {
|
||||
Id: nowPlayingItem.SeriesId,
|
||||
Name: nowPlayingItem.SeriesName,
|
||||
Type: 'Series',
|
||||
IsFolder: true
|
||||
};
|
||||
} else {
|
||||
topItem = null;
|
||||
}
|
||||
}
|
||||
else if (nowPlayingItem.ProductionYear && includeNonNameInfo !== false) {
|
||||
bottomText = nowPlayingItem.ProductionYear;
|
||||
}
|
||||
|
||||
var list = [];
|
||||
return list.push({
|
||||
|
||||
list.push({
|
||||
text: topText,
|
||||
item: topItem
|
||||
}), bottomText && list.push({
|
||||
text: bottomText,
|
||||
item: bottomItem
|
||||
}), list
|
||||
});
|
||||
|
||||
if (bottomText) {
|
||||
list.push({
|
||||
text: bottomText,
|
||||
item: bottomItem
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
return {
|
||||
getNowPlayingNames: getNowPlayingNames
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,29 +1,56 @@
|
|||
define(["connectionManager", "globalize"], function(connectionManager, globalize) {
|
||||
define(['connectionManager', 'globalize'], function (connectionManager, globalize) {
|
||||
"use strict";
|
||||
|
||||
function getRequirePromise(deps) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
require(deps, resolve)
|
||||
})
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
require(deps, resolve);
|
||||
});
|
||||
}
|
||||
|
||||
function showErrorMessage() {
|
||||
return getRequirePromise(["alert"]).then(function(alert) {
|
||||
return alert(globalize.translate("sharedcomponents#MessagePlayAccessRestricted")).then(function() {
|
||||
return Promise.reject()
|
||||
})
|
||||
})
|
||||
return getRequirePromise(['alert']).then(function (alert) {
|
||||
|
||||
return alert(globalize.translate('sharedcomponents#MessagePlayAccessRestricted')).then(function () {
|
||||
return Promise.reject();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function PlayAccessValidation() {
|
||||
this.name = "Playback validation", this.type = "preplayintercept", this.id = "playaccessvalidation", this.order = -2
|
||||
|
||||
this.name = 'Playback validation';
|
||||
this.type = 'preplayintercept';
|
||||
this.id = 'playaccessvalidation';
|
||||
this.order = -2;
|
||||
}
|
||||
return PlayAccessValidation.prototype.intercept = function(options) {
|
||||
|
||||
PlayAccessValidation.prototype.intercept = function (options) {
|
||||
|
||||
var item = options.item;
|
||||
if (!item) return Promise.resolve();
|
||||
if (!item) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
var serverId = item.ServerId;
|
||||
return serverId ? connectionManager.getApiClient(serverId).getCurrentUser().then(function(user) {
|
||||
return user.Policy.EnableMediaPlayback ? Promise.resolve() : options.fullscreen ? showErrorMessage() : Promise.reject()
|
||||
}) : Promise.resolve()
|
||||
}, PlayAccessValidation
|
||||
if (!serverId) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return connectionManager.getApiClient(serverId).getCurrentUser().then(function (user) {
|
||||
|
||||
if (user.Policy.EnableMediaPlayback) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// reject but don't show an error message
|
||||
if (!options.fullscreen) {
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
return showErrorMessage();
|
||||
});
|
||||
};
|
||||
|
||||
return PlayAccessValidation;
|
||||
});
|
File diff suppressed because it is too large
Load diff
|
@ -1,35 +1,57 @@
|
|||
define(["playbackManager", "layoutManager", "events"], function(playbackManager, layoutManager, events) {
|
||||
define(['playbackManager', 'layoutManager', 'events'], function (playbackManager, layoutManager, events) {
|
||||
"use strict";
|
||||
|
||||
var orientationLocked;
|
||||
|
||||
function onOrientationChangeSuccess() {
|
||||
orientationLocked = !0
|
||||
orientationLocked = true;
|
||||
}
|
||||
|
||||
function onOrientationChangeError(err) {
|
||||
orientationLocked = !1, console.log("error locking orientation: " + err)
|
||||
orientationLocked = false;
|
||||
console.log('error locking orientation: ' + err);
|
||||
}
|
||||
var orientationLocked;
|
||||
events.on(playbackManager, "playbackstart", function(e, player, state) {
|
||||
if (player.isLocalPlayer && !player.isExternalPlayer && playbackManager.isPlayingVideo(player) && layoutManager.mobile) {
|
||||
var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation || screen.orientation && screen.orientation.lock;
|
||||
if (lockOrientation) try {
|
||||
var promise = lockOrientation("landscape");
|
||||
promise.then ? promise.then(onOrientationChangeSuccess, onOrientationChangeError) : orientationLocked = promise
|
||||
} catch (err) {
|
||||
onOrientationChangeError(err)
|
||||
|
||||
events.on(playbackManager, 'playbackstart', function (e, player, state) {
|
||||
|
||||
var isLocalVideo = player.isLocalPlayer && !player.isExternalPlayer && playbackManager.isPlayingVideo(player);
|
||||
|
||||
if (isLocalVideo && layoutManager.mobile) {
|
||||
var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation || (screen.orientation && screen.orientation.lock);
|
||||
|
||||
if (lockOrientation) {
|
||||
|
||||
try {
|
||||
var promise = lockOrientation('landscape');
|
||||
if (promise.then) {
|
||||
promise.then(onOrientationChangeSuccess, onOrientationChangeError);
|
||||
} else {
|
||||
// returns a boolean
|
||||
orientationLocked = promise;
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
onOrientationChangeError(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}), events.on(playbackManager, "playbackstop", function(e, playbackStopInfo) {
|
||||
});
|
||||
|
||||
events.on(playbackManager, 'playbackstop', function (e, playbackStopInfo) {
|
||||
|
||||
if (orientationLocked && !playbackStopInfo.nextMediaType) {
|
||||
var unlockOrientation = screen.unlockOrientation || screen.mozUnlockOrientation || screen.msUnlockOrientation || screen.orientation && screen.orientation.unlock;
|
||||
|
||||
var unlockOrientation = screen.unlockOrientation || screen.mozUnlockOrientation || screen.msUnlockOrientation || (screen.orientation && screen.orientation.unlock);
|
||||
|
||||
if (unlockOrientation) {
|
||||
try {
|
||||
unlockOrientation()
|
||||
} catch (err) {
|
||||
console.log("error unlocking orientation: " + err)
|
||||
unlockOrientation();
|
||||
}
|
||||
orientationLocked = !1
|
||||
catch (err) {
|
||||
console.log('error unlocking orientation: ' + err);
|
||||
}
|
||||
orientationLocked = false;
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
|
@ -1,43 +1,80 @@
|
|||
define(["playbackManager", "itemHelper"], function(playbackManager, itemHelper) {
|
||||
define(['playbackManager', 'itemHelper'], function (playbackManager, itemHelper) {
|
||||
"use strict";
|
||||
|
||||
function getRequirePromise(deps) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
require(deps, resolve)
|
||||
})
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
require(deps, resolve);
|
||||
});
|
||||
}
|
||||
|
||||
function validatePlayback(options) {
|
||||
var feature = "playback";
|
||||
if (!options.item || "TvChannel" !== options.item.Type && "Recording" !== options.item.Type || (feature = "livetv"), "playback" === feature) {
|
||||
var player = playbackManager.getCurrentPlayer();
|
||||
if (player && !player.isLocalPlayer) return Promise.resolve()
|
||||
|
||||
var feature = 'playback';
|
||||
if (options.item && (options.item.Type === 'TvChannel' || options.item.Type === 'Recording')) {
|
||||
feature = 'livetv';
|
||||
}
|
||||
return getRequirePromise(["registrationServices"]).then(function(registrationServices) {
|
||||
return registrationServices.validateFeature(feature, options).then(function(result) {
|
||||
result && result.enableTimeLimit && startAutoStopTimer()
|
||||
})
|
||||
})
|
||||
|
||||
if (feature === 'playback') {
|
||||
var player = playbackManager.getCurrentPlayer();
|
||||
if (player && !player.isLocalPlayer) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
return getRequirePromise(["registrationServices"]).then(function (registrationServices) {
|
||||
|
||||
return registrationServices.validateFeature(feature, options).then(function (result) {
|
||||
|
||||
if (result && result.enableTimeLimit) {
|
||||
startAutoStopTimer();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var autoStopTimeout;
|
||||
function startAutoStopTimer() {
|
||||
stopAutoStopTimer(), autoStopTimeout = setTimeout(onAutoStopTimeout, 63e3)
|
||||
stopAutoStopTimer();
|
||||
autoStopTimeout = setTimeout(onAutoStopTimeout, 63000);
|
||||
}
|
||||
|
||||
function onAutoStopTimeout() {
|
||||
stopAutoStopTimer(), playbackManager.stop()
|
||||
stopAutoStopTimer();
|
||||
playbackManager.stop();
|
||||
}
|
||||
|
||||
function stopAutoStopTimer() {
|
||||
|
||||
var timeout = autoStopTimeout;
|
||||
timeout && (clearTimeout(timeout), autoStopTimeout = null)
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
autoStopTimeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
function PlaybackValidation() {
|
||||
this.name = "Playback validation", this.type = "preplayintercept", this.id = "playbackvalidation", this.order = -1
|
||||
|
||||
this.name = 'Playback validation';
|
||||
this.type = 'preplayintercept';
|
||||
this.id = 'playbackvalidation';
|
||||
this.order = -1;
|
||||
}
|
||||
var autoStopTimeout;
|
||||
return PlaybackValidation.prototype.intercept = function(options) {
|
||||
return options.fullscreen ? options.item && itemHelper.isLocalItem(options.item) ? Promise.resolve() : validatePlayback(options) : Promise.resolve()
|
||||
}, PlaybackValidation
|
||||
|
||||
PlaybackValidation.prototype.intercept = function (options) {
|
||||
|
||||
// Don't care about video backdrops, or theme music or any kind of non-fullscreen playback
|
||||
if (!options.fullscreen) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (options.item && itemHelper.isLocalItem(options.item)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return validatePlayback(options);
|
||||
};
|
||||
|
||||
return PlaybackValidation;
|
||||
});
|
|
@ -1,158 +1,323 @@
|
|||
define(["appSettings", "events", "browser", "loading", "playbackManager", "appRouter", "globalize", "apphost"], function(appSettings, events, browser, loading, playbackManager, appRouter, globalize, appHost) {
|
||||
"use strict";
|
||||
define(['appSettings', 'events', 'browser', 'loading', 'playbackManager', 'appRouter', 'globalize', 'apphost'], function (appSettings, events, browser, loading, playbackManager, appRouter, globalize, appHost) {
|
||||
'use strict';
|
||||
|
||||
function mirrorItem(info, player) {
|
||||
|
||||
var item = info.item;
|
||||
|
||||
playbackManager.displayContent({
|
||||
|
||||
ItemName: item.Name,
|
||||
ItemId: item.Id,
|
||||
ItemType: item.Type,
|
||||
Context: info.context
|
||||
}, player)
|
||||
}, player);
|
||||
}
|
||||
|
||||
function mirrorIfEnabled(info) {
|
||||
|
||||
if (info && playbackManager.enableDisplayMirroring()) {
|
||||
|
||||
var getPlayerInfo = playbackManager.getPlayerInfo();
|
||||
getPlayerInfo && (getPlayerInfo.isLocalPlayer || -1 === getPlayerInfo.supportedCommands.indexOf("DisplayContent") || mirrorItem(info, playbackManager.getCurrentPlayer()))
|
||||
|
||||
if (getPlayerInfo) {
|
||||
if (!getPlayerInfo.isLocalPlayer && getPlayerInfo.supportedCommands.indexOf('DisplayContent') !== -1) {
|
||||
mirrorItem(info, playbackManager.getCurrentPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emptyCallback() {}
|
||||
function emptyCallback() {
|
||||
// avoid console logs about uncaught promises
|
||||
}
|
||||
|
||||
function getTargetSecondaryText(target) {
|
||||
return target.user ? target.user.Name : null
|
||||
|
||||
if (target.user) {
|
||||
|
||||
return target.user.Name;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getIcon(target) {
|
||||
|
||||
var deviceType = target.deviceType;
|
||||
switch (!deviceType && target.isLocalPlayer && (deviceType = browser.tv ? "tv" : browser.mobile ? "smartphone" : "desktop"), deviceType || (deviceType = "tv"), deviceType) {
|
||||
case "smartphone":
|
||||
return "";
|
||||
case "tablet":
|
||||
return "";
|
||||
case "tv":
|
||||
return "";
|
||||
case "cast":
|
||||
return "";
|
||||
case "desktop":
|
||||
return "";
|
||||
|
||||
if (!deviceType && target.isLocalPlayer) {
|
||||
if (browser.tv) {
|
||||
deviceType = 'tv';
|
||||
} else if (browser.mobile) {
|
||||
deviceType = 'smartphone';
|
||||
} else {
|
||||
deviceType = 'desktop';
|
||||
}
|
||||
}
|
||||
|
||||
if (!deviceType) {
|
||||
deviceType = 'tv';
|
||||
}
|
||||
|
||||
switch (deviceType) {
|
||||
|
||||
case 'smartphone':
|
||||
return '';
|
||||
case 'tablet':
|
||||
return '';
|
||||
case 'tv':
|
||||
return '';
|
||||
case 'cast':
|
||||
return '';
|
||||
case 'desktop':
|
||||
return '';
|
||||
default:
|
||||
return ""
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function showPlayerSelection(button) {
|
||||
|
||||
var currentPlayerInfo = playbackManager.getPlayerInfo();
|
||||
if (currentPlayerInfo && !currentPlayerInfo.isLocalPlayer) return void showActivePlayerMenu(currentPlayerInfo);
|
||||
|
||||
if (currentPlayerInfo) {
|
||||
if (!currentPlayerInfo.isLocalPlayer) {
|
||||
showActivePlayerMenu(currentPlayerInfo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var currentPlayerId = currentPlayerInfo ? currentPlayerInfo.id : null;
|
||||
loading.show(), playbackManager.getTargets().then(function(targets) {
|
||||
var menuItems = targets.map(function(t) {
|
||||
|
||||
loading.show();
|
||||
|
||||
playbackManager.getTargets().then(function (targets) {
|
||||
|
||||
var menuItems = targets.map(function (t) {
|
||||
|
||||
var name = t.name;
|
||||
return t.appName && t.appName !== t.name && (name += " - " + t.appName), {
|
||||
|
||||
if (t.appName && t.appName !== t.name) {
|
||||
name += " - " + t.appName;
|
||||
}
|
||||
|
||||
return {
|
||||
name: name,
|
||||
id: t.id,
|
||||
selected: currentPlayerId === t.id,
|
||||
secondaryText: getTargetSecondaryText(t),
|
||||
icon: getIcon(t)
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
require(["actionsheet"], function(actionsheet) {
|
||||
|
||||
require(['actionsheet'], function (actionsheet) {
|
||||
|
||||
loading.hide();
|
||||
|
||||
var menuOptions = {
|
||||
title: globalize.translate("sharedcomponents#HeaderPlayOn"),
|
||||
title: globalize.translate('sharedcomponents#HeaderPlayOn'),
|
||||
items: menuItems,
|
||||
positionTo: button,
|
||||
resolveOnClick: !0,
|
||||
border: !0
|
||||
|
||||
resolveOnClick: true,
|
||||
border: true
|
||||
};
|
||||
browser.chrome && !appHost.supports("castmenuhashchange") && (menuOptions.enableHistory = !1), actionsheet.show(menuOptions).then(function(id) {
|
||||
var target = targets.filter(function(t) {
|
||||
return t.id === id
|
||||
|
||||
// Unfortunately we can't allow the url to change or chromecast will throw a security error
|
||||
// Might be able to solve this in the future by moving the dialogs to hashbangs
|
||||
if (!(!browser.chrome || appHost.supports('castmenuhashchange'))) {
|
||||
menuOptions.enableHistory = false;
|
||||
}
|
||||
|
||||
actionsheet.show(menuOptions).then(function (id) {
|
||||
|
||||
var target = targets.filter(function (t) {
|
||||
return t.id === id;
|
||||
})[0];
|
||||
playbackManager.trySetActivePlayer(target.playerName, target), mirrorIfEnabled()
|
||||
}, emptyCallback)
|
||||
})
|
||||
})
|
||||
|
||||
playbackManager.trySetActivePlayer(target.playerName, target);
|
||||
|
||||
mirrorIfEnabled();
|
||||
|
||||
}, emptyCallback);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function showActivePlayerMenu(playerInfo) {
|
||||
require(["dialogHelper", "dialog", "emby-checkbox", "emby-button"], function(dialogHelper) {
|
||||
showActivePlayerMenuInternal(dialogHelper, playerInfo)
|
||||
})
|
||||
|
||||
require(['dialogHelper', 'dialog', 'emby-checkbox', 'emby-button'], function (dialogHelper) {
|
||||
showActivePlayerMenuInternal(dialogHelper, playerInfo);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function disconnectFromPlayer(currentDeviceName) {
|
||||
-1 !== playbackManager.getSupportedCommands().indexOf("EndSession") ? require(["dialog"], function(dialog) {
|
||||
var menuItems = [];
|
||||
menuItems.push({
|
||||
name: globalize.translate("sharedcomponents#Yes"),
|
||||
id: "yes"
|
||||
}), menuItems.push({
|
||||
name: globalize.translate("sharedcomponents#No"),
|
||||
id: "no"
|
||||
}), dialog({
|
||||
buttons: menuItems,
|
||||
text: globalize.translate("sharedcomponents#ConfirmEndPlayerSession", currentDeviceName)
|
||||
}).then(function(id) {
|
||||
switch (id) {
|
||||
case "yes":
|
||||
playbackManager.getCurrentPlayer().endSession(), playbackManager.setDefaultPlayerActive();
|
||||
break;
|
||||
case "no":
|
||||
playbackManager.setDefaultPlayerActive()
|
||||
}
|
||||
})
|
||||
}) : playbackManager.setDefaultPlayerActive()
|
||||
|
||||
if (playbackManager.getSupportedCommands().indexOf('EndSession') !== -1) {
|
||||
|
||||
require(['dialog'], function (dialog) {
|
||||
|
||||
var menuItems = [];
|
||||
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#Yes'),
|
||||
id: 'yes'
|
||||
});
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#No'),
|
||||
id: 'no'
|
||||
});
|
||||
|
||||
dialog({
|
||||
buttons: menuItems,
|
||||
//positionTo: positionTo,
|
||||
text: globalize.translate('sharedcomponents#ConfirmEndPlayerSession', currentDeviceName)
|
||||
|
||||
}).then(function (id) {
|
||||
switch (id) {
|
||||
|
||||
case 'yes':
|
||||
playbackManager.getCurrentPlayer().endSession();
|
||||
playbackManager.setDefaultPlayerActive();
|
||||
break;
|
||||
case 'no':
|
||||
playbackManager.setDefaultPlayerActive();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
playbackManager.setDefaultPlayerActive();
|
||||
}
|
||||
}
|
||||
|
||||
function showActivePlayerMenuInternal(dialogHelper, playerInfo) {
|
||||
var html = "",
|
||||
dialogOptions = {
|
||||
removeOnClose: !0
|
||||
};
|
||||
dialogOptions.modal = !1, dialogOptions.entryAnimationDuration = 160, dialogOptions.exitAnimationDuration = 160, dialogOptions.autoFocus = !1;
|
||||
|
||||
var html = '';
|
||||
|
||||
var dialogOptions = {
|
||||
removeOnClose: true
|
||||
};
|
||||
|
||||
dialogOptions.modal = false;
|
||||
dialogOptions.entryAnimationDuration = 160;
|
||||
dialogOptions.exitAnimationDuration = 160;
|
||||
dialogOptions.autoFocus = false;
|
||||
|
||||
var dlg = dialogHelper.createDialog(dialogOptions);
|
||||
dlg.classList.add("promptDialog");
|
||||
var currentDeviceName = playerInfo.deviceName || playerInfo.name;
|
||||
if (html += '<div class="promptDialogContent" style="padding:1.5em;">', html += '<h2 style="margin-top:.5em;">', html += currentDeviceName, html += "</h2>", html += "<div>", -1 !== playerInfo.supportedCommands.indexOf("DisplayContent")) {
|
||||
|
||||
dlg.classList.add('promptDialog');
|
||||
|
||||
var currentDeviceName = (playerInfo.deviceName || playerInfo.name);
|
||||
|
||||
html += '<div class="promptDialogContent" style="padding:1.5em;">';
|
||||
html += '<h2 style="margin-top:.5em;">';
|
||||
html += currentDeviceName;
|
||||
html += '</h2>';
|
||||
|
||||
html += '<div>';
|
||||
|
||||
if (playerInfo.supportedCommands.indexOf('DisplayContent') !== -1) {
|
||||
|
||||
html += '<label class="checkboxContainer">';
|
||||
html += '<input type="checkbox" is="emby-checkbox" class="chkMirror"' + (playbackManager.enableDisplayMirroring() ? " checked" : "") + "/>", html += "<span>" + globalize.translate("sharedcomponents#EnableDisplayMirroring") + "</span>", html += "</label>"
|
||||
var checkedHtml = playbackManager.enableDisplayMirroring() ? ' checked' : '';
|
||||
html += '<input type="checkbox" is="emby-checkbox" class="chkMirror"' + checkedHtml + '/>';
|
||||
html += '<span>' + globalize.translate('sharedcomponents#EnableDisplayMirroring') + '</span>';
|
||||
html += '</label>';
|
||||
}
|
||||
html += "</div>", html += '<div style="margin-top:1em;display:flex;justify-content: flex-end;">', html += '<button is="emby-button" type="button" class="button-flat btnRemoteControl promptDialogButton">' + globalize.translate("sharedcomponents#HeaderRemoteControl") + "</button>", html += '<button is="emby-button" type="button" class="button-flat btnDisconnect promptDialogButton ">' + globalize.translate("sharedcomponents#Disconnect") + "</button>", html += '<button is="emby-button" type="button" class="button-flat btnCancel promptDialogButton">' + globalize.translate("sharedcomponents#ButtonCancel") + "</button>", html += "</div>", html += "</div>", dlg.innerHTML = html;
|
||||
var chkMirror = dlg.querySelector(".chkMirror");
|
||||
chkMirror && chkMirror.addEventListener("change", onMirrorChange);
|
||||
var destination = "",
|
||||
btnRemoteControl = dlg.querySelector(".btnRemoteControl");
|
||||
btnRemoteControl && btnRemoteControl.addEventListener("click", function() {
|
||||
destination = "nowplaying", dialogHelper.close(dlg)
|
||||
}), dlg.querySelector(".btnDisconnect").addEventListener("click", function() {
|
||||
destination = "disconnectFromPlayer", dialogHelper.close(dlg)
|
||||
}), dlg.querySelector(".btnCancel").addEventListener("click", function() {
|
||||
dialogHelper.close(dlg)
|
||||
}), dialogHelper.open(dlg).then(function() {
|
||||
"nowplaying" === destination ? appRouter.showNowPlaying() : "disconnectFromPlayer" === destination && disconnectFromPlayer(currentDeviceName)
|
||||
}, emptyCallback)
|
||||
|
||||
html += '</div>';
|
||||
|
||||
html += '<div style="margin-top:1em;display:flex;justify-content: flex-end;">';
|
||||
|
||||
html += '<button is="emby-button" type="button" class="button-flat btnRemoteControl promptDialogButton">' + globalize.translate('sharedcomponents#HeaderRemoteControl') + '</button>';
|
||||
html += '<button is="emby-button" type="button" class="button-flat btnDisconnect promptDialogButton ">' + globalize.translate('sharedcomponents#Disconnect') + '</button>';
|
||||
html += '<button is="emby-button" type="button" class="button-flat btnCancel promptDialogButton">' + globalize.translate('sharedcomponents#ButtonCancel') + '</button>';
|
||||
html += '</div>';
|
||||
|
||||
html += '</div>';
|
||||
dlg.innerHTML = html;
|
||||
|
||||
var chkMirror = dlg.querySelector('.chkMirror');
|
||||
|
||||
if (chkMirror) {
|
||||
chkMirror.addEventListener('change', onMirrorChange);
|
||||
}
|
||||
|
||||
var destination = '';
|
||||
|
||||
var btnRemoteControl = dlg.querySelector('.btnRemoteControl');
|
||||
if (btnRemoteControl) {
|
||||
btnRemoteControl.addEventListener('click', function () {
|
||||
destination = 'nowplaying';
|
||||
dialogHelper.close(dlg);
|
||||
});
|
||||
}
|
||||
|
||||
dlg.querySelector('.btnDisconnect').addEventListener('click', function () {
|
||||
destination = 'disconnectFromPlayer';
|
||||
dialogHelper.close(dlg);
|
||||
});
|
||||
|
||||
dlg.querySelector('.btnCancel').addEventListener('click', function () {
|
||||
dialogHelper.close(dlg);
|
||||
});
|
||||
|
||||
dialogHelper.open(dlg).then(function () {
|
||||
if (destination === 'nowplaying') {
|
||||
appRouter.showNowPlaying();
|
||||
}
|
||||
else if (destination === 'disconnectFromPlayer') {
|
||||
disconnectFromPlayer(currentDeviceName);
|
||||
}
|
||||
}, emptyCallback);
|
||||
}
|
||||
|
||||
function onMirrorChange() {
|
||||
playbackManager.enableDisplayMirroring(this.checked)
|
||||
playbackManager.enableDisplayMirroring(this.checked);
|
||||
}
|
||||
return document.addEventListener("viewshow", function(e) {
|
||||
var state = e.detail.state || {},
|
||||
item = state.item;
|
||||
if (item && item.ServerId) return void mirrorIfEnabled({
|
||||
item: item
|
||||
})
|
||||
}), events.on(appSettings, "change", function(e, name) {
|
||||
"displaymirror" === name && mirrorIfEnabled()
|
||||
}), events.on(playbackManager, "pairing", function(e) {
|
||||
loading.show()
|
||||
}), events.on(playbackManager, "paired", function(e) {
|
||||
loading.hide()
|
||||
}), events.on(playbackManager, "pairerror", function(e) {
|
||||
loading.hide()
|
||||
}), {
|
||||
|
||||
document.addEventListener('viewshow', function (e) {
|
||||
|
||||
var state = e.detail.state || {};
|
||||
var item = state.item;
|
||||
|
||||
if (item && item.ServerId) {
|
||||
mirrorIfEnabled({
|
||||
item: item
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
events.on(appSettings, 'change', function (e, name) {
|
||||
if (name === 'displaymirror') {
|
||||
mirrorIfEnabled();
|
||||
}
|
||||
});
|
||||
|
||||
events.on(playbackManager, 'pairing', function (e) {
|
||||
loading.show();
|
||||
});
|
||||
|
||||
events.on(playbackManager, 'paired', function (e) {
|
||||
loading.hide();
|
||||
});
|
||||
|
||||
events.on(playbackManager, 'pairerror', function (e) {
|
||||
loading.hide();
|
||||
});
|
||||
|
||||
return {
|
||||
show: showPlayerSelection
|
||||
}
|
||||
};
|
||||
});
|
|
@ -1,195 +1,315 @@
|
|||
define(["connectionManager", "actionsheet", "datetime", "playbackManager", "globalize", "appSettings", "qualityoptions"], function(connectionManager, actionsheet, datetime, playbackManager, globalize, appSettings, qualityoptions) {
|
||||
"use strict";
|
||||
define(['connectionManager', 'actionsheet', 'datetime', 'playbackManager', 'globalize', 'appSettings', 'qualityoptions'], function (connectionManager, actionsheet, datetime, playbackManager, globalize, appSettings, qualityoptions) {
|
||||
'use strict';
|
||||
|
||||
function showQualityMenu(player, btn) {
|
||||
var videoStream = playbackManager.currentMediaSource(player).MediaStreams.filter(function(stream) {
|
||||
return "Video" === stream.Type
|
||||
})[0],
|
||||
videoWidth = videoStream ? videoStream.Width : null,
|
||||
options = qualityoptions.getVideoQualityOptions({
|
||||
currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player),
|
||||
isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player),
|
||||
videoWidth: videoWidth,
|
||||
enableAuto: !0
|
||||
}),
|
||||
menuItems = options.map(function(o) {
|
||||
var opt = {
|
||||
name: o.name,
|
||||
id: o.bitrate,
|
||||
asideText: o.secondaryText
|
||||
};
|
||||
return o.selected && (opt.selected = !0), opt
|
||||
}),
|
||||
selectedId = options.filter(function(o) {
|
||||
return o.selected
|
||||
});
|
||||
return selectedId = selectedId.length ? selectedId[0].bitrate : null, actionsheet.show({
|
||||
items: menuItems,
|
||||
positionTo: btn
|
||||
}).then(function(id) {
|
||||
var bitrate = parseInt(id);
|
||||
bitrate !== selectedId && playbackManager.setMaxStreamingBitrate({
|
||||
enableAutomaticBitrateDetection: !bitrate,
|
||||
maxBitrate: bitrate
|
||||
}, player)
|
||||
})
|
||||
}
|
||||
|
||||
function showRepeatModeMenu(player, btn) {
|
||||
var menuItems = [],
|
||||
currentValue = playbackManager.getRepeatMode(player);
|
||||
return menuItems.push({
|
||||
name: globalize.translate("sharedcomponents#RepeatAll"),
|
||||
id: "RepeatAll",
|
||||
selected: "RepeatAll" === currentValue
|
||||
}), menuItems.push({
|
||||
name: globalize.translate("sharedcomponents#RepeatOne"),
|
||||
id: "RepeatOne",
|
||||
selected: "RepeatOne" === currentValue
|
||||
}), menuItems.push({
|
||||
name: globalize.translate("sharedcomponents#None"),
|
||||
id: "RepeatNone",
|
||||
selected: "RepeatNone" === currentValue
|
||||
}), actionsheet.show({
|
||||
items: menuItems,
|
||||
positionTo: btn
|
||||
}).then(function(mode) {
|
||||
mode && playbackManager.setRepeatMode(mode, player)
|
||||
})
|
||||
}
|
||||
var videoStream = playbackManager.currentMediaSource(player).MediaStreams.filter(function (stream) {
|
||||
return stream.Type === "Video";
|
||||
})[0];
|
||||
var videoWidth = videoStream ? videoStream.Width : null;
|
||||
|
||||
function getQualitySecondaryText(player) {
|
||||
var state = playbackManager.getPlayerState(player),
|
||||
videoStream = (playbackManager.enableAutomaticBitrateDetection(player), playbackManager.getMaxStreamingBitrate(player), playbackManager.currentMediaSource(player).MediaStreams.filter(function(stream) {
|
||||
return "Video" === stream.Type
|
||||
})[0]),
|
||||
videoWidth = videoStream ? videoStream.Width : null,
|
||||
options = qualityoptions.getVideoQualityOptions({
|
||||
currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player),
|
||||
isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player),
|
||||
videoWidth: videoWidth,
|
||||
enableAuto: !0
|
||||
}),
|
||||
selectedOption = (options.map(function(o) {
|
||||
var opt = {
|
||||
name: o.name,
|
||||
id: o.bitrate,
|
||||
asideText: o.secondaryText
|
||||
};
|
||||
return o.selected && (opt.selected = !0), opt
|
||||
}), options.filter(function(o) {
|
||||
return o.selected
|
||||
}));
|
||||
if (!selectedOption.length) return null;
|
||||
selectedOption = selectedOption[0];
|
||||
var text = selectedOption.name;
|
||||
return selectedOption.autoText && (state.PlayState && "Transcode" !== state.PlayState.PlayMethod ? text += " - Direct" : text += " " + selectedOption.autoText), text
|
||||
}
|
||||
var options = qualityoptions.getVideoQualityOptions({
|
||||
currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player),
|
||||
isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player),
|
||||
videoWidth: videoWidth,
|
||||
enableAuto: true
|
||||
});
|
||||
|
||||
var menuItems = options.map(function (o) {
|
||||
|
||||
var opt = {
|
||||
name: o.name,
|
||||
id: o.bitrate,
|
||||
asideText: o.secondaryText
|
||||
};
|
||||
|
||||
if (o.selected) {
|
||||
opt.selected = true;
|
||||
}
|
||||
|
||||
return opt;
|
||||
});
|
||||
|
||||
var selectedId = options.filter(function (o) {
|
||||
return o.selected;
|
||||
});
|
||||
|
||||
selectedId = selectedId.length ? selectedId[0].bitrate : null;
|
||||
|
||||
function showAspectRatioMenu(player, btn) {
|
||||
var currentId = playbackManager.getAspectRatio(player),
|
||||
menuItems = playbackManager.getSupportedAspectRatios(player).map(function(i) {
|
||||
return {
|
||||
id: i.id,
|
||||
name: i.name,
|
||||
selected: i.id === currentId
|
||||
}
|
||||
});
|
||||
return actionsheet.show({
|
||||
items: menuItems,
|
||||
positionTo: btn
|
||||
}).then(function(id) {
|
||||
return id ? (playbackManager.setAspectRatio(id, player), Promise.resolve()) : Promise.reject()
|
||||
})
|
||||
|
||||
}).then(function (id) {
|
||||
var bitrate = parseInt(id);
|
||||
if (bitrate !== selectedId) {
|
||||
|
||||
playbackManager.setMaxStreamingBitrate({
|
||||
|
||||
enableAutomaticBitrateDetection: bitrate ? false : true,
|
||||
maxBitrate: bitrate
|
||||
|
||||
}, player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showRepeatModeMenu(player, btn) {
|
||||
|
||||
var menuItems = [];
|
||||
|
||||
var currentValue = playbackManager.getRepeatMode(player);
|
||||
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#RepeatAll'),
|
||||
id: 'RepeatAll',
|
||||
selected: currentValue === 'RepeatAll'
|
||||
});
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#RepeatOne'),
|
||||
id: 'RepeatOne',
|
||||
selected: currentValue === 'RepeatOne'
|
||||
});
|
||||
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#None'),
|
||||
id: 'RepeatNone',
|
||||
selected: currentValue === 'RepeatNone'
|
||||
});
|
||||
|
||||
return actionsheet.show({
|
||||
items: menuItems,
|
||||
positionTo: btn
|
||||
|
||||
}).then(function (mode) {
|
||||
|
||||
if (mode) {
|
||||
playbackManager.setRepeatMode(mode, player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getQualitySecondaryText(player) {
|
||||
|
||||
var state = playbackManager.getPlayerState(player);
|
||||
|
||||
var isAutoEnabled = playbackManager.enableAutomaticBitrateDetection(player);
|
||||
var currentMaxBitrate = playbackManager.getMaxStreamingBitrate(player);
|
||||
|
||||
var videoStream = playbackManager.currentMediaSource(player).MediaStreams.filter(function (stream) {
|
||||
return stream.Type === "Video";
|
||||
})[0];
|
||||
var videoWidth = videoStream ? videoStream.Width : null;
|
||||
|
||||
var options = qualityoptions.getVideoQualityOptions({
|
||||
currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player),
|
||||
isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player),
|
||||
videoWidth: videoWidth,
|
||||
enableAuto: true
|
||||
});
|
||||
|
||||
var menuItems = options.map(function (o) {
|
||||
|
||||
var opt = {
|
||||
name: o.name,
|
||||
id: o.bitrate,
|
||||
asideText: o.secondaryText
|
||||
};
|
||||
|
||||
if (o.selected) {
|
||||
opt.selected = true;
|
||||
}
|
||||
|
||||
return opt;
|
||||
});
|
||||
|
||||
var selectedOption = options.filter(function (o) {
|
||||
return o.selected;
|
||||
});
|
||||
|
||||
if (!selectedOption.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
selectedOption = selectedOption[0];
|
||||
|
||||
var text = selectedOption.name;
|
||||
|
||||
if (selectedOption.autoText) {
|
||||
if (state.PlayState && state.PlayState.PlayMethod !== 'Transcode') {
|
||||
text += ' - Direct';
|
||||
} else {
|
||||
text += ' ' + selectedOption.autoText;
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
function showAspectRatioMenu(player, btn) {
|
||||
|
||||
// Each has name/id
|
||||
var currentId = playbackManager.getAspectRatio(player);
|
||||
var menuItems = playbackManager.getSupportedAspectRatios(player).map(function (i) {
|
||||
return {
|
||||
id: i.id,
|
||||
name: i.name,
|
||||
selected: i.id === currentId
|
||||
};
|
||||
});
|
||||
|
||||
return actionsheet.show({
|
||||
|
||||
items: menuItems,
|
||||
positionTo: btn
|
||||
|
||||
}).then(function (id) {
|
||||
|
||||
if (id) {
|
||||
playbackManager.setAspectRatio(id, player);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return Promise.reject();
|
||||
});
|
||||
}
|
||||
|
||||
function showWithUser(options, player, user) {
|
||||
var supportedCommands = playbackManager.getSupportedCommands(player),
|
||||
menuItems = (options.mediaType, []);
|
||||
if (-1 !== supportedCommands.indexOf("SetAspectRatio")) {
|
||||
var currentAspectRatioId = playbackManager.getAspectRatio(player),
|
||||
currentAspectRatio = playbackManager.getSupportedAspectRatios(player).filter(function(i) {
|
||||
return i.id === currentAspectRatioId
|
||||
})[0];
|
||||
|
||||
var supportedCommands = playbackManager.getSupportedCommands(player);
|
||||
|
||||
var mediaType = options.mediaType;
|
||||
|
||||
var menuItems = [];
|
||||
|
||||
if (supportedCommands.indexOf('SetAspectRatio') !== -1) {
|
||||
|
||||
var currentAspectRatioId = playbackManager.getAspectRatio(player);
|
||||
var currentAspectRatio = playbackManager.getSupportedAspectRatios(player).filter(function (i) {
|
||||
return i.id === currentAspectRatioId;
|
||||
})[0];
|
||||
|
||||
menuItems.push({
|
||||
name: globalize.translate("sharedcomponents#AspectRatio"),
|
||||
id: "aspectratio",
|
||||
name: globalize.translate('sharedcomponents#AspectRatio'),
|
||||
id: 'aspectratio',
|
||||
asideText: currentAspectRatio ? currentAspectRatio.name : null
|
||||
})
|
||||
});
|
||||
}
|
||||
if (menuItems.push({
|
||||
name: globalize.translate("sharedcomponents#PlaybackSettings"),
|
||||
id: "playbacksettings"
|
||||
}), user && user.Policy.EnableVideoPlaybackTranscoding) {
|
||||
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#PlaybackSettings'),
|
||||
id: 'playbacksettings'
|
||||
});
|
||||
|
||||
if (user && user.Policy.EnableVideoPlaybackTranscoding) {
|
||||
var secondaryQualityText = getQualitySecondaryText(player);
|
||||
|
||||
menuItems.push({
|
||||
name: globalize.translate("sharedcomponents#Quality"),
|
||||
id: "quality",
|
||||
name: globalize.translate('sharedcomponents#Quality'),
|
||||
id: 'quality',
|
||||
asideText: secondaryQualityText
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
var repeatMode = playbackManager.getRepeatMode(player);
|
||||
return -1 !== supportedCommands.indexOf("SetRepeatMode") && playbackManager.currentMediaSource(player).RunTimeTicks && menuItems.push({
|
||||
name: globalize.translate("sharedcomponents#RepeatMode"),
|
||||
id: "repeatmode",
|
||||
asideText: "RepeatNone" === repeatMode ? globalize.translate("sharedcomponents#None") : globalize.translate("sharedcomponents#" + repeatMode)
|
||||
}), options.stats && menuItems.push({
|
||||
name: globalize.translate("sharedcomponents#StatsForNerds"),
|
||||
id: "stats",
|
||||
asideText: null
|
||||
}), menuItems.push({
|
||||
name: globalize.translate("sharedcomponents#SubtitleSettings"),
|
||||
id: "subtitlesettings"
|
||||
}), actionsheet.show({
|
||||
|
||||
if (supportedCommands.indexOf('SetRepeatMode') !== -1 && playbackManager.currentMediaSource(player).RunTimeTicks) {
|
||||
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#RepeatMode'),
|
||||
id: 'repeatmode',
|
||||
asideText: repeatMode === 'RepeatNone' ? globalize.translate('sharedcomponents#None') : globalize.translate('sharedcomponents#' + repeatMode)
|
||||
});
|
||||
}
|
||||
|
||||
if (options.stats) {
|
||||
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#StatsForNerds'),
|
||||
id: 'stats',
|
||||
asideText: null
|
||||
});
|
||||
}
|
||||
|
||||
menuItems.push({
|
||||
name: globalize.translate('sharedcomponents#SubtitleSettings'),
|
||||
id: 'subtitlesettings'
|
||||
});
|
||||
|
||||
return actionsheet.show({
|
||||
|
||||
items: menuItems,
|
||||
positionTo: options.positionTo
|
||||
}).then(function(id) {
|
||||
return handleSelectedOption(id, options, player)
|
||||
})
|
||||
|
||||
}).then(function (id) {
|
||||
|
||||
return handleSelectedOption(id, options, player);
|
||||
});
|
||||
}
|
||||
|
||||
function show(options) {
|
||||
var player = options.player,
|
||||
currentItem = playbackManager.currentItem(player);
|
||||
return currentItem && currentItem.ServerId ? connectionManager.getApiClient(currentItem.ServerId).getCurrentUser().then(function(user) {
|
||||
return showWithUser(options, player, user)
|
||||
}) : showWithUser(options, player, null)
|
||||
|
||||
var player = options.player;
|
||||
|
||||
var currentItem = playbackManager.currentItem(player);
|
||||
|
||||
if (!currentItem || !currentItem.ServerId) {
|
||||
return showWithUser(options, player, null);
|
||||
}
|
||||
|
||||
var apiClient = connectionManager.getApiClient(currentItem.ServerId);
|
||||
|
||||
return apiClient.getCurrentUser().then(function (user) {
|
||||
return showWithUser(options, player, user);
|
||||
});
|
||||
}
|
||||
|
||||
function alertText(text) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
require(["alert"], function(alert) {
|
||||
alert(text).then(resolve)
|
||||
})
|
||||
})
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
require(['alert'], function (alert) {
|
||||
|
||||
alert(text).then(resolve);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function showSubtitleSettings(player, btn) {
|
||||
return alertText(globalize.translate("sharedcomponents#SubtitleSettingsIntro"))
|
||||
return alertText(globalize.translate('sharedcomponents#SubtitleSettingsIntro'));
|
||||
}
|
||||
|
||||
function showPlaybackSettings(player, btn) {
|
||||
return alertText(globalize.translate("sharedcomponents#PlaybackSettingsIntro"))
|
||||
return alertText(globalize.translate('sharedcomponents#PlaybackSettingsIntro'));
|
||||
}
|
||||
|
||||
function handleSelectedOption(id, options, player) {
|
||||
|
||||
switch (id) {
|
||||
case "quality":
|
||||
|
||||
case 'quality':
|
||||
return showQualityMenu(player, options.positionTo);
|
||||
case "aspectratio":
|
||||
case 'aspectratio':
|
||||
return showAspectRatioMenu(player, options.positionTo);
|
||||
case "repeatmode":
|
||||
case 'repeatmode':
|
||||
return showRepeatModeMenu(player, options.positionTo);
|
||||
case "subtitlesettings":
|
||||
case 'subtitlesettings':
|
||||
return showSubtitleSettings(player, options.positionTo);
|
||||
case "playbacksettings":
|
||||
case 'playbacksettings':
|
||||
return showPlaybackSettings(player, options.positionTo);
|
||||
case "stats":
|
||||
return options.onOption && options.onOption("stats"), Promise.resolve()
|
||||
case 'stats':
|
||||
if (options.onOption) {
|
||||
options.onOption('stats');
|
||||
}
|
||||
return Promise.resolve();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Promise.reject()
|
||||
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
return {
|
||||
show: show
|
||||
}
|
||||
};
|
||||
});
|
|
@ -1,10 +1,27 @@
|
|||
define([], function() {
|
||||
"use strict";
|
||||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function getDisplayPlayMethod(session) {
|
||||
return session.NowPlayingItem ? session.TranscodingInfo && session.TranscodingInfo.IsVideoDirect ? "DirectStream" : "Transcode" === session.PlayState.PlayMethod ? "Transcode" : "DirectStream" === session.PlayState.PlayMethod ? "DirectPlay" : "DirectPlay" === session.PlayState.PlayMethod ? "DirectPlay" : void 0 : null
|
||||
|
||||
if (!session.NowPlayingItem) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (session.TranscodingInfo && session.TranscodingInfo.IsVideoDirect) {
|
||||
return 'DirectStream';
|
||||
}
|
||||
else if (session.PlayState.PlayMethod === 'Transcode') {
|
||||
return 'Transcode';
|
||||
}
|
||||
else if (session.PlayState.PlayMethod === 'DirectStream') {
|
||||
return 'DirectPlay';
|
||||
}
|
||||
else if (session.PlayState.PlayMethod === 'DirectPlay') {
|
||||
return 'DirectPlay';
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
getDisplayPlayMethod: getDisplayPlayMethod
|
||||
}
|
||||
};
|
||||
});
|
|
@ -1,103 +1,233 @@
|
|||
define([], function() {
|
||||
"use strict";
|
||||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
var currentId = 0;
|
||||
function addUniquePlaylistItemId(item) {
|
||||
item.PlaylistItemId || (item.PlaylistItemId = "playlistItem" + currentId, currentId++)
|
||||
|
||||
if (!item.PlaylistItemId) {
|
||||
|
||||
item.PlaylistItemId = "playlistItem" + currentId;
|
||||
currentId++;
|
||||
}
|
||||
}
|
||||
|
||||
function findPlaylistIndex(playlistItemId, list) {
|
||||
for (var i = 0, length = list.length; i < length; i++)
|
||||
if (list[i].PlaylistItemId === playlistItemId) return i;
|
||||
return -1
|
||||
|
||||
for (var i = 0, length = list.length; i < length; i++) {
|
||||
if (list[i].PlaylistItemId === playlistItemId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
function PlayQueueManager() {
|
||||
this._playlist = [], this._repeatMode = "RepeatNone"
|
||||
|
||||
this._playlist = [];
|
||||
this._repeatMode = 'RepeatNone';
|
||||
}
|
||||
|
||||
PlayQueueManager.prototype.getPlaylist = function () {
|
||||
return this._playlist.slice(0);
|
||||
};
|
||||
|
||||
PlayQueueManager.prototype.setPlaylist = function (items) {
|
||||
|
||||
items = items.slice(0);
|
||||
|
||||
for (var i = 0, length = items.length; i < length; i++) {
|
||||
|
||||
addUniquePlaylistItemId(items[i]);
|
||||
}
|
||||
|
||||
this._currentPlaylistItemId = null;
|
||||
this._playlist = items;
|
||||
this._repeatMode = 'RepeatNone';
|
||||
};
|
||||
|
||||
PlayQueueManager.prototype.queue = function (items) {
|
||||
|
||||
for (var i = 0, length = items.length; i < length; i++) {
|
||||
|
||||
addUniquePlaylistItemId(items[i]);
|
||||
|
||||
this._playlist.push(items[i]);
|
||||
}
|
||||
};
|
||||
|
||||
function arrayInsertAt(destArray, pos, arrayToInsert) {
|
||||
var args = [];
|
||||
args.push(pos), args.push(0), args = args.concat(arrayToInsert), destArray.splice.apply(destArray, args)
|
||||
args.push(pos); // where to insert
|
||||
args.push(0); // nothing to remove
|
||||
args = args.concat(arrayToInsert); // add on array to insert
|
||||
destArray.splice.apply(destArray, args); // splice it in
|
||||
}
|
||||
|
||||
function moveInArray(array, from, to) {
|
||||
array.splice(to, 0, array.splice(from, 1)[0])
|
||||
}
|
||||
var currentId = 0;
|
||||
return PlayQueueManager.prototype.getPlaylist = function() {
|
||||
return this._playlist.slice(0)
|
||||
}, PlayQueueManager.prototype.setPlaylist = function(items) {
|
||||
items = items.slice(0);
|
||||
for (var i = 0, length = items.length; i < length; i++) addUniquePlaylistItemId(items[i]);
|
||||
this._currentPlaylistItemId = null, this._playlist = items, this._repeatMode = "RepeatNone"
|
||||
}, PlayQueueManager.prototype.queue = function(items) {
|
||||
for (var i = 0, length = items.length; i < length; i++) addUniquePlaylistItemId(items[i]), this._playlist.push(items[i])
|
||||
}, PlayQueueManager.prototype.queueNext = function(items) {
|
||||
PlayQueueManager.prototype.queueNext = function (items) {
|
||||
|
||||
var i, length;
|
||||
for (i = 0, length = items.length; i < length; i++) addUniquePlaylistItemId(items[i]);
|
||||
var currentIndex = this.getCurrentPlaylistIndex(); - 1 === currentIndex ? currentIndex = this._playlist.length : currentIndex++, arrayInsertAt(this._playlist, currentIndex, items)
|
||||
}, PlayQueueManager.prototype.getCurrentPlaylistIndex = function() {
|
||||
return findPlaylistIndex(this.getCurrentPlaylistItemId(), this._playlist)
|
||||
}, PlayQueueManager.prototype.getCurrentItem = function() {
|
||||
var index = findPlaylistIndex(this.getCurrentPlaylistItemId(), this._playlist);
|
||||
return -1 === index ? null : this._playlist[index]
|
||||
}, PlayQueueManager.prototype.getCurrentPlaylistItemId = function() {
|
||||
return this._currentPlaylistItemId
|
||||
}, PlayQueueManager.prototype.setPlaylistState = function(playlistItemId, playlistIndex) {
|
||||
this._currentPlaylistItemId = playlistItemId
|
||||
}, PlayQueueManager.prototype.setPlaylistIndex = function(playlistIndex) {
|
||||
playlistIndex < 0 ? this.setPlaylistState(null) : this.setPlaylistState(this._playlist[playlistIndex].PlaylistItemId)
|
||||
}, PlayQueueManager.prototype.removeFromPlaylist = function(playlistItemIds) {
|
||||
var playlist = this.getPlaylist();
|
||||
if (playlist.length <= playlistItemIds.length) return {
|
||||
result: "empty"
|
||||
};
|
||||
var currentPlaylistItemId = this.getCurrentPlaylistItemId(),
|
||||
isCurrentIndex = -1 !== playlistItemIds.indexOf(currentPlaylistItemId);
|
||||
return this._playlist = playlist.filter(function(item) {
|
||||
return -1 === playlistItemIds.indexOf(item.PlaylistItemId)
|
||||
}), {
|
||||
result: "removed",
|
||||
isCurrentIndex: isCurrentIndex
|
||||
|
||||
for (i = 0, length = items.length; i < length; i++) {
|
||||
|
||||
addUniquePlaylistItemId(items[i]);
|
||||
}
|
||||
}, PlayQueueManager.prototype.movePlaylistItem = function(playlistItemId, newIndex) {
|
||||
for (var oldIndex, playlist = this.getPlaylist(), i = 0, length = playlist.length; i < length; i++)
|
||||
|
||||
var currentIndex = this.getCurrentPlaylistIndex();
|
||||
|
||||
if (currentIndex === -1) {
|
||||
currentIndex = this._playlist.length;
|
||||
} else {
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
arrayInsertAt(this._playlist, currentIndex, items);
|
||||
};
|
||||
|
||||
PlayQueueManager.prototype.getCurrentPlaylistIndex = function () {
|
||||
|
||||
return findPlaylistIndex(this.getCurrentPlaylistItemId(), this._playlist);
|
||||
};
|
||||
|
||||
PlayQueueManager.prototype.getCurrentItem = function () {
|
||||
|
||||
var index = findPlaylistIndex(this.getCurrentPlaylistItemId(), this._playlist);
|
||||
|
||||
return index === -1 ? null : this._playlist[index];
|
||||
};
|
||||
|
||||
PlayQueueManager.prototype.getCurrentPlaylistItemId = function () {
|
||||
return this._currentPlaylistItemId;
|
||||
};
|
||||
|
||||
PlayQueueManager.prototype.setPlaylistState = function (playlistItemId, playlistIndex) {
|
||||
|
||||
this._currentPlaylistItemId = playlistItemId;
|
||||
};
|
||||
|
||||
PlayQueueManager.prototype.setPlaylistIndex = function (playlistIndex) {
|
||||
|
||||
if (playlistIndex < 0) {
|
||||
this.setPlaylistState(null);
|
||||
} else {
|
||||
this.setPlaylistState(this._playlist[playlistIndex].PlaylistItemId);
|
||||
}
|
||||
};
|
||||
|
||||
PlayQueueManager.prototype.removeFromPlaylist = function (playlistItemIds) {
|
||||
|
||||
var playlist = this.getPlaylist();
|
||||
|
||||
if (playlist.length <= playlistItemIds.length) {
|
||||
return {
|
||||
result: 'empty'
|
||||
};
|
||||
}
|
||||
|
||||
var currentPlaylistItemId = this.getCurrentPlaylistItemId();
|
||||
var isCurrentIndex = playlistItemIds.indexOf(currentPlaylistItemId) !== -1;
|
||||
|
||||
this._playlist = playlist.filter(function (item) {
|
||||
return playlistItemIds.indexOf(item.PlaylistItemId) === -1;
|
||||
});
|
||||
|
||||
return {
|
||||
result: 'removed',
|
||||
isCurrentIndex: isCurrentIndex
|
||||
};
|
||||
};
|
||||
|
||||
function moveInArray(array, from, to) {
|
||||
array.splice(to, 0, array.splice(from, 1)[0]);
|
||||
}
|
||||
|
||||
PlayQueueManager.prototype.movePlaylistItem = function (playlistItemId, newIndex) {
|
||||
|
||||
var playlist = this.getPlaylist();
|
||||
|
||||
var oldIndex;
|
||||
for (var i = 0, length = playlist.length; i < length; i++) {
|
||||
if (playlist[i].PlaylistItemId === playlistItemId) {
|
||||
oldIndex = i;
|
||||
break
|
||||
} if (-1 === oldIndex || oldIndex === newIndex) return {
|
||||
result: "noop"
|
||||
};
|
||||
if (newIndex >= playlist.length) throw new Error("newIndex out of bounds");
|
||||
return moveInArray(playlist, oldIndex, newIndex), this._playlist = playlist, {
|
||||
result: "moved",
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldIndex === -1 || oldIndex === newIndex) {
|
||||
return {
|
||||
result: 'noop'
|
||||
};
|
||||
}
|
||||
|
||||
if (newIndex >= playlist.length) {
|
||||
throw new Error('newIndex out of bounds');
|
||||
}
|
||||
|
||||
moveInArray(playlist, oldIndex, newIndex);
|
||||
|
||||
this._playlist = playlist;
|
||||
|
||||
return {
|
||||
result: 'moved',
|
||||
playlistItemId: playlistItemId,
|
||||
newIndex: newIndex
|
||||
}
|
||||
}, PlayQueueManager.prototype.reset = function() {
|
||||
this._playlist = [], this._currentPlaylistItemId = null, this._repeatMode = "RepeatNone"
|
||||
}, PlayQueueManager.prototype.setRepeatMode = function(value) {
|
||||
this._repeatMode = value
|
||||
}, PlayQueueManager.prototype.getRepeatMode = function() {
|
||||
return this._repeatMode
|
||||
}, PlayQueueManager.prototype.getNextItemInfo = function() {
|
||||
var newIndex, playlist = this.getPlaylist(),
|
||||
playlistLength = playlist.length;
|
||||
};
|
||||
};
|
||||
|
||||
PlayQueueManager.prototype.reset = function () {
|
||||
|
||||
this._playlist = [];
|
||||
this._currentPlaylistItemId = null;
|
||||
this._repeatMode = 'RepeatNone';
|
||||
};
|
||||
|
||||
PlayQueueManager.prototype.setRepeatMode = function (value) {
|
||||
|
||||
this._repeatMode = value;
|
||||
};
|
||||
|
||||
PlayQueueManager.prototype.getRepeatMode = function () {
|
||||
|
||||
return this._repeatMode;
|
||||
};
|
||||
|
||||
PlayQueueManager.prototype.getNextItemInfo = function () {
|
||||
|
||||
var newIndex;
|
||||
var playlist = this.getPlaylist();
|
||||
var playlistLength = playlist.length;
|
||||
|
||||
switch (this.getRepeatMode()) {
|
||||
case "RepeatOne":
|
||||
|
||||
case 'RepeatOne':
|
||||
newIndex = this.getCurrentPlaylistIndex();
|
||||
break;
|
||||
case "RepeatAll":
|
||||
newIndex = this.getCurrentPlaylistIndex() + 1, newIndex >= playlistLength && (newIndex = 0);
|
||||
case 'RepeatAll':
|
||||
newIndex = this.getCurrentPlaylistIndex() + 1;
|
||||
if (newIndex >= playlistLength) {
|
||||
newIndex = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
newIndex = this.getCurrentPlaylistIndex() + 1
|
||||
newIndex = this.getCurrentPlaylistIndex() + 1;
|
||||
break;
|
||||
}
|
||||
if (newIndex < 0 || newIndex >= playlistLength) return null;
|
||||
|
||||
if (newIndex < 0 || newIndex >= playlistLength) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var item = playlist[newIndex];
|
||||
return item ? {
|
||||
|
||||
if (!item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
item: item,
|
||||
index: newIndex
|
||||
} : null
|
||||
}, PlayQueueManager
|
||||
};
|
||||
};
|
||||
|
||||
return PlayQueueManager;
|
||||
});
|
|
@ -1,22 +1,47 @@
|
|||
define(["events", "playbackManager"], function(events, playbackManager) {
|
||||
"use strict";
|
||||
define(['events', 'playbackManager'], function (events, playbackManager) {
|
||||
'use strict';
|
||||
|
||||
function transferPlayback(oldPlayer, newPlayer) {
|
||||
var state = playbackManager.getPlayerState(oldPlayer),
|
||||
item = state.NowPlayingItem;
|
||||
if (item) {
|
||||
var playState = state.PlayState || {},
|
||||
resumePositionTicks = playState.PositionTicks || 0;
|
||||
playbackManager.stop(oldPlayer).then(function() {
|
||||
playbackManager.play({
|
||||
ids: [item.Id],
|
||||
serverId: item.ServerId,
|
||||
startPositionTicks: resumePositionTicks
|
||||
}, newPlayer)
|
||||
})
|
||||
|
||||
var state = playbackManager.getPlayerState(oldPlayer);
|
||||
|
||||
var item = state.NowPlayingItem;
|
||||
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
var playState = state.PlayState || {};
|
||||
var resumePositionTicks = playState.PositionTicks || 0;
|
||||
|
||||
playbackManager.stop(oldPlayer).then(function () {
|
||||
|
||||
playbackManager.play({
|
||||
ids: [item.Id],
|
||||
serverId: item.ServerId,
|
||||
startPositionTicks: resumePositionTicks
|
||||
|
||||
}, newPlayer);
|
||||
});
|
||||
}
|
||||
events.on(playbackManager, "playerchange", function(e, newPlayer, newTarget, oldPlayer) {
|
||||
if (oldPlayer && newPlayer) return oldPlayer.isLocalPlayer ? newPlayer.isLocalPlayer ? void console.log("Skipping remote control autoplay because newPlayer is a local player") : void transferPlayback(oldPlayer, newPlayer) : void console.log("Skipping remote control autoplay because oldPlayer is not a local player")
|
||||
})
|
||||
|
||||
events.on(playbackManager, 'playerchange', function (e, newPlayer, newTarget, oldPlayer) {
|
||||
|
||||
if (!oldPlayer || !newPlayer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!oldPlayer.isLocalPlayer) {
|
||||
console.log('Skipping remote control autoplay because oldPlayer is not a local player');
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPlayer.isLocalPlayer) {
|
||||
console.log('Skipping remote control autoplay because newPlayer is a local player');
|
||||
return;
|
||||
}
|
||||
|
||||
transferPlayback(oldPlayer, newPlayer);
|
||||
});
|
||||
|
||||
});
|
|
@ -1,63 +1,158 @@
|
|||
define(["events", "playbackManager", "dom", "browser", "css!./iconosd", "material-icons"], function(events, playbackManager, dom, browser) {
|
||||
"use strict";
|
||||
define(['events', 'playbackManager', 'dom', 'browser', 'css!./iconosd', 'material-icons'], function (events, playbackManager, dom, browser) {
|
||||
'use strict';
|
||||
|
||||
var currentPlayer;
|
||||
var osdElement;
|
||||
var iconElement;
|
||||
var progressElement;
|
||||
|
||||
var enableAnimation;
|
||||
|
||||
function getOsdElementHtml() {
|
||||
var html = "";
|
||||
return html += '<i class="md-icon iconOsdIcon"></i>', html += '<div class="iconOsdProgressOuter"><div class="iconOsdProgressInner"></div></div>'
|
||||
var html = '';
|
||||
|
||||
html += '<i class="md-icon iconOsdIcon"></i>';
|
||||
|
||||
html += '<div class="iconOsdProgressOuter"><div class="iconOsdProgressInner"></div></div>';
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function ensureOsdElement() {
|
||||
|
||||
var elem = osdElement;
|
||||
elem || (enableAnimation = browser.supportsCssAnimation(), elem = document.createElement("div"), elem.classList.add("hide"), elem.classList.add("iconOsd"), elem.classList.add("iconOsd-hidden"), elem.classList.add("volumeOsd"), elem.innerHTML = getOsdElementHtml(), iconElement = elem.querySelector("i"), progressElement = elem.querySelector(".iconOsdProgressInner"), document.body.appendChild(elem), osdElement = elem)
|
||||
if (!elem) {
|
||||
|
||||
enableAnimation = browser.supportsCssAnimation();
|
||||
|
||||
elem = document.createElement('div');
|
||||
elem.classList.add('hide');
|
||||
elem.classList.add('iconOsd');
|
||||
elem.classList.add('iconOsd-hidden');
|
||||
elem.classList.add('volumeOsd');
|
||||
elem.innerHTML = getOsdElementHtml();
|
||||
|
||||
iconElement = elem.querySelector('i');
|
||||
progressElement = elem.querySelector('.iconOsdProgressInner');
|
||||
|
||||
document.body.appendChild(elem);
|
||||
osdElement = elem;
|
||||
}
|
||||
}
|
||||
|
||||
function onHideComplete() {
|
||||
this.classList.add("hide")
|
||||
this.classList.add('hide');
|
||||
}
|
||||
|
||||
var hideTimeout;
|
||||
function showOsd() {
|
||||
|
||||
clearHideTimeout();
|
||||
|
||||
var elem = osdElement;
|
||||
|
||||
dom.removeEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
|
||||
once: !0
|
||||
}), elem.classList.remove("hide"), elem.offsetWidth, requestAnimationFrame(function() {
|
||||
elem.classList.remove("iconOsd-hidden"), hideTimeout = setTimeout(hideOsd, 3e3)
|
||||
})
|
||||
once: true
|
||||
});
|
||||
|
||||
elem.classList.remove('hide');
|
||||
|
||||
// trigger reflow
|
||||
void elem.offsetWidth;
|
||||
|
||||
requestAnimationFrame(function () {
|
||||
elem.classList.remove('iconOsd-hidden');
|
||||
|
||||
hideTimeout = setTimeout(hideOsd, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
function clearHideTimeout() {
|
||||
hideTimeout && (clearTimeout(hideTimeout), hideTimeout = null)
|
||||
if (hideTimeout) {
|
||||
clearTimeout(hideTimeout);
|
||||
hideTimeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
function hideOsd() {
|
||||
|
||||
clearHideTimeout();
|
||||
|
||||
var elem = osdElement;
|
||||
elem && (enableAnimation ? (elem.offsetWidth, requestAnimationFrame(function() {
|
||||
elem.classList.add("iconOsd-hidden"), dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
|
||||
once: !0
|
||||
})
|
||||
})) : onHideComplete.call(elem))
|
||||
if (elem) {
|
||||
|
||||
if (enableAnimation) {
|
||||
// trigger reflow
|
||||
void elem.offsetWidth;
|
||||
|
||||
requestAnimationFrame(function () {
|
||||
elem.classList.add('iconOsd-hidden');
|
||||
|
||||
dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
|
||||
once: true
|
||||
});
|
||||
});
|
||||
} else {
|
||||
onHideComplete.call(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updatePlayerVolumeState(isMuted, volume) {
|
||||
iconElement && (iconElement.innerHTML = isMuted ? "" : ""), progressElement && (progressElement.style.width = (volume || 0) + "%")
|
||||
|
||||
if (iconElement) {
|
||||
iconElement.innerHTML = isMuted ? '' : '';
|
||||
}
|
||||
if (progressElement) {
|
||||
progressElement.style.width = (volume || 0) + '%';
|
||||
}
|
||||
}
|
||||
|
||||
function releaseCurrentPlayer() {
|
||||
|
||||
var player = currentPlayer;
|
||||
player && (events.off(player, "volumechange", onVolumeChanged), events.off(player, "playbackstop", hideOsd), currentPlayer = null)
|
||||
|
||||
if (player) {
|
||||
events.off(player, 'volumechange', onVolumeChanged);
|
||||
events.off(player, 'playbackstop', hideOsd);
|
||||
currentPlayer = null;
|
||||
}
|
||||
}
|
||||
|
||||
function onVolumeChanged(e) {
|
||||
|
||||
var player = this;
|
||||
ensureOsdElement(), updatePlayerVolumeState(player.isMuted(), player.getVolume()), showOsd()
|
||||
|
||||
ensureOsdElement();
|
||||
|
||||
updatePlayerVolumeState(player.isMuted(), player.getVolume());
|
||||
|
||||
showOsd();
|
||||
}
|
||||
|
||||
function bindToPlayer(player) {
|
||||
player !== currentPlayer && (releaseCurrentPlayer(), currentPlayer = player, player && (hideOsd(), events.on(player, "volumechange", onVolumeChanged), events.on(player, "playbackstop", hideOsd)))
|
||||
|
||||
if (player === currentPlayer) {
|
||||
return;
|
||||
}
|
||||
|
||||
releaseCurrentPlayer();
|
||||
|
||||
currentPlayer = player;
|
||||
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
|
||||
hideOsd();
|
||||
events.on(player, 'volumechange', onVolumeChanged);
|
||||
events.on(player, 'playbackstop', hideOsd);
|
||||
}
|
||||
var currentPlayer, osdElement, iconElement, progressElement, enableAnimation, hideTimeout;
|
||||
events.on(playbackManager, "playerchange", function() {
|
||||
bindToPlayer(playbackManager.getCurrentPlayer())
|
||||
}), bindToPlayer(playbackManager.getCurrentPlayer())
|
||||
|
||||
events.on(playbackManager, 'playerchange', function () {
|
||||
bindToPlayer(playbackManager.getCurrentPlayer());
|
||||
});
|
||||
|
||||
bindToPlayer(playbackManager.getCurrentPlayer());
|
||||
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue