mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
commit
c9852fea56
734 changed files with 14033 additions and 38534 deletions
|
@ -1,4 +1,4 @@
|
|||
<div id="addPluginPage" data-role="page" class="page type-interior pluginConfigurationPage" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Plugins" data-require="emby-select,emby-collapse,registrationservices,scripts/ratingdialog,scripts/addpluginpage">
|
||||
<div id="addPluginPage" data-role="page" class="page type-interior pluginConfigurationPage" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Plugins" data-require="emby-select,emby-collapse">
|
||||
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
|
@ -27,7 +27,7 @@
|
|||
|
||||
<p id="btnInstallDiv" class="hide">
|
||||
<button is="emby-button" type="submit" id="btnInstall" class="raised button-submit block">
|
||||
<i class="md-icon">check</i><span>${Install}</span>
|
||||
<span>${Install}</span>
|
||||
</button>
|
||||
</p>
|
||||
<p id="nonServerMsg"></p>
|
||||
|
@ -65,7 +65,6 @@
|
|||
<input type="hidden" name="notify_url" value="https://mb3admin.com/admin/service/services/ppipn.php">
|
||||
<input type="hidden" name="return" id="paypalReturnUrl" value="#">
|
||||
<button is="emby-button" type="submit" id="ppButton" class="raised block button-submit" style="background-color: #179BD7;color:#fff;">
|
||||
<i class="md-icon">check</i>
|
||||
<span>${RegisterWithPayPal}</span>
|
||||
</button>
|
||||
|
||||
|
@ -78,14 +77,6 @@
|
|||
</div>
|
||||
<br />
|
||||
<div class="readOnlyContent">
|
||||
<div is="emby-collapse" title="${HeaderReviews}">
|
||||
<div class="collapseContent">
|
||||
<br />
|
||||
<div id="ratingLine"></div>
|
||||
<div id="latestReviews"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div is="emby-collapse" title="${HeaderDeveloperInfo}">
|
||||
<div class="collapseContent">
|
||||
<p id="developer"></p>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
<p>${AutoOrganizeHelp}</p>
|
||||
|
||||
<p>${AutoOrganizeTvHelp}</p>
|
||||
<div>
|
||||
<label class="checkboxContainer">
|
||||
<input type="checkbox" is="emby-checkbox" id="chkEnableTvSorting" />
|
||||
|
@ -19,7 +18,7 @@
|
|||
<input is="emby-input" id="txtWatchFolder" type="text" label="${LabelWatchFolder}" />
|
||||
<div class="fieldDescription">${LabelWatchFolderHelp}</div>
|
||||
</div>
|
||||
<button type="button" is="emby-button" id="btnSelectWatchFolder" title="${ButtonSelectDirectory}" class="autoSize"><i class="md-icon">search</i></button>
|
||||
<button type="button" is="paper-icon-button-light" id="btnSelectWatchFolder" title="${ButtonSelectDirectory}" class="autoSize"><i class="md-icon">search</i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
|
@ -35,8 +34,6 @@
|
|||
<div class="fieldDescription"></div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div is="emby-collapse" title="${HeaderEpisodeFilePattern}">
|
||||
<div class="collapseContent">
|
||||
<br />
|
||||
|
@ -157,7 +154,7 @@
|
|||
<div class="fieldDescription checkboxFieldDescription">${LabelDeleteEmptyFoldersHelp}</div>
|
||||
</div>
|
||||
<div>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block"><i class="md-icon">check</i><span>${ButtonSave}</span></button>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block"><span>${ButtonSave}</span></button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
|
35
dashboard-ui/bower_components/document-register-element/.bower.json
vendored
Normal file
35
dashboard-ui/bower_components/document-register-element/.bower.json
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "document-register-element",
|
||||
"description": "A stand-alone working lightweight version of the W3C Custom Elements specification",
|
||||
"main": "./build/document-register-element.js",
|
||||
"ignore": [
|
||||
"test",
|
||||
".jshintrc",
|
||||
".travis.yml",
|
||||
".TO_LOCALE.md",
|
||||
".gitignore",
|
||||
".gitmodules",
|
||||
".npmignore",
|
||||
"benchmark",
|
||||
"dom4",
|
||||
"ie8",
|
||||
"src",
|
||||
"template",
|
||||
"package.json",
|
||||
"index.html",
|
||||
"testrhino.js",
|
||||
"Makefile"
|
||||
],
|
||||
"homepage": "https://github.com/WebReflection/document-register-element",
|
||||
"version": "0.5.4",
|
||||
"_release": "0.5.4",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "0.5.4",
|
||||
"commit": "d1d0e80a1c8a0e3f9369280fca834e2cbac2ce6e"
|
||||
},
|
||||
"_source": "https://github.com/WebReflection/document-register-element.git",
|
||||
"_target": "^0.5.4",
|
||||
"_originalSource": "document-register-element",
|
||||
"_direct": true
|
||||
}
|
19
dashboard-ui/bower_components/document-register-element/LICENSE.txt
vendored
Normal file
19
dashboard-ui/bower_components/document-register-element/LICENSE.txt
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
Copyright (C) 2014-2015 by WebReflection
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
9
dashboard-ui/bower_components/document-register-element/RESOURCES.md
vendored
Normal file
9
dashboard-ui/bower_components/document-register-element/RESOURCES.md
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
# A list of resources related to Custom Elements and this polyfill
|
||||
|
||||
## Demo
|
||||
|
||||
* [Self contained Custom Elements via restyle()](http://webreflection.blogspot.co.uk/2014/08/self-contained-custom-elements-via.html) post and its cross browser [demo](https://webreflection.github.io/custom-element/)
|
||||
* [transform-3d](https://github.com/kentaromiura/transform-3d/) repo and [its demo](http://kentaromiura.github.io/transform-3d/)
|
||||
* comparison against Polymer and demos in [Why Web Components Are Ready For Production](http://developer.telerik.com/featured/web-components-ready-production/)
|
||||
* [W3C Specifications](http://w3c.github.io/webcomponents/spec/custom/)
|
||||
* [HTML5 Rocks Article](http://www.html5rocks.com/en/tutorials/webcomponents/customelements/) except for the Shadow DOM being completely different specification
|
12
dashboard-ui/bower_components/document-register-element/basic.html
vendored
Normal file
12
dashboard-ui/bower_components/document-register-element/basic.html
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>testing my-element</title>
|
||||
<script src="build/document-register-element.js"></script>
|
||||
<script src="test/my-element.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<my-element>
|
||||
some content
|
||||
</my-element>
|
||||
</body>
|
23
dashboard-ui/bower_components/document-register-element/bower.json
vendored
Normal file
23
dashboard-ui/bower_components/document-register-element/bower.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "document-register-element",
|
||||
"description": "A stand-alone working lightweight version of the W3C Custom Elements specification",
|
||||
"main": "./build/document-register-element.js",
|
||||
"ignore": [
|
||||
"test",
|
||||
".jshintrc",
|
||||
".travis.yml",
|
||||
".TO_LOCALE.md",
|
||||
".gitignore",
|
||||
".gitmodules",
|
||||
".npmignore",
|
||||
"benchmark",
|
||||
"dom4",
|
||||
"ie8",
|
||||
"src",
|
||||
"template",
|
||||
"package.json",
|
||||
"index.html",
|
||||
"testrhino.js",
|
||||
"Makefile"
|
||||
]
|
||||
}
|
2
dashboard-ui/bower_components/document-register-element/build/document-register-element.js
vendored
Normal file
2
dashboard-ui/bower_components/document-register-element/build/document-register-element.js
vendored
Normal file
File diff suppressed because one or more lines are too long
52
dashboard-ui/bower_components/document-register-element/testrunner.js
vendored
Normal file
52
dashboard-ui/bower_components/document-register-element/testrunner.js
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
console.log('Loading: test.html');
|
||||
var page = require('webpage').create();
|
||||
var url = 'index.html';
|
||||
page.open(url, function (status) {
|
||||
if (status === 'success') {
|
||||
setTimeout(function () {
|
||||
var results = page.evaluate(function() {
|
||||
// remove the first node with the total from the following counts
|
||||
var passed = Math.max(0, document.querySelectorAll('.pass').length - 1);
|
||||
return {
|
||||
// retrieve the total executed tests number
|
||||
total: ''.concat(
|
||||
passed,
|
||||
' blocks (',
|
||||
document.querySelector('#wru strong').textContent.replace(/\D/g, ''),
|
||||
' single tests)'
|
||||
),
|
||||
passed: passed,
|
||||
failed: Math.max(0, document.querySelectorAll('.fail').length - 1),
|
||||
failures: [].map.call(document.querySelectorAll('.fail'), function (node) {
|
||||
return node.textContent;
|
||||
}),
|
||||
errored: Math.max(0, document.querySelectorAll('.error').length - 1),
|
||||
errors: [].map.call(document.querySelectorAll('.error'), function (node) {
|
||||
return node.textContent;
|
||||
})
|
||||
};
|
||||
});
|
||||
console.log('- - - - - - - - - -');
|
||||
console.log('total: ' + results.total);
|
||||
console.log('- - - - - - - - - -');
|
||||
console.log('passed: ' + results.passed);
|
||||
if (results.failed) {
|
||||
console.log('failures: \n' + results.failures.join('\n'));
|
||||
} else {
|
||||
console.log('failed: ' + results.failed);
|
||||
}
|
||||
if (results.errored) {
|
||||
console.log('errors: \n' + results.errors.join('\n'));
|
||||
} else {
|
||||
console.log('errored: ' + results.errored);
|
||||
}
|
||||
console.log('- - - - - - - - - -');
|
||||
if (0 < results.failed + results.errored) {
|
||||
status = 'failed';
|
||||
}
|
||||
phantom.exit(0);
|
||||
}, 2000);
|
||||
} else {
|
||||
phantom.exit(1);
|
||||
}
|
||||
});
|
|
@ -16,12 +16,12 @@
|
|||
},
|
||||
"devDependencies": {},
|
||||
"ignore": [],
|
||||
"version": "1.1.79",
|
||||
"_release": "1.1.79",
|
||||
"version": "1.1.87",
|
||||
"_release": "1.1.87",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.1.79",
|
||||
"commit": "bec0b71fec80821578400743ad836ce1a05c0c00"
|
||||
"tag": "1.1.87",
|
||||
"commit": "21057764cdf82e9ef08514cca4e48c76d47e535f"
|
||||
},
|
||||
"_source": "https://github.com/MediaBrowser/Emby.ApiClient.Javascript.git",
|
||||
"_target": "^1.1.51",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['events'], function (events) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Creates a new api client instance
|
||||
|
@ -29,11 +30,11 @@
|
|||
|
||||
if (val != null) {
|
||||
|
||||
if (val.toLowerCase().indexOf('http') != 0) {
|
||||
if (val.toLowerCase().indexOf('http') !== 0) {
|
||||
throw new Error('Invalid url: ' + val);
|
||||
}
|
||||
|
||||
var changed = val != serverAddress;
|
||||
var changed = val !== serverAddress;
|
||||
|
||||
serverAddress = val;
|
||||
|
||||
|
@ -189,7 +190,7 @@
|
|||
|
||||
var headers = request.headers || {};
|
||||
|
||||
if (request.dataType == 'json') {
|
||||
if (request.dataType === 'json') {
|
||||
headers.accept = 'application/json';
|
||||
}
|
||||
|
||||
|
@ -274,16 +275,16 @@
|
|||
self.setRequestHeaders(request.headers);
|
||||
}
|
||||
|
||||
if (self.enableAutomaticNetworking === false || request.type != "GET") {
|
||||
if (self.enableAutomaticNetworking === false || request.type !== "GET") {
|
||||
console.log('Requesting url without automatic networking: ' + request.url);
|
||||
|
||||
return getFetchPromise(request).then(function (response) {
|
||||
|
||||
if (response.status < 400) {
|
||||
|
||||
if (request.dataType == 'json' || request.headers.accept == 'application/json') {
|
||||
if (request.dataType === 'json' || request.headers.accept === 'application/json') {
|
||||
return response.json();
|
||||
} else if (request.dataType == 'text' || (response.headers.get('Content-Type') || '').toLowerCase().indexOf('text/') == 0) {
|
||||
} else if (request.dataType === 'text' || (response.headers.get('Content-Type') || '').toLowerCase().indexOf('text/') === 0) {
|
||||
return response.text();
|
||||
} else {
|
||||
return response;
|
||||
|
@ -349,7 +350,7 @@
|
|||
|
||||
console.log("Attempting reconnection to " + url);
|
||||
|
||||
var timeout = connectionMode == MediaBrowser.ConnectionMode.Local ? 7000 : 15000;
|
||||
var timeout = connectionMode === MediaBrowser.ConnectionMode.Local ? 7000 : 15000;
|
||||
|
||||
fetchWithTimeout(url + "/system/info/public", {
|
||||
|
||||
|
@ -406,9 +407,9 @@
|
|||
|
||||
if (response.status < 400) {
|
||||
|
||||
if (request.dataType == 'json' || request.headers.accept == 'application/json') {
|
||||
if (request.dataType === 'json' || request.headers.accept === 'application/json') {
|
||||
return response.json();
|
||||
} else if (request.dataType == 'text' || (response.headers.get('Content-Type') || '').toLowerCase().indexOf('text/') == 0) {
|
||||
} else if (request.dataType === 'text' || (response.headers.get('Content-Type') || '').toLowerCase().indexOf('text/') === 0) {
|
||||
return response.text();
|
||||
} else {
|
||||
return response;
|
||||
|
@ -478,11 +479,11 @@
|
|||
throw new Error("serverAddress is yet not set");
|
||||
}
|
||||
var lowered = url.toLowerCase();
|
||||
if (lowered.indexOf('/emby') == -1 && lowered.indexOf('/mediabrowser') == -1) {
|
||||
if (lowered.indexOf('/emby') === -1 && lowered.indexOf('/mediabrowser') === -1) {
|
||||
url += '/emby';
|
||||
}
|
||||
|
||||
if (name.charAt(0) != '/') {
|
||||
if (name.charAt(0) !== '/') {
|
||||
url += '/';
|
||||
}
|
||||
|
||||
|
@ -535,7 +536,11 @@
|
|||
return;
|
||||
}
|
||||
|
||||
self.openWebSocket();
|
||||
try {
|
||||
self.openWebSocket();
|
||||
} catch (err) {
|
||||
console.log("Error opening web socket: " + err);
|
||||
}
|
||||
};
|
||||
|
||||
function replaceAll(originalString, strReplace, strWith) {
|
||||
|
@ -598,7 +603,7 @@
|
|||
else if (msg.MessageType === "UserUpdated" || msg.MessageType === "UserConfigurationUpdated") {
|
||||
|
||||
var user = msg.Data;
|
||||
if (user.Id == self.getCurrentUserId()) {
|
||||
if (user.Id === self.getCurrentUserId()) {
|
||||
|
||||
currentUser = null;
|
||||
}
|
||||
|
@ -670,13 +675,13 @@
|
|||
return self.getDownloadSpeed(1000000).then(function (bitrate) {
|
||||
|
||||
if (bitrate < 1000000) {
|
||||
return Math.round(bitrate * .8);
|
||||
return Math.round(bitrate * 0.8);
|
||||
} else {
|
||||
|
||||
// If that produced a fairly high speed, try again with a larger size to get a more accurate result
|
||||
return self.getDownloadSpeed(2400000).then(function (bitrate) {
|
||||
|
||||
return Math.round(bitrate * .8);
|
||||
return Math.round(bitrate * 0.8);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1735,7 +1740,7 @@
|
|||
* Adds a virtual folder
|
||||
* @param {String} name
|
||||
*/
|
||||
self.addVirtualFolder = function (name, type, refreshLibrary, initialPaths, libraryOptions) {
|
||||
self.addVirtualFolder = function (name, type, refreshLibrary, libraryOptions) {
|
||||
|
||||
if (!name) {
|
||||
throw new Error("null name");
|
||||
|
@ -1758,7 +1763,6 @@
|
|||
type: "POST",
|
||||
url: url,
|
||||
data: JSON.stringify({
|
||||
Paths: initialPaths,
|
||||
LibraryOptions: libraryOptions
|
||||
}),
|
||||
contentType: 'application/json'
|
||||
|
@ -1813,7 +1817,7 @@
|
|||
* Adds an additional mediaPath to an existing virtual folder
|
||||
* @param {String} name
|
||||
*/
|
||||
self.addMediaPath = function (virtualFolderName, mediaPath, refreshLibrary) {
|
||||
self.addMediaPath = function (virtualFolderName, mediaPath, networkSharePath, refreshLibrary) {
|
||||
|
||||
if (!virtualFolderName) {
|
||||
throw new Error("null virtualFolderName");
|
||||
|
@ -1825,15 +1829,50 @@
|
|||
|
||||
var url = "Library/VirtualFolders/Paths";
|
||||
|
||||
var pathInfo = {
|
||||
Path: mediaPath
|
||||
};
|
||||
if (networkSharePath) {
|
||||
pathInfo.NetworkPath = networkSharePath;
|
||||
}
|
||||
|
||||
url = self.getUrl(url, {
|
||||
refreshLibrary: refreshLibrary ? true : false,
|
||||
path: mediaPath,
|
||||
name: virtualFolderName
|
||||
refreshLibrary: refreshLibrary ? true : false
|
||||
});
|
||||
|
||||
return self.ajax({
|
||||
type: "POST",
|
||||
url: url
|
||||
url: url,
|
||||
data: JSON.stringify({
|
||||
Name: virtualFolderName,
|
||||
PathInfo: pathInfo
|
||||
}),
|
||||
contentType: 'application/json'
|
||||
});
|
||||
};
|
||||
|
||||
self.updateMediaPath = function (virtualFolderName, pathInfo) {
|
||||
|
||||
if (!virtualFolderName) {
|
||||
throw new Error("null virtualFolderName");
|
||||
}
|
||||
|
||||
if (!pathInfo) {
|
||||
throw new Error("null pathInfo");
|
||||
}
|
||||
|
||||
var url = "Library/VirtualFolders/Paths/Update";
|
||||
|
||||
url = self.getUrl(url);
|
||||
|
||||
return self.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
data: JSON.stringify({
|
||||
Name: virtualFolderName,
|
||||
PathInfo: pathInfo
|
||||
}),
|
||||
contentType: 'application/json'
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -2035,7 +2074,7 @@
|
|||
throw new Error("File must be an image.");
|
||||
}
|
||||
|
||||
if (file.type != "image/png" && file.type != "image/jpeg" && file.type != "image/jpeg") {
|
||||
if (file.type !== "image/png" && file.type !== "image/jpeg" && file.type !== "image/jpeg") {
|
||||
throw new Error("File must be an image.");
|
||||
}
|
||||
|
||||
|
@ -2092,7 +2131,7 @@
|
|||
throw new Error("File must be an image.");
|
||||
}
|
||||
|
||||
if (file.type != "image/png" && file.type != "image/jpeg" && file.type != "image/jpeg") {
|
||||
if (file.type !== "image/png" && file.type !== "image/jpeg" && file.type !== "image/jpeg") {
|
||||
throw new Error("File must be an image.");
|
||||
}
|
||||
|
||||
|
@ -2326,7 +2365,7 @@
|
|||
};
|
||||
|
||||
self.getDefaultImageQuality = function (imageType) {
|
||||
return imageType.toLowerCase() == 'backdrop' ? 80 : 90;
|
||||
return imageType.toLowerCase() === 'backdrop' ? 80 : 90;
|
||||
};
|
||||
|
||||
function normalizeImageOptions(options) {
|
||||
|
@ -2866,7 +2905,7 @@
|
|||
|
||||
var url;
|
||||
|
||||
if ((typeof userId).toString().toLowerCase() == 'string') {
|
||||
if ((typeof userId).toString().toLowerCase() === 'string') {
|
||||
url = self.getUrl("Users/" + userId + "/Items", options);
|
||||
} else {
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
var myStore = {};
|
||||
var cache;
|
||||
|
@ -11,7 +12,7 @@
|
|||
myStore.setItem = function (name, value) {
|
||||
|
||||
if (localData) {
|
||||
var changed = localData[name] != value;
|
||||
var changed = localData[name] !== value;
|
||||
|
||||
if (changed) {
|
||||
localData[name] = value;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
var myStore = {};
|
||||
var cache;
|
||||
|
@ -12,7 +13,7 @@
|
|||
localStorage.setItem(name, value);
|
||||
|
||||
if (localData) {
|
||||
var changed = localData[name] != value;
|
||||
var changed = localData[name] !== value;
|
||||
|
||||
if (changed) {
|
||||
localData[name] = value;
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function myStore(defaultObject) {
|
||||
function MyStore(defaultObject) {
|
||||
|
||||
this.localData = {};
|
||||
}
|
||||
|
||||
myStore.prototype.setItem = function (name, value) {
|
||||
MyStore.prototype.setItem = function (name, value) {
|
||||
this.localData[name] = value;
|
||||
};
|
||||
|
||||
myStore.prototype.getItem = function (name) {
|
||||
MyStore.prototype.getItem = function (name) {
|
||||
return this.localData[name];
|
||||
};
|
||||
|
||||
myStore.prototype.removeItem = function (name) {
|
||||
MyStore.prototype.removeItem = function (name) {
|
||||
this.localData[name] = null;
|
||||
};
|
||||
|
||||
return new myStore();
|
||||
return new MyStore();
|
||||
});
|
|
@ -1,4 +1,5 @@
|
|||
define(['events', 'apiclient', 'appStorage'], function (events, apiClientFactory, appStorage) {
|
||||
'use strict';
|
||||
|
||||
var ConnectionState = {
|
||||
Unavailable: 0,
|
||||
|
@ -83,7 +84,7 @@
|
|||
|
||||
var headers = request.headers || {};
|
||||
|
||||
if (request.dataType == 'json') {
|
||||
if (request.dataType === 'json') {
|
||||
headers.accept = 'application/json';
|
||||
}
|
||||
|
||||
|
@ -177,7 +178,7 @@
|
|||
|
||||
if (response.status < 400) {
|
||||
|
||||
if (request.dataType == 'json' || request.headers.accept == 'application/json') {
|
||||
if (request.dataType === 'json' || request.headers.accept === 'application/json') {
|
||||
return response.json();
|
||||
} else {
|
||||
return response;
|
||||
|
@ -215,7 +216,7 @@
|
|||
return connectUser;
|
||||
};
|
||||
|
||||
var minServerVersion = '3.0.5972';
|
||||
var minServerVersion = '3.0.5986';
|
||||
self.minServerVersion = function (val) {
|
||||
|
||||
if (val) {
|
||||
|
@ -256,7 +257,7 @@
|
|||
|
||||
return servers.filter(function (s) {
|
||||
|
||||
return s.Id == id;
|
||||
return s.Id === id;
|
||||
|
||||
})[0];
|
||||
};
|
||||
|
@ -402,7 +403,7 @@
|
|||
|
||||
var credentials = credentialProvider.credentials();
|
||||
var servers = credentials.Servers.filter(function (s) {
|
||||
return s.Id == result.ServerId;
|
||||
return s.Id === result.ServerId;
|
||||
});
|
||||
|
||||
var server = servers.length ? servers[0] : apiClient.serverInfo();
|
||||
|
@ -435,7 +436,7 @@
|
|||
var info = {
|
||||
Id: user.Id,
|
||||
IsSignedInOffline: true
|
||||
}
|
||||
};
|
||||
|
||||
credentialProvider.addOrUpdateUser(server, info);
|
||||
}
|
||||
|
@ -448,12 +449,9 @@
|
|||
}
|
||||
|
||||
if (options.enableWebSocket !== false) {
|
||||
if (!apiClient.isWebSocketOpenOrConnecting() && apiClient.isWebSocketSupported()) {
|
||||
console.log('calling apiClient.ensureWebSocket');
|
||||
|
||||
console.log('calling apiClient.openWebSocket');
|
||||
|
||||
apiClient.openWebSocket();
|
||||
}
|
||||
apiClient.ensureWebSocket();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -474,7 +472,7 @@
|
|||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
if (connectUser && connectUser.Id == credentials.ConnectUserId) {
|
||||
if (connectUser && connectUser.Id === credentials.ConnectUserId) {
|
||||
resolve();
|
||||
}
|
||||
|
||||
|
@ -537,12 +535,15 @@
|
|||
|
||||
url = getEmbyServerUrl(url, "Connect/Exchange?format=json&ConnectUserId=" + credentials.ConnectUserId);
|
||||
|
||||
var auth = 'MediaBrowser Client="' + appName + '", Device="' + deviceName + '", DeviceId="' + deviceId + '", Version="' + appVersion + '"';
|
||||
|
||||
return ajax({
|
||||
type: "GET",
|
||||
url: url,
|
||||
dataType: "json",
|
||||
headers: {
|
||||
"X-MediaBrowser-Token": server.ExchangeToken
|
||||
"X-MediaBrowser-Token": server.ExchangeToken,
|
||||
"X-Emby-Authorization": auth
|
||||
}
|
||||
|
||||
}).then(function (auth) {
|
||||
|
@ -707,7 +708,7 @@
|
|||
var credentials = credentialProvider.credentials();
|
||||
|
||||
var servers = credentials.Servers.filter(function (u) {
|
||||
return u.UserLinkType != "Guest";
|
||||
return u.UserLinkType !== "Guest";
|
||||
});
|
||||
|
||||
for (var j = 0, numServers = servers.length; j < numServers; j++) {
|
||||
|
@ -785,7 +786,7 @@
|
|||
Name: i.Name,
|
||||
RemoteAddress: i.Url,
|
||||
LocalAddress: i.LocalAddress,
|
||||
UserLinkType: (i.UserType || '').toLowerCase() == "guest" ? "Guest" : "LinkedUser"
|
||||
UserLinkType: (i.UserType || '').toLowerCase() === "guest" ? "Guest" : "LinkedUser"
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -849,7 +850,7 @@
|
|||
|
||||
return connectServers.filter(function (connectServer) {
|
||||
|
||||
return server.Id == connectServer.Id;
|
||||
return server.Id === connectServer.Id;
|
||||
|
||||
}).length > 0;
|
||||
});
|
||||
|
@ -924,11 +925,11 @@
|
|||
|
||||
console.log('Begin connectToServers, with ' + servers.length + ' servers');
|
||||
|
||||
if (servers.length == 1) {
|
||||
if (servers.length === 1) {
|
||||
|
||||
return self.connectToServer(servers[0], options).then(function (result) {
|
||||
|
||||
if (result.State == ConnectionState.Unavailable) {
|
||||
if (result.State === ConnectionState.Unavailable) {
|
||||
|
||||
result.State = result.ConnectUser == null ?
|
||||
ConnectionState.ConnectSignIn :
|
||||
|
@ -945,7 +946,7 @@
|
|||
if (firstServer) {
|
||||
return self.connectToServer(firstServer, options).then(function (result) {
|
||||
|
||||
if (result.State == ConnectionState.SignedIn) {
|
||||
if (result.State === ConnectionState.SignedIn) {
|
||||
|
||||
return result;
|
||||
|
||||
|
@ -992,9 +993,9 @@
|
|||
if (server.LastConnectionMode != null) {
|
||||
//tests.push(server.LastConnectionMode);
|
||||
}
|
||||
if (tests.indexOf(ConnectionMode.Manual) == -1) { tests.push(ConnectionMode.Manual); }
|
||||
if (tests.indexOf(ConnectionMode.Local) == -1) { tests.push(ConnectionMode.Local); }
|
||||
if (tests.indexOf(ConnectionMode.Remote) == -1) { tests.push(ConnectionMode.Remote); }
|
||||
if (tests.indexOf(ConnectionMode.Manual) === -1) { tests.push(ConnectionMode.Manual); }
|
||||
if (tests.indexOf(ConnectionMode.Local) === -1) { tests.push(ConnectionMode.Local); }
|
||||
if (tests.indexOf(ConnectionMode.Remote) === -1) { tests.push(ConnectionMode.Remote); }
|
||||
|
||||
//beginWakeServer(server);
|
||||
|
||||
|
@ -1007,7 +1008,7 @@
|
|||
|
||||
function stringEqualsIgnoreCase(str1, str2) {
|
||||
|
||||
return (str1 || '').toLowerCase() == (str2 || '').toLowerCase();
|
||||
return (str1 || '').toLowerCase() === (str2 || '').toLowerCase();
|
||||
}
|
||||
|
||||
function compareVersions(a, b) {
|
||||
|
@ -1049,7 +1050,7 @@
|
|||
var skipTest = false;
|
||||
var timeout = defaultTimeout;
|
||||
|
||||
if (mode == ConnectionMode.Local) {
|
||||
if (mode === ConnectionMode.Local) {
|
||||
|
||||
enableRetry = true;
|
||||
timeout = 8000;
|
||||
|
@ -1060,7 +1061,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
else if (mode == ConnectionMode.Manual) {
|
||||
else if (mode === ConnectionMode.Manual) {
|
||||
|
||||
if (stringEqualsIgnoreCase(address, server.LocalAddress)) {
|
||||
enableRetry = true;
|
||||
|
@ -1078,7 +1079,7 @@
|
|||
|
||||
tryConnect(address, timeout).then(function (result) {
|
||||
|
||||
if (compareVersions(self.minServerVersion(), result.Version) == 1) {
|
||||
if (compareVersions(self.minServerVersion(), result.Version) === 1) {
|
||||
|
||||
console.log('minServerVersion requirement not met. Server version: ' + result.Version);
|
||||
resolve({
|
||||
|
@ -1086,6 +1087,11 @@
|
|||
Servers: [server]
|
||||
});
|
||||
|
||||
} if (result.Id !== server.Id) {
|
||||
|
||||
// http request succeeded, but it's a different server than what was expected
|
||||
testNextConnectionMode(tests, index + 1, server, options, resolve);
|
||||
|
||||
} else {
|
||||
console.log('calling onSuccessfulConnection with connection mode ' + mode + ' with server ' + server.Name);
|
||||
onSuccessfulConnection(server, result, mode, options, resolve);
|
||||
|
@ -1178,7 +1184,7 @@
|
|||
result.Servers.push(server);
|
||||
result.ApiClient.updateServerInfo(server, connectionMode);
|
||||
|
||||
if (result.State == ConnectionState.SignedIn) {
|
||||
if (result.State === ConnectionState.SignedIn) {
|
||||
afterConnected(result.ApiClient, options);
|
||||
}
|
||||
|
||||
|
@ -1197,7 +1203,7 @@
|
|||
// attempt to correct bad input
|
||||
address = address.trim();
|
||||
|
||||
if (address.toLowerCase().indexOf('http') != 0) {
|
||||
if (address.toLowerCase().indexOf('http') !== 0) {
|
||||
address = "http://" + address;
|
||||
}
|
||||
|
||||
|
@ -1314,7 +1320,7 @@
|
|||
reject({ errorCode: 'passwordmatch' });
|
||||
return;
|
||||
}
|
||||
if (password != passwordConfirm) {
|
||||
if (password !== passwordConfirm) {
|
||||
reject({ errorCode: 'passwordmatch' });
|
||||
return;
|
||||
}
|
||||
|
@ -1406,7 +1412,7 @@
|
|||
var serverInfo = a.serverInfo();
|
||||
|
||||
// We have to keep this hack in here because of the addApiClient method
|
||||
return !serverInfo || serverInfo.Id == item;
|
||||
return !serverInfo || serverInfo.Id === item;
|
||||
|
||||
})[0];
|
||||
};
|
||||
|
@ -1443,7 +1449,7 @@
|
|||
}
|
||||
|
||||
var server = credentialProvider.credentials().Servers.filter(function (s) {
|
||||
return s.Id == serverId;
|
||||
return s.Id === serverId;
|
||||
});
|
||||
server = server.length ? server[0] : null;
|
||||
|
||||
|
@ -1453,7 +1459,7 @@
|
|||
var credentials = credentialProvider.credentials();
|
||||
|
||||
credentials.Servers = credentials.Servers.filter(function (s) {
|
||||
return s.Id != serverId;
|
||||
return s.Id !== serverId;
|
||||
});
|
||||
|
||||
credentialProvider.credentials(credentials);
|
||||
|
@ -1560,7 +1566,7 @@
|
|||
|
||||
console.log('getRegistrationInfo has cached info');
|
||||
|
||||
if (regInfo.deviceId == params.deviceId) {
|
||||
if (regInfo.deviceId === params.deviceId) {
|
||||
console.log('getRegistrationInfo returning cached info');
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
@ -1593,17 +1599,17 @@
|
|||
var status = response.status;
|
||||
console.log('getRegistrationInfo response: ' + status);
|
||||
|
||||
if (status == 200) {
|
||||
if (status === 200) {
|
||||
appStorage.setItem(cacheKey, JSON.stringify({
|
||||
lastValidDate: new Date().getTime(),
|
||||
deviceId: params.deviceId
|
||||
}));
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (status == 401) {
|
||||
if (status === 401) {
|
||||
return Promise.reject();
|
||||
}
|
||||
if (status == 403) {
|
||||
if (status === 403) {
|
||||
return Promise.reject('overlimit');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['events', 'appStorage'], function (events, appStorage) {
|
||||
'use strict';
|
||||
|
||||
return function (key) {
|
||||
|
||||
|
@ -57,7 +58,7 @@
|
|||
}
|
||||
|
||||
var existing = list.filter(function (s) {
|
||||
return s.Id == server.Id;
|
||||
return s.Id === server.Id;
|
||||
})[0];
|
||||
|
||||
if (existing) {
|
||||
|
@ -109,7 +110,7 @@
|
|||
server.Users = server.Users || [];
|
||||
|
||||
var existing = server.Users.filter(function (s) {
|
||||
return s.Id == user.Id;
|
||||
return s.Id === user.Id;
|
||||
})[0];
|
||||
|
||||
if (existing) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function getCallbacks(obj, name) {
|
||||
|
||||
|
@ -32,7 +33,7 @@
|
|||
var list = getCallbacks(obj, eventName);
|
||||
|
||||
var i = list.indexOf(fn);
|
||||
if (i != -1) {
|
||||
if (i !== -1) {
|
||||
list.splice(i, 1);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
return function () {
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function getLocalMediaSource(serverId, itemId) {
|
||||
return Promise.resolve(null);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function stringToArrayBuffer(string) {
|
||||
// UTF-16LE
|
||||
|
@ -79,7 +80,7 @@
|
|||
|
||||
console.log(info);
|
||||
|
||||
if (info != null && info.socketId == socketId) {
|
||||
if (info != null && info.socketId === socketId) {
|
||||
var json = arrayBufferToString(info.data);
|
||||
console.log('Server discovery json: ' + json);
|
||||
var server = JSON.parse(json);
|
||||
|
@ -119,7 +120,7 @@
|
|||
console.log('chrome.sockets.udp.bind');
|
||||
chrome.sockets.udp.bind(createInfo.socketId, '0.0.0.0', 0, function (bindResult) {
|
||||
|
||||
if (getResultCode(bindResult) != 0) {
|
||||
if (getResultCode(bindResult) !== 0) {
|
||||
console.log('bind fail: ' + bindResult);
|
||||
return;
|
||||
}
|
||||
|
@ -130,7 +131,7 @@
|
|||
|
||||
chrome.sockets.udp.send(createInfo.socketId, data, '255.255.255.255', port, function (sendResult) {
|
||||
|
||||
if (getResultCode(sendResult) != 0) {
|
||||
if (getResultCode(sendResult) !== 0) {
|
||||
console.log('send fail: ' + sendResult);
|
||||
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function listenerSession(resolve, timeoutMs) {
|
||||
|
||||
|
@ -78,7 +79,7 @@
|
|||
var stringLength = eventArguments.getDataReader().unconsumedBufferLength;
|
||||
var receivedMessage = eventArguments.getDataReader().readString(stringLength);
|
||||
|
||||
if (receivedMessage == stringToSend) {
|
||||
if (receivedMessage === stringToSend) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -97,7 +98,7 @@
|
|||
servers.push(server);
|
||||
|
||||
} catch (exception) {
|
||||
onError("Error receiving message: " + receivedMessage);
|
||||
onError("Error receiving message: " + exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
return {
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['localassetmanager'], function (localAssetManager) {
|
||||
'use strict';
|
||||
|
||||
return function (connectionManager) {
|
||||
|
||||
|
@ -43,9 +44,9 @@
|
|||
|
||||
return uploadHistory.FilesUploaded.filter(function (u) {
|
||||
|
||||
return getUploadId(file) == u.Id;
|
||||
return getUploadId(file) === u.Id;
|
||||
|
||||
}).length == 0;
|
||||
}).length === 0;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['localassetmanager'], function (LocalAssetManager) {
|
||||
'use strict';
|
||||
|
||||
return function () {
|
||||
|
||||
|
@ -248,55 +249,54 @@
|
|||
|
||||
// Just for now while media syncing gets worked out
|
||||
deferred.resolve();
|
||||
return;
|
||||
|
||||
var libraryItem = localItem.Item;
|
||||
//var libraryItem = localItem.Item;
|
||||
|
||||
var serverId = libraryItem.ServerId;
|
||||
var itemId = null;
|
||||
var imageTag = null;
|
||||
var imageType = "Primary";
|
||||
//var serverId = libraryItem.ServerId;
|
||||
//var itemId = null;
|
||||
//var imageTag = null;
|
||||
//var imageType = "Primary";
|
||||
|
||||
switch (index) {
|
||||
//switch (index) {
|
||||
|
||||
case 0:
|
||||
itemId = libraryItem.Id;
|
||||
imageType = "Primary";
|
||||
imageTag = (libraryItem.ImageTags || {})["Primary"];
|
||||
break;
|
||||
case 1:
|
||||
itemId = libraryItem.SeriesId;
|
||||
imageType = "Primary";
|
||||
imageTag = libraryItem.SeriesPrimaryImageTag;
|
||||
break;
|
||||
case 2:
|
||||
itemId = libraryItem.SeriesId;
|
||||
imageType = "Thumb";
|
||||
imageTag = libraryItem.SeriesPrimaryImageTag;
|
||||
break;
|
||||
case 3:
|
||||
itemId = libraryItem.AlbumId;
|
||||
imageType = "Primary";
|
||||
imageTag = libraryItem.AlbumPrimaryImageTag;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// case 0:
|
||||
// itemId = libraryItem.Id;
|
||||
// imageType = "Primary";
|
||||
// imageTag = (libraryItem.ImageTags || {})["Primary"];
|
||||
// break;
|
||||
// case 1:
|
||||
// itemId = libraryItem.SeriesId;
|
||||
// imageType = "Primary";
|
||||
// imageTag = libraryItem.SeriesPrimaryImageTag;
|
||||
// break;
|
||||
// case 2:
|
||||
// itemId = libraryItem.SeriesId;
|
||||
// imageType = "Thumb";
|
||||
// imageTag = libraryItem.SeriesPrimaryImageTag;
|
||||
// break;
|
||||
// case 3:
|
||||
// itemId = libraryItem.AlbumId;
|
||||
// imageType = "Primary";
|
||||
// imageTag = libraryItem.AlbumPrimaryImageTag;
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
//}
|
||||
|
||||
if (!itemId || !imageTag) {
|
||||
getNextImage(index + 1, apiClient, localItem, deferred);
|
||||
return;
|
||||
}
|
||||
//if (!itemId || !imageTag) {
|
||||
// getNextImage(index + 1, apiClient, localItem, deferred);
|
||||
// return;
|
||||
//}
|
||||
|
||||
downloadImage(apiClient, serverId, itemId, imageTag, imageType).then(function () {
|
||||
//downloadImage(apiClient, serverId, itemId, imageTag, imageType).then(function () {
|
||||
|
||||
// For the sake of simplicity, limit to one image
|
||||
deferred.resolve();
|
||||
return;
|
||||
// // For the sake of simplicity, limit to one image
|
||||
// deferred.resolve();
|
||||
// return;
|
||||
|
||||
getNextImage(index + 1, apiClient, localItem, deferred);
|
||||
// getNextImage(index + 1, apiClient, localItem, deferred);
|
||||
|
||||
}, getOnFail(deferred));
|
||||
//}, getOnFail(deferred));
|
||||
}
|
||||
|
||||
function downloadImage(apiClient, serverId, itemId, imageTag, imageType) {
|
||||
|
@ -340,7 +340,7 @@
|
|||
}
|
||||
|
||||
var files = jobItem.AdditionalFiles.filter(function (f) {
|
||||
return f.Type == 'Subtitles';
|
||||
return f.Type === 'Subtitles';
|
||||
});
|
||||
|
||||
var mediaSource = jobItem.Item.MediaSources[0];
|
||||
|
@ -375,7 +375,7 @@
|
|||
var deferred = DeferredBuilder.Deferred();
|
||||
|
||||
var subtitleStream = mediaSource.MediaStreams.filter(function (m) {
|
||||
return m.Type == 'Subtitle' && m.Index == file.Index;
|
||||
return m.Type === 'Subtitle' && m.Index === file.Index;
|
||||
})[0];
|
||||
|
||||
if (!subtitleStream) {
|
||||
|
@ -445,7 +445,7 @@
|
|||
|
||||
var userIdsWithAccess = syncDataResult.ItemUserAccess[itemId];
|
||||
|
||||
if (userIdsWithAccess.join(',') == savedUserIdsWithAccess.join(',')) {
|
||||
if (userIdsWithAccess.join(',') === savedUserIdsWithAccess.join(',')) {
|
||||
// Hasn't changed, nothing to do
|
||||
deferred.resolve();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['serversync'], function (ServerSync) {
|
||||
'use strict';
|
||||
|
||||
function syncNext(connectionManager, servers, index, options, resolve, reject) {
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['localassetmanager'], function (localAssetManager) {
|
||||
'use strict';
|
||||
|
||||
function syncNext(users, index, resolve, reject, apiClient, server) {
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
return function (connectionManager) {
|
||||
|
||||
|
@ -20,7 +21,7 @@
|
|||
|
||||
return connectionManager.connectToServer(server, connectionOptions).then(function (result) {
|
||||
|
||||
if (result.State == MediaBrowser.ConnectionState.SignedIn) {
|
||||
if (result.State === MediaBrowser.ConnectionState.SignedIn) {
|
||||
return performSync(server, options);
|
||||
} else {
|
||||
console.log('Unable to connect to server id: ' + server.Id);
|
||||
|
@ -42,7 +43,7 @@
|
|||
|
||||
var uploadPhotos = options.uploadPhotos !== false;
|
||||
|
||||
if (options.cameraUploadServers && options.cameraUploadServers.indexOf(server.Id) == -1) {
|
||||
if (options.cameraUploadServers && options.cameraUploadServers.indexOf(server.Id) === -1) {
|
||||
uploadPhotos = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function send(info) {
|
||||
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
},
|
||||
"devDependencies": {},
|
||||
"ignore": [],
|
||||
"version": "1.4.236",
|
||||
"_release": "1.4.236",
|
||||
"version": "1.4.299",
|
||||
"_release": "1.4.299",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.4.236",
|
||||
"commit": "d369818012719cb7fd38b052073428631937ae6f"
|
||||
"tag": "1.4.299",
|
||||
"commit": "7e708cf27aa74f7f0d0aaa30d95d3e1f09b71ce3"
|
||||
},
|
||||
"_source": "https://github.com/MediaBrowser/emby-webcomponents.git",
|
||||
"_target": "^1.2.1",
|
||||
|
|
|
@ -4,10 +4,21 @@
|
|||
padding: 0;
|
||||
border: none;
|
||||
max-height: 84%;
|
||||
border-radius: 1px !important;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.actionsheet-not-fullscreen {
|
||||
background-color: #2a2a2a;
|
||||
}
|
||||
|
||||
.actionSheetMenuItem:hover {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
.actionsheet-fullscreen {
|
||||
max-height: none;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.actionSheetContent-centered {
|
||||
|
@ -35,6 +46,8 @@
|
|||
font-weight: inherit;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.actionSheetMenuItem-noflex {
|
||||
|
@ -94,4 +107,4 @@
|
|||
position: fixed;
|
||||
top: .75em;
|
||||
left: .5em;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-button', 'css!./actionsheet', 'material-icons', 'scrollStyles'], function (dialogHelper, layoutManager, globalize, browser, dom) {
|
||||
'use strict';
|
||||
|
||||
function getOffsets(elems) {
|
||||
|
||||
|
@ -25,7 +26,9 @@
|
|||
|
||||
results[i] = {
|
||||
top: box.top,
|
||||
left: box.left
|
||||
left: box.left,
|
||||
width: box.width,
|
||||
height: box.height
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -44,11 +47,11 @@
|
|||
|
||||
var pos = getOffsets([options.positionTo])[0];
|
||||
|
||||
if (options.positionY != 'top') {
|
||||
pos.top += options.positionTo.offsetHeight / 2;
|
||||
if (options.positionY !== 'top') {
|
||||
pos.top += (pos.height || 0) / 2;
|
||||
}
|
||||
|
||||
pos.left += options.positionTo.offsetWidth / 2;
|
||||
pos.left += (pos.width || 0) / 2;
|
||||
|
||||
var height = dlg.offsetHeight || 300;
|
||||
var width = dlg.offsetWidth || 160;
|
||||
|
@ -119,6 +122,8 @@
|
|||
|
||||
if (isFullscreen) {
|
||||
dlg.classList.add('actionsheet-fullscreen');
|
||||
} else {
|
||||
dlg.classList.add('actionsheet-not-fullscreen');
|
||||
}
|
||||
|
||||
var extraSpacing = !layoutManager.tv;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['dialog', 'globalize'], function (dialog, globalize) {
|
||||
'use strict';
|
||||
|
||||
return function (text, title) {
|
||||
|
||||
|
@ -15,7 +16,7 @@ define(['dialog', 'globalize'], function (dialog, globalize) {
|
|||
var items = [];
|
||||
|
||||
items.push({
|
||||
name: globalize.translate('sharedcomponents#ButtonOk'),
|
||||
name: globalize.translate('sharedcomponents#ButtonGotIt'),
|
||||
id: 'ok',
|
||||
type: 'submit'
|
||||
});
|
||||
|
@ -23,7 +24,7 @@ define(['dialog', 'globalize'], function (dialog, globalize) {
|
|||
options.buttons = items;
|
||||
|
||||
return dialog(options).then(function (result) {
|
||||
if (result == 'ok') {
|
||||
if (result === 'ok') {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function replaceAll(str, find, replace) {
|
||||
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
define(['focusManager', 'css!./style.css', 'paper-icon-button-light', 'material-icons'], function (focusManager) {
|
||||
'use strict';
|
||||
|
||||
var selectedButtonClass = 'alphaPickerButton-selected';
|
||||
|
||||
function focus() {
|
||||
var selected = this.querySelector('.' + selectedButtonClass);
|
||||
var scope = this;
|
||||
var selected = scope.querySelector('.' + selectedButtonClass);
|
||||
|
||||
if (selected) {
|
||||
focusManager.focus(selected);
|
||||
} else {
|
||||
focusManager.autoFocus(this, true);
|
||||
focusManager.autoFocus(scope, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,11 +27,9 @@ define(['focusManager', 'css!./style.css', 'paper-icon-button-light', 'material-
|
|||
var letters;
|
||||
|
||||
html += '<div class="alphaPickerRow">';
|
||||
if (options.mode == 'keyboard') {
|
||||
if (options.mode === 'keyboard') {
|
||||
// space_bar icon
|
||||
html += '<button data-value=" " is="paper-icon-button-light" class="alphaPickerButton autoSize">\
|
||||
<i class="md-icon alphaPickerButtonIcon"></i>\
|
||||
</button>';
|
||||
html += '<button data-value=" " is="paper-icon-button-light" class="alphaPickerButton autoSize"><i class="md-icon alphaPickerButtonIcon"></i></button>';
|
||||
} else {
|
||||
letters = ['#'];
|
||||
html += letters.map(getLetterButton).join('');
|
||||
|
@ -38,11 +38,9 @@ define(['focusManager', 'css!./style.css', 'paper-icon-button-light', 'material-
|
|||
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') {
|
||||
if (options.mode === 'keyboard') {
|
||||
// backspace icon
|
||||
html += '<button data-value="backspace" is="paper-icon-button-light" class="alphaPickerButton autoSize">\
|
||||
<i class="md-icon alphaPickerButtonIcon"></i>\
|
||||
</button>';
|
||||
html += '<button data-value="backspace" is="paper-icon-button-light" class="alphaPickerButton autoSize"><i class="md-icon alphaPickerButtonIcon"></i></button>';
|
||||
html += '</div>';
|
||||
|
||||
letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
|
@ -60,7 +58,7 @@ define(['focusManager', 'css!./style.css', 'paper-icon-button-light', 'material-
|
|||
element.focus = focus;
|
||||
}
|
||||
|
||||
function alphaPicker(options) {
|
||||
function AlphaPicker(options) {
|
||||
|
||||
var self = this;
|
||||
|
||||
|
@ -83,7 +81,7 @@ define(['focusManager', 'css!./style.css', 'paper-icon-button-light', 'material-
|
|||
|
||||
alphaFocusTimeout = null;
|
||||
|
||||
if (document.activeElement == alphaFocusedElement) {
|
||||
if (document.activeElement === alphaFocusedElement) {
|
||||
var value = alphaFocusedElement.getAttribute('data-value');
|
||||
self.value(value, true);
|
||||
}
|
||||
|
@ -125,7 +123,7 @@ define(['focusManager', 'css!./style.css', 'paper-icon-button-light', 'material-
|
|||
if (alphaPickerButton) {
|
||||
var value = alphaPickerButton.getAttribute('data-value');
|
||||
|
||||
if (currentValue == value.toUpperCase()) {
|
||||
if (currentValue === value.toUpperCase()) {
|
||||
self.value(null, true);
|
||||
} else {
|
||||
self.value(value, true);
|
||||
|
@ -173,7 +171,7 @@ define(['focusManager', 'css!./style.css', 'paper-icon-button-light', 'material-
|
|||
itemsContainer.addEventListener('focus', onItemsFocusIn, true);
|
||||
}
|
||||
|
||||
if (options.mode == 'keyboard') {
|
||||
if (options.mode === 'keyboard') {
|
||||
element.addEventListener('click', onAlphaPickerInKeyboardModeClick);
|
||||
}
|
||||
|
||||
|
@ -225,14 +223,14 @@ define(['focusManager', 'css!./style.css', 'paper-icon-button-light', 'material-
|
|||
value = value.toUpperCase();
|
||||
currentValue = value;
|
||||
|
||||
if (options.mode != 'keyboard') {
|
||||
if (options.mode !== 'keyboard') {
|
||||
selected = element.querySelector('.' + selectedButtonClass);
|
||||
btn = element.querySelector('.alphaPickerButton[data-value=\'' + value + '\']');
|
||||
|
||||
if (btn && btn != selected) {
|
||||
if (btn && btn !== selected) {
|
||||
btn.classList.add(selectedButtonClass);
|
||||
}
|
||||
if (selected && selected != btn) {
|
||||
if (selected && selected !== btn) {
|
||||
selected.classList.remove(selectedButtonClass);
|
||||
}
|
||||
}
|
||||
|
@ -281,5 +279,5 @@ define(['focusManager', 'css!./style.css', 'paper-icon-button-light', 'material-
|
|||
self.visible(true);
|
||||
}
|
||||
|
||||
return alphaPicker;
|
||||
return AlphaPicker;
|
||||
});
|
|
@ -1,4 +1,5 @@
|
|||
define(['appStorage', 'events'], function (appStorage, events) {
|
||||
'use strict';
|
||||
|
||||
function getKey(name, userId) {
|
||||
|
||||
|
@ -9,7 +10,7 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
return name;
|
||||
}
|
||||
|
||||
return new function () {
|
||||
function AppSettings() {
|
||||
|
||||
var self = this;
|
||||
|
||||
|
@ -19,7 +20,7 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
self.set('enableAutoLogin', val.toString());
|
||||
}
|
||||
|
||||
return self.get('enableAutoLogin') != 'false';
|
||||
return self.get('enableAutoLogin') !== 'false';
|
||||
};
|
||||
|
||||
self.enableAutomaticBitrateDetection = function (val) {
|
||||
|
@ -28,7 +29,7 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
self.set('enableAutomaticBitrateDetection', val.toString());
|
||||
}
|
||||
|
||||
return self.get('enableAutomaticBitrateDetection') != 'false';
|
||||
return self.get('enableAutomaticBitrateDetection') !== 'false';
|
||||
};
|
||||
|
||||
self.maxStreamingBitrate = function (val) {
|
||||
|
@ -66,7 +67,7 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
self.set('syncOnlyOnWifi', val.toString());
|
||||
}
|
||||
|
||||
return self.get('syncOnlyOnWifi') != 'false';
|
||||
return self.get('syncOnlyOnWifi') !== 'false';
|
||||
};
|
||||
|
||||
self.syncPath = function (val) {
|
||||
|
@ -99,7 +100,7 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
|
||||
appStorage.setItem(getKey(name, userId), value);
|
||||
|
||||
if (currentValue != value) {
|
||||
if (currentValue !== value) {
|
||||
events.trigger(self, 'change', [name]);
|
||||
}
|
||||
};
|
||||
|
@ -108,5 +109,7 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
|
||||
return appStorage.getItem(getKey(name, userId));
|
||||
};
|
||||
}();
|
||||
}
|
||||
|
||||
return new AppSettings();
|
||||
});
|
|
@ -1,4 +1,5 @@
|
|||
define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style'], function (browser, connectionManager, playbackManager, dom) {
|
||||
'use strict';
|
||||
|
||||
function enableAnimation(elem) {
|
||||
|
||||
|
@ -18,7 +19,7 @@
|
|||
return true;
|
||||
}
|
||||
|
||||
function backdrop() {
|
||||
function Backdrop() {
|
||||
|
||||
var self = this;
|
||||
var isDestroyed;
|
||||
|
@ -52,7 +53,7 @@
|
|||
currentAnimation = animation;
|
||||
animation.onfinish = function () {
|
||||
|
||||
if (animation == currentAnimation) {
|
||||
if (animation === currentAnimation) {
|
||||
currentAnimation = null;
|
||||
}
|
||||
if (existingBackdropImage && existingBackdropImage.parentNode) {
|
||||
|
@ -166,14 +167,14 @@
|
|||
var elem = getBackdropContainer();
|
||||
var existingBackdropImage = elem.querySelector('.displayingBackdropImage');
|
||||
|
||||
if (existingBackdropImage && existingBackdropImage.getAttribute('data-url') == url) {
|
||||
if (existingBackdropImage.getAttribute('data-url') == url) {
|
||||
if (existingBackdropImage && existingBackdropImage.getAttribute('data-url') === url) {
|
||||
if (existingBackdropImage.getAttribute('data-url') === url) {
|
||||
return;
|
||||
}
|
||||
existingBackdropImage.classList.remove('displayingBackdropImage');
|
||||
}
|
||||
|
||||
var instance = new backdrop();
|
||||
var instance = new Backdrop();
|
||||
instance.load(url, elem, existingBackdropImage);
|
||||
currentLoadingBackdrop = instance;
|
||||
}
|
||||
|
@ -215,28 +216,38 @@
|
|||
|
||||
var list = [];
|
||||
|
||||
var onImg = function (img) {
|
||||
list.push(img);
|
||||
};
|
||||
|
||||
for (var i = 0, length = items.length; i < length; i++) {
|
||||
|
||||
var itemImages = getItemImageUrls(items[i]);
|
||||
|
||||
itemImages.forEach(function (img) {
|
||||
list.push(img);
|
||||
});
|
||||
itemImages.forEach(onImg);
|
||||
}
|
||||
|
||||
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 (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;
|
||||
if (a[i] !== b[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,27 +1,28 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function isTv() {
|
||||
|
||||
// This is going to be really difficult to get right
|
||||
var userAgent = navigator.userAgent.toLowerCase();
|
||||
|
||||
if (userAgent.indexOf('tv') != -1) {
|
||||
if (userAgent.indexOf('tv') !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userAgent.indexOf('samsungbrowser') != -1) {
|
||||
if (userAgent.indexOf('samsungbrowser') !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userAgent.indexOf('nintendo') != -1) {
|
||||
if (userAgent.indexOf('nintendo') !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userAgent.indexOf('viera') != -1) {
|
||||
if (userAgent.indexOf('viera') !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userAgent.indexOf('webos') != -1) {
|
||||
if (userAgent.indexOf('webos') !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -45,7 +46,7 @@
|
|||
var lower = userAgent.toLowerCase();
|
||||
|
||||
for (var i = 0, length = terms.length; i < length; i++) {
|
||||
if (lower.indexOf(terms[i]) != -1) {
|
||||
if (lower.indexOf(terms[i]) !== -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +88,34 @@
|
|||
}
|
||||
}
|
||||
|
||||
function hasKeyboard(browser) {
|
||||
|
||||
if (browser.touch) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (browser.xboxOne) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (browser.ps4) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (browser.edgeUwp) {
|
||||
// This is OK for now, but this won't always be true
|
||||
// Should we use this?
|
||||
// https://gist.github.com/wagonli/40d8a31bd0d6f0dd7a5d
|
||||
return true;
|
||||
}
|
||||
|
||||
if (browser.tv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var uaMatch = function (ua) {
|
||||
ua = ua.toLowerCase();
|
||||
|
||||
|
@ -100,6 +129,8 @@
|
|||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
|
||||
[];
|
||||
|
||||
var versionMatch = /(version)[ \/]([\w.]+)/.exec(ua);
|
||||
|
||||
var platform_match = /(ipad)/.exec(ua) ||
|
||||
/(iphone)/.exec(ua) ||
|
||||
/(android)/.exec(ua) ||
|
||||
|
@ -107,27 +138,41 @@
|
|||
|
||||
var browser = match[1] || "";
|
||||
|
||||
if (browser == "edge") {
|
||||
if (browser === "edge") {
|
||||
platform_match = [""];
|
||||
} else {
|
||||
if (ua.indexOf("windows phone") != -1 || ua.indexOf("iemobile") != -1) {
|
||||
if (ua.indexOf("windows phone") !== -1 || ua.indexOf("iemobile") !== -1) {
|
||||
|
||||
// http://www.neowin.net/news/ie11-fakes-user-agent-to-fool-gmail-in-windows-phone-81-gdr1-update
|
||||
browser = "msie";
|
||||
}
|
||||
else if (ua.indexOf("like gecko") != -1 && ua.indexOf('webkit') == -1 && ua.indexOf('opera') == -1 && ua.indexOf('chrome') == -1 && ua.indexOf('safari') == -1) {
|
||||
else if (ua.indexOf("like gecko") !== -1 && ua.indexOf('webkit') === -1 && ua.indexOf('opera') === -1 && ua.indexOf('chrome') === -1 && ua.indexOf('safari') === -1) {
|
||||
browser = "msie";
|
||||
}
|
||||
}
|
||||
|
||||
if (browser == 'opr') {
|
||||
if (browser === 'opr') {
|
||||
browser = 'opera';
|
||||
}
|
||||
|
||||
var version;
|
||||
if (versionMatch && versionMatch.length > 2) {
|
||||
version = versionMatch[2];
|
||||
}
|
||||
|
||||
version = version || match[2] || "0";
|
||||
|
||||
var versionMajor = parseInt(version.split('.')[0]);
|
||||
|
||||
if (isNaN(versionMajor)) {
|
||||
versionMajor = 0;
|
||||
}
|
||||
|
||||
return {
|
||||
browser: browser,
|
||||
version: match[2] || "0",
|
||||
platform: platform_match[0] || ""
|
||||
version: version,
|
||||
platform: platform_match[0] || "",
|
||||
versionMajor: versionMajor
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -138,17 +183,18 @@
|
|||
if (matched.browser) {
|
||||
browser[matched.browser] = true;
|
||||
browser.version = matched.version;
|
||||
browser.versionMajor = matched.versionMajor;
|
||||
}
|
||||
|
||||
if (matched.platform) {
|
||||
browser[matched.platform] = true;
|
||||
}
|
||||
|
||||
if (!browser.chrome && !browser.msie && !browser.edge && !browser.opera && userAgent.toLowerCase().indexOf("webkit") != -1) {
|
||||
if (!browser.chrome && !browser.msie && !browser.edge && !browser.opera && userAgent.toLowerCase().indexOf("webkit") !== -1) {
|
||||
browser.safari = true;
|
||||
}
|
||||
|
||||
if (userAgent.toLowerCase().indexOf("playstation 4") != -1) {
|
||||
if (userAgent.toLowerCase().indexOf("playstation 4") !== -1) {
|
||||
browser.ps4 = true;
|
||||
browser.tv = true;
|
||||
}
|
||||
|
@ -157,14 +203,14 @@
|
|||
browser.mobile = true;
|
||||
}
|
||||
|
||||
browser.xboxOne = userAgent.toLowerCase().indexOf('xbox') != -1;
|
||||
browser.xboxOne = userAgent.toLowerCase().indexOf('xbox') !== -1;
|
||||
browser.animate = document.documentElement.animate != null;
|
||||
browser.tizen = userAgent.toLowerCase().indexOf('tizen') != -1 || userAgent.toLowerCase().indexOf('smarthub') != -1;
|
||||
browser.web0s = userAgent.toLowerCase().indexOf('Web0S'.toLowerCase()) != -1;
|
||||
browser.edgeUwp = browser.edge && userAgent.toLowerCase().indexOf('msapphost') != -1;
|
||||
browser.tizen = userAgent.toLowerCase().indexOf('tizen') !== -1 || userAgent.toLowerCase().indexOf('smarthub') !== -1;
|
||||
browser.web0s = userAgent.toLowerCase().indexOf('Web0S'.toLowerCase()) !== -1;
|
||||
browser.edgeUwp = browser.edge && userAgent.toLowerCase().indexOf('msapphost') !== -1;
|
||||
|
||||
browser.tv = isTv();
|
||||
browser.operaTv = browser.tv && userAgent.toLowerCase().indexOf('opr/') != -1;
|
||||
browser.operaTv = browser.tv && userAgent.toLowerCase().indexOf('opr/') !== -1;
|
||||
|
||||
if (!isStyleSupported('display', 'flex')) {
|
||||
browser.noFlex = true;
|
||||
|
@ -178,5 +224,7 @@
|
|||
browser.touch = true;
|
||||
}
|
||||
|
||||
browser.keyboard = hasKeyboard(browser);
|
||||
|
||||
return browser;
|
||||
});
|
|
@ -1,4 +1,5 @@
|
|||
define(['browser'], function (browser) {
|
||||
'use strict';
|
||||
|
||||
function canPlayH264() {
|
||||
var v = document.createElement('video');
|
||||
|
@ -46,7 +47,7 @@ define(['browser'], function (browser) {
|
|||
}
|
||||
|
||||
function canPlayHlsWithMSE() {
|
||||
if (window.MediaSource != null && !browser.firefox) {
|
||||
if (window.MediaSource != null) {
|
||||
// text tracks don’t work with this in firefox
|
||||
return true;
|
||||
}
|
||||
|
@ -58,7 +59,7 @@ define(['browser'], function (browser) {
|
|||
|
||||
var typeString;
|
||||
|
||||
if (format == 'flac') {
|
||||
if (format === 'flac') {
|
||||
if (browser.tizen) {
|
||||
return true;
|
||||
}
|
||||
|
@ -67,7 +68,7 @@ define(['browser'], function (browser) {
|
|||
}
|
||||
}
|
||||
|
||||
else if (format == 'wma') {
|
||||
else if (format === 'wma') {
|
||||
if (browser.tizen) {
|
||||
return true;
|
||||
}
|
||||
|
@ -76,7 +77,7 @@ define(['browser'], function (browser) {
|
|||
}
|
||||
}
|
||||
|
||||
else if (format == 'opus') {
|
||||
else if (format === 'opus') {
|
||||
typeString = 'audio/ogg; codecs="opus"';
|
||||
|
||||
if (document.createElement('audio').canPlayType(typeString).replace(/no/, '')) {
|
||||
|
@ -86,7 +87,7 @@ define(['browser'], function (browser) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (format == 'webma') {
|
||||
if (format === 'webma') {
|
||||
typeString = 'audio/webm';
|
||||
} else {
|
||||
typeString = 'audio/' + format;
|
||||
|
@ -117,7 +118,7 @@ define(['browser'], function (browser) {
|
|||
}
|
||||
|
||||
// Filter out browsers based on chromium that don't support mkv
|
||||
if (userAgent.indexOf('vivaldi') != -1 || userAgent.indexOf('opera') != -1) {
|
||||
if (userAgent.indexOf('vivaldi') !== -1 || userAgent.indexOf('opera') !== -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -138,13 +139,14 @@ define(['browser'], function (browser) {
|
|||
|
||||
function testCanPlayTs() {
|
||||
|
||||
return browser.tizen || browser.web0s;
|
||||
return browser.tizen || browser.web0s || browser.edgeUwp;
|
||||
}
|
||||
|
||||
function getDirectPlayProfileForVideoContainer(container, videoAudioCodecs) {
|
||||
|
||||
var supported = false;
|
||||
var profileContainer = container;
|
||||
var videoCodecs = [];
|
||||
|
||||
switch (container) {
|
||||
|
||||
|
@ -153,7 +155,7 @@ define(['browser'], function (browser) {
|
|||
videoAudioCodecs = [];
|
||||
break;
|
||||
case 'avi':
|
||||
supported = browser.edgeUwp;
|
||||
supported = browser.tizen || browser.edgeUwp;
|
||||
break;
|
||||
case 'mpg':
|
||||
case 'mpeg':
|
||||
|
@ -169,16 +171,19 @@ define(['browser'], function (browser) {
|
|||
break;
|
||||
case 'mov':
|
||||
supported = browser.chrome || browser.edgeUwp;
|
||||
videoCodecs.push('h264');
|
||||
break;
|
||||
case 'm2ts':
|
||||
supported = browser.tizen || browser.web0s || browser.edgeUwp;
|
||||
videoCodecs.push('h264');
|
||||
break;
|
||||
case 'wmv':
|
||||
supported = browser.tizen || browser.web0s || browser.edgeUwp;
|
||||
videoAudioCodecs = [];
|
||||
break;
|
||||
case 'ts':
|
||||
supported = browser.tizen || browser.web0s || browser.edgeUwp;
|
||||
supported = testCanPlayTs();
|
||||
videoCodecs.push('h264');
|
||||
profileContainer = 'ts,mpegts';
|
||||
break;
|
||||
default:
|
||||
|
@ -192,6 +197,7 @@ define(['browser'], function (browser) {
|
|||
return {
|
||||
Container: profileContainer,
|
||||
Type: 'Video',
|
||||
VideoCodec: videoCodecs.join(','),
|
||||
AudioCodec: videoAudioCodecs.join(',')
|
||||
};
|
||||
}
|
||||
|
@ -199,7 +205,7 @@ define(['browser'], function (browser) {
|
|||
function getMaxBitrate() {
|
||||
|
||||
if (browser.edgeUwp) {
|
||||
return 15000000;
|
||||
return 30000000;
|
||||
}
|
||||
|
||||
// 10mbps
|
||||
|
@ -216,7 +222,7 @@ define(['browser'], function (browser) {
|
|||
if (browser.tizen) {
|
||||
|
||||
// 2015 models
|
||||
if (userAgent.indexOf('tizen 2.3') != -1) {
|
||||
if (userAgent.indexOf('tizen 2.3') !== -1) {
|
||||
return 20000000;
|
||||
}
|
||||
|
||||
|
@ -239,7 +245,6 @@ define(['browser'], function (browser) {
|
|||
var canPlayWebm = videoTestElement.canPlayType('video/webm').replace(/no/, '');
|
||||
|
||||
var canPlayMkv = testCanPlayMkv(videoTestElement);
|
||||
var canPlayTs = testCanPlayTs();
|
||||
|
||||
var profile = {};
|
||||
|
||||
|
@ -269,19 +274,20 @@ define(['browser'], function (browser) {
|
|||
}
|
||||
|
||||
var mp3Added = false;
|
||||
if (canPlayMkv || canPlayTs) {
|
||||
if (canPlayMkv) {
|
||||
if (supportsMp3VideoAudio) {
|
||||
mp3Added = true;
|
||||
videoAudioCodecs.push('mp3');
|
||||
hlsVideoAudioCodecs.push('mp3');
|
||||
}
|
||||
}
|
||||
if (videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.2"').replace(/no/, '')) {
|
||||
videoAudioCodecs.push('aac');
|
||||
hlsVideoAudioCodecs.push('aac');
|
||||
}
|
||||
if (!mp3Added && supportsMp3VideoAudio) {
|
||||
videoAudioCodecs.push('mp3');
|
||||
if (supportsMp3VideoAudio) {
|
||||
if (!mp3Added) {
|
||||
videoAudioCodecs.push('mp3');
|
||||
}
|
||||
hlsVideoAudioCodecs.push('mp3');
|
||||
}
|
||||
|
||||
|
@ -342,12 +348,12 @@ define(['browser'], function (browser) {
|
|||
['opus', 'mp3', 'aac', 'flac', 'webma', 'wma', 'wav'].filter(canPlayAudioFormat).forEach(function (audioFormat) {
|
||||
|
||||
profile.DirectPlayProfiles.push({
|
||||
Container: audioFormat == 'webma' ? 'webma,webm' : audioFormat,
|
||||
Container: audioFormat === 'webma' ? 'webma,webm' : audioFormat,
|
||||
Type: 'Audio'
|
||||
});
|
||||
|
||||
// aac also appears in the m4a container
|
||||
if (audioFormat == 'aac') {
|
||||
if (audioFormat === 'aac') {
|
||||
profile.DirectPlayProfiles.push({
|
||||
Container: 'm4a',
|
||||
AudioCodec: audioFormat,
|
||||
|
@ -389,7 +395,7 @@ define(['browser'], function (browser) {
|
|||
}
|
||||
|
||||
// Can't use mkv on mobile because we have to use the native player controls and they won't be able to seek it
|
||||
if (canPlayMkv && options.supportsCustomSeeking && !browser.tizen) {
|
||||
if (canPlayMkv && options.supportsCustomSeeking && !browser.tizen && options.enableMkvProgressive !== false) {
|
||||
profile.TranscodingProfiles.push({
|
||||
Container: 'mkv',
|
||||
Type: 'Video',
|
||||
|
@ -400,28 +406,15 @@ define(['browser'], function (browser) {
|
|||
});
|
||||
}
|
||||
|
||||
if (canPlayTs && options.supportsCustomSeeking && !browser.tizen && !browser.web0s) {
|
||||
profile.TranscodingProfiles.push({
|
||||
Container: 'ts',
|
||||
Type: 'Video',
|
||||
AudioCodec: videoAudioCodecs.join(','),
|
||||
VideoCodec: 'h264',
|
||||
Context: 'Streaming',
|
||||
CopyTimestamps: copyTimestamps,
|
||||
// If audio transcoding is needed, limit channels to number of physical audio channels
|
||||
// Trying to transcode to 5 channels when there are only 2 speakers generally does not sound good
|
||||
MaxAudioChannels: physicalAudioChannels.toString()
|
||||
});
|
||||
}
|
||||
|
||||
if (canPlayHls()) {
|
||||
if (canPlayHls() && options.enableHls !== false) {
|
||||
profile.TranscodingProfiles.push({
|
||||
Container: 'ts',
|
||||
Type: 'Video',
|
||||
AudioCodec: hlsVideoAudioCodecs.join(','),
|
||||
VideoCodec: 'h264',
|
||||
Context: 'Streaming',
|
||||
Protocol: 'hls'
|
||||
Protocol: 'hls',
|
||||
MaxAudioChannels: physicalAudioChannels.toString()
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -565,6 +558,15 @@ define(['browser'], function (browser) {
|
|||
}]
|
||||
});
|
||||
|
||||
if (!browser.edgeUwp && !browser.tizen && !browser.web0s) {
|
||||
profile.CodecProfiles[profile.CodecProfiles.length - 1].Conditions.push({
|
||||
Condition: 'NotEquals',
|
||||
Property: 'IsAVC',
|
||||
Value: 'false',
|
||||
IsRequired: false
|
||||
});
|
||||
}
|
||||
|
||||
profile.CodecProfiles.push({
|
||||
Type: 'Video',
|
||||
Codec: 'vpx',
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
button::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
-webkit-border-fit: border !important;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 0;
|
||||
font-size: inherit !important;
|
||||
|
@ -82,10 +91,14 @@
|
|||
transform: scale(1.16, 1.16);
|
||||
}
|
||||
|
||||
.cardBox-mobile {
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
@media all and (min-width: 600px) {
|
||||
|
||||
.cardBox-mobile {
|
||||
margin: 3px;
|
||||
margin: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,7 +160,7 @@
|
|||
|
||||
.cardImageContainer {
|
||||
/* Should be 0 with visualCardBox, but not really noticeable */
|
||||
border-radius: 2px;
|
||||
border-radius: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,6 +192,8 @@
|
|||
bottom: 0;
|
||||
/* Needed in case this is a button */
|
||||
display: block;
|
||||
/* Needed in safari */
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.cardImage {
|
||||
|
@ -192,6 +207,23 @@
|
|||
background-position: center bottom;
|
||||
}
|
||||
|
||||
.cardImage-img {
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
/* This is simply for lazy image purposes, to ensure the image is visible sooner when scrolling */
|
||||
min-height: 70%;
|
||||
min-width: 70%;
|
||||
align-self: flex-end;
|
||||
position: static;
|
||||
}
|
||||
|
||||
.coveredImage-img {
|
||||
max-height: none;
|
||||
max-width: none;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.coveredImage {
|
||||
background-size: 100% 100%;
|
||||
background-position: center center;
|
||||
|
@ -211,12 +243,8 @@
|
|||
}
|
||||
|
||||
.visualCardBox-cardFooter {
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
-moz-box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
-ms-box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
-webkit-box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
border-bottom-left-radius: 1px;
|
||||
border-bottom-right-radius: 1px;
|
||||
}
|
||||
|
||||
.innerCardFooter {
|
||||
|
@ -245,6 +273,11 @@
|
|||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: inherit;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.singleCardText {
|
||||
padding: .5em;
|
||||
}
|
||||
|
||||
.cardTextCentered {
|
||||
|
@ -259,8 +292,9 @@
|
|||
margin-right: 2em;
|
||||
}
|
||||
|
||||
.cardCenteredText {
|
||||
.cardDefaultText {
|
||||
white-space: normal;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.textActionButton {
|
||||
|
@ -315,15 +349,21 @@
|
|||
|
||||
.cardOverlayButton {
|
||||
color: #fff !important;
|
||||
background-color: rgba(0,0,0,.7) !important;
|
||||
background-color: rgba(0,0,0,.8) !important;
|
||||
border-radius: 500px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin: 0 .35em .5em 0;
|
||||
z-index: 1;
|
||||
/*opacity: 0;
|
||||
transition: opacity 0.5s ease-in; /* vendorless fallback */ */;
|
||||
}
|
||||
|
||||
/*.card:hover .cardOverlayButton {
|
||||
opacity: 1;
|
||||
}*/
|
||||
|
||||
.cardOverlayButton:hover {
|
||||
background-color: rgba(0,0,0,.9) !important;
|
||||
transition: background-color .5s ease-out;
|
||||
|
@ -375,7 +415,7 @@
|
|||
}
|
||||
|
||||
.overflowBackdropCard-scalable {
|
||||
width: 84%;
|
||||
width: 80%;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
|
@ -514,7 +554,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@media all and (min-width: 1600px) {
|
||||
|
||||
.portraitCard-scalable {
|
||||
|
@ -524,12 +563,27 @@
|
|||
.smallBackdropCard-scalable {
|
||||
width: 12.5%;
|
||||
}
|
||||
|
||||
.backdropCard-scalable {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.squareCard-scalable {
|
||||
width: 12.5%;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 1800px) {
|
||||
|
||||
.smallBackdropCard-scalable {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 1920px) {
|
||||
|
||||
.squareCard-scalable {
|
||||
width: 12.5%;
|
||||
width: 11.111111111111111111111111111111%;
|
||||
}
|
||||
|
||||
.smallBackdropCard-scalable {
|
||||
|
@ -539,10 +593,6 @@
|
|||
|
||||
@media all and (min-width: 2100px) {
|
||||
|
||||
.squareCard-scalable {
|
||||
width: 11.111111111111111111111111111111%;
|
||||
}
|
||||
|
||||
.backdropCard-scalable {
|
||||
width: 20%;
|
||||
}
|
||||
|
@ -582,6 +632,10 @@
|
|||
width: 16.66666666666666667%;
|
||||
}
|
||||
|
||||
.layout-tv .personCard-scalable {
|
||||
width: 14.285714285714285714285714285714%;
|
||||
|
||||
@media all and (min-width: 1600px) {
|
||||
|
||||
.layout-tv .backdropCard-scalable {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,5 @@
|
|||
define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager'], function (datetime, imageLoader, connectionManager, layoutManager) {
|
||||
'use strict';
|
||||
|
||||
function buildChapterCardsHtml(item, chapters, options) {
|
||||
|
||||
|
@ -6,7 +7,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager'], functi
|
|||
|
||||
var mediaStreams = ((item.MediaSources || [])[0] || {}).MediaStreams || [];
|
||||
var videoStream = mediaStreams.filter(function (i) {
|
||||
return i.Type == 'Video';
|
||||
return i.Type === 'Video';
|
||||
})[0] || {};
|
||||
|
||||
var shape = (options.backdropShape || 'backdrop');
|
||||
|
@ -32,7 +33,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager'], functi
|
|||
|
||||
for (var i = 0, length = chapters.length; i < length; i++) {
|
||||
|
||||
if (options.rows && itemsInRow == 0) {
|
||||
if (options.rows && itemsInRow === 0) {
|
||||
html += '<div class="cardColumn">';
|
||||
}
|
||||
|
||||
|
@ -91,22 +92,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager'], functi
|
|||
cardBoxCssClass += ' cardBox-focustransform';
|
||||
}
|
||||
|
||||
var html = '\
|
||||
<button type="button" class="' + className + '"' + dataAttributes + '> \
|
||||
<div class="' + cardBoxCssClass + '">\
|
||||
<div class="cardScalable">\
|
||||
<div class="cardPadder-'+ shape + '"></div>\
|
||||
<div class="cardContent">\
|
||||
' + cardImageContainer + '\
|
||||
</div>\
|
||||
<div class="innerCardFooter">\
|
||||
' + nameHtml + '\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</button>'
|
||||
;
|
||||
var html = '<button type="button" class="' + className + '"' + dataAttributes + '><div class="' + cardBoxCssClass + '"><div class="cardScalable"><div class="cardPadder-' + shape + '"></div><div class="cardContent">' + cardImageContainer + '</div><div class="innerCardFooter">' + nameHtml + '</div></div></div></div></button>';
|
||||
|
||||
return html;
|
||||
}
|
||||
|
|
|
@ -1,133 +1,17 @@
|
|||
define(['imageLoader', 'itemShortcuts', 'connectionManager', 'layoutManager'], function (imageLoader, itemShortcuts, connectionManager, layoutManager) {
|
||||
|
||||
function buildPeopleCardsHtml(people, options) {
|
||||
|
||||
var className = 'card ' + (options.shape || 'portrait') + 'Card personCard';
|
||||
|
||||
if (options.block || options.rows) {
|
||||
className += ' block';
|
||||
}
|
||||
|
||||
var html = '';
|
||||
var itemsInRow = 0;
|
||||
|
||||
var serverId = options.serverId;
|
||||
var apiClient = connectionManager.getApiClient(serverId);
|
||||
|
||||
for (var i = 0, length = people.length; i < length; i++) {
|
||||
|
||||
if (options.rows && itemsInRow == 0) {
|
||||
html += '<div class="cardColumn">';
|
||||
}
|
||||
|
||||
var person = people[i];
|
||||
|
||||
html += buildPersonCard(person, apiClient, serverId, options, className);
|
||||
itemsInRow++;
|
||||
|
||||
if (options.rows && itemsInRow >= options.rows) {
|
||||
itemsInRow = 0;
|
||||
html += '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function getImgUrl(person, maxWidth, apiClient) {
|
||||
|
||||
if (person.PrimaryImageTag) {
|
||||
|
||||
return apiClient.getScaledImageUrl(person.Id, {
|
||||
|
||||
maxWidth: maxWidth,
|
||||
tag: person.PrimaryImageTag,
|
||||
type: "Primary"
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function buildPersonCard(person, apiClient, serverId, options, className) {
|
||||
|
||||
className += " itemAction scalableCard personCard-scalable";
|
||||
className += " " + (options.shape || 'portrait') + 'Card-scalable';
|
||||
|
||||
var imgUrl = getImgUrl(person, options.width, apiClient);
|
||||
|
||||
var cardImageContainerClass = 'cardImageContainer';
|
||||
if (options.coverImage) {
|
||||
cardImageContainerClass += ' coveredImage';
|
||||
}
|
||||
var cardImageContainer = imgUrl ? ('<div class="' + cardImageContainerClass + ' lazy" data-src="' + imgUrl + '">') : ('<div class="' + cardImageContainerClass + '">');
|
||||
|
||||
if (!imgUrl) {
|
||||
cardImageContainer += '<i class="md-icon cardImageIcon">person</i>';
|
||||
}
|
||||
|
||||
var nameHtml = '';
|
||||
nameHtml += '<div class="cardText">' + person.Name + '</div>';
|
||||
|
||||
if (person.Role) {
|
||||
nameHtml += '<div class="cardText cardText-secondary">as ' + person.Role + '</div>';
|
||||
}
|
||||
else if (person.Type) {
|
||||
nameHtml += '<div class="cardText cardText-secondary">' + Globalize.translate('core#' + person.Type) + '</div>';
|
||||
} else {
|
||||
nameHtml += '<div class="cardText cardText-secondary"> </div>';
|
||||
}
|
||||
|
||||
var cardBoxCssClass = 'visualCardBox cardBox';
|
||||
|
||||
if (layoutManager.tv) {
|
||||
cardBoxCssClass += ' cardBox-focustransform';
|
||||
}
|
||||
|
||||
var html = '\
|
||||
<button type="button" data-isfolder="' + person.IsFolder + '" data-type="' + person.Type + '" data-action="link" data-id="' + person.Id + '" data-serverid="' + serverId + '" raised class="' + className + '"> \
|
||||
<div class="' + cardBoxCssClass + '">\
|
||||
<div class="cardScalable visualCardBox-cardScalable">\
|
||||
<div class="cardPadder-portrait"></div>\
|
||||
<div class="cardContent">\
|
||||
' + cardImageContainer + '\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="cardFooter visualCardBox-cardFooter">\
|
||||
' + nameHtml + '\
|
||||
</div>\
|
||||
</div>\
|
||||
</button>'
|
||||
;
|
||||
|
||||
return html;
|
||||
}
|
||||
define(['cardBuilder'], function (cardBuilder) {
|
||||
'use strict';
|
||||
|
||||
function buildPeopleCards(items, options) {
|
||||
|
||||
if (options.parentContainer) {
|
||||
// Abort if the container has been disposed
|
||||
if (!document.body.contains(options.parentContainer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (items.length) {
|
||||
options.parentContainer.classList.remove('hide');
|
||||
} else {
|
||||
options.parentContainer.classList.add('hide');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var html = buildPeopleCardsHtml(items, options);
|
||||
|
||||
options.itemsContainer.innerHTML = html;
|
||||
|
||||
imageLoader.lazyChildren(options.itemsContainer);
|
||||
|
||||
itemShortcuts.off(options.itemsContainer);
|
||||
itemShortcuts.on(options.itemsContainer);
|
||||
options = Object.assign(options || {}, {
|
||||
cardLayout: true,
|
||||
centerText: true,
|
||||
showTitle: true,
|
||||
cardFooterAside: 'none',
|
||||
showPersonRoleOrType: true,
|
||||
cardCssClass: 'personCard'
|
||||
});
|
||||
cardBuilder.buildCards(items, options);
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['dialog', 'globalize'], function (dialog, globalize) {
|
||||
'use strict';
|
||||
|
||||
return function (text, title) {
|
||||
|
||||
|
@ -15,21 +16,21 @@ define(['dialog', 'globalize'], function (dialog, globalize) {
|
|||
var items = [];
|
||||
|
||||
items.push({
|
||||
name: globalize.translate('sharedcomponents#ButtonOk'),
|
||||
id: 'ok',
|
||||
type: 'submit'
|
||||
name: options.cancelText || globalize.translate('sharedcomponents#ButtonCancel'),
|
||||
id: 'cancel',
|
||||
type: options.primary === 'cancel' ? 'submit' : 'cancel'
|
||||
});
|
||||
|
||||
items.push({
|
||||
name: globalize.translate('sharedcomponents#ButtonCancel'),
|
||||
id: 'cancel',
|
||||
type: 'cancel'
|
||||
name: options.confirmText || globalize.translate('sharedcomponents#ButtonOk'),
|
||||
id: 'ok',
|
||||
type: options.primary === 'cancel' ? 'cancel' : 'submit'
|
||||
});
|
||||
|
||||
options.buttons = items;
|
||||
|
||||
return dialog(options).then(function (result) {
|
||||
if (result == 'ok') {
|
||||
if (result === 'ok') {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function replaceAll(str, find, replace) {
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['globalize'], function (globalize) {
|
||||
'use strict';
|
||||
|
||||
function parseISO8601Date(s, toLocal) {
|
||||
|
||||
|
@ -40,12 +41,12 @@
|
|||
}
|
||||
|
||||
// if there's a timezone, calculate it
|
||||
if (d[8] != "Z" && d[10]) {
|
||||
if (d[8] !== "Z" && d[10]) {
|
||||
var offset = d[10] * 60 * 60 * 1000;
|
||||
if (d[11]) {
|
||||
offset += d[11] * 60 * 1000;
|
||||
}
|
||||
if (d[9] == "-") {
|
||||
if (d[9] === "-") {
|
||||
ms -= offset;
|
||||
} else {
|
||||
ms += offset;
|
||||
|
@ -103,60 +104,36 @@
|
|||
return false;
|
||||
}();
|
||||
|
||||
function toLocaleString(date) {
|
||||
var currentLocale = globalize.getCurrentLocale();
|
||||
function getCurrentLocale() {
|
||||
var locale = globalize.getCurrentLocale();
|
||||
|
||||
return locale;
|
||||
}
|
||||
|
||||
function toLocaleString(date, options) {
|
||||
var currentLocale = getCurrentLocale();
|
||||
|
||||
return currentLocale && toLocaleTimeStringSupportsLocales ?
|
||||
date.toLocaleString(currentLocale) :
|
||||
date.toLocaleString(currentLocale, options || {}) :
|
||||
date.toLocaleString();
|
||||
}
|
||||
|
||||
function getLocaleDateStringParts(date) {
|
||||
function toLocaleDateString(date, options) {
|
||||
|
||||
var day = getDayName(date);
|
||||
date = toLocaleDateString(date);
|
||||
|
||||
var parts = [];
|
||||
|
||||
if (date.toLowerCase().indexOf(day.toLowerCase()) == -1) {
|
||||
parts.push(day);
|
||||
}
|
||||
|
||||
parts.push(date);
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
function getDayName(date) {
|
||||
|
||||
var weekday = [];
|
||||
weekday[0] = globalize.translate('sharedcomponents#Sunday');
|
||||
weekday[1] = globalize.translate('sharedcomponents#Monday');
|
||||
weekday[2] = globalize.translate('sharedcomponents#Tuesday');
|
||||
weekday[3] = globalize.translate('sharedcomponents#Wednesday');
|
||||
weekday[4] = globalize.translate('sharedcomponents#Thursday');
|
||||
weekday[5] = globalize.translate('sharedcomponents#Friday');
|
||||
weekday[6] = globalize.translate('sharedcomponents#Saturday');
|
||||
|
||||
return weekday[date.getDay()];
|
||||
}
|
||||
|
||||
function toLocaleDateString(date) {
|
||||
|
||||
var currentLocale = globalize.getCurrentLocale();
|
||||
var currentLocale = getCurrentLocale();
|
||||
|
||||
return currentLocale && toLocaleTimeStringSupportsLocales ?
|
||||
date.toLocaleDateString(currentLocale) :
|
||||
date.toLocaleDateString(currentLocale, options || {}) :
|
||||
date.toLocaleDateString();
|
||||
}
|
||||
|
||||
function toLocaleTimeString(date) {
|
||||
function toLocaleTimeString(date, options) {
|
||||
|
||||
var currentLocale = globalize.getCurrentLocale();
|
||||
var currentLocale = getCurrentLocale();
|
||||
|
||||
return currentLocale && toLocaleTimeStringSupportsLocales ?
|
||||
date.toLocaleTimeString(currentLocale) :
|
||||
date.toLocaleTimeString();
|
||||
date.toLocaleTimeString(currentLocale, options || {}).toLowerCase() :
|
||||
date.toLocaleTimeString().toLowerCase();
|
||||
}
|
||||
|
||||
function getDisplayTime(date) {
|
||||
|
@ -171,36 +148,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
var time = toLocaleTimeString(date);
|
||||
return toLocaleTimeString(date, {
|
||||
|
||||
var timeLower = time.toLowerCase();
|
||||
hour: 'numeric',
|
||||
minute: '2-digit'
|
||||
|
||||
if (timeLower.indexOf('am') != -1 || timeLower.indexOf('pm') != -1) {
|
||||
|
||||
time = timeLower;
|
||||
var hour = date.getHours() % 12;
|
||||
var suffix = date.getHours() > 11 ? 'pm' : 'am';
|
||||
if (!hour) {
|
||||
hour = 12;
|
||||
}
|
||||
var minutes = date.getMinutes();
|
||||
|
||||
if (minutes < 10) {
|
||||
minutes = '0' + minutes;
|
||||
}
|
||||
time = hour + ':' + minutes + suffix;
|
||||
} else {
|
||||
|
||||
var timeParts = time.split(':');
|
||||
|
||||
// Trim off seconds
|
||||
if (timeParts.length > 2) {
|
||||
timeParts.length -= 1;
|
||||
time = timeParts.join(':');
|
||||
}
|
||||
}
|
||||
|
||||
return time;
|
||||
});
|
||||
}
|
||||
|
||||
function isRelativeDay(date, offsetInDays) {
|
||||
|
@ -209,7 +162,7 @@
|
|||
|
||||
yesterday.setDate(day); // automatically adjusts month/year appropriately
|
||||
|
||||
return date.getFullYear() == yesterday.getFullYear() && date.getMonth() == yesterday.getMonth() && date.getDate() == day;
|
||||
return date.getFullYear() === yesterday.getFullYear() && date.getMonth() === yesterday.getMonth() && date.getDate() === day;
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -218,7 +171,6 @@
|
|||
toLocaleDateString: toLocaleDateString,
|
||||
toLocaleString: toLocaleString,
|
||||
getDisplayTime: getDisplayTime,
|
||||
isRelativeDay: isRelativeDay,
|
||||
getLocaleDateStringParts: getLocaleDateStringParts
|
||||
isRelativeDay: isRelativeDay
|
||||
};
|
||||
});
|
|
@ -1,20 +1,5 @@
|
|||
define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 'require', 'material-icons', 'emby-button', 'paper-icon-button-light', 'emby-input', 'formDialogStyle'], function (dialogHelper, dom, layoutManager, scrollHelper, globalize, require) {
|
||||
|
||||
function showTvDialog(options) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
require(['actionsheet'], function (actionSheet) {
|
||||
|
||||
actionSheet.show({
|
||||
|
||||
title: options.text,
|
||||
items: options.buttons,
|
||||
timeout: options.timeout
|
||||
|
||||
}).then(resolve, reject);
|
||||
});
|
||||
});
|
||||
}
|
||||
'use strict';
|
||||
|
||||
function showDialog(options, template) {
|
||||
|
||||
|
@ -23,10 +8,10 @@ define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 're
|
|||
scrollY: false
|
||||
};
|
||||
|
||||
if (layoutManager.tv) {
|
||||
var enableTvLayout = layoutManager.tv;
|
||||
|
||||
if (enableTvLayout) {
|
||||
dialogOptions.size = 'fullscreen';
|
||||
} else {
|
||||
//dialogOptions.size = 'mini';
|
||||
}
|
||||
|
||||
var dlg = dialogHelper.createDialog(dialogOptions);
|
||||
|
@ -35,17 +20,29 @@ define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 're
|
|||
|
||||
dlg.innerHTML = globalize.translateHtml(template, 'sharedcomponents');
|
||||
|
||||
if (layoutManager.tv) {
|
||||
scrollHelper.centerFocus.on(dlg.querySelector('.formDialogContent'), false);
|
||||
dlg.style['align-items'] = 'center';
|
||||
dlg.style['justify-content'] = 'center';
|
||||
var formDialogContent = dlg.querySelector('.formDialogContent');
|
||||
formDialogContent.style['flex-grow'] = 'initial';
|
||||
|
||||
if (enableTvLayout) {
|
||||
formDialogContent.style['max-width'] = '50%';
|
||||
formDialogContent.style['max-height'] = '60%';
|
||||
scrollHelper.centerFocus.on(formDialogContent, false);
|
||||
} else {
|
||||
dlg.querySelector('.dialogContentInner').classList.add('dialogContentInner-mini');
|
||||
formDialogContent.style.maxWidth = (Math.min((options.buttons.length * 150) + 200, dom.getWindowSize().innerWidth - 50)) + 'px';
|
||||
dlg.classList.add('dialog-fullscreen-lowres');
|
||||
}
|
||||
|
||||
//dlg.querySelector('.btnCancel').addEventListener('click', function (e) {
|
||||
// dialogHelper.close(dlg);
|
||||
//});
|
||||
|
||||
dlg.querySelector('.formDialogHeaderTitle').innerHTML = options.title || '';
|
||||
if (options.title) {
|
||||
dlg.querySelector('.formDialogHeaderTitle').innerHTML = options.title || '';
|
||||
} else {
|
||||
dlg.querySelector('.formDialogHeaderTitle').classList.add('hide');
|
||||
}
|
||||
|
||||
dlg.querySelector('.text').innerHTML = options.html || options.text || '';
|
||||
|
||||
|
@ -54,9 +51,9 @@ define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 're
|
|||
for (i = 0, length = options.buttons.length; i < length; i++) {
|
||||
|
||||
var item = options.buttons[i];
|
||||
var autoFocus = i == 0 ? ' autofocus' : '';
|
||||
var autoFocus = i === 0 ? ' autofocus' : '';
|
||||
|
||||
var buttonClass = 'btnOption raised block formDialogFooterItem';
|
||||
var buttonClass = 'btnOption raised formDialogFooterItem formDialogFooterItem-autosize';
|
||||
|
||||
if (item.type) {
|
||||
buttonClass += ' button-' + item.type;
|
||||
|
@ -65,8 +62,6 @@ define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 're
|
|||
html += '<button is="emby-button" type="button" class="' + buttonClass + '" data-id="' + item.id + '"' + autoFocus + '>' + item.name + '</button>';
|
||||
}
|
||||
|
||||
dlg.style.minWidth = (Math.min(options.buttons.length * 150, dom.getWindowSize().innerWidth - 50)) + 'px';
|
||||
|
||||
dlg.querySelector('.formDialogFooter').innerHTML = html;
|
||||
|
||||
var dialogResult;
|
||||
|
@ -82,7 +77,7 @@ define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 're
|
|||
|
||||
return dialogHelper.open(dlg).then(function () {
|
||||
|
||||
if (layoutManager.tv) {
|
||||
if (enableTvLayout) {
|
||||
scrollHelper.centerFocus.off(dlg.querySelector('.formDialogContent'), false);
|
||||
}
|
||||
|
||||
|
@ -106,10 +101,6 @@ define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 're
|
|||
options = text;
|
||||
}
|
||||
|
||||
if (layoutManager.tv) {
|
||||
return showTvDialog(options);
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
require(['text!./dialog.template.html'], function (template) {
|
||||
showDialog(options, template).then(resolve, reject);
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
<div class="formDialogHeader">
|
||||
<h3 class="formDialogHeaderTitle" style="margin-left:.75em;"></h3>
|
||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1" style="visibility:hidden;"><i class="md-icon"></i></button>
|
||||
<div class="formDialogHeader formDialogHeader-clear" style="justify-content:center;">
|
||||
<h1 class="formDialogHeaderTitle" style="margin-left:0;margin-top: .5em;padding: 0 1em;"></h1>
|
||||
</div>
|
||||
|
||||
<div class="formDialogContent smoothScrollY">
|
||||
<div class="dialogContentInner dialog-content-centered" style="padding-top:2em;">
|
||||
<div class="dialogContentInner dialog-content-centered" style="padding-top:2em;padding-bottom: 2em; text-align: center;">
|
||||
|
||||
<div class="text">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="formDialogFooter">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="formDialogFooter formDialogFooter-clear formDialogFooter-flex" style="padding-bottom: 1.5em;">
|
||||
</div>
|
|
@ -13,14 +13,14 @@
|
|||
|
||||
.dialog {
|
||||
margin: 0;
|
||||
border-radius: 1px;
|
||||
border-radius: 4px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.4);
|
||||
border: 0;
|
||||
padding: 0;
|
||||
will-change: transform;
|
||||
/* Strict does not work well with actionsheet */
|
||||
contain: style;
|
||||
box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.dialog-fixedSize {
|
||||
|
@ -37,16 +37,19 @@
|
|||
left: 0;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@media all and (max-width: 1280px), all and (max-height: 720px) {
|
||||
.dialog-fixedSize {
|
||||
|
||||
.dialog-fixedSize, .dialog-fullscreen-lowres {
|
||||
position: fixed !important;
|
||||
top: 0 !important;
|
||||
bottom: 0 !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
margin: 0 !important;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,5 +95,5 @@
|
|||
}
|
||||
|
||||
.dialogBackdropOpened {
|
||||
opacity: .7;
|
||||
opacity: .6;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['historyManager', 'focusManager', 'browser', 'layoutManager', 'inputManager', 'dom', 'css!./dialoghelper.css', 'scrollStyles'], function (historyManager, focusManager, browser, layoutManager, inputManager, dom) {
|
||||
'use strict';
|
||||
|
||||
var globalOnOpenCallback;
|
||||
|
||||
|
@ -27,7 +28,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
function dialogHashHandler(dlg, hash, resolve) {
|
||||
function DialogHashHandler(dlg, hash, resolve) {
|
||||
|
||||
var self = this;
|
||||
self.originalUrl = window.location.href;
|
||||
|
@ -36,7 +37,7 @@
|
|||
|
||||
function onHashChange(e) {
|
||||
|
||||
var isBack = self.originalUrl == window.location.href;
|
||||
var isBack = self.originalUrl === window.location.href;
|
||||
|
||||
if (isBack || !isOpened(dlg)) {
|
||||
window.removeEventListener('popstate', onHashChange);
|
||||
|
@ -50,10 +51,11 @@
|
|||
|
||||
function onBackCommand(e) {
|
||||
|
||||
if (e.detail.command == 'back') {
|
||||
if (e.detail.command === 'back') {
|
||||
self.closedByBack = true;
|
||||
closeDialog(dlg);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
closeDialog(dlg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +76,7 @@
|
|||
|
||||
if (!self.closedByBack && isHistoryEnabled(dlg)) {
|
||||
var state = history.state || {};
|
||||
if (state.dialogId == hash) {
|
||||
if (state.dialogId === hash) {
|
||||
history.back();
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +85,7 @@
|
|||
activeElement.focus();
|
||||
}
|
||||
|
||||
if (dlg.getAttribute('data-removeonclose') != 'false') {
|
||||
if (dlg.getAttribute('data-removeonclose') !== 'false') {
|
||||
removeCenterFocus(dlg);
|
||||
|
||||
var dialogContainer = dlg.dialogContainer;
|
||||
|
@ -117,8 +119,12 @@
|
|||
addBackdropOverlay(dlg);
|
||||
|
||||
dlg.classList.add('opened');
|
||||
dlg.dispatchEvent(new CustomEvent('open', {
|
||||
bubbles: false,
|
||||
cancelable: false
|
||||
}));
|
||||
|
||||
if (dlg.getAttribute('data-lockscroll') == 'true' && !document.body.classList.contains('noScroll')) {
|
||||
if (dlg.getAttribute('data-lockscroll') === 'true' && !document.body.classList.contains('noScroll')) {
|
||||
document.body.classList.add('noScroll');
|
||||
removeScrollLockOnClose = true;
|
||||
}
|
||||
|
@ -126,7 +132,7 @@
|
|||
animateDialogOpen(dlg);
|
||||
|
||||
if (isHistoryEnabled(dlg)) {
|
||||
historyManager.pushState({ dialogId: hash }, "Dialog", hash);
|
||||
historyManager.pushState({ dialogId: hash }, "Dialog", '#' + hash);
|
||||
|
||||
window.addEventListener('popstate', onHashChange);
|
||||
} else {
|
||||
|
@ -149,7 +155,7 @@
|
|||
}, 0);
|
||||
|
||||
dom.addEventListener((dlg.dialogContainer || backdrop), 'click', function (e) {
|
||||
if (e.target == dlg.dialogContainer) {
|
||||
if (e.target === dlg.dialogContainer) {
|
||||
close(dlg);
|
||||
}
|
||||
}, {
|
||||
|
@ -158,7 +164,7 @@
|
|||
}
|
||||
|
||||
function isHistoryEnabled(dlg) {
|
||||
return dlg.getAttribute('data-history') == 'true';
|
||||
return dlg.getAttribute('data-history') === 'true';
|
||||
}
|
||||
|
||||
function open(dlg) {
|
||||
|
@ -180,7 +186,7 @@
|
|||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
new dialogHashHandler(dlg, 'dlg' + new Date().getTime(), resolve);
|
||||
new DialogHashHandler(dlg, 'dlg' + new Date().getTime(), resolve);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -207,7 +213,7 @@
|
|||
{ transform: 'scale(0)', offset: 0 },
|
||||
{ transform: 'none', offset: 1 }];
|
||||
var timing = elem.animationConfig.entry.timing;
|
||||
return elem.animate(keyframes, timing).onfinish = onFinish;
|
||||
elem.animate(keyframes, timing).onfinish = onFinish;
|
||||
}
|
||||
|
||||
function slideUp(elem, onFinish) {
|
||||
|
@ -216,7 +222,7 @@
|
|||
{ transform: 'translate3d(0,30%,0)', opacity: 0, offset: 0 },
|
||||
{ transform: 'none', opacity: 1, offset: 1 }];
|
||||
var timing = elem.animationConfig.entry.timing;
|
||||
return elem.animate(keyframes, timing).onfinish = onFinish;
|
||||
elem.animate(keyframes, timing).onfinish = onFinish;
|
||||
}
|
||||
|
||||
function fadeIn(elem, onFinish) {
|
||||
|
@ -225,7 +231,7 @@
|
|||
{ opacity: '0', offset: 0 },
|
||||
{ opacity: '1', offset: 1 }];
|
||||
var timing = elem.animationConfig.entry.timing;
|
||||
return elem.animate(keyframes, timing).onfinish = onFinish;
|
||||
elem.animate(keyframes, timing).onfinish = onFinish;
|
||||
}
|
||||
|
||||
function scaleDown(elem) {
|
||||
|
@ -277,18 +283,18 @@
|
|||
}));
|
||||
}
|
||||
};
|
||||
if (!dlg.animationConfig || !dlg.animate) {
|
||||
if (!dlg.animationConfig) {
|
||||
onAnimationFinish();
|
||||
return;
|
||||
}
|
||||
|
||||
var animation;
|
||||
|
||||
if (dlg.animationConfig.exit.name == 'fadeout') {
|
||||
if (dlg.animationConfig.exit.name === 'fadeout') {
|
||||
animation = fadeOut(dlg);
|
||||
} else if (dlg.animationConfig.exit.name == 'scaledown') {
|
||||
} else if (dlg.animationConfig.exit.name === 'scaledown') {
|
||||
animation = scaleDown(dlg);
|
||||
} else if (dlg.animationConfig.exit.name == 'slidedown') {
|
||||
} else if (dlg.animationConfig.exit.name === 'slidedown') {
|
||||
animation = slideDown(dlg);
|
||||
} else {
|
||||
onAnimationFinish();
|
||||
|
@ -303,20 +309,20 @@
|
|||
|
||||
var onAnimationFinish = function () {
|
||||
focusManager.pushScope(dlg);
|
||||
if (dlg.getAttribute('data-autofocus') == 'true') {
|
||||
if (dlg.getAttribute('data-autofocus') === 'true') {
|
||||
focusManager.autoFocus(dlg);
|
||||
}
|
||||
};
|
||||
|
||||
if (!dlg.animationConfig || !dlg.animate) {
|
||||
if (!dlg.animationConfig) {
|
||||
onAnimationFinish();
|
||||
return;
|
||||
}
|
||||
if (dlg.animationConfig.entry.name == 'fadein') {
|
||||
if (dlg.animationConfig.entry.name === 'fadein') {
|
||||
fadeIn(dlg, onAnimationFinish);
|
||||
} else if (dlg.animationConfig.entry.name == 'scaleup') {
|
||||
} else if (dlg.animationConfig.entry.name === 'scaleup') {
|
||||
scaleUp(dlg, onAnimationFinish);
|
||||
} else if (dlg.animationConfig.entry.name == 'slideup') {
|
||||
} else if (dlg.animationConfig.entry.name === 'slideup') {
|
||||
slideUp(dlg, onAnimationFinish);
|
||||
}
|
||||
}
|
||||
|
@ -327,7 +333,7 @@
|
|||
return options.lockScroll;
|
||||
}
|
||||
|
||||
if (options.size == 'fullscreen') {
|
||||
if (options.size === 'fullscreen') {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function parentWithAttribute(elem, name, value) {
|
||||
|
||||
while ((value ? elem.getAttribute(name) != value : !elem.getAttribute(name))) {
|
||||
while ((value ? elem.getAttribute(name) !== value : !elem.getAttribute(name))) {
|
||||
elem = elem.parentNode;
|
||||
|
||||
if (!elem || !elem.getAttribute) {
|
||||
|
@ -20,7 +21,7 @@ define([], function () {
|
|||
tagNames = [tagNames];
|
||||
}
|
||||
|
||||
while (tagNames.indexOf(elem.tagName || '') == -1) {
|
||||
while (tagNames.indexOf(elem.tagName || '') === -1) {
|
||||
elem = elem.parentNode;
|
||||
|
||||
if (!elem) {
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
margin: 0 .29em;
|
||||
background: transparent;
|
||||
text-align: center;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
|
@ -27,52 +26,57 @@
|
|||
position: relative;
|
||||
overflow: hidden;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
/* Disable webkit tap highlighting */
|
||||
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
||||
}
|
||||
|
||||
.emby-button.raised, .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);
|
||||
.emby-button::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.emby-button > i {
|
||||
/* For non-fab buttons that have icons */
|
||||
font-size: 1.5em;
|
||||
width: auto;
|
||||
.button-flat {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.emby-button > i {
|
||||
/* For non-fab buttons that have icons */
|
||||
font-size: 1.36em;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.fab {
|
||||
display: inline-flex;
|
||||
border-radius: 50%;
|
||||
background-color: #444;
|
||||
padding: .6em;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.fab > i {
|
||||
height: auto;
|
||||
width: auto;
|
||||
vertical-align: middle;
|
||||
font-size: 2.85em;
|
||||
}
|
||||
|
||||
.emby-button.fab {
|
||||
display: inline-flex;
|
||||
border-radius: 50%;
|
||||
background-color: #444;
|
||||
padding: .6em;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.emby-button.fab > i {
|
||||
height: auto;
|
||||
width: auto;
|
||||
vertical-align: middle;
|
||||
font-size: 2.85em;
|
||||
}
|
||||
|
||||
.emby-button-noflex {
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.emby-button.fab.mini {
|
||||
.fab.mini {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.emby-button.fab.mini > i {
|
||||
.fab.mini > i {
|
||||
height: auto;
|
||||
width: auto;
|
||||
font-size: 1.72em;
|
||||
|
@ -86,7 +90,7 @@
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.emby-button.raised:focus {
|
||||
.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);
|
||||
}
|
||||
|
@ -95,22 +99,10 @@
|
|||
margin-left: .5em;
|
||||
}
|
||||
|
||||
.emby-button span + i {
|
||||
.emby-button > span + i {
|
||||
margin-left: .5em;
|
||||
}
|
||||
|
||||
.emby-button.iconRight > i {
|
||||
margin-left: auto;
|
||||
margin-right: .25em;
|
||||
}
|
||||
|
||||
.emby-button-noflex.iconRight > i {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 25%;
|
||||
margin-right: .5em;
|
||||
}
|
||||
|
||||
.paper-icon-button-light {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
|
@ -149,6 +141,10 @@
|
|||
justify-content: center;
|
||||
}
|
||||
|
||||
.paper-icon-button-light::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.paper-icon-button-light[disabled] {
|
||||
opacity: .3;
|
||||
}
|
||||
|
@ -156,7 +152,7 @@
|
|||
.paper-icon-button-light > i {
|
||||
width: auto;
|
||||
height: auto;
|
||||
font-size: 1.72em;
|
||||
font-size: 1.6em;
|
||||
/* Make sure its on top of the ripple */
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['browser', 'dom', 'css!./emby-button', 'registerElement'], function (browser, dom) {
|
||||
'use strict';
|
||||
|
||||
var EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype);
|
||||
|
||||
|
@ -30,9 +31,8 @@
|
|||
}, false);
|
||||
}
|
||||
|
||||
function animateButton(e) {
|
||||
function animateButton(e, btn) {
|
||||
|
||||
var btn = this;
|
||||
requestAnimationFrame(function () {
|
||||
animateButtonInternal(e, btn);
|
||||
});
|
||||
|
@ -40,18 +40,23 @@
|
|||
|
||||
function onKeyDown(e) {
|
||||
|
||||
if (e.keyCode == 13) {
|
||||
animateButton.call(this, e);
|
||||
if (e.keyCode === 13) {
|
||||
animateButton(e, this);
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseDown(e) {
|
||||
|
||||
if (e.button == 0) {
|
||||
animateButton.call(this, e);
|
||||
if (e.button === 0) {
|
||||
animateButton(e, this);
|
||||
}
|
||||
}
|
||||
|
||||
function onClick(e) {
|
||||
|
||||
animateButton(e, this);
|
||||
}
|
||||
|
||||
function enableAnimation() {
|
||||
if (browser.tv) {
|
||||
// too slow
|
||||
|
@ -77,7 +82,7 @@
|
|||
passive: true
|
||||
});
|
||||
if (browser.safari) {
|
||||
dom.addEventListener(this, 'click', animateButton, {
|
||||
dom.addEventListener(this, 'click', onClick, {
|
||||
passive: true
|
||||
});
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['browser', 'dom', 'css!./emby-button', 'registerElement'], function (browser, dom) {
|
||||
'use strict';
|
||||
|
||||
var EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype);
|
||||
|
||||
|
@ -33,9 +34,8 @@
|
|||
}, false);
|
||||
}
|
||||
|
||||
function animateButton(e) {
|
||||
function animateButton(e, btn) {
|
||||
|
||||
var btn = this;
|
||||
requestAnimationFrame(function () {
|
||||
animateButtonInternal(e, btn);
|
||||
});
|
||||
|
@ -43,11 +43,16 @@
|
|||
|
||||
function onKeyDown(e) {
|
||||
|
||||
if (e.keyCode == 13) {
|
||||
animateButton.call(this, e);
|
||||
if (e.keyCode === 13) {
|
||||
animateButton(e, this);
|
||||
}
|
||||
}
|
||||
|
||||
function onClick(e) {
|
||||
|
||||
animateButton(e, this);
|
||||
}
|
||||
|
||||
EmbyButtonPrototype.createdCallback = function () {
|
||||
|
||||
if (this.classList.contains('paper-icon-button-light')) {
|
||||
|
@ -60,7 +65,7 @@
|
|||
dom.addEventListener(this, 'keydown', onKeyDown, {
|
||||
passive: true
|
||||
});
|
||||
dom.addEventListener(this, 'click', animateButton, {
|
||||
dom.addEventListener(this, 'click', onClick, {
|
||||
passive: true
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
position: relative;
|
||||
z-index: 1;
|
||||
vertical-align: middle;
|
||||
display: inline-flex;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
|
@ -18,7 +18,18 @@
|
|||
|
||||
.checkboxContainer {
|
||||
margin-bottom: 1.8em;
|
||||
display: flex;
|
||||
display: block;
|
||||
}
|
||||
|
||||
@supports (display: flex) {
|
||||
|
||||
.mdl-checkbox {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.checkboxContainer {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.checkboxContainer-withDescription {
|
||||
|
@ -113,15 +124,17 @@
|
|||
cursor: auto;
|
||||
}
|
||||
|
||||
.checkboxList .mdl-checkbox {
|
||||
.checkboxList > .mdl-checkbox {
|
||||
display: flex;
|
||||
margin: .5em 0;
|
||||
}
|
||||
|
||||
.checkboxList-paperList {
|
||||
padding: 1em !important;
|
||||
margin: .75em 0 !important;
|
||||
}
|
||||
|
||||
.checkboxListLabel {
|
||||
opacity: .7;
|
||||
}
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
define(['css!./emby-checkbox', 'registerElement'], function () {
|
||||
'use strict';
|
||||
|
||||
var EmbyCheckboxPrototype = Object.create(HTMLInputElement.prototype);
|
||||
|
||||
function onKeyDown(e) {
|
||||
|
||||
// Don't submit form on enter
|
||||
if (e.keyCode == 13) {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
|
||||
this.checked = !this.checked;
|
||||
|
@ -20,7 +21,7 @@
|
|||
|
||||
EmbyCheckboxPrototype.attachedCallback = function () {
|
||||
|
||||
if (this.getAttribute('data-embycheckbox') == 'true') {
|
||||
if (this.getAttribute('data-embycheckbox') === 'true') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,11 +23,16 @@
|
|||
text-transform: none;
|
||||
border-bottom: 1px solid #333;
|
||||
padding-left: .1em;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.emby-collapse-expandIcon {
|
||||
transform-origin: 50% 50%;
|
||||
transition: transform 180ms ease-out;
|
||||
position: absolute;
|
||||
right: .5em;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.emby-collapse-expandIconExpanded {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['browser', 'css!./emby-collapse', 'registerElement'], function (browser) {
|
||||
'use strict';
|
||||
|
||||
var EmbyButtonPrototype = Object.create(HTMLDivElement.prototype);
|
||||
|
||||
|
@ -9,7 +10,9 @@
|
|||
elem.style.height = 'auto';
|
||||
var height = elem.offsetHeight + 'px';
|
||||
elem.style.height = '0';
|
||||
elem.offsetHeight;
|
||||
|
||||
// trigger reflow
|
||||
var newHeight = elem.offsetHeight;
|
||||
elem.style.height = height;
|
||||
|
||||
setTimeout(function () {
|
||||
|
@ -29,7 +32,8 @@
|
|||
function slideUpToHide(button, elem) {
|
||||
|
||||
elem.style.height = elem.offsetHeight + 'px';
|
||||
elem.offsetHeight;
|
||||
// trigger reflow
|
||||
var newHeight = elem.offsetHeight;
|
||||
|
||||
elem.classList.remove('expanded');
|
||||
elem.style.height = '0';
|
||||
|
@ -49,14 +53,15 @@
|
|||
|
||||
function onButtonClick(e) {
|
||||
|
||||
var collapseContent = this.parentNode.querySelector('.collapseContent');
|
||||
var button = this;
|
||||
var collapseContent = button.parentNode.querySelector('.collapseContent');
|
||||
|
||||
if (collapseContent.expanded) {
|
||||
collapseContent.expanded = false;
|
||||
slideUpToHide(this, collapseContent);
|
||||
slideUpToHide(button, collapseContent);
|
||||
} else {
|
||||
collapseContent.expanded = true;
|
||||
slideDownToShow(this, collapseContent);
|
||||
slideDownToShow(button, collapseContent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,10 +80,7 @@
|
|||
|
||||
var title = this.getAttribute('title');
|
||||
|
||||
var html = '<button is="emby-button" type="button" on-click="toggleExpand" id="expandButton" class="emby-collapsible-button iconRight">\
|
||||
<h3 class="emby-collapsible-title" title="' + title + '">' + title + '</h3>\
|
||||
<i class="md-icon emby-collapse-expandIcon">expand_more</i>\
|
||||
</button>';
|
||||
var html = '<button is="emby-button" type="button" on-click="toggleExpand" id="expandButton" class="emby-collapsible-button iconRight"><h3 class="emby-collapsible-title" title="' + title + '">' + title + '</h3><i class="md-icon emby-collapse-expandIcon">expand_more</i></button>';
|
||||
|
||||
this.insertAdjacentHTML('afterbegin', html);
|
||||
|
||||
|
@ -86,7 +88,7 @@
|
|||
|
||||
button.addEventListener('click', onButtonClick);
|
||||
|
||||
if (this.getAttribute('data-expanded') == 'true') {
|
||||
if (this.getAttribute('data-expanded') === 'true') {
|
||||
onButtonClick.call(button);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
margin: 0;
|
||||
margin-bottom: 0 !important;
|
||||
background: none;
|
||||
border: 1px solid rgb(221, 221, 221);
|
||||
border: 1px solid #383838;
|
||||
border-width: 0 0 1px 0;
|
||||
/* Prefixed box-sizing rules necessary for older browsers */
|
||||
-webkit-box-sizing: border-box;
|
||||
|
@ -21,6 +21,8 @@
|
|||
width: 100%;
|
||||
background-color: transparent;
|
||||
border-radius: 0;
|
||||
/* Ensure it is over the label so that it can be clicked */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.inputContainer {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['layoutManager', 'browser', 'dom', 'css!./emby-input', 'registerElement'], function (layoutManager, browser, dom) {
|
||||
'use strict';
|
||||
|
||||
var EmbyInputPrototype = Object.create(HTMLInputElement.prototype);
|
||||
|
||||
|
@ -19,7 +20,7 @@
|
|||
bubbles: false,
|
||||
cancelable: false
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperty(HTMLInputElement.prototype, 'value', descriptor);
|
||||
supportsFloatingLabel = true;
|
||||
|
@ -86,7 +87,7 @@
|
|||
label.classList.remove('inputLabel-float');
|
||||
} else {
|
||||
|
||||
var instanceSupportsFloat = supportsFloatingLabel && this.type != 'date' && this.type != 'time';
|
||||
var instanceSupportsFloat = supportsFloatingLabel && this.type !== 'date' && this.type !== 'time';
|
||||
|
||||
if (instanceSupportsFloat) {
|
||||
label.classList.add('inputLabel-float');
|
||||
|
|
|
@ -183,6 +183,57 @@
|
|||
});
|
||||
}
|
||||
|
||||
function onTimerCreated(e, apiClient, data) {
|
||||
|
||||
var itemsContainer = this;
|
||||
|
||||
var programId = data.ProgramId;
|
||||
// This could be null, not supported by all tv providers
|
||||
var newTimerId = data.Id;
|
||||
|
||||
require(['cardBuilder'], function (cardBuilder) {
|
||||
cardBuilder.onTimerCreated(programId, newTimerId, itemsContainer);
|
||||
});
|
||||
}
|
||||
|
||||
function onSeriesTimerCreated(e, apiClient, data) {
|
||||
var itemsContainer = this;
|
||||
}
|
||||
|
||||
function onTimerCancelled(e, apiClient, data) {
|
||||
var itemsContainer = this;
|
||||
var id = data.Id;
|
||||
|
||||
require(['cardBuilder'], function (cardBuilder) {
|
||||
cardBuilder.onTimerCancelled(id, itemsContainer);
|
||||
});
|
||||
}
|
||||
|
||||
function onSeriesTimerCancelled(e, apiClient, data) {
|
||||
var itemsContainer = this;
|
||||
var id = data.Id;
|
||||
|
||||
require(['cardBuilder'], function (cardBuilder) {
|
||||
cardBuilder.onSeriesTimerCancelled(id, itemsContainer);
|
||||
});
|
||||
}
|
||||
|
||||
function addNotificationEvent(instance, name, handler) {
|
||||
|
||||
var localHandler = handler.bind(instance);
|
||||
events.on(serverNotifications, name, localHandler);
|
||||
instance[name] = localHandler;
|
||||
}
|
||||
|
||||
function removeNotificationEvent(instance, name) {
|
||||
|
||||
var handler = instance[name];
|
||||
if (handler) {
|
||||
events.off(serverNotifications, 'UserDataChanged', handler);
|
||||
instance[name] = null;
|
||||
}
|
||||
}
|
||||
|
||||
ItemsContainerProtoType.attachedCallback = function () {
|
||||
|
||||
this.addEventListener('click', onClick);
|
||||
|
@ -190,7 +241,9 @@
|
|||
if (browser.touch) {
|
||||
this.addEventListener('contextmenu', disableEvent);
|
||||
} else {
|
||||
this.addEventListener('contextmenu', onContextMenu);
|
||||
if (this.getAttribute('data-contextmenu') !== 'false') {
|
||||
this.addEventListener('contextmenu', onContextMenu);
|
||||
}
|
||||
}
|
||||
|
||||
if (layoutManager.desktop) {
|
||||
|
@ -203,9 +256,11 @@
|
|||
|
||||
itemShortcuts.on(this, getShortcutOptions());
|
||||
|
||||
var userDataHandler = onUserDataChanged.bind(this);
|
||||
events.on(serverNotifications, 'UserDataChanged', userDataHandler);
|
||||
this.userDataHandler = userDataHandler;
|
||||
addNotificationEvent(this, 'UserDataChanged', onUserDataChanged);
|
||||
addNotificationEvent(this, 'TimerCreated', onTimerCreated);
|
||||
addNotificationEvent(this, 'SeriesTimerCreated', onSeriesTimerCreated);
|
||||
addNotificationEvent(this, 'TimerCancelled', onTimerCancelled);
|
||||
addNotificationEvent(this, 'SeriesTimerCancelled', onSeriesTimerCancelled);
|
||||
};
|
||||
|
||||
ItemsContainerProtoType.detachedCallback = function () {
|
||||
|
@ -218,11 +273,11 @@
|
|||
this.removeEventListener('contextmenu', disableEvent);
|
||||
itemShortcuts.off(this, getShortcutOptions());
|
||||
|
||||
var userDataHandler = this.userDataHandler;
|
||||
if (userDataHandler) {
|
||||
events.off(serverNotifications, 'UserDataChanged', userDataHandler);
|
||||
this.userDataHandler = null;
|
||||
}
|
||||
removeNotificationEvent(this, 'UserDataChanged');
|
||||
removeNotificationEvent(this, 'TimerCreated');
|
||||
removeNotificationEvent(this, 'SeriesTimerCreated');
|
||||
removeNotificationEvent(this, 'TimerCancelled');
|
||||
removeNotificationEvent(this, 'SeriesTimerCancelled');
|
||||
};
|
||||
|
||||
document.registerElement('emby-itemscontainer', {
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
.mdl-radio__button {
|
||||
line-height: 24px;
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
/* 1px is for focusing purposes, so the focusManager doesn't skip over it */
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
opacity: 0;
|
||||
|
@ -43,13 +44,13 @@
|
|||
height: 16px;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
border: 2px solid rgba(0,0,0, 0.54);
|
||||
border: 2px solid currentcolor;
|
||||
border-radius: 50%;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.mdl-radio__button:checked + .mdl-radio__label + .mdl-radio__outer-circle {
|
||||
border: 2px solid rgb(63,81,181);
|
||||
border: 2px solid rgb(82, 181, 75);
|
||||
}
|
||||
|
||||
.mdl-radio__button:disabled + .mdl-radio__label + .mdl-radio__outer-circle {
|
||||
|
@ -75,7 +76,7 @@
|
|||
-webkit-transform: scale3d(0, 0, 0);
|
||||
transform: scale3d(0, 0, 0);
|
||||
border-radius: 50%;
|
||||
background: rgb(63,81,181);
|
||||
background: rgb(82, 181, 75);
|
||||
}
|
||||
|
||||
.mdl-radio__button:checked + .mdl-radio__label + .mdl-radio__outer-circle + .mdl-radio__inner-circle {
|
||||
|
@ -89,7 +90,11 @@
|
|||
}
|
||||
|
||||
.mdl-radio__button:focus + .mdl-radio__label + .mdl-radio__outer-circle + .mdl-radio__inner-circle {
|
||||
box-shadow: 0 0 0px 10px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 0 0px 10px rgba(255, 255, 255, 0.76);
|
||||
}
|
||||
|
||||
.mdl-radio__button:checked:focus + .mdl-radio__label + .mdl-radio__outer-circle + .mdl-radio__inner-circle {
|
||||
box-shadow: 0 0 0px 10px rgba(82, 181, 75, 0.26);
|
||||
}
|
||||
|
||||
.mdl-radio__label {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
define(['css!./emby-radio', 'registerElement'], function () {
|
||||
'use strict';
|
||||
|
||||
var EmbyRadioPrototype = Object.create(HTMLInputElement.prototype);
|
||||
|
||||
function onKeyDown(e) {
|
||||
|
||||
// Don't submit form on enter
|
||||
if (e.keyCode == 13) {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
|
||||
this.checked = true;
|
||||
|
@ -16,7 +17,7 @@
|
|||
|
||||
EmbyRadioPrototype.attachedCallback = function () {
|
||||
|
||||
if (this.getAttribute('data-radio') == 'true') {
|
||||
if (this.getAttribute('data-radio') === 'true') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
margin: 0;
|
||||
margin-bottom: 0 !important;
|
||||
background: none;
|
||||
border: 1px solid rgb(221, 221, 221);
|
||||
border: 1px solid #383838;
|
||||
border-width: 0 0 1px 0;
|
||||
/* Prefixed box-sizing rules necessary for older browsers */
|
||||
-webkit-box-sizing: border-box;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['layoutManager', 'browser', 'actionsheet', 'css!./emby-select', 'registerElement'], function (layoutManager, browser, actionsheet) {
|
||||
'use strict';
|
||||
|
||||
var EmbySelectPrototype = Object.create(HTMLSelectElement.prototype);
|
||||
|
||||
|
@ -54,7 +55,7 @@
|
|||
|
||||
function getLabel(select) {
|
||||
var elem = select.previousSibling;
|
||||
while (elem && elem.tagName != 'LABEL') {
|
||||
while (elem && elem.tagName !== 'LABEL') {
|
||||
elem = elem.previousSibling;
|
||||
}
|
||||
return elem;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['browser', 'css!./emby-slider', 'registerElement', 'emby-input'], function (browser) {
|
||||
'use strict';
|
||||
|
||||
var EmbySliderPrototype = Object.create(HTMLInputElement.prototype);
|
||||
|
||||
|
@ -28,9 +29,8 @@
|
|||
});
|
||||
}
|
||||
|
||||
function updateBubble(range, bubble) {
|
||||
function updateBubble(range, value, bubble) {
|
||||
|
||||
var value = range.value;
|
||||
bubble.style.left = (value - 1) + '%';
|
||||
|
||||
if (range.getBubbleText) {
|
||||
|
@ -41,7 +41,7 @@
|
|||
|
||||
EmbySliderPrototype.attachedCallback = function () {
|
||||
|
||||
if (this.getAttribute('data-embycheckbox') == 'true') {
|
||||
if (this.getAttribute('data-embycheckbox') === 'true') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -71,16 +71,26 @@
|
|||
|
||||
this.addEventListener('input', function (e) {
|
||||
this.dragging = true;
|
||||
updateBubble(this, sliderBubble);
|
||||
});
|
||||
this.addEventListener('change', function () {
|
||||
this.dragging = false;
|
||||
updateValues(this, backgroundLower, backgroundUpper);
|
||||
});
|
||||
|
||||
this.addEventListener('mousemove', function (e) {
|
||||
|
||||
var rect = this.getBoundingClientRect();
|
||||
var clientX = e.clientX;
|
||||
var bubbleValue = (clientX - rect.left) / rect.width;
|
||||
bubbleValue *= 100;
|
||||
updateBubble(this, Math.round(bubbleValue), sliderBubble);
|
||||
|
||||
if (hasHideClass) {
|
||||
sliderBubble.classList.remove('hide');
|
||||
hasHideClass = false;
|
||||
}
|
||||
});
|
||||
this.addEventListener('change', function () {
|
||||
this.dragging = false;
|
||||
updateValues(this, backgroundLower, backgroundUpper);
|
||||
this.addEventListener('mouseleave', function () {
|
||||
sliderBubble.classList.add('hide');
|
||||
hasHideClass = true;
|
||||
});
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
.emby-tab-button {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
border: 2px solid transparent;
|
||||
border-width: 0 0 2px 0;
|
||||
cursor: pointer;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['dom', 'scroller', 'browser', 'registerElement', 'css!./emby-tabs', 'scrollStyles'], function (dom, scroller, browser) {
|
||||
'use strict';
|
||||
|
||||
var EmbyTabs = Object.create(HTMLDivElement.prototype);
|
||||
var buttonClass = 'emby-tab-button';
|
||||
|
@ -78,7 +79,7 @@
|
|||
|
||||
var onAnimationFinish = function () {
|
||||
|
||||
//if (tabs.getAttribute('data-selectionbar') != 'false') {
|
||||
//if (tabs.getAttribute('data-selectionbar') !== 'false') {
|
||||
// showButtonSelectionBar(newButton);
|
||||
//}
|
||||
newButton.classList.add(activeButtonClass);
|
||||
|
@ -103,7 +104,7 @@
|
|||
var current = tabs.querySelector('.' + activeButtonClass);
|
||||
var tabButton = dom.parentWithClass(e.target, buttonClass);
|
||||
|
||||
if (tabButton && tabButton != current) {
|
||||
if (tabButton && tabButton !== current) {
|
||||
|
||||
if (current) {
|
||||
current.classList.remove(activeButtonClass);
|
||||
|
@ -186,7 +187,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
if (tabs.getAttribute('data-selectionbar') == 'false') {
|
||||
if (tabs.getAttribute('data-selectionbar') === 'false') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -253,7 +254,7 @@
|
|||
|
||||
var tabButtons = tabs.querySelectorAll('.' + buttonClass);
|
||||
|
||||
if (current == selected || triggerEvent === false) {
|
||||
if (current === selected || triggerEvent === false) {
|
||||
|
||||
tabs.dispatchEvent(new CustomEvent("beforetabchange", {
|
||||
detail: {
|
||||
|
@ -269,7 +270,7 @@
|
|||
var currentTabButton = tabButtons[current];
|
||||
moveSelectionBar(tabs, tabButtons[selected], currentTabButton, false);
|
||||
|
||||
if (current != selected && currentTabButton) {
|
||||
if (current !== selected && currentTabButton) {
|
||||
currentTabButton.classList.remove(activeButtonClass);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
margin: 0;
|
||||
margin-bottom: 0 !important;
|
||||
background: none;
|
||||
border: 1px solid rgb(221, 221, 221);
|
||||
border: 1px solid #383838;
|
||||
border-width: 0 0 1px 0;
|
||||
/* Prefixed box-sizing rules necessary for older browsers */
|
||||
-webkit-box-sizing: border-box;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['layoutManager', 'browser', 'css!./emby-textarea', 'registerElement'], function (layoutManager, browser) {
|
||||
'use strict';
|
||||
|
||||
function autoGrow(textarea, maxLines) {
|
||||
var self = this;
|
||||
|
@ -84,7 +85,7 @@
|
|||
bubbles: false,
|
||||
cancelable: false
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperty(HTMLTextAreaElement.prototype, 'value', descriptor);
|
||||
supportsFloatingLabel = true;
|
||||
|
@ -113,7 +114,7 @@
|
|||
label.innerHTML = this.getAttribute('label') || '';
|
||||
label.classList.add('textareaLabel');
|
||||
|
||||
if (!supportsFloatingLabel || this.type == 'date') {
|
||||
if (!supportsFloatingLabel || this.type === 'date') {
|
||||
label.classList.add('nofloat');
|
||||
}
|
||||
|
||||
|
|
137
dashboard-ui/bower_components/emby-webcomponents/emby-toggle/emby-toggle.css
vendored
Normal file
137
dashboard-ui/bower_components/emby-webcomponents/emby-toggle/emby-toggle.css
vendored
Normal file
|
@ -0,0 +1,137 @@
|
|||
.mdl-switch {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
vertical-align: middle;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.toggleContainer {
|
||||
margin-bottom: 1.8em;
|
||||
}
|
||||
|
||||
.mdl-switch__input {
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
opacity: 0;
|
||||
-ms-appearance: none;
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.mdl-switch__trackContainer {
|
||||
position: relative;
|
||||
width: 2.9em;
|
||||
}
|
||||
|
||||
.mdl-switch__track {
|
||||
background: rgba(255,255,255, 0.26);
|
||||
height: 1em;
|
||||
border-radius: 1em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mdl-switch__input:checked + .mdl-switch__label + .mdl-switch__trackContainer > .mdl-switch__track {
|
||||
background: rgba(82,181,75, 0.5);
|
||||
}
|
||||
|
||||
.mdl-switch__input.red:checked + .mdl-switch__label + .mdl-switch__trackContainer > .mdl-switch__track {
|
||||
background: rgba(204,51,51, 0.5);
|
||||
}
|
||||
|
||||
.mdl-switch__input[disabled] + .mdl-switch__label + .mdl-switch__trackContainer > .mdl-switch__track {
|
||||
background: rgba(0,0,0, 0.12);
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.mdl-switch__thumb {
|
||||
background: #999;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: -.25em;
|
||||
height: 1.44em;
|
||||
width: 1.44em;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||
transition-duration: 0.28s;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-property: left;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.mdl-switch__input:checked + .mdl-switch__label + .mdl-switch__trackContainer > .mdl-switch__thumb {
|
||||
background: rgb(82,181,75);
|
||||
left: 1.466em;
|
||||
box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), 0 3px 3px -2px rgba(0, 0, 0, 0.2), 0 1px 8px 0 rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.mdl-switch__input.red:checked + .mdl-switch__label + .mdl-switch__trackContainer > .mdl-switch__thumb {
|
||||
background: rgb(204,51,51);
|
||||
box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), 0 3px 3px -2px rgba(0, 0, 0, 0.2), 0 1px 8px 0 rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.mdl-switch__input[disabled] + .mdl-switch__label + .mdl-switch__trackContainer > .mdl-switch__thumb {
|
||||
background: rgb(189,189,189);
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.mdl-switch__focus-helper {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
width: .6em;
|
||||
height: .6em;
|
||||
border-radius: 50%;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.mdl-switch__input:focus + .mdl-switch__label + .mdl-switch__trackContainer .mdl-switch__focus-helper {
|
||||
box-shadow: 0 0 0px 20px rgba(255,255,255, 0.26);
|
||||
background-color: rgba(255,255,255, 0.26);
|
||||
}
|
||||
|
||||
.mdl-switch__input:checked:focus + .mdl-switch__label + .mdl-switch__trackContainer .mdl-switch__focus-helper {
|
||||
box-shadow: 0 0 0px 20px rgba(82,181,75, 0.26);
|
||||
background-color: rgba(82,181,75, 0.26);
|
||||
}
|
||||
|
||||
.mdl-switch__input.red:checked:focus + .mdl-switch__label + .mdl-switch__trackContainer .mdl-switch__focus-helper {
|
||||
box-shadow: 0 0 0px 20px rgba(204,51,51, 0.26);
|
||||
background-color: rgba(204,51,51, 0.26);
|
||||
}
|
||||
|
||||
.mdl-switch__label {
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-left: .7em;
|
||||
}
|
||||
|
||||
.mdl-switch__input[disabled] .mdl-switch__label {
|
||||
color: rgb(189,189,189);
|
||||
cursor: auto;
|
||||
}
|
50
dashboard-ui/bower_components/emby-webcomponents/emby-toggle/emby-toggle.js
vendored
Normal file
50
dashboard-ui/bower_components/emby-webcomponents/emby-toggle/emby-toggle.js
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
define(['css!./emby-toggle', 'registerElement'], function () {
|
||||
'use strict';
|
||||
|
||||
var EmbyTogglePrototype = Object.create(HTMLInputElement.prototype);
|
||||
|
||||
function onKeyDown(e) {
|
||||
|
||||
// Don't submit form on enter
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
|
||||
this.checked = !this.checked;
|
||||
|
||||
this.dispatchEvent(new CustomEvent('change', {
|
||||
bubbles: true
|
||||
}));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
EmbyTogglePrototype.attachedCallback = function () {
|
||||
|
||||
if (this.getAttribute('data-embytoggle') === 'true') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setAttribute('data-embytoggle', 'true');
|
||||
|
||||
this.classList.add('mdl-switch__input');
|
||||
|
||||
var labelElement = this.parentNode;
|
||||
labelElement.classList.add('mdl-switch');
|
||||
labelElement.classList.add('mdl-js-switch');
|
||||
|
||||
var labelTextElement = labelElement.querySelector('span');
|
||||
|
||||
labelElement.insertAdjacentHTML('beforeend', '<div class="mdl-switch__trackContainer"><div class="mdl-switch__track"></div><div class="mdl-switch__thumb"><span class="mdl-switch__focus-helper"></span></div></div>');
|
||||
|
||||
labelTextElement.classList.add('toggleButtonLabel');
|
||||
labelTextElement.classList.add('mdl-switch__label');
|
||||
|
||||
this.addEventListener('keydown', onKeyDown);
|
||||
};
|
||||
|
||||
document.registerElement('emby-toggle', {
|
||||
prototype: EmbyTogglePrototype,
|
||||
extends: 'input'
|
||||
});
|
||||
});
|
|
@ -1,10 +1,11 @@
|
|||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
function getFetchPromise(request) {
|
||||
|
||||
var headers = request.headers || {};
|
||||
|
||||
if (request.dataType == 'json') {
|
||||
if (request.dataType === 'json') {
|
||||
headers.accept = 'application/json';
|
||||
}
|
||||
|
||||
|
@ -107,9 +108,9 @@
|
|||
|
||||
if (response.status < 400) {
|
||||
|
||||
if (request.dataType == 'json' || request.headers.accept == 'application/json') {
|
||||
if (request.dataType === 'json' || request.headers.accept === 'application/json') {
|
||||
return response.json();
|
||||
} else if (request.dataType == 'text' || (response.headers.get('Content-Type') || '').toLowerCase().indexOf('text/') == 0) {
|
||||
} else if (request.dataType === 'text' || (response.headers.get('Content-Type') || '').toLowerCase().indexOf('text/') === 0) {
|
||||
return response.text();
|
||||
} else {
|
||||
return response;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['dom'], function (dom) {
|
||||
'use strict';
|
||||
|
||||
var scopes = [];
|
||||
function pushScope(elem) {
|
||||
|
@ -48,7 +49,7 @@ define(['dom'], function (dom) {
|
|||
var focusableContainerTagNames = ['BODY', 'DIALOG'];
|
||||
var focusableQuery = focusableTagNames.map(function (t) {
|
||||
|
||||
if (t == 'INPUT') {
|
||||
if (t === 'INPUT') {
|
||||
t += ':not([type="range"])';
|
||||
}
|
||||
return t + ':not([tabindex="-1"]):not(:disabled)';
|
||||
|
@ -57,7 +58,7 @@ define(['dom'], function (dom) {
|
|||
|
||||
function isFocusable(elem) {
|
||||
|
||||
if (focusableTagNames.indexOf(elem.tagName) != -1) {
|
||||
if (focusableTagNames.indexOf(elem.tagName) !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -99,13 +100,13 @@ define(['dom'], function (dom) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (elem.getAttribute('tabindex') == "-1") {
|
||||
if (elem.getAttribute('tabindex') === "-1") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (elem.tagName == 'INPUT') {
|
||||
if (elem.tagName === 'INPUT') {
|
||||
var type = elem.type;
|
||||
if (type == 'range') {
|
||||
if (type === 'range') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +140,7 @@ define(['dom'], function (dom) {
|
|||
|
||||
function isFocusContainer(elem, direction) {
|
||||
|
||||
if (focusableContainerTagNames.indexOf(elem.tagName) != -1) {
|
||||
if (focusableContainerTagNames.indexOf(elem.tagName) !== -1) {
|
||||
return true;
|
||||
}
|
||||
if (elem.classList.contains('focuscontainer')) {
|
||||
|
@ -151,7 +152,7 @@ define(['dom'], function (dom) {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
else if (direction == 3) {
|
||||
else if (direction === 3) {
|
||||
if (elem.classList.contains('focuscontainer-down')) {
|
||||
return true;
|
||||
}
|
||||
|
@ -230,11 +231,11 @@ define(['dom'], function (dom) {
|
|||
for (var i = 0, length = focusable.length; i < length; i++) {
|
||||
var curr = focusable[i];
|
||||
|
||||
if (curr == activeElement) {
|
||||
if (curr === activeElement) {
|
||||
continue;
|
||||
}
|
||||
// Don't refocus into the same container
|
||||
if (curr == focusableContainer) {
|
||||
if (curr === focusableContainer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -256,7 +257,7 @@ define(['dom'], function (dom) {
|
|||
if (elementRect.left >= rect.left) {
|
||||
continue;
|
||||
}
|
||||
if (elementRect.right == rect.right) {
|
||||
if (elementRect.right === rect.right) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
@ -265,7 +266,7 @@ define(['dom'], function (dom) {
|
|||
if (elementRect.right <= rect.right) {
|
||||
continue;
|
||||
}
|
||||
if (elementRect.left == rect.left) {
|
||||
if (elementRect.left === rect.left) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
@ -304,8 +305,8 @@ define(['dom'], function (dom) {
|
|||
|
||||
// See if there's a focusable container, and if so, send the focus command to that
|
||||
var nearestElementFocusableParent = dom.parentWithClass(nearestElement, 'focusable');
|
||||
if (nearestElementFocusableParent && nearestElementFocusableParent != nearestElement && activeElement) {
|
||||
if (dom.parentWithClass(activeElement, 'focusable') != nearestElementFocusableParent) {
|
||||
if (nearestElementFocusableParent && nearestElementFocusableParent !== nearestElement && activeElement) {
|
||||
if (dom.parentWithClass(activeElement, 'focusable') !== nearestElementFocusableParent) {
|
||||
nearestElement = nearestElementFocusableParent;
|
||||
}
|
||||
}
|
||||
|
@ -404,12 +405,12 @@ define(['dom'], function (dom) {
|
|||
function sortNodesT(a, b) {
|
||||
|
||||
var result = a.distT - b.distT;
|
||||
if (result != 0) {
|
||||
if (result !== 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = a.index - b.index;
|
||||
if (result != 0) {
|
||||
if (result !== 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
background-color: #222326;
|
||||
}
|
||||
|
||||
.formDialogHeader-clear, .formDialogFooter-clear {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.formDialogHeaderTitle {
|
||||
margin-left: .25em;
|
||||
/* In case of h1, h2, h3 */
|
||||
|
@ -27,7 +31,7 @@
|
|||
}
|
||||
|
||||
.dialogContentInner {
|
||||
padding: .5em 1.5em 20em 1.5em;
|
||||
padding: .5em 1em 20em 1em;
|
||||
}
|
||||
|
||||
.dialogContentInner-mini {
|
||||
|
@ -49,11 +53,16 @@
|
|||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
padding: 1.5em;
|
||||
padding: 1.25em 1em;
|
||||
/* Without this emby-checkbox is able to appear on top */
|
||||
z-index: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.formDialogFooter-flex {
|
||||
position: static;
|
||||
}
|
||||
|
||||
.formDialogFooterItem {
|
||||
|
@ -61,6 +70,14 @@
|
|||
margin-right: .5em !important;
|
||||
flex-grow: 1;
|
||||
text-align: center;
|
||||
flex-basis: 0;
|
||||
}
|
||||
|
||||
.formDialogFooterItem-autosize {
|
||||
flex-basis: initial;
|
||||
flex-grow: initial;
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
@media all and (min-width: 800px) {
|
||||
|
@ -68,6 +85,11 @@
|
|||
.formDialogFooterItem {
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.dialogContentInner {
|
||||
padding-left: 1.5em;
|
||||
padding-right: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 1280px) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['connectionManager', 'userSettings', 'events'], function (connectionManager, userSettings, events) {
|
||||
'use strict';
|
||||
|
||||
var allTranslations = {};
|
||||
var currentCulture;
|
||||
|
@ -69,20 +70,20 @@ define(['connectionManager', 'userSettings', 'events'], function (connectionMana
|
|||
|
||||
// If it's de-DE, convert to just de
|
||||
var parts = culture.split('-');
|
||||
if (parts.length == 2) {
|
||||
if (parts[0].toLowerCase() == parts[1].toLowerCase()) {
|
||||
if (parts.length === 2) {
|
||||
if (parts[0].toLowerCase() === parts[1].toLowerCase()) {
|
||||
culture = parts[0].toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
var lower = culture.toLowerCase();
|
||||
|
||||
if (lower == 'ca-es') {
|
||||
if (lower === 'ca-es') {
|
||||
return 'ca';
|
||||
}
|
||||
|
||||
// normalize Swedish
|
||||
if (lower == 'sv-se') {
|
||||
if (lower === 'sv-se') {
|
||||
return 'sv';
|
||||
}
|
||||
|
||||
|
@ -130,12 +131,12 @@ define(['connectionManager', 'userSettings', 'events'], function (connectionMana
|
|||
lang = normalizeLocaleName(lang);
|
||||
|
||||
var filtered = translations.filter(function (t) {
|
||||
return normalizeLocaleName(t.lang) == lang;
|
||||
return normalizeLocaleName(t.lang) === lang;
|
||||
});
|
||||
|
||||
if (!filtered.length) {
|
||||
filtered = translations.filter(function (t) {
|
||||
return normalizeLocaleName(t.lang) == 'en-us';
|
||||
return normalizeLocaleName(t.lang) === 'en-us';
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -148,7 +149,7 @@ define(['connectionManager', 'userSettings', 'events'], function (connectionMana
|
|||
|
||||
var url = filtered[0].path;
|
||||
|
||||
url += url.indexOf('?') == -1 ? '?' : '&';
|
||||
url += url.indexOf('?') === -1 ? '?' : '&';
|
||||
url += 'v=' + cacheParam;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
@ -217,14 +218,14 @@ define(['connectionManager', 'userSettings', 'events'], function (connectionMana
|
|||
|
||||
var startIndex = html.indexOf('${');
|
||||
|
||||
if (startIndex == -1) {
|
||||
if (startIndex === -1) {
|
||||
return html;
|
||||
}
|
||||
|
||||
startIndex += 2;
|
||||
var endIndex = html.indexOf('}', startIndex);
|
||||
|
||||
if (endIndex == -1) {
|
||||
if (endIndex === -1) {
|
||||
return html;
|
||||
}
|
||||
|
||||
|
@ -250,7 +251,7 @@ define(['connectionManager', 'userSettings', 'events'], function (connectionMana
|
|||
|
||||
events.on(connectionManager, 'localusersignedin', updateCurrentCulture);
|
||||
events.on(userSettings, 'change', function (e, name) {
|
||||
if (name == 'language') {
|
||||
if (name === 'language') {
|
||||
updateCurrentCulture();
|
||||
}
|
||||
});
|
||||
|
|
106
dashboard-ui/bower_components/emby-webcomponents/guide/guide-categories.js
vendored
Normal file
106
dashboard-ui/bower_components/emby-webcomponents/guide/guide-categories.js
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectionManager', 'require', 'loading', 'scrollHelper', 'emby-checkbox', 'css!./../formdialog', 'material-icons'], function (dialogHelper, globalize, userSettings, layoutManager, connectionManager, require, loading, scrollHelper) {
|
||||
'use strict';
|
||||
|
||||
function save(context, options) {
|
||||
|
||||
var categories = [];
|
||||
|
||||
var chkCategorys = context.querySelectorAll('.chkCategory');
|
||||
for (var i = 0, length = chkCategorys.length; i < length; i++) {
|
||||
|
||||
var type = chkCategorys[i].getAttribute('data-type');
|
||||
|
||||
if (chkCategorys[i].checked) {
|
||||
categories.push(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (categories.length >= 4) {
|
||||
categories.push('series');
|
||||
}
|
||||
|
||||
// differentiate between none and all
|
||||
categories.push('all');
|
||||
options.categories = categories;
|
||||
}
|
||||
|
||||
function load(context, options) {
|
||||
|
||||
var selectedCategories = options.categories || [];
|
||||
|
||||
var chkCategorys = context.querySelectorAll('.chkCategory');
|
||||
for (var i = 0, length = chkCategorys.length; i < length; i++) {
|
||||
|
||||
var type = chkCategorys[i].getAttribute('data-type');
|
||||
|
||||
chkCategorys[i].checked = !selectedCategories.length || selectedCategories.indexOf(type) !== -1;
|
||||
}
|
||||
}
|
||||
|
||||
function showEditor(options) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
var settingsChanged = false;
|
||||
|
||||
require(['text!./guide-categories.template.html'], function (template) {
|
||||
|
||||
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 = '';
|
||||
|
||||
html += globalize.translateDocument(template, 'sharedcomponents');
|
||||
|
||||
dlg.innerHTML = html;
|
||||
|
||||
dlg.addEventListener('change', function () {
|
||||
|
||||
settingsChanged = true;
|
||||
});
|
||||
|
||||
dlg.addEventListener('close', function () {
|
||||
|
||||
if (layoutManager.tv) {
|
||||
scrollHelper.centerFocus.off(dlg.querySelector('.formDialogContent'), false);
|
||||
}
|
||||
|
||||
save(dlg, options);
|
||||
|
||||
if (settingsChanged) {
|
||||
resolve(options);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
|
||||
dlg.querySelector('.btnCancel').addEventListener('click', function () {
|
||||
dialogHelper.close(dlg);
|
||||
});
|
||||
|
||||
if (layoutManager.tv) {
|
||||
scrollHelper.centerFocus.on(dlg.querySelector('.formDialogContent'), false);
|
||||
}
|
||||
|
||||
load(dlg, options);
|
||||
dialogHelper.open(dlg);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
show: showEditor
|
||||
};
|
||||
});
|
29
dashboard-ui/bower_components/emby-webcomponents/guide/guide-categories.template.html
vendored
Normal file
29
dashboard-ui/bower_components/emby-webcomponents/guide/guide-categories.template.html
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
<div class="formDialogHeader">
|
||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="md-icon"></i></button>
|
||||
<h3 class="formDialogHeaderTitle">
|
||||
${Categories}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="formDialogContent smoothScrollY">
|
||||
<form class="dialogContentInner dialog-content-centered" style="padding-top:2em;">
|
||||
|
||||
<div class="checkboxList">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" class="chkCategory" data-type="movies" />
|
||||
<span>${Movies}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" class="chkCategory" data-type="sports" />
|
||||
<span>${Sports}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" class="chkCategory" data-type="kids" />
|
||||
<span>${Kids}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" class="chkCategory" data-type="news" />
|
||||
<span>${News}</span>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
|
@ -1,27 +1,66 @@
|
|||
define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectionManager', 'require', 'loading', 'scrollHelper', 'emby-checkbox', 'css!./../formdialog', 'material-icons'], function (dialogHelper, globalize, userSettings, layoutManager, connectionManager, require, loading, scrollHelper) {
|
||||
define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectionManager', 'require', 'loading', 'scrollHelper', 'emby-checkbox', 'emby-radio', 'css!./../formdialog', 'material-icons'], function (dialogHelper, globalize, userSettings, layoutManager, connectionManager, require, loading, scrollHelper) {
|
||||
'use strict';
|
||||
|
||||
function save(context) {
|
||||
|
||||
var i, length;
|
||||
|
||||
var chkIndicators = context.querySelectorAll('.chkIndicator');
|
||||
for (var i = 0, length = chkIndicators.length; i < length; i++) {
|
||||
for (i = 0, length = chkIndicators.length; i < length; i++) {
|
||||
|
||||
var type = chkIndicators[i].getAttribute('data-type');
|
||||
userSettings.set('guide-indicator-' + type, chkIndicators[i].checked);
|
||||
}
|
||||
|
||||
userSettings.set('guide-colorcodedbackgrounds', context.querySelector('.chkColorCodedBackgrounds').checked);
|
||||
userSettings.set('livetv-favoritechannelsattop', context.querySelector('.chkFavoriteChannelsAtTop').checked);
|
||||
|
||||
var sortBys = context.querySelectorAll('.chkSortOrder');
|
||||
for (i = 0, length = sortBys.length; i < length; i++) {
|
||||
if (sortBys[i].checked) {
|
||||
userSettings.set('livetv-channelorder', sortBys[i].value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function load(context) {
|
||||
|
||||
var i, length;
|
||||
|
||||
var chkIndicators = context.querySelectorAll('.chkIndicator');
|
||||
for (var i = 0, length = chkIndicators.length; i < length; i++) {
|
||||
for (i = 0, length = chkIndicators.length; i < length; i++) {
|
||||
|
||||
var type = chkIndicators[i].getAttribute('data-type');
|
||||
|
||||
if (chkIndicators[i].getAttribute('data-default') == 'true') {
|
||||
chkIndicators[i].checked = userSettings.get('guide-indicator-' + type) != 'false';
|
||||
if (chkIndicators[i].getAttribute('data-default') === 'true') {
|
||||
chkIndicators[i].checked = userSettings.get('guide-indicator-' + type) !== 'false';
|
||||
} else {
|
||||
chkIndicators[i].checked = userSettings.get('guide-indicator-' + type) == 'true';
|
||||
chkIndicators[i].checked = userSettings.get('guide-indicator-' + type) === 'true';
|
||||
}
|
||||
}
|
||||
|
||||
context.querySelector('.chkColorCodedBackgrounds').checked = userSettings.get('guide-colorcodedbackgrounds') === 'true';
|
||||
context.querySelector('.chkFavoriteChannelsAtTop').checked = userSettings.get('livetv-favoritechannelsattop') !== 'false';
|
||||
|
||||
var sortByValue = userSettings.get('livetv-channelorder') || 'DatePlayed';
|
||||
|
||||
var sortBys = context.querySelectorAll('.chkSortOrder');
|
||||
for (i = 0, length = sortBys.length; i < length; i++) {
|
||||
sortBys[i].checked = sortBys[i].value === sortByValue;
|
||||
}
|
||||
}
|
||||
|
||||
function onSortByChange() {
|
||||
var newValue = this.value;
|
||||
if (this.checked) {
|
||||
var changed = options.query.SortBy !== newValue;
|
||||
|
||||
options.query.SortBy = newValue.replace('_', ',');
|
||||
options.query.StartIndex = 0;
|
||||
|
||||
if (options.callback && changed) {
|
||||
options.callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,14 @@
|
|||
<div class="formDialogContent smoothScrollY">
|
||||
<form class="dialogContentInner dialog-content-centered" style="padding-top:2em;">
|
||||
|
||||
<h3 class="checkboxListLabel">${SortChannelsBy}</h3>
|
||||
<label class="radio-label-block"><input type="radio" is="emby-radio" name="ChannelSortOrder" value="Number" class="chkSortOrder" /><span>${ChannelNumber}</span></label>
|
||||
<label class="radio-label-block"><input type="radio" is="emby-radio" name="ChannelSortOrder" value="DatePlayed" class="chkSortOrder" /><span>${RecentlyWatched}</span></label>
|
||||
<br />
|
||||
<label class="checkboxContainer">
|
||||
<input type="checkbox" is="emby-checkbox" class="chkFavoriteChannelsAtTop" />
|
||||
<span>${PlaceFavoriteChannelsAtBeginning}</span>
|
||||
</label>
|
||||
<h3 class="checkboxListLabel">${ShowIndicatorsFor}</h3>
|
||||
<div class="checkboxList">
|
||||
<label>
|
||||
|
@ -30,5 +38,10 @@
|
|||
<span>${RepeatEpisodes}</span>
|
||||
</label>
|
||||
</div>
|
||||
<br />
|
||||
<label class="checkboxContainer">
|
||||
<input type="checkbox" is="emby-checkbox" class="chkColorCodedBackgrounds" />
|
||||
<span>${EnableColorCodedBackgrounds}</span>
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
|
@ -8,6 +8,8 @@
|
|||
white-space: nowrap;
|
||||
width: 100%;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
padding-left: 3.4em;
|
||||
}
|
||||
|
||||
.tvProgramSectionHeader {
|
||||
|
@ -21,34 +23,10 @@
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.tvProgramTimeSlotInner {
|
||||
padding: .5em;
|
||||
}
|
||||
|
||||
.tvProgramInfo {
|
||||
vertical-align: middle;
|
||||
padding: .5em .5em;
|
||||
border-bottom: .65vh solid #121212;
|
||||
}
|
||||
|
||||
.tvProgramCurrentTimeSlot {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.tvProgramName {
|
||||
color: #fff;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
.tvProgramTime {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.guideProgramIndicator {
|
||||
text-transform: uppercase;
|
||||
border-radius: 2px;
|
||||
margin-right: .5em;
|
||||
color: #fff;
|
||||
font-size: 74%;
|
||||
padding: .2em .25em;
|
||||
display: inline-flex;
|
||||
|
@ -58,48 +36,8 @@
|
|||
color: #fff;
|
||||
}
|
||||
|
||||
.newTvProgram {
|
||||
background: #64A239;
|
||||
}
|
||||
|
||||
.liveTvProgram {
|
||||
background: #EC407A;
|
||||
}
|
||||
|
||||
.premiereTvProgram {
|
||||
background: #EF6C00;
|
||||
}
|
||||
|
||||
.repeatTvProgram {
|
||||
background: #009688;
|
||||
}
|
||||
|
||||
.programAccent {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.sportsAccent {
|
||||
background-color: #0A7C33;
|
||||
}
|
||||
|
||||
.newsAccent {
|
||||
background-color: #523378;
|
||||
}
|
||||
|
||||
.movieAccent {
|
||||
background-color: #A43913;
|
||||
}
|
||||
|
||||
.childAccent {
|
||||
background-color: #0B487D;
|
||||
}
|
||||
|
||||
.channelTimeslotHeader {
|
||||
float: left;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.timeslotHeaders {
|
||||
|
@ -109,15 +47,14 @@
|
|||
.programContainer {
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.programGridContainer {
|
||||
margin-left: 12.2vw;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.channelPrograms {
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.timeslotHeadersInner {
|
||||
|
@ -200,7 +137,6 @@
|
|||
background: rgba(40, 40, 40, .9);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff !important;
|
||||
text-decoration: none;
|
||||
/* Needed in firefox */
|
||||
text-align: left;
|
||||
|
@ -281,7 +217,7 @@
|
|||
.channelHeaderCell {
|
||||
border-bottom: .65vh solid #121212 !important;
|
||||
background-size: auto 70%;
|
||||
background-position: 90% center;
|
||||
background-position: 92% center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
|
@ -301,6 +237,12 @@
|
|||
|
||||
.channelPrograms, .channelHeaderCell {
|
||||
height: 4em;
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.channelPrograms {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.channelPrograms-tv, .channelHeaderCell-tv {
|
||||
|
@ -319,14 +261,6 @@
|
|||
height: 3em;
|
||||
}
|
||||
|
||||
.pointerInput .channelHeaderCell:hover {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
.channelList {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.programGrid {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
@ -343,7 +277,6 @@
|
|||
border-left: .65vh solid #121212 !important;
|
||||
background-color: rgba(32, 32, 32, .95);
|
||||
display: flex;
|
||||
color: #fff !important;
|
||||
text-decoration: none;
|
||||
overflow: hidden;
|
||||
align-items: center;
|
||||
|
@ -352,15 +285,32 @@
|
|||
contain: strict;
|
||||
}
|
||||
|
||||
.timeslotCellInner {
|
||||
.programAccent {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: #fff !important;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.sportsAccent {
|
||||
background-color: #3949AB;
|
||||
}
|
||||
|
||||
.movieAccent {
|
||||
background-color: #5E35B1;
|
||||
}
|
||||
|
||||
.childAccent {
|
||||
background-color: #039BE5;
|
||||
}
|
||||
|
||||
.newsAccent {
|
||||
background-color: #43A047;
|
||||
}
|
||||
|
||||
.specialsAccent {
|
||||
background-color: #FB8C00;
|
||||
}
|
||||
|
||||
.guideProgramName {
|
||||
|
@ -371,11 +321,6 @@
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
.guideProgramTime {
|
||||
padding: 0 .5em .35em;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.programIcon {
|
||||
margin-left: auto;
|
||||
margin-right: .25em;
|
||||
|
@ -419,8 +364,41 @@
|
|||
}
|
||||
}
|
||||
|
||||
.channelsContainer {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.btnCategories {
|
||||
margin: 0 .3em 0 .5em !important;
|
||||
padding: 0 !important;
|
||||
flex-shrink: 0;
|
||||
background: rgba(40, 40, 40, .9);
|
||||
border-radius: 0 !important;
|
||||
width: 2.6em;
|
||||
font-weight: normal !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.btnCategoriesText {
|
||||
transform: rotate(90deg);
|
||||
text-transform: uppercase;
|
||||
transform-origin: left;
|
||||
margin-left: 1.2em;
|
||||
letter-spacing: .25em;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
margin-top: 1em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.channelList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.channelList, .programGrid {
|
||||
height: auto !important;
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
.programCell, .channelHeaderCell, .btnSelectDate {
|
||||
|
@ -435,6 +413,11 @@
|
|||
color: #cc3333 !important;
|
||||
}
|
||||
|
||||
.seriesTimerIcon-inactive {
|
||||
color: inherit !important;
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.visibleGuideScroller::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
|
@ -460,3 +443,14 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media all and (max-width: 800px), all and (max-height: 600px) {
|
||||
|
||||
.tvGuideHeader {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.btnCategories {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['require', 'browser', 'globalize', 'connectionManager', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'registrationservices', 'dom', 'clearButtonStyle', 'css!./guide.css', 'material-icons', 'scrollStyles', 'emby-button', 'paper-icon-button-light'], function (require, browser, globalize, connectionManager, serverNotifications, loading, datetime, focusManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, registrationServices, dom) {
|
||||
define(['require', 'browser', 'globalize', 'connectionManager', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'registrationservices', 'dom', 'clearButtonStyle', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-button', 'paper-icon-button-light'], function (require, browser, globalize, connectionManager, serverNotifications, loading, datetime, focusManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, registrationServices, dom) {
|
||||
'use strict';
|
||||
|
||||
function showViewSettings(instance) {
|
||||
|
||||
|
@ -9,12 +10,24 @@
|
|||
});
|
||||
}
|
||||
|
||||
function showCategoryOptions(instance) {
|
||||
|
||||
require(['guide-categories-dialog'], function (guideCategoriesDialog) {
|
||||
guideCategoriesDialog.show(instance.categoryOptions).then(function (categoryOptions) {
|
||||
|
||||
instance.categoryOptions = categoryOptions;
|
||||
instance.refresh();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function Guide(options) {
|
||||
|
||||
var self = this;
|
||||
var items = {};
|
||||
|
||||
self.options = options;
|
||||
self.categoryOptions = { categories: [] };
|
||||
|
||||
// 30 mins
|
||||
var cellCurationMinutes = 30;
|
||||
|
@ -26,14 +39,6 @@
|
|||
var currentStartIndex = 0;
|
||||
var currentChannelLimit = 0;
|
||||
|
||||
var channelQuery = {
|
||||
|
||||
StartIndex: 0,
|
||||
EnableFavoriteSorting: true
|
||||
};
|
||||
|
||||
var channelsPromise;
|
||||
|
||||
self.refresh = function () {
|
||||
|
||||
currentDate = null;
|
||||
|
@ -151,6 +156,12 @@
|
|||
|
||||
var apiClient = connectionManager.currentApiClient();
|
||||
|
||||
var channelQuery = {
|
||||
|
||||
StartIndex: 0,
|
||||
EnableFavoriteSorting: userSettings.get('livetv-favoritechannelsattop') !== 'false'
|
||||
};
|
||||
|
||||
channelQuery.UserId = apiClient.getCurrentUserId();
|
||||
|
||||
getChannelLimit(context).then(function (channelLimit) {
|
||||
|
@ -165,7 +176,44 @@
|
|||
channelQuery.EnableUserData = false;
|
||||
channelQuery.EnableImageTypes = "Primary";
|
||||
|
||||
channelsPromise = channelsPromise || apiClient.getLiveTvChannels(channelQuery);
|
||||
var categories = self.categoryOptions.categories || [];
|
||||
var displayMovieContent = !categories.length || categories.indexOf('movies') !== -1;
|
||||
var displaySportsContent = !categories.length || categories.indexOf('sports') !== -1;
|
||||
var displayNewsContent = !categories.length || categories.indexOf('news') !== -1;
|
||||
var displayKidsContent = !categories.length || categories.indexOf('kids') !== -1;
|
||||
var displaySeriesContent = !categories.length || categories.indexOf('series') !== -1;
|
||||
|
||||
if (displayMovieContent && displaySportsContent && displayNewsContent && displayKidsContent) {
|
||||
channelQuery.IsMovie = null;
|
||||
channelQuery.IsSports = null;
|
||||
channelQuery.IsKids = null;
|
||||
channelQuery.IsNews = null;
|
||||
channelQuery.IsSeries = null;
|
||||
} else {
|
||||
if (displayNewsContent) {
|
||||
channelQuery.IsNews = true;
|
||||
}
|
||||
if (displaySportsContent) {
|
||||
channelQuery.IsSports = true;
|
||||
}
|
||||
if (displayKidsContent) {
|
||||
channelQuery.IsKids = true;
|
||||
}
|
||||
if (displayMovieContent) {
|
||||
channelQuery.IsMovie = true;
|
||||
}
|
||||
if (displaySeriesContent) {
|
||||
channelQuery.IsSeries = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (userSettings.get('livetv-channelorder') === 'Number') {
|
||||
channelQuery.SortBy = "SortName";
|
||||
channelQuery.SortOrder = "Ascending";
|
||||
} else {
|
||||
channelQuery.SortBy = "DatePlayed";
|
||||
channelQuery.SortOrder = "Descending";
|
||||
}
|
||||
|
||||
var date = newStartDate;
|
||||
// Add one second to avoid getting programs that are just ending
|
||||
|
@ -175,7 +223,7 @@
|
|||
var nextDay = new Date(date.getTime() + msPerDay - 2000);
|
||||
|
||||
console.log(nextDay);
|
||||
channelsPromise.then(function (channelsResult) {
|
||||
apiClient.getLiveTvChannels(channelQuery).then(function (channelsResult) {
|
||||
|
||||
var btnPreviousPage = context.querySelector('.btnPreviousPage');
|
||||
var btnNextPage = context.querySelector('.btnNextPage');
|
||||
|
@ -299,6 +347,37 @@
|
|||
return null;
|
||||
}
|
||||
|
||||
function getTimerIndicator(item) {
|
||||
|
||||
var status;
|
||||
|
||||
if (item.Type === 'SeriesTimer') {
|
||||
return '<i class="md-icon programIcon seriesTimerIcon"></i>';
|
||||
}
|
||||
else if (item.TimerId || item.SeriesTimerId) {
|
||||
|
||||
status = item.Status || 'Cancelled';
|
||||
}
|
||||
else if (item.Type === 'Timer') {
|
||||
|
||||
status = item.Status;
|
||||
}
|
||||
else {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (item.SeriesTimerId) {
|
||||
|
||||
if (status !== 'Cancelled') {
|
||||
return '<i class="md-icon programIcon seriesTimerIcon"></i>';
|
||||
}
|
||||
|
||||
return '<i class="md-icon programIcon seriesTimerIcon seriesTimerIcon-inactive"></i>';
|
||||
}
|
||||
|
||||
return '<i class="md-icon programIcon timerIcon"></i>';
|
||||
}
|
||||
|
||||
function getChannelProgramsHtml(context, date, channel, programs, options) {
|
||||
|
||||
var html = '';
|
||||
|
@ -307,18 +386,28 @@
|
|||
var endMs = startMs + msPerDay - 1;
|
||||
|
||||
programs = programs.filter(function (curr) {
|
||||
return curr.ChannelId == channel.Id;
|
||||
return curr.ChannelId === channel.Id;
|
||||
});
|
||||
|
||||
var cssClass = layoutManager.tv ? 'channelPrograms channelPrograms-tv' : 'channelPrograms';
|
||||
var outerCssClass = layoutManager.tv ? 'channelPrograms channelPrograms-tv' : 'channelPrograms';
|
||||
|
||||
html += '<div class="' + cssClass + '" data-channelid="' + channel.Id + '">';
|
||||
html += '<div class="' + outerCssClass + '" data-channelid="' + channel.Id + '">';
|
||||
|
||||
var clickAction = layoutManager.tv ? 'link' : 'programdialog';
|
||||
|
||||
var categories = self.categoryOptions.categories || [];
|
||||
var displayMovieContent = !categories.length || categories.indexOf('movies') !== -1;
|
||||
var displaySportsContent = !categories.length || categories.indexOf('sports') !== -1;
|
||||
var displayNewsContent = !categories.length || categories.indexOf('news') !== -1;
|
||||
var displayKidsContent = !categories.length || categories.indexOf('kids') !== -1;
|
||||
var displaySeriesContent = !categories.length || categories.indexOf('series') !== -1;
|
||||
var enableColorCodedBackgrounds = userSettings.get('guide-colorcodedbackgrounds') === 'true';
|
||||
|
||||
for (var i = 0, length = programs.length; i < length; i++) {
|
||||
|
||||
var program = programs[i];
|
||||
|
||||
if (program.ChannelId != channel.Id) {
|
||||
if (program.ChannelId !== channel.Id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -344,20 +433,45 @@
|
|||
endPercent *= 100;
|
||||
|
||||
var cssClass = "programCell clearButton itemAction";
|
||||
var addAccent = true;
|
||||
var accentCssClass = null;
|
||||
var displayInnerContent = true;
|
||||
|
||||
if (program.IsKids) {
|
||||
cssClass += " childProgramInfo";
|
||||
displayInnerContent = displayKidsContent;
|
||||
accentCssClass = 'childAccent';
|
||||
} else if (program.IsSports) {
|
||||
cssClass += " sportsProgramInfo";
|
||||
displayInnerContent = displaySportsContent;
|
||||
accentCssClass = 'sportsAccent';
|
||||
} else if (program.IsNews) {
|
||||
cssClass += " newsProgramInfo";
|
||||
displayInnerContent = displayNewsContent;
|
||||
accentCssClass = 'newsAccent';
|
||||
} else if (program.IsMovie) {
|
||||
cssClass += " movieProgramInfo";
|
||||
displayInnerContent = displayMovieContent;
|
||||
accentCssClass = 'movieAccent';
|
||||
}
|
||||
else if (program.IsSeries) {
|
||||
cssClass += " plainProgramInfo";
|
||||
displayInnerContent = displaySeriesContent;
|
||||
}
|
||||
else {
|
||||
cssClass += " plainProgramInfo";
|
||||
addAccent = false;
|
||||
displayInnerContent = displayMovieContent && displayNewsContent && displaySportsContent && displayKidsContent && displaySeriesContent;
|
||||
}
|
||||
|
||||
if (!displayInnerContent) {
|
||||
accentCssClass = null;
|
||||
}
|
||||
|
||||
if (enableColorCodedBackgrounds && accentCssClass) {
|
||||
cssClass += ' ' + accentCssClass;
|
||||
|
||||
accentCssClass = null;
|
||||
} else {
|
||||
accentCssClass = null;
|
||||
}
|
||||
|
||||
var timerAttributes = '';
|
||||
|
@ -367,49 +481,38 @@
|
|||
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";
|
||||
html += '<button data-action="' + clickAction + '"' + timerAttributes + ' data-isfolder="' + program.IsFolder + '" data-id="' + program.Id + '" data-serverid="' + program.ServerId + '" data-type="' + program.Type + '" class="' + cssClass + '" style="left:' + startPercent + '%;width:' + endPercent + '%;">';
|
||||
|
||||
html += '<div class="' + guideProgramNameClass + '">';
|
||||
if (displayInnerContent) {
|
||||
var guideProgramNameClass = "guideProgramName";
|
||||
|
||||
if (program.IsLive && options.showLiveIndicator) {
|
||||
html += '<span class="liveTvProgram guideProgramIndicator">' + globalize.translate('sharedcomponents#Live') + '</span>';
|
||||
}
|
||||
else if (program.IsPremiere && options.showPremiereIndicator) {
|
||||
html += '<span class="premiereTvProgram guideProgramIndicator">' + globalize.translate('sharedcomponents#Premiere') + '</span>';
|
||||
}
|
||||
else if (program.IsSeries && !program.IsRepeat && options.showNewIndicator) {
|
||||
html += '<span class="newTvProgram guideProgramIndicator">' + globalize.translate('sharedcomponents#AttributeNew') + '</span>';
|
||||
}
|
||||
else if (program.IsSeries && program.IsRepeat && options.showRepeatIndicator) {
|
||||
html += '<span class="repeatTvProgram guideProgramIndicator">' + globalize.translate('sharedcomponents#Repeat') + '</span>';
|
||||
}
|
||||
html += '<div class="' + guideProgramNameClass + '">';
|
||||
|
||||
html += program.Name;
|
||||
html += '</div>';
|
||||
if (program.IsLive && options.showLiveIndicator) {
|
||||
html += '<span class="liveTvProgram guideProgramIndicator">' + globalize.translate('sharedcomponents#Live') + '</span>';
|
||||
}
|
||||
else if (program.IsPremiere && options.showPremiereIndicator) {
|
||||
html += '<span class="premiereTvProgram guideProgramIndicator">' + globalize.translate('sharedcomponents#Premiere') + '</span>';
|
||||
}
|
||||
else if (program.IsSeries && !program.IsRepeat && options.showNewIndicator) {
|
||||
html += '<span class="newTvProgram guideProgramIndicator">' + globalize.translate('sharedcomponents#AttributeNew') + '</span>';
|
||||
}
|
||||
else if (program.IsSeries && program.IsRepeat && options.showRepeatIndicator) {
|
||||
html += '<span class="repeatTvProgram guideProgramIndicator">' + globalize.translate('sharedcomponents#Repeat') + '</span>';
|
||||
}
|
||||
|
||||
if (program.IsHD && options.showHdIcon) {
|
||||
html += '<i class="guideHdIcon md-icon programIcon">hd</i>';
|
||||
}
|
||||
html += program.Name;
|
||||
html += '</div>';
|
||||
|
||||
if (program.SeriesTimerId) {
|
||||
html += '<i class="seriesTimerIcon md-icon programIcon">fiber_smart_record</i>';
|
||||
}
|
||||
else if (program.TimerId) {
|
||||
html += '<i class="timerIcon md-icon programIcon">fiber_manual_record</i>';
|
||||
}
|
||||
if (program.IsHD && options.showHdIcon) {
|
||||
html += '<i class="guideHdIcon md-icon programIcon">hd</i>';
|
||||
}
|
||||
|
||||
if (addAccent) {
|
||||
html += getTimerIndicator(program);
|
||||
|
||||
if (program.IsKids) {
|
||||
html += '<div class="programAccent childAccent"></div>';
|
||||
} else if (program.IsSports) {
|
||||
html += '<div class="programAccent sportsAccent"></div>';
|
||||
} else if (program.IsNews) {
|
||||
html += '<div class="programAccent newsAccent"></div>';
|
||||
} else if (program.IsMovie) {
|
||||
html += '<div class="programAccent movieAccent"></div>';
|
||||
if (accentCssClass) {
|
||||
html += '<div class="programAccent ' + accentCssClass + '"></div>';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,11 +534,11 @@
|
|||
var allowIndicators = dom.getWindowSize().innerWidth >= 600;
|
||||
|
||||
var options = {
|
||||
showHdIcon: allowIndicators && userSettings.get('guide-indicator-hd') == 'true',
|
||||
showLiveIndicator: allowIndicators && userSettings.get('guide-indicator-live') != 'false',
|
||||
showPremiereIndicator: allowIndicators && userSettings.get('guide-indicator-premiere') != 'false',
|
||||
showNewIndicator: allowIndicators && userSettings.get('guide-indicator-new') == 'true',
|
||||
showRepeatIndicator: allowIndicators && userSettings.get('guide-indicator-repeat') == 'true'
|
||||
showHdIcon: allowIndicators && userSettings.get('guide-indicator-hd') === 'true',
|
||||
showLiveIndicator: allowIndicators && userSettings.get('guide-indicator-live') !== 'false',
|
||||
showPremiereIndicator: allowIndicators && userSettings.get('guide-indicator-premiere') !== 'false',
|
||||
showNewIndicator: allowIndicators && userSettings.get('guide-indicator-new') === 'true',
|
||||
showRepeatIndicator: allowIndicators && userSettings.get('guide-indicator-repeat') === 'true'
|
||||
};
|
||||
|
||||
for (var i = 0, length = channels.length; i < length; i++) {
|
||||
|
@ -497,19 +600,6 @@
|
|||
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 = [];
|
||||
|
@ -555,7 +645,7 @@
|
|||
var channelRowId = null;
|
||||
|
||||
if (activeElement) {
|
||||
channelRowId = parentWithClass(activeElement, 'channelPrograms');
|
||||
channelRowId = dom.parentWithClass(activeElement, 'channelPrograms');
|
||||
channelRowId = channelRowId && channelRowId.getAttribute ? channelRowId.getAttribute('data-channelid') : null;
|
||||
}
|
||||
|
||||
|
@ -572,7 +662,7 @@
|
|||
|
||||
var focusElem;
|
||||
if (itemId) {
|
||||
focusElem = context.querySelector('[data-id="' + itemId + '"]')
|
||||
focusElem = context.querySelector('[data-id="' + itemId + '"]');
|
||||
}
|
||||
|
||||
if (focusElem) {
|
||||
|
@ -582,7 +672,7 @@
|
|||
var autoFocusParent;
|
||||
|
||||
if (channelRowId) {
|
||||
autoFocusParent = context.querySelector('[data-channelid="' + channelRowId + '"]')
|
||||
autoFocusParent = context.querySelector('[data-channelid="' + channelRowId + '"]');
|
||||
}
|
||||
|
||||
if (!autoFocusParent) {
|
||||
|
@ -637,13 +727,8 @@
|
|||
|
||||
reloadGuide(page, newStartDate);
|
||||
|
||||
var dateText = datetime.getLocaleDateStringParts(date);
|
||||
var dateText = datetime.toLocaleDateString(date, { weekday: 'short', month: 'short', day: 'numeric' });
|
||||
|
||||
if (dateText.length == 1) {
|
||||
dateText = dateText[0];
|
||||
} else {
|
||||
dateText = '<div>' + dateText[0] + '</div><div class="guideDateTextDate">' + dateText[1] + '</div>';
|
||||
}
|
||||
page.querySelector('.guideDateText').innerHTML = dateText;
|
||||
}
|
||||
|
||||
|
@ -671,7 +756,7 @@
|
|||
while (start <= end) {
|
||||
|
||||
dateOptions.push({
|
||||
name: datetime.getLocaleDateStringParts(start).join(' '),
|
||||
name: datetime.toLocaleDateString(start, { weekday: 'long', month: 'long', day: 'numeric' }),
|
||||
id: start.getTime()
|
||||
});
|
||||
|
||||
|
@ -704,7 +789,7 @@
|
|||
|
||||
var selectedDate = currentDate || new Date();
|
||||
dateOptions.forEach(function (d) {
|
||||
d.selected = new Date(d.id).getDate() == selectedDate.getDate();
|
||||
d.selected = new Date(d.id).getDate() === selectedDate.getDate();
|
||||
});
|
||||
|
||||
require(['actionsheet'], function (actionsheet) {
|
||||
|
@ -735,22 +820,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
function parentWithClass(elem, className) {
|
||||
|
||||
while (!elem.classList || !elem.classList.contains(className)) {
|
||||
elem = elem.parentNode;
|
||||
|
||||
if (!elem) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
function onProgramGridFocus(e) {
|
||||
|
||||
var programCell = parentWithClass(e.target, 'programCell');
|
||||
var programCell = dom.parentWithClass(e.target, 'programCell');
|
||||
|
||||
if (!programCell) {
|
||||
return;
|
||||
|
@ -781,7 +853,7 @@
|
|||
|
||||
var icon = cell.querySelector('.timerIcon');
|
||||
if (!icon) {
|
||||
cell.insertAdjacentHTML('beforeend', '<i class="timerIcon md-icon">fiber_manual_record</i>');
|
||||
cell.insertAdjacentHTML('beforeend', '<i class="timerIcon md-icon"></i>');
|
||||
}
|
||||
|
||||
if (newTimerId) {
|
||||
|
@ -855,19 +927,16 @@
|
|||
|
||||
context.querySelector('.btnUnlockGuide').addEventListener('click', function () {
|
||||
currentStartIndex = 0;
|
||||
channelsPromise = null;
|
||||
reloadPage(context);
|
||||
});
|
||||
|
||||
context.querySelector('.btnNextPage').addEventListener('click', function () {
|
||||
currentStartIndex += currentChannelLimit;
|
||||
channelsPromise = null;
|
||||
reloadPage(context);
|
||||
});
|
||||
|
||||
context.querySelector('.btnPreviousPage').addEventListener('click', function () {
|
||||
currentStartIndex = Math.max(currentStartIndex - currentChannelLimit, 0);
|
||||
channelsPromise = null;
|
||||
reloadPage(context);
|
||||
});
|
||||
|
||||
|
@ -875,6 +944,10 @@
|
|||
showViewSettings(self);
|
||||
});
|
||||
|
||||
context.querySelector('.btnCategories').addEventListener('click', function () {
|
||||
showCategoryOptions(self);
|
||||
});
|
||||
|
||||
context.classList.add('tvguide');
|
||||
|
||||
setScrollEvents(context, true);
|
||||
|
@ -889,7 +962,7 @@
|
|||
|
||||
self.refresh();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
return Guide;
|
||||
});
|
15
dashboard-ui/bower_components/emby-webcomponents/guide/programs.css
vendored
Normal file
15
dashboard-ui/bower_components/emby-webcomponents/guide/programs.css
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
.newTvProgram {
|
||||
background: #64A239;
|
||||
}
|
||||
|
||||
.liveTvProgram {
|
||||
background: #EC407A;
|
||||
}
|
||||
|
||||
.premiereTvProgram {
|
||||
background: #EF6C00;
|
||||
}
|
||||
|
||||
.repeatTvProgram {
|
||||
background: #009688;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<div class="tvGuideHeader">
|
||||
<div class="channelTimeslotHeader">
|
||||
<button is="emby-button" type="button" class="btnSelectDate block">
|
||||
<button is="emby-button" type="button" class="btnSelectDate block button-flat">
|
||||
<div class="btnSelectDateContent">
|
||||
<div class="guideDateText">
|
||||
</div>
|
||||
|
@ -14,10 +14,19 @@
|
|||
<div class="timeslotHeaders smoothScrollX guideScroller" style="scroll-behavior: auto;"></div>
|
||||
</div>
|
||||
|
||||
<div class="smoothScrollY guideVerticalScroller programContainer guideScroller" style="flex-grow: 1;">
|
||||
<div class="channelList"></div>
|
||||
<div style="display: flex;flex-grow:1;overflow:hidden;">
|
||||
|
||||
<div class="programGridContainer programGrid smoothScrollX guideScroller" style="white-space: nowrap;">
|
||||
<button is="emby-button" type="button" class="btnCategories">
|
||||
<div class="btnCategoriesText">${Categories}</div>
|
||||
</button>
|
||||
<div class="smoothScrollY guideVerticalScroller programContainer guideScroller" style="flex-grow: 1;">
|
||||
|
||||
<div class="channelsContainer">
|
||||
<div class="channelList"></div>
|
||||
</div>
|
||||
|
||||
<div class="programGridContainer programGrid smoothScrollX guideScroller" style="white-space: nowrap;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager', 'focusManager', 'globalize', 'scrollHelper', 'imageLoader', 'require', 'cardStyle', 'formDialogStyle', 'emby-button', 'paper-icon-button-light'], function (dialogHelper, connectionManager, loading, dom, layoutManager, focusManager, globalize, scrollHelper, imageLoader, require) {
|
||||
'use strict';
|
||||
|
||||
var currentItem;
|
||||
var hasChanges = false;
|
||||
|
@ -78,11 +79,11 @@
|
|||
options.type = type;
|
||||
options.index = index;
|
||||
|
||||
if (type == 'Backdrop') {
|
||||
if (type === 'Backdrop') {
|
||||
options.tag = item.BackdropImageTags[index];
|
||||
} else if (type == 'Screenshot') {
|
||||
} else if (type === 'Screenshot') {
|
||||
options.tag = item.ScreenshotImageTags[index];
|
||||
} else if (type == 'Primary') {
|
||||
} else if (type === 'Primary') {
|
||||
options.tag = item.PrimaryImageTag || item.ImageTags[type];
|
||||
} else {
|
||||
options.tag = item.ImageTags[type];
|
||||
|
@ -101,7 +102,7 @@
|
|||
|
||||
cssClass += " backdropCard backdropCard-scalable";
|
||||
|
||||
if (tagName == 'button') {
|
||||
if (tagName === 'button') {
|
||||
cssClass += ' card-focusscale btnImageCard';
|
||||
cardBoxCssClass += ' cardBox-focustransform cardBox-focustransform-transition';
|
||||
|
||||
|
@ -142,27 +143,27 @@
|
|||
if (enableFooterButtons) {
|
||||
html += '<div class="cardText cardTextCentered">';
|
||||
|
||||
if (image.ImageType == "Backdrop" || image.ImageType == "Screenshot") {
|
||||
if (image.ImageType === "Backdrop" || image.ImageType === "Screenshot") {
|
||||
|
||||
if (index > 0) {
|
||||
html += '<button is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex - 1) + '" title="' + globalize.translate('sharedcomponents#MoveLeft') + '"><i class="md-icon">chevron_left</i></button>';
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex - 1) + '" title="' + globalize.translate('sharedcomponents#MoveLeft') + '"><i class="md-icon">chevron_left</i></button>';
|
||||
} else {
|
||||
html += '<button is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('sharedcomponents#MoveLeft') + '"><i class="md-icon">chevron_left</i></button>';
|
||||
html += '<button type="button" is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('sharedcomponents#MoveLeft') + '"><i class="md-icon">chevron_left</i></button>';
|
||||
}
|
||||
|
||||
if (index < numImages - 1) {
|
||||
html += '<button is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex + 1) + '" title="' + globalize.translate('sharedcomponents#MoveRight') + '"><i class="md-icon">chevron_right</i></button>';
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex + 1) + '" title="' + globalize.translate('sharedcomponents#MoveRight') + '"><i class="md-icon">chevron_right</i></button>';
|
||||
} else {
|
||||
html += '<button is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('sharedcomponents#MoveRight') + '"><i class="md-icon">chevron_right</i></button>';
|
||||
html += '<button type="button" is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('sharedcomponents#MoveRight') + '"><i class="md-icon">chevron_right</i></button>';
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (imageProviders.length) {
|
||||
html += '<button is="paper-icon-button-light" data-imagetype="' + image.ImageType + '" class="btnSearchImages autoSize" title="' + globalize.translate('sharedcomponents#Search') + '"><i class="md-icon">search</i></button>';
|
||||
html += '<button type="button" is="paper-icon-button-light" data-imagetype="' + image.ImageType + '" class="btnSearchImages autoSize" title="' + globalize.translate('sharedcomponents#Search') + '"><i class="md-icon">search</i></button>';
|
||||
}
|
||||
}
|
||||
|
||||
html += '<button is="paper-icon-button-light" data-imagetype="' + image.ImageType + '" data-index="' + (image.ImageIndex != null ? image.ImageIndex : "null") + '" class="btnDeleteImage autoSize" title="' + globalize.translate('sharedcomponents#Delete') + '"><i class="md-icon">delete</i></button>';
|
||||
html += '<button type="button" is="paper-icon-button-light" data-imagetype="' + image.ImageType + '" data-index="' + (image.ImageIndex != null ? image.ImageIndex : "null") + '" class="btnDeleteImage autoSize" title="' + globalize.translate('sharedcomponents#Delete') + '"><i class="md-icon">delete</i></button>';
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
|
@ -192,7 +193,13 @@
|
|||
|
||||
require(['confirm'], function (confirm) {
|
||||
|
||||
confirm(globalize.translate('sharedcomponents#ConfirmDeleteImage')).then(afterConfirm);
|
||||
confirm({
|
||||
|
||||
text: globalize.translate('sharedcomponents#ConfirmDeleteImage'),
|
||||
confirmText: globalize.translate('sharedcomponents#Delete'),
|
||||
primary: 'cancel'
|
||||
|
||||
}).then(afterConfirm);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -202,6 +209,11 @@
|
|||
|
||||
hasChanges = true;
|
||||
reload(context, null, focusContext);
|
||||
}, function() {
|
||||
|
||||
require(['alert'], function (alert) {
|
||||
alert(globalize.translate('sharedcomponents#DefaultErrorMessage'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -227,31 +239,12 @@
|
|||
|
||||
elem.innerHTML = html;
|
||||
imageLoader.lazyChildren(elem);
|
||||
|
||||
addListeners(elem, 'btnSearchImages', 'click', function () {
|
||||
showImageDownloader(page, this.getAttribute('data-imagetype'));
|
||||
});
|
||||
|
||||
addListeners(elem, 'btnDeleteImage', 'click', function () {
|
||||
var type = this.getAttribute('data-imagetype');
|
||||
var index = this.getAttribute('data-index');
|
||||
index = index == "null" ? null : parseInt(index);
|
||||
|
||||
deleteImage(page, currentItem.Id, type, index, apiClient, true);
|
||||
});
|
||||
|
||||
addListeners(elem, 'btnMoveImage', 'click', function () {
|
||||
var type = this.getAttribute('data-imagetype');
|
||||
var index = this.getAttribute('data-index');
|
||||
var newIndex = this.getAttribute('data-newindex');
|
||||
moveImage(page, apiClient, currentItem.Id, type, index, newIndex, dom.parentWithClass(this, 'itemsContainer'));
|
||||
});
|
||||
}
|
||||
|
||||
function renderStandardImages(page, apiClient, item, imageInfos, imageProviders) {
|
||||
|
||||
var images = imageInfos.filter(function (i) {
|
||||
return i.ImageType != "Screenshot" && i.ImageType != "Backdrop" && i.ImageType != "Chapter";
|
||||
return i.ImageType !== "Screenshot" && i.ImageType !== "Backdrop" && i.ImageType !== "Chapter";
|
||||
});
|
||||
|
||||
renderImages(page, item, apiClient, images, imageProviders, page.querySelector('#images'));
|
||||
|
@ -260,7 +253,7 @@
|
|||
function renderBackdrops(page, apiClient, item, imageInfos, imageProviders) {
|
||||
|
||||
var images = imageInfos.filter(function (i) {
|
||||
return i.ImageType == "Backdrop";
|
||||
return i.ImageType === "Backdrop";
|
||||
|
||||
}).sort(function (a, b) {
|
||||
return a.ImageIndex - b.ImageIndex;
|
||||
|
@ -277,7 +270,7 @@
|
|||
function renderScreenshots(page, apiClient, item, imageInfos, imageProviders) {
|
||||
|
||||
var images = imageInfos.filter(function (i) {
|
||||
return i.ImageType == "Screenshot";
|
||||
return i.ImageType === "Screenshot";
|
||||
|
||||
}).sort(function (a, b) {
|
||||
return a.ImageIndex - b.ImageIndex;
|
||||
|
@ -299,6 +292,10 @@
|
|||
hasChanges = true;
|
||||
reload(page);
|
||||
});
|
||||
}, function () {
|
||||
require(['alert'], function (alert) {
|
||||
alert('This feature is coming soon to Emby Theater.');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -322,7 +319,7 @@
|
|||
id: 'delete'
|
||||
});
|
||||
|
||||
if (type == 'Backdrop' || type == 'Screenshot') {
|
||||
if (type === 'Backdrop' || type === 'Screenshot') {
|
||||
if (index > 0) {
|
||||
commands.push({
|
||||
name: globalize.translate('sharedcomponents#MoveLeft'),
|
||||
|
@ -374,9 +371,9 @@
|
|||
});
|
||||
}
|
||||
|
||||
function initEditor(page, options) {
|
||||
function initEditor(context, options) {
|
||||
|
||||
addListeners(page, 'btnOpenUploadMenu', 'click', function () {
|
||||
addListeners(context, 'btnOpenUploadMenu', 'click', function () {
|
||||
var imageType = this.getAttribute('data-imagetype');
|
||||
|
||||
require(['components/imageuploader/imageuploader'], function (imageUploader) {
|
||||
|
@ -390,18 +387,42 @@
|
|||
|
||||
if (hasChanged) {
|
||||
hasChanges = true;
|
||||
reload(page);
|
||||
reload(context);
|
||||
}
|
||||
});
|
||||
}, function () {
|
||||
require(['alert'], function (alert) {
|
||||
alert('This feature is coming soon to Emby Theater.');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
addListeners(page, 'btnBrowseAllImages', 'click', function () {
|
||||
showImageDownloader(page, this.getAttribute('data-imagetype') || 'Primary');
|
||||
addListeners(context, 'btnSearchImages', 'click', function () {
|
||||
showImageDownloader(context, this.getAttribute('data-imagetype'));
|
||||
});
|
||||
|
||||
addListeners(page, 'btnImageCard', 'click', function () {
|
||||
showActionSheet(page, this);
|
||||
addListeners(context, 'btnBrowseAllImages', 'click', function () {
|
||||
showImageDownloader(context, this.getAttribute('data-imagetype') || 'Primary');
|
||||
});
|
||||
|
||||
addListeners(context, 'btnImageCard', 'click', function () {
|
||||
showActionSheet(context, this);
|
||||
});
|
||||
|
||||
addListeners(context, 'btnDeleteImage', 'click', function () {
|
||||
var type = this.getAttribute('data-imagetype');
|
||||
var index = this.getAttribute('data-index');
|
||||
index = index === "null" ? null : parseInt(index);
|
||||
var apiClient = connectionManager.getApiClient(currentItem.ServerId);
|
||||
deleteImage(context, currentItem.Id, type, index, apiClient, true);
|
||||
});
|
||||
|
||||
addListeners(context, 'btnMoveImage', 'click', function () {
|
||||
var type = this.getAttribute('data-imagetype');
|
||||
var index = this.getAttribute('data-index');
|
||||
var newIndex = this.getAttribute('data-newindex');
|
||||
var apiClient = connectionManager.getApiClient(currentItem.ServerId);
|
||||
moveImage(context, apiClient, currentItem.Id, type, index, newIndex, dom.parentWithClass(this, 'itemsContainer'));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,25 @@
|
|||
define([], function () {
|
||||
define(['dom'], function (dom) {
|
||||
'use strict';
|
||||
|
||||
function loadImage(elem, url) {
|
||||
|
||||
if (elem.tagName !== "IMG") {
|
||||
|
||||
elem.style.backgroundImage = "url('" + url + "')";
|
||||
return Promise.resolve(elem);
|
||||
return Promise.resolve();
|
||||
|
||||
} else {
|
||||
elem.setAttribute("src", url);
|
||||
return Promise.resolve(elem);
|
||||
}
|
||||
return loadImageIntoImg(elem, url);
|
||||
}
|
||||
|
||||
function loadImageIntoImg(elem, url) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
dom.addEventListener(elem, 'load', resolve, {
|
||||
once: true
|
||||
});
|
||||
elem.setAttribute("src", url);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser', 'dom'], function (visibleinviewport, imageFetcher, layoutManager, events, browser, dom) {
|
||||
define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser', 'dom', 'appSettings', 'require'], function (visibleinviewport, imageFetcher, layoutManager, events, browser, dom, appSettings, require) {
|
||||
'use strict';
|
||||
|
||||
var thresholdX;
|
||||
var thresholdY;
|
||||
|
||||
var requestIdleCallback = window.requestIdleCallback || function (fn) {
|
||||
fn();
|
||||
};
|
||||
|
||||
//var imagesWorker = new Worker(require.toUrl('.').split('?')[0] + '/imagesworker.js');
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -25,8 +26,8 @@ define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser
|
|||
var y = screen.availHeight;
|
||||
|
||||
if (browser.touch) {
|
||||
x *= 2;
|
||||
y *= 2;
|
||||
x *= 1.5;
|
||||
y *= 1.5;
|
||||
}
|
||||
|
||||
thresholdX = x;
|
||||
|
@ -53,14 +54,174 @@ define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser
|
|||
if (!source) {
|
||||
source = elem.getAttribute('data-src');
|
||||
}
|
||||
if (source) {
|
||||
if (enableFade && !layoutManager.tv && enableEffects !== false) {
|
||||
imageFetcher.loadImage(elem, source).then(fadeIn);
|
||||
} else {
|
||||
imageFetcher.loadImage(elem, source);
|
||||
}
|
||||
elem.removeAttribute("data-src");
|
||||
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
fillImageElement(elem, source, enableEffects);
|
||||
}
|
||||
|
||||
function fillImageElement(elem, source, enableEffects) {
|
||||
imageFetcher.loadImage(elem, source).then(function () {
|
||||
|
||||
var fillingVibrant = elem.tagName !== 'IMG' ? false : fillVibrant(elem, source);
|
||||
|
||||
if (enableFade && !layoutManager.tv && enableEffects !== false && !fillingVibrant) {
|
||||
fadeIn(elem);
|
||||
}
|
||||
|
||||
elem.removeAttribute("data-src");
|
||||
});
|
||||
}
|
||||
|
||||
//var placeholder = document.createElement('div');
|
||||
//imagesWorker.onmessage = function (evt) {
|
||||
// placeholder.dispatchEvent(new CustomEvent('decoded', {
|
||||
// detail: evt.data,
|
||||
// bubbles: false,
|
||||
// cancellable: false
|
||||
// }));
|
||||
//};
|
||||
|
||||
//var uniqueId = 0;
|
||||
|
||||
//function fillCanvas(elem, source) {
|
||||
|
||||
// var newUniqueId = (++uniqueId);
|
||||
|
||||
// imagesWorker.postMessage({
|
||||
// url: source,
|
||||
// id: newUniqueId
|
||||
// });
|
||||
|
||||
// placeholder.addEventListener('decoded', function (e) {
|
||||
|
||||
// if (e.detail.id == newUniqueId) {
|
||||
|
||||
// var imageBitmap = e.detail.imageBitmap;
|
||||
// var canvas = document.createElement('canvas');
|
||||
// var canvasContext = canvas.getContext('2d');
|
||||
|
||||
// //drawWidth *= ratio;
|
||||
// //drawHeight *= ratio;
|
||||
|
||||
// // https://stackoverflow.com/questions/21961839/simulation-background-size-cover-in-canvas/21961894#21961894
|
||||
// canvasContext.imageSmoothingEnabled = false;
|
||||
// var width = canvas.width = elem.offsetWidth;
|
||||
// var height = canvas.height = elem.offsetHeight;
|
||||
// canvasContext.drawImage(imageBitmap, 0, 0, imageBitmap.width, imageBitmap.height, 0, 0, width, height);
|
||||
|
||||
// fillVibrant(elem, source, canvas, canvasContext);
|
||||
|
||||
// elem.insertBefore(canvas, elem.firstChild);
|
||||
// elem.removeAttribute("data-src");
|
||||
// }
|
||||
// });
|
||||
//}
|
||||
|
||||
function fillVibrant(img, url, canvas, canvasContext) {
|
||||
|
||||
var vibrantElement = img.getAttribute('data-vibrant');
|
||||
if (!vibrantElement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (window.Vibrant) {
|
||||
fillVibrantOnLoaded(img, url, vibrantElement, canvas, canvasContext);
|
||||
return true;
|
||||
}
|
||||
|
||||
require(['vibrant'], function () {
|
||||
fillVibrantOnLoaded(img, url, vibrantElement, canvas, canvasContext);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
function fillVibrantOnLoaded(img, url, vibrantElement, canvas, canvasContext) {
|
||||
|
||||
vibrantElement = document.getElementById(vibrantElement);
|
||||
if (!vibrantElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
requestIdleCallback(function () {
|
||||
|
||||
//var now = new Date().getTime();
|
||||
var swatch = getVibrantInfo(canvas || img, url, canvasContext).split('|');
|
||||
//console.log('vibrant took ' + (new Date().getTime() - now) + 'ms');
|
||||
if (swatch.length) {
|
||||
|
||||
var index = 0;
|
||||
vibrantElement.style.backgroundColor = swatch[index];
|
||||
vibrantElement.style.color = swatch[index + 1];
|
||||
}
|
||||
});
|
||||
/*
|
||||
* Results into:
|
||||
* Vibrant #7a4426
|
||||
* Muted #7b9eae
|
||||
* DarkVibrant #348945
|
||||
* DarkMuted #141414
|
||||
* LightVibrant #f3ccb4
|
||||
*/
|
||||
}
|
||||
|
||||
function getSettingsKey(url) {
|
||||
|
||||
var parts = url.split('://');
|
||||
url = parts[parts.length - 1];
|
||||
|
||||
url = url.substring(url.indexOf('/') + 1);
|
||||
|
||||
url = url.split('?')[0];
|
||||
|
||||
var cacheKey = 'vibrant11';
|
||||
return cacheKey + url;
|
||||
}
|
||||
|
||||
function getCachedVibrantInfo(url) {
|
||||
|
||||
return appSettings.get(getSettingsKey(url));
|
||||
}
|
||||
|
||||
function getVibrantInfo(img, url, canvasContext) {
|
||||
|
||||
var value = getCachedVibrantInfo(url);
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
var vibrant = new Vibrant(img, canvasContext);
|
||||
var swatches = vibrant.swatches();
|
||||
|
||||
value = '';
|
||||
var swatch = swatches.DarkVibrant;
|
||||
if (swatch) {
|
||||
value += swatch.getHex() + '|' + swatch.getBodyTextColor();
|
||||
}
|
||||
//swatch = swatches.DarkMuted;
|
||||
//if (swatch) {
|
||||
// value += '|' + swatch.getHex() + '|' + swatch.getBodyTextColor();
|
||||
//} else {
|
||||
// value += '||';
|
||||
//}
|
||||
//swatch = swatches.Vibrant;
|
||||
//if (swatch) {
|
||||
// value += '|' + swatch.getHex() + '|' + swatch.getBodyTextColor();
|
||||
//} else {
|
||||
// value += '||';
|
||||
//}
|
||||
//swatch = swatches.Muted;
|
||||
//if (swatch) {
|
||||
// value += '|' + swatch.getHex() + '|' + swatch.getBodyTextColor();
|
||||
//} else {
|
||||
// value += '||';
|
||||
//}
|
||||
|
||||
appSettings.set(getSettingsKey(url), value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function fadeIn(elem) {
|
||||
|
@ -231,31 +392,33 @@ define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser
|
|||
|
||||
var result;
|
||||
|
||||
if (values.length % 2)
|
||||
if (values.length % 2) {
|
||||
result = values[half];
|
||||
else
|
||||
}
|
||||
else {
|
||||
result = (values[half - 1] + values[half]) / 2.0;
|
||||
}
|
||||
|
||||
// If really close to 2:3 (poster image), just return 2:3
|
||||
var aspect2x3 = 2 / 3;
|
||||
if (Math.abs(aspect2x3 - result) <= .15) {
|
||||
if (Math.abs(aspect2x3 - result) <= 0.15) {
|
||||
return aspect2x3;
|
||||
}
|
||||
|
||||
// If really close to 16:9 (episode image), just return 16:9
|
||||
var aspect16x9 = 16 / 9;
|
||||
if (Math.abs(aspect16x9 - result) <= .2) {
|
||||
if (Math.abs(aspect16x9 - result) <= 0.2) {
|
||||
return aspect16x9;
|
||||
}
|
||||
|
||||
// If really close to 1 (square image), just return 1
|
||||
if (Math.abs(1 - result) <= .15) {
|
||||
if (Math.abs(1 - result) <= 0.15) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// If really close to 4:3 (poster image), just return 2:3
|
||||
var aspect4x3 = 4 / 3;
|
||||
if (Math.abs(aspect4x3 - result) <= .15) {
|
||||
if (Math.abs(aspect4x3 - result) <= 0.15) {
|
||||
return aspect4x3;
|
||||
}
|
||||
|
||||
|
@ -274,6 +437,7 @@ define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser
|
|||
self.lazyImage = fillImage;
|
||||
self.lazyChildren = lazyChildren;
|
||||
self.getPrimaryImageAspectRatio = getPrimaryImageAspectRatio;
|
||||
self.getCachedVibrantInfo = getCachedVibrantInfo;
|
||||
|
||||
return self;
|
||||
});
|
177
dashboard-ui/bower_components/emby-webcomponents/images/indexeddbimagefetcher.js
vendored
Normal file
177
dashboard-ui/bower_components/emby-webcomponents/images/indexeddbimagefetcher.js
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
define(['cryptojs-md5'], function () {
|
||||
'use strict';
|
||||
|
||||
var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB;
|
||||
var dbVersion = 1;
|
||||
var imagesTableName = "images";
|
||||
var db;
|
||||
|
||||
function createObjectStore(dataBase) {
|
||||
|
||||
dataBase.createObjectStore(imagesTableName, { keyPath: "id" });
|
||||
db = dataBase;
|
||||
}
|
||||
|
||||
// Create/open database
|
||||
var request = indexedDB.open("imagesDb2", dbVersion);
|
||||
|
||||
request.onupgradeneeded = function () {
|
||||
createObjectStore(request.result);
|
||||
};
|
||||
|
||||
request.onsuccess = function (event) {
|
||||
|
||||
console.log("Success creating/accessing IndexedDB database");
|
||||
|
||||
var localDb = request.result;
|
||||
|
||||
localDb.onerror = function (event) {
|
||||
console.log("Error creating/accessing IndexedDB database");
|
||||
};
|
||||
|
||||
// Interim solution for Google Chrome to create an objectStore. Will be deprecated
|
||||
if (localDb.setVersion) {
|
||||
if (localDb.version !== dbVersion) {
|
||||
var setVersion = localDb.setVersion(dbVersion);
|
||||
setVersion.onsuccess = function () {
|
||||
createObjectStore(localDb);
|
||||
};
|
||||
} else {
|
||||
db = localDb;
|
||||
}
|
||||
} else {
|
||||
db = localDb;
|
||||
}
|
||||
};
|
||||
|
||||
function revoke(url) {
|
||||
|
||||
//URL.revokeObjectURL(url);
|
||||
|
||||
}
|
||||
|
||||
function loadImage(elem, url) {
|
||||
|
||||
if (elem.tagName !== "IMG") {
|
||||
|
||||
elem.style.backgroundImage = "url('" + url + "')";
|
||||
revoke(url);
|
||||
return Promise.resolve(elem);
|
||||
|
||||
} else {
|
||||
elem.setAttribute("src", url);
|
||||
revoke(url);
|
||||
return Promise.resolve(elem);
|
||||
}
|
||||
}
|
||||
|
||||
function getCacheKey(url) {
|
||||
|
||||
// Try to strip off the domain to share the cache between local and remote connections
|
||||
var index = url.indexOf('://');
|
||||
|
||||
if (index !== -1) {
|
||||
url = url.substring(index + 3);
|
||||
|
||||
index = url.indexOf('/');
|
||||
|
||||
if (index !== -1) {
|
||||
url = url.substring(index + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return CryptoJS.MD5(url).toString();
|
||||
}
|
||||
|
||||
function getFromDb(key) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
var transaction = db.transaction(imagesTableName, "read");
|
||||
|
||||
// Retrieve the file that was just stored
|
||||
var request = transaction.objectStore(imagesTableName).get(key);
|
||||
|
||||
request.onsuccess = function (event) {
|
||||
var imgFile = event.target.result;
|
||||
|
||||
// Get window.URL object
|
||||
var URL = window.URL || window.webkitURL;
|
||||
|
||||
// Create and revoke ObjectURL
|
||||
var imgURL = URL.createObjectURL(imgFile);
|
||||
|
||||
resolve(imgURL);
|
||||
};
|
||||
|
||||
request.onerror = reject;
|
||||
});
|
||||
}
|
||||
|
||||
function saveImageToDb(blob, key, resolve) {
|
||||
|
||||
// Open a transaction to the database
|
||||
var transaction = db.transaction(imagesTableName, "readwrite");
|
||||
|
||||
// Put the blob into the dabase
|
||||
var put = transaction.objectStore(imagesTableName).put({ id: key, data: blob });
|
||||
|
||||
// Get window.URL object
|
||||
var URL = window.URL || window.webkitURL;
|
||||
|
||||
var imgURL = URL.createObjectURL(blob);
|
||||
|
||||
resolve(imgURL);
|
||||
}
|
||||
|
||||
function getImageUrl(originalUrl) {
|
||||
|
||||
var key = getCacheKey(originalUrl);
|
||||
|
||||
return getFromDb(key).catch(function () {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open("GET", originalUrl, true);
|
||||
// Set the responseType to blob
|
||||
xhr.responseType = "blob";
|
||||
|
||||
xhr.addEventListener("load", function () {
|
||||
if (xhr.status === 200) {
|
||||
|
||||
// Put the received blob into IndexedDB
|
||||
saveImageToDb(xhr.response, key, resolve);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
}, false);
|
||||
|
||||
xhr.onerror = reject;
|
||||
|
||||
// Send XHR
|
||||
xhr.send();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
loadImage: function (elem, url) {
|
||||
|
||||
if (!db) {
|
||||
return loadImage(elem, url);
|
||||
}
|
||||
|
||||
return getImageUrl(url).then(function (localUrl) {
|
||||
|
||||
return loadImage(elem, localUrl);
|
||||
|
||||
}, function () {
|
||||
return loadImage(elem, url);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
});
|
|
@ -1,4 +1,5 @@
|
|||
define(['cryptojs-md5'], function () {
|
||||
'use strict';
|
||||
|
||||
function loadImage(elem, url) {
|
||||
|
||||
|
@ -20,7 +21,7 @@ define(['cryptojs-md5'], function () {
|
|||
|
||||
function createDir(rootDirEntry, folders, callback, errorCallback) {
|
||||
// Throw out './' or '/' and move on to prevent something like '/foo/.//bar'.
|
||||
if (folders[0] == '.' || folders[0] == '') {
|
||||
if (folders[0] === '.' || folders[0] === '') {
|
||||
folders = folders.slice(1);
|
||||
}
|
||||
rootDirEntry.getDirectory(folders[0], { create: true }, function (dirEntry) {
|
||||
|
@ -140,12 +141,12 @@ define(['cryptojs-md5'], function () {
|
|||
// Try to strip off the domain to share the cache between local and remote connections
|
||||
var index = url.indexOf('://');
|
||||
|
||||
if (index != -1) {
|
||||
if (index !== -1) {
|
||||
url = url.substring(index + 3);
|
||||
|
||||
index = url.indexOf('/');
|
||||
|
||||
if (index != -1) {
|
||||
if (index !== -1) {
|
||||
url = url.substring(index + 1);
|
||||
}
|
||||
|
||||
|
@ -163,12 +164,12 @@ define(['cryptojs-md5'], function () {
|
|||
xhr.responseType = "arraybuffer";
|
||||
|
||||
xhr.onload = function (e) {
|
||||
if (this.status == 200) {
|
||||
if (this.status === 200) {
|
||||
writeData(dir, filename, this.getResponseHeader('Content-Type'), this.response, callback, errorCallback);
|
||||
} else {
|
||||
errorCallback();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send();
|
||||
}
|
||||
|
@ -200,7 +201,7 @@ define(['cryptojs-md5'], function () {
|
|||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
if (originalUrl.indexOf('tag=') != -1) {
|
||||
if (originalUrl.indexOf('tag=') !== -1) {
|
||||
originalUrl += "&accept=webp";
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
color: #CB272A;
|
||||
}
|
||||
|
||||
.timerIndicator-inactive {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.indicator + .indicator {
|
||||
margin-left: .25em;
|
||||
}
|
||||
|
@ -73,4 +77,4 @@
|
|||
|
||||
.fullSyncIndicator {
|
||||
background: rgba(82,181,75,1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
define(['css!./indicators.css', 'material-icons'], function () {
|
||||
'use strict';
|
||||
|
||||
function enableProgressIndicator(item) {
|
||||
|
||||
if (item.MediaType == 'Video') {
|
||||
if (item.Type != 'TvChannel') {
|
||||
if (item.MediaType === 'Video') {
|
||||
if (item.Type !== 'TvChannel') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +28,7 @@ define(['css!./indicators.css', 'material-icons'], function () {
|
|||
function getProgressBarHtml(item, options) {
|
||||
|
||||
if (enableProgressIndicator(item)) {
|
||||
if (item.Type == "Recording" && item.CompletionPercentage) {
|
||||
if (item.Type === "Recording" && item.CompletionPercentage) {
|
||||
|
||||
return getProgressHtml(item.CompletionPercentage, options);
|
||||
}
|
||||
|
@ -48,9 +49,9 @@ define(['css!./indicators.css', 'material-icons'], function () {
|
|||
|
||||
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 === "Series" || item.Type === "Season" || item.Type === "BoxSet" || item.MediaType === "Video" || item.MediaType === "Game" || item.MediaType === "Book") {
|
||||
|
||||
if (item.Type != 'TvChannel') {
|
||||
if (item.Type !== 'TvChannel') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -98,19 +99,38 @@ define(['css!./indicators.css', 'material-icons'], function () {
|
|||
|
||||
function getTimerIndicator(item) {
|
||||
|
||||
if (item.SeriesTimerId) {
|
||||
return '<i class="md-icon timerIndicator indicatorIcon">fiber_smart_record</i>';
|
||||
var status;
|
||||
|
||||
if (item.Type === 'SeriesTimer') {
|
||||
return '<i class="md-icon timerIndicator indicatorIcon"></i>';
|
||||
}
|
||||
if (item.TimerId) {
|
||||
return '<i class="md-icon timerIndicator indicatorIcon">fiber_manual_record</i>';
|
||||
else if (item.TimerId || item.SeriesTimerId) {
|
||||
|
||||
status = item.Status || 'Cancelled';
|
||||
}
|
||||
else if (item.Type === 'Timer') {
|
||||
|
||||
status = item.Status;
|
||||
}
|
||||
else {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '';
|
||||
if (item.SeriesTimerId) {
|
||||
|
||||
if (status !== 'Cancelled') {
|
||||
return '<i class="md-icon timerIndicator indicatorIcon"></i>';
|
||||
}
|
||||
|
||||
return '<i class="md-icon timerIndicator timerIndicator-inactive indicatorIcon"></i>';
|
||||
}
|
||||
|
||||
return '<i class="md-icon timerIndicator indicatorIcon"></i>';
|
||||
}
|
||||
|
||||
function getSyncIndicator(item) {
|
||||
|
||||
if (item.SyncPercent == 100) {
|
||||
if (item.SyncPercent === 100) {
|
||||
return '<div class="syncIndicator indicator fullSyncIndicator"><i class="md-icon indicatorIcon">file_download</i></div>';
|
||||
} else if (item.SyncPercent != null) {
|
||||
return '<div class="syncIndicator indicator emptySyncIndicator"><i class="md-icon indicatorIcon">file_download</i></div>';
|
||||
|
|
|
@ -153,6 +153,12 @@ define(['playbackManager', 'focusManager', 'embyRouter', 'dom'], function (playb
|
|||
case 'togglemute':
|
||||
playbackManager.toggleMute();
|
||||
break;
|
||||
case 'channelup':
|
||||
playbackManager.nextTrack();
|
||||
break;
|
||||
case 'channeldown':
|
||||
playbackManager.previousTrack();
|
||||
break;
|
||||
case 'volumedown':
|
||||
playbackManager.volumeDown();
|
||||
break;
|
||||
|
|
|
@ -29,25 +29,47 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
|||
});
|
||||
}
|
||||
|
||||
if (item.Type == 'Timer' && user.Policy.EnableLiveTvManagement) {
|
||||
if ((item.Type == 'Timer') && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) {
|
||||
commands.push({
|
||||
name: globalize.translate('sharedcomponents#ButtonCancel'),
|
||||
name: globalize.translate('sharedcomponents#CancelRecording'),
|
||||
id: 'canceltimer'
|
||||
});
|
||||
}
|
||||
|
||||
if (item.CanDelete) {
|
||||
if ((item.Type == 'Recording' && item.Status == 'InProgress') && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) {
|
||||
commands.push({
|
||||
name: globalize.translate('sharedcomponents#Delete'),
|
||||
id: 'delete'
|
||||
name: globalize.translate('sharedcomponents#CancelRecording'),
|
||||
id: 'canceltimer'
|
||||
});
|
||||
}
|
||||
|
||||
if (itemHelper.canEdit(user, item.Type)) {
|
||||
if ((item.Type == 'SeriesTimer') && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) {
|
||||
commands.push({
|
||||
name: globalize.translate('sharedcomponents#CancelSeries'),
|
||||
id: 'cancelseriestimer'
|
||||
});
|
||||
}
|
||||
|
||||
if (options.edit !== false) {
|
||||
if (item.CanDelete) {
|
||||
|
||||
var text = item.Type == 'Timer' ? globalize.translate('sharedcomponents#Edit') : globalize.translate('sharedcomponents#EditInfo');
|
||||
if (item.Type == 'Playlist' || item.Type == 'BoxSet') {
|
||||
commands.push({
|
||||
name: globalize.translate('sharedcomponents#Delete'),
|
||||
id: 'delete'
|
||||
});
|
||||
} else {
|
||||
commands.push({
|
||||
name: globalize.translate('sharedcomponents#DeleteMedia'),
|
||||
id: 'delete'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (itemHelper.canEdit(user, item)) {
|
||||
|
||||
if (options.edit !== false && item.Type != 'SeriesTimer') {
|
||||
|
||||
var text = (item.Type == 'Timer' || item.Type == 'SeriesTimer') ? globalize.translate('sharedcomponents#Edit') : globalize.translate('sharedcomponents#EditInfo');
|
||||
|
||||
commands.push({
|
||||
name: text,
|
||||
|
@ -56,7 +78,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
|||
}
|
||||
}
|
||||
|
||||
if (itemHelper.canEditImages(user, item.Type)) {
|
||||
if (itemHelper.canEditImages(user, item)) {
|
||||
|
||||
if (options.editImages !== false) {
|
||||
commands.push({
|
||||
|
@ -66,9 +88,9 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
|||
}
|
||||
}
|
||||
|
||||
if (itemHelper.canEdit(user, item.Type)) {
|
||||
if (itemHelper.canEdit(user, item)) {
|
||||
|
||||
if (item.MediaType == 'Video' && item.Type != 'TvChannel' && item.Type != 'Program' && item.LocationType != 'Virtual') {
|
||||
if (item.MediaType == 'Video' && item.Type != 'TvChannel' && item.Type != 'Program' && item.LocationType != 'Virtual' && !(item.Type == 'Recording' && item.Status != 'Completed')) {
|
||||
if (options.editSubtitles !== false) {
|
||||
commands.push({
|
||||
name: globalize.translate('sharedcomponents#EditSubtitles'),
|
||||
|
@ -112,15 +134,6 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
|||
}
|
||||
}
|
||||
|
||||
//if (options.open !== false) {
|
||||
// if (item.Type != 'Timer' && item.Type != 'Audio') {
|
||||
// commands.push({
|
||||
// name: globalize.translate('sharedcomponents#Open'),
|
||||
// id: 'open'
|
||||
// });
|
||||
// }
|
||||
//}
|
||||
|
||||
if (canPlay) {
|
||||
if (options.play !== false) {
|
||||
commands.push({
|
||||
|
@ -160,7 +173,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
|||
}
|
||||
}
|
||||
|
||||
if (item.Type == 'Program' && (!item.TimerId && !item.SeriesTimerId)) {
|
||||
if (item.Type == 'Program') {
|
||||
|
||||
commands.push({
|
||||
name: Globalize.translate('sharedcomponents#Record'),
|
||||
|
@ -170,7 +183,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
|||
|
||||
if (user.Policy.IsAdministrator) {
|
||||
|
||||
if (item.Type != 'Timer' && item.Type != 'Program') {
|
||||
if (item.Type != 'Timer' && item.Type != 'SeriesTimer' && item.Type != 'Program' && !(item.Type == 'Recording' && item.Status != 'Completed')) {
|
||||
commands.push({
|
||||
name: globalize.translate('sharedcomponents#Refresh'),
|
||||
id: 'refresh'
|
||||
|
@ -383,7 +396,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
|||
}
|
||||
case 'delete':
|
||||
{
|
||||
deleteItem(apiClient, itemId).then(getResolveFunction(resolve, id, true, true), getResolveFunction(resolve, id));
|
||||
deleteItem(apiClient, item).then(getResolveFunction(resolve, id, true, true), getResolveFunction(resolve, id));
|
||||
break;
|
||||
}
|
||||
case 'share':
|
||||
|
@ -480,6 +493,9 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
|||
case 'canceltimer':
|
||||
deleteTimer(apiClient, item, resolve, id);
|
||||
break;
|
||||
case 'cancelseriestimer':
|
||||
deleteSeriesTimer(apiClient, item, resolve, id);
|
||||
break;
|
||||
default:
|
||||
reject();
|
||||
break;
|
||||
|
@ -489,21 +505,22 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
|||
|
||||
function deleteTimer(apiClient, item, resolve, command) {
|
||||
|
||||
require(['confirm'], function (confirm) {
|
||||
require(['recordingHelper'], function (recordingHelper) {
|
||||
|
||||
confirm(globalize.translate('sharedcomponents#MessageConfirmRecordingCancellation'), globalize.translate('sharedcomponents#HeaderConfirmRecordingCancellation')).then(function () {
|
||||
var timerId = item.TimerId || item.Id;
|
||||
|
||||
loading.show();
|
||||
recordingHelper.cancelTimerWithConfirmation(timerId, item.ServerId).then(function () {
|
||||
getResolveFunction(resolve, command, true)();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
apiClient.cancelLiveTvTimer(item.Id).then(function () {
|
||||
function deleteSeriesTimer(apiClient, item, resolve, command) {
|
||||
|
||||
require(['toast'], function (toast) {
|
||||
toast(globalize.translate('sharedcomponents#RecordingCancelled'));
|
||||
});
|
||||
require(['recordingHelper'], function (recordingHelper) {
|
||||
|
||||
loading.hide();
|
||||
getResolveFunction(resolve, command, true)();
|
||||
});
|
||||
recordingHelper.cancelSeriesTimerWithConfirmation(item.Id, item.ServerId).then(function () {
|
||||
getResolveFunction(resolve, command, true)();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -539,6 +556,11 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
|||
if (item.Type == 'Timer') {
|
||||
require(['recordingEditor'], function (recordingEditor) {
|
||||
|
||||
recordingEditor.show(item.Id, serverId).then(resolve, reject);
|
||||
});
|
||||
} else if (item.Type == 'SeriesTimer') {
|
||||
require(['seriesRecordingEditor'], function (recordingEditor) {
|
||||
|
||||
recordingEditor.show(item.Id, serverId).then(resolve, reject);
|
||||
});
|
||||
} else {
|
||||
|
@ -550,16 +572,25 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
|||
});
|
||||
}
|
||||
|
||||
function deleteItem(apiClient, itemId) {
|
||||
function deleteItem(apiClient, item) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
var itemId = item.Id;
|
||||
|
||||
var msg = globalize.translate('sharedcomponents#ConfirmDeleteItem');
|
||||
var title = globalize.translate('sharedcomponents#HeaderDeleteItem');
|
||||
|
||||
require(['confirm'], function (confirm) {
|
||||
|
||||
confirm(msg, title).then(function () {
|
||||
confirm({
|
||||
|
||||
title: title,
|
||||
text: msg,
|
||||
confirmText: globalize.translate('sharedcomponents#Delete'),
|
||||
primary: 'cancel'
|
||||
|
||||
}).then(function () {
|
||||
|
||||
apiClient.deleteItem(itemId).then(function () {
|
||||
resolve(true);
|
||||
|
@ -585,6 +616,10 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
|||
|
||||
return getCommands(options).then(function (commands) {
|
||||
|
||||
if (!commands.length) {
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
require(['actionsheet'], function (actionSheet) {
|
||||
|
|
|
@ -8,7 +8,11 @@ define(['apphost'], function (appHost) {
|
|||
|
||||
options = options || {};
|
||||
|
||||
var name = item.EpisodeTitle || item.Name || '';
|
||||
if (item.Type == 'Timer') {
|
||||
item = item.ProgramInfo || item;
|
||||
}
|
||||
|
||||
var name = (item.Type == 'Program' && item.IsSeries ? item.EpisodeTitle : item.Name) || '';
|
||||
|
||||
if (item.Type == "TvChannel") {
|
||||
|
||||
|
@ -37,7 +41,7 @@ define(['apphost'], function (appHost) {
|
|||
number += "-" + displayIndexNumber;
|
||||
}
|
||||
|
||||
name = number + " - " + name;
|
||||
name = name ? (number + " - " + name) : number;
|
||||
|
||||
}
|
||||
|
||||
|
@ -46,26 +50,45 @@ define(['apphost'], function (appHost) {
|
|||
|
||||
function supportsAddingToCollection(item) {
|
||||
|
||||
if (item.Type == 'Timer') {
|
||||
if (item.Type == 'Timer' || item.Type == 'SeriesTimer') {
|
||||
return false;
|
||||
}
|
||||
|
||||
var invalidTypes = ['Person', 'Genre', 'MusicGenre', 'Studio', 'GameGenre', 'BoxSet', 'Playlist', 'UserView', 'CollectionFolder', 'Audio', 'TvChannel', 'Program', 'MusicAlbum', 'Timer'];
|
||||
|
||||
if (item.Type == 'Recording') {
|
||||
if (item.Status != 'Completed') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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";
|
||||
if (item.Type == 'SeriesTimer') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (item.Type == 'Recording') {
|
||||
if (item.Status != 'Completed') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return item.MediaType || item.IsFolder || item.Type == "Genre" || item.Type == "MusicGenre" || item.Type == "MusicArtist";
|
||||
}
|
||||
|
||||
function canEdit(user, itemType) {
|
||||
function canEdit(user, item) {
|
||||
|
||||
var itemType = item.Type;
|
||||
|
||||
if (itemType == "UserRootFolder" || /*itemType == "CollectionFolder" ||*/ itemType == "UserView") {
|
||||
return false;
|
||||
|
@ -75,12 +98,13 @@ define(['apphost'], function (appHost) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (user.Policy.IsAdministrator) {
|
||||
|
||||
return true;
|
||||
if (item.Type == 'Recording') {
|
||||
if (item.Status != 'Completed') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return user.Policy.IsAdministrator;
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -111,7 +135,9 @@ define(['apphost'], function (appHost) {
|
|||
|
||||
canEdit: canEdit,
|
||||
|
||||
canEditImages: function (user, itemType) {
|
||||
canEditImages: function (user, item) {
|
||||
|
||||
var itemType = item.Type;
|
||||
|
||||
if (itemType == 'UserView') {
|
||||
if (user.Policy.IsAdministrator) {
|
||||
|
@ -122,7 +148,13 @@ define(['apphost'], function (appHost) {
|
|||
return false;
|
||||
}
|
||||
|
||||
return itemType != 'Timer' && canEdit(user, itemType);
|
||||
if (item.Type == 'Recording') {
|
||||
if (item.Status != 'Completed') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return itemType != 'Timer' && itemType != 'SeriesTimer' && canEdit(user, item);
|
||||
},
|
||||
|
||||
canSync: function (user, item) {
|
||||
|
@ -139,6 +171,14 @@ define(['apphost'], function (appHost) {
|
|||
if (item.Type == 'Timer') {
|
||||
return false;
|
||||
}
|
||||
if (item.Type == 'SeriesTimer') {
|
||||
return false;
|
||||
}
|
||||
if (item.Type == 'Recording') {
|
||||
if (item.Status != 'Completed') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return user.Policy.EnablePublicSharing && appHost.supports('sharing');
|
||||
}
|
||||
};
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
var isPortrait = className.indexOf('portrait') != -1;
|
||||
|
||||
var parentName = isSmallItem || isMiniItem || isPortrait ? null : item.SeriesName;
|
||||
var name = itemHelper.getDisplayName(item);
|
||||
var name = item.EpisodeTitle ? item.Name : itemHelper.getDisplayName(item);
|
||||
|
||||
html += '<div>';
|
||||
var logoHeight = 26;
|
||||
|
@ -140,13 +140,6 @@
|
|||
html += '<button is="emby-button" class="itemAction autoSize fab cardOverlayFab mini" data-action="menu" data-playoptions="false"><i class="md-icon cardOverlayFab-md-icon">' + moreIcon + '</i></button>';
|
||||
buttonCount++;
|
||||
|
||||
html += userdataButtons.getIconsHtml({
|
||||
item: item,
|
||||
style: 'fab-mini',
|
||||
cssClass: 'cardOverlayFab',
|
||||
iconCssClass: 'cardOverlayFab-md-icon'
|
||||
});
|
||||
|
||||
html += '</div>';
|
||||
|
||||
html += '</div>';
|
||||
|
@ -198,7 +191,7 @@
|
|||
var id = dataElement.getAttribute('data-id');
|
||||
var type = dataElement.getAttribute('data-type');
|
||||
|
||||
if (type == 'Timer') {
|
||||
if (type == 'Timer' || type == 'SeriesTimer') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -215,6 +208,16 @@
|
|||
|
||||
innerElem.innerHTML = getOverlayHtml(apiClient, item, user, dataElement);
|
||||
|
||||
userdataButtons.fill({
|
||||
item: item,
|
||||
style: 'fab-mini',
|
||||
cssClass: 'cardOverlayFab',
|
||||
iconCssClass: 'cardOverlayFab-md-icon',
|
||||
element: innerElem.querySelector('.cardOverlayButtons'),
|
||||
fillMode: 'insertAdjacent',
|
||||
insertLocation: 'beforeend'
|
||||
});
|
||||
|
||||
innerElem.querySelector('.cardOverlayButtons').addEventListener('click', onCardOverlayButtonsClick);
|
||||
});
|
||||
|
||||
|
@ -243,7 +246,7 @@
|
|||
showOverlayTimeout = setTimeout(function () {
|
||||
onShowTimerExpired(card);
|
||||
|
||||
}, 1000);
|
||||
}, 1400);
|
||||
}
|
||||
|
||||
function preventTouchHover() {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(['browser', 'appSettings', 'events'], function (browser, appSettings, events) {
|
||||
'use strict';
|
||||
|
||||
function setLayout(self, layout, selectedLayout) {
|
||||
|
||||
|
@ -17,7 +18,7 @@ define(['browser', 'appSettings', 'events'], function (browser, appSettings, eve
|
|||
|
||||
self.setLayout = function (layout, save) {
|
||||
|
||||
if (!layout || layout == 'auto') {
|
||||
if (!layout || layout === 'auto') {
|
||||
self.autoLayout();
|
||||
|
||||
if (save !== false) {
|
||||
|
|
|
@ -15,19 +15,10 @@
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
.listItem-border {
|
||||
border-bottom: 1px solid #2a2a2a;
|
||||
}
|
||||
|
||||
.listItem-button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.listItem-nosidepadding {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.listItem-largeImage {
|
||||
padding: .5em !important;
|
||||
}
|
||||
|
@ -46,6 +37,7 @@
|
|||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
flex-shrink: 0;
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
.listViewDragHandle {
|
||||
|
@ -54,33 +46,20 @@
|
|||
|
||||
.listItemBody {
|
||||
flex-grow: 1;
|
||||
padding: 0 1em;
|
||||
padding: .8em 1em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex-direction: column;
|
||||
vertical-align: middle;
|
||||
justify-content: center;
|
||||
min-height: 3.44em;
|
||||
}
|
||||
|
||||
.listItemBody-nogrow {
|
||||
flex-grow: initial;
|
||||
flex-shrink: 0;
|
||||
width: 9em;
|
||||
opacity: .7;
|
||||
.listItemBody-noleftpadding {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
|
||||
.listItemBody-nogrow {
|
||||
width: 4em;
|
||||
}
|
||||
}
|
||||
|
||||
.two-line {
|
||||
min-height: 5.15em;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
.listItem-odd {
|
||||
background: #1c1c1c;
|
||||
}
|
||||
|
||||
.three-line {
|
||||
|
@ -128,7 +107,6 @@
|
|||
background-color: #52B54B;
|
||||
padding: .5em;
|
||||
color: #fff;
|
||||
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);
|
||||
}
|
||||
|
||||
.listItemProgressBar {
|
||||
|
@ -169,6 +147,7 @@
|
|||
/* Don't display if flex not supported */
|
||||
display: none;
|
||||
align-items: center;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.listGroupHeader {
|
||||
|
@ -191,6 +170,7 @@
|
|||
|
||||
.listItem, .listItemBody, .listItemMediaInfo {
|
||||
display: flex;
|
||||
contain: layout style;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,3 +180,7 @@
|
|||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.listItemCheckboxContainer {
|
||||
width: auto !important;
|
||||
}
|
||||
|
|
|
@ -111,6 +111,12 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
|||
|
||||
for (var i = 0, length = textlines.length; i < length; i++) {
|
||||
|
||||
var text = textlines[i];
|
||||
|
||||
if (!text) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i === 0) {
|
||||
if (isLargeStyle) {
|
||||
html += '<h2 class="listItemBodyText">';
|
||||
|
@ -143,7 +149,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
|||
|
||||
var clickEntireItem = layoutManager.tv ? true : false;
|
||||
var outerTagName = clickEntireItem ? 'button' : 'div';
|
||||
var enableSideMediaInfo = options.enableSideMediaInfo != null ? options.enableSideMediaInfo : clickEntireItem;
|
||||
var enableSideMediaInfo = options.enableSideMediaInfo != null ? options.enableSideMediaInfo : true;
|
||||
|
||||
var outerHtml = '';
|
||||
|
||||
|
@ -178,10 +184,12 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
|||
}
|
||||
}
|
||||
|
||||
var cssClass = "listItem listItem-nosidepadding";
|
||||
var cssClass = "listItem";
|
||||
|
||||
if (options.border !== false) {
|
||||
cssClass += ' listItem-border';
|
||||
if (options.highlight !== false) {
|
||||
if (i % 2 == 1) {
|
||||
cssClass += ' listItem-odd';
|
||||
}
|
||||
}
|
||||
|
||||
if (clickEntireItem) {
|
||||
|
@ -242,23 +250,32 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
|||
html += '</div>';
|
||||
}
|
||||
|
||||
if (options.showProgramTimeColumn) {
|
||||
html += '<div class="listItemBody listItemBody-nogrow listItemBody-rightborder"><div class="listItemBodyText">';
|
||||
html += datetime.getDisplayTime(datetime.parseISO8601Date(item.StartDate));
|
||||
html += ' - ';
|
||||
html += datetime.getDisplayTime(datetime.parseISO8601Date(item.EndDate));
|
||||
html += '</div></div>';
|
||||
var textlines = [];
|
||||
|
||||
if (options.showProgramDateTime) {
|
||||
textlines.push(datetime.toLocaleString(datetime.parseISO8601Date(item.StartDate), {
|
||||
|
||||
weekday: 'long',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: '2-digit'
|
||||
}));
|
||||
}
|
||||
|
||||
var textlines = [];
|
||||
if (options.showProgramTime) {
|
||||
textlines.push(datetime.getDisplayTime(datetime.parseISO8601Date(item.StartDate)));
|
||||
}
|
||||
|
||||
var parentTitle = null;
|
||||
|
||||
if (options.showParentTitle) {
|
||||
if (item.Type == 'Episode') {
|
||||
textlines.push(item.SeriesName || ' ');
|
||||
parentTitle = item.SeriesName;
|
||||
}
|
||||
|
||||
if (item.EpisodeTitle) {
|
||||
textlines.push(item.Name || ' ');
|
||||
else if (item.IsSeries) {
|
||||
parentTitle = item.Name;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,21 +284,42 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
|||
if (options.showIndexNumber && item.IndexNumber != null) {
|
||||
displayName = item.IndexNumber + ". " + displayName;
|
||||
}
|
||||
textlines.push(displayName);
|
||||
|
||||
if (item.ArtistItems && item.Type != 'MusicAlbum') {
|
||||
textlines.push(item.ArtistItems.map(function (a) {
|
||||
return a.Name;
|
||||
if (options.showParentTitle && options.parentTitleWithTitle) {
|
||||
|
||||
}).join(', ') || ' ');
|
||||
if (displayName) {
|
||||
|
||||
if (parentTitle) {
|
||||
parentTitle += ' - ';
|
||||
}
|
||||
parentTitle = (parentTitle || '') + displayName;
|
||||
}
|
||||
|
||||
textlines.push(parentTitle || '');
|
||||
}
|
||||
else if (options.showParentTitle) {
|
||||
textlines.push(parentTitle || '');
|
||||
}
|
||||
|
||||
if (item.AlbumArtist && item.Type == 'MusicAlbum') {
|
||||
textlines.push(item.AlbumArtist || ' ');
|
||||
if (displayName && !options.parentTitleWithTitle) {
|
||||
textlines.push(displayName);
|
||||
}
|
||||
|
||||
if (options.artist !== false) {
|
||||
if (item.ArtistItems && item.Type != 'MusicAlbum') {
|
||||
textlines.push(item.ArtistItems.map(function (a) {
|
||||
return a.Name;
|
||||
|
||||
}).join(', '));
|
||||
}
|
||||
|
||||
if (item.AlbumArtist && item.Type == 'MusicAlbum') {
|
||||
textlines.push(item.AlbumArtist);
|
||||
}
|
||||
}
|
||||
|
||||
if (item.Type == 'Game') {
|
||||
textlines.push(item.GameSystem || ' ');
|
||||
textlines.push(item.GameSystem);
|
||||
}
|
||||
|
||||
if (item.Type == 'TvChannel') {
|
||||
|
@ -291,24 +329,31 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
|||
}
|
||||
}
|
||||
|
||||
cssClass = 'listItemBody two-line';
|
||||
cssClass = 'listItemBody';
|
||||
if (!clickEntireItem) {
|
||||
cssClass += ' itemAction';
|
||||
}
|
||||
|
||||
if (options.image === false) {
|
||||
cssClass += ' itemAction listItemBody-noleftpadding';
|
||||
}
|
||||
|
||||
html += '<div class="' + cssClass + '">';
|
||||
|
||||
var moreIcon = appHost.moreIcon == 'dots-horiz' ? '' : '';
|
||||
|
||||
html += getTextLinesHtml(textlines, isLargeStyle);
|
||||
|
||||
if (!enableSideMediaInfo) {
|
||||
if (options.mediaInfo !== false) {
|
||||
if (!enableSideMediaInfo) {
|
||||
|
||||
var mediaInfoClass = 'secondary listItemMediaInfo listItemBodyText';
|
||||
var mediaInfoClass = 'secondary listItemMediaInfo listItemBodyText';
|
||||
|
||||
html += '<div class="' + mediaInfoClass + '">' + mediaInfo.getPrimaryMediaInfoHtml(item, {
|
||||
episodeTitle: false
|
||||
}) + '</div>';
|
||||
html += '<div class="' + mediaInfoClass + '">' + mediaInfo.getPrimaryMediaInfoHtml(item, {
|
||||
episodeTitle: false,
|
||||
originalAirDate: false
|
||||
}) + '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
if (enableOverview && item.Overview) {
|
||||
|
@ -319,18 +364,32 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
|||
|
||||
html += '</div>';
|
||||
|
||||
if (enableSideMediaInfo) {
|
||||
html += '<div class="secondary listItemMediaInfo">' + mediaInfo.getPrimaryMediaInfoHtml(item, {
|
||||
if (options.mediaInfo !== false) {
|
||||
if (enableSideMediaInfo) {
|
||||
html += '<div class="secondary listItemMediaInfo">' + mediaInfo.getPrimaryMediaInfoHtml(item, {
|
||||
|
||||
year: false,
|
||||
container: false,
|
||||
episodeTitle: false
|
||||
year: false,
|
||||
container: false,
|
||||
episodeTitle: false
|
||||
|
||||
}) + '</div>';
|
||||
}) + '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.recordButton && (item.Type == 'Timer' || item.Type == 'Program')) {
|
||||
html += indicators.getTimerIndicator(item).replace('indicatorIcon', 'indicatorIcon listItemAside');
|
||||
}
|
||||
|
||||
if (!clickEntireItem) {
|
||||
html += '<button is="paper-icon-button-light" class="listItemButton itemAction autoSize" data-action="menu"><i class="md-icon">' + moreIcon + '</i></button>';
|
||||
|
||||
if (options.moreButton !== false) {
|
||||
html += '<button is="paper-icon-button-light" class="listItemButton itemAction autoSize" data-action="menu"><i class="md-icon">' + moreIcon + '</i></button>';
|
||||
}
|
||||
|
||||
if (options.recordButton) {
|
||||
|
||||
html += '<button is="paper-icon-button-light" class="listItemButton itemAction autoSize" data-action="programdialog">' + indicators.getTimerIndicator(item) + '</button>';
|
||||
}
|
||||
|
||||
if (options.enableUserDataButtons !== false) {
|
||||
html += '<span class="listViewUserDataButtons">';
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
.mediaInfoProgramAttribute {
|
||||
color: #fff;
|
||||
text-transform: uppercase;
|
||||
background: #EF6C00;
|
||||
padding: .16em .6em;
|
||||
border-radius: .15em;
|
||||
font-size: 80%;
|
||||
|
|
|
@ -1,4 +1,35 @@
|
|||
define(['datetime', 'globalize', 'embyRouter', 'itemHelper', 'material-icons', 'css!./mediainfo.css'], function (datetime, globalize, embyRouter, itemHelper) {
|
||||
define(['datetime', 'globalize', 'embyRouter', 'itemHelper', 'material-icons', 'css!./mediainfo.css', 'programStyles'], function (datetime, globalize, embyRouter, itemHelper) {
|
||||
|
||||
function getTimerIndicator(item) {
|
||||
|
||||
var status;
|
||||
|
||||
if (item.Type == 'SeriesTimer') {
|
||||
return '<i class="md-icon mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon"></i>';
|
||||
}
|
||||
else if (item.TimerId || item.SeriesTimerId) {
|
||||
|
||||
status = item.Status || 'Cancelled';
|
||||
}
|
||||
else if (item.Type == 'Timer') {
|
||||
|
||||
status = item.Status;
|
||||
}
|
||||
else {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (item.SeriesTimerId) {
|
||||
|
||||
if (status != 'Cancelled') {
|
||||
return '<i class="md-icon mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon"></i>';
|
||||
}
|
||||
|
||||
return '<i class="md-icon mediaInfoItem mediaInfoIconItem"></i>';
|
||||
}
|
||||
|
||||
return '<i class="md-icon mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon"></i>';
|
||||
}
|
||||
|
||||
function getProgramInfoHtml(item, options) {
|
||||
var html = '';
|
||||
|
@ -6,23 +37,14 @@ define(['datetime', 'globalize', 'embyRouter', 'itemHelper', 'material-icons', '
|
|||
var miscInfo = [];
|
||||
var text, date;
|
||||
|
||||
if (item.ChannelName) {
|
||||
|
||||
if (options.interactive && item.ChannelId) {
|
||||
miscInfo.push('<a class="lnkChannel" data-id="' + item.ChannelId + '" data-serverid="' + item.ServerId + '" href="#">' + item.ChannelName + '</a>');
|
||||
} else {
|
||||
miscInfo.push(item.ChannelName);
|
||||
}
|
||||
}
|
||||
|
||||
if (item.StartDate) {
|
||||
|
||||
try {
|
||||
date = datetime.parseISO8601Date(item.StartDate);
|
||||
|
||||
text = datetime.toLocaleDateString(date);
|
||||
text = datetime.toLocaleDateString(date, { weekday: 'short', month: 'short', day: 'numeric' });
|
||||
|
||||
text += ', ' + datetime.getDisplayTime(date);
|
||||
text += ' ' + datetime.getDisplayTime(date);
|
||||
|
||||
if (item.EndDate) {
|
||||
date = datetime.parseISO8601Date(item.EndDate);
|
||||
|
@ -40,15 +62,22 @@ define(['datetime', 'globalize', 'embyRouter', 'itemHelper', 'material-icons', '
|
|||
miscInfo.push('CH ' + item.ChannelNumber);
|
||||
}
|
||||
|
||||
if (item.SeriesTimerId) {
|
||||
miscInfo.push({
|
||||
html: '<i class="md-icon mediaInfoItem mediaInfoTimerIcon mediaInfoIconItem"></i>'
|
||||
});
|
||||
if (item.ChannelName) {
|
||||
|
||||
if (options.interactive && item.ChannelId) {
|
||||
miscInfo.push('<a class="lnkChannel" data-id="' + item.ChannelId + '" data-serverid="' + item.ServerId + '" href="#">' + item.ChannelName + '</a>');
|
||||
} else {
|
||||
miscInfo.push(item.ChannelName);
|
||||
}
|
||||
}
|
||||
else if (item.TimerId) {
|
||||
miscInfo.push({
|
||||
html: '<i class="md-icon mediaInfoItem mediaInfoTimerIcon mediaInfoIconItem"></i>'
|
||||
});
|
||||
|
||||
if (options.timerIndicator !== false) {
|
||||
var timerHtml = getTimerIndicator(item);
|
||||
if (timerHtml) {
|
||||
miscInfo.push({
|
||||
html: timerHtml
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
html += miscInfo.map(function (m) {
|
||||
|
@ -159,22 +188,22 @@ define(['datetime', 'globalize', 'embyRouter', 'itemHelper', 'material-icons', '
|
|||
|
||||
if (item.IsLive) {
|
||||
miscInfo.push({
|
||||
html: '<div class="mediaInfoProgramAttribute mediaInfoItem">' + globalize.translate('sharedcomponents#Live') + '</div>'
|
||||
html: '<div class="mediaInfoProgramAttribute mediaInfoItem liveTvProgram">' + globalize.translate('sharedcomponents#Live') + '</div>'
|
||||
});
|
||||
}
|
||||
else if (item.IsPremiere) {
|
||||
miscInfo.push({
|
||||
html: '<div class="mediaInfoProgramAttribute mediaInfoItem">' + globalize.translate('sharedcomponents#Premiere') + '</div>'
|
||||
html: '<div class="mediaInfoProgramAttribute mediaInfoItem premiereTvProgram">' + globalize.translate('sharedcomponents#Premiere') + '</div>'
|
||||
});
|
||||
}
|
||||
else if (item.IsSeries && !item.IsRepeat) {
|
||||
miscInfo.push({
|
||||
html: '<div class="mediaInfoProgramAttribute mediaInfoItem">' + globalize.translate('sharedcomponents#AttributeNew') + '</div>'
|
||||
html: '<div class="mediaInfoProgramAttribute mediaInfoItem newTvProgram">' + globalize.translate('sharedcomponents#AttributeNew') + '</div>'
|
||||
});
|
||||
}
|
||||
else if (item.IsSeries && item.IsRepeat) {
|
||||
miscInfo.push({
|
||||
html: '<div class="mediaInfoProgramAttribute mediaInfoItem">' + globalize.translate('sharedcomponents#Repeat') + '</div>'
|
||||
html: '<div class="mediaInfoProgramAttribute mediaInfoItem repeatTvProgram">' + globalize.translate('sharedcomponents#Repeat') + '</div>'
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -182,7 +211,7 @@ define(['datetime', 'globalize', 'embyRouter', 'itemHelper', 'material-icons', '
|
|||
miscInfo.push(itemHelper.getDisplayName(item));
|
||||
}
|
||||
|
||||
else if (item.PremiereDate) {
|
||||
else if (item.PremiereDate && options.originalAirDate !== false) {
|
||||
|
||||
try {
|
||||
date = datetime.parseISO8601Date(item.PremiereDate);
|
||||
|
@ -198,20 +227,22 @@ define(['datetime', 'globalize', 'embyRouter', 'itemHelper', 'material-icons', '
|
|||
}
|
||||
}
|
||||
|
||||
if (item.Type != "Series" && item.Type != "Episode" && item.Type != "Person" && item.MediaType != 'Photo' && item.Type != 'Program') {
|
||||
if (options.year !== false) {
|
||||
if (item.Type != "Series" && item.Type != "Episode" && item.Type != "Person" && item.MediaType != 'Photo' && item.Type != 'Program') {
|
||||
|
||||
if (item.ProductionYear) {
|
||||
if (item.ProductionYear) {
|
||||
|
||||
miscInfo.push(item.ProductionYear);
|
||||
}
|
||||
else if (item.PremiereDate) {
|
||||
|
||||
try {
|
||||
text = datetime.parseISO8601Date(item.PremiereDate).getFullYear();
|
||||
miscInfo.push(text);
|
||||
miscInfo.push(item.ProductionYear);
|
||||
}
|
||||
catch (e) {
|
||||
console.log("Error parsing date: " + item.PremiereDate);
|
||||
else if (item.PremiereDate) {
|
||||
|
||||
try {
|
||||
text = datetime.parseISO8601Date(item.PremiereDate).getFullYear();
|
||||
miscInfo.push(text);
|
||||
}
|
||||
catch (e) {
|
||||
console.log("Error parsing date: " + item.PremiereDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,7 +156,6 @@
|
|||
AirDays: getSelectedAirDays(form),
|
||||
AirTime: form.querySelector('#txtAirTime').value,
|
||||
Genres: editableListViewValues(form.querySelector("#listGenres")),
|
||||
ProductionLocations: editableListViewValues(form.querySelector("#listCountries")),
|
||||
Tags: editableListViewValues(form.querySelector("#listTags")),
|
||||
Keywords: editableListViewValues(form.querySelector("#listKeywords")),
|
||||
Studios: editableListViewValues(form.querySelector("#listStudios")).map(function (element) { return { Name: element }; }),
|
||||
|
@ -683,12 +682,6 @@
|
|||
showElement('#fldCustomRating', context);
|
||||
}
|
||||
|
||||
if (item.Type == "Movie" || item.Type == "Trailer" || item.Type == "MusicArtist") {
|
||||
showElement('#countriesCollapsible', context);
|
||||
} else {
|
||||
hideElement('#countriesCollapsible', context);
|
||||
}
|
||||
|
||||
if (item.Type == "TvChannel") {
|
||||
hideElement('#tagsCollapsible', context);
|
||||
hideElement('#metadataSettingsCollapsible', context);
|
||||
|
@ -809,7 +802,6 @@
|
|||
el.checked = (item.AirDays || []).indexOf(el.getAttribute('data-day')) != -1;
|
||||
});
|
||||
|
||||
populateListView(context.querySelector('#listCountries'), item.ProductionLocations || []);
|
||||
populateListView(context.querySelector('#listGenres'), item.Genres);
|
||||
populatePeople(context, item.People || []);
|
||||
|
||||
|
|
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