mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge branch 'dev'
This commit is contained in:
commit
73f434091c
728 changed files with 16844 additions and 79096 deletions
|
@ -63,11 +63,9 @@
|
|||
<input type="hidden" id="featureId" name="item_number" value="">
|
||||
<input type="hidden" name="notify_url" value="https://mb3admin.com/admin/service/services/ppipn.php">
|
||||
<input type="hidden" name="return" id="paypalReturnUrl" value="#">
|
||||
<button type="submit" id="ppButton" class="clearButton">
|
||||
<paper-button raised class="block" style="background-color: #179BD7;color:#fff;">
|
||||
<iron-icon icon="check"></iron-icon>
|
||||
<span>${RegisterWithPayPal}</span>
|
||||
</paper-button>
|
||||
<button is="emby-button" type="submit" id="ppButton" class="raised block" style="background-color: #179BD7;color:#fff;">
|
||||
<iron-icon icon="check"></iron-icon>
|
||||
<span>${RegisterWithPayPal}</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -2,18 +2,15 @@
|
|||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
|
||||
<div style="margin: -25px 0 1em; text-align: right;">
|
||||
<div class="listTopPaging" style="float: left; position: relative; top: 15px;">
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<div style="float: right; position: relative; top: 15px;margin-top: -5px;display:none;" class="organizeTaskPanel">
|
||||
<paper-button type="button" class="btnClearLog" raised style="display: inline-block;"><iron-icon icon="clear-all"></iron-icon><span>${ButtonClear}</span></paper-button>
|
||||
<paper-button type="button" class="btnOrganize" raised><iron-icon icon="check"></iron-icon><span>${ButtonOrganize}</span></paper-button>
|
||||
<progress max="100" min="0" style="width:100px;display:none;" class="organizeProgress"></progress>
|
||||
<div style="text-align:right;" class="organizeTaskPanel hide">
|
||||
<button is="emby-button" type="button" class="btnClearLog raised subdued"><iron-icon icon="clear-all"></iron-icon><span>${ButtonClear}</span></button>
|
||||
<button is="emby-button" type="button" class="btnOrganize raised subdued"><iron-icon icon="check"></iron-icon><span>${ButtonOrganize}</span></button>
|
||||
<progress max="100" min="0" style="width:100px;" class="organizeProgress"></progress>
|
||||
</div>
|
||||
<div class="listTopPaging">
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
<table data-role="table" data-mode="reflow" class="tblOrganizationResults stripedTable ui-responsive table-stroke">
|
||||
<thead>
|
||||
|
|
|
@ -151,9 +151,7 @@
|
|||
|
||||
<ul data-role="listview" class="ulForm">
|
||||
<li>
|
||||
<button type="submit" data-role="none" class="clearButton">
|
||||
<paper-button raised class="submit block"><iron-icon icon="check"></iron-icon><span>${ButtonSave}</span></paper-button>
|
||||
</button>
|
||||
<button is="emby-button" type="submit" class="raised submit block"><iron-icon icon="check"></iron-icon><span>${ButtonSave}</span></button>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
},
|
||||
"devDependencies": {},
|
||||
"ignore": [],
|
||||
"version": "1.1.55",
|
||||
"_release": "1.1.55",
|
||||
"version": "1.1.64",
|
||||
"_release": "1.1.64",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.1.55",
|
||||
"commit": "c985db6d4a2c6013dcb3bcb200532144a909732c"
|
||||
"tag": "1.1.64",
|
||||
"commit": "a1d00ddc6a767b00a588729b13c8202b99b1eadb"
|
||||
},
|
||||
"_source": "https://github.com/MediaBrowser/Emby.ApiClient.Javascript.git",
|
||||
"_target": "^1.1.51",
|
||||
|
|
|
@ -534,6 +534,11 @@
|
|||
self.openWebSocket();
|
||||
};
|
||||
|
||||
function replaceAll(originalString, strReplace, strWith) {
|
||||
var reg = new RegExp(strReplace, 'ig');
|
||||
return originalString.replace(reg, strWith);
|
||||
}
|
||||
|
||||
self.openWebSocket = function () {
|
||||
|
||||
var accessToken = self.accessToken();
|
||||
|
@ -542,7 +547,10 @@
|
|||
throw new Error("Cannot open web socket without access token.");
|
||||
}
|
||||
|
||||
var url = self.getUrl("socket").replace("emby/socket", "embywebsocket").replace('http', 'ws');
|
||||
var url = self.getUrl("socket");
|
||||
|
||||
url = replaceAll(url, 'emby/socket', 'embywebsocket');
|
||||
url = replaceAll(url, 'http', 'ws');
|
||||
|
||||
url += "?api_key=" + accessToken;
|
||||
url += "&deviceId=" + deviceId;
|
||||
|
@ -2980,6 +2988,20 @@
|
|||
return self.getJSON(url);
|
||||
};
|
||||
|
||||
self.getGameSystems = function () {
|
||||
|
||||
var options = {};
|
||||
|
||||
var userId = self.getCurrentUserId();
|
||||
if (userId) {
|
||||
options.userId = userId;
|
||||
}
|
||||
|
||||
var url = self.getUrl("Games/SystemSummaries", options);
|
||||
|
||||
return self.getJSON(url);
|
||||
};
|
||||
|
||||
self.getAdditionalVideoParts = function (userId, itemId) {
|
||||
|
||||
if (!itemId) {
|
||||
|
|
|
@ -215,7 +215,7 @@
|
|||
return connectUser;
|
||||
};
|
||||
|
||||
var minServerVersion = '3.0.5818';
|
||||
var minServerVersion = '3.0.5882';
|
||||
self.minServerVersion = function (val) {
|
||||
|
||||
if (val) {
|
||||
|
@ -582,12 +582,12 @@
|
|||
"X-MediaBrowser-Token": server.AccessToken
|
||||
}
|
||||
|
||||
}).then(function(user) {
|
||||
}).then(function (user) {
|
||||
|
||||
onLocalUserSignIn(server, connectionMode, user);
|
||||
return Promise.resolve();
|
||||
|
||||
}, function() {
|
||||
}, function () {
|
||||
|
||||
server.UserId = null;
|
||||
server.AccessToken = null;
|
||||
|
@ -900,7 +900,7 @@
|
|||
return null;
|
||||
}
|
||||
|
||||
self.connect = function () {
|
||||
self.connect = function (options) {
|
||||
|
||||
console.log('Begin connect');
|
||||
|
||||
|
@ -908,7 +908,7 @@
|
|||
|
||||
self.getAvailableServers().then(function (servers) {
|
||||
|
||||
self.connectToServers(servers).then(function (result) {
|
||||
self.connectToServers(servers, options).then(function (result) {
|
||||
|
||||
resolve(result);
|
||||
});
|
||||
|
@ -921,7 +921,7 @@
|
|||
// TODO: Implement
|
||||
};
|
||||
|
||||
self.connectToServers = function (servers) {
|
||||
self.connectToServers = function (servers, options) {
|
||||
|
||||
console.log('Begin connectToServers, with ' + servers.length + ' servers');
|
||||
|
||||
|
@ -929,7 +929,7 @@
|
|||
|
||||
if (servers.length == 1) {
|
||||
|
||||
self.connectToServer(servers[0]).then(function (result) {
|
||||
self.connectToServer(servers[0], options).then(function (result) {
|
||||
|
||||
if (result.State == ConnectionState.Unavailable) {
|
||||
|
||||
|
@ -948,7 +948,7 @@
|
|||
var firstServer = servers.length ? servers[0] : null;
|
||||
// See if we have any saved credentials and can auto sign in
|
||||
if (firstServer) {
|
||||
self.connectToServer(firstServer).then(function (result) {
|
||||
self.connectToServer(firstServer, options).then(function (result) {
|
||||
|
||||
if (result.State == ConnectionState.SignedIn) {
|
||||
|
||||
|
@ -1058,13 +1058,17 @@
|
|||
|
||||
enableRetry = true;
|
||||
timeout = 8000;
|
||||
|
||||
if (stringEqualsIgnoreCase(address, server.ManualAddress)) {
|
||||
skipTest = true;
|
||||
}
|
||||
}
|
||||
|
||||
else if (mode == ConnectionMode.Manual) {
|
||||
|
||||
if (stringEqualsIgnoreCase(address, server.LocalAddress) ||
|
||||
stringEqualsIgnoreCase(address, server.RemoteAddress)) {
|
||||
skipTest = true;
|
||||
if (stringEqualsIgnoreCase(address, server.LocalAddress)) {
|
||||
enableRetry = true;
|
||||
timeout = 8000;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1112,7 +1116,8 @@
|
|||
function onSuccessfulConnection(server, systemInfo, connectionMode, options, resolve) {
|
||||
|
||||
var credentials = credentialProvider.credentials();
|
||||
if (credentials.ConnectAccessToken) {
|
||||
options = options || {};
|
||||
if (credentials.ConnectAccessToken && options.enableAutoLogin !== false) {
|
||||
|
||||
ensureConnectUser(credentials).then(function () {
|
||||
|
||||
|
@ -1139,7 +1144,14 @@
|
|||
|
||||
function afterConnectValidated(server, credentials, systemInfo, connectionMode, verifyLocalAuthentication, options, resolve) {
|
||||
|
||||
if (verifyLocalAuthentication && server.AccessToken) {
|
||||
options = options || {};
|
||||
|
||||
if (options.enableAutoLogin === false) {
|
||||
|
||||
server.UserId = null;
|
||||
server.AccessToken = null;
|
||||
|
||||
} else if (verifyLocalAuthentication && server.AccessToken && options.enableAutoLogin !== false) {
|
||||
|
||||
validateAuthentication(server, connectionMode).then(function () {
|
||||
|
||||
|
@ -1164,7 +1176,7 @@
|
|||
};
|
||||
|
||||
result.ApiClient = getOrAddApiClient(server, connectionMode);
|
||||
result.State = server.AccessToken ?
|
||||
result.State = server.AccessToken && options.enableAutoLogin !== false ?
|
||||
ConnectionState.SignedIn :
|
||||
ConnectionState.ServerSignIn;
|
||||
|
||||
|
@ -1180,6 +1192,11 @@
|
|||
Events.trigger(self, 'connected', [result]);
|
||||
}
|
||||
|
||||
function replaceAll(originalString, strReplace, strWith) {
|
||||
var reg = new RegExp(strReplace, 'ig');
|
||||
return originalString.replace(reg, strWith);
|
||||
}
|
||||
|
||||
function normalizeAddress(address) {
|
||||
|
||||
// attempt to correct bad input
|
||||
|
@ -1190,13 +1207,13 @@
|
|||
}
|
||||
|
||||
// Seeing failures in iOS when protocol isn't lowercase
|
||||
address = address.replace('Http:', 'http:');
|
||||
address = address.replace('Https:', 'https:');
|
||||
address = replaceAll(address, 'Http:', 'http:');
|
||||
address = replaceAll(address, 'Https:', 'https:');
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
self.connectToAddress = function (address) {
|
||||
self.connectToAddress = function (address, options) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
|
@ -1222,7 +1239,7 @@
|
|||
};
|
||||
updateServerInfo(server, publicInfo);
|
||||
|
||||
self.connectToServer(server).then(resolve, onFail);
|
||||
self.connectToServer(server, options).then(resolve, onFail);
|
||||
|
||||
}, onFail);
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<link rel="import" href="../polymer/polymer.html">
|
||||
<link rel="import" href="../iron-icon/iron-icon.html">
|
||||
<link rel="import" href="../paper-button/paper-button.html">
|
||||
<link rel="import" href="../neon-animation/neon-animation-runner-behavior.html">
|
||||
<link rel="import" href="../neon-animation/animations/transform-animation.html">
|
||||
<link rel="import" href="../iron-collapse/iron-collapse.html">
|
||||
|
@ -37,11 +36,11 @@
|
|||
}
|
||||
</style>
|
||||
<div>
|
||||
<paper-button on-tap="toggleExpand" id="expandButton" class="emby-collapsible-button">
|
||||
<button is="emby-button" type="button" on-click="toggleExpand" id="expandButton" class="emby-collapsible-button block">
|
||||
<iron-icon id="titleIcon" icon="[[icon]]" style="[[iconstyle]]"></iron-icon>
|
||||
<h3 class="emby-collapsible-title" title="[[title]]">[[title]]</h3>
|
||||
<iron-icon id="expandIcon" style="margin-left: auto; margin-right: .5em;"></iron-icon>
|
||||
</paper-button>
|
||||
</button>
|
||||
<iron-collapse id="contentCollapse" class="emby-collapsible-content" opened="{{expanded}}">
|
||||
<content></content>
|
||||
</iron-collapse>
|
||||
|
|
|
@ -11,17 +11,16 @@
|
|||
"homepage": "https://github.com/MediaBrowser/emby-webcomponents",
|
||||
"dependencies": {
|
||||
"requirejs": "requirejs#^2.1.22",
|
||||
"isMobile": "isMobile#^0.3.9",
|
||||
"material-design-lite": "material-design-lite#^1.1.2"
|
||||
"isMobile": "isMobile#^0.3.9"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"ignore": [],
|
||||
"version": "1.3.52",
|
||||
"_release": "1.3.52",
|
||||
"version": "1.4.51",
|
||||
"_release": "1.4.51",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.3.52",
|
||||
"commit": "c00f1f1e92a8572cd01145ad02137e3eb74442fd"
|
||||
"tag": "1.4.51",
|
||||
"commit": "90b14ccc0e927221ab1d6c7556d1fadccf3876b9"
|
||||
},
|
||||
"_source": "https://github.com/MediaBrowser/emby-webcomponents.git",
|
||||
"_target": "^1.2.0",
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.actionSheetMenuItem {
|
||||
button.actionSheetMenuItem {
|
||||
padding: 0 1.6em;
|
||||
margin: 0;
|
||||
text-transform: none;
|
||||
|
@ -35,13 +35,22 @@
|
|||
display: flex;
|
||||
font-weight: inherit;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.actionSheetItemText {
|
||||
padding: .8em 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.layout-tv .actionSheetMenuItem {
|
||||
.noflex .actionSheetItemText {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.layout-tv button.actionSheetMenuItem {
|
||||
padding-top: .16em;
|
||||
padding-bottom: .16em;
|
||||
}
|
||||
|
@ -53,10 +62,15 @@
|
|||
.actionSheetScroller {
|
||||
/* Override default style being applied by polymer */
|
||||
margin-bottom: 0 !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.layout-tv .actionSheetScroller {
|
||||
max-height: 60%;
|
||||
max-width: 60%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
h1.actionSheetTitle {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(['dialogHelper', 'layoutManager', 'globalize', 'paper-button', 'css!./actionsheet', 'html!./../icons/nav.html', 'scrollStyles'], function (dialogHelper, layoutManager, globalize) {
|
||||
define(['dialogHelper', 'layoutManager', 'globalize', 'emby-button', 'css!./actionsheet', 'material-icons', 'scrollStyles'], function (dialogHelper, layoutManager, globalize) {
|
||||
|
||||
function parentWithClass(elem, className) {
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
|||
function getPosition(options, dlg) {
|
||||
|
||||
var windowHeight = window.innerHeight;
|
||||
var windowWidth = window.innerWidth;
|
||||
|
||||
if (windowHeight < 540) {
|
||||
return null;
|
||||
|
@ -58,13 +59,23 @@
|
|||
pos.top += options.positionTo.offsetHeight / 2;
|
||||
pos.left += options.positionTo.offsetWidth / 2;
|
||||
|
||||
var height = dlg.offsetHeight || 300;
|
||||
var width = dlg.offsetWidth || 160;
|
||||
|
||||
// Account for popup size
|
||||
pos.top -= ((dlg.offsetHeight || 300) / 2);
|
||||
pos.left -= ((dlg.offsetWidth || 160) / 2);
|
||||
pos.top -= height / 2;
|
||||
pos.left -= width / 2;
|
||||
|
||||
// Avoid showing too close to the bottom
|
||||
pos.top = Math.min(pos.top, windowHeight - 300);
|
||||
pos.left = Math.min(pos.left, window.innerWidth - 300);
|
||||
var overflowX = pos.left + width - windowWidth;
|
||||
var overflowY = pos.top + height - windowHeight;
|
||||
|
||||
if (overflowX > 0) {
|
||||
pos.left -= (overflowX + 20);
|
||||
}
|
||||
if (overflowY > 0) {
|
||||
pos.top -= (overflowY + 20);
|
||||
}
|
||||
|
||||
// Do some boundary checking
|
||||
pos.top = Math.max(pos.top, 10);
|
||||
|
@ -130,46 +141,51 @@
|
|||
}
|
||||
}
|
||||
|
||||
html += '<div class="actionSheetScroller hiddenScrollY">';
|
||||
var scrollType = layoutManager.desktop ? 'smoothScrollY' : 'hiddenScrollY';
|
||||
|
||||
options.items.forEach(function (o) {
|
||||
o.ironIcon = o.selected ? 'nav:check' : null;
|
||||
});
|
||||
html += '<div class="actionSheetScroller ' + scrollType + '">';
|
||||
|
||||
var itemsWithIcons = options.items.filter(function (o) {
|
||||
return o.ironIcon;
|
||||
});
|
||||
var i, length, option;
|
||||
var renderIcon = false;
|
||||
for (i = 0, length = options.items.length; i < length; i++) {
|
||||
|
||||
option = options.items[i];
|
||||
option.icon = option.selected ? 'check' : null;
|
||||
|
||||
if (option.icon) {
|
||||
renderIcon = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If any items have an icon, give them all an icon just to make sure they're all lined up evenly
|
||||
var renderIcon = itemsWithIcons.length;
|
||||
var center = options.title && (!itemsWithIcons.length /*|| itemsWithIcons.length != options.items.length*/);
|
||||
var center = options.title && (!renderIcon /*|| itemsWithIcons.length != options.items.length*/);
|
||||
|
||||
if (center) {
|
||||
dlg.classList.add('centered');
|
||||
}
|
||||
|
||||
var itemTagName = 'paper-button';
|
||||
var itemTagName = 'button';
|
||||
|
||||
for (var i = 0, length = options.items.length; i < length; i++) {
|
||||
for (i = 0, length = options.items.length; i < length; i++) {
|
||||
|
||||
var option = options.items[i];
|
||||
option = options.items[i];
|
||||
|
||||
var autoFocus = option.selected ? ' autoFocus' : '';
|
||||
html += '<' + itemTagName + autoFocus + ' class="actionSheetMenuItem" data-id="' + option.id + '">';
|
||||
html += '<' + itemTagName + autoFocus + ' is="emby-button" type="button" class="actionSheetMenuItem" data-id="' + (option.id || option.value) + '">';
|
||||
|
||||
if (option.ironIcon) {
|
||||
html += '<iron-icon class="actionSheetItemIcon" icon="' + option.ironIcon + '"></iron-icon>';
|
||||
if (option.icon) {
|
||||
html += '<i class="actionSheetItemIcon md-icon">' + option.icon + '</i>';
|
||||
}
|
||||
else if (renderIcon && !center) {
|
||||
html += '<iron-icon class="actionSheetItemIcon"></iron-icon>';
|
||||
html += '<i class="actionSheetItemIcon md-icon" style="visibility:hidden;">check</i>';
|
||||
}
|
||||
html += '<div class="actionSheetItemText">' + option.name + '</div>';
|
||||
html += '<div class="actionSheetItemText">' + (option.name || option.textContent || option.innerText) + '</div>';
|
||||
html += '</' + itemTagName + '>';
|
||||
}
|
||||
|
||||
if (options.showCancel) {
|
||||
html += '<div class="buttons">';
|
||||
html += '<paper-button class="btnCancel">' + globalize.translate('sharedcomponents#ButtonCancel') + '</paper-button>';
|
||||
html += '<button is="emby-button" type="button" class="btnCancel">' + globalize.translate('sharedcomponents#ButtonCancel') + '</button>';
|
||||
html += '</div>';
|
||||
}
|
||||
html += '</div>';
|
||||
|
@ -190,32 +206,30 @@
|
|||
|
||||
// Seeing an issue in some non-chrome browsers where this is requiring a double click
|
||||
//var eventName = browser.firefox ? 'mousedown' : 'click';
|
||||
var eventName = 'click';
|
||||
var selectedId;
|
||||
|
||||
dlg.addEventListener('click', function (e) {
|
||||
|
||||
var actionSheetMenuItem = parentWithClass(e.target, 'actionSheetMenuItem');
|
||||
|
||||
if (actionSheetMenuItem) {
|
||||
selectedId = actionSheetMenuItem.getAttribute('data-id');
|
||||
dialogHelper.close(dlg);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
dlg.addEventListener(eventName, function (e) {
|
||||
dlg.addEventListener('close', function () {
|
||||
|
||||
var actionSheetMenuItem = parentWithClass(e.target, 'actionSheetMenuItem');
|
||||
if (selectedId != null) {
|
||||
if (options.callback) {
|
||||
options.callback(selectedId);
|
||||
}
|
||||
|
||||
if (actionSheetMenuItem) {
|
||||
|
||||
var selectedId = actionSheetMenuItem.getAttribute('data-id');
|
||||
|
||||
dialogHelper.close(dlg);
|
||||
|
||||
// Add a delay here to allow the click animation to finish, for nice effect
|
||||
setTimeout(function () {
|
||||
|
||||
if (options.callback) {
|
||||
options.callback(selectedId);
|
||||
}
|
||||
|
||||
resolve(selectedId);
|
||||
|
||||
}, 100);
|
||||
resolve(selectedId);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
dialogHelper.open(dlg);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
define(['dialogHelper', 'layoutManager', 'globalize', 'html!./../icons/nav.html', 'css!./../prompt/style.css', 'paper-button', 'paper-icon-button-light', 'paper-input'], function (dialogHelper, layoutManager, globalize) {
|
||||
define(['dialogHelper', 'layoutManager', 'globalize', 'material-icons', 'css!./../prompt/style.css', 'emby-button', 'paper-icon-button-light'], function (dialogHelper, layoutManager, globalize) {
|
||||
|
||||
function getIcon(icon, cssClass, canFocus, autoFocus) {
|
||||
|
||||
var tabIndex = canFocus ? '' : ' tabindex="-1"';
|
||||
autoFocus = autoFocus ? ' autofocus' : '';
|
||||
return '<button is="paper-icon-button-light" class="' + cssClass + '"' + tabIndex + autoFocus + '><iron-icon icon="' + icon + '"></iron-icon></button>';
|
||||
return '<button is="paper-icon-button-light" class="autoSize ' + cssClass + '"' + tabIndex + autoFocus + '><i class="md-icon">' + icon + '</i></button>';
|
||||
}
|
||||
|
||||
return function (options) {
|
||||
|
@ -44,7 +44,7 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'html!./../icons/nav.html'
|
|||
|
||||
html += '<div class="promptDialogContent">';
|
||||
if (backButton) {
|
||||
html += getIcon('dialog:arrow-back', 'btnPromptExit', false);
|
||||
html += getIcon('arrow_back', 'btnPromptExit', false);
|
||||
}
|
||||
|
||||
if (options.title) {
|
||||
|
@ -72,10 +72,10 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'html!./../icons/nav.html'
|
|||
|
||||
var buttonText = options.type == 'error' ? 'sharedcomponents#ButtonOk' : 'sharedcomponents#ButtonGotIt';
|
||||
if (raisedButtons) {
|
||||
html += '<paper-button raised class="btnSubmit"><iron-icon icon="nav:check"></iron-icon><span>' + globalize.translate(buttonText) + '</span></paper-button>';
|
||||
html += '<button is="emby-button" type="button" class="raised btnSubmit"><i class="md-icon">check</i><span>' + globalize.translate(buttonText) + '</span></button>';
|
||||
} else {
|
||||
html += '<div class="buttons" style="text-align:right;">';
|
||||
html += '<paper-button class="btnSubmit">' + globalize.translate(buttonText) + '</paper-button>';
|
||||
html += '<button is="emby-button" type="button" class="btnSubmit">' + globalize.translate(buttonText) + '</button>';
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
|
|
279
dashboard-ui/bower_components/emby-webcomponents/alphapicker/alphapicker.js
vendored
Normal file
279
dashboard-ui/bower_components/emby-webcomponents/alphapicker/alphapicker.js
vendored
Normal file
|
@ -0,0 +1,279 @@
|
|||
define(['focusManager', 'css!./style.css', 'clearButtonStyle', 'paper-icon-button-light', 'material-icons'], function (focusManager) {
|
||||
|
||||
function focus() {
|
||||
var selected = this.querySelector('.selected');
|
||||
|
||||
if (selected) {
|
||||
focusManager.focus(selected);
|
||||
} else {
|
||||
focusManager.autoFocus(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
function getLetterButton(l) {
|
||||
return '<button data-value="' + l + '" class="clearButton alphaPickerButton">' + l + '</button>';
|
||||
}
|
||||
|
||||
function render(element, options) {
|
||||
|
||||
element.classList.add('alphaPicker');
|
||||
element.classList.add('focuscontainer-x');
|
||||
|
||||
var html = '';
|
||||
var letters;
|
||||
|
||||
html += '<div class="alphaPickerRow">';
|
||||
if (options.mode == 'keyboard') {
|
||||
html += '<button data-value=" " is="paper-icon-button-light" class="alphaPickerButton autoSize">\
|
||||
<i class="md-icon">space_bar</i>\
|
||||
</button>';
|
||||
} else {
|
||||
letters = ['#'];
|
||||
html += letters.map(getLetterButton).join('');
|
||||
}
|
||||
|
||||
letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
|
||||
html += letters.map(getLetterButton).join('');
|
||||
|
||||
if (options.mode == 'keyboard') {
|
||||
html += '<button data-value="backspace" is="paper-icon-button-light" class="alphaPickerButton autoSize">\
|
||||
<i class="md-icon">backspace</i>\
|
||||
</button>';
|
||||
html += '</div>';
|
||||
|
||||
letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
html += '<div class="alphaPickerRow">';
|
||||
html += '<br/>';
|
||||
html += letters.map(getLetterButton).join('');
|
||||
html += '</div>';
|
||||
} else {
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
element.innerHTML = html;
|
||||
|
||||
element.classList.add('focusable');
|
||||
element.focus = focus;
|
||||
}
|
||||
|
||||
function alphaPicker(options) {
|
||||
|
||||
var self = this;
|
||||
|
||||
var element = options.element;
|
||||
var itemsContainer = options.itemsContainer;
|
||||
var itemClass = options.itemClass;
|
||||
|
||||
var itemFocusValue;
|
||||
var itemFocusTimeout;
|
||||
|
||||
function onItemFocusTimeout() {
|
||||
itemFocusTimeout = null;
|
||||
self.value(itemFocusValue);
|
||||
}
|
||||
|
||||
var alphaFocusedElement;
|
||||
var alphaFocusTimeout;
|
||||
|
||||
function onAlphaFocusTimeout() {
|
||||
|
||||
alphaFocusTimeout = null;
|
||||
|
||||
if (document.activeElement == alphaFocusedElement) {
|
||||
var value = alphaFocusedElement.getAttribute('data-value');
|
||||
self.value(value, true);
|
||||
}
|
||||
}
|
||||
|
||||
function parentWithClass(elem, className) {
|
||||
|
||||
while (!elem.classList || !elem.classList.contains(className)) {
|
||||
elem = elem.parentNode;
|
||||
|
||||
if (!elem) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
function onAlphaPickerInKeyboardModeClick(e) {
|
||||
|
||||
var alphaPickerButton = parentWithClass(e.target, 'alphaPickerButton');
|
||||
|
||||
if (alphaPickerButton) {
|
||||
var value = alphaPickerButton.getAttribute('data-value');
|
||||
|
||||
element.dispatchEvent(new CustomEvent("alphavalueclicked", {
|
||||
detail: {
|
||||
value: value
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
function onAlphaPickerClick(e) {
|
||||
|
||||
var alphaPickerButton = parentWithClass(e.target, 'alphaPickerButton');
|
||||
|
||||
if (alphaPickerButton) {
|
||||
var value = alphaPickerButton.getAttribute('data-value');
|
||||
|
||||
if (currentValue == value.toUpperCase()) {
|
||||
self.value(null, true);
|
||||
} else {
|
||||
self.value(value, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onAlphaPickerFocusIn(e) {
|
||||
|
||||
if (alphaFocusTimeout) {
|
||||
clearTimeout(alphaFocusTimeout);
|
||||
alphaFocusTimeout = null;
|
||||
}
|
||||
|
||||
var alphaPickerButton = parentWithClass(e.target, 'alphaPickerButton');
|
||||
|
||||
if (alphaPickerButton) {
|
||||
alphaFocusedElement = alphaPickerButton;
|
||||
alphaFocusTimeout = setTimeout(onAlphaFocusTimeout, 100);
|
||||
}
|
||||
}
|
||||
|
||||
function onItemsFocusIn(e) {
|
||||
|
||||
var item = parentWithClass(e.target, itemClass);
|
||||
|
||||
if (item) {
|
||||
var prefix = item.getAttribute('data-prefix');
|
||||
if (prefix && prefix.length) {
|
||||
|
||||
itemFocusValue = prefix[0];
|
||||
if (itemFocusTimeout) {
|
||||
clearTimeout(itemFocusTimeout);
|
||||
}
|
||||
itemFocusTimeout = setTimeout(onItemFocusTimeout, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.enabled = function (enabled) {
|
||||
|
||||
if (enabled) {
|
||||
|
||||
if (itemsContainer) {
|
||||
itemsContainer.addEventListener('focus', onItemsFocusIn, true);
|
||||
}
|
||||
|
||||
if (options.mode == 'keyboard') {
|
||||
element.addEventListener('click', onAlphaPickerInKeyboardModeClick);
|
||||
}
|
||||
|
||||
if (options.valueChangeEvent !== 'click') {
|
||||
element.addEventListener('focus', onAlphaPickerFocusIn, true);
|
||||
} else {
|
||||
element.addEventListener('click', onAlphaPickerClick);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (itemsContainer) {
|
||||
itemsContainer.removeEventListener('focus', onItemsFocusIn, true);
|
||||
}
|
||||
|
||||
element.removeEventListener('click', onAlphaPickerInKeyboardModeClick);
|
||||
element.removeEventListener('focus', onAlphaPickerFocusIn, true);
|
||||
element.removeEventListener('click', onAlphaPickerClick);
|
||||
}
|
||||
};
|
||||
|
||||
self.on = function (name, fn) {
|
||||
element.addEventListener(name, fn);
|
||||
};
|
||||
|
||||
self.off = function (name, fn) {
|
||||
element.removeEventListener(name, fn);
|
||||
};
|
||||
|
||||
self.destroy = function () {
|
||||
|
||||
self.enabled(false);
|
||||
element.classList.remove('focuscontainer-x');
|
||||
};
|
||||
|
||||
self.visible = function (visible) {
|
||||
|
||||
element.style.visibility = visible ? 'visible' : 'hidden';
|
||||
};
|
||||
|
||||
var currentValue;
|
||||
self.value = function (value, applyValue) {
|
||||
|
||||
var btn, selected;
|
||||
|
||||
if (value !== undefined) {
|
||||
if (value != null) {
|
||||
|
||||
value = value.toUpperCase();
|
||||
currentValue = value;
|
||||
|
||||
if (options.mode != 'keyboard') {
|
||||
selected = element.querySelector('.selected');
|
||||
btn = element.querySelector('.alphaPickerButton[data-value=\'' + value + '\']');
|
||||
|
||||
if (btn && btn != selected) {
|
||||
btn.classList.add('selected');
|
||||
}
|
||||
if (selected && selected != btn) {
|
||||
selected.classList.remove('selected');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
currentValue = value;
|
||||
|
||||
selected = element.querySelector('.selected');
|
||||
if (selected) {
|
||||
selected.classList.remove('selected');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (applyValue) {
|
||||
element.dispatchEvent(new CustomEvent("alphavaluechanged", {
|
||||
detail: {
|
||||
value: value
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
return currentValue;
|
||||
};
|
||||
|
||||
self.values = function () {
|
||||
|
||||
var elems = element.querySelectorAll('.alphaPickerButton');
|
||||
var values = [];
|
||||
for (var i = 0, length = elems.length; i < length; i++) {
|
||||
|
||||
values.push(elems[i].getAttribute('data-value'));
|
||||
|
||||
}
|
||||
|
||||
return values;
|
||||
};
|
||||
|
||||
self.focus = function () {
|
||||
focusManager.autoFocus(element, true);
|
||||
};
|
||||
|
||||
render(element, options);
|
||||
|
||||
self.enabled(true);
|
||||
self.visible(true);
|
||||
}
|
||||
|
||||
return alphaPicker;
|
||||
});
|
52
dashboard-ui/bower_components/emby-webcomponents/alphapicker/style.css
vendored
Normal file
52
dashboard-ui/bower_components/emby-webcomponents/alphapicker/style.css
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
.alphaPicker {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.alphaPickerRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.alphaPicker.vertical .alphaPickerRow {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
button.alphaPickerButton {
|
||||
min-width: initial;
|
||||
margin: 0;
|
||||
padding: .1em .4em !important;
|
||||
width: auto;
|
||||
border-radius: .1em;
|
||||
font-weight: normal;
|
||||
opacity: .25;
|
||||
}
|
||||
|
||||
.vertical .alphaPickerButton {
|
||||
padding: .25em .4em !important;
|
||||
}
|
||||
|
||||
.layout-desktop .alphaPickerButton {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
[is=paper-icon-button-light].alphaPickerButton i {
|
||||
width: 3.3vh;
|
||||
height: 3.3vh;
|
||||
font-size: 3.3vh;
|
||||
}
|
||||
|
||||
.alphaPickerButton.selected {
|
||||
color: #000;
|
||||
background-color: #bbb;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.layout-tv .alphaPickerButton:focus {
|
||||
background-color: #52B54B;
|
||||
opacity: 1;
|
||||
color: #fff;
|
||||
}
|
|
@ -13,6 +13,15 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
|
||||
var self = this;
|
||||
|
||||
self.enableAutoLogin = function (val) {
|
||||
|
||||
if (val != null) {
|
||||
self.set('enableAutoLogin', val.toString());
|
||||
}
|
||||
|
||||
return self.get('enableAutoLogin') != 'false';
|
||||
};
|
||||
|
||||
self.enableAutomaticBitrateDetection = function (val) {
|
||||
|
||||
if (val != null) {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
define(['browser', 'css!./style'], function (browser) {
|
||||
define(['browser', 'connectionManager', 'playbackManager', 'css!./style'], function (browser, connectionManager, playbackManager) {
|
||||
|
||||
function enableAnimation(elem) {
|
||||
|
||||
if (browser.mobile) {
|
||||
i
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -99,6 +100,8 @@
|
|||
|
||||
function clearBackdrop(clearAll) {
|
||||
|
||||
clearRotation();
|
||||
|
||||
if (currentLoadingBackdrop) {
|
||||
currentLoadingBackdrop.destroy();
|
||||
currentLoadingBackdrop = null;
|
||||
|
@ -114,16 +117,18 @@
|
|||
}
|
||||
|
||||
var skinContainer;
|
||||
function setSkinContainerBackgroundEnabled() {
|
||||
|
||||
function getSkinContainer() {
|
||||
if (!skinContainer) {
|
||||
skinContainer = document.querySelector('.skinContainer');
|
||||
}
|
||||
return skinContainer;
|
||||
}
|
||||
function setSkinContainerBackgroundEnabled() {
|
||||
|
||||
if (hasInternalBackdrop || hasExternalBackdrop) {
|
||||
skinContainer.classList.add('withBackdrop');
|
||||
getSkinContainer().classList.add('withBackdrop');
|
||||
} else {
|
||||
skinContainer.classList.remove('withBackdrop');
|
||||
getSkinContainer().classList.remove('withBackdrop');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,58 +171,145 @@
|
|||
currentLoadingBackdrop = instance;
|
||||
}
|
||||
|
||||
function setBackdrops(items) {
|
||||
var windowWidth;
|
||||
function resetWindowSize() {
|
||||
windowWidth = screen.availWidth || window.innerWidth;
|
||||
}
|
||||
window.addEventListener("orientationchange", resetWindowSize);
|
||||
window.addEventListener('resize', resetWindowSize);
|
||||
resetWindowSize();
|
||||
|
||||
var images = items.map(function (i) {
|
||||
function getItemImageUrls(item) {
|
||||
|
||||
if (i.BackdropImageTags && i.BackdropImageTags.length > 0) {
|
||||
return {
|
||||
id: i.Id,
|
||||
tag: i.BackdropImageTags[0],
|
||||
serverId: i.ServerId
|
||||
};
|
||||
}
|
||||
var apiClient = connectionManager.getApiClient(item.ServerId);
|
||||
|
||||
if (i.ParentBackdropItemId && i.ParentBackdropImageTags && i.ParentBackdropImageTags.length) {
|
||||
if (item.BackdropImageTags && item.BackdropImageTags.length > 0) {
|
||||
|
||||
return {
|
||||
id: i.ParentBackdropItemId,
|
||||
tag: i.ParentBackdropImageTags[0],
|
||||
serverId: i.ServerId
|
||||
};
|
||||
}
|
||||
return null;
|
||||
return item.BackdropImageTags.map(function (imgTag, index) {
|
||||
|
||||
}).filter(function (i) {
|
||||
return i != null;
|
||||
});
|
||||
return apiClient.getScaledImageUrl(item.Id, {
|
||||
type: "Backdrop",
|
||||
tag: imgTag,
|
||||
maxWidth: Math.min(windowWidth, 1920),
|
||||
index: index
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) {
|
||||
|
||||
return item.ParentBackdropImageTags.map(function (imgTag, index) {
|
||||
|
||||
return apiClient.getScaledImageUrl(item.ParentBackdropItemId, {
|
||||
type: "Backdrop",
|
||||
tag: imgTag,
|
||||
maxWidth: Math.min(windowWidth, 1920),
|
||||
index: index
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function getImageUrls(items) {
|
||||
|
||||
var list = [];
|
||||
|
||||
for (var i = 0, length = items.length; i < length; i++) {
|
||||
|
||||
var itemImages = getItemImageUrls(items[i]);
|
||||
|
||||
itemImages.forEach(function (img) {
|
||||
list.push(img);
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
function arraysEqual(a, b) {
|
||||
if (a === b) return true;
|
||||
if (a == null || b == null) return false;
|
||||
if (a.length != b.length) return false;
|
||||
|
||||
// If you don't care about the order of the elements inside
|
||||
// the array, you should sort both arrays here.
|
||||
|
||||
for (var i = 0; i < a.length; ++i) {
|
||||
if (a[i] !== b[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var rotationInterval;
|
||||
var currentRotatingImages = [];
|
||||
var currentRotationIndex = -1;
|
||||
function setBackdrops(items, imageSetId) {
|
||||
|
||||
var images = getImageUrls(items);
|
||||
|
||||
imageSetId = imageSetId || new Date().getTime();
|
||||
if (images.length) {
|
||||
|
||||
var index = getRandom(0, images.length - 1);
|
||||
var item = images[index];
|
||||
|
||||
require(['connectionManager'], function (connectionManager) {
|
||||
|
||||
var apiClient = connectionManager.getApiClient(item.serverId);
|
||||
var imgUrl = apiClient.getScaledImageUrl(item.id, {
|
||||
type: "Backdrop",
|
||||
tag: item.tag,
|
||||
//maxWidth: window.innerWidth,
|
||||
quality: 100
|
||||
});
|
||||
|
||||
setBackdrop(imgUrl);
|
||||
});
|
||||
startRotation(images, imageSetId);
|
||||
|
||||
} else {
|
||||
clearBackdrop();
|
||||
}
|
||||
}
|
||||
|
||||
function startRotation(images) {
|
||||
|
||||
if (arraysEqual(images, currentRotatingImages)) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearRotation();
|
||||
|
||||
currentRotatingImages = images;
|
||||
currentRotationIndex = -1;
|
||||
|
||||
if (images.length > 1) {
|
||||
rotationInterval = setInterval(onRotationInterval, 20000);
|
||||
}
|
||||
onRotationInterval();
|
||||
}
|
||||
|
||||
function onRotationInterval() {
|
||||
|
||||
if (playbackManager.isPlayingVideo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var newIndex = currentRotationIndex + 1;
|
||||
if (newIndex >= currentRotatingImages.length) {
|
||||
newIndex = 0;
|
||||
}
|
||||
|
||||
currentRotationIndex = newIndex;
|
||||
setBackdropImage(currentRotatingImages[newIndex]);
|
||||
}
|
||||
|
||||
function clearRotation() {
|
||||
var interval = rotationInterval;
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
rotationInterval = null;
|
||||
currentRotatingImages = [];
|
||||
currentRotationIndex = -1;
|
||||
}
|
||||
|
||||
function setBackdrop(url) {
|
||||
|
||||
if (typeof url !== 'string') {
|
||||
url = getImageUrls([url])[0];
|
||||
}
|
||||
|
||||
if (url) {
|
||||
clearRotation();
|
||||
|
||||
setBackdropImage(url);
|
||||
|
||||
} else {
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
.backdropContainer {
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
.backdropImage {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
|
@ -8,4 +12,5 @@
|
|||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
contain: layout style;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
"homepage": "https://github.com/MediaBrowser/emby-webcomponents",
|
||||
"dependencies": {
|
||||
"requirejs": "requirejs#^2.1.22",
|
||||
"isMobile": "isMobile#^0.3.9",
|
||||
"material-design-lite": "material-design-lite#^1.1.2"
|
||||
"isMobile": "isMobile#^0.3.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
|
|
|
@ -101,5 +101,7 @@
|
|||
browser.tv = isTv();
|
||||
browser.operaTv = browser.tv && userAgent.toLowerCase().indexOf('opr/') != -1;
|
||||
|
||||
browser.noFlex = browser.tv && !browser.chrome && !browser.operaTv;
|
||||
|
||||
return browser;
|
||||
});
|
|
@ -151,6 +151,11 @@ define(['browser'], function (browser) {
|
|||
|
||||
function getMaxBitrate() {
|
||||
|
||||
// 10mbps
|
||||
if (browser.xboxOne) {
|
||||
return 10000000;
|
||||
}
|
||||
|
||||
var userAgent = navigator.userAgent.toLowerCase();
|
||||
|
||||
if (browser.tizen) {
|
||||
|
|
280
dashboard-ui/bower_components/emby-webcomponents/collectioneditor/collectioneditor.js
vendored
Normal file
280
dashboard-ui/bower_components/emby-webcomponents/collectioneditor/collectioneditor.js
vendored
Normal file
|
@ -0,0 +1,280 @@
|
|||
define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionManager', 'scrollHelper', 'embyRouter', 'globalize', 'emby-checkbox', 'emby-input', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button'], function (shell, dialogHelper, loading, layoutManager, connectionManager, scrollHelper, embyRouter, globalize) {
|
||||
|
||||
var currentServerId;
|
||||
|
||||
function parentWithClass(elem, className) {
|
||||
|
||||
while (!elem.classList || !elem.classList.contains(className)) {
|
||||
elem = elem.parentNode;
|
||||
|
||||
if (!elem) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
function onSubmit(e) {
|
||||
loading.show();
|
||||
|
||||
var panel = parentWithClass(this, 'dialog');
|
||||
|
||||
var collectionId = panel.querySelector('#selectCollectionToAddTo').value;
|
||||
|
||||
var apiClient = connectionManager.getApiClient(currentServerId);
|
||||
|
||||
if (collectionId) {
|
||||
addToCollection(apiClient, panel, collectionId);
|
||||
} else {
|
||||
createCollection(apiClient, panel);
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
function createCollection(apiClient, dlg) {
|
||||
|
||||
var url = apiClient.getUrl("Collections", {
|
||||
|
||||
Name: dlg.querySelector('#txtNewCollectionName').value,
|
||||
IsLocked: !dlg.querySelector('#chkEnableInternetMetadata').checked,
|
||||
Ids: dlg.querySelector('.fldSelectedItemIds').value || ''
|
||||
|
||||
//ParentId: getParameterByName('parentId') || LibraryMenu.getTopParentId()
|
||||
|
||||
});
|
||||
|
||||
apiClient.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
dataType: "json"
|
||||
|
||||
}).then(function (result) {
|
||||
|
||||
loading.hide();
|
||||
|
||||
var id = result.Id;
|
||||
|
||||
dialogHelper.close(dlg);
|
||||
redirectToCollection(apiClient, id);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function redirectToCollection(apiClient, id) {
|
||||
|
||||
apiClient.getItem(apiClient.getCurrentUserId(), id).then(function (item) {
|
||||
|
||||
embyRouter.showItem(item);
|
||||
});
|
||||
}
|
||||
|
||||
function addToCollection(apiClient, dlg, id) {
|
||||
|
||||
var url = apiClient.getUrl("Collections/" + id + "/Items", {
|
||||
|
||||
Ids: dlg.querySelector('.fldSelectedItemIds').value || ''
|
||||
});
|
||||
|
||||
apiClient.ajax({
|
||||
type: "POST",
|
||||
url: url
|
||||
|
||||
}).then(function () {
|
||||
|
||||
loading.hide();
|
||||
|
||||
dialogHelper.close(dlg);
|
||||
|
||||
require(['toast'], function (toast) {
|
||||
toast(globalize.translate('sharedcomponents#MessageItemsAdded'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function triggerChange(select) {
|
||||
select.dispatchEvent(new CustomEvent('change', {}));
|
||||
}
|
||||
|
||||
function populateCollections(panel) {
|
||||
|
||||
loading.show();
|
||||
|
||||
var select = panel.querySelector('#selectCollectionToAddTo');
|
||||
|
||||
panel.querySelector('.newCollectionInfo').classList.add('hide');
|
||||
|
||||
var options = {
|
||||
|
||||
Recursive: true,
|
||||
IncludeItemTypes: "BoxSet",
|
||||
SortBy: "SortName"
|
||||
};
|
||||
|
||||
var apiClient = connectionManager.getApiClient(currentServerId);
|
||||
apiClient.getItems(apiClient.getCurrentUserId(), options).then(function (result) {
|
||||
|
||||
var html = '';
|
||||
|
||||
html += '<option value="">' + globalize.translate('sharedcomponents#OptionNew') + '</option>';
|
||||
|
||||
html += result.Items.map(function (i) {
|
||||
|
||||
return '<option value="' + i.Id + '">' + i.Name + '</option>';
|
||||
});
|
||||
|
||||
select.innerHTML = html;
|
||||
select.value = '';
|
||||
triggerChange(select);
|
||||
|
||||
loading.hide();
|
||||
});
|
||||
}
|
||||
|
||||
function getEditorHtml() {
|
||||
|
||||
var html = '';
|
||||
|
||||
html += '<div class="dialogContent smoothScrollY">';
|
||||
html += '<div class="dialogContentInner centeredContent">';
|
||||
html += '<form class="newCollectionForm" style="margin:auto;">';
|
||||
|
||||
html += '<div>';
|
||||
html += globalize.translate('sharedcomponents#NewCollectionHelp');
|
||||
html += '</div>';
|
||||
|
||||
html += '<div class="fldSelectCollection">';
|
||||
html += '<br/>';
|
||||
html += '<br/>';
|
||||
html += '<select is="emby-select" label="' + globalize.translate('sharedcomponents#LabelCollection') + '" id="selectCollectionToAddTo" autofocus></select>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<div class="newCollectionInfo">';
|
||||
|
||||
html += '<div class="inputContainer">';
|
||||
html += '<input is="emby-input" type="text" id="txtNewCollectionName" required="required" label="' + globalize.translate('sharedcomponents#LabelName') + '" />';
|
||||
html += '<div class="fieldDescription">' + globalize.translate('sharedcomponents#NewCollectionNameExample') + '</div>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<label class="checkboxContainer">';
|
||||
html += '<input is="emby-checkbox" type="checkbox" id="chkEnableInternetMetadata" />';
|
||||
html += '<span>' + globalize.translate('sharedcomponents#SearchForCollectionInternetMetadata') + '</span>';
|
||||
html += '</label>';
|
||||
|
||||
// newCollectionInfo
|
||||
html += '</div>';
|
||||
|
||||
html += '<div>';
|
||||
html += '<button is="emby-button" type="submit" class="raised btnSubmit block">' + globalize.translate('sharedcomponents#ButtonOk') + '</button>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<input type="hidden" class="fldSelectedItemIds" />';
|
||||
|
||||
html += '</form>';
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function onHelpClick(e) {
|
||||
|
||||
shell.openUrl(this.href);
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
function initEditor(content, items) {
|
||||
|
||||
content.querySelector('#selectCollectionToAddTo').addEventListener('change', function () {
|
||||
if (this.value) {
|
||||
content.querySelector('.newCollectionInfo').classList.add('hide');
|
||||
content.querySelector('#txtNewCollectionName').removeAttribute('required');
|
||||
} else {
|
||||
content.querySelector('.newCollectionInfo').classList.remove('hide');
|
||||
content.querySelector('#txtNewCollectionName').setAttribute('required', 'required');
|
||||
}
|
||||
});
|
||||
|
||||
content.querySelector('form').addEventListener('submit', onSubmit);
|
||||
|
||||
content.querySelector('.fldSelectedItemIds', content).value = items.join(',');
|
||||
|
||||
if (items.length) {
|
||||
content.querySelector('.fldSelectCollection').classList.remove('hide');
|
||||
populateCollections(content);
|
||||
} else {
|
||||
content.querySelector('.fldSelectCollection').classList.add('hide');
|
||||
|
||||
var selectCollectionToAddTo = content.querySelector('#selectCollectionToAddTo');
|
||||
selectCollectionToAddTo.innerHTML = '';
|
||||
selectCollectionToAddTo.value = '';
|
||||
triggerChange(selectCollectionToAddTo);
|
||||
}
|
||||
}
|
||||
|
||||
function collectioneditor() {
|
||||
|
||||
var self = this;
|
||||
|
||||
self.show = function (options) {
|
||||
|
||||
var items = options.items || {};
|
||||
currentServerId = options.serverId;
|
||||
|
||||
var dialogOptions = {
|
||||
removeOnClose: true,
|
||||
scrollY: false
|
||||
};
|
||||
|
||||
if (layoutManager.tv) {
|
||||
dialogOptions.size = 'fullscreen';
|
||||
} else {
|
||||
dialogOptions.size = 'small';
|
||||
}
|
||||
|
||||
var dlg = dialogHelper.createDialog(dialogOptions);
|
||||
|
||||
dlg.classList.add('formDialog');
|
||||
|
||||
var html = '';
|
||||
var title = items.length ? globalize.translate('sharedcomponents#AddToCollection') : globalize.translate('sharedcomponents#NewCollection');
|
||||
|
||||
html += '<div class="dialogHeader" style="margin:0 0 2em;">';
|
||||
html += '<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="md-icon">arrow_back</i></button>';
|
||||
html += '<div class="dialogHeaderTitle">';
|
||||
html += title;
|
||||
html += '</div>';
|
||||
|
||||
html += '<a class="btnHelp" href="https://github.com/MediaBrowser/Wiki/wiki/Collections" target="_blank" style="margin-left:auto;margin-right:.5em;display:inline-block;padding:.25em;display:flex;align-items:center;" title="' + globalize.translate('sharedcomponents#Help') + '"><i class="md-icon">info</i><span style="margin-left:.25em;">' + globalize.translate('sharedcomponents#Help') + '</span></a>';
|
||||
|
||||
html += '</div>';
|
||||
|
||||
html += getEditorHtml();
|
||||
|
||||
dlg.innerHTML = html;
|
||||
document.body.appendChild(dlg);
|
||||
|
||||
initEditor(dlg, items);
|
||||
|
||||
dlg.querySelector('.btnCancel').addEventListener('click', function () {
|
||||
|
||||
dialogHelper.close(dlg);
|
||||
});
|
||||
|
||||
if (layoutManager.tv) {
|
||||
scrollHelper.centerFocus.on(dlg.querySelector('.dialogContent'), false);
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
dlg.addEventListener('close', resolve);
|
||||
dialogHelper.open(dlg);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
return collectioneditor;
|
||||
});
|
|
@ -74,9 +74,9 @@ define(['layoutManager', 'globalize'], function (layoutManager, globalize) {
|
|||
|
||||
html += '<div class="buttons">';
|
||||
|
||||
html += '<paper-button class="btnConfirm" autofocus>' + globalize.translate('sharedcomponents#ButtonOk') + '</paper-button>';
|
||||
html += '<button is="emby-button" type="button" class="btnConfirm" autofocus>' + globalize.translate('sharedcomponents#ButtonOk') + '</button>';
|
||||
|
||||
html += '<paper-button class="btnCancel">' + globalize.translate('sharedcomponents#ButtonCancel') + '</paper-button>';
|
||||
html += '<button is="emby-button" type="button" class="btnCancel">' + globalize.translate('sharedcomponents#ButtonCancel') + '</button>';
|
||||
|
||||
html += '</div>';
|
||||
|
||||
|
@ -106,7 +106,7 @@ define(['layoutManager', 'globalize'], function (layoutManager, globalize) {
|
|||
function showConfirm(options) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
require(['dialogHelper', 'paper-button'], function (dialogHelper) {
|
||||
require(['dialogHelper', 'emby-button'], function (dialogHelper) {
|
||||
showConfirmInternal(options, dialogHelper, resolve, reject);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
border: 0;
|
||||
padding: 0;
|
||||
will-change: transform;
|
||||
contain: style;
|
||||
}
|
||||
|
||||
.dialog.fixedSize {
|
||||
|
@ -29,6 +30,7 @@
|
|||
top: 50%;
|
||||
left: 50%;
|
||||
max-width: 70%;
|
||||
max-height: 84%;
|
||||
}
|
||||
|
||||
@media all and (min-width: 1280px) and (min-height: 720px) {
|
||||
|
@ -92,7 +94,7 @@
|
|||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
margin: 0 !important;
|
||||
z-index: 999998 !important;
|
||||
z-index: 999999 !important;
|
||||
transition: opacity ease-out 0.2s;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,19 @@
|
|||
|
||||
var globalOnOpenCallback;
|
||||
|
||||
function enableAnimation() {
|
||||
|
||||
if (browser.animate) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (browser.edge) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function dialogHashHandler(dlg, hash, resolve) {
|
||||
|
||||
var self = this;
|
||||
|
@ -129,8 +142,8 @@
|
|||
|
||||
dlg.addEventListener('click', function (event) {
|
||||
var rect = dlg.getBoundingClientRect();
|
||||
var isInDialog = (rect.top <= event.clientY && event.clientY <= rect.top + rect.height
|
||||
&& rect.left <= event.clientX && event.clientX <= rect.left + rect.width);
|
||||
var isInDialog = (rect.top <= event.clientY && event.clientY <= (rect.top + rect.height)
|
||||
&& rect.left <= event.clientX && event.clientX <= (rect.left + rect.width));
|
||||
|
||||
if (!isInDialog) {
|
||||
if (parentWithTag(event.target, 'SELECT')) {
|
||||
|
@ -150,7 +163,7 @@
|
|||
// Without this, seeing some script errors in Firefox
|
||||
// Also for some reason it won't auto-focus without a delay here, still investigating that
|
||||
|
||||
var delay = browser.animate ? 0 : 300;
|
||||
var delay = enableAnimation() ? 300 : 300;
|
||||
|
||||
setTimeout(function () {
|
||||
focusManager.autoFocus(dlg);
|
||||
|
@ -167,7 +180,7 @@
|
|||
|
||||
var backdrop = document.createElement('div');
|
||||
backdrop.classList.add('dialogBackdrop');
|
||||
dlg.parentNode.insertBefore(backdrop, dlg.nextSibling);
|
||||
dlg.parentNode.insertBefore(backdrop, dlg);
|
||||
dlg.backdrop = backdrop;
|
||||
|
||||
// Doing this immediately causes the opacity to jump immediately without animating
|
||||
|
@ -240,6 +253,15 @@
|
|||
return elem.animate(keyframes, timing).onfinish = onFinish;
|
||||
}
|
||||
|
||||
function scaleDown(elem) {
|
||||
|
||||
var keyframes = [
|
||||
{ transform: 'none', opacity: 1, offset: 0 },
|
||||
{ transform: 'scale(0)', opacity: 0, offset: 1 }];
|
||||
var timing = elem.animationConfig.exit.timing;
|
||||
return elem.animate(keyframes, timing);
|
||||
}
|
||||
|
||||
function fadeOut(elem) {
|
||||
|
||||
var keyframes = [
|
||||
|
@ -282,6 +304,8 @@
|
|||
|
||||
if (dlg.animationConfig.exit.name == 'fadeout') {
|
||||
animation = fadeOut(dlg);
|
||||
} else if (dlg.animationConfig.exit.name == 'scaledown') {
|
||||
animation = scaleDown(dlg);
|
||||
} else if (dlg.animationConfig.exit.name == 'slidedown') {
|
||||
animation = slideDown(dlg);
|
||||
} else {
|
||||
|
@ -386,33 +410,40 @@
|
|||
dlg.setAttribute('data-autofocus', 'true');
|
||||
}
|
||||
|
||||
var defaultEntryAnimation = browser.animate ? 'scaleup' : 'fadein';
|
||||
dlg.entryAnimation = options.entryAnimation || defaultEntryAnimation;
|
||||
dlg.exitAnimation = 'fadeout';
|
||||
var defaultEntryAnimation = 'scaleup';
|
||||
var entryAnimation = options.entryAnimation || defaultEntryAnimation;
|
||||
var defaultExitAnimation = 'scaledown';
|
||||
var exitAnimation = options.exitAnimation || defaultExitAnimation;
|
||||
|
||||
// If it's not fullscreen then lower the default animation speed to make it open really fast
|
||||
var entryAnimationDuration = options.entryAnimationDuration || (options.size ? 200 : 300);
|
||||
var exitAnimationDuration = options.exitAnimationDuration || (options.size ? 200 : 300);
|
||||
|
||||
dlg.animationConfig = {
|
||||
// scale up
|
||||
'entry': {
|
||||
name: dlg.entryAnimation,
|
||||
name: entryAnimation,
|
||||
node: dlg,
|
||||
timing: { duration: entryAnimationDuration, easing: 'ease-out' }
|
||||
timing: {
|
||||
duration: entryAnimationDuration,
|
||||
easing: 'ease-out'
|
||||
}
|
||||
},
|
||||
// fade out
|
||||
'exit': {
|
||||
name: dlg.exitAnimation,
|
||||
name: exitAnimation,
|
||||
node: dlg,
|
||||
timing: { duration: options.exitAnimationDuration || 300, easing: 'ease-in' }
|
||||
timing: {
|
||||
duration: exitAnimationDuration,
|
||||
easing: 'ease-out',
|
||||
fill: 'both'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// too buggy in IE, not even worth it
|
||||
if (!browser.animate) {
|
||||
if (!enableAnimation()) {
|
||||
dlg.animationConfig = null;
|
||||
dlg.entryAnimation = null;
|
||||
dlg.exitAnimation = null;
|
||||
}
|
||||
|
||||
dlg.classList.add('dialog');
|
||||
|
|
250
dashboard-ui/bower_components/emby-webcomponents/emby-button/emby-button.css
vendored
Normal file
250
dashboard-ui/bower_components/emby-webcomponents/emby-button/emby-button.css
vendored
Normal file
|
@ -0,0 +1,250 @@
|
|||
[is="emby-button"] {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
margin: 0 .29em;
|
||||
background: transparent;
|
||||
text-align: center;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
color: inherit;
|
||||
outline-width: 0;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
z-index: 0;
|
||||
padding: 0.7em 0.57em;
|
||||
font-weight: normal;
|
||||
vertical-align: middle;
|
||||
border: 0;
|
||||
vertical-align: middle;
|
||||
border-radius: 3px;
|
||||
/* These are getting an outline in opera tv browsers, which run chrome 30 */
|
||||
outline: none !important;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
[is="emby-button"].raised, [is="emby-button"].fab {
|
||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
[is="emby-button"].fab {
|
||||
display: inline-flex;
|
||||
border-radius: 50%;
|
||||
min-width: 56px;
|
||||
min-height: 56px;
|
||||
height: 5.2vh;
|
||||
width: 5.2vh;
|
||||
background-color: #444;
|
||||
padding: .6em;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
color: #fff !important;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
[is="emby-button"].fab i {
|
||||
height: 4.4vh;
|
||||
width: 4.4vh;
|
||||
vertical-align: middle;
|
||||
font-size: 4.4vh;
|
||||
}
|
||||
|
||||
[is="emby-button"].noflex {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
[is="emby-button"].fab.mini:not(.autoSize) {
|
||||
min-width: 40px !important;
|
||||
min-height: 40px !important;
|
||||
height: 3.3vh !important;
|
||||
width: 3.3vh !important;
|
||||
}
|
||||
|
||||
[is="emby-button"].fab.mini {
|
||||
padding: .4em;
|
||||
}
|
||||
|
||||
[is="emby-button"].fab.mini i {
|
||||
height: 2.4vh !important;
|
||||
width: 2.4vh !important;
|
||||
font-size: 2.4vh !important;
|
||||
}
|
||||
|
||||
[is="emby-button"].fab iron-icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
[is="emby-button"].fab i {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
[is="emby-button"].block {
|
||||
display: block;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: .25em 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
[is="emby-button"].raised:focus {
|
||||
box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.4);
|
||||
transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
[is="emby-button"] iron-icon + span {
|
||||
margin-left: .5em;
|
||||
}
|
||||
|
||||
[is="emby-button"] i + span {
|
||||
margin-left: .5em;
|
||||
}
|
||||
|
||||
[is=emby-button].autoSize {
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
min-height: initial !important;
|
||||
min-width: initial !important;
|
||||
}
|
||||
|
||||
[is=paper-icon-button-light] {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
margin: 0 .29em;
|
||||
background: transparent;
|
||||
text-align: center;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
color: inherit;
|
||||
outline-width: 0;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
z-index: 0;
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 8px;
|
||||
font-weight: normal;
|
||||
vertical-align: middle;
|
||||
border: 0;
|
||||
vertical-align: middle;
|
||||
/* These are getting an outline in opera tv browsers, which run chrome 30 */
|
||||
outline: none !important;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
border-radius: 50%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
[is=paper-icon-button-light].autoSize {
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
[is=paper-icon-button-light][disabled] {
|
||||
opacity: .3;
|
||||
}
|
||||
|
||||
[is=paper-icon-button-light] i {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font-size: 24px;
|
||||
/* Make sure its on top of the ripple */
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.layout-tv [is=paper-icon-button-light] {
|
||||
width: auto;
|
||||
height: auto;
|
||||
min-width: initial;
|
||||
min-height: initial;
|
||||
}
|
||||
|
||||
.layout-tv [is=paper-icon-button-light] i {
|
||||
width: 3.7vh;
|
||||
height: 3.7vh;
|
||||
font-size: 3.7vh;
|
||||
}
|
||||
|
||||
[is=paper-icon-button-light] iron-icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* Make sure its on top of the ripple */
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
[is=paper-icon-button-light] img {
|
||||
width: 100%;
|
||||
/* Can't use 100% height or it will stretch past the boundaries in safari */
|
||||
/*height: 100%;*/
|
||||
max-height: 100%;
|
||||
/* Make sure its on top of the ripple */
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
[is=paper-icon-button-light]:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
transition: opacity .3s ease-out;
|
||||
background: currentcolor;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
[is=paper-icon-button-light]:focus:after {
|
||||
opacity: .2;
|
||||
}
|
||||
|
||||
.ripple-effect {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
background: currentcolor;
|
||||
animation: ripple-animation .8s;
|
||||
opacity: 0.25;
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
@keyframes ripple-animation {
|
||||
from {
|
||||
transform: none;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
to {
|
||||
transform: scale(20);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
73
dashboard-ui/bower_components/emby-webcomponents/emby-button/emby-button.js
vendored
Normal file
73
dashboard-ui/bower_components/emby-webcomponents/emby-button/emby-button.js
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
define(['browser', 'css!./emby-button', 'registerElement'], function (browser) {
|
||||
|
||||
var EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype);
|
||||
|
||||
function animateButtonInternal(e, btn) {
|
||||
|
||||
var div = document.createElement('div');
|
||||
|
||||
div.classList.add('ripple-effect');
|
||||
|
||||
var offsetX = e.offsetX || 0;
|
||||
var offsetY = e.offsetY || 0;
|
||||
|
||||
if (offsetX > 0 && offsetY > 0) {
|
||||
div.style.left = offsetX + 'px';
|
||||
div.style.top = offsetY + 'px';
|
||||
}
|
||||
|
||||
btn.appendChild(div);
|
||||
|
||||
div.addEventListener("animationend", function () {
|
||||
div.parentNode.removeChild(div);
|
||||
}, false);
|
||||
}
|
||||
|
||||
function animateButton(e) {
|
||||
|
||||
var btn = this;
|
||||
requestAnimationFrame(function () {
|
||||
animateButtonInternal(e, btn);
|
||||
});
|
||||
}
|
||||
|
||||
function onKeyDown(e) {
|
||||
|
||||
if (e.keyCode == 13) {
|
||||
animateButton.call(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseDown(e) {
|
||||
|
||||
if (e.button == 0) {
|
||||
animateButton.call(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
EmbyButtonPrototype.attachedCallback = function () {
|
||||
|
||||
if (this.getAttribute('data-embybutton') == 'true') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setAttribute('data-embybutton', 'true');
|
||||
|
||||
if (browser.safari || browser.firefox || browser.noFlex) {
|
||||
this.classList.add('noflex');
|
||||
}
|
||||
|
||||
this.addEventListener('keydown', onKeyDown);
|
||||
if (browser.safari) {
|
||||
this.addEventListener('click', animateButton);
|
||||
} else {
|
||||
this.addEventListener('mousedown', onMouseDown);
|
||||
//this.addEventListener('touchstart', animateButton);
|
||||
}
|
||||
};
|
||||
|
||||
document.registerElement('emby-button', {
|
||||
prototype: EmbyButtonPrototype,
|
||||
extends: 'button'
|
||||
});
|
||||
});
|
57
dashboard-ui/bower_components/emby-webcomponents/emby-button/paper-icon-button-light.js
vendored
Normal file
57
dashboard-ui/bower_components/emby-webcomponents/emby-button/paper-icon-button-light.js
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
define(['css!./emby-button', 'registerElement'], function () {
|
||||
|
||||
var EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype);
|
||||
|
||||
function animateButtonInternal(e, btn) {
|
||||
|
||||
var div = document.createElement('div');
|
||||
|
||||
div.classList.add('ripple-effect');
|
||||
|
||||
var offsetX = e.offsetX || 0;
|
||||
var offsetY = e.offsetY || 0;
|
||||
|
||||
if (offsetX > 0 && offsetY > 0) {
|
||||
div.style.left = offsetX + 'px';
|
||||
div.style.top = offsetY + 'px';
|
||||
}
|
||||
|
||||
btn.appendChild(div);
|
||||
|
||||
div.addEventListener("animationend", function () {
|
||||
div.parentNode.removeChild(div);
|
||||
}, false);
|
||||
}
|
||||
|
||||
function animateButton(e) {
|
||||
|
||||
var btn = this;
|
||||
requestAnimationFrame(function () {
|
||||
animateButtonInternal(e, btn);
|
||||
});
|
||||
}
|
||||
|
||||
function onKeyDown(e) {
|
||||
|
||||
if (e.keyCode == 13) {
|
||||
animateButton.call(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
EmbyButtonPrototype.attachedCallback = function () {
|
||||
|
||||
if (this.getAttribute('data-embybutton') == 'true') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setAttribute('data-embybutton', 'true');
|
||||
|
||||
this.addEventListener('keydown', onKeyDown);
|
||||
this.addEventListener('click', animateButton);
|
||||
};
|
||||
|
||||
document.registerElement('paper-icon-button-light', {
|
||||
prototype: EmbyButtonPrototype,
|
||||
extends: 'button'
|
||||
});
|
||||
});
|
139
dashboard-ui/bower_components/emby-webcomponents/emby-checkbox/emby-checkbox.css
vendored
Normal file
139
dashboard-ui/bower_components/emby-webcomponents/emby-checkbox/emby-checkbox.css
vendored
Normal file
|
@ -0,0 +1,139 @@
|
|||
.mdl-checkbox {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
vertical-align: middle;
|
||||
display: inline-flex;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-left: 36px;
|
||||
align-items: center;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.checkboxFieldDescription {
|
||||
padding-left: 36px;
|
||||
}
|
||||
|
||||
.checkboxContainer {
|
||||
margin-bottom: 2em;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
div.checkboxContainer {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mdl-checkbox__input {
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
opacity: 0;
|
||||
-ms-appearance: none;
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.checkboxOutline {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 0;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
border: 2px solid currentcolor;
|
||||
border-radius: 2px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.mdl-checkbox__input:checked + span + span + .checkboxOutline {
|
||||
border-color: #52B54B;
|
||||
}
|
||||
|
||||
.mdl-checkbox__input[disabled] + span + span + .checkboxOutline {
|
||||
border-color: rgba(0, 0, 0, 0.26);
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.mdl-checkbox__focus-helper {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: -12px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
margin: 3px 0 0 0;
|
||||
border-radius: 50%;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.mdl-checkbox__input:focus + span + .mdl-checkbox__focus-helper {
|
||||
background-color: rgba(82, 181, 75, 0.26);
|
||||
}
|
||||
|
||||
.mdl-checkbox__tick-outline {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
transition-duration: 0.28s;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-property: background;
|
||||
}
|
||||
|
||||
.mdl-checkbox__input:checked + span + span + .checkboxOutline .mdl-checkbox__tick-outline {
|
||||
background: #52B54B url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K");
|
||||
}
|
||||
|
||||
.mdl-checkbox__input:checked[disabled] + span + span + .checkboxOutline .mdl-checkbox__tick-outline {
|
||||
background: rgba(0, 0, 0, 0.26) url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K");
|
||||
}
|
||||
|
||||
.checkboxLabel {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.mdl-checkbox__input[disabled] + .checkboxLabel {
|
||||
color: rgba(0, 0, 0, 0.26);
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.checkboxList .mdl-checkbox {
|
||||
display: flex;
|
||||
margin: .5em 0;
|
||||
}
|
||||
|
||||
.layout-tv .mdl-checkbox {
|
||||
height: 4.6vh;
|
||||
padding-left: 6vh;
|
||||
}
|
||||
|
||||
.layout-tv .checkboxFieldDescription {
|
||||
padding-left: 6vh;
|
||||
}
|
||||
|
||||
.layout-tv .checkboxOutline {
|
||||
width: 4.6vh;
|
||||
height: 4.6vh;
|
||||
}
|
||||
|
||||
.layout-tv .mdl-checkbox__focus-helper {
|
||||
top: -3.7vh;
|
||||
left: -3.7vh;
|
||||
width: 12vh;
|
||||
height: 12vh;
|
||||
}
|
45
dashboard-ui/bower_components/emby-webcomponents/emby-checkbox/emby-checkbox.js
vendored
Normal file
45
dashboard-ui/bower_components/emby-webcomponents/emby-checkbox/emby-checkbox.js
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
define(['css!./emby-checkbox', 'registerElement'], function () {
|
||||
|
||||
var EmbyCheckboxPrototype = Object.create(HTMLInputElement.prototype);
|
||||
|
||||
function onKeyDown(e) {
|
||||
|
||||
// Don't submit form on enter
|
||||
if (e.keyCode == 13) {
|
||||
e.preventDefault();
|
||||
|
||||
this.checked = !this.checked;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
EmbyCheckboxPrototype.attachedCallback = function () {
|
||||
|
||||
if (this.getAttribute('data-embycheckbox') == 'true') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setAttribute('data-embycheckbox', 'true');
|
||||
|
||||
this.classList.add('mdl-checkbox__input');
|
||||
|
||||
var labelElement = this.parentNode;
|
||||
//labelElement.classList.add('mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events');
|
||||
labelElement.classList.add('mdl-checkbox');
|
||||
labelElement.classList.add('mdl-js-checkbox');
|
||||
labelElement.classList.add('mdl-js-ripple-effect');
|
||||
|
||||
var labelTextElement = labelElement.querySelector('span');
|
||||
labelElement.insertAdjacentHTML('beforeend', '<span class="mdl-checkbox__focus-helper"></span><span class="checkboxOutline"><span class="mdl-checkbox__tick-outline"></span></span>');
|
||||
|
||||
labelTextElement.classList.add('checkboxLabel');
|
||||
|
||||
this.addEventListener('keydown', onKeyDown);
|
||||
};
|
||||
|
||||
document.registerElement('emby-checkbox', {
|
||||
prototype: EmbyCheckboxPrototype,
|
||||
extends: 'input'
|
||||
});
|
||||
});
|
59
dashboard-ui/bower_components/emby-webcomponents/emby-input/emby-input.css
vendored
Normal file
59
dashboard-ui/bower_components/emby-webcomponents/emby-input/emby-input.css
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
[is="emby-input"] {
|
||||
display: block;
|
||||
margin: 0;
|
||||
margin-bottom: 0 !important;
|
||||
background: none;
|
||||
border: 1px solid rgb(221, 221, 221);
|
||||
border-width: 0 0 1px 0;
|
||||
/* Prefixed box-sizing rules necessary for older browsers */
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
/* Remove select styling */
|
||||
/* Font size must the 16px or larger to prevent iOS page zoom on focus */
|
||||
font-size: inherit;
|
||||
/* General select styles: change as needed */
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
color: inherit;
|
||||
padding: .35em 0 .3em 0;
|
||||
cursor: pointer;
|
||||
outline: none !important;
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.inputContainer {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.inputLabel {
|
||||
display: inline-block;
|
||||
transition: all .2s ease-out;
|
||||
}
|
||||
|
||||
.inputLabel.blank:not(.nofloat) {
|
||||
transform-origin: left top;
|
||||
transform: scale(1.4,1.4) translateY(80%);
|
||||
}
|
||||
|
||||
.inputLabel.focused:not(.blank) {
|
||||
color: #52B54B;
|
||||
}
|
||||
|
||||
.emby-input-selectionbar {
|
||||
height: 2px;
|
||||
transform: scale(.01, 1);
|
||||
transition: transform .25s ease-out;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
margin-bottom: .5em;
|
||||
-webkit-transform-origin: center center;
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
||||
[is="emby-input"]:focus + .emby-input-selectionbar {
|
||||
background-color: #52B54B;
|
||||
transform: none;
|
||||
}
|
93
dashboard-ui/bower_components/emby-webcomponents/emby-input/emby-input.js
vendored
Normal file
93
dashboard-ui/bower_components/emby-webcomponents/emby-input/emby-input.js
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
define(['layoutManager', 'browser', 'css!./emby-input', 'registerElement'], function (layoutManager, browser) {
|
||||
|
||||
var EmbyInputPrototype = Object.create(HTMLInputElement.prototype);
|
||||
|
||||
var inputId = 0;
|
||||
var supportsFloatingLabel = false;
|
||||
|
||||
if (Object.getOwnPropertyDescriptor && Object.defineProperty) {
|
||||
|
||||
var descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
|
||||
|
||||
// descriptor returning null in webos
|
||||
if (descriptor && descriptor.configurable) {
|
||||
var baseSetMethod = descriptor.set;
|
||||
descriptor.set = function (value) {
|
||||
baseSetMethod.call(this, value);
|
||||
|
||||
this.dispatchEvent(new CustomEvent('valueset', {
|
||||
bubbles: false,
|
||||
cancelable: false
|
||||
}));
|
||||
}
|
||||
|
||||
Object.defineProperty(HTMLInputElement.prototype, 'value', descriptor);
|
||||
supportsFloatingLabel = true;
|
||||
}
|
||||
}
|
||||
|
||||
EmbyInputPrototype.createdCallback = function () {
|
||||
|
||||
if (!this.id) {
|
||||
this.id = 'embyinput' + inputId;
|
||||
inputId++;
|
||||
}
|
||||
};
|
||||
|
||||
EmbyInputPrototype.attachedCallback = function () {
|
||||
|
||||
if (this.getAttribute('data-embyinput') == 'true') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setAttribute('data-embyinput', 'true');
|
||||
|
||||
var parentNode = this.parentNode;
|
||||
var label = this.ownerDocument.createElement('label');
|
||||
label.innerHTML = this.getAttribute('label') || '';
|
||||
label.classList.add('inputLabel');
|
||||
|
||||
if (!supportsFloatingLabel || this.type == 'date') {
|
||||
label.classList.add('nofloat');
|
||||
}
|
||||
|
||||
label.htmlFor = this.id;
|
||||
parentNode.insertBefore(label, this);
|
||||
|
||||
var div = document.createElement('div');
|
||||
div.classList.add('emby-input-selectionbar');
|
||||
parentNode.insertBefore(div, this.nextSibling);
|
||||
|
||||
function onChange() {
|
||||
if (this.value) {
|
||||
label.classList.remove('blank');
|
||||
} else {
|
||||
label.classList.add('blank');
|
||||
}
|
||||
}
|
||||
|
||||
this.addEventListener('focus', function () {
|
||||
onChange.call(this);
|
||||
label.classList.add('focused');
|
||||
});
|
||||
this.addEventListener('blur', function () {
|
||||
onChange.call(this);
|
||||
label.classList.remove('focused');
|
||||
});
|
||||
|
||||
this.addEventListener('change', onChange);
|
||||
this.addEventListener('input', onChange);
|
||||
this.addEventListener('valueset', onChange);
|
||||
|
||||
onChange.call(this);
|
||||
|
||||
this.label = function (text) {
|
||||
label.innerHTML = text;
|
||||
};
|
||||
};
|
||||
|
||||
document.registerElement('emby-input', {
|
||||
prototype: EmbyInputPrototype,
|
||||
extends: 'input'
|
||||
});
|
||||
});
|
55
dashboard-ui/bower_components/emby-webcomponents/emby-select/emby-select.css
vendored
Normal file
55
dashboard-ui/bower_components/emby-webcomponents/emby-select/emby-select.css
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
[is="emby-select"] {
|
||||
display: block;
|
||||
margin: 0;
|
||||
margin-bottom: 0 !important;
|
||||
background: none;
|
||||
border: 1px solid rgb(221, 221, 221);
|
||||
border-width: 0 0 1px 0;
|
||||
/* Prefixed box-sizing rules necessary for older browsers */
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
/* Remove select styling */
|
||||
/* Font size must the 16px or larger to prevent iOS page zoom on focus */
|
||||
font-size: inherit;
|
||||
/* General select styles: change as needed */
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
color: inherit;
|
||||
padding: .35em .8em .3em 0;
|
||||
cursor: pointer;
|
||||
outline: none !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
[is="emby-select"] option {
|
||||
color: initial;
|
||||
}
|
||||
|
||||
.selectContainer {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.selectLabel {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.selectLabelFocused {
|
||||
color: #52B54B;
|
||||
}
|
||||
|
||||
.emby-select-selectionbar {
|
||||
height: 2px;
|
||||
transform: scale(.01, 1);
|
||||
transition: transform .25s ease-out;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
margin-bottom: .5em;
|
||||
-webkit-transform-origin: center center;
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
||||
[is="emby-select"]:focus + .emby-select-selectionbar {
|
||||
background-color: #52B54B;
|
||||
transform: none;
|
||||
}
|
156
dashboard-ui/bower_components/emby-webcomponents/emby-select/emby-select.js
vendored
Normal file
156
dashboard-ui/bower_components/emby-webcomponents/emby-select/emby-select.js
vendored
Normal file
|
@ -0,0 +1,156 @@
|
|||
define(['layoutManager', 'browser', 'actionsheet', 'css!./emby-select', 'registerElement'], function (layoutManager, browser, actionsheet) {
|
||||
|
||||
var EmbySelectPrototype = Object.create(HTMLSelectElement.prototype);
|
||||
|
||||
function enableNativeMenu() {
|
||||
|
||||
if (browser.xboxOne) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Take advantage of the native input methods
|
||||
if (browser.tv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (layoutManager.tv) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function triggerChange(select) {
|
||||
var evt = document.createEvent("HTMLEvents");
|
||||
evt.initEvent("change", false, true);
|
||||
select.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
function setValue(select, value) {
|
||||
|
||||
select.value = value;
|
||||
}
|
||||
|
||||
function showActionSheeet(select) {
|
||||
|
||||
var labelElem = getLabel(select);
|
||||
var title = labelElem ? (labelElem.textContent || labelElem.innerText) : null;
|
||||
|
||||
actionsheet.show({
|
||||
items: select.options,
|
||||
positionTo: select,
|
||||
title: title
|
||||
|
||||
}).then(function (value) {
|
||||
setValue(select, value);
|
||||
triggerChange(select);
|
||||
});
|
||||
}
|
||||
|
||||
function getLabel(select) {
|
||||
var elem = select.previousSibling;
|
||||
while (elem && elem.tagName != 'LABEL') {
|
||||
elem = elem.previousSibling;
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
|
||||
function onFocus(e) {
|
||||
var label = getLabel(this);
|
||||
if (label) {
|
||||
label.classList.add('selectLabelFocused');
|
||||
label.classList.remove('selectLabelUnfocused');
|
||||
}
|
||||
}
|
||||
|
||||
function onBlur(e) {
|
||||
var label = getLabel(this);
|
||||
if (label) {
|
||||
label.classList.add('selectLabelUnfocused');
|
||||
label.classList.remove('selectLabelFocused');
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseDown(e) {
|
||||
|
||||
// e.button=0 for primary (left) mouse button click
|
||||
if (!e.button && !enableNativeMenu()) {
|
||||
e.preventDefault();
|
||||
showActionSheeet(this);
|
||||
}
|
||||
}
|
||||
|
||||
function onKeyDown(e) {
|
||||
|
||||
switch (e.keyCode) {
|
||||
|
||||
case 13:
|
||||
if (!enableNativeMenu()) {
|
||||
e.preventDefault();
|
||||
showActionSheeet(this);
|
||||
}
|
||||
return;
|
||||
case 37:
|
||||
case 38:
|
||||
case 39:
|
||||
case 40:
|
||||
if (layoutManager.tv) {
|
||||
e.preventDefault();
|
||||
}
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var inputId = 0;
|
||||
|
||||
EmbySelectPrototype.createdCallback = function () {
|
||||
|
||||
var parent = this.parentNode;
|
||||
if (!parent.classList.contains('selectContainer')) {
|
||||
var div = this.ownerDocument.createElement('div');
|
||||
div.classList.add('selectContainer');
|
||||
parent.replaceChild(div, this);
|
||||
div.appendChild(this);
|
||||
}
|
||||
|
||||
if (!this.id) {
|
||||
this.id = 'embyselect' + inputId;
|
||||
inputId++;
|
||||
}
|
||||
|
||||
this.removeEventListener('mousedown', onMouseDown);
|
||||
this.removeEventListener('keydown', onKeyDown);
|
||||
this.removeEventListener('focus', onFocus);
|
||||
this.removeEventListener('blur', onBlur);
|
||||
|
||||
this.addEventListener('mousedown', onMouseDown);
|
||||
this.addEventListener('keydown', onKeyDown);
|
||||
this.addEventListener('focus', onFocus);
|
||||
this.addEventListener('blur', onBlur);
|
||||
};
|
||||
|
||||
EmbySelectPrototype.attachedCallback = function () {
|
||||
|
||||
if (this.getAttribute('data-embyselect') != 'true') {
|
||||
this.setAttribute('data-embyselect', 'true');
|
||||
|
||||
var label = this.ownerDocument.createElement('label');
|
||||
label.innerHTML = this.getAttribute('label') || '';
|
||||
label.classList.add('selectLabel');
|
||||
label.classList.add('selectLabelUnfocused');
|
||||
label.htmlFor = this.id;
|
||||
this.parentNode.insertBefore(label, this);
|
||||
|
||||
var div = document.createElement('div');
|
||||
div.classList.add('emby-select-selectionbar');
|
||||
this.parentNode.insertBefore(div, this.nextSibling);
|
||||
}
|
||||
};
|
||||
|
||||
document.registerElement('emby-select', {
|
||||
prototype: EmbySelectPrototype,
|
||||
extends: 'select'
|
||||
});
|
||||
});
|
338
dashboard-ui/bower_components/emby-webcomponents/emby-slider/emby-slider.css
vendored
Normal file
338
dashboard-ui/bower_components/emby-webcomponents/emby-slider/emby-slider.css
vendored
Normal file
|
@ -0,0 +1,338 @@
|
|||
_:-ms-input-placeholder, :root .mdl-slider.mdl-slider {
|
||||
-ms-appearance: none;
|
||||
height: 32px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.mdl-slider {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mdl-slider {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
height: 2px;
|
||||
background: transparent;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
outline: 0;
|
||||
padding: 0;
|
||||
color: #52B54B;
|
||||
-webkit-align-self: center;
|
||||
-ms-flex-item-align: center;
|
||||
align-self: center;
|
||||
z-index: 1;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
/**************************** Tracks ****************************/
|
||||
/**************************** Thumbs ****************************/
|
||||
/**************************** 0-value ****************************/
|
||||
/**************************** Disabled ****************************/
|
||||
}
|
||||
|
||||
.layout-tv .mdl-slider {
|
||||
height: .56vh;
|
||||
}
|
||||
|
||||
.mdl-slider::-moz-focus-outer {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.mdl-slider::-ms-tooltip {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mdl-slider::-webkit-slider-runnable-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.mdl-slider::-moz-range-track {
|
||||
background: #666;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.mdl-slider::-moz-range-progress {
|
||||
background: #52B54B;
|
||||
}
|
||||
|
||||
.mdl-slider::-ms-track {
|
||||
background: none;
|
||||
color: transparent;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.layout-tv .mdl-slider::-ms-track {
|
||||
height: .56vh;
|
||||
}
|
||||
|
||||
.mdl-slider::-ms-fill-lower {
|
||||
padding: 0;
|
||||
background: linear-gradient(to right, transparent, transparent 16px, #52B54B 16px, #52B54B 0);
|
||||
}
|
||||
|
||||
.mdl-slider::-ms-fill-upper {
|
||||
padding: 0;
|
||||
background: linear-gradient(to left, transparent, transparent 16px, #666 16px, #666 0);
|
||||
}
|
||||
|
||||
.mdl-slider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 50%;
|
||||
background: #52B54B;
|
||||
border: none;
|
||||
transition: border 0.18s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.18s cubic-bezier(0.4, 0, 0.2, 1), background 0.28s cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 0.18s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1), border 0.18s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.18s cubic-bezier(0.4, 0, 0.2, 1), background 0.28s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1), border 0.18s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.18s cubic-bezier(0.4, 0, 0.2, 1), background 0.28s cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 0.18s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.layout-tv .mdl-slider::-webkit-slider-thumb {
|
||||
width: 2vh;
|
||||
height: 2vh;
|
||||
}
|
||||
|
||||
.mdl-slider::-moz-range-thumb {
|
||||
-moz-appearance: none;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 50%;
|
||||
background-image: none;
|
||||
background: #52B54B;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.layout-tv .mdl-slider::-moz-range-thumb {
|
||||
width: 2vh;
|
||||
height: 2vh;
|
||||
}
|
||||
|
||||
.mdl-slider:focus:not(:active)::-webkit-slider-thumb {
|
||||
box-shadow: 0 0 0 10px rgba(82, 181, 75, 0.26);
|
||||
}
|
||||
|
||||
.mdl-slider:focus:not(:active)::-moz-range-thumb {
|
||||
box-shadow: 0 0 0 10px rgba(82, 181, 75, 0.26);
|
||||
}
|
||||
|
||||
.mdl-slider:active::-webkit-slider-thumb {
|
||||
background-image: none;
|
||||
background: #52B54B;
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
.mdl-slider:active::-moz-range-thumb {
|
||||
background-image: none;
|
||||
background: #52B54B;
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
.mdl-slider::-ms-thumb {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
background: #52B54B;
|
||||
}
|
||||
|
||||
.mdl-slider[disabled]::-ms-thumb {
|
||||
background: gray;
|
||||
}
|
||||
|
||||
.layout-tv .mdl-slider::-ms-thumb {
|
||||
width: 2vh;
|
||||
height: 2vh;
|
||||
}
|
||||
|
||||
.layout-tv .mdl-slider::-webkit-slider-thumb {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layout-tv .mdl-slider:hover::-webkit-slider-thumb {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value::-webkit-slider-thumb {
|
||||
/*border: 2px solid #52B54B;
|
||||
background: transparent;*/
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value::-moz-range-thumb {
|
||||
/*border: 2px solid #52B54B;
|
||||
background: transparent;*/
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value + .mdl-slider__background-flex > .mdl-slider__background-upper {
|
||||
left: 6px;
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value:focus:not(:active)::-webkit-slider-thumb {
|
||||
/*box-shadow: 0 0 0 10px rgba(0,0,0, 0.12);
|
||||
background: rgba(0,0,0, 0.12);*/
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value:focus:not(:active)::-moz-range-thumb {
|
||||
/*box-shadow: 0 0 0 10px rgba(0,0,0, 0.12);
|
||||
background: rgba(0,0,0, 0.12);*/
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value:active::-webkit-slider-thumb {
|
||||
border: 1.6px solid #52B54B;
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value:active + .mdl-slider__background-flex > .mdl-slider__background-upper {
|
||||
left: 9px;
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value:active::-moz-range-thumb {
|
||||
border: 1.5px solid #52B54B;
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value::-ms-fill-lower {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value::-ms-fill-upper {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value:active::-ms-fill-upper {
|
||||
margin-left: 9px;
|
||||
}
|
||||
|
||||
.mdl-slider:disabled:focus::-webkit-slider-thumb, .mdl-slider:disabled:active::-webkit-slider-thumb, .mdl-slider:disabled::-webkit-slider-thumb {
|
||||
-webkit-transform: scale(0.667);
|
||||
transform: scale(0.667);
|
||||
background: rgba(0,0,0, 0.26);
|
||||
}
|
||||
|
||||
.mdl-slider:disabled:focus::-moz-range-thumb, .mdl-slider:disabled:active::-moz-range-thumb, .mdl-slider:disabled::-moz-range-thumb {
|
||||
transform: scale(0.667);
|
||||
background: rgba(0,0,0, 0.26);
|
||||
}
|
||||
|
||||
.mdl-slider:disabled + .mdl-slider__background-flex > .mdl-slider__background-lower {
|
||||
background-color: #666;
|
||||
left: -6px;
|
||||
}
|
||||
|
||||
.mdl-slider:disabled + .mdl-slider__background-flex > .mdl-slider__background-upper {
|
||||
left: 6px;
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value:disabled:focus::-webkit-slider-thumb, .mdl-slider.is-lowest-value:disabled:active::-webkit-slider-thumb, .mdl-slider.is-lowest-value:disabled::-webkit-slider-thumb {
|
||||
border: 3px solid rgba(0,0,0, 0.26);
|
||||
background: transparent;
|
||||
-webkit-transform: scale(0.667);
|
||||
transform: scale(0.667);
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value:disabled:focus::-moz-range-thumb, .mdl-slider.is-lowest-value:disabled:active::-moz-range-thumb, .mdl-slider.is-lowest-value:disabled::-moz-range-thumb {
|
||||
border: 3px solid rgba(0,0,0, 0.26);
|
||||
background: transparent;
|
||||
transform: scale(0.667);
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value:disabled:active + .mdl-slider__background-flex > .mdl-slider__background-upper {
|
||||
left: 6px;
|
||||
}
|
||||
|
||||
.mdl-slider:disabled::-ms-fill-lower {
|
||||
margin-right: 6px;
|
||||
background: linear-gradient(to right, transparent, transparent 25px, rgba(30,30,30, 0.7) 25px, rgba(30,30,30, 0.7) 0);
|
||||
}
|
||||
|
||||
.mdl-slider:disabled::-ms-fill-upper {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.mdl-slider.is-lowest-value:disabled:active::-ms-fill-upper {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.mdl-slider__ie-container {
|
||||
height: 18px;
|
||||
overflow: visible;
|
||||
border: none;
|
||||
margin: none;
|
||||
padding: none;
|
||||
}
|
||||
|
||||
.mdl-slider__container {
|
||||
height: 18px;
|
||||
position: relative;
|
||||
background: none;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.mdl-slider__background-flex {
|
||||
background: transparent;
|
||||
position: absolute;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
-webkit-transform: translate(0, -1px);
|
||||
transform: translate(0, -1px);
|
||||
}
|
||||
|
||||
.layout-tv .mdl-slider__background-flex {
|
||||
height: .56vh;
|
||||
}
|
||||
|
||||
.mdl-slider__background-lower {
|
||||
background: #52B54B;
|
||||
-webkit-flex: 0;
|
||||
-ms-flex: 0;
|
||||
flex: 0;
|
||||
position: relative;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mdl-slider__background-upper {
|
||||
background: #666;
|
||||
-webkit-flex: 0;
|
||||
-ms-flex: 0;
|
||||
flex: 0;
|
||||
position: relative;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
transition: left 0.18s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.sliderBubble {
|
||||
position: absolute;
|
||||
top: -3.7em;
|
||||
left: 0;
|
||||
padding: .75em;
|
||||
background: #3367d6;
|
||||
color: #fff;
|
||||
border-radius: 1000px;
|
||||
font-size: 90%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
120
dashboard-ui/bower_components/emby-webcomponents/emby-slider/emby-slider.js
vendored
Normal file
120
dashboard-ui/bower_components/emby-webcomponents/emby-slider/emby-slider.js
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
define(['browser', 'css!./emby-slider', 'registerElement', 'emby-input'], function (browser) {
|
||||
|
||||
var EmbySliderPrototype = Object.create(HTMLInputElement.prototype);
|
||||
|
||||
var supportsNativeProgressStyle = browser.firefox || browser.edge || browser.msie;
|
||||
var supportsValueSetOverride = false;
|
||||
|
||||
if (Object.getOwnPropertyDescriptor && Object.defineProperty) {
|
||||
|
||||
var descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
|
||||
// descriptor returning null in webos
|
||||
if (descriptor && descriptor.configurable) {
|
||||
supportsValueSetOverride = true;
|
||||
}
|
||||
}
|
||||
|
||||
function updateValues(range, backgroundLower, backgroundUpper) {
|
||||
|
||||
//if (fraction === 0) {
|
||||
// range.classList.add('is-lowest-value');
|
||||
//} else {
|
||||
// range.classList.remove('is-lowest-value');
|
||||
//}
|
||||
|
||||
if (backgroundLower) {
|
||||
var fraction = (range.value - range.min) / (range.max - range.min);
|
||||
|
||||
backgroundLower.style.flex = fraction;
|
||||
backgroundLower.style.webkitFlex = fraction;
|
||||
backgroundUpper.style.flex = 1 - fraction;
|
||||
backgroundUpper.style.webkitFlex = 1 - fraction;
|
||||
}
|
||||
}
|
||||
|
||||
function updateBubble(range, bubble) {
|
||||
|
||||
var value = range.value;
|
||||
bubble.style.left = (value - 1) + '%';
|
||||
|
||||
if (range.getBubbleText) {
|
||||
value = range.getBubbleText(value);
|
||||
}
|
||||
bubble.innerHTML = value;
|
||||
}
|
||||
|
||||
EmbySliderPrototype.attachedCallback = function () {
|
||||
|
||||
if (this.getAttribute('data-embycheckbox') == 'true') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setAttribute('data-embycheckbox', 'true');
|
||||
|
||||
this.classList.add('mdl-slider');
|
||||
this.classList.add('mdl-js-slider');
|
||||
|
||||
var containerElement = this.parentNode;
|
||||
containerElement.classList.add('mdl-slider__container');
|
||||
|
||||
var htmlToInsert = '';
|
||||
|
||||
if (!supportsNativeProgressStyle) {
|
||||
htmlToInsert += '<div class="mdl-slider__background-flex"><div class="mdl-slider__background-lower"></div><div class="mdl-slider__background-upper"></div></div>';
|
||||
}
|
||||
|
||||
htmlToInsert += '<div class="sliderBubble hide"></div>';
|
||||
|
||||
containerElement.insertAdjacentHTML('beforeend', htmlToInsert);
|
||||
|
||||
var backgroundLower = containerElement.querySelector('.mdl-slider__background-lower');
|
||||
var backgroundUpper = containerElement.querySelector('.mdl-slider__background-upper');
|
||||
var sliderBubble = containerElement.querySelector('.sliderBubble');
|
||||
|
||||
this.addEventListener('input', function (e) {
|
||||
this.dragging = true;
|
||||
updateBubble(this, sliderBubble);
|
||||
sliderBubble.classList.remove('hide');
|
||||
});
|
||||
this.addEventListener('change', function () {
|
||||
this.dragging = false;
|
||||
updateValues(this, backgroundLower, backgroundUpper);
|
||||
sliderBubble.classList.add('hide');
|
||||
});
|
||||
|
||||
if (!supportsNativeProgressStyle) {
|
||||
|
||||
if (supportsValueSetOverride) {
|
||||
this.addEventListener('valueset', function () {
|
||||
updateValues(this, backgroundLower, backgroundUpper);
|
||||
});
|
||||
} else {
|
||||
startInterval(this, backgroundLower, backgroundUpper);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function startInterval(range, backgroundLower, backgroundUpper) {
|
||||
var interval = range.interval;
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
range.interval = setInterval(function () {
|
||||
updateValues(range, backgroundLower, backgroundUpper);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
EmbySliderPrototype.detachedCallback = function () {
|
||||
|
||||
var interval = this.interval;
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
this.interval = null;
|
||||
};
|
||||
|
||||
document.registerElement('emby-slider', {
|
||||
prototype: EmbySliderPrototype,
|
||||
extends: 'input'
|
||||
});
|
||||
});
|
|
@ -20,11 +20,6 @@ define([], function () {
|
|||
|
||||
function focus(element) {
|
||||
|
||||
var tagName = element.tagName;
|
||||
if (tagName == 'PAPER-INPUT' || tagName == 'EMBY-DROPDOWN-MENU') {
|
||||
element = element.querySelector('input') || element;
|
||||
}
|
||||
|
||||
try {
|
||||
element.focus();
|
||||
} catch (err) {
|
||||
|
@ -32,7 +27,7 @@ define([], function () {
|
|||
}
|
||||
}
|
||||
|
||||
var focusableTagNames = ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON', 'A', 'PAPER-BUTTON', 'PAPER-INPUT', 'PAPER-TEXTAREA', 'PAPER-FAB', 'PAPER-CHECKBOX', 'PAPER-ICON-ITEM', 'PAPER-MENU-ITEM', 'EMBY-DROPDOWN-MENU'];
|
||||
var focusableTagNames = ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON', 'A', 'PAPER-CHECKBOX'];
|
||||
var focusableContainerTagNames = ['BODY', 'DIALOG'];
|
||||
var focusableQuery = focusableTagNames.join(',') + ',.focusable';
|
||||
|
||||
|
@ -340,89 +335,62 @@ define([], function () {
|
|||
|
||||
var distX;
|
||||
var distY;
|
||||
var distX2;
|
||||
var distY2;
|
||||
|
||||
switch (direction) {
|
||||
|
||||
case 0:
|
||||
// left
|
||||
distX = distX2 = Math.abs(point1x - Math.min(point1x, x2));
|
||||
distX = Math.abs(point1x - Math.min(point1x, x2));
|
||||
distY = intersectY ? 0 : Math.abs(sourceMidY - midY);
|
||||
distY2 = Math.abs(sourceMidY - midY);
|
||||
break;
|
||||
case 1:
|
||||
// right
|
||||
distX = distX2 = Math.abs(point2x - Math.max(point2x, x));
|
||||
distX = Math.abs(point2x - Math.max(point2x, x));
|
||||
distY = intersectY ? 0 : Math.abs(sourceMidY - midY);
|
||||
distY2 = Math.abs(sourceMidY - midY);
|
||||
break;
|
||||
case 2:
|
||||
// up
|
||||
distY = distY2 = Math.abs(point1y - Math.min(point1y, y2));
|
||||
distY = Math.abs(point1y - Math.min(point1y, y2));
|
||||
distX = intersectX ? 0 : Math.abs(sourceMidX - midX);
|
||||
distX2 = Math.abs(sourceMidX - midX);
|
||||
break;
|
||||
case 3:
|
||||
// down
|
||||
distY = distY2 = Math.abs(point2y - Math.max(point2y, y));
|
||||
distY = Math.abs(point2y - Math.max(point2y, y));
|
||||
distX = intersectX ? 0 : Math.abs(sourceMidX - midX);
|
||||
distX2 = Math.abs(sourceMidX - midX);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
var distT = Math.sqrt(distX * distX + distY * distY);
|
||||
var distT2 = Math.sqrt(distX2 * distX2 + distY2 * distY2);
|
||||
|
||||
cache.push({
|
||||
node: elem,
|
||||
distX: distX,
|
||||
distY: distY,
|
||||
distT: distT,
|
||||
distT2: distT2
|
||||
index: i
|
||||
});
|
||||
}
|
||||
|
||||
cache.sort(sortNodesT);
|
||||
//if (direction >= 2) {
|
||||
// cache.sort(sortNodesX);
|
||||
//} else {
|
||||
// cache.sort(sortNodesY);
|
||||
//}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
function sortNodesX(a, b) {
|
||||
var result = a.distX - b.distX;
|
||||
|
||||
if (result == 0) {
|
||||
return a.distT - b.distT;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function sortNodesT(a, b) {
|
||||
|
||||
var result = a.distT - b.distT;
|
||||
|
||||
if (result == 0) {
|
||||
return a.distT2 - b.distT2;
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function sortNodesY(a, b) {
|
||||
var result = a.distY - b.distY;
|
||||
|
||||
if (result == 0) {
|
||||
return a.distT - b.distT;
|
||||
result = a.index - b.index;
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function sendText(text) {
|
||||
|
|
|
@ -1,20 +1,25 @@
|
|||
@font-face {
|
||||
font-family: 'Material Icons';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Material Icons'), local('MaterialIcons-Regular'), url(2fcrYFNaTjcS6g4U3t-Y5ZjZjT5FdEJ140U2DJYC3mY.woff2) format('woff2'), url(2fcrYFNaTjcS6g4U3t-Y5ewrjPiaoEww8AihgqWRJAo.woff) format('woff');
|
||||
font-family: 'Material Icons';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Material Icons'), local('MaterialIcons-Regular'), url(2fcrYFNaTjcS6g4U3t-Y5ZjZjT5FdEJ140U2DJYC3mY.woff2) format('woff2'), url(2fcrYFNaTjcS6g4U3t-Y5ewrjPiaoEww8AihgqWRJAo.woff) format('woff');
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-feature-settings: 'liga';
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
.md-icon {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-feature-settings: 'liga';
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "liga" 1;
|
||||
line-height: 1;
|
||||
overflow: hidden;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
.formDialog .dialogContentInner {
|
||||
padding-bottom: 10vh;
|
||||
padding-top: .5em;
|
||||
}
|
||||
|
||||
.layout-tv .formDialog .dialogContentInner {
|
||||
|
@ -32,7 +33,7 @@
|
|||
}
|
||||
|
||||
.formDialog .centeredContent {
|
||||
max-width: 700px;
|
||||
max-width: 740px;
|
||||
}
|
||||
|
||||
.formDialog .dialogContentTitle {
|
||||
|
@ -46,13 +47,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
@media all and (max-height: 1400px) {
|
||||
|
||||
.itemOverview {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.layout-tv .formDialog .dialogHeader {
|
||||
padding-top: 1.5em;
|
||||
padding-bottom: 1.5em;
|
||||
|
|
|
@ -105,6 +105,47 @@
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.timeslotHeadersInner {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.currentTimeIndicatorBar {
|
||||
position: absolute;
|
||||
bottom: .05em;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
display: flex;
|
||||
margin-left: .65vh;
|
||||
background-color: #52B54B;
|
||||
height: 2px;
|
||||
transform-origin: left;
|
||||
transition: transform 500ms ease-out;
|
||||
}
|
||||
|
||||
.currentTimeIndicatorArrowContainer {
|
||||
position: absolute;
|
||||
bottom: -1.3vh;
|
||||
width: 100%;
|
||||
color: #52B54B;
|
||||
margin-left: .65vh;
|
||||
transform-origin: left;
|
||||
transition: transform 500ms ease-out;
|
||||
}
|
||||
|
||||
.layout-tv .currentTimeIndicatorBar, .layout-tv .currentTimeIndicatorArrowContainer {
|
||||
/* Need to account for the scrollbar not being there */
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.currentTimeIndicatorArrow {
|
||||
width: 4vh;
|
||||
height: 4vh;
|
||||
font-size: 4vh;
|
||||
color: #52B54B;
|
||||
margin-left: -2vh;
|
||||
}
|
||||
|
||||
.channelPrograms, .timeslotHeadersInner {
|
||||
width: 1800vw;
|
||||
}
|
||||
|
@ -148,6 +189,7 @@
|
|||
text-decoration: none;
|
||||
/* Needed in firefox */
|
||||
text-align: left;
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
@media all and (min-width: 500px) {
|
||||
|
@ -185,7 +227,7 @@
|
|||
|
||||
.channelHeaderCell {
|
||||
border-bottom: .65vh solid #121212 !important;
|
||||
background-size: auto 65.7%;
|
||||
background-size: auto 70%;
|
||||
background-position: 90% center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
@ -201,7 +243,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 1280px) {
|
||||
@media all and (max-width: 1200px) {
|
||||
|
||||
.channelHeaderCell.withImage .guideChannelNumber {
|
||||
display: none;
|
||||
|
@ -233,7 +275,7 @@
|
|||
}
|
||||
|
||||
.layout-tv .channelPrograms, .layout-tv .channelHeaderCell {
|
||||
height: 7.6vh;
|
||||
height: 9vh;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,6 +342,7 @@
|
|||
align-items: center;
|
||||
/* Needed for Firefox */
|
||||
text-align: left;
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.timeslotCellInner {
|
||||
|
@ -324,16 +367,17 @@
|
|||
color: #bbb;
|
||||
}
|
||||
|
||||
.programCell iron-icon {
|
||||
.programCell i {
|
||||
margin-left: auto;
|
||||
margin-right: .5em;
|
||||
height: 3.5vh;
|
||||
width: 3.5vh;
|
||||
font-size: 3.5vh;
|
||||
color: #ddd;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.programCell iron-icon + iron-icon {
|
||||
.programCell i + i {
|
||||
margin-left: .25em;
|
||||
}
|
||||
|
||||
|
@ -347,14 +391,21 @@
|
|||
.guideChannelName {
|
||||
margin-left: auto;
|
||||
margin-right: 1em;
|
||||
max-width: 40%;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
max-width: 70%;
|
||||
}
|
||||
|
||||
@media all and (min-width: 1000px) {
|
||||
|
||||
.guideChannelName {
|
||||
max-width: 40%;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 1000px) {
|
||||
|
||||
.guideChannelName {
|
||||
.guideChannelNumber {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
@ -363,13 +414,12 @@
|
|||
height: auto !important;
|
||||
}
|
||||
|
||||
.programCell:focus, .channelHeaderCell:focus, .btnSelectDate:focus {
|
||||
background-color: #52B54B;
|
||||
.programCell, .channelHeaderCell, .btnSelectDate {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.programCell:focus .programAccent {
|
||||
background-color: transparent !important;
|
||||
.programCell:focus, .channelHeaderCell:focus, .btnSelectDate:focus {
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
.timerIcon, .seriesTimerIcon {
|
||||
|
|
|
@ -1,25 +1,17 @@
|
|||
define(['require', 'browser', 'globalize', 'connectionManager', 'loading', 'scrollHelper', 'datetime', 'focusManager', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'registrationservices', 'clearButtonStyle', 'css!./guide.css', 'html!./../icons/mediainfo.html', 'html!./../icons/nav.html', 'scrollStyles'], function (require, browser, globalize, connectionManager, loading, scrollHelper, datetime, focusManager, imageLoader, events, layoutManager, itemShortcuts, registrationServices) {
|
||||
define(['require', 'browser', 'globalize', 'connectionManager', 'serverNotifications', 'loading', 'scrollHelper', 'datetime', 'focusManager', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'registrationservices', 'clearButtonStyle', 'css!./guide.css', 'material-icons', 'scrollStyles', 'emby-button'], function (require, browser, globalize, connectionManager, serverNotifications, loading, scrollHelper, datetime, focusManager, imageLoader, events, layoutManager, itemShortcuts, registrationServices) {
|
||||
|
||||
function Guide(options) {
|
||||
|
||||
var self = this;
|
||||
var items = {};
|
||||
|
||||
self.refresh = function () {
|
||||
reloadPage(options.element);
|
||||
};
|
||||
|
||||
self.destroy = function () {
|
||||
itemShortcuts.off(options.element);
|
||||
items = {};
|
||||
};
|
||||
|
||||
self.options = options;
|
||||
|
||||
// 30 mins
|
||||
var cellCurationMinutes = 30;
|
||||
var cellDurationMs = cellCurationMinutes * 60 * 1000;
|
||||
var msPerDay = 86400000;
|
||||
var totalRendererdMs = msPerDay;
|
||||
|
||||
var currentDate;
|
||||
|
||||
|
@ -31,6 +23,24 @@
|
|||
|
||||
var channelsPromise;
|
||||
|
||||
self.refresh = function () {
|
||||
|
||||
currentDate = null;
|
||||
reloadPage(options.element);
|
||||
};
|
||||
|
||||
self.destroy = function () {
|
||||
|
||||
events.off(serverNotifications, 'TimerCreated', onTimerCreated);
|
||||
events.off(serverNotifications, 'SeriesTimerCreated', onSeriesTimerCreated);
|
||||
events.off(serverNotifications, 'TimerCancelled', onTimerCancelled);
|
||||
events.off(serverNotifications, 'SeriesTimerCancelled', onSeriesTimerCancelled);
|
||||
|
||||
clearCurrentTimeUpdateInterval();
|
||||
itemShortcuts.off(options.element);
|
||||
items = {};
|
||||
};
|
||||
|
||||
function normalizeDateToTimeslot(date) {
|
||||
|
||||
var minutesOffset = date.getMinutes() - cellCurationMinutes;
|
||||
|
@ -55,6 +65,55 @@
|
|||
loading.hide();
|
||||
}
|
||||
|
||||
var currentTimeUpdateInterval;
|
||||
var currentTimeIndicatorBar;
|
||||
var currentTimeIndicatorArrow;
|
||||
function startCurrentTimeUpdateInterval() {
|
||||
clearCurrentTimeUpdateInterval();
|
||||
|
||||
//currentTimeUpdateInterval = setInterval(updateCurrentTimeIndicator, 1000);
|
||||
currentTimeUpdateInterval = setInterval(updateCurrentTimeIndicator, 60000);
|
||||
updateCurrentTimeIndicator();
|
||||
}
|
||||
|
||||
function clearCurrentTimeUpdateInterval() {
|
||||
var interval = currentTimeUpdateInterval;
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
currentTimeUpdateInterval = null;
|
||||
currentTimeIndicatorBar = null;
|
||||
currentTimeIndicatorArrow = null;
|
||||
}
|
||||
|
||||
function updateCurrentTimeIndicator() {
|
||||
|
||||
if (!currentTimeIndicatorBar) {
|
||||
currentTimeIndicatorBar = options.element.querySelector('.currentTimeIndicatorBar');
|
||||
}
|
||||
if (!currentTimeIndicatorArrow) {
|
||||
currentTimeIndicatorArrow = options.element.querySelector('.currentTimeIndicatorArrowContainer');
|
||||
}
|
||||
|
||||
var dateDifference = new Date().getTime() - currentDate.getTime();
|
||||
var pct = dateDifference > 0 ? (dateDifference / totalRendererdMs) : 0;
|
||||
pct = Math.min(pct, 1);
|
||||
|
||||
if (pct <= 0 || pct >= 1) {
|
||||
currentTimeIndicatorBar.classList.add('hide');
|
||||
currentTimeIndicatorArrow.classList.add('hide');
|
||||
} else {
|
||||
currentTimeIndicatorBar.classList.remove('hide');
|
||||
currentTimeIndicatorArrow.classList.remove('hide');
|
||||
|
||||
//pct *= 100;
|
||||
//pct = 100 - pct;
|
||||
//currentTimeIndicatorElement.style.width = (pct * 100) + '%';
|
||||
currentTimeIndicatorBar.style.transform = 'scaleX(' + pct + ')';
|
||||
currentTimeIndicatorArrow.style.transform = 'translateX(' + (pct * 100) + '%)';
|
||||
}
|
||||
}
|
||||
|
||||
function getChannelLimit(context) {
|
||||
|
||||
return registrationServices.validateFeature('livetv').then(function () {
|
||||
|
@ -70,7 +129,7 @@
|
|||
var limit = 5;
|
||||
|
||||
context.querySelector('.guideRequiresUnlock').classList.remove('hide');
|
||||
context.querySelector('.unlockText').innerHTML = globalize.translate('LiveTvGuideRequiresUnlock', limit);
|
||||
context.querySelector('.unlockText').innerHTML = globalize.translate('sharedcomponents#LiveTvGuideRequiresUnlock', limit);
|
||||
|
||||
return limit;
|
||||
});
|
||||
|
@ -158,6 +217,11 @@
|
|||
// Add 30 mins
|
||||
startDate.setTime(startDate.getTime() + cellDurationMs);
|
||||
}
|
||||
|
||||
html += '<div class="currentTimeIndicatorBar hide">';
|
||||
html += '</div>';
|
||||
html += '<div class="currentTimeIndicatorArrowContainer hide">';
|
||||
html += '<i class="currentTimeIndicatorArrow md-icon">arrow_drop_down</i>';
|
||||
html += '</div>';
|
||||
|
||||
return html;
|
||||
|
@ -201,7 +265,7 @@
|
|||
return curr.ChannelId == channel.Id;
|
||||
});
|
||||
|
||||
html += '<div class="channelPrograms">';
|
||||
html += '<div class="channelPrograms" data-channelid="' + channel.Id + '">';
|
||||
|
||||
for (var i = 0, length = programs.length; i < length; i++) {
|
||||
|
||||
|
@ -249,7 +313,14 @@
|
|||
addAccent = false;
|
||||
}
|
||||
|
||||
html += '<button data-action="link" data-isfolder="' + program.IsFolder + '" data-id="' + program.Id + '" data-serverid="' + program.ServerId + '" data-type="' + program.Type + '" class="' + cssClass + '" style="left:' + startPercent + '%;width:' + endPercent + '%;">';
|
||||
var timerAttributes = '';
|
||||
if (program.TimerId) {
|
||||
timerAttributes += ' data-timerid="' + program.TimerId + '"';
|
||||
}
|
||||
if (program.SeriesTimerId) {
|
||||
timerAttributes += ' data-seriestimerid="' + program.SeriesTimerId + '"';
|
||||
}
|
||||
html += '<button data-action="link"' + timerAttributes + ' data-isfolder="' + program.IsFolder + '" data-id="' + program.Id + '" data-serverid="' + program.ServerId + '" data-type="' + program.Type + '" class="' + cssClass + '" style="left:' + startPercent + '%;width:' + endPercent + '%;">';
|
||||
|
||||
var guideProgramNameClass = "guideProgramName";
|
||||
|
||||
|
@ -269,14 +340,14 @@
|
|||
html += '</div>';
|
||||
|
||||
if (program.IsHD && options.showHdIcon) {
|
||||
html += '<iron-icon class="guideHdIcon" icon="mediainfo:hd"></iron-icon>';
|
||||
html += '<i class="guideHdIcon md-icon">hd</i>';
|
||||
}
|
||||
|
||||
if (program.SeriesTimerId) {
|
||||
html += '<iron-icon class="seriesTimerIcon" icon="mediainfo:fiber-smart-record"></iron-icon>';
|
||||
html += '<i class="seriesTimerIcon md-icon">fiber_smart_record</i>';
|
||||
}
|
||||
else if (program.TimerId) {
|
||||
html += '<iron-icon class="timerIcon" icon="mediainfo:fiber-manual-record"></iron-icon>';
|
||||
html += '<i class="timerIcon md-icon">fiber_manual_record</i>';
|
||||
}
|
||||
|
||||
if (addAccent) {
|
||||
|
@ -299,6 +370,7 @@
|
|||
// but since mobile browsers are often underpowered,
|
||||
// it can help performance to get them out of the markup
|
||||
var showIndicators = window.innerWidth >= 800;
|
||||
showIndicators = false;
|
||||
|
||||
var options = {
|
||||
showHdIcon: showIndicators,
|
||||
|
@ -360,6 +432,19 @@
|
|||
imageLoader.lazyChildren(channelList);
|
||||
}
|
||||
|
||||
function parentWithClass(elem, className) {
|
||||
|
||||
while (!elem.classList || !elem.classList.contains(className)) {
|
||||
elem = elem.parentNode;
|
||||
|
||||
if (!elem) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
function renderGuide(context, date, channels, programs, apiClient) {
|
||||
|
||||
//var list = [];
|
||||
|
@ -400,16 +485,46 @@
|
|||
// list.push(i);
|
||||
//});
|
||||
//channels = list;
|
||||
var activeElement = document.activeElement;
|
||||
var itemId = activeElement && activeElement.getAttribute ? activeElement.getAttribute('data-id') : null;
|
||||
var channelRowId = null;
|
||||
|
||||
if (activeElement) {
|
||||
channelRowId = parentWithClass(activeElement, 'channelPrograms');
|
||||
channelRowId = channelRowId && channelRowId.getAttribute ? channelRowId.getAttribute('data-channelid') : null;
|
||||
}
|
||||
|
||||
renderChannelHeaders(context, channels, apiClient);
|
||||
|
||||
var startDate = date;
|
||||
var endDate = new Date(startDate.getTime() + msPerDay);
|
||||
context.querySelector('.timeslotHeaders').innerHTML = getTimeslotHeadersHtml(startDate, endDate);
|
||||
startCurrentTimeUpdateInterval();
|
||||
items = {};
|
||||
renderPrograms(context, date, channels, programs);
|
||||
|
||||
if (layoutManager.tv) {
|
||||
focusManager.autoFocus(context.querySelector('.programGrid'), true);
|
||||
|
||||
var focusElem;
|
||||
if (itemId) {
|
||||
focusElem = context.querySelector('[data-id="' + itemId + '"]')
|
||||
}
|
||||
|
||||
if (focusElem) {
|
||||
focusManager.focus(focusElem);
|
||||
} else {
|
||||
|
||||
var autoFocusParent;
|
||||
|
||||
if (channelRowId) {
|
||||
autoFocusParent = context.querySelector('[data-channelid="' + channelRowId + '"]')
|
||||
}
|
||||
|
||||
if (!autoFocusParent) {
|
||||
autoFocusParent = context.querySelector('.programGrid');
|
||||
}
|
||||
focusManager.autoFocus(autoFocusParent, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -471,6 +586,8 @@
|
|||
|
||||
function changeDate(page, date) {
|
||||
|
||||
clearCurrentTimeUpdateInterval();
|
||||
|
||||
var newStartDate = normalizeDateToTimeslot(date);
|
||||
currentDate = newStartDate;
|
||||
|
||||
|
@ -626,9 +743,62 @@
|
|||
target.addEventListener(type, handler, optionsOrCapture);
|
||||
}
|
||||
|
||||
function onTimerCreated(e, apiClient, data) {
|
||||
|
||||
var programId = data.ProgramId;
|
||||
// This could be null, not supported by all tv providers
|
||||
var newTimerId = data.Id;
|
||||
|
||||
// find guide cells by program id, ensure timer icon
|
||||
var cells = options.element.querySelectorAll('.programCell[data-id="' + programId + '"]');
|
||||
for (var i = 0, length = cells.length; i < length; i++) {
|
||||
var cell = cells[i];
|
||||
|
||||
var icon = cell.querySelector('.timerIcon');
|
||||
if (!icon) {
|
||||
cell.insertAdjacentHTML('beforeend', '<i class="timerIcon md-icon">fiber_manual_record</i>');
|
||||
}
|
||||
|
||||
if (newTimerId) {
|
||||
cell.setAttribute('data-timerid', newTimerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onSeriesTimerCreated(e, apiClient, data) {
|
||||
}
|
||||
|
||||
function onTimerCancelled(e, apiClient, data) {
|
||||
var id = data.Id;
|
||||
// find guide cells by timer id, remove timer icon
|
||||
var cells = options.element.querySelectorAll('.programCell[data-timerid="' + id + '"]');
|
||||
for (var i = 0, length = cells.length; i < length; i++) {
|
||||
var cells = cells[i];
|
||||
var icon = cell.querySelector('.timerIcon');
|
||||
if (icon) {
|
||||
icon.parentNode.removeChild(icon);
|
||||
}
|
||||
cell.removeAttribute('data-timerid');
|
||||
}
|
||||
}
|
||||
|
||||
function onSeriesTimerCancelled(e, apiClient, data) {
|
||||
var id = data.Id;
|
||||
// find guide cells by timer id, remove timer icon
|
||||
var cells = options.element.querySelectorAll('.programCell[data-seriestimerid="' + id + '"]');
|
||||
for (var i = 0, length = cells.length; i < length; i++) {
|
||||
var cells = cells[i];
|
||||
var icon = cell.querySelector('.seriesTimerIcon');
|
||||
if (icon) {
|
||||
icon.parentNode.removeChild(icon);
|
||||
}
|
||||
cell.removeAttribute('data-seriestimerid');
|
||||
}
|
||||
}
|
||||
|
||||
require(['text!./tvguide.template.html'], function (template) {
|
||||
var context = options.element;
|
||||
context.innerHTML = globalize.translateDocument(template, 'core');
|
||||
context.innerHTML = globalize.translateDocument(template, 'sharedcomponents');
|
||||
|
||||
var programGrid = context.querySelector('.programGrid');
|
||||
var timeslotHeaders = context.querySelector('.timeslotHeaders');
|
||||
|
@ -662,6 +832,11 @@
|
|||
|
||||
events.trigger(self, 'load');
|
||||
|
||||
events.on(serverNotifications, 'TimerCreated', onTimerCreated);
|
||||
events.on(serverNotifications, 'SeriesTimerCreated', onSeriesTimerCreated);
|
||||
events.on(serverNotifications, 'TimerCancelled', onTimerCancelled);
|
||||
events.on(serverNotifications, 'SeriesTimerCancelled', onSeriesTimerCancelled);
|
||||
|
||||
self.refresh();
|
||||
});
|
||||
};
|
||||
|
|
|
@ -18,5 +18,8 @@
|
|||
|
||||
<div class="guideRequiresUnlock readOnlyContent hide" style="margin:1em auto;text-align:center;padding:1em;flex-shrink:0;">
|
||||
<p class="unlockText"></p>
|
||||
<paper-button raised class="secondary block btnUnlockGuide"><iron-icon icon="nav:check"></iron-icon><span>${ButtonUnlockGuide}</span></paper-button>
|
||||
<button is="emby-button" type="button" class="raised secondary block btnUnlockGuide">
|
||||
<i class="md-icon">check</i>
|
||||
<span>${UnlockGuide}</span>
|
||||
</button>
|
||||
</div>
|
|
@ -1,45 +0,0 @@
|
|||
<!--
|
||||
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
Code distributed by Google as part of the polymer project is also
|
||||
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
-->
|
||||
<!--
|
||||
`iron-icons` is a utility import that includes the definition for the `iron-icon` element, `iron-iconset-svg` element, as well as an import for the default icon set.
|
||||
|
||||
The `iron-icons` directory also includes imports for additional icon sets that can be loaded into your project.
|
||||
|
||||
Example loading icon set:
|
||||
|
||||
<link rel="import" href="../iron-icons/maps-icons.html">
|
||||
|
||||
To use an icon from one of these sets, first prefix your `iron-icon` with the icon set name, followed by a colon, ":", and then the icon id.
|
||||
|
||||
Example using the directions-bus icon from the maps icon set:
|
||||
|
||||
<iron-icon icon="maps:directions-bus"></iron-icon>
|
||||
|
||||
|
||||
See [iron-icon](#iron-icon) for more information about working with icons.
|
||||
|
||||
See [iron-iconset](#iron-iconset) and [iron-iconset-svg](#iron-iconset-svg) for more information about how to create a custom iconset.
|
||||
|
||||
@group Iron Elements
|
||||
@element iron-icons
|
||||
@demo demo/index.html
|
||||
-->
|
||||
|
||||
<iron-iconset-svg name="mediainfo" size="24">
|
||||
<svg>
|
||||
<defs>
|
||||
<g id="fiber-manual-record"><circle cx="12" cy="12" r="8" /></g>
|
||||
<g id="fiber-smart-record"><g><circle cx="9" cy="12" r="8" /><path d="M17 4.26v2.09c2.33.82 4 3.04 4 5.65s-1.67 4.83-4 5.65v2.09c3.45-.89 6-4.01 6-7.74s-2.55-6.85-6-7.74z" /></g></g>
|
||||
<g id="hd"><path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm2-6h4c.55 0 1 .45 1 1v4c0 .55-.45 1-1 1h-4V9zm1.5 4.5h2v-3h-2v3z" /></g>
|
||||
<g id="closed-caption"><path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z" /></g>
|
||||
<g id="star"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" /></g>
|
||||
<g id="star-half"><path d="M22 9.74l-7.19-.62L12 2.5 9.19 9.13 2 9.74l5.46 4.73-1.64 7.03L12 17.77l6.18 3.73-1.63-7.03L22 9.74zM12 15.9V6.6l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.9z" /></g>
|
||||
</defs>
|
||||
</svg>
|
||||
</iron-iconset-svg>
|
|
@ -1,41 +0,0 @@
|
|||
<!--
|
||||
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
Code distributed by Google as part of the polymer project is also
|
||||
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
-->
|
||||
<!--
|
||||
`iron-icons` is a utility import that includes the definition for the `iron-icon` element, `iron-iconset-svg` element, as well as an import for the default icon set.
|
||||
|
||||
The `iron-icons` directory also includes imports for additional icon sets that can be loaded into your project.
|
||||
|
||||
Example loading icon set:
|
||||
|
||||
<link rel="import" href="../iron-icons/maps-icons.html">
|
||||
|
||||
To use an icon from one of these sets, first prefix your `iron-icon` with the icon set name, followed by a colon, ":", and then the icon id.
|
||||
|
||||
Example using the directions-bus icon from the maps icon set:
|
||||
|
||||
<iron-icon icon="maps:directions-bus"></iron-icon>
|
||||
|
||||
|
||||
See [iron-icon](#iron-icon) for more information about working with icons.
|
||||
|
||||
See [iron-iconset](#iron-iconset) and [iron-iconset-svg](#iron-iconset-svg) for more information about how to create a custom iconset.
|
||||
|
||||
@group Iron Elements
|
||||
@element iron-icons
|
||||
@demo demo/index.html
|
||||
-->
|
||||
|
||||
<iron-iconset-svg name="nav" size="24">
|
||||
<svg>
|
||||
<defs>
|
||||
<g id="arrow-back"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" /></g>
|
||||
<g id="check"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" /></g>
|
||||
</defs>
|
||||
</svg>
|
||||
</iron-iconset-svg>
|
|
@ -4,6 +4,29 @@ define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser
|
|||
var thresholdY;
|
||||
var windowSize;
|
||||
|
||||
var supportsIntersectionObserver = function () {
|
||||
|
||||
if (window.IntersectionObserver) {
|
||||
|
||||
// The api exists in chrome 50 but doesn't work
|
||||
if (browser.chrome) {
|
||||
|
||||
var version = parseInt(browser.version.split('.')[0]);
|
||||
return version >= 51;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}();
|
||||
|
||||
function resetWindowSize() {
|
||||
windowSize = {
|
||||
innerHeight: window.innerHeight,
|
||||
innerWidth: window.innerWidth
|
||||
};
|
||||
}
|
||||
|
||||
function resetThresholds() {
|
||||
|
||||
var x = screen.availWidth;
|
||||
|
@ -19,33 +42,29 @@ define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser
|
|||
resetWindowSize();
|
||||
}
|
||||
|
||||
window.addEventListener("orientationchange", resetThresholds);
|
||||
window.addEventListener('resize', resetThresholds);
|
||||
events.on(layoutManager, 'modechange', resetThresholds);
|
||||
|
||||
var wheelEvent = (document.implementation.hasFeature('Event.wheel', '3.0') ? 'wheel' : 'mousewheel');
|
||||
|
||||
function resetWindowSize() {
|
||||
windowSize = {
|
||||
innerHeight: window.innerHeight,
|
||||
innerWidth: window.innerWidth
|
||||
};
|
||||
if (!supportsIntersectionObserver) {
|
||||
window.addEventListener("orientationchange", resetThresholds);
|
||||
window.addEventListener('resize', resetThresholds);
|
||||
events.on(layoutManager, 'modechange', resetThresholds);
|
||||
resetThresholds();
|
||||
}
|
||||
resetThresholds();
|
||||
|
||||
function isVisible(elem) {
|
||||
return visibleinviewport(elem, true, thresholdX, thresholdY, windowSize);
|
||||
}
|
||||
|
||||
var wheelEvent = (document.implementation.hasFeature('Event.wheel', '3.0') ? 'wheel' : 'mousewheel');
|
||||
var self = {};
|
||||
|
||||
var enableFade = browser.animate && !browser.mobile && !browser.operaTv;
|
||||
|
||||
function fillImage(elem, source, enableEffects) {
|
||||
|
||||
if (!source) {
|
||||
source = elem.getAttribute('data-src');
|
||||
}
|
||||
if (source) {
|
||||
if (self.enableFade && enableEffects !== false) {
|
||||
if (enableFade && !layoutManager.tv && enableEffects !== false) {
|
||||
imageFetcher.loadImage(elem, source).then(fadeIn);
|
||||
} else {
|
||||
imageFetcher.loadImage(elem, source);
|
||||
|
@ -56,10 +75,12 @@ define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser
|
|||
|
||||
function fadeIn(elem) {
|
||||
|
||||
var duration = layoutManager.tv ? 160 : 300;
|
||||
|
||||
var keyframes = [
|
||||
{ opacity: '0', offset: 0 },
|
||||
{ opacity: '1', offset: 1 }];
|
||||
var timing = { duration: 300, iterations: 1 };
|
||||
var timing = { duration: duration, iterations: 1 };
|
||||
elem.animate(keyframes, timing);
|
||||
}
|
||||
|
||||
|
@ -88,30 +109,28 @@ define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser
|
|||
target.addEventListener(type, handler, optionsOrCapture);
|
||||
}
|
||||
|
||||
function unveilWithIntersection(images) {
|
||||
function unveilWithIntersection(images, root) {
|
||||
|
||||
var filledCount = 0;
|
||||
|
||||
var options = {};
|
||||
|
||||
//options.rootMargin = "300%";
|
||||
|
||||
var observer = new IntersectionObserver(function (entries) {
|
||||
for (var j = 0, length2 = entries.length; j < length2; j++) {
|
||||
var entry = entries[j];
|
||||
var intersectionRatio = entry.intersectionRatio;
|
||||
if (intersectionRatio) {
|
||||
|
||||
var target = entry.target;
|
||||
observer.unobserve(target);
|
||||
fillImage(target);
|
||||
filledCount++;
|
||||
}
|
||||
var target = entry.target;
|
||||
observer.unobserve(target);
|
||||
fillImage(target);
|
||||
filledCount++;
|
||||
}
|
||||
|
||||
if (filledCount >= images.length) {
|
||||
//observer.disconnect();
|
||||
observer.disconnect();
|
||||
}
|
||||
},
|
||||
{
|
||||
/* Using default options. Details below */
|
||||
}
|
||||
options
|
||||
);
|
||||
// Start observing an element
|
||||
for (var i = 0, length = images.length; i < length; i++) {
|
||||
|
@ -119,30 +138,14 @@ define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser
|
|||
}
|
||||
}
|
||||
|
||||
var supportsIntersectionObserver = function () {
|
||||
|
||||
if (window.IntersectionObserver) {
|
||||
|
||||
// The api exists in chrome 50 but doesn't work
|
||||
if (browser.chrome) {
|
||||
|
||||
var version = parseInt(browser.version.split('.')[0]);
|
||||
return version >= 51;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}();
|
||||
|
||||
function unveilElements(images) {
|
||||
function unveilElements(images, root) {
|
||||
|
||||
if (!images.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (supportsIntersectionObserver) {
|
||||
unveilWithIntersection(images);
|
||||
unveilWithIntersection(images, root);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -216,7 +219,7 @@ define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser
|
|||
|
||||
function lazyChildren(elem) {
|
||||
|
||||
unveilElements(elem.getElementsByClassName('lazy'));
|
||||
unveilElements(elem.getElementsByClassName('lazy'), elem);
|
||||
}
|
||||
|
||||
function getPrimaryImageAspectRatio(items) {
|
||||
|
|
15
dashboard-ui/bower_components/emby-webcomponents/indicators/indicators.css
vendored
Normal file
15
dashboard-ui/bower_components/emby-webcomponents/indicators/indicators.css
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
.itemProgressBar {
|
||||
background: rgba(0,0,0,.5);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.itemProgressBarForeground {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.timerIndicator {
|
||||
color: #CB272A;
|
||||
}
|
111
dashboard-ui/bower_components/emby-webcomponents/indicators/indicators.js
vendored
Normal file
111
dashboard-ui/bower_components/emby-webcomponents/indicators/indicators.js
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
define(['css!./indicators.css', 'material-icons'], function () {
|
||||
|
||||
function enableProgressIndicator(item) {
|
||||
|
||||
if (item.MediaType == 'Video') {
|
||||
if (item.Type != 'TvChannel') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getProgressHtml(pct) {
|
||||
|
||||
return '<div class="itemProgressBar"><div class="itemProgressBarForeground" style="width:' + pct + '%;"></div></div>';
|
||||
}
|
||||
|
||||
function getProgressBarHtml(item) {
|
||||
|
||||
if (enableProgressIndicator(item)) {
|
||||
if (item.Type == "Recording" && item.CompletionPercentage) {
|
||||
|
||||
return getProgressHtml(item.CompletionPercentage);
|
||||
}
|
||||
|
||||
var userData = item.UserData;
|
||||
if (userData) {
|
||||
var pct = userData.PlayedPercentage;
|
||||
|
||||
if (pct && pct < 100) {
|
||||
|
||||
return getProgressHtml(pct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function enablePlayedIndicator(item) {
|
||||
|
||||
if (item.Type == "Series" || item.Type == "Season" || item.Type == "BoxSet" || item.MediaType == "Video" || item.MediaType == "Game" || item.MediaType == "Book") {
|
||||
|
||||
if (item.Type != 'TvChannel') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getPlayedIndicator(item) {
|
||||
|
||||
if (enablePlayedIndicator(item)) {
|
||||
|
||||
var userData = item.UserData || {};
|
||||
|
||||
if (userData.UnplayedItemCount) {
|
||||
return '<div class="countIndicator indicator">' + userData.UnplayedItemCount + '</div>';
|
||||
}
|
||||
|
||||
if (userData.PlayedPercentage && userData.PlayedPercentage >= 100 || (userData.Played)) {
|
||||
return '<div class="playedIndicator indicator"><i class="md-icon">check</i></div>';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function getCountIndicatorHtml(count) {
|
||||
|
||||
return '<div class="countIndicator indicator">' + count + '</div>';
|
||||
}
|
||||
|
||||
function getChildCountIndicatorHtml(item, options) {
|
||||
|
||||
var minCount = 0;
|
||||
|
||||
if (options) {
|
||||
minCount = options.minCount || minCount;
|
||||
}
|
||||
|
||||
if (item.ChildCount && item.ChildCount > minCount) {
|
||||
return getCountIndicatorHtml(item.ChildCount);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function getTimerIndicator(item) {
|
||||
|
||||
if (item.SeriesTimerId) {
|
||||
return '<i class="md-icon timerIndicator indicator">fiber_smart_record</i>';
|
||||
}
|
||||
if (item.TimerId) {
|
||||
return '<i class="md-icon timerIndicator indicator">fiber_manual_record</i>';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
return {
|
||||
getProgressBarHtml: getProgressBarHtml,
|
||||
getPlayedIndicatorHtml: getPlayedIndicator,
|
||||
getChildCountIndicatorHtml: getChildCountIndicatorHtml,
|
||||
enableProgressIndicator: enableProgressIndicator,
|
||||
getTimerIndicator: getTimerIndicator,
|
||||
enablePlayedIndicator: enablePlayedIndicator
|
||||
};
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
define(['apphost', 'globalize', 'connectionManager'], function (appHost, globalize, connectionManager) {
|
||||
define(['apphost', 'globalize', 'connectionManager', 'itemHelper'], function (appHost, globalize, connectionManager, itemHelper) {
|
||||
|
||||
function getCommands(options) {
|
||||
|
||||
|
@ -11,6 +11,20 @@ define(['apphost', 'globalize', 'connectionManager'], function (appHost, globali
|
|||
|
||||
var commands = [];
|
||||
|
||||
if (itemHelper.supportsAddingToCollection(item)) {
|
||||
commands.push({
|
||||
name: globalize.translate('sharedcomponents#AddToCollection'),
|
||||
id: 'addtocollection'
|
||||
});
|
||||
}
|
||||
|
||||
if (itemHelper.supportsAddingToPlaylist(item)) {
|
||||
commands.push({
|
||||
name: globalize.translate('sharedcomponents#AddToPlaylist'),
|
||||
id: 'addtoplaylist'
|
||||
});
|
||||
}
|
||||
|
||||
if (item.CanDelete) {
|
||||
commands.push({
|
||||
name: globalize.translate('sharedcomponents#Delete'),
|
||||
|
@ -18,6 +32,15 @@ define(['apphost', 'globalize', 'connectionManager'], function (appHost, globali
|
|||
});
|
||||
}
|
||||
|
||||
if (user.Policy.IsAdministrator) {
|
||||
if (item.MediaType == 'Video' && item.Type != 'TvChannel' && item.Type != 'Program' && item.LocationType != 'Virtual') {
|
||||
commands.push({
|
||||
name: globalize.translate('sharedcomponents#EditSubtitles'),
|
||||
id: 'editsubtitles'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (item.CanDownload && appHost.supports('filedownload')) {
|
||||
commands.push({
|
||||
name: globalize.translate('sharedcomponents#Download'),
|
||||
|
@ -54,6 +77,30 @@ define(['apphost', 'globalize', 'connectionManager'], function (appHost, globali
|
|||
|
||||
switch (id) {
|
||||
|
||||
case 'addtocollection':
|
||||
{
|
||||
require(['collectionEditor'], function (collectionEditor) {
|
||||
|
||||
new collectionEditor().show({
|
||||
items: [itemId],
|
||||
serverId: serverId
|
||||
|
||||
}).then(reject, reject);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'addtoplaylist':
|
||||
{
|
||||
require(['playlistEditor'], function (playlistEditor) {
|
||||
|
||||
new playlistEditor().show({
|
||||
items: [itemId],
|
||||
serverId: serverId
|
||||
|
||||
}).then(reject, reject);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'download':
|
||||
{
|
||||
require(['fileDownloader'], function (fileDownloader) {
|
||||
|
@ -71,6 +118,15 @@ define(['apphost', 'globalize', 'connectionManager'], function (appHost, globali
|
|||
reject();
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
case 'editsubtitles':
|
||||
{
|
||||
require(['subtitleEditor'], function (subtitleEditor) {
|
||||
|
||||
var serverId = apiClient.serverInfo().Id;
|
||||
subtitleEditor.show(itemId, serverId).then(resolve, reject);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'refresh':
|
||||
|
@ -127,17 +183,11 @@ define(['apphost', 'globalize', 'connectionManager'], function (appHost, globali
|
|||
|
||||
function refresh(apiClient, itemId) {
|
||||
|
||||
apiClient.refreshItem(itemId, {
|
||||
|
||||
Recursive: true,
|
||||
ImageRefreshMode: 'FullRefresh',
|
||||
MetadataRefreshMode: 'FullRefresh',
|
||||
ReplaceAllImages: false,
|
||||
ReplaceAllMetadata: true
|
||||
});
|
||||
|
||||
require(['toast'], function (toast) {
|
||||
toast(globalize.translate('sharedcomponents#RefreshQueued'));
|
||||
require(['refreshDialog'], function (refreshDialog) {
|
||||
new refreshDialog({
|
||||
itemIds: [itemId],
|
||||
serverId: apiClient.serverInfo().Id
|
||||
}).show();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,25 @@ define([], function () {
|
|||
return name;
|
||||
}
|
||||
|
||||
function supportsAddingToCollection(item) {
|
||||
var invalidTypes = ['Person', 'Genre', 'MusicGenre', 'Studio', 'GameGenre', 'BoxSet', 'Playlist', 'UserView', 'CollectionFolder', 'Audio', 'TvChannel', 'Program', 'MusicAlbum', 'Timer'];
|
||||
|
||||
return !item.CollectionType && invalidTypes.indexOf(item.Type) == -1 && item.MediaType != 'Photo';
|
||||
}
|
||||
|
||||
function supportsAddingToPlaylist(item) {
|
||||
if (item.Type == 'Program') {
|
||||
return false;
|
||||
}
|
||||
if (item.Type == 'Timer') {
|
||||
return false;
|
||||
}
|
||||
return item.RunTimeTicks || item.IsFolder || item.Type == "Genre" || item.Type == "MusicGenre" || item.Type == "MusicArtist";
|
||||
}
|
||||
|
||||
return {
|
||||
getDisplayName: getDisplayName
|
||||
getDisplayName: getDisplayName,
|
||||
supportsAddingToCollection: supportsAddingToCollection,
|
||||
supportsAddingToPlaylist: supportsAddingToPlaylist
|
||||
};
|
||||
});
|
107
dashboard-ui/bower_components/emby-webcomponents/listview/listview.css
vendored
Normal file
107
dashboard-ui/bower_components/emby-webcomponents/listview/listview.css
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
button.listItem {
|
||||
background: transparent;
|
||||
border: 0 !important;
|
||||
cursor: pointer;
|
||||
outline: none !important;
|
||||
color: inherit;
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-align: left;
|
||||
padding: .25em 1.25em !important;
|
||||
}
|
||||
|
||||
.listItem.largeImage {
|
||||
padding: 1em 0 1em 1em;
|
||||
}
|
||||
|
||||
.listItem > *:not(.listItemBody) {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.listItemBody {
|
||||
flex-grow: 1;
|
||||
padding: .85em 1.25em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.listItemBody h3 {
|
||||
margin: 0;
|
||||
font-weight: normal;
|
||||
padding: .25em 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.layout-tv .listItemBody h3 {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.listItemBodyText {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.listItemImage {
|
||||
width: 7.4vh;
|
||||
height: 7.4vh;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.listItemIcon {
|
||||
width: 3vh;
|
||||
height: 3vh;
|
||||
font-size: 3vh;
|
||||
}
|
||||
|
||||
.listItem.largeImage .listItemImage {
|
||||
width: 45vh;
|
||||
height: 30vh;
|
||||
background-position: center center;
|
||||
position: relative;
|
||||
margin-right: 2%;
|
||||
margin-left: 1%;
|
||||
}
|
||||
|
||||
.listItemImage .itemProgressBar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.listItem .secondary {
|
||||
color: #737373;
|
||||
}
|
||||
|
||||
.listItem:focus .secondary {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
transition: transform .2s ease-out;
|
||||
}
|
||||
|
||||
.listItem:focus {
|
||||
transform: scale(1.025, 1.025);
|
||||
}
|
||||
|
||||
.paperList {
|
||||
padding: .5em 0;
|
||||
margin: 1em auto;
|
||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.paperList.clear {
|
||||
box-shadow: none !important;
|
||||
background-color: transparent !important;
|
||||
}
|
142
dashboard-ui/bower_components/emby-webcomponents/listview/listview.js
vendored
Normal file
142
dashboard-ui/bower_components/emby-webcomponents/listview/listview.js
vendored
Normal file
|
@ -0,0 +1,142 @@
|
|||
define(['itemHelper', 'mediaInfo', 'indicators', 'css!./listview'], function (itemHelper, mediaInfo, indicators) {
|
||||
|
||||
function getListViewHtml(items, options) {
|
||||
|
||||
var outerHtml = "";
|
||||
|
||||
var index = 0;
|
||||
var groupTitle = '';
|
||||
var action = options.action || 'link';
|
||||
|
||||
var isLargeStyle = options.imageSize == 'large';
|
||||
var enableOverview = options.enableOverview;
|
||||
|
||||
outerHtml += items.map(function (item) {
|
||||
|
||||
var html = '';
|
||||
|
||||
var cssClass = "itemAction listItem";
|
||||
|
||||
var downloadWidth = 80;
|
||||
|
||||
if (isLargeStyle) {
|
||||
cssClass += " largeImage";
|
||||
downloadWidth = 500;
|
||||
}
|
||||
|
||||
html += '<button class="' + cssClass + '" data-index="' + index + '" data-action="' + action + '" data-isfolder="' + item.IsFolder + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-type="' + item.Type + '">';
|
||||
|
||||
var imgUrl = Emby.Models.imageUrl(item, {
|
||||
width: downloadWidth,
|
||||
type: "Primary"
|
||||
});
|
||||
|
||||
if (!imgUrl) {
|
||||
imgUrl = Emby.Models.thumbImageUrl(item, {
|
||||
width: downloadWidth,
|
||||
type: "Thumb"
|
||||
});
|
||||
}
|
||||
|
||||
if (imgUrl) {
|
||||
html += '<div class="listItemImage lazy" data-src="' + imgUrl + '" item-icon>';
|
||||
} else {
|
||||
html += '<div class="listItemImage" item-icon>';
|
||||
}
|
||||
|
||||
var indicatorsHtml = '';
|
||||
indicatorsHtml += indicators.getPlayedIndicatorHtml(item);
|
||||
|
||||
if (indicatorsHtml) {
|
||||
html += '<div class="indicators">' + indicatorsHtml + '</div>';
|
||||
}
|
||||
|
||||
var progressHtml = indicators.getProgressBarHtml(item);
|
||||
|
||||
if (progressHtml) {
|
||||
html += progressHtml;
|
||||
}
|
||||
html += '</div>';
|
||||
|
||||
var textlines = [];
|
||||
|
||||
if (options.showParentTitle) {
|
||||
if (item.Type == 'Episode') {
|
||||
textlines.push(item.SeriesName || ' ');
|
||||
} else if (item.Type == 'MusicAlbum') {
|
||||
textlines.push(item.AlbumArtist || ' ');
|
||||
}
|
||||
}
|
||||
|
||||
var displayName = itemHelper.getDisplayName(item);
|
||||
|
||||
if (options.showIndexNumber && item.IndexNumber != null) {
|
||||
displayName = item.IndexNumber + ". " + displayName;
|
||||
}
|
||||
textlines.push(displayName);
|
||||
|
||||
if (item.Type == 'Audio') {
|
||||
textlines.push(item.ArtistItems.map(function (a) {
|
||||
return a.Name;
|
||||
|
||||
}).join(', ') || ' ');
|
||||
}
|
||||
|
||||
var lineCount = textlines.length;
|
||||
if (!options.enableSideMediaInfo) {
|
||||
lineCount++;
|
||||
}
|
||||
if (enableOverview && item.Overview) {
|
||||
lineCount++;
|
||||
}
|
||||
|
||||
html += '<div class="listItemBody">';
|
||||
|
||||
for (var i = 0, textLinesLength = textlines.length; i < textLinesLength; i++) {
|
||||
|
||||
if (i == 0 && isLargeStyle) {
|
||||
html += '<h2 class="listItemTitle">';
|
||||
}
|
||||
else if (i == 0) {
|
||||
html += '<div>';
|
||||
} else {
|
||||
html += '<div class="secondary">';
|
||||
}
|
||||
html += textlines[i] || ' ';
|
||||
if (i == 0 && isLargeStyle) {
|
||||
html += '</h2>';
|
||||
} else {
|
||||
html += '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.enableSideMediaInfo) {
|
||||
html += '<div class="secondary listItemMediaInfo">' + mediaInfo.getPrimaryMediaInfoHtml(item) + '</div>';
|
||||
}
|
||||
|
||||
if (enableOverview && item.Overview) {
|
||||
html += '<div class="secondary overview">';
|
||||
html += item.Overview;
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
html += '</div>';
|
||||
|
||||
if (options.enableSideMediaInfo) {
|
||||
html += '<div class="secondary listItemMediaInfo">' + mediaInfo.getPrimaryMediaInfoHtml(item) + '</div>';
|
||||
}
|
||||
|
||||
html += '</button>';
|
||||
|
||||
index++;
|
||||
return html;
|
||||
|
||||
}).join('');
|
||||
|
||||
return outerHtml;
|
||||
}
|
||||
|
||||
return {
|
||||
getListViewHtml: getListViewHtml
|
||||
};
|
||||
});
|
522
dashboard-ui/bower_components/emby-webcomponents/loading/loading-lite.css
vendored
Normal file
522
dashboard-ui/bower_components/emby-webcomponents/loading/loading-lite.css
vendored
Normal file
|
@ -0,0 +1,522 @@
|
|||
.mdl-spinner {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.mdl-spinner.is-active {
|
||||
-webkit-animation: mdl-spinner__container-rotate 1568.23529412ms linear infinite;
|
||||
animation: mdl-spinner__container-rotate 1568.23529412ms linear infinite;
|
||||
}
|
||||
|
||||
@-webkit-keyframes mdl-spinner__container-rotate {
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mdl-spinner__container-rotate {
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.mdl-spinner__layer {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.mdl-spinner__layer-1 {
|
||||
border-color: rgb(66,165,245);
|
||||
}
|
||||
|
||||
.mdl-spinner--single-color .mdl-spinner__layer-1 {
|
||||
border-color: rgb(63,81,181);
|
||||
}
|
||||
|
||||
.mdl-spinner.is-active .mdl-spinner__layer-1 {
|
||||
-webkit-animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
||||
animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
||||
}
|
||||
|
||||
.mdl-spinner__layer-2 {
|
||||
border-color: rgb(244,67,54);
|
||||
}
|
||||
|
||||
.mdl-spinner--single-color .mdl-spinner__layer-2 {
|
||||
border-color: rgb(63,81,181);
|
||||
}
|
||||
|
||||
.mdl-spinner.is-active .mdl-spinner__layer-2 {
|
||||
-webkit-animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
||||
animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
||||
}
|
||||
|
||||
.mdl-spinner__layer-3 {
|
||||
border-color: rgb(253,216,53);
|
||||
}
|
||||
|
||||
.mdl-spinner--single-color .mdl-spinner__layer-3 {
|
||||
border-color: rgb(63,81,181);
|
||||
}
|
||||
|
||||
.mdl-spinner.is-active .mdl-spinner__layer-3 {
|
||||
-webkit-animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
||||
animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
||||
}
|
||||
|
||||
.mdl-spinner__layer-4 {
|
||||
border-color: rgb(76,175,80);
|
||||
}
|
||||
|
||||
.mdl-spinner--single-color .mdl-spinner__layer-4 {
|
||||
border-color: rgb(63,81,181);
|
||||
}
|
||||
|
||||
.mdl-spinner.is-active .mdl-spinner__layer-4 {
|
||||
-webkit-animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
||||
animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
||||
}
|
||||
|
||||
@-webkit-keyframes mdl-spinner__fill-unfill-rotate {
|
||||
12.5% {
|
||||
-webkit-transform: rotate(135deg);
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
|
||||
25% {
|
||||
-webkit-transform: rotate(270deg);
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
|
||||
37.5% {
|
||||
-webkit-transform: rotate(405deg);
|
||||
transform: rotate(405deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
-webkit-transform: rotate(540deg);
|
||||
transform: rotate(540deg);
|
||||
}
|
||||
|
||||
62.5% {
|
||||
-webkit-transform: rotate(675deg);
|
||||
transform: rotate(675deg);
|
||||
}
|
||||
|
||||
75% {
|
||||
-webkit-transform: rotate(810deg);
|
||||
transform: rotate(810deg);
|
||||
}
|
||||
|
||||
87.5% {
|
||||
-webkit-transform: rotate(945deg);
|
||||
transform: rotate(945deg);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(1080deg);
|
||||
transform: rotate(1080deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mdl-spinner__fill-unfill-rotate {
|
||||
12.5% {
|
||||
-webkit-transform: rotate(135deg);
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
|
||||
25% {
|
||||
-webkit-transform: rotate(270deg);
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
|
||||
37.5% {
|
||||
-webkit-transform: rotate(405deg);
|
||||
transform: rotate(405deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
-webkit-transform: rotate(540deg);
|
||||
transform: rotate(540deg);
|
||||
}
|
||||
|
||||
62.5% {
|
||||
-webkit-transform: rotate(675deg);
|
||||
transform: rotate(675deg);
|
||||
}
|
||||
|
||||
75% {
|
||||
-webkit-transform: rotate(810deg);
|
||||
transform: rotate(810deg);
|
||||
}
|
||||
|
||||
87.5% {
|
||||
-webkit-transform: rotate(945deg);
|
||||
transform: rotate(945deg);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(1080deg);
|
||||
transform: rotate(1080deg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HACK: Even though the intention is to have the current .mdl-spinner__layer-N
|
||||
* at `opacity: 1`, we set it to `opacity: 0.99` instead since this forces Chrome
|
||||
* to do proper subpixel rendering for the elements being animated. This is
|
||||
* especially visible in Chrome 39 on Ubuntu 14.04. See:
|
||||
*
|
||||
* - https://github.com/Polymer/paper-spinner/issues/9
|
||||
* - https://code.google.com/p/chromium/issues/detail?id=436255
|
||||
*/
|
||||
@-webkit-keyframes mdl-spinner__layer-1-fade-in-out {
|
||||
from {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
25% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
26% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
89% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
90% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mdl-spinner__layer-1-fade-in-out {
|
||||
from {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
25% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
26% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
89% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
90% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes mdl-spinner__layer-2-fade-in-out {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
15% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
25% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
51% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mdl-spinner__layer-2-fade-in-out {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
15% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
25% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
51% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes mdl-spinner__layer-3-fade-in-out {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
40% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
75% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
76% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mdl-spinner__layer-3-fade-in-out {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
40% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
75% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
76% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes mdl-spinner__layer-4-fade-in-out {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
65% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
75% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
90% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mdl-spinner__layer-4-fade-in-out {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
65% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
75% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
90% {
|
||||
opacity: 0.99;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch the gap that appear between the two adjacent
|
||||
* div.mdl-spinner__circle-clipper while the spinner is rotating
|
||||
* (appears on Chrome 38, Safari 7.1, and IE 11).
|
||||
*
|
||||
* Update: the gap no longer appears on Chrome when .mdl-spinner__layer-N's
|
||||
* opacity is 0.99, but still does on Safari and IE.
|
||||
*/
|
||||
.mdl-spinner__gap-patch {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
top: 0;
|
||||
left: 45%;
|
||||
width: 10%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
border-color: inherit;
|
||||
}
|
||||
|
||||
.mdl-spinner__gap-patch .mdl-spinner__circle {
|
||||
width: 1000%;
|
||||
left: -450%;
|
||||
}
|
||||
|
||||
.mdl-spinner__circle-clipper {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
border-color: inherit;
|
||||
}
|
||||
|
||||
.mdl-spinner__circle-clipper .mdl-spinner__circle {
|
||||
width: 200%;
|
||||
}
|
||||
|
||||
.mdl-spinner__circle {
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
border-width: 3px;
|
||||
border-style: solid;
|
||||
border-color: inherit;
|
||||
border-bottom-color: transparent !important;
|
||||
border-radius: 50%;
|
||||
-webkit-animation: none;
|
||||
animation: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.mdl-spinner__left .mdl-spinner__circle {
|
||||
border-right-color: transparent !important;
|
||||
-webkit-transform: rotate(129deg);
|
||||
transform: rotate(129deg);
|
||||
}
|
||||
|
||||
.mdl-spinner.is-active .mdl-spinner__left .mdl-spinner__circle {
|
||||
-webkit-animation: mdl-spinner__left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
||||
animation: mdl-spinner__left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
||||
}
|
||||
|
||||
.mdl-spinner__right .mdl-spinner__circle {
|
||||
left: -100%;
|
||||
border-left-color: transparent !important;
|
||||
-webkit-transform: rotate(-129deg);
|
||||
transform: rotate(-129deg);
|
||||
}
|
||||
|
||||
.mdl-spinner.is-active .mdl-spinner__right .mdl-spinner__circle {
|
||||
-webkit-animation: mdl-spinner__right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
||||
animation: mdl-spinner__right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
||||
}
|
||||
|
||||
@-webkit-keyframes mdl-spinner__left-spin {
|
||||
from {
|
||||
-webkit-transform: rotate(130deg);
|
||||
transform: rotate(130deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
-webkit-transform: rotate(-5deg);
|
||||
transform: rotate(-5deg);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(130deg);
|
||||
transform: rotate(130deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mdl-spinner__left-spin {
|
||||
from {
|
||||
-webkit-transform: rotate(130deg);
|
||||
transform: rotate(130deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
-webkit-transform: rotate(-5deg);
|
||||
transform: rotate(-5deg);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(130deg);
|
||||
transform: rotate(130deg);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes mdl-spinner__right-spin {
|
||||
from {
|
||||
-webkit-transform: rotate(-130deg);
|
||||
transform: rotate(-130deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
-webkit-transform: rotate(5deg);
|
||||
transform: rotate(5deg);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(-130deg);
|
||||
transform: rotate(-130deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mdl-spinner__right-spin {
|
||||
from {
|
||||
-webkit-transform: rotate(-130deg);
|
||||
transform: rotate(-130deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
-webkit-transform: rotate(5deg);
|
||||
transform: rotate(5deg);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(-130deg);
|
||||
transform: rotate(-130deg);
|
||||
}
|
||||
}
|
||||
|
||||
.docspinner {
|
||||
margin-top: -5vh;
|
||||
margin-left: -5vh;
|
||||
width: 10vh;
|
||||
height: 10vh;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 9999999;
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
.loadingHide {
|
||||
display: none !important;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
define(['MaterialSpinner', 'css!./loading'], function () {
|
||||
define(['css!./loading-lite'], function () {
|
||||
|
||||
var loadingElem;
|
||||
|
||||
|
@ -15,8 +15,9 @@ define(['MaterialSpinner', 'css!./loading'], function () {
|
|||
elem.classList.add('mdl-spinner');
|
||||
elem.classList.add('mdl-js-spinner');
|
||||
|
||||
elem.innerHTML = '<div class="mdl-spinner__layer mdl-spinner__layer-1"><div class="mdl-spinner__circle-clipper mdl-spinner__left"><div class="mdl-spinner__circle"></div></div><div class="mdl-spinner__gap-patch"><div class="mdl-spinner__circle"></div></div><div class="mdl-spinner__circle-clipper mdl-spinner__right"><div class="mdl-spinner__circle"></div></div></div><div class="mdl-spinner__layer mdl-spinner__layer-2"><div class="mdl-spinner__circle-clipper mdl-spinner__left"><div class="mdl-spinner__circle"></div></div><div class="mdl-spinner__gap-patch"><div class="mdl-spinner__circle"></div></div><div class="mdl-spinner__circle-clipper mdl-spinner__right"><div class="mdl-spinner__circle"></div></div></div><div class="mdl-spinner__layer mdl-spinner__layer-3"><div class="mdl-spinner__circle-clipper mdl-spinner__left"><div class="mdl-spinner__circle"></div></div><div class="mdl-spinner__gap-patch"><div class="mdl-spinner__circle"></div></div><div class="mdl-spinner__circle-clipper mdl-spinner__right"><div class="mdl-spinner__circle"></div></div></div><div class="mdl-spinner__layer mdl-spinner__layer-4"><div class="mdl-spinner__circle-clipper mdl-spinner__left"><div class="mdl-spinner__circle"></div></div><div class="mdl-spinner__gap-patch"><div class="mdl-spinner__circle"></div></div><div class="mdl-spinner__circle-clipper mdl-spinner__right"><div class="mdl-spinner__circle"></div></div></div>';
|
||||
|
||||
document.body.appendChild(elem);
|
||||
componentHandler.upgradeElement(elem, 'MaterialSpinner');
|
||||
}
|
||||
|
||||
elem.classList.add('is-active');
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
margin: 0 1em 0 0;
|
||||
}
|
||||
|
||||
iron-icon.mediaInfoItem {
|
||||
i.mediaInfoItem {
|
||||
width: 3vh;
|
||||
height: 3vh;
|
||||
font-size: 3vh;
|
||||
margin-right: .6em;
|
||||
}
|
||||
|
||||
|
@ -21,10 +22,11 @@ iron-icon.mediaInfoItem {
|
|||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.starRatingContainer iron-icon {
|
||||
.starRatingContainer i {
|
||||
color: #CB272A;
|
||||
width: 3vh;
|
||||
height: 3vh;
|
||||
font-size: 3vh;
|
||||
}
|
||||
|
||||
.mediaInfoItem.criticRating {
|
||||
|
@ -54,12 +56,14 @@ iron-icon.mediaInfoItem {
|
|||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.layout-tv iron-icon.mediaInfoItem {
|
||||
.layout-tv i.mediaInfoItem {
|
||||
width: 4vh;
|
||||
height: 4vh;
|
||||
font-size: 4vh;
|
||||
}
|
||||
|
||||
.layout-tv .starRatingContainer iron-icon {
|
||||
.layout-tv .starRatingContainer i {
|
||||
width: 3.4vh;
|
||||
height: 3.4vh;
|
||||
font-size: 3.4vh;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(['datetime', 'globalize', 'embyRouter', 'html!./../icons/mediainfo.html', 'css!./mediainfo.css'], function (datetime, globalize, embyRouter) {
|
||||
define(['datetime', 'globalize', 'embyRouter', 'material-icons', 'css!./mediainfo.css'], function (datetime, globalize, embyRouter) {
|
||||
|
||||
function getProgramInfoHtml(item, options) {
|
||||
var html = '';
|
||||
|
@ -42,12 +42,12 @@ define(['datetime', 'globalize', 'embyRouter', 'html!./../icons/mediainfo.html',
|
|||
|
||||
if (item.SeriesTimerId) {
|
||||
miscInfo.push({
|
||||
html: '<iron-icon class="mediaInfoItem timerIcon" icon="mediainfo:fiber-smart-record"></iron-icon>'
|
||||
html: '<i class="md-icon mediaInfoItem timerIcon">fiber-smart-record</i>'
|
||||
});
|
||||
}
|
||||
else if (item.TimerId) {
|
||||
miscInfo.push({
|
||||
html: '<iron-icon class="mediaInfoItem timerIcon" icon="mediainfo:fiber-manual-record"></iron-icon>'
|
||||
html: '<i class="md-icon mediaInfoItem timerIcon">fiber-manual-record</i>'
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -244,7 +244,7 @@ define(['datetime', 'globalize', 'embyRouter', 'html!./../icons/mediainfo.html',
|
|||
html += getStarIconsHtml(item);
|
||||
|
||||
if (item.HasSubtitles && options.subtitles !== false) {
|
||||
html += '<iron-icon class="mediaInfoItem closedCaptionIcon" icon="mediainfo:closed-caption"></iron-icon>';
|
||||
html += '<i class="md-icon mediaInfoItem closedCaptionIcon">closed_caption</i>';
|
||||
}
|
||||
|
||||
if (item.CriticRating && options.criticRating !== false) {
|
||||
|
@ -321,7 +321,7 @@ define(['datetime', 'globalize', 'embyRouter', 'html!./../icons/mediainfo.html',
|
|||
if (rating) {
|
||||
html += '<div class="starRatingContainer mediaInfoItem">';
|
||||
|
||||
html += '<iron-icon icon="mediainfo:star"></iron-icon>';
|
||||
html += '<i class="md-icon">star</i>';
|
||||
html += rating;
|
||||
html += '</div>';
|
||||
}
|
||||
|
|
259
dashboard-ui/bower_components/emby-webcomponents/playlisteditor/playlisteditor.js
vendored
Normal file
259
dashboard-ui/bower_components/emby-webcomponents/playlisteditor/playlisteditor.js
vendored
Normal file
|
@ -0,0 +1,259 @@
|
|||
define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionManager', 'scrollHelper', 'embyRouter', 'globalize', 'emby-input', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button'], function (shell, dialogHelper, loading, layoutManager, connectionManager, scrollHelper, embyRouter, globalize) {
|
||||
|
||||
var lastPlaylistId = '';
|
||||
var currentServerId;
|
||||
|
||||
function parentWithClass(elem, className) {
|
||||
|
||||
while (!elem.classList || !elem.classList.contains(className)) {
|
||||
elem = elem.parentNode;
|
||||
|
||||
if (!elem) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
function onSubmit(e) {
|
||||
|
||||
loading.show();
|
||||
|
||||
var panel = parentWithClass(this, 'dialog');
|
||||
|
||||
var playlistId = panel.querySelector('#selectPlaylistToAddTo').value;
|
||||
var apiClient = connectionManager.getApiClient(currentServerId);
|
||||
|
||||
if (playlistId) {
|
||||
lastPlaylistId = playlistId;
|
||||
addToPlaylist(apiClient, panel, playlistId);
|
||||
} else {
|
||||
createPlaylist(apiClient, panel);
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
function createPlaylist(apiClient, dlg) {
|
||||
|
||||
var url = apiClient.getUrl("Playlists", {
|
||||
|
||||
Name: dlg.querySelector('#txtNewPlaylistName').value,
|
||||
Ids: dlg.querySelector('.fldSelectedItemIds').value || '',
|
||||
userId: apiClient.getCurrentUserId()
|
||||
|
||||
});
|
||||
|
||||
apiClient.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
dataType: "json"
|
||||
|
||||
}).then(function (result) {
|
||||
|
||||
loading.hide();
|
||||
|
||||
var id = result.Id;
|
||||
|
||||
dialogHelper.close(dlg);
|
||||
redirectToPlaylist(apiClient, id);
|
||||
});
|
||||
}
|
||||
|
||||
function redirectToPlaylist(apiClient, id) {
|
||||
|
||||
apiClient.getItem(apiClient.getCurrentUserId(), id).then(function (item) {
|
||||
|
||||
embyRouter.showItem(item);
|
||||
});
|
||||
}
|
||||
|
||||
function addToPlaylist(apiClient, dlg, id) {
|
||||
|
||||
var url = apiClient.getUrl("Playlists/" + id + "/Items", {
|
||||
|
||||
Ids: dlg.querySelector('.fldSelectedItemIds').value || '',
|
||||
userId: apiClient.getCurrentUserId()
|
||||
});
|
||||
|
||||
apiClient.ajax({
|
||||
type: "POST",
|
||||
url: url
|
||||
|
||||
}).then(function () {
|
||||
|
||||
loading.hide();
|
||||
|
||||
dialogHelper.close(dlg);
|
||||
|
||||
require(['toast'], function (toast) {
|
||||
toast(globalize.translate('sharedcomponents#MessageItemsAdded'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function triggerChange(select) {
|
||||
select.dispatchEvent(new CustomEvent('change', {}));
|
||||
}
|
||||
|
||||
function populatePlaylists(panel) {
|
||||
|
||||
var select = panel.querySelector('#selectPlaylistToAddTo');
|
||||
|
||||
loading.hide();
|
||||
|
||||
panel.querySelector('.newPlaylistInfo').classList.add('hide');
|
||||
|
||||
var options = {
|
||||
|
||||
Recursive: true,
|
||||
IncludeItemTypes: "Playlist",
|
||||
SortBy: 'SortName'
|
||||
};
|
||||
|
||||
var apiClient = connectionManager.getApiClient(currentServerId);
|
||||
apiClient.getItems(apiClient.getCurrentUserId(), options).then(function (result) {
|
||||
|
||||
var html = '';
|
||||
|
||||
html += '<option value="">' + globalize.translate('sharedcomponents#OptionNew') + '</option>';
|
||||
|
||||
html += result.Items.map(function (i) {
|
||||
|
||||
return '<option value="' + i.Id + '">' + i.Name + '</option>';
|
||||
});
|
||||
|
||||
select.innerHTML = html;
|
||||
select.value = lastPlaylistId || '';
|
||||
triggerChange(select);
|
||||
|
||||
loading.hide();
|
||||
});
|
||||
}
|
||||
|
||||
function getEditorHtml() {
|
||||
|
||||
var html = '';
|
||||
|
||||
html += '<div class="dialogContent smoothScrollY">';
|
||||
html += '<div class="dialogContentInner centeredContent">';
|
||||
html += '<form style="margin:auto;">';
|
||||
|
||||
html += '<div class="fldSelectPlaylist">';
|
||||
html += '<select is="emby-select" id="selectPlaylistToAddTo" label="' + globalize.translate('sharedcomponents#LabelPlaylist') + '" autofocus></select>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<div class="newPlaylistInfo">';
|
||||
|
||||
html += '<div class="inputContainer">';
|
||||
html += '<input is="emby-input" type="text" id="txtNewPlaylistName" required="required" label="' + globalize.translate('sharedcomponents#LabelName') + '" />';
|
||||
html += '</div>';
|
||||
|
||||
// newPlaylistInfo
|
||||
html += '</div>';
|
||||
|
||||
html += '<div>';
|
||||
html += '<button is="emby-button" type="submit" class="raised btnSubmit block">' + globalize.translate('sharedcomponents#ButtonOk') + '</button>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<input type="hidden" class="fldSelectedItemIds" />';
|
||||
|
||||
html += '</form>';
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function initEditor(content, items) {
|
||||
|
||||
content.querySelector('#selectPlaylistToAddTo').addEventListener('change', function () {
|
||||
if (this.value) {
|
||||
content.querySelector('.newPlaylistInfo').classList.add('hide');
|
||||
content.querySelector('#txtNewPlaylistName').removeAttribute('required');
|
||||
} else {
|
||||
content.querySelector('.newPlaylistInfo').classList.remove('hide');
|
||||
content.querySelector('#txtNewPlaylistName').setAttribute('required', 'required');
|
||||
}
|
||||
});
|
||||
|
||||
content.querySelector('form').addEventListener('submit', onSubmit);
|
||||
|
||||
content.querySelector('.fldSelectedItemIds', content).value = items.join(',');
|
||||
|
||||
if (items.length) {
|
||||
content.querySelector('.fldSelectPlaylist').classList.remove('hide');
|
||||
populatePlaylists(content);
|
||||
} else {
|
||||
content.querySelector('.fldSelectPlaylist').classList.add('hide');
|
||||
|
||||
var selectPlaylistToAddTo = content.querySelector('#selectPlaylistToAddTo');
|
||||
selectPlaylistToAddTo.innerHTML = '';
|
||||
selectPlaylistToAddTo.value = '';
|
||||
triggerChange(selectPlaylistToAddTo);
|
||||
}
|
||||
}
|
||||
|
||||
function playlisteditor() {
|
||||
|
||||
var self = this;
|
||||
|
||||
self.show = function (options) {
|
||||
|
||||
var items = options.items || {};
|
||||
currentServerId = options.serverId;
|
||||
|
||||
var dialogOptions = {
|
||||
removeOnClose: true,
|
||||
scrollY: false
|
||||
};
|
||||
|
||||
if (layoutManager.tv) {
|
||||
dialogOptions.size = 'fullscreen';
|
||||
} else {
|
||||
dialogOptions.size = 'small';
|
||||
}
|
||||
|
||||
var dlg = dialogHelper.createDialog(dialogOptions);
|
||||
|
||||
dlg.classList.add('formDialog');
|
||||
|
||||
var html = '';
|
||||
var title = globalize.translate('sharedcomponents#AddToPlaylist');
|
||||
|
||||
html += '<div class="dialogHeader" style="margin:0 0 2em;">';
|
||||
html += '<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="md-icon">arrow_back</i></button>';
|
||||
html += '<div class="dialogHeaderTitle">';
|
||||
html += title;
|
||||
html += '</div>';
|
||||
|
||||
html += '</div>';
|
||||
|
||||
html += getEditorHtml();
|
||||
|
||||
dlg.innerHTML = html;
|
||||
document.body.appendChild(dlg);
|
||||
|
||||
initEditor(dlg, items);
|
||||
|
||||
dlg.querySelector('.btnCancel').addEventListener('click', function () {
|
||||
|
||||
dialogHelper.close(dlg);
|
||||
});
|
||||
|
||||
if (layoutManager.tv) {
|
||||
scrollHelper.centerFocus.on(dlg.querySelector('.dialogContent'), false);
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
dlg.addEventListener('close', resolve);
|
||||
dialogHelper.open(dlg);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
return playlisteditor;
|
||||
});
|
|
@ -1,10 +1,10 @@
|
|||
define(['dialogHelper', 'layoutManager', 'globalize', 'html!./../icons/nav.html', 'css!./style.css', 'paper-button', 'paper-icon-button-light', 'paper-input'], function (dialogHelper, layoutManager, globalize) {
|
||||
define(['dialogHelper', 'layoutManager', 'globalize', 'material-icons', 'css!./style.css', 'emby-button', 'paper-icon-button-light', 'emby-input'], function (dialogHelper, layoutManager, globalize) {
|
||||
|
||||
function getIcon(icon, cssClass, canFocus, autoFocus) {
|
||||
|
||||
var tabIndex = canFocus ? '' : ' tabindex="-1"';
|
||||
autoFocus = autoFocus ? ' autofocus' : '';
|
||||
return '<button is="paper-icon-button-light" class="' + cssClass + '"' + tabIndex + autoFocus + '><iron-icon icon="' + icon + '"></iron-icon></button>';
|
||||
return '<button is="paper-icon-button-light" class="autoSize ' + cssClass + '"' + tabIndex + autoFocus + '><i class="md-icon">' + icon + '</i></button>';
|
||||
}
|
||||
|
||||
return function (options) {
|
||||
|
@ -43,7 +43,7 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'html!./../icons/nav.html'
|
|||
|
||||
html += '<div class="promptDialogContent">';
|
||||
if (backButton) {
|
||||
html += getIcon('dialog:arrow-back', 'btnPromptExit', false);
|
||||
html += getIcon('arrow_back', 'btnPromptExit', false);
|
||||
}
|
||||
|
||||
if (options.title) {
|
||||
|
@ -54,21 +54,23 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'html!./../icons/nav.html'
|
|||
|
||||
html += '<form>';
|
||||
|
||||
html += '<paper-input autoFocus class="txtPromptValue" value="' + (options.value || '') + '" label="' + (options.label || '') + '"></paper-input>';
|
||||
html += '<div class="inputContainer">';
|
||||
html += '<input is="emby-input" type="text" autoFocus class="txtPromptValue" value="' + (options.value || '') + '" label="' + (options.label || '') + '"/>';
|
||||
|
||||
if (options.description) {
|
||||
html += '<div class="fieldDescription">';
|
||||
html += options.description;
|
||||
html += '</div>';
|
||||
}
|
||||
html += '</div>';
|
||||
|
||||
html += '<br/>';
|
||||
if (raisedButtons) {
|
||||
html += '<paper-button raised class="btnSubmit"><iron-icon icon="nav:check"></iron-icon><span>' + globalize.translate('sharedcomponents#ButtonOk') + '</span></paper-button>';
|
||||
html += '<button is="emby-button" type="submit" class="raised btnSubmit"><i class="md-icon">check</i><span>' + globalize.translate('sharedcomponents#ButtonOk') + '</span></button>';
|
||||
} else {
|
||||
html += '<div class="buttons">';
|
||||
html += '<paper-button class="btnSubmit">' + globalize.translate('sharedcomponents#ButtonOk') + '</paper-button>';
|
||||
html += '<paper-button class="btnPromptExit">' + globalize.translate('sharedcomponents#ButtonCancel') + '</paper-button>';
|
||||
html += '<button is="emby-button" type="submit" class="btnSubmit">' + globalize.translate('sharedcomponents#ButtonOk') + '</button>';
|
||||
html += '<button is="emby-button" type="button" class="btnPromptExit">' + globalize.translate('sharedcomponents#ButtonCancel') + '</button>';
|
||||
html += '</div>';
|
||||
}
|
||||
html += '</form>';
|
||||
|
@ -93,18 +95,6 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'html!./../icons/nav.html'
|
|||
return false;
|
||||
});
|
||||
|
||||
dlg.querySelector('.btnSubmit').addEventListener('click', function (e) {
|
||||
|
||||
// Do a fake form submit this the button isn't a real submit button
|
||||
var fakeSubmit = document.createElement('input');
|
||||
fakeSubmit.setAttribute('type', 'submit');
|
||||
fakeSubmit.style.display = 'none';
|
||||
var form = dlg.querySelector('form');
|
||||
form.appendChild(fakeSubmit);
|
||||
fakeSubmit.click();
|
||||
form.removeChild(fakeSubmit);
|
||||
});
|
||||
|
||||
dlg.querySelector('.btnPromptExit').addEventListener('click', function (e) {
|
||||
|
||||
dialogHelper.close(dlg);
|
||||
|
|
|
@ -22,7 +22,10 @@
|
|||
}
|
||||
|
||||
.promptDialog.fullscreen .btnSubmit {
|
||||
display: block;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.promptDialog.fullscreen .btnPromptExit {
|
||||
|
@ -30,6 +33,10 @@
|
|||
position: absolute;
|
||||
top: .5em;
|
||||
left: .5em;
|
||||
width: 5.2vh;
|
||||
height: 5.2vh;
|
||||
}
|
||||
|
||||
.promptDialog.fullscreen .btnPromptExit i {
|
||||
width: 4.4vh;
|
||||
height: 4.4vh;
|
||||
font-size: 4.4vh;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
.recordingDialog .btnSubmit iron-icon {
|
||||
.recordingDialog .btnSubmit .md-icon {
|
||||
color: #cc3333;
|
||||
}
|
||||
|
||||
.layout-tv .btnHeaderSave {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media all and (max-height: 1400px) {
|
||||
|
||||
.layout-tv .recordingDialog .itemOverview {
|
||||
display: none;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'scrollStyles', 'paper-checkbox', 'emby-collapsible', 'paper-input', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'html!./../icons/mediainfo.html', 'html!./../icons/nav.html'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper) {
|
||||
define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'emby-checkbox', 'emby-button', 'emby-collapsible', 'emby-input', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'material-icons'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper) {
|
||||
|
||||
var currentProgramId;
|
||||
var currentServerId;
|
||||
|
@ -38,7 +38,9 @@
|
|||
}
|
||||
|
||||
function hideSeriesRecordingFields(context) {
|
||||
slideUpToHide(context.querySelector('#seriesFields'));
|
||||
|
||||
slideUpToHide(context.querySelector('.seriesFields'));
|
||||
slideUpToHide(context.querySelector('.seriesDays'));
|
||||
context.querySelector('.btnSubmit').classList.remove('hide');
|
||||
context.querySelector('.supporterContainer').classList.add('hide');
|
||||
}
|
||||
|
@ -123,8 +125,19 @@
|
|||
});
|
||||
}
|
||||
|
||||
function showSeriesDays(context) {
|
||||
|
||||
if (context.querySelector('#chkAnyTime').checked) {
|
||||
slideUpToHide(context.querySelector('.seriesDays'));
|
||||
} else {
|
||||
slideDownToShow(context.querySelector('.seriesDays'));
|
||||
}
|
||||
}
|
||||
|
||||
function showSeriesRecordingFields(context, apiClient) {
|
||||
slideDownToShow(context.querySelector('#seriesFields'));
|
||||
|
||||
slideDownToShow(context.querySelector('.seriesFields'));
|
||||
showSeriesDays(context);
|
||||
context.querySelector('.btnSubmit').classList.remove('hide');
|
||||
|
||||
getRegistration(currentProgramId, apiClient).then(function (regInfo) {
|
||||
|
@ -195,21 +208,10 @@
|
|||
});
|
||||
}
|
||||
|
||||
function onPremiereLinkClicked(e) {
|
||||
|
||||
require(['shell'], function (shell) {
|
||||
shell.openUrl('https://emby.media/premiere');
|
||||
});
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
function init(context) {
|
||||
|
||||
var apiClient = connectionManager.getApiClient(currentServerId);
|
||||
|
||||
context.querySelector('.lnkPremiere').addEventListener('click', onPremiereLinkClicked);
|
||||
|
||||
context.querySelector('#chkRecordSeries').addEventListener('change', function () {
|
||||
|
||||
if (this.checked) {
|
||||
|
@ -219,27 +221,16 @@
|
|||
}
|
||||
});
|
||||
|
||||
context.querySelector('.btnSubmit').addEventListener('click', function () {
|
||||
|
||||
// Do a fake form submit this the button isn't a real submit button
|
||||
var fakeSubmit = document.createElement('input');
|
||||
fakeSubmit.setAttribute('type', 'submit');
|
||||
fakeSubmit.style.display = 'none';
|
||||
var form = context.querySelector('form');
|
||||
form.appendChild(fakeSubmit);
|
||||
fakeSubmit.click();
|
||||
|
||||
// Seeing issues in smart tv browsers where the form does not get submitted if the button is removed prior to the submission actually happening
|
||||
setTimeout(function () {
|
||||
form.removeChild(fakeSubmit);
|
||||
}, 500);
|
||||
});
|
||||
|
||||
context.querySelector('.btnCancel').addEventListener('click', function () {
|
||||
|
||||
closeDialog(false);
|
||||
});
|
||||
|
||||
context.querySelector('#chkAnyTime').addEventListener('change', function () {
|
||||
|
||||
showSeriesDays(context);
|
||||
});
|
||||
|
||||
context.querySelector('form', context).addEventListener('submit', onSubmit);
|
||||
|
||||
var supporterButtons = context.querySelectorAll('.btnSupporter');
|
||||
|
@ -251,12 +242,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
if (appHost.supports('externalpremium')) {
|
||||
context.querySelector('.btnSupporterForConverting a').href = 'https://emby.media/premiere';
|
||||
} else {
|
||||
context.querySelector('.btnSupporterForConverting a').href = '#';
|
||||
}
|
||||
|
||||
apiClient.getNamedConfiguration("livetv").then(function (config) {
|
||||
|
||||
context.querySelector('#chkConvertRecordings').checked = config.EnableRecordingEncoding;
|
||||
|
@ -330,6 +315,15 @@
|
|||
});
|
||||
}
|
||||
|
||||
function onSupporterButtonClick() {
|
||||
if (appHost.supports('externalpremium')) {
|
||||
require(['shell'], function (shell) {
|
||||
shell.openUrl('https://emby.media/premiere');
|
||||
});
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
function reload(context, programId) {
|
||||
|
||||
loading.show();
|
||||
|
@ -400,6 +394,8 @@
|
|||
scrollHelper.centerFocus.on(dlg.querySelector('.dialogContent'), false);
|
||||
}
|
||||
|
||||
dlg.querySelector('.btnSupporterForConverting').addEventListener('click', onSupporterButtonClick);
|
||||
|
||||
hideSeriesRecordingFields(dlg);
|
||||
init(dlg);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="dialogHeader">
|
||||
<button is="paper-icon-button-light" class="btnCancel" tabindex="-1"><iron-icon icon="nav:arrow-back"></iron-icon></button>
|
||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="md-icon">arrow_back</i></button>
|
||||
<div class="dialogHeaderTitle">
|
||||
${HeaderNewRecording}
|
||||
</div>
|
||||
|
@ -14,49 +14,84 @@
|
|||
|
||||
<div id="eligibleForSeriesFields" class="hide">
|
||||
<br />
|
||||
<div>
|
||||
<paper-checkbox id="chkRecordSeries">${RecordSeries}</paper-checkbox>
|
||||
</div>
|
||||
<label class="checkboxContainer">
|
||||
<input type="checkbox" is="emby-checkbox" id="chkRecordSeries" />
|
||||
<span>${RecordSeries}</span>
|
||||
</label>
|
||||
|
||||
<div id="seriesFields" class="hide">
|
||||
<div>
|
||||
<h1>${Days}</h1>
|
||||
</div>
|
||||
<div class="paperCheckboxList">
|
||||
<paper-checkbox id="chkSunday">${Sunday}</paper-checkbox>
|
||||
<paper-checkbox id="chkMonday">${Monday}</paper-checkbox>
|
||||
<paper-checkbox id="chkTuesday">${Tuesday}</paper-checkbox>
|
||||
<paper-checkbox id="chkWednesday">${Wednesday}</paper-checkbox>
|
||||
<paper-checkbox id="chkThursday">${Thursday}</paper-checkbox>
|
||||
<paper-checkbox id="chkFriday">${Friday}</paper-checkbox>
|
||||
<paper-checkbox id="chkSaturday">${Saturday}</paper-checkbox>
|
||||
<div class="seriesFields hide">
|
||||
<div class="checkboxList">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkNewOnly" />
|
||||
<span>${RecordOnlyNewEpisodes}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkAnyTime" />
|
||||
<span>${RecordAnytime}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkAllChannels" />
|
||||
<span>${RecordOnAllChannels}</span>
|
||||
</label>
|
||||
</div>
|
||||
<br />
|
||||
<div class="paperCheckboxList">
|
||||
<paper-checkbox id="chkNewOnly">${RecordOnlyNewEpisodes}</paper-checkbox>
|
||||
<paper-checkbox id="chkAnyTime">${RecordAnytime}</paper-checkbox>
|
||||
<paper-checkbox id="chkAllChannels">${RecordOnAllChannels}</paper-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="convertRecordingsContainer hide">
|
||||
<br />
|
||||
<paper-checkbox id="chkConvertRecordings">${OptionConvertRecordingsToStreamingFormat}</paper-checkbox>
|
||||
<div class="fieldDescription paperCheckboxFieldDescription">${OptionConvertRecordingsToStreamingFormatHelp}</div>
|
||||
<div class="fieldDescription paperCheckboxFieldDescription btnSupporterForConverting hide">
|
||||
<div class="convertRecordingsContainer hide checkboxContainer">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkConvertRecordings" />
|
||||
<span>${OptionConvertRecordingsToStreamingFormat}</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${OptionConvertRecordingsToStreamingFormatHelp}</div>
|
||||
<div class="fieldDescription checkboxFieldDescription btnSupporterForConverting hide">
|
||||
<a href="#" class="accent lnkPremiere">${FeatureRequiresEmbyPremiere}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="advanced hide">
|
||||
<br />
|
||||
<br />
|
||||
<emby-collapsible title="${Advanced}">
|
||||
<div>
|
||||
<paper-input type="number" id="txtPrePaddingMinutes" pattern="[0-9]*" required="required" min="0" step="1" label="${LabelPrePaddingMinutes}"></paper-input>
|
||||
<div class="seriesDays hide">
|
||||
<div>
|
||||
<h1>${Days}</h1>
|
||||
</div>
|
||||
<div class="checkboxList">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkSunday" />
|
||||
<span>${Sunday}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkMonday" />
|
||||
<span>${Monday}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkTuesday" />
|
||||
<span>${Tuesday}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkWednesday" />
|
||||
<span>${Wednesday}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkThursday" />
|
||||
<span>${Thursday}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkFriday" />
|
||||
<span>${Friday}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkSaturday" />
|
||||
<span>${Saturday}</span>
|
||||
</label>
|
||||
</div>
|
||||
<br />
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<paper-input type="number" id="txtPostPaddingMinutes" pattern="[0-9]*" required="required" min="0" step="1" label="${LabelPostPaddingMinutes}"></paper-input>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="number" id="txtPrePaddingMinutes" pattern="[0-9]*" required="required" min="0" step="1" label="${LabelPrePaddingMinutes}" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="number" id="txtPostPaddingMinutes" pattern="[0-9]*" required="required" min="0" step="1" label="${LabelPostPaddingMinutes}" />
|
||||
</div>
|
||||
</emby-collapsible>
|
||||
<br />
|
||||
|
@ -66,9 +101,15 @@
|
|||
<div class="supporterContainer hide">
|
||||
<p>${MessageActiveSubscriptionRequiredSeriesRecordings}</p>
|
||||
<p class="supporterTrial hide">${HeaderEnjoyDayTrial}</p>
|
||||
<a class="clearLink btnSupporter hide" href="http://emby.media/premiere" target="_blank"><paper-button raised class="accent block"><iron-icon icon="nav:check"></iron-icon><span>${HeaderBecomeProjectSupporter}</span></paper-button></a>
|
||||
<button is="emby-button" type="button" raised class="btnSupporter hide raised accent block">
|
||||
<i class="md-icon">check</i>
|
||||
<span>${HeaderBecomeProjectSupporter}</span>
|
||||
</button>
|
||||
</div>
|
||||
<paper-button raised class="btnSubmit block" autofocus><iron-icon icon="mediainfo:fiber-manual-record"></iron-icon><span>${Record}</span></paper-button>
|
||||
<button is="emby-button" type="submit" class="raised btnSubmit block" autofocus>
|
||||
<i class="md-icon">fiber_manual_record</i>
|
||||
<span>${Record}</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
|
@ -1,4 +1,4 @@
|
|||
define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'scrollStyles', 'paper-checkbox', 'emby-collapsible', 'paper-input', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'html!./../icons/mediainfo.html', 'html!./../icons/nav.html'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper) {
|
||||
define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'scrollStyles', 'emby-button', 'emby-collapsible', 'emby-input', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'material-icons'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper) {
|
||||
|
||||
var currentDialog;
|
||||
var recordingUpdated = false;
|
||||
|
@ -81,22 +81,6 @@
|
|||
|
||||
context.querySelector('.btnSubmit').click();
|
||||
});
|
||||
|
||||
context.querySelector('.btnSubmit').addEventListener('click', function () {
|
||||
|
||||
// Do a fake form submit this the button isn't a real submit button
|
||||
var fakeSubmit = document.createElement('input');
|
||||
fakeSubmit.setAttribute('type', 'submit');
|
||||
fakeSubmit.style.display = 'none';
|
||||
var form = context.querySelector('form');
|
||||
form.appendChild(fakeSubmit);
|
||||
fakeSubmit.click();
|
||||
|
||||
// Seeing issues in smart tv browsers where the form does not get submitted if the button is removed prior to the submission actually happening
|
||||
setTimeout(function () {
|
||||
form.removeChild(fakeSubmit);
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
function reload(context, id) {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<div class="dialogHeader" style="margin:0 0 2em;">
|
||||
<button is="paper-icon-button-light" class="btnCancel" tabindex="-1"><iron-icon icon="arrow-back"></iron-icon></button>
|
||||
<div class="dialogHeader">
|
||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="md-icon">arrow_back</i></button>
|
||||
<div class="dialogHeaderTitle">
|
||||
${Edit}
|
||||
</div>
|
||||
<div style="margin-left:auto; display: flex; align-items: center; justify-content: center;">
|
||||
<paper-button class="btnHeaderSave accent" tabindex="-1">
|
||||
<iron-icon icon="check"></iron-icon>
|
||||
<button is="emby-button" type="button" class="btnHeaderSave accent" tabindex="-1">
|
||||
<i class="md-icon">check</i>
|
||||
<span>${Save}</span>
|
||||
</paper-button>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -24,15 +24,18 @@
|
|||
</p>
|
||||
|
||||
<form>
|
||||
<div>
|
||||
<paper-input type="number" id="txtPrePaddingMinutes" pattern="[0-9]*" required="required" min="0" step="1" label="${LabelPrePaddingMinutes}"></paper-input>
|
||||
<br />
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="number" id="txtPrePaddingMinutes" pattern="[0-9]*" required="required" min="0" step="1" label="${LabelPrePaddingMinutes}" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="number" id="txtPostPaddingMinutes" pattern="[0-9]*" required="required" min="0" step="1" label="${LabelPostPaddingMinutes}" />
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<paper-input type="number" id="txtPostPaddingMinutes" pattern="[0-9]*" required="required" min="0" step="1" label="${LabelPostPaddingMinutes}"></paper-input>
|
||||
</div>
|
||||
<br />
|
||||
<paper-button raised class="btnSubmit block" autofocus><iron-icon icon="mediainfo:fiber-manual-record"></iron-icon><span>${Save}</span></paper-button>
|
||||
<button is="emby-button" type="submit" class="raised btnSubmit block" autofocus>
|
||||
<i class="md-icon">fiber_manual_record</i>
|
||||
<span>${Save}</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
148
dashboard-ui/bower_components/emby-webcomponents/refreshdialog/refreshdialog.js
vendored
Normal file
148
dashboard-ui/bower_components/emby-webcomponents/refreshdialog/refreshdialog.js
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionManager', 'scrollHelper', 'embyRouter', 'globalize', 'emby-input', 'emby-checkbox', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button'], function (shell, dialogHelper, loading, layoutManager, connectionManager, scrollHelper, embyRouter, globalize) {
|
||||
|
||||
function parentWithClass(elem, className) {
|
||||
|
||||
while (!elem.classList || !elem.classList.contains(className)) {
|
||||
elem = elem.parentNode;
|
||||
|
||||
if (!elem) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
function getEditorHtml() {
|
||||
|
||||
var html = '';
|
||||
|
||||
html += '<div class="dialogContent smoothScrollY">';
|
||||
html += '<div class="dialogContentInner centeredContent">';
|
||||
html += '<form style="margin:auto;">';
|
||||
|
||||
html += '<div class="fldSelectPlaylist selectContainer">';
|
||||
html += '<select is="emby-select" id="selectMetadataRefreshMode" label="' + globalize.translate('sharedcomponents#LabelRefreshMode') + '">';
|
||||
html += '<option value="missing">' + globalize.translate('sharedcomponents#SearchForMissingMetadata') + '</option>';
|
||||
html += '<option value="all" selected>' + globalize.translate('sharedcomponents#ReplaceAllMetadata') + '</option>';
|
||||
html += '</select>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<label class="checkboxContainer">';
|
||||
html += '<input type="checkbox" is="emby-checkbox" class="chkReplaceImages" />';
|
||||
html += '<span>' + globalize.translate('sharedcomponents#ReplaceExistingImages') + '</span>';
|
||||
html += '</label>';
|
||||
|
||||
html += '<div class="fieldDescription">';
|
||||
html += globalize.translate('sharedcomponents#RefreshDialogHelp');
|
||||
html += '</div>';
|
||||
|
||||
html += '<br />';
|
||||
html += '<div>';
|
||||
html += '<button is="emby-button" type="submit" class="raised btnSubmit block" autofocus>' + globalize.translate('sharedcomponents#ButtonOk') + '</button>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<input type="hidden" class="fldSelectedItemIds" />';
|
||||
|
||||
html += '</form>';
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
return function (options) {
|
||||
|
||||
var self = this;
|
||||
|
||||
function onSubmit(e) {
|
||||
|
||||
loading.show();
|
||||
|
||||
var dlg = parentWithClass(this, 'dialog');
|
||||
|
||||
var apiClient = connectionManager.getApiClient(options.serverId);
|
||||
|
||||
var replaceAllImages = dlg.querySelector('.chkReplaceImages').checked;
|
||||
var replaceAllMetadata = dlg.querySelector('#selectMetadataRefreshMode').value == 'all';
|
||||
|
||||
options.itemIds.forEach(function (itemId) {
|
||||
apiClient.refreshItem(itemId, {
|
||||
|
||||
Recursive: true,
|
||||
ImageRefreshMode: 'FullRefresh',
|
||||
MetadataRefreshMode: 'FullRefresh',
|
||||
ReplaceAllImages: replaceAllImages,
|
||||
ReplaceAllMetadata: replaceAllMetadata
|
||||
});
|
||||
});
|
||||
|
||||
dialogHelper.close(dlg);
|
||||
|
||||
require(['toast'], function (toast) {
|
||||
toast(globalize.translate('sharedcomponents#RefreshQueued'));
|
||||
});
|
||||
|
||||
loading.hide();
|
||||
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
function initEditor(content, items) {
|
||||
|
||||
content.querySelector('form').addEventListener('submit', onSubmit);
|
||||
}
|
||||
|
||||
self.show = function () {
|
||||
|
||||
var dialogOptions = {
|
||||
removeOnClose: true,
|
||||
scrollY: false
|
||||
};
|
||||
|
||||
if (layoutManager.tv) {
|
||||
dialogOptions.size = 'fullscreen';
|
||||
} else {
|
||||
dialogOptions.size = 'small';
|
||||
}
|
||||
|
||||
var dlg = dialogHelper.createDialog(dialogOptions);
|
||||
|
||||
dlg.classList.add('formDialog');
|
||||
|
||||
var html = '';
|
||||
var title = globalize.translate('sharedcomponents#RefreshMetadata');
|
||||
|
||||
html += '<div class="dialogHeader" style="margin:0 0 2em;">';
|
||||
html += '<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="md-icon">arrow_back</i></button>';
|
||||
html += '<div class="dialogHeaderTitle">';
|
||||
html += title;
|
||||
html += '</div>';
|
||||
|
||||
html += '</div>';
|
||||
|
||||
html += getEditorHtml();
|
||||
|
||||
dlg.innerHTML = html;
|
||||
document.body.appendChild(dlg);
|
||||
|
||||
initEditor(dlg);
|
||||
|
||||
dlg.querySelector('.btnCancel').addEventListener('click', function () {
|
||||
|
||||
dialogHelper.close(dlg);
|
||||
});
|
||||
|
||||
if (layoutManager.tv) {
|
||||
scrollHelper.centerFocus.on(dlg.querySelector('.dialogContent'), false);
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
dlg.addEventListener('close', resolve);
|
||||
dialogHelper.open(dlg);
|
||||
});
|
||||
};
|
||||
};
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
define(['loading', 'viewManager', 'skinManager', 'pluginManager', 'backdrop', 'browser', 'pageJs'], function (loading, viewManager, skinManager, pluginManager, backdrop, browser, page) {
|
||||
define(['loading', 'viewManager', 'skinManager', 'pluginManager', 'backdrop', 'browser', 'pageJs', 'appSettings'], function (loading, viewManager, skinManager, pluginManager, backdrop, browser, page, appSettings) {
|
||||
|
||||
var embyRouter = {
|
||||
showLocalLogin: function (apiClient, serverId, manualLogin) {
|
||||
|
@ -35,7 +35,11 @@ define(['loading', 'viewManager', 'skinManager', 'pluginManager', 'backdrop', 'b
|
|||
|
||||
loading.show();
|
||||
|
||||
connectionManager.connect().then(function (result) {
|
||||
connectionManager.connect({
|
||||
|
||||
enableAutoLogin: appSettings.enableAutoLogin()
|
||||
|
||||
}).then(function (result) {
|
||||
handleConnectionResult(result, loading);
|
||||
});
|
||||
}
|
||||
|
@ -210,8 +214,8 @@ define(['loading', 'viewManager', 'skinManager', 'pluginManager', 'backdrop', 'b
|
|||
if (!isBackNav) {
|
||||
// Don't force a new view for home due to the back menu
|
||||
//if (route.type != 'home') {
|
||||
onNewViewNeeded();
|
||||
return;
|
||||
onNewViewNeeded();
|
||||
return;
|
||||
//}
|
||||
}
|
||||
viewManager.tryRestoreView(currentRequest).then(function () {
|
||||
|
@ -234,7 +238,11 @@ define(['loading', 'viewManager', 'skinManager', 'pluginManager', 'backdrop', 'b
|
|||
|
||||
connectionManager = connectionManagerInstance;
|
||||
|
||||
connectionManager.connect().then(function (result) {
|
||||
connectionManager.connect({
|
||||
|
||||
enableAutoLogin: appSettings.enableAutoLogin()
|
||||
|
||||
}).then(function (result) {
|
||||
|
||||
firstConnectionResult = result;
|
||||
|
||||
|
|
|
@ -26,6 +26,10 @@ define(['connectionManager', 'events'], function (connectionManager, events) {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (msg.MessageType === "TimerCreated" || msg.MessageType === "SeriesTimerCreated" || msg.MessageType === "TimerCancelled" || msg.MessageType === "SeriesTimerCancelled") {
|
||||
|
||||
events.trigger(serverNotifications, msg.MessageType, [apiClient, msg.Data]);
|
||||
}
|
||||
}
|
||||
|
||||
function bindEvents(apiClient) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(['dialogHelper', 'layoutManager', 'globalize', './social-share-kit-1.0.4/dist/js/social-share-kit.min', 'css!./social-share-kit-1.0.4/dist/css/social-share-kit.css'], function (dialogHelper, layoutManager, globalize) {
|
||||
define(['dialogHelper', 'layoutManager', 'globalize', './social-share-kit-1.0.4/dist/js/social-share-kit.min', 'css!./social-share-kit-1.0.4/dist/css/social-share-kit.css', 'emby-button'], function (dialogHelper, layoutManager, globalize) {
|
||||
|
||||
function showMenu(options) {
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
|||
html += '</div>';
|
||||
|
||||
html += '<div class="buttons">';
|
||||
html += '<paper-button class="btnCancel">' + globalize.translate('sharedcomponents#ButtonCancel') + '</paper-button>';
|
||||
html += '<button is="emby-button" type="button" class="btnCancel">' + globalize.translate('sharedcomponents#ButtonCancel') + '</button>';
|
||||
html += '</div>';
|
||||
|
||||
dlg.innerHTML = html;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter'], function (playbackManager, inputManager, connectionManager, embyRouter) {
|
||||
define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'globalize', 'loading'], function (playbackManager, inputManager, connectionManager, embyRouter, globalize, loading) {
|
||||
|
||||
function playAllFromHere(card, serverId) {
|
||||
var cards = card.parentNode.querySelectorAll('.itemAction[data-id]');
|
||||
|
@ -111,6 +111,86 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter'], f
|
|||
else if (action == 'setplaylistindex') {
|
||||
|
||||
}
|
||||
|
||||
else if (action == 'record') {
|
||||
onRecordCommand(serverId, id, type, card.getAttribute('data-timerid'), card.getAttribute('data-seriestimerid'));
|
||||
}
|
||||
}
|
||||
|
||||
function onRecordCommand(serverId, id, type, timerId, seriesTimerId) {
|
||||
|
||||
var apiClient = connectionManager.getApiClient(serverId);
|
||||
|
||||
if (seriesTimerId && timerId) {
|
||||
|
||||
// cancel
|
||||
cancelTimer(apiClient, timerId, true);
|
||||
|
||||
} else if (timerId) {
|
||||
|
||||
// change to series recording, if possible
|
||||
// otherwise cancel individual recording
|
||||
changeRecordingToSeries(apiClient, timerId, id);
|
||||
|
||||
} else if (type == 'Program') {
|
||||
// schedule recording
|
||||
createRecording(apiClient, id);
|
||||
}
|
||||
}
|
||||
|
||||
function changeRecordingToSeries(apiClient, timerId, programId) {
|
||||
|
||||
loading.show();
|
||||
|
||||
apiClient.getItem(apiClient.getCurrentUserId(), programId).then(function (item) {
|
||||
|
||||
if (item.IsSeries) {
|
||||
// cancel, then create series
|
||||
cancelTimer(apiClient, timerId, false).then(function () {
|
||||
apiClient.getNewLiveTvTimerDefaults({ programId: programId }).then(function (timerDefaults) {
|
||||
|
||||
apiClient.createLiveTvSeriesTimer(timerDefaults).then(function () {
|
||||
|
||||
loading.hide();
|
||||
sendToast(globalize.translate('sharedcomponents#SeriesRecordingScheduled'));
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// cancel
|
||||
cancelTimer(apiClient, timerId, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function cancelTimer(apiClient, timerId, hideLoading) {
|
||||
loading.show();
|
||||
return apiClient.cancelLiveTvTimer(timerId).then(function () {
|
||||
|
||||
if (hideLoading) {
|
||||
loading.hide();
|
||||
sendToast(globalize.translate('sharedcomponents#RecordingCancelled'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createRecording(apiClient, programId) {
|
||||
|
||||
loading.show();
|
||||
apiClient.getNewLiveTvTimerDefaults({ programId: programId }).then(function (item) {
|
||||
|
||||
apiClient.createLiveTvTimer(item).then(function () {
|
||||
|
||||
loading.hide();
|
||||
sendToast(globalize.translate('sharedcomponents#RecordingScheduled'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function sendToast(msg) {
|
||||
require(['toast'], function (toast) {
|
||||
toast(msg);
|
||||
});
|
||||
}
|
||||
|
||||
function onClick(e) {
|
||||
|
@ -141,7 +221,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter'], f
|
|||
function onCommand(e) {
|
||||
var cmd = e.detail.command;
|
||||
|
||||
if (cmd == 'play') {
|
||||
if (cmd == 'play' || cmd == 'record') {
|
||||
var card = parentWithClass(e.target, 'itemAction');
|
||||
|
||||
if (card) {
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
<!--
|
||||
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
Code distributed by Google as part of the polymer project is also
|
||||
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
-->
|
||||
<!--
|
||||
`iron-icons` is a utility import that includes the definition for the `iron-icon` element, `iron-iconset-svg` element, as well as an import for the default icon set.
|
||||
|
||||
The `iron-icons` directory also includes imports for additional icon sets that can be loaded into your project.
|
||||
|
||||
Example loading icon set:
|
||||
|
||||
<link rel="import" href="../iron-icons/maps-icons.html">
|
||||
|
||||
To use an icon from one of these sets, first prefix your `iron-icon` with the icon set name, followed by a colon, ":", and then the icon id.
|
||||
|
||||
Example using the directions-bus icon from the maps icon set:
|
||||
|
||||
<iron-icon icon="maps:directions-bus"></iron-icon>
|
||||
|
||||
|
||||
See [iron-icon](#iron-icon) for more information about working with icons.
|
||||
|
||||
See [iron-iconset](#iron-iconset) and [iron-iconset-svg](#iron-iconset-svg) for more information about how to create a custom iconset.
|
||||
|
||||
@group Iron Elements
|
||||
@element iron-icons
|
||||
@demo demo/index.html
|
||||
-->
|
||||
|
||||
<iron-iconset-svg name="slideshow" size="24">
|
||||
<svg>
|
||||
<defs>
|
||||
<g id="close"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" /></g>
|
||||
<g id="pause"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" /></g>
|
||||
<g id="keyboard-arrow-left"><path d="M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z" /></g>
|
||||
<g id="keyboard-arrow-right"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z" /></g>
|
||||
<g id="play-arrow"><path d="M8 5v14l11-7z" /></g>
|
||||
<g id="file-download"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z" /></g>
|
||||
<g id="share"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z" /></g>
|
||||
</defs>
|
||||
</svg>
|
||||
</iron-iconset-svg>
|
|
@ -1,4 +1,4 @@
|
|||
define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'focusManager', 'apphost', 'css!./style', 'html!./icons', 'iron-icon-set', 'paper-icon-button-light', 'paper-spinner'], function (dialogHelper, inputmanager, connectionManager, layoutManager, focusManager, appHost) {
|
||||
define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'focusManager', 'apphost', 'loading', 'css!./style', 'material-icons', 'paper-icon-button-light'], function (dialogHelper, inputmanager, connectionManager, layoutManager, focusManager, appHost, loading) {
|
||||
|
||||
function getImageUrl(item, options, apiClient) {
|
||||
|
||||
|
@ -51,15 +51,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
options = options || {};
|
||||
options.type = options.type || "Backdrop";
|
||||
|
||||
options.width = null;
|
||||
delete options.width;
|
||||
options.maxWidth = null;
|
||||
delete options.maxWidth;
|
||||
options.maxHeight = null;
|
||||
delete options.maxHeight;
|
||||
options.height = null;
|
||||
delete options.height;
|
||||
|
||||
// If not resizing, get the original image
|
||||
if (!options.maxWidth && !options.width && !options.maxHeight && !options.height) {
|
||||
options.quality = 100;
|
||||
|
@ -100,7 +91,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
|
||||
var tabIndex = canFocus ? '' : ' tabindex="-1"';
|
||||
autoFocus = autoFocus ? ' autofocus' : '';
|
||||
return '<button is="paper-icon-button-light" class="' + cssClass + '"' + tabIndex + autoFocus + '><iron-icon icon="' + icon + '"></iron-icon></button>';
|
||||
return '<button is="paper-icon-button-light" class="autoSize ' + cssClass + '"' + tabIndex + autoFocus + '><i class="md-icon">' + icon + '</i></button>';
|
||||
}
|
||||
|
||||
return function (options) {
|
||||
|
@ -119,7 +110,8 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
exitAnimationDuration: options.interactive ? 400 : 800,
|
||||
size: 'fullscreen',
|
||||
autoFocus: false,
|
||||
scrollY: false
|
||||
scrollY: false,
|
||||
exitAnimation: 'fadeout'
|
||||
});
|
||||
|
||||
dlg.classList.add('slideshowDialog');
|
||||
|
@ -133,30 +125,30 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
html += '<div>';
|
||||
html += '<div class="slideshowSwiperContainer"><div class="swiper-wrapper"></div></div>';
|
||||
|
||||
html += getIcon('slideshow:keyboard-arrow-left', 'btnSlideshowPrevious slideshowButton', false);
|
||||
html += getIcon('slideshow:keyboard-arrow-right', 'btnSlideshowNext slideshowButton', false);
|
||||
html += getIcon('keyboard_arrow_left', 'btnSlideshowPrevious slideshowButton', false);
|
||||
html += getIcon('keyboard_arrow_right', 'btnSlideshowNext slideshowButton', false);
|
||||
|
||||
html += '<div class="topActionButtons">';
|
||||
if (actionButtonsOnTop) {
|
||||
if (appHost.supports('filedownload')) {
|
||||
html += getIcon('slideshow:file-download', 'btnDownload slideshowButton', true);
|
||||
html += getIcon('file_download', 'btnDownload slideshowButton', true);
|
||||
}
|
||||
if (appHost.supports('sharing')) {
|
||||
html += getIcon('slideshow:share', 'btnShare slideshowButton', true);
|
||||
html += getIcon('share', 'btnShare slideshowButton', true);
|
||||
}
|
||||
}
|
||||
html += getIcon('slideshow:close', 'slideshowButton btnSlideshowExit', false);
|
||||
html += getIcon('close', 'slideshowButton btnSlideshowExit', false);
|
||||
html += '</div>';
|
||||
|
||||
if (!actionButtonsOnTop) {
|
||||
html += '<div class="slideshowBottomBar hide">';
|
||||
|
||||
html += getIcon('slideshow:pause', 'btnSlideshowPause slideshowButton', true, true);
|
||||
html += getIcon('pause', 'btnSlideshowPause slideshowButton', true, true);
|
||||
if (appHost.supports('filedownload')) {
|
||||
html += getIcon('slideshow:file-download', 'btnDownload slideshowButton', true);
|
||||
html += getIcon('file_download', 'btnDownload slideshowButton', true);
|
||||
}
|
||||
if (appHost.supports('sharing')) {
|
||||
html += getIcon('slideshow:share', 'btnShare slideshowButton', true);
|
||||
html += getIcon('share', 'btnShare slideshowButton', true);
|
||||
}
|
||||
|
||||
html += '</div>';
|
||||
|
@ -233,7 +225,8 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
lazyLoading: true,
|
||||
lazyLoadingInPrevNext: true,
|
||||
autoplayDisableOnInteraction: false,
|
||||
initialSlide: options.startIndex || 0
|
||||
initialSlide: options.startIndex || 0,
|
||||
speed: 240
|
||||
});
|
||||
|
||||
swiperInstance.on('onLazyImageLoad', onSlideChangeStart);
|
||||
|
@ -261,20 +254,12 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
|
||||
function onSlideChangeStart(swiper, slide, image) {
|
||||
|
||||
var spinner = slide.querySelector('paper-spinner');
|
||||
if (spinner) {
|
||||
spinner.active = true;
|
||||
}
|
||||
//loading.show();
|
||||
}
|
||||
|
||||
function onSlideChangeEnd(swiper, slide, image) {
|
||||
|
||||
var spinner = slide.querySelector('paper-spinner');
|
||||
if (spinner) {
|
||||
spinner.active = false;
|
||||
// Remove it because in IE it might just keep in spinning forever
|
||||
spinner.parentNode.removeChild(spinner);
|
||||
}
|
||||
//loading.hide();
|
||||
}
|
||||
|
||||
function getSwiperSlideHtmlFromSlide(item) {
|
||||
|
@ -282,7 +267,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
var html = '';
|
||||
html += '<div class="swiper-slide" data-original="' + item.originalImage + '" data-itemid="' + item.Id + '" data-serverid="' + item.ServerId + '">';
|
||||
html += '<img data-src="' + item.imageUrl + '" class="swiper-lazy">';
|
||||
html += '<paper-spinner></paper-spinner>';
|
||||
if (item.title || item.subtitle) {
|
||||
html += '<div class="slideText">';
|
||||
html += '<div class="slideTextInner">';
|
||||
|
@ -369,9 +353,9 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
|
||||
function play() {
|
||||
|
||||
var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause iron-icon');
|
||||
var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i');
|
||||
if (btnSlideshowPause) {
|
||||
btnSlideshowPause.icon = "slideshow:pause";
|
||||
btnSlideshowPause.innerHTML = "pause";
|
||||
}
|
||||
|
||||
swiperInstance.startAutoplay();
|
||||
|
@ -379,9 +363,9 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
|
||||
function pause() {
|
||||
|
||||
var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause iron-icon');
|
||||
var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i');
|
||||
if (btnSlideshowPause) {
|
||||
btnSlideshowPause.icon = "slideshow:play-arrow";
|
||||
btnSlideshowPause.innerHTML = "play_arrow";
|
||||
}
|
||||
|
||||
swiperInstance.stopAutoplay();
|
||||
|
@ -389,7 +373,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
|
||||
function playPause() {
|
||||
|
||||
var paused = dlg.querySelector('.btnSlideshowPause iron-icon').icon != "slideshow:pause";
|
||||
var paused = dlg.querySelector('.btnSlideshowPause i').innerHTML != "pause";
|
||||
if (paused) {
|
||||
play();
|
||||
} else {
|
||||
|
|
|
@ -45,24 +45,27 @@
|
|||
top: 50%;
|
||||
}
|
||||
|
||||
.slideshowDialog .slideshowButton {
|
||||
width: 5.2vh;
|
||||
height: 5.2vh;
|
||||
.slideshowDialog .slideshowButton i {
|
||||
width: 4.5vh;
|
||||
height: 4.5vh;
|
||||
font-size: 4.5vh;
|
||||
color: #fff;
|
||||
opacity: .7;
|
||||
min-width: 40px;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.layout-tv .slideshowDialog .slideshowButtonn {
|
||||
width: 7vh;
|
||||
height: 7vh;
|
||||
.layout-tv .slideshowDialog .slideshowButton i {
|
||||
width: 6.3vh;
|
||||
height: 6.3vh;
|
||||
font-size: 6.3vh;
|
||||
}
|
||||
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (min-device-pixel-ratio: 1.3), only screen and (min-resolution: 120dpi) {
|
||||
.slideshowDialog paper-icon-button {
|
||||
width: 11vmin;
|
||||
height: 11vmin;
|
||||
.slideshowDialog [is=paper-icon-button-light] i {
|
||||
width: 10.3vmin;
|
||||
height: 10.3vmin;
|
||||
font-size: 10.3vmin;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
"Delete": "Delete",
|
||||
"HeaderDeleteItem": "Delete Item",
|
||||
"ConfirmDeleteItem": "Deleting this item will delete it from both the file system and your media library. Are you sure you wish to continue?",
|
||||
"ValueSpecialEpisodeName": "Special - {0}",
|
||||
"Share": "Del",
|
||||
"ServerUpdateNeeded": "Denne Emby server b\u00f8r opdateres. For at downloade den nyeste version bes\u00f8g venligst {0}",
|
||||
|
@ -26,7 +23,9 @@
|
|||
"ButtonOk": "Ok",
|
||||
"ButtonCancel": "Annuller",
|
||||
"ButtonGotIt": "Forst\u00e5et",
|
||||
"RecordingCancelled": "Recording cancelled.",
|
||||
"RecordingScheduled": "Optagelse planlagt.",
|
||||
"SeriesRecordingScheduled": "Series recording scheduled.",
|
||||
"HeaderNewRecording": "Ny optagelse",
|
||||
"Sunday": "S\u00f8ndag",
|
||||
"Monday": "Mandag",
|
||||
|
@ -53,6 +52,39 @@
|
|||
"Edit": "Rediger",
|
||||
"Download": "Hent",
|
||||
"Advanced": "Avanceret",
|
||||
"Delete": "Delete",
|
||||
"HeaderDeleteItem": "Delete Item",
|
||||
"ConfirmDeleteItem": "Deleting this item will delete it from both the file system and your media library. Are you sure you wish to continue?",
|
||||
"Refresh": "Opdater",
|
||||
"RefreshQueued": "Opdatering sat i k\u00f8"
|
||||
"RefreshQueued": "Opdatering sat i k\u00f8",
|
||||
"AddToCollection": "Add to Collection",
|
||||
"NewCollection": "New Collection",
|
||||
"LabelCollection": "Collection:",
|
||||
"Help": "Help",
|
||||
"NewCollectionHelp": "Collections allow you to create personalized groupings of movies and other library content.",
|
||||
"SearchForCollectionInternetMetadata": "Search the internet for artwork and metadata",
|
||||
"LabelName": "Name:",
|
||||
"NewCollectionNameExample": "Example: Star Wars Collection",
|
||||
"MessageItemsAdded": "Items added.",
|
||||
"OptionNew": "New...",
|
||||
"LabelPlaylist": "Playlist:",
|
||||
"AddToPlaylist": "Add to Playlist",
|
||||
"Subtitles": "Subtitles",
|
||||
"SearchForSubtitles": "Search for Subtitles",
|
||||
"LabelLanguage": "Language:",
|
||||
"Search": "Search",
|
||||
"NoSubtitleSearchResultsFound": "No results found.",
|
||||
"File": "File",
|
||||
"MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?",
|
||||
"ConfirmDeletion": "Confirm Deletion",
|
||||
"MySubtitles": "My Subtitles",
|
||||
"MessageDownloadQueued": "Download queued.",
|
||||
"EditSubtitles": "Edit Subtitles",
|
||||
"UnlockGuide": "Unlock Guide",
|
||||
"RefreshMetadata": "Refresh Metadata",
|
||||
"ReplaceExistingImages": "Replace existing images",
|
||||
"ReplaceAllMetadata": "Replace all metadata",
|
||||
"SearchForMissingMetadata": "Search for missing metadata",
|
||||
"LabelRefreshMode": "Refresh mode:",
|
||||
"RefreshDialogHelp": "Metadata is refreshed based on settings and internet services that are enabled in the Emby Server dashboard."
|
||||
}
|
90
dashboard-ui/bower_components/emby-webcomponents/strings/de.json
vendored
Normal file
90
dashboard-ui/bower_components/emby-webcomponents/strings/de.json
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"ValueSpecialEpisodeName": "Special - {0}",
|
||||
"Share": "Teilen",
|
||||
"ServerUpdateNeeded": "Dieser Emby Server sollte aktualisiert werden. Um die neueste Version zu laden, besuche bitte {0}",
|
||||
"LiveTvGuideRequiresUnlock": "The Live TV Guide is currently limited to {0} channels. Click the unlock button to learn how to enjoy the full experience.",
|
||||
"AttributeNew": "Neu",
|
||||
"AttributePremiere": "Premiere",
|
||||
"AttributeLive": "Live",
|
||||
"TrackCount": "{0} tracks",
|
||||
"ItemCount": "{0} items",
|
||||
"ValueSeriesYearToPresent": "{0}-Present",
|
||||
"ReleaseYearValue": "Erscheinungsjahr: {0}",
|
||||
"OriginalAirDateValue": "Original air date: {0}",
|
||||
"EndsAtValue": "Ends at {0}",
|
||||
"OptionSundayShort": "Sun",
|
||||
"OptionMondayShort": "Mon",
|
||||
"OptionTuesdayShort": "Tue",
|
||||
"OptionWednesdayShort": "Wed",
|
||||
"OptionThursdayShort": "Thu",
|
||||
"OptionFridayShort": "Fri",
|
||||
"OptionSaturdayShort": "Sat",
|
||||
"HeaderSelectDate": "Select Date",
|
||||
"ButtonOk": "Ok",
|
||||
"ButtonCancel": "Cancel",
|
||||
"ButtonGotIt": "Got It",
|
||||
"RecordingCancelled": "Recording cancelled.",
|
||||
"RecordingScheduled": "Recording scheduled.",
|
||||
"SeriesRecordingScheduled": "Series recording scheduled.",
|
||||
"HeaderNewRecording": "New Recording",
|
||||
"Sunday": "Sonntag",
|
||||
"Monday": "Montag",
|
||||
"Tuesday": "Dienstag",
|
||||
"Wednesday": "Mittwoch",
|
||||
"Thursday": "Donnerstag",
|
||||
"Friday": "Freitag",
|
||||
"Saturday": "Samstag",
|
||||
"Days": "Tage",
|
||||
"RecordSeries": "Record series",
|
||||
"LabelPrePaddingMinutes": "Pre-padding minutes:",
|
||||
"LabelPostPaddingMinutes": "Post-padding minutes:",
|
||||
"RecordOnAllChannels": "Record on all channels",
|
||||
"RecordAnytime": "Record at any time",
|
||||
"RecordOnlyNewEpisodes": "Record only new episodes",
|
||||
"HeaderBecomeProjectSupporter": "Get Emby Premiere",
|
||||
"HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial",
|
||||
"MessageActiveSubscriptionRequiredSeriesRecordings": "An active Emby Premiere subscription is required in order to create automated series recordings.",
|
||||
"OptionConvertRecordingsToStreamingFormat": "Automatically convert recordings to a streaming friendly format",
|
||||
"OptionConvertRecordingsToStreamingFormatHelp": "Recordings will be converted on the fly to MP4 for easy playback on your devices.",
|
||||
"FeatureRequiresEmbyPremiere": "This feature requires an active Emby Premiere subscription.",
|
||||
"Record": "Record",
|
||||
"Save": "Speichern",
|
||||
"Edit": "Bearbeiten",
|
||||
"Download": "Download",
|
||||
"Advanced": "Erweitert",
|
||||
"Delete": "L\u00f6schen",
|
||||
"HeaderDeleteItem": "Delete Item",
|
||||
"ConfirmDeleteItem": "Deleting this item will delete it from both the file system and your media library. Are you sure you wish to continue?",
|
||||
"Refresh": "Neu laden",
|
||||
"RefreshQueued": "Refresh queued.",
|
||||
"AddToCollection": "Add to Collection",
|
||||
"NewCollection": "New Collection",
|
||||
"LabelCollection": "Sammlung:",
|
||||
"Help": "Hilfe",
|
||||
"NewCollectionHelp": "Collections allow you to create personalized groupings of movies and other library content.",
|
||||
"SearchForCollectionInternetMetadata": "Search the internet for artwork and metadata",
|
||||
"LabelName": "Name:",
|
||||
"NewCollectionNameExample": "Beispiel: Star Wars Collection",
|
||||
"MessageItemsAdded": "Eintr\u00e4ge hinzugef\u00fcgt",
|
||||
"OptionNew": "Neu...",
|
||||
"LabelPlaylist": "Wiedergabeliste",
|
||||
"AddToPlaylist": "Zur Wiedergabeliste hinzuf\u00fcgen",
|
||||
"Subtitles": "Subtitles",
|
||||
"SearchForSubtitles": "Search for Subtitles",
|
||||
"LabelLanguage": "Language:",
|
||||
"Search": "Search",
|
||||
"NoSubtitleSearchResultsFound": "No results found.",
|
||||
"File": "File",
|
||||
"MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?",
|
||||
"ConfirmDeletion": "Confirm Deletion",
|
||||
"MySubtitles": "My Subtitles",
|
||||
"MessageDownloadQueued": "Download queued.",
|
||||
"EditSubtitles": "Edit Subtitles",
|
||||
"UnlockGuide": "Unlock Guide",
|
||||
"RefreshMetadata": "Refresh Metadata",
|
||||
"ReplaceExistingImages": "Replace existing images",
|
||||
"ReplaceAllMetadata": "Replace all metadata",
|
||||
"SearchForMissingMetadata": "Search for missing metadata",
|
||||
"LabelRefreshMode": "Refresh mode:",
|
||||
"RefreshDialogHelp": "Metadata is refreshed based on settings and internet services that are enabled in the Emby Server dashboard."
|
||||
}
|
|
@ -23,7 +23,9 @@
|
|||
"ButtonOk": "Ok",
|
||||
"ButtonCancel": "Cancel",
|
||||
"ButtonGotIt": "Got It",
|
||||
"RecordingCancelled": "Recording cancelled.",
|
||||
"RecordingScheduled": "Recording scheduled.",
|
||||
"SeriesRecordingScheduled": "Series recording scheduled.",
|
||||
"HeaderNewRecording": "New Recording",
|
||||
"Sunday": "Sunday",
|
||||
"Monday": "Monday",
|
||||
|
@ -54,5 +56,35 @@
|
|||
"HeaderDeleteItem": "Delete Item",
|
||||
"ConfirmDeleteItem": "Deleting this item will delete it from both the file system and your media library. Are you sure you wish to continue?",
|
||||
"Refresh": "Refresh",
|
||||
"RefreshQueued": "Refresh queued."
|
||||
"RefreshQueued": "Refresh queued.",
|
||||
"AddToCollection": "Add to Collection",
|
||||
"NewCollection": "New Collection",
|
||||
"LabelCollection": "Collection:",
|
||||
"Help": "Help",
|
||||
"NewCollectionHelp": "Collections allow you to create personalized groupings of movies and other library content.",
|
||||
"SearchForCollectionInternetMetadata": "Search the internet for artwork and metadata",
|
||||
"LabelName": "Name:",
|
||||
"NewCollectionNameExample": "Example: Star Wars Collection",
|
||||
"MessageItemsAdded": "Items added.",
|
||||
"OptionNew": "New...",
|
||||
"LabelPlaylist": "Playlist:",
|
||||
"AddToPlaylist": "Add to Playlist",
|
||||
"Subtitles": "Subtitles",
|
||||
"SearchForSubtitles": "Search for Subtitles",
|
||||
"LabelLanguage": "Language:",
|
||||
"Search": "Search",
|
||||
"NoSubtitleSearchResultsFound": "No results found.",
|
||||
"File": "File",
|
||||
"MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?",
|
||||
"ConfirmDeletion": "Confirm Deletion",
|
||||
"MySubtitles": "My Subtitles",
|
||||
"MessageDownloadQueued": "Download queued.",
|
||||
"EditSubtitles": "Edit Subtitles",
|
||||
"UnlockGuide": "Unlock Guide",
|
||||
"RefreshMetadata": "Refresh Metadata",
|
||||
"ReplaceExistingImages": "Replace existing images",
|
||||
"ReplaceAllMetadata": "Replace all metadata",
|
||||
"SearchForMissingMetadata": "Search for missing metadata",
|
||||
"LabelRefreshMode": "Refresh mode:",
|
||||
"RefreshDialogHelp": "Metadata is refreshed based on settings and internet services that are enabled in the Emby Server dashboard."
|
||||
}
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
"Delete": "Delete",
|
||||
"HeaderDeleteItem": "Delete Item",
|
||||
"ConfirmDeleteItem": "Deleting this item will delete it from both the file system and your media library. Are you sure you wish to continue?",
|
||||
"ValueSpecialEpisodeName": "Especial - {0}",
|
||||
"Share": "Compartir",
|
||||
"ServerUpdateNeeded": "Este Servidor Emby necesita ser actualizado. Para descargar la ultima versi\u00f3n, por favor visite {0}",
|
||||
|
@ -26,7 +23,9 @@
|
|||
"ButtonOk": "Ok",
|
||||
"ButtonCancel": "Cancelar",
|
||||
"ButtonGotIt": "Hecho",
|
||||
"RecordingCancelled": "Recording cancelled.",
|
||||
"RecordingScheduled": "Grabaci\u00f3n programada.",
|
||||
"SeriesRecordingScheduled": "Series recording scheduled.",
|
||||
"HeaderNewRecording": "Nueva Grabaci\u00f3n",
|
||||
"Sunday": "Domingo",
|
||||
"Monday": "Lunes",
|
||||
|
@ -53,6 +52,39 @@
|
|||
"Edit": "Editar",
|
||||
"Download": "Descargar",
|
||||
"Advanced": "Avanzado",
|
||||
"Delete": "Eliminar",
|
||||
"HeaderDeleteItem": "Eliminar \u00cdtem",
|
||||
"ConfirmDeleteItem": "Al eliminar este \u00edtem se eliminar\u00e1 tanto del sistema de archivos como de su biblioteca de medios. \u00bfEsta seguro de querer continuar?",
|
||||
"Refresh": "Actualizar",
|
||||
"RefreshQueued": "Actualizaci\u00f3n programada"
|
||||
"RefreshQueued": "Actualizaci\u00f3n programada",
|
||||
"AddToCollection": "Agregar a Colecci\u00f3n.",
|
||||
"NewCollection": "Nueva Colecci\u00f3n",
|
||||
"LabelCollection": "Colecci\u00f3n:",
|
||||
"Help": "Ayuda",
|
||||
"NewCollectionHelp": "Las colecciones le permiten disfrutar de agrupaciones personalizadas de pel\u00edculas y otros contenidos de la biblioteca.",
|
||||
"SearchForCollectionInternetMetadata": "Buscar en internet ilustraciones y metadatos",
|
||||
"LabelName": "Nombre:",
|
||||
"NewCollectionNameExample": "Ejemplo: Colecci\u00f3n Guerra de las Galaxias",
|
||||
"MessageItemsAdded": "\u00cdtems agregados.",
|
||||
"OptionNew": "Nuevo...",
|
||||
"LabelPlaylist": "Lista de Reproducci\u00f3n:",
|
||||
"AddToPlaylist": "Agregar a lista de reproducci\u00f3n",
|
||||
"Subtitles": "Subtitles",
|
||||
"SearchForSubtitles": "Search for Subtitles",
|
||||
"LabelLanguage": "Language:",
|
||||
"Search": "Search",
|
||||
"NoSubtitleSearchResultsFound": "No results found.",
|
||||
"File": "File",
|
||||
"MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?",
|
||||
"ConfirmDeletion": "Confirm Deletion",
|
||||
"MySubtitles": "My Subtitles",
|
||||
"MessageDownloadQueued": "Download queued.",
|
||||
"EditSubtitles": "Edit Subtitles",
|
||||
"UnlockGuide": "Unlock Guide",
|
||||
"RefreshMetadata": "Refresh Metadata",
|
||||
"ReplaceExistingImages": "Replace existing images",
|
||||
"ReplaceAllMetadata": "Replace all metadata",
|
||||
"SearchForMissingMetadata": "Search for missing metadata",
|
||||
"LabelRefreshMode": "Refresh mode:",
|
||||
"RefreshDialogHelp": "Metadata is refreshed based on settings and internet services that are enabled in the Emby Server dashboard."
|
||||
}
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
"Delete": "Delete",
|
||||
"HeaderDeleteItem": "Delete Item",
|
||||
"ConfirmDeleteItem": "Deleting this item will delete it from both the file system and your media library. Are you sure you wish to continue?",
|
||||
"ValueSpecialEpisodeName": "\u0410\u0440\u043d\u0430\u0439\u044b - {0}",
|
||||
"Share": "\u041e\u0440\u0442\u0430\u049b\u0442\u0430\u0441\u0443",
|
||||
"ServerUpdateNeeded": "\u041e\u0441\u044b Emby Server \u0436\u0430\u04a3\u0430\u0440\u0442\u044b\u043b\u0443\u044b \u049b\u0430\u0436\u0435\u0442. \u0421\u043e\u04a3\u0493\u044b \u043d\u04b1\u0441\u049b\u0430\u0441\u044b\u043d \u0436\u04af\u043a\u0442\u0435\u043f \u0430\u043b\u0443 \u04af\u0448\u0456\u043d, {0} \u043a\u0456\u0440\u0456\u04a3\u0456\u0437",
|
||||
|
@ -26,7 +23,9 @@
|
|||
"ButtonOk": "\u0416\u0430\u0440\u0430\u0439\u0434\u044b",
|
||||
"ButtonCancel": "\u0411\u043e\u043b\u0434\u044b\u0440\u043c\u0430\u0443",
|
||||
"ButtonGotIt": "\u0422\u04af\u0441\u0456\u043d\u0456\u043a\u0442\u0456",
|
||||
"RecordingCancelled": "\u0416\u0430\u0437\u0431\u0430 \u0431\u043e\u043b\u0434\u044b\u0440\u044b\u043b\u043c\u0430\u0434\u044b.",
|
||||
"RecordingScheduled": "\u0416\u0430\u0437\u0443 \u0436\u043e\u0441\u043f\u0430\u0440\u043b\u0430\u0493\u0430\u043d.",
|
||||
"SeriesRecordingScheduled": "\u0422\u0435\u043b\u0435\u0445\u0438\u043a\u0430\u044f \u0436\u0430\u0437\u0443\u044b \u0436\u043e\u0441\u043f\u0430\u0440\u043b\u0430\u0493\u0430\u043d.",
|
||||
"HeaderNewRecording": "\u0416\u0430\u04a3\u0430 \u0436\u0430\u0437\u0443",
|
||||
"Sunday": "\u0436\u0435\u043a\u0441\u0435\u043d\u0431\u0456",
|
||||
"Monday": "\u0434\u04af\u0439\u0441\u0435\u043d\u0431\u0456",
|
||||
|
@ -53,6 +52,39 @@
|
|||
"Edit": "\u04e8\u04a3\u0434\u0435\u0443",
|
||||
"Download": "\u0416\u04af\u043a\u0442\u0435\u043f \u0430\u043b\u0443",
|
||||
"Advanced": "\u041a\u0435\u04a3\u0435\u0439\u0442\u0456\u043b\u0433\u0435\u043d",
|
||||
"Delete": "\u0416\u043e\u044e",
|
||||
"HeaderDeleteItem": "\u0422\u0430\u0440\u043c\u0430\u049b\u0442\u044b \u0436\u043e\u044e",
|
||||
"ConfirmDeleteItem": "\u041e\u0441\u044b \u0442\u0430\u0440\u043c\u0430\u049b\u0442\u044b \u0436\u043e\u0439\u0493\u0430\u043d\u0434\u0430, \u043e\u043b \u0444\u0430\u0439\u043b \u0436\u04af\u0439\u0435\u0441\u0456\u043d\u0435\u043d \u0434\u0435, \u0442\u0430\u0441\u044b\u0493\u044b\u0448\u0445\u0430\u043d\u0430\u04a3\u044b\u0437\u0434\u0430\u043d \u0434\u0430 \u0436\u043e\u0439\u044b\u043b\u0430\u0434\u044b. \u0428\u044b\u043d\u044b\u043c\u0435\u043d \u0436\u0430\u043b\u0493\u0430\u0441\u0442\u044b\u0440\u0443 \u049b\u0430\u0436\u0435\u0442 \u043f\u0435?",
|
||||
"Refresh": "\u0416\u0430\u04a3\u0493\u044b\u0440\u0442\u0443",
|
||||
"RefreshQueued": "\u0416\u0430\u04a3\u0493\u044b\u0440\u0442\u0443 \u043a\u0435\u0437\u0435\u043a\u0442\u0435."
|
||||
"RefreshQueued": "\u0416\u0430\u04a3\u0493\u044b\u0440\u0442\u0443 \u043a\u0435\u0437\u0435\u043a\u0442\u0435.",
|
||||
"AddToCollection": "\u0416\u0438\u044b\u043d\u0442\u044b\u049b\u049b\u0430 \u04af\u0441\u0442\u0435\u0443",
|
||||
"NewCollection": "\u0416\u0430\u04a3\u0430 \u0436\u0438\u044b\u043d\u0442\u044b\u049b",
|
||||
"LabelCollection": "\u0416\u0438\u044b\u043d\u0442\u044b\u049b:",
|
||||
"Help": "\u0410\u043d\u044b\u049b\u0442\u0430\u043c\u0430",
|
||||
"NewCollectionHelp": "\u0416\u0438\u044b\u043d\u0442\u044b\u049b\u0442\u0430\u0440 \u0441\u0456\u0437\u0433\u0435 \u0424\u0438\u043b\u044c\u043c\u0434\u0435\u0440\u0434\u0456\u04a3 \u0436\u04d9\u043d\u0435 \u0442\u0430\u0493\u044b \u0431\u0430\u0441\u049b\u0430 \u0442\u0430\u0441\u044b\u0493\u044b\u0448\u0445\u0430\u043d\u0430\u043d\u044b\u04a3 \u043c\u0430\u0437\u043c\u04b1\u043d\u044b\u043d \u0434\u0435\u0440\u0431\u0435\u0441\u0442\u0435\u043d\u0434\u0456\u0440\u0456\u043b\u0433\u0435\u043d \u0442\u043e\u043f\u0442\u0430\u0443\u043b\u0430\u0440\u044b\u043c\u0435\u043d \u0442\u0430\u043c\u0430\u0448\u0430\u043b\u0430\u043d\u0443 \u04af\u0448\u0456\u043d \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0435\u0434\u0456.",
|
||||
"SearchForCollectionInternetMetadata": "\u0421\u0443\u0440\u0435\u0442\u0442\u0435\u043c\u0435\u043b\u0435\u0440 \u0431\u0435\u043d \u043c\u0435\u0442\u0430\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440\u0434\u0456 \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0442\u0435\u043d \u0456\u0437\u0434\u0435\u0443",
|
||||
"LabelName": "\u0410\u0442\u044b:",
|
||||
"NewCollectionNameExample": "\u041c\u044b\u0441\u0430\u043b: \u0416\u04b1\u043b\u0434\u044b\u0437 \u0441\u043e\u0493\u044b\u0441\u0442\u0430\u0440\u044b (\u0436\u0438\u044b\u043d\u0442\u044b\u049b)",
|
||||
"MessageItemsAdded": "\u0422\u0430\u0440\u043c\u0430\u049b\u0442\u0430\u0440 \u04af\u0441\u0442\u0435\u043b\u0433\u0435\u043d.",
|
||||
"OptionNew": "\u0416\u0430\u04a3\u0430...",
|
||||
"LabelPlaylist": "\u041e\u0439\u043d\u0430\u0442\u0443 \u0442\u0456\u0437\u0456\u043c\u0456:",
|
||||
"AddToPlaylist": "\u041e\u0439\u043d\u0430\u0442\u0443 \u0442\u0456\u0437\u0456\u043c\u0456\u043d\u0435 \u04af\u0441\u0442\u0435\u0443",
|
||||
"Subtitles": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440",
|
||||
"SearchForSubtitles": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440\u0434\u0456 \u0456\u0437\u0434\u0435\u0443",
|
||||
"LabelLanguage": "\u0422\u0456\u043b:",
|
||||
"Search": "\u0406\u0437\u0434\u0435\u0443",
|
||||
"NoSubtitleSearchResultsFound": "\u0415\u0448\u049b\u0430\u043d\u0434\u0430\u0439 \u043d\u04d9\u0442\u0438\u0436\u0435\u043b\u0435\u0440 \u0442\u0430\u0431\u044b\u043b\u043c\u0430\u0434\u044b.",
|
||||
"File": "\u0424\u0430\u0439\u043b",
|
||||
"MessageAreYouSureDeleteSubtitles": "\u0428\u044b\u043d\u044b\u043c\u0435\u043d \u043e\u0441\u044b \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440 \u0444\u0430\u0439\u043b\u044b\u043d \u0436\u043e\u044e \u049b\u0430\u0436\u0435\u0442 \u043f\u0435?",
|
||||
"ConfirmDeletion": "\u0416\u043e\u044e\u0434\u044b \u0440\u0430\u0441\u0442\u0430\u0443",
|
||||
"MySubtitles": "\u041c\u0435\u043d\u0456\u04a3 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440\u0456\u043c",
|
||||
"MessageDownloadQueued": "\u0416\u04af\u043a\u0442\u0435\u043f \u0430\u043b\u0443 \u043a\u0435\u0437\u0435\u043a\u0442\u0435.",
|
||||
"EditSubtitles": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440\u0434\u0456 \u04e9\u04a3\u0434\u0435\u0443",
|
||||
"UnlockGuide": "\u0422\u0435\u043b\u0435\u0433\u0438\u0434\u0442\u0456 \u049b\u04b1\u0440\u0441\u0430\u0443\u0434\u0430\u043d \u0431\u043e\u0441\u0430\u0442\u0443",
|
||||
"RefreshMetadata": "Refresh Metadata",
|
||||
"ReplaceExistingImages": "Replace existing images",
|
||||
"ReplaceAllMetadata": "Replace all metadata",
|
||||
"SearchForMissingMetadata": "Search for missing metadata",
|
||||
"LabelRefreshMode": "Refresh mode:",
|
||||
"RefreshDialogHelp": "Metadata is refreshed based on settings and internet services that are enabled in the Emby Server dashboard."
|
||||
}
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
"Delete": "Slett",
|
||||
"HeaderDeleteItem": "Slett element",
|
||||
"ConfirmDeleteItem": "Ved \u00e5 slette dette element vil du b\u00e5de slette det fra statement og mediebiblioteket. Er du sikker p\u00e5 at du vil forsette?",
|
||||
"ValueSpecialEpisodeName": "Spesial - {0}",
|
||||
"Share": "Del",
|
||||
"ServerUpdateNeeded": "Denne Emby serveren trenger en oppdatering. For \u00e5 laste ned nyeste versjon, vennligst bes\u00f8k: {0}",
|
||||
|
@ -26,7 +23,9 @@
|
|||
"ButtonOk": "Ok",
|
||||
"ButtonCancel": "Avbryt",
|
||||
"ButtonGotIt": "Skj\u00f8nner",
|
||||
"RecordingCancelled": "Recording cancelled.",
|
||||
"RecordingScheduled": "Planlagte opptak.",
|
||||
"SeriesRecordingScheduled": "Series recording scheduled.",
|
||||
"HeaderNewRecording": "Tar opp n\u00e5",
|
||||
"Sunday": "S\u00f8ndag",
|
||||
"Monday": "Mandag",
|
||||
|
@ -53,6 +52,39 @@
|
|||
"Edit": "Endre",
|
||||
"Download": "Last ned",
|
||||
"Advanced": "Avansert",
|
||||
"Delete": "Slett",
|
||||
"HeaderDeleteItem": "Slett element",
|
||||
"ConfirmDeleteItem": "Ved \u00e5 slette dette element vil du b\u00e5de slette det fra statement og mediebiblioteket. Er du sikker p\u00e5 at du vil forsette?",
|
||||
"Refresh": "Oppdater",
|
||||
"RefreshQueued": "Oppdatering k\u00f8"
|
||||
"RefreshQueued": "Oppdatering k\u00f8",
|
||||
"AddToCollection": "Legg til i Samling",
|
||||
"NewCollection": "Ny Samling",
|
||||
"LabelCollection": "Samling:",
|
||||
"Help": "Hjelp",
|
||||
"NewCollectionHelp": "Samling lar deg lage personlige grupper av filmer eller andre biblioteker.",
|
||||
"SearchForCollectionInternetMetadata": "S\u00f8k p\u00e5 internet etter kunstverk og metadata",
|
||||
"LabelName": "Navn:",
|
||||
"NewCollectionNameExample": "Eksempel: Star Wars Samling",
|
||||
"MessageItemsAdded": "Elementer lagt til.",
|
||||
"OptionNew": "Ny",
|
||||
"LabelPlaylist": "Spilleliste:",
|
||||
"AddToPlaylist": "Legg til i Spilleliste",
|
||||
"Subtitles": "Subtitles",
|
||||
"SearchForSubtitles": "Search for Subtitles",
|
||||
"LabelLanguage": "Language:",
|
||||
"Search": "Search",
|
||||
"NoSubtitleSearchResultsFound": "No results found.",
|
||||
"File": "File",
|
||||
"MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?",
|
||||
"ConfirmDeletion": "Confirm Deletion",
|
||||
"MySubtitles": "My Subtitles",
|
||||
"MessageDownloadQueued": "Download queued.",
|
||||
"EditSubtitles": "Edit Subtitles",
|
||||
"UnlockGuide": "Unlock Guide",
|
||||
"RefreshMetadata": "Refresh Metadata",
|
||||
"ReplaceExistingImages": "Replace existing images",
|
||||
"ReplaceAllMetadata": "Replace all metadata",
|
||||
"SearchForMissingMetadata": "Search for missing metadata",
|
||||
"LabelRefreshMode": "Refresh mode:",
|
||||
"RefreshDialogHelp": "Metadata is refreshed based on settings and internet services that are enabled in the Emby Server dashboard."
|
||||
}
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
"Delete": "Verwijder",
|
||||
"HeaderDeleteItem": "Item verwijderen",
|
||||
"ConfirmDeleteItem": "Verwijderen van dit item zal het verwijderen uit zowel het bestandssysteem als de Media Bibliotheek. Weet u zeker dat u wilt doorgaan?",
|
||||
"ValueSpecialEpisodeName": "Speciaal - {0}",
|
||||
"Share": "Delen",
|
||||
"ServerUpdateNeeded": "Deze Emby Server moet worden bijgewerkt. Om de laatste versie te downloaden, gaat u naar {0}",
|
||||
|
@ -26,7 +23,9 @@
|
|||
"ButtonOk": "Ok",
|
||||
"ButtonCancel": "Annuleren",
|
||||
"ButtonGotIt": "Begrepen",
|
||||
"RecordingCancelled": "Recording cancelled.",
|
||||
"RecordingScheduled": "Opname schema",
|
||||
"SeriesRecordingScheduled": "Series recording scheduled.",
|
||||
"HeaderNewRecording": "Nieuwe opname",
|
||||
"Sunday": "Zondag",
|
||||
"Monday": "Maandag",
|
||||
|
@ -53,6 +52,39 @@
|
|||
"Edit": "Bewerken",
|
||||
"Download": "Downloaden",
|
||||
"Advanced": "Geavanceerd",
|
||||
"Delete": "Verwijder",
|
||||
"HeaderDeleteItem": "Item verwijderen",
|
||||
"ConfirmDeleteItem": "Verwijderen van dit item zal het verwijderen uit zowel het bestandssysteem als de Media Bibliotheek. Weet u zeker dat u wilt doorgaan?",
|
||||
"Refresh": "Vernieuwen",
|
||||
"RefreshQueued": "Vernieuwen wachtrij"
|
||||
"RefreshQueued": "Vernieuwen wachtrij",
|
||||
"AddToCollection": "Add to Collection",
|
||||
"NewCollection": "New Collection",
|
||||
"LabelCollection": "Collection:",
|
||||
"Help": "Help",
|
||||
"NewCollectionHelp": "Collections allow you to create personalized groupings of movies and other library content.",
|
||||
"SearchForCollectionInternetMetadata": "Search the internet for artwork and metadata",
|
||||
"LabelName": "Name:",
|
||||
"NewCollectionNameExample": "Example: Star Wars Collection",
|
||||
"MessageItemsAdded": "Items added.",
|
||||
"OptionNew": "New...",
|
||||
"LabelPlaylist": "Playlist:",
|
||||
"AddToPlaylist": "Add to Playlist",
|
||||
"Subtitles": "Subtitles",
|
||||
"SearchForSubtitles": "Search for Subtitles",
|
||||
"LabelLanguage": "Language:",
|
||||
"Search": "Search",
|
||||
"NoSubtitleSearchResultsFound": "No results found.",
|
||||
"File": "File",
|
||||
"MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?",
|
||||
"ConfirmDeletion": "Confirm Deletion",
|
||||
"MySubtitles": "My Subtitles",
|
||||
"MessageDownloadQueued": "Download queued.",
|
||||
"EditSubtitles": "Edit Subtitles",
|
||||
"UnlockGuide": "Unlock Guide",
|
||||
"RefreshMetadata": "Refresh Metadata",
|
||||
"ReplaceExistingImages": "Replace existing images",
|
||||
"ReplaceAllMetadata": "Replace all metadata",
|
||||
"SearchForMissingMetadata": "Search for missing metadata",
|
||||
"LabelRefreshMode": "Refresh mode:",
|
||||
"RefreshDialogHelp": "Metadata is refreshed based on settings and internet services that are enabled in the Emby Server dashboard."
|
||||
}
|
90
dashboard-ui/bower_components/emby-webcomponents/strings/pt-BR.json
vendored
Normal file
90
dashboard-ui/bower_components/emby-webcomponents/strings/pt-BR.json
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"ValueSpecialEpisodeName": "Especial - {0}",
|
||||
"Share": "Compartilhar",
|
||||
"ServerUpdateNeeded": "Este servidor Emby precisa ser atualizado. Para baixar a \u00faltima vers\u00e3o, por favor visite {0}",
|
||||
"LiveTvGuideRequiresUnlock": "O Guia da TV ao Vivo atualmente est\u00e1 limitado a {0} canais. Clique no bot\u00e3o desbloquear para aprender como aproveitar a experi\u00eancia completa.",
|
||||
"AttributeNew": "Novo",
|
||||
"AttributePremiere": "Estr\u00e9ia",
|
||||
"AttributeLive": "Ao Vivo",
|
||||
"TrackCount": "{0} faixas",
|
||||
"ItemCount": "{0} itens",
|
||||
"ValueSeriesYearToPresent": "{0}-Presente",
|
||||
"ReleaseYearValue": "Ano de lan\u00e7amento: {0}",
|
||||
"OriginalAirDateValue": "Data de exibi\u00e7\u00e3o original: {0}",
|
||||
"EndsAtValue": "Termina \u00e0s {0}",
|
||||
"OptionSundayShort": "Dom",
|
||||
"OptionMondayShort": "Seg",
|
||||
"OptionTuesdayShort": "Ter",
|
||||
"OptionWednesdayShort": "Qua",
|
||||
"OptionThursdayShort": "Qui",
|
||||
"OptionFridayShort": "Sex",
|
||||
"OptionSaturdayShort": "S\u00e1b",
|
||||
"HeaderSelectDate": "Selecionar Data",
|
||||
"ButtonOk": "Ok",
|
||||
"ButtonCancel": "Cancelar",
|
||||
"ButtonGotIt": "Entendi",
|
||||
"RecordingCancelled": "Grava\u00e7\u00e3o cancelada.",
|
||||
"RecordingScheduled": "Grava\u00e7\u00e3o agendada.",
|
||||
"SeriesRecordingScheduled": "Grava\u00e7\u00e3o de s\u00e9rie agendada.",
|
||||
"HeaderNewRecording": "Nova grava\u00e7\u00e3o.",
|
||||
"Sunday": "Domingo",
|
||||
"Monday": "Segunda-feira",
|
||||
"Tuesday": "Ter\u00e7a-feira",
|
||||
"Wednesday": "Quarta-feira",
|
||||
"Thursday": "Quinta-feira",
|
||||
"Friday": "Sexta-feira",
|
||||
"Saturday": "S\u00e1bado",
|
||||
"Days": "Dias",
|
||||
"RecordSeries": "Gravar s\u00e9rie",
|
||||
"LabelPrePaddingMinutes": "Minutos de anteced\u00eancia:",
|
||||
"LabelPostPaddingMinutes": "Minutos p\u00f3s-t\u00e9rmino:",
|
||||
"RecordOnAllChannels": "Gravar em todos os canais",
|
||||
"RecordAnytime": "Gravar a qualquer momento",
|
||||
"RecordOnlyNewEpisodes": "Gravar apenas novos epis\u00f3dios",
|
||||
"HeaderBecomeProjectSupporter": "Obter Emby Premiere",
|
||||
"HeaderEnjoyDayTrial": "Aproveite um per\u00edodo de 14 dias gr\u00e1tis para testes",
|
||||
"MessageActiveSubscriptionRequiredSeriesRecordings": "Uma subscri\u00e7\u00e3o ativa do Emby Premiere \u00e9 requerida para criar a grava\u00e7\u00e3o automatizada de s\u00e9ries.",
|
||||
"OptionConvertRecordingsToStreamingFormat": "Converter automaticamente grava\u00e7\u00f5es para um formato amig\u00e1vel de streaming",
|
||||
"OptionConvertRecordingsToStreamingFormatHelp": "Grava\u00e7\u00f5es ser\u00e3o convertidas automaticamente para MP4 para uma reprodu\u00e7\u00e3o mais f\u00e1cil em seus dispositivos.",
|
||||
"FeatureRequiresEmbyPremiere": "Este recurso requer uma subscri\u00e7\u00e3o ativa do Emby Premiere",
|
||||
"Record": "Gravar",
|
||||
"Save": "Salvar",
|
||||
"Edit": "Editar",
|
||||
"Download": "Baixar",
|
||||
"Advanced": "Avan\u00e7ado",
|
||||
"Delete": "Excluir",
|
||||
"HeaderDeleteItem": "Excluir item",
|
||||
"ConfirmDeleteItem": "Excluir este item o excluir\u00e1 do sistema de arquivos e tamb\u00e9m da biblioteca de m\u00eddia. Deseja realmente continuar?",
|
||||
"Refresh": "Atualizar",
|
||||
"RefreshQueued": "Atualiza\u00e7\u00e3o iniciada.",
|
||||
"AddToCollection": "Adicionar \u00e0 Colet\u00e2nea",
|
||||
"NewCollection": "Nova Colet\u00e2nea",
|
||||
"LabelCollection": "Colet\u00e2nea:",
|
||||
"Help": "Ajuda",
|
||||
"NewCollectionHelp": "Colet\u00e2neas permitem que voc\u00ea crie grupos personalizados de filmes e outros conte\u00fados da biblioteca.",
|
||||
"SearchForCollectionInternetMetadata": "Buscar artwork e metadados na internet",
|
||||
"LabelName": "Nome:",
|
||||
"NewCollectionNameExample": "Exemplo: Colet\u00e2nea Star Wars",
|
||||
"MessageItemsAdded": "Itens adicionados.",
|
||||
"OptionNew": "Novo...",
|
||||
"LabelPlaylist": "Lista de Reprodu\u00e7\u00e3o:",
|
||||
"AddToPlaylist": "Adicionar \u00e0 lista de reprodu\u00e7\u00e3o",
|
||||
"Subtitles": "Legendas",
|
||||
"SearchForSubtitles": "Buscar Legendas",
|
||||
"LabelLanguage": "Idioma:",
|
||||
"Search": "Busca",
|
||||
"NoSubtitleSearchResultsFound": "Nenhum resultado encontrado.",
|
||||
"File": "Arquivo",
|
||||
"MessageAreYouSureDeleteSubtitles": "Deseja realmente excluir este arquivo de legendas?",
|
||||
"ConfirmDeletion": "Confirmar Exclus\u00e3o",
|
||||
"MySubtitles": "Minhas Legendas",
|
||||
"MessageDownloadQueued": "Download enfileirado.",
|
||||
"EditSubtitles": "Editar Legendas",
|
||||
"UnlockGuide": "Desbloquear Guia",
|
||||
"RefreshMetadata": "Atualizar Metadados",
|
||||
"ReplaceExistingImages": "Substituir as imagens existentes",
|
||||
"ReplaceAllMetadata": "Substituir todos os metadados",
|
||||
"SearchForMissingMetadata": "Buscar por metadados que faltam",
|
||||
"LabelRefreshMode": "Mode de atualiza\u00e7\u00e3o:",
|
||||
"RefreshDialogHelp": "Os metadados s\u00e3o atualizados com bases nas defini\u00e7\u00f5es e nos servi\u00e7os de internet que est\u00e3o ativos no painel do Servidor Emby."
|
||||
}
|
90
dashboard-ui/bower_components/emby-webcomponents/strings/pt-PT.json
vendored
Normal file
90
dashboard-ui/bower_components/emby-webcomponents/strings/pt-PT.json
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"ValueSpecialEpisodeName": "Especial - {0}",
|
||||
"Share": "Partilhar",
|
||||
"ServerUpdateNeeded": "Este Servidor Emby precisa ser atualizado. Para fazer download da vers\u00e3o mais recente, por favor visite {0}",
|
||||
"LiveTvGuideRequiresUnlock": "The Live TV Guide is currently limited to {0} channels. Click the unlock button to learn how to enjoy the full experience.",
|
||||
"AttributeNew": "Novo",
|
||||
"AttributePremiere": "Estreia",
|
||||
"AttributeLive": "Ao vivo",
|
||||
"TrackCount": "{0} faixas",
|
||||
"ItemCount": "{0} itens",
|
||||
"ValueSeriesYearToPresent": "{0}-Presente",
|
||||
"ReleaseYearValue": "Ano de lan\u00e7amento: {0}",
|
||||
"OriginalAirDateValue": "Original air date: {0}",
|
||||
"EndsAtValue": "Ends at {0}",
|
||||
"OptionSundayShort": "Sun",
|
||||
"OptionMondayShort": "Mon",
|
||||
"OptionTuesdayShort": "Tue",
|
||||
"OptionWednesdayShort": "Wed",
|
||||
"OptionThursdayShort": "Thu",
|
||||
"OptionFridayShort": "Fri",
|
||||
"OptionSaturdayShort": "Sat",
|
||||
"HeaderSelectDate": "Select Date",
|
||||
"ButtonOk": "Ok",
|
||||
"ButtonCancel": "Cancel",
|
||||
"ButtonGotIt": "Got It",
|
||||
"RecordingCancelled": "Recording cancelled.",
|
||||
"RecordingScheduled": "Recording scheduled.",
|
||||
"SeriesRecordingScheduled": "Series recording scheduled.",
|
||||
"HeaderNewRecording": "New Recording",
|
||||
"Sunday": "Sunday",
|
||||
"Monday": "Monday",
|
||||
"Tuesday": "Tuesday",
|
||||
"Wednesday": "Wednesday",
|
||||
"Thursday": "Thursday",
|
||||
"Friday": "Friday",
|
||||
"Saturday": "Saturday",
|
||||
"Days": "Days",
|
||||
"RecordSeries": "Record series",
|
||||
"LabelPrePaddingMinutes": "Pre-padding minutes:",
|
||||
"LabelPostPaddingMinutes": "Post-padding minutes:",
|
||||
"RecordOnAllChannels": "Record on all channels",
|
||||
"RecordAnytime": "Record at any time",
|
||||
"RecordOnlyNewEpisodes": "Record only new episodes",
|
||||
"HeaderBecomeProjectSupporter": "Get Emby Premiere",
|
||||
"HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial",
|
||||
"MessageActiveSubscriptionRequiredSeriesRecordings": "An active Emby Premiere subscription is required in order to create automated series recordings.",
|
||||
"OptionConvertRecordingsToStreamingFormat": "Automatically convert recordings to a streaming friendly format",
|
||||
"OptionConvertRecordingsToStreamingFormatHelp": "Recordings will be converted on the fly to MP4 for easy playback on your devices.",
|
||||
"FeatureRequiresEmbyPremiere": "This feature requires an active Emby Premiere subscription.",
|
||||
"Record": "Record",
|
||||
"Save": "Save",
|
||||
"Edit": "Edit",
|
||||
"Download": "Download",
|
||||
"Advanced": "Advanced",
|
||||
"Delete": "Delete",
|
||||
"HeaderDeleteItem": "Delete Item",
|
||||
"ConfirmDeleteItem": "Deleting this item will delete it from both the file system and your media library. Are you sure you wish to continue?",
|
||||
"Refresh": "Refresh",
|
||||
"RefreshQueued": "Refresh queued.",
|
||||
"AddToCollection": "Add to Collection",
|
||||
"NewCollection": "New Collection",
|
||||
"LabelCollection": "Collection:",
|
||||
"Help": "Help",
|
||||
"NewCollectionHelp": "Collections allow you to create personalized groupings of movies and other library content.",
|
||||
"SearchForCollectionInternetMetadata": "Search the internet for artwork and metadata",
|
||||
"LabelName": "Name:",
|
||||
"NewCollectionNameExample": "Example: Star Wars Collection",
|
||||
"MessageItemsAdded": "Items added.",
|
||||
"OptionNew": "New...",
|
||||
"LabelPlaylist": "Playlist:",
|
||||
"AddToPlaylist": "Add to Playlist",
|
||||
"Subtitles": "Subtitles",
|
||||
"SearchForSubtitles": "Search for Subtitles",
|
||||
"LabelLanguage": "Language:",
|
||||
"Search": "Search",
|
||||
"NoSubtitleSearchResultsFound": "No results found.",
|
||||
"File": "File",
|
||||
"MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?",
|
||||
"ConfirmDeletion": "Confirm Deletion",
|
||||
"MySubtitles": "My Subtitles",
|
||||
"MessageDownloadQueued": "Download queued.",
|
||||
"EditSubtitles": "Edit Subtitles",
|
||||
"UnlockGuide": "Unlock Guide",
|
||||
"RefreshMetadata": "Refresh Metadata",
|
||||
"ReplaceExistingImages": "Replace existing images",
|
||||
"ReplaceAllMetadata": "Replace all metadata",
|
||||
"SearchForMissingMetadata": "Search for missing metadata",
|
||||
"LabelRefreshMode": "Refresh mode:",
|
||||
"RefreshDialogHelp": "Metadata is refreshed based on settings and internet services that are enabled in the Emby Server dashboard."
|
||||
}
|
|
@ -1,20 +1,17 @@
|
|||
{
|
||||
"Delete": "Delete",
|
||||
"HeaderDeleteItem": "Delete Item",
|
||||
"ConfirmDeleteItem": "Deleting this item will delete it from both the file system and your media library. Are you sure you wish to continue?",
|
||||
"ValueSpecialEpisodeName": "\u0421\u043f\u0435\u0446\u044d\u043f\u0438\u0437\u043e\u0434 - {0}",
|
||||
"Share": "\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f",
|
||||
"ServerUpdateNeeded": "\u0414\u0430\u043d\u043d\u044b\u0439 Emby \u0421\u0435\u0440\u0432\u0435\u0440 \u043d\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438. \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0432\u0435\u0440\u0441\u0438\u044e, \u043f\u043e\u0441\u0435\u0442\u0438\u0442\u0435 {0}",
|
||||
"ServerUpdateNeeded": "\u0414\u0430\u043d\u043d\u044b\u0439 Emby Server \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c. \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0432\u0435\u0440\u0441\u0438\u044e, \u043f\u043e\u0441\u0435\u0442\u0438\u0442\u0435 {0}",
|
||||
"LiveTvGuideRequiresUnlock": "\u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0442\u0435\u043b\u0435\u0433\u0438\u0434 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d {0} \u043a\u0430\u043d\u0430\u043b(\u043e\u043c\/\u0430\u043c\u0438). \u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043a\u043d\u043e\u043f\u043a\u0443 \u0420\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0443\u0437\u043d\u0430\u0442\u044c \u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u044d\u0444\u0444\u0435\u043a\u0442.",
|
||||
"AttributeNew": "\u041d\u043e\u0432\u043e\u0435",
|
||||
"AttributePremiere": "\u041f\u0440\u0435\u043c\u044c\u0435\u0440\u0430",
|
||||
"AttributeLive": "\u042d\u0444\u0438\u0440",
|
||||
"AttributeLive": "\u042d\u0444\u0438\u0440\u043d\u043e\u0435",
|
||||
"TrackCount": "{0} \u0434\u043e\u0440\u043e\u0436(\u043a\u0438\/\u0435\u043a)",
|
||||
"ItemCount": "{0} \u044d\u043b\u0435\u043c\u0435\u043d\u0442(\u0430\/\u043e\u0432)",
|
||||
"ValueSeriesYearToPresent": "{0} - \u041d.\u0412.",
|
||||
"ReleaseYearValue": "\u0413\u043e\u0434 \u0432\u044b\u043f\u0443\u0441\u043a\u0430: {0}",
|
||||
"OriginalAirDateValue": "\u0414\u0430\u0442\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u044d\u0444\u0438\u0440\u0430: {0}",
|
||||
"EndsAtValue": "\u041a\u043e\u043d\u0447\u0430\u0435\u0442\u0441\u044f \u0432 {0}",
|
||||
"OriginalAirDateValue": "\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u044d\u0444\u0438\u0440: {0}",
|
||||
"EndsAtValue": "\u041a\u043e\u043d\u0435\u0446 \u0432 {0}",
|
||||
"OptionSundayShort": "\u0432\u0441\u043a",
|
||||
"OptionMondayShort": "\u043f\u043d\u0434",
|
||||
"OptionTuesdayShort": "\u0432\u0442\u0440",
|
||||
|
@ -26,7 +23,9 @@
|
|||
"ButtonOk": "\u041e\u043a",
|
||||
"ButtonCancel": "\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c",
|
||||
"ButtonGotIt": "\u041f\u043e\u043d\u044f\u0442\u043d\u043e",
|
||||
"RecordingCancelled": "\u0417\u0430\u043f\u0438\u0441\u044c \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430.",
|
||||
"RecordingScheduled": "\u0417\u0430\u043f\u0438\u0441\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430.",
|
||||
"SeriesRecordingScheduled": "\u0417\u0430\u043f\u0438\u0441\u044c \u0441\u0435\u0440\u0438\u0430\u043b\u0430 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430.",
|
||||
"HeaderNewRecording": "\u041d\u043e\u0432\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c",
|
||||
"Sunday": "\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435",
|
||||
"Monday": "\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a",
|
||||
|
@ -42,10 +41,10 @@
|
|||
"RecordOnAllChannels": "\u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0441\u043e \u0432\u0441\u0435\u0445 \u043a\u0430\u043d\u0430\u043b\u043e\u0432",
|
||||
"RecordAnytime": "\u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432 \u043b\u044e\u0431\u043e\u0435 \u0432\u0440\u0435\u043c\u044f",
|
||||
"RecordOnlyNewEpisodes": "\u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u043e\u0432\u044b\u0435 \u044d\u043f\u0438\u0437\u043e\u0434\u044b",
|
||||
"HeaderBecomeProjectSupporter": "\u041f\u0440\u0438\u043e\u0431\u0440\u0435\u0441\u0442\u0438 Emby Premiere",
|
||||
"HeaderBecomeProjectSupporter": "\u041f\u0440\u0438\u043e\u0431\u0440\u0435\u0442\u0435\u043d\u0438\u0435 Emby Premiere",
|
||||
"HeaderEnjoyDayTrial": "\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043d\u0430 14 \u0434\u043d\u0435\u0439",
|
||||
"MessageActiveSubscriptionRequiredSeriesRecordings": "\u0414\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 Emby Premiere \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0441\u0435\u0440\u0438\u0439.",
|
||||
"OptionConvertRecordingsToStreamingFormat": "\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0434\u043b\u044f \u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u0438 \u0444\u043e\u0440\u043c\u0430\u0442",
|
||||
"OptionConvertRecordingsToStreamingFormat": "\u0417\u0430\u043f\u0438\u0441\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0434\u043b\u044f \u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u0438 \u0444\u043e\u0440\u043c\u0430\u0442",
|
||||
"OptionConvertRecordingsToStreamingFormatHelp": "\u0417\u0430\u043f\u0438\u0441\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 MP4 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043d\u0430 \u0432\u0430\u0448\u0438\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445.",
|
||||
"FeatureRequiresEmbyPremiere": "\u0414\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 Emby Premiere.",
|
||||
"Record": "\u0417\u0430\u043f\u0438\u0441\u0430\u0442\u044c",
|
||||
|
@ -53,6 +52,39 @@
|
|||
"Edit": "\u041f\u0440\u0430\u0432\u0438\u0442\u044c",
|
||||
"Download": "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c",
|
||||
"Advanced": "\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u0435",
|
||||
"Delete": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c",
|
||||
"HeaderDeleteItem": "\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430",
|
||||
"ConfirmDeleteItem": "\u041f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u043e\u043d \u0443\u0434\u0430\u043b\u0438\u0442\u0441\u044f \u0438 \u0438\u0437 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0438 \u0438\u0437 \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438. \u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c?",
|
||||
"Refresh": "\u041f\u043e\u0434\u043d\u043e\u0432\u0438\u0442\u044c",
|
||||
"RefreshQueued": "\u041f\u043e\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438."
|
||||
"RefreshQueued": "\u041f\u043e\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438.",
|
||||
"AddToCollection": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e",
|
||||
"NewCollection": "\u041d\u043e\u0432\u0430\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f",
|
||||
"LabelCollection": "\u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f:",
|
||||
"Help": "\u0421\u043f\u0440\u0430\u0432\u043a\u0430",
|
||||
"NewCollectionHelp": "\u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0431\u043e\u0441\u043e\u0431\u043b\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0431\u0440\u0430\u043d\u0438\u044f \u0444\u0438\u043b\u044c\u043c\u043e\u0432 \u0438 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438.",
|
||||
"SearchForCollectionInternetMetadata": "\u0418\u0441\u043a\u0430\u0442\u044c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435",
|
||||
"LabelName": "\u0418\u043c\u044f:",
|
||||
"NewCollectionNameExample": "\u041f\u0440\u0438\u043c\u0435\u0440: \u0417\u0432\u0451\u0437\u0434\u043d\u044b\u0435 \u0432\u043e\u0439\u043d\u044b (\u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f)",
|
||||
"MessageItemsAdded": "\u042d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b.",
|
||||
"OptionNew": "\u041d\u043e\u0432\u043e\u0435...",
|
||||
"LabelPlaylist": "\u041f\u043b\u0435\u0439-\u043b\u0438\u0441\u0442:",
|
||||
"AddToPlaylist": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043f\u043b\u0435\u0439-\u043b\u0438\u0441\u0442",
|
||||
"Subtitles": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u044b",
|
||||
"SearchForSubtitles": "\u041f\u043e\u0438\u0441\u043a \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043e\u0432",
|
||||
"LabelLanguage": "\u042f\u0437\u044b\u043a:",
|
||||
"Search": "\u041f\u043e\u0438\u0441\u043a",
|
||||
"NoSubtitleSearchResultsFound": "\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e.",
|
||||
"File": "\u0424\u0430\u0439\u043b",
|
||||
"MessageAreYouSureDeleteSubtitles": "\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0441\u0443\u0431\u0438\u0442\u0440\u043e\u0432?",
|
||||
"ConfirmDeletion": "\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f",
|
||||
"MySubtitles": "\u041c\u043e\u0438 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u044b",
|
||||
"MessageDownloadQueued": "\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438.",
|
||||
"EditSubtitles": "\u041f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u044b",
|
||||
"UnlockGuide": "\u0420\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043b\u0435\u0433\u0438\u0434",
|
||||
"RefreshMetadata": "Refresh Metadata",
|
||||
"ReplaceExistingImages": "Replace existing images",
|
||||
"ReplaceAllMetadata": "Replace all metadata",
|
||||
"SearchForMissingMetadata": "Search for missing metadata",
|
||||
"LabelRefreshMode": "Refresh mode:",
|
||||
"RefreshDialogHelp": "Metadata is refreshed based on settings and internet services that are enabled in the Emby Server dashboard."
|
||||
}
|
3
dashboard-ui/bower_components/emby-webcomponents/subtitleeditor/subtitleeditor.css
vendored
Normal file
3
dashboard-ui/bower_components/emby-webcomponents/subtitleeditor/subtitleeditor.css
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
.subtitleEditorDialog .originalFileLabel {
|
||||
margin-right: 1em;
|
||||
}
|
491
dashboard-ui/bower_components/emby-webcomponents/subtitleeditor/subtitleeditor.js
vendored
Normal file
491
dashboard-ui/bower_components/emby-webcomponents/subtitleeditor/subtitleeditor.js
vendored
Normal file
|
@ -0,0 +1,491 @@
|
|||
define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'scrollHelper', 'appStorage', 'connectionManager', 'loading', 'focusManager', 'emby-select', 'listViewStyle', 'paper-icon-button-light', 'css!./../formdialog', 'material-icons', 'css!./subtitleeditor', 'emby-button'], function (dialogHelper, require, layoutManager, globalize, scrollHelper, appStorage, connectionManager, loading, focusManager) {
|
||||
|
||||
var currentItem;
|
||||
var hasChanges;
|
||||
|
||||
function showLocalSubtitles(context, index) {
|
||||
|
||||
loading.show();
|
||||
|
||||
var subtitleContent = context.querySelector('.subtitleContent');
|
||||
subtitleContent.innerHTML = '';
|
||||
|
||||
var apiClient = connectionManager.getApiClient(currentItem.ServerId);
|
||||
var url = 'Videos/' + currentItem.Id + '/Subtitles/' + index;
|
||||
|
||||
apiClient.ajax({
|
||||
|
||||
type: 'GET',
|
||||
url: url
|
||||
|
||||
}).then(function (result) {
|
||||
|
||||
subtitleContent.innerHTML = result;
|
||||
|
||||
loading.hide();
|
||||
});
|
||||
}
|
||||
|
||||
function showRemoteSubtitles(context, id) {
|
||||
|
||||
loading.show();
|
||||
|
||||
var url = 'Providers/Subtitles/Subtitles/' + id;
|
||||
|
||||
ApiClient.get(ApiClient.getUrl(url)).then(function (result) {
|
||||
|
||||
// show result
|
||||
|
||||
loading.hide();
|
||||
});
|
||||
}
|
||||
|
||||
function downloadRemoteSubtitles(context, id) {
|
||||
|
||||
var url = 'Items/' + currentItem.Id + '/RemoteSearch/Subtitles/' + id;
|
||||
|
||||
var apiClient = connectionManager.getApiClient(currentItem.ServerId);
|
||||
apiClient.ajax({
|
||||
|
||||
type: "POST",
|
||||
url: apiClient.getUrl(url)
|
||||
|
||||
}).then(function () {
|
||||
|
||||
hasChanges = true;
|
||||
|
||||
require(['toast'], function (toast) {
|
||||
toast(globalize.translate('sharedcomponents#MessageDownloadQueued'));
|
||||
});
|
||||
|
||||
focusManager.autoFocus(context);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteLocalSubtitle(context, index) {
|
||||
|
||||
var msg = globalize.translate('sharedcomponents#MessageAreYouSureDeleteSubtitles');
|
||||
|
||||
require(['confirm'], function (confirm) {
|
||||
|
||||
confirm(msg, globalize.translate('sharedcomponents#ConfirmDeletion')).then(function () {
|
||||
|
||||
loading.show();
|
||||
|
||||
var itemId = currentItem.Id;
|
||||
var url = 'Videos/' + itemId + '/Subtitles/' + index;
|
||||
|
||||
var apiClient = connectionManager.getApiClient(currentItem.ServerId);
|
||||
|
||||
apiClient.ajax({
|
||||
|
||||
type: "DELETE",
|
||||
url: apiClient.getUrl(url)
|
||||
|
||||
}).then(function () {
|
||||
|
||||
hasChanges = true;
|
||||
reload(context, apiClient, itemId);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function fillSubtitleList(context, item) {
|
||||
|
||||
var streams = item.MediaStreams || [];
|
||||
|
||||
var subs = streams.filter(function (s) {
|
||||
|
||||
return s.Type == 'Subtitle';
|
||||
});
|
||||
|
||||
var html = '';
|
||||
|
||||
if (subs.length) {
|
||||
|
||||
html += '<h1>' + globalize.translate('sharedcomponents#MySubtitles') + '</h1>';
|
||||
|
||||
if (layoutManager.tv) {
|
||||
html += '<div class="paperList clear">';
|
||||
} else {
|
||||
html += '<div class="paperList">';
|
||||
}
|
||||
|
||||
html += subs.map(function (s) {
|
||||
|
||||
var itemHtml = '';
|
||||
|
||||
var tagName = layoutManager.tv ? 'button' : 'div';
|
||||
var className = layoutManager.tv && s.Path ? 'listItem btnDelete' : 'listItem';
|
||||
|
||||
itemHtml += '<' + tagName + ' class="' + className + '" data-index="' + s.Index + '">';
|
||||
|
||||
itemHtml += '<i class="listItemIcon md-icon">closed_caption</i>';
|
||||
|
||||
itemHtml += '<div class="listItemBody">';
|
||||
|
||||
itemHtml += '<h3 class="listItemBodyText">';
|
||||
itemHtml += s.DisplayTitle || '';
|
||||
itemHtml += '</h3>';
|
||||
|
||||
if (s.Path) {
|
||||
itemHtml += '<div class="secondary listItemBodyText">' + (s.Path) + '</div>';
|
||||
}
|
||||
|
||||
itemHtml += '</a>';
|
||||
itemHtml += '</div>';
|
||||
|
||||
if (!layoutManager.tv) {
|
||||
if (s.Path) {
|
||||
itemHtml += '<button is="paper-icon-button-light" data-index="' + s.Index + '" title="' + globalize.translate('sharedcomponents#Delete') + '" class="btnDelete"><i class="md-icon">delete</i></button>';
|
||||
}
|
||||
}
|
||||
|
||||
itemHtml += '</' + tagName + '>';
|
||||
|
||||
return itemHtml;
|
||||
|
||||
}).join('');
|
||||
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
var elem = context.querySelector('.subtitleList');
|
||||
|
||||
if (subs.length) {
|
||||
elem.classList.remove('hide');
|
||||
} else {
|
||||
elem.classList.add('hide');
|
||||
}
|
||||
elem.innerHTML = html;
|
||||
|
||||
//('.btnViewSubtitles', elem).on('click', function () {
|
||||
|
||||
// var index = this.getAttribute('data-index');
|
||||
|
||||
// showLocalSubtitles(context, index);
|
||||
|
||||
//});
|
||||
}
|
||||
|
||||
function fillLanguages(context, apiClient, languages) {
|
||||
|
||||
var selectLanguage = context.querySelector('#selectLanguage');
|
||||
|
||||
selectLanguage.innerHTML = languages.map(function (l) {
|
||||
|
||||
return '<option value="' + l.ThreeLetterISOLanguageName + '">' + l.DisplayName + '</option>';
|
||||
});
|
||||
|
||||
var lastLanguage = appStorage.getItem('subtitleeditor-language');
|
||||
if (lastLanguage) {
|
||||
selectLanguage.value = lastLanguage;
|
||||
}
|
||||
else {
|
||||
|
||||
apiClient.getCurrentUser().then(function (user) {
|
||||
|
||||
var lang = user.Configuration.SubtitleLanguagePreference;
|
||||
|
||||
if (lang) {
|
||||
selectLanguage.value = lang;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function renderSearchResults(context, results) {
|
||||
|
||||
var lastProvider = '';
|
||||
var html = '';
|
||||
|
||||
if (!results.length) {
|
||||
|
||||
context.querySelector('.noSearchResults').classList.remove('hide');
|
||||
context.querySelector('.subtitleResults').innerHTML = '';
|
||||
loading.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
context.querySelector('.noSearchResults').classList.add('hide');
|
||||
|
||||
for (var i = 0, length = results.length; i < length; i++) {
|
||||
|
||||
var result = results[i];
|
||||
|
||||
var provider = result.ProviderName;
|
||||
|
||||
if (provider != lastProvider) {
|
||||
|
||||
if (i > 0) {
|
||||
html += '</div>';
|
||||
}
|
||||
html += '<h1>' + provider + '</h1>';
|
||||
if (layoutManager.tv) {
|
||||
html += '<div class="paperList clear">';
|
||||
} else {
|
||||
html += '<div class="paperList">';
|
||||
}
|
||||
lastProvider = provider;
|
||||
}
|
||||
|
||||
var tagName = layoutManager.tv ? 'button' : 'div';
|
||||
var className = layoutManager.tv ? 'listItem btnOptions' : 'listItem';
|
||||
|
||||
html += '<' + tagName + ' class="' + className + '" data-subid="' + result.Id + '">';
|
||||
|
||||
html += '<i class="listItemIcon md-icon">closed_caption</i>';
|
||||
|
||||
html += '<div class="listItemBody">';
|
||||
|
||||
//html += '<a class="btnViewSubtitle" href="#" data-subid="' + result.Id + '">';
|
||||
|
||||
html += '<h3 class="listItemBodyText">' + (result.Name) + '</h3>';
|
||||
html += '<div class="secondary listItemBodyText">' + (result.Format) + '</div>';
|
||||
|
||||
if (result.Comment) {
|
||||
html += '<div class="secondary listItemBodyText">' + (result.Comment) + '</div>';
|
||||
}
|
||||
|
||||
//html += '</a>';
|
||||
|
||||
html += '</div>';
|
||||
|
||||
html += '<div class="secondary">' + /*(result.CommunityRating || 0) + ' / ' +*/ (result.DownloadCount || 0) + '</div>';
|
||||
|
||||
if (!layoutManager.tv) {
|
||||
html += '<button type="button" is="paper-icon-button-light" data-subid="' + result.Id + '" class="btnOptions"><i class="md-icon">more_vert</i></button>';
|
||||
}
|
||||
|
||||
html += '</' + tagName + '>';
|
||||
}
|
||||
|
||||
if (results.length) {
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
var elem = context.querySelector('.subtitleResults');
|
||||
elem.innerHTML = html;
|
||||
|
||||
//('.btnViewSubtitle', elem).on('click', function () {
|
||||
|
||||
// var id = this.getAttribute('data-subid');
|
||||
// showRemoteSubtitles(context, id);
|
||||
//});
|
||||
|
||||
loading.hide();
|
||||
}
|
||||
|
||||
function searchForSubtitles(context, language) {
|
||||
|
||||
appStorage.setItem('subtitleeditor-language', language);
|
||||
|
||||
loading.show();
|
||||
|
||||
var apiClient = connectionManager.getApiClient(currentItem.ServerId);
|
||||
var url = apiClient.getUrl('Items/' + currentItem.Id + '/RemoteSearch/Subtitles/' + language);
|
||||
|
||||
apiClient.getJSON(url).then(function (results) {
|
||||
|
||||
renderSearchResults(context, results);
|
||||
});
|
||||
}
|
||||
|
||||
function reload(context, apiClient, itemId) {
|
||||
|
||||
context.querySelector('.noSearchResults').classList.add('hide');
|
||||
|
||||
function onGetItem(item) {
|
||||
|
||||
currentItem = item;
|
||||
|
||||
fillSubtitleList(context, item);
|
||||
var file = item.Path || '';
|
||||
var index = Math.max(file.lastIndexOf('/'), file.lastIndexOf('\\'));
|
||||
if (index > -1) {
|
||||
file = file.substring(index + 1);
|
||||
}
|
||||
|
||||
if (file) {
|
||||
context.querySelector('.pathValue').innerHTML = file;
|
||||
context.querySelector('.originalFile').classList.remove('hide');
|
||||
} else {
|
||||
context.querySelector('.pathValue').innerHTML = '';
|
||||
context.querySelector('.originalFile').classList.add('hide');
|
||||
}
|
||||
|
||||
loading.hide();
|
||||
}
|
||||
|
||||
if (typeof itemId == 'string') {
|
||||
apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(onGetItem);
|
||||
}
|
||||
else {
|
||||
onGetItem(itemId);
|
||||
}
|
||||
}
|
||||
|
||||
function parentWithClass(elem, className) {
|
||||
|
||||
while (!elem.classList || !elem.classList.contains(className)) {
|
||||
elem = elem.parentNode;
|
||||
|
||||
if (!elem) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
function onSearchSubmit(e) {
|
||||
var form = this;
|
||||
|
||||
var lang = form.querySelector('#selectLanguage', form).value;
|
||||
|
||||
searchForSubtitles(parentWithClass(form, 'dialogContent'), lang);
|
||||
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
function onSubtitleListClick(e) {
|
||||
|
||||
var btnDelete = parentWithClass(e.target, 'btnDelete');
|
||||
if (btnDelete) {
|
||||
var index = btnDelete.getAttribute('data-index');
|
||||
var context = parentWithClass(btnDelete, 'subtitleEditorDialog');
|
||||
deleteLocalSubtitle(context, index);
|
||||
}
|
||||
}
|
||||
|
||||
function onSubtitleResultsClick(e) {
|
||||
|
||||
var btnOptions = parentWithClass(e.target, 'btnOptions');
|
||||
if (btnOptions) {
|
||||
var subtitleId = btnOptions.getAttribute('data-subid');
|
||||
var context = parentWithClass(btnOptions, 'subtitleEditorDialog');
|
||||
showDownloadOptions(btnOptions, context, subtitleId);
|
||||
}
|
||||
}
|
||||
|
||||
function showDownloadOptions(button, context, subtitleId) {
|
||||
|
||||
var items = [];
|
||||
|
||||
items.push({
|
||||
name: Globalize.translate('sharedcomponents#Download'),
|
||||
id: 'download'
|
||||
});
|
||||
|
||||
require(['actionsheet'], function (actionsheet) {
|
||||
|
||||
actionsheet.show({
|
||||
items: items,
|
||||
positionTo: button
|
||||
|
||||
}).then(function (id) {
|
||||
|
||||
switch (id) {
|
||||
|
||||
case 'download':
|
||||
downloadRemoteSubtitles(context, subtitleId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function showEditorInternal(itemId, serverId, template) {
|
||||
|
||||
hasChanges = false;
|
||||
|
||||
var apiClient = connectionManager.getApiClient(serverId);
|
||||
return apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) {
|
||||
|
||||
var dialogOptions = {
|
||||
removeOnClose: true
|
||||
};
|
||||
|
||||
if (layoutManager.tv) {
|
||||
dialogOptions.size = 'fullscreen';
|
||||
} else {
|
||||
dialogOptions.size = 'small';
|
||||
}
|
||||
|
||||
var dlg = dialogHelper.createDialog(dialogOptions);
|
||||
|
||||
dlg.classList.add('formDialog');
|
||||
dlg.classList.add('subtitleEditorDialog');
|
||||
|
||||
dlg.innerHTML = globalize.translateDocument(template, 'sharedcomponents');
|
||||
document.body.appendChild(dlg);
|
||||
|
||||
dlg.querySelector('.originalFileLabel').innerHTML = globalize.translate('sharedcomponents#File');
|
||||
|
||||
dlg.querySelector('.subtitleSearchForm').addEventListener('submit', onSearchSubmit);
|
||||
|
||||
var btnSubmit = dlg.querySelector('.btnSubmit');
|
||||
|
||||
if (layoutManager.tv) {
|
||||
scrollHelper.centerFocus.on(dlg.querySelector('.dialogContent'), false);
|
||||
dlg.querySelector('.btnSearchSubtitles').classList.add('hide');
|
||||
} else {
|
||||
btnSubmit.classList.add('hide');
|
||||
}
|
||||
|
||||
var editorContent = dlg.querySelector('.dialogContent');
|
||||
|
||||
dlg.querySelector('.subtitleList').addEventListener('click', onSubtitleListClick);
|
||||
dlg.querySelector('.subtitleResults').addEventListener('click', onSubtitleResultsClick);
|
||||
|
||||
apiClient.getCultures().then(function (languages) {
|
||||
|
||||
fillLanguages(editorContent, apiClient, languages);
|
||||
});
|
||||
|
||||
dlg.querySelector('.btnCancel').addEventListener('click', function () {
|
||||
|
||||
dialogHelper.close(dlg);
|
||||
});
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
dlg.addEventListener('close', function () {
|
||||
|
||||
if (hasChanges) {
|
||||
resolve();
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
|
||||
dialogHelper.open(dlg);
|
||||
|
||||
reload(editorContent, apiClient, item);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function showEditor(itemId, serverId) {
|
||||
|
||||
loading.show();
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
require(['text!./subtitleeditor.template.html'], function (template) {
|
||||
|
||||
showEditorInternal(itemId, serverId, template).then(resolve, reject);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
show: showEditor
|
||||
};
|
||||
});
|
28
dashboard-ui/bower_components/emby-webcomponents/subtitleeditor/subtitleeditor.template.html
vendored
Normal file
28
dashboard-ui/bower_components/emby-webcomponents/subtitleeditor/subtitleeditor.template.html
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
<div class="dialogHeader">
|
||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="md-icon">arrow_back</i></button>
|
||||
<div class="dialogHeaderTitle">${Subtitles}</div>
|
||||
</div>
|
||||
<div class="dialogContent smoothScrollY">
|
||||
<div class="dialogContentInner centeredContent">
|
||||
|
||||
<div class="subtitleList" style="margin-bottom:2em;"></div>
|
||||
<h1>${SearchForSubtitles}</h1>
|
||||
|
||||
<p style="margin: 1.5em 0;" class="originalFile"><span class="originalFileLabel dimText"></span><span class="pathValue"></span></p>
|
||||
|
||||
<form class="subtitleSearchForm" style="max-width: none;">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<div class="selectContainer" style="flex-grow: 1; margin-bottom: 0;">
|
||||
<select is="emby-select" id="selectLanguage" required="required" label="${LabelLanguage}"></select>
|
||||
</div>
|
||||
<button type="submit" is="paper-icon-button-light" title="${Search}" class="btnSearchSubtitles" style="flex-shrink: 0;"><i class="md-icon">search</i></button>
|
||||
</div>
|
||||
<button is="emby-button" type="submit" class="raised btnSubmit block">${Search}</button>
|
||||
</form>
|
||||
<br />
|
||||
<div class="subtitleResults"></div>
|
||||
<div class="noSearchResults hide">
|
||||
${NoSubtitleSearchResultsFound}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
26
dashboard-ui/bower_components/emby-webcomponents/toast/toast.css
vendored
Normal file
26
dashboard-ui/bower_components/emby-webcomponents/toast/toast.css
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
.toast {
|
||||
position: fixed;
|
||||
min-width: 288px;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
|
||||
border-radius: 2px;
|
||||
font-size: 14px;
|
||||
cursor: default;
|
||||
-webkit-transition: -webkit-transform .3s ease-out;
|
||||
transition: transform .3s ease-out;
|
||||
background: #303030;
|
||||
color: #fff;
|
||||
min-height: initial;
|
||||
padding: 1em 1.5em;
|
||||
bottom: 1em;
|
||||
left: 1em;
|
||||
font-size: 110%;
|
||||
z-index: 9999999;
|
||||
-webkit-transform: translateY(200px);
|
||||
transform: translateY(200px);
|
||||
}
|
||||
|
||||
.toast.visible {
|
||||
-webkit-transform: none;
|
||||
transform: none;
|
||||
}
|
|
@ -1,6 +1,21 @@
|
|||
define(['paper-toast'], function () {
|
||||
define(['css!./toast'], function () {
|
||||
|
||||
var toastId = 0;
|
||||
function remove(elem) {
|
||||
|
||||
setTimeout(function () {
|
||||
elem.parentNode.removeChild(elem);
|
||||
}, 300);
|
||||
}
|
||||
|
||||
function animateRemove(elem) {
|
||||
|
||||
setTimeout(function () {
|
||||
|
||||
elem.classList.remove('visible');
|
||||
remove(elem);
|
||||
|
||||
}, 3300);
|
||||
}
|
||||
|
||||
return function (options) {
|
||||
|
||||
|
@ -10,16 +25,17 @@ define(['paper-toast'], function () {
|
|||
};
|
||||
}
|
||||
|
||||
var elem = document.createElement("paper-toast");
|
||||
elem.setAttribute('text', options.text);
|
||||
elem.id = 'toast' + (toastId++);
|
||||
var elem = document.createElement("div");
|
||||
elem.classList.add('toast');
|
||||
elem.innerHTML = options.text;
|
||||
|
||||
document.body.appendChild(elem);
|
||||
|
||||
// This timeout is obviously messy but it's unclear how to determine when the webcomponent is ready for use
|
||||
// element onload never fires
|
||||
setTimeout(function () {
|
||||
elem.show();
|
||||
elem.classList.add('visible');
|
||||
|
||||
animateRemove(elem);
|
||||
|
||||
}, 300);
|
||||
};
|
||||
});
|
10
dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewcontainer-lite.css
vendored
Normal file
10
dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewcontainer-lite.css
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
.mainAnimatedPage {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
contain: layout style;
|
||||
/* Can't use will-change because it causes the alpha picker to move when the page scrolls*/
|
||||
/*will-change: transform;*/
|
||||
}
|
|
@ -1,17 +1,18 @@
|
|||
define(['browser'], function (browser) {
|
||||
define(['browser', 'css!./viewcontainer-lite'], function (browser) {
|
||||
|
||||
var allPages = document.querySelectorAll('.mainAnimatedPage');
|
||||
var mainAnimatedPages = document.querySelector('.mainAnimatedPages');
|
||||
var allPages = [];
|
||||
var currentUrls = [];
|
||||
var pageContainerCount = allPages.length;
|
||||
var allowAnimation = true;
|
||||
var pageContainerCount = 3;
|
||||
var selectedPageIndex = -1;
|
||||
|
||||
function enableAnimation() {
|
||||
|
||||
if (!allowAnimation) {
|
||||
if (browser.tv) {
|
||||
return false;
|
||||
}
|
||||
if (browser.tv) {
|
||||
|
||||
if (browser.operaTv) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -26,7 +27,7 @@ define(['browser'], function (browser) {
|
|||
|
||||
cancelActiveAnimations();
|
||||
|
||||
var selected = getSelectedIndex(allPages);
|
||||
var selected = selectedPageIndex;
|
||||
var previousAnimatable = selected == -1 ? null : allPages[selected];
|
||||
var pageIndex = selected + 1;
|
||||
|
||||
|
@ -35,23 +36,26 @@ define(['browser'], function (browser) {
|
|||
}
|
||||
|
||||
var view = document.createElement('div');
|
||||
view.classList.add('page-view');
|
||||
|
||||
if (options.type) {
|
||||
view.setAttribute('data-type', options.type);
|
||||
}
|
||||
view.innerHTML = options.view;
|
||||
|
||||
var animatable = allPages[pageIndex];
|
||||
var currentPage = allPages[pageIndex];
|
||||
var animatable = view;
|
||||
|
||||
var currentPage = animatable.querySelector('.page-view');
|
||||
view.classList.add('mainAnimatedPage');
|
||||
|
||||
if (currentPage) {
|
||||
triggerDestroy(currentPage);
|
||||
animatable.replaceChild(view, currentPage);
|
||||
mainAnimatedPages.replaceChild(view, currentPage);
|
||||
} else {
|
||||
animatable.appendChild(view);
|
||||
mainAnimatedPages.appendChild(view);
|
||||
}
|
||||
|
||||
allPages[pageIndex] = view;
|
||||
|
||||
if (onBeforeChange) {
|
||||
onBeforeChange(view, false, options);
|
||||
}
|
||||
|
@ -101,12 +105,6 @@ define(['browser'], function (browser) {
|
|||
}
|
||||
}
|
||||
|
||||
return nullAnimation(newAnimatedPage, oldAnimatedPage, transition, isBack);
|
||||
}
|
||||
|
||||
function nullAnimation(newAnimatedPage, oldAnimatedPage, transition, isBack) {
|
||||
|
||||
newAnimatedPage.classList.remove('hide');
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
|
@ -116,7 +114,8 @@ define(['browser'], function (browser) {
|
|||
var timings = {
|
||||
duration: 450,
|
||||
iterations: 1,
|
||||
easing: 'ease-out'
|
||||
easing: 'ease-out',
|
||||
fill: 'both'
|
||||
}
|
||||
|
||||
var animations = [];
|
||||
|
@ -132,8 +131,6 @@ define(['browser'], function (browser) {
|
|||
], timings));
|
||||
}
|
||||
|
||||
newAnimatedPage.classList.remove('hide');
|
||||
|
||||
var start = isBack ? '-100%' : '100%';
|
||||
|
||||
animations.push(newAnimatedPage.animate([
|
||||
|
@ -155,7 +152,8 @@ define(['browser'], function (browser) {
|
|||
var timings = {
|
||||
duration: 200,
|
||||
iterations: 1,
|
||||
easing: 'ease-out'
|
||||
easing: 'ease-out',
|
||||
fill: 'both'
|
||||
}
|
||||
|
||||
var animations = [];
|
||||
|
@ -169,8 +167,6 @@ define(['browser'], function (browser) {
|
|||
], timings));
|
||||
}
|
||||
|
||||
newAnimatedPage.classList.remove('hide');
|
||||
|
||||
animations.push(newAnimatedPage.animate([
|
||||
|
||||
{ opacity: 0, offset: 0 },
|
||||
|
@ -207,19 +203,15 @@ define(['browser'], function (browser) {
|
|||
onBeforeChange = fn;
|
||||
}
|
||||
|
||||
function getSelectedIndex(allPages) {
|
||||
|
||||
return selectedPageIndex;
|
||||
}
|
||||
|
||||
function tryRestoreView(options) {
|
||||
|
||||
var url = options.url;
|
||||
var index = currentUrls.indexOf(url);
|
||||
|
||||
if (index != -1) {
|
||||
var page = allPages[index];
|
||||
var view = page.querySelector(".page-view");
|
||||
|
||||
var animatable = allPages[index];
|
||||
var view = animatable;
|
||||
|
||||
if (view) {
|
||||
|
||||
|
@ -229,8 +221,7 @@ define(['browser'], function (browser) {
|
|||
|
||||
cancelActiveAnimations();
|
||||
|
||||
var animatable = allPages[index];
|
||||
var selected = getSelectedIndex(allPages);
|
||||
var selected = selectedPageIndex;
|
||||
var previousAnimatable = selected == -1 ? null : allPages[selected];
|
||||
|
||||
if (onBeforeChange) {
|
||||
|
@ -239,6 +230,8 @@ define(['browser'], function (browser) {
|
|||
|
||||
beforeAnimate(allPages, index, selected);
|
||||
|
||||
animatable.classList.remove('hide');
|
||||
|
||||
return animate(animatable, previousAnimatable, options.transition, options.isBack).then(function () {
|
||||
|
||||
selectedPageIndex = index;
|
||||
|
@ -259,7 +252,10 @@ define(['browser'], function (browser) {
|
|||
|
||||
function reset() {
|
||||
|
||||
allPages = [];
|
||||
currentUrls = [];
|
||||
mainAnimatedPages.innerHTML = '';
|
||||
selectedPageIndex = -1;
|
||||
}
|
||||
|
||||
if (enableAnimation() && !document.documentElement.animate) {
|
||||
|
|
|
@ -120,8 +120,8 @@ define(['viewcontainer', 'focusManager', 'queryString', 'connectionManager', 'ev
|
|||
|
||||
document.addEventListener('skinunload', resetCachedViews);
|
||||
|
||||
events.on(connectionManager, 'localusersignedin', resetCachedViews);
|
||||
events.on(connectionManager, 'localusersignedout', resetCachedViews);
|
||||
//events.on(connectionManager, 'localusersignedin', resetCachedViews);
|
||||
//events.on(connectionManager, 'localusersignedout', resetCachedViews);
|
||||
|
||||
function tryRestoreInternal(viewcontainer, options, resolve, reject) {
|
||||
|
||||
|
@ -176,6 +176,10 @@ define(['viewcontainer', 'focusManager', 'queryString', 'connectionManager', 'ev
|
|||
});
|
||||
};
|
||||
|
||||
self.currentView = function () {
|
||||
return currentView;
|
||||
};
|
||||
|
||||
self.dispatchPageEvents = function (value) {
|
||||
dispatchPageEvents = value;
|
||||
};
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
"spec"
|
||||
],
|
||||
"homepage": "https://github.com/Valve/fingerprintjs2",
|
||||
"version": "1.1.4",
|
||||
"_release": "1.1.4",
|
||||
"version": "1.4.0",
|
||||
"_release": "1.4.0",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.1.4",
|
||||
"commit": "ae5719db3d942a1a84ab43b707d4d1c34138934e"
|
||||
"tag": "1.4.0",
|
||||
"commit": "75cbd474158f8ecce43e00f198c76e486b896937"
|
||||
},
|
||||
"_source": "https://github.com/Valve/fingerprintjs2.git",
|
||||
"_target": "^1.1.3",
|
||||
|
|
|
@ -13,7 +13,7 @@ Include in the issue:
|
|||
* Include library call code (I need all options you used when calling the library function)
|
||||
|
||||
## Want to add a feature / contribute?
|
||||
|
||||
* Make sure the issue/suggestion does not exist by searching existing issues
|
||||
* Fork the project and make the required changes in it (don't forget to add specs)
|
||||
* PRs w/out specs will not be accepted
|
||||
* Run `gulp` to catch stylistic errors and produce the minified version.
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Fingerprintjs2 1.1.4 - Modern & flexible browser fingerprint library v2
|
||||
* Fingerprintjs2 1.4.0 - Modern & flexible browser fingerprint library v2
|
||||
* https://github.com/Valve/fingerprintjs2
|
||||
* Copyright (c) 2015 Valentin Vasilyev (valentin.vasilyev@outlook.com)
|
||||
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
|
||||
|
@ -84,6 +84,7 @@
|
|||
keys = this.userAgentKey(keys);
|
||||
keys = this.languageKey(keys);
|
||||
keys = this.colorDepthKey(keys);
|
||||
keys = this.pixelRatioKey(keys);
|
||||
keys = this.screenResolutionKey(keys);
|
||||
keys = this.availableScreenResolutionKey(keys);
|
||||
keys = this.timezoneOffsetKey(keys);
|
||||
|
@ -141,6 +142,15 @@
|
|||
}
|
||||
return keys;
|
||||
},
|
||||
pixelRatioKey: function(keys) {
|
||||
if(!this.options.excludePixelRatio) {
|
||||
keys.push({key: "pixel_ratio", value: this.getPixelRatio()});
|
||||
}
|
||||
return keys;
|
||||
},
|
||||
getPixelRatio: function() {
|
||||
return window.devicePixelRatio || "";
|
||||
},
|
||||
screenResolutionKey: function(keys) {
|
||||
if(!this.options.excludeScreenResolution) {
|
||||
return this.getScreenResolution(keys);
|
||||
|
@ -334,6 +344,57 @@
|
|||
// and if it doesn't match all 3 then that font is not available.
|
||||
var baseFonts = ["monospace", "sans-serif", "serif"];
|
||||
|
||||
var fontList = [
|
||||
"Andale Mono", "Arial", "Arial Black", "Arial Hebrew", "Arial MT", "Arial Narrow", "Arial Rounded MT Bold", "Arial Unicode MS",
|
||||
"Bitstream Vera Sans Mono", "Book Antiqua", "Bookman Old Style",
|
||||
"Calibri", "Cambria", "Cambria Math", "Century", "Century Gothic", "Century Schoolbook", "Comic Sans", "Comic Sans MS", "Consolas", "Courier", "Courier New",
|
||||
"Garamond", "Geneva", "Georgia",
|
||||
"Helvetica", "Helvetica Neue",
|
||||
"Impact",
|
||||
"Lucida Bright", "Lucida Calligraphy", "Lucida Console", "Lucida Fax", "LUCIDA GRANDE", "Lucida Handwriting", "Lucida Sans", "Lucida Sans Typewriter", "Lucida Sans Unicode",
|
||||
"Microsoft Sans Serif", "Monaco", "Monotype Corsiva", "MS Gothic", "MS Outlook", "MS PGothic", "MS Reference Sans Serif", "MS Sans Serif", "MS Serif", "MYRIAD", "MYRIAD PRO",
|
||||
"Palatino", "Palatino Linotype",
|
||||
"Segoe Print", "Segoe Script", "Segoe UI", "Segoe UI Light", "Segoe UI Semibold", "Segoe UI Symbol",
|
||||
"Tahoma", "Times", "Times New Roman", "Times New Roman PS", "Trebuchet MS",
|
||||
"Verdana", "Wingdings", "Wingdings 2", "Wingdings 3"
|
||||
];
|
||||
var extendedFontList = [
|
||||
"Abadi MT Condensed Light", "Academy Engraved LET", "ADOBE CASLON PRO", "Adobe Garamond", "ADOBE GARAMOND PRO", "Agency FB", "Aharoni", "Albertus Extra Bold", "Albertus Medium", "Algerian", "Amazone BT", "American Typewriter",
|
||||
"American Typewriter Condensed", "AmerType Md BT", "Andalus", "Angsana New", "AngsanaUPC", "Antique Olive", "Aparajita", "Apple Chancery", "Apple Color Emoji", "Apple SD Gothic Neo", "Arabic Typesetting", "ARCHER",
|
||||
"ARNO PRO", "Arrus BT", "Aurora Cn BT", "AvantGarde Bk BT", "AvantGarde Md BT", "AVENIR", "Ayuthaya", "Bandy", "Bangla Sangam MN", "Bank Gothic", "BankGothic Md BT", "Baskerville",
|
||||
"Baskerville Old Face", "Batang", "BatangChe", "Bauer Bodoni", "Bauhaus 93", "Bazooka", "Bell MT", "Bembo", "Benguiat Bk BT", "Berlin Sans FB", "Berlin Sans FB Demi", "Bernard MT Condensed", "BernhardFashion BT", "BernhardMod BT", "Big Caslon", "BinnerD",
|
||||
"Blackadder ITC", "BlairMdITC TT", "Bodoni 72", "Bodoni 72 Oldstyle", "Bodoni 72 Smallcaps", "Bodoni MT", "Bodoni MT Black", "Bodoni MT Condensed", "Bodoni MT Poster Compressed",
|
||||
"Bookshelf Symbol 7", "Boulder", "Bradley Hand", "Bradley Hand ITC", "Bremen Bd BT", "Britannic Bold", "Broadway", "Browallia New", "BrowalliaUPC", "Brush Script MT", "Californian FB", "Calisto MT", "Calligrapher", "Candara",
|
||||
"CaslonOpnface BT", "Castellar", "Centaur", "Cezanne", "CG Omega", "CG Times", "Chalkboard", "Chalkboard SE", "Chalkduster", "Charlesworth", "Charter Bd BT", "Charter BT", "Chaucer",
|
||||
"ChelthmITC Bk BT", "Chiller", "Clarendon", "Clarendon Condensed", "CloisterBlack BT", "Cochin", "Colonna MT", "Constantia", "Cooper Black", "Copperplate", "Copperplate Gothic", "Copperplate Gothic Bold",
|
||||
"Copperplate Gothic Light", "CopperplGoth Bd BT", "Corbel", "Cordia New", "CordiaUPC", "Cornerstone", "Coronet", "Cuckoo", "Curlz MT", "DaunPenh", "Dauphin", "David", "DB LCD Temp", "DELICIOUS", "Denmark",
|
||||
"DFKai-SB", "Didot", "DilleniaUPC", "DIN", "DokChampa", "Dotum", "DotumChe", "Ebrima", "Edwardian Script ITC", "Elephant", "English 111 Vivace BT", "Engravers MT", "EngraversGothic BT", "Eras Bold ITC", "Eras Demi ITC", "Eras Light ITC", "Eras Medium ITC",
|
||||
"EucrosiaUPC", "Euphemia", "Euphemia UCAS", "EUROSTILE", "Exotc350 Bd BT", "FangSong", "Felix Titling", "Fixedsys", "FONTIN", "Footlight MT Light", "Forte",
|
||||
"FrankRuehl", "Fransiscan", "Freefrm721 Blk BT", "FreesiaUPC", "Freestyle Script", "French Script MT", "FrnkGothITC Bk BT", "Fruitger", "FRUTIGER",
|
||||
"Futura", "Futura Bk BT", "Futura Lt BT", "Futura Md BT", "Futura ZBlk BT", "FuturaBlack BT", "Gabriola", "Galliard BT", "Gautami", "Geeza Pro", "Geometr231 BT", "Geometr231 Hv BT", "Geometr231 Lt BT", "GeoSlab 703 Lt BT",
|
||||
"GeoSlab 703 XBd BT", "Gigi", "Gill Sans", "Gill Sans MT", "Gill Sans MT Condensed", "Gill Sans MT Ext Condensed Bold", "Gill Sans Ultra Bold", "Gill Sans Ultra Bold Condensed", "Gisha", "Gloucester MT Extra Condensed", "GOTHAM", "GOTHAM BOLD",
|
||||
"Goudy Old Style", "Goudy Stout", "GoudyHandtooled BT", "GoudyOLSt BT", "Gujarati Sangam MN", "Gulim", "GulimChe", "Gungsuh", "GungsuhChe", "Gurmukhi MN", "Haettenschweiler", "Harlow Solid Italic", "Harrington", "Heather", "Heiti SC", "Heiti TC", "HELV",
|
||||
"Herald", "High Tower Text", "Hiragino Kaku Gothic ProN", "Hiragino Mincho ProN", "Hoefler Text", "Humanst 521 Cn BT", "Humanst521 BT", "Humanst521 Lt BT", "Imprint MT Shadow", "Incised901 Bd BT", "Incised901 BT",
|
||||
"Incised901 Lt BT", "INCONSOLATA", "Informal Roman", "Informal011 BT", "INTERSTATE", "IrisUPC", "Iskoola Pota", "JasmineUPC", "Jazz LET", "Jenson", "Jester", "Jokerman", "Juice ITC", "Kabel Bk BT", "Kabel Ult BT", "Kailasa", "KaiTi", "Kalinga", "Kannada Sangam MN",
|
||||
"Kartika", "Kaufmann Bd BT", "Kaufmann BT", "Khmer UI", "KodchiangUPC", "Kokila", "Korinna BT", "Kristen ITC", "Krungthep", "Kunstler Script", "Lao UI", "Latha", "Leelawadee", "Letter Gothic", "Levenim MT", "LilyUPC", "Lithograph", "Lithograph Light", "Long Island",
|
||||
"Lydian BT", "Magneto", "Maiandra GD", "Malayalam Sangam MN", "Malgun Gothic",
|
||||
"Mangal", "Marigold", "Marion", "Marker Felt", "Market", "Marlett", "Matisse ITC", "Matura MT Script Capitals", "Meiryo", "Meiryo UI", "Microsoft Himalaya", "Microsoft JhengHei", "Microsoft New Tai Lue", "Microsoft PhagsPa", "Microsoft Tai Le",
|
||||
"Microsoft Uighur", "Microsoft YaHei", "Microsoft Yi Baiti", "MingLiU", "MingLiU_HKSCS", "MingLiU_HKSCS-ExtB", "MingLiU-ExtB", "Minion", "Minion Pro", "Miriam", "Miriam Fixed", "Mistral", "Modern", "Modern No. 20", "Mona Lisa Solid ITC TT", "Mongolian Baiti",
|
||||
"MONO", "MoolBoran", "Mrs Eaves", "MS LineDraw", "MS Mincho", "MS PMincho", "MS Reference Specialty", "MS UI Gothic", "MT Extra", "MUSEO", "MV Boli",
|
||||
"Nadeem", "Narkisim", "NEVIS", "News Gothic", "News GothicMT", "NewsGoth BT", "Niagara Engraved", "Niagara Solid", "Noteworthy", "NSimSun", "Nyala", "OCR A Extended", "Old Century", "Old English Text MT", "Onyx", "Onyx BT", "OPTIMA", "Oriya Sangam MN",
|
||||
"OSAKA", "OzHandicraft BT", "Palace Script MT", "Papyrus", "Parchment", "Party LET", "Pegasus", "Perpetua", "Perpetua Titling MT", "PetitaBold", "Pickwick", "Plantagenet Cherokee", "Playbill", "PMingLiU", "PMingLiU-ExtB",
|
||||
"Poor Richard", "Poster", "PosterBodoni BT", "PRINCETOWN LET", "Pristina", "PTBarnum BT", "Pythagoras", "Raavi", "Rage Italic", "Ravie", "Ribbon131 Bd BT", "Rockwell", "Rockwell Condensed", "Rockwell Extra Bold", "Rod", "Roman", "Sakkal Majalla",
|
||||
"Santa Fe LET", "Savoye LET", "Sceptre", "Script", "Script MT Bold", "SCRIPTINA", "Serifa", "Serifa BT", "Serifa Th BT", "ShelleyVolante BT", "Sherwood",
|
||||
"Shonar Bangla", "Showcard Gothic", "Shruti", "Signboard", "SILKSCREEN", "SimHei", "Simplified Arabic", "Simplified Arabic Fixed", "SimSun", "SimSun-ExtB", "Sinhala Sangam MN", "Sketch Rockwell", "Skia", "Small Fonts", "Snap ITC", "Snell Roundhand", "Socket",
|
||||
"Souvenir Lt BT", "Staccato222 BT", "Steamer", "Stencil", "Storybook", "Styllo", "Subway", "Swis721 BlkEx BT", "Swiss911 XCm BT", "Sylfaen", "Synchro LET", "System", "Tamil Sangam MN", "Technical", "Teletype", "Telugu Sangam MN", "Tempus Sans ITC",
|
||||
"Terminal", "Thonburi", "Traditional Arabic", "Trajan", "TRAJAN PRO", "Tristan", "Tubular", "Tunga", "Tw Cen MT", "Tw Cen MT Condensed", "Tw Cen MT Condensed Extra Bold",
|
||||
"TypoUpright BT", "Unicorn", "Univers", "Univers CE 55 Medium", "Univers Condensed", "Utsaah", "Vagabond", "Vani", "Vijaya", "Viner Hand ITC", "VisualUI", "Vivaldi", "Vladimir Script", "Vrinda", "Westminster", "WHITNEY", "Wide Latin",
|
||||
"ZapfEllipt BT", "ZapfHumnst BT", "ZapfHumnst Dm BT", "Zapfino", "Zurich BlkEx BT", "Zurich Ex BT", "ZWAdobeF"];
|
||||
|
||||
if(that.options.extendedJsFonts) {
|
||||
fontList = fontList.concat(extendedFontList);
|
||||
}
|
||||
|
||||
//we use m or w because these two characters take up the maximum width.
|
||||
// And we use a LLi so that the same matching fonts can get separated
|
||||
var testString = "mmmmmmmmmmlli";
|
||||
|
@ -343,94 +404,106 @@
|
|||
|
||||
var h = document.getElementsByTagName("body")[0];
|
||||
|
||||
// create a SPAN in the document to get the width of the text we use to test
|
||||
var s = document.createElement("span");
|
||||
/*
|
||||
* We need this css as in some weird browser this
|
||||
* span elements shows up for a microSec which creates a
|
||||
* bad user experience
|
||||
*/
|
||||
s.style.position = "absolute";
|
||||
s.style.left = "-9999px";
|
||||
s.style.fontSize = testSize;
|
||||
s.innerHTML = testString;
|
||||
// div to load spans for the base fonts
|
||||
var baseFontsDiv = document.createElement("div");
|
||||
|
||||
// div to load spans for the fonts to detect
|
||||
var fontsDiv = document.createElement("div");
|
||||
|
||||
var defaultWidth = {};
|
||||
var defaultHeight = {};
|
||||
for (var index = 0, length = baseFonts.length; index < length; index++) {
|
||||
//get the default width for the three base fonts
|
||||
s.style.fontFamily = baseFonts[index];
|
||||
h.appendChild(s);
|
||||
defaultWidth[baseFonts[index]] = s.offsetWidth; //width for the default font
|
||||
defaultHeight[baseFonts[index]] = s.offsetHeight; //height for the defualt font
|
||||
h.removeChild(s);
|
||||
}
|
||||
var detect = function (font) {
|
||||
|
||||
// creates a span where the fonts will be loaded
|
||||
var createSpan = function() {
|
||||
var s = document.createElement("span");
|
||||
/*
|
||||
* We need this css as in some weird browser this
|
||||
* span elements shows up for a microSec which creates a
|
||||
* bad user experience
|
||||
*/
|
||||
s.style.position = "absolute";
|
||||
s.style.left = "-9999px";
|
||||
s.style.fontSize = testSize;
|
||||
s.innerHTML = testString;
|
||||
return s;
|
||||
};
|
||||
|
||||
// creates a span and load the font to detect and a base font for fallback
|
||||
var createSpanWithFonts = function(fontToDetect, baseFont) {
|
||||
var s = createSpan();
|
||||
s.style.fontFamily = "'" + fontToDetect + "'," + baseFont;
|
||||
return s;
|
||||
};
|
||||
|
||||
// creates spans for the base fonts and adds them to baseFontsDiv
|
||||
var initializeBaseFontsSpans = function() {
|
||||
var spans = [];
|
||||
for (var index = 0, length = baseFonts.length; index < length; index++) {
|
||||
var s = createSpan();
|
||||
s.style.fontFamily = baseFonts[index];
|
||||
baseFontsDiv.appendChild(s);
|
||||
spans.push(s);
|
||||
}
|
||||
return spans;
|
||||
};
|
||||
|
||||
// creates spans for the fonts to detect and adds them to fontsDiv
|
||||
var initializeFontsSpans = function() {
|
||||
var spans = {};
|
||||
for(var i = 0, l = fontList.length; i < l; i++) {
|
||||
var fontSpans = [];
|
||||
for(var j = 0, numDefaultFonts = baseFonts.length; j < numDefaultFonts; j++) {
|
||||
var s = createSpanWithFonts(fontList[i], baseFonts[j]);
|
||||
fontsDiv.appendChild(s);
|
||||
fontSpans.push(s);
|
||||
}
|
||||
spans[fontList[i]] = fontSpans; // Stores {fontName : [spans for that font]}
|
||||
}
|
||||
return spans;
|
||||
};
|
||||
|
||||
// checks if a font is available
|
||||
var isFontAvailable = function(fontSpans) {
|
||||
var detected = false;
|
||||
for (var index = 0, l = baseFonts.length; index < l; index++) {
|
||||
s.style.fontFamily = font + "," + baseFonts[index]; // name of the font along with the base font for fallback.
|
||||
h.appendChild(s);
|
||||
var matched = (s.offsetWidth !== defaultWidth[baseFonts[index]] || s.offsetHeight !== defaultHeight[baseFonts[index]]);
|
||||
h.removeChild(s);
|
||||
detected = detected || matched;
|
||||
for(var i = 0; i < baseFonts.length; i++) {
|
||||
detected = (fontSpans[i].offsetWidth !== defaultWidth[baseFonts[i]] || fontSpans[i].offsetHeight !== defaultHeight[baseFonts[i]]);
|
||||
if(detected) {
|
||||
return detected;
|
||||
}
|
||||
}
|
||||
return detected;
|
||||
};
|
||||
var fontList = [
|
||||
"Andale Mono", "Arial", "Arial Black", "Arial Hebrew", "Arial MT", "Arial Narrow", "Arial Rounded MT Bold", "Arial Unicode MS",
|
||||
"Bitstream Vera Sans Mono", "Book Antiqua", "Bookman Old Style",
|
||||
"Calibri", "Cambria", "Cambria Math", "Century", "Century Gothic", "Century Schoolbook", "Comic Sans", "Comic Sans MS", "Consolas", "Courier", "Courier New",
|
||||
"Garamond", "Geneva", "Georgia",
|
||||
"Helvetica", "Helvetica Neue",
|
||||
"Impact",
|
||||
"Lucida Bright", "Lucida Calligraphy", "Lucida Console", "Lucida Fax", "LUCIDA GRANDE", "Lucida Handwriting", "Lucida Sans", "Lucida Sans Typewriter", "Lucida Sans Unicode",
|
||||
"Microsoft Sans Serif", "Monaco", "Monotype Corsiva", "MS Gothic", "MS Outlook", "MS PGothic", "MS Reference Sans Serif", "MS Sans Serif", "MS Serif", "MYRIAD", "MYRIAD PRO",
|
||||
"Palatino", "Palatino Linotype",
|
||||
"Segoe Print", "Segoe Script", "Segoe UI", "Segoe UI Light", "Segoe UI Semibold", "Segoe UI Symbol",
|
||||
"Tahoma", "Times", "Times New Roman", "Times New Roman PS", "Trebuchet MS",
|
||||
"Verdana", "Wingdings", "Wingdings 2", "Wingdings 3"
|
||||
];
|
||||
var extendedFontList = [
|
||||
"Abadi MT Condensed Light", "Academy Engraved LET", "ADOBE CASLON PRO", "Adobe Garamond", "ADOBE GARAMOND PRO", "Agency FB", "Aharoni", "Albertus Extra Bold", "Albertus Medium", "Algerian", "Amazone BT", "American Typewriter",
|
||||
"American Typewriter Condensed", "AmerType Md BT", "Andalus", "Angsana New", "AngsanaUPC", "Antique Olive", "Aparajita", "Apple Chancery", "Apple Color Emoji", "Apple SD Gothic Neo", "Arabic Typesetting", "ARCHER",
|
||||
"ARNO PRO", "Arrus BT", "Aurora Cn BT", "AvantGarde Bk BT", "AvantGarde Md BT", "AVENIR", "Ayuthaya", "Bandy", "Bangla Sangam MN", "Bank Gothic", "BankGothic Md BT", "Baskerville",
|
||||
"Baskerville Old Face", "Batang", "BatangChe", "Bauer Bodoni", "Bauhaus 93", "Bazooka", "Bell MT", "Bembo", "Benguiat Bk BT", "Berlin Sans FB", "Berlin Sans FB Demi", "Bernard MT Condensed", "BernhardFashion BT", "BernhardMod BT", "Big Caslon", "BinnerD",
|
||||
"Blackadder ITC", "BlairMdITC TT", "Bodoni 72", "Bodoni 72 Oldstyle", "Bodoni 72 Smallcaps", "Bodoni MT", "Bodoni MT Black", "Bodoni MT Condensed", "Bodoni MT Poster Compressed",
|
||||
"Bookshelf Symbol 7", "Boulder", "Bradley Hand", "Bradley Hand ITC", "Bremen Bd BT", "Britannic Bold", "Broadway", "Browallia New", "BrowalliaUPC", "Brush Script MT", "Californian FB", "Calisto MT", "Calligrapher", "Candara",
|
||||
"CaslonOpnface BT", "Castellar", "Centaur", "Cezanne", "CG Omega", "CG Times", "Chalkboard", "Chalkboard SE", "Chalkduster", "Charlesworth", "Charter Bd BT", "Charter BT", "Chaucer",
|
||||
"ChelthmITC Bk BT", "Chiller", "Clarendon", "Clarendon Condensed", "CloisterBlack BT", "Cochin", "Colonna MT", "Constantia", "Cooper Black", "Copperplate", "Copperplate Gothic", "Copperplate Gothic Bold",
|
||||
"Copperplate Gothic Light", "CopperplGoth Bd BT", "Corbel", "Cordia New", "CordiaUPC", "Cornerstone", "Coronet", "Cuckoo", "Curlz MT", "DaunPenh", "Dauphin", "David", "DB LCD Temp", "DELICIOUS", "Denmark",
|
||||
"DFKai-SB", "Didot", "DilleniaUPC", "DIN", "DokChampa", "Dotum", "DotumChe", "Ebrima", "Edwardian Script ITC", "Elephant", "English 111 Vivace BT", "Engravers MT", "EngraversGothic BT", "Eras Bold ITC", "Eras Demi ITC", "Eras Light ITC", "Eras Medium ITC",
|
||||
"EucrosiaUPC", "Euphemia", "Euphemia UCAS", "EUROSTILE", "Exotc350 Bd BT", "FangSong", "Felix Titling", "Fixedsys", "FONTIN", "Footlight MT Light", "Forte",
|
||||
"FrankRuehl", "Fransiscan", "Freefrm721 Blk BT", "FreesiaUPC", "Freestyle Script", "French Script MT", "FrnkGothITC Bk BT", "Fruitger", "FRUTIGER",
|
||||
"Futura", "Futura Bk BT", "Futura Lt BT", "Futura Md BT", "Futura ZBlk BT", "FuturaBlack BT", "Gabriola", "Galliard BT", "Gautami", "Geeza Pro", "Geometr231 BT", "Geometr231 Hv BT", "Geometr231 Lt BT", "GeoSlab 703 Lt BT",
|
||||
"GeoSlab 703 XBd BT", "Gigi", "Gill Sans", "Gill Sans MT", "Gill Sans MT Condensed", "Gill Sans MT Ext Condensed Bold", "Gill Sans Ultra Bold", "Gill Sans Ultra Bold Condensed", "Gisha", "Gloucester MT Extra Condensed", "GOTHAM", "GOTHAM BOLD",
|
||||
"Goudy Old Style", "Goudy Stout", "GoudyHandtooled BT", "GoudyOLSt BT", "Gujarati Sangam MN", "Gulim", "GulimChe", "Gungsuh", "GungsuhChe", "Gurmukhi MN", "Haettenschweiler", "Harlow Solid Italic", "Harrington", "Heather", "Heiti SC", "Heiti TC", "HELV",
|
||||
"Herald", "High Tower Text", "Hiragino Kaku Gothic ProN", "Hiragino Mincho ProN", "Hoefler Text", "Humanst 521 Cn BT", "Humanst521 BT", "Humanst521 Lt BT", "Imprint MT Shadow", "Incised901 Bd BT", "Incised901 BT",
|
||||
"Incised901 Lt BT", "INCONSOLATA", "Informal Roman", "Informal011 BT", "INTERSTATE", "IrisUPC", "Iskoola Pota", "JasmineUPC", "Jazz LET", "Jenson", "Jester", "Jokerman", "Juice ITC", "Kabel Bk BT", "Kabel Ult BT", "Kailasa", "KaiTi", "Kalinga", "Kannada Sangam MN",
|
||||
"Kartika", "Kaufmann Bd BT", "Kaufmann BT", "Khmer UI", "KodchiangUPC", "Kokila", "Korinna BT", "Kristen ITC", "Krungthep", "Kunstler Script", "Lao UI", "Latha", "Leelawadee", "Letter Gothic", "Levenim MT", "LilyUPC", "Lithograph", "Lithograph Light", "Long Island",
|
||||
"Lydian BT", "Magneto", "Maiandra GD", "Malayalam Sangam MN", "Malgun Gothic",
|
||||
"Mangal", "Marigold", "Marion", "Marker Felt", "Market", "Marlett", "Matisse ITC", "Matura MT Script Capitals", "Meiryo", "Meiryo UI", "Microsoft Himalaya", "Microsoft JhengHei", "Microsoft New Tai Lue", "Microsoft PhagsPa", "Microsoft Tai Le",
|
||||
"Microsoft Uighur", "Microsoft YaHei", "Microsoft Yi Baiti", "MingLiU", "MingLiU_HKSCS", "MingLiU_HKSCS-ExtB", "MingLiU-ExtB", "Minion", "Minion Pro", "Miriam", "Miriam Fixed", "Mistral", "Modern", "Modern No. 20", "Mona Lisa Solid ITC TT", "Mongolian Baiti",
|
||||
"MONO", "MoolBoran", "Mrs Eaves", "MS LineDraw", "MS Mincho", "MS PMincho", "MS Reference Specialty", "MS UI Gothic", "MT Extra", "MUSEO", "MV Boli",
|
||||
"Nadeem", "Narkisim", "NEVIS", "News Gothic", "News GothicMT", "NewsGoth BT", "Niagara Engraved", "Niagara Solid", "Noteworthy", "NSimSun", "Nyala", "OCR A Extended", "Old Century", "Old English Text MT", "Onyx", "Onyx BT", "OPTIMA", "Oriya Sangam MN",
|
||||
"OSAKA", "OzHandicraft BT", "Palace Script MT", "Papyrus", "Parchment", "Party LET", "Pegasus", "Perpetua", "Perpetua Titling MT", "PetitaBold", "Pickwick", "Plantagenet Cherokee", "Playbill", "PMingLiU", "PMingLiU-ExtB",
|
||||
"Poor Richard", "Poster", "PosterBodoni BT", "PRINCETOWN LET", "Pristina", "PTBarnum BT", "Pythagoras", "Raavi", "Rage Italic", "Ravie", "Ribbon131 Bd BT", "Rockwell", "Rockwell Condensed", "Rockwell Extra Bold", "Rod", "Roman", "Sakkal Majalla",
|
||||
"Santa Fe LET", "Savoye LET", "Sceptre", "Script", "Script MT Bold", "SCRIPTINA", "Serifa", "Serifa BT", "Serifa Th BT", "ShelleyVolante BT", "Sherwood",
|
||||
"Shonar Bangla", "Showcard Gothic", "Shruti", "Signboard", "SILKSCREEN", "SimHei", "Simplified Arabic", "Simplified Arabic Fixed", "SimSun", "SimSun-ExtB", "Sinhala Sangam MN", "Sketch Rockwell", "Skia", "Small Fonts", "Snap ITC", "Snell Roundhand", "Socket",
|
||||
"Souvenir Lt BT", "Staccato222 BT", "Steamer", "Stencil", "Storybook", "Styllo", "Subway", "Swis721 BlkEx BT", "Swiss911 XCm BT", "Sylfaen", "Synchro LET", "System", "Tamil Sangam MN", "Technical", "Teletype", "Telugu Sangam MN", "Tempus Sans ITC",
|
||||
"Terminal", "Thonburi", "Traditional Arabic", "Trajan", "TRAJAN PRO", "Tristan", "Tubular", "Tunga", "Tw Cen MT", "Tw Cen MT Condensed", "Tw Cen MT Condensed Extra Bold",
|
||||
"TypoUpright BT", "Unicorn", "Univers", "Univers CE 55 Medium", "Univers Condensed", "Utsaah", "Vagabond", "Vani", "Vijaya", "Viner Hand ITC", "VisualUI", "Vivaldi", "Vladimir Script", "Vrinda", "Westminster", "WHITNEY", "Wide Latin",
|
||||
"ZapfEllipt BT", "ZapfHumnst BT", "ZapfHumnst Dm BT", "Zapfino", "Zurich BlkEx BT", "Zurich Ex BT", "ZWAdobeF"];
|
||||
|
||||
if(that.options.extendedJsFonts) {
|
||||
fontList = fontList.concat(extendedFontList);
|
||||
// create spans for base fonts
|
||||
var baseFontsSpans = initializeBaseFontsSpans();
|
||||
|
||||
// add the spans to the DOM
|
||||
h.appendChild(baseFontsDiv);
|
||||
|
||||
// get the default width for the three base fonts
|
||||
for (var index = 0, length = baseFonts.length; index < length; index++) {
|
||||
defaultWidth[baseFonts[index]] = baseFontsSpans[index].offsetWidth; // width for the default font
|
||||
defaultHeight[baseFonts[index]] = baseFontsSpans[index].offsetHeight; // height for the default font
|
||||
}
|
||||
|
||||
// create spans for fonts to detect
|
||||
var fontsSpans = initializeFontsSpans();
|
||||
|
||||
// add all the spans to the DOM
|
||||
h.appendChild(fontsDiv);
|
||||
|
||||
// check available fonts
|
||||
var available = [];
|
||||
for (var i = 0, l = fontList.length; i < l; i++) {
|
||||
if(detect(fontList[i])) {
|
||||
available.push(fontList[i]);
|
||||
}
|
||||
for(var i = 0, l = fontList.length; i < l; i++) {
|
||||
if(isFontAvailable(fontsSpans[fontList[i]])) {
|
||||
available.push(fontList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// remove spans from DOM
|
||||
h.removeChild(fontsDiv);
|
||||
h.removeChild(baseFontsDiv);
|
||||
|
||||
keys.push({key: "js_fonts", value: available});
|
||||
done(keys);
|
||||
}, 1);
|
||||
|
@ -616,7 +689,7 @@
|
|||
ctx.font = "11pt no-real-font-123";
|
||||
}
|
||||
ctx.fillText("Cwm fjordbank glyphs vext quiz, \ud83d\ude03", 2, 15);
|
||||
ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
|
||||
ctx.fillStyle = "rgba(102, 204, 0, 0.2)";
|
||||
ctx.font = "18pt Arial";
|
||||
ctx.fillText("Cwm fjordbank glyphs vext quiz, \ud83d\ude03", 4, 45);
|
||||
|
||||
|
@ -770,14 +843,18 @@
|
|||
},
|
||||
getAdBlock: function(){
|
||||
var ads = document.createElement("div");
|
||||
ads.setAttribute("id", "ads");
|
||||
ads.innerHTML = " ";
|
||||
ads.className = "adsbox";
|
||||
var result = false;
|
||||
try {
|
||||
// body may not exist, that's why we need try/catch
|
||||
document.body.appendChild(ads);
|
||||
return document.getElementById("ads") ? false : true;
|
||||
result = document.getElementsByClassName("adsbox")[0].offsetHeight === 0;
|
||||
document.body.removeChild(ads);
|
||||
} catch (e) {
|
||||
return false;
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
getHasLiedLanguages: function(){
|
||||
//We check if navigator.language is equal to the first language of navigator.languages
|
||||
|
@ -787,7 +864,7 @@
|
|||
if(firstLanguages !== navigator.language.substr(0, 2)){
|
||||
return true;
|
||||
}
|
||||
} catch(err){
|
||||
} catch(err) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1206,6 +1283,6 @@
|
|||
return ("00000000" + (h1[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h1[1] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[1] >>> 0).toString(16)).slice(-8);
|
||||
}
|
||||
};
|
||||
Fingerprint2.VERSION = "1.1.4";
|
||||
Fingerprint2.VERSION = "1.4.0";
|
||||
return Fingerprint2;
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "fingerprintjs2",
|
||||
"version": "1.1.4",
|
||||
"version": "1.4.0",
|
||||
"description": "Modern & flexible browser fingerprinting library",
|
||||
"main": "dist/fingerprint2.min.js",
|
||||
"devDependencies": {
|
||||
|
|
|
@ -71,6 +71,15 @@ describe("Fingerprint2", function () {
|
|||
});
|
||||
});
|
||||
|
||||
it("does not use pixelRatio when excluded", function (done) {
|
||||
var fp2 = new Fingerprint2({excludePixelRatio: true});
|
||||
spyOn(fp2, "getPixelRatio");
|
||||
fp2.get(function(result) {
|
||||
expect(fp2.getPixelRatio).not.toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("does not use screen resolution when excluded", function (done) {
|
||||
var fp2 = new Fingerprint2({excludeScreenResolution: true});
|
||||
spyOn(fp2, "getScreenResolution");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "hls.js",
|
||||
"version": "0.5.32",
|
||||
"version": "0.5.36",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
||||
"homepage": "https://github.com/dailymotion/hls.js",
|
||||
|
@ -16,11 +16,11 @@
|
|||
"test",
|
||||
"tests"
|
||||
],
|
||||
"_release": "0.5.32",
|
||||
"_release": "0.5.36",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.5.32",
|
||||
"commit": "bceb5b05fb906e6877e48778828378c05353d2b8"
|
||||
"tag": "v0.5.36",
|
||||
"commit": "a39814dc1e5be2516518a30edf9f1629e05dea27"
|
||||
},
|
||||
"_source": "git://github.com/dailymotion/hls.js.git",
|
||||
"_target": "~0.5.7",
|
||||
|
|
27
dashboard-ui/bower_components/hls.js/API.md
vendored
27
dashboard-ui/bower_components/hls.js/API.md
vendored
|
@ -474,6 +474,33 @@ whether or not to enable CEA-708 captions
|
|||
|
||||
parameter should be a boolean
|
||||
|
||||
#### ```abrEwmaFast```
|
||||
(default : 0.0)
|
||||
|
||||
Fast bitrate Exponential moving average half-life , used to compute average bitrate
|
||||
Half of the estimate is based on the last abrEwmaFast seconds of sample history.
|
||||
parameter should be a float greater than 0
|
||||
|
||||
#### ```abrEwmaSlow```
|
||||
(default : 0.0)
|
||||
|
||||
Slow bitrate Exponential moving average half-life , used to compute average bitrate
|
||||
Half of the estimate is based on the last abrEwmaFast seconds of sample history.
|
||||
parameter should be a float greater than abrEwmaFast
|
||||
|
||||
|
||||
#### ```abrBandWidthFactor```
|
||||
(default : 0.8)
|
||||
|
||||
scale factor to be applied against measured bandwidth average, to determine whether we can stay on current or lower quality level
|
||||
If ``` abrBandWidthFactor * bandwidth average < level.bitrate ``` then ABR can switch to that level providing that it is equal or less than current level
|
||||
|
||||
#### ```abrBandWidthUpFactor```
|
||||
(default : 0.7)
|
||||
|
||||
scale factor to be applied against measured bandwidth average, to determine whether we can switch up to a higher quality level
|
||||
If ``` abrBandWidthUpFactor * bandwidth average < level.bitrate ``` then ABR can switch up to that quality level
|
||||
|
||||
## Video Binding/Unbinding API
|
||||
|
||||
#### ```hls.attachMedia(videoElement)```
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "hls.js",
|
||||
"version": "0.5.32",
|
||||
"version": "0.5.36",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
||||
"homepage": "https://github.com/dailymotion/hls.js",
|
||||
|
|
|
@ -535,7 +535,7 @@
|
|||
ctx.fillStyle = "black";
|
||||
ctx.font = "15px Arial";
|
||||
legend = event.type;
|
||||
if (event.name) legend+= ':' + event.name;
|
||||
if (event.name !== undefined) legend+= ':' + event.name;
|
||||
ctx.fillText(legend,5,yoffset+15);
|
||||
|
||||
|
||||
|
|
528
dashboard-ui/bower_components/hls.js/dist/hls.js
vendored
528
dashboard-ui/bower_components/hls.js/dist/hls.js
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue