From fdb7c99ed445850b775b0214ce3883e100404b0b Mon Sep 17 00:00:00 2001 From: dkanada Date: Fri, 25 Oct 2019 23:14:42 +0900 Subject: [PATCH 01/42] remove dashboard icon from header --- src/scripts/librarymenu.js | 33 +++++---------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/src/scripts/librarymenu.js b/src/scripts/librarymenu.js index 3c7918d66c..a3ce22fe9f 100644 --- a/src/scripts/librarymenu.js +++ b/src/scripts/librarymenu.js @@ -52,14 +52,6 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " headerSearchButton.classList.remove("hide"); } - if (headerSettingsButton) { - if (user.localUser.Policy.IsAdministrator) { - headerSettingsButton.classList.remove("hide"); - } else { - headerSettingsButton.classList.add("hide"); - } - } - headerCastButton.classList.remove("hide"); } else { headerHomeButton.classList.add("hide"); @@ -68,10 +60,6 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " if (headerSearchButton) { headerSearchButton.classList.add("hide"); } - - if (headerSettingsButton) { - headerSettingsButton.classList.add("hide"); - } } requiresUserRefresh = false; @@ -95,10 +83,6 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " Dashboard.navigate("mypreferencesmenu.html"); } - function onSettingsClick(e) { - Dashboard.navigate("dashboard.html"); - } - function onHeaderHomeButtonClick() { Dashboard.navigate("home.html"); } @@ -121,12 +105,9 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " headerUserButton.addEventListener("click", onHeaderUserButtonClick); headerHomeButton.addEventListener("click", onHeaderHomeButtonClick); - initHeadRoom(skinHeader); headerCastButton.addEventListener("click", onCastButtonClicked); - if (headerSettingsButton) { - headerSettingsButton.addEventListener("click", onSettingsClick); - } + initHeadRoom(skinHeader); } function onCastButtonClicked() { @@ -747,7 +728,6 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " var headerBackButton; var headerUserButton; var currentUser; - var headerSettingsButton; var headerCastButton; var headerSearchButton; var enableLibraryNavDrawer = !layoutManager.tv; @@ -873,23 +853,20 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " html += ''; html += ''; html += ''; - - if (!layoutManager.mobile) { - html += ''; - } - html += ""; html += ""; html += '
'; html += "
"; + skinHeader.classList.add("skinHeader-withBackground"); + skinHeader.classList.add("skinHeader-blurred"); skinHeader.innerHTML = html; + headerHomeButton = skinHeader.querySelector(".headerHomeButton"); headerUserButton = skinHeader.querySelector(".headerUserButton"); - headerSettingsButton = skinHeader.querySelector(".headerSettingsButton"); headerCastButton = skinHeader.querySelector(".headerCastButton"); headerSearchButton = skinHeader.querySelector(".headerSearchButton"); - skinHeader.classList.add("skinHeader-blurred"); + lazyLoadViewMenuBarImages(); bindMenuEvents(); })(); From c565c9015b5700114ec5c38ba2b5b2bbae18f0ab Mon Sep 17 00:00:00 2001 From: Pika <15848969+ThatNerdyPikachu@users.noreply.github.com> Date: Sat, 26 Oct 2019 20:45:14 -0400 Subject: [PATCH 02/42] Actually make DatePlayed use a colon on ItemDetails --- src/controllers/itemdetailpage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/itemdetailpage.js b/src/controllers/itemdetailpage.js index 03e0f68a9b..16cf3fe362 100644 --- a/src/controllers/itemdetailpage.js +++ b/src/controllers/itemdetailpage.js @@ -399,7 +399,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild if (item.UserData && item.UserData.LastPlayedDate) { lastPlayedElement.classList.remove("hide"); var datePlayed = datetime.parseISO8601Date(item.UserData.LastPlayedDate); - lastPlayedElement.innerHTML = globalize.translate("DatePlayed") + " " + datetime.toLocaleDateString(datePlayed) + " " + datetime.getDisplayTime(datePlayed); + lastPlayedElement.innerHTML = globalize.translate("DatePlayed") + ": " + datetime.toLocaleDateString(datePlayed) + " " + datetime.getDisplayTime(datePlayed); } else { lastPlayedElement.classList.add("hide"); } From 651a53d64a2d44abaa7bfd9bf1bf58e5a7fe4122 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Sun, 27 Oct 2019 16:55:18 +0300 Subject: [PATCH 03/42] Move almada and require.js from source control to npm --- assets.js | 6 + package.json | 3 + src/bower_components/alameda/alameda.js | 419 --------------- src/bower_components/requirejs/require.js | 607 ---------------------- src/scripts/apploader.js | 2 +- webpack.common.js | 15 +- 6 files changed, 24 insertions(+), 1028 deletions(-) create mode 100644 assets.js delete mode 100644 src/bower_components/alameda/alameda.js delete mode 100644 src/bower_components/requirejs/require.js diff --git a/assets.js b/assets.js new file mode 100644 index 0000000000..98ec18c227 --- /dev/null +++ b/assets.js @@ -0,0 +1,6 @@ +const JS = [ + 'alameda/alameda.js', + 'requirejs/require.js' +]; + +module.exports = [...JS]; diff --git a/package.json b/package.json index bcbdd3dacc..051102239b 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "repository": "https://github.com/jellyfin/jellyfin-web", "license": "GPL-2.0-or-later", "devDependencies": { + "clean-webpack-plugin": "^3.0.0", "copy-webpack-plugin": "^5.0.3", "css-loader": "^2.1.0", "eslint": "^5.16.0", @@ -16,12 +17,14 @@ "webpack-merge": "^4.2.2" }, "dependencies": { + "alameda": "^1.3.0", "flv.js": "^1.5.0", "hls.js": "^0.12.4", "howler": "^2.1.2", "jquery": "^3.4.1", "jstree": "^3.3.7", "libjass": "^0.11.0", + "requirejs": "^2.3.5", "shaka-player": "^2.5.5", "sortablejs": "^1.9.0", "swiper": "^3.4.2" diff --git a/src/bower_components/alameda/alameda.js b/src/bower_components/alameda/alameda.js deleted file mode 100644 index 4ac0f7496b..0000000000 --- a/src/bower_components/alameda/alameda.js +++ /dev/null @@ -1,419 +0,0 @@ -var requirejs, require, define; -! function(global, Promise, undef) { - function commentReplace(match, singlePrefix) { - return singlePrefix || "" - } - - function hasProp(obj, prop) { - return hasOwn.call(obj, prop) - } - - function getOwn(obj, prop) { - return obj && hasProp(obj, prop) && obj[prop] - } - - function obj() { - return Object.create(null) - } - - function eachProp(obj, func) { - var prop; - for (prop in obj) - if (hasProp(obj, prop) && func(obj[prop], prop)) break - } - - function mixin(target, source, force, deepStringMixin) { - return source && eachProp(source, function(value, prop) { - !force && hasProp(target, prop) || (!deepStringMixin || "object" != typeof value || !value || Array.isArray(value) || "function" == typeof value || value instanceof RegExp ? target[prop] = value : (target[prop] || (target[prop] = {}), mixin(target[prop], value, force, deepStringMixin))) - }), target - } - - function getGlobal(value) { - if (!value) return value; - var g = global; - return value.split(".").forEach(function(part) { - g = g[part] - }), g - } - - function newContext(contextName) { - function trimDots(ary) { - var i, part, length = ary.length; - for (i = 0; i < length; i++) - if ("." === (part = ary[i])) ary.splice(i, 1), i -= 1; - else if (".." === part) { - if (0 === i || 1 === i && ".." === ary[2] || ".." === ary[i - 1]) continue; - i > 0 && (ary.splice(i - 1, 2), i -= 2) - } - } - - function normalize(name, baseName, applyMap) { - var mapValue, nameParts, i, j, nameSegment, lastIndex, foundMap, foundI, foundStarMap, starI, baseParts = baseName && baseName.split("/"), - normalizedBaseParts = baseParts, - map = config.map, - starMap = map && map["*"]; - if (name && (name = name.split("/"), lastIndex = name.length - 1, config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex]) && (name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, "")), "." === name[0].charAt(0) && baseParts && (normalizedBaseParts = baseParts.slice(0, baseParts.length - 1), name = normalizedBaseParts.concat(name)), trimDots(name), name = name.join("/")), applyMap && map && (baseParts || starMap)) { - nameParts = name.split("/"); - outerLoop: for (i = nameParts.length; i > 0; i -= 1) { - if (nameSegment = nameParts.slice(0, i).join("/"), baseParts) - for (j = baseParts.length; j > 0; j -= 1) - if ((mapValue = getOwn(map, baseParts.slice(0, j).join("/"))) && (mapValue = getOwn(mapValue, nameSegment))) { - foundMap = mapValue, foundI = i; - break outerLoop - }! foundStarMap && starMap && getOwn(starMap, nameSegment) && (foundStarMap = getOwn(starMap, nameSegment), starI = i) - }!foundMap && foundStarMap && (foundMap = foundStarMap, foundI = starI), foundMap && (nameParts.splice(0, foundI, foundMap), name = nameParts.join("/")) - } - return getOwn(config.pkgs, name) || name - } - - function makeShimExports(value) { - function fn() { - var ret; - return value.init && (ret = value.init.apply(global, arguments)), ret || value.exports && getGlobal(value.exports) - } - return fn - } - - function takeQueue(anonId) { - var i, id, args, shim; - for (i = 0; i < queue.length; i += 1) { - if ("string" != typeof queue[i][0]) { - if (!anonId) break; - queue[i].unshift(anonId), anonId = undef - } - args = queue.shift(), id = args[0], i -= 1, id in defined || id in waiting || (id in deferreds ? main.apply(undef, args) : waiting[id] = args) - } - anonId && (shim = getOwn(config.shim, anonId) || {}, main(anonId, shim.deps || [], shim.exportsFn)) - } - - function makeRequire(relName, topLevel) { - var req = function(deps, callback, errback, alt) { - var name, cfg; - if (topLevel && takeQueue(), "string" == typeof deps) { - if (handlers[deps]) return handlers[deps](relName); - if (!((name = makeMap(deps, relName, !0).id) in defined)) throw new Error("Not loaded: " + name); - return defined[name] - } - return deps && !Array.isArray(deps) && (cfg = deps, deps = undef, Array.isArray(callback) && (deps = callback, callback = errback, errback = alt), topLevel) ? req.config(cfg)(deps, callback, errback) : (callback = callback || function() { - return slice.call(arguments, 0) - }, asyncResolve.then(function() { - return takeQueue(), main(undef, deps || [], callback, errback, relName) - })) - }; - return req.isBrowser = "undefined" != typeof document && "undefined" != typeof navigator, req.nameToUrl = function(moduleName, ext, skipExt) { - var paths, syms, i, parentModule, url, parentPath, bundleId, pkgMain = getOwn(config.pkgs, moduleName); - if (pkgMain && (moduleName = pkgMain), bundleId = getOwn(bundlesMap, moduleName)) return req.nameToUrl(bundleId, ext, skipExt); - if (urlRegExp.test(moduleName)) url = moduleName + (ext || ""); - else { - for (paths = config.paths, syms = moduleName.split("/"), i = syms.length; i > 0; i -= 1) - if (parentModule = syms.slice(0, i).join("/"), parentPath = getOwn(paths, parentModule)) { - Array.isArray(parentPath) && (parentPath = parentPath[0]), syms.splice(0, i, parentPath); - break - } url = syms.join("/"), url += ext || (/^data\:|^blob\:|\?/.test(url) || skipExt ? "" : ".js"), url = ("/" === url.charAt(0) || url.match(/^[\w\+\.\-]+:/) ? "" : config.baseUrl) + url - } - return config.urlArgs && !/^blob\:/.test(url) ? url + config.urlArgs(moduleName, url) : url - }, req.toUrl = function(moduleNamePlusExt) { - var ext, index = moduleNamePlusExt.lastIndexOf("."), - segment = moduleNamePlusExt.split("/")[0], - isRelative = "." === segment || ".." === segment; - return -1 !== index && (!isRelative || index > 1) && (ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length), moduleNamePlusExt = moduleNamePlusExt.substring(0, index)), req.nameToUrl(normalize(moduleNamePlusExt, relName), ext, !0) - }, req.defined = function(id) { - return makeMap(id, relName, !0).id in defined - }, req.specified = function(id) { - return (id = makeMap(id, relName, !0).id) in defined || id in deferreds - }, req - } - - function resolve(name, d, value) { - name && (defined[name] = value, requirejs.onResourceLoad && requirejs.onResourceLoad(context, d.map, d.deps)), d.finished = !0, d.resolve(value) - } - - function reject(d, err) { - d.finished = !0, d.rejected = !0, d.reject(err) - } - - function makeNormalize(relName) { - return function(name) { - return normalize(name, relName, !0) - } - } - - function defineModule(d) { - d.factoryCalled = !0; - var ret, name = d.map.id; - try { - ret = context.execCb(name, d.factory, d.values, defined[name]) - } catch (err) { - return reject(d, err) - } - name ? ret === undef && (d.cjsModule ? ret = d.cjsModule.exports : d.usingExports && (ret = defined[name])) : requireDeferreds.splice(requireDeferreds.indexOf(d), 1), resolve(name, d, ret) - } - - function depFinished(val, i) { - this.rejected || this.depDefined[i] || (this.depDefined[i] = !0, this.depCount += 1, this.values[i] = val, this.depending || this.depCount !== this.depMax || defineModule(this)) - } - - function makeDefer(name, calculatedMap) { - var d = {}; - return d.promise = new Promise(function(resolve, reject) { - d.resolve = resolve, d.reject = function(err) { - name || requireDeferreds.splice(requireDeferreds.indexOf(d), 1), reject(err) - } - }), d.map = name ? calculatedMap || makeMap(name) : {}, d.depCount = 0, d.depMax = 0, d.values = [], d.depDefined = [], d.depFinished = depFinished, d.map.pr && (d.deps = [makeMap(d.map.pr)]), d - } - - function getDefer(name, calculatedMap) { - var d; - return name ? (d = name in deferreds && deferreds[name]) || (d = deferreds[name] = makeDefer(name, calculatedMap)) : (d = makeDefer(), requireDeferreds.push(d)), d - } - - function makeErrback(d, name) { - return function(err) { - d.rejected || (err.dynaId || (err.dynaId = "id" + (errCount += 1), err.requireModules = [name]), reject(d, err)) - } - } - - function waitForDep(depMap, relName, d, i) { - d.depMax += 1, callDep(depMap, relName).then(function(val) { - d.depFinished(val, i) - }, makeErrback(d, depMap.id)).catch(makeErrback(d, d.map.id)) - } - - function makeLoad(id) { - function load(value) { - fromTextCalled || resolve(id, getDefer(id), value) - } - var fromTextCalled; - return load.error = function(err) { - reject(getDefer(id), err) - }, load.fromText = function(text, textAlt) { - var execError, d = getDefer(id), - map = makeMap(makeMap(id).n), - plainId = map.id; - fromTextCalled = !0, d.factory = function(p, val) { - return val - }, textAlt && (text = textAlt), hasProp(config.config, id) && (config.config[plainId] = config.config[id]); - try { - req.exec(text) - } catch (e) { - execError = new Error("fromText eval for " + plainId + " failed: " + e), execError.requireType = "fromtexteval", reject(d, execError) - } - takeQueue(plainId), d.deps = [map], waitForDep(map, null, d, d.deps.length) - }, load - } - - function callPlugin(plugin, map, relName) { - plugin.load(map.n, makeRequire(relName), makeLoad(map.id), config) - } - - function splitPrefix(name) { - var prefix, index = name ? name.indexOf("!") : -1; - return index > -1 && (prefix = name.substring(0, index), name = name.substring(index + 1, name.length)), [prefix, name] - } - - function breakCycle(d, traced, processed) { - var id = d.map.id; - traced[id] = !0, !d.finished && d.deps && d.deps.forEach(function(depMap) { - var depId = depMap.id, - dep = !hasProp(handlers, depId) && getDefer(depId, depMap); - !dep || dep.finished || processed[depId] || (hasProp(traced, depId) ? d.deps.forEach(function(depMap, i) { - depMap.id === depId && d.depFinished(defined[depId], i) - }) : breakCycle(dep, traced, processed)) - }), processed[id] = !0 - } - - function check(d) { - var err, mid, dfd, notFinished = [], - waitInterval = 1e3 * config.waitSeconds, - expired = waitInterval && startTime + waitInterval < (new Date).getTime(); - if (0 === loadCount && (d ? d.finished || breakCycle(d, {}, {}) : requireDeferreds.length && requireDeferreds.forEach(function(d) { - breakCycle(d, {}, {}) - })), expired) { - for (mid in deferreds) dfd = deferreds[mid], dfd.finished || notFinished.push(dfd.map.id); - err = new Error("Timeout for modules: " + notFinished), err.requireModules = notFinished, err.requireType = "timeout", notFinished.forEach(function(id) { - reject(getDefer(id), err) - }) - } else(loadCount || requireDeferreds.length) && (checkingLater || (checkingLater = !0, setTimeout(function() { - checkingLater = !1, check() - }, 70))) - } - - function delayedError(e) { - console.log(e.stack); - return setTimeout(function() { - e.dynaId && trackedErrors[e.dynaId] || (trackedErrors[e.dynaId] = !0, req.onError(e)) - }), e - } - var req, main, makeMap, callDep, handlers, checkingLater, load, context, defined = obj(), - waiting = obj(), - config = { - waitSeconds: 7, - baseUrl: "./", - paths: {}, - bundles: {}, - pkgs: {}, - shim: {}, - config: {} - }, - mapCache = obj(), - requireDeferreds = [], - deferreds = obj(), - calledDefine = obj(), - calledPlugin = obj(), - loadCount = 0, - startTime = (new Date).getTime(), - errCount = 0, - trackedErrors = obj(), - urlFetched = obj(), - bundlesMap = obj(), - asyncResolve = Promise.resolve(undefined); - return load = "function" == typeof importScripts ? function(map) { - var url = map.url; - urlFetched[url] || (urlFetched[url] = !0, getDefer(map.id), importScripts(url), takeQueue(map.id)) - } : function(map) { - var script, id = map.id, - url = map.url; - urlFetched[url] || (urlFetched[url] = !0, script = document.createElement("script"), script.setAttribute("data-requiremodule", id), script.type = config.scriptType || "text/javascript", script.charset = "utf-8", script.async = !0, loadCount += 1, script.addEventListener("load", function() { - loadCount -= 1, takeQueue(id) - }, !1), script.addEventListener("error", function() { - loadCount -= 1; - var err, pathConfig = getOwn(config.paths, id); - if (pathConfig && Array.isArray(pathConfig) && pathConfig.length > 1) { - script.parentNode.removeChild(script), pathConfig.shift(); - var d = getDefer(id); - d.map = makeMap(id), d.map.url = req.nameToUrl(id), load(d.map) - } else err = new Error("Load failed: " + id + ": " + script.src), err.requireModules = [id], err.requireType = "scripterror", reject(getDefer(id), err) - }, !1), script.src = url, 10 === document.documentMode ? asap.then(function() { - document.head.appendChild(script) - }) : document.head.appendChild(script)) - }, callDep = function(map, relName) { - var args, bundleId, name = map.id, - shim = config.shim[name]; - if (name in waiting) args = waiting[name], delete waiting[name], main.apply(undef, args); - else if (!(name in deferreds)) - if (map.pr) { - if (!(bundleId = getOwn(bundlesMap, name))) return callDep(makeMap(map.pr)).then(function(plugin) { - var newMap = map.prn ? map : makeMap(name, relName, !0), - newId = newMap.id, - shim = getOwn(config.shim, newId); - return newId in calledPlugin || (calledPlugin[newId] = !0, shim && shim.deps ? req(shim.deps, function() { - callPlugin(plugin, newMap, relName) - }) : callPlugin(plugin, newMap, relName)), getDefer(newId).promise - }); - map.url = req.nameToUrl(bundleId), load(map) - } else shim && shim.deps ? req(shim.deps, function() { - load(map) - }) : load(map); - return getDefer(name).promise - }, makeMap = function(name, relName, applyMap) { - if ("string" != typeof name) return name; - var plugin, url, parts, prefix, result, prefixNormalized, cacheKey = name + " & " + (relName || "") + " & " + !!applyMap; - return parts = splitPrefix(name), prefix = parts[0], name = parts[1], !prefix && cacheKey in mapCache ? mapCache[cacheKey] : (prefix && (prefix = normalize(prefix, relName, applyMap), plugin = prefix in defined && defined[prefix]), prefix ? plugin && plugin.normalize ? (name = plugin.normalize(name, makeNormalize(relName)), prefixNormalized = !0) : name = -1 === name.indexOf("!") ? normalize(name, relName, applyMap) : name : (name = normalize(name, relName, applyMap), parts = splitPrefix(name), prefix = parts[0], name = parts[1], url = req.nameToUrl(name)), result = { - id: prefix ? prefix + "!" + name : name, - n: name, - pr: prefix, - url: url, - prn: prefix && prefixNormalized - }, prefix || (mapCache[cacheKey] = result), result) - }, handlers = { - require: function(name) { - return makeRequire(name) - }, - exports: function(name) { - var e = defined[name]; - return void 0 !== e ? e : defined[name] = {} - }, - module: function(name) { - return { - id: name, - uri: "", - exports: handlers.exports(name), - config: function() { - return getOwn(config.config, name) || {} - } - } - } - }, main = function(name, deps, factory, errback, relName) { - if (name) { - if (name in calledDefine) return; - calledDefine[name] = !0 - } - var d = getDefer(name); - return deps && !Array.isArray(deps) && (factory = deps, deps = []), deps = deps ? slice.call(deps, 0) : null, errback || (hasProp(config, "defaultErrback") ? config.defaultErrback && (errback = config.defaultErrback) : errback = delayedError), errback && d.promise.catch(errback), relName = relName || name, "function" == typeof factory ? (!deps.length && factory.length && (factory.toString().replace(commentRegExp, commentReplace).replace(cjsRequireRegExp, function(match, dep) { - deps.push(dep) - }), deps = (1 === factory.length ? ["require"] : ["require", "exports", "module"]).concat(deps)), d.factory = factory, d.deps = deps, d.depending = !0, deps.forEach(function(depName, i) { - var depMap; - deps[i] = depMap = makeMap(depName, relName, !0), depName = depMap.id, "require" === depName ? d.values[i] = handlers.require(name) : "exports" === depName ? (d.values[i] = handlers.exports(name), d.usingExports = !0) : "module" === depName ? d.values[i] = d.cjsModule = handlers.module(name) : void 0 === depName ? d.values[i] = void 0 : waitForDep(depMap, relName, d, i) - }), d.depending = !1, d.depCount === d.depMax && defineModule(d)) : name && resolve(name, d, factory), startTime = (new Date).getTime(), name || check(d), d.promise - }, req = makeRequire(null, !0), req.config = function(cfg) { - if (cfg.context && cfg.context !== contextName) { - var existingContext = getOwn(contexts, cfg.context); - return existingContext ? existingContext.req.config(cfg) : newContext(cfg.context).config(cfg) - } - if (mapCache = obj(), cfg.baseUrl && "/" !== cfg.baseUrl.charAt(cfg.baseUrl.length - 1) && (cfg.baseUrl += "/"), "string" == typeof cfg.urlArgs) { - var urlArgs = cfg.urlArgs; - cfg.urlArgs = function(id, url) { - return (-1 === url.indexOf("?") ? "?" : "&") + urlArgs - } - } - var shim = config.shim, - objs = { - paths: !0, - bundles: !0, - config: !0, - map: !0 - }; - return eachProp(cfg, function(value, prop) { - objs[prop] ? (config[prop] || (config[prop] = {}), mixin(config[prop], value, !0, !0)) : config[prop] = value - }), cfg.bundles && eachProp(cfg.bundles, function(value, prop) { - value.forEach(function(v) { - v !== prop && (bundlesMap[v] = prop) - }) - }), cfg.shim && (eachProp(cfg.shim, function(value, id) { - Array.isArray(value) && (value = { - deps: value - }), !value.exports && !value.init || value.exportsFn || (value.exportsFn = makeShimExports(value)), shim[id] = value - }), config.shim = shim), cfg.packages && cfg.packages.forEach(function(pkgObj) { - var location, name; - pkgObj = "string" == typeof pkgObj ? { - name: pkgObj - } : pkgObj, name = pkgObj.name, location = pkgObj.location, location && (config.paths[name] = pkgObj.location), config.pkgs[name] = pkgObj.name + "/" + (pkgObj.main || "main").replace(currDirRegExp, "").replace(jsSuffixRegExp, "") - }), (cfg.deps || cfg.callback) && req(cfg.deps, cfg.callback), req - }, req.onError = function(err) { - throw err - }, context = { - id: contextName, - defined: defined, - waiting: waiting, - config: config, - deferreds: deferreds, - req: req, - execCb: function(name, callback, args, exports) { - return callback.apply(exports, args) - } - }, contexts[contextName] = context, req - } - if (!Promise) throw new Error("No Promise implementation available"); - var topReq, dataMain, src, subPath, bootstrapConfig = requirejs || require, - hasOwn = Object.prototype.hasOwnProperty, - contexts = {}, - queue = [], - currDirRegExp = /^\.\//, - urlRegExp = /^\/|\:|\?|\.js$/, - commentRegExp = /\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm, - cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, - jsSuffixRegExp = /\.js$/, - slice = Array.prototype.slice; - if ("function" != typeof requirejs) { - var asap = Promise.resolve(void 0); - requirejs = topReq = newContext("_"), "function" != typeof require && (require = topReq), topReq.exec = function(text) { - return eval(text) - }, topReq.contexts = contexts, define = function() { - queue.push(slice.call(arguments, 0)) - }, define.amd = { - jQuery: !0 - }, bootstrapConfig && topReq.config(bootstrapConfig), topReq.isBrowser && !contexts._.config.skipDataMain && (dataMain = document.querySelectorAll("script[data-main]")[0], (dataMain = dataMain && dataMain.getAttribute("data-main")) && (dataMain = dataMain.replace(jsSuffixRegExp, ""), bootstrapConfig && bootstrapConfig.baseUrl || -1 !== dataMain.indexOf("!") || (src = dataMain.split("/"), dataMain = src.pop(), subPath = src.length ? src.join("/") + "/" : "./", topReq.config({ - baseUrl: subPath - })), topReq([dataMain]))) - } -}(this, "undefined" != typeof Promise ? Promise : void 0); diff --git a/src/bower_components/requirejs/require.js b/src/bower_components/requirejs/require.js deleted file mode 100644 index 71ac94c3b5..0000000000 --- a/src/bower_components/requirejs/require.js +++ /dev/null @@ -1,607 +0,0 @@ -var requirejs, require, define; -! function(global, setTimeout) { - function commentReplace(match, singlePrefix) { - return singlePrefix || "" - } - - function isFunction(it) { - return "[object Function]" === ostring.call(it) - } - - function isArray(it) { - return "[object Array]" === ostring.call(it) - } - - function each(ary, func) { - if (ary) { - var i; - for (i = 0; i < ary.length && (!ary[i] || !func(ary[i], i, ary)); i += 1); - } - } - - function eachReverse(ary, func) { - if (ary) { - var i; - for (i = ary.length - 1; i > -1 && (!ary[i] || !func(ary[i], i, ary)); i -= 1); - } - } - - function hasProp(obj, prop) { - return hasOwn.call(obj, prop) - } - - function getOwn(obj, prop) { - return hasProp(obj, prop) && obj[prop] - } - - function eachProp(obj, func) { - var prop; - for (prop in obj) - if (hasProp(obj, prop) && func(obj[prop], prop)) break - } - - function mixin(target, source, force, deepStringMixin) { - return source && eachProp(source, function(value, prop) { - !force && hasProp(target, prop) || (!deepStringMixin || "object" != typeof value || !value || isArray(value) || isFunction(value) || value instanceof RegExp ? target[prop] = value : (target[prop] || (target[prop] = {}), mixin(target[prop], value, force, deepStringMixin))) - }), target - } - - function bind(obj, fn) { - return function() { - return fn.apply(obj, arguments) - } - } - - function scripts() { - return document.getElementsByTagName("script") - } - - function defaultOnError(err) { - throw err - } - - function getGlobal(value) { - if (!value) return value; - var g = global; - return each(value.split("."), function(part) { - g = g[part] - }), g - } - - function makeError(id, msg, err, requireModules) { - var e = new Error(msg + "\nhttp://requirejs.org/docs/errors.html#" + id); - return e.requireType = id, e.requireModules = requireModules, err && (e.originalError = err), e - } - - function newContext(contextName) { - function trimDots(ary) { - var i, part; - for (i = 0; i < ary.length; i++) - if ("." === (part = ary[i])) ary.splice(i, 1), i -= 1; - else if (".." === part) { - if (0 === i || 1 === i && ".." === ary[2] || ".." === ary[i - 1]) continue; - i > 0 && (ary.splice(i - 1, 2), i -= 2) - } - } - - function normalize(name, baseName, applyMap) { - var mapValue, nameParts, i, j, nameSegment, lastIndex, foundMap, foundI, foundStarMap, starI, normalizedBaseParts, baseParts = baseName && baseName.split("/"), - map = config.map, - starMap = map && map["*"]; - if (name && (name = name.split("/"), lastIndex = name.length - 1, config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex]) && (name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, "")), "." === name[0].charAt(0) && baseParts && (normalizedBaseParts = baseParts.slice(0, baseParts.length - 1), name = normalizedBaseParts.concat(name)), trimDots(name), name = name.join("/")), applyMap && map && (baseParts || starMap)) { - nameParts = name.split("/"); - outerLoop: for (i = nameParts.length; i > 0; i -= 1) { - if (nameSegment = nameParts.slice(0, i).join("/"), baseParts) - for (j = baseParts.length; j > 0; j -= 1) - if ((mapValue = getOwn(map, baseParts.slice(0, j).join("/"))) && (mapValue = getOwn(mapValue, nameSegment))) { - foundMap = mapValue, foundI = i; - break outerLoop - }! foundStarMap && starMap && getOwn(starMap, nameSegment) && (foundStarMap = getOwn(starMap, nameSegment), starI = i) - }!foundMap && foundStarMap && (foundMap = foundStarMap, foundI = starI), foundMap && (nameParts.splice(0, foundI, foundMap), name = nameParts.join("/")) - } - return getOwn(config.pkgs, name) || name - } - - function removeScript(name) { - isBrowser && each(scripts(), function(scriptNode) { - if (scriptNode.getAttribute("data-requiremodule") === name && scriptNode.getAttribute("data-requirecontext") === context.contextName) return scriptNode.parentNode.removeChild(scriptNode), !0 - }) - } - - function hasPathFallback(id) { - var pathConfig = getOwn(config.paths, id); - if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) return pathConfig.shift(), context.require.undef(id), context.makeRequire(null, { - skipMap: !0 - })([id]), !0 - } - - function splitPrefix(name) { - var prefix, index = name ? name.indexOf("!") : -1; - return index > -1 && (prefix = name.substring(0, index), name = name.substring(index + 1, name.length)), [prefix, name] - } - - function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { - var url, pluginModule, suffix, nameParts, prefix = null, - parentName = parentModuleMap ? parentModuleMap.name : null, - originalName = name, - isDefine = !0, - normalizedName = ""; - return name || (isDefine = !1, name = "_@r" + (requireCounter += 1)), nameParts = splitPrefix(name), prefix = nameParts[0], name = nameParts[1], prefix && (prefix = normalize(prefix, parentName, applyMap), pluginModule = getOwn(defined, prefix)), name && (prefix ? normalizedName = isNormalized ? name : pluginModule && pluginModule.normalize ? pluginModule.normalize(name, function(name) { - return normalize(name, parentName, applyMap) - }) : -1 === name.indexOf("!") ? normalize(name, parentName, applyMap) : name : (normalizedName = normalize(name, parentName, applyMap), nameParts = splitPrefix(normalizedName), prefix = nameParts[0], normalizedName = nameParts[1], isNormalized = !0, url = context.nameToUrl(normalizedName))), suffix = !prefix || pluginModule || isNormalized ? "" : "_unnormalized" + (unnormalizedCounter += 1), { - prefix: prefix, - name: normalizedName, - parentMap: parentModuleMap, - unnormalized: !!suffix, - url: url, - originalName: originalName, - isDefine: isDefine, - id: (prefix ? prefix + "!" + normalizedName : normalizedName) + suffix - } - } - - function getModule(depMap) { - var id = depMap.id, - mod = getOwn(registry, id); - return mod || (mod = registry[id] = new context.Module(depMap)), mod - } - - function on(depMap, name, fn) { - var id = depMap.id, - mod = getOwn(registry, id); - !hasProp(defined, id) || mod && !mod.defineEmitComplete ? (mod = getModule(depMap), mod.error && "error" === name ? fn(mod.error) : mod.on(name, fn)) : "defined" === name && fn(defined[id]) - } - - function onError(err, errback) { - var ids = err.requireModules, - notified = !1; - errback ? errback(err) : (each(ids, function(id) { - var mod = getOwn(registry, id); - mod && (mod.error = err, mod.events.error && (notified = !0, mod.emit("error", err))) - }), notified || req.onError(err)) - } - - function takeGlobalQueue() { - globalDefQueue.length && (each(globalDefQueue, function(queueItem) { - var id = queueItem[0]; - "string" == typeof id && (context.defQueueMap[id] = !0), defQueue.push(queueItem) - }), globalDefQueue = []) - } - - function cleanRegistry(id) { - delete registry[id], delete enabledRegistry[id] - } - - function breakCycle(mod, traced, processed) { - var id = mod.map.id; - mod.error ? mod.emit("error", mod.error) : (traced[id] = !0, each(mod.depMaps, function(depMap, i) { - var depId = depMap.id, - dep = getOwn(registry, depId); - !dep || mod.depMatched[i] || processed[depId] || (getOwn(traced, depId) ? (mod.defineDep(i, defined[depId]), mod.check()) : breakCycle(dep, traced, processed)) - }), processed[id] = !0) - } - - function checkLoaded() { - var err, usingPathFallback, waitInterval = 1e3 * config.waitSeconds, - expired = waitInterval && context.startTime + waitInterval < (new Date).getTime(), - noLoads = [], - reqCalls = [], - stillLoading = !1, - needCycleCheck = !0; - if (!inCheckLoaded) { - if (inCheckLoaded = !0, eachProp(enabledRegistry, function(mod) { - var map = mod.map, - modId = map.id; - if (mod.enabled && (map.isDefine || reqCalls.push(mod), !mod.error)) - if (!mod.inited && expired) hasPathFallback(modId) ? (usingPathFallback = !0, stillLoading = !0) : (noLoads.push(modId), removeScript(modId)); - else if (!mod.inited && mod.fetched && map.isDefine && (stillLoading = !0, !map.prefix)) return needCycleCheck = !1 - }), expired && noLoads.length) return err = makeError("timeout", "Load timeout for modules: " + noLoads, null, noLoads), err.contextName = context.contextName, onError(err); - needCycleCheck && each(reqCalls, function(mod) { - breakCycle(mod, {}, {}) - }), expired && !usingPathFallback || !stillLoading || !isBrowser && !isWebWorker || checkLoadedTimeoutId || (checkLoadedTimeoutId = setTimeout(function() { - checkLoadedTimeoutId = 0, checkLoaded() - }, 50)), inCheckLoaded = !1 - } - } - - function callGetModule(args) { - hasProp(defined, args[0]) || getModule(makeModuleMap(args[0], null, !0)).init(args[1], args[2]) - } - - function removeListener(node, func, name, ieName) { - node.detachEvent && !isOpera ? ieName && node.detachEvent(ieName, func) : node.removeEventListener(name, func, !1) - } - - function getScriptData(evt) { - var node = evt.currentTarget || evt.srcElement; - return removeListener(node, context.onScriptLoad, "load", "onreadystatechange"), removeListener(node, context.onScriptError, "error"), { - node: node, - id: node && node.getAttribute("data-requiremodule") - } - } - - function intakeDefines() { - var args; - for (takeGlobalQueue(); defQueue.length;) { - if (args = defQueue.shift(), null === args[0]) return onError(makeError("mismatch", "Mismatched anonymous define() module: " + args[args.length - 1])); - callGetModule(args) - } - context.defQueueMap = {} - } - var inCheckLoaded, Module, context, handlers, checkLoadedTimeoutId, config = { - waitSeconds: 7, - baseUrl: "./", - paths: {}, - bundles: {}, - pkgs: {}, - shim: {}, - config: {} - }, - registry = {}, - enabledRegistry = {}, - undefEvents = {}, - defQueue = [], - defined = {}, - urlFetched = {}, - bundlesMap = {}, - requireCounter = 1, - unnormalizedCounter = 1; - return handlers = { - require: function(mod) { - return mod.require ? mod.require : mod.require = context.makeRequire(mod.map) - }, - exports: function(mod) { - if (mod.usingExports = !0, mod.map.isDefine) return mod.exports ? defined[mod.map.id] = mod.exports : mod.exports = defined[mod.map.id] = {} - }, - module: function(mod) { - return mod.module ? mod.module : mod.module = { - id: mod.map.id, - uri: mod.map.url, - config: function() { - return getOwn(config.config, mod.map.id) || {} - }, - exports: mod.exports || (mod.exports = {}) - } - } - }, Module = function(map) { - this.events = getOwn(undefEvents, map.id) || {}, this.map = map, this.shim = getOwn(config.shim, map.id), this.depExports = [], this.depMaps = [], this.depMatched = [], this.pluginMaps = {}, this.depCount = 0 - }, Module.prototype = { - init: function(depMaps, factory, errback, options) { - options = options || {}, this.inited || (this.factory = factory, errback ? this.on("error", errback) : this.events.error && (errback = bind(this, function(err) { - this.emit("error", err) - })), this.depMaps = depMaps && depMaps.slice(0), this.errback = errback, this.inited = !0, this.ignore = options.ignore, options.enabled || this.enabled ? this.enable() : this.check()) - }, - defineDep: function(i, depExports) { - this.depMatched[i] || (this.depMatched[i] = !0, this.depCount -= 1, this.depExports[i] = depExports) - }, - fetch: function() { - if (!this.fetched) { - this.fetched = !0, context.startTime = (new Date).getTime(); - var map = this.map; - if (!this.shim) return map.prefix ? this.callPlugin() : this.load(); - context.makeRequire(this.map, { - enableBuildCallback: !0 - })(this.shim.deps || [], bind(this, function() { - return map.prefix ? this.callPlugin() : this.load() - })) - } - }, - load: function() { - var url = this.map.url; - urlFetched[url] || (urlFetched[url] = !0, context.load(this.map.id, url)) - }, - check: function() { - if (this.enabled && !this.enabling) { - var err, cjsModule, id = this.map.id, - depExports = this.depExports, - exports = this.exports, - factory = this.factory; - if (this.inited) { - if (this.error) this.emit("error", this.error); - else if (!this.defining) { - if (this.defining = !0, this.depCount < 1 && !this.defined) { - if (isFunction(factory)) { - if (this.events.error && this.map.isDefine || req.onError !== defaultOnError) try { - exports = context.execCb(id, factory, depExports, exports) - } catch (e) { - err = e - } else exports = context.execCb(id, factory, depExports, exports); - if (this.map.isDefine && void 0 === exports && (cjsModule = this.module, cjsModule ? exports = cjsModule.exports : this.usingExports && (exports = this.exports)), err) return err.requireMap = this.map, err.requireModules = this.map.isDefine ? [this.map.id] : null, err.requireType = this.map.isDefine ? "define" : "require", onError(this.error = err) - } else exports = factory; - if (this.exports = exports, this.map.isDefine && !this.ignore && (defined[id] = exports, req.onResourceLoad)) { - var resLoadMaps = []; - each(this.depMaps, function(depMap) { - resLoadMaps.push(depMap.normalizedMap || depMap) - }), req.onResourceLoad(context, this.map, resLoadMaps) - } - cleanRegistry(id), this.defined = !0 - } - this.defining = !1, this.defined && !this.defineEmitted && (this.defineEmitted = !0, this.emit("defined", this.exports), this.defineEmitComplete = !0) - } - } else hasProp(context.defQueueMap, id) || this.fetch() - } - }, - callPlugin: function() { - var map = this.map, - id = map.id, - pluginMap = makeModuleMap(map.prefix); - this.depMaps.push(pluginMap), on(pluginMap, "defined", bind(this, function(plugin) { - var load, normalizedMap, normalizedMod, bundleId = getOwn(bundlesMap, this.map.id), - name = this.map.name, - parentName = this.map.parentMap ? this.map.parentMap.name : null, - localRequire = context.makeRequire(map.parentMap, { - enableBuildCallback: !0 - }); - return this.map.unnormalized ? (plugin.normalize && (name = plugin.normalize(name, function(name) { - return normalize(name, parentName, !0) - }) || ""), normalizedMap = makeModuleMap(map.prefix + "!" + name, this.map.parentMap, !0), on(normalizedMap, "defined", bind(this, function(value) { - this.map.normalizedMap = normalizedMap, this.init([], function() { - return value - }, null, { - enabled: !0, - ignore: !0 - }) - })), void((normalizedMod = getOwn(registry, normalizedMap.id)) && (this.depMaps.push(normalizedMap), this.events.error && normalizedMod.on("error", bind(this, function(err) { - this.emit("error", err) - })), normalizedMod.enable()))) : bundleId ? (this.map.url = context.nameToUrl(bundleId), void this.load()) : (load = bind(this, function(value) { - this.init([], function() { - return value - }, null, { - enabled: !0 - }) - }), load.error = bind(this, function(err) { - this.inited = !0, this.error = err, err.requireModules = [id], eachProp(registry, function(mod) { - 0 === mod.map.id.indexOf(id + "_unnormalized") && cleanRegistry(mod.map.id) - }), onError(err) - }), load.fromText = bind(this, function(text, textAlt) { - var moduleName = map.name, - moduleMap = makeModuleMap(moduleName), - hasInteractive = useInteractive; - textAlt && (text = textAlt), hasInteractive && (useInteractive = !1), getModule(moduleMap), hasProp(config.config, id) && (config.config[moduleName] = config.config[id]); - try { - req.exec(text) - } catch (e) { - return onError(makeError("fromtexteval", "fromText eval for " + id + " failed: " + e, e, [id])) - } - hasInteractive && (useInteractive = !0), this.depMaps.push(moduleMap), context.completeLoad(moduleName), localRequire([moduleName], load) - }), void plugin.load(map.name, localRequire, load, config)) - })), context.enable(pluginMap, this), this.pluginMaps[pluginMap.id] = pluginMap - }, - enable: function() { - enabledRegistry[this.map.id] = this, this.enabled = !0, this.enabling = !0, each(this.depMaps, bind(this, function(depMap, i) { - var id, mod, handler; - if ("string" == typeof depMap) { - if (depMap = makeModuleMap(depMap, this.map.isDefine ? this.map : this.map.parentMap, !1, !this.skipMap), this.depMaps[i] = depMap, handler = getOwn(handlers, depMap.id)) return void(this.depExports[i] = handler(this)); - this.depCount += 1, on(depMap, "defined", bind(this, function(depExports) { - this.undefed || (this.defineDep(i, depExports), this.check()) - })), this.errback ? on(depMap, "error", bind(this, this.errback)) : this.events.error && on(depMap, "error", bind(this, function(err) { - this.emit("error", err) - })) - } - id = depMap.id, mod = registry[id], hasProp(handlers, id) || !mod || mod.enabled || context.enable(depMap, this) - })), eachProp(this.pluginMaps, bind(this, function(pluginMap) { - var mod = getOwn(registry, pluginMap.id); - mod && !mod.enabled && context.enable(pluginMap, this) - })), this.enabling = !1, this.check() - }, - on: function(name, cb) { - var cbs = this.events[name]; - cbs || (cbs = this.events[name] = []), cbs.push(cb) - }, - emit: function(name, evt) { - each(this.events[name], function(cb) { - cb(evt) - }), "error" === name && delete this.events[name] - } - }, context = { - config: config, - contextName: contextName, - registry: registry, - defined: defined, - urlFetched: urlFetched, - defQueue: defQueue, - defQueueMap: {}, - Module: Module, - makeModuleMap: makeModuleMap, - nextTick: req.nextTick, - onError: onError, - configure: function(cfg) { - if (cfg.baseUrl && "/" !== cfg.baseUrl.charAt(cfg.baseUrl.length - 1) && (cfg.baseUrl += "/"), "string" == typeof cfg.urlArgs) { - var urlArgs = cfg.urlArgs; - cfg.urlArgs = function(id, url) { - return (-1 === url.indexOf("?") ? "?" : "&") + urlArgs - } - } - var shim = config.shim, - objs = { - paths: !0, - bundles: !0, - config: !0, - map: !0 - }; - eachProp(cfg, function(value, prop) { - objs[prop] ? (config[prop] || (config[prop] = {}), mixin(config[prop], value, !0, !0)) : config[prop] = value - }), cfg.bundles && eachProp(cfg.bundles, function(value, prop) { - each(value, function(v) { - v !== prop && (bundlesMap[v] = prop) - }) - }), cfg.shim && (eachProp(cfg.shim, function(value, id) { - isArray(value) && (value = { - deps: value - }), !value.exports && !value.init || value.exportsFn || (value.exportsFn = context.makeShimExports(value)), shim[id] = value - }), config.shim = shim), cfg.packages && each(cfg.packages, function(pkgObj) { - var location, name; - pkgObj = "string" == typeof pkgObj ? { - name: pkgObj - } : pkgObj, name = pkgObj.name, location = pkgObj.location, location && (config.paths[name] = pkgObj.location), config.pkgs[name] = pkgObj.name + "/" + (pkgObj.main || "main").replace(currDirRegExp, "").replace(jsSuffixRegExp, "") - }), eachProp(registry, function(mod, id) { - mod.inited || mod.map.unnormalized || (mod.map = makeModuleMap(id, null, !0)) - }), (cfg.deps || cfg.callback) && context.require(cfg.deps || [], cfg.callback) - }, - makeShimExports: function(value) { - function fn() { - var ret; - return value.init && (ret = value.init.apply(global, arguments)), ret || value.exports && getGlobal(value.exports) - } - return fn - }, - makeRequire: function(relMap, options) { - function localRequire(deps, callback, errback) { - var id, map, requireMod; - return options.enableBuildCallback && callback && isFunction(callback) && (callback.__requireJsBuild = !0), "string" == typeof deps ? isFunction(callback) ? onError(makeError("requireargs", "Invalid require call"), errback) : relMap && hasProp(handlers, deps) ? handlers[deps](registry[relMap.id]) : req.get ? req.get(context, deps, relMap, localRequire) : (map = makeModuleMap(deps, relMap, !1, !0), id = map.id, hasProp(defined, id) ? defined[id] : onError(makeError("notloaded", 'Module name "' + id + '" has not been loaded yet for context: ' + contextName + (relMap ? "" : ". Use require([])")))) : (intakeDefines(), context.nextTick(function() { - intakeDefines(), requireMod = getModule(makeModuleMap(null, relMap)), requireMod.skipMap = options.skipMap, requireMod.init(deps, callback, errback, { - enabled: !0 - }), checkLoaded() - }), localRequire) - } - return options = options || {}, mixin(localRequire, { - isBrowser: isBrowser, - toUrl: function(moduleNamePlusExt) { - var ext, index = moduleNamePlusExt.lastIndexOf("."), - segment = moduleNamePlusExt.split("/")[0], - isRelative = "." === segment || ".." === segment; - return -1 !== index && (!isRelative || index > 1) && (ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length), moduleNamePlusExt = moduleNamePlusExt.substring(0, index)), context.nameToUrl(normalize(moduleNamePlusExt, relMap && relMap.id, !0), ext, !0) - }, - defined: function(id) { - return hasProp(defined, makeModuleMap(id, relMap, !1, !0).id) - }, - specified: function(id) { - return id = makeModuleMap(id, relMap, !1, !0).id, hasProp(defined, id) || hasProp(registry, id) - } - }), relMap || (localRequire.undef = function(id) { - takeGlobalQueue(); - var map = makeModuleMap(id, relMap, !0), - mod = getOwn(registry, id); - mod.undefed = !0, removeScript(id), delete defined[id], delete urlFetched[map.url], delete undefEvents[id], eachReverse(defQueue, function(args, i) { - args[0] === id && defQueue.splice(i, 1) - }), delete context.defQueueMap[id], mod && (mod.events.defined && (undefEvents[id] = mod.events), cleanRegistry(id)) - }), localRequire - }, - enable: function(depMap) { - getOwn(registry, depMap.id) && getModule(depMap).enable() - }, - completeLoad: function(moduleName) { - var found, args, mod, shim = getOwn(config.shim, moduleName) || {}, - shExports = shim.exports; - for (takeGlobalQueue(); defQueue.length;) { - if (args = defQueue.shift(), null === args[0]) { - if (args[0] = moduleName, found) break; - found = !0 - } else args[0] === moduleName && (found = !0); - callGetModule(args) - } - if (context.defQueueMap = {}, mod = getOwn(registry, moduleName), !found && !hasProp(defined, moduleName) && mod && !mod.inited) { - if (!(!config.enforceDefine || shExports && getGlobal(shExports))) return hasPathFallback(moduleName) ? void 0 : onError(makeError("nodefine", "No define call for " + moduleName, null, [moduleName])); - callGetModule([moduleName, shim.deps || [], shim.exportsFn]) - } - checkLoaded() - }, - nameToUrl: function(moduleName, ext, skipExt) { - var paths, syms, i, parentModule, url, parentPath, bundleId, pkgMain = getOwn(config.pkgs, moduleName); - if (pkgMain && (moduleName = pkgMain), bundleId = getOwn(bundlesMap, moduleName)) return context.nameToUrl(bundleId, ext, skipExt); - if (req.jsExtRegExp.test(moduleName)) url = moduleName + (ext || ""); - else { - for (paths = config.paths, syms = moduleName.split("/"), i = syms.length; i > 0; i -= 1) - if (parentModule = syms.slice(0, i).join("/"), parentPath = getOwn(paths, parentModule)) { - isArray(parentPath) && (parentPath = parentPath[0]), syms.splice(0, i, parentPath); - break - } url = syms.join("/"), url += ext || (/^data\:|^blob\:|\?/.test(url) || skipExt ? "" : ".js"), url = ("/" === url.charAt(0) || url.match(/^[\w\+\.\-]+:/) ? "" : config.baseUrl) + url - } - return config.urlArgs && !/^blob\:/.test(url) ? url + config.urlArgs(moduleName, url) : url - }, - load: function(id, url) { - req.load(context, id, url) - }, - execCb: function(name, callback, args, exports) { - return callback.apply(exports, args) - }, - onScriptLoad: function(evt) { - if ("load" === evt.type || readyRegExp.test((evt.currentTarget || evt.srcElement).readyState)) { - interactiveScript = null; - var data = getScriptData(evt); - context.completeLoad(data.id) - } - }, - onScriptError: function(evt) { - var data = getScriptData(evt); - if (!hasPathFallback(data.id)) { - var parents = []; - return eachProp(registry, function(value, key) { - 0 !== key.indexOf("_@r") && each(value.depMaps, function(depMap) { - if (depMap.id === data.id) return parents.push(key), !0 - }) - }), onError(makeError("scripterror", 'Script error for "' + data.id + (parents.length ? '", needed by: ' + parents.join(", ") : '"'), evt, [data.id])) - } - } - }, context.require = context.makeRequire(), context - } - - function getInteractiveScript() { - return interactiveScript && "interactive" === interactiveScript.readyState ? interactiveScript : (eachReverse(scripts(), function(script) { - if ("interactive" === script.readyState) return interactiveScript = script - }), interactiveScript) - } - var req, s, head, baseElement, dataMain, src, interactiveScript, currentlyAddingScript, mainScript, subPath, version = "2.3.5", - commentRegExp = /\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm, - cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, - jsSuffixRegExp = /\.js$/, - currDirRegExp = /^\.\//, - op = Object.prototype, - ostring = op.toString, - hasOwn = op.hasOwnProperty, - isBrowser = !("undefined" == typeof window || "undefined" == typeof navigator || !window.document), - isWebWorker = !isBrowser && "undefined" != typeof importScripts, - readyRegExp = isBrowser && "PLAYSTATION 3" === navigator.platform ? /^complete$/ : /^(complete|loaded)$/, - defContextName = "_", - isOpera = "undefined" != typeof opera && "[object Opera]" === opera.toString(), - contexts = {}, - cfg = {}, - globalDefQueue = [], - useInteractive = !1; - if (void 0 === define) { - if (void 0 !== requirejs) { - if (isFunction(requirejs)) return; - cfg = requirejs, requirejs = void 0 - } - void 0 === require || isFunction(require) || (cfg = require, require = void 0), req = requirejs = function(deps, callback, errback, optional) { - var context, config, contextName = defContextName; - return isArray(deps) || "string" == typeof deps || (config = deps, isArray(callback) ? (deps = callback, callback = errback, errback = optional) : deps = []), config && config.context && (contextName = config.context), context = getOwn(contexts, contextName), context || (context = contexts[contextName] = req.s.newContext(contextName)), config && context.configure(config), context.require(deps, callback, errback) - }, req.config = function(config) { - return req(config) - }, req.nextTick = void 0 !== setTimeout ? function(fn) { - setTimeout(fn, 4) - } : function(fn) { - fn() - }, require || (require = req), req.version = version, req.jsExtRegExp = /^\/|:|\?|\.js$/, req.isBrowser = isBrowser, s = req.s = { - contexts: contexts, - newContext: newContext - }, req({}), each(["toUrl", "undef", "defined", "specified"], function(prop) { - req[prop] = function() { - var ctx = contexts[defContextName]; - return ctx.require[prop].apply(ctx, arguments) - } - }), isBrowser && (head = s.head = document.getElementsByTagName("head")[0], (baseElement = document.getElementsByTagName("base")[0]) && (head = s.head = baseElement.parentNode)), req.onError = defaultOnError, req.createNode = function(config, moduleName, url) { - var node = config.xhtml ? document.createElementNS("http://www.w3.org/1999/xhtml", "html:script") : document.createElement("script"); - return node.type = config.scriptType || "text/javascript", node.charset = "utf-8", node.async = !0, node - }, req.load = function(context, moduleName, url) { - var node, config = context && context.config || {}; - if (isBrowser) return node = req.createNode(config, moduleName, url), node.setAttribute("data-requirecontext", context.contextName), node.setAttribute("data-requiremodule", moduleName), !node.attachEvent || node.attachEvent.toString && node.attachEvent.toString().indexOf("[native code") < 0 || isOpera ? (node.addEventListener("load", context.onScriptLoad, !1), node.addEventListener("error", context.onScriptError, !1)) : (useInteractive = !0, node.attachEvent("onreadystatechange", context.onScriptLoad)), node.src = url, config.onNodeCreated && config.onNodeCreated(node, config, moduleName, url), currentlyAddingScript = node, baseElement ? head.insertBefore(node, baseElement) : head.appendChild(node), currentlyAddingScript = null, node; - if (isWebWorker) try { - setTimeout(function() {}, 0), importScripts(url), context.completeLoad(moduleName) - } catch (e) { - context.onError(makeError("importscripts", "importScripts failed for " + moduleName + " at " + url, e, [moduleName])) - } - }, isBrowser && !cfg.skipDataMain && eachReverse(scripts(), function(script) { - if (head || (head = script.parentNode), dataMain = script.getAttribute("data-main")) return mainScript = dataMain, cfg.baseUrl || -1 !== mainScript.indexOf("!") || (src = mainScript.split("/"), mainScript = src.pop(), subPath = src.length ? src.join("/") + "/" : "./", cfg.baseUrl = subPath), mainScript = mainScript.replace(jsSuffixRegExp, ""), req.jsExtRegExp.test(mainScript) && (mainScript = dataMain), cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript], !0 - }), define = function(name, deps, callback) { - var node, context; - "string" != typeof name && (callback = deps, deps = name, name = null), isArray(deps) || (callback = deps, deps = null), !deps && isFunction(callback) && (deps = [], callback.length && (callback.toString().replace(commentRegExp, commentReplace).replace(cjsRequireRegExp, function(match, dep) { - deps.push(dep) - }), deps = (1 === callback.length ? ["require"] : ["require", "exports", "module"]).concat(deps))), useInteractive && (node = currentlyAddingScript || getInteractiveScript()) && (name || (name = node.getAttribute("data-requiremodule")), context = contexts[node.getAttribute("data-requirecontext")]), context ? (context.defQueue.push([name, deps, callback]), context.defQueueMap[name] = !0) : globalDefQueue.push([name, deps, callback]) - }, define.amd = { - jQuery: !0 - }, req.exec = function(text) { - return eval(text) - }, req(cfg) - } -}(this, "undefined" == typeof setTimeout ? void 0 : setTimeout); \ No newline at end of file diff --git a/src/scripts/apploader.js b/src/scripts/apploader.js index 9067ae6070..2328f88968 100644 --- a/src/scripts/apploader.js +++ b/src/scripts/apploader.js @@ -20,7 +20,7 @@ } injectScriptElement( - self.Promise ? "./bower_components/alameda/alameda.js" : "./bower_components/requirejs/require.js", + self.Promise ? "./bower_components/alameda.js" : "./bower_components/require.js", function() { // onload of require library injectScriptElement("./scripts/site.js"); diff --git a/webpack.common.js b/webpack.common.js index 05b2b0cb46..6e82da181e 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -1,6 +1,10 @@ const path = require("path"); +const { CleanWebpackPlugin} = require("clean-webpack-plugin"); const CopyPlugin = require("copy-webpack-plugin"); +// assets.js +const Assets = require('./assets'); + module.exports = { context: path.resolve(__dirname, "src"), entry: "./bundle.js", @@ -10,9 +14,18 @@ module.exports = { ] }, plugins: [ + new CleanWebpackPlugin(), new CopyPlugin([{ from: "**/*", to: "." - }]) + }]), + new CopyPlugin( + Assets.map(asset => { + return { + from: path.resolve(__dirname, `./node_modules/${asset}`), + to: path.resolve(__dirname, './dist/bower_components') + }; + }) + ) ] }; From 23677db99011b84f6da92e11e4afd2e468d7e833 Mon Sep 17 00:00:00 2001 From: grafixeyehero <32230989+grafixeyehero@users.noreply.github.com> Date: Wed, 6 Nov 2019 13:43:39 +0300 Subject: [PATCH 04/42] Deminify part 2 (#509) This de-minifies and de-uglifies `controllers` subdirectory --- src/controllers/addpluginpage.js | 59 +- src/controllers/addserver.js | 2 +- src/controllers/apikeys.js | 64 +- src/controllers/dashboardpage.js | 70 +- src/controllers/device.js | 42 +- src/controllers/devices.js | 93 +- src/controllers/dlnaprofile.js | 74 +- src/controllers/dlnaprofiles.js | 84 +- src/controllers/dlnasettings.js | 58 +- src/controllers/edititemmetadata.js | 38 +- src/controllers/encodingsettings.js | 174 +- src/controllers/forgotpassword.js | 52 +- src/controllers/forgotpasswordpin.js | 32 +- src/controllers/home.js | 65 +- src/controllers/hometab.js | 83 +- src/controllers/installedplugins.js | 60 +- src/controllers/itemdetailpage.js | 2380 ++++++++++++------ src/controllers/list.js | 1146 +++++++-- src/controllers/livetv/livetvchannels.js | 122 +- src/controllers/livetv/livetvguide.js | 43 +- src/controllers/livetv/livetvrecordings.js | 115 +- src/controllers/livetv/livetvschedule.js | 133 +- src/controllers/livetv/livetvseriestimers.js | 52 +- src/controllers/livetv/livetvsuggested.js | 40 +- src/controllers/livetvguideprovider.js | 28 +- src/controllers/livetvsettings.js | 156 +- src/controllers/livetvstatus.js | 244 +- src/controllers/livetvtuner.js | 204 +- src/controllers/metadatanfo.js | 66 +- src/controllers/movies/moviecollections.js | 316 ++- src/controllers/movies/moviegenres.js | 267 +- src/controllers/movies/movies.js | 354 +-- src/controllers/movies/moviesrecommended.js | 358 ++- src/controllers/movies/movietrailers.js | 382 +-- src/controllers/music/musicalbums.js | 373 +-- src/controllers/music/musicartists.js | 298 ++- src/controllers/music/musicgenres.js | 171 +- src/controllers/music/musicplaylists.js | 93 +- src/controllers/music/musicrecommended.js | 345 ++- src/controllers/music/songs.js | 264 +- src/controllers/notificationsetting.js | 173 +- src/controllers/nowplayingpage.js | 31 +- src/controllers/playbackconfiguration.js | 35 +- src/controllers/scheduledtaskpage.js | 266 +- src/controllers/searchpage.js | 49 +- src/controllers/selectserver.js | 120 +- src/controllers/serveractivity.js | 41 +- src/controllers/shows/episodes.js | 326 ++- src/controllers/shows/tvgenres.js | 263 +- src/controllers/shows/tvlatest.js | 76 +- src/controllers/shows/tvrecommended.js | 296 ++- src/controllers/shows/tvshows.js | 403 +-- src/controllers/shows/tvstudios.js | 77 +- src/controllers/shows/tvupcoming.js | 149 +- src/controllers/streamingsettings.js | 52 +- src/controllers/user/display.js | 71 +- src/controllers/user/home.js | 68 +- src/controllers/user/menu.js | 6 +- src/controllers/user/playback.js | 68 +- src/controllers/user/subtitles.js | 68 +- src/controllers/useredit.js | 148 +- src/controllers/userlibraryaccess.js | 198 +- src/controllers/usernew.js | 49 +- src/controllers/userparentalcontrol.js | 290 ++- src/controllers/userpasswordpage.js | 198 +- src/controllers/wizardfinishpage.js | 2 +- 66 files changed, 8296 insertions(+), 4227 deletions(-) diff --git a/src/controllers/addpluginpage.js b/src/controllers/addpluginpage.js index 0ecb65ab75..7930d6927b 100644 --- a/src/controllers/addpluginpage.js +++ b/src/controllers/addpluginpage.js @@ -1,31 +1,37 @@ -define(["jQuery", "loading", "libraryMenu", "globalize", "connectionManager", "emby-button"], function($, loading, libraryMenu, globalize, connectionManager) { +define(["jQuery", "loading", "libraryMenu", "globalize", "connectionManager", "emby-button"], function ($, loading, libraryMenu, globalize, connectionManager) { "use strict"; function populateHistory(packageInfo, page) { var html = ""; var length = Math.min(packageInfo.versions.length, 10); + for (var i = 0; i < length; i++) { var version = packageInfo.versions[i]; html += '

' + version.versionStr + " (" + version.classification + ")

"; html += '
' + version.description + "
"; } + $("#revisionHistory", page).html(html); } function populateVersions(packageInfo, page, installedPlugin) { var html = ""; + for (var i = 0; i < packageInfo.versions.length; i++) { var version = packageInfo.versions[i]; html += '"; } + var selectmenu = $("#selectVersion", page).html(html); + if (!installedPlugin) { $("#pCurrentVersion", page).hide().html(""); } - var packageVersion = packageInfo.versions.filter(function(current) { + + var packageVersion = packageInfo.versions.filter(function (current) { return "Release" == current.classification; })[0]; - packageVersion = packageVersion || packageInfo.versions.filter(function(current) { + packageVersion = packageVersion || packageInfo.versions.filter(function (current) { return "Beta" == current.classification; })[0]; @@ -36,12 +42,13 @@ define(["jQuery", "loading", "libraryMenu", "globalize", "connectionManager", "e } function renderPackage(pkg, installedPlugins, page) { - var installedPlugin = installedPlugins.filter(function(ip) { - return ip.Name == pkg.name + var installedPlugin = installedPlugins.filter(function (ip) { + return ip.Name == pkg.name; })[0]; populateVersions(pkg, page, installedPlugin); populateHistory(pkg, page); $(".pluginName", page).html(pkg.name); + if ("Server" == pkg.targetSystem) { $("#btnInstallDiv", page).removeClass("hide"); $("#nonServerMsg", page).hide(); @@ -52,60 +59,69 @@ define(["jQuery", "loading", "libraryMenu", "globalize", "connectionManager", "e var msg = globalize.translate("MessageInstallPluginFromApp"); $("#nonServerMsg", page).html(msg).show(); } + if (pkg.shortDescription) { $("#tagline", page).show().html(pkg.shortDescription); } else { $("#tagline", page).hide(); } + $("#overview", page).html(pkg.overview || ""); $("#developer", page).html(pkg.owner); + if (pkg.richDescUrl) { $("#pViewWebsite", page).show(); $("#pViewWebsite a", page).attr("href", pkg.richDescUrl); } else { $("#pViewWebsite", page).hide(); } + if (pkg.previewImage || pkg.thumbImage) { var img = pkg.previewImage ? pkg.previewImage : pkg.thumbImage; $("#pPreviewImage", page).show().html(""); } else { $("#pPreviewImage", page).hide().html(""); } + if (installedPlugin) { var currentVersionText = globalize.translate("MessageYouHaveVersionInstalled").replace("{0}", "" + installedPlugin.Version + ""); $("#pCurrentVersion", page).show().html(currentVersionText); } else { $("#pCurrentVersion", page).hide().html(""); } + loading.hide(); } function alertText(options) { - require(["alert"], function(alert) { - alert(options) - }) + require(["alert"], function (alert) { + alert(options); + }); } function performInstallation(page, packageName, guid, updateClass, version) { var developer = $("#developer", page).html().toLowerCase(); - var alertCallback = function() { + + var alertCallback = function () { loading.show(); page.querySelector("#btnInstall").disabled = true; - ApiClient.installPlugin(packageName, guid, updateClass, version).then(function() { + ApiClient.installPlugin(packageName, guid, updateClass, version).then(function () { loading.hide(); alertText(globalize.translate("PluginInstalledMessage")); }); }; + if (developer !== 'jellyfin') { loading.hide(); var msg = globalize.translate("MessagePluginInstallDisclaimer"); msg += "
"; msg += "
"; msg += globalize.translate("PleaseConfirmPluginInstallation"); - require(["confirm"], function(confirm) { - confirm(msg, globalize.translate("HeaderConfirmPluginInstallation")).then(function() { + + require(["confirm"], function (confirm) { + confirm(msg, globalize.translate("HeaderConfirmPluginInstallation")).then(function () { alertCallback(); - }, function() { + }, function () { console.log('plugin not installed'); }); }); @@ -114,18 +130,19 @@ define(["jQuery", "loading", "libraryMenu", "globalize", "connectionManager", "e } } - return function(view, params) { - $(".addPluginForm", view).on("submit", function() { + return function (view, params) { + $(".addPluginForm", view).on("submit", function () { loading.show(); var page = $(this).parents("#addPluginPage")[0]; var name = params.name; var guid = params.guid; - ApiClient.getInstalledPlugins().then(function(plugins) { - var installedPlugin = plugins.filter(function(plugin) { + ApiClient.getInstalledPlugins().then(function (plugins) { + var installedPlugin = plugins.filter(function (plugin) { return plugin.Name == name; })[0]; var vals = $("#selectVersion", page).val().split("|"); var version = vals[0]; + if (installedPlugin) { if (installedPlugin.Version === version) { loading.hide(); @@ -140,16 +157,16 @@ define(["jQuery", "loading", "libraryMenu", "globalize", "connectionManager", "e }); return false; }); - view.addEventListener("viewshow", function() { + view.addEventListener("viewshow", function () { var page = this; loading.show(); var name = params.name; var guid = params.guid; var promise1 = ApiClient.getPackageInfo(name, guid); var promise2 = ApiClient.getInstalledPlugins(); - Promise.all([promise1, promise2]).then(function(responses) { + Promise.all([promise1, promise2]).then(function (responses) { renderPackage(responses[0], responses[1], page); }); - }) - } + }); + }; }); diff --git a/src/controllers/addserver.js b/src/controllers/addserver.js index 6d596632b2..55b670f546 100644 --- a/src/controllers/addserver.js +++ b/src/controllers/addserver.js @@ -57,5 +57,5 @@ define(["appSettings", "loading", "browser", "emby-button"], function(appSetting appRouter.back(); }); } - } + }; }); diff --git a/src/controllers/apikeys.js b/src/controllers/apikeys.js index 3315e304e3..448ffa29a7 100644 --- a/src/controllers/apikeys.js +++ b/src/controllers/apikeys.js @@ -1,14 +1,14 @@ -define(["datetime", "loading", "libraryMenu", "dom", "globalize", "emby-button"], function(datetime, loading, libraryMenu, dom, globalize) { +define(["datetime", "loading", "libraryMenu", "dom", "globalize", "emby-button"], function (datetime, loading, libraryMenu, dom, globalize) { "use strict"; function revoke(page, key) { - require(["confirm"], function(confirm) { - confirm(globalize.translate("MessageConfirmRevokeApiKey"), globalize.translate("HeaderConfirmRevokeApiKey")).then(function() { + require(["confirm"], function (confirm) { + confirm(globalize.translate("MessageConfirmRevokeApiKey"), globalize.translate("HeaderConfirmRevokeApiKey")).then(function () { loading.show(); ApiClient.ajax({ type: "DELETE", url: ApiClient.getUrl("Auth/Keys/" + key) - }).then(function() { + }).then(function () { loadData(page); }); }); @@ -16,11 +16,23 @@ define(["datetime", "loading", "libraryMenu", "dom", "globalize", "emby-button"] } function renderKeys(page, keys) { - var rows = keys.map(function(item) { + var rows = keys.map(function (item) { var html = ""; - html += '', html += '', html += '", html += "", html += '', html += item.AccessToken, html += "", html += '', html += item.AppName || "", html += "", html += ''; - var date = datetime.parseISO8601Date(item.DateCreated, !0); - return html += datetime.toLocaleDateString(date) + " " + datetime.getDisplayTime(date), html += "", html += "" + html += ''; + html += ''; + html += '"; + html += ""; + html += ''; + html += item.AccessToken; + html += ""; + html += ''; + html += item.AppName || ""; + html += ""; + html += ''; + var date = datetime.parseISO8601Date(item.DateCreated, true); + html += datetime.toLocaleDateString(date) + " " + datetime.getDisplayTime(date); + html += ""; + return html += ""; }).join(""); page.querySelector(".resultBody").innerHTML = rows; loading.hide(); @@ -28,42 +40,44 @@ define(["datetime", "loading", "libraryMenu", "dom", "globalize", "emby-button"] function loadData(page) { loading.show(); - ApiClient.getJSON(ApiClient.getUrl("Auth/Keys")).then(function(result) { + ApiClient.getJSON(ApiClient.getUrl("Auth/Keys")).then(function (result) { renderKeys(page, result.Items); }); } function showNewKeyPrompt(page) { - require(["prompt"], function(prompt) { + require(["prompt"], function (prompt) { prompt({ title: globalize.translate("HeaderNewApiKey"), label: globalize.translate("LabelAppName"), description: globalize.translate("LabelAppNameExample") - }).then(function(value) { + }).then(function (value) { ApiClient.ajax({ type: "POST", url: ApiClient.getUrl("Auth/Keys", { App: value }) - }).then(function() { - loadData(page) - }) - }) - }) + }).then(function () { + loadData(page); + }); + }); + }); } - pageIdOn("pageinit", "apiKeysPage", function() { + pageIdOn("pageinit", "apiKeysPage", function () { var page = this; - page.querySelector(".btnNewKey").addEventListener("click", function() { - showNewKeyPrompt(page) + page.querySelector(".btnNewKey").addEventListener("click", function () { + showNewKeyPrompt(page); }); - page.querySelector(".tblApiKeys").addEventListener("click", function(e) { + page.querySelector(".tblApiKeys").addEventListener("click", function (e) { var btnRevoke = dom.parentWithClass(e.target, "btnRevoke"); - btnRevoke && revoke(page, btnRevoke.getAttribute("data-token")) + + if (btnRevoke) { + revoke(page, btnRevoke.getAttribute("data-token")); + } }); }); - - pageIdOn("pagebeforeshow", "apiKeysPage", function() { + pageIdOn("pagebeforeshow", "apiKeysPage", function () { loadData(this); - }) -}); \ No newline at end of file + }); +}); diff --git a/src/controllers/dashboardpage.js b/src/controllers/dashboardpage.js index 229befdeda..de86ffc2bd 100644 --- a/src/controllers/dashboardpage.js +++ b/src/controllers/dashboardpage.js @@ -5,8 +5,8 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa require(["alert"], function (alert) { var title; var text = []; - var displayPlayMethod = playMethodHelper.getDisplayPlayMethod(session); + if (displayPlayMethod === "DirectStream") { title = globalize.translate("DirectStreaming"); text.push(globalize.translate("DirectStreamHelp1")); @@ -15,6 +15,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa } else if (displayPlayMethod === "Transcode") { title = globalize.translate("Transcoding"); text.push(globalize.translate("MediaIsBeingConverted")); + if (session.TranscodingInfo && session.TranscodingInfo.TranscodeReasons && session.TranscodingInfo.TranscodeReasons.length) { text.push("
"); text.push(globalize.translate("LabelReasonForTranscoding")); @@ -23,6 +24,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa }); } } + alert({ text: text.join("
"), title: title @@ -73,6 +75,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa case "sendmessage": showSendMessageForm(btn, session); break; + case "transcodinginfo": showPlaybackInfo(btn, session); } @@ -124,6 +127,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa list.push(session); } } + return list; } @@ -139,7 +143,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa if (!result.Items.length) { view.querySelector(".activeRecordingsSection").classList.add("hide"); - return void (itemsContainer.innerHTML = ""); + return void(itemsContainer.innerHTML = ""); } view.querySelector(".activeRecordingsSection").classList.remove("hide"); @@ -165,13 +169,13 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa function reloadSystemInfo(view, apiClient) { apiClient.getSystemInfo().then(function (systemInfo) { view.querySelector("#serverName").innerHTML = globalize.translate("DashboardServerName", systemInfo.ServerName); - var localizedVersion = globalize.translate("DashboardVersionNumber", systemInfo.Version); + if (systemInfo.SystemUpdateLevel !== "Release") { localizedVersion += " " + systemInfo.SystemUpdateLevel; } - view.querySelector("#versionNumber").innerHTML = localizedVersion; + view.querySelector("#versionNumber").innerHTML = localizedVersion; view.querySelector("#operatingSystem").innerHTML = globalize.translate("DashboardOperatingSystem", systemInfo.OperatingSystem); view.querySelector("#architecture").innerHTML = globalize.translate("DashboardArchitecture", systemInfo.SystemArchitecture); @@ -226,14 +230,13 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa } else { var nowPlayingItem = session.NowPlayingItem; var className = "scalableCard card activeSession backdropCard backdropCard-scalable"; - html += '
'; html += '
'; html += '
'; html += '
'; html += '
'; - var imgUrl = DashboardPage.getNowPlayingImageUrl(nowPlayingItem); + if (imgUrl) { html += '
"; @@ -243,8 +246,8 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa html += '
'; html += '
'; - var clientImage = DashboardPage.getClientImage(session); + if (clientImage) { html += clientImage; } @@ -261,28 +264,36 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa html += '
'; } - html += '
' + html += '
'; var nowPlayingName = DashboardPage.getNowPlayingName(session); html += '
'; html += nowPlayingName.html; html += "
"; html += '
' + DashboardPage.getSessionNowPlayingTime(session) + "
"; - html += '
' + html += '
'; if (nowPlayingItem && nowPlayingItem.RunTimeTicks) { var percent = 100 * (session.PlayState.PositionTicks || 0) / nowPlayingItem.RunTimeTicks; - html += indicators.getProgressHtml(percent, { containerClass: "playbackProgress" }); + html += indicators.getProgressHtml(percent, { + containerClass: "playbackProgress" + }); } else { // need to leave the element in just in case the device starts playback - html += indicators.getProgressHtml(0, { containerClass: "playbackProgress hide" }); + html += indicators.getProgressHtml(0, { + containerClass: "playbackProgress hide" + }); } if (session.TranscodingInfo && session.TranscodingInfo.CompletionPercentage) { var percent = session.TranscodingInfo.CompletionPercentage.toFixed(1); - html += indicators.getProgressHtml(percent, { containerClass: "transcodingProgress" }); + html += indicators.getProgressHtml(percent, { + containerClass: "transcodingProgress" + }); } else { // same issue as playbackProgress element above - html += indicators.getProgressHtml(0, { containerClass: "transcodingProgress hide" }); + html += indicators.getProgressHtml(0, { + containerClass: "transcodingProgress hide" + }); } html += "
"; @@ -317,6 +328,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa parentElement.insertAdjacentHTML("beforeend", html); var deadSessionElem = parentElement.querySelector(".deadSession"); + if (deadSessionElem) { deadSessionElem.parentNode.removeChild(deadSessionElem); } @@ -340,9 +352,9 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa for (var i = 0, length = tasks.length; i < length; i++) { var task = tasks[i]; - html += "

"; html += task.Name + "
"; + if (task.State === "Running") { var progress = (task.CurrentProgressPercentage || 0).toFixed(1); html += ''; @@ -373,19 +385,24 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa var html = ""; var showTranscodingInfo = false; var displayPlayMethod = playMethodHelper.getDisplayPlayMethod(session); + if (displayPlayMethod === "DirectStream") { html += globalize.translate("DirectStreaming"); } else if (displayPlayMethod === "Transcode") { html += globalize.translate("Transcoding"); + if (session.TranscodingInfo && session.TranscodingInfo.Framerate) { html += " (" + session.TranscodingInfo.Framerate + " fps)"; } + showTranscodingInfo = true; } else if (displayPlayMethod === "DirectPlay") { html += globalize.translate("DirectPlaying"); } + if (showTranscodingInfo) { var line = []; + if (session.TranscodingInfo) { if (session.TranscodingInfo.Bitrate) { if (session.TranscodingInfo.Bitrate > 1e6) { @@ -493,6 +510,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa }, getUsersHtml: function (session) { var html = []; + if (session.UserId) { html.push(session.UserName); } @@ -516,8 +534,8 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa }, updateSession: function (row, session) { row.classList.remove("deadSession"); - var nowPlayingItem = session.NowPlayingItem; + if (nowPlayingItem) { row.classList.add("playingSession"); } else { @@ -537,6 +555,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa } var btnSessionPlayPause = row.querySelector(".btnSessionPlayPause"); + if (session.ServerId && nowPlayingItem && session.SupportsRemoteControl && session.DeviceId !== connectionManager.deviceId()) { btnSessionPlayPause.classList.remove("hide"); row.querySelector(".btnSessionStop").classList.remove("hide"); @@ -565,19 +584,29 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa } var playbackProgressElem = row.querySelector(".playbackProgress"); + if (nowPlayingItem && nowPlayingItem.RunTimeTicks) { var percent = 100 * (session.PlayState.PositionTicks || 0) / nowPlayingItem.RunTimeTicks; - playbackProgressElem.outerHTML = indicators.getProgressHtml(percent, { containerClass: "playbackProgress" }); + playbackProgressElem.outerHTML = indicators.getProgressHtml(percent, { + containerClass: "playbackProgress" + }); } else { - playbackProgressElem.outerHTML = indicators.getProgressHtml(0, { containerClass: "playbackProgress hide" }); + playbackProgressElem.outerHTML = indicators.getProgressHtml(0, { + containerClass: "playbackProgress hide" + }); } var transcodingProgress = row.querySelector(".transcodingProgress"); + if (session.TranscodingInfo && session.TranscodingInfo.CompletionPercentage) { var percent = session.TranscodingInfo.CompletionPercentage.toFixed(1); - transcodingProgress.outerHTML = indicators.getProgressHtml(percent, { containerClass: "transcodingProgress" }); + transcodingProgress.outerHTML = indicators.getProgressHtml(percent, { + containerClass: "transcodingProgress" + }); } else { - transcodingProgress.outerHTML = indicators.getProgressHtml(0, { containerClass: "transcodingProgress hide" }); + transcodingProgress.outerHTML = indicators.getProgressHtml(0, { + containerClass: "transcodingProgress hide" + }); } var imgUrl = DashboardPage.getNowPlayingImageUrl(nowPlayingItem) || ""; @@ -815,10 +844,13 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa view.addEventListener("viewdestroy", function () { var page = this; var userActivityLog = page.userActivityLog; + if (userActivityLog) { userActivityLog.destroy(); } + var serverActivityLog = page.serverActivityLog; + if (serverActivityLog) { serverActivityLog.destroy(); } diff --git a/src/controllers/device.js b/src/controllers/device.js index e704b964aa..cfe7efbe73 100644 --- a/src/controllers/device.js +++ b/src/controllers/device.js @@ -1,23 +1,25 @@ -define(["loading", "libraryMenu", "dom", "emby-input", "emby-button"], function(loading, libraryMenu, dom) { +define(["loading", "libraryMenu", "dom", "emby-input", "emby-button"], function (loading, libraryMenu, dom) { "use strict"; function load(page, device, deviceOptions) { - page.querySelector("#txtCustomName", page).value = deviceOptions.CustomName || "", page.querySelector(".reportedName", page).innerHTML = device.Name || "" + page.querySelector("#txtCustomName", page).value = deviceOptions.CustomName || ""; + page.querySelector(".reportedName", page).innerHTML = device.Name || ""; } function loadData() { var page = this; loading.show(); - var id = getParameterByName("id"), - promise1 = ApiClient.getJSON(ApiClient.getUrl("Devices/Info", { - Id: id - })), - promise2 = ApiClient.getJSON(ApiClient.getUrl("Devices/Options", { - Id: id - })); - Promise.all([promise1, promise2]).then(function(responses) { - load(page, responses[0], responses[1]), loading.hide() - }) + var id = getParameterByName("id"); + var promise1 = ApiClient.getJSON(ApiClient.getUrl("Devices/Info", { + Id: id + })); + var promise2 = ApiClient.getJSON(ApiClient.getUrl("Devices/Options", { + Id: id + })); + Promise.all([promise1, promise2]).then(function (responses) { + load(page, responses[0], responses[1]); + loading.hide(); + }); } function save(page) { @@ -31,14 +33,18 @@ define(["loading", "libraryMenu", "dom", "emby-input", "emby-button"], function( CustomName: page.querySelector("#txtCustomName").value }), contentType: "application/json" - }).then(Dashboard.processServerConfigurationUpdateResult) + }).then(Dashboard.processServerConfigurationUpdateResult); } function onSubmit(e) { var form = this; - return save(dom.parentWithClass(form, "page")), e.preventDefault(), !1 + save(dom.parentWithClass(form, "page")); + e.preventDefault(); + return false; } - return function(view, params) { - view.querySelector("form").addEventListener("submit", onSubmit), view.addEventListener("viewshow", loadData) - } -}); \ No newline at end of file + + return function (view, params) { + view.querySelector("form").addEventListener("submit", onSubmit); + view.addEventListener("viewshow", loadData); + }; +}); diff --git a/src/controllers/devices.js b/src/controllers/devices.js index 94d7eb70ea..36f2cf88a6 100644 --- a/src/controllers/devices.js +++ b/src/controllers/devices.js @@ -1,61 +1,73 @@ -define(["loading", "dom", "libraryMenu", "globalize", "scripts/imagehelper", "humanedate", "emby-button", "emby-itemscontainer", "cardStyle"], function(loading, dom, libraryMenu, globalize, imageHelper) { +define(["loading", "dom", "libraryMenu", "globalize", "scripts/imagehelper", "humanedate", "emby-button", "emby-itemscontainer", "cardStyle"], function (loading, dom, libraryMenu, globalize, imageHelper) { "use strict"; function canDelete(deviceId) { - return deviceId !== ApiClient.deviceId() + return deviceId !== ApiClient.deviceId(); } function deleteDevice(page, id) { var msg = globalize.translate("DeleteDeviceConfirmation"); - require(["confirm"], function(confirm) { + + require(["confirm"], function (confirm) { confirm({ text: msg, title: globalize.translate("HeaderDeleteDevice"), confirmText: globalize.translate("ButtonDelete"), primary: "delete" - }).then(function() { - loading.show(), ApiClient.ajax({ + }).then(function () { + loading.show(); + ApiClient.ajax({ type: "DELETE", url: ApiClient.getUrl("Devices", { Id: id }) - }).then(function() { - loadData(page) - }) - }) - }) + }).then(function () { + loadData(page); + }); + }); + }); } function showDeviceMenu(view, btn, deviceId) { var menuItems = []; - canEdit && menuItems.push({ - name: globalize.translate("Edit"), - id: "open", - ironIcon: "mode-edit" - }), canDelete(deviceId) && menuItems.push({ - name: globalize.translate("Delete"), - id: "delete", - ironIcon: "delete" - }), require(["actionsheet"], function(actionsheet) { + + if (canEdit) { + menuItems.push({ + name: globalize.translate("Edit"), + id: "open", + ironIcon: "mode-edit" + }); + } + + if (canDelete(deviceId)) { + menuItems.push({ + name: globalize.translate("Delete"), + id: "delete", + ironIcon: "delete" + }); + } + + require(["actionsheet"], function (actionsheet) { actionsheet.show({ items: menuItems, positionTo: btn, - callback: function(id) { + callback: function (id) { switch (id) { case "open": Dashboard.navigate("device.html?id=" + deviceId); break; + case "delete": - deleteDevice(view, deviceId) + deleteDevice(view, deviceId); } } - }) - }) + }); + }); } function load(page, devices) { var html = ""; - html += devices.map(function(device) { + html += devices.map(function (device) { var deviceHtml = ""; deviceHtml += "

"; deviceHtml += '
'; @@ -63,20 +75,24 @@ define(["loading", "dom", "libraryMenu", "globalize", "scripts/imagehelper", "hu deviceHtml += '
'; deviceHtml += ''; var iconUrl = imageHelper.getDeviceIcon(device.Name); + if (iconUrl) { deviceHtml += '
"; deviceHtml += "
"; } else { deviceHtml += 'tablet_android'; } + deviceHtml += "
"; deviceHtml += "
"; deviceHtml += '
'; + if (canEdit || canDelete(device.Id)) { deviceHtml += '
'; deviceHtml += ''; deviceHtml += "
"; } + deviceHtml += "
"; deviceHtml += device.Name; deviceHtml += "
"; @@ -84,10 +100,12 @@ define(["loading", "dom", "libraryMenu", "globalize", "scripts/imagehelper", "hu deviceHtml += device.AppName + " " + device.AppVersion; deviceHtml += "
"; deviceHtml += "
"; + if (device.LastUserName) { deviceHtml += device.LastUserName; deviceHtml += ", " + humaneDate(device.DateLastActivity); } + deviceHtml += " "; deviceHtml += "
"; deviceHtml += "
"; @@ -99,17 +117,24 @@ define(["loading", "dom", "libraryMenu", "globalize", "scripts/imagehelper", "hu } function loadData(page) { - loading.show(), ApiClient.getJSON(ApiClient.getUrl("Devices")).then(function(result) { - load(page, result.Items), loading.hide() - }) + loading.show(); + ApiClient.getJSON(ApiClient.getUrl("Devices")).then(function (result) { + load(page, result.Items); + loading.hide(); + }); } + var canEdit = ApiClient.isMinServerVersion("3.4.1.31"); - return function(view, params) { - view.querySelector(".devicesList").addEventListener("click", function(e) { + return function (view, params) { + view.querySelector(".devicesList").addEventListener("click", function (e) { var btnDeviceMenu = dom.parentWithClass(e.target, "btnDeviceMenu"); - btnDeviceMenu && showDeviceMenu(view, btnDeviceMenu, btnDeviceMenu.getAttribute("data-id")) - }), view.addEventListener("viewshow", function() { - loadData(this) - }) - } + + if (btnDeviceMenu) { + showDeviceMenu(view, btnDeviceMenu, btnDeviceMenu.getAttribute("data-id")); + } + }); + view.addEventListener("viewshow", function () { + loadData(this); + }); + }; }); diff --git a/src/controllers/dlnaprofile.js b/src/controllers/dlnaprofile.js index b4e320e6e4..e9239693d8 100644 --- a/src/controllers/dlnaprofile.js +++ b/src/controllers/dlnaprofile.js @@ -65,8 +65,8 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in profile.ContainerProfiles = profile.ContainerProfiles || []; profile.CodecProfiles = profile.CodecProfiles || []; profile.ResponseProfiles = profile.ResponseProfiles || []; - var usersHtml = "" + users.map(function (u__w) { - return '"; + var usersHtml = "" + users.map(function (u) { + return '"; }).join(""); $("#selectUser", page).html(usersHtml).val(profile.UserId || ""); renderSubProfiles(page, profile); @@ -74,12 +74,12 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in function renderIdentificationHeaders(page, headers) { var index = 0; - var html = '
' + headers.map(function (h__e) { + var html = '
' + headers.map(function (h) { var li = '
'; li += 'info'; li += '
'; - li += '

' + h__e.Name + ": " + (h__e.Value || "") + "

"; - li += '
' + (h__e.Match || "") + "
"; + li += '

' + h.Name + ": " + (h.Value || "") + "

"; + li += '
' + (h.Match || "") + "
"; li += "
"; li += ''; li += "
"; @@ -130,11 +130,11 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in } function renderXmlDocumentAttributes(page, attribute) { - var html = '
' + attribute.map(function (h__r) { + var html = '
' + attribute.map(function (h) { var li = '
'; li += 'info'; li += '
'; - li += '

' + h__r.Name + " = " + (h__r.Value || "") + "

"; + li += '

' + h.Name + " = " + (h.Value || "") + "

"; li += "
"; li += ''; return li += "
"; @@ -172,11 +172,11 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in function renderSubtitleProfiles(page, profiles) { var index = 0; - var html = '
' + profiles.map(function (h__t) { + var html = '
' + profiles.map(function (h) { var li = '
'; li += 'info'; li += '
'; - li += '

' + (h__t.Format || "") + "

"; + li += '

' + (h.Format || "") + "

"; li += "
"; li += ''; li += "
"; @@ -248,8 +248,8 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in html += '
    '; var currentType; - for (var i__y = 0, length = profiles.length; i__y < length; i__y++) { - var profile = profiles[i__y]; + for (var i = 0, length = profiles.length; i < length; i++) { + var profile = profiles[i]; if (profile.Type !== currentType) { html += '
  • ' + profile.Type + "
  • "; @@ -257,7 +257,7 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in } html += ""; } @@ -308,8 +308,8 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in html += '
      '; var currentType; - for (var i__u = 0, length = profiles.length; i__u < length; i__u++) { - var profile = profiles[i__u]; + for (var i = 0, length = profiles.length; i < length; i++) { + var profile = profiles[i]; if (profile.Type !== currentType) { html += '
    • ' + profile.Type + "
    • "; @@ -317,7 +317,7 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in } html += ""; } @@ -394,8 +394,8 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in html += '
        '; var currentType; - for (var i__i = 0, length = profiles.length; i__i < length; i__i++) { - var profile = profiles[i__i]; + for (var i = 0, length = profiles.length; i < length; i++) { + var profile = profiles[i]; if (profile.Type !== currentType) { html += '
      • ' + profile.Type + "
      • "; @@ -403,19 +403,19 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in } html += ""; } @@ -465,8 +465,8 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in html += '
          '; var currentType; - for (var i__p = 0, length = profiles.length; i__p < length; i__p++) { - var profile = profiles[i__p]; + for (var i = 0, length = profiles.length; i < length; i++) { + var profile = profiles[i]; var type = profile.Type.replace("VideoAudio", "Video Audio"); if (type !== currentType) { @@ -475,19 +475,19 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in } html += ""; } @@ -537,8 +537,8 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in html += '
            '; var currentType; - for (var i__s = 0, length = profiles.length; i__s < length; i__s++) { - var profile = profiles[i__s]; + for (var i = 0, length = profiles.length; i < length; i++) { + var profile = profiles[i]; if (profile.Type !== currentType) { html += '
          • ' + profile.Type + "
          • "; @@ -546,7 +546,7 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in } html += ""; } @@ -649,8 +649,8 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in profile.Name = $("#txtName", page).val(); profile.EnableAlbumArtInDidl = $("#chkEnableAlbumArtInDidl", page).checked(); profile.EnableSingleAlbumArtLimit = $("#chkEnableSingleImageLimit", page).checked(); - profile.SupportedMediaTypes = $(".chkMediaType:checked", page).get().map(function (c__f) { - return c__f.getAttribute("data-value"); + profile.SupportedMediaTypes = $(".chkMediaType:checked", page).get().map(function (c) { + return c.getAttribute("data-value"); }).join(","); profile.Identification = profile.Identification || {}; profile.FriendlyName = $("#txtInfoFriendlyName", page).val(); diff --git a/src/controllers/dlnaprofiles.js b/src/controllers/dlnaprofiles.js index 95350120c5..ae708bcd4e 100644 --- a/src/controllers/dlnaprofiles.js +++ b/src/controllers/dlnaprofiles.js @@ -1,48 +1,75 @@ -define(["jQuery", "globalize", "loading", "libraryMenu", "listViewStyle", "emby-button"], function($, globalize, loading, libraryMenu) { +define(["jQuery", "globalize", "loading", "libraryMenu", "listViewStyle", "emby-button"], function ($, globalize, loading, libraryMenu) { "use strict"; function loadProfiles(page) { - loading.show(), ApiClient.getJSON(ApiClient.getUrl("Dlna/ProfileInfos")).then(function(result) { - renderUserProfiles(page, result), renderSystemProfiles(page, result), loading.hide() - }) + loading.show(); + ApiClient.getJSON(ApiClient.getUrl("Dlna/ProfileInfos")).then(function (result) { + renderUserProfiles(page, result); + renderSystemProfiles(page, result); + loading.hide(); + }); } function renderUserProfiles(page, profiles) { - renderProfiles(page, page.querySelector(".customProfiles"), profiles.filter(function(p) { - return "User" == p.Type - })) + renderProfiles(page, page.querySelector(".customProfiles"), profiles.filter(function (p) { + return "User" == p.Type; + })); } function renderSystemProfiles(page, profiles) { - renderProfiles(page, page.querySelector(".systemProfiles"), profiles.filter(function(p) { - return "System" == p.Type - })) + renderProfiles(page, page.querySelector(".systemProfiles"), profiles.filter(function (p) { + return "System" == p.Type; + })); } function renderProfiles(page, element, profiles) { var html = ""; - profiles.length && (html += '
            '); + + if (profiles.length) { + html += '
            '; + } + for (var i = 0, length = profiles.length; i < length; i++) { var profile = profiles[i]; - html += '
            ', html += 'live_tv', html += '", "User" == profile.Type && (html += ''), html += "
            " + html += '
            '; + html += 'live_tv'; + html += '"; + + if ("User" == profile.Type) { + html += ''; + } + + html += "
            "; } - profiles.length && (html += "
            "), element.innerHTML = html, $(".btnDeleteProfile", element).on("click", function() { + + if (profiles.length) { + html += "
            "; + } + + element.innerHTML = html; + $(".btnDeleteProfile", element).on("click", function () { var id = this.getAttribute("data-profileid"); - deleteProfile(page, id) - }) + deleteProfile(page, id); + }); } function deleteProfile(page, id) { - require(["confirm"], function(confirm) { - confirm(globalize.translate("MessageConfirmProfileDeletion"), globalize.translate("HeaderConfirmProfileDeletion")).then(function() { - loading.show(), ApiClient.ajax({ + require(["confirm"], function (confirm) { + confirm(globalize.translate("MessageConfirmProfileDeletion"), globalize.translate("HeaderConfirmProfileDeletion")).then(function () { + loading.show(); + ApiClient.ajax({ type: "DELETE", url: ApiClient.getUrl("Dlna/Profiles/" + id) - }).then(function() { - loading.hide(), loadProfiles(page) - }) - }) - }) + }).then(function () { + loading.hide(); + loadProfiles(page); + }); + }); + }); } function getTabs() { @@ -52,10 +79,11 @@ define(["jQuery", "globalize", "loading", "libraryMenu", "listViewStyle", "emby- }, { href: "dlnaprofiles.html", name: globalize.translate("TabProfiles") - }] + }]; } - $(document).on("pageshow", "#dlnaProfilesPage", function() { - libraryMenu.setTabs("dlna", 1, getTabs), loadProfiles(this) - }) -}); \ No newline at end of file + $(document).on("pageshow", "#dlnaProfilesPage", function () { + libraryMenu.setTabs("dlna", 1, getTabs); + loadProfiles(this); + }); +}); diff --git a/src/controllers/dlnasettings.js b/src/controllers/dlnasettings.js index cc4693096a..fbb3af1205 100644 --- a/src/controllers/dlnasettings.js +++ b/src/controllers/dlnasettings.js @@ -1,20 +1,34 @@ -define(["jQuery", "loading", "libraryMenu", "fnchecked"], function($, loading, libraryMenu) { +define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, libraryMenu) { "use strict"; function loadPage(page, config, users) { - page.querySelector("#chkEnablePlayTo").checked = config.EnablePlayTo, page.querySelector("#chkEnableDlnaDebugLogging").checked = config.EnableDebugLog, $("#txtClientDiscoveryInterval", page).val(config.ClientDiscoveryIntervalSeconds), $("#chkEnableServer", page).checked(config.EnableServer), $("#chkBlastAliveMessages", page).checked(config.BlastAliveMessages), $("#txtBlastInterval", page).val(config.BlastAliveMessageIntervalSeconds); - var usersHtml = users.map(function(u) { - return '" + page.querySelector("#chkEnablePlayTo").checked = config.EnablePlayTo; + page.querySelector("#chkEnableDlnaDebugLogging").checked = config.EnableDebugLog; + $("#txtClientDiscoveryInterval", page).val(config.ClientDiscoveryIntervalSeconds); + $("#chkEnableServer", page).checked(config.EnableServer); + $("#chkBlastAliveMessages", page).checked(config.BlastAliveMessages); + $("#txtBlastInterval", page).val(config.BlastAliveMessageIntervalSeconds); + var usersHtml = users.map(function (u) { + return '"; }).join(""); - $("#selectUser", page).html(usersHtml).val(config.DefaultUserId || ""), loading.hide() + $("#selectUser", page).html(usersHtml).val(config.DefaultUserId || ""); + loading.hide(); } function onSubmit() { loading.show(); var form = this; - return ApiClient.getNamedConfiguration("dlna").then(function(config) { - config.EnablePlayTo = form.querySelector("#chkEnablePlayTo").checked, config.EnableDebugLog = form.querySelector("#chkEnableDlnaDebugLogging").checked, config.ClientDiscoveryIntervalSeconds = $("#txtClientDiscoveryInterval", form).val(), config.EnableServer = $("#chkEnableServer", form).checked(), config.BlastAliveMessages = $("#chkBlastAliveMessages", form).checked(), config.BlastAliveMessageIntervalSeconds = $("#txtBlastInterval", form).val(), config.DefaultUserId = $("#selectUser", form).val(), ApiClient.updateNamedConfiguration("dlna", config).then(Dashboard.processServerConfigurationUpdateResult) - }), !1 + ApiClient.getNamedConfiguration("dlna").then(function (config) { + config.EnablePlayTo = form.querySelector("#chkEnablePlayTo").checked; + config.EnableDebugLog = form.querySelector("#chkEnableDlnaDebugLogging").checked; + config.ClientDiscoveryIntervalSeconds = $("#txtClientDiscoveryInterval", form).val(); + config.EnableServer = $("#chkEnableServer", form).checked(); + config.BlastAliveMessages = $("#chkBlastAliveMessages", form).checked(); + config.BlastAliveMessageIntervalSeconds = $("#txtBlastInterval", form).val(); + config.DefaultUserId = $("#selectUser", form).val(); + ApiClient.updateNamedConfiguration("dlna", config).then(Dashboard.processServerConfigurationUpdateResult); + }); + return false; } function getTabs() { @@ -24,17 +38,19 @@ define(["jQuery", "loading", "libraryMenu", "fnchecked"], function($, loading, l }, { href: "dlnaprofiles.html", name: Globalize.translate("TabProfiles") - }] + }]; } - $(document).on("pageinit", "#dlnaSettingsPage", function() { - $(".dlnaSettingsForm").off("submit", onSubmit).on("submit", onSubmit) - }).on("pageshow", "#dlnaSettingsPage", function() { - libraryMenu.setTabs("dlna", 0, getTabs), loading.show(); - var page = this, - promise1 = ApiClient.getNamedConfiguration("dlna"), - promise2 = ApiClient.getUsers(); - Promise.all([promise1, promise2]).then(function(responses) { - loadPage(page, responses[0], responses[1]) - }) - }) -}); \ No newline at end of file + + $(document).on("pageinit", "#dlnaSettingsPage", function () { + $(".dlnaSettingsForm").off("submit", onSubmit).on("submit", onSubmit); + }).on("pageshow", "#dlnaSettingsPage", function () { + libraryMenu.setTabs("dlna", 0, getTabs); + loading.show(); + var page = this; + var promise1 = ApiClient.getNamedConfiguration("dlna"); + var promise2 = ApiClient.getUsers(); + Promise.all([promise1, promise2]).then(function (responses) { + loadPage(page, responses[0], responses[1]); + }); + }); +}); diff --git a/src/controllers/edititemmetadata.js b/src/controllers/edititemmetadata.js index bb5e70695a..aba741d64c 100644 --- a/src/controllers/edititemmetadata.js +++ b/src/controllers/edititemmetadata.js @@ -1,17 +1,31 @@ -define(["loading", "scripts/editorsidebar"], function(loading) { +define(["loading", "scripts/editorsidebar"], function (loading) { "use strict"; function reload(context, itemId) { - loading.show(), itemId ? require(["metadataEditor"], function(metadataEditor) { - metadataEditor.embed(context.querySelector(".editPageInnerContent"), itemId, ApiClient.serverInfo().Id) - }) : (context.querySelector(".editPageInnerContent").innerHTML = "", loading.hide()) + loading.show(); + + if (itemId) { + require(["metadataEditor"], function (metadataEditor) { + metadataEditor.embed(context.querySelector(".editPageInnerContent"), itemId, ApiClient.serverInfo().Id); + }); + } else { + context.querySelector(".editPageInnerContent").innerHTML = ""; + loading.hide(); + } } - return function(view, params) { - view.addEventListener("viewshow", function() { - reload(this, MetadataEditor.getCurrentItemId()) - }), MetadataEditor.setCurrentItemId(null), view.querySelector(".libraryTree").addEventListener("itemclicked", function(event) { + + return function (view, params) { + view.addEventListener("viewshow", function () { + reload(this, MetadataEditor.getCurrentItemId()); + }); + MetadataEditor.setCurrentItemId(null); + view.querySelector(".libraryTree").addEventListener("itemclicked", function (event) { var data = event.detail; - data.id != MetadataEditor.getCurrentItemId() && (MetadataEditor.setCurrentItemId(data.id), reload(view, data.id)) - }) - } -}); \ No newline at end of file + + if (data.id != MetadataEditor.getCurrentItemId()) { + MetadataEditor.setCurrentItemId(data.id); + reload(view, data.id); + } + }); + }; +}); diff --git a/src/controllers/encodingsettings.js b/src/controllers/encodingsettings.js index 0319d59a79..f3dfd2706e 100644 --- a/src/controllers/encodingsettings.js +++ b/src/controllers/encodingsettings.js @@ -1,9 +1,9 @@ -define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function($, loading, globalize, dom, libraryMenu) { +define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function ($, loading, globalize, dom, libraryMenu) { "use strict"; function loadPage(page, config, systemInfo) { - Array.prototype.forEach.call(page.querySelectorAll(".chkDecodeCodec"), function(c) { - c.checked = -1 !== (config.HardwareDecodingCodecs || []).indexOf(c.getAttribute("data-codec")) + Array.prototype.forEach.call(page.querySelectorAll(".chkDecodeCodec"), function (c) { + c.checked = -1 !== (config.HardwareDecodingCodecs || []).indexOf(c.getAttribute("data-codec")); }); page.querySelector("#chkHardwareEncoding").checked = config.EnableHardwareEncoding; $("#selectVideoDecoder", page).val(config.HardwareAccelerationType); @@ -17,19 +17,22 @@ define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function($, loa page.querySelector("#chkEnableSubtitleExtraction").checked = config.EnableSubtitleExtraction || false; page.querySelector("#selectVideoDecoder").dispatchEvent(new CustomEvent("change", { bubbles: true - })), loading.hide() + })); + loading.hide(); } function onSaveEncodingPathFailure(response) { loading.hide(); var msg = ""; - msg = globalize.translate("FFmpegSavePathNotFound"), require(["alert"], function(alert) { - alert(msg) - }) + msg = globalize.translate("FFmpegSavePathNotFound"); + + require(["alert"], function (alert) { + alert(msg); + }); } function updateEncoder(form) { - return ApiClient.getSystemInfo().then(function(systemInfo) { + return ApiClient.getSystemInfo().then(function (systemInfo) { return ApiClient.ajax({ url: ApiClient.getUrl("System/MediaEncoder/Path"), type: "POST", @@ -37,37 +40,67 @@ define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function($, loa Path: form.querySelector(".txtEncoderPath").value, PathType: "Custom" } - }).then(Dashboard.processServerConfigurationUpdateResult, onSaveEncodingPathFailure) - }) + }).then(Dashboard.processServerConfigurationUpdateResult, onSaveEncodingPathFailure); + }); } function onSubmit() { - var form = this, - onDecoderConfirmed = function() { - loading.show(), ApiClient.getNamedConfiguration("encoding").then(function(config) { - config.DownMixAudioBoost = $("#txtDownMixAudioBoost", form).val(), config.TranscodingTempPath = $("#txtTranscodingTempPath", form).val(), config.EncodingThreadCount = $("#selectThreadCount", form).val(), config.HardwareAccelerationType = $("#selectVideoDecoder", form).val(), config.VaapiDevice = $("#txtVaapiDevice", form).val(), config.H264Preset = form.querySelector("#selectH264Preset").value, config.H264Crf = parseInt(form.querySelector("#txtH264Crf").value || "0"), config.EnableSubtitleExtraction = form.querySelector("#chkEnableSubtitleExtraction").checked, config.HardwareDecodingCodecs = Array.prototype.map.call(Array.prototype.filter.call(form.querySelectorAll(".chkDecodeCodec"), function(c) { - return c.checked - }), function(c) { - return c.getAttribute("data-codec") - }), config.EnableHardwareEncoding = form.querySelector("#chkHardwareEncoding").checked, ApiClient.updateNamedConfiguration("encoding", config).then(function() { - updateEncoder(form) - }) - }) - }; - return $("#selectVideoDecoder", form).val() ? require(["alert"], function(alert) { - alert({ - title: globalize.translate("TitleHardwareAcceleration"), - text: globalize.translate("HardwareAccelerationWarning") - }).then(onDecoderConfirmed) - }) : onDecoderConfirmed(), !1 + var form = this; + + var onDecoderConfirmed = function () { + loading.show(); + ApiClient.getNamedConfiguration("encoding").then(function (config) { + config.DownMixAudioBoost = $("#txtDownMixAudioBoost", form).val(); + config.TranscodingTempPath = $("#txtTranscodingTempPath", form).val(); + config.EncodingThreadCount = $("#selectThreadCount", form).val(); + config.HardwareAccelerationType = $("#selectVideoDecoder", form).val(); + config.VaapiDevice = $("#txtVaapiDevice", form).val(); + config.H264Preset = form.querySelector("#selectH264Preset").value; + config.H264Crf = parseInt(form.querySelector("#txtH264Crf").value || "0"); + config.EnableSubtitleExtraction = form.querySelector("#chkEnableSubtitleExtraction").checked; + config.HardwareDecodingCodecs = Array.prototype.map.call(Array.prototype.filter.call(form.querySelectorAll(".chkDecodeCodec"), function (c) { + return c.checked; + }), function (c) { + return c.getAttribute("data-codec"); + }); + config.EnableHardwareEncoding = form.querySelector("#chkHardwareEncoding").checked; + ApiClient.updateNamedConfiguration("encoding", config).then(function () { + updateEncoder(form); + }); + }); + }; + + if ($("#selectVideoDecoder", form).val()) { + require(["alert"], function (alert) { + alert({ + title: globalize.translate("TitleHardwareAcceleration"), + text: globalize.translate("HardwareAccelerationWarning") + }).then(onDecoderConfirmed); + }); + } else { + onDecoderConfirmed(); + } + + return false; } function setDecodingCodecsVisible(context, value) { value = value || ""; var any; - Array.prototype.forEach.call(context.querySelectorAll(".chkDecodeCodec"), function(c) { - -1 === c.getAttribute("data-types").split(",").indexOf(value) ? dom.parentWithTag(c, "LABEL").classList.add("hide") : (dom.parentWithTag(c, "LABEL").classList.remove("hide"), any = !0) - }), any ? context.querySelector(".decodingCodecsList").classList.remove("hide") : context.querySelector(".decodingCodecsList").classList.add("hide") + Array.prototype.forEach.call(context.querySelectorAll(".chkDecodeCodec"), function (c) { + if (-1 === c.getAttribute("data-types").split(",").indexOf(value)) { + dom.parentWithTag(c, "LABEL").classList.add("hide"); + } else { + dom.parentWithTag(c, "LABEL").classList.remove("hide"); + any = true; + } + }); + + if (any) { + context.querySelector(".decodingCodecsList").classList.remove("hide"); + } else { + context.querySelector(".decodingCodecsList").classList.add("hide"); + } } function getTabs() { @@ -80,44 +113,69 @@ define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function($, loa }, { href: "streamingsettings.html", name: Globalize.translate("TabStreaming") - }] + }]; } - $(document).on("pageinit", "#encodingSettingsPage", function() { + $(document).on("pageinit", "#encodingSettingsPage", function () { var page = this; - page.querySelector("#selectVideoDecoder").addEventListener("change", function() { - "vaapi" == this.value ? (page.querySelector(".fldVaapiDevice").classList.remove("hide"), page.querySelector("#txtVaapiDevice").setAttribute("required", "required")) : (page.querySelector(".fldVaapiDevice").classList.add("hide"), page.querySelector("#txtVaapiDevice").removeAttribute("required")), this.value ? page.querySelector(".hardwareAccelerationOptions").classList.remove("hide") : page.querySelector(".hardwareAccelerationOptions").classList.add("hide"), setDecodingCodecsVisible(page, this.value) - }), $("#btnSelectEncoderPath", page).on("click.selectDirectory", function() { - require(["directorybrowser"], function(directoryBrowser) { - var picker = new directoryBrowser; + page.querySelector("#selectVideoDecoder").addEventListener("change", function () { + if ("vaapi" == this.value) { + page.querySelector(".fldVaapiDevice").classList.remove("hide"); + page.querySelector("#txtVaapiDevice").setAttribute("required", "required"); + } else { + page.querySelector(".fldVaapiDevice").classList.add("hide"); + page.querySelector("#txtVaapiDevice").removeAttribute("required"); + } + + if (this.value) { + page.querySelector(".hardwareAccelerationOptions").classList.remove("hide"); + } else { + page.querySelector(".hardwareAccelerationOptions").classList.add("hide"); + } + + setDecodingCodecsVisible(page, this.value); + }); + $("#btnSelectEncoderPath", page).on("click.selectDirectory", function () { + require(["directorybrowser"], function (directoryBrowser) { + var picker = new directoryBrowser(); picker.show({ - includeFiles: !0, - callback: function(path) { - path && $(".txtEncoderPath", page).val(path), picker.close() + includeFiles: true, + callback: function (path) { + if (path) { + $(".txtEncoderPath", page).val(path); + } + + picker.close(); } - }) - }) - }), $("#btnSelectTranscodingTempPath", page).on("click.selectDirectory", function() { - require(["directorybrowser"], function(directoryBrowser) { - var picker = new directoryBrowser; + }); + }); + }); + $("#btnSelectTranscodingTempPath", page).on("click.selectDirectory", function () { + require(["directorybrowser"], function (directoryBrowser) { + var picker = new directoryBrowser(); picker.show({ - callback: function(path) { - path && $("#txtTranscodingTempPath", page).val(path), picker.close() + callback: function (path) { + if (path) { + $("#txtTranscodingTempPath", page).val(path); + } + + picker.close(); }, - validateWriteable: !0, + validateWriteable: true, header: globalize.translate("HeaderSelectTranscodingPath"), instruction: globalize.translate("HeaderSelectTranscodingPathHelp") - }) - }) - }), $(".encodingSettingsForm").off("submit", onSubmit).on("submit", onSubmit) - }).on("pageshow", "#encodingSettingsPage", function() { + }); + }); + }); + $(".encodingSettingsForm").off("submit", onSubmit).on("submit", onSubmit); + }).on("pageshow", "#encodingSettingsPage", function () { loading.show(); libraryMenu.setTabs("playback", 0, getTabs); var page = this; - ApiClient.getNamedConfiguration("encoding").then(function(config) { - ApiClient.getSystemInfo().then(function(systemInfo) { + ApiClient.getNamedConfiguration("encoding").then(function (config) { + ApiClient.getSystemInfo().then(function (systemInfo) { loadPage(page, config, systemInfo); - }) - }) - }) + }); + }); + }); }); diff --git a/src/controllers/forgotpassword.js b/src/controllers/forgotpassword.js index ac010a9b34..e0f8ea4ef8 100644 --- a/src/controllers/forgotpassword.js +++ b/src/controllers/forgotpassword.js @@ -1,37 +1,53 @@ -define([], function() { +define([], function () { "use strict"; function processForgotPasswordResult(result) { - if ("ContactAdmin" == result.Action) return void Dashboard.alert({ - message: Globalize.translate("MessageContactAdminToResetPassword"), - title: Globalize.translate("HeaderForgotPassword") - }); - if ("InNetworkRequired" == result.Action) return void Dashboard.alert({ - message: Globalize.translate("MessageForgotPasswordInNetworkRequired"), - title: Globalize.translate("HeaderForgotPassword") - }); + if ("ContactAdmin" == result.Action) { + return void Dashboard.alert({ + message: Globalize.translate("MessageContactAdminToResetPassword"), + title: Globalize.translate("HeaderForgotPassword") + }); + } + + if ("InNetworkRequired" == result.Action) { + return void Dashboard.alert({ + message: Globalize.translate("MessageForgotPasswordInNetworkRequired"), + title: Globalize.translate("HeaderForgotPassword") + }); + } + if ("PinCode" == result.Action) { var msg = Globalize.translate("MessageForgotPasswordFileCreated"); - return msg += "
            ", msg += "
            ", msg += "Enter PIN here to finish Password Reset
            " ,msg += "
            ",msg += result.PinFile, msg += "
            ", void Dashboard.alert({ + msg += "
            "; + msg += "
            "; + msg += "Enter PIN here to finish Password Reset
            "; + msg += "
            "; + msg += result.PinFile; + msg += "
            "; + return void Dashboard.alert({ message: msg, title: Globalize.translate("HeaderForgotPassword"), - callback: function() { - Dashboard.navigate("forgotpasswordpin.html") + callback: function () { + Dashboard.navigate("forgotpasswordpin.html"); } - }) + }); } } - return function(view, params) { + + return function (view, params) { function onSubmit(e) { - return ApiClient.ajax({ + ApiClient.ajax({ type: "POST", url: ApiClient.getUrl("Users/ForgotPassword"), dataType: "json", data: { EnteredUsername: view.querySelector("#txtName").value } - }).then(processForgotPasswordResult), e.preventDefault(), !1 + }).then(processForgotPasswordResult); + e.preventDefault(); + return false; } - view.querySelector("form").addEventListener("submit", onSubmit) - } + + view.querySelector("form").addEventListener("submit", onSubmit); + }; }); diff --git a/src/controllers/forgotpasswordpin.js b/src/controllers/forgotpasswordpin.js index e7dccc7be1..47b1c899b9 100644 --- a/src/controllers/forgotpasswordpin.js +++ b/src/controllers/forgotpasswordpin.js @@ -1,33 +1,41 @@ -define([], function() { +define([], function () { "use strict"; function processForgotPasswordResult(result) { if (result.Success) { var msg = Globalize.translate("MessagePasswordResetForUsers"); - return msg += "
            ", msg += "
            ", msg += result.UsersReset.join("
            "), void Dashboard.alert({ + msg += "
            "; + msg += "
            "; + msg += result.UsersReset.join("
            "); + return void Dashboard.alert({ message: msg, title: Globalize.translate("HeaderPasswordReset"), - callback: function() { - window.location.href = "index.html" + callback: function () { + window.location.href = "index.html"; } - }) + }); } + Dashboard.alert({ message: Globalize.translate("MessageInvalidForgotPasswordPin"), title: Globalize.translate("HeaderPasswordReset") - }) + }); } - return function(view, params) { + + return function (view, params) { function onSubmit(e) { - return ApiClient.ajax({ + ApiClient.ajax({ type: "POST", url: ApiClient.getUrl("Users/ForgotPassword/Pin"), dataType: "json", data: { Pin: view.querySelector("#txtPin").value } - }).then(processForgotPasswordResult), e.preventDefault(), !1 + }).then(processForgotPasswordResult); + e.preventDefault(); + return false; } - view.querySelector("form").addEventListener("submit", onSubmit) - } -}); \ No newline at end of file + + view.querySelector("form").addEventListener("submit", onSubmit); + }; +}); diff --git a/src/controllers/home.js b/src/controllers/home.js index 0ab31f291d..b1dd70ebd6 100644 --- a/src/controllers/home.js +++ b/src/controllers/home.js @@ -1,4 +1,4 @@ -define(["tabbedView", "globalize", "require", "emby-tabs", "emby-button", "emby-scroller"], function(TabbedView, globalize, require) { +define(["tabbedView", "globalize", "require", "emby-tabs", "emby-button", "emby-scroller"], function (TabbedView, globalize, require) { "use strict"; function getTabs() { @@ -6,47 +6,70 @@ define(["tabbedView", "globalize", "require", "emby-tabs", "emby-button", "emby- name: globalize.translate("Home") }, { name: globalize.translate("Favorites") - }] + }]; } function getDefaultTabIndex() { - return 0 + return 0; } function getRequirePromise(deps) { - return new Promise(function(resolve, reject) { - require(deps, resolve) - }) + return new Promise(function (resolve, reject) { + require(deps, resolve); + }); } function getTabController(index) { - if (null == index) throw new Error("index cannot be null"); + if (null == index) { + throw new Error("index cannot be null"); + } + var depends = []; + switch (index) { case 0: depends.push("controllers/hometab"); break; + case 1: - depends.push("controllers/favorites") + depends.push("controllers/favorites"); } + var instance = this; - return getRequirePromise(depends).then(function(controllerFactory) { + return getRequirePromise(depends).then(function (controllerFactory) { var controller = instance.tabControllers[index]; + if (!controller) { - controller = new controllerFactory(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params), instance.tabControllers[index] = controller + controller = new controllerFactory(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params); + instance.tabControllers[index] = controller; } - return controller - }) + + return controller; + }); } function HomeView(view, params) { - TabbedView.call(this, view, params) + TabbedView.call(this, view, params); } - return Object.assign(HomeView.prototype, TabbedView.prototype), HomeView.prototype.getTabs = getTabs, HomeView.prototype.getDefaultTabIndex = getDefaultTabIndex, HomeView.prototype.getTabController = getTabController, HomeView.prototype.setTitle = function() { - Emby.Page.setTitle(null) - }, HomeView.prototype.onPause = function() { - TabbedView.prototype.onPause.call(this), document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader") - }, HomeView.prototype.onResume = function(options) { - TabbedView.prototype.onResume.call(this, options), document.querySelector(".skinHeader").classList.add("noHomeButtonHeader") - }, HomeView -}); \ No newline at end of file + + Object.assign(HomeView.prototype, TabbedView.prototype); + HomeView.prototype.getTabs = getTabs; + HomeView.prototype.getDefaultTabIndex = getDefaultTabIndex; + HomeView.prototype.getTabController = getTabController; + + HomeView.prototype.setTitle = function () { + Emby.Page.setTitle(null); + }; + + HomeView.prototype.onPause = function () { + TabbedView.prototype.onPause.call(this); + document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader"); + }; + + HomeView.prototype.onResume = function (options) { + TabbedView.prototype.onResume.call(this, options); + document.querySelector(".skinHeader").classList.add("noHomeButtonHeader"); + }; + + return HomeView; +}); diff --git a/src/controllers/hometab.js b/src/controllers/hometab.js index fed9b72146..d2adcb2da2 100644 --- a/src/controllers/hometab.js +++ b/src/controllers/hometab.js @@ -1,35 +1,74 @@ -define(["userSettings", "loading", "connectionManager", "apphost", "layoutManager", "focusManager", "homeSections", "emby-itemscontainer"], function(userSettings, loading, connectionManager, appHost, layoutManager, focusManager, homeSections) { +define(["userSettings", "loading", "connectionManager", "apphost", "layoutManager", "focusManager", "homeSections", "emby-itemscontainer"], function (userSettings, loading, connectionManager, appHost, layoutManager, focusManager, homeSections) { "use strict"; function HomeTab(view, params) { - this.view = view, this.params = params, this.apiClient = connectionManager.currentApiClient(), this.sectionsContainer = view.querySelector(".sections"), view.querySelector(".sections").addEventListener("settingschange", onHomeScreenSettingsChanged.bind(this)) + this.view = view; + this.params = params; + this.apiClient = connectionManager.currentApiClient(); + this.sectionsContainer = view.querySelector(".sections"); + view.querySelector(".sections").addEventListener("settingschange", onHomeScreenSettingsChanged.bind(this)); } function onHomeScreenSettingsChanged() { - this.sectionsRendered = !1, this.paused || this.onResume({ - refresh: !0 - }) + this.sectionsRendered = false; + + if (!this.paused) { + this.onResume({ + refresh: true + }); + } } - return HomeTab.prototype.onResume = function(options) { + + HomeTab.prototype.onResume = function (options) { if (this.sectionsRendered) { var sectionsContainer = this.sectionsContainer; - return sectionsContainer ? homeSections.resume(sectionsContainer, options) : Promise.resolve() + + if (sectionsContainer) { + return homeSections.resume(sectionsContainer, options); + } + + return Promise.resolve(); } + loading.show(); - var view = this.view, - apiClient = this.apiClient; - return this.destroyHomeSections(), this.sectionsRendered = !0, apiClient.getCurrentUser().then(function(user) { - return homeSections.loadSections(view.querySelector(".sections"), apiClient, user, userSettings).then(function() { - options.autoFocus && focusManager.autoFocus(view), loading.hide() - }) - }) - }, HomeTab.prototype.onPause = function() { + var view = this.view; + var apiClient = this.apiClient; + this.destroyHomeSections(); + this.sectionsRendered = true; + return apiClient.getCurrentUser().then(function (user) { + return homeSections.loadSections(view.querySelector(".sections"), apiClient, user, userSettings).then(function () { + if (options.autoFocus) { + focusManager.autoFocus(view); + } + + loading.hide(); + }); + }); + }; + + HomeTab.prototype.onPause = function () { var sectionsContainer = this.sectionsContainer; - sectionsContainer && homeSections.pause(sectionsContainer) - }, HomeTab.prototype.destroy = function() { - this.view = null, this.params = null, this.apiClient = null, this.destroyHomeSections(), this.sectionsContainer = null - }, HomeTab.prototype.destroyHomeSections = function() { + + if (sectionsContainer) { + homeSections.pause(sectionsContainer); + } + }; + + HomeTab.prototype.destroy = function () { + this.view = null; + this.params = null; + this.apiClient = null; + this.destroyHomeSections(); + this.sectionsContainer = null; + }; + + HomeTab.prototype.destroyHomeSections = function () { var sectionsContainer = this.sectionsContainer; - sectionsContainer && homeSections.destroySections(sectionsContainer) - }, HomeTab -}); \ No newline at end of file + + if (sectionsContainer) { + homeSections.destroySections(sectionsContainer); + } + }; + + return HomeTab; +}); diff --git a/src/controllers/installedplugins.js b/src/controllers/installedplugins.js index f9653fe260..a88f49d186 100644 --- a/src/controllers/installedplugins.js +++ b/src/controllers/installedplugins.js @@ -1,21 +1,22 @@ -define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button"], function(loading, libraryMenu, dom, globalize) { +define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button"], function (loading, libraryMenu, dom, globalize) { "use strict"; function deletePlugin(page, uniqueid, name) { var msg = globalize.translate("UninstallPluginConfirmation").replace("{0}", name); - require(["confirm"], function(confirm) { + + require(["confirm"], function (confirm) { confirm({ title: globalize.translate("UninstallPluginHeader"), text: msg, primary: "delete", confirmText: globalize.translate("UninstallPluginHeader") - }).then(function() { + }).then(function () { loading.show(); - ApiClient.uninstallPlugin(uniqueid).then(function() { + ApiClient.uninstallPlugin(uniqueid).then(function () { reloadList(page); }); - }) - }) + }); + }); } function showNoConfigurationMessage() { @@ -31,23 +32,24 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" } function getPluginCardHtml(plugin, pluginConfigurationPages) { - var configPage = pluginConfigurationPages.filter(function(pluginConfigurationPage) { - return pluginConfigurationPage.PluginId == plugin.Id; + var configPage = pluginConfigurationPages.filter(function (pluginConfigurationPage) { + return pluginConfigurationPage.PluginId == plugin.Id; })[0]; var configPageUrl = configPage ? Dashboard.getConfigurationPageUrl(configPage.Name) : null; - var html = ""; html += "
            "; html += '
            '; html += '"; html += '
            '; @@ -67,21 +69,26 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" } function renderPlugins(page, plugins) { - ApiClient.getJSON(ApiClient.getUrl("web/configurationpages") + "?pageType=PluginConfiguration").then(function(configPages) { + ApiClient.getJSON(ApiClient.getUrl("web/configurationpages") + "?pageType=PluginConfiguration").then(function (configPages) { populateList(page, plugins, configPages); }); } function populateList(page, plugins, pluginConfigurationPages) { - plugins = plugins.sort(function(plugin1, plugin2) { - return plugin1.Name > plugin2.Name ? 1 : -1 + plugins = plugins.sort(function (plugin1, plugin2) { + if (plugin1.Name > plugin2.Name) { + return 1; + } + + return -1; }); - var html = plugins.map(function(p) { - return getPluginCardHtml(p, pluginConfigurationPages) + var html = plugins.map(function (p) { + return getPluginCardHtml(p, pluginConfigurationPages); }).join(""); var installedPluginsElement = page.querySelector(".installedPlugins"); installedPluginsElement.removeEventListener("click", onInstalledPluginsClick); installedPluginsElement.addEventListener("click", onInstalledPluginsClick); + if (plugins.length) { installedPluginsElement.classList.add("itemsContainer"); installedPluginsElement.classList.add("vertical-wrap"); @@ -93,6 +100,7 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" html += "

            "; html += "
            "; } + installedPluginsElement.innerHTML = html; loading.hide(); } @@ -103,6 +111,7 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" var name = card.getAttribute("data-name"); var configHref = card.querySelector(".cardContent").getAttribute("href"); var menuItems = []; + if (configHref) { menuItems.push({ name: globalize.translate("ButtonSettings"), @@ -110,22 +119,25 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" ironIcon: "mode-edit" }); } + menuItems.push({ name: globalize.translate("ButtonUninstall"), id: "delete", ironIcon: "delete" }); - require(["actionsheet"], function(actionsheet) { + + require(["actionsheet"], function (actionsheet) { actionsheet.show({ items: menuItems, positionTo: elem, - callback: function(resultId) { + callback: function (resultId) { switch (resultId) { case "open": Dashboard.navigate(configHref); break; + case "delete": - deletePlugin(page, id, name) + deletePlugin(page, id, name); } } }); @@ -134,7 +146,7 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" function reloadList(page) { loading.show(); - ApiClient.getInstalledPlugins().then(function(plugins) { + ApiClient.getInstalledPlugins().then(function (plugins) { renderPlugins(page, plugins); }); } @@ -146,7 +158,7 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" }, { href: "availableplugins.html", name: globalize.translate("TabCatalog") - }] + }]; } function onInstalledPluginsClick(e) { @@ -156,16 +168,18 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" showConnectMessage(); } else { var btnCardMenu = dom.parentWithClass(e.target, "btnCardMenu"); - btnCardMenu && showPluginMenu(dom.parentWithClass(btnCardMenu, "page"), btnCardMenu); + + if (btnCardMenu) { + showPluginMenu(dom.parentWithClass(btnCardMenu, "page"), btnCardMenu); + } } } - pageIdOn("pageshow", "pluginsPage", function() { + pageIdOn("pageshow", "pluginsPage", function () { libraryMenu.setTabs("plugins", 0, getTabs); reloadList(this); }); - window.PluginsPage = { renderPlugins: renderPlugins - } + }; }); diff --git a/src/controllers/itemdetailpage.js b/src/controllers/itemdetailpage.js index 6991f63caa..37416dd3b7 100644 --- a/src/controllers/itemdetailpage.js +++ b/src/controllers/itemdetailpage.js @@ -1,37 +1,61 @@ -define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuilder", "datetime", "mediaInfo", "backdrop", "listView", "itemContextMenu", "itemHelper", "dom", "indicators", "apphost", "imageLoader", "libraryMenu", "globalize", "browser", "events", "scrollHelper", "playbackManager", "libraryBrowser", "scrollStyles", "emby-itemscontainer", "emby-checkbox", "emby-button", "emby-playstatebutton", "emby-ratingbutton", "emby-scroller", "emby-select"], function(loading, appRouter, layoutManager, connectionManager, cardBuilder, datetime, mediaInfo, backdrop, listView, itemContextMenu, itemHelper, dom, indicators, appHost, imageLoader, libraryMenu, globalize, browser, events, scrollHelper, playbackManager, libraryBrowser) { +define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuilder", "datetime", "mediaInfo", "backdrop", "listView", "itemContextMenu", "itemHelper", "dom", "indicators", "apphost", "imageLoader", "libraryMenu", "globalize", "browser", "events", "scrollHelper", "playbackManager", "libraryBrowser", "scrollStyles", "emby-itemscontainer", "emby-checkbox", "emby-button", "emby-playstatebutton", "emby-ratingbutton", "emby-scroller", "emby-select"], function (loading, appRouter, layoutManager, connectionManager, cardBuilder, datetime, mediaInfo, backdrop, listView, itemContextMenu, itemHelper, dom, indicators, appHost, imageLoader, libraryMenu, globalize, browser, events, scrollHelper, playbackManager, libraryBrowser) { "use strict"; function getPromise(apiClient, params) { var id = params.id; - if (id) return apiClient.getItem(apiClient.getCurrentUserId(), id); - if (params.seriesTimerId) return apiClient.getLiveTvSeriesTimer(params.seriesTimerId); - var name = params.genre; - if (name) return apiClient.getGenre(name, apiClient.getCurrentUserId()); - if (name = params.musicgenre) return apiClient.getMusicGenre(name, apiClient.getCurrentUserId()); - if (name = params.musicartist) return apiClient.getArtist(name, apiClient.getCurrentUserId()); - throw new Error("Invalid request") + + if (id) { + return apiClient.getItem(apiClient.getCurrentUserId(), id); + } + + if (params.seriesTimerId) { + return apiClient.getLiveTvSeriesTimer(params.seriesTimerId); + } + + if (params.genre) { + return apiClient.getGenre(params.genre, apiClient.getCurrentUserId()); + } + + if (params.musicgenre) { + return apiClient.getMusicGenre(params.musicgenre, apiClient.getCurrentUserId()); + } + + if (params.musicartist) { + return apiClient.getArtist(params.musicartist, apiClient.getCurrentUserId()); + } + + throw new Error("Invalid request"); } function hideAll(page, className, show) { - var i, length, elems = page.querySelectorAll("." + className); - for (i = 0, length = elems.length; i < length; i++) show ? elems[i].classList.remove("hide") : elems[i].classList.add("hide") + var i; + var length; + var elems = page.querySelectorAll("." + className); + + for (i = 0, length = elems.length; i < length; i++) { + if (show) { + elems[i].classList.remove("hide"); + } else { + elems[i].classList.add("hide"); + } + } } function getContextMenuOptions(item, user, button) { var options = { item: item, - open: !1, - play: !1, - playAllFromHere: !1, - queueAllFromHere: !1, + open: false, + play: false, + playAllFromHere: false, + queueAllFromHere: false, positionTo: button, - cancelTimer: !1, - record: !1, - deleteItem: !0 === item.IsFolder, - shuffle: !1, - instantMix: !1, + cancelTimer: false, + record: false, + deleteItem: true === item.IsFolder, + shuffle: false, + instantMix: false, user: user, - share: !0 + share: true }; return options; } @@ -39,18 +63,20 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild function getProgramScheduleHtml(items, options) { options = options || {}; var html = ""; - return html += '
            ', html += listView.getListViewHtml({ + html += '
            '; + html += listView.getListViewHtml({ items: items, - enableUserDataButtons: !1, - image: !0, + enableUserDataButtons: false, + image: true, imageSource: "channel", - showProgramDateTime: !0, - showChannel: !1, - mediaInfo: !1, + showProgramDateTime: true, + showChannel: false, + mediaInfo: false, action: "none", - moreButton: !1, - recordButton: !1 - }), html += "
            " + moreButton: false, + recordButton: false + }); + return html += "
            "; } function renderSeriesTimerSchedule(page, apiClient, seriesTimerId) { @@ -59,184 +85,339 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild ImageTypeLimit: 1, EnableImageTypes: "Primary,Backdrop,Thumb", SortBy: "StartDate", - EnableTotalRecordCount: !1, - EnableUserData: !1, + EnableTotalRecordCount: false, + EnableUserData: false, SeriesTimerId: seriesTimerId, Fields: "ChannelInfo,ChannelImage" - }).then(function(result) { - result.Items.length && result.Items[0].SeriesTimerId != seriesTimerId && (result.Items = []); - var html = getProgramScheduleHtml(result.Items), - scheduleTab = page.querySelector(".seriesTimerSchedule"); - scheduleTab.innerHTML = html, imageLoader.lazyChildren(scheduleTab) - }) + }).then(function (result) { + if (result.Items.length && result.Items[0].SeriesTimerId != seriesTimerId) { + result.Items = []; + } + + var html = getProgramScheduleHtml(result.Items); + var scheduleTab = page.querySelector(".seriesTimerSchedule"); + scheduleTab.innerHTML = html; + imageLoader.lazyChildren(scheduleTab); + }); } function renderTimerEditor(page, item, apiClient, user) { - if ("Recording" !== item.Type || !user.Policy.EnableLiveTvManagement || !item.TimerId || "InProgress" !== item.Status) return void hideAll(page, "btnCancelTimer"); - hideAll(page, "btnCancelTimer", !0) + if ("Recording" !== item.Type || !user.Policy.EnableLiveTvManagement || !item.TimerId || "InProgress" !== item.Status) { + return void hideAll(page, "btnCancelTimer"); + } + + hideAll(page, "btnCancelTimer", true); } function renderSeriesTimerEditor(page, item, apiClient, user) { - return "SeriesTimer" !== item.Type ? void hideAll(page, "btnCancelSeriesTimer") : user.Policy.EnableLiveTvManagement ? (require(["seriesRecordingEditor"], function(seriesRecordingEditor) { - seriesRecordingEditor.embed(item, apiClient.serverId(), { - context: page.querySelector(".seriesRecordingEditor") - }) - }), page.querySelector(".seriesTimerScheduleSection").classList.remove("hide"), hideAll(page, "btnCancelSeriesTimer", !0), void renderSeriesTimerSchedule(page, apiClient, item.Id)) : (page.querySelector(".seriesTimerScheduleSection").classList.add("hide"), void hideAll(page, "btnCancelSeriesTimer")) + if ("SeriesTimer" !== item.Type) { + return void hideAll(page, "btnCancelSeriesTimer"); + } + + if (user.Policy.EnableLiveTvManagement) { + require(["seriesRecordingEditor"], function (seriesRecordingEditor) { + seriesRecordingEditor.embed(item, apiClient.serverId(), { + context: page.querySelector(".seriesRecordingEditor") + }); + }); + + page.querySelector(".seriesTimerScheduleSection").classList.remove("hide"); + hideAll(page, "btnCancelSeriesTimer", true); + return void renderSeriesTimerSchedule(page, apiClient, item.Id); + } + + page.querySelector(".seriesTimerScheduleSection").classList.add("hide"); + return void hideAll(page, "btnCancelSeriesTimer"); } function renderTrackSelections(page, instance, item, forceReload) { var select = page.querySelector(".selectSource"); - if (!item.MediaSources || !itemHelper.supportsMediaSourceSelection(item) || -1 === playbackManager.getSupportedCommands().indexOf("PlayMediaSource") || !playbackManager.canPlay(item)) return page.querySelector(".trackSelections").classList.add("hide"), select.innerHTML = "", page.querySelector(".selectVideo").innerHTML = "", page.querySelector(".selectAudio").innerHTML = "", void(page.querySelector(".selectSubtitles").innerHTML = ""); - playbackManager.getPlaybackMediaSources(item).then(function(mediaSources) { - instance._currentPlaybackMediaSources = mediaSources, page.querySelector(".trackSelections").classList.remove("hide"), select.setLabel(globalize.translate("LabelVersion")); - var currentValue = select.value, - selectedId = mediaSources[0].Id; - select.innerHTML = mediaSources.map(function(v) { + + if (!item.MediaSources || !itemHelper.supportsMediaSourceSelection(item) || -1 === playbackManager.getSupportedCommands().indexOf("PlayMediaSource") || !playbackManager.canPlay(item)) { + page.querySelector(".trackSelections").classList.add("hide"); + select.innerHTML = ""; + page.querySelector(".selectVideo").innerHTML = ""; + page.querySelector(".selectAudio").innerHTML = ""; + page.querySelector(".selectSubtitles").innerHTML = ""; + return; + } + + playbackManager.getPlaybackMediaSources(item).then(function (mediaSources) { + instance._currentPlaybackMediaSources = mediaSources; + page.querySelector(".trackSelections").classList.remove("hide"); + select.setLabel(globalize.translate("LabelVersion")); + var currentValue = select.value; + var selectedId = mediaSources[0].Id; + select.innerHTML = mediaSources.map(function (v) { var selected = v.Id === selectedId ? " selected" : ""; - return '" - }).join(""), mediaSources.length > 1 ? page.querySelector(".selectSourceContainer").classList.remove("hide") : page.querySelector(".selectSourceContainer").classList.add("hide"), (select.value !== currentValue || forceReload) && (renderVideoSelections(page, mediaSources), renderAudioSelections(page, mediaSources), renderSubtitleSelections(page, mediaSources)) - }) + return '"; + }).join(""); + + if (mediaSources.length > 1) { + page.querySelector(".selectSourceContainer").classList.remove("hide"); + } else { + page.querySelector(".selectSourceContainer").classList.add("hide"); + } + + if (select.value !== currentValue || forceReload) { + renderVideoSelections(page, mediaSources); + renderAudioSelections(page, mediaSources); + renderSubtitleSelections(page, mediaSources); + } + }); } function renderVideoSelections(page, mediaSources) { - var mediaSourceId = page.querySelector(".selectSource").value, - mediaSource = mediaSources.filter(function(m) { - return m.Id === mediaSourceId - })[0], - tracks = mediaSource.MediaStreams.filter(function(m) { - return "Video" === m.Type - }), - select = page.querySelector(".selectVideo"); + var mediaSourceId = page.querySelector(".selectSource").value; + var mediaSource = mediaSources.filter(function (m) { + return m.Id === mediaSourceId; + })[0]; + var tracks = mediaSource.MediaStreams.filter(function (m) { + return "Video" === m.Type; + }); + var select = page.querySelector(".selectVideo"); select.setLabel(globalize.translate("LabelVideo")); var selectedId = tracks.length ? tracks[0].Index : -1; - select.innerHTML = tracks.map(function(v) { - var selected = v.Index === selectedId ? " selected" : "", - titleParts = [], - resolutionText = mediaInfo.getResolutionText(v); - return resolutionText && titleParts.push(resolutionText), v.Codec && titleParts.push(v.Codec.toUpperCase()), '" - }).join(""), select.setAttribute("disabled", "disabled"), tracks.length ? page.querySelector(".selectVideoContainer").classList.remove("hide") : page.querySelector(".selectVideoContainer").classList.add("hide") + select.innerHTML = tracks.map(function (v) { + var selected = v.Index === selectedId ? " selected" : ""; + var titleParts = []; + var resolutionText = mediaInfo.getResolutionText(v); + + if (resolutionText) { + titleParts.push(resolutionText); + } + + if (v.Codec) { + titleParts.push(v.Codec.toUpperCase()); + } + + return '"; + }).join(""); + select.setAttribute("disabled", "disabled"); + + if (tracks.length) { + page.querySelector(".selectVideoContainer").classList.remove("hide"); + } else { + page.querySelector(".selectVideoContainer").classList.add("hide"); + } } function renderAudioSelections(page, mediaSources) { - var mediaSourceId = page.querySelector(".selectSource").value, - mediaSource = mediaSources.filter(function(m) { - return m.Id === mediaSourceId - })[0], - tracks = mediaSource.MediaStreams.filter(function(m) { - return "Audio" === m.Type - }), - select = page.querySelector(".selectAudio"); + var mediaSourceId = page.querySelector(".selectSource").value; + var mediaSource = mediaSources.filter(function (m) { + return m.Id === mediaSourceId; + })[0]; + var tracks = mediaSource.MediaStreams.filter(function (m) { + return "Audio" === m.Type; + }); + var select = page.querySelector(".selectAudio"); select.setLabel(globalize.translate("LabelAudio")); var selectedId = mediaSource.DefaultAudioStreamIndex; - select.innerHTML = tracks.map(function(v) { + select.innerHTML = tracks.map(function (v) { var selected = v.Index === selectedId ? " selected" : ""; - return '" - }).join(""), tracks.length > 1 ? select.removeAttribute("disabled") : select.setAttribute("disabled", "disabled"), tracks.length ? page.querySelector(".selectAudioContainer").classList.remove("hide") : page.querySelector(".selectAudioContainer").classList.add("hide") + return '"; + }).join(""); + + if (tracks.length > 1) { + select.removeAttribute("disabled"); + } else { + select.setAttribute("disabled", "disabled"); + } + + if (tracks.length) { + page.querySelector(".selectAudioContainer").classList.remove("hide"); + } else { + page.querySelector(".selectAudioContainer").classList.add("hide"); + } } function renderSubtitleSelections(page, mediaSources) { - var mediaSourceId = page.querySelector(".selectSource").value, - mediaSource = mediaSources.filter(function(m) { - return m.Id === mediaSourceId - })[0], - tracks = mediaSource.MediaStreams.filter(function(m) { - return "Subtitle" === m.Type - }), - select = page.querySelector(".selectSubtitles"); + var mediaSourceId = page.querySelector(".selectSource").value; + var mediaSource = mediaSources.filter(function (m) { + return m.Id === mediaSourceId; + })[0]; + var tracks = mediaSource.MediaStreams.filter(function (m) { + return "Subtitle" === m.Type; + }); + var select = page.querySelector(".selectSubtitles"); select.setLabel(globalize.translate("LabelSubtitles")); var selectedId = null == mediaSource.DefaultSubtitleStreamIndex ? -1 : mediaSource.DefaultSubtitleStreamIndex; + if (tracks.length) { var selected = -1 === selectedId ? " selected" : ""; - select.innerHTML = '" + tracks.map(function(v) { - return selected = v.Index === selectedId ? " selected" : "", '" - }).join(""), page.querySelector(".selectSubtitlesContainer").classList.remove("hide") - } else select.innerHTML = "", page.querySelector(".selectSubtitlesContainer").classList.add("hide") + select.innerHTML = '" + tracks.map(function (v) { + selected = v.Index === selectedId ? " selected" : ""; + return '"; + }).join(""); + page.querySelector(".selectSubtitlesContainer").classList.remove("hide"); + } else { + select.innerHTML = ""; + page.querySelector(".selectSubtitlesContainer").classList.add("hide"); + } } function reloadPlayButtons(page, item) { - var canPlay = !1; + var canPlay = false; + if ("Program" == item.Type) { - var now = new Date; - now >= datetime.parseISO8601Date(item.StartDate, !0) && now < datetime.parseISO8601Date(item.EndDate, !0) ? (hideAll(page, "btnPlay", !0), canPlay = !0) : hideAll(page, "btnPlay"), hideAll(page, "btnResume"), hideAll(page, "btnInstantMix"), hideAll(page, "btnShuffle") + var now = new Date(); + + if (now >= datetime.parseISO8601Date(item.StartDate, true) && now < datetime.parseISO8601Date(item.EndDate, true)) { + hideAll(page, "btnPlay", true); + canPlay = true; + } else { + hideAll(page, "btnPlay"); + } + + hideAll(page, "btnResume"); + hideAll(page, "btnInstantMix"); + hideAll(page, "btnShuffle"); } else if (playbackManager.canPlay(item)) { - hideAll(page, "btnPlay", !0); + hideAll(page, "btnPlay", true); var enableInstantMix = -1 !== ["Audio", "MusicAlbum", "MusicGenre", "MusicArtist"].indexOf(item.Type); hideAll(page, "btnInstantMix", enableInstantMix); var enableShuffle = item.IsFolder || -1 !== ["MusicAlbum", "MusicGenre", "MusicArtist"].indexOf(item.Type); - hideAll(page, "btnShuffle", enableShuffle), canPlay = !0, hideAll(page, "btnResume", item.UserData && item.UserData.PlaybackPositionTicks > 0) - } else hideAll(page, "btnPlay"), hideAll(page, "btnResume"), hideAll(page, "btnInstantMix"), hideAll(page, "btnShuffle"); - return canPlay + hideAll(page, "btnShuffle", enableShuffle); + canPlay = true; + hideAll(page, "btnResume", item.UserData && item.UserData.PlaybackPositionTicks > 0); + } else { + hideAll(page, "btnPlay"); + hideAll(page, "btnResume"); + hideAll(page, "btnInstantMix"); + hideAll(page, "btnShuffle"); + } + + return canPlay; } function reloadUserDataButtons(page, item) { - var i, length, btnPlaystates = page.querySelectorAll(".btnPlaystate"); + var i; + var length; + var btnPlaystates = page.querySelectorAll(".btnPlaystate"); + for (i = 0, length = btnPlaystates.length; i < length; i++) { var btnPlaystate = btnPlaystates[i]; - itemHelper.canMarkPlayed(item) ? (btnPlaystate.classList.remove("hide"), btnPlaystate.setItem(item)) : (btnPlaystate.classList.add("hide"), btnPlaystate.setItem(null)) + + if (itemHelper.canMarkPlayed(item)) { + btnPlaystate.classList.remove("hide"); + btnPlaystate.setItem(item); + } else { + btnPlaystate.classList.add("hide"); + btnPlaystate.setItem(null); + } } + var btnUserRatings = page.querySelectorAll(".btnUserRating"); + for (i = 0, length = btnUserRatings.length; i < length; i++) { var btnUserRating = btnUserRatings[i]; - itemHelper.canRate(item) ? (btnUserRating.classList.remove("hide"), btnUserRating.setItem(item)) : (btnUserRating.classList.add("hide"), btnUserRating.setItem(null)) + + if (itemHelper.canRate(item)) { + btnUserRating.classList.remove("hide"); + btnUserRating.setItem(item); + } else { + btnUserRating.classList.add("hide"); + btnUserRating.setItem(null); + } } } function getArtistLinksHtml(artists, serverId, context) { - for (var html = [], i = 0, length = artists.length; i < length; i++) { - var artist = artists[i], - href = appRouter.getRouteUrl(artist, { - context: context, - itemType: "MusicArtist", - serverId: serverId - }); - html.push('' + artist.Name + "") + var html = []; + + for (var i = 0, length = artists.length; i < length; i++) { + var artist = artists[i]; + var href = appRouter.getRouteUrl(artist, { + context: context, + itemType: "MusicArtist", + serverId: serverId + }); + html.push('' + artist.Name + ""); } - return html = html.join(" / ") + + return html = html.join(" / "); } function renderName(item, container, isStatic, context) { - var parentRoute, parentNameHtml = [], - parentNameLast = !1; - item.AlbumArtists ? (parentNameHtml.push(getArtistLinksHtml(item.AlbumArtists, item.ServerId, context)), parentNameLast = !0) : item.ArtistItems && item.ArtistItems.length && "MusicVideo" === item.Type ? (parentNameHtml.push(getArtistLinksHtml(item.ArtistItems, item.ServerId, context)), parentNameLast = !0) : item.SeriesName && "Episode" === item.Type ? (parentRoute = appRouter.getRouteUrl({ - Id: item.SeriesId, - Name: item.SeriesName, - Type: "Series", - IsFolder: !0, - ServerId: item.ServerId - }, { - context: context - }), parentNameHtml.push('' + item.SeriesName + "")) : (item.IsSeries || item.EpisodeTitle) && parentNameHtml.push(item.Name), item.SeriesName && "Season" === item.Type ? (parentRoute = appRouter.getRouteUrl({ - Id: item.SeriesId, - Name: item.SeriesName, - Type: "Series", - IsFolder: !0, - ServerId: item.ServerId - }, { - context: context - }), parentNameHtml.push('' + item.SeriesName + "")) : null != item.ParentIndexNumber && "Episode" === item.Type ? (parentRoute = appRouter.getRouteUrl({ - Id: item.SeasonId, - Name: item.SeasonName, - Type: "Season", - IsFolder: !0, - ServerId: item.ServerId - }, { - context: context - }), parentNameHtml.push('' + item.SeasonName + "")) : null != item.ParentIndexNumber && item.IsSeries ? parentNameHtml.push(item.SeasonName || "S" + item.ParentIndexNumber) : item.Album && item.AlbumId && ("MusicVideo" === item.Type || "Audio" === item.Type) ? (parentRoute = appRouter.getRouteUrl({ - Id: item.AlbumId, - Name: item.Album, - Type: "MusicAlbum", - IsFolder: !0, - ServerId: item.ServerId - }, { - context: context - }), parentNameHtml.push('' + item.Album + "")) : item.Album && parentNameHtml.push(item.Album); - var html = ""; - parentNameHtml.length && (html = parentNameLast ? '

            ' + parentNameHtml.join(" - ") + "

            " : '

            ' + parentNameHtml.join(" - ") + "

            "); - var name = itemHelper.getDisplayName(item, { - includeParentInfo: !1 - }); + var parentRoute; + var parentNameHtml = []; + var parentNameLast = false; + if (item.AlbumArtists) { + parentNameHtml.push(getArtistLinksHtml(item.AlbumArtists, item.ServerId, context)); + parentNameLast = true; + } else if (item.ArtistItems && item.ArtistItems.length && "MusicVideo" === item.Type) { + parentNameHtml.push(getArtistLinksHtml(item.ArtistItems, item.ServerId, context)); + parentNameLast = true; + } else if (item.SeriesName && "Episode" === item.Type) { + parentRoute = appRouter.getRouteUrl({ + Id: item.SeriesId, + Name: item.SeriesName, + Type: "Series", + IsFolder: true, + ServerId: item.ServerId + }, { + context: context + }); + parentNameHtml.push('' + item.SeriesName + ""); + } else if (item.IsSeries || item.EpisodeTitle) { + parentNameHtml.push(item.Name); + } + + if (item.SeriesName && "Season" === item.Type) { + parentRoute = appRouter.getRouteUrl({ + Id: item.SeriesId, + Name: item.SeriesName, + Type: "Series", + IsFolder: true, + ServerId: item.ServerId + }, { + context: context + }); + parentNameHtml.push('' + item.SeriesName + ""); + } else if (null != item.ParentIndexNumber && "Episode" === item.Type) { + parentRoute = appRouter.getRouteUrl({ + Id: item.SeasonId, + Name: item.SeasonName, + Type: "Season", + IsFolder: true, + ServerId: item.ServerId + }, { + context: context + }); + parentNameHtml.push('' + item.SeasonName + ""); + } else if (null != item.ParentIndexNumber && item.IsSeries) { + parentNameHtml.push(item.SeasonName || "S" + item.ParentIndexNumber); + } else if (item.Album && item.AlbumId && ("MusicVideo" === item.Type || "Audio" === item.Type)) { + parentRoute = appRouter.getRouteUrl({ + Id: item.AlbumId, + Name: item.Album, + Type: "MusicAlbum", + IsFolder: true, + ServerId: item.ServerId + }, { + context: context + }); + parentNameHtml.push('' + item.Album + ""); + } else if (item.Album) { + parentNameHtml.push(item.Album); + } + + var html = ""; + + if (parentNameHtml.length) { + if (parentNameLast) { + html = '

            ' + parentNameHtml.join(" - ") + "

            "; + } else { + html = '

            ' + parentNameHtml.join(" - ") + "

            "; + } + } + + var name = itemHelper.getDisplayName(item, { + includeParentInfo: false + }); var offset = parentNameLast ? ".25em" : ".5em"; + if (html && !parentNameLast) { html += '

            ' + name + '

            '; } else { @@ -248,110 +429,206 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild } container.innerHTML = html; - html.length ? container.classList.remove("hide") : container.classList.add("hide") + + if (html.length) { + container.classList.remove("hide"); + } else { + container.classList.add("hide"); + } } function setTrailerButtonVisibility(page, item) { - (item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && -1 !== playbackManager.getSupportedCommands().indexOf("PlayTrailers") ? hideAll(page, "btnPlayTrailer", !0) : hideAll(page, "btnPlayTrailer") - } - - function renderDetailPageBackdrop(page, item, apiClient) { - var imgUrl, screenWidth = screen.availWidth, - hasbackdrop = !1, - itemBackdropElement = page.querySelector("#itemBackdrop"), - usePrimaryImage = ("Video" === item.MediaType && "Movie" !== item.Type && "Trailer" !== item.Type) || (item.MediaType && "Video" !== item.MediaType) || ("MusicAlbum" === item.Type) || ("MusicArtist" === item.Type); - return "Program" === item.Type && item.ImageTags && item.ImageTags.Thumb ? (imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: "Thumb", - index: 0, - maxWidth: screenWidth, - tag: item.ImageTags.Thumb - }), itemBackdropElement.classList.remove("noBackdrop"), imageLoader.lazyImage(itemBackdropElement, imgUrl, !1), hasbackdrop = !0) : usePrimaryImage && item.ImageTags && item.ImageTags.Primary ? (imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: "Primary", - index: 0, - maxWidth: screenWidth, - tag: item.ImageTags.Primary - }), itemBackdropElement.classList.remove("noBackdrop"), imageLoader.lazyImage(itemBackdropElement, imgUrl, !1), hasbackdrop = !0) : item.BackdropImageTags && item.BackdropImageTags.length ? (imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: "Backdrop", - index: 0, - maxWidth: screenWidth, - tag: item.BackdropImageTags[0] - }), itemBackdropElement.classList.remove("noBackdrop"), imageLoader.lazyImage(itemBackdropElement, imgUrl, !1), hasbackdrop = !0) : item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length ? (imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, { - type: "Backdrop", - index: 0, - tag: item.ParentBackdropImageTags[0], - maxWidth: screenWidth - }), itemBackdropElement.classList.remove("noBackdrop"), imageLoader.lazyImage(itemBackdropElement, imgUrl, !1), hasbackdrop = !0) : item.ImageTags && item.ImageTags.Thumb ? (imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: "Thumb", - index: 0, - maxWidth: screenWidth, - tag: item.ImageTags.Thumb - }), itemBackdropElement.classList.remove("noBackdrop"), imageLoader.lazyImage(itemBackdropElement, imgUrl, !1), hasbackdrop = !0) : (itemBackdropElement.classList.add("noBackdrop"), itemBackdropElement.style.backgroundImage = ""), hasbackdrop - } - - function reloadFromItem(instance, page, params, item, user) { - var context = params.context; - renderName(item, page.querySelector(".nameContainer"), !1, context); - var apiClient = connectionManager.getApiClient(item.ServerId); - renderSeriesTimerEditor(page, item, apiClient, user), renderTimerEditor(page, item, apiClient, user), renderImage(page, item, apiClient, user), renderLogo(page, item, apiClient), setTitle(item, apiClient), setInitialCollapsibleState(page, item, apiClient, context, user), renderDetails(page, item, apiClient, context), renderTrackSelections(page, instance, item), dom.getWindowSize().innerWidth >= 1e3 ? backdrop.setBackdrops([item]) : backdrop.clear(), renderDetailPageBackdrop(page, item, apiClient); - var canPlay = reloadPlayButtons(page, item); if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && -1 !== playbackManager.getSupportedCommands().indexOf("PlayTrailers")) { hideAll(page, "btnPlayTrailer", true); } else { hideAll(page, "btnPlayTrailer"); } + } + + function renderDetailPageBackdrop(page, item, apiClient) { + var imgUrl; + var screenWidth = screen.availWidth; + var hasbackdrop = false; + var itemBackdropElement = page.querySelector("#itemBackdrop"); + var usePrimaryImage = item.MediaType === "Video" && item.Type !== "Movie" && item.Type !== "Trailer" || + item.MediaType && item.MediaType !== "Video" || + item.Type === "MusicAlbum" || + item.Type === "MusicArtist"; + + if ("Program" === item.Type && item.ImageTags && item.ImageTags.Thumb) { + imgUrl = apiClient.getScaledImageUrl(item.Id, { + type: "Thumb", + index: 0, + maxWidth: screenWidth, + tag: item.ImageTags.Thumb + }); + itemBackdropElement.classList.remove("noBackdrop"); + imageLoader.lazyImage(itemBackdropElement, imgUrl, false); + hasbackdrop = true; + } else if (usePrimaryImage && item.ImageTags && item.ImageTags.Primary) { + imgUrl = apiClient.getScaledImageUrl(item.Id, { + type: "Primary", + index: 0, + maxWidth: screenWidth, + tag: item.ImageTags.Primary + }); + itemBackdropElement.classList.remove("noBackdrop"); + imageLoader.lazyImage(itemBackdropElement, imgUrl, false); + hasbackdrop = true; + } else if (item.BackdropImageTags && item.BackdropImageTags.length) { + imgUrl = apiClient.getScaledImageUrl(item.Id, { + type: "Backdrop", + index: 0, + maxWidth: screenWidth, + tag: item.BackdropImageTags[0] + }); + itemBackdropElement.classList.remove("noBackdrop"); + imageLoader.lazyImage(itemBackdropElement, imgUrl, false); + hasbackdrop = true; + } else if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) { + imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, { + type: "Backdrop", + index: 0, + tag: item.ParentBackdropImageTags[0], + maxWidth: screenWidth + }); + itemBackdropElement.classList.remove("noBackdrop"); + imageLoader.lazyImage(itemBackdropElement, imgUrl, false); + hasbackdrop = true; + } else if (item.ImageTags && item.ImageTags.Thumb) { + imgUrl = apiClient.getScaledImageUrl(item.Id, { + type: "Thumb", + index: 0, + maxWidth: screenWidth, + tag: item.ImageTags.Thumb + }); + itemBackdropElement.classList.remove("noBackdrop"); + imageLoader.lazyImage(itemBackdropElement, imgUrl, false); + hasbackdrop = true; + } else { + itemBackdropElement.classList.add("noBackdrop"); + itemBackdropElement.style.backgroundImage = ""; + } + + return hasbackdrop; + } + + function reloadFromItem(instance, page, params, item, user) { + var context = params.context; + renderName(item, page.querySelector(".nameContainer"), false, context); + var apiClient = connectionManager.getApiClient(item.ServerId); + renderSeriesTimerEditor(page, item, apiClient, user); + renderTimerEditor(page, item, apiClient, user); + renderImage(page, item, apiClient, user); + renderLogo(page, item, apiClient); + setTitle(item, apiClient); + setInitialCollapsibleState(page, item, apiClient, context, user); + renderDetails(page, item, apiClient, context); + renderTrackSelections(page, instance, item); + + if (dom.getWindowSize().innerWidth >= 1000) { + backdrop.setBackdrops([item]); + } else { + backdrop.clear(); + } + + renderDetailPageBackdrop(page, item, apiClient); + var canPlay = reloadPlayButtons(page, item); + + if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && -1 !== playbackManager.getSupportedCommands().indexOf("PlayTrailers")) { + hideAll(page, "btnPlayTrailer", true); + } else { + hideAll(page, "btnPlayTrailer"); + } + setTrailerButtonVisibility(page, item); + if (item.CanDelete && !item.IsFolder) { hideAll(page, "btnDeleteItem", true); } else { hideAll(page, "btnDeleteItem"); } + if ("Program" !== item.Type || canPlay) { hideAll(page, "mainDetailButtons", true); } else { hideAll(page, "mainDetailButtons"); } + showRecordingFields(instance, page, item, user); - var groupedVersions = (item.MediaSources || []).filter(function(g) { - return "Grouping" == g.Type + var groupedVersions = (item.MediaSources || []).filter(function (g) { + return "Grouping" == g.Type; }); - user.Policy.IsAdministrator && groupedVersions.length ? page.querySelector(".btnSplitVersions").classList.remove("hide") : page.querySelector(".btnSplitVersions").classList.add("hide"), itemContextMenu.getCommands(getContextMenuOptions(item, user)).length ? hideAll(page, "btnMoreCommands", !0) : hideAll(page, "btnMoreCommands"); - var itemBirthday = page.querySelector("#itemBirthday"); - if ("Person" == item.Type && item.PremiereDate) try { - var birthday = datetime.parseISO8601Date(item.PremiereDate, !0).toDateString(); - itemBirthday.classList.remove("hide"), itemBirthday.innerHTML = globalize.translate("BirthDateValue").replace("{0}", birthday) - } catch (err) { - itemBirthday.classList.add("hide") - } else itemBirthday.classList.add("hide"); - var itemDeathDate = page.querySelector("#itemDeathDate"); - if ("Person" == item.Type && item.EndDate) try { - var deathday = datetime.parseISO8601Date(item.EndDate, !0).toDateString(); - itemDeathDate.classList.remove("hide"), itemDeathDate.innerHTML = globalize.translate("DeathDateValue").replace("{0}", deathday) - } catch (err) { - itemDeathDate.classList.add("hide") + + if (user.Policy.IsAdministrator && groupedVersions.length) { + page.querySelector(".btnSplitVersions").classList.remove("hide"); + } else { + page.querySelector(".btnSplitVersions").classList.add("hide"); } + + if (itemContextMenu.getCommands(getContextMenuOptions(item, user)).length) { + hideAll(page, "btnMoreCommands", true); + } else { + hideAll(page, "btnMoreCommands"); + } + + var itemBirthday = page.querySelector("#itemBirthday"); + + if ("Person" == item.Type && item.PremiereDate) { + try { + var birthday = datetime.parseISO8601Date(item.PremiereDate, true).toDateString(); + itemBirthday.classList.remove("hide"); + itemBirthday.innerHTML = globalize.translate("BirthDateValue").replace("{0}", birthday); + } catch (err) { + itemBirthday.classList.add("hide"); + } + } else { + itemBirthday.classList.add("hide"); + } + + var itemDeathDate = page.querySelector("#itemDeathDate"); + + if ("Person" == item.Type && item.EndDate) { + try { + var deathday = datetime.parseISO8601Date(item.EndDate, true).toDateString(); + itemDeathDate.classList.remove("hide"); + itemDeathDate.innerHTML = globalize.translate("DeathDateValue").replace("{0}", deathday); + } catch (err) { + itemDeathDate.classList.add("hide"); + } + } else { + itemDeathDate.classList.add("hide"); + } + var itemBirthLocation = page.querySelector("#itemBirthLocation"); + if ("Person" == item.Type && item.ProductionLocations && item.ProductionLocations.length) { var gmap = '' + item.ProductionLocations[0] + ""; - itemBirthLocation.classList.remove("hide"), itemBirthLocation.innerHTML = globalize.translate("BirthPlaceValue").replace("{0}", gmap) - } else itemBirthLocation.classList.add("hide"); - setPeopleHeader(page, item), loading.hide() + itemBirthLocation.classList.remove("hide"); + itemBirthLocation.innerHTML = globalize.translate("BirthPlaceValue").replace("{0}", gmap); + } else { + itemBirthLocation.classList.add("hide"); + } + + setPeopleHeader(page, item); + loading.hide(); if (item.Type === "Book") { hideAll(page, "btnDownload", true); } try { - require(["focusManager"], function(focusManager) { + require(["focusManager"], function (focusManager) { [".btnResume", ".btnPlay"].every(function (cls) { - var elems = page.querySelectorAll(cls); - + for (var i = 0; i < elems.length; i++) { if (focusManager.isCurrentlyFocusable(elems[i])) { focusManager.focus(elems[i]); return false; } } + return true; }); }); @@ -361,35 +638,68 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild } function logoImageUrl(item, apiClient, options) { - return options = options || {}, options.type = "Logo", item.ImageTags && item.ImageTags.Logo ? (options.tag = item.ImageTags.Logo, apiClient.getScaledImageUrl(item.Id, options)) : item.ParentLogoImageTag ? (options.tag = item.ParentLogoImageTag, apiClient.getScaledImageUrl(item.ParentLogoItemId, options)) : null + options = options || {}; + options.type = "Logo"; + + if (item.ImageTags && item.ImageTags.Logo) { + options.tag = item.ImageTags.Logo; + return apiClient.getScaledImageUrl(item.Id, options); + } + + if (item.ParentLogoImageTag) { + options.tag = item.ParentLogoImageTag; + return apiClient.getScaledImageUrl(item.ParentLogoItemId, options); + } + + return null; } function setTitle(item, apiClient) { var url = logoImageUrl(item, apiClient, {}); + if (url = null) { var pageTitle = document.querySelector(".pageTitle"); - pageTitle.style.backgroundImage = "url('" + url + "')", pageTitle.classList.add("pageTitleWithLogo"), pageTitle.innerHTML = "" - } else Emby.Page.setTitle("") + pageTitle.style.backgroundImage = "url('" + url + "')"; + pageTitle.classList.add("pageTitleWithLogo"); + pageTitle.innerHTML = ""; + } else { + Emby.Page.setTitle(""); + } } function renderLogo(page, item, apiClient) { var url = logoImageUrl(item, apiClient, { - maxWidth: 400 - }), - detailLogo = page.querySelector(".detailLogo"); - url ? (detailLogo.classList.remove("hide"), detailLogo.classList.add("lazy"), detailLogo.setAttribute("data-src", url), imageLoader.lazyImage(detailLogo)) : detailLogo.classList.add("hide") + maxWidth: 400 + }); + var detailLogo = page.querySelector(".detailLogo"); + + if (url) { + detailLogo.classList.remove("hide"); + detailLogo.classList.add("lazy"); + detailLogo.setAttribute("data-src", url); + imageLoader.lazyImage(detailLogo); + } else { + detailLogo.classList.add("hide"); + } } function showRecordingFields(instance, page, item, user) { if (!instance.currentRecordingFields) { var recordingFieldsElement = page.querySelector(".recordingFields"); - "Program" == item.Type && user.Policy.EnableLiveTvManagement ? require(["recordingFields"], function(recordingFields) { - instance.currentRecordingFields = new recordingFields({ - parent: recordingFieldsElement, - programId: item.Id, - serverId: item.ServerId - }), recordingFieldsElement.classList.remove("hide") - }) : (recordingFieldsElement.classList.add("hide"), recordingFieldsElement.innerHTML = "") + + if ("Program" == item.Type && user.Policy.EnableLiveTvManagement) { + require(["recordingFields"], function (recordingFields) { + instance.currentRecordingFields = new recordingFields({ + parent: recordingFieldsElement, + programId: item.Id, + serverId: item.ServerId + }); + recordingFieldsElement.classList.remove("hide"); + }); + } else { + recordingFieldsElement.classList.add("hide"); + recordingFieldsElement.innerHTML = ""; + } } } @@ -407,145 +717,340 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild function renderLinks(linksElem, item) { var html = []; + if (item.DateCreated && itemHelper.enableDateAddedDisplay(item)) { var dateCreated = datetime.parseISO8601Date(item.DateCreated); - html.push(globalize.translate("AddedOnValue", datetime.toLocaleDateString(dateCreated) + " " + datetime.getDisplayTime(dateCreated))) + html.push(globalize.translate("AddedOnValue", datetime.toLocaleDateString(dateCreated) + " " + datetime.getDisplayTime(dateCreated))); } + var links = []; - if (!layoutManager.tv && (item.HomePageUrl && links.push('' + globalize.translate("ButtonWebsite") + ""), item.ExternalUrls)) + + if (!layoutManager.tv && item.HomePageUrl) { + links.push('' + globalize.translate("ButtonWebsite") + ""); + } + if (item.ExternalUrls) { for (var i = 0, length = item.ExternalUrls.length; i < length; i++) { var url = item.ExternalUrls[i]; - links.push('' + url.Name + "") + links.push('' + url.Name + ""); } - links.length && html.push(globalize.translate("LinksValue", links.join(", "))), linksElem.innerHTML = html.join(", "), html.length ? linksElem.classList.remove("hide") : linksElem.classList.add("hide") + } + + if (links.length) { + html.push(globalize.translate("LinksValue", links.join(", "))); + } + + linksElem.innerHTML = html.join(", "); + + if (html.length) { + linksElem.classList.remove("hide"); + } else { + linksElem.classList.add("hide"); + } } function renderDetailImage(page, elem, item, apiClient, editable, imageLoader, indicators) { - "SeriesTimer" !== item.Type && "Program" !== item.Type || (editable = !1), "Person" !== item.Type ? (elem.classList.add("detailimg-hidemobile"), page.querySelector(".detailPageContent").classList.add("detailPageContent-nodetailimg")) : page.querySelector(".detailPageContent").classList.remove("detailPageContent-nodetailimg"); + if ("SeriesTimer" === item.Type || "Program" === item.Type) { + editable = false; + } + + if ("Person" !== item.Type) { + elem.classList.add("detailimg-hidemobile"); + page.querySelector(".detailPageContent").classList.add("detailPageContent-nodetailimg"); + } else { + page.querySelector(".detailPageContent").classList.remove("detailPageContent-nodetailimg"); + } + var imageTags = item.ImageTags || {}; - item.PrimaryImageTag && (imageTags.Primary = item.PrimaryImageTag); - var url, html = "", - shape = "portrait", - detectRatio = !1; - imageTags.Primary ? (url = apiClient.getScaledImageUrl(item.Id, { - type: "Primary", - tag: item.ImageTags.Primary - }), detectRatio = !0) : item.BackdropImageTags && item.BackdropImageTags.length ? (url = apiClient.getScaledImageUrl(item.Id, { - type: "Backdrop", - tag: item.BackdropImageTags[0] - }), shape = "thumb") : imageTags.Thumb ? (url = apiClient.getScaledImageUrl(item.Id, { - type: "Thumb", - tag: item.ImageTags.Thumb - }), shape = "thumb") : imageTags.Disc ? (url = apiClient.getScaledImageUrl(item.Id, { - type: "Disc", - tag: item.ImageTags.Disc - }), shape = "square") : item.AlbumId && item.AlbumPrimaryImageTag ? (url = apiClient.getScaledImageUrl(item.AlbumId, { - type: "Primary", - tag: item.AlbumPrimaryImageTag - }), shape = "square") : item.SeriesId && item.SeriesPrimaryImageTag ? url = apiClient.getScaledImageUrl(item.SeriesId, { - type: "Primary", - tag: item.SeriesPrimaryImageTag - }) : item.ParentPrimaryImageItemId && item.ParentPrimaryImageTag && (url = apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, { - type: "Primary", - tag: item.ParentPrimaryImageTag - })), html += '
            ', editable && (html += ""), detectRatio && item.PrimaryImageAspectRatio && (item.PrimaryImageAspectRatio >= 1.48 ? shape = "thumb" : item.PrimaryImageAspectRatio >= .85 && item.PrimaryImageAspectRatio <= 1.34 && (shape = "square")), html += "", editable && (html += ""); + + if (item.PrimaryImageTag) { + imageTags.Primary = item.PrimaryImageTag; + } + + var url; + var html = ""; + var shape = "portrait"; + var detectRatio = false; + + if (imageTags.Primary) { + url = apiClient.getScaledImageUrl(item.Id, { + type: "Primary", + tag: item.ImageTags.Primary + }); + detectRatio = true; + } else if (item.BackdropImageTags && item.BackdropImageTags.length) { + url = apiClient.getScaledImageUrl(item.Id, { + type: "Backdrop", + tag: item.BackdropImageTags[0] + }); + shape = "thumb"; + } else if (imageTags.Thumb) { + url = apiClient.getScaledImageUrl(item.Id, { + type: "Thumb", + tag: item.ImageTags.Thumb + }); + shape = "thumb"; + } else if (imageTags.Disc) { + url = apiClient.getScaledImageUrl(item.Id, { + type: "Disc", + tag: item.ImageTags.Disc + }); + shape = "square"; + } else if (item.AlbumId && item.AlbumPrimaryImageTag) { + url = apiClient.getScaledImageUrl(item.AlbumId, { + type: "Primary", + tag: item.AlbumPrimaryImageTag + }); + shape = "square"; + } else if (item.SeriesId && item.SeriesPrimaryImageTag) { + url = apiClient.getScaledImageUrl(item.SeriesId, { + type: "Primary", + tag: item.SeriesPrimaryImageTag + }); + } else if (item.ParentPrimaryImageItemId && item.ParentPrimaryImageTag) { + url = apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, { + type: "Primary", + tag: item.ParentPrimaryImageTag + }); + } + + html += '
            '; + + if (editable) { + html += ""; + } + + if (detectRatio && item.PrimaryImageAspectRatio) { + if (item.PrimaryImageAspectRatio >= 1.48) { + shape = "thumb"; + } else if (item.PrimaryImageAspectRatio >= .85 && item.PrimaryImageAspectRatio <= 1.34) { + shape = "square"; + } + } + + html += ""; + + if (editable) { + html += ""; + } + var progressHtml = item.IsFolder || !item.UserData ? "" : indicators.getProgressBarHtml(item); - html += '
            ', progressHtml && (html += progressHtml), html += "
            ", html += "
            ", elem.innerHTML = html, "thumb" == shape ? (elem.classList.add("thumbDetailImageContainer"), elem.classList.remove("portraitDetailImageContainer"), elem.classList.remove("squareDetailImageContainer")) : "square" == shape ? (elem.classList.remove("thumbDetailImageContainer"), elem.classList.remove("portraitDetailImageContainer"), elem.classList.add("squareDetailImageContainer")) : (elem.classList.remove("thumbDetailImageContainer"), elem.classList.add("portraitDetailImageContainer"), elem.classList.remove("squareDetailImageContainer")), url && imageLoader.lazyImage(elem.querySelector("img"), url) + html += '
            '; + + if (progressHtml) { + html += progressHtml; + } + + html += "
            "; + html += "
            "; + elem.innerHTML = html; + + if ("thumb" == shape) { + elem.classList.add("thumbDetailImageContainer"); + elem.classList.remove("portraitDetailImageContainer"); + elem.classList.remove("squareDetailImageContainer"); + } else if ("square" == shape) { + elem.classList.remove("thumbDetailImageContainer"); + elem.classList.remove("portraitDetailImageContainer"); + elem.classList.add("squareDetailImageContainer"); + } else { + elem.classList.remove("thumbDetailImageContainer"); + elem.classList.add("portraitDetailImageContainer"); + elem.classList.remove("squareDetailImageContainer"); + } + + + if (url) { + imageLoader.lazyImage(elem.querySelector("img"), url); + } } function renderImage(page, item, apiClient, user) { - renderDetailImage(page, page.querySelector(".detailImageContainer"), item, apiClient, user.Policy.IsAdministrator && "Photo" != item.MediaType, imageLoader, indicators) + renderDetailImage( + page, + page.querySelector(".detailImageContainer"), + item, + apiClient, + user.Policy.IsAdministrator && "Photo" != item.MediaType, + imageLoader, + indicators + ); } function refreshDetailImageUserData(elem, item) { - elem.querySelector(".detailImageProgressContainer").innerHTML = indicators.getProgressBarHtml(item) + elem.querySelector(".detailImageProgressContainer").innerHTML = indicators.getProgressBarHtml(item); } function refreshImage(page, item, user) { - refreshDetailImageUserData(page.querySelector(".detailImageContainer"), item) + refreshDetailImageUserData(page.querySelector(".detailImageContainer"), item); } function setPeopleHeader(page, item) { - "Audio" == item.MediaType || "MusicAlbum" == item.Type || "Book" == item.MediaType || "Photo" == item.MediaType ? page.querySelector("#peopleHeader").innerHTML = globalize.translate("HeaderPeople") : page.querySelector("#peopleHeader").innerHTML = globalize.translate("HeaderCastAndCrew") + if ("Audio" == item.MediaType || "MusicAlbum" == item.Type || "Book" == item.MediaType || "Photo" == item.MediaType) { + page.querySelector("#peopleHeader").innerHTML = globalize.translate("HeaderPeople"); + } else { + page.querySelector("#peopleHeader").innerHTML = globalize.translate("HeaderCastAndCrew"); + } } function renderNextUp(page, item, user) { var section = page.querySelector(".nextUpSection"); - if ("Series" != item.Type) return void section.classList.add("hide"); + + if ("Series" != item.Type) { + return void section.classList.add("hide"); + } + connectionManager.getApiClient(item.ServerId).getNextUpEpisodes({ SeriesId: item.Id, UserId: user.Id - }).then(function(result) { - result.Items.length ? section.classList.remove("hide") : section.classList.add("hide"); + }).then(function (result) { + if (result.Items.length) { + section.classList.remove("hide"); + } else { + section.classList.add("hide"); + } + var html = cardBuilder.getCardsHtml({ - items: result.Items, - shape: getThumbShape(!1), - showTitle: !0, - displayAsSpecial: "Season" == item.Type && item.IndexNumber, - overlayText: !1, - centerText: !0, - overlayPlayButton: !0 - }), - itemsContainer = section.querySelector(".nextUpItems"); - itemsContainer.innerHTML = html, imageLoader.lazyChildren(itemsContainer) - }) + items: result.Items, + shape: getThumbShape(false), + showTitle: true, + displayAsSpecial: "Season" == item.Type && item.IndexNumber, + overlayText: false, + centerText: true, + overlayPlayButton: true + }); + var itemsContainer = section.querySelector(".nextUpItems"); + itemsContainer.innerHTML = html; + imageLoader.lazyChildren(itemsContainer); + }); } function setInitialCollapsibleState(page, item, apiClient, context, user) { - page.querySelector(".collectionItems").innerHTML = "", "Playlist" == item.Type ? (page.querySelector("#childrenCollapsible").classList.remove("hide"), renderPlaylistItems(page, item, user)) : "Studio" == item.Type || "Person" == item.Type || "Genre" == item.Type || "MusicGenre" == item.Type || "MusicArtist" == item.Type ? (page.querySelector("#childrenCollapsible").classList.remove("hide"), renderItemsByName(page, item, user)) : item.IsFolder ? ("BoxSet" == item.Type && page.querySelector("#childrenCollapsible").classList.add("hide"), renderChildren(page, item)) : page.querySelector("#childrenCollapsible").classList.add("hide"), "Series" == item.Type && renderSeriesSchedule(page, item, user), "Series" == item.Type ? renderNextUp(page, item, user) : page.querySelector(".nextUpSection").classList.add("hide"), renderScenes(page, item), item.SpecialFeatureCount && 0 != item.SpecialFeatureCount && "Series" != item.Type ? (page.querySelector("#specialsCollapsible").classList.remove("hide"), renderSpecials(page, item, user, 6)) : page.querySelector("#specialsCollapsible").classList.add("hide"), renderCast(page, item, context, enableScrollX() ? null : 12), item.PartCount && item.PartCount > 1 ? (page.querySelector("#additionalPartsCollapsible").classList.remove("hide"), renderAdditionalParts(page, item, user)) : page.querySelector("#additionalPartsCollapsible").classList.add("hide"), "MusicAlbum" == item.Type ? renderMusicVideos(page, item, user) : page.querySelector("#musicVideosCollapsible").classList.add("hide") + page.querySelector(".collectionItems").innerHTML = ""; + + if ("Playlist" == item.Type) { + page.querySelector("#childrenCollapsible").classList.remove("hide"); + renderPlaylistItems(page, item, user); + } else if ("Studio" == item.Type || "Person" == item.Type || "Genre" == item.Type || "MusicGenre" == item.Type || "MusicArtist" == item.Type) { + page.querySelector("#childrenCollapsible").classList.remove("hide"); + renderItemsByName(page, item, user); + } else if (item.IsFolder) { + if ("BoxSet" == item.Type) { + page.querySelector("#childrenCollapsible").classList.add("hide"); + } + + renderChildren(page, item); + } else { + page.querySelector("#childrenCollapsible").classList.add("hide"); + } + + if ("Series" == item.Type) { + renderSeriesSchedule(page, item, user); + renderNextUp(page, item, user); + } else { + page.querySelector(".nextUpSection").classList.add("hide"); + } + + renderScenes(page, item); + + if (item.SpecialFeatureCount && 0 != item.SpecialFeatureCount && "Series" != item.Type) { + page.querySelector("#specialsCollapsible").classList.remove("hide"); + renderSpecials(page, item, user, 6); + } else { + page.querySelector("#specialsCollapsible").classList.add("hide"); + } + + renderCast(page, item, context, enableScrollX() ? null : 12); + + if (item.PartCount && item.PartCount > 1) { + page.querySelector("#additionalPartsCollapsible").classList.remove("hide"); + renderAdditionalParts(page, item, user); + } else { + page.querySelector("#additionalPartsCollapsible").classList.add("hide"); + } + + if ("MusicAlbum" == item.Type) { + renderMusicVideos(page, item, user); + } else { + page.querySelector("#musicVideosCollapsible").classList.add("hide"); + } } function renderOverview(elems, item) { for (var i = 0, length = elems.length; i < length; i++) { - var elem = elems[i], - overview = item.Overview || ""; + var elem = elems[i]; + var overview = item.Overview || ""; + if (overview) { - elem.innerHTML = overview, elem.classList.remove("hide"); - for (var anchors = elem.querySelectorAll("a"), j = 0, length2 = anchors.length; j < length2; j++) anchors[j].setAttribute("target", "_blank") - } else elem.innerHTML = "", elem.classList.add("hide") + elem.innerHTML = overview; + elem.classList.remove("hide"); + var anchors = elem.querySelectorAll("a"); + + for (var j = 0, length2 = anchors.length; j < length2; j++) { + anchors[j].setAttribute("target", "_blank"); + } + } else { + elem.innerHTML = ""; + elem.classList.add("hide"); + } } } function renderGenres(page, item, apiClient, context, isStatic) { context = context || inferContext(item); - var type, genres = item.GenreItems || []; + var type; + var genres = item.GenreItems || []; + switch (context) { case "music": type = "MusicGenre"; break; + default: - type = "Genre" + type = "Genre"; + } + + var html = genres.map(function (p) { + return '' + p.Name + ""; + }).join(", "); + var elem = page.querySelector(".genres"); + elem.innerHTML = globalize.translate(genres.length > 1 ? "GenresValue" : "GenreValue", html); + + if (genres.length) { + elem.classList.remove("hide"); + } else { + elem.classList.add("hide"); } - var html = genres.map(function(p) { - return '' + p.Name + "" - }).join(", "), - elem = page.querySelector(".genres"); - elem.innerHTML = genres.length > 1 ? globalize.translate("GenresValue", html) : globalize.translate("GenreValue", html), genres.length ? elem.classList.remove("hide") : elem.classList.add("hide") } function renderDirector(page, item, apiClient, context, isStatic) { - var directors = (item.People || []).filter(function(p) { - return "Director" === p.Type - }), - html = directors.map(function(p) { - return '' + p.Name + "" - }).join(", "), - elem = page.querySelector(".directors"); - elem.innerHTML = directors.length > 1 ? globalize.translate("DirectorsValue", html) : globalize.translate("DirectorValue", html), directors.length ? elem.classList.remove("hide") : elem.classList.add("hide") + var directors = (item.People || []).filter(function (p) { + return "Director" === p.Type; + }); + var html = directors.map(function (p) { + return '' + p.Name + ""; + }).join(", "); + var elem = page.querySelector(".directors"); + elem.innerHTML = globalize.translate(directors.length > 1 ? "DirectorsValue" : "DirectorValue", html); + + if (directors.length) { + elem.classList.remove("hide"); + } else { + elem.classList.add("hide"); + } } function renderDetails(page, item, apiClient, context, isStatic) { @@ -555,8 +1060,8 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild renderDirector(page, item, apiClient, context, isStatic); renderGenres(page, item, apiClient, context, isStatic); renderChannelGuide(page, apiClient, item); - var taglineElement = page.querySelector(".tagline"); + if (item.Taglines && item.Taglines.length) { taglineElement.classList.remove("hide"); taglineElement.innerHTML = item.Taglines[0]; @@ -571,15 +1076,17 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild overview.classList.add("detailsHiddenOnMobile"); externalLinksElem.classList.add("detailsHiddenOnMobile"); } - renderOverview([overview], item); - var i, itemMiscInfo; + renderOverview([overview], item); + var i; + var itemMiscInfo; itemMiscInfo = page.querySelectorAll(".itemMiscInfo-primary"); + for (i = 0; i < itemMiscInfo.length; i++) { mediaInfo.fillPrimaryMediaInfo(itemMiscInfo[i], item, { - interactive: !0, - episodeTitle: !1, - subtitles: !1 + interactive: true, + episodeTitle: false, + subtitles: false }); if (itemMiscInfo[i].innerHTML && "SeriesTimer" !== item.Type) { @@ -589,11 +1096,12 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild } } - itemMiscInfo = page.querySelectorAll(".itemMiscInfo-secondary") + itemMiscInfo = page.querySelectorAll(".itemMiscInfo-secondary"); + for (i = 0; i < itemMiscInfo.length; i++) { mediaInfo.fillSecondaryMediaInfo(itemMiscInfo[i], item, { - interactive: !0 - }) + interactive: true + }); if (itemMiscInfo[i].innerHTML && "SeriesTimer" !== item.Type) { itemMiscInfo[i].classList.remove("hide"); @@ -601,230 +1109,382 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild itemMiscInfo[i].classList.add("hide"); } } - + reloadUserDataButtons(page, item); renderLinks(externalLinksElem, item); renderUserInfo(page, item); renderTags(page, item); - renderSeriesAirTime(page, item, isStatic) + renderSeriesAirTime(page, item, isStatic); } function enableScrollX() { - return browser.mobile && screen.availWidth <= 1e3 + return browser.mobile && screen.availWidth <= 1000; } function getPortraitShape(scrollX) { - return null == scrollX && (scrollX = enableScrollX()), scrollX ? "overflowPortrait" : "portrait" + if (null == scrollX) { + scrollX = enableScrollX(); + } + + return scrollX ? "overflowPortrait" : "portrait"; } function getSquareShape(scrollX) { - return null == scrollX && (scrollX = enableScrollX()), scrollX ? "overflowSquare" : "square" + if (null == scrollX) { + scrollX = enableScrollX(); + } + + return scrollX ? "overflowSquare" : "square"; } function getThumbShape(scrollX) { - return null == scrollX && (scrollX = enableScrollX()), scrollX ? "overflowBackdrop" : "backdrop" + if (null == scrollX) { + scrollX = enableScrollX(); + } + + return scrollX ? "overflowBackdrop" : "backdrop"; } function renderMoreFromSeason(view, item, apiClient) { var section = view.querySelector(".moreFromSeasonSection"); + if (section) { - if ("Episode" !== item.Type || !item.SeasonId || !item.SeriesId) return void section.classList.add("hide"); + if ("Episode" !== item.Type || !item.SeasonId || !item.SeriesId) { + return void section.classList.add("hide"); + } + var userId = apiClient.getCurrentUserId(); apiClient.getEpisodes(item.SeriesId, { SeasonId: item.SeasonId, UserId: userId, Fields: "ItemCounts,PrimaryImageAspectRatio,BasicSyncInfo,CanDelete,MediaSourceCount" - }).then(function(result) { - if (result.Items.length < 2) return void section.classList.add("hide"); - section.classList.remove("hide"), section.querySelector("h2").innerHTML = globalize.translate("MoreFromValue", item.SeasonName); + }).then(function (result) { + if (result.Items.length < 2) { + return void section.classList.add("hide"); + } + + section.classList.remove("hide"); + section.querySelector("h2").innerHTML = globalize.translate("MoreFromValue", item.SeasonName); var itemsContainer = section.querySelector(".itemsContainer"); cardBuilder.buildCards(result.Items, { parentContainer: section, itemsContainer: itemsContainer, shape: "autooverflow", sectionTitleTagName: "h2", - scalable: !0, - showTitle: !0, - overlayText: !1, - centerText: !0, - includeParentInfoInTitle: !1, - allowBottomPadding: !1 + scalable: true, + showTitle: true, + overlayText: false, + centerText: true, + includeParentInfoInTitle: false, + allowBottomPadding: false }); var card = itemsContainer.querySelector('.card[data-id="' + item.Id + '"]'); - card && setTimeout(function() { - section.querySelector(".emby-scroller").toStart(card.previousSibling || card, !0) - }, 100) - }) + + if (card) { + setTimeout(function () { + section.querySelector(".emby-scroller").toStart(card.previousSibling || card, true); + }, 100); + } + }); } } function renderMoreFromArtist(view, item, apiClient) { var section = view.querySelector(".moreFromArtistSection"); + if (section) { if ("MusicArtist" === item.Type) { - if (!apiClient.isMinServerVersion("3.4.1.19")) return void section.classList.add("hide") - } else if ("MusicAlbum" !== item.Type || !item.AlbumArtists || !item.AlbumArtists.length) return void section.classList.add("hide"); + if (!apiClient.isMinServerVersion("3.4.1.19")) { + return void section.classList.add("hide"); + } + } else if ("MusicAlbum" !== item.Type || !item.AlbumArtists || !item.AlbumArtists.length) { + return void section.classList.add("hide"); + } + var query = { IncludeItemTypes: "MusicAlbum", - Recursive: !0, + Recursive: true, ExcludeItemIds: item.Id, SortBy: "ProductionYear,SortName", SortOrder: "Descending" }; - "MusicArtist" === item.Type ? query.ContributingArtistIds = item.Id : apiClient.isMinServerVersion("3.4.1.18") ? query.AlbumArtistIds = item.AlbumArtists[0].Id : query.ArtistIds = item.AlbumArtists[0].Id, apiClient.getItems(apiClient.getCurrentUserId(), query).then(function(result) { - if (!result.Items.length) return void section.classList.add("hide"); - section.classList.remove("hide"), "MusicArtist" === item.Type ? section.querySelector("h2").innerHTML = globalize.translate("HeaderAppearsOn") : section.querySelector("h2").innerHTML = globalize.translate("MoreFromValue", item.AlbumArtists[0].Name), cardBuilder.buildCards(result.Items, { + + if ("MusicArtist" === item.Type) { + query.ContributingArtistIds = item.Id; + } else if (apiClient.isMinServerVersion("3.4.1.18")) { + query.AlbumArtistIds = item.AlbumArtists[0].Id; + } else { + query.ArtistIds = item.AlbumArtists[0].Id; + } + + apiClient.getItems(apiClient.getCurrentUserId(), query).then(function (result) { + if (!result.Items.length) { + return void section.classList.add("hide"); + } + + section.classList.remove("hide"); + + if ("MusicArtist" === item.Type) { + section.querySelector("h2").innerHTML = globalize.translate("HeaderAppearsOn"); + } else { + section.querySelector("h2").innerHTML = globalize.translate("MoreFromValue", item.AlbumArtists[0].Name); + } + + cardBuilder.buildCards(result.Items, { parentContainer: section, itemsContainer: section.querySelector(".itemsContainer"), shape: "autooverflow", sectionTitleTagName: "h2", - scalable: !0, + scalable: true, coverImage: "MusicArtist" === item.Type || "MusicAlbum" === item.Type, - showTitle: !0, - showParentTitle: !1, - centerText: !0, - overlayText: !1, - overlayPlayButton: !0, - showYear: !0 - }) - }) + showTitle: true, + showParentTitle: false, + centerText: true, + overlayText: false, + overlayPlayButton: true, + showYear: true + }); + }); } } function renderSimilarItems(page, item, context) { var similarCollapsible = page.querySelector("#similarCollapsible"); + if (similarCollapsible) { - if ("Movie" != item.Type && "Trailer" != item.Type && "Series" != item.Type && "Program" != item.Type && "Recording" != item.Type && "MusicAlbum" != item.Type && "MusicArtist" != item.Type && "Playlist" != item.Type) return void similarCollapsible.classList.add("hide"); + if ("Movie" != item.Type && "Trailer" != item.Type && "Series" != item.Type && "Program" != item.Type && "Recording" != item.Type && "MusicAlbum" != item.Type && "MusicArtist" != item.Type && "Playlist" != item.Type) { + return void similarCollapsible.classList.add("hide"); + } + similarCollapsible.classList.remove("hide"); - var apiClient = connectionManager.getApiClient(item.ServerId), - options = { - userId: apiClient.getCurrentUserId(), - limit: 12, - fields: "PrimaryImageAspectRatio,UserData,CanDelete" - }; - "MusicAlbum" == item.Type && item.AlbumArtists && item.AlbumArtists.length && (options.ExcludeArtistIds = item.AlbumArtists[0].Id), apiClient.getSimilarItems(item.Id, options).then(function(result) { - if (!result.Items.length) return void similarCollapsible.classList.add("hide"); + var apiClient = connectionManager.getApiClient(item.ServerId); + var options = { + userId: apiClient.getCurrentUserId(), + limit: 12, + fields: "PrimaryImageAspectRatio,UserData,CanDelete" + }; + + if ("MusicAlbum" == item.Type && item.AlbumArtists && item.AlbumArtists.length) { + options.ExcludeArtistIds = item.AlbumArtists[0].Id; + } + + apiClient.getSimilarItems(item.Id, options).then(function (result) { + if (!result.Items.length) { + return void similarCollapsible.classList.add("hide"); + } + similarCollapsible.classList.remove("hide"); var html = ""; html += cardBuilder.getCardsHtml({ items: result.Items, shape: "autooverflow", showParentTitle: "MusicAlbum" == item.Type, - centerText: !0, - showTitle: !0, + centerText: true, + showTitle: true, context: context, - lazy: !0, - showDetailsMenu: !0, + lazy: true, + showDetailsMenu: true, coverImage: "MusicAlbum" == item.Type || "MusicArtist" == item.Type, - overlayPlayButton: !0, - overlayText: !1, + overlayPlayButton: true, + overlayText: false, showYear: "Movie" === item.Type || "Trailer" === item.Type }); var similarContent = similarCollapsible.querySelector(".similarContent"); - similarContent.innerHTML = html, imageLoader.lazyChildren(similarContent) - }) + similarContent.innerHTML = html; + imageLoader.lazyChildren(similarContent); + }); } } function renderSeriesAirTime(page, item, isStatic) { var seriesAirTime = page.querySelector("#seriesAirTime"); - if ("Series" != item.Type) return void seriesAirTime.classList.add("hide"); + if ("Series" != item.Type) { + seriesAirTime.classList.add("hide"); + return; + } var html = ""; - if (item.AirDays && item.AirDays.length && (html += 7 == item.AirDays.length ? "daily" : item.AirDays.map(function(a) { - return a + "s" - }).join(",")), item.AirTime && (html += " at " + item.AirTime), item.Studios.length) - if (isStatic) html += " on " + item.Studios[0].Name; - else { - var context = inferContext(item), - href = appRouter.getRouteUrl(item.Studios[0], { - context: context, - itemType: "Studio", - serverId: item.ServerId - }); - html += ' on ' + item.Studios[0].Name + "" - } html ? (html = ("Ended" == item.Status ? "Aired " : "Airs ") + html, seriesAirTime.innerHTML = html, seriesAirTime.classList.remove("hide")) : seriesAirTime.classList.add("hide") + if (item.AirDays && item.AirDays.length) { + if (7 == item.AirDays.length) { + html += "daily"; + } else { + html += item.AirDays.map(function (a) { + return a + "s"; + }).join(","); + } + } + if (item.AirTime) { + html += " at " + item.AirTime; + } + if (item.Studios.length) { + if (isStatic) { + html += " on " + item.Studios[0].Name; + } else { + var context = inferContext(item); + var href = appRouter.getRouteUrl(item.Studios[0], { + context: context, + itemType: "Studio", + serverId: item.ServerId + }); + html += ' on ' + item.Studios[0].Name + ""; + } + } + if (html) { + html = ("Ended" == item.Status ? "Aired " : "Airs ") + html; + seriesAirTime.innerHTML = html; + seriesAirTime.classList.remove("hide"); + } else { + seriesAirTime.classList.add("hide"); + } } function renderTags(page, item) { - var itemTags = page.querySelector(".itemTags"), - tagElements = [], - tags = item.Tags || []; - "Program" === item.Type && (tags = []); - for (var i = 0, length = tags.length; i < length; i++) tagElements.push(tags[i]); - tagElements.length ? (itemTags.innerHTML = globalize.translate("TagsValue", tagElements.join(", ")), itemTags.classList.remove("hide")) : (itemTags.innerHTML = "", itemTags.classList.add("hide")) + var itemTags = page.querySelector(".itemTags"); + var tagElements = []; + var tags = item.Tags || []; + + if ("Program" === item.Type) { + tags = []; + } + + for (var i = 0, length = tags.length; i < length; i++) { + tagElements.push(tags[i]); + } + + if (tagElements.length) { + itemTags.innerHTML = globalize.translate("TagsValue", tagElements.join(", ")); + itemTags.classList.remove("hide"); + } else { + itemTags.innerHTML = ""; + itemTags.classList.add("hide"); + } } function renderChildren(page, item) { - var fields = "ItemCounts,PrimaryImageAspectRatio,BasicSyncInfo,CanDelete,MediaSourceCount", - query = { - ParentId: item.Id, + var fields = "ItemCounts,PrimaryImageAspectRatio,BasicSyncInfo,CanDelete,MediaSourceCount"; + var query = { + ParentId: item.Id, + Fields: fields + }; + + if ("BoxSet" !== item.Type) { + query.SortBy = "SortName"; + } + + var promise; + var apiClient = connectionManager.getApiClient(item.ServerId); + var userId = apiClient.getCurrentUserId(); + + if ("Series" == item.Type) { + promise = apiClient.getSeasons(item.Id, { + userId: userId, Fields: fields - }; - "BoxSet" !== item.Type && (query.SortBy = "SortName"); - var promise, apiClient = connectionManager.getApiClient(item.ServerId), - userId = apiClient.getCurrentUserId(); - "Series" == item.Type ? promise = apiClient.getSeasons(item.Id, { - userId: userId, - Fields: fields - }) : "Season" == item.Type ? (fields += ",Overview", promise = apiClient.getEpisodes(item.SeriesId, { - seasonId: item.Id, - userId: userId, - Fields: fields - })) : "MusicAlbum" == item.Type || "MusicArtist" == item.Type && (query.SortBy = "ProductionYear,SortName"), promise = promise || apiClient.getItems(apiClient.getCurrentUserId(), query), promise.then(function(result) { - var html = "", - scrollX = !1, - isList = !1, - childrenItemsContainer = page.querySelector(".childrenItemsContainer"); - if ("MusicAlbum" == item.Type) html = listView.getListViewHtml({ - items: result.Items, - smallIcon: !0, - showIndex: !0, - index: "disc", - showIndexNumberLeft: !0, - playFromHere: !0, - action: "playallfromhere", - image: !1, - artist: "auto", - containerAlbumArtists: item.AlbumArtists, - addToListButton: !0 - }), isList = !0; - else if ("Series" == item.Type) scrollX = enableScrollX(), html = cardBuilder.getCardsHtml({ - items: result.Items, - shape: getPortraitShape(), - showTitle: !0, - centerText: !0, - lazy: !0, - overlayPlayButton: !0, - allowBottomPadding: !scrollX }); - else if ("Season" == item.Type || "Episode" == item.Type) { - if ("Episode" === item.Type || (isList = !0), scrollX = "Episode" == item.Type, result.Items.length < 2 && "Episode" === item.Type) return; - "Episode" === item.Type ? html = cardBuilder.getCardsHtml({ + } else if ("Season" == item.Type) { + fields += ",Overview"; + promise = apiClient.getEpisodes(item.SeriesId, { + seasonId: item.Id, + userId: userId, + Fields: fields + }); + } else if ("MusicArtist" == item.Type) { + query.SortBy = "ProductionYear,SortName"; + } + + promise = promise || apiClient.getItems(apiClient.getCurrentUserId(), query); + promise.then(function (result) { + var html = ""; + var scrollX = false; + var isList = false; + var childrenItemsContainer = page.querySelector(".childrenItemsContainer"); + + if ("MusicAlbum" == item.Type) { + html = listView.getListViewHtml({ items: result.Items, - shape: getThumbShape(scrollX), - showTitle: !0, - displayAsSpecial: "Season" == item.Type && item.IndexNumber, - playFromHere: !0, - overlayText: !0, - lazy: !0, - showDetailsMenu: !0, - overlayPlayButton: !0, - allowBottomPadding: !scrollX, - includeParentInfoInTitle: !1 - }) : "Season" === item.Type && (html = listView.getListViewHtml({ + smallIcon: true, + showIndex: true, + index: "disc", + showIndexNumberLeft: true, + playFromHere: true, + action: "playallfromhere", + image: false, + artist: "auto", + containerAlbumArtists: item.AlbumArtists, + addToListButton: true + }); + isList = true; + } else if ("Series" == item.Type) { + scrollX = enableScrollX(); + html = cardBuilder.getCardsHtml({ items: result.Items, - showIndexNumber: !1, - enableOverview: !0, - imageSize: "large", - enableSideMediaInfo: !1, - highlight: !1, - action: layoutManager.tv ? "resume" : "none", - infoButton: !0, - imagePlayButton: !0, - includeParentInfoInTitle: !1 - })) + shape: getPortraitShape(), + showTitle: true, + centerText: true, + lazy: true, + overlayPlayButton: true, + allowBottomPadding: !scrollX + }); + } else if ("Season" == item.Type || "Episode" == item.Type) { + if ("Episode" !== item.Type) { + isList = true; + } + scrollX = "Episode" == item.Type; + if (result.Items.length < 2 && "Episode" === item.Type) { + return; + } + + if ("Episode" === item.Type) { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: getThumbShape(scrollX), + showTitle: true, + displayAsSpecial: "Season" == item.Type && item.IndexNumber, + playFromHere: true, + overlayText: true, + lazy: true, + showDetailsMenu: true, + overlayPlayButton: true, + allowBottomPadding: !scrollX, + includeParentInfoInTitle: false + }); + } else if ("Season" === item.Type) { + html = listView.getListViewHtml({ + items: result.Items, + showIndexNumber: false, + enableOverview: true, + imageSize: "large", + enableSideMediaInfo: false, + highlight: false, + action: layoutManager.tv ? "resume" : "none", + infoButton: true, + imagePlayButton: true, + includeParentInfoInTitle: false + }); + } } - if ("BoxSet" !== item.Type && page.querySelector("#childrenCollapsible").classList.remove("hide"), scrollX ? (childrenItemsContainer.classList.add("scrollX"), childrenItemsContainer.classList.add("hiddenScrollX"), childrenItemsContainer.classList.remove("vertical-wrap"), childrenItemsContainer.classList.remove("vertical-list")) : (childrenItemsContainer.classList.remove("scrollX"), childrenItemsContainer.classList.remove("hiddenScrollX"), childrenItemsContainer.classList.remove("smoothScrollX"), isList ? (childrenItemsContainer.classList.add("vertical-list"), childrenItemsContainer.classList.remove("vertical-wrap")) : (childrenItemsContainer.classList.add("vertical-wrap"), childrenItemsContainer.classList.remove("vertical-list"))), childrenItemsContainer.innerHTML = html, imageLoader.lazyChildren(childrenItemsContainer), "BoxSet" == item.Type) { + + if ("BoxSet" !== item.Type) { + page.querySelector("#childrenCollapsible").classList.remove("hide"); + } + if (scrollX) { + childrenItemsContainer.classList.add("scrollX"); + childrenItemsContainer.classList.add("hiddenScrollX"); + childrenItemsContainer.classList.remove("vertical-wrap"); + childrenItemsContainer.classList.remove("vertical-list"); + } else { + childrenItemsContainer.classList.remove("scrollX"); + childrenItemsContainer.classList.remove("hiddenScrollX"); + childrenItemsContainer.classList.remove("smoothScrollX"); + if (isList) { + childrenItemsContainer.classList.add("vertical-list"); + childrenItemsContainer.classList.remove("vertical-wrap"); + } else { + childrenItemsContainer.classList.add("vertical-wrap"); + childrenItemsContainer.classList.remove("vertical-list"); + } + } + childrenItemsContainer.innerHTML = html; + imageLoader.lazyChildren(childrenItemsContainer); + if ("BoxSet" == item.Type) { var collectionItemTypes = [{ name: globalize.translate("HeaderVideos"), mediaType: "Video" @@ -838,175 +1498,276 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild name: globalize.translate("HeaderBooks"), type: "Book" }]; - renderCollectionItems(page, item, collectionItemTypes, result.Items) + renderCollectionItems(page, item, collectionItemTypes, result.Items); } - }), "Season" == item.Type ? page.querySelector("#childrenTitle").innerHTML = globalize.translate("HeaderEpisodes") : "Series" == item.Type ? page.querySelector("#childrenTitle").innerHTML = globalize.translate("HeaderSeasons") : "MusicAlbum" == item.Type ? page.querySelector("#childrenTitle").innerHTML = globalize.translate("HeaderTracks") : page.querySelector("#childrenTitle").innerHTML = globalize.translate("HeaderItems"), "MusicAlbum" == item.Type || "Season" == item.Type ? (page.querySelector(".childrenSectionHeader").classList.add("hide"), page.querySelector("#childrenCollapsible").classList.add("verticalSection-extrabottompadding")) : page.querySelector(".childrenSectionHeader").classList.remove("hide") + }); + + if ("Season" == item.Type) { + page.querySelector("#childrenTitle").innerHTML = globalize.translate("HeaderEpisodes"); + } else if ("Series" == item.Type) { + page.querySelector("#childrenTitle").innerHTML = globalize.translate("HeaderSeasons"); + } else if ("MusicAlbum" == item.Type) { + page.querySelector("#childrenTitle").innerHTML = globalize.translate("HeaderTracks"); + } else { + page.querySelector("#childrenTitle").innerHTML = globalize.translate("HeaderItems"); + } + + if ("MusicAlbum" == item.Type || "Season" == item.Type) { + page.querySelector(".childrenSectionHeader").classList.add("hide"); + page.querySelector("#childrenCollapsible").classList.add("verticalSection-extrabottompadding"); + } else { + page.querySelector(".childrenSectionHeader").classList.remove("hide"); + } } function renderItemsByName(page, item, user) { - require("scripts/itembynamedetailpage".split(","), function() { - window.ItemsByName.renderItems(page, item) - }) + require("scripts/itembynamedetailpage".split(","), function () { + window.ItemsByName.renderItems(page, item); + }); } function renderPlaylistItems(page, item, user) { - require("scripts/playlistedit".split(","), function() { - PlaylistViewer.render(page, item) - }) + require("scripts/playlistedit".split(","), function () { + PlaylistViewer.render(page, item); + }); } function renderProgramsForChannel(page, result) { - for (var html = "", currentItems = [], currentStartDate = null, i = 0, length = result.Items.length; i < length; i++) { - var item = result.Items[i], - itemStartDate = datetime.parseISO8601Date(item.StartDate); - currentStartDate && currentStartDate.toDateString() === itemStartDate.toDateString() || (currentItems.length && (html += '
            ', html += '

            ' + datetime.toLocaleDateString(currentStartDate, { + var html = ""; + var currentItems = []; + var currentStartDate = null; + + for (var i = 0, length = result.Items.length; i < length; i++) { + var item = result.Items[i]; + var itemStartDate = datetime.parseISO8601Date(item.StartDate); + + if (!(currentStartDate && currentStartDate.toDateString() === itemStartDate.toDateString())) { + if (currentItems.length) { + html += '
            '; + html += '

            ' + datetime.toLocaleDateString(currentStartDate, { + weekday: "long", + month: "long", + day: "numeric" + }) + "

            "; + html += '
            ' + listView.getListViewHtml({ + items: currentItems, + enableUserDataButtons: false, + showParentTitle: true, + image: false, + showProgramTime: true, + mediaInfo: false, + parentTitleWithTitle: true + }) + "
            "; + } + + currentStartDate = itemStartDate; + currentItems = []; + } + + currentItems.push(item); + } + + if (currentItems.length) { + html += '
            '; + html += '

            ' + datetime.toLocaleDateString(currentStartDate, { weekday: "long", month: "long", day: "numeric" - }) + "

            ", html += '
            ' + listView.getListViewHtml({ + }) + "

            "; + html += '
            ' + listView.getListViewHtml({ items: currentItems, - enableUserDataButtons: !1, - showParentTitle: !0, - image: !1, - showProgramTime: !0, - mediaInfo: !1, - parentTitleWithTitle: !0 - }) + "
            "), currentStartDate = itemStartDate, currentItems = []), currentItems.push(item) + enableUserDataButtons: false, + showParentTitle: true, + image: false, + showProgramTime: true, + mediaInfo: false, + parentTitleWithTitle: true + }) + "
            "; } - currentItems.length && (html += '
            ', html += '

            ' + datetime.toLocaleDateString(currentStartDate, { - weekday: "long", - month: "long", - day: "numeric" - }) + "

            ", html += '
            ' + listView.getListViewHtml({ - items: currentItems, - enableUserDataButtons: !1, - showParentTitle: !0, - image: !1, - showProgramTime: !0, - mediaInfo: !1, - parentTitleWithTitle: !0 - }) + "
            "), page.querySelector(".programGuide").innerHTML = html + + page.querySelector(".programGuide").innerHTML = html; } function renderChannelGuide(page, apiClient, item) { - "TvChannel" === item.Type && (page.querySelector(".programGuideSection").classList.remove("hide"), apiClient.getLiveTvPrograms({ - ChannelIds: item.Id, - UserId: apiClient.getCurrentUserId(), - HasAired: !1, - SortBy: "StartDate", - EnableTotalRecordCount: !1, - EnableImages: !1, - ImageTypeLimit: 0, - EnableUserData: !1 - }).then(function(result) { - renderProgramsForChannel(page, result) - })) + if ("TvChannel" === item.Type) { + page.querySelector(".programGuideSection").classList.remove("hide"); + apiClient.getLiveTvPrograms({ + ChannelIds: item.Id, + UserId: apiClient.getCurrentUserId(), + HasAired: false, + SortBy: "StartDate", + EnableTotalRecordCount: false, + EnableImages: false, + ImageTypeLimit: 0, + EnableUserData: false + }).then(function (result) { + renderProgramsForChannel(page, result); + }); + } } function renderSeriesSchedule(page, item, user) { var apiClient = connectionManager.getApiClient(item.ServerId); apiClient.getLiveTvPrograms({ UserId: apiClient.getCurrentUserId(), - HasAired: !1, + HasAired: false, SortBy: "StartDate", - EnableTotalRecordCount: !1, - EnableImages: !1, + EnableTotalRecordCount: false, + EnableImages: false, ImageTypeLimit: 0, Limit: 50, - EnableUserData: !1, + EnableUserData: false, LibrarySeriesId: item.Id - }).then(function(result) { - result.Items.length ? page.querySelector("#seriesScheduleSection").classList.remove("hide") : page.querySelector("#seriesScheduleSection").classList.add("hide"), page.querySelector("#seriesScheduleList").innerHTML = listView.getListViewHtml({ + }).then(function (result) { + if (result.Items.length) { + page.querySelector("#seriesScheduleSection").classList.remove("hide"); + } else { + page.querySelector("#seriesScheduleSection").classList.add("hide"); + } + + page.querySelector("#seriesScheduleList").innerHTML = listView.getListViewHtml({ items: result.Items, - enableUserDataButtons: !1, - showParentTitle: !1, - image: !1, - showProgramDateTime: !0, - mediaInfo: !1, - showTitle: !0, - moreButton: !1, + enableUserDataButtons: false, + showParentTitle: false, + image: false, + showProgramDateTime: true, + mediaInfo: false, + showTitle: true, + moreButton: false, action: "programdialog" - }), loading.hide() - }) + }); + loading.hide(); + }); } function inferContext(item) { - return "Movie" === item.Type || "BoxSet" === item.Type ? "movies" : "Series" === item.Type || "Season" === item.Type || "Episode" === item.Type ? "tvshows" : "MusicArtist" === item.Type || "MusicAlbum" === item.Type || "Audio" === item.Type || "AudioBook" === item.Type ? "music" : "Program" === item.Type ? "livetv" : null + if ("Movie" === item.Type || "BoxSet" === item.Type) { + return "movies"; + } + + if ("Series" === item.Type || "Season" === item.Type || "Episode" === item.Type) { + return "tvshows"; + } + + if ("MusicArtist" === item.Type || "MusicAlbum" === item.Type || "Audio" === item.Type || "AudioBook" === item.Type) { + return "music"; + } + + if ("Program" === item.Type) { + return "livetv"; + } + + return null; } function filterItemsByCollectionItemType(items, typeInfo) { - return items.filter(function(item) { - return typeInfo.mediaType ? item.MediaType == typeInfo.mediaType : item.Type == typeInfo.type - }) + return items.filter(function (item) { + if (typeInfo.mediaType) { + return item.MediaType == typeInfo.mediaType; + } + + return item.Type == typeInfo.type; + }); } function canPlaySomeItemInCollection(items) { var i = 0; + for (length = items.length; i < length; i++) { if (playbackManager.canPlay(items[i])) { return true; } } + return false; } function renderCollectionItems(page, parentItem, types, items) { page.querySelector(".collectionItems").innerHTML = ""; - var i, length; + var i; + var length; + for (i = 0, length = types.length; i < length; i++) { - var type = types[i], - typeItems = filterItemsByCollectionItemType(items, type); - typeItems.length && renderCollectionItemType(page, parentItem, type, typeItems) + var type = types[i]; + var typeItems = filterItemsByCollectionItemType(items, type); + + if (typeItems.length) { + renderCollectionItemType(page, parentItem, type, typeItems); + } } + var otherType = { - name: globalize.translate("HeaderOtherItems") - }, - otherTypeItems = items.filter(function(curr) { - return !types.filter(function(t) { - return filterItemsByCollectionItemType([curr], t).length > 0 - }).length - }); - otherTypeItems.length && renderCollectionItemType(page, parentItem, otherType, otherTypeItems), items.length || renderCollectionItemType(page, parentItem, { - name: globalize.translate("HeaderItems") - }, items); - var containers = page.querySelectorAll(".collectionItemsContainer"), - notifyRefreshNeeded = function() { - renderChildren(page, parentItem) - }; - for (i = 0, length = containers.length; i < length; i++) containers[i].notifyRefreshNeeded = notifyRefreshNeeded + name: globalize.translate("HeaderOtherItems") + }; + var otherTypeItems = items.filter(function (curr) { + return !types.filter(function (t) { + return filterItemsByCollectionItemType([curr], t).length > 0; + }).length; + }); + + if (otherTypeItems.length) { + renderCollectionItemType(page, parentItem, otherType, otherTypeItems); + } + + if (!items.length) { + renderCollectionItemType(page, parentItem, { + name: globalize.translate("HeaderItems") + }, items); + } + + var containers = page.querySelectorAll(".collectionItemsContainer"); + + var notifyRefreshNeeded = function () { + renderChildren(page, parentItem); + }; + + for (i = 0, length = containers.length; i < length; i++) { + containers[i].notifyRefreshNeeded = notifyRefreshNeeded; + } // if nothing in the collection can be played hide play and shuffle buttons if (!canPlaySomeItemInCollection(items)) { hideAll(page, "btnPlay", false); hideAll(page, "btnShuffle", false); - } + } } function renderCollectionItemType(page, parentItem, type, items) { var html = ""; - html += '
            ', html += '
            ', html += '

            ', html += "" + type.name + "", html += "

            ", html += '', html += "
            ", html += '
            '; - var shape = "MusicAlbum" == type.type ? getSquareShape(!1) : getPortraitShape(!1); + html += '
            '; + html += '
            '; + html += '

            '; + html += "" + type.name + ""; + html += "

            "; + html += ''; + html += "
            "; + html += '
            '; + var shape = "MusicAlbum" == type.type ? getSquareShape(false) : getPortraitShape(false); html += cardBuilder.getCardsHtml({ items: items, shape: shape, - showTitle: !0, - centerText: !0, - lazy: !0, - showDetailsMenu: !0, - overlayMoreButton: !0, - showAddToCollection: !1, - showRemoveFromCollection: !0, + showTitle: true, + centerText: true, + lazy: true, + showDetailsMenu: true, + overlayMoreButton: true, + showAddToCollection: false, + showRemoveFromCollection: true, collectionId: parentItem.Id - }), html += "
            ", html += "
            "; + }); + html += "
            "; + html += "
            "; var collectionItems = page.querySelector(".collectionItems"); - collectionItems.insertAdjacentHTML("beforeend", html), imageLoader.lazyChildren(collectionItems), collectionItems.querySelector(".btnAddToCollection").addEventListener("click", function() { - require(["alert"], function(alert) { + collectionItems.insertAdjacentHTML("beforeend", html); + imageLoader.lazyChildren(collectionItems); + collectionItems.querySelector(".btnAddToCollection").addEventListener("click", function () { + require(["alert"], function (alert) { alert({ text: globalize.translate("AddItemToCollectionHelp"), html: globalize.translate("AddItemToCollectionHelp") + '

            ' + globalize.translate("ButtonLearnMore") + "" - }) - }) - }) + }); + }); + }); } function renderMusicVideos(page, item, user) { @@ -1014,295 +1775,362 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild SortBy: "SortName", SortOrder: "Ascending", IncludeItemTypes: "MusicVideo", - Recursive: !0, + Recursive: true, Fields: "PrimaryImageAspectRatio,BasicSyncInfo,CanDelete,MediaSourceCount", AlbumIds: item.Id - }).then(function(result) { + }).then(function (result) { if (result.Items.length) { page.querySelector("#musicVideosCollapsible").classList.remove("hide"); var musicVideosContent = page.querySelector(".musicVideosContent"); - musicVideosContent.innerHTML = getVideosHtml(result.Items, user), imageLoader.lazyChildren(musicVideosContent) - } else page.querySelector("#musicVideosCollapsible").classList.add("hide") - }) + musicVideosContent.innerHTML = getVideosHtml(result.Items, user); + imageLoader.lazyChildren(musicVideosContent); + } else { + page.querySelector("#musicVideosCollapsible").classList.add("hide"); + } + }); } function renderAdditionalParts(page, item, user) { - connectionManager.getApiClient(item.ServerId).getAdditionalVideoParts(user.Id, item.Id).then(function(result) { + connectionManager.getApiClient(item.ServerId).getAdditionalVideoParts(user.Id, item.Id).then(function (result) { if (result.Items.length) { page.querySelector("#additionalPartsCollapsible").classList.remove("hide"); var additionalPartsContent = page.querySelector("#additionalPartsContent"); - additionalPartsContent.innerHTML = getVideosHtml(result.Items, user), imageLoader.lazyChildren(additionalPartsContent) - } else page.querySelector("#additionalPartsCollapsible").classList.add("hide") - }) + additionalPartsContent.innerHTML = getVideosHtml(result.Items, user); + imageLoader.lazyChildren(additionalPartsContent); + } else { + page.querySelector("#additionalPartsCollapsible").classList.add("hide"); + } + }); } function renderScenes(page, item) { var chapters = item.Chapters || []; + if (chapters.length && !chapters[0].ImageTag && (chapters = []), chapters.length) { page.querySelector("#scenesCollapsible").classList.remove("hide"); var scenesContent = page.querySelector("#scenesContent"); - require(["chaptercardbuilder"], function(chaptercardbuilder) { + + require(["chaptercardbuilder"], function (chaptercardbuilder) { chaptercardbuilder.buildChapterCards(item, chapters, { itemsContainer: scenesContent, width: 400, backdropShape: "overflowBackdrop", squareShape: "overflowSquare" - }) - }) - } else page.querySelector("#scenesCollapsible").classList.add("hide") + }); + }); + } else { + page.querySelector("#scenesCollapsible").classList.add("hide"); + } } function getVideosHtml(items, user, limit, moreButtonClass) { var html = cardBuilder.getCardsHtml({ items: items, shape: "auto", - showTitle: !0, + showTitle: true, action: "play", - overlayText: !1, - centerText: !0, - showRuntime: !0 + overlayText: false, + centerText: true, + showRuntime: true }); - return limit && items.length > limit && (html += '

            "), html + + if (limit && items.length > limit) { + html += '

            "; + } + + return html; } function renderSpecials(page, item, user, limit) { - connectionManager.getApiClient(item.ServerId).getSpecialFeatures(user.Id, item.Id).then(function(specials) { + connectionManager.getApiClient(item.ServerId).getSpecialFeatures(user.Id, item.Id).then(function (specials) { var specialsContent = page.querySelector("#specialsContent"); - specialsContent.innerHTML = getVideosHtml(specials, user, limit, "moreSpecials"), imageLoader.lazyChildren(specialsContent) - }) + specialsContent.innerHTML = getVideosHtml(specials, user, limit, "moreSpecials"); + imageLoader.lazyChildren(specialsContent); + }); } function renderCast(page, item, context, limit, isStatic) { - var people = (item.People || []).filter(function(p) { - return "Director" !== p.Type + var people = (item.People || []).filter(function (p) { + return "Director" !== p.Type; }); - if (!people.length) return void page.querySelector("#castCollapsible").classList.add("hide"); + + if (!people.length) { + return void page.querySelector("#castCollapsible").classList.add("hide"); + } + page.querySelector("#castCollapsible").classList.remove("hide"); var castContent = page.querySelector("#castContent"); - require(["peoplecardbuilder"], function(peoplecardbuilder) { + + require(["peoplecardbuilder"], function (peoplecardbuilder) { peoplecardbuilder.buildPeopleCards(people, { itemsContainer: castContent, - coverImage: !0, + coverImage: true, serverId: item.ServerId, width: 160, shape: getPortraitShape() - }) - }) + }); + }); } function itemDetailPage() { var self = this; - self.setInitialCollapsibleState = setInitialCollapsibleState, self.renderDetails = renderDetails, self.renderCast = renderCast + self.setInitialCollapsibleState = setInitialCollapsibleState; + self.renderDetails = renderDetails; + self.renderCast = renderCast; } function bindAll(view, selector, eventName, fn) { - var i, length, elems = view.querySelectorAll(selector); - for (i = 0, length = elems.length; i < length; i++) elems[i].addEventListener(eventName, fn) + var i; + var length; + var elems = view.querySelectorAll(selector); + + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener(eventName, fn); + } } function onTrackSelectionsSubmit(e) { - return e.preventDefault(), !1 + e.preventDefault(); + return false; } - return window.ItemDetailPage = new itemDetailPage, - function(view, params) { - function reload(instance, page, params) { - loading.show(); - var apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient, - promises = [getPromise(apiClient, params), apiClient.getCurrentUser()]; - Promise.all(promises).then(function(responses) { - var item = responses[0], - user = responses[1]; - currentItem = item, reloadFromItem(instance, page, params, item, user) - }) - } - function splitVersions(instance, page, apiClient, params) { - require(["confirm"], function(confirm) { - confirm("Are you sure you wish to split the media sources into separate items?", "Split Media Apart").then(function() { - loading.show(), apiClient.ajax({ - type: "DELETE", - url: apiClient.getUrl("Videos/" + params.id + "/AlternateSources") - }).then(function() { - loading.hide(), reload(instance, page, params) - }) - }) - }) - } + window.ItemDetailPage = new itemDetailPage(); + return function (view, params) { + function reload(instance, page, params) { + loading.show(); + var apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient; + var promises = [getPromise(apiClient, params), apiClient.getCurrentUser()]; + Promise.all(promises).then(function (responses) { + var item = responses[0]; + var user = responses[1]; + currentItem = item; + reloadFromItem(instance, page, params, item, user); + }); + } - function getPlayOptions(startPosition) { - var audioStreamIndex = view.querySelector(".selectAudio").value || null; - return { - startPositionTicks: startPosition, - mediaSourceId: view.querySelector(".selectSource").value, - audioStreamIndex: audioStreamIndex, - subtitleStreamIndex: view.querySelector(".selectSubtitles").value - } - } + function splitVersions(instance, page, apiClient, params) { + require(["confirm"], function (confirm) { + confirm("Are you sure you wish to split the media sources into separate items?", "Split Media Apart").then(function () { + loading.show(); + apiClient.ajax({ + type: "DELETE", + url: apiClient.getUrl("Videos/" + params.id + "/AlternateSources") + }).then(function () { + loading.hide(); + reload(instance, page, params); + }); + }); + }); + } - function playItem(item, startPosition) { - var playOptions = getPlayOptions(startPosition); - playOptions.items = [item], playbackManager.play(playOptions) - } + function getPlayOptions(startPosition) { + var audioStreamIndex = view.querySelector(".selectAudio").value || null; + return { + startPositionTicks: startPosition, + mediaSourceId: view.querySelector(".selectSource").value, + audioStreamIndex: audioStreamIndex, + subtitleStreamIndex: view.querySelector(".selectSubtitles").value + }; + } - function playTrailer(page) { - playbackManager.playTrailers(currentItem) - } + function playItem(item, startPosition) { + var playOptions = getPlayOptions(startPosition); + playOptions.items = [item]; + playbackManager.play(playOptions); + } - function playCurrentItem(button, mode) { - var item = currentItem; - if ("Program" === item.Type) { - var apiClient = connectionManager.getApiClient(item.ServerId); - return void apiClient.getLiveTvChannel(item.ChannelId, apiClient.getCurrentUserId()).then(function(channel) { - playbackManager.play({ - items: [channel] - }) - }) - } - playItem(item, item.UserData && "resume" === mode ? item.UserData.PlaybackPositionTicks : 0) - } + function playTrailer(page) { + playbackManager.playTrailers(currentItem); + } - function onPlayClick() { - playCurrentItem(this, this.getAttribute("data-mode")) - } + function playCurrentItem(button, mode) { + var item = currentItem; - function onInstantMixClick() { - playbackManager.instantMix(currentItem) - } - - function onShuffleClick() { - playbackManager.shuffle(currentItem) - } - - function onDeleteClick() { - require(["deleteHelper"], function(deleteHelper) { - deleteHelper.deleteItem({ - item: currentItem, - navigate: !0 - }) - }) - } - - function onCancelSeriesTimerClick() { - require(["recordingHelper"], function(recordingHelper) { - recordingHelper.cancelSeriesTimerWithConfirmation(currentItem.Id, currentItem.ServerId).then(function() { - Dashboard.navigate("livetv.html") - }) - }) - } - - function onCancelTimerClick() { - require(["recordingHelper"], function(recordingHelper) { - recordingHelper.cancelTimer(connectionManager.getApiClient(currentItem.ServerId), currentItem.TimerId).then(function() { - reload(self, view, params) - }) - }) - } - - function onPlayTrailerClick() { - playTrailer(view) - } - - function onDownloadChange() { - reload(self, view, params) - } - - function onDownloadClick() { - require(['fileDownloader'], function (fileDownloader) { - var downloadHref = apiClient.getItemDownloadUrl(currentItem.Id); - fileDownloader.download([{ - url: downloadHref, - itemId: currentItem.Id, - serverId: currentItem.serverId - }]); + if ("Program" === item.Type) { + var apiClient = connectionManager.getApiClient(item.ServerId); + return void apiClient.getLiveTvChannel(item.ChannelId, apiClient.getCurrentUserId()).then(function (channel) { + playbackManager.play({ + items: [channel] + }); }); } - function onMoreCommandsClick() { - var button = this; - apiClient.getCurrentUser().then(function(user) { - itemContextMenu.show(getContextMenuOptions(currentItem, user, button)).then(function(result) { - result.deleted ? appRouter.goHome() : result.updated && reload(self, view, params) - }) - }) - } + playItem(item, item.UserData && "resume" === mode ? item.UserData.PlaybackPositionTicks : 0); + } - function onPlayerChange() { - renderTrackSelections(view, self, currentItem), setTrailerButtonVisibility(view, currentItem) - } + function onPlayClick() { + playCurrentItem(this, this.getAttribute("data-mode")); + } - function editImages() { - return new Promise(function(resolve, reject) { - require(["imageEditor"], function(imageEditor) { - imageEditor.show({ - itemId: currentItem.Id, - serverId: currentItem.ServerId - }).then(resolve, reject) - }) - }) - } + function onInstantMixClick() { + playbackManager.instantMix(currentItem); + } - function onWebSocketMessage(e, data) { - var msg = data; - if ("UserDataChanged" === msg.MessageType && currentItem && msg.Data.UserId == apiClient.getCurrentUserId()) { - var key = currentItem.UserData.Key, - userData = msg.Data.UserDataList.filter(function(u) { - return u.Key == key - })[0]; - userData && (currentItem.UserData = userData, reloadPlayButtons(view, currentItem), apiClient.getCurrentUser().then(function(user) { - refreshImage(view, currentItem, user) - })) + function onShuffleClick() { + playbackManager.shuffle(currentItem); + } + + function onDeleteClick() { + require(["deleteHelper"], function (deleteHelper) { + deleteHelper.deleteItem({ + item: currentItem, + navigate: true + }); + }); + } + + function onCancelSeriesTimerClick() { + require(["recordingHelper"], function (recordingHelper) { + recordingHelper.cancelSeriesTimerWithConfirmation(currentItem.Id, currentItem.ServerId).then(function () { + Dashboard.navigate("livetv.html"); + }); + }); + } + + function onCancelTimerClick() { + require(["recordingHelper"], function (recordingHelper) { + recordingHelper.cancelTimer(connectionManager.getApiClient(currentItem.ServerId), currentItem.TimerId).then(function () { + reload(self, view, params); + }); + }); + } + + function onPlayTrailerClick() { + playTrailer(view); + } + + function onDownloadChange() { + reload(self, view, params); + } + + function onDownloadClick() { + require(['fileDownloader'], function (fileDownloader) { + var downloadHref = apiClient.getItemDownloadUrl(currentItem.Id); + fileDownloader.download([{ + url: downloadHref, + itemId: currentItem.Id, + serverId: currentItem.serverId + }]); + }); + } + + function onMoreCommandsClick() { + var button = this; + apiClient.getCurrentUser().then(function (user) { + itemContextMenu.show(getContextMenuOptions(currentItem, user, button)).then(function (result) { + if (result.deleted) { + appRouter.goHome(); + } else if (result.updated) { + reload(self, view, params); + } + }); + }); + } + + function onPlayerChange() { + renderTrackSelections(view, self, currentItem); + setTrailerButtonVisibility(view, currentItem); + } + + function editImages() { + return new Promise(function (resolve, reject) { + require(["imageEditor"], function (imageEditor) { + imageEditor.show({ + itemId: currentItem.Id, + serverId: currentItem.ServerId + }).then(resolve, reject); + }); + }); + } + + function onWebSocketMessage(e, data) { + var msg = data; + + if ("UserDataChanged" === msg.MessageType && currentItem && msg.Data.UserId == apiClient.getCurrentUserId()) { + var key = currentItem.UserData.Key; + var userData = msg.Data.UserDataList.filter(function (u) { + return u.Key == key; + })[0]; + + if (userData) { + currentItem.UserData = userData; + reloadPlayButtons(view, currentItem); + apiClient.getCurrentUser().then(function (user) { + refreshImage(view, currentItem, user); + }); } } - - var currentItem; - var self = this; - var apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient; - view.querySelectorAll(".btnPlay"); - bindAll(view, ".btnPlay", "click", onPlayClick); - bindAll(view, ".btnResume", "click", onPlayClick); - bindAll(view, ".btnInstantMix", "click", onInstantMixClick); - bindAll(view, ".btnShuffle", "click", onShuffleClick); - bindAll(view, ".btnPlayTrailer", "click", onPlayTrailerClick); - bindAll(view, ".btnCancelSeriesTimer", "click", onCancelSeriesTimerClick); - bindAll(view, ".btnCancelTimer", "click", onCancelTimerClick); - bindAll(view, ".btnDeleteItem", "click", onDeleteClick); - bindAll(view, ".btnDownload", "click", onDownloadClick); - view.querySelector(".btnMoreCommands i").innerHTML = ""; - view.querySelector(".trackSelections").addEventListener("submit", onTrackSelectionsSubmit); - view.querySelector(".btnSplitVersions").addEventListener("click", function() { - splitVersions(self, view, apiClient, params) - }); - bindAll(view, ".btnMoreCommands", "click", onMoreCommandsClick); - view.querySelector(".selectSource").addEventListener("change", function() { - renderVideoSelections(view, self._currentPlaybackMediaSources); - renderAudioSelections(view, self._currentPlaybackMediaSources); - renderSubtitleSelections(view, self._currentPlaybackMediaSources); - }); - view.addEventListener("click", function(e) { - dom.parentWithClass(e.target, "moreScenes") ? apiClient.getCurrentUser().then(function(user) { - renderScenes(view, currentItem) - }) : dom.parentWithClass(e.target, "morePeople") ? renderCast(view, currentItem, params.context) : dom.parentWithClass(e.target, "moreSpecials") && apiClient.getCurrentUser().then(function(user) { - renderSpecials(view, currentItem, user) - }) - }); - view.querySelector(".detailImageContainer").addEventListener("click", function(e) { - dom.parentWithClass(e.target, "itemDetailGalleryLink") && editImages().then(function() { - reload(self, view, params) - }) - }); - view.addEventListener("viewshow", function(e) { - var page = this; - libraryMenu.setTransparentMenu(!0), e.detail.isRestored ? currentItem && (setTitle(currentItem, connectionManager.getApiClient(currentItem.ServerId)), renderTrackSelections(page, self, currentItem, !0)) : reload(self, page, params), events.on(apiClient, "message", onWebSocketMessage), events.on(playbackManager, "playerchange", onPlayerChange) - }); - view.addEventListener("viewbeforehide", function() { - events.off(apiClient, "message", onWebSocketMessage); - events.off(playbackManager, "playerchange", onPlayerChange); - libraryMenu.setTransparentMenu(false); - }); - view.addEventListener("viewdestroy", function() { - currentItem = null; - self._currentPlaybackMediaSources = null; - self.currentRecordingFields = null; - }) } + + var currentItem; + var self = this; + var apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient; + view.querySelectorAll(".btnPlay"); + bindAll(view, ".btnPlay", "click", onPlayClick); + bindAll(view, ".btnResume", "click", onPlayClick); + bindAll(view, ".btnInstantMix", "click", onInstantMixClick); + bindAll(view, ".btnShuffle", "click", onShuffleClick); + bindAll(view, ".btnPlayTrailer", "click", onPlayTrailerClick); + bindAll(view, ".btnCancelSeriesTimer", "click", onCancelSeriesTimerClick); + bindAll(view, ".btnCancelTimer", "click", onCancelTimerClick); + bindAll(view, ".btnDeleteItem", "click", onDeleteClick); + bindAll(view, ".btnDownload", "click", onDownloadClick); + view.querySelector(".btnMoreCommands i").innerHTML = ""; + view.querySelector(".trackSelections").addEventListener("submit", onTrackSelectionsSubmit); + view.querySelector(".btnSplitVersions").addEventListener("click", function () { + splitVersions(self, view, apiClient, params); + }); + bindAll(view, ".btnMoreCommands", "click", onMoreCommandsClick); + view.querySelector(".selectSource").addEventListener("change", function () { + renderVideoSelections(view, self._currentPlaybackMediaSources); + renderAudioSelections(view, self._currentPlaybackMediaSources); + renderSubtitleSelections(view, self._currentPlaybackMediaSources); + }); + view.addEventListener("click", function (e) { + if (dom.parentWithClass(e.target, "moreScenes")) { + apiClient.getCurrentUser().then(function (user) { + renderScenes(view, currentItem); + }); + } else if (dom.parentWithClass(e.target, "morePeople")) { + renderCast(view, currentItem, params.context); + } else if (dom.parentWithClass(e.target, "moreSpecials")) { + apiClient.getCurrentUser().then(function (user) { + renderSpecials(view, currentItem, user); + }); + } + }); + view.querySelector(".detailImageContainer").addEventListener("click", function (e) { + if (dom.parentWithClass(e.target, "itemDetailGalleryLink")) { + editImages().then(function () { + reload(self, view, params); + }); + } + }); + view.addEventListener("viewshow", function (e) { + var page = this; + libraryMenu.setTransparentMenu(true); + + if (e.detail.isRestored) { + if (currentItem) { + setTitle(currentItem, connectionManager.getApiClient(currentItem.ServerId)); + renderTrackSelections(page, self, currentItem, true); + } + } else { + reload(self, page, params); + } + + events.on(apiClient, "message", onWebSocketMessage); + events.on(playbackManager, "playerchange", onPlayerChange); + }); + view.addEventListener("viewbeforehide", function () { + events.off(apiClient, "message", onWebSocketMessage); + events.off(playbackManager, "playerchange", onPlayerChange); + libraryMenu.setTransparentMenu(false); + }); + view.addEventListener("viewdestroy", function () { + currentItem = null; + self._currentPlaybackMediaSources = null; + self.currentRecordingFields = null; + }); + }; }); diff --git a/src/controllers/list.js b/src/controllers/list.js index aac1818592..d15ebd2444 100644 --- a/src/controllers/list.js +++ b/src/controllers/list.js @@ -1,4 +1,4 @@ -define(["globalize", "listView", "layoutManager", "userSettings", "focusManager", "cardBuilder", "loading", "connectionManager", "alphaNumericShortcuts", "scroller", "playbackManager", "alphaPicker", "emby-itemscontainer", "emby-scroller"], function(globalize, listView, layoutManager, userSettings, focusManager, cardBuilder, loading, connectionManager, AlphaNumericShortcuts, scroller, playbackManager, alphaPicker) { +define(["globalize", "listView", "layoutManager", "userSettings", "focusManager", "cardBuilder", "loading", "connectionManager", "alphaNumericShortcuts", "scroller", "playbackManager", "alphaPicker", "emby-itemscontainer", "emby-scroller"], function (globalize, listView, layoutManager, userSettings, focusManager, cardBuilder, loading, connectionManager, AlphaNumericShortcuts, scroller, playbackManager, alphaPicker) { "use strict"; function getInitialLiveTvQuery(instance, params) { @@ -8,83 +8,303 @@ define(["globalize", "listView", "layoutManager", "userSettings", "focusManager" Fields: "ChannelInfo,PrimaryImageAspectRatio", Limit: 300 }; - return "Recordings" === params.type ? query.IsInProgress = !1 : query.HasAired = !1, params.genreId && (query.GenreIds = params.genreId), "true" === params.IsMovie ? query.IsMovie = !0 : "false" === params.IsMovie && (query.IsMovie = !1), "true" === params.IsSeries ? query.IsSeries = !0 : "false" === params.IsSeries && (query.IsSeries = !1), "true" === params.IsNews ? query.IsNews = !0 : "false" === params.IsNews && (query.IsNews = !1), "true" === params.IsSports ? query.IsSports = !0 : "false" === params.IsSports && (query.IsSports = !1), "true" === params.IsKids ? query.IsKids = !0 : "false" === params.IsKids && (query.IsKids = !1), "true" === params.IsAiring ? query.IsAiring = !0 : "false" === params.IsAiring && (query.IsAiring = !1), modifyQueryWithFilters(instance, query) + + if ("Recordings" === params.type) { + query.IsInProgress = false; + } else { + query.HasAired = false; + } + + if (params.genreId) { + query.GenreIds = params.genreId; + } + + if ("true" === params.IsMovie) { + query.IsMovie = true; + } else if ("false" === params.IsMovie) { + query.IsMovie = false; + } + + if ("true" === params.IsSeries) { + query.IsSeries = true; + } else if ("false" === params.IsSeries) { + query.IsSeries = false; + } + + if ("true" === params.IsNews) { + query.IsNews = true; + } else if ("false" === params.IsNews) { + query.IsNews = false; + } + + if ("true" === params.IsSports) { + query.IsSports = true; + } else if ("false" === params.IsSports) { + query.IsSports = false; + } + + if ("true" === params.IsKids) { + query.IsKids = true; + } else if ("false" === params.IsKids) { + query.IsKids = false; + } + + if ("true" === params.IsAiring) { + query.IsAiring = true; + } else if ("false" === params.IsAiring) { + query.IsAiring = false; + } + + return modifyQueryWithFilters(instance, query); } function modifyQueryWithFilters(instance, query) { var sortValues = instance.getSortValues(); - query.SortBy || (query.SortBy = sortValues.sortBy, query.SortOrder = sortValues.sortOrder), query.Fields = query.Fields ? query.Fields + ",PrimaryImageAspectRatio" : "PrimaryImageAspectRatio", query.ImageTypeLimit = 1; - var hasFilters, queryFilters = [], - filters = instance.getFilters(); - return filters.IsPlayed && (queryFilters.push("IsPlayed"), hasFilters = !0), filters.IsUnplayed && (queryFilters.push("IsUnplayed"), hasFilters = !0), filters.IsFavorite && (queryFilters.push("IsFavorite"), hasFilters = !0), filters.IsResumable && (queryFilters.push("IsResumable"), hasFilters = !0), filters.VideoTypes && (hasFilters = !0, query.VideoTypes = filters.VideoTypes), filters.GenreIds && (hasFilters = !0, query.GenreIds = filters.GenreIds), filters.Is4K && (query.Is4K = !0, hasFilters = !0), filters.IsHD && (query.IsHD = !0, hasFilters = !0), filters.IsSD && (query.IsHD = !1, hasFilters = !0), filters.Is3D && (query.Is3D = !0, hasFilters = !0), filters.HasSubtitles && (query.HasSubtitles = !0, hasFilters = !0), filters.HasTrailer && (query.HasTrailer = !0, hasFilters = !0), filters.HasSpecialFeature && (query.HasSpecialFeature = !0, hasFilters = !0), filters.HasThemeSong && (query.HasThemeSong = !0, hasFilters = !0), filters.HasThemeVideo && (query.HasThemeVideo = !0, hasFilters = !0), query.Filters = queryFilters.length ? queryFilters.join(",") : null, instance.setFilterStatus(hasFilters), instance.alphaPicker && (query.NameStartsWithOrGreater = instance.alphaPicker.value()), query + + if (!query.SortBy) { + query.SortBy = sortValues.sortBy; + query.SortOrder = sortValues.sortOrder; + } + + query.Fields = query.Fields ? query.Fields + ",PrimaryImageAspectRatio" : "PrimaryImageAspectRatio"; + query.ImageTypeLimit = 1; + var hasFilters; + var queryFilters = []; + var filters = instance.getFilters(); + + if (filters.IsPlayed) { + queryFilters.push("IsPlayed"); + hasFilters = true; + } + + if (filters.IsUnplayed) { + queryFilters.push("IsUnplayed"); + hasFilters = true; + } + + if (filters.IsFavorite) { + queryFilters.push("IsFavorite"); + hasFilters = true; + } + + if (filters.IsResumable) { + queryFilters.push("IsResumable"); + hasFilters = true; + } + + if (filters.VideoTypes) { + hasFilters = true; + query.VideoTypes = filters.VideoTypes; + } + + if (filters.GenreIds) { + hasFilters = true; + query.GenreIds = filters.GenreIds; + } + + if (filters.Is4K) { + query.Is4K = true; + hasFilters = true; + } + + if (filters.IsHD) { + query.IsHD = true; + hasFilters = true; + } + + if (filters.IsSD) { + query.IsHD = false; + hasFilters = true; + } + + if (filters.Is3D) { + query.Is3D = true; + hasFilters = true; + } + + if (filters.HasSubtitles) { + query.HasSubtitles = true; + hasFilters = true; + } + + if (filters.HasTrailer) { + query.HasTrailer = true; + hasFilters = true; + } + + if (filters.HasSpecialFeature) { + query.HasSpecialFeature = true; + hasFilters = true; + } + + if (filters.HasThemeSong) { + query.HasThemeSong = true; + hasFilters = true; + } + + if (filters.HasThemeVideo) { + query.HasThemeVideo = true; + hasFilters = true; + } + + query.Filters = queryFilters.length ? queryFilters.join(",") : null; + instance.setFilterStatus(hasFilters); + + if (instance.alphaPicker) { + query.NameStartsWithOrGreater = instance.alphaPicker.value(); + } + + return query; } function updateSortText(instance) { var btnSortText = instance.btnSortText; + if (btnSortText) { - for (var options = instance.getSortMenuOptions(), values = instance.getSortValues(), sortBy = values.sortBy, i = 0, length = options.length; i < length; i++) + var options = instance.getSortMenuOptions(); + var values = instance.getSortValues(); + var sortBy = values.sortBy; + + for (var i = 0, length = options.length; i < length; i++) { if (sortBy === options[i].value) { btnSortText.innerHTML = globalize.translate("SortByValue", options[i].name); - break - } var btnSortIcon = instance.btnSortIcon; - btnSortIcon && (btnSortIcon.innerHTML = "Descending" === values.sortOrder ? "" : "") + break; + } + } + + var btnSortIcon = instance.btnSortIcon; + + if (btnSortIcon) { + btnSortIcon.innerHTML = "Descending" === values.sortOrder ? "" : ""; + } } } function updateItemsContainerForViewType(instance) { - "list" === instance.getViewSettings().imageType ? (instance.itemsContainer.classList.remove("vertical-wrap"), instance.itemsContainer.classList.add("vertical-list")) : (instance.itemsContainer.classList.add("vertical-wrap"), instance.itemsContainer.classList.remove("vertical-list")) + if ("list" === instance.getViewSettings().imageType) { + instance.itemsContainer.classList.remove("vertical-wrap"); + instance.itemsContainer.classList.add("vertical-list"); + } else { + instance.itemsContainer.classList.add("vertical-wrap"); + instance.itemsContainer.classList.remove("vertical-list"); + } } function updateAlphaPickerState(instance, numItems) { if (instance.alphaPicker) { var alphaPicker = instance.alphaPickerElement; + if (alphaPicker) { var values = instance.getSortValues(); - null == numItems && (numItems = 100), "SortName" === values.sortBy && "Ascending" === values.sortOrder && numItems > 40 ? (alphaPicker.classList.remove("hide"), layoutManager.tv ? instance.itemsContainer.parentNode.classList.add("padded-left-withalphapicker") : instance.itemsContainer.parentNode.classList.add("padded-right-withalphapicker")) : (alphaPicker.classList.add("hide"), instance.itemsContainer.parentNode.classList.remove("padded-left-withalphapicker"), instance.itemsContainer.parentNode.classList.remove("padded-right-withalphapicker")) + + if (null == numItems) { + numItems = 100; + } + + if ("SortName" === values.sortBy && "Ascending" === values.sortOrder && numItems > 40) { + alphaPicker.classList.remove("hide"); + + if (layoutManager.tv) { + instance.itemsContainer.parentNode.classList.add("padded-left-withalphapicker"); + } else { + instance.itemsContainer.parentNode.classList.add("padded-right-withalphapicker"); + } + } else { + alphaPicker.classList.add("hide"); + instance.itemsContainer.parentNode.classList.remove("padded-left-withalphapicker"); + instance.itemsContainer.parentNode.classList.remove("padded-right-withalphapicker"); + } } } } function getItems(instance, params, item, sortBy, startIndex, limit) { var apiClient = connectionManager.getApiClient(params.serverId); - if (instance.queryRecursive = !1, "Recordings" === params.type) return apiClient.getLiveTvRecordings(getInitialLiveTvQuery(instance, params)); - if ("Programs" === params.type) return "true" === params.IsAiring ? apiClient.getLiveTvRecommendedPrograms(getInitialLiveTvQuery(instance, params)) : apiClient.getLiveTvPrograms(getInitialLiveTvQuery(instance, params)); - if ("nextup" === params.type) return apiClient.getNextUpEpisodes(modifyQueryWithFilters(instance, { - Limit: limit, - Fields: "PrimaryImageAspectRatio,SeriesInfo,DateCreated,BasicSyncInfo", - UserId: apiClient.getCurrentUserId(), - ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Thumb", - EnableTotalRecordCount: !1, - SortBy: sortBy - })); + + instance.queryRecursive = false; + if ("Recordings" === params.type) { + return apiClient.getLiveTvRecordings(getInitialLiveTvQuery(instance, params)); + } + + if ("Programs" === params.type) { + if ("true" === params.IsAiring) { + return apiClient.getLiveTvRecommendedPrograms(getInitialLiveTvQuery(instance, params)); + } + + return apiClient.getLiveTvPrograms(getInitialLiveTvQuery(instance, params)); + } + + if ("nextup" === params.type) { + return apiClient.getNextUpEpisodes(modifyQueryWithFilters(instance, { + Limit: limit, + Fields: "PrimaryImageAspectRatio,SeriesInfo,DateCreated,BasicSyncInfo", + UserId: apiClient.getCurrentUserId(), + ImageTypeLimit: 1, + EnableImageTypes: "Primary,Backdrop,Thumb", + EnableTotalRecordCount: false, + SortBy: sortBy + })); + } + if (!item) { - instance.queryRecursive = !0; + instance.queryRecursive = true; var method = "getItems"; - return "MusicArtist" === params.type ? method = "getArtists" : "Person" === params.type && (method = "getPeople"), apiClient[method](apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, { + + if ("MusicArtist" === params.type) { + method = "getArtists"; + } else if ("Person" === params.type) { + method = "getPeople"; + } + + return apiClient[method](apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, { StartIndex: startIndex, Limit: limit, Fields: "PrimaryImageAspectRatio,SortName", ImageTypeLimit: 1, IncludeItemTypes: "MusicArtist" === params.type || "Person" === params.type ? null : params.type, - Recursive: !0, + Recursive: true, IsFavorite: "true" === params.IsFavorite || null, ArtistIds: params.artistId || null, SortBy: sortBy - })) + })); } + if ("Genre" === item.Type || "MusicGenre" === item.Type || "Studio" === item.Type || "Person" === item.Type) { - instance.queryRecursive = !0; + instance.queryRecursive = true; var query = { StartIndex: startIndex, Limit: limit, Fields: "PrimaryImageAspectRatio,SortName", - Recursive: !0, + Recursive: true, parentId: params.parentId, SortBy: sortBy }; - return "Studio" === item.Type ? query.StudioIds = item.Id : "Genre" === item.Type || "MusicGenre" === item.Type ? query.GenreIds = item.Id : "Person" === item.Type && (query.PersonIds = item.Id), "MusicGenre" === item.Type ? query.IncludeItemTypes = "MusicAlbum" : "GameGenre" === item.Type ? query.IncludeItemTypes = "Game" : "movies" === item.CollectionType ? query.IncludeItemTypes = "Movie" : "tvshows" === item.CollectionType ? query.IncludeItemTypes = "Series" : "Genre" === item.Type ? query.IncludeItemTypes = "Movie,Series,Video" : "Person" === item.Type && (query.IncludeItemTypes = params.type), apiClient.getItems(apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, query)) + + if ("Studio" === item.Type) { + query.StudioIds = item.Id; + } else if ("Genre" === item.Type || "MusicGenre" === item.Type) { + query.GenreIds = item.Id; + } else if ("Person" === item.Type) { + query.PersonIds = item.Id; + } + + if ("MusicGenre" === item.Type) { + query.IncludeItemTypes = "MusicAlbum"; + } else if ("GameGenre" === item.Type) { + query.IncludeItemTypes = "Game"; + } else if ("movies" === item.CollectionType) { + query.IncludeItemTypes = "Movie"; + } else if ("tvshows" === item.CollectionType) { + query.IncludeItemTypes = "Series"; + } else if ("Genre" === item.Type) { + query.IncludeItemTypes = "Movie,Series,Video"; + } else if ("Person" === item.Type) { + query.IncludeItemTypes = params.type; + } + + return apiClient.getItems(apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, query)); } + return apiClient.getItems(apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, { StartIndex: startIndex, Limit: limit, @@ -92,35 +312,44 @@ define(["globalize", "listView", "layoutManager", "userSettings", "focusManager" ImageTypeLimit: 1, ParentId: item.Id, SortBy: sortBy - })) + })); } function getItem(params) { - if ("Recordings" === params.type) return Promise.resolve(null); - if ("Programs" === params.type) return Promise.resolve(null); - if ("nextup" === params.type) return Promise.resolve(null); - var apiClient = connectionManager.getApiClient(params.serverId), - itemId = params.genreId || params.musicGenreId || params.studioId || params.personId || params.parentId; - return itemId ? apiClient.getItem(apiClient.getCurrentUserId(), itemId) : Promise.resolve(null) + if ("Recordings" === params.type || "Programs" === params.type || "nextup" === params.type) { + return Promise.resolve(null); + } + + var apiClient = connectionManager.getApiClient(params.serverId); + var itemId = params.genreId || params.musicGenreId || params.studioId || params.personId || params.parentId; + + if (itemId) { + return apiClient.getItem(apiClient.getCurrentUserId(), itemId); + } + + return Promise.resolve(null); } function showViewSettingsMenu() { var instance = this; - require(["viewSettings"], function(ViewSettings) { - (new ViewSettings).show({ + + require(["viewSettings"], function (ViewSettings) { + new ViewSettings().show({ settingsKey: instance.getSettingsKey(), settings: instance.getViewSettings(), visibleSettings: instance.getVisibleViewSettings() - }).then(function() { - updateItemsContainerForViewType(instance), instance.itemsContainer.refreshItems() - }) - }) + }).then(function () { + updateItemsContainerForViewType(instance); + instance.itemsContainer.refreshItems(); + }); + }); } function showFilterMenu() { var instance = this; - require(["filterMenu"], function(FilterMenu) { - (new FilterMenu).show({ + + require(["filterMenu"], function (FilterMenu) { + new FilterMenu().show({ settingsKey: instance.getSettingsKey(), settings: instance.getFilters(), visibleSettings: instance.getVisibleFilters(), @@ -129,201 +358,497 @@ define(["globalize", "listView", "layoutManager", "userSettings", "focusManager" itemTypes: instance.getItemTypes(), serverId: instance.params.serverId, filterMenuOptions: instance.getFilterMenuOptions() - }).then(function() { - instance.itemsContainer.refreshItems() - }) - }) + }).then(function () { + instance.itemsContainer.refreshItems(); + }); + }); } function showSortMenu() { var instance = this; - require(["sortMenu"], function(SortMenu) { - (new SortMenu).show({ + + require(["sortMenu"], function (SortMenu) { + new SortMenu().show({ settingsKey: instance.getSettingsKey(), settings: instance.getSortValues(), onChange: instance.itemsContainer.refreshItems.bind(instance.itemsContainer), serverId: instance.params.serverId, sortOptions: instance.getSortMenuOptions() - }).then(function() { - updateSortText(instance), updateAlphaPickerState(instance), instance.itemsContainer.refreshItems() - }) - }) + }).then(function () { + updateSortText(instance); + updateAlphaPickerState(instance); + instance.itemsContainer.refreshItems(); + }); + }); } function onNewItemClick() { var instance = this; - require(["playlistEditor"], function(playlistEditor) { - (new playlistEditor).show({ + + require(["playlistEditor"], function (playlistEditor) { + new playlistEditor().show({ items: [], serverId: instance.params.serverId - }) - }) + }); + }); } function hideOrShowAll(elems, hide) { - for (var i = 0, length = elems.length; i < length; i++) hide ? elems[i].classList.add("hide") : elems[i].classList.remove("hide") + for (var i = 0, length = elems.length; i < length; i++) { + if (hide) { + elems[i].classList.add("hide"); + } else { + elems[i].classList.remove("hide"); + } + } } function bindAll(elems, eventName, fn) { - for (var i = 0, length = elems.length; i < length; i++) elems[i].addEventListener(eventName, fn) + for (var i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener(eventName, fn); + } } function ItemsView(view, params) { function fetchData() { - return getItems(self, params, self.currentItem).then(function(result) { - return null == self.totalItemCount && (self.totalItemCount = result.Items ? result.Items.length : result.length), updateAlphaPickerState(self, self.totalItemCount), result - }) + return getItems(self, params, self.currentItem).then(function (result) { + if (null == self.totalItemCount) { + self.totalItemCount = result.Items ? result.Items.length : result.length; + } + + updateAlphaPickerState(self, self.totalItemCount); + return result; + }); } function getItemsHtml(items) { var settings = self.getViewSettings(); - if ("list" === settings.imageType) return listView.getListViewHtml({ - items: items - }); - var shape, preferThumb, preferDisc, preferLogo, defaultShape, item = self.currentItem, - lines = settings.showTitle ? 2 : 0; - "banner" === settings.imageType ? shape = "banner" : "disc" === settings.imageType ? (shape = "square", preferDisc = !0) : "logo" === settings.imageType ? (shape = "backdrop", preferLogo = !0) : "thumb" === settings.imageType ? (shape = "backdrop", preferThumb = !0) : "nextup" === params.type ? (shape = "backdrop", preferThumb = "thumb" === settings.imageType) : "Programs" === params.type || "Recordings" === params.type ? (shape = "true" === params.IsMovie ? "portrait" : "autoVertical", preferThumb = "true" !== params.IsMovie && "auto", defaultShape = "true" === params.IsMovie ? "portrait" : "backdrop") : shape = "autoVertical"; + + if ("list" === settings.imageType) { + return listView.getListViewHtml({ + items: items + }); + } + + var shape; + var preferThumb; + var preferDisc; + var preferLogo; + var defaultShape; + var item = self.currentItem; + var lines = settings.showTitle ? 2 : 0; + + if ("banner" === settings.imageType) { + shape = "banner"; + } else if ("disc" === settings.imageType) { + shape = "square"; + preferDisc = true; + } else if ("logo" === settings.imageType) { + shape = "backdrop"; + preferLogo = true; + } else if ("thumb" === settings.imageType) { + shape = "backdrop"; + preferThumb = true; + } else if ("nextup" === params.type) { + shape = "backdrop"; + preferThumb = "thumb" === settings.imageType; + } else if ("Programs" === params.type || "Recordings" === params.type) { + shape = "true" === params.IsMovie ? "portrait" : "autoVertical"; + preferThumb = "true" !== params.IsMovie ? "auto" : false; + defaultShape = "true" === params.IsMovie ? "portrait" : "backdrop"; + } else { + shape = "autoVertical"; + } + var posterOptions = { shape: shape, showTitle: settings.showTitle, showYear: settings.showTitle, - centerText: !0, - coverImage: !0, + centerText: true, + coverImage: true, preferThumb: preferThumb, preferDisc: preferDisc, preferLogo: preferLogo, - overlayPlayButton: !1, - overlayMoreButton: !0, + overlayPlayButton: false, + overlayMoreButton: true, overlayText: !settings.showTitle, defaultShape: defaultShape, action: "Audio" === params.type ? "playallfromhere" : null }; - if ("nextup" === params.type) posterOptions.showParentTitle = settings.showTitle; - else if ("Person" === params.type) posterOptions.showYear = !1, posterOptions.showParentTitle = !1, lines = 1; - else if ("Audio" === params.type) posterOptions.showParentTitle = settings.showTitle; - else if ("MusicAlbum" === params.type) posterOptions.showParentTitle = settings.showTitle; - else if ("Episode" === params.type) posterOptions.showParentTitle = settings.showTitle; - else if ("MusicArtist" === params.type) posterOptions.showYear = !1, lines = 1; - else if ("Programs" === params.type) { + + if ("nextup" === params.type) { + posterOptions.showParentTitle = settings.showTitle; + } else if ("Person" === params.type) { + posterOptions.showYear = false; + posterOptions.showParentTitle = false; + lines = 1; + } else if ("Audio" === params.type) { + posterOptions.showParentTitle = settings.showTitle; + } else if ("MusicAlbum" === params.type) { + posterOptions.showParentTitle = settings.showTitle; + } else if ("Episode" === params.type) { + posterOptions.showParentTitle = settings.showTitle; + } else if ("MusicArtist" === params.type) { + posterOptions.showYear = false; + lines = 1; + } else if ("Programs" === params.type) { lines = settings.showTitle ? 1 : 0; var showParentTitle = settings.showTitle && "true" !== params.IsMovie; - showParentTitle && lines++; + + if (showParentTitle) { + lines++; + } + var showAirTime = settings.showTitle && "Recordings" !== params.type; - showAirTime && lines++; + + if (showAirTime) { + lines++; + } + var showYear = settings.showTitle && "true" === params.IsMovie && "Recordings" === params.type; - showYear && lines++, posterOptions = Object.assign(posterOptions, { + + if (showYear) { + lines++; + } + + posterOptions = Object.assign(posterOptions, { inheritThumb: "Recordings" === params.type, context: "livetv", showParentTitle: showParentTitle, showAirTime: showAirTime, showAirDateTime: showAirTime, - overlayPlayButton: !1, - overlayMoreButton: !0, + overlayPlayButton: false, + overlayMoreButton: true, showYear: showYear, - coverImage: !0 - }) - } else posterOptions.showParentTitle = settings.showTitle; - return posterOptions.lines = lines, posterOptions.items = items, item && "folders" === item.CollectionType && (posterOptions.context = "folders"), cardBuilder.getCardsHtml(posterOptions) + coverImage: true + }); + } else { + posterOptions.showParentTitle = settings.showTitle; + } + + posterOptions.lines = lines; + posterOptions.items = items; + + if (item && "folders" === item.CollectionType) { + posterOptions.context = "folders"; + } + + return cardBuilder.getCardsHtml(posterOptions); } function initAlphaPicker() { self.scroller = view.querySelector(".scrollFrameY"); var alphaPickerElement = self.alphaPickerElement; - layoutManager.tv ? (alphaPickerElement.classList.add("alphaPicker-fixed-left"), alphaPickerElement.classList.add("focuscontainer-left"), self.itemsContainer.parentNode.classList.add("padded-left-withalphapicker")) : (alphaPickerElement.classList.add("alphaPicker-fixed-right"), alphaPickerElement.classList.add("focuscontainer-right"), self.itemsContainer.parentNode.classList.add("padded-right-withalphapicker")), self.alphaPicker = new alphaPicker({ + + if (layoutManager.tv) { + alphaPickerElement.classList.add("alphaPicker-fixed-left"); + alphaPickerElement.classList.add("focuscontainer-left"); + self.itemsContainer.parentNode.classList.add("padded-left-withalphapicker"); + } else { + alphaPickerElement.classList.add("alphaPicker-fixed-right"); + alphaPickerElement.classList.add("focuscontainer-right"); + self.itemsContainer.parentNode.classList.add("padded-right-withalphapicker"); + } + + self.alphaPicker = new alphaPicker({ element: alphaPickerElement, itemsContainer: layoutManager.tv ? self.itemsContainer : null, itemClass: "card", valueChangeEvent: layoutManager.tv ? null : "click" - }), self.alphaPicker.on("alphavaluechanged", onAlphaPickerValueChanged) + }); + self.alphaPicker.on("alphavaluechanged", onAlphaPickerValueChanged); } function onAlphaPickerValueChanged() { self.alphaPicker.value(); - self.itemsContainer.refreshItems() + self.itemsContainer.refreshItems(); } function setTitle(item) { - Emby.Page.setTitle(getTitle(item) || ""), item && "playlists" === item.CollectionType ? hideOrShowAll(view.querySelectorAll(".btnNewItem"), !1) : hideOrShowAll(view.querySelectorAll(".btnNewItem"), !0) + Emby.Page.setTitle(getTitle(item) || ""); + + if (item && "playlists" === item.CollectionType) { + hideOrShowAll(view.querySelectorAll(".btnNewItem"), false); + } else { + hideOrShowAll(view.querySelectorAll(".btnNewItem"), true); + } } function getTitle(item) { - return "Recordings" === params.type ? globalize.translate("Recordings") : "Programs" === params.type ? "true" === params.IsMovie ? globalize.translate("Movies") : "true" === params.IsSports ? globalize.translate("Sports") : "true" === params.IsKids ? globalize.translate("HeaderForKids") : "true" === params.IsAiring ? globalize.translate("HeaderOnNow") : "true" === params.IsSeries ? globalize.translate("Shows") : "true" === params.IsNews ? globalize.translate("News") : globalize.translate("Programs") : "nextup" === params.type ? globalize.translate("NextUp") : "favoritemovies" === params.type ? globalize.translate("FavoriteMovies") : item ? item.Name : "Movie" === params.type ? globalize.translate("Movies") : "Series" === params.type ? globalize.translate("Shows") : "Season" === params.type ? globalize.translate("Seasons") : "Episode" === params.type ? globalize.translate("Episodes") : "MusicArtist" === params.type ? globalize.translate("Artists") : "MusicAlbum" === params.type ? globalize.translate("Albums") : "Audio" === params.type ? globalize.translate("Songs") : "Video" === params.type ? globalize.translate("Videos") : void 0 + if ("Recordings" === params.type) { + return globalize.translate("Recordings"); + } + + if ("Programs" === params.type) { + if ("true" === params.IsMovie) { + return globalize.translate("Movies"); + } + + if ("true" === params.IsSports) { + return globalize.translate("Sports"); + } + + if ("true" === params.IsKids) { + return globalize.translate("HeaderForKids"); + } + + if ("true" === params.IsAiring) { + return globalize.translate("HeaderOnNow"); + } + + if ("true" === params.IsSeries) { + return globalize.translate("Shows"); + } + + if ("true" === params.IsNews) { + return globalize.translate("News"); + } + + return globalize.translate("Programs"); + } + + if ("nextup" === params.type) { + return globalize.translate("NextUp"); + } + + if ("favoritemovies" === params.type) { + return globalize.translate("FavoriteMovies"); + } + + if (item) { + return item.Name; + } + + if ("Movie" === params.type) { + return globalize.translate("Movies"); + } + + if ("Series" === params.type) { + return globalize.translate("Shows"); + } + + if ("Season" === params.type) { + return globalize.translate("Seasons"); + } + + if ("Episode" === params.type) { + return globalize.translate("Episodes"); + } + + if ("MusicArtist" === params.type) { + return globalize.translate("Artists"); + } + + if ("MusicAlbum" === params.type) { + return globalize.translate("Albums"); + } + + if ("Audio" === params.type) { + return globalize.translate("Songs"); + } + + if ("Video" === params.type) { + return globalize.translate("Videos"); + } + + return void 0; } function play() { var currentItem = self.currentItem; - if (currentItem && !self.hasFilters) return void playbackManager.play({ - items: [currentItem] - }); - getItems(self, self.params, currentItem, null, null, 300).then(function(result) { + + if (currentItem && !self.hasFilters) { playbackManager.play({ - items: result.Items - }) - }) + items: [currentItem] + }); + } else { + getItems(self, self.params, currentItem, null, null, 300).then(function (result) { + playbackManager.play({ + items: result.Items + }); + }); + } } function queue() { var currentItem = self.currentItem; - if (currentItem && !self.hasFilters) return void playbackManager.queue({ - items: [currentItem] - }); - getItems(self, self.params, currentItem, null, null, 300).then(function(result) { + + if (currentItem && !self.hasFilters) { playbackManager.queue({ - items: result.Items - }) - }) + items: [currentItem] + }); + } else { + getItems(self, self.params, currentItem, null, null, 300).then(function (result) { + playbackManager.queue({ + items: result.Items + }); + }); + } } function shuffle() { var currentItem = self.currentItem; - if (currentItem && !self.hasFilters) return void playbackManager.shuffle(currentItem); - getItems(self, self.params, currentItem, "Random", null, 300).then(function(result) { - playbackManager.play({ - items: result.Items - }) - }) + + if (currentItem && !self.hasFilters) { + playbackManager.shuffle(currentItem); + } else { + getItems(self, self.params, currentItem, "Random", null, 300).then(function (result) { + playbackManager.play({ + items: result.Items + }); + }); + } } + var self = this; - self.params = params, this.itemsContainer = view.querySelector(".itemsContainer"), params.parentId ? this.itemsContainer.setAttribute("data-parentid", params.parentId) : "nextup" === params.type ? this.itemsContainer.setAttribute("data-monitor", "videoplayback") : "favoritemovies" === params.type ? this.itemsContainer.setAttribute("data-monitor", "markfavorite") : "Programs" === params.type && this.itemsContainer.setAttribute("data-refreshinterval", "300000"); - var i, length, btnViewSettings = view.querySelectorAll(".btnViewSettings"); - for (i = 0, length = btnViewSettings.length; i < length; i++) btnViewSettings[i].addEventListener("click", showViewSettingsMenu.bind(this)); + self.params = params; + this.itemsContainer = view.querySelector(".itemsContainer"); + + if (params.parentId) { + this.itemsContainer.setAttribute("data-parentid", params.parentId); + } else if ("nextup" === params.type) { + this.itemsContainer.setAttribute("data-monitor", "videoplayback"); + } else if ("favoritemovies" === params.type) { + this.itemsContainer.setAttribute("data-monitor", "markfavorite"); + } else if ("Programs" === params.type) { + this.itemsContainer.setAttribute("data-refreshinterval", "300000"); + } + + var i; + var length; + var btnViewSettings = view.querySelectorAll(".btnViewSettings"); + + for (i = 0, length = btnViewSettings.length; i < length; i++) { + btnViewSettings[i].addEventListener("click", showViewSettingsMenu.bind(this)); + } + var filterButtons = view.querySelectorAll(".btnFilter"); this.filterButtons = filterButtons; var hasVisibleFilters = this.getVisibleFilters().length; + for (i = 0, length = filterButtons.length; i < length; i++) { var btnFilter = filterButtons[i]; - btnFilter.addEventListener("click", showFilterMenu.bind(this)), hasVisibleFilters ? btnFilter.classList.remove("hide") : btnFilter.classList.add("hide") + btnFilter.addEventListener("click", showFilterMenu.bind(this)); + + if (hasVisibleFilters) { + btnFilter.classList.remove("hide"); + } else { + btnFilter.classList.add("hide"); + } } + var sortButtons = view.querySelectorAll(".btnSort"); + for (this.sortButtons = sortButtons, i = 0, length = sortButtons.length; i < length; i++) { var sortButton = sortButtons[i]; - sortButton.addEventListener("click", showSortMenu.bind(this)), "nextup" !== params.type && sortButton.classList.remove("hide") + sortButton.addEventListener("click", showSortMenu.bind(this)); + + if ("nextup" !== params.type) { + sortButton.classList.remove("hide"); + } } - this.btnSortText = view.querySelector(".btnSortText"), this.btnSortIcon = view.querySelector(".btnSortIcon"), bindAll(view.querySelectorAll(".btnNewItem"), "click", onNewItemClick.bind(this)), this.alphaPickerElement = view.querySelector(".alphaPicker"), self.itemsContainer.fetchData = fetchData, self.itemsContainer.getItemsHtml = getItemsHtml, view.addEventListener("viewshow", function(e) { + + this.btnSortText = view.querySelector(".btnSortText"); + this.btnSortIcon = view.querySelector(".btnSortIcon"); + bindAll(view.querySelectorAll(".btnNewItem"), "click", onNewItemClick.bind(this)); + this.alphaPickerElement = view.querySelector(".alphaPicker"); + self.itemsContainer.fetchData = fetchData; + self.itemsContainer.getItemsHtml = getItemsHtml; + view.addEventListener("viewshow", function (e) { var isRestored = e.detail.isRestored; - isRestored || (loading.show(), updateSortText(self), updateItemsContainerForViewType(self)), setTitle(null), getItem(params).then(function(item) { - setTitle(item), self.currentItem = item; + + if (!isRestored) { + loading.show(); + updateSortText(self); + updateItemsContainerForViewType(self); + } + + setTitle(null); + getItem(params).then(function (item) { + setTitle(item); + self.currentItem = item; var refresh = !isRestored; self.itemsContainer.resume({ refresh: refresh - }).then(function() { - loading.hide(), refresh && focusManager.autoFocus(self.itemsContainer) - }), isRestored || item && "PhotoAlbum" !== item.Type && initAlphaPicker(); + }).then(function () { + loading.hide(); + + if (refresh) { + focusManager.autoFocus(self.itemsContainer); + } + }); + + if (!isRestored && item && "PhotoAlbum" !== item.Type) { + initAlphaPicker(); + } + var itemType = item ? item.Type : null; - "MusicGenre" === itemType || "Programs" !== params.type && "Channel" !== itemType ? hideOrShowAll(view.querySelectorAll(".btnPlay"), !1) : hideOrShowAll(view.querySelectorAll(".btnPlay"), !0), "MusicGenre" === itemType || "Programs" !== params.type && "nextup" !== params.type && "Channel" !== itemType ? hideOrShowAll(view.querySelectorAll(".btnShuffle"), !1) : hideOrShowAll(view.querySelectorAll(".btnShuffle"), !0), item && playbackManager.canQueue(item) ? hideOrShowAll(view.querySelectorAll(".btnQueue"), !1) : hideOrShowAll(view.querySelectorAll(".btnQueue"), !0) - }), isRestored || (bindAll(view.querySelectorAll(".btnPlay"), "click", play), bindAll(view.querySelectorAll(".btnQueue"), "click", queue), bindAll(view.querySelectorAll(".btnShuffle"), "click", shuffle)), this.alphaNumericShortcuts = new AlphaNumericShortcuts({ + + if ("MusicGenre" === itemType || "Programs" !== params.type && "Channel" !== itemType) { + hideOrShowAll(view.querySelectorAll(".btnPlay"), false); + } else { + hideOrShowAll(view.querySelectorAll(".btnPlay"), true); + } + + if ("MusicGenre" === itemType || "Programs" !== params.type && "nextup" !== params.type && "Channel" !== itemType) { + hideOrShowAll(view.querySelectorAll(".btnShuffle"), false); + } else { + hideOrShowAll(view.querySelectorAll(".btnShuffle"), true); + } + + if (item && playbackManager.canQueue(item)) { + hideOrShowAll(view.querySelectorAll(".btnQueue"), false); + } else { + hideOrShowAll(view.querySelectorAll(".btnQueue"), true); + } + }); + + if (!isRestored) { + bindAll(view.querySelectorAll(".btnPlay"), "click", play); + bindAll(view.querySelectorAll(".btnQueue"), "click", queue); + bindAll(view.querySelectorAll(".btnShuffle"), "click", shuffle); + } + + this.alphaNumericShortcuts = new AlphaNumericShortcuts({ itemsContainer: self.itemsContainer - }) - }), view.addEventListener("viewhide", function(e) { + }); + }); + view.addEventListener("viewhide", function (e) { var itemsContainer = self.itemsContainer; - itemsContainer && itemsContainer.pause(); + + if (itemsContainer) { + itemsContainer.pause(); + } + var alphaNumericShortcuts = self.alphaNumericShortcuts; - alphaNumericShortcuts && (alphaNumericShortcuts.destroy(), self.alphaNumericShortcuts = null) - }), view.addEventListener("viewdestroy", function() { - self.listController && self.listController.destroy(), self.alphaPicker && (self.alphaPicker.off("alphavaluechanged", onAlphaPickerValueChanged), self.alphaPicker.destroy()), self.currentItem = null, self.scroller = null, self.itemsContainer = null, self.filterButtons = null, self.sortButtons = null, self.btnSortText = null, self.btnSortIcon = null, self.alphaPickerElement = null - }) + + if (alphaNumericShortcuts) { + alphaNumericShortcuts.destroy(); + self.alphaNumericShortcuts = null; + } + }); + view.addEventListener("viewdestroy", function () { + if (self.listController) { + self.listController.destroy(); + } + + if (self.alphaPicker) { + self.alphaPicker.off("alphavaluechanged", onAlphaPickerValueChanged); + self.alphaPicker.destroy(); + } + + self.currentItem = null; + self.scroller = null; + self.itemsContainer = null; + self.filterButtons = null; + self.sortButtons = null; + self.btnSortText = null; + self.btnSortIcon = null; + self.alphaPickerElement = null; + }); } - return ItemsView.prototype.getFilters = function() { + + ItemsView.prototype.getFilters = function () { var basekey = this.getSettingsKey(); return { IsPlayed: "true" === userSettings.getFilter(basekey + "-filter-IsPlayed"), @@ -342,87 +867,211 @@ define(["globalize", "listView", "layoutManager", "userSettings", "focusManager" HasThemeSong: userSettings.getFilter(basekey + "-filter-HasThemeSong"), HasThemeVideo: userSettings.getFilter(basekey + "-filter-HasThemeVideo"), GenreIds: userSettings.getFilter(basekey + "-filter-GenreIds") - } - }, ItemsView.prototype.getSortValues = function() { + }; + }; + + ItemsView.prototype.getSortValues = function () { var basekey = this.getSettingsKey(); return { sortBy: userSettings.getFilter(basekey + "-sortby") || this.getDefaultSortBy(), sortOrder: "Descending" === userSettings.getFilter(basekey + "-sortorder") ? "Descending" : "Ascending" + }; + }; + + ItemsView.prototype.getDefaultSortBy = function () { + var params = this.params; + var sortNameOption = this.getNameSortOption(params); + + if (params.type) { + return sortNameOption.value; } - }, ItemsView.prototype.getDefaultSortBy = function() { - var params = this.params, - sortNameOption = this.getNameSortOption(params); - return params.type ? sortNameOption.value : "IsFolder," + sortNameOption.value - }, ItemsView.prototype.getSortMenuOptions = function() { - var sortBy = [], - params = this.params; - "Programs" === params.type && sortBy.push({ - name: globalize.translate("AirDate"), - value: "StartDate,SortName" - }); + + return "IsFolder," + sortNameOption.value; + }; + + ItemsView.prototype.getSortMenuOptions = function () { + var sortBy = []; + var params = this.params; + + if ("Programs" === params.type) { + sortBy.push({ + name: globalize.translate("AirDate"), + value: "StartDate,SortName" + }); + } + var option = this.getNameSortOption(params); - return option && sortBy.push(option), option = this.getCommunityRatingSortOption(), option && sortBy.push(option), option = this.getCriticRatingSortOption(), option && sortBy.push(option), "Programs" !== params.type && sortBy.push({ - name: globalize.translate("DateAdded"), - value: "DateCreated,SortName" - }), option = this.getDatePlayedSortOption(), option && sortBy.push(option), params.type || (option = this.getNameSortOption(params), sortBy.push({ - name: globalize.translate("Folders"), - value: "IsFolder," + option.value - })), sortBy.push({ + + if (option) { + sortBy.push(option); + } + + option = this.getCommunityRatingSortOption(); + + if (option) { + sortBy.push(option); + } + + option = this.getCriticRatingSortOption(); + + if (option) { + sortBy.push(option); + } + + if ("Programs" !== params.type) { + sortBy.push({ + name: globalize.translate("DateAdded"), + value: "DateCreated,SortName" + }); + } + + option = this.getDatePlayedSortOption(); + + if (option) { + sortBy.push(option); + } + + if (!params.type) { + option = this.getNameSortOption(params); + sortBy.push({ + name: globalize.translate("Folders"), + value: "IsFolder," + option.value + }); + } + + sortBy.push({ name: globalize.translate("ParentalRating"), value: "OfficialRating,SortName" - }), option = this.getPlayCountSortOption(), option && sortBy.push(option), sortBy.push({ + }); + option = this.getPlayCountSortOption(); + + if (option) { + sortBy.push(option); + } + + sortBy.push({ name: globalize.translate("ReleaseDate"), value: "ProductionYear,PremiereDate,SortName" - }), sortBy.push({ + }); + sortBy.push({ name: globalize.translate("Runtime"), value: "Runtime,SortName" - }), sortBy - }, ItemsView.prototype.getNameSortOption = function(params) { - return "Episode" === params.type ? { - name: globalize.translate("Name"), - value: "SeriesName,SortName" - } : { + }); + return sortBy; + }; + + ItemsView.prototype.getNameSortOption = function (params) { + if ("Episode" === params.type) { + return { + name: globalize.translate("Name"), + value: "SeriesName,SortName" + }; + } + + return { name: globalize.translate("Name"), value: "SortName" + }; + }; + + ItemsView.prototype.getPlayCountSortOption = function () { + if ("Programs" === this.params.type) { + return null; } - }, ItemsView.prototype.getPlayCountSortOption = function() { - return "Programs" === this.params.type ? null : { + + return { name: globalize.translate("PlayCount"), value: "PlayCount,SortName" + }; + }; + + ItemsView.prototype.getDatePlayedSortOption = function () { + if ("Programs" === this.params.type) { + return null; } - }, ItemsView.prototype.getDatePlayedSortOption = function() { - return "Programs" === this.params.type ? null : { + + return { name: globalize.translate("DatePlayed"), value: "DatePlayed,SortName" + }; + }; + + ItemsView.prototype.getCriticRatingSortOption = function () { + if ("Programs" === this.params.type) { + return null; } - }, ItemsView.prototype.getCriticRatingSortOption = function() { - return "Programs" === this.params.type ? null : { + + return { name: globalize.translate("CriticRating"), value: "CriticRating,SortName" - } - }, ItemsView.prototype.getCommunityRatingSortOption = function() { + }; + }; + + ItemsView.prototype.getCommunityRatingSortOption = function () { return { name: globalize.translate("CommunityRating"), value: "CommunityRating,SortName" + }; + }; + + ItemsView.prototype.getVisibleFilters = function () { + var filters = []; + var params = this.params; + + if (!("nextup" === params.type)) { + if ("Programs" === params.type) { + filters.push("Genres"); + } else { + params.type; + filters.push("IsUnplayed"); + filters.push("IsPlayed"); + + if (!params.IsFavorite) { + filters.push("IsFavorite"); + } + + filters.push("IsResumable"); + filters.push("VideoType"); + filters.push("HasSubtitles"); + filters.push("HasTrailer"); + filters.push("HasSpecialFeature"); + filters.push("HasThemeSong"); + filters.push("HasThemeVideo"); + } } - }, ItemsView.prototype.getVisibleFilters = function() { - var filters = [], - params = this.params; - return "nextup" === params.type || ("Programs" === params.type ? filters.push("Genres") : (params.type, filters.push("IsUnplayed"), filters.push("IsPlayed"), params.IsFavorite || filters.push("IsFavorite"), filters.push("IsResumable"), filters.push("VideoType"), filters.push("HasSubtitles"), filters.push("HasTrailer"), filters.push("HasSpecialFeature"), filters.push("HasThemeSong"), filters.push("HasThemeVideo"))), filters - }, ItemsView.prototype.setFilterStatus = function(hasFilters) { + + return filters; + }; + + ItemsView.prototype.setFilterStatus = function (hasFilters) { this.hasFilters = hasFilters; var filterButtons = this.filterButtons; - if (filterButtons.length) + + if (filterButtons.length) { for (var i = 0, length = filterButtons.length; i < length; i++) { - var btnFilter = filterButtons[i], - bubble = btnFilter.querySelector(".filterButtonBubble"); + var btnFilter = filterButtons[i]; + var bubble = btnFilter.querySelector(".filterButtonBubble"); + if (!bubble) { - if (!hasFilters) continue; - btnFilter.insertAdjacentHTML("afterbegin", '
            !
            '), btnFilter.classList.add("btnFilterWithBubble"), bubble = btnFilter.querySelector(".filterButtonBubble") + if (!hasFilters) { + continue; + } + + btnFilter.insertAdjacentHTML("afterbegin", '
            !
            '); + btnFilter.classList.add("btnFilterWithBubble"); + bubble = btnFilter.querySelector(".filterButtonBubble"); + } + + if (hasFilters) { + bubble.classList.remove("hide"); + } else { + bubble.classList.add("hide"); } - hasFilters ? bubble.classList.remove("hide") : bubble.classList.add("hide") } - }, ItemsView.prototype.getFilterMenuOptions = function() { + } + }; + + ItemsView.prototype.getFilterMenuOptions = function () { var params = this.params; return { IsAiring: params.IsAiring, @@ -432,31 +1081,126 @@ define(["globalize", "listView", "layoutManager", "userSettings", "focusManager" IsNews: params.IsNews, IsSeries: params.IsSeries, Recursive: this.queryRecursive + }; + }; + + ItemsView.prototype.getVisibleViewSettings = function () { + var item = (this.params, this.currentItem); + var fields = ["showTitle"]; + + if (!item || "PhotoAlbum" !== item.Type && "ChannelFolderItem" !== item.Type) { + fields.push("imageType"); } - }, ItemsView.prototype.getVisibleViewSettings = function() { - var item = (this.params, this.currentItem), - fields = ["showTitle"]; - return (!item || "PhotoAlbum" !== item.Type && "ChannelFolderItem" !== item.Type) && fields.push("imageType"), fields.push("viewType"), fields - }, ItemsView.prototype.getViewSettings = function() { - var basekey = this.getSettingsKey(), - params = this.params, - item = this.currentItem, - showTitle = userSettings.get(basekey + "-showTitle"); - "true" === showTitle ? showTitle = !0 : "false" === showTitle ? showTitle = !1 : "Programs" === params.type || "Recordings" === params.type || "Person" === params.type || "nextup" === params.type || "Audio" === params.type || "MusicAlbum" === params.type || "MusicArtist" === params.type ? showTitle = !0 : item && "PhotoAlbum" !== item.Type && (showTitle = !0); + + fields.push("viewType"); + return fields; + }; + + ItemsView.prototype.getViewSettings = function () { + var basekey = this.getSettingsKey(); + var params = this.params; + var item = this.currentItem; + var showTitle = userSettings.get(basekey + "-showTitle"); + + if ("true" === showTitle) { + showTitle = true; + } else if ("false" === showTitle) { + showTitle = false; + } else if ("Programs" === params.type || "Recordings" === params.type || "Person" === params.type || "nextup" === params.type || "Audio" === params.type || "MusicAlbum" === params.type || "MusicArtist" === params.type) { + showTitle = true; + } else if (item && "PhotoAlbum" !== item.Type) { + showTitle = true; + } + var imageType = userSettings.get(basekey + "-imageType"); - return imageType || "nextup" === params.type && (imageType = "thumb"), { + + if (!imageType && "nextup" === params.type) { + imageType = "thumb"; + } + + return { showTitle: showTitle, showYear: "false" !== userSettings.get(basekey + "-showYear"), imageType: imageType || "primary", viewType: userSettings.get(basekey + "-viewType") || "images" - } - }, ItemsView.prototype.getItemTypes = function() { + }; + }; + + ItemsView.prototype.getItemTypes = function () { var params = this.params; - return "nextup" === params.type ? ["Episode"] : "Programs" === params.type ? ["Program"] : [] - }, ItemsView.prototype.getSettingsKey = function() { + + if ("nextup" === params.type) { + return ["Episode"]; + } + + if ("Programs" === params.type) { + return ["Program"]; + } + + return []; + }; + + ItemsView.prototype.getSettingsKey = function () { var values = []; values.push("items"); var params = this.params; - return params.type ? values.push(params.type) : params.parentId && values.push(params.parentId), params.IsAiring && values.push("IsAiring"), params.IsMovie && values.push("IsMovie"), params.IsKids && values.push("IsKids"), params.IsSports && values.push("IsSports"), params.IsNews && values.push("IsNews"), params.IsSeries && values.push("IsSeries"), params.IsFavorite && values.push("IsFavorite"), params.genreId && values.push("Genre"), params.musicGenreId && values.push("MusicGenre"), params.studioId && values.push("Studio"), params.personId && values.push("Person"), params.parentId && values.push("Folder"), values.join("-") - }, ItemsView + + if (params.type) { + values.push(params.type); + } else if (params.parentId) { + values.push(params.parentId); + } + + if (params.IsAiring) { + values.push("IsAiring"); + } + + if (params.IsMovie) { + values.push("IsMovie"); + } + + if (params.IsKids) { + values.push("IsKids"); + } + + if (params.IsSports) { + values.push("IsSports"); + } + + if (params.IsNews) { + values.push("IsNews"); + } + + if (params.IsSeries) { + values.push("IsSeries"); + } + + if (params.IsFavorite) { + values.push("IsFavorite"); + } + + if (params.genreId) { + values.push("Genre"); + } + + if (params.musicGenreId) { + values.push("MusicGenre"); + } + + if (params.studioId) { + values.push("Studio"); + } + + if (params.personId) { + values.push("Person"); + } + + if (params.parentId) { + values.push("Folder"); + } + + return values.join("-"); + }; + + return ItemsView; }); diff --git a/src/controllers/livetv/livetvchannels.js b/src/controllers/livetv/livetvchannels.js index cc2eda5053..3e310a17a3 100644 --- a/src/controllers/livetv/livetvchannels.js +++ b/src/controllers/livetv/livetvchannels.js @@ -1,89 +1,119 @@ -define(["cardBuilder", "imageLoader", "libraryBrowser", "loading", "events", "emby-itemscontainer"], function(cardBuilder, imageLoader, libraryBrowser, loading, events) { +define(["cardBuilder", "imageLoader", "libraryBrowser", "loading", "events", "emby-itemscontainer"], function (cardBuilder, imageLoader, libraryBrowser, loading, events) { "use strict"; - return function(view, params, tabContent) { + + return function (view, params, tabContent) { function getPageData() { - return pageData || (pageData = { - query: { - StartIndex: 0, - Limit: 100, - Fields: "PrimaryImageAspectRatio" - } - }), pageData + if (!pageData) { + pageData = { + query: { + StartIndex: 0, + Limit: 100, + Fields: "PrimaryImageAspectRatio" + } + }; + } + + return pageData; } function getQuery() { - return getPageData().query + return getPageData().query; } function getChannelsHtml(channels) { return cardBuilder.getCardsHtml({ items: channels, shape: "square", - showTitle: !0, - lazy: !0, - cardLayout: !0, - showDetailsMenu: !0, - showCurrentProgram: !0, - showCurrentProgramTime: !0 - }) + showTitle: true, + lazy: true, + cardLayout: true, + showDetailsMenu: true, + showCurrentProgram: true, + showCurrentProgramTime: true + }); } function renderChannels(context, result) { function onNextPageClick() { - if (isLoading) return; - query.StartIndex += query.Limit, reloadItems(context) + if (isLoading) { + return; + } + + query.StartIndex += query.Limit; + reloadItems(context); } function onPreviousPageClick() { - if (isLoading) return; - query.StartIndex -= query.Limit, reloadItems(context) + if (isLoading) { + return; + } + + query.StartIndex -= query.Limit; + reloadItems(context); } + var query = getQuery(); context.querySelector(".paging").innerHTML = libraryBrowser.getQueryPagingHtml({ startIndex: query.StartIndex, limit: query.Limit, totalRecordCount: result.TotalRecordCount, - showLimit: !1, - updatePageSizeSetting: !1, - filterButton: !1 + showLimit: false, + updatePageSizeSetting: false, + filterButton: false }); - var html = getChannelsHtml(result.Items), - elem = context.querySelector("#items"); - elem.innerHTML = html, imageLoader.lazyChildren(elem); - var i, length, elems; - for (elems = context.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick); - for (elems = context.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick) + var html = getChannelsHtml(result.Items); + var elem = context.querySelector("#items"); + elem.innerHTML = html; + imageLoader.lazyChildren(elem); + var i; + var length; + var elems; + + for (elems = context.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onNextPageClick); + } + + for (elems = context.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onPreviousPageClick); + } } function showFilterMenu(context) { - require(["components/filterdialog/filterdialog"], function(filterDialogFactory) { + require(["components/filterdialog/filterdialog"], function (filterDialogFactory) { var filterDialog = new filterDialogFactory({ query: getQuery(), mode: "livetvchannels", serverId: ApiClient.serverId() }); - events.on(filterDialog, "filterchange", function() { - reloadItems(context) - }), filterDialog.show() - }) + events.on(filterDialog, "filterchange", function () { + reloadItems(context); + }); + filterDialog.show(); + }); } function reloadItems(context, save) { loading.show(); isLoading = true; - var query = getQuery(), - apiClient = ApiClient; - query.UserId = apiClient.getCurrentUserId(), apiClient.getLiveTvChannels(query).then(function(result) { + var query = getQuery(); + var apiClient = ApiClient; + query.UserId = apiClient.getCurrentUserId(); + apiClient.getLiveTvChannels(query).then(function (result) { renderChannels(context, result); loading.hide(); isLoading = false; - }) + }); } - var pageData, self = this, isLoading = false; - tabContent.querySelector(".btnFilter").addEventListener("click", function() { - showFilterMenu(tabContent) - }), self.renderTab = function() { - reloadItems(tabContent) - } - } + + var pageData; + var self = this; + var isLoading = false; + tabContent.querySelector(".btnFilter").addEventListener("click", function () { + showFilterMenu(tabContent); + }); + + self.renderTab = function () { + reloadItems(tabContent); + }; + }; }); diff --git a/src/controllers/livetv/livetvguide.js b/src/controllers/livetv/livetvguide.js index 3c8b3f4109..f7c2f1baaa 100644 --- a/src/controllers/livetv/livetvguide.js +++ b/src/controllers/livetv/livetvguide.js @@ -1,16 +1,29 @@ -define(["tvguide"], function(tvguide) { +define(["tvguide"], function (tvguide) { "use strict"; - return function(view, params, tabContent) { - var guideInstance, self = this; - self.renderTab = function() { - guideInstance || (guideInstance = new tvguide({ - element: tabContent, - serverId: ApiClient.serverId() - })) - }, self.onShow = function() { - guideInstance && guideInstance.resume() - }, self.onHide = function() { - guideInstance && guideInstance.pause() - } - } -}); \ No newline at end of file + + return function (view, params, tabContent) { + var guideInstance; + var self = this; + + self.renderTab = function () { + if (!guideInstance) { + guideInstance = new tvguide({ + element: tabContent, + serverId: ApiClient.serverId() + }); + } + }; + + self.onShow = function () { + if (guideInstance) { + guideInstance.resume(); + } + }; + + self.onHide = function () { + if (guideInstance) { + guideInstance.pause(); + } + }; + }; +}); diff --git a/src/controllers/livetv/livetvrecordings.js b/src/controllers/livetv/livetvrecordings.js index f82b150a21..ed3ae24087 100644 --- a/src/controllers/livetv/livetvrecordings.js +++ b/src/controllers/livetv/livetvrecordings.js @@ -1,69 +1,106 @@ -define(["layoutManager", "loading", "cardBuilder", "apphost", "imageLoader", "scripts/livetvcomponents", "listViewStyle", "emby-itemscontainer"], function(layoutManager, loading, cardBuilder, appHost, imageLoader) { +define(["layoutManager", "loading", "cardBuilder", "apphost", "imageLoader", "scripts/livetvcomponents", "listViewStyle", "emby-itemscontainer"], function (layoutManager, loading, cardBuilder, appHost, imageLoader) { "use strict"; function renderRecordings(elem, recordings, cardOptions, scrollX) { - recordings.length ? elem.classList.remove("hide") : elem.classList.add("hide"); + if (recordings.length) { + elem.classList.remove("hide"); + } else { + elem.classList.add("hide"); + } + var recordingItems = elem.querySelector(".recordingItems"); - scrollX ? (recordingItems.classList.add("scrollX"), recordingItems.classList.add("hiddenScrollX"), recordingItems.classList.remove("vertical-wrap")) : (recordingItems.classList.remove("scrollX"), recordingItems.classList.remove("hiddenScrollX"), recordingItems.classList.add("vertical-wrap")); + + if (scrollX) { + recordingItems.classList.add("scrollX"); + recordingItems.classList.add("hiddenScrollX"); + recordingItems.classList.remove("vertical-wrap"); + } else { + recordingItems.classList.remove("scrollX"); + recordingItems.classList.remove("hiddenScrollX"); + recordingItems.classList.add("vertical-wrap"); + } + appHost.supports("imageanalysis"); recordingItems.innerHTML = cardBuilder.getCardsHtml(Object.assign({ items: recordings, shape: scrollX ? "autooverflow" : "auto", defaultShape: scrollX ? "overflowBackdrop" : "backdrop", - showTitle: !0, - showParentTitle: !0, - coverImage: !0, - cardLayout: !1, - centerText: !0, + showTitle: true, + showParentTitle: true, + coverImage: true, + cardLayout: false, + centerText: true, allowBottomPadding: !scrollX, preferThumb: "auto", - overlayText: !1 - }, cardOptions || {})), imageLoader.lazyChildren(recordingItems) + overlayText: false + }, cardOptions || {})); + imageLoader.lazyChildren(recordingItems); } function renderLatestRecordings(context, promise) { - promise.then(function(result) { + promise.then(function (result) { renderRecordings(context.querySelector("#latestRecordings"), result.Items, { - showYear: !0, + showYear: true, lines: 2 - }, !1), loading.hide() - }) + }, false); + loading.hide(); + }); } function renderRecordingFolders(context, promise) { - promise.then(function(result) { + promise.then(function (result) { renderRecordings(context.querySelector("#recordingFolders"), result.Items, { - showYear: !1, - showParentTitle: !1 - }, !1) - }) + showYear: false, + showParentTitle: false + }, false); + }); } function onMoreClick(e) { - var type = this.getAttribute("data-type"), - serverId = ApiClient.serverId(); + var type = this.getAttribute("data-type"); + var serverId = ApiClient.serverId(); + switch (type) { case "latest": - Dashboard.navigate("list.html?type=Recordings&serverId=" + serverId) + Dashboard.navigate("list.html?type=Recordings&serverId=" + serverId); } } - return function(view, params, tabContent) { + + return function (view, params, tabContent) { function enableFullRender() { - return (new Date).getTime() - lastFullRender > 3e5 + return new Date().getTime() - lastFullRender > 300000; } - var foldersPromise, latestPromise, self = this, - lastFullRender = 0; - for (var moreButtons = tabContent.querySelectorAll(".more"), i = 0, length = moreButtons.length; i < length; i++) moreButtons[i].addEventListener("click", onMoreClick); - self.preRender = function() { - enableFullRender() && (latestPromise = ApiClient.getLiveTvRecordings({ - UserId: Dashboard.getCurrentUserId(), - Limit: 12, - Fields: "CanDelete,PrimaryImageAspectRatio,BasicSyncInfo", - EnableTotalRecordCount: !1, - EnableImageTypes: "Primary,Thumb,Backdrop" - }), foldersPromise = ApiClient.getRecordingFolders(Dashboard.getCurrentUserId())) - }, self.renderTab = function() { - enableFullRender() && (loading.show(), renderLatestRecordings(tabContent, latestPromise), renderRecordingFolders(tabContent, foldersPromise), lastFullRender = (new Date).getTime()) + + var foldersPromise; + var latestPromise; + var self = this; + var lastFullRender = 0; + var moreButtons = tabContent.querySelectorAll(".more"); + + for (var i = 0, length = moreButtons.length; i < length; i++) { + moreButtons[i].addEventListener("click", onMoreClick); } - } -}); \ No newline at end of file + + self.preRender = function () { + if (enableFullRender()) { + latestPromise = ApiClient.getLiveTvRecordings({ + UserId: Dashboard.getCurrentUserId(), + Limit: 12, + Fields: "CanDelete,PrimaryImageAspectRatio,BasicSyncInfo", + EnableTotalRecordCount: false, + EnableImageTypes: "Primary,Thumb,Backdrop" + }); + foldersPromise = ApiClient.getRecordingFolders(Dashboard.getCurrentUserId()); + } + }; + + self.renderTab = function () { + if (enableFullRender()) { + loading.show(); + renderLatestRecordings(tabContent, latestPromise); + renderRecordingFolders(tabContent, foldersPromise); + lastFullRender = new Date().getTime(); + } + }; + }; +}); diff --git a/src/controllers/livetv/livetvschedule.js b/src/controllers/livetv/livetvschedule.js index 24ece42dbe..3ee56a2a95 100644 --- a/src/controllers/livetv/livetvschedule.js +++ b/src/controllers/livetv/livetvschedule.js @@ -1,27 +1,50 @@ -define(["layoutManager", "cardBuilder", "apphost", "imageLoader", "loading", "scripts/livetvcomponents", "emby-button", "emby-itemscontainer"], function(layoutManager, cardBuilder, appHost, imageLoader, loading) { +define(["layoutManager", "cardBuilder", "apphost", "imageLoader", "loading", "scripts/livetvcomponents", "emby-button", "emby-itemscontainer"], function (layoutManager, cardBuilder, appHost, imageLoader, loading) { "use strict"; function enableScrollX() { - return !layoutManager.desktop + return !layoutManager.desktop; } function renderRecordings(elem, recordings, cardOptions) { - recordings.length ? elem.classList.remove("hide") : elem.classList.add("hide"); + if (recordings.length) { + elem.classList.remove("hide"); + } else { + elem.classList.add("hide"); + } + var recordingItems = elem.querySelector(".recordingItems"); - enableScrollX() ? (recordingItems.classList.add("scrollX"), layoutManager.tv && recordingItems.classList.add("smoothScrollX"), recordingItems.classList.add("hiddenScrollX"), recordingItems.classList.remove("vertical-wrap")) : (recordingItems.classList.remove("scrollX"), recordingItems.classList.remove("smoothScrollX"), recordingItems.classList.remove("hiddenScrollX"), recordingItems.classList.add("vertical-wrap")); - var supportsImageAnalysis = appHost.supports("imageanalysis"), - cardLayout = appHost.preferVisualCards || supportsImageAnalysis; - cardLayout = !1, recordingItems.innerHTML = cardBuilder.getCardsHtml(Object.assign({ + + if (enableScrollX()) { + recordingItems.classList.add("scrollX"); + + if (layoutManager.tv) { + recordingItems.classList.add("smoothScrollX"); + } + + recordingItems.classList.add("hiddenScrollX"); + recordingItems.classList.remove("vertical-wrap"); + } else { + recordingItems.classList.remove("scrollX"); + recordingItems.classList.remove("smoothScrollX"); + recordingItems.classList.remove("hiddenScrollX"); + recordingItems.classList.add("vertical-wrap"); + } + + var supportsImageAnalysis = appHost.supports("imageanalysis"); + var cardLayout = appHost.preferVisualCards || supportsImageAnalysis; + cardLayout = false; + recordingItems.innerHTML = cardBuilder.getCardsHtml(Object.assign({ items: recordings, shape: enableScrollX() ? "autooverflow" : "auto", - showTitle: !0, - showParentTitle: !0, - coverImage: !0, + showTitle: true, + showParentTitle: true, + coverImage: true, cardLayout: cardLayout, centerText: !cardLayout, allowBottomPadding: !enableScrollX(), preferThumb: "auto" - }, cardOptions || {})), imageLoader.lazyChildren(recordingItems) + }, cardOptions || {})); + imageLoader.lazyChildren(recordingItems); } function getBackdropShape() { @@ -29,52 +52,72 @@ define(["layoutManager", "cardBuilder", "apphost", "imageLoader", "loading", "sc } function renderActiveRecordings(context, promise) { - promise.then(function(result) { + promise.then(function (result) { renderRecordings(context.querySelector("#activeRecordings"), result.Items, { shape: enableScrollX() ? "autooverflow" : "auto", defaultShape: getBackdropShape(), - showParentTitle: !1, - showParentTitleOrTitle: !0, - showTitle: !1, - showAirTime: !0, - showAirEndTime: !0, - showChannelName: !0, - coverImage: !0, - overlayText: !1, - overlayMoreButton: !0 - }) - }) + showParentTitle: false, + showParentTitleOrTitle: true, + showTitle: false, + showAirTime: true, + showAirEndTime: true, + showChannelName: true, + coverImage: true, + overlayText: false, + overlayMoreButton: true + }); + }); } function renderTimers(context, timers, options) { - LiveTvHelpers.getTimersHtml(timers, options).then(function(html) { + LiveTvHelpers.getTimersHtml(timers, options).then(function (html) { var elem = context; - html ? elem.classList.remove("hide") : elem.classList.add("hide"), elem.querySelector(".recordingItems").innerHTML = html, imageLoader.lazyChildren(elem) - }) + + if (html) { + elem.classList.remove("hide"); + } else { + elem.classList.add("hide"); + } + + elem.querySelector(".recordingItems").innerHTML = html; + imageLoader.lazyChildren(elem); + }); } function renderUpcomingRecordings(context, promise) { - promise.then(function(result) { - renderTimers(context.querySelector("#upcomingRecordings"), result.Items), loading.hide() - }) + promise.then(function (result) { + renderTimers(context.querySelector("#upcomingRecordings"), result.Items); + loading.hide(); + }); } - return function(view, params, tabContent) { - var activeRecordingsPromise, upcomingRecordingsPromise, self = this; - tabContent.querySelector("#upcomingRecordings .recordingItems").addEventListener("timercancelled", function() { - self.preRender(), self.renderTab() - }), self.preRender = function() { + + return function (view, params, tabContent) { + var activeRecordingsPromise; + var upcomingRecordingsPromise; + var self = this; + tabContent.querySelector("#upcomingRecordings .recordingItems").addEventListener("timercancelled", function () { + self.preRender(); + self.renderTab(); + }); + + self.preRender = function () { activeRecordingsPromise = ApiClient.getLiveTvRecordings({ UserId: Dashboard.getCurrentUserId(), - IsInProgress: !0, + IsInProgress: true, Fields: "CanDelete,PrimaryImageAspectRatio,BasicSyncInfo", - EnableTotalRecordCount: !1, + EnableTotalRecordCount: false, EnableImageTypes: "Primary,Thumb,Backdrop" - }), upcomingRecordingsPromise = ApiClient.getLiveTvTimers({ - IsActive: !1, - IsScheduled: !0 - }) - }, self.renderTab = function() { - loading.show(), renderActiveRecordings(tabContent, activeRecordingsPromise), renderUpcomingRecordings(tabContent, upcomingRecordingsPromise) - } - } -}); \ No newline at end of file + }); + upcomingRecordingsPromise = ApiClient.getLiveTvTimers({ + IsActive: false, + IsScheduled: true + }); + }; + + self.renderTab = function () { + loading.show(); + renderActiveRecordings(tabContent, activeRecordingsPromise); + renderUpcomingRecordings(tabContent, upcomingRecordingsPromise); + }; + }; +}); diff --git a/src/controllers/livetv/livetvseriestimers.js b/src/controllers/livetv/livetvseriestimers.js index 5acd9f326c..9c95cfa91f 100644 --- a/src/controllers/livetv/livetvseriestimers.js +++ b/src/controllers/livetv/livetvseriestimers.js @@ -1,4 +1,4 @@ -define(["datetime", "cardBuilder", "imageLoader", "apphost", "loading", "paper-icon-button-light", "emby-button"], function(datetime, cardBuilder, imageLoader, appHost, loading) { +define(["datetime", "cardBuilder", "imageLoader", "apphost", "loading", "paper-icon-button-light", "emby-button"], function (datetime, cardBuilder, imageLoader, appHost, loading) { "use strict"; function renderTimers(context, timers) { @@ -8,36 +8,44 @@ define(["datetime", "cardBuilder", "imageLoader", "apphost", "loading", "paper-i items: timers, shape: "auto", defaultShape: "portrait", - showTitle: !0, - cardLayout: !1, + showTitle: true, + cardLayout: false, preferThumb: "auto", - coverImage: !0, - overlayText: !1, - showSeriesTimerTime: !0, - showSeriesTimerChannel: !0, - centerText: !0, - overlayMoreButton: !0, + coverImage: true, + overlayText: false, + showSeriesTimerTime: true, + showSeriesTimerChannel: true, + centerText: true, + overlayMoreButton: true, lines: 3 }); var elem = context.querySelector("#items"); - elem.innerHTML = html, imageLoader.lazyChildren(elem), loading.hide() + elem.innerHTML = html; + imageLoader.lazyChildren(elem); + loading.hide(); } function reload(context, promise) { - loading.show(), promise.then(function(result) { - renderTimers(context, result.Items) - }) + loading.show(); + promise.then(function (result) { + renderTimers(context, result.Items); + }); } + var query = { SortBy: "SortName", SortOrder: "Ascending" }; - return function(view, params, tabContent) { - var timersPromise, self = this; - self.preRender = function() { - timersPromise = ApiClient.getLiveTvSeriesTimers(query) - }, self.renderTab = function() { - reload(tabContent, timersPromise) - } - } -}); \ No newline at end of file + return function (view, params, tabContent) { + var timersPromise; + var self = this; + + self.preRender = function () { + timersPromise = ApiClient.getLiveTvSeriesTimers(query); + }; + + self.renderTab = function () { + reload(tabContent, timersPromise); + }; + }; +}); diff --git a/src/controllers/livetv/livetvsuggested.js b/src/controllers/livetv/livetvsuggested.js index 4fc51467e6..509b7f521c 100644 --- a/src/controllers/livetv/livetvsuggested.js +++ b/src/controllers/livetv/livetvsuggested.js @@ -23,6 +23,7 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize", if (enableScrollX()) { return 12; } + return 9; } @@ -150,15 +151,22 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize", } function getTabs() { - return [ - { name: globalize.translate("Programs") }, - { name: globalize.translate("TabGuide") }, - { name: globalize.translate("TabChannels") }, - { name: globalize.translate("TabRecordings") }, - { name: globalize.translate("HeaderSchedule") }, - { name: globalize.translate("TabSeries") }, - { name: globalize.translate("ButtonSearch"), cssClass: "searchTabButton" } - ]; + return [{ + name: globalize.translate("Programs") + }, { + name: globalize.translate("TabGuide") + }, { + name: globalize.translate("TabChannels") + }, { + name: globalize.translate("TabRecordings") + }, { + name: globalize.translate("HeaderSchedule") + }, { + name: globalize.translate("TabSeries") + }, { + name: globalize.translate("ButtonSearch"), + cssClass: "searchTabButton" + }]; } function setScrollClasses(elem, scrollX) { @@ -183,6 +191,7 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize", if (userSettings.get("landing-" + folderId) === "guide") { return 1; } + return 0; } @@ -220,21 +229,27 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize", switch (index) { case 0: break; + case 1: depends.push("controllers/livetv/livetvguide"); break; + case 2: depends.push("controllers/livetv/livetvchannels"); break; + case 3: depends.push("controllers/livetv/livetvrecordings"); break; + case 4: depends.push("controllers/livetv/livetvschedule"); break; + case 5: depends.push("controllers/livetv/livetvseriestimers"); break; + case 6: depends.push("scripts/searchtab"); } @@ -251,6 +266,7 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize", if (!controller) { tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); + if (0 === index) { controller = self; } else if (6 === index) { @@ -260,6 +276,7 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize", } else { controller = new controllerFactory(view, params, tabContent); } + tabControllers[index] = controller; if (controller.initTab) { @@ -347,15 +364,18 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize", }); view.addEventListener("viewshow", function (evt) { isViewRestored = evt.detail.isRestored; + if (!isViewRestored) { mainTabsManager.selectedTabIndex(initialTabIndex); } + inputManager.on(window, onInputCommand); }); - view.addEventListener("viewbeforehide", function (e__u) { + view.addEventListener("viewbeforehide", function (e) { if (currentTabController && currentTabController.onHide) { currentTabController.onHide(); } + inputManager.off(window, onInputCommand); }); view.addEventListener("viewdestroy", function (evt) { diff --git a/src/controllers/livetvguideprovider.js b/src/controllers/livetvguideprovider.js index 40617cdb90..a58917f22d 100644 --- a/src/controllers/livetvguideprovider.js +++ b/src/controllers/livetvguideprovider.js @@ -1,26 +1,30 @@ -define(["events", "loading"], function(events, loading) { +define(["events", "loading"], function (events, loading) { "use strict"; function onListingsSubmitted() { - Dashboard.navigate("livetvstatus.html") + Dashboard.navigate("livetvstatus.html"); } function init(page, type, providerId) { var url = "components/tvproviders/" + type + ".js"; - require([url], function(factory) { + + require([url], function (factory) { var instance = new factory(page, providerId, {}); - events.on(instance, "submitted", onListingsSubmitted), instance.init() - }) + events.on(instance, "submitted", onListingsSubmitted); + instance.init(); + }); } function loadTemplate(page, type, providerId) { - require(["text!./components/tvproviders/" + type + ".template.html"], function(html) { - page.querySelector(".providerTemplate").innerHTML = Globalize.translateDocument(html), init(page, type, providerId) - }) + require(["text!./components/tvproviders/" + type + ".template.html"], function (html) { + page.querySelector(".providerTemplate").innerHTML = Globalize.translateDocument(html); + init(page, type, providerId); + }); } - pageIdOn("pageshow", "liveTvGuideProviderPage", function() { + + pageIdOn("pageshow", "liveTvGuideProviderPage", function () { loading.show(); var providerId = getParameterByName("id"); - loadTemplate(this, getParameterByName("type"), providerId) - }) -}); \ No newline at end of file + loadTemplate(this, getParameterByName("type"), providerId); + }); +}); diff --git a/src/controllers/livetvsettings.js b/src/controllers/livetvsettings.js index 422257e33d..2b11071c75 100644 --- a/src/controllers/livetvsettings.js +++ b/src/controllers/livetvsettings.js @@ -1,79 +1,127 @@ -define(["jQuery", "loading", "fnchecked", "emby-button"], function($, loading) { +define(["jQuery", "loading", "fnchecked", "emby-button"], function ($, loading) { "use strict"; function loadPage(page, config) { - $(".liveTvSettingsForm", page).show(), $(".noLiveTvServices", page).hide(), $("#selectGuideDays", page).val(config.GuideDays || ""), $("#txtPrePaddingMinutes", page).val(config.PrePaddingSeconds / 60), $("#txtPostPaddingMinutes", page).val(config.PostPaddingSeconds / 60), page.querySelector("#txtRecordingPath").value = config.RecordingPath || "", page.querySelector("#txtMovieRecordingPath").value = config.MovieRecordingPath || "", page.querySelector("#txtSeriesRecordingPath").value = config.SeriesRecordingPath || "", page.querySelector("#txtPostProcessor").value = config.RecordingPostProcessor || "", page.querySelector("#txtPostProcessorArguments").value = config.RecordingPostProcessorArguments || "", loading.hide() + $(".liveTvSettingsForm", page).show(); + $(".noLiveTvServices", page).hide(); + $("#selectGuideDays", page).val(config.GuideDays || ""); + $("#txtPrePaddingMinutes", page).val(config.PrePaddingSeconds / 60); + $("#txtPostPaddingMinutes", page).val(config.PostPaddingSeconds / 60); + page.querySelector("#txtRecordingPath").value = config.RecordingPath || ""; + page.querySelector("#txtMovieRecordingPath").value = config.MovieRecordingPath || ""; + page.querySelector("#txtSeriesRecordingPath").value = config.SeriesRecordingPath || ""; + page.querySelector("#txtPostProcessor").value = config.RecordingPostProcessor || ""; + page.querySelector("#txtPostProcessorArguments").value = config.RecordingPostProcessorArguments || ""; + loading.hide(); } function onSubmit() { loading.show(); var form = this; - return ApiClient.getNamedConfiguration("livetv").then(function(config) { + ApiClient.getNamedConfiguration("livetv").then(function (config) { config.GuideDays = $("#selectGuideDays", form).val() || null; - var recordingPath = form.querySelector("#txtRecordingPath").value || null, - movieRecordingPath = form.querySelector("#txtMovieRecordingPath").value || null, - seriesRecordingPath = form.querySelector("#txtSeriesRecordingPath").value || null, - recordingPathChanged = recordingPath != config.RecordingPath || movieRecordingPath != config.MovieRecordingPath || seriesRecordingPath != config.SeriesRecordingPath; - config.RecordingPath = recordingPath, config.MovieRecordingPath = movieRecordingPath, config.SeriesRecordingPath = seriesRecordingPath, config.RecordingEncodingFormat = "mkv", config.PrePaddingSeconds = 60 * $("#txtPrePaddingMinutes", form).val(), config.PostPaddingSeconds = 60 * $("#txtPostPaddingMinutes", form).val(), config.RecordingPostProcessor = $("#txtPostProcessor", form).val(), config.RecordingPostProcessorArguments = $("#txtPostProcessorArguments", form).val(), ApiClient.updateNamedConfiguration("livetv", config).then(function() { - Dashboard.processServerConfigurationUpdateResult(), showSaveMessage(recordingPathChanged) - }) - }), !1 + var recordingPath = form.querySelector("#txtRecordingPath").value || null; + var movieRecordingPath = form.querySelector("#txtMovieRecordingPath").value || null; + var seriesRecordingPath = form.querySelector("#txtSeriesRecordingPath").value || null; + var recordingPathChanged = recordingPath != config.RecordingPath || movieRecordingPath != config.MovieRecordingPath || seriesRecordingPath != config.SeriesRecordingPath; + config.RecordingPath = recordingPath; + config.MovieRecordingPath = movieRecordingPath; + config.SeriesRecordingPath = seriesRecordingPath; + config.RecordingEncodingFormat = "mkv"; + config.PrePaddingSeconds = 60 * $("#txtPrePaddingMinutes", form).val(); + config.PostPaddingSeconds = 60 * $("#txtPostPaddingMinutes", form).val(); + config.RecordingPostProcessor = $("#txtPostProcessor", form).val(); + config.RecordingPostProcessorArguments = $("#txtPostProcessorArguments", form).val(); + ApiClient.updateNamedConfiguration("livetv", config).then(function () { + Dashboard.processServerConfigurationUpdateResult(); + showSaveMessage(recordingPathChanged); + }); + }); + return false; } function showSaveMessage(recordingPathChanged) { var msg = ""; - recordingPathChanged && (msg += Globalize.translate("RecordingPathChangeMessage")), msg && require(["alert"], function(alert) { - alert(msg) - }) + + if (recordingPathChanged) { + msg += Globalize.translate("RecordingPathChangeMessage"); + } + + if (msg) { + require(["alert"], function (alert) { + alert(msg); + }); + } } - $(document).on("pageinit", "#liveTvSettingsPage", function() { + + $(document).on("pageinit", "#liveTvSettingsPage", function () { var page = this; - $(".liveTvSettingsForm").off("submit", onSubmit).on("submit", onSubmit), $("#btnSelectRecordingPath", page).on("click.selectDirectory", function() { - require(["directorybrowser"], function(directoryBrowser) { - var picker = new directoryBrowser; + $(".liveTvSettingsForm").off("submit", onSubmit).on("submit", onSubmit); + $("#btnSelectRecordingPath", page).on("click.selectDirectory", function () { + require(["directorybrowser"], function (directoryBrowser) { + var picker = new directoryBrowser(); picker.show({ - callback: function(path) { - path && $("#txtRecordingPath", page).val(path), picker.close() + callback: function (path) { + if (path) { + $("#txtRecordingPath", page).val(path); + } + + picker.close(); }, - validateWriteable: !0 - }) - }) - }), $("#btnSelectMovieRecordingPath", page).on("click.selectDirectory", function() { - require(["directorybrowser"], function(directoryBrowser) { - var picker = new directoryBrowser; + validateWriteable: true + }); + }); + }); + $("#btnSelectMovieRecordingPath", page).on("click.selectDirectory", function () { + require(["directorybrowser"], function (directoryBrowser) { + var picker = new directoryBrowser(); picker.show({ - callback: function(path) { - path && $("#txtMovieRecordingPath", page).val(path), picker.close() + callback: function (path) { + if (path) { + $("#txtMovieRecordingPath", page).val(path); + } + + picker.close(); }, - validateWriteable: !0 - }) - }) - }), $("#btnSelectSeriesRecordingPath", page).on("click.selectDirectory", function() { - require(["directorybrowser"], function(directoryBrowser) { - var picker = new directoryBrowser; + validateWriteable: true + }); + }); + }); + $("#btnSelectSeriesRecordingPath", page).on("click.selectDirectory", function () { + require(["directorybrowser"], function (directoryBrowser) { + var picker = new directoryBrowser(); picker.show({ - callback: function(path) { - path && $("#txtSeriesRecordingPath", page).val(path), picker.close() + callback: function (path) { + if (path) { + $("#txtSeriesRecordingPath", page).val(path); + } + + picker.close(); }, - validateWriteable: !0 - }) - }) - }), $("#btnSelectPostProcessorPath", page).on("click.selectDirectory", function() { - require(["directorybrowser"], function(directoryBrowser) { - var picker = new directoryBrowser; + validateWriteable: true + }); + }); + }); + $("#btnSelectPostProcessorPath", page).on("click.selectDirectory", function () { + require(["directorybrowser"], function (directoryBrowser) { + var picker = new directoryBrowser(); picker.show({ - includeFiles: !0, - callback: function(path) { - path && $("#txtPostProcessor", page).val(path), picker.close() + includeFiles: true, + callback: function (path) { + if (path) { + $("#txtPostProcessor", page).val(path); + } + + picker.close(); } - }) - }) - }) - }).on("pageshow", "#liveTvSettingsPage", function() { + }); + }); + }); + }).on("pageshow", "#liveTvSettingsPage", function () { loading.show(); var page = this; - ApiClient.getNamedConfiguration("livetv").then(function(config) { - loadPage(page, config) - }) - }) -}); \ No newline at end of file + ApiClient.getNamedConfiguration("livetv").then(function (config) { + loadPage(page, config); + }); + }); +}); diff --git a/src/controllers/livetvstatus.js b/src/controllers/livetvstatus.js index d268be2991..03cad1a907 100644 --- a/src/controllers/livetvstatus.js +++ b/src/controllers/livetvstatus.js @@ -1,42 +1,75 @@ -define(["jQuery", "globalize", "scripts/taskbutton", "dom", "libraryMenu", "layoutManager", "loading", "listViewStyle", "flexStyles", "emby-itemscontainer", "cardStyle", "material-icons", "emby-button"], function($, globalize, taskButton, dom, libraryMenu, layoutManager, loading) { +define(["jQuery", "globalize", "scripts/taskbutton", "dom", "libraryMenu", "layoutManager", "loading", "listViewStyle", "flexStyles", "emby-itemscontainer", "cardStyle", "material-icons", "emby-button"], function ($, globalize, taskButton, dom, libraryMenu, layoutManager, loading) { "use strict"; function getDeviceHtml(device) { - var padderClass, html = "", - cssClass = "card scalableCard", - cardBoxCssClass = "cardBox visualCardBox"; - return cssClass += " backdropCard backdropCard-scalable", padderClass = "cardPadder-backdrop", layoutManager.tv && (cssClass += " card-focusscale", cardBoxCssClass += " cardBox-focustransform"), cardBoxCssClass += " card-focuscontent", html += '
            ', html += '
            ', html += '
            ', html += '
            ', html += '
            ', html += '
            dvr
            ', html += "
            ", html += "
            ", html += '
            ', html += '', html += '
            ' + (device.FriendlyName || getTunerName(device.Type)) + "
            ", html += '
            ', html += device.Url || " ", html += "
            ", html += "
            ", html += "
            ", html += "
            " + var padderClass; + var html = ""; + var cssClass = "card scalableCard"; + var cardBoxCssClass = "cardBox visualCardBox"; + cssClass += " backdropCard backdropCard-scalable"; + padderClass = "cardPadder-backdrop"; + + if (layoutManager.tv) { + cssClass += " card-focusscale"; + cardBoxCssClass += " cardBox-focustransform"; + } + + cardBoxCssClass += " card-focuscontent"; + html += '
            '; + html += '
            '; + html += '
            '; + html += '
            '; + html += '
            '; + html += '
            dvr
            '; + html += "
            "; + html += "
            "; + html += '
            '; + html += ''; + html += '
            ' + (device.FriendlyName || getTunerName(device.Type)) + "
            "; + html += '
            '; + html += device.Url || " "; + html += "
            "; + html += "
            "; + html += "
            "; + return html += "
            "; } function renderDevices(page, devices) { var html = devices.map(getDeviceHtml).join(""); - page.querySelector(".devicesList").innerHTML = html + page.querySelector(".devicesList").innerHTML = html; } function deleteDevice(page, id) { var message = globalize.translate("MessageConfirmDeleteTunerDevice"); - require(["confirm"], function(confirm) { - confirm(message, globalize.translate("HeaderDeleteDevice")).then(function() { - loading.show(), ApiClient.ajax({ + + require(["confirm"], function (confirm) { + confirm(message, globalize.translate("HeaderDeleteDevice")).then(function () { + loading.show(); + ApiClient.ajax({ type: "DELETE", url: ApiClient.getUrl("LiveTv/TunerHosts", { Id: id }) - }).then(function() { - reload(page) - }) - }) - }) + }).then(function () { + reload(page); + }); + }); + }); } function reload(page) { - loading.show(), ApiClient.getNamedConfiguration("livetv").then(function(config) { - renderDevices(page, config.TunerHosts), renderProviders(page, config.ListingProviders) - }), loading.hide() + loading.show(); + ApiClient.getNamedConfiguration("livetv").then(function (config) { + renderDevices(page, config.TunerHosts); + renderProviders(page, config.ListingProviders); + }); + loading.hide(); } function submitAddDeviceForm(page) { - page.querySelector(".dlgAddDevice").close(), loading.show(), ApiClient.ajax({ + page.querySelector(".dlgAddDevice").close(); + loading.show(); + ApiClient.ajax({ type: "POST", url: ApiClient.getUrl("LiveTv/TunerHosts"), data: JSON.stringify({ @@ -44,30 +77,47 @@ define(["jQuery", "globalize", "scripts/taskbutton", "dom", "libraryMenu", "layo Url: $("#txtDevicePath", page).val() }), contentType: "application/json" - }).then(function() { - reload(page) - }, function() { + }).then(function () { + reload(page); + }, function () { Dashboard.alert({ message: globalize.translate("ErrorAddingTunerDevice") - }) - }) + }); + }); } function renderProviders(page, providers) { var html = ""; + if (providers.length) { html += '
            '; + for (var i = 0, length = providers.length; i < length; i++) { var provider = providers[i]; - html += '" + html += '"; } - html += "
            " + + html += "
"; } + var elem = $(".providerList", page).html(html); - $(".btnOptions", elem).on("click", function() { + $(".btnOptions", elem).on("click", function () { var id = this.getAttribute("data-id"); - showProviderOptions(page, id, this) - }) + showProviderOptions(page, id, this); + }); } function showProviderOptions(page, providerId, button) { @@ -75,64 +125,74 @@ define(["jQuery", "globalize", "scripts/taskbutton", "dom", "libraryMenu", "layo items.push({ name: globalize.translate("ButtonDelete"), id: "delete" - }), items.push({ + }); + items.push({ name: globalize.translate("MapChannels"), id: "map" - }), require(["actionsheet"], function(actionsheet) { + }); + + require(["actionsheet"], function (actionsheet) { actionsheet.show({ items: items, positionTo: button - }).then(function(id) { + }).then(function (id) { switch (id) { case "delete": deleteProvider(page, providerId); break; + case "map": - mapChannels(page, providerId) + mapChannels(page, providerId); } - }) - }) + }); + }); } function mapChannels(page, providerId) { - require(["components/channelmapper/channelmapper"], function(channelmapper) { + require(["components/channelmapper/channelmapper"], function (channelmapper) { new channelmapper({ serverId: ApiClient.serverInfo().Id, providerId: providerId - }).show() - }) + }).show(); + }); } function deleteProvider(page, id) { var message = globalize.translate("MessageConfirmDeleteGuideProvider"); - require(["confirm"], function(confirm) { - confirm(message, globalize.translate("HeaderDeleteProvider")).then(function() { - loading.show(), ApiClient.ajax({ + + require(["confirm"], function (confirm) { + confirm(message, globalize.translate("HeaderDeleteProvider")).then(function () { + loading.show(); + ApiClient.ajax({ type: "DELETE", url: ApiClient.getUrl("LiveTv/ListingProviders", { Id: id }) - }).then(function() { - reload(page) - }, function() { - reload(page) - }) - }) - }) + }).then(function () { + reload(page); + }, function () { + reload(page); + }); + }); + }); } function getTunerName(providerId) { switch (providerId = providerId.toLowerCase()) { case "m3u": return "M3U"; + case "hdhomerun": return "HDHomerun"; + case "hauppauge": return "Hauppauge"; + case "satip": return "DVB"; + default: - return "Unknown" + return "Unknown"; } } @@ -140,12 +200,15 @@ define(["jQuery", "globalize", "scripts/taskbutton", "dom", "libraryMenu", "layo switch (providerId = providerId.toLowerCase()) { case "schedulesdirect": return "Schedules Direct"; + case "xmltv": return "Xml TV"; + case "emby": return "Emby Guide"; + default: - return "Unknown" + return "Unknown"; } } @@ -153,10 +216,12 @@ define(["jQuery", "globalize", "scripts/taskbutton", "dom", "libraryMenu", "layo switch (providerId = providerId.toLowerCase()) { case "xmltv": return "livetvguideprovider.html?type=xmltv"; + case "schedulesdirect": return "livetvguideprovider.html?type=schedulesdirect"; + case "emby": - return "livetvguideprovider.html?type=emby" + return "livetvguideprovider.html?type=emby"; } } @@ -165,22 +230,25 @@ define(["jQuery", "globalize", "scripts/taskbutton", "dom", "libraryMenu", "layo menuItems.push({ name: "Schedules Direct", id: "SchedulesDirect" - }), menuItems.push({ + }); + menuItems.push({ name: "Xml TV", id: "xmltv" - }), require(["actionsheet"], function(actionsheet) { + }); + + require(["actionsheet"], function (actionsheet) { actionsheet.show({ items: menuItems, positionTo: button, - callback: function(id) { - Dashboard.navigate(getProviderConfigurationUrl(id)) + callback: function (id) { + Dashboard.navigate(getProviderConfigurationUrl(id)); } - }) - }) + }); + }); } function addDevice(button) { - Dashboard.navigate("livetvtuner.html") + Dashboard.navigate("livetvtuner.html"); } function showDeviceMenu(button, tunerDeviceId) { @@ -188,57 +256,73 @@ define(["jQuery", "globalize", "scripts/taskbutton", "dom", "libraryMenu", "layo items.push({ name: globalize.translate("ButtonDelete"), id: "delete" - }), items.push({ + }); + items.push({ name: globalize.translate("ButtonEdit"), id: "edit" - }), require(["actionsheet"], function(actionsheet) { + }); + + require(["actionsheet"], function (actionsheet) { actionsheet.show({ items: items, positionTo: button - }).then(function(id) { + }).then(function (id) { switch (id) { case "delete": deleteDevice(dom.parentWithClass(button, "page"), tunerDeviceId); break; + case "edit": - Dashboard.navigate("livetvtuner.html?id=" + tunerDeviceId) + Dashboard.navigate("livetvtuner.html?id=" + tunerDeviceId); } - }) - }) + }); + }); } function onDevicesListClick(e) { var card = dom.parentWithClass(e.target, "card"); + if (card) { - var id = card.getAttribute("data-id"), - btnCardOptions = dom.parentWithClass(e.target, "btnCardOptions"); - btnCardOptions ? showDeviceMenu(btnCardOptions, id) : Dashboard.navigate("livetvtuner.html?id=" + id) + var id = card.getAttribute("data-id"); + var btnCardOptions = dom.parentWithClass(e.target, "btnCardOptions"); + + if (btnCardOptions) { + showDeviceMenu(btnCardOptions, id); + } else { + Dashboard.navigate("livetvtuner.html?id=" + id); + } } } - $(document).on("pageinit", "#liveTvStatusPage", function() { + + $(document).on("pageinit", "#liveTvStatusPage", function () { var page = this; - $(".btnAddDevice", page).on("click", function() { - addDevice(this) - }), $(".formAddDevice", page).on("submit", function() { - return submitAddDeviceForm(page), !1 - }), $(".btnAddProvider", page).on("click", function() { - addProvider(this) - }), page.querySelector(".devicesList").addEventListener("click", onDevicesListClick) - }).on("pageshow", "#liveTvStatusPage", function() { + $(".btnAddDevice", page).on("click", function () { + addDevice(this); + }); + $(".formAddDevice", page).on("submit", function () { + submitAddDeviceForm(page); + return false; + }); + $(".btnAddProvider", page).on("click", function () { + addProvider(this); + }); + page.querySelector(".devicesList").addEventListener("click", onDevicesListClick); + }).on("pageshow", "#liveTvStatusPage", function () { var page = this; - reload(page), taskButton({ + reload(page); + taskButton({ mode: "on", progressElem: page.querySelector(".refreshGuideProgress"), taskKey: "RefreshGuide", button: page.querySelector(".btnRefresh") - }) - }).on("pagehide", "#liveTvStatusPage", function() { + }); + }).on("pagehide", "#liveTvStatusPage", function () { var page = this; taskButton({ mode: "off", progressElem: page.querySelector(".refreshGuideProgress"), taskKey: "RefreshGuide", button: page.querySelector(".btnRefresh") - }) - }) + }); + }); }); diff --git a/src/controllers/livetvtuner.js b/src/controllers/livetvtuner.js index 43082e6844..55a86d4be7 100644 --- a/src/controllers/livetvtuner.js +++ b/src/controllers/livetvtuner.js @@ -1,4 +1,4 @@ -define(["globalize", "loading", "libraryMenu", "dom", "emby-input", "emby-button", "emby-checkbox", "emby-select"], function(globalize, loading, libraryMenu, dom) { +define(["globalize", "loading", "libraryMenu", "dom", "emby-input", "emby-button", "emby-checkbox", "emby-select"], function (globalize, loading, libraryMenu, dom) { "use strict"; function isM3uVariant(type) { @@ -6,17 +6,16 @@ define(["globalize", "loading", "libraryMenu", "dom", "emby-input", "emby-button } function fillTypes(view, currentId) { - return ApiClient.getJSON(ApiClient.getUrl("LiveTv/TunerHosts/Types")).then(function(types) { + return ApiClient.getJSON(ApiClient.getUrl("LiveTv/TunerHosts/Types")).then(function (types) { var selectType = view.querySelector(".selectType"); var html = ""; - html += types.map(function(tuner) { + html += types.map(function (tuner) { return '"; }).join(""); html += '"; selectType.innerHTML = html; - selectType.disabled = null != currentId; selectType.value = ""; onTypeChange.call(selectType); @@ -27,9 +26,10 @@ define(["globalize", "loading", "libraryMenu", "dom", "emby-input", "emby-button view.querySelector(".txtDevicePath").value = ""; view.querySelector(".chkFavorite").checked = false; view.querySelector(".txtDevicePath").value = ""; + if (providerId) { - ApiClient.getNamedConfiguration("livetv").then(function(config) { - var info = config.TunerHosts.filter(function(i) { + ApiClient.getNamedConfiguration("livetv").then(function (config) { + var info = config.TunerHosts.filter(function (i) { return i.Id === providerId; })[0]; fillTunerHostInfo(view, info); @@ -40,9 +40,11 @@ define(["globalize", "loading", "libraryMenu", "dom", "emby-input", "emby-button function fillTunerHostInfo(view, info) { var selectType = view.querySelector(".selectType"); var type = info.Type || ""; + if (info.Source && isM3uVariant(info.Source)) { type = info.Source; } + selectType.value = type; onTypeChange.call(selectType); view.querySelector(".txtDevicePath").value = info.Url || ""; @@ -68,76 +70,164 @@ define(["globalize", "loading", "libraryMenu", "dom", "emby-input", "emby-button AllowHWTranscoding: page.querySelector(".chkTranscode").checked, EnableStreamLooping: page.querySelector(".chkStreamLoop").checked }; - isM3uVariant(info.Type) && (info.Source = info.Type, info.Type = "m3u"); + + if (isM3uVariant(info.Type)) { + info.Source = info.Type; + info.Type = "m3u"; + } + var id = getParameterByName("id"); - id && (info.Id = id); + + if (id) { + info.Id = id; + } + info.Id; ApiClient.ajax({ type: "POST", url: ApiClient.getUrl("LiveTv/TunerHosts"), data: JSON.stringify(info), contentType: "application/json" - }).then(function(result) { - Dashboard.processServerConfigurationUpdateResult(), Dashboard.navigate("livetvstatus.html") - }, function() { - loading.hide(), Dashboard.alert({ + }).then(function (result) { + Dashboard.processServerConfigurationUpdateResult(); + Dashboard.navigate("livetvstatus.html"); + }, function () { + loading.hide(); + Dashboard.alert({ message: globalize.translate("ErrorSavingTvProvider") - }) - }) + }); + }); } function getRequirePromise(deps) { - return new Promise(function(resolve, reject) { - require(deps, resolve) - }) + return new Promise(function (resolve, reject) { + require(deps, resolve); + }); } function getDetectedDevice() { - return getRequirePromise(["tunerPicker"]).then(function(tunerPicker) { - return (new tunerPicker).show({ + return getRequirePromise(["tunerPicker"]).then(function (tunerPicker) { + return new tunerPicker().show({ serverId: ApiClient.serverId() - }) - }) + }); + }); } function onTypeChange() { - var value = this.value, - view = dom.parentWithClass(this, "page"), - mayIncludeUnsupportedDrmChannels = "hdhomerun" === value, - supportsTranscoding = "hdhomerun" === value, - supportsFavorites = "hdhomerun" === value, - supportsTunerIpAddress = "hdhomerun" === value, - supportsTunerFileOrUrl = "m3u" === value, - supportsStreamLooping = "m3u" === value, - supportsTunerCount = "m3u" === value, - supportsUserAgent = "m3u" === value, - suppportsSubmit = "other" !== value, - supportsSelectablePath = supportsTunerFileOrUrl, - txtDevicePath = view.querySelector(".txtDevicePath"); - supportsTunerIpAddress ? (txtDevicePath.label(globalize.translate("LabelTunerIpAddress")), view.querySelector(".fldPath").classList.remove("hide")) : supportsTunerFileOrUrl ? (txtDevicePath.label(globalize.translate("LabelFileOrUrl")), view.querySelector(".fldPath").classList.remove("hide")) : view.querySelector(".fldPath").classList.add("hide"), supportsSelectablePath ? (view.querySelector(".btnSelectPath").classList.remove("hide"), view.querySelector(".txtDevicePath").setAttribute("required", "required")) : (view.querySelector(".btnSelectPath").classList.add("hide"), view.querySelector(".txtDevicePath").removeAttribute("required")), supportsUserAgent ? view.querySelector(".fldUserAgent").classList.remove("hide") : view.querySelector(".fldUserAgent").classList.add("hide"), supportsFavorites ? view.querySelector(".fldFavorites").classList.remove("hide") : view.querySelector(".fldFavorites").classList.add("hide"), supportsTranscoding ? view.querySelector(".fldTranscode").classList.remove("hide") : view.querySelector(".fldTranscode").classList.add("hide"), supportsStreamLooping ? view.querySelector(".fldStreamLoop").classList.remove("hide") : view.querySelector(".fldStreamLoop").classList.add("hide"), supportsTunerCount ? (view.querySelector(".fldTunerCount").classList.remove("hide"), view.querySelector(".txtTunerCount").setAttribute("required", "required")) : (view.querySelector(".fldTunerCount").classList.add("hide"), view.querySelector(".txtTunerCount").removeAttribute("required")), mayIncludeUnsupportedDrmChannels ? view.querySelector(".drmMessage").classList.remove("hide") : view.querySelector(".drmMessage").classList.add("hide"), suppportsSubmit ? view.querySelector(".button-submit").classList.remove("hide") : view.querySelector(".button-submit").classList.add("hide") + var value = this.value; + var view = dom.parentWithClass(this, "page"); + var mayIncludeUnsupportedDrmChannels = "hdhomerun" === value; + var supportsTranscoding = "hdhomerun" === value; + var supportsFavorites = "hdhomerun" === value; + var supportsTunerIpAddress = "hdhomerun" === value; + var supportsTunerFileOrUrl = "m3u" === value; + var supportsStreamLooping = "m3u" === value; + var supportsTunerCount = "m3u" === value; + var supportsUserAgent = "m3u" === value; + var suppportsSubmit = "other" !== value; + var supportsSelectablePath = supportsTunerFileOrUrl; + var txtDevicePath = view.querySelector(".txtDevicePath"); + + if (supportsTunerIpAddress) { + txtDevicePath.label(globalize.translate("LabelTunerIpAddress")); + view.querySelector(".fldPath").classList.remove("hide"); + } else if (supportsTunerFileOrUrl) { + txtDevicePath.label(globalize.translate("LabelFileOrUrl")); + view.querySelector(".fldPath").classList.remove("hide"); + } else { + view.querySelector(".fldPath").classList.add("hide"); + } + + if (supportsSelectablePath) { + view.querySelector(".btnSelectPath").classList.remove("hide"); + view.querySelector(".txtDevicePath").setAttribute("required", "required"); + } else { + view.querySelector(".btnSelectPath").classList.add("hide"); + view.querySelector(".txtDevicePath").removeAttribute("required"); + } + + if (supportsUserAgent) { + view.querySelector(".fldUserAgent").classList.remove("hide"); + } else { + view.querySelector(".fldUserAgent").classList.add("hide"); + } + + if (supportsFavorites) { + view.querySelector(".fldFavorites").classList.remove("hide"); + } else { + view.querySelector(".fldFavorites").classList.add("hide"); + } + + if (supportsTranscoding) { + view.querySelector(".fldTranscode").classList.remove("hide"); + } else { + view.querySelector(".fldTranscode").classList.add("hide"); + } + + if (supportsStreamLooping) { + view.querySelector(".fldStreamLoop").classList.remove("hide"); + } else { + view.querySelector(".fldStreamLoop").classList.add("hide"); + } + + if (supportsTunerCount) { + view.querySelector(".fldTunerCount").classList.remove("hide"); + view.querySelector(".txtTunerCount").setAttribute("required", "required"); + } else { + view.querySelector(".fldTunerCount").classList.add("hide"); + view.querySelector(".txtTunerCount").removeAttribute("required"); + } + + if (mayIncludeUnsupportedDrmChannels) { + view.querySelector(".drmMessage").classList.remove("hide"); + } else { + view.querySelector(".drmMessage").classList.add("hide"); + } + + if (suppportsSubmit) { + view.querySelector(".button-submit").classList.remove("hide"); + } else { + view.querySelector(".button-submit").classList.add("hide"); + } } - return function(view, params) { - params.id || view.querySelector(".btnDetect").classList.remove("hide"), view.addEventListener("viewshow", function() { + + return function (view, params) { + if (!params.id) { + view.querySelector(".btnDetect").classList.remove("hide"); + } + + view.addEventListener("viewshow", function () { var currentId = params.id; - fillTypes(view, currentId).then(function() { - reload(view, currentId) - }) - }), view.querySelector("form").addEventListener("submit", function(e) { - return submitForm(view), e.preventDefault(), e.stopPropagation(), !1 - }), view.querySelector(".selectType").addEventListener("change", onTypeChange), view.querySelector(".btnDetect").addEventListener("click", function() { - getDetectedDevice().then(function(info) { - fillTunerHostInfo(view, info) - }) - }), view.querySelector(".btnSelectPath").addEventListener("click", function() { - require(["directorybrowser"], function(directoryBrowser) { - var picker = new directoryBrowser; + fillTypes(view, currentId).then(function () { + reload(view, currentId); + }); + }); + view.querySelector("form").addEventListener("submit", function (e) { + submitForm(view); + e.preventDefault(); + e.stopPropagation(); + return false; + }); + view.querySelector(".selectType").addEventListener("change", onTypeChange); + view.querySelector(".btnDetect").addEventListener("click", function () { + getDetectedDevice().then(function (info) { + fillTunerHostInfo(view, info); + }); + }); + view.querySelector(".btnSelectPath").addEventListener("click", function () { + require(["directorybrowser"], function (directoryBrowser) { + var picker = new directoryBrowser(); picker.show({ - includeFiles: !0, - callback: function(path) { - path && (view.querySelector(".txtDevicePath").value = path), picker.close() + includeFiles: true, + callback: function (path) { + if (path) { + view.querySelector(".txtDevicePath").value = path; + } + + picker.close(); } - }) - }) - }) - } -}); \ No newline at end of file + }); + }); + }); + }; +}); diff --git a/src/controllers/metadatanfo.js b/src/controllers/metadatanfo.js index 1de17ae836..20049837dd 100644 --- a/src/controllers/metadatanfo.js +++ b/src/controllers/metadatanfo.js @@ -1,30 +1,45 @@ -define(["jQuery", "loading", "libraryMenu"], function($, loading, libraryMenu) { +define(["jQuery", "loading", "libraryMenu"], function ($, loading, libraryMenu) { "use strict"; function loadPage(page, config, users) { var html = '"; - html += users.map(function(user) { - return '" - }).join(""), $("#selectUser", page).html(html).val(config.UserId || ""), $("#selectReleaseDateFormat", page).val(config.ReleaseDateFormat), page.querySelector("#chkSaveImagePaths").checked = config.SaveImagePathsInNfo, page.querySelector("#chkEnablePathSubstitution").checked = config.EnablePathSubstitution, page.querySelector("#chkEnableExtraThumbs").checked = config.EnableExtraThumbsDuplication, loading.hide() + html += users.map(function (user) { + return '"; + }).join(""); + $("#selectUser", page).html(html).val(config.UserId || ""); + $("#selectReleaseDateFormat", page).val(config.ReleaseDateFormat); + page.querySelector("#chkSaveImagePaths").checked = config.SaveImagePathsInNfo; + page.querySelector("#chkEnablePathSubstitution").checked = config.EnablePathSubstitution; + page.querySelector("#chkEnableExtraThumbs").checked = config.EnableExtraThumbsDuplication; + loading.hide(); } function onSubmit() { loading.show(); var form = this; - return ApiClient.getNamedConfiguration(metadataKey).then(function(config) { - config.UserId = $("#selectUser", form).val() || null, config.ReleaseDateFormat = $("#selectReleaseDateFormat", form).val(), config.SaveImagePathsInNfo = form.querySelector("#chkSaveImagePaths").checked, config.EnablePathSubstitution = form.querySelector("#chkEnablePathSubstitution").checked, config.EnableExtraThumbsDuplication = form.querySelector("#chkEnableExtraThumbs").checked, ApiClient.updateNamedConfiguration(metadataKey, config).then(function() { - Dashboard.processServerConfigurationUpdateResult(), showConfirmMessage(config) - }) - }), !1 + ApiClient.getNamedConfiguration(metadataKey).then(function (config) { + config.UserId = $("#selectUser", form).val() || null; + config.ReleaseDateFormat = $("#selectReleaseDateFormat", form).val(); + config.SaveImagePathsInNfo = form.querySelector("#chkSaveImagePaths").checked; + config.EnablePathSubstitution = form.querySelector("#chkEnablePathSubstitution").checked; + config.EnableExtraThumbsDuplication = form.querySelector("#chkEnableExtraThumbs").checked; + ApiClient.updateNamedConfiguration(metadataKey, config).then(function () { + Dashboard.processServerConfigurationUpdateResult(); + showConfirmMessage(config); + }); + }); + return false; } function showConfirmMessage(config) { var msg = []; - msg.push(Globalize.translate("MetadataSettingChangeHelp")), require(["alert"], function(alert) { + msg.push(Globalize.translate("MetadataSettingChangeHelp")); + + require(["alert"], function (alert) { alert({ text: msg.join("

") - }) - }) + }); + }); } function getTabs() { @@ -40,19 +55,20 @@ define(["jQuery", "loading", "libraryMenu"], function($, loading, libraryMenu) { }, { href: "metadatanfo.html", name: Globalize.translate("TabNfoSettings") - }] + }]; } var metadataKey = "xbmcmetadata"; - $(document).on("pageinit", "#metadataNfoPage", function() { - $(".metadataNfoForm").off("submit", onSubmit).on("submit", onSubmit) - }).on("pageshow", "#metadataNfoPage", function() { - libraryMenu.setTabs("metadata", 3, getTabs), loading.show(); - var page = this, - promise1 = ApiClient.getUsers(), - promise2 = ApiClient.getNamedConfiguration(metadataKey); - Promise.all([promise1, promise2]).then(function(responses) { - loadPage(page, responses[1], responses[0]) - }) - }) -}); \ No newline at end of file + $(document).on("pageinit", "#metadataNfoPage", function () { + $(".metadataNfoForm").off("submit", onSubmit).on("submit", onSubmit); + }).on("pageshow", "#metadataNfoPage", function () { + libraryMenu.setTabs("metadata", 3, getTabs); + loading.show(); + var page = this; + var promise1 = ApiClient.getUsers(); + var promise2 = ApiClient.getNamedConfiguration(metadataKey); + Promise.all([promise1, promise2]).then(function (responses) { + loadPage(page, responses[1], responses[0]); + }); + }); +}); diff --git a/src/controllers/movies/moviecollections.js b/src/controllers/movies/moviecollections.js index 1e83f11f3c..d5bd96d349 100644 --- a/src/controllers/movies/moviecollections.js +++ b/src/controllers/movies/moviecollections.js @@ -1,9 +1,11 @@ -define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function(loading, events, libraryBrowser, imageLoader, listView, cardBuilder, appHost) { +define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder, appHost) { "use strict"; - return function(view, params, tabContent) { + + return function (view, params, tabContent) { function getPageData(context) { - var key = getSavedQueryKey(context), - pageData = data[key]; + var key = getSavedQueryKey(context); + var pageData = data[key]; + if (!pageData) { pageData = data[key] = { query: { @@ -22,153 +24,223 @@ define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardB pageData.query.ParentId = params.topParentId; libraryBrowser.loadSavedQueryValues(key, pageData.query); } + return pageData; } function getQuery(context) { - return getPageData(context).query + return getPageData(context).query; } function getSavedQueryKey(context) { - return context.savedQueryKey || (context.savedQueryKey = libraryBrowser.getSavedQueryKey("moviecollections")), context.savedQueryKey + if (!context.savedQueryKey) { + context.savedQueryKey = libraryBrowser.getSavedQueryKey("moviecollections"); + } + + return context.savedQueryKey; } function onViewStyleChange() { - var viewStyle = self.getCurrentViewStyle(), - itemsContainer = tabContent.querySelector(".itemsContainer"); - "List" == viewStyle ? (itemsContainer.classList.add("vertical-list"), itemsContainer.classList.remove("vertical-wrap")) : (itemsContainer.classList.remove("vertical-list"), itemsContainer.classList.add("vertical-wrap")), itemsContainer.innerHTML = "" + var viewStyle = self.getCurrentViewStyle(); + var itemsContainer = tabContent.querySelector(".itemsContainer"); + + if ("List" == viewStyle) { + itemsContainer.classList.add("vertical-list"); + itemsContainer.classList.remove("vertical-wrap"); + } else { + itemsContainer.classList.remove("vertical-list"); + itemsContainer.classList.add("vertical-wrap"); + } + + itemsContainer.innerHTML = ""; } function reloadItems(page) { loading.show(); isLoading = true; var query = getQuery(page); - ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function(result) { + ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) { function onNextPageClick() { - if (isLoading) return; - query.StartIndex += query.Limit, reloadItems(tabContent) + if (isLoading) { + return; + } + + query.StartIndex += query.Limit; + reloadItems(tabContent); } function onPreviousPageClick() { - if (isLoading) return; - query.StartIndex -= query.Limit, reloadItems(tabContent) + if (isLoading) { + return; + } + + query.StartIndex -= query.Limit; + reloadItems(tabContent); } + window.scrollTo(0, 0); - var html, pagingHtml = libraryBrowser.getQueryPagingHtml({ - startIndex: query.StartIndex, - limit: query.Limit, - totalRecordCount: result.TotalRecordCount, - showLimit: !1, - updatePageSizeSetting: !1, - addLayoutButton: !1, - sortButton: !1, - filterButton: !1 - }), - viewStyle = self.getCurrentViewStyle(); - html = "Thumb" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "backdrop", - preferThumb: !0, - context: "movies", - overlayPlayButton: !0, - centerText: !0, - showTitle: !0 - }) : "ThumbCard" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "backdrop", - preferThumb: !0, - context: "movies", - lazy: !0, - cardLayout: !0, - showTitle: !0 - }) : "Banner" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "banner", - preferBanner: !0, - context: "movies", - lazy: !0 - }) : "List" == viewStyle ? listView.getListViewHtml({ - items: result.Items, - context: "movies", - sortBy: query.SortBy - }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "auto", - context: "movies", - showTitle: !0, - centerText: !1, - cardLayout: !0 - }) : cardBuilder.getCardsHtml({ - items: result.Items, - shape: "auto", - context: "movies", - centerText: !0, - overlayPlayButton: !0, - showTitle: !0 + var html; + var pagingHtml = libraryBrowser.getQueryPagingHtml({ + startIndex: query.StartIndex, + limit: query.Limit, + totalRecordCount: result.TotalRecordCount, + showLimit: false, + updatePageSizeSetting: false, + addLayoutButton: false, + sortButton: false, + filterButton: false }); - var i, length, elems = tabContent.querySelectorAll(".paging"); - for (i = 0, length = elems.length; i < length; i++) elems[i].innerHTML = pagingHtml; - for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick); - for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick); - result.Items.length || (html = '

' + Globalize.translate("MessageNoCollectionsAvailable") + "

"); + var viewStyle = self.getCurrentViewStyle(); + if (viewStyle == "Thumb") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "backdrop", + preferThumb: true, + context: "movies", + overlayPlayButton: true, + centerText: true, + showTitle: true + }); + } else if (viewStyle == "ThumbCard") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "backdrop", + preferThumb: true, + context: "movies", + lazy: true, + cardLayout: true, + showTitle: true + }); + } else if (viewStyle == "Banner") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "banner", + preferBanner: true, + context: "movies", + lazy: true + }); + } else if (viewStyle == "List") { + html = listView.getListViewHtml({ + items: result.Items, + context: "movies", + sortBy: query.SortBy + }); + } else if (viewStyle == "PosterCard") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "auto", + context: "movies", + showTitle: true, + centerText: false, + cardLayout: true + }); + } else { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "auto", + context: "movies", + centerText: true, + overlayPlayButton: true, + showTitle: true + }); + } + var i; + var length; + var elems = tabContent.querySelectorAll(".paging"); + + for (i = 0, length = elems.length; i < length; i++) { + elems[i].innerHTML = pagingHtml; + } + + elems = tabContent.querySelectorAll(".btnNextPage"); + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onNextPageClick); + } + + elems = tabContent.querySelectorAll(".btnPreviousPage"); + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onPreviousPageClick); + } + + if (!result.Items.length) { + html = '

' + Globalize.translate("MessageNoCollectionsAvailable") + "

"; + } + var itemsContainer = tabContent.querySelector(".itemsContainer"); itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); libraryBrowser.saveQueryValues(getSavedQueryKey(page), query); loading.hide(); isLoading = false; - }) + }); } - var self = this, - pageSize = 100, - data = {}, - isLoading = false; - self.getCurrentViewStyle = function() { - return getPageData(tabContent).view - }, - function(tabContent) { - tabContent.querySelector(".btnSort").addEventListener("click", function(e) { - libraryBrowser.showSortMenu({ - items: [{ - name: Globalize.translate("OptionNameSort"), - id: "SortName" - }, { - name: Globalize.translate("OptionImdbRating"), - id: "CommunityRating,SortName" - }, { - name: Globalize.translate("OptionDateAdded"), - id: "DateCreated,SortName" - }, { - name: Globalize.translate("OptionParentalRating"), - id: "OfficialRating,SortName" - }, { - name: Globalize.translate("OptionReleaseDate"), - id: "PremiereDate,SortName" - }], - callback: function() { - getQuery(tabContent).StartIndex = 0, reloadItems(tabContent) - }, - query: getQuery(tabContent), - button: e.target - }) + + var self = this; + var pageSize = 100; + var data = {}; + var isLoading = false; + + self.getCurrentViewStyle = function () { + return getPageData(tabContent).view; + }; + + function initPage(tabContent) { + tabContent.querySelector(".btnSort").addEventListener("click", function (e) { + libraryBrowser.showSortMenu({ + items: [{ + name: Globalize.translate("OptionNameSort"), + id: "SortName" + }, { + name: Globalize.translate("OptionImdbRating"), + id: "CommunityRating,SortName" + }, { + name: Globalize.translate("OptionDateAdded"), + id: "DateCreated,SortName" + }, { + name: Globalize.translate("OptionParentalRating"), + id: "OfficialRating,SortName" + }, { + name: Globalize.translate("OptionReleaseDate"), + id: "PremiereDate,SortName" + }], + callback: function () { + getQuery(tabContent).StartIndex = 0; + reloadItems(tabContent); + }, + query: getQuery(tabContent), + button: e.target }); - var btnSelectView = tabContent.querySelector(".btnSelectView"); - btnSelectView.addEventListener("click", function(e) { - libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard,Thumb,ThumbCard".split(",")) - }), btnSelectView.addEventListener("layoutchange", function(e) { - var viewStyle = e.detail.viewStyle; - getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), getQuery(tabContent).StartIndex = 0, onViewStyleChange(), reloadItems(tabContent) - }), tabContent.querySelector(".btnNewCollection").addEventListener("click", function() { - require(["collectionEditor"], function(collectionEditor) { - var serverId = ApiClient.serverInfo().Id; - (new collectionEditor).show({ - items: [], - serverId: serverId - }) - }) - }) - }(tabContent), onViewStyleChange(), self.renderTab = function() { - reloadItems(tabContent) - }, self.destroy = function() {} - } + }); + var btnSelectView = tabContent.querySelector(".btnSelectView"); + btnSelectView.addEventListener("click", function (e) { + libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard,Thumb,ThumbCard".split(",")); + }); + btnSelectView.addEventListener("layoutchange", function (e) { + var viewStyle = e.detail.viewStyle; + getPageData(tabContent).view = viewStyle; + libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle); + getQuery(tabContent).StartIndex = 0; + onViewStyleChange(); + reloadItems(tabContent); + }); + tabContent.querySelector(".btnNewCollection").addEventListener("click", function () { + require(["collectionEditor"], function (collectionEditor) { + var serverId = ApiClient.serverInfo().Id; + new collectionEditor().show({ + items: [], + serverId: serverId + }); + }); + }); + } + + initPage(tabContent); + onViewStyleChange(); + + self.renderTab = function () { + reloadItems(tabContent); + }; + + self.destroy = function () {}; + }; }); diff --git a/src/controllers/movies/moviegenres.js b/src/controllers/movies/moviegenres.js index 78fd601fd7..80197b01cc 100644 --- a/src/controllers/movies/moviegenres.js +++ b/src/controllers/movies/moviegenres.js @@ -1,139 +1,204 @@ -define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader", "apphost", "globalize", "appRouter", "dom", "emby-button"], function(layoutManager, loading, libraryBrowser, cardBuilder, lazyLoader, appHost, globalize, appRouter, dom) { +define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader", "apphost", "globalize", "appRouter", "dom", "emby-button"], function (layoutManager, loading, libraryBrowser, cardBuilder, lazyLoader, appHost, globalize, appRouter, dom) { "use strict"; - return function(view, params, tabContent) { + + return function (view, params, tabContent) { function getPageData() { - var key = getSavedQueryKey(), - pageData = data[key]; - return pageData || (pageData = data[key] = { - query: { - SortBy: "SortName", - SortOrder: "Ascending", - IncludeItemTypes: "Movie", - Recursive: !0, - EnableTotalRecordCount: !1 - }, - view: "Poster" - }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData + var key = getSavedQueryKey(); + var pageData = data[key]; + + if (!pageData) { + pageData = data[key] = { + query: { + SortBy: "SortName", + SortOrder: "Ascending", + IncludeItemTypes: "Movie", + Recursive: true, + EnableTotalRecordCount: false + }, + view: "Poster" + }; + pageData.query.ParentId = params.topParentId; + libraryBrowser.loadSavedQueryValues(key, pageData.query); + } + + return pageData; } function getQuery() { - return getPageData().query + return getPageData().query; } function getSavedQueryKey() { - return libraryBrowser.getSavedQueryKey("moviegenres") + return libraryBrowser.getSavedQueryKey("moviegenres"); } function getPromise() { loading.show(); var query = getQuery(); - return ApiClient.getGenres(ApiClient.getCurrentUserId(), query) + return ApiClient.getGenres(ApiClient.getCurrentUserId(), query); } function enableScrollX() { - return !layoutManager.desktop + return !layoutManager.desktop; } function getThumbShape() { - return enableScrollX() ? "overflowBackdrop" : "backdrop" + return enableScrollX() ? "overflowBackdrop" : "backdrop"; } function getPortraitShape() { - return enableScrollX() ? "overflowPortrait" : "portrait" + return enableScrollX() ? "overflowPortrait" : "portrait"; } function fillItemsContainer(elem) { - var id = elem.getAttribute("data-id"), - viewStyle = self.getCurrentViewStyle(), - limit = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? 5 : 9; - enableScrollX() && (limit = 10); - var enableImageTypes = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? "Primary,Backdrop,Thumb" : "Primary", - query = { - SortBy: "SortName", - SortOrder: "Ascending", - IncludeItemTypes: "Movie", - Recursive: !0, - Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo", - ImageTypeLimit: 1, - EnableImageTypes: enableImageTypes, - Limit: limit, - GenreIds: id, - EnableTotalRecordCount: !1, - ParentId: params.topParentId - }; - ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function(result) { + var id = elem.getAttribute("data-id"); + var viewStyle = self.getCurrentViewStyle(); + var limit = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? 5 : 9; + + if (enableScrollX()) { + limit = 10; + } + + var enableImageTypes = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? "Primary,Backdrop,Thumb" : "Primary"; + var query = { + SortBy: "SortName", + SortOrder: "Ascending", + IncludeItemTypes: "Movie", + Recursive: true, + Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo", + ImageTypeLimit: 1, + EnableImageTypes: enableImageTypes, + Limit: limit, + GenreIds: id, + EnableTotalRecordCount: false, + ParentId: params.topParentId + }; + ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) { var supportsImageAnalysis = appHost.supports("imageanalysis"); - "Thumb" == viewStyle ? cardBuilder.buildCards(result.Items, { - itemsContainer: elem, - shape: getThumbShape(), - preferThumb: !0, - showTitle: !0, - scalable: !0, - centerText: !0, - overlayMoreButton: !0, - allowBottomPadding: !1 - }) : "ThumbCard" == viewStyle ? cardBuilder.buildCards(result.Items, { - itemsContainer: elem, - shape: getThumbShape(), - preferThumb: !0, - showTitle: !0, - scalable: !0, - centerText: !1, - cardLayout: !0, - showYear: !0 - }) : "PosterCard" == viewStyle ? cardBuilder.buildCards(result.Items, { - itemsContainer: elem, - shape: getPortraitShape(), - showTitle: !0, - scalable: !0, - centerText: !1, - cardLayout: !0, - showYear: !0 - }) : "Poster" == viewStyle && cardBuilder.buildCards(result.Items, { - itemsContainer: elem, - shape: getPortraitShape(), - scalable: !0, - overlayMoreButton: !0, - allowBottomPadding: !1 - }), result.Items.length >= query.Limit && tabContent.querySelector(".btnMoreFromGenre" + id + " i").classList.remove("hide") - }) + + if (viewStyle == "Thumb") { + cardBuilder.buildCards(result.Items, { + itemsContainer: elem, + shape: getThumbShape(), + preferThumb: true, + showTitle: true, + scalable: true, + centerText: true, + overlayMoreButton: true, + allowBottomPadding: false + }); + } else if (viewStyle == "ThumbCard") { + cardBuilder.buildCards(result.Items, { + itemsContainer: elem, + shape: getThumbShape(), + preferThumb: true, + showTitle: true, + scalable: true, + centerText: false, + cardLayout: true, + showYear: true + }); + } else if (viewStyle == "PosterCard") { + cardBuilder.buildCards(result.Items, { + itemsContainer: elem, + shape: getPortraitShape(), + showTitle: true, + scalable: true, + centerText: false, + cardLayout: true, + showYear: true + }); + } else if (viewStyle == "Poster") { + cardBuilder.buildCards(result.Items, { + itemsContainer: elem, + shape: getPortraitShape(), + scalable: true, + overlayMoreButton: true, + allowBottomPadding: false + }); + } + if (result.Items.length >= query.Limit) { + tabContent.querySelector(".btnMoreFromGenre" + id + " i").classList.remove("hide"); + } + }); } function reloadItems(context, promise) { var query = getQuery(); - promise.then(function(result) { - for (var elem = context.querySelector("#items"), html = "", items = result.Items, i = 0, length = items.length; i < length; i++) { + promise.then(function (result) { + var elem = context.querySelector("#items"); + var html = ""; + var items = result.Items; + + for (var i = 0, length = items.length; i < length; i++) { var item = items[i]; - if (html += '
', html += '", enableScrollX()) { + + html += '
'; + html += '"; + if (enableScrollX()) { var scrollXClass = "scrollX hiddenScrollX"; - layoutManager.tv && (scrollXClass += " smoothScrollX"), html += '
' - } else html += '
'; - html += "
", html += "
" + + if (layoutManager.tv) { + scrollXClass += "smoothScrollX"; + } + + html += '
'; + } else { + html += '
'; + } + + html += "
"; + html += "
"; } - elem.innerHTML = html, lazyLoader.lazyChildren(elem, fillItemsContainer), libraryBrowser.saveQueryValues(getSavedQueryKey(), query), loading.hide() - }) + + elem.innerHTML = html; + lazyLoader.lazyChildren(elem, fillItemsContainer); + libraryBrowser.saveQueryValues(getSavedQueryKey(), query); + loading.hide(); + }); } function fullyReload() { - self.preRender(), self.renderTab() + self.preRender(); + self.renderTab(); } - var self = this, - data = {}; - self.getViewStyles = function() { - return "Poster,PosterCard,Thumb,ThumbCard".split(",") - }, self.getCurrentViewStyle = function() { - return getPageData(tabContent).view - }, self.setCurrentViewStyle = function(viewStyle) { - getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), fullyReload() - }, self.enableViewSelection = !0; + + var self = this; + var data = {}; + + self.getViewStyles = function () { + return "Poster,PosterCard,Thumb,ThumbCard".split(","); + }; + + self.getCurrentViewStyle = function () { + return getPageData(tabContent).view; + }; + + self.setCurrentViewStyle = function (viewStyle) { + getPageData(tabContent).view = viewStyle; + libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle); + fullyReload(); + }; + + self.enableViewSelection = true; var promise; - self.preRender = function() { - promise = getPromise() - }, self.renderTab = function() { - reloadItems(tabContent, promise) - } - } -}); \ No newline at end of file + + self.preRender = function () { + promise = getPromise(); + }; + + self.renderTab = function () { + reloadItems(tabContent, promise); + }; + }; +}); diff --git a/src/controllers/movies/movies.js b/src/controllers/movies/movies.js index e0a5947ca6..b4e30602fd 100644 --- a/src/controllers/movies/movies.js +++ b/src/controllers/movies/movies.js @@ -1,7 +1,7 @@ -define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser", "alphaPicker", "listView", "cardBuilder", "emby-itemscontainer"], - function(loading, layoutManager, userSettings, events, libraryBrowser, alphaPicker, listView, cardBuilder) { +define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser", "alphaPicker", "listView", "cardBuilder", "emby-itemscontainer"], function (loading, layoutManager, userSettings, events, libraryBrowser, alphaPicker, listView, cardBuilder) { "use strict"; - return function(view, params, tabContent, options) { + + return function (view, params, tabContent, options) { function onViewStyleChange() { if (self.getCurrentViewStyle() == "List") { itemsContainer.classList.add("vertical-list"); @@ -10,103 +10,141 @@ define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser", itemsContainer.classList.remove("vertical-list"); itemsContainer.classList.add("vertical-wrap"); } + itemsContainer.innerHTML = ""; } function updateFilterControls() { - self.alphaPicker && self.alphaPicker.value(query.NameStartsWithOrGreater) + if (self.alphaPicker) { + self.alphaPicker.value(query.NameStartsWithOrGreater); + } } function fetchData() { isLoading = true; loading.show(); - return ApiClient.getItems(ApiClient.getCurrentUserId(), query) + return ApiClient.getItems(ApiClient.getCurrentUserId(), query); } function afterRefresh(result) { function onNextPageClick() { - if (isLoading) return; + if (isLoading) { + return; + } + query.StartIndex += query.Limit; itemsContainer.refreshItems(); } function onPreviousPageClick() { - if (isLoading) return; + if (isLoading) { + return; + } + query.StartIndex -= query.Limit; itemsContainer.refreshItems(); } + window.scrollTo(0, 0); updateFilterControls(); - var i, length, elems, pagingHtml = libraryBrowser.getQueryPagingHtml({ - startIndex: query.StartIndex, - limit: query.Limit, - totalRecordCount: result.TotalRecordCount, - showLimit: !1, - updatePageSizeSetting: !1, - addLayoutButton: !1, - sortButton: !1, - filterButton: !1 - }); - for (elems = tabContent.querySelectorAll(".paging"), i = 0, length = elems.length; i < length; i++) + var pagingHtml = libraryBrowser.getQueryPagingHtml({ + startIndex: query.StartIndex, + limit: query.Limit, + totalRecordCount: result.TotalRecordCount, + showLimit: false, + updatePageSizeSetting: false, + addLayoutButton: false, + sortButton: false, + filterButton: false + }); + var i; + var length; + var elems = tabContent.querySelectorAll(".paging"); + + for (i = 0, length = elems.length; i < length; i++) { elems[i].innerHTML = pagingHtml; - for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) + } + + elems = tabContent.querySelectorAll(".btnNextPage"); + for (i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener("click", onNextPageClick); - for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) - elems[i].addEventListener("click", onPreviousPageClick) + } + + elems = tabContent.querySelectorAll(".btnPreviousPage"); + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onPreviousPageClick); + } + isLoading = false; loading.hide(); } function getItemsHtml(items) { + var html; var viewStyle = self.getCurrentViewStyle(); - return "Thumb" == viewStyle ? cardBuilder.getCardsHtml({ - items: items, - shape: "backdrop", - preferThumb: !0, - context: "movies", - lazy: !0, - overlayPlayButton: !0, - showTitle: !0, - showYear: !0, - centerText: !0 - }) : "ThumbCard" == viewStyle ? cardBuilder.getCardsHtml({ - items: items, - shape: "backdrop", - preferThumb: !0, - context: "movies", - lazy: !0, - cardLayout: !0, - showTitle: !0, - showYear: !0, - centerText: !0 - }) : "Banner" == viewStyle ? cardBuilder.getCardsHtml({ - items: items, - shape: "banner", - preferBanner: !0, - context: "movies", - lazy: !0 - }) : "List" == viewStyle ? listView.getListViewHtml({ - items: items, - context: "movies", - sortBy: query.SortBy - }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({ - items: items, - shape: "portrait", - context: "movies", - showTitle: !0, - showYear: !0, - centerText: !0, - lazy: !0, - cardLayout: !0 - }) : cardBuilder.getCardsHtml({ - items: items, - shape: "portrait", - context: "movies", - overlayPlayButton: !0, - showTitle: !0, - showYear: !0, - centerText: !0 - }) + + if (viewStyle == "Thumb") { + html = cardBuilder.getCardsHtml({ + items: items, + shape: "backdrop", + preferThumb: true, + context: "movies", + lazy: true, + overlayPlayButton: true, + showTitle: true, + showYear: true, + centerText: true + }); + } else if (viewStyle == "ThumbCard") { + html = cardBuilder.getCardsHtml({ + items: items, + shape: "backdrop", + preferThumb: true, + context: "movies", + lazy: true, + cardLayout: true, + showTitle: true, + showYear: true, + centerText: true + }); + } else if (viewStyle == "Banner") { + html = cardBuilder.getCardsHtml({ + items: items, + shape: "banner", + preferBanner: true, + context: "movies", + lazy: true + }); + } else if (viewStyle == "List") { + html = listView.getListViewHtml({ + items: items, + context: "movies", + sortBy: query.SortBy + }); + } else if (viewStyle == "PosterCard") { + html = cardBuilder.getCardsHtml({ + items: items, + shape: "portrait", + context: "movies", + showTitle: true, + showYear: true, + centerText: true, + lazy: true, + cardLayout: true + }); + } else { + html = cardBuilder.getCardsHtml({ + items: items, + shape: "portrait", + context: "movies", + overlayPlayButton: true, + showTitle: true, + showYear: true, + centerText: true + }); + } + + return html; } function initPage(tabContent) { @@ -114,8 +152,9 @@ define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser", itemsContainer.getItemsHtml = getItemsHtml; itemsContainer.afterRefresh = afterRefresh; var alphaPickerElement = tabContent.querySelector(".alphaPicker"); + if (alphaPickerElement) { - alphaPickerElement.addEventListener("alphavaluechanged", function(e) { + alphaPickerElement.addEventListener("alphavaluechanged", function (e) { var newValue = e.detail.value; query.NameStartsWithOrGreater = newValue; query.StartIndex = 0; @@ -125,109 +164,132 @@ define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser", element: alphaPickerElement, valueChangeEvent: "click" }); + if (layoutManager.desktop || layoutManager.mobile) { alphaPickerElement.classList.add("alphabetPicker-right"); itemsContainer.classList.remove("padded-left-withalphapicker"); itemsContainer.classList.add("padded-right-withalphapicker"); } } + var btnFilter = tabContent.querySelector(".btnFilter"); - btnFilter && btnFilter.addEventListener("click", function() { - self.showFilterMenu() - }); + + if (btnFilter) { + btnFilter.addEventListener("click", function () { + self.showFilterMenu(); + }); + } var btnSort = tabContent.querySelector(".btnSort"); - btnSort && btnSort.addEventListener("click", function(e) { - libraryBrowser.showSortMenu({ - items: [{ - name: Globalize.translate("OptionNameSort"), - id: "SortName,ProductionYear" - }, { - name: Globalize.translate("OptionImdbRating"), - id: "CommunityRating,SortName,ProductionYear" - }, { - name: Globalize.translate("OptionCriticRating"), - id: "CriticRating,SortName,ProductionYear" - }, { - name: Globalize.translate("OptionDateAdded"), - id: "DateCreated,SortName,ProductionYear" - }, { - name: Globalize.translate("OptionDatePlayed"), - id: "DatePlayed,SortName,ProductionYear" - }, { - name: Globalize.translate("OptionParentalRating"), - id: "OfficialRating,SortName,ProductionYear" - }, { - name: Globalize.translate("OptionPlayCount"), - id: "PlayCount,SortName,ProductionYear" - }, { - name: Globalize.translate("OptionReleaseDate"), - id: "PremiereDate,SortName,ProductionYear" - }, { - name: Globalize.translate("OptionRuntime"), - id: "Runtime,SortName,ProductionYear" - }], - callback: function() { - query.StartIndex = 0, userSettings.saveQuerySettings(savedQueryKey, query), itemsContainer.refreshItems() - }, - query: query, - button: e.target - }) - }); + + if (btnSort) { + btnSort.addEventListener("click", function (e) { + libraryBrowser.showSortMenu({ + items: [{ + name: Globalize.translate("OptionNameSort"), + id: "SortName,ProductionYear" + }, { + name: Globalize.translate("OptionImdbRating"), + id: "CommunityRating,SortName,ProductionYear" + }, { + name: Globalize.translate("OptionCriticRating"), + id: "CriticRating,SortName,ProductionYear" + }, { + name: Globalize.translate("OptionDateAdded"), + id: "DateCreated,SortName,ProductionYear" + }, { + name: Globalize.translate("OptionDatePlayed"), + id: "DatePlayed,SortName,ProductionYear" + }, { + name: Globalize.translate("OptionParentalRating"), + id: "OfficialRating,SortName,ProductionYear" + }, { + name: Globalize.translate("OptionPlayCount"), + id: "PlayCount,SortName,ProductionYear" + }, { + name: Globalize.translate("OptionReleaseDate"), + id: "PremiereDate,SortName,ProductionYear" + }, { + name: Globalize.translate("OptionRuntime"), + id: "Runtime,SortName,ProductionYear" + }], + callback: function () { + query.StartIndex = 0; + userSettings.saveQuerySettings(savedQueryKey, query); + itemsContainer.refreshItems(); + }, + query: query, + button: e.target + }); + }); + } var btnSelectView = tabContent.querySelector(".btnSelectView"); - btnSelectView.addEventListener("click", function(e) { - libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "Banner,List,Poster,PosterCard,Thumb,ThumbCard".split(",")) - }), btnSelectView.addEventListener("layoutchange", function(e) { + btnSelectView.addEventListener("click", function (e) { + libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "Banner,List,Poster,PosterCard,Thumb,ThumbCard".split(",")); + }); + btnSelectView.addEventListener("layoutchange", function (e) { var viewStyle = e.detail.viewStyle; userSettings.set(savedViewKey, viewStyle); query.StartIndex = 0; onViewStyleChange(); itemsContainer.refreshItems(); - }) + }); } - var self = this, - itemsContainer = tabContent.querySelector(".itemsContainer"), - savedQueryKey = params.topParentId + "-" + options.mode, - savedViewKey = savedQueryKey + "-view", - query = { - SortBy: "SortName,ProductionYear", - SortOrder: "Ascending", - IncludeItemTypes: "Movie", - Recursive: !0, - Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo", - ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb", - StartIndex: 0, - Limit: 100, - ParentId: params.topParentId - }, - isLoading = false; - if (options.mode === "favorites") query.IsFavorite = true; + + var self = this; + var itemsContainer = tabContent.querySelector(".itemsContainer"); + var savedQueryKey = params.topParentId + "-" + options.mode; + var savedViewKey = savedQueryKey + "-view"; + var query = { + SortBy: "SortName,ProductionYear", + SortOrder: "Ascending", + IncludeItemTypes: "Movie", + Recursive: true, + Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo", + ImageTypeLimit: 1, + EnableImageTypes: "Primary,Backdrop,Banner,Thumb", + StartIndex: 0, + Limit: 100, + ParentId: params.topParentId + }; + var isLoading = false; + + if (options.mode === "favorites") { + query.IsFavorite = true; + } + query = userSettings.loadQuerySettings(savedQueryKey, query); - self.showFilterMenu = function() { - require(["components/filterdialog/filterdialog"], function(filterDialogFactory) { + + self.showFilterMenu = function () { + require(["components/filterdialog/filterdialog"], function (filterDialogFactory) { var filterDialog = new filterDialogFactory({ query: query, mode: "movies", serverId: ApiClient.serverId() }); - events.on(filterDialog, "filterchange", function() { - query.StartIndex = 0, itemsContainer.refreshItems() - }), filterDialog.show() - }) + events.on(filterDialog, "filterchange", function () { + query.StartIndex = 0; + itemsContainer.refreshItems(); + }); + filterDialog.show(); + }); }; - self.getCurrentViewStyle = function() { - return userSettings.get(savedViewKey) || "Poster" + + self.getCurrentViewStyle = function () { + return userSettings.get(savedViewKey) || "Poster"; }; - self.initTab = function() { + + self.initTab = function () { initPage(tabContent); onViewStyleChange(); }; - self.renderTab = function() { + + self.renderTab = function () { itemsContainer.refreshItems(); updateFilterControls(); }; - self.destroy = function() { - itemsContainer = null - } - } + + self.destroy = function () { + itemsContainer = null; + }; + }; }); diff --git a/src/controllers/movies/moviesrecommended.js b/src/controllers/movies/moviesrecommended.js index 2bab767735..82c0b6a12d 100644 --- a/src/controllers/movies/moviesrecommended.js +++ b/src/controllers/movies/moviesrecommended.js @@ -1,16 +1,16 @@ -define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu", "mainTabsManager", "cardBuilder", "dom", "imageLoader", "playbackManager", "emby-itemscontainer", "emby-tabs", "emby-button"], function(events, layoutManager, inputManager, userSettings, libraryMenu, mainTabsManager, cardBuilder, dom, imageLoader, playbackManager) { +define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu", "mainTabsManager", "cardBuilder", "dom", "imageLoader", "playbackManager", "emby-itemscontainer", "emby-tabs", "emby-button"], function (events, layoutManager, inputManager, userSettings, libraryMenu, mainTabsManager, cardBuilder, dom, imageLoader, playbackManager) { "use strict"; function enableScrollX() { - return !layoutManager.desktop + return !layoutManager.desktop; } function getPortraitShape() { - return enableScrollX() ? "overflowPortrait" : "portrait" + return enableScrollX() ? "overflowPortrait" : "portrait"; } function getThumbShape() { - return enableScrollX() ? "overflowBackdrop" : "backdrop" + return enableScrollX() ? "overflowBackdrop" : "backdrop"; } function loadLatest(page, userId, parentId) { @@ -21,118 +21,168 @@ define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu" ParentId: parentId, ImageTypeLimit: 1, EnableImageTypes: "Primary,Backdrop,Banner,Thumb", - EnableTotalRecordCount: !1 + EnableTotalRecordCount: false }; - ApiClient.getJSON(ApiClient.getUrl("Users/" + userId + "/Items/Latest", options)).then(function(items) { - var allowBottomPadding = !enableScrollX(), - container = page.querySelector("#recentlyAddedItems"); + ApiClient.getJSON(ApiClient.getUrl("Users/" + userId + "/Items/Latest", options)).then(function (items) { + var allowBottomPadding = !enableScrollX(); + var container = page.querySelector("#recentlyAddedItems"); cardBuilder.buildCards(items, { itemsContainer: container, shape: getPortraitShape(), - scalable: !0, - overlayPlayButton: !0, + scalable: true, + overlayPlayButton: true, allowBottomPadding: allowBottomPadding, - showTitle: !0, - showYear: !0, - centerText: !0 - }) - }) + showTitle: true, + showYear: true, + centerText: true + }); + }); } function loadResume(page, userId, parentId) { - var screenWidth = dom.getWindowSize().innerWidth, - options = { - SortBy: "DatePlayed", - SortOrder: "Descending", - IncludeItemTypes: "Movie", - Filters: "IsResumable", - Limit: screenWidth >= 1920 ? 5 : screenWidth >= 1600 ? 5 : 3, - Recursive: !0, - Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo", - CollapseBoxSetItems: !1, - ParentId: parentId, - ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb", - EnableTotalRecordCount: !1 - }; - ApiClient.getItems(userId, options).then(function(result) { - result.Items.length ? page.querySelector("#resumableSection").classList.remove("hide") : page.querySelector("#resumableSection").classList.add("hide"); - var allowBottomPadding = !enableScrollX(), - container = page.querySelector("#resumableItems"); + var screenWidth = dom.getWindowSize().innerWidth; + var options = { + SortBy: "DatePlayed", + SortOrder: "Descending", + IncludeItemTypes: "Movie", + Filters: "IsResumable", + Limit: screenWidth >= 1920 ? 5 : screenWidth >= 1600 ? 5 : 3, + Recursive: true, + Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo", + CollapseBoxSetItems: false, + ParentId: parentId, + ImageTypeLimit: 1, + EnableImageTypes: "Primary,Backdrop,Banner,Thumb", + EnableTotalRecordCount: false + }; + ApiClient.getItems(userId, options).then(function (result) { + if (result.Items.length) { + page.querySelector("#resumableSection").classList.remove("hide"); + } else { + page.querySelector("#resumableSection").classList.add("hide"); + } + + var allowBottomPadding = !enableScrollX(); + var container = page.querySelector("#resumableItems"); cardBuilder.buildCards(result.Items, { itemsContainer: container, - preferThumb: !0, + preferThumb: true, shape: getThumbShape(), - scalable: !0, - overlayPlayButton: !0, + scalable: true, + overlayPlayButton: true, allowBottomPadding: allowBottomPadding, - cardLayout: !1, - showTitle: !0, - showYear: !0, - centerText: !0 - }) - }) + cardLayout: false, + showTitle: true, + showYear: true, + centerText: true + }); + }); } function getRecommendationHtml(recommendation) { - var html = "", - title = ""; + var html = ""; + var title = ""; + switch (recommendation.RecommendationType) { case "SimilarToRecentlyPlayed": title = Globalize.translate("RecommendationBecauseYouWatched").replace("{0}", recommendation.BaselineItemName); break; + case "SimilarToLikedItem": title = Globalize.translate("RecommendationBecauseYouLike").replace("{0}", recommendation.BaselineItemName); break; + case "HasDirectorFromRecentlyPlayed": case "HasLikedDirector": title = Globalize.translate("RecommendationDirectedBy").replace("{0}", recommendation.BaselineItemName); break; + case "HasActorFromRecentlyPlayed": case "HasLikedActor": - title = Globalize.translate("RecommendationStarring").replace("{0}", recommendation.BaselineItemName) + title = Globalize.translate("RecommendationStarring").replace("{0}", recommendation.BaselineItemName); + break; } - html += '
', html += '

' + title + "

"; - var allowBottomPadding = !0; - return enableScrollX() ? (allowBottomPadding = !1, html += '
') : html += '
', html += cardBuilder.getCardsHtml(recommendation.Items, { + + html += '
'; + html += '

' + title + "

"; + var allowBottomPadding = true; + + if (enableScrollX()) { + allowBottomPadding = false; + html += '
'; + } else { + html += '
'; + } + + html += cardBuilder.getCardsHtml(recommendation.Items, { shape: getPortraitShape(), - scalable: !0, - overlayPlayButton: !0, + scalable: true, + overlayPlayButton: true, allowBottomPadding: allowBottomPadding - }), html += "
", html += "
" + }); + html += "
"; + html += "
"; + return html; } function loadSuggestions(page, userId, parentId) { - var screenWidth = dom.getWindowSize().innerWidth, - url = ApiClient.getUrl("Movies/Recommendations", { - userId: userId, - categoryLimit: 6, - ItemLimit: screenWidth >= 1920 ? 8 : screenWidth >= 1600 ? 8 : screenWidth >= 1200 ? 6 : 5, - Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo", - ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb" - }); - ApiClient.getJSON(url).then(function(recommendations) { - if (!recommendations.length) return page.querySelector(".noItemsMessage").classList.remove("hide"), void(page.querySelector(".recommendations").innerHTML = ""); + var screenWidth = dom.getWindowSize().innerWidth; + var url = ApiClient.getUrl("Movies/Recommendations", { + userId: userId, + categoryLimit: 6, + ItemLimit: screenWidth >= 1920 ? 8 : screenWidth >= 1600 ? 8 : screenWidth >= 1200 ? 6 : 5, + Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo", + ImageTypeLimit: 1, + EnableImageTypes: "Primary,Backdrop,Banner,Thumb" + }); + ApiClient.getJSON(url).then(function (recommendations) { + if (!recommendations.length) { + page.querySelector(".noItemsMessage").classList.remove("hide"); + page.querySelector(".recommendations").innerHTML = ""; + return; + } + var html = recommendations.map(getRecommendationHtml).join(""); page.querySelector(".noItemsMessage").classList.add("hide"); var recs = page.querySelector(".recommendations"); - recs.innerHTML = html, imageLoader.lazyChildren(recs) - }) + recs.innerHTML = html; + imageLoader.lazyChildren(recs); + }); } function setScrollClasses(elem, scrollX) { - scrollX ? (elem.classList.add("hiddenScrollX"), layoutManager.tv && elem.classList.add("smoothScrollX"), elem.classList.add("scrollX"), elem.classList.remove("vertical-wrap")) : (elem.classList.remove("hiddenScrollX"), elem.classList.remove("smoothScrollX"), elem.classList.remove("scrollX"), elem.classList.add("vertical-wrap")) + if (scrollX) { + elem.classList.add("hiddenScrollX"); + + if (layoutManager.tv) { + elem.classList.add("smoothScrollX"); + } + + elem.classList.add("scrollX"); + elem.classList.remove("vertical-wrap"); + } else { + elem.classList.remove("hiddenScrollX"); + elem.classList.remove("smoothScrollX"); + elem.classList.remove("scrollX"); + elem.classList.add("vertical-wrap"); + } } function initSuggestedTab(page, tabContent) { - for (var containers = tabContent.querySelectorAll(".itemsContainer"), i = 0, length = containers.length; i < length; i++) setScrollClasses(containers[i], enableScrollX()) + var containers = tabContent.querySelectorAll(".itemsContainer"); + + for (var i = 0, length = containers.length; i < length; i++) { + setScrollClasses(containers[i], enableScrollX()); + } } function loadSuggestionsTab(view, params, tabContent) { - var parentId = params.topParentId, - userId = ApiClient.getCurrentUserId(); - console.log("loadSuggestionsTab"), loadResume(tabContent, userId, parentId), loadLatest(tabContent, userId, parentId), loadSuggestions(tabContent, userId, parentId) + var parentId = params.topParentId; + var userId = ApiClient.getCurrentUserId(); + console.log("loadSuggestionsTab"); + loadResume(tabContent, userId, parentId); + loadLatest(tabContent, userId, parentId); + loadSuggestions(tabContent, userId, parentId); } function getTabs() { @@ -151,126 +201,196 @@ define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu" }, { name: Globalize.translate("ButtonSearch"), cssClass: "searchTabButton" - }] + }]; } function getDefaultTabIndex(folderId) { switch (userSettings.get("landing-" + folderId)) { case "suggestions": return 1; + case "favorites": return 3; + case "collections": return 4; + case "genres": return 5; + default: - return 0 + return 0; } } - return function(view, params) { + + return function (view, params) { function onBeforeTabChange(e) { - preLoadTab(view, parseInt(e.detail.selectedTabIndex)) + preLoadTab(view, parseInt(e.detail.selectedTabIndex)); } function onTabChange(e) { var newIndex = parseInt(e.detail.selectedTabIndex); - loadTab(view, newIndex) + loadTab(view, newIndex); } function getTabContainers() { - return view.querySelectorAll(".pageTabContent") + return view.querySelectorAll(".pageTabContent"); } function initTabs() { - mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange) + mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange); } function getTabController(page, index, callback) { var depends = []; + switch (index) { case 0: depends.push("controllers/movies/movies"); break; + case 1: break; + case 2: depends.push("controllers/movies/movietrailers"); break; + case 3: depends.push("controllers/movies/movies"); break; + case 4: depends.push("controllers/movies/moviecollections"); break; + case 5: depends.push("controllers/movies/moviegenres"); break; + case 6: - depends.push("scripts/searchtab") + depends.push("scripts/searchtab"); } - require(depends, function(controllerFactory) { + + require(depends, function (controllerFactory) { var tabContent; - index === suggestionsTabIndex && (tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"), self.tabContent = tabContent); + + if (index === suggestionsTabIndex) { + tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); + self.tabContent = tabContent; + } + var controller = tabControllers[index]; - controller || (tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"), controller = index === suggestionsTabIndex ? self : 6 === index ? new controllerFactory(view, tabContent, { - collectionType: "movies", - parentId: params.topParentId - }) : 0 === index || 3 === index ? new controllerFactory(view, params, tabContent, { - mode: index ? "favorites" : "movies" - }) : new controllerFactory(view, params, tabContent), tabControllers[index] = controller, controller.initTab && controller.initTab()), callback(controller) - }) + + if (!controller) { + tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); + + if (index === suggestionsTabIndex) { + controller = self; + } else if (index === 6) { + controller = new controllerFactory(view, tabContent, { + collectionType: "movies", + parentId: params.topParentId + }); + } else if (index == 0 || index == 3) { + controller = new controllerFactory(view, params, tabContent, { + mode: index ? "favorites" : "movies" + }); + } else { + controller = new controllerFactory(view, params, tabContent); + } + + tabControllers[index] = controller; + + if (controller.initTab) { + controller.initTab(); + } + } + + callback(controller); + }); } function preLoadTab(page, index) { - getTabController(page, index, function(controller) { - -1 == renderedTabs.indexOf(index) && controller.preRender && controller.preRender() - }) + getTabController(page, index, function (controller) { + if (renderedTabs.indexOf(index) == -1 && controller.preRender) { + controller.preRender(); + } + }); } function loadTab(page, index) { - currentTabIndex = index, getTabController(page, index, function(controller) { - initialTabIndex = null, -1 == renderedTabs.indexOf(index) && (renderedTabs.push(index), controller.renderTab()) - }) + currentTabIndex = index; + getTabController(page, index, function (controller) { + initialTabIndex = null; + + if (renderedTabs.indexOf(index) == -1) { + renderedTabs.push(index); + controller.renderTab(); + } + }); } function onPlaybackStop(e, state) { - state.NowPlayingItem && "Video" == state.NowPlayingItem.MediaType && (renderedTabs = [], mainTabsManager.getTabsElement().triggerTabChange()) + if (state.NowPlayingItem && state.NowPlayingItem.MediaType == "Video") { + renderedTabs = []; + mainTabsManager.getTabsElement().triggerTabChange(); + } } function onInputCommand(e) { switch (e.detail.command) { case "search": - e.preventDefault(), Dashboard.navigate("search.html?collectionType=movies&parentId=" + params.topParentId) + e.preventDefault(); + Dashboard.navigate("search.html?collectionType=movies&parentId=" + params.topParentId); } } - var isViewRestored, self = this, - currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)), - initialTabIndex = currentTabIndex, - suggestionsTabIndex = 1; - self.initTab = function() { + + var isViewRestored; + var self = this; + var currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)); + var initialTabIndex = currentTabIndex; + var suggestionsTabIndex = 1; + + self.initTab = function () { var tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']"); initSuggestedTab(view, tabContent); - }, self.renderTab = function() { - var tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']"); - loadSuggestionsTab(view, params, tabContent) }; - var tabControllers = [], - renderedTabs = []; - view.addEventListener("viewshow", function(e) { + + self.renderTab = function () { + var tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']"); + loadSuggestionsTab(view, params, tabContent); + }; + + var tabControllers = []; + var renderedTabs = []; + view.addEventListener("viewshow", function (e) { if (isViewRestored = e.detail.isRestored, initTabs(), !view.getAttribute("data-title")) { var parentId = params.topParentId; - parentId ? ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function(item) { - view.setAttribute("data-title", item.Name), libraryMenu.setTitle(item.Name) - }) : (view.setAttribute("data-title", Globalize.translate("TabMovies")), libraryMenu.setTitle(Globalize.translate("TabMovies"))) + + if (parentId) { + ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function (item) { + view.setAttribute("data-title", item.Name); + libraryMenu.setTitle(item.Name); + }); + } else { + view.setAttribute("data-title", Globalize.translate("TabMovies")); + libraryMenu.setTitle(Globalize.translate("TabMovies")); + } } - events.on(playbackManager, "playbackstop", onPlaybackStop), inputManager.on(window, onInputCommand) - }), view.addEventListener("viewbeforehide", function(e) { - inputManager.off(window, onInputCommand) - }), view.addEventListener("viewdestroy", function(e) { - tabControllers.forEach(function(t) { - t.destroy && t.destroy() - }) - }) - } -}); \ No newline at end of file + + events.on(playbackManager, "playbackstop", onPlaybackStop); + inputManager.on(window, onInputCommand); + }); + view.addEventListener("viewbeforehide", function (e) { + inputManager.off(window, onInputCommand); + }); + view.addEventListener("viewdestroy", function (e) { + tabControllers.forEach(function (t) { + if (t.destroy) { + t.destroy(); + } + }); + }); + }; +}); diff --git a/src/controllers/movies/movietrailers.js b/src/controllers/movies/movietrailers.js index 2d1fdda63c..3e62298613 100644 --- a/src/controllers/movies/movietrailers.js +++ b/src/controllers/movies/movietrailers.js @@ -1,185 +1,261 @@ -define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function(layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) { +define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) { "use strict"; - return function(view, params, tabContent) { + + return function (view, params, tabContent) { function getPageData(context) { - var key = getSavedQueryKey(context), - pageData = data[key]; - return pageData || (pageData = data[key] = { - query: { - SortBy: "SortName", - SortOrder: "Ascending", - IncludeItemTypes: "Trailer", - Recursive: !0, - Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo", - ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb", - StartIndex: 0, - Limit: pageSize - }, - view: libraryBrowser.getSavedView(key) || "Poster" - }, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData + var key = getSavedQueryKey(context); + var pageData = data[key]; + + if (!pageData) { + pageData = data[key] = { + query: { + SortBy: "SortName", + SortOrder: "Ascending", + IncludeItemTypes: "Trailer", + Recursive: true, + Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo", + ImageTypeLimit: 1, + EnableImageTypes: "Primary,Backdrop,Banner,Thumb", + StartIndex: 0, + Limit: pageSize + }, + view: libraryBrowser.getSavedView(key) || "Poster" + }; + libraryBrowser.loadSavedQueryValues(key, pageData.query); + } + + return pageData; } function getQuery(context) { - return getPageData(context).query + return getPageData(context).query; } function getSavedQueryKey(context) { - return context.savedQueryKey || (context.savedQueryKey = libraryBrowser.getSavedQueryKey("trailers")), context.savedQueryKey + if (!context.savedQueryKey) { + context.savedQueryKey = libraryBrowser.getSavedQueryKey("trailers"); + } + + return context.savedQueryKey; } function reloadItems() { loading.show(); isLoading = true; var query = getQuery(tabContent); - ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function(result) { + ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) { function onNextPageClick() { - if (isLoading) return; - query.StartIndex += query.Limit, reloadItems() + if (isLoading) { + return; + } + + query.StartIndex += query.Limit; + reloadItems(); } function onPreviousPageClick() { - if (isLoading) return; - query.StartIndex -= query.Limit, reloadItems() + if (isLoading) { + return; + } + + query.StartIndex -= query.Limit; + reloadItems(); } - window.scrollTo(0, 0), updateFilterControls(tabContent); - var html, pagingHtml = libraryBrowser.getQueryPagingHtml({ - startIndex: query.StartIndex, - limit: query.Limit, - totalRecordCount: result.TotalRecordCount, - showLimit: !1, - updatePageSizeSetting: !1, - addLayoutButton: !1, - sortButton: !1, - filterButton: !1 - }), - viewStyle = self.getCurrentViewStyle(); - html = "Thumb" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "backdrop", - preferThumb: !0, - context: "movies", - overlayPlayButton: !0 - }) : "ThumbCard" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "backdrop", - preferThumb: !0, - context: "movies", - cardLayout: !0, - showTitle: !0, - showYear: !0, - centerText: !0 - }) : "Banner" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "banner", - preferBanner: !0, - context: "movies" - }) : "List" == viewStyle ? listView.getListViewHtml({ - items: result.Items, - context: "movies", - sortBy: query.SortBy - }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "portrait", - context: "movies", - showTitle: !0, - showYear: !0, - centerText: !0, - cardLayout: !0 - }) : cardBuilder.getCardsHtml({ - items: result.Items, - shape: "portrait", - context: "movies", - centerText: !0, - overlayPlayButton: !0, - showTitle: !0, - showYear: !0 + + window.scrollTo(0, 0); + updateFilterControls(tabContent); + var pagingHtml = libraryBrowser.getQueryPagingHtml({ + startIndex: query.StartIndex, + limit: query.Limit, + totalRecordCount: result.TotalRecordCount, + showLimit: false, + updatePageSizeSetting: false, + addLayoutButton: false, + sortButton: false, + filterButton: false }); - var i, length, elems = tabContent.querySelectorAll(".paging"); - for (i = 0, length = elems.length; i < length; i++) elems[i].innerHTML = pagingHtml; - for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick); - for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick); - result.Items.length || (html = '

' + Globalize.translate("MessageNoTrailersFound") + "

"); + var html; + var viewStyle = self.getCurrentViewStyle(); + + if (viewStyle == "Thumb") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "backdrop", + preferThumb: true, + context: "movies", + overlayPlayButton: true + }); + } else if (viewStyle == "ThumbCard") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "backdrop", + preferThumb: true, + context: "movies", + cardLayout: true, + showTitle: true, + showYear: true, + centerText: true + }); + } else if (viewStyle == "Banner") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "banner", + preferBanner: true, + context: "movies" + }); + } else if (viewStyle == "List") { + html = listView.getListViewHtml({ + items: result.Items, + context: "movies", + sortBy: query.SortBy + }); + } else if (viewStyle == "PosterCard") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "portrait", + context: "movies", + showTitle: true, + showYear: true, + cardLayout: true, + centerText: true + }); + } else { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "portrait", + context: "movies", + centerText: true, + overlayPlayButton: true, + showTitle: true, + showYear: true + }); + } + + var i; + var length; + var elems = tabContent.querySelectorAll(".paging"); + + for (i = 0, length = elems.length; i < length; i++) { + elems[i].innerHTML = pagingHtml; + } + + elems = tabContent.querySelectorAll(".btnNextPage"); + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onNextPageClick); + } + + elems = tabContent.querySelectorAll(".btnPreviousPage"); + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onPreviousPageClick); + } + + if (!result.Items.length) { + html = '

' + Globalize.translate("MessageNoTrailersFound") + "

"; + } + var itemsContainer = tabContent.querySelector(".itemsContainer"); itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); libraryBrowser.saveQueryValues(getSavedQueryKey(tabContent), query); loading.hide(); isLoading = false; - }) + }); } function updateFilterControls(tabContent) { var query = getQuery(tabContent); - self.alphaPicker.value(query.NameStartsWithOrGreater) + self.alphaPicker.value(query.NameStartsWithOrGreater); } - var self = this, - pageSize = 100, - data = {}, - isLoading = false; - self.showFilterMenu = function() { - require(["components/filterdialog/filterdialog"], function(filterDialogFactory) { - var filterDialog = new filterDialogFactory({ - query: getQuery(tabContent), - mode: "movies", - serverId: ApiClient.serverId() - }); - events.on(filterDialog, "filterchange", function() { - getQuery(tabContent).StartIndex = 0, reloadItems() - }), filterDialog.show() - }) - }, self.getCurrentViewStyle = function() { - return getPageData(tabContent).view - }, - function(tabContent) { - var alphaPickerElement = tabContent.querySelector(".alphaPicker"); - if (alphaPickerElement.addEventListener("alphavaluechanged", function(e) { - var newValue = e.detail.value, - query = getQuery(tabContent); - query.NameStartsWithOrGreater = newValue, query.StartIndex = 0, reloadItems() - }), self.alphaPicker = new alphaPicker({ - element: alphaPickerElement, - valueChangeEvent: "click" - }), layoutManager.desktop || layoutManager.mobile) { - tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right"); - var itemsContainer = tabContent.querySelector(".itemsContainer"); - itemsContainer.classList.remove("padded-left-withalphapicker"), itemsContainer.classList.add("padded-right-withalphapicker") - } - tabContent.querySelector(".btnFilter").addEventListener("click", function() { - self.showFilterMenu() - }), tabContent.querySelector(".btnSort").addEventListener("click", function(e) { - libraryBrowser.showSortMenu({ - items: [{ - name: Globalize.translate("OptionNameSort"), - id: "SortName" - }, { - name: Globalize.translate("OptionImdbRating"), - id: "CommunityRating,SortName" - }, { - name: Globalize.translate("OptionDateAdded"), - id: "DateCreated,SortName" - }, { - name: Globalize.translate("OptionDatePlayed"), - id: "DatePlayed,SortName" - }, { - name: Globalize.translate("OptionParentalRating"), - id: "OfficialRating,SortName" - }, { - name: Globalize.translate("OptionPlayCount"), - id: "PlayCount,SortName" - }, { - name: Globalize.translate("OptionReleaseDate"), - id: "PremiereDate,SortName" - }], - callback: function() { - getQuery(tabContent).StartIndex = 0, reloadItems() - }, - query: getQuery(tabContent), - button: e.target - }) - }) - }(tabContent), self.renderTab = function() { - reloadItems(), updateFilterControls(tabContent) - }, self.destroy = function() {} - } + + var self = this; + var pageSize = 100; + var data = {}; + var isLoading = false; + + self.showFilterMenu = function () { + require(["components/filterdialog/filterdialog"], function (filterDialogFactory) { + var filterDialog = new filterDialogFactory({ + query: getQuery(tabContent), + mode: "movies", + serverId: ApiClient.serverId() + }); + events.on(filterDialog, "filterchange", function () { + getQuery(tabContent).StartIndex = 0; + reloadItems(); + }); + filterDialog.show(); + }); + }; + + self.getCurrentViewStyle = function () { + return getPageData(tabContent).view; + }; + + function initPage(tabContent) { + var alphaPickerElement = tabContent.querySelector(".alphaPicker"); + alphaPickerElement.addEventListener("alphavaluechanged", function (e) { + var newValue = e.detail.value; + var query = getQuery(tabContent); + query.NameStartsWithOrGreater = newValue; + query.StartIndex = 0; + reloadItems(); + }); + self.alphaPicker = new alphaPicker({ + element: alphaPickerElement, + valueChangeEvent: "click" + }); + + if (layoutManager.desktop || layoutManager.mobile) { + tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right"); + var itemsContainer = tabContent.querySelector(".itemsContainer"); + itemsContainer.classList.remove("padded-left-withalphapicker"); + itemsContainer.classList.add("padded-right-withalphapicker"); + } + + tabContent.querySelector(".btnFilter").addEventListener("click", function () { + self.showFilterMenu(); + }); + tabContent.querySelector(".btnSort").addEventListener("click", function (e) { + libraryBrowser.showSortMenu({ + items: [{ + name: Globalize.translate("OptionNameSort"), + id: "SortName" + }, { + name: Globalize.translate("OptionImdbRating"), + id: "CommunityRating,SortName" + }, { + name: Globalize.translate("OptionDateAdded"), + id: "DateCreated,SortName" + }, { + name: Globalize.translate("OptionDatePlayed"), + id: "DatePlayed,SortName" + }, { + name: Globalize.translate("OptionParentalRating"), + id: "OfficialRating,SortName" + }, { + name: Globalize.translate("OptionPlayCount"), + id: "PlayCount,SortName" + }, { + name: Globalize.translate("OptionReleaseDate"), + id: "PremiereDate,SortName" + }], + callback: function () { + getQuery(tabContent).StartIndex = 0; + reloadItems(); + }, + query: getQuery(tabContent), + button: e.target + }); + }); + } + + initPage(tabContent); + + self.renderTab = function () { + reloadItems(); + updateFilterControls(tabContent); + }; + + self.destroy = function () {}; + }; }); diff --git a/src/controllers/music/musicalbums.js b/src/controllers/music/musicalbums.js index 8a562c532d..ac45d9a15b 100644 --- a/src/controllers/music/musicalbums.js +++ b/src/controllers/music/musicalbums.js @@ -1,190 +1,275 @@ -define(["layoutManager", "playbackManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function(layoutManager, playbackManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) { +define(["layoutManager", "playbackManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function (layoutManager, playbackManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) { "use strict"; - return function(view, params, tabContent) { + + return function (view, params, tabContent) { function playAll() { - ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function(item) { + ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function (item) { playbackManager.play({ items: [item] - }) - }) + }); + }); } function shuffle() { - ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function(item) { + ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function (item) { getQuery(); - playbackManager.shuffle(item, null) - }) + playbackManager.shuffle(item, null); + }); } function getPageData() { var key = getSavedQueryKey(); - return pageData || (pageData = { - query: { - SortBy: "SortName", - SortOrder: "Ascending", - IncludeItemTypes: "MusicAlbum", - Recursive: !0, - Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo", - ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb", - StartIndex: 0, - Limit: pageSize - }, - view: libraryBrowser.getSavedView(key) || "Poster" - }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData + + if (!pageData) { + pageData = { + query: { + SortBy: "SortName", + SortOrder: "Ascending", + IncludeItemTypes: "MusicAlbum", + Recursive: true, + Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo", + ImageTypeLimit: 1, + EnableImageTypes: "Primary,Backdrop,Banner,Thumb", + StartIndex: 0, + Limit: pageSize + }, + view: libraryBrowser.getSavedView(key) || "Poster" + }; + pageData.query.ParentId = params.topParentId; + libraryBrowser.loadSavedQueryValues(key, pageData.query); + } + + return pageData; } function getQuery() { - return getPageData().query + return getPageData().query; } function getSavedQueryKey() { - return savedQueryKey || (savedQueryKey = libraryBrowser.getSavedQueryKey("musicalbums")), savedQueryKey + if (!savedQueryKey) { + savedQueryKey = libraryBrowser.getSavedQueryKey("musicalbums"); + } + + return savedQueryKey; } function onViewStyleChange() { - var viewStyle = self.getCurrentViewStyle(), - itemsContainer = tabContent.querySelector(".itemsContainer"); - "List" == viewStyle ? (itemsContainer.classList.add("vertical-list"), itemsContainer.classList.remove("vertical-wrap")) : (itemsContainer.classList.remove("vertical-list"), itemsContainer.classList.add("vertical-wrap")), itemsContainer.innerHTML = "" + var viewStyle = self.getCurrentViewStyle(); + var itemsContainer = tabContent.querySelector(".itemsContainer"); + + if ("List" == viewStyle) { + itemsContainer.classList.add("vertical-list"); + itemsContainer.classList.remove("vertical-wrap"); + } else { + itemsContainer.classList.remove("vertical-list"); + itemsContainer.classList.add("vertical-wrap"); + } + + itemsContainer.innerHTML = ""; } function reloadItems(page) { loading.show(); isLoading = true; var query = getQuery(); - ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function(result) { + ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) { function onNextPageClick() { - if (isLoading) return; - query.StartIndex += query.Limit, reloadItems(tabContent) + if (isLoading) { + return; + } + + query.StartIndex += query.Limit; + reloadItems(tabContent); } function onPreviousPageClick() { - if (isLoading) return; - query.StartIndex -= query.Limit, reloadItems(tabContent) + if (isLoading) { + return; + } + + query.StartIndex -= query.Limit; + reloadItems(tabContent); } - window.scrollTo(0, 0), updateFilterControls(page); - var html, pagingHtml = libraryBrowser.getQueryPagingHtml({ - startIndex: query.StartIndex, - limit: query.Limit, - totalRecordCount: result.TotalRecordCount, - showLimit: !1, - updatePageSizeSetting: !1, - addLayoutButton: !1, - sortButton: !1, - filterButton: !1 - }), - viewStyle = self.getCurrentViewStyle(); - html = "List" == viewStyle ? listView.getListViewHtml({ - items: result.Items, - context: "music", - sortBy: query.SortBy, - addToListButton: !0 - }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "square", - context: "music", - showTitle: !0, - coverImage: !0, - showParentTitle: !0, - lazy: !0, - cardLayout: !0 - }) : cardBuilder.getCardsHtml({ - items: result.Items, - shape: "square", - context: "music", - showTitle: !0, - showParentTitle: !0, - lazy: !0, - centerText: !0, - overlayPlayButton: !0 + + window.scrollTo(0, 0); + updateFilterControls(page); + var html; + var pagingHtml = libraryBrowser.getQueryPagingHtml({ + startIndex: query.StartIndex, + limit: query.Limit, + totalRecordCount: result.TotalRecordCount, + showLimit: false, + updatePageSizeSetting: false, + addLayoutButton: false, + sortButton: false, + filterButton: false }); - var i, length, elems = tabContent.querySelectorAll(".paging"); - for (i = 0, length = elems.length; i < length; i++) elems[i].innerHTML = pagingHtml; - for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick); - for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick); + var viewStyle = self.getCurrentViewStyle(); + if (viewStyle == "List") { + html = listView.getListViewHtml({ + items: result.Items, + context: "music", + sortBy: query.SortBy, + addToListButton: true + }); + } else if (viewStyle == "PosterCard") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "square", + context: "music", + showTitle: true, + coverImage: true, + showParentTitle: true, + lazy: true, + cardLayout: true + }); + } else { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "square", + context: "music", + showTitle: true, + showParentTitle: true, + lazy: true, + centerText: true, + overlayPlayButton: true + }); + } + var i; + var length; + var elems = tabContent.querySelectorAll(".paging"); + + for (i = 0, length = elems.length; i < length; i++) { + elems[i].innerHTML = pagingHtml; + } + + elems = tabContent.querySelectorAll(".btnNextPage"); + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onNextPageClick); + } + + elems = tabContent.querySelectorAll(".btnPreviousPage"); + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onPreviousPageClick); + } + var itemsContainer = tabContent.querySelector(".itemsContainer"); itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); libraryBrowser.saveQueryValues(getSavedQueryKey(), query); loading.hide(); isLoading = false; - }) + }); } function updateFilterControls(tabContent) { var query = getQuery(); - self.alphaPicker.value(query.NameStartsWithOrGreater) + self.alphaPicker.value(query.NameStartsWithOrGreater); } - var savedQueryKey, pageData, self = this, - pageSize = 100, - isLoading = false; - self.showFilterMenu = function() { - require(["components/filterdialog/filterdialog"], function(filterDialogFactory) { - var filterDialog = new filterDialogFactory({ - query: getQuery(), - mode: "albums", - serverId: ApiClient.serverId() - }); - events.on(filterDialog, "filterchange", function() { - getQuery().StartIndex = 0, reloadItems(tabContent) - }), filterDialog.show() - }) - }, self.getCurrentViewStyle = function() { - return getPageData().view - }, - function(tabContent) { - var alphaPickerElement = tabContent.querySelector(".alphaPicker"); - if (alphaPickerElement.addEventListener("alphavaluechanged", function(e) { - var newValue = e.detail.value, - query = getQuery(); - query.NameStartsWithOrGreater = newValue, query.StartIndex = 0, reloadItems(tabContent) - }), self.alphaPicker = new alphaPicker({ - element: alphaPickerElement, - valueChangeEvent: "click" - }), layoutManager.desktop || layoutManager.mobile) { - tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right"); - var itemsContainer = tabContent.querySelector(".itemsContainer"); - itemsContainer.classList.remove("padded-left-withalphapicker"), itemsContainer.classList.add("padded-right-withalphapicker") - } - tabContent.querySelector(".btnFilter").addEventListener("click", function() { - self.showFilterMenu() - }), tabContent.querySelector(".btnSort").addEventListener("click", function(e) { - libraryBrowser.showSortMenu({ - items: [{ - name: Globalize.translate("OptionNameSort"), - id: "SortName" - }, { - name: Globalize.translate("OptionAlbumArtist"), - id: "AlbumArtist,SortName" - }, { - name: Globalize.translate("OptionCommunityRating"), - id: "CommunityRating,SortName" - }, { - name: Globalize.translate("OptionCriticRating"), - id: "CriticRating,SortName" - }, { - name: Globalize.translate("OptionDateAdded"), - id: "DateCreated,SortName" - }, { - name: Globalize.translate("OptionReleaseDate"), - id: "ProductionYear,PremiereDate,SortName" - }], - callback: function() { - getQuery().StartIndex = 0, reloadItems(tabContent) - }, - query: getQuery(), - button: e.target - }) + + var savedQueryKey; + var pageData; + var self = this; + var pageSize = 100; + var isLoading = false; + + self.showFilterMenu = function () { + require(["components/filterdialog/filterdialog"], function (filterDialogFactory) { + var filterDialog = new filterDialogFactory({ + query: getQuery(), + mode: "albums", + serverId: ApiClient.serverId() }); - var btnSelectView = tabContent.querySelector(".btnSelectView"); - btnSelectView.addEventListener("click", function(e) { - libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard".split(",")) - }), btnSelectView.addEventListener("layoutchange", function(e) { - var viewStyle = e.detail.viewStyle; - getPageData().view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle), getQuery().StartIndex = 0, onViewStyleChange(), reloadItems(tabContent) - }), tabContent.querySelector(".btnPlayAll").addEventListener("click", playAll), tabContent.querySelector(".btnShuffle").addEventListener("click", shuffle) - }(tabContent), onViewStyleChange(), self.renderTab = function() { - reloadItems(tabContent), updateFilterControls(tabContent) - }, self.destroy = function() {} - } + events.on(filterDialog, "filterchange", function () { + getQuery().StartIndex = 0; + reloadItems(tabContent); + }); + filterDialog.show(); + }); + }; + + self.getCurrentViewStyle = function () { + return getPageData().view; + }; + + function initPage(tabContent) { + var alphaPickerElement = tabContent.querySelector(".alphaPicker"); + + alphaPickerElement.addEventListener("alphavaluechanged", function (e) { + var newValue = e.detail.value; + var query = getQuery(); + query.NameStartsWithOrGreater = newValue; + query.StartIndex = 0; + reloadItems(tabContent); + }); + self.alphaPicker = new alphaPicker({ + element: alphaPickerElement, + valueChangeEvent: "click" + }); + if (layoutManager.desktop || layoutManager.mobile) { + tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right"); + var itemsContainer = tabContent.querySelector(".itemsContainer"); + itemsContainer.classList.remove("padded-left-withalphapicker"); + itemsContainer.classList.add("padded-right-withalphapicker"); + } + + tabContent.querySelector(".btnFilter").addEventListener("click", function () { + self.showFilterMenu(); + }); + tabContent.querySelector(".btnSort").addEventListener("click", function (e) { + libraryBrowser.showSortMenu({ + items: [{ + name: Globalize.translate("OptionNameSort"), + id: "SortName" + }, { + name: Globalize.translate("OptionAlbumArtist"), + id: "AlbumArtist,SortName" + }, { + name: Globalize.translate("OptionCommunityRating"), + id: "CommunityRating,SortName" + }, { + name: Globalize.translate("OptionCriticRating"), + id: "CriticRating,SortName" + }, { + name: Globalize.translate("OptionDateAdded"), + id: "DateCreated,SortName" + }, { + name: Globalize.translate("OptionReleaseDate"), + id: "ProductionYear,PremiereDate,SortName" + }], + callback: function () { + getQuery().StartIndex = 0; + reloadItems(tabContent); + }, + query: getQuery(), + button: e.target + }); + }); + var btnSelectView = tabContent.querySelector(".btnSelectView"); + btnSelectView.addEventListener("click", function (e) { + libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard".split(",")); + }); + btnSelectView.addEventListener("layoutchange", function (e) { + var viewStyle = e.detail.viewStyle; + getPageData().view = viewStyle; + libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle); + getQuery().StartIndex = 0; + onViewStyleChange(); + reloadItems(tabContent); + }); + tabContent.querySelector(".btnPlayAll").addEventListener("click", playAll); + tabContent.querySelector(".btnShuffle").addEventListener("click", shuffle); + } + + initPage(tabContent); + onViewStyleChange(); + + self.renderTab = function () { + reloadItems(tabContent); + updateFilterControls(tabContent); + }; + + self.destroy = function () {}; + }; }); diff --git a/src/controllers/music/musicartists.js b/src/controllers/music/musicartists.js index b28385169d..5159f635f8 100644 --- a/src/controllers/music/musicartists.js +++ b/src/controllers/music/musicartists.js @@ -1,144 +1,226 @@ -define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function(layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) { +define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) { "use strict"; - return function(view, params, tabContent) { + + return function (view, params, tabContent) { function getPageData(context) { - var key = getSavedQueryKey(context), - pageData = data[key]; - return pageData || (pageData = data[key] = { - query: { - SortBy: "SortName", - SortOrder: "Ascending", - Recursive: !0, - Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo", - StartIndex: 0, - ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb", - Limit: 100 - }, - view: libraryBrowser.getSavedView(key) || "Poster" - }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData + var key = getSavedQueryKey(context); + var pageData = data[key]; + + if (!pageData) { + pageData = data[key] = { + query: { + SortBy: "SortName", + SortOrder: "Ascending", + Recursive: true, + Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo", + StartIndex: 0, + ImageTypeLimit: 1, + EnableImageTypes: "Primary,Backdrop,Banner,Thumb", + Limit: 100 + }, + view: libraryBrowser.getSavedView(key) || "Poster" + }; + pageData.query.ParentId = params.topParentId; + libraryBrowser.loadSavedQueryValues(key, pageData.query); + } + + return pageData; } function getQuery(context) { - return getPageData(context).query + return getPageData(context).query; } function getSavedQueryKey(context) { - return context.savedQueryKey || (context.savedQueryKey = libraryBrowser.getSavedQueryKey(self.mode)), context.savedQueryKey + if (!context.savedQueryKey) { + context.savedQueryKey = libraryBrowser.getSavedQueryKey(self.mode); + } + + return context.savedQueryKey; } function onViewStyleChange() { - var viewStyle = self.getCurrentViewStyle(), - itemsContainer = tabContent.querySelector(".itemsContainer"); - "List" == viewStyle ? (itemsContainer.classList.add("vertical-list"), itemsContainer.classList.remove("vertical-wrap")) : (itemsContainer.classList.remove("vertical-list"), itemsContainer.classList.add("vertical-wrap")), itemsContainer.innerHTML = "" + var viewStyle = self.getCurrentViewStyle(); + var itemsContainer = tabContent.querySelector(".itemsContainer"); + + if ("List" == viewStyle) { + itemsContainer.classList.add("vertical-list"); + itemsContainer.classList.remove("vertical-wrap"); + } else { + itemsContainer.classList.remove("vertical-list"); + itemsContainer.classList.add("vertical-wrap"); + } + + itemsContainer.innerHTML = ""; } function reloadItems(page) { loading.show(); isLoading = true; var query = getQuery(page); - ("albumartists" == self.mode ? ApiClient.getAlbumArtists(ApiClient.getCurrentUserId(), query) : ApiClient.getArtists(ApiClient.getCurrentUserId(), query)).then(function(result) { + var promise = self.mode == 'albumartists' ? + ApiClient.getAlbumArtists(ApiClient.getCurrentUserId(), query) : + ApiClient.getArtists(ApiClient.getCurrentUserId(), query); + promise.then(function (result) { function onNextPageClick() { - if (isLoading) return; - query.StartIndex += query.Limit, reloadItems(tabContent) + if (isLoading) { + return; + } + + query.StartIndex += query.Limit; + reloadItems(tabContent); } function onPreviousPageClick() { - if (isLoading) return; - query.StartIndex -= query.Limit, reloadItems(tabContent) + if (isLoading) { + return; + } + + query.StartIndex -= query.Limit; + reloadItems(tabContent); } - window.scrollTo(0, 0), updateFilterControls(page); - var html, pagingHtml = libraryBrowser.getQueryPagingHtml({ - startIndex: query.StartIndex, - limit: query.Limit, - totalRecordCount: result.TotalRecordCount, - showLimit: !1, - updatePageSizeSetting: !1, - addLayoutButton: !1, - sortButton: !1, - filterButton: !1 - }), - viewStyle = self.getCurrentViewStyle(); - html = "List" == viewStyle ? listView.getListViewHtml({ - items: result.Items, - sortBy: query.SortBy - }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "square", - context: "music", - showTitle: !0, - coverImage: !0, - cardLayout: !0 - }) : cardBuilder.getCardsHtml({ - items: result.Items, - shape: "square", - context: "music", - showTitle: !0, - coverImage: !0, - lazy: !0, - centerText: !0, - overlayPlayButton: !0 + + window.scrollTo(0, 0); + updateFilterControls(page); + var html; + var pagingHtml = libraryBrowser.getQueryPagingHtml({ + startIndex: query.StartIndex, + limit: query.Limit, + totalRecordCount: result.TotalRecordCount, + showLimit: false, + updatePageSizeSetting: false, + addLayoutButton: false, + sortButton: false, + filterButton: false }); - var i, length, elems = tabContent.querySelectorAll(".paging"); - for (i = 0, length = elems.length; i < length; i++) elems[i].innerHTML = pagingHtml; - for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick); - for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick); + var viewStyle = self.getCurrentViewStyle(); + if (viewStyle == "List") { + html = listView.getListViewHtml({ + items: result.Items, + sortBy: query.SortBy + }); + } else if (viewStyle == "PosterCard") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "square", + context: "music", + showTitle: true, + coverImage: true, + cardLayout: true + }); + } else { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "square", + context: "music", + showTitle: true, + coverImage: true, + lazy: true, + centerText: true, + overlayPlayButton: true + }); + } + var i; + var length; + var elems = tabContent.querySelectorAll(".paging"); + + for (i = 0, length = elems.length; i < length; i++) { + elems[i].innerHTML = pagingHtml; + } + + elems = tabContent.querySelectorAll(".btnNextPage"); + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onNextPageClick); + } + + elems = tabContent.querySelectorAll(".btnPreviousPage"); + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onPreviousPageClick); + } + var itemsContainer = tabContent.querySelector(".itemsContainer"); itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); libraryBrowser.saveQueryValues(getSavedQueryKey(page), query); loading.hide(); isLoading = false; - }) + }); } function updateFilterControls(tabContent) { var query = getQuery(tabContent); - self.alphaPicker.value(query.NameStartsWithOrGreater) + self.alphaPicker.value(query.NameStartsWithOrGreater); } - var self = this, - data = {}, - isLoading = false; - self.showFilterMenu = function() { - require(["components/filterdialog/filterdialog"], function(filterDialogFactory) { - var filterDialog = new filterDialogFactory({ - query: getQuery(tabContent), - mode: self.mode, - serverId: ApiClient.serverId() - }); - events.on(filterDialog, "filterchange", function() { - getQuery(tabContent).StartIndex = 0, reloadItems(tabContent) - }), filterDialog.show() - }) - }, self.getCurrentViewStyle = function() { - return getPageData(tabContent).view - }, - function(tabContent) { - var alphaPickerElement = tabContent.querySelector(".alphaPicker"); - if (alphaPickerElement.addEventListener("alphavaluechanged", function(e) { - var newValue = e.detail.value, - query = getQuery(tabContent); - query.NameStartsWithOrGreater = newValue, query.StartIndex = 0, reloadItems(tabContent) - }), self.alphaPicker = new alphaPicker({ - element: alphaPickerElement, - valueChangeEvent: "click" - }), layoutManager.desktop || layoutManager.mobile) { - tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right"); - var itemsContainer = tabContent.querySelector(".itemsContainer"); - itemsContainer.classList.remove("padded-left-withalphapicker"), itemsContainer.classList.add("padded-right-withalphapicker") - } - tabContent.querySelector(".btnFilter").addEventListener("click", function() { - self.showFilterMenu() + + var self = this; + var data = {}; + var isLoading = false; + + self.showFilterMenu = function () { + require(["components/filterdialog/filterdialog"], function (filterDialogFactory) { + var filterDialog = new filterDialogFactory({ + query: getQuery(tabContent), + mode: self.mode, + serverId: ApiClient.serverId() }); - var btnSelectView = tabContent.querySelector(".btnSelectView"); - btnSelectView.addEventListener("click", function(e) { - libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard".split(",")) - }), btnSelectView.addEventListener("layoutchange", function(e) { - var viewStyle = e.detail.viewStyle; - getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), getQuery(tabContent).StartIndex = 0, onViewStyleChange(), reloadItems(tabContent) - }) - }(tabContent), onViewStyleChange(), self.renderTab = function() { - reloadItems(tabContent), updateFilterControls(tabContent) - }, self.destroy = function() {} - } + events.on(filterDialog, "filterchange", function () { + getQuery(tabContent).StartIndex = 0; + reloadItems(tabContent); + }); + filterDialog.show(); + }); + }; + + self.getCurrentViewStyle = function () { + return getPageData(tabContent).view; + }; + + function initPage(tabContent) { + var alphaPickerElement = tabContent.querySelector(".alphaPicker"); + + alphaPickerElement.addEventListener("alphavaluechanged", function (e) { + var newValue = e.detail.value; + var query = getQuery(tabContent); + query.NameStartsWithOrGreater = newValue; + query.StartIndex = 0; + reloadItems(tabContent); + }); + self.alphaPicker = new alphaPicker({ + element: alphaPickerElement, + valueChangeEvent: "click" + }); + if (layoutManager.desktop || layoutManager.mobile) { + tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right"); + var itemsContainer = tabContent.querySelector(".itemsContainer"); + itemsContainer.classList.remove("padded-left-withalphapicker"); + itemsContainer.classList.add("padded-right-withalphapicker"); + } + + tabContent.querySelector(".btnFilter").addEventListener("click", function () { + self.showFilterMenu(); + }); + var btnSelectView = tabContent.querySelector(".btnSelectView"); + btnSelectView.addEventListener("click", function (e) { + libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard".split(",")); + }); + btnSelectView.addEventListener("layoutchange", function (e) { + var viewStyle = e.detail.viewStyle; + getPageData(tabContent).view = viewStyle; + libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle); + getQuery(tabContent).StartIndex = 0; + onViewStyleChange(); + reloadItems(tabContent); + }); + } + + initPage(tabContent); + onViewStyleChange(); + + self.renderTab = function () { + reloadItems(tabContent); + updateFilterControls(tabContent); + }; + + self.destroy = function () {}; + }; }); diff --git a/src/controllers/music/musicgenres.js b/src/controllers/music/musicgenres.js index f66afcdb20..ed1efc0a6a 100644 --- a/src/controllers/music/musicgenres.js +++ b/src/controllers/music/musicgenres.js @@ -1,91 +1,126 @@ -define(["libraryBrowser", "cardBuilder", "apphost", "imageLoader", "loading"], function(libraryBrowser, cardBuilder, appHost, imageLoader, loading) { +define(["libraryBrowser", "cardBuilder", "apphost", "imageLoader", "loading"], function (libraryBrowser, cardBuilder, appHost, imageLoader, loading) { "use strict"; - return function(view, params, tabContent) { + + return function (view, params, tabContent) { function getPageData() { - var key = getSavedQueryKey(), - pageData = data[key]; - return pageData || (pageData = data[key] = { - query: { - SortBy: "SortName", - SortOrder: "Ascending", - Recursive: !0, - Fields: "PrimaryImageAspectRatio,ItemCounts", - StartIndex: 0 - }, - view: libraryBrowser.getSavedView(key) || "Poster" - }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData + var key = getSavedQueryKey(); + var pageData = data[key]; + + if (!pageData) { + pageData = data[key] = { + query: { + SortBy: "SortName", + SortOrder: "Ascending", + Recursive: true, + Fields: "PrimaryImageAspectRatio,ItemCounts", + StartIndex: 0 + }, + view: libraryBrowser.getSavedView(key) || "Poster" + }; + pageData.query.ParentId = params.topParentId; + libraryBrowser.loadSavedQueryValues(key, pageData.query); + } + + return pageData; } function getQuery() { - return getPageData().query + return getPageData().query; } function getSavedQueryKey() { - return libraryBrowser.getSavedQueryKey("genres") + return libraryBrowser.getSavedQueryKey("genres"); } function getPromise() { loading.show(); var query = getQuery(); - return ApiClient.getGenres(ApiClient.getCurrentUserId(), query) + return ApiClient.getGenres(ApiClient.getCurrentUserId(), query); } function reloadItems(context, promise) { var query = getQuery(); - promise.then(function(result) { - var html = "", - viewStyle = self.getCurrentViewStyle(); - "Thumb" == viewStyle ? html = cardBuilder.getCardsHtml({ - items: result.Items, - shape: "backdrop", - preferThumb: !0, - context: "music", - centerText: !0, - overlayMoreButton: !0, - showTitle: !0 - }) : "ThumbCard" == viewStyle ? html = cardBuilder.getCardsHtml({ - items: result.Items, - shape: "backdrop", - preferThumb: !0, - context: "music", - cardLayout: !0, - showTitle: !0 - }) : "PosterCard" == viewStyle ? html = cardBuilder.getCardsHtml({ - items: result.Items, - shape: "auto", - context: "music", - cardLayout: !0, - showTitle: !0 - }) : "Poster" == viewStyle && (html = cardBuilder.getCardsHtml({ - items: result.Items, - shape: "auto", - context: "music", - centerText: !0, - overlayMoreButton: !0, - showTitle: !0 - })); + promise.then(function (result) { + var html = ""; + var viewStyle = self.getCurrentViewStyle(); + + if (viewStyle == "Thumb") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "backdrop", + preferThumb: true, + context: 'music', + centerText: true, + overlayMoreButton: true, + showTitle: true + }); + } else if (viewStyle == "ThumbCard") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "backdrop", + preferThumb: true, + context: 'music', + cardLayout: true, + showTitle: true, + }); + } else if (viewStyle == "PosterCard") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "auto", + context: 'music', + cardLayout: true, + showTitle: true, + }); + } else if (viewStyle == "Poster") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "auto", + context: 'music', + centerText: true, + overlayMoreButton: true, + showTitle: true + }); + } + var elem = context.querySelector("#items"); - elem.innerHTML = html, imageLoader.lazyChildren(elem), libraryBrowser.saveQueryValues(getSavedQueryKey(), query), loading.hide() - }) + elem.innerHTML = html; + imageLoader.lazyChildren(elem); + libraryBrowser.saveQueryValues(getSavedQueryKey(), query); + loading.hide(); + }); } function fullyReload() { - self.preRender(), self.renderTab() + self.preRender(); + self.renderTab(); } - var self = this, - data = {}; - self.getViewStyles = function() { - return "Poster,PosterCard,Thumb,ThumbCard".split(",") - }, self.getCurrentViewStyle = function() { - return getPageData(tabContent).view - }, self.setCurrentViewStyle = function(viewStyle) { - getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), fullyReload() - }, self.enableViewSelection = !0; + + var self = this; + var data = {}; + + self.getViewStyles = function () { + return "Poster,PosterCard,Thumb,ThumbCard".split(","); + }; + + self.getCurrentViewStyle = function () { + return getPageData(tabContent).view; + }; + + self.setCurrentViewStyle = function (viewStyle) { + getPageData(tabContent).view = viewStyle; + libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle); + fullyReload(); + }; + + self.enableViewSelection = true; var promise; - self.preRender = function() { - promise = getPromise() - }, self.renderTab = function() { - reloadItems(tabContent, promise) - } - } -}); \ No newline at end of file + + self.preRender = function () { + promise = getPromise(); + }; + + self.renderTab = function () { + reloadItems(tabContent, promise); + }; + }; +}); diff --git a/src/controllers/music/musicplaylists.js b/src/controllers/music/musicplaylists.js index 511ace73a7..964896077b 100644 --- a/src/controllers/music/musicplaylists.js +++ b/src/controllers/music/musicplaylists.js @@ -1,64 +1,81 @@ -define(["libraryBrowser", "cardBuilder", "apphost", "imageLoader", "loading"], function(libraryBrowser, cardBuilder, appHost, imageLoader, loading) { +define(["libraryBrowser", "cardBuilder", "apphost", "imageLoader", "loading"], function (libraryBrowser, cardBuilder, appHost, imageLoader, loading) { "use strict"; - return function(view, params, tabContent) { + + return function (view, params, tabContent) { function getPageData() { - var key = getSavedQueryKey(), - pageData = data[key]; - return pageData || (pageData = data[key] = { - query: { - SortBy: "SortName", - SortOrder: "Ascending", - IncludeItemTypes: "Playlist", - Recursive: !0, - Fields: "PrimaryImageAspectRatio,SortName,CanDelete", - StartIndex: 0 - }, - view: libraryBrowser.getSavedView(key) || "Poster" - }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData + var key = getSavedQueryKey(); + var pageData = data[key]; + + if (!pageData) { + pageData = data[key] = { + query: { + SortBy: "SortName", + SortOrder: "Ascending", + IncludeItemTypes: "Playlist", + Recursive: true, + Fields: "PrimaryImageAspectRatio,SortName,CanDelete", + StartIndex: 0 + }, + view: libraryBrowser.getSavedView(key) || "Poster" + }; + pageData.query.ParentId = params.topParentId; + libraryBrowser.loadSavedQueryValues(key, pageData.query); + } + + return pageData; } function getQuery() { - return getPageData().query + return getPageData().query; } function getSavedQueryKey() { - return libraryBrowser.getSavedQueryKey("genres") + return libraryBrowser.getSavedQueryKey("genres"); } function getPromise() { loading.show(); var query = getQuery(); - return ApiClient.getItems(ApiClient.getCurrentUserId(), query) + return ApiClient.getItems(ApiClient.getCurrentUserId(), query); } function reloadItems(context, promise) { var query = getQuery(); - promise.then(function(result) { + promise.then(function (result) { var html = ""; html = cardBuilder.getCardsHtml({ items: result.Items, shape: "square", - showTitle: !0, - coverImage: !0, - centerText: !0, - overlayPlayButton: !0, - allowBottomPadding: !0, - cardLayout: !1 + showTitle: true, + coverImage: true, + centerText: true, + overlayPlayButton: true, + allowBottomPadding: true, + cardLayout: false }); var elem = context.querySelector("#items"); - elem.innerHTML = html, imageLoader.lazyChildren(elem), libraryBrowser.saveQueryValues(getSavedQueryKey(), query), loading.hide() - }) + elem.innerHTML = html; + imageLoader.lazyChildren(elem); + libraryBrowser.saveQueryValues(getSavedQueryKey(), query); + loading.hide(); + }); } - var self = this, - data = {}; - self.getCurrentViewStyle = function() { - return getPageData(tabContent).view + + var self = this; + var data = {}; + + self.getCurrentViewStyle = function () { + return getPageData(tabContent).view; }; + var promise; - self.preRender = function() { - promise = getPromise() - }, self.renderTab = function() { - reloadItems(tabContent, promise) - } - } -}); \ No newline at end of file + + self.preRender = function () { + promise = getPromise(); + }; + + self.renderTab = function () { + reloadItems(tabContent, promise); + }; + }; +}); diff --git a/src/controllers/music/musicrecommended.js b/src/controllers/music/musicrecommended.js index 5dee7c5f52..fc3371833d 100644 --- a/src/controllers/music/musicrecommended.js +++ b/src/controllers/music/musicrecommended.js @@ -1,49 +1,65 @@ -define(["browser", "layoutManager", "userSettings", "inputManager", "loading", "cardBuilder", "dom", "apphost", "imageLoader", "libraryMenu", "playbackManager", "mainTabsManager", "scrollStyles", "emby-itemscontainer", "emby-tabs", "emby-button", "flexStyles"], function(browser, layoutManager, userSettings, inputManager, loading, cardBuilder, dom, appHost, imageLoader, libraryMenu, playbackManager, mainTabsManager) { +define(["browser", "layoutManager", "userSettings", "inputManager", "loading", "cardBuilder", "dom", "apphost", "imageLoader", "libraryMenu", "playbackManager", "mainTabsManager", "scrollStyles", "emby-itemscontainer", "emby-tabs", "emby-button", "flexStyles"], function (browser, layoutManager, userSettings, inputManager, loading, cardBuilder, dom, appHost, imageLoader, libraryMenu, playbackManager, mainTabsManager) { "use strict"; function itemsPerRow() { var screenWidth = dom.getWindowSize().innerWidth; - return screenWidth >= 1920 ? 9 : screenWidth >= 1200 ? 12 : screenWidth >= 1e3 ? 10 : 8 + + if (screenWidth >= 1920) { + return 9; + } + + if (screenWidth >= 1200) { + return 12; + } + + if (screenWidth >= 1000) { + return 10; + } + + return 8; } function enableScrollX() { - return !layoutManager.desktop + return !layoutManager.desktop; } function getSquareShape() { - return enableScrollX() ? "overflowSquare" : "square" + return enableScrollX() ? "overflowSquare" : "square"; } function loadLatest(page, parentId) { loading.show(); - var userId = ApiClient.getCurrentUserId(), - options = { - IncludeItemTypes: "Audio", - Limit: enableScrollX() ? 3 * itemsPerRow() : 2 * itemsPerRow(), - Fields: "PrimaryImageAspectRatio,BasicSyncInfo", - ParentId: parentId, - ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb", - EnableTotalRecordCount: !1 - }; - ApiClient.getJSON(ApiClient.getUrl("Users/" + userId + "/Items/Latest", options)).then(function(items) { - var elem = page.querySelector("#recentlyAddedSongs"), - supportsImageAnalysis = appHost.supports("imageanalysis"); - supportsImageAnalysis = !1, elem.innerHTML = cardBuilder.getCardsHtml({ + var userId = ApiClient.getCurrentUserId(); + var options = { + IncludeItemTypes: "Audio", + Limit: enableScrollX() ? 3 * itemsPerRow() : 2 * itemsPerRow(), + Fields: "PrimaryImageAspectRatio,BasicSyncInfo", + ParentId: parentId, + ImageTypeLimit: 1, + EnableImageTypes: "Primary,Backdrop,Banner,Thumb", + EnableTotalRecordCount: false + }; + ApiClient.getJSON(ApiClient.getUrl("Users/" + userId + "/Items/Latest", options)).then(function (items) { + var elem = page.querySelector("#recentlyAddedSongs"); + var supportsImageAnalysis = appHost.supports("imageanalysis"); + supportsImageAnalysis = false; + elem.innerHTML = cardBuilder.getCardsHtml({ items: items, - showUnplayedIndicator: !1, - showLatestItemsPopup: !1, + showUnplayedIndicator: false, + showLatestItemsPopup: false, shape: getSquareShape(), - showTitle: !0, - showParentTitle: !0, - lazy: !0, + showTitle: true, + showParentTitle: true, + lazy: true, centerText: !supportsImageAnalysis, overlayPlayButton: !supportsImageAnalysis, allowBottomPadding: !enableScrollX(), cardLayout: supportsImageAnalysis, - coverImage: !0 - }), imageLoader.lazyChildren(elem), loading.hide() - }) + coverImage: true + }); + imageLoader.lazyChildren(elem); + loading.hide(); + }); } function loadRecentlyPlayed(page, parentId) { @@ -52,34 +68,42 @@ define(["browser", "layoutManager", "userSettings", "inputManager", "loading", " SortOrder: "Descending", IncludeItemTypes: "Audio", Limit: itemsPerRow(), - Recursive: !0, + Recursive: true, Fields: "PrimaryImageAspectRatio,AudioInfo", Filters: "IsPlayed", ParentId: parentId, ImageTypeLimit: 1, EnableImageTypes: "Primary,Backdrop,Banner,Thumb", - EnableTotalRecordCount: !1 + EnableTotalRecordCount: false }; - ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function(result) { + ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) { var elem = page.querySelector("#recentlyPlayed"); - result.Items.length ? elem.classList.remove("hide") : elem.classList.add("hide"); - var itemsContainer = elem.querySelector(".itemsContainer"), - supportsImageAnalysis = appHost.supports("imageanalysis"); - supportsImageAnalysis = !1, itemsContainer.innerHTML = cardBuilder.getCardsHtml({ + + if (result.Items.length) { + elem.classList.remove("hide"); + } else { + elem.classList.add("hide"); + } + + var itemsContainer = elem.querySelector(".itemsContainer"); + var supportsImageAnalysis = appHost.supports("imageanalysis"); + supportsImageAnalysis = false; + itemsContainer.innerHTML = cardBuilder.getCardsHtml({ items: result.Items, - showUnplayedIndicator: !1, + showUnplayedIndicator: false, shape: getSquareShape(), - showTitle: !0, - showParentTitle: !0, + showTitle: true, + showParentTitle: true, action: "instantmix", - lazy: !0, + lazy: true, centerText: !supportsImageAnalysis, overlayMoreButton: !supportsImageAnalysis, allowBottomPadding: !enableScrollX(), cardLayout: supportsImageAnalysis, - coverImage: !0 - }), imageLoader.lazyChildren(itemsContainer) - }) + coverImage: true + }); + imageLoader.lazyChildren(itemsContainer); + }); } function loadFrequentlyPlayed(page, parentId) { @@ -88,40 +112,53 @@ define(["browser", "layoutManager", "userSettings", "inputManager", "loading", " SortOrder: "Descending", IncludeItemTypes: "Audio", Limit: itemsPerRow(), - Recursive: !0, + Recursive: true, Fields: "PrimaryImageAspectRatio,AudioInfo", Filters: "IsPlayed", ParentId: parentId, ImageTypeLimit: 1, EnableImageTypes: "Primary,Backdrop,Banner,Thumb", - EnableTotalRecordCount: !1 + EnableTotalRecordCount: false }; - ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function(result) { + ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) { var elem = page.querySelector("#topPlayed"); - result.Items.length ? elem.classList.remove("hide") : elem.classList.add("hide"); - var itemsContainer = elem.querySelector(".itemsContainer"), - supportsImageAnalysis = appHost.supports("imageanalysis"); - supportsImageAnalysis = !1, itemsContainer.innerHTML = cardBuilder.getCardsHtml({ + + if (result.Items.length) { + elem.classList.remove("hide"); + } else { + elem.classList.add("hide"); + } + + var itemsContainer = elem.querySelector(".itemsContainer"); + var supportsImageAnalysis = appHost.supports("imageanalysis"); + supportsImageAnalysis = false; + itemsContainer.innerHTML = cardBuilder.getCardsHtml({ items: result.Items, - showUnplayedIndicator: !1, + showUnplayedIndicator: false, shape: getSquareShape(), - showTitle: !0, - showParentTitle: !0, + showTitle: true, + showParentTitle: true, action: "instantmix", - lazy: !0, + lazy: true, centerText: !supportsImageAnalysis, overlayMoreButton: !supportsImageAnalysis, allowBottomPadding: !enableScrollX(), cardLayout: supportsImageAnalysis, - coverImage: !0 - }), imageLoader.lazyChildren(itemsContainer) - }) + coverImage: true + }); + imageLoader.lazyChildren(itemsContainer); + }); } function loadSuggestionsTab(page, tabContent, parentId) { - console.log("loadSuggestionsTab"), loadLatest(tabContent, parentId), loadRecentlyPlayed(tabContent, parentId), loadFrequentlyPlayed(tabContent, parentId), require(["components/favoriteitems"], function(favoriteItems) { - favoriteItems.render(tabContent, ApiClient.getCurrentUserId(), parentId, ["favoriteArtists", "favoriteAlbums", "favoriteSongs"]) - }) + console.log("loadSuggestionsTab"); + loadLatest(tabContent, parentId); + loadRecentlyPlayed(tabContent, parentId); + loadFrequentlyPlayed(tabContent, parentId); + + require(["components/favoriteitems"], function (favoriteItems) { + favoriteItems.render(tabContent, ApiClient.getCurrentUserId(), parentId, ["favoriteArtists", "favoriteAlbums", "favoriteSongs"]); + }); } function getTabs() { @@ -142,135 +179,227 @@ define(["browser", "layoutManager", "userSettings", "inputManager", "loading", " }, { name: Globalize.translate("ButtonSearch"), cssClass: "searchTabButton" - }] + }]; } function getDefaultTabIndex(folderId) { switch (userSettings.get("landing-" + folderId)) { case "albums": return 1; + case "albumartists": return 2; + case "artists": return 3; + case "playlists": return 4; + case "songs": return 5; + case "genres": return 6; + default: - return 0 + return 0; } } - return function(view, params) { + + return function (view, params) { function reload() { loading.show(); var tabContent = view.querySelector(".pageTabContent[data-index='0']"); - loadSuggestionsTab(view, tabContent, params.topParentId) + loadSuggestionsTab(view, tabContent, params.topParentId); } function enableScrollX() { - return browser.mobile + return browser.mobile; } function setScrollClasses(elem, scrollX) { - scrollX ? (elem.classList.add("hiddenScrollX"), layoutManager.tv && elem.classList.add("smoothScrollX"), elem.classList.add("scrollX"), elem.classList.remove("vertical-wrap")) : (elem.classList.remove("hiddenScrollX"), elem.classList.remove("smoothScrollX"), elem.classList.remove("scrollX"), elem.classList.add("vertical-wrap")) + if (scrollX) { + elem.classList.add("hiddenScrollX"); + + if (layoutManager.tv) { + elem.classList.add("smoothScrollX"); + } + + elem.classList.add("scrollX"); + elem.classList.remove("vertical-wrap"); + } else { + elem.classList.remove("hiddenScrollX"); + elem.classList.remove("smoothScrollX"); + elem.classList.remove("scrollX"); + elem.classList.add("vertical-wrap"); + } } function onBeforeTabChange(e) { - preLoadTab(view, parseInt(e.detail.selectedTabIndex)) + preLoadTab(view, parseInt(e.detail.selectedTabIndex)); } function onTabChange(e) { - loadTab(view, parseInt(e.detail.selectedTabIndex)) + loadTab(view, parseInt(e.detail.selectedTabIndex)); } function getTabContainers() { - return view.querySelectorAll(".pageTabContent") + return view.querySelectorAll(".pageTabContent"); } function initTabs() { - mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange) + mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange); } function getTabController(page, index, callback) { var depends = []; + switch (index) { case 0: break; + case 1: depends.push("controllers/music/musicalbums"); break; + case 2: case 3: depends.push("controllers/music/musicartists"); break; + case 4: depends.push("controllers/music/musicplaylists"); break; + case 5: depends.push("controllers/music/songs"); break; + case 6: depends.push("controllers/music/musicgenres"); break; + case 7: - depends.push("scripts/searchtab") + depends.push("scripts/searchtab"); } - require(depends, function(controllerFactory) { + + require(depends, function (controllerFactory) { var tabContent; - 0 == index && (tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"), self.tabContent = tabContent); + + if (0 == index) { + tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); + self.tabContent = tabContent; + } + var controller = tabControllers[index]; - controller || (tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"), controller = 0 === index ? self : 7 === index ? new controllerFactory(view, tabContent, { - collectionType: "music", - parentId: params.topParentId - }) : new controllerFactory(view, params, tabContent), 2 == index ? controller.mode = "albumartists" : 3 == index && (controller.mode = "artists"), tabControllers[index] = controller, controller.initTab && controller.initTab()), callback(controller) - }) + + if (!controller) { + tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); + + if (index === 0) { + controller = self; + } else if (index === 7) { + controller = new controllerFactory(view, tabContent, { + collectionType: "music", + parentId: params.topParentId + }); + } else { + controller = new controllerFactory(view, params, tabContent); + } + + if (index == 2) { + controller.mode = "albumartists"; + } else if (index == 3) { + controller.mode = "artists"; + } + + tabControllers[index] = controller; + if (controller.initTab) { + controller.initTab(); + } + } + + callback(controller); + }); } function preLoadTab(page, index) { - getTabController(page, index, function(controller) { - -1 == renderedTabs.indexOf(index) && controller.preRender && controller.preRender() - }) + getTabController(page, index, function (controller) { + if (renderedTabs.indexOf(index) == -1 && controller.preRender) { + controller.preRender(); + } + }); } function loadTab(page, index) { - currentTabIndex = index, getTabController(page, index, function(controller) { - initialTabIndex = null, -1 == renderedTabs.indexOf(index) && (renderedTabs.push(index), controller.renderTab()) - }) + currentTabIndex = index; + getTabController(page, index, function (controller) { + initialTabIndex = null; + + if (renderedTabs.indexOf(index) == -1) { + renderedTabs.push(index); + controller.renderTab(); + } + }); } function onInputCommand(e) { switch (e.detail.command) { case "search": - e.preventDefault(), Dashboard.navigate("search.html?collectionType=music&parentId=" + params.topParentId) + e.preventDefault(); + Dashboard.navigate("search.html?collectionType=music&parentId=" + params.topParentId); } } - var isViewRestored, self = this, - currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)), - initialTabIndex = currentTabIndex; - self.initTab = function() { - for (var tabContent = view.querySelector(".pageTabContent[data-index='0']"), containers = tabContent.querySelectorAll(".itemsContainer"), i = 0, length = containers.length; i < length; i++) setScrollClasses(containers[i], enableScrollX()) - }, self.renderTab = function() { - reload() - }; - var tabControllers = [], - renderedTabs = []; - view.addEventListener("viewshow", function(e) { - if (isViewRestored = e.detail.isRestored, initTabs(), !view.getAttribute("data-title")) { - var parentId = params.topParentId; - parentId ? ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function(item) { - view.setAttribute("data-title", item.Name), libraryMenu.setTitle(item.Name) - }) : (view.setAttribute("data-title", Globalize.translate("TabMusic")), libraryMenu.setTitle(Globalize.translate("TabMusic"))) + + var isViewRestored; + var self = this; + var currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)); + var initialTabIndex = currentTabIndex; + + self.initTab = function () { + var tabContent = view.querySelector(".pageTabContent[data-index='0']"); + var containers = tabContent.querySelectorAll(".itemsContainer"); + + for (var i = 0, length = containers.length; i < length; i++) { + setScrollClasses(containers[i], enableScrollX()); } - inputManager.on(window, onInputCommand) - }), view.addEventListener("viewbeforehide", function(e) { - inputManager.off(window, onInputCommand) - }), view.addEventListener("viewdestroy", function(e) { - tabControllers.forEach(function(t) { - t.destroy && t.destroy() - }) - }) - } -}); \ No newline at end of file + }; + + self.renderTab = function () { + reload(); + }; + + var tabControllers = []; + var renderedTabs = []; + view.addEventListener("viewshow", function (e) { + isViewRestored = e.detail.isRestored; + initTabs(); + if (!view.getAttribute("data-title")) { + var parentId = params.topParentId; + + if (parentId) { + ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function (item) { + view.setAttribute("data-title", item.Name); + libraryMenu.setTitle(item.Name); + }); + } else { + view.setAttribute("data-title", Globalize.translate("TabMusic")); + libraryMenu.setTitle(Globalize.translate("TabMusic")); + } + } + + inputManager.on(window, onInputCommand); + }); + view.addEventListener("viewbeforehide", function (e) { + inputManager.off(window, onInputCommand); + }); + view.addEventListener("viewdestroy", function (e) { + tabControllers.forEach(function (t) { + if (t.destroy) { + t.destroy(); + } + }); + }); + }; +}); diff --git a/src/controllers/music/songs.js b/src/controllers/music/songs.js index f03abe75ff..4806195edd 100644 --- a/src/controllers/music/songs.js +++ b/src/controllers/music/songs.js @@ -1,135 +1,185 @@ -define(["events", "libraryBrowser", "imageLoader", "listView", "loading", "emby-itemscontainer"], function(events, libraryBrowser, imageLoader, listView, loading) { +define(["events", "libraryBrowser", "imageLoader", "listView", "loading", "emby-itemscontainer"], function (events, libraryBrowser, imageLoader, listView, loading) { "use strict"; - return function(view, params, tabContent) { + + return function (view, params, tabContent) { function getPageData(context) { - var key = getSavedQueryKey(context), - pageData = data[key]; - return pageData || (pageData = data[key] = { - query: { - SortBy: "Album,SortName", - SortOrder: "Ascending", - IncludeItemTypes: "Audio", - Recursive: !0, - Fields: "AudioInfo,ParentId", - Limit: 100, - StartIndex: 0, - ImageTypeLimit: 1, - EnableImageTypes: "Primary" - } - }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData + var key = getSavedQueryKey(context); + var pageData = data[key]; + + if (!pageData) { + pageData = data[key] = { + query: { + SortBy: "Album,SortName", + SortOrder: "Ascending", + IncludeItemTypes: "Audio", + Recursive: true, + Fields: "AudioInfo,ParentId", + Limit: 100, + StartIndex: 0, + ImageTypeLimit: 1, + EnableImageTypes: "Primary" + } + }; + pageData.query.ParentId = params.topParentId; + libraryBrowser.loadSavedQueryValues(key, pageData.query); + } + + return pageData; } function getQuery(context) { - return getPageData(context).query + return getPageData(context).query; } function getSavedQueryKey(context) { - return context.savedQueryKey || (context.savedQueryKey = libraryBrowser.getSavedQueryKey("songs")), context.savedQueryKey + if (!context.savedQueryKey) { + context.savedQueryKey = libraryBrowser.getSavedQueryKey("songs"); + } + + return context.savedQueryKey; } function reloadItems(page) { loading.show(); isLoading = true; var query = getQuery(page); - ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function(result) { + ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) { function onNextPageClick() { - if (isLoading) return; - query.StartIndex += query.Limit, reloadItems(tabContent) + if (isLoading) { + return; + } + + query.StartIndex += query.Limit; + reloadItems(tabContent); } function onPreviousPageClick() { - if (isLoading) return; - query.StartIndex -= query.Limit, reloadItems(tabContent) + if (isLoading) { + return; + } + + query.StartIndex -= query.Limit; + reloadItems(tabContent); } + window.scrollTo(0, 0); - var i, length, pagingHtml = libraryBrowser.getQueryPagingHtml({ - startIndex: query.StartIndex, - limit: query.Limit, - totalRecordCount: result.TotalRecordCount, - showLimit: !1, - updatePageSizeSetting: !1, - addLayoutButton: !1, - sortButton: !1, - filterButton: !1 - }), - html = listView.getListViewHtml({ - items: result.Items, - action: "playallfromhere", - smallIcon: !0, - artist: !0, - addToListButton: !0 - }), - elems = tabContent.querySelectorAll(".paging"); - for (i = 0, length = elems.length; i < length; i++) elems[i].innerHTML = pagingHtml; - for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick); - for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick); + var i; + var length; + var pagingHtml = libraryBrowser.getQueryPagingHtml({ + startIndex: query.StartIndex, + limit: query.Limit, + totalRecordCount: result.TotalRecordCount, + showLimit: false, + updatePageSizeSetting: false, + addLayoutButton: false, + sortButton: false, + filterButton: false + }); + var html = listView.getListViewHtml({ + items: result.Items, + action: "playallfromhere", + smallIcon: true, + artist: true, + addToListButton: true + }); + var elems = tabContent.querySelectorAll(".paging"); + + for (i = 0, length = elems.length; i < length; i++) { + elems[i].innerHTML = pagingHtml; + } + + elems = tabContent.querySelectorAll(".btnNextPage"); + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onNextPageClick); + } + + elems = tabContent.querySelectorAll(".btnPreviousPage"); + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onPreviousPageClick); + } + var itemsContainer = tabContent.querySelector(".itemsContainer"); itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); libraryBrowser.saveQueryValues(getSavedQueryKey(page), query); loading.hide(); isLoading = false; - }) + }); } - var self = this, - data = {}, - isLoading = false; - self.showFilterMenu = function() { - require(["components/filterdialog/filterdialog"], function(filterDialogFactory) { - var filterDialog = new filterDialogFactory({ - query: getQuery(tabContent), - mode: "songs", - serverId: ApiClient.serverId() - }); - events.on(filterDialog, "filterchange", function() { - getQuery(tabContent).StartIndex = 0, reloadItems(tabContent) - }), filterDialog.show() - }) - }, self.getCurrentViewStyle = function() { - return getPageData(tabContent).view - }, - function(tabContent) { - tabContent.querySelector(".btnFilter").addEventListener("click", function() { - self.showFilterMenu() - }), tabContent.querySelector(".btnSort").addEventListener("click", function(e) { - libraryBrowser.showSortMenu({ - items: [{ - name: Globalize.translate("OptionTrackName"), - id: "Name" - }, { - name: Globalize.translate("OptionAlbum"), - id: "Album,SortName" - }, { - name: Globalize.translate("OptionAlbumArtist"), - id: "AlbumArtist,Album,SortName" - }, { - name: Globalize.translate("OptionArtist"), - id: "Artist,Album,SortName" - }, { - name: Globalize.translate("OptionDateAdded"), - id: "DateCreated,SortName" - }, { - name: Globalize.translate("OptionDatePlayed"), - id: "DatePlayed,SortName" - }, { - name: Globalize.translate("OptionPlayCount"), - id: "PlayCount,SortName" - }, { - name: Globalize.translate("OptionReleaseDate"), - id: "PremiereDate,AlbumArtist,Album,SortName" - }, { - name: Globalize.translate("OptionRuntime"), - id: "Runtime,AlbumArtist,Album,SortName" - }], - callback: function() { - getQuery(tabContent).StartIndex = 0, reloadItems(tabContent) - }, - query: getQuery(tabContent), - button: e.target - }) - }) - }(tabContent), self.renderTab = function() { - reloadItems(tabContent) - }, self.destroy = function() {} - } + + var self = this; + var data = {}; + var isLoading = false; + + self.showFilterMenu = function () { + require(["components/filterdialog/filterdialog"], function (filterDialogFactory) { + var filterDialog = new filterDialogFactory({ + query: getQuery(tabContent), + mode: "songs", + serverId: ApiClient.serverId() + }); + events.on(filterDialog, "filterchange", function () { + getQuery(tabContent).StartIndex = 0; + reloadItems(tabContent); + }); + filterDialog.show(); + }); + }; + + self.getCurrentViewStyle = function () { + return getPageData(tabContent).view; + }; + + function initPage(tabContent) { + tabContent.querySelector(".btnFilter").addEventListener("click", function () { + self.showFilterMenu(); + }); + tabContent.querySelector(".btnSort").addEventListener("click", function (e) { + libraryBrowser.showSortMenu({ + items: [{ + name: Globalize.translate("OptionTrackName"), + id: "Name" + }, { + name: Globalize.translate("OptionAlbum"), + id: "Album,SortName" + }, { + name: Globalize.translate("OptionAlbumArtist"), + id: "AlbumArtist,Album,SortName" + }, { + name: Globalize.translate("OptionArtist"), + id: "Artist,Album,SortName" + }, { + name: Globalize.translate("OptionDateAdded"), + id: "DateCreated,SortName" + }, { + name: Globalize.translate("OptionDatePlayed"), + id: "DatePlayed,SortName" + }, { + name: Globalize.translate("OptionPlayCount"), + id: "PlayCount,SortName" + }, { + name: Globalize.translate("OptionReleaseDate"), + id: "PremiereDate,AlbumArtist,Album,SortName" + }, { + name: Globalize.translate("OptionRuntime"), + id: "Runtime,AlbumArtist,Album,SortName" + }], + callback: function () { + getQuery(tabContent).StartIndex = 0; + reloadItems(tabContent); + }, + query: getQuery(tabContent), + button: e.target + }); + }); + } + + initPage(tabContent); + + self.renderTab = function () { + reloadItems(tabContent); + }; + + self.destroy = function () {}; + }; }); diff --git a/src/controllers/notificationsetting.js b/src/controllers/notificationsetting.js index a9333ba5a3..70e6adaf61 100644 --- a/src/controllers/notificationsetting.js +++ b/src/controllers/notificationsetting.js @@ -1,85 +1,122 @@ -define(["jQuery", "emby-checkbox", "fnchecked"], function($) { +define(["jQuery", "emby-checkbox", "fnchecked"], function ($) { "use strict"; function fillItems(elem, items, cssClass, idPrefix, currentList, isEnabledList) { var html = '
'; - html += items.map(function(u) { - var isChecked = isEnabledList ? -1 != currentList.indexOf(u.Id) : -1 == currentList.indexOf(u.Id), - checkedHtml = isChecked ? ' checked="checked"' : ""; - return '" - }).join(""), html += "
", elem.html(html).trigger("create") + html += items.map(function (u) { + var isChecked = isEnabledList ? currentList.indexOf(u.Id) != -1 : currentList.indexOf(u.Id) == -1; + var checkedHtml = isChecked ? ' checked="checked"' : ""; + return '"; + }).join(""); + html += "
"; + elem.html(html).trigger("create"); } function reload(page) { - var type = getParameterByName("type"), - promise1 = ApiClient.getUsers(), - promise2 = ApiClient.getNamedConfiguration(notificationsConfigurationKey), - promise3 = ApiClient.getJSON(ApiClient.getUrl("Notifications/Types")), - promise4 = ApiClient.getJSON(ApiClient.getUrl("Notifications/Services")); - Promise.all([promise1, promise2, promise3, promise4]).then(function(responses) { - var users = responses[0], - notificationOptions = responses[1], - types = responses[2], - services = responses[3], - notificationConfig = notificationOptions.Options.filter(function(n) { - return n.Type == type - })[0], - typeInfo = types.filter(function(n) { - return n.Type == type - })[0] || {}; - typeInfo.IsBasedOnUserEvent ? $(".monitorUsers", page).show() : $(".monitorUsers", page).hide(), $(".notificationType", page).html(typeInfo.Name || "Unknown Notification"), notificationConfig || (notificationConfig = { - DisabledMonitorUsers: [], - SendToUsers: [], - DisabledServices: [], - SendToUserMode: "Admins" - }), fillItems($(".monitorUsersList", page), users, "chkMonitor", "chkMonitor", notificationConfig.DisabledMonitorUsers), fillItems($(".sendToUsersList", page), users, "chkSendTo", "chkSendTo", notificationConfig.SendToUsers, !0), fillItems($(".servicesList", page), services, "chkService", "chkService", notificationConfig.DisabledServices), $("#chkEnabled", page).checked(notificationConfig.Enabled || !1), $("#selectUsers", page).val(notificationConfig.SendToUserMode).trigger("change") - }) + var type = getParameterByName("type"); + var promise1 = ApiClient.getUsers(); + var promise2 = ApiClient.getNamedConfiguration(notificationsConfigurationKey); + var promise3 = ApiClient.getJSON(ApiClient.getUrl("Notifications/Types")); + var promise4 = ApiClient.getJSON(ApiClient.getUrl("Notifications/Services")); + Promise.all([promise1, promise2, promise3, promise4]).then(function (responses) { + var users = responses[0]; + var notificationOptions = responses[1]; + var types = responses[2]; + var services = responses[3]; + var notificationConfig = notificationOptions.Options.filter(function (n) { + return n.Type == type; + })[0]; + var typeInfo = types.filter(function (n) { + return n.Type == type; + })[0] || {}; + + if (typeInfo.IsBasedOnUserEvent) { + $(".monitorUsers", page).show(); + } else { + $(".monitorUsers", page).hide(); + } + + $(".notificationType", page).html(typeInfo.Name || "Unknown Notification"); + + if (!notificationConfig) { + notificationConfig = { + DisabledMonitorUsers: [], + SendToUsers: [], + DisabledServices: [], + SendToUserMode: "Admins" + }; + } + + fillItems($(".monitorUsersList", page), users, "chkMonitor", "chkMonitor", notificationConfig.DisabledMonitorUsers); + fillItems($(".sendToUsersList", page), users, "chkSendTo", "chkSendTo", notificationConfig.SendToUsers, true); + fillItems($(".servicesList", page), services, "chkService", "chkService", notificationConfig.DisabledServices); + $("#chkEnabled", page).checked(notificationConfig.Enabled || false); + $("#selectUsers", page).val(notificationConfig.SendToUserMode).trigger("change"); + }); } function save(page) { - var type = getParameterByName("type"), - promise1 = ApiClient.getNamedConfiguration(notificationsConfigurationKey), - promise2 = ApiClient.getJSON(ApiClient.getUrl("Notifications/Types")); - Promise.all([promise1, promise2]).then(function(responses) { - var notificationOptions = responses[0], - types = responses[1], - notificationConfig = notificationOptions.Options.filter(function(n) { - return n.Type == type - })[0]; - notificationConfig || (notificationConfig = { - Type: type - }, notificationOptions.Options.push(notificationConfig)); - types.filter(function(n) { - return n.Type == type + var type = getParameterByName("type"); + var promise1 = ApiClient.getNamedConfiguration(notificationsConfigurationKey); + var promise2 = ApiClient.getJSON(ApiClient.getUrl("Notifications/Types")); + Promise.all([promise1, promise2]).then(function (responses) { + var notificationOptions = responses[0]; + var types = responses[1]; + var notificationConfig = notificationOptions.Options.filter(function (n) { + return n.Type == type; })[0]; - notificationConfig.Enabled = $("#chkEnabled", page).checked(), notificationConfig.SendToUserMode = $("#selectUsers", page).val(), notificationConfig.DisabledMonitorUsers = $(".chkMonitor", page).get().filter(function(c) { - return !c.checked - }).map(function(c) { - return c.getAttribute("data-itemid") - }), notificationConfig.SendToUsers = $(".chkSendTo", page).get().filter(function(c) { - return c.checked - }).map(function(c) { - return c.getAttribute("data-itemid") - }), notificationConfig.DisabledServices = $(".chkService", page).get().filter(function(c) { - return !c.checked - }).map(function(c) { - return c.getAttribute("data-itemid") - }), ApiClient.updateNamedConfiguration(notificationsConfigurationKey, notificationOptions).then(function(r) { - Dashboard.processServerConfigurationUpdateResult(), Dashboard.navigate("notificationsettings.html") - }) - }) + + if (!notificationConfig) { + notificationConfig = { + Type: type + }; + notificationOptions.Options.push(notificationConfig); + } + + types.filter(function (n) { + return n.Type == type; + })[0]; + notificationConfig.Enabled = $("#chkEnabled", page).checked(); + notificationConfig.SendToUserMode = $("#selectUsers", page).val(); + notificationConfig.DisabledMonitorUsers = $(".chkMonitor", page).get().filter(function (c) { + return !c.checked; + }).map(function (c) { + return c.getAttribute("data-itemid"); + }); + notificationConfig.SendToUsers = $(".chkSendTo", page).get().filter(function (c) { + return c.checked; + }).map(function (c) { + return c.getAttribute("data-itemid"); + }); + notificationConfig.DisabledServices = $(".chkService", page).get().filter(function (c) { + return !c.checked; + }).map(function (c) { + return c.getAttribute("data-itemid"); + }); + ApiClient.updateNamedConfiguration(notificationsConfigurationKey, notificationOptions).then(function (r) { + Dashboard.processServerConfigurationUpdateResult(); + Dashboard.navigate("notificationsettings.html"); + }); + }); } function onSubmit() { - return save($(this).parents(".page")), !1 + save($(this).parents(".page")); + return false; } + var notificationsConfigurationKey = "notifications"; - $(document).on("pageinit", "#notificationSettingPage", function() { + $(document).on("pageinit", "#notificationSettingPage", function () { var page = this; - $("#selectUsers", page).on("change", function() { - "Custom" == this.value ? $(".selectCustomUsers", page).show() : $(".selectCustomUsers", page).hide() - }), $(".notificationSettingForm").off("submit", onSubmit).on("submit", onSubmit) - }).on("pageshow", "#notificationSettingPage", function() { - reload(this) - }) -}); \ No newline at end of file + $("#selectUsers", page).on("change", function () { + if ("Custom" == this.value) { + $(".selectCustomUsers", page).show(); + } else { + $(".selectCustomUsers", page).hide(); + } + }); + $(".notificationSettingForm").off("submit", onSubmit).on("submit", onSubmit); + }).on("pageshow", "#notificationSettingPage", function () { + reload(this); + }); +}); diff --git a/src/controllers/nowplayingpage.js b/src/controllers/nowplayingpage.js index 7f1b9b3f11..6fcdb2a79c 100644 --- a/src/controllers/nowplayingpage.js +++ b/src/controllers/nowplayingpage.js @@ -1,11 +1,22 @@ -define(["components/remotecontrol/remotecontrol", "libraryMenu", "emby-button"], function(remotecontrolFactory, libraryMenu) { +define(["components/remotecontrol/remotecontrol", "libraryMenu", "emby-button"], function (remotecontrolFactory, libraryMenu) { "use strict"; - return function(view, params) { - var remoteControl = new remotecontrolFactory; - remoteControl.init(view, view.querySelector(".remoteControlContent")), view.addEventListener("viewshow", function(e) { - libraryMenu.setTransparentMenu(!0), remoteControl && remoteControl.onShow() - }), view.addEventListener("viewbeforehide", function(e) { - libraryMenu.setTransparentMenu(!1), remoteControl && remoteControl.destroy() - }) - } -}); \ No newline at end of file + + return function (view, params) { + var remoteControl = new remotecontrolFactory(); + remoteControl.init(view, view.querySelector(".remoteControlContent")); + view.addEventListener("viewshow", function (e) { + libraryMenu.setTransparentMenu(true); + + if (remoteControl) { + remoteControl.onShow(); + } + }); + view.addEventListener("viewbeforehide", function (e) { + libraryMenu.setTransparentMenu(false); + + if (remoteControl) { + remoteControl.destroy(); + } + }); + }; +}); diff --git a/src/controllers/playbackconfiguration.js b/src/controllers/playbackconfiguration.js index 35a780949d..76c704f7eb 100644 --- a/src/controllers/playbackconfiguration.js +++ b/src/controllers/playbackconfiguration.js @@ -1,16 +1,25 @@ -define(["jQuery", "loading", "libraryMenu"], function($, loading, libraryMenu) { +define(["jQuery", "loading", "libraryMenu"], function ($, loading, libraryMenu) { "use strict"; function loadPage(page, config) { - $("#txtMinResumePct", page).val(config.MinResumePct), $("#txtMaxResumePct", page).val(config.MaxResumePct), $("#txtMinResumeDuration", page).val(config.MinResumeDurationSeconds), loading.hide() + $("#txtMinResumePct", page).val(config.MinResumePct); + $("#txtMaxResumePct", page).val(config.MaxResumePct); + $("#txtMinResumeDuration", page).val(config.MinResumeDurationSeconds); + loading.hide(); } function onSubmit() { loading.show(); var form = this; - return ApiClient.getServerConfiguration().then(function(config) { - config.MinResumePct = $("#txtMinResumePct", form).val(), config.MaxResumePct = $("#txtMaxResumePct", form).val(), config.MinResumeDurationSeconds = $("#txtMinResumeDuration", form).val(), ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult) - }), !1 + ApiClient.getServerConfiguration().then(function (config) { + config.MinResumePct = $('#txtMinResumePct', form).val(); + config.MaxResumePct = $('#txtMaxResumePct', form).val(); + config.MinResumeDurationSeconds = $('#txtMinResumeDuration', form).val(); + + ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult); + }); + + return false; } function getTabs() { @@ -23,17 +32,17 @@ define(["jQuery", "loading", "libraryMenu"], function($, loading, libraryMenu) { }, { href: "streamingsettings.html", name: Globalize.translate("TabStreaming") - }] + }]; } - $(document).on("pageinit", "#playbackConfigurationPage", function() { + $(document).on("pageinit", "#playbackConfigurationPage", function () { $(".playbackConfigurationForm").off("submit", onSubmit).on("submit", onSubmit) - }).on("pageshow", "#playbackConfigurationPage", function() { + }).on("pageshow", "#playbackConfigurationPage", function () { loading.show(); libraryMenu.setTabs("playback", 1, getTabs); var page = this; - ApiClient.getServerConfiguration().then(function(config) { - loadPage(page, config) - }) - }) -}); \ No newline at end of file + ApiClient.getServerConfiguration().then(function (config) { + loadPage(page, config); + }); + }); +}); diff --git a/src/controllers/scheduledtaskpage.js b/src/controllers/scheduledtaskpage.js index 32838c6de3..7dae03cb3d 100644 --- a/src/controllers/scheduledtaskpage.js +++ b/src/controllers/scheduledtaskpage.js @@ -1,111 +1,237 @@ -define(["jQuery", "loading", "datetime", "dom", "globalize", "emby-input", "emby-button", "emby-select"], function($, loading, datetime, dom, globalize) { +define(["jQuery", "loading", "datetime", "dom", "globalize", "emby-input", "emby-button", "emby-select"], function ($, loading, datetime, dom, globalize) { "use strict"; function fillTimeOfDay(select) { - for (var options = [], i = 0; i < 864e5; i += 9e5) options.push({ - name: ScheduledTaskPage.getDisplayTime(1e4 * i), - value: 1e4 * i - }); - select.innerHTML = options.map(function(o) { - return '" - }).join("") + + var options = []; + + for (var i = 0; i < 86400000; i += 900000) { + options.push({ + name: ScheduledTaskPage.getDisplayTime(i * 10000), + value: i * 10000 + }); + } + + select.innerHTML = options.map(function (o) { + return ''; + }).join(""); } - Array.prototype.remove = function(from, to) { + + Array.prototype.remove = function (from, to) { var rest = this.slice((to || from) + 1 || this.length); - return this.length = from < 0 ? this.length + from : from, this.push.apply(this, rest) + this.length = from < 0 ? this.length + from : from; + return this.push.apply(this, rest); }; + var ScheduledTaskPage = { - refreshScheduledTask: function(view) { + refreshScheduledTask: function (view) { loading.show(); var id = getParameterByName("id"); - ApiClient.getScheduledTask(id).then(function(task) { - ScheduledTaskPage.loadScheduledTask(view, task) - }) + ApiClient.getScheduledTask(id).then(function (task) { + ScheduledTaskPage.loadScheduledTask(view, task); + }); }, - loadScheduledTask: function(view, task) { - $(".taskName", view).html(task.Name), $("#pTaskDescription", view).html(task.Description), require(["listViewStyle"], function() { - ScheduledTaskPage.loadTaskTriggers(view, task) - }), loading.hide() + loadScheduledTask: function (view, task) { + $(".taskName", view).html(task.Name); + $("#pTaskDescription", view).html(task.Description); + + require(["listViewStyle"], function () { + ScheduledTaskPage.loadTaskTriggers(view, task); + }); + + loading.hide(); }, - loadTaskTriggers: function(context, task) { + loadTaskTriggers: function (context, task) { var html = ""; html += '
'; + for (var i = 0, length = task.Triggers.length; i < length; i++) { var trigger = task.Triggers[i]; - if (html += '
', html += 'schedule', trigger.MaxRuntimeTicks ? html += '
' : html += '
', html += "
" + ScheduledTaskPage.getTriggerFriendlyName(trigger) + "
", trigger.MaxRuntimeTicks) { + + html += '
'; + html += 'schedule'; + if (trigger.MaxRuntimeMs) { + html += '
'; + } else { + html += '
'; + } + html += "
" + ScheduledTaskPage.getTriggerFriendlyName(trigger) + "
"; + if (trigger.MaxRuntimeMs) { html += '
'; var hours = trigger.MaxRuntimeTicks / 36e9; - html += 1 == hours ? globalize.translate("ValueTimeLimitSingleHour") : globalize.translate("ValueTimeLimitMultiHour", hours), html += "
" + if (hours == 1) { + html += globalize.translate("ValueTimeLimitSingleHour"); + } else { + html += globalize.translate("ValueTimeLimitMultiHour", hours); + } + html += "
"; } - html += "
", html += '', html += "
" + + html += "
"; + html += ''; + html += "
"; } - html += "
", context.querySelector(".taskTriggers").innerHTML = html + + html += "
"; + context.querySelector(".taskTriggers").innerHTML = html; }, - getTriggerFriendlyName: function(trigger) { - if ("DailyTrigger" == trigger.Type) return "Daily at " + ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks); - if ("WeeklyTrigger" == trigger.Type) return trigger.DayOfWeek + "s at " + ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks); - if ("SystemEventTrigger" == trigger.Type && "WakeFromSleep" == trigger.SystemEvent) return "On wake from sleep"; - if ("IntervalTrigger" == trigger.Type) { + getTriggerFriendlyName: function (trigger) { + if ("DailyTrigger" == trigger.Type) { + return "Daily at " + ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks); + } + + if ("WeeklyTrigger" == trigger.Type) { + return trigger.DayOfWeek + "s at " + ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks); + } + + if ("SystemEventTrigger" == trigger.Type && "WakeFromSleep" == trigger.SystemEvent) { + return "On wake from sleep"; + } + + if (trigger.Type == "IntervalTrigger") { + var hours = trigger.IntervalTicks / 36e9; - return .25 == hours ? "Every 15 minutes" : .5 == hours ? "Every 30 minutes" : .75 == hours ? "Every 45 minutes" : 1 == hours ? "Every hour" : "Every " + hours + " hours" + + if (hours == .25) { + return "Every 15 minutes"; + } + if (hours == .5) { + return "Every 30 minutes"; + } + if (hours == .75) { + return "Every 45 minutes"; + } + if (hours == 1) { + return "Every hour"; + } + + return "Every " + hours + " hours"; } - return "StartupTrigger" == trigger.Type ? "On application startup" : trigger.Type + + if (trigger.Type == "StartupTrigger") { + return "On application startup"; + } + + return trigger.Type; }, - getDisplayTime: function(ticks) { - var ms = ticks / 1e4, - now = new Date; - return now.setHours(0, 0, 0, 0), now.setTime(now.getTime() + ms), datetime.getDisplayTime(now) + getDisplayTime: function (ticks) { + var ms = ticks / 1e4; + var now = new Date(); + now.setHours(0, 0, 0, 0); + now.setTime(now.getTime() + ms); + return datetime.getDisplayTime(now); }, - showAddTriggerPopup: function(view) { - $("#selectTriggerType", view).val("DailyTrigger"), view.querySelector("#selectTriggerType").dispatchEvent(new CustomEvent("change", {})), $("#popupAddTrigger", view).removeClass("hide") + showAddTriggerPopup: function (view) { + $("#selectTriggerType", view).val("DailyTrigger"); + view.querySelector("#selectTriggerType").dispatchEvent(new CustomEvent("change", {})); + $("#popupAddTrigger", view).removeClass("hide"); }, - confirmDeleteTrigger: function(view, index) { - require(["confirm"], function(confirm) { - confirm(globalize.translate("MessageDeleteTaskTrigger"), globalize.translate("HeaderDeleteTaskTrigger")).then(function() { - ScheduledTaskPage.deleteTrigger(view, index) - }) - }) + confirmDeleteTrigger: function (view, index) { + require(["confirm"], function (confirm) { + confirm(globalize.translate("MessageDeleteTaskTrigger"), globalize.translate("HeaderDeleteTaskTrigger")).then(function () { + ScheduledTaskPage.deleteTrigger(view, index); + }); + }); }, - deleteTrigger: function(view, index) { + deleteTrigger: function (view, index) { loading.show(); var id = getParameterByName("id"); - ApiClient.getScheduledTask(id).then(function(task) { - task.Triggers.remove(index), ApiClient.updateScheduledTaskTriggers(task.Id, task.Triggers).then(function() { - ScheduledTaskPage.refreshScheduledTask(view) - }) - }) + ApiClient.getScheduledTask(id).then(function (task) { + task.Triggers.remove(index); + ApiClient.updateScheduledTaskTriggers(task.Id, task.Triggers).then(function () { + ScheduledTaskPage.refreshScheduledTask(view); + }); + }); }, - refreshTriggerFields: function(page, triggerType) { - "DailyTrigger" == triggerType ? ($("#fldTimeOfDay", page).show(), $("#fldDayOfWeek", page).hide(), $("#fldSelectSystemEvent", page).hide(), $("#fldSelectInterval", page).hide(), $("#selectTimeOfDay", page).attr("required", "required")) : "WeeklyTrigger" == triggerType ? ($("#fldTimeOfDay", page).show(), $("#fldDayOfWeek", page).show(), $("#fldSelectSystemEvent", page).hide(), $("#fldSelectInterval", page).hide(), $("#selectTimeOfDay", page).attr("required", "required")) : "SystemEventTrigger" == triggerType ? ($("#fldTimeOfDay", page).hide(), $("#fldDayOfWeek", page).hide(), $("#fldSelectSystemEvent", page).show(), $("#fldSelectInterval", page).hide(), $("#selectTimeOfDay", page).removeAttr("required")) : "IntervalTrigger" == triggerType ? ($("#fldTimeOfDay", page).hide(), $("#fldDayOfWeek", page).hide(), $("#fldSelectSystemEvent", page).hide(), $("#fldSelectInterval", page).show(), $("#selectTimeOfDay", page).removeAttr("required")) : "StartupTrigger" == triggerType && ($("#fldTimeOfDay", page).hide(), $("#fldDayOfWeek", page).hide(), $("#fldSelectSystemEvent", page).hide(), $("#fldSelectInterval", page).hide(), $("#selectTimeOfDay", page).removeAttr("required")) + refreshTriggerFields: function (page, triggerType) { + if (triggerType == "DailyTrigger") { + $("#fldTimeOfDay", page).show(); + $("#fldDayOfWeek", page).hide(); + $("#fldSelectSystemEvent", page).hide(); + $("#fldSelectInterval", page).hide(); + $("#selectTimeOfDay", page).attr("required", "required"); + } else if (triggerType == "WeeklyTrigger") { + $("#fldTimeOfDay", page).show(); + $("#fldDayOfWeek", page).show(); + $("#fldSelectSystemEvent", page).hide(); + $("#fldSelectInterval", page).hide(); + $("#selectTimeOfDay", page).attr("required", "required"); + } else if (triggerType == "SystemEventTrigger") { + $("#fldTimeOfDay", page).hide(); + $("#fldDayOfWeek", page).hide(); + $("#fldSelectSystemEvent", page).show(); + $("#fldSelectInterval", page).hide(); + $("#selectTimeOfDay", page).removeAttr("required"); + } else if (triggerType == "IntervalTrigger") { + $("#fldTimeOfDay", page).hide(); + $("#fldDayOfWeek", page).hide(); + $("#fldSelectSystemEvent", page).hide(); + $("#fldSelectInterval", page).show(); + $("#selectTimeOfDay", page).removeAttr("required"); + } else if (triggerType == "StartupTrigger") { + $("#fldTimeOfDay", page).hide(); + $("#fldDayOfWeek", page).hide(); + $("#fldSelectSystemEvent", page).hide(); + $("#fldSelectInterval", page).hide(); + $("#selectTimeOfDay", page).removeAttr("required"); + } }, - getTriggerToAdd: function(page) { + getTriggerToAdd: function (page) { var trigger = { Type: $("#selectTriggerType", page).val() }; - "DailyTrigger" == trigger.Type ? trigger.TimeOfDayTicks = $("#selectTimeOfDay", page).val() : "WeeklyTrigger" == trigger.Type ? (trigger.DayOfWeek = $("#selectDayOfWeek", page).val(), trigger.TimeOfDayTicks = $("#selectTimeOfDay", page).val()) : "SystemEventTrigger" == trigger.Type ? trigger.SystemEvent = $("#selectSystemEvent", page).val() : "IntervalTrigger" == trigger.Type && (trigger.IntervalTicks = $("#selectInterval", page).val()); + + if (trigger.Type == "DailyTrigger") { + trigger.TimeOfDayTicks = $("#selectTimeOfDay", page).val(); + } else if (trigger.Type == "WeeklyTrigger") { + trigger.DayOfWeek = $("#selectDayOfWeek", page).val(); + trigger.TimeOfDayTicks = $("#selectTimeOfDay", page).val(); + } else if (trigger.Type == "SystemEventTrigger") { + trigger.SystemEvent = $("#selectSystemEvent", page).val(); + } else if (trigger.Type == "IntervalTrigger") { + trigger.IntervalTicks = $("#selectInterval", page).val(); + } + var timeLimit = $("#txtTimeLimit", page).val() || "0"; - return timeLimit = 36e5 * parseFloat(timeLimit), trigger.MaxRuntimeMs = timeLimit || null, trigger + timeLimit = parseFloat(timeLimit) * 3600000; + + trigger.MaxRuntimeMs = timeLimit || null; + + return trigger; } }; - return function(view, params) { + return function (view, params) { function onSubmit(e) { loading.show(); var id = getParameterByName("id"); - ApiClient.getScheduledTask(id).then(function(task) { - task.Triggers.push(ScheduledTaskPage.getTriggerToAdd(view)), ApiClient.updateScheduledTaskTriggers(task.Id, task.Triggers).then(function() { - $("#popupAddTrigger").addClass("hide"), ScheduledTaskPage.refreshScheduledTask(view) - }) - }), e.preventDefault() + ApiClient.getScheduledTask(id).then(function (task) { + task.Triggers.push(ScheduledTaskPage.getTriggerToAdd(view)); + ApiClient.updateScheduledTaskTriggers(task.Id, task.Triggers).then(function () { + $("#popupAddTrigger").addClass("hide"); + ScheduledTaskPage.refreshScheduledTask(view); + }); + }); + e.preventDefault(); } - view.querySelector(".addTriggerForm").addEventListener("submit", onSubmit), fillTimeOfDay(view.querySelector("#selectTimeOfDay")), $(view.querySelector("#popupAddTrigger").parentNode).trigger("create"), view.querySelector(".selectTriggerType").addEventListener("change", function() { - ScheduledTaskPage.refreshTriggerFields(view, this.value) - }), view.querySelector(".btnAddTrigger").addEventListener("click", function() { - ScheduledTaskPage.showAddTriggerPopup(view) - }), view.addEventListener("click", function(e) { + + view.querySelector(".addTriggerForm").addEventListener("submit", onSubmit); + fillTimeOfDay(view.querySelector("#selectTimeOfDay")); + $(view.querySelector("#popupAddTrigger").parentNode).trigger("create"); + view.querySelector(".selectTriggerType").addEventListener("change", function () { + ScheduledTaskPage.refreshTriggerFields(view, this.value); + }); + view.querySelector(".btnAddTrigger").addEventListener("click", function () { + ScheduledTaskPage.showAddTriggerPopup(view); + }); + view.addEventListener("click", function (e) { var btnDeleteTrigger = dom.parentWithClass(e.target, "btnDeleteTrigger"); - btnDeleteTrigger && ScheduledTaskPage.confirmDeleteTrigger(view, parseInt(btnDeleteTrigger.getAttribute("data-index"))) - }), view.addEventListener("viewshow", function() { - ScheduledTaskPage.refreshScheduledTask(view) - }) - } -}); \ No newline at end of file + + if (btnDeleteTrigger) { + ScheduledTaskPage.confirmDeleteTrigger(view, parseInt(btnDeleteTrigger.getAttribute("data-index"))); + } + }); + view.addEventListener("viewshow", function () { + ScheduledTaskPage.refreshScheduledTask(view); + }); + }; +}); diff --git a/src/controllers/searchpage.js b/src/controllers/searchpage.js index b188a8b318..b260ef5751 100644 --- a/src/controllers/searchpage.js +++ b/src/controllers/searchpage.js @@ -1,21 +1,36 @@ -define(["focusManager", "searchFields", "searchResults", "events"], function(focusManager, SearchFields, SearchResults, events) { +define(["focusManager", "searchFields", "searchResults", "events"], function (focusManager, SearchFields, SearchResults, events) { "use strict"; - return function(view, params) { + + return function (view, params) { function onSearch(e, value) { - self.searchResults.search(value) + self.searchResults.search(value); } + var self = this; - view.addEventListener("viewshow", function() { - self.searchFields || (self.searchFields = new SearchFields({ - element: view.querySelector(".searchFields") - }), self.searchResults = new SearchResults({ - element: view.querySelector(".searchResults"), - serverId: params.serverId || ApiClient.serverId(), - parentId: params.parentId, - collectionType: params.collectionType - }), events.on(self.searchFields, "search", onSearch)) - }), view.addEventListener("viewdestroy", function() { - self.searchFields && (self.searchFields.destroy(), self.searchFields = null), self.searchResults && (self.searchResults.destroy(), self.searchResults = null) - }) - } -}); \ No newline at end of file + view.addEventListener("viewshow", function () { + if (!self.searchFields) { + self.searchFields = new SearchFields({ + element: view.querySelector(".searchFields") + }); + self.searchResults = new SearchResults({ + element: view.querySelector(".searchResults"), + serverId: params.serverId || ApiClient.serverId(), + parentId: params.parentId, + collectionType: params.collectionType + }); + events.on(self.searchFields, "search", onSearch); + } + }); + view.addEventListener("viewdestroy", function () { + if (self.searchFields) { + self.searchFields.destroy(); + self.searchFields = null; + } + + if (self.searchResults) { + self.searchResults.destroy(); + self.searchResults = null; + } + }); + }; +}); diff --git a/src/controllers/selectserver.js b/src/controllers/selectserver.js index 385ab69ca2..80ecb13f00 100644 --- a/src/controllers/selectserver.js +++ b/src/controllers/selectserver.js @@ -1,50 +1,56 @@ -define(["loading", "appRouter", "layoutManager", "appSettings", "apphost", "focusManager", "connectionManager", "globalize", "actionsheet", "dom", "material-icons", "flexStyles", "emby-scroller", "emby-itemscontainer", "cardStyle", "emby-button"], function(loading, appRouter, layoutManager, appSettings, appHost, focusManager, connectionManager, globalize, actionSheet, dom) { +define(["loading", "appRouter", "layoutManager", "appSettings", "apphost", "focusManager", "connectionManager", "globalize", "actionsheet", "dom", "material-icons", "flexStyles", "emby-scroller", "emby-itemscontainer", "cardStyle", "emby-button"], function (loading, appRouter, layoutManager, appSettings, appHost, focusManager, connectionManager, globalize, actionSheet, dom) { "use strict"; function renderSelectServerItems(view, servers) { - var items = servers.map(function(server) { - return { - name: server.Name, - showIcon: !0, - icon: "", - cardType: "", - id: server.Id, - server: server - } + var items = servers.map(function (server) { + return { + name: server.Name, + showIcon: true, + icon: "", + cardType: "", + id: server.Id, + server: server + }; }); - var html = items.map(function(item) { - var cardImageContainer; - if (item.showIcon) { - cardImageContainer = '' + item.icon + ""; - } else { - cardImageContainer = '
'; - } - var cardBoxCssClass = "cardBox"; - if (layoutManager.tv) { - cardBoxCssClass += " cardBox-focustransform"; - } - var innerOpening = '
'; - var cardContainer = ''; - cardContainer += '
'; - return cardContainer; + var html = items.map(function (item) { + var cardImageContainer; + + if (item.showIcon) { + cardImageContainer = '' + item.icon + ""; + } else { + cardImageContainer = '
'; + } + + var cardBoxCssClass = "cardBox"; + + if (layoutManager.tv) { + cardBoxCssClass += " cardBox-focustransform"; + } + + var innerOpening = '
'; + var cardContainer = ''; + cardContainer += '
'; + return cardContainer; }).join(""); var itemsContainer = view.querySelector(".servers"); + if (!items.length) { html = '

' + globalize.translate("MessageNoServersAvailable") + "

"; } + itemsContainer.innerHTML = html; loading.hide(); } @@ -73,7 +79,7 @@ define(["loading", "appRouter", "layoutManager", "appSettings", "apphost", "focu } function alertTextWithOptions(options) { - require(["alert"], function(alert) { + require(["alert"], function (alert) { alert(options); }); } @@ -82,38 +88,42 @@ define(["loading", "appRouter", "layoutManager", "appSettings", "apphost", "focu alertText(globalize.translate("MessageUnableToConnectToServer"), globalize.translate("HeaderConnectionFailure")); } - return function(view, params) { + return function (view, params) { function connectToServer(server) { loading.show(); connectionManager.connectToServer(server, { enableAutoLogin: appSettings.enableAutoLogin() - }).then(function(result) { + }).then(function (result) { loading.hide(); var apiClient = result.ApiClient; + switch (result.State) { case "SignedIn": Dashboard.onServerChanged(apiClient.getCurrentUserId(), apiClient.accessToken(), apiClient); Dashboard.navigate("home.html"); break; + case "ServerSignIn": Dashboard.onServerChanged(null, null, apiClient); Dashboard.navigate("login.html?serverid=" + result.Servers[0].Id); break; + case "ServerUpdateNeeded": alertTextWithOptions({ text: globalize.translate("core#ServerUpdateNeeded", "https://github.com/jellyfin/jellyfin"), html: globalize.translate("core#ServerUpdateNeeded", 'https://github.com/jellyfin/jellyfin') }); break; + default: showServerConnectionFailure(); } - }) + }); } function deleteServer(server) { loading.show(); - connectionManager.deleteServer(server.Id).then(function() { + connectionManager.deleteServer(server.Id).then(function () { loading.hide(); loadServers(); }); @@ -132,20 +142,22 @@ define(["loading", "appRouter", "layoutManager", "appSettings", "apphost", "focu actionSheet.show({ items: menuItems, title: server.Name - }).then(function(id) { + }).then(function (id) { switch (id) { case "connect": connectToServer(server); break; + case "delete": deleteServer(server); } - }) + }); } function onServersRetrieved(result) { servers = result; renderSelectServerItems(view, result); + if (layoutManager.tv) { focusManager.autoFocus(view); } @@ -158,25 +170,29 @@ define(["loading", "appRouter", "layoutManager", "appSettings", "apphost", "focu var servers; updatePageStyle(view, params); - - view.addEventListener("viewshow", function(e) { + view.addEventListener("viewshow", function (e) { var isRestored = e.detail.isRestored; appRouter.setTitle(null); - if (!isRestored) loadServers(); + + if (!isRestored) { + loadServers(); + } }); - view.querySelector(".servers").addEventListener("click", function(e) { + view.querySelector(".servers").addEventListener("click", function (e) { var card = dom.parentWithClass(e.target, "card"); + if (card) { var url = card.getAttribute("data-url"); + if (url) { appRouter.show(url); } else { var id = card.getAttribute("data-id"); - onServerClick(servers.filter(function(s) { + onServerClick(servers.filter(function (s) { return s.Id === id; })[0]); } } - }) - } + }); + }; }); diff --git a/src/controllers/serveractivity.js b/src/controllers/serveractivity.js index 2b43215c93..fb3b8112dc 100644 --- a/src/controllers/serveractivity.js +++ b/src/controllers/serveractivity.js @@ -1,14 +1,31 @@ -define(["components/activitylog", "globalize"], function(ActivityLog, globalize) { +define(["components/activitylog", "globalize"], function (ActivityLog, globalize) { "use strict"; - return function(view, params) { + + return function (view, params) { var activityLog; - "false" !== params.useractivity ? (view.querySelector(".activityItems").setAttribute("data-useractivity", "true"), view.querySelector(".sectionTitle").innerHTML = globalize.translate("HeaderActivity")) : (view.querySelector(".activityItems").setAttribute("data-useractivity", "false"), view.querySelector(".sectionTitle").innerHTML = globalize.translate("Alerts")), view.addEventListener("viewshow", function() { - activityLog || (activityLog = new ActivityLog({ - serverId: ApiClient.serverId(), - element: view.querySelector(".activityItems") - })) - }), view.addEventListener("viewdestroy", function() { - activityLog && activityLog.destroy(), activityLog = null - }) - } -}); \ No newline at end of file + + if (params.useractivity !== "false") { + view.querySelector(".activityItems").setAttribute("data-useractivity", "true"); + view.querySelector(".sectionTitle").innerHTML = globalize.translate("HeaderActivity"); + } else { + view.querySelector(".activityItems").setAttribute("data-useractivity", "false"); + view.querySelector(".sectionTitle").innerHTML = globalize.translate("Alerts"); + } + + view.addEventListener("viewshow", function () { + if (!activityLog) { + activityLog = new ActivityLog({ + serverId: ApiClient.serverId(), + element: view.querySelector(".activityItems") + }); + } + }); + view.addEventListener("viewdestroy", function () { + if (activityLog) { + activityLog.destroy(); + } + + activityLog = null; + }); + }; +}); diff --git a/src/controllers/shows/episodes.js b/src/controllers/shows/episodes.js index 1f783631fb..42d9d89f7a 100644 --- a/src/controllers/shows/episodes.js +++ b/src/controllers/shows/episodes.js @@ -1,169 +1,233 @@ -define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "emby-itemscontainer"], function(loading, events, libraryBrowser, imageLoader, listView, cardBuilder) { +define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "emby-itemscontainer"], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder) { "use strict"; - return function(view, params, tabContent) { + + return function (view, params, tabContent) { function getPageData(context) { - var key = getSavedQueryKey(context), - pageData = data[key]; - return pageData || (pageData = data[key] = { - query: { - SortBy: "SeriesSortName,SortName", - SortOrder: "Ascending", - IncludeItemTypes: "Episode", - Recursive: !0, - Fields: "PrimaryImageAspectRatio,MediaSourceCount,UserData", - IsMissing: !1, - ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Thumb", - StartIndex: 0, - Limit: pageSize - }, - view: libraryBrowser.getSavedView(key) || "Poster" - }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData + var key = getSavedQueryKey(context); + var pageData = data[key]; + + if (!pageData) { + pageData = data[key] = { + query: { + SortBy: "SeriesSortName,SortName", + SortOrder: "Ascending", + IncludeItemTypes: "Episode", + Recursive: true, + Fields: "PrimaryImageAspectRatio,MediaSourceCount,UserData", + IsMissing: false, + ImageTypeLimit: 1, + EnableImageTypes: "Primary,Backdrop,Thumb", + StartIndex: 0, + Limit: pageSize + }, + view: libraryBrowser.getSavedView(key) || "Poster" + }; + pageData.query.ParentId = params.topParentId; + libraryBrowser.loadSavedQueryValues(key, pageData.query); + } + + return pageData; } function getQuery(context) { - return getPageData(context).query + return getPageData(context).query; } function getSavedQueryKey(context) { - return context.savedQueryKey || (context.savedQueryKey = libraryBrowser.getSavedQueryKey("episodes")), context.savedQueryKey + if (!context.savedQueryKey) { + context.savedQueryKey = libraryBrowser.getSavedQueryKey("episodes"); + } + + return context.savedQueryKey; } function onViewStyleChange() { - var viewStyle = self.getCurrentViewStyle(), - itemsContainer = tabContent.querySelector(".itemsContainer"); - "List" == viewStyle ? (itemsContainer.classList.add("vertical-list"), itemsContainer.classList.remove("vertical-wrap")) : (itemsContainer.classList.remove("vertical-list"), itemsContainer.classList.add("vertical-wrap")), itemsContainer.innerHTML = "" + var viewStyle = self.getCurrentViewStyle(); + var itemsContainer = tabContent.querySelector(".itemsContainer"); + + if ("List" == viewStyle) { + itemsContainer.classList.add("vertical-list"); + itemsContainer.classList.remove("vertical-wrap"); + } else { + itemsContainer.classList.remove("vertical-list"); + itemsContainer.classList.add("vertical-wrap"); + } + + itemsContainer.innerHTML = ""; } function reloadItems(page) { loading.show(); isLoading = true; var query = getQuery(page); - ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function(result) { + ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) { function onNextPageClick() { - if (isLoading) return; + if (isLoading) { + return; + } + query.StartIndex += query.Limit; - reloadItems(tabContent) + reloadItems(tabContent); } function onPreviousPageClick() { - if (isLoading) return; + if (isLoading) { + return; + } + query.StartIndex -= query.Limit; - reloadItems(tabContent) + reloadItems(tabContent); } window.scrollTo(0, 0); - var html, pagingHtml = libraryBrowser.getQueryPagingHtml({ - startIndex: query.StartIndex, - limit: query.Limit, - totalRecordCount: result.TotalRecordCount, - showLimit: !1, - updatePageSizeSetting: !1, - addLayoutButton: !1, - sortButton: !1, - filterButton: !1 - }), - viewStyle = self.getCurrentViewStyle(), - itemsContainer = tabContent.querySelector(".itemsContainer"); - html = "List" == viewStyle ? listView.getListViewHtml({ - items: result.Items, - sortBy: query.SortBy, - showParentTitle: !0 - }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "backdrop", - showTitle: !0, - showParentTitle: !0, - scalable: !0, - cardLayout: !0 - }) : cardBuilder.getCardsHtml({ - items: result.Items, - shape: "backdrop", - showTitle: !0, - showParentTitle: !0, - overlayText: !1, - centerText: !0, - scalable: !0, - overlayPlayButton: !0 + var html; + var pagingHtml = libraryBrowser.getQueryPagingHtml({ + startIndex: query.StartIndex, + limit: query.Limit, + totalRecordCount: result.TotalRecordCount, + showLimit: false, + updatePageSizeSetting: false, + addLayoutButton: false, + sortButton: false, + filterButton: false }); - var i, length, elems; - for (elems = tabContent.querySelectorAll(".paging"), i = 0, length = elems.length; i < length; i++) + var viewStyle = self.getCurrentViewStyle(); + var itemsContainer = tabContent.querySelector(".itemsContainer"); + if (viewStyle == "List") { + html = listView.getListViewHtml({ + items: result.Items, + sortBy: query.SortBy, + showParentTitle: true + }); + } else if (viewStyle == "PosterCard") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "backdrop", + showTitle: true, + showParentTitle: true, + scalable: true, + cardLayout: true + }); + } else { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "backdrop", + showTitle: true, + showParentTitle: true, + overlayText: false, + centerText: true, + scalable: true, + overlayPlayButton: true + }); + } + var i; + var length; + var elems; + + elems = tabContent.querySelectorAll(".paging"); + for (i = 0, length = elems.length; i < length; i++) { elems[i].innerHTML = pagingHtml; - for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) + } + + elems = tabContent.querySelectorAll(".btnNextPage"); + for (i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener("click", onNextPageClick); - for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) + } + + elems = tabContent.querySelectorAll(".btnPreviousPage"); + for (i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener("click", onPreviousPageClick); + } + itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); libraryBrowser.saveQueryValues(getSavedQueryKey(page), query); loading.hide(); isLoading = false; - }) + }); } - var self = this, - pageSize = 100, - data = {}, - isLoading = false; - self.showFilterMenu = function() { - require(["components/filterdialog/filterdialog"], function(filterDialogFactory) { - var filterDialog = new filterDialogFactory({ - query: getQuery(tabContent), - mode: "episodes", - serverId: ApiClient.serverId() - }); - events.on(filterDialog, "filterchange", function() { - reloadItems(tabContent) - }), filterDialog.show() - }) - }, self.getCurrentViewStyle = function() { - return getPageData(tabContent).view - }, - function(tabContent) { - tabContent.querySelector(".btnFilter").addEventListener("click", function() { - self.showFilterMenu() - }), tabContent.querySelector(".btnSort").addEventListener("click", function(e) { - libraryBrowser.showSortMenu({ - items: [{ - name: Globalize.translate("OptionNameSort"), - id: "SeriesSortName,SortName" - }, { - name: Globalize.translate("OptionTvdbRating"), - id: "CommunityRating,SeriesSortName,SortName" - }, { - name: Globalize.translate("OptionDateAdded"), - id: "DateCreated,SeriesSortName,SortName" - }, { - name: Globalize.translate("OptionPremiereDate"), - id: "PremiereDate,SeriesSortName,SortName" - }, { - name: Globalize.translate("OptionDatePlayed"), - id: "DatePlayed,SeriesSortName,SortName" - }, { - name: Globalize.translate("OptionParentalRating"), - id: "OfficialRating,SeriesSortName,SortName" - }, { - name: Globalize.translate("OptionPlayCount"), - id: "PlayCount,SeriesSortName,SortName" - }, { - name: Globalize.translate("OptionRuntime"), - id: "Runtime,SeriesSortName,SortName" - }], - callback: function() { - reloadItems(tabContent) - }, - query: getQuery(tabContent), - button: e.target - }) + + var self = this; + var pageSize = 100; + var data = {}; + var isLoading = false; + + self.showFilterMenu = function () { + require(["components/filterdialog/filterdialog"], function (filterDialogFactory) { + var filterDialog = new filterDialogFactory({ + query: getQuery(tabContent), + mode: "episodes", + serverId: ApiClient.serverId() }); - var btnSelectView = tabContent.querySelector(".btnSelectView"); - btnSelectView.addEventListener("click", function(e) { - libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard".split(",")) - }), btnSelectView.addEventListener("layoutchange", function(e) { - var viewStyle = e.detail.viewStyle; - getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), onViewStyleChange(), reloadItems(tabContent) - }) - }(tabContent), onViewStyleChange(), self.renderTab = function() { - reloadItems(tabContent) - }, self.destroy = function() {} - } + events.on(filterDialog, "filterchange", function () { + reloadItems(tabContent); + }); + filterDialog.show(); + }); + }; + + self.getCurrentViewStyle = function () { + return getPageData(tabContent).view; + }; + + function initPage(tabContent) { + tabContent.querySelector(".btnFilter").addEventListener("click", function () { + self.showFilterMenu(); + }); + tabContent.querySelector(".btnSort").addEventListener("click", function (e) { + libraryBrowser.showSortMenu({ + items: [{ + name: Globalize.translate("OptionNameSort"), + id: "SeriesSortName,SortName" + }, { + name: Globalize.translate("OptionTvdbRating"), + id: "CommunityRating,SeriesSortName,SortName" + }, { + name: Globalize.translate("OptionDateAdded"), + id: "DateCreated,SeriesSortName,SortName" + }, { + name: Globalize.translate("OptionPremiereDate"), + id: "PremiereDate,SeriesSortName,SortName" + }, { + name: Globalize.translate("OptionDatePlayed"), + id: "DatePlayed,SeriesSortName,SortName" + }, { + name: Globalize.translate("OptionParentalRating"), + id: "OfficialRating,SeriesSortName,SortName" + }, { + name: Globalize.translate("OptionPlayCount"), + id: "PlayCount,SeriesSortName,SortName" + }, { + name: Globalize.translate("OptionRuntime"), + id: "Runtime,SeriesSortName,SortName" + }], + callback: function () { + reloadItems(tabContent); + }, + query: getQuery(tabContent), + button: e.target + }); + }); + var btnSelectView = tabContent.querySelector(".btnSelectView"); + btnSelectView.addEventListener("click", function (e) { + libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard".split(",")); + }); + btnSelectView.addEventListener("layoutchange", function (e) { + var viewStyle = e.detail.viewStyle; + getPageData(tabContent).view = viewStyle; + libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle); + onViewStyleChange(); + reloadItems(tabContent); + }); + } + + initPage(tabContent); + onViewStyleChange(); + + self.renderTab = function () { + reloadItems(tabContent); + }; + + self.destroy = function () {}; + }; }); diff --git a/src/controllers/shows/tvgenres.js b/src/controllers/shows/tvgenres.js index e9559155e1..956b8fa6fa 100644 --- a/src/controllers/shows/tvgenres.js +++ b/src/controllers/shows/tvgenres.js @@ -1,139 +1,200 @@ -define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader", "apphost", "globalize", "appRouter", "dom", "emby-button"], function(layoutManager, loading, libraryBrowser, cardBuilder, lazyLoader, appHost, globalize, appRouter, dom) { +define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader", "apphost", "globalize", "appRouter", "dom", "emby-button"], function (layoutManager, loading, libraryBrowser, cardBuilder, lazyLoader, appHost, globalize, appRouter, dom) { "use strict"; - return function(view, params, tabContent) { + + return function (view, params, tabContent) { function getPageData() { - var key = getSavedQueryKey(), - pageData = data[key]; - return pageData || (pageData = data[key] = { - query: { - SortBy: "SortName", - SortOrder: "Ascending", - IncludeItemTypes: "Series", - Recursive: !0, - EnableTotalRecordCount: !1 - }, - view: "Poster" - }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData + var key = getSavedQueryKey(); + var pageData = data[key]; + + if (!pageData) { + pageData = data[key] = { + query: { + SortBy: "SortName", + SortOrder: "Ascending", + IncludeItemTypes: "Series", + Recursive: true, + EnableTotalRecordCount: false + }, + view: "Poster" + }; + pageData.query.ParentId = params.topParentId; + libraryBrowser.loadSavedQueryValues(key, pageData.query); + } + + return pageData; } function getQuery() { - return getPageData().query + return getPageData().query; } function getSavedQueryKey() { - return libraryBrowser.getSavedQueryKey("seriesgenres") + return libraryBrowser.getSavedQueryKey("seriesgenres"); } function getPromise() { loading.show(); var query = getQuery(); - return ApiClient.getGenres(ApiClient.getCurrentUserId(), query) + return ApiClient.getGenres(ApiClient.getCurrentUserId(), query); } function enableScrollX() { - return !layoutManager.desktop + return !layoutManager.desktop; } function getThumbShape() { - return enableScrollX() ? "overflowBackdrop" : "backdrop" + return enableScrollX() ? "overflowBackdrop" : "backdrop"; } function getPortraitShape() { - return enableScrollX() ? "overflowPortrait" : "portrait" + return enableScrollX() ? "overflowPortrait" : "portrait"; } function fillItemsContainer(elem) { - var id = elem.getAttribute("data-id"), - viewStyle = self.getCurrentViewStyle(), - limit = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? 5 : 9; - enableScrollX() && (limit = 10); - var enableImageTypes = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? "Primary,Backdrop,Thumb" : "Primary", - query = { - SortBy: "SortName", - SortOrder: "Ascending", - IncludeItemTypes: "Series", - Recursive: !0, - Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo", - ImageTypeLimit: 1, - EnableImageTypes: enableImageTypes, - Limit: limit, - GenreIds: id, - EnableTotalRecordCount: !1, - ParentId: params.topParentId - }; - ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function(result) { + var id = elem.getAttribute("data-id"); + var viewStyle = self.getCurrentViewStyle(); + var limit = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? 5 : 9; + + if (enableScrollX()) { + limit = 10; + } + + var enableImageTypes = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? "Primary,Backdrop,Thumb" : "Primary"; + var query = { + SortBy: "SortName", + SortOrder: "Ascending", + IncludeItemTypes: "Series", + Recursive: true, + Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo", + ImageTypeLimit: 1, + EnableImageTypes: enableImageTypes, + Limit: limit, + GenreIds: id, + EnableTotalRecordCount: false, + ParentId: params.topParentId + }; + ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) { var supportsImageAnalysis = appHost.supports("imageanalysis"); - "Thumb" == viewStyle ? cardBuilder.buildCards(result.Items, { - itemsContainer: elem, - shape: getThumbShape(), - preferThumb: !0, - showTitle: !0, - scalable: !0, - centerText: !0, - overlayMoreButton: !0, - allowBottomPadding: !1 - }) : "ThumbCard" == viewStyle ? cardBuilder.buildCards(result.Items, { - itemsContainer: elem, - shape: getThumbShape(), - preferThumb: !0, - showTitle: !0, - scalable: !0, - centerText: !1, - cardLayout: !0, - showYear: !0 - }) : "PosterCard" == viewStyle ? cardBuilder.buildCards(result.Items, { - itemsContainer: elem, - shape: getPortraitShape(), - showTitle: !0, - scalable: !0, - centerText: !1, - cardLayout: !0, - showYear: !0 - }) : "Poster" == viewStyle && cardBuilder.buildCards(result.Items, { - itemsContainer: elem, - shape: getPortraitShape(), - scalable: !0, - overlayMoreButton: !0, - allowBottomPadding: !1 - }), result.Items.length >= query.Limit && tabContent.querySelector(".btnMoreFromGenre" + id + " i").classList.remove("hide") - }) + + if (viewStyle == "Thumb") { + cardBuilder.buildCards(result.Items, { + itemsContainer: elem, + shape: getThumbShape(), + preferThumb: true, + showTitle: true, + scalable: true, + centerText: true, + overlayMoreButton: true, + allowBottomPadding: false + }); + } else if (viewStyle == "ThumbCard") { + cardBuilder.buildCards(result.Items, { + itemsContainer: elem, + shape: getThumbShape(), + preferThumb: true, + showTitle: true, + scalable: true, + centerText: false, + cardLayout: true, + showYear: true + }); + } else if (viewStyle == "PosterCard") { + cardBuilder.buildCards(result.Items, { + itemsContainer: elem, + shape: getPortraitShape(), + showTitle: true, + scalable: true, + centerText: false, + cardLayout: true, + showYear: true + }); + } else if (viewStyle == "Poster") { + cardBuilder.buildCards(result.Items, { + itemsContainer: elem, + shape: getPortraitShape(), + scalable: true, + overlayMoreButton: true, + allowBottomPadding: false + }); + } + if (result.Items.length >= query.Limit) { + tabContent.querySelector(".btnMoreFromGenre" + id + " i").classList.remove("hide"); + } + }); } function reloadItems(context, promise) { var query = getQuery(); - promise.then(function(result) { - for (var elem = context.querySelector("#items"), html = "", items = result.Items, i = 0, length = items.length; i < length; i++) { + promise.then(function (result) { + var elem = context.querySelector("#items"); + var html = ""; + var items = result.Items; + + for (var i = 0, length = items.length; i < length; i++) { var item = items[i]; - if (html += '
', html += '", enableScrollX()) { + html += '
'; + html += '"; + if (enableScrollX()) { var scrollXClass = "scrollX hiddenScrollX"; - layoutManager.tv && (scrollXClass += " smoothScrollX"), html += '
' - } else html += '
'; - html += "
", html += "
" + if (layoutManager.tv) { + scrollXClass += "smoothScrollX"; + } + html += '
'; + } else { + html += '
'; + } + html += "
"; + html += "
"; } - elem.innerHTML = html, lazyLoader.lazyChildren(elem, fillItemsContainer), libraryBrowser.saveQueryValues(getSavedQueryKey(), query), loading.hide() - }) + + elem.innerHTML = html; + lazyLoader.lazyChildren(elem, fillItemsContainer); + libraryBrowser.saveQueryValues(getSavedQueryKey(), query); + loading.hide(); + }); } function fullyReload() { - self.preRender(), self.renderTab() + self.preRender(); + self.renderTab(); } - var self = this, - data = {}; - self.getViewStyles = function() { - return "Poster,PosterCard,Thumb,ThumbCard".split(",") - }, self.getCurrentViewStyle = function() { - return getPageData(tabContent).view - }, self.setCurrentViewStyle = function(viewStyle) { - getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), fullyReload() - }, self.enableViewSelection = !0; + + var self = this; + var data = {}; + + self.getViewStyles = function () { + return "Poster,PosterCard,Thumb,ThumbCard".split(","); + }; + + self.getCurrentViewStyle = function () { + return getPageData(tabContent).view; + }; + + self.setCurrentViewStyle = function (viewStyle) { + getPageData(tabContent).view = viewStyle; + libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle); + fullyReload(); + }; + + self.enableViewSelection = true; var promise; - self.preRender = function() { - promise = getPromise() - }, self.renderTab = function() { - reloadItems(tabContent, promise) - } - } -}); \ No newline at end of file + + self.preRender = function () { + promise = getPromise(); + }; + + self.renderTab = function () { + reloadItems(tabContent, promise); + }; + }; +}); diff --git a/src/controllers/shows/tvlatest.js b/src/controllers/shows/tvlatest.js index 006f41e6ce..2a1ed56bf4 100644 --- a/src/controllers/shows/tvlatest.js +++ b/src/controllers/shows/tvlatest.js @@ -1,52 +1,60 @@ -define(["loading", "components/groupedcards", "cardBuilder", "apphost", "imageLoader"], function(loading, groupedcards, cardBuilder, appHost, imageLoader) { +define(["loading", "components/groupedcards", "cardBuilder", "apphost", "imageLoader"], function (loading, groupedcards, cardBuilder, appHost, imageLoader) { "use strict"; function getLatestPromise(context, params) { loading.show(); - var userId = ApiClient.getCurrentUserId(), - parentId = params.topParentId, - options = { - IncludeItemTypes: "Episode", - Limit: 30, - Fields: "PrimaryImageAspectRatio,BasicSyncInfo", - ParentId: parentId, - ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Thumb" - }; - return ApiClient.getJSON(ApiClient.getUrl("Users/" + userId + "/Items/Latest", options)) + var userId = ApiClient.getCurrentUserId(); + var parentId = params.topParentId; + var options = { + IncludeItemTypes: "Episode", + Limit: 30, + Fields: "PrimaryImageAspectRatio,BasicSyncInfo", + ParentId: parentId, + ImageTypeLimit: 1, + EnableImageTypes: "Primary,Backdrop,Thumb" + }; + return ApiClient.getJSON(ApiClient.getUrl("Users/" + userId + "/Items/Latest", options)); } function loadLatest(context, params, promise) { - promise.then(function(items) { + promise.then(function (items) { var html = ""; appHost.supports("imageanalysis"); html += cardBuilder.getCardsHtml({ items: items, shape: "backdrop", - preferThumb: !0, - showTitle: !0, - showSeriesYear: !0, - showParentTitle: !0, - overlayText: !1, - cardLayout: !1, - showUnplayedIndicator: !1, - showChildCountIndicator: !0, - centerText: !0, - lazy: !0, - overlayPlayButton: !0, + preferThumb: true, + showTitle: true, + showSeriesYear: true, + showParentTitle: true, + overlayText: false, + cardLayout: false, + showUnplayedIndicator: false, + showChildCountIndicator: true, + centerText: true, + lazy: true, + overlayPlayButton: true, lines: 2 }); var elem = context.querySelector("#latestEpisodes"); - elem.innerHTML = html, imageLoader.lazyChildren(elem), loading.hide() - }) + elem.innerHTML = html; + imageLoader.lazyChildren(elem); + loading.hide(); + }); } - return function(view, params, tabContent) { + + return function (view, params, tabContent) { var self = this; var latestPromise; - self.preRender = function() { - latestPromise = getLatestPromise(view, params) - }, self.renderTab = function() { - loadLatest(tabContent, params, latestPromise) - }, tabContent.querySelector("#latestEpisodes").addEventListener("click", groupedcards.onItemsContainerClick) - } -}); \ No newline at end of file + + self.preRender = function () { + latestPromise = getLatestPromise(view, params); + }; + + self.renderTab = function () { + loadLatest(tabContent, params, latestPromise); + }; + + tabContent.querySelector("#latestEpisodes").addEventListener("click", groupedcards.onItemsContainerClick); + }; +}); diff --git a/src/controllers/shows/tvrecommended.js b/src/controllers/shows/tvrecommended.js index 9de1461b3d..1386e76a31 100644 --- a/src/controllers/shows/tvrecommended.js +++ b/src/controllers/shows/tvrecommended.js @@ -1,4 +1,4 @@ -define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "dom", "userSettings", "cardBuilder", "playbackManager", "mainTabsManager", "scrollStyles", "emby-itemscontainer", "emby-button"], function(events, inputManager, libraryMenu, layoutManager, loading, dom, userSettings, cardBuilder, playbackManager, mainTabsManager) { +define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "dom", "userSettings", "cardBuilder", "playbackManager", "mainTabsManager", "scrollStyles", "emby-itemscontainer", "emby-button"], function (events, inputManager, libraryMenu, layoutManager, loading, dom, userSettings, cardBuilder, playbackManager, mainTabsManager) { "use strict"; function getTabs() { @@ -19,30 +19,51 @@ define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "do }, { name: Globalize.translate("ButtonSearch"), cssClass: "searchTabButton" - }] + }]; } function getDefaultTabIndex(folderId) { switch (userSettings.get("landing-" + folderId)) { case "suggestions": return 1; + case "latest": return 2; + case "favorites": return 1; + case "genres": return 4; + default: - return 0 + return 0; } } function setScrollClasses(elem, scrollX) { - scrollX ? (elem.classList.add("hiddenScrollX"), layoutManager.tv && elem.classList.add("smoothScrollX"), elem.classList.add("scrollX"), elem.classList.remove("vertical-wrap")) : (elem.classList.remove("hiddenScrollX"), elem.classList.remove("smoothScrollX"), elem.classList.remove("scrollX"), elem.classList.add("vertical-wrap")) + if (scrollX) { + elem.classList.add("hiddenScrollX"); + + if (layoutManager.tv) { + elem.classList.add("smoothScrollX"); + } + + elem.classList.add("scrollX"); + elem.classList.remove("vertical-wrap"); + } else { + elem.classList.remove("hiddenScrollX"); + elem.classList.remove("smoothScrollX"); + elem.classList.remove("scrollX"); + elem.classList.add("vertical-wrap"); + } } - return function(view, params) { + + return function (view, params) { function reload() { - loading.show(), loadResume(), loadNextUp() + loading.show(); + loadResume(); + loadNextUp(); } function loadNextUp() { @@ -52,178 +73,263 @@ define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "do UserId: ApiClient.getCurrentUserId(), ImageTypeLimit: 1, EnableImageTypes: "Primary,Backdrop,Thumb", - EnableTotalRecordCount: !1 + EnableTotalRecordCount: false }; - query.ParentId = libraryMenu.getTopParentId(), ApiClient.getNextUpEpisodes(query).then(function(result) { - result.Items.length ? view.querySelector(".noNextUpItems").classList.add("hide") : view.querySelector(".noNextUpItems").classList.remove("hide"); + query.ParentId = libraryMenu.getTopParentId(); + ApiClient.getNextUpEpisodes(query).then(function (result) { + if (result.Items.length) { + view.querySelector(".noNextUpItems").classList.add("hide"); + } else { + view.querySelector(".noNextUpItems").classList.remove("hide"); + } + var container = view.querySelector("#nextUpItems"); cardBuilder.buildCards(result.Items, { itemsContainer: container, - preferThumb: !0, + preferThumb: true, shape: "backdrop", - scalable: !0, - showTitle: !0, - showParentTitle: !0, - overlayText: !1, - centerText: !0, - overlayPlayButton: !0, - cardLayout: !1 - }), loading.hide() - }) + scalable: true, + showTitle: true, + showParentTitle: true, + overlayText: false, + centerText: true, + overlayPlayButton: true, + cardLayout: false + }); + loading.hide(); + }); } function enableScrollX() { - return !layoutManager.desktop + return !layoutManager.desktop; } function getThumbShape() { - return enableScrollX() ? "overflowBackdrop" : "backdrop" + return enableScrollX() ? "overflowBackdrop" : "backdrop"; } function loadResume() { - var parentId = libraryMenu.getTopParentId(), - screenWidth = dom.getWindowSize().innerWidth, - limit = screenWidth >= 1600 ? 5 : 6, - options = { - SortBy: "DatePlayed", - SortOrder: "Descending", - IncludeItemTypes: "Episode", - Filters: "IsResumable", - Limit: limit, - Recursive: !0, - Fields: "PrimaryImageAspectRatio,SeriesInfo,UserData,BasicSyncInfo", - ExcludeLocationTypes: "Virtual", - ParentId: parentId, - ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Thumb", - EnableTotalRecordCount: !1 - }; - ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function(result) { - result.Items.length ? view.querySelector("#resumableSection").classList.remove("hide") : view.querySelector("#resumableSection").classList.add("hide"); - var allowBottomPadding = !enableScrollX(), - container = view.querySelector("#resumableItems"); + var parentId = libraryMenu.getTopParentId(); + var screenWidth = dom.getWindowSize().innerWidth; + var limit = screenWidth >= 1600 ? 5 : 6; + var options = { + SortBy: "DatePlayed", + SortOrder: "Descending", + IncludeItemTypes: "Episode", + Filters: "IsResumable", + Limit: limit, + Recursive: true, + Fields: "PrimaryImageAspectRatio,SeriesInfo,UserData,BasicSyncInfo", + ExcludeLocationTypes: "Virtual", + ParentId: parentId, + ImageTypeLimit: 1, + EnableImageTypes: "Primary,Backdrop,Thumb", + EnableTotalRecordCount: false + }; + ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) { + if (result.Items.length) { + view.querySelector("#resumableSection").classList.remove("hide"); + } else { + view.querySelector("#resumableSection").classList.add("hide"); + } + + var allowBottomPadding = !enableScrollX(); + var container = view.querySelector("#resumableItems"); cardBuilder.buildCards(result.Items, { itemsContainer: container, - preferThumb: !0, + preferThumb: true, shape: getThumbShape(), - scalable: !0, - showTitle: !0, - showParentTitle: !0, - overlayText: !1, - centerText: !0, - overlayPlayButton: !0, + scalable: true, + showTitle: true, + showParentTitle: true, + overlayText: false, + centerText: true, + overlayPlayButton: true, allowBottomPadding: allowBottomPadding, - cardLayout: !1 - }) - }) + cardLayout: false + }); + }); } function onBeforeTabChange(e) { - preLoadTab(view, parseInt(e.detail.selectedTabIndex)) + preLoadTab(view, parseInt(e.detail.selectedTabIndex)); } function onTabChange(e) { var newIndex = parseInt(e.detail.selectedTabIndex); - loadTab(view, newIndex) + loadTab(view, newIndex); } function getTabContainers() { - return view.querySelectorAll(".pageTabContent") + return view.querySelectorAll(".pageTabContent"); } function initTabs() { - mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange) + mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange); } function getTabController(page, index, callback) { var depends = []; + switch (index) { case 0: depends.push("controllers/shows/tvshows"); break; + case 1: break; + case 2: depends.push("controllers/shows/tvlatest"); break; + case 3: depends.push("controllers/shows/tvupcoming"); break; + case 4: depends.push("controllers/shows/tvgenres"); break; + case 5: depends.push("controllers/shows/tvstudios"); break; + case 6: depends.push("controllers/shows/episodes"); break; + case 7: - depends.push("scripts/searchtab") + depends.push("scripts/searchtab"); } - require(depends, function(controllerFactory) { + + require(depends, function (controllerFactory) { var tabContent; - 1 === index && (tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"), self.tabContent = tabContent); + + if (index === 1) { + tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); + self.tabContent = tabContent; + } + var controller = tabControllers[index]; - controller || (tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"), controller = 1 === index ? self : 7 === index ? new controllerFactory(view, tabContent, { - collectionType: "tvshows", - parentId: params.topParentId - }) : new controllerFactory(view, params, tabContent), tabControllers[index] = controller, controller.initTab && controller.initTab()), callback(controller) - }) + + if (!controller) { + tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); + + if (index === 1) { + controller = self; + } else if (index === 7) { + controller = new controllerFactory(view, tabContent, { + collectionType: "tvshows", + parentId: params.topParentId + }); + } else { + controller = new controllerFactory(view, params, tabContent); + } + + tabControllers[index] = controller; + + if (controller.initTab) { + controller.initTab(); + } + } + + callback(controller); + }); } function preLoadTab(page, index) { - getTabController(page, index, function(controller) { - -1 == renderedTabs.indexOf(index) && controller.preRender && controller.preRender() - }) + getTabController(page, index, function (controller) { + if (renderedTabs.indexOf(index) == -1 && controller.preRender) { + controller.preRender(); + } + }); } function loadTab(page, index) { - currentTabIndex = index, getTabController(page, index, function(controller) { - initialTabIndex = null, -1 == renderedTabs.indexOf(index) && (renderedTabs.push(index), controller.renderTab()) - }) + currentTabIndex = index; + getTabController(page, index, function (controller) { + initialTabIndex = null; + + if (renderedTabs.indexOf(index) == -1) { + renderedTabs.push(index); + controller.renderTab(); + } + }); } function onPlaybackStop(e, state) { - state.NowPlayingItem && "Video" == state.NowPlayingItem.MediaType && (renderedTabs = [], mainTabsManager.getTabsElement().triggerTabChange()) + if (state.NowPlayingItem && state.NowPlayingItem.MediaType == "Video") { + renderedTabs = []; + mainTabsManager.getTabsElement().triggerTabChange(); + } } function onWebSocketMessage(e, data) { var msg = data; - "UserDataChanged" === msg.MessageType && msg.Data.UserId == ApiClient.getCurrentUserId() && (renderedTabs = []) + + if (msg.MessageType === "UserDataChanged" && msg.Data.UserId == ApiClient.getCurrentUserId()) { + renderedTabs = []; + } } function onInputCommand(e) { switch (e.detail.command) { case "search": - e.preventDefault(), Dashboard.navigate("search.html?collectionType=tv&parentId=" + params.topParentId) + e.preventDefault(); + Dashboard.navigate("search.html?collectionType=tv&parentId=" + params.topParentId); } } - var isViewRestored, self = this, - currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)), - initialTabIndex = currentTabIndex; - self.initTab = function() { + + var isViewRestored; + var self = this; + var currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)); + var initialTabIndex = currentTabIndex; + + self.initTab = function () { var tabContent = self.tabContent; setScrollClasses(tabContent.querySelector("#resumableItems"), enableScrollX()); - }, self.renderTab = function() { - reload() }; - var tabControllers = [], - renderedTabs = []; - setScrollClasses(view.querySelector("#resumableItems"), enableScrollX()), view.addEventListener("viewshow", function(e) { - if (isViewRestored = e.detail.isRestored, initTabs(), !view.getAttribute("data-title")) { + + self.renderTab = function () { + reload(); + }; + + var tabControllers = []; + var renderedTabs = []; + setScrollClasses(view.querySelector("#resumableItems"), enableScrollX()); + view.addEventListener("viewshow", function (e) { + isViewRestored = e.detail.isRestored; + initTabs(); + if (!view.getAttribute("data-title")) { var parentId = params.topParentId; - parentId ? ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function(item) { - view.setAttribute("data-title", item.Name), libraryMenu.setTitle(item.Name) - }) : (view.setAttribute("data-title", Globalize.translate("TabShows")), libraryMenu.setTitle(Globalize.translate("TabShows"))) + + if (parentId) { + ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function (item) { + view.setAttribute("data-title", item.Name); + libraryMenu.setTitle(item.Name); + }); + } else { + view.setAttribute("data-title", Globalize.translate("TabShows")); + libraryMenu.setTitle(Globalize.translate("TabShows")); + } } - events.on(playbackManager, "playbackstop", onPlaybackStop), events.on(ApiClient, "message", onWebSocketMessage), inputManager.on(window, onInputCommand) - }), view.addEventListener("viewbeforehide", function(e) { - inputManager.off(window, onInputCommand), events.off(playbackManager, "playbackstop", onPlaybackStop), events.off(ApiClient, "message", onWebSocketMessage) - }), view.addEventListener("viewdestroy", function(e) { - tabControllers.forEach(function(t) { - t.destroy && t.destroy() - }) - }) - } + + events.on(playbackManager, "playbackstop", onPlaybackStop); + events.on(ApiClient, "message", onWebSocketMessage); + inputManager.on(window, onInputCommand); + }); + view.addEventListener("viewbeforehide", function (e) { + inputManager.off(window, onInputCommand); + events.off(playbackManager, "playbackstop", onPlaybackStop); + events.off(ApiClient, "message", onWebSocketMessage); + }); + view.addEventListener("viewdestroy", function (e) { + tabControllers.forEach(function (t) { + if (t.destroy) { + t.destroy(); + } + }); + }); + }; }); diff --git a/src/controllers/shows/tvshows.js b/src/controllers/shows/tvshows.js index ac832a915e..adccd98234 100644 --- a/src/controllers/shows/tvshows.js +++ b/src/controllers/shows/tvshows.js @@ -1,199 +1,284 @@ -define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "alphaPicker", "emby-itemscontainer"], function(layoutManager, loading, events, libraryBrowser, imageLoader, listView, cardBuilder, alphaPicker) { +define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "alphaPicker", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, listView, cardBuilder, alphaPicker) { "use strict"; - return function(view, params, tabContent) { + + return function (view, params, tabContent) { function getPageData(context) { - var key = getSavedQueryKey(context), - pageData = data[key]; - return pageData || (pageData = data[key] = { - query: { - SortBy: "SortName", - SortOrder: "Ascending", - IncludeItemTypes: "Series", - Recursive: !0, - Fields: "PrimaryImageAspectRatio,BasicSyncInfo", - ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb", - StartIndex: 0, - Limit: pageSize - }, - view: libraryBrowser.getSavedView(key) || "Poster" - }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData + var key = getSavedQueryKey(context); + var pageData = data[key]; + + if (!pageData) { + pageData = data[key] = { + query: { + SortBy: "SortName", + SortOrder: "Ascending", + IncludeItemTypes: "Series", + Recursive: true, + Fields: "PrimaryImageAspectRatio,BasicSyncInfo", + ImageTypeLimit: 1, + EnableImageTypes: "Primary,Backdrop,Banner,Thumb", + StartIndex: 0, + Limit: pageSize + }, + view: libraryBrowser.getSavedView(key) || "Poster" + }; + pageData.query.ParentId = params.topParentId; + libraryBrowser.loadSavedQueryValues(key, pageData.query); + } + + return pageData; } function getQuery(context) { - return getPageData(context).query + return getPageData(context).query; } function getSavedQueryKey(context) { - return context.savedQueryKey || (context.savedQueryKey = libraryBrowser.getSavedQueryKey("series")), context.savedQueryKey + if (!context.savedQueryKey) { + context.savedQueryKey = libraryBrowser.getSavedQueryKey("series"); + } + + return context.savedQueryKey; } function onViewStyleChange() { - var viewStyle = self.getCurrentViewStyle(), - itemsContainer = tabContent.querySelector(".itemsContainer"); - "List" == viewStyle ? (itemsContainer.classList.add("vertical-list"), itemsContainer.classList.remove("vertical-wrap")) : (itemsContainer.classList.remove("vertical-list"), itemsContainer.classList.add("vertical-wrap")), itemsContainer.innerHTML = "" + var viewStyle = self.getCurrentViewStyle(); + var itemsContainer = tabContent.querySelector(".itemsContainer"); + + if ("List" == viewStyle) { + itemsContainer.classList.add("vertical-list"); + itemsContainer.classList.remove("vertical-wrap"); + } else { + itemsContainer.classList.remove("vertical-list"); + itemsContainer.classList.add("vertical-wrap"); + } + + itemsContainer.innerHTML = ""; } function reloadItems(page) { loading.show(); isLoading = true; var query = getQuery(page); - ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function(result) { + ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) { function onNextPageClick() { - if (isLoading) return; + if (isLoading) { + return; + } + query.StartIndex += query.Limit; reloadItems(tabContent); } function onPreviousPageClick() { - if (isLoading) return; + if (isLoading) { + return; + } + query.StartIndex -= query.Limit; reloadItems(tabContent); } - window.scrollTo(0, 0), updateFilterControls(page); - var html, pagingHtml = libraryBrowser.getQueryPagingHtml({ - startIndex: query.StartIndex, - limit: query.Limit, - totalRecordCount: result.TotalRecordCount, - showLimit: !1, - updatePageSizeSetting: !1, - addLayoutButton: !1, - sortButton: !1, - filterButton: !1 - }), - viewStyle = self.getCurrentViewStyle(); - html = "Thumb" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "backdrop", - preferThumb: !0, - context: "tvshows", - overlayMoreButton: !0, - showTitle: !0, - centerText: !0 - }) : "ThumbCard" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "backdrop", - preferThumb: !0, - context: "tvshows", - cardLayout: !0, - showTitle: !0, - showYear: !0, - centerText: !0 - }) : "Banner" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "banner", - preferBanner: !0, - context: "tvshows" - }) : "List" == viewStyle ? listView.getListViewHtml({ - items: result.Items, - context: "tvshows", - sortBy: query.SortBy - }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({ - items: result.Items, - shape: "portrait", - context: "tvshows", - showTitle: !0, - showYear: !0, - centerText: !0, - cardLayout: !0 - }) : cardBuilder.getCardsHtml({ - items: result.Items, - shape: "portrait", - context: "tvshows", - centerText: !0, - lazy: !0, - overlayMoreButton: !0, - showTitle: !0, - showYear: !0 + + window.scrollTo(0, 0); + updateFilterControls(page); + var html; + var pagingHtml = libraryBrowser.getQueryPagingHtml({ + startIndex: query.StartIndex, + limit: query.Limit, + totalRecordCount: result.TotalRecordCount, + showLimit: false, + updatePageSizeSetting: false, + addLayoutButton: false, + sortButton: false, + filterButton: false }); - var i, length, elems = tabContent.querySelectorAll(".paging"); - for (i = 0, length = elems.length; i < length; i++) elems[i].innerHTML = pagingHtml; - for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick); - for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick); + var viewStyle = self.getCurrentViewStyle(); + if (viewStyle == "Thumb") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "backdrop", + preferThumb: true, + context: "tvshows", + overlayMoreButton: true, + showTitle: true, + centerText: true + }); + } else if (viewStyle == "ThumbCard") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "backdrop", + preferThumb: true, + context: "tvshows", + cardLayout: true, + showTitle: true, + showYear: true, + centerText: true + }); + } else if (viewStyle == "Banner") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "banner", + preferBanner: true, + context: "tvshows" + }); + } else if (viewStyle == "List") { + html = listView.getListViewHtml({ + items: result.Items, + context: "tvshows", + sortBy: query.SortBy + }); + } else if (viewStyle == "PosterCard") { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "portrait", + context: "tvshows", + showTitle: true, + showYear: true, + centerText: true, + cardLayout: true + }); + } else { + html = cardBuilder.getCardsHtml({ + items: result.Items, + shape: "portrait", + context: "tvshows", + centerText: true, + lazy: true, + overlayMoreButton: true, + showTitle: true, + showYear: true + }); + } + var i; + var length; + var elems = tabContent.querySelectorAll(".paging"); + + for (i = 0, length = elems.length; i < length; i++) { + elems[i].innerHTML = pagingHtml; + } + + elems = tabContent.querySelectorAll(".btnNextPage"); + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onNextPageClick); + } + + elems = tabContent.querySelectorAll(".btnPreviousPage"); + for (i = 0, length = elems.length; i < length; i++) { + elems[i].addEventListener("click", onPreviousPageClick); + } + var itemsContainer = tabContent.querySelector(".itemsContainer"); itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); libraryBrowser.saveQueryValues(getSavedQueryKey(page), query); loading.hide(); isLoading = false; - }) + }); } function updateFilterControls(tabContent) { var query = getQuery(tabContent); - self.alphaPicker.value(query.NameStartsWithOrGreater) + self.alphaPicker.value(query.NameStartsWithOrGreater); } - var self = this, - pageSize = 100, - data = {}, - isLoading = false; - self.showFilterMenu = function() { - require(["components/filterdialog/filterdialog"], function(filterDialogFactory) { - var filterDialog = new filterDialogFactory({ - query: getQuery(tabContent), - mode: "series", - serverId: ApiClient.serverId() - }); - events.on(filterDialog, "filterchange", function() { - getQuery(tabContent).StartIndex = 0, reloadItems(tabContent) - }), filterDialog.show() - }) - }, self.getCurrentViewStyle = function() { - return getPageData(tabContent).view - }, - function(tabContent) { - var alphaPickerElement = tabContent.querySelector(".alphaPicker"); - if (alphaPickerElement.addEventListener("alphavaluechanged", function(e) { - var newValue = e.detail.value, - query = getQuery(tabContent); - query.NameStartsWithOrGreater = newValue, query.StartIndex = 0, reloadItems(tabContent) - }), self.alphaPicker = new alphaPicker({ - element: alphaPickerElement, - valueChangeEvent: "click" - }), layoutManager.desktop || layoutManager.mobile) { - tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right"); - var itemsContainer = tabContent.querySelector(".itemsContainer"); - itemsContainer.classList.remove("padded-left-withalphapicker"), itemsContainer.classList.add("padded-right-withalphapicker") - } - tabContent.querySelector(".btnFilter").addEventListener("click", function() { - self.showFilterMenu() - }), tabContent.querySelector(".btnSort").addEventListener("click", function(e) { - libraryBrowser.showSortMenu({ - items: [{ - name: Globalize.translate("OptionNameSort"), - id: "SortName" - }, { - name: Globalize.translate("OptionImdbRating"), - id: "CommunityRating,SortName" - }, { - name: Globalize.translate("OptionDateAdded"), - id: "DateCreated,SortName" - }, { - name: Globalize.translate("OptionDatePlayed"), - id: "DatePlayed,SortName" - }, { - name: Globalize.translate("OptionParentalRating"), - id: "OfficialRating,SortName" - }, { - name: Globalize.translate("OptionReleaseDate"), - id: "PremiereDate,SortName" - }], - callback: function() { - getQuery(tabContent).StartIndex = 0, reloadItems(tabContent) - }, - query: getQuery(tabContent), - button: e.target - }) + + var self = this; + var pageSize = 100; + var data = {}; + var isLoading = false; + + self.showFilterMenu = function () { + require(["components/filterdialog/filterdialog"], function (filterDialogFactory) { + var filterDialog = new filterDialogFactory({ + query: getQuery(tabContent), + mode: "series", + serverId: ApiClient.serverId() }); - var btnSelectView = tabContent.querySelector(".btnSelectView"); - btnSelectView.addEventListener("click", function(e) { - libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "Banner,List,Poster,PosterCard,Thumb,ThumbCard".split(",")) - }), btnSelectView.addEventListener("layoutchange", function(e) { - var viewStyle = e.detail.viewStyle; - getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), getQuery(tabContent).StartIndex = 0, onViewStyleChange(), reloadItems(tabContent) - }) - }(tabContent), onViewStyleChange(), self.renderTab = function() { - reloadItems(tabContent), updateFilterControls(tabContent) - }, self.destroy = function() {} - } + events.on(filterDialog, "filterchange", function () { + getQuery(tabContent).StartIndex = 0; + reloadItems(tabContent); + }); + filterDialog.show(); + }); + }; + + self.getCurrentViewStyle = function () { + return getPageData(tabContent).view; + }; + + function initPage(tabContent) { + var alphaPickerElement = tabContent.querySelector(".alphaPicker"); + + alphaPickerElement.addEventListener("alphavaluechanged", function (e) { + var newValue = e.detail.value; + var query = getQuery(tabContent); + query.NameStartsWithOrGreater = newValue; + query.StartIndex = 0; + reloadItems(tabContent); + }); + self.alphaPicker = new alphaPicker({ + element: alphaPickerElement, + valueChangeEvent: "click" + }); + if (layoutManager.desktop || layoutManager.mobile) { + tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right"); + var itemsContainer = tabContent.querySelector(".itemsContainer"); + itemsContainer.classList.remove("padded-left-withalphapicker"); + itemsContainer.classList.add("padded-right-withalphapicker"); + } + + tabContent.querySelector(".btnFilter").addEventListener("click", function () { + self.showFilterMenu(); + }); + tabContent.querySelector(".btnSort").addEventListener("click", function (e) { + libraryBrowser.showSortMenu({ + items: [{ + name: Globalize.translate("OptionNameSort"), + id: "SortName" + }, { + name: Globalize.translate("OptionImdbRating"), + id: "CommunityRating,SortName" + }, { + name: Globalize.translate("OptionDateAdded"), + id: "DateCreated,SortName" + }, { + name: Globalize.translate("OptionDatePlayed"), + id: "DatePlayed,SortName" + }, { + name: Globalize.translate("OptionParentalRating"), + id: "OfficialRating,SortName" + }, { + name: Globalize.translate("OptionReleaseDate"), + id: "PremiereDate,SortName" + }], + callback: function () { + getQuery(tabContent).StartIndex = 0; + reloadItems(tabContent); + }, + query: getQuery(tabContent), + button: e.target + }); + }); + var btnSelectView = tabContent.querySelector(".btnSelectView"); + btnSelectView.addEventListener("click", function (e) { + libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "Banner,List,Poster,PosterCard,Thumb,ThumbCard".split(",")); + }); + btnSelectView.addEventListener("layoutchange", function (e) { + var viewStyle = e.detail.viewStyle; + getPageData(tabContent).view = viewStyle; + libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle); + getQuery(tabContent).StartIndex = 0; + onViewStyleChange(); + reloadItems(tabContent); + }); + } + + initPage(tabContent); + onViewStyleChange(); + + self.renderTab = function () { + reloadItems(tabContent); + updateFilterControls(tabContent); + }; + + self.destroy = function () {}; + }; }); diff --git a/src/controllers/shows/tvstudios.js b/src/controllers/shows/tvstudios.js index bfa33401f4..3c000a8e72 100644 --- a/src/controllers/shows/tvstudios.js +++ b/src/controllers/shows/tvstudios.js @@ -1,52 +1,65 @@ -define(["loading", "libraryBrowser", "cardBuilder", "apphost"], function(loading, libraryBrowser, cardBuilder, appHost) { +define(["loading", "libraryBrowser", "cardBuilder", "apphost"], function (loading, libraryBrowser, cardBuilder, appHost) { "use strict"; function getQuery(params) { - var key = getSavedQueryKey(), - pageData = data[key]; - return pageData || (pageData = data[key] = { - query: { - SortBy: "SortName", - SortOrder: "Ascending", - IncludeItemTypes: "Series", - Recursive: !0, - Fields: "DateCreated,PrimaryImageAspectRatio", - StartIndex: 0 - } - }, pageData.query.ParentId = params.topParentId), pageData.query + var key = getSavedQueryKey(); + var pageData = data[key]; + + if (!pageData) { + pageData = data[key] = { + query: { + SortBy: "SortName", + SortOrder: "Ascending", + IncludeItemTypes: "Series", + Recursive: true, + Fields: "DateCreated,PrimaryImageAspectRatio", + StartIndex: 0 + } + }; + pageData.query.ParentId = params.topParentId; + } + + return pageData.query; } function getSavedQueryKey() { - return libraryBrowser.getSavedQueryKey("studios") + return libraryBrowser.getSavedQueryKey("studios"); } function getPromise(context, params) { var query = getQuery(params); - return loading.show(), ApiClient.getStudios(ApiClient.getCurrentUserId(), query) + loading.show(); + return ApiClient.getStudios(ApiClient.getCurrentUserId(), query); } function reloadItems(context, params, promise) { - promise.then(function(result) { + promise.then(function (result) { var elem = context.querySelector("#items"); cardBuilder.buildCards(result.Items, { itemsContainer: elem, shape: "backdrop", - preferThumb: !0, - showTitle: !0, - scalable: !0, - centerText: !0, - overlayMoreButton: !0, + preferThumb: true, + showTitle: true, + scalable: true, + centerText: true, + overlayMoreButton: true, context: "tvshows" - }), loading.hide() - }) + }); + loading.hide(); + }); } + var data = {}; - return function(view, params, tabContent) { - var promise, self = this; - self.preRender = function() { - promise = getPromise(view, params) - }, self.renderTab = function() { - reloadItems(tabContent, params, promise) - } - } -}); \ No newline at end of file + return function (view, params, tabContent) { + var promise; + var self = this; + + self.preRender = function () { + promise = getPromise(view, params); + }; + + self.renderTab = function () { + reloadItems(tabContent, params, promise); + }; + }; +}); diff --git a/src/controllers/shows/tvupcoming.js b/src/controllers/shows/tvupcoming.js index 9d6a79a5ef..162e6fcb34 100644 --- a/src/controllers/shows/tvupcoming.js +++ b/src/controllers/shows/tvupcoming.js @@ -1,4 +1,4 @@ -define(["layoutManager", "loading", "datetime", "libraryBrowser", "cardBuilder", "apphost", "imageLoader", "scrollStyles", "emby-itemscontainer"], function(layoutManager, loading, datetime, libraryBrowser, cardBuilder, appHost, imageLoader) { +define(["layoutManager", "loading", "datetime", "libraryBrowser", "cardBuilder", "apphost", "imageLoader", "scrollStyles", "emby-itemscontainer"], function (layoutManager, loading, datetime, libraryBrowser, cardBuilder, appHost, imageLoader) { "use strict"; function getUpcomingPromise(context, params) { @@ -9,82 +9,129 @@ define(["layoutManager", "loading", "datetime", "libraryBrowser", "cardBuilder", UserId: ApiClient.getCurrentUserId(), ImageTypeLimit: 1, EnableImageTypes: "Primary,Backdrop,Banner,Thumb", - EnableTotalRecordCount: !1 + EnableTotalRecordCount: false }; - return query.ParentId = params.topParentId, ApiClient.getJSON(ApiClient.getUrl("Shows/Upcoming", query)) + query.ParentId = params.topParentId; + return ApiClient.getJSON(ApiClient.getUrl("Shows/Upcoming", query)); } function loadUpcoming(context, params, promise) { - promise.then(function(result) { + promise.then(function (result) { var items = result.Items; - items.length ? context.querySelector(".noItemsMessage").style.display = "none" : context.querySelector(".noItemsMessage").style.display = "block", renderUpcoming(context.querySelector("#upcomingItems"), items), loading.hide() - }) + + if (items.length) { + context.querySelector(".noItemsMessage").style.display = "none"; + } else { + context.querySelector(".noItemsMessage").style.display = "block"; + } + + renderUpcoming(context.querySelector("#upcomingItems"), items); + loading.hide(); + }); } function enableScrollX() { - return !layoutManager.desktop + return !layoutManager.desktop; } function getThumbShape() { - return enableScrollX() ? "overflowBackdrop" : "backdrop" + return enableScrollX() ? "overflowBackdrop" : "backdrop"; } function renderUpcoming(elem, items) { - var i, length, groups = [], - currentGroupName = "", - currentGroup = []; + var i; + var length; + var groups = []; + var currentGroupName = ""; + var currentGroup = []; + for (i = 0, length = items.length; i < length; i++) { - var item = items[i], - dateText = ""; - if (item.PremiereDate) try { - var premiereDate = datetime.parseISO8601Date(item.PremiereDate, !0); - dateText = datetime.isRelativeDay(premiereDate, -1) ? Globalize.translate("Yesterday") : datetime.toLocaleDateString(premiereDate, { - weekday: "long", - month: "short", - day: "numeric" - }) - } catch (err) {} - dateText != currentGroupName ? (currentGroup.length && groups.push({ - name: currentGroupName, - items: currentGroup - }), currentGroupName = dateText, currentGroup = [item]) : currentGroup.push(item) + var item = items[i]; + var dateText = ""; + + if (item.PremiereDate) { + try { + var premiereDate = datetime.parseISO8601Date(item.PremiereDate, true); + dateText = datetime.isRelativeDay(premiereDate, -1) ? Globalize.translate("Yesterday") : datetime.toLocaleDateString(premiereDate, { + weekday: "long", + month: "short", + day: "numeric" + }); + } catch (err) {} + } + + if (dateText != currentGroupName) { + if (currentGroup.length) { + groups.push({ + name: currentGroupName, + items: currentGroup + }); + } + + currentGroupName = dateText; + currentGroup = [item]; + } else { + currentGroup.push(item); + } } + var html = ""; + for (i = 0, length = groups.length; i < length; i++) { var group = groups[i]; - html += '
', html += '

' + group.name + "

"; - var allowBottomPadding = !0; + html += '
'; + html += '

' + group.name + "

"; + var allowBottomPadding = true; + if (enableScrollX()) { - allowBottomPadding = !1; + allowBottomPadding = false; var scrollXClass = "scrollX hiddenScrollX"; - layoutManager.tv && (scrollXClass += " smoothScrollX"), html += '
' - } else html += '
'; + + if (layoutManager.tv) { + scrollXClass += " smoothScrollX"; + } + + html += '
'; + } else { + html += '
'; + } + var supportsImageAnalysis = appHost.supports("imageanalysis"); - supportsImageAnalysis = !1, html += cardBuilder.getCardsHtml({ + supportsImageAnalysis = false; + html += cardBuilder.getCardsHtml({ items: group.items, - showLocationTypeIndicator: !1, + showLocationTypeIndicator: false, shape: getThumbShape(), - showTitle: !0, - preferThumb: !0, - lazy: !0, - showDetailsMenu: !0, + showTitle: true, + preferThumb: true, + lazy: true, + showDetailsMenu: true, centerText: !supportsImageAnalysis, - showParentTitle: !0, - overlayText: !1, + showParentTitle: true, + overlayText: false, allowBottomPadding: allowBottomPadding, cardLayout: supportsImageAnalysis, - overlayMoreButton: !0, - missingIndicator: !1 - }), html += "
", html += "
" + overlayMoreButton: true, + missingIndicator: false + }); + html += "
"; + html += "
"; } - elem.innerHTML = html, imageLoader.lazyChildren(elem) + + elem.innerHTML = html; + imageLoader.lazyChildren(elem); } - return function(view, params, tabContent) { - var upcomingPromise, self = this; - self.preRender = function() { - upcomingPromise = getUpcomingPromise(view, params) - }, self.renderTab = function() { - loadUpcoming(tabContent, params, upcomingPromise) - } - } -}); \ No newline at end of file + + return function (view, params, tabContent) { + var upcomingPromise; + var self = this; + + self.preRender = function () { + upcomingPromise = getUpcomingPromise(view, params); + }; + + self.renderTab = function () { + loadUpcoming(tabContent, params, upcomingPromise); + }; + }; +}); diff --git a/src/controllers/streamingsettings.js b/src/controllers/streamingsettings.js index 6f19a68422..6c85034458 100644 --- a/src/controllers/streamingsettings.js +++ b/src/controllers/streamingsettings.js @@ -1,16 +1,19 @@ -define(["jQuery", "libraryMenu", "loading"], function($, libraryMenu, loading) { +define(["jQuery", "libraryMenu", "loading"], function ($, libraryMenu, loading) { "use strict"; function loadPage(page, config) { - $("#txtRemoteClientBitrateLimit", page).val(config.RemoteClientBitrateLimit / 1e6 || ""), loading.hide() + $("#txtRemoteClientBitrateLimit", page).val(config.RemoteClientBitrateLimit / 1e6 || ""); + loading.hide(); } function onSubmit() { loading.show(); var form = this; - return ApiClient.getServerConfiguration().then(function(config) { - config.RemoteClientBitrateLimit = parseInt(1e6 * parseFloat($("#txtRemoteClientBitrateLimit", form).val() || "0")), ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult) - }), !1 + ApiClient.getServerConfiguration().then(function (config) { + config.RemoteClientBitrateLimit = parseInt(1e6 * parseFloat($("#txtRemoteClientBitrateLimit", form).val() || "0")); + ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult); + }); + return false; } function getTabs() { @@ -23,30 +26,35 @@ define(["jQuery", "libraryMenu", "loading"], function($, libraryMenu, loading) { }, { href: "streamingsettings.html", name: Globalize.translate("TabStreaming") - }] + }]; } - $(document).on("pageinit", "#streamingSettingsPage", function() { + $(document).on("pageinit", "#streamingSettingsPage", function () { var page = this; - $("#btnSelectTranscodingTempPath", page).on("click.selectDirectory", function() { - require(["directorybrowser"], function(directoryBrowser) { - var picker = new directoryBrowser; + $("#btnSelectTranscodingTempPath", page).on("click.selectDirectory", function () { + require(["directorybrowser"], function (directoryBrowser) { + var picker = new directoryBrowser(); picker.show({ - callback: function(path) { - path && $("#txtTranscodingTempPath", page).val(path), picker.close() + callback: function (path) { + if (path) { + $("#txtTranscodingTempPath", page).val(path); + } + + picker.close(); }, - validateWriteable: !0, + validateWriteable: true, header: Globalize.translate("HeaderSelectTranscodingPath"), instruction: Globalize.translate("HeaderSelectTranscodingPathHelp") - }) - }) - }), $(".streamingSettingsForm").off("submit", onSubmit).on("submit", onSubmit) - }).on("pageshow", "#streamingSettingsPage", function() { + }); + }); + }); + $(".streamingSettingsForm").off("submit", onSubmit).on("submit", onSubmit); + }).on("pageshow", "#streamingSettingsPage", function () { loading.show(); libraryMenu.setTabs("playback", 2, getTabs); var page = this; - ApiClient.getServerConfiguration().then(function(config) { - loadPage(page, config) - }) - }) -}); \ No newline at end of file + ApiClient.getServerConfiguration().then(function (config) { + loadPage(page, config); + }); + }); +}); diff --git a/src/controllers/user/display.js b/src/controllers/user/display.js index 4b4440f96a..f91e874a89 100644 --- a/src/controllers/user/display.js +++ b/src/controllers/user/display.js @@ -1,28 +1,49 @@ -define(["displaySettings", "userSettingsBuilder", "userSettings"], function(DisplaySettings, userSettingsBuilder, currentUserSettings) { +define(["displaySettings", "userSettingsBuilder", "userSettings"], function (DisplaySettings, userSettingsBuilder, currentUserSettings) { "use strict"; - return function(view, params) { + + return function (view, params) { function onBeforeUnload(e) { - hasChanges && (e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?") + if (hasChanges) { + e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?"; + } } - var settingsInstance, hasChanges, userId = params.userId || ApiClient.getCurrentUserId(), - userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder; - view.addEventListener("viewshow", function() { - window.addEventListener("beforeunload", onBeforeUnload), settingsInstance ? settingsInstance.loadData() : settingsInstance = new DisplaySettings({ - serverId: ApiClient.serverId(), - userId: userId, - element: view.querySelector(".settingsContainer"), - userSettings: userSettings, - enableSaveButton: !1, - enableSaveConfirmation: !1 - }) - }), view.addEventListener("change", function() { - hasChanges = !0 - }), view.addEventListener("viewbeforehide", function() { - window.removeEventListener("beforeunload", onBeforeUnload), hasChanges = !1, settingsInstance && settingsInstance.submit() - }), view.addEventListener("viewdestroy", function() { - settingsInstance && (settingsInstance.destroy(), settingsInstance = null) - }), view.addEventListener("viewdestroy", function() { - settingsInstance && (settingsInstance.destroy(), settingsInstance = null) - }) - } -}); \ No newline at end of file + + var settingsInstance; + var hasChanges; + var userId = params.userId || ApiClient.getCurrentUserId(); + var userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder(); + view.addEventListener("viewshow", function () { + window.addEventListener("beforeunload", onBeforeUnload); + + if (settingsInstance) { + settingsInstance.loadData(); + } else { + settingsInstance = new DisplaySettings({ + serverId: ApiClient.serverId(), + userId: userId, + element: view.querySelector(".settingsContainer"), + userSettings: userSettings, + enableSaveButton: false, + enableSaveConfirmation: false + }); + } + }); + view.addEventListener("change", function () { + hasChanges = true; + }); + view.addEventListener("viewbeforehide", function () { + window.removeEventListener("beforeunload", onBeforeUnload); + hasChanges = false; + + if (settingsInstance) { + settingsInstance.submit(); + } + }); + view.addEventListener("viewdestroy", function () { + if (settingsInstance) { + settingsInstance.destroy(); + settingsInstance = null; + } + }); + }; +}); diff --git a/src/controllers/user/home.js b/src/controllers/user/home.js index a7147ddda3..5794d58723 100644 --- a/src/controllers/user/home.js +++ b/src/controllers/user/home.js @@ -1,26 +1,48 @@ -define(["homescreenSettings", "userSettingsBuilder", "dom", "globalize", "loading", "userSettings", "listViewStyle"], function(HomescreenSettings, userSettingsBuilder, dom, globalize, loading, currentUserSettings) { +define(["homescreenSettings", "userSettingsBuilder", "dom", "globalize", "loading", "userSettings", "listViewStyle"], function (HomescreenSettings, userSettingsBuilder, dom, globalize, loading, currentUserSettings) { "use strict"; - return function(view, params) { + + return function (view, params) { function onBeforeUnload(e) { - hasChanges && (e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?") + if (hasChanges) { + e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?"; + } } - var homescreenSettingsInstance, hasChanges, userId = params.userId || ApiClient.getCurrentUserId(), - userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder; - view.addEventListener("viewshow", function() { - window.addEventListener("beforeunload", onBeforeUnload), homescreenSettingsInstance ? homescreenSettingsInstance.loadData() : homescreenSettingsInstance = new HomescreenSettings({ - serverId: ApiClient.serverId(), - userId: userId, - element: view.querySelector(".homeScreenSettingsContainer"), - userSettings: userSettings, - enableSaveButton: !1, - enableSaveConfirmation: !1 - }) - }), view.addEventListener("change", function() { - hasChanges = !0 - }), view.addEventListener("viewbeforehide", function() { - hasChanges = !1, homescreenSettingsInstance && homescreenSettingsInstance.submit() - }), view.addEventListener("viewdestroy", function() { - homescreenSettingsInstance && (homescreenSettingsInstance.destroy(), homescreenSettingsInstance = null) - }) - } -}); \ No newline at end of file + + var homescreenSettingsInstance; + var hasChanges; + var userId = params.userId || ApiClient.getCurrentUserId(); + var userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder(); + view.addEventListener("viewshow", function () { + window.addEventListener("beforeunload", onBeforeUnload); + + if (homescreenSettingsInstance) { + homescreenSettingsInstance.loadData(); + } else { + homescreenSettingsInstance = new HomescreenSettings({ + serverId: ApiClient.serverId(), + userId: userId, + element: view.querySelector(".homeScreenSettingsContainer"), + userSettings: userSettings, + enableSaveButton: false, + enableSaveConfirmation: false + }); + } + }); + view.addEventListener("change", function () { + hasChanges = true; + }); + view.addEventListener("viewbeforehide", function () { + hasChanges = false; + + if (homescreenSettingsInstance) { + homescreenSettingsInstance.submit(); + } + }); + view.addEventListener("viewdestroy", function () { + if (homescreenSettingsInstance) { + homescreenSettingsInstance.destroy(); + homescreenSettingsInstance = null; + } + }); + }; +}); diff --git a/src/controllers/user/menu.js b/src/controllers/user/menu.js index 6bac0011d2..d9fa2ab998 100644 --- a/src/controllers/user/menu.js +++ b/src/controllers/user/menu.js @@ -18,7 +18,7 @@ define(["apphost", "connectionManager", "listViewStyle", "emby-button"], functio page.querySelector(".lnkSubtitlePreferences").setAttribute("href", "mypreferencessubtitles.html?userId=" + userId); if (appHost.supports("multiserver")) { - page.querySelector(".selectServer").classList.remove("hide") + page.querySelector(".selectServer").classList.remove("hide"); } else { page.querySelector(".selectServer").classList.add("hide"); } @@ -35,6 +35,6 @@ define(["apphost", "connectionManager", "listViewStyle", "emby-button"], functio page.querySelector(".adminSection").classList.add("hide"); } }); - }) - } + }); + }; }); diff --git a/src/controllers/user/playback.js b/src/controllers/user/playback.js index 856470948a..f2463ad8df 100644 --- a/src/controllers/user/playback.js +++ b/src/controllers/user/playback.js @@ -1,26 +1,48 @@ -define(["playbackSettings", "userSettingsBuilder", "dom", "globalize", "loading", "userSettings", "listViewStyle"], function(PlaybackSettings, userSettingsBuilder, dom, globalize, loading, currentUserSettings) { +define(["playbackSettings", "userSettingsBuilder", "dom", "globalize", "loading", "userSettings", "listViewStyle"], function (PlaybackSettings, userSettingsBuilder, dom, globalize, loading, currentUserSettings) { "use strict"; - return function(view, params) { + + return function (view, params) { function onBeforeUnload(e) { - hasChanges && (e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?") + if (hasChanges) { + e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?"; + } } - var settingsInstance, hasChanges, userId = params.userId || ApiClient.getCurrentUserId(), - userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder; - view.addEventListener("viewshow", function() { - window.addEventListener("beforeunload", onBeforeUnload), settingsInstance ? settingsInstance.loadData() : settingsInstance = new PlaybackSettings({ - serverId: ApiClient.serverId(), - userId: userId, - element: view.querySelector(".settingsContainer"), - userSettings: userSettings, - enableSaveButton: !1, - enableSaveConfirmation: !1 - }) - }), view.addEventListener("change", function() { - hasChanges = !0 - }), view.addEventListener("viewbeforehide", function() { - hasChanges = !1, settingsInstance && settingsInstance.submit() - }), view.addEventListener("viewdestroy", function() { - settingsInstance && (settingsInstance.destroy(), settingsInstance = null) - }) - } -}); \ No newline at end of file + + var settingsInstance; + var hasChanges; + var userId = params.userId || ApiClient.getCurrentUserId(); + var userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder(); + view.addEventListener("viewshow", function () { + window.addEventListener("beforeunload", onBeforeUnload); + + if (settingsInstance) { + settingsInstance.loadData(); + } else { + settingsInstance = new PlaybackSettings({ + serverId: ApiClient.serverId(), + userId: userId, + element: view.querySelector(".settingsContainer"), + userSettings: userSettings, + enableSaveButton: false, + enableSaveConfirmation: false + }); + } + }); + view.addEventListener("change", function () { + hasChanges = true; + }); + view.addEventListener("viewbeforehide", function () { + hasChanges = false; + + if (settingsInstance) { + settingsInstance.submit(); + } + }); + view.addEventListener("viewdestroy", function () { + if (settingsInstance) { + settingsInstance.destroy(); + settingsInstance = null; + } + }); + }; +}); diff --git a/src/controllers/user/subtitles.js b/src/controllers/user/subtitles.js index 81d949e1a9..205265efcd 100644 --- a/src/controllers/user/subtitles.js +++ b/src/controllers/user/subtitles.js @@ -1,26 +1,48 @@ -define(["subtitleSettings", "userSettingsBuilder", "userSettings"], function(SubtitleSettings, userSettingsBuilder, currentUserSettings) { +define(["subtitleSettings", "userSettingsBuilder", "userSettings"], function (SubtitleSettings, userSettingsBuilder, currentUserSettings) { "use strict"; - return function(view, params) { + + return function (view, params) { function onBeforeUnload(e) { - hasChanges && (e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?") + if (hasChanges) { + e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?"; + } } - var subtitleSettingsInstance, hasChanges, userId = params.userId || ApiClient.getCurrentUserId(), - userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder; - view.addEventListener("viewshow", function() { - window.addEventListener("beforeunload", onBeforeUnload), subtitleSettingsInstance ? subtitleSettingsInstance.loadData() : subtitleSettingsInstance = new SubtitleSettings({ - serverId: ApiClient.serverId(), - userId: userId, - element: view.querySelector(".settingsContainer"), - userSettings: userSettings, - enableSaveButton: !1, - enableSaveConfirmation: !1 - }) - }), view.addEventListener("change", function() { - hasChanges = !0 - }), view.addEventListener("viewbeforehide", function() { - hasChanges = !1, subtitleSettingsInstance && subtitleSettingsInstance.submit() - }), view.addEventListener("viewdestroy", function() { - subtitleSettingsInstance && (subtitleSettingsInstance.destroy(), subtitleSettingsInstance = null) - }) - } -}); \ No newline at end of file + + var subtitleSettingsInstance; + var hasChanges; + var userId = params.userId || ApiClient.getCurrentUserId(); + var userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder(); + view.addEventListener("viewshow", function () { + window.addEventListener("beforeunload", onBeforeUnload); + + if (subtitleSettingsInstance) { + subtitleSettingsInstance.loadData(); + } else { + subtitleSettingsInstance = new SubtitleSettings({ + serverId: ApiClient.serverId(), + userId: userId, + element: view.querySelector(".settingsContainer"), + userSettings: userSettings, + enableSaveButton: false, + enableSaveConfirmation: false + }); + } + }); + view.addEventListener("change", function () { + hasChanges = true; + }); + view.addEventListener("viewbeforehide", function () { + hasChanges = false; + + if (subtitleSettingsInstance) { + subtitleSettingsInstance.submit(); + } + }); + view.addEventListener("viewdestroy", function () { + if (subtitleSettingsInstance) { + subtitleSettingsInstance.destroy(); + subtitleSettingsInstance = null; + } + }); + }; +}); diff --git a/src/controllers/useredit.js b/src/controllers/useredit.js index 0709e8dae9..fb6a3f94cd 100644 --- a/src/controllers/useredit.js +++ b/src/controllers/useredit.js @@ -1,53 +1,84 @@ -define(["jQuery", "loading", "libraryMenu", "fnchecked"], function($, loading, libraryMenu) { +define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, libraryMenu) { "use strict"; function loadDeleteFolders(page, user, mediaFolders) { ApiClient.getJSON(ApiClient.getUrl("Channels", { - SupportsMediaDeletion: !0 - })).then(function(channelsResult) { - var i, length, folder, isChecked, checkedAttribute, html = ""; - for (i = 0, length = mediaFolders.length; i < length; i++) folder = mediaFolders[i], isChecked = user.Policy.EnableContentDeletion || -1 != user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id), checkedAttribute = isChecked ? ' checked="checked"' : "", html += '"; - for (i = 0, length = channelsResult.Items.length; i < length; i++) folder = channelsResult.Items[i], isChecked = user.Policy.EnableContentDeletion || -1 != user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id), checkedAttribute = isChecked ? ' checked="checked"' : "", html += '"; - $(".deleteAccess", page).html(html).trigger("create"), $("#chkEnableDeleteAllFolders", page).checked(user.Policy.EnableContentDeletion).trigger("change") - }) + SupportsMediaDeletion: true + })).then(function (channelsResult) { + var i; + var length; + var folder; + var isChecked; + var checkedAttribute; + var html = ""; + + for (i = 0, length = mediaFolders.length; i < length; i++) { + folder = mediaFolders[i]; + isChecked = user.Policy.EnableContentDeletion || -1 != user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id); + checkedAttribute = isChecked ? ' checked="checked"' : ""; + html += '"; + } + + for (i = 0, length = channelsResult.Items.length; i < length; i++) { + folder = channelsResult.Items[i]; + isChecked = user.Policy.EnableContentDeletion || -1 != user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id); + checkedAttribute = isChecked ? ' checked="checked"' : ""; + html += '"; + } + + $(".deleteAccess", page).html(html).trigger("create"); + $("#chkEnableDeleteAllFolders", page).checked(user.Policy.EnableContentDeletion).trigger("change"); + }); } function loadAuthProviders(page, user, providers) { - providers.length > 1 ? page.querySelector(".fldSelectLoginProvider").classList.remove("hide") : page.querySelector(".fldSelectLoginProvider").classList.add("hide"); + if (providers.length > 1) { + page.querySelector(".fldSelectLoginProvider").classList.remove("hide"); + } else { + page.querySelector(".fldSelectLoginProvider").classList.add("hide"); + } + var currentProviderId = user.Policy.AuthenticationProviderId; - page.querySelector(".selectLoginProvider").innerHTML = providers.map(function(provider) { + page.querySelector(".selectLoginProvider").innerHTML = providers.map(function (provider) { var selected = provider.Id === currentProviderId || providers.length < 2 ? " selected" : ""; - return '" - }) + return '"; + }); } function loadPasswordResetProviders(page, user, providers) { - providers.length > 1 ? page.querySelector(".fldSelectPasswordResetProvider").classList.remove("hide") : page.querySelector(".fldSelectPasswordResetProvider").classList.add("hide"); + if (providers.length > 1) { + page.querySelector(".fldSelectPasswordResetProvider").classList.remove("hide"); + } else { + page.querySelector(".fldSelectPasswordResetProvider").classList.add("hide"); + } + var currentProviderId = user.Policy.PasswordResetProviderId; - page.querySelector(".selectPasswordResetProvider").innerHTML = providers.map(function(provider) { - var selected = (provider.Id === currentProviderId || providers.length < 2) ? " selected" : ""; - return '" - }) + page.querySelector(".selectPasswordResetProvider").innerHTML = providers.map(function (provider) { + var selected = provider.Id === currentProviderId || providers.length < 2 ? " selected" : ""; + return '"; + }); } function loadUser(page, user) { currentUser = user; - ApiClient.getJSON(ApiClient.getUrl("Auth/Providers")).then(function(providers) { - loadAuthProviders(page, user, providers) + ApiClient.getJSON(ApiClient.getUrl("Auth/Providers")).then(function (providers) { + loadAuthProviders(page, user, providers); }); - ApiClient.getJSON(ApiClient.getUrl("Auth/PasswordResetProviders")).then(function(providers) { - loadPasswordResetProviders(page, user, providers) + ApiClient.getJSON(ApiClient.getUrl("Auth/PasswordResetProviders")).then(function (providers) { + loadPasswordResetProviders(page, user, providers); }); ApiClient.getJSON(ApiClient.getUrl("Library/MediaFolders", { - IsHidden: false - })).then(function(folders) { - loadDeleteFolders(page, user, folders.Items) + IsHidden: false + })).then(function (folders) { + loadDeleteFolders(page, user, folders.Items); }); + if (user.Policy.IsDisabled) { $(".disabledUserBanner", page).show(); } else { $(".disabledUserBanner", page).hide(); } + $("#txtUserName", page).prop("disabled", "").removeAttr("disabled"); $("#fldConnectInfo", page).show(); $(".lnkEditUserPreferences", page).attr("href", "mypreferencesmenu.html?userId=" + user.Id); @@ -78,7 +109,8 @@ define(["jQuery", "loading", "libraryMenu", "fnchecked"], function($, loading, l function onSaveComplete(page, user) { Dashboard.navigate("userprofiles.html"); loading.hide(); - require(["toast"], function(toast) { + + require(["toast"], function (toast) { toast(Globalize.translate("SettingsSaved")); }); } @@ -106,45 +138,59 @@ define(["jQuery", "loading", "libraryMenu", "fnchecked"], function($, loading, l user.Policy.AuthenticationProviderId = page.querySelector(".selectLoginProvider").value; user.Policy.PasswordResetProviderId = page.querySelector(".selectPasswordResetProvider").value; user.Policy.EnableContentDeletion = $("#chkEnableDeleteAllFolders", page).checked(); - user.Policy.EnableContentDeletionFromFolders = user.Policy.EnableContentDeletion ? [] : $(".chkFolder", page).get().filter(function(c) { - return c.checked - }).map(function(c) { - return c.getAttribute("data-id") + user.Policy.EnableContentDeletionFromFolders = user.Policy.EnableContentDeletion ? [] : $(".chkFolder", page).get().filter(function (c) { + return c.checked; + }).map(function (c) { + return c.getAttribute("data-id"); + }); + ApiClient.updateUser(user).then(function () { + ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { + onSaveComplete(page, user); + }); }); - ApiClient.updateUser(user).then(function() { - ApiClient.updateUserPolicy(user.Id, user.Policy).then(function() { - onSaveComplete(page, user) - }) - }) } function onSubmit() { var page = $(this).parents(".page")[0]; - return loading.show(), getUser().then(function(result) { - saveUser(result, page) - }), !1 + loading.show(); + getUser().then(function (result) { + saveUser(result, page); + }); + return false; } function getUser() { var userId = getParameterByName("userId"); - return ApiClient.getUser(userId) + return ApiClient.getUser(userId); } function loadData(page) { - loading.show(), getUser().then(function(user) { - loadUser(page, user) - }) + loading.show(); + getUser().then(function (user) { + loadUser(page, user); + }); } + var currentUser; - $(document).on("pageinit", "#editUserPage", function() { - $(".editUserProfileForm").off("submit", onSubmit).on("submit", onSubmit), this.querySelector(".sharingHelp").innerHTML = Globalize.translate("OptionAllowLinkSharingHelp", 30); + $(document).on("pageinit", "#editUserPage", function () { + $(".editUserProfileForm").off("submit", onSubmit).on("submit", onSubmit); + this.querySelector(".sharingHelp").innerHTML = Globalize.translate("OptionAllowLinkSharingHelp", 30); var page = this; - $("#chkEnableDeleteAllFolders", this).on("change", function() { - this.checked ? $(".deleteAccess", page).hide() : $(".deleteAccess", page).show() - }), ApiClient.getServerConfiguration().then(function(config) { - config.EnableRemoteAccess ? page.querySelector(".fldRemoteAccess").classList.remove("hide") : page.querySelector(".fldRemoteAccess").classList.add("hide") - }) - }).on("pagebeforeshow", "#editUserPage", function() { - loadData(this) - }) + $("#chkEnableDeleteAllFolders", this).on("change", function () { + if (this.checked) { + $(".deleteAccess", page).hide(); + } else { + $(".deleteAccess", page).show(); + } + }); + ApiClient.getServerConfiguration().then(function (config) { + if (config.EnableRemoteAccess) { + page.querySelector(".fldRemoteAccess").classList.remove("hide"); + } else { + page.querySelector(".fldRemoteAccess").classList.add("hide"); + } + }); + }).on("pagebeforeshow", "#editUserPage", function () { + loadData(this); + }); }); diff --git a/src/controllers/userlibraryaccess.js b/src/controllers/userlibraryaccess.js index 8352e90c3e..38418f5190 100644 --- a/src/controllers/userlibraryaccess.js +++ b/src/controllers/userlibraryaccess.js @@ -1,112 +1,178 @@ -define(["jQuery", "loading", "libraryMenu", "fnchecked"], function($, loading, libraryMenu) { +define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, libraryMenu) { "use strict"; function triggerChange(select) { var evt = document.createEvent("HTMLEvents"); - evt.initEvent("change", !1, !0), select.dispatchEvent(evt) + evt.initEvent("change", false, true); + select.dispatchEvent(evt); } function loadMediaFolders(page, user, mediaFolders) { var html = ""; - html += '

' + Globalize.translate("HeaderLibraries") + "

", html += '
'; + html += '

' + Globalize.translate("HeaderLibraries") + "

"; + html += '
'; + for (var i = 0, length = mediaFolders.length; i < length; i++) { - var folder = mediaFolders[i], - isChecked = user.Policy.EnableAllFolders || -1 != user.Policy.EnabledFolders.indexOf(folder.Id), - checkedAttribute = isChecked ? ' checked="checked"' : ""; - html += '" + var folder = mediaFolders[i]; + var isChecked = user.Policy.EnableAllFolders || -1 != user.Policy.EnabledFolders.indexOf(folder.Id); + var checkedAttribute = isChecked ? ' checked="checked"' : ""; + html += '"; } - html += "
", page.querySelector(".folderAccess").innerHTML = html; + + html += "
"; + page.querySelector(".folderAccess").innerHTML = html; var chkEnableAllFolders = page.querySelector("#chkEnableAllFolders"); - chkEnableAllFolders.checked = user.Policy.EnableAllFolders, triggerChange(chkEnableAllFolders) + chkEnableAllFolders.checked = user.Policy.EnableAllFolders; + triggerChange(chkEnableAllFolders); } function loadChannels(page, user, channels) { var html = ""; - html += '

' + Globalize.translate("HeaderChannels") + "

", html += '
'; + html += '

' + Globalize.translate("HeaderChannels") + "

"; + html += '
'; + for (var i = 0, length = channels.length; i < length; i++) { - var folder = channels[i], - isChecked = user.Policy.EnableAllChannels || -1 != user.Policy.EnabledChannels.indexOf(folder.Id), - checkedAttribute = isChecked ? ' checked="checked"' : ""; - html += '" + var folder = channels[i]; + var isChecked = user.Policy.EnableAllChannels || -1 != user.Policy.EnabledChannels.indexOf(folder.Id); + var checkedAttribute = isChecked ? ' checked="checked"' : ""; + html += '"; } - html += "
", $(".channelAccess", page).show().html(html), channels.length ? $(".channelAccessContainer", page).show() : $(".channelAccessContainer", page).hide(), $("#chkEnableAllChannels", page).checked(user.Policy.EnableAllChannels).trigger("change") + + html += "
"; + $(".channelAccess", page).show().html(html); + + if (channels.length) { + $(".channelAccessContainer", page).show(); + } else { + $(".channelAccessContainer", page).hide(); + } + + $("#chkEnableAllChannels", page).checked(user.Policy.EnableAllChannels).trigger("change"); } function loadDevices(page, user, devices) { var html = ""; - html += '

' + Globalize.translate("HeaderDevices") + "

", html += '
'; + html += '

' + Globalize.translate("HeaderDevices") + "

"; + html += '
'; + for (var i = 0, length = devices.length; i < length; i++) { - var device = devices[i], - checkedAttribute = user.Policy.EnableAllDevices || -1 != user.Policy.EnabledDevices.indexOf(device.Id) ? ' checked="checked"' : ""; - html += '" + var device = devices[i]; + var checkedAttribute = user.Policy.EnableAllDevices || -1 != user.Policy.EnabledDevices.indexOf(device.Id) ? ' checked="checked"' : ""; + html += '"; + } + + html += "
"; + $(".deviceAccess", page).show().html(html); + $("#chkEnableAllDevices", page).checked(user.Policy.EnableAllDevices).trigger("change"); + + if (user.Policy.IsAdministrator) { + page.querySelector(".deviceAccessContainer").classList.add("hide"); + } else { + page.querySelector(".deviceAccessContainer").classList.remove("hide"); } - html += "
", $(".deviceAccess", page).show().html(html), $("#chkEnableAllDevices", page).checked(user.Policy.EnableAllDevices).trigger("change"), user.Policy.IsAdministrator ? page.querySelector(".deviceAccessContainer").classList.add("hide") : page.querySelector(".deviceAccessContainer").classList.remove("hide") } function loadUser(page, user, loggedInUser, mediaFolders, channels, devices) { - page.querySelector(".username").innerHTML = user.Name, libraryMenu.setTitle(user.Name), loadChannels(page, user, channels), loadMediaFolders(page, user, mediaFolders), loadDevices(page, user, devices), loading.hide() + page.querySelector(".username").innerHTML = user.Name; + libraryMenu.setTitle(user.Name); + loadChannels(page, user, channels); + loadMediaFolders(page, user, mediaFolders); + loadDevices(page, user, devices); + loading.hide(); } function onSaveComplete(page) { - loading.hide(), require(["toast"], function(toast) { - toast(Globalize.translate("SettingsSaved")) - }) + loading.hide(); + + require(["toast"], function (toast) { + toast(Globalize.translate("SettingsSaved")); + }); } function saveUser(user, page) { - user.Policy.EnableAllFolders = $("#chkEnableAllFolders", page).checked(), user.Policy.EnabledFolders = user.Policy.EnableAllFolders ? [] : $(".chkFolder", page).get().filter(function(c) { - return c.checked - }).map(function(c) { - return c.getAttribute("data-id") - }), user.Policy.EnableAllChannels = $("#chkEnableAllChannels", page).checked(), user.Policy.EnabledChannels = user.Policy.EnableAllChannels ? [] : $(".chkChannel", page).get().filter(function(c) { - return c.checked - }).map(function(c) { - return c.getAttribute("data-id") - }), user.Policy.EnableAllDevices = $("#chkEnableAllDevices", page).checked(), user.Policy.EnabledDevices = user.Policy.EnableAllDevices ? [] : $(".chkDevice", page).get().filter(function(c) { - return c.checked - }).map(function(c) { - return c.getAttribute("data-id") - }), user.Policy.BlockedChannels = null, user.Policy.BlockedMediaFolders = null, ApiClient.updateUserPolicy(user.Id, user.Policy).then(function() { - onSaveComplete(page) - }) + user.Policy.EnableAllFolders = $("#chkEnableAllFolders", page).checked(); + user.Policy.EnabledFolders = user.Policy.EnableAllFolders ? [] : $(".chkFolder", page).get().filter(function (c) { + return c.checked; + }).map(function (c) { + return c.getAttribute("data-id"); + }); + user.Policy.EnableAllChannels = $("#chkEnableAllChannels", page).checked(); + user.Policy.EnabledChannels = user.Policy.EnableAllChannels ? [] : $(".chkChannel", page).get().filter(function (c) { + return c.checked; + }).map(function (c) { + return c.getAttribute("data-id"); + }); + user.Policy.EnableAllDevices = $("#chkEnableAllDevices", page).checked(); + user.Policy.EnabledDevices = user.Policy.EnableAllDevices ? [] : $(".chkDevice", page).get().filter(function (c) { + return c.checked; + }).map(function (c) { + return c.getAttribute("data-id"); + }); + user.Policy.BlockedChannels = null; + user.Policy.BlockedMediaFolders = null; + ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { + onSaveComplete(page); + }); } function onSubmit() { var page = $(this).parents(".page"); loading.show(); var userId = getParameterByName("userId"); - return ApiClient.getUser(userId).then(function(result) { - saveUser(result, page) - }), !1 + ApiClient.getUser(userId).then(function (result) { + saveUser(result, page); + }); + return false; } - $(document).on("pageinit", "#userLibraryAccessPage", function() { + + $(document).on("pageinit", "#userLibraryAccessPage", function () { var page = this; - $("#chkEnableAllDevices", page).on("change", function() { - this.checked ? $(".deviceAccessListContainer", page).hide() : $(".deviceAccessListContainer", page).show() - }), $("#chkEnableAllChannels", page).on("change", function() { - this.checked ? $(".channelAccessListContainer", page).hide() : $(".channelAccessListContainer", page).show() - }), page.querySelector("#chkEnableAllFolders").addEventListener("change", function() { - this.checked ? page.querySelector(".folderAccessListContainer").classList.add("hide") : page.querySelector(".folderAccessListContainer").classList.remove("hide") - }), $(".userLibraryAccessForm").off("submit", onSubmit).on("submit", onSubmit) - }).on("pageshow", "#userLibraryAccessPage", function() { + $("#chkEnableAllDevices", page).on("change", function () { + if (this.checked) { + $(".deviceAccessListContainer", page).hide(); + } else { + $(".deviceAccessListContainer", page).show(); + } + }); + $("#chkEnableAllChannels", page).on("change", function () { + if (this.checked) { + $(".channelAccessListContainer", page).hide(); + } else { + $(".channelAccessListContainer", page).show(); + } + }); + page.querySelector("#chkEnableAllFolders").addEventListener("change", function () { + if (this.checked) { + page.querySelector(".folderAccessListContainer").classList.add("hide"); + } else { + page.querySelector(".folderAccessListContainer").classList.remove("hide"); + } + }); + $(".userLibraryAccessForm").off("submit", onSubmit).on("submit", onSubmit); + }).on("pageshow", "#userLibraryAccessPage", function () { var page = this; loading.show(); - var promise1, userId = getParameterByName("userId"); - if (userId) promise1 = ApiClient.getUser(userId); - else { + var promise1; + var userId = getParameterByName("userId"); + + if (userId) { + promise1 = ApiClient.getUser(userId); + } else { var deferred = $.Deferred(); deferred.resolveWith(null, [{ Configuration: {} - }]), promise1 = deferred.promise() + }]); + promise1 = deferred.promise(); } - var promise2 = Dashboard.getCurrentUser(), - promise4 = ApiClient.getJSON(ApiClient.getUrl("Library/MediaFolders", { - IsHidden: !1 - })), - promise5 = ApiClient.getJSON(ApiClient.getUrl("Channels")), - promise6 = ApiClient.getJSON(ApiClient.getUrl("Devices")); - Promise.all([promise1, promise2, promise4, promise5, promise6]).then(function(responses) { - loadUser(page, responses[0], responses[1], responses[2].Items, responses[3].Items, responses[4].Items) - }) - }) -}); \ No newline at end of file + + var promise2 = Dashboard.getCurrentUser(); + var promise4 = ApiClient.getJSON(ApiClient.getUrl("Library/MediaFolders", { + IsHidden: false + })); + var promise5 = ApiClient.getJSON(ApiClient.getUrl("Channels")); + var promise6 = ApiClient.getJSON(ApiClient.getUrl("Devices")); + Promise.all([promise1, promise2, promise4, promise5, promise6]).then(function (responses) { + loadUser(page, responses[0], responses[1], responses[2].Items, responses[3].Items, responses[4].Items); + }); + }); +}); diff --git a/src/controllers/usernew.js b/src/controllers/usernew.js index 10fa6fc4f3..ec80679f8c 100644 --- a/src/controllers/usernew.js +++ b/src/controllers/usernew.js @@ -1,14 +1,16 @@ -define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function($, loading) { +define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function ($, loading) { "use strict"; function loadMediaFolders(page, mediaFolders) { var html = ""; html += '

' + Globalize.translate("HeaderLibraries") + "

"; html += '
'; + for (var i = 0; i < mediaFolders.length; i++) { var folder = mediaFolders[i]; html += '"; } + html += "
"; $(".folderAccess", page).html(html).trigger("create"); $("#chkEnableAllFolders", page).checked(true).trigger("change"); @@ -18,17 +20,21 @@ define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function($, loading) var html = ""; html += '

' + Globalize.translate("HeaderChannels") + "

"; html += '
'; + for (var i = 0; i < channels.length; i++) { var folder = channels[i]; html += '"; } + html += "
"; $(".channelAccess", page).show().html(html).trigger("create"); + if (channels.length) { $(".channelAccessContainer", page).show(); } else { $(".channelAccessContainer", page).hide(); } + $("#chkEnableAllChannels", page).checked(true).trigger("change"); } @@ -37,46 +43,51 @@ define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function($, loading) $("#txtPassword", page).val(""); loading.show(); var promiseFolders = ApiClient.getJSON(ApiClient.getUrl("Library/MediaFolders", { - IsHidden: false + IsHidden: false })); var promiseChannels = ApiClient.getJSON(ApiClient.getUrl("Channels")); - Promise.all([promiseFolders, promiseChannels]).then(function(responses) { + Promise.all([promiseFolders, promiseChannels]).then(function (responses) { loadMediaFolders(page, responses[0].Items); loadChannels(page, responses[1].Items); loading.hide(); - }) + }); } function saveUser(page) { var user = {}; user.Name = $("#txtUsername", page).val(); user.Password = $("#txtPassword", page).val(); - ApiClient.createUser(user).then(function(user) { + ApiClient.createUser(user).then(function (user) { user.Policy.EnableAllFolders = $("#chkEnableAllFolders", page).checked(); user.Policy.EnabledFolders = []; + if (!user.Policy.EnableAllFolders) { - user.Policy.EnabledFolders = $(".chkFolder", page).get().filter(function(i) { - return i.checked - }).map(function(i) { + user.Policy.EnabledFolders = $(".chkFolder", page).get().filter(function (i) { + return i.checked; + }).map(function (i) { return i.getAttribute("data-id"); }); } + user.Policy.EnableAllChannels = $("#chkEnableAllChannels", page).checked(); user.Policy.EnabledChannels = []; + if (!user.Policy.EnableAllChannels) { - user.Policy.EnabledChannels = $(".chkChannel", page).get().filter(function(i) { - return i.checked - }).map(function(i) { + user.Policy.EnabledChannels = $(".chkChannel", page).get().filter(function (i) { + return i.checked; + }).map(function (i) { return i.getAttribute("data-id"); }); } - ApiClient.updateUserPolicy(user.Id, user.Policy).then(function() { + + ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { Dashboard.navigate("useredit.html?userId=" + user.Id); }); - }, function(response) { - require(["toast"], function(toast) { + }, function (response) { + require(["toast"], function (toast) { toast(Globalize.translate("DefaultErrorMessage")); }); + loading.hide(); }); } @@ -92,16 +103,16 @@ define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function($, loading) loadUser(page); } - $(document).on("pageinit", "#newUserPage", function() { + $(document).on("pageinit", "#newUserPage", function () { var page = this; - $("#chkEnableAllChannels", page).on("change", function() { + $("#chkEnableAllChannels", page).on("change", function () { if (this.checked) { $(".channelAccessListContainer", page).hide(); } else { $(".channelAccessListContainer", page).show(); } }); - $("#chkEnableAllFolders", page).on("change", function() { + $("#chkEnableAllFolders", page).on("change", function () { if (this.checked) { $(".folderAccessListContainer", page).hide(); } else { @@ -109,7 +120,7 @@ define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function($, loading) } }); $(".newUserProfileForm").off("submit", onSubmit).on("submit", onSubmit); - }).on("pageshow", "#newUserPage", function() { + }).on("pageshow", "#newUserPage", function () { loadData(this); }); -}); \ No newline at end of file +}); diff --git a/src/controllers/userparentalcontrol.js b/src/controllers/userparentalcontrol.js index 381dc8cea9..2a862912d5 100644 --- a/src/controllers/userparentalcontrol.js +++ b/src/controllers/userparentalcontrol.js @@ -1,185 +1,271 @@ -define(["jQuery", "datetime", "loading", "libraryMenu", "listViewStyle", "paper-icon-button-light"], function($, datetime, loading, libraryMenu) { +define(["jQuery", "datetime", "loading", "libraryMenu", "listViewStyle", "paper-icon-button-light"], function ($, datetime, loading, libraryMenu) { "use strict"; function populateRatings(allParentalRatings, page) { var html = ""; html += ""; - var i, length, rating, ratings = []; + var i; + var length; + var rating; + var ratings = []; + for (i = 0, length = allParentalRatings.length; i < length; i++) { if (rating = allParentalRatings[i], ratings.length) { var lastRating = ratings[ratings.length - 1]; + if (lastRating.Value === rating.Value) { lastRating.Name += "/" + rating.Name; - continue + continue; } } + ratings.push({ Name: rating.Name, Value: rating.Value - }) + }); } - for (i = 0, length = ratings.length; i < length; i++) rating = ratings[i], html += ""; - $("#selectMaxParentalRating", page).html(html) + + for (i = 0, length = ratings.length; i < length; i++) { + rating = ratings[i]; + html += ""; + } + + $("#selectMaxParentalRating", page).html(html); } function loadUnratedItems(page, user) { var items = [{ - name: Globalize.translate("OptionBlockBooks"), - value: "Book" - }, { - name: Globalize.translate("OptionBlockChannelContent"), - value: "ChannelContent" - }, { - name: Globalize.translate("OptionBlockLiveTvChannels"), - value: "LiveTvChannel" - }, { - name: Globalize.translate("OptionBlockMovies"), - value: "Movie" - }, { - name: Globalize.translate("OptionBlockMusic"), - value: "Music" - }, { - name: Globalize.translate("OptionBlockTrailers"), - value: "Trailer" - }, { - name: Globalize.translate("OptionBlockTvShows"), - value: "Series" - }], - html = ""; - html += '

' + Globalize.translate("HeaderBlockItemsWithNoRating") + "

", html += '
'; + name: Globalize.translate("OptionBlockBooks"), + value: "Book" + }, { + name: Globalize.translate("OptionBlockChannelContent"), + value: "ChannelContent" + }, { + name: Globalize.translate("OptionBlockLiveTvChannels"), + value: "LiveTvChannel" + }, { + name: Globalize.translate("OptionBlockMovies"), + value: "Movie" + }, { + name: Globalize.translate("OptionBlockMusic"), + value: "Music" + }, { + name: Globalize.translate("OptionBlockTrailers"), + value: "Trailer" + }, { + name: Globalize.translate("OptionBlockTvShows"), + value: "Series" + }]; + var html = ""; + html += '

' + Globalize.translate("HeaderBlockItemsWithNoRating") + "

"; + html += '
'; + for (var i = 0, length = items.length; i < length; i++) { - var item = items[i], - checkedAttribute = -1 != user.Policy.BlockUnratedItems.indexOf(item.value) ? ' checked="checked"' : ""; - html += '" + var item = items[i]; + var checkedAttribute = -1 != user.Policy.BlockUnratedItems.indexOf(item.value) ? ' checked="checked"' : ""; + html += '"; } - html += "
", $(".blockUnratedItems", page).html(html).trigger("create") + + html += "
"; + $(".blockUnratedItems", page).html(html).trigger("create"); } function loadUser(page, user, allParentalRatings) { - page.querySelector(".username").innerHTML = user.Name, libraryMenu.setTitle(user.Name), loadUnratedItems(page, user), loadBlockedTags(page, user.Policy.BlockedTags), populateRatings(allParentalRatings, page); + page.querySelector(".username").innerHTML = user.Name; + libraryMenu.setTitle(user.Name); + loadUnratedItems(page, user); + loadBlockedTags(page, user.Policy.BlockedTags); + populateRatings(allParentalRatings, page); var ratingValue = ""; - if (user.Policy.MaxParentalRating) + + if (user.Policy.MaxParentalRating) { for (var i = 0, length = allParentalRatings.length; i < length; i++) { var rating = allParentalRatings[i]; - user.Policy.MaxParentalRating >= rating.Value && (ratingValue = rating.Value) + + if (user.Policy.MaxParentalRating >= rating.Value) { + ratingValue = rating.Value; + } } - $("#selectMaxParentalRating", page).val(ratingValue), user.Policy.IsAdministrator ? $(".accessScheduleSection", page).hide() : $(".accessScheduleSection", page).show(), renderAccessSchedule(page, user.Policy.AccessSchedules || []), loading.hide() + } + + $("#selectMaxParentalRating", page).val(ratingValue); + + if (user.Policy.IsAdministrator) { + $(".accessScheduleSection", page).hide(); + } else { + $(".accessScheduleSection", page).show(); + } + + renderAccessSchedule(page, user.Policy.AccessSchedules || []); + loading.hide(); } function loadBlockedTags(page, tags) { - var html = tags.map(function(h) { + var html = tags.map(function (h) { var li = '
'; - return li += '
', li += '

', li += h, li += "

", li += "
", li += '', li += "
" + li += '
'; + li += '

'; + li += h; + li += "

"; + li += "
"; + li += ''; + return li += "
"; }).join(""); - html && (html = '
' + html + "
"); + + if (html) { + html = '
' + html + "
"; + } + var elem = $(".blockedTags", page).html(html).trigger("create"); - $(".btnDeleteTag", elem).on("click", function() { - var tag = this.getAttribute("data-tag"), - newTags = tags.filter(function(t) { - return t != tag - }); - loadBlockedTags(page, newTags) - }) + $(".btnDeleteTag", elem).on("click", function () { + var tag = this.getAttribute("data-tag"); + var newTags = tags.filter(function (t) { + return t != tag; + }); + loadBlockedTags(page, newTags); + }); } function deleteAccessSchedule(page, schedules, index) { - schedules.splice(index, 1), renderAccessSchedule(page, schedules) + schedules.splice(index, 1); + renderAccessSchedule(page, schedules); } function renderAccessSchedule(page, schedules) { - var html = "", - index = 0; - html += schedules.map(function(a) { + var html = ""; + var index = 0; + html += schedules.map(function (a) { var itemHtml = ""; - return itemHtml += '
', itemHtml += '
', itemHtml += '

', itemHtml += Globalize.translate("Option" + a.DayOfWeek), itemHtml += "

", itemHtml += '
' + getDisplayTime(a.StartHour) + " - " + getDisplayTime(a.EndHour) + "
", itemHtml += "
", itemHtml += '', itemHtml += "
", index++, itemHtml + itemHtml += '
'; + itemHtml += '
'; + itemHtml += '

'; + itemHtml += Globalize.translate("Option" + a.DayOfWeek); + itemHtml += "

"; + itemHtml += '
' + getDisplayTime(a.StartHour) + " - " + getDisplayTime(a.EndHour) + "
"; + itemHtml += "
"; + itemHtml += ''; + itemHtml += "
"; + index++; + return itemHtml; }).join(""); var accessScheduleList = page.querySelector(".accessScheduleList"); - accessScheduleList.innerHTML = html, $(".btnDelete", accessScheduleList).on("click", function() { - deleteAccessSchedule(page, schedules, parseInt(this.getAttribute("data-index"))) - }) + accessScheduleList.innerHTML = html; + $(".btnDelete", accessScheduleList).on("click", function () { + deleteAccessSchedule(page, schedules, parseInt(this.getAttribute("data-index"))); + }); } function onSaveComplete(page) { - loading.hide(), require(["toast"], function(toast) { - toast(Globalize.translate("SettingsSaved")) - }) + loading.hide(); + + require(["toast"], function (toast) { + toast(Globalize.translate("SettingsSaved")); + }); } function saveUser(user, page) { - user.Policy.MaxParentalRating = $("#selectMaxParentalRating", page).val() || null, user.Policy.BlockUnratedItems = $(".chkUnratedItem", page).get().filter(function(i) { - return i.checked - }).map(function(i) { - return i.getAttribute("data-itemtype") - }), user.Policy.AccessSchedules = getSchedulesFromPage(page), user.Policy.BlockedTags = getBlockedTagsFromPage(page), ApiClient.updateUserPolicy(user.Id, user.Policy).then(function() { - onSaveComplete(page) - }) + user.Policy.MaxParentalRating = $("#selectMaxParentalRating", page).val() || null; + user.Policy.BlockUnratedItems = $(".chkUnratedItem", page).get().filter(function (i) { + return i.checked; + }).map(function (i) { + return i.getAttribute("data-itemtype"); + }); + user.Policy.AccessSchedules = getSchedulesFromPage(page); + user.Policy.BlockedTags = getBlockedTagsFromPage(page); + ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { + onSaveComplete(page); + }); } function getDisplayTime(hours) { - var minutes = 0, - pct = hours % 1; - return pct && (minutes = parseInt(60 * pct)), datetime.getDisplayTime(new Date(2e3, 1, 1, hours, minutes, 0, 0)) + var minutes = 0; + var pct = hours % 1; + + if (pct) { + minutes = parseInt(60 * pct); + } + + return datetime.getDisplayTime(new Date(2000, 1, 1, hours, minutes, 0, 0)); } function showSchedulePopup(page, schedule, index) { - schedule = schedule || {}, require(["components/accessschedule/accessschedule"], function(accessschedule) { + schedule = schedule || {}; + + require(["components/accessschedule/accessschedule"], function (accessschedule) { accessschedule.show({ schedule: schedule - }).then(function(updatedSchedule) { - var schedules = getSchedulesFromPage(page); - 1 == index && (index = schedules.length), schedules[index] = updatedSchedule, renderAccessSchedule(page, schedules) - }) - }) + }).then(function (updatedSchedule) { + var schedules = getSchedulesFromPage(page); + + if (-1 == index) { + index = schedules.length; + } + + schedules[index] = updatedSchedule; + renderAccessSchedule(page, schedules); + }); + }); } function getSchedulesFromPage(page) { - return $(".liSchedule", page).map(function() { + return $(".liSchedule", page).map(function () { return { DayOfWeek: this.getAttribute("data-day"), StartHour: this.getAttribute("data-start"), EndHour: this.getAttribute("data-end") - } - }).get() + }; + }).get(); } function getBlockedTagsFromPage(page) { - return $(".blockedTag", page).map(function() { - return this.getAttribute("data-tag") - }).get() + return $(".blockedTag", page).map(function () { + return this.getAttribute("data-tag"); + }).get(); } function showBlockedTagPopup(page) { - require(["prompt"], function(prompt) { + require(["prompt"], function (prompt) { prompt({ label: Globalize.translate("LabelTag") - }).then(function(value) { - var tags = getBlockedTagsFromPage(page); - 1 == tags.indexOf(value) && (tags.push(value), loadBlockedTags(page, tags)) - }) - }) + }).then(function (value) { + var tags = getBlockedTagsFromPage(page); + + if (-1 == tags.indexOf(value)) { + tags.push(value); + loadBlockedTags(page, tags); + } + }); + }); } + window.UserParentalControlPage = { - onSubmit: function() { + onSubmit: function () { var page = $(this).parents(".page"); loading.show(); var userId = getParameterByName("userId"); - return ApiClient.getUser(userId).then(function(result) { - saveUser(result, page) - }), !1 + ApiClient.getUser(userId).then(function (result) { + saveUser(result, page); + }); + return false; } - }, $(document).on("pageinit", "#userParentalControlPage", function() { + }; + $(document).on("pageinit", "#userParentalControlPage", function () { var page = this; - $(".btnAddSchedule", page).on("click", function() { - showSchedulePopup(page, {}, -1) - }), $(".btnAddBlockedTag", page).on("click", function() { - showBlockedTagPopup(page) - }), $(".userParentalControlForm").off("submit", UserParentalControlPage.onSubmit).on("submit", UserParentalControlPage.onSubmit) - }).on("pageshow", "#userParentalControlPage", function() { + $(".btnAddSchedule", page).on("click", function () { + showSchedulePopup(page, {}, -1); + }); + $(".btnAddBlockedTag", page).on("click", function () { + showBlockedTagPopup(page); + }); + $(".userParentalControlForm").off("submit", UserParentalControlPage.onSubmit).on("submit", UserParentalControlPage.onSubmit); + }).on("pageshow", "#userParentalControlPage", function () { var page = this; loading.show(); - var userId = getParameterByName("userId"), - promise1 = ApiClient.getUser(userId), - promise2 = ApiClient.getParentalRatings(); - Promise.all([promise1, promise2]).then(function(responses) { - loadUser(page, responses[0], responses[1]) - }) - }) + var userId = getParameterByName("userId"); + var promise1 = ApiClient.getUser(userId); + var promise2 = ApiClient.getParentalRatings(); + Promise.all([promise1, promise2]).then(function (responses) { + loadUser(page, responses[0], responses[1]); + }); + }); }); diff --git a/src/controllers/userpasswordpage.js b/src/controllers/userpasswordpage.js index d1eef004f6..30ca063278 100644 --- a/src/controllers/userpasswordpage.js +++ b/src/controllers/userpasswordpage.js @@ -1,101 +1,183 @@ -define(["loading", "libraryMenu", "emby-button"], function(loading, libraryMenu) { +define(["loading", "libraryMenu", "emby-button"], function (loading, libraryMenu) { "use strict"; function loadUser(page, params) { var userid = params.userId; - ApiClient.getUser(userid).then(function(user) { - Dashboard.getCurrentUser().then(function(loggedInUser) { - libraryMenu.setTitle(user.Name), page.querySelector(".username").innerHTML = user.Name; - var showPasswordSection = !0, - showLocalAccessSection = !1; - "Guest" == user.ConnectLinkType ? (page.querySelector(".localAccessSection").classList.add("hide"), showPasswordSection = !1) : user.HasConfiguredPassword ? (page.querySelector("#btnResetPassword").classList.remove("hide"), page.querySelector("#fldCurrentPassword").classList.remove("hide"), showLocalAccessSection = !0) : (page.querySelector("#btnResetPassword").classList.add("hide"), page.querySelector("#fldCurrentPassword").classList.add("hide")), showPasswordSection && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess) ? page.querySelector(".passwordSection").classList.remove("hide") : page.querySelector(".passwordSection").classList.add("hide"), showLocalAccessSection && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess) ? page.querySelector(".localAccessSection").classList.remove("hide") : page.querySelector(".localAccessSection").classList.add("hide"); + ApiClient.getUser(userid).then(function (user) { + Dashboard.getCurrentUser().then(function (loggedInUser) { + libraryMenu.setTitle(user.Name); + page.querySelector(".username").innerHTML = user.Name; + var showPasswordSection = true; + var showLocalAccessSection = false; + + if ("Guest" == user.ConnectLinkType) { + page.querySelector(".localAccessSection").classList.add("hide"); + showPasswordSection = false; + } else if (user.HasConfiguredPassword) { + page.querySelector("#btnResetPassword").classList.remove("hide"); + page.querySelector("#fldCurrentPassword").classList.remove("hide"); + showLocalAccessSection = true; + } else { + page.querySelector("#btnResetPassword").classList.add("hide"); + page.querySelector("#fldCurrentPassword").classList.add("hide"); + } + + if (showPasswordSection && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess)) { + page.querySelector(".passwordSection").classList.remove("hide"); + } else { + page.querySelector(".passwordSection").classList.add("hide"); + } + + if (showLocalAccessSection && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess)) { + page.querySelector(".localAccessSection").classList.remove("hide"); + } else { + page.querySelector(".localAccessSection").classList.add("hide"); + } + var txtEasyPassword = page.querySelector("#txtEasyPassword"); - txtEasyPassword.value = "", user.HasConfiguredEasyPassword ? (txtEasyPassword.placeholder = "******", page.querySelector("#btnResetEasyPassword").classList.remove("hide")) : (txtEasyPassword.removeAttribute("placeholder"), txtEasyPassword.placeholder = "", page.querySelector("#btnResetEasyPassword").classList.add("hide")), page.querySelector(".chkEnableLocalEasyPassword").checked = user.Configuration.EnableLocalPassword - }) - }), page.querySelector("#txtCurrentPassword").value = "", page.querySelector("#txtNewPassword").value = "", page.querySelector("#txtNewPasswordConfirm").value = "" + txtEasyPassword.value = ""; + + if (user.HasConfiguredEasyPassword) { + txtEasyPassword.placeholder = "******"; + page.querySelector("#btnResetEasyPassword").classList.remove("hide"); + } else { + txtEasyPassword.removeAttribute("placeholder"); + txtEasyPassword.placeholder = ""; + page.querySelector("#btnResetEasyPassword").classList.add("hide"); + } + + page.querySelector(".chkEnableLocalEasyPassword").checked = user.Configuration.EnableLocalPassword; + }); + }); + page.querySelector("#txtCurrentPassword").value = ""; + page.querySelector("#txtNewPassword").value = ""; + page.querySelector("#txtNewPasswordConfirm").value = ""; } - return function(view, params) { + + return function (view, params) { function saveEasyPassword() { - var userId = params.userId, - easyPassword = view.querySelector("#txtEasyPassword").value; - easyPassword ? ApiClient.updateEasyPassword(userId, easyPassword).then(function() { - onEasyPasswordSaved(userId) - }) : onEasyPasswordSaved(userId) + var userId = params.userId; + var easyPassword = view.querySelector("#txtEasyPassword").value; + + if (easyPassword) { + ApiClient.updateEasyPassword(userId, easyPassword).then(function () { + onEasyPasswordSaved(userId); + }); + } else { + onEasyPasswordSaved(userId); + } } function onEasyPasswordSaved(userId) { - ApiClient.getUser(userId).then(function(user) { - user.Configuration.EnableLocalPassword = view.querySelector(".chkEnableLocalEasyPassword").checked, ApiClient.updateUserConfiguration(user.Id, user.Configuration).then(function() { - loading.hide(), require(["toast"], function(toast) { - toast(Globalize.translate("MessageSettingsSaved")) - }), loadUser(view, params) - }) - }) + ApiClient.getUser(userId).then(function (user) { + user.Configuration.EnableLocalPassword = view.querySelector(".chkEnableLocalEasyPassword").checked; + ApiClient.updateUserConfiguration(user.Id, user.Configuration).then(function () { + loading.hide(); + + require(["toast"], function (toast) { + toast(Globalize.translate("MessageSettingsSaved")); + }); + + loadUser(view, params); + }); + }); } function savePassword() { - var userId = params.userId, - currentPassword = view.querySelector("#txtCurrentPassword").value, - newPassword = view.querySelector("#txtNewPassword").value; + var userId = params.userId; + var currentPassword = view.querySelector("#txtCurrentPassword").value; + var newPassword = view.querySelector("#txtNewPassword").value; + if (view.querySelector("#fldCurrentPassword").classList.contains("hide")) { // Firefox does not respect autocomplete=off, so clear it if the field is supposed to be hidden (and blank) // This should only happen when user.HasConfiguredPassword is false, but this information is not passed on currentPassword = ""; } - ApiClient.updateUserPassword(userId, currentPassword, newPassword).then(function() { - loading.hide(), require(["toast"], function(toast) { - toast(Globalize.translate("PasswordSaved")) - }), loadUser(view, params) - }, function() { - loading.hide(), Dashboard.alert({ + + ApiClient.updateUserPassword(userId, currentPassword, newPassword).then(function () { + loading.hide(); + + require(["toast"], function (toast) { + toast(Globalize.translate("PasswordSaved")); + }); + + loadUser(view, params); + }, function () { + loading.hide(); + Dashboard.alert({ title: Globalize.translate("HeaderLoginFailure"), message: Globalize.translate("MessageInvalidUser") - }) - }) + }); + }); } function onSubmit(e) { var form = this; - return form.querySelector("#txtNewPassword").value != form.querySelector("#txtNewPasswordConfirm").value ? require(["toast"], function(toast) { - toast(Globalize.translate("PasswordMatchError")) - }) : (loading.show(), savePassword()), e.preventDefault(), !1 + + if (form.querySelector("#txtNewPassword").value != form.querySelector("#txtNewPasswordConfirm").value) { + require(["toast"], function (toast) { + toast(Globalize.translate("PasswordMatchError")); + }); + } else { + loading.show(); + savePassword(); + } + + e.preventDefault(); + return false; } function onLocalAccessSubmit(e) { - return loading.show(), saveEasyPassword(), e.preventDefault(), !1 + loading.show(); + saveEasyPassword(); + e.preventDefault(); + return false; } function resetPassword() { var msg = Globalize.translate("PasswordResetConfirmation"); - require(["confirm"], function(confirm) { - confirm(msg, Globalize.translate("PasswordResetHeader")).then(function() { + + require(["confirm"], function (confirm) { + confirm(msg, Globalize.translate("PasswordResetHeader")).then(function () { var userId = params.userId; - loading.show(), ApiClient.resetUserPassword(userId).then(function() { - loading.hide(), Dashboard.alert({ + loading.show(); + ApiClient.resetUserPassword(userId).then(function () { + loading.hide(); + Dashboard.alert({ message: Globalize.translate("PasswordResetComplete"), title: Globalize.translate("PasswordResetHeader") - }), loadUser(view, params) - }) - }) - }) + }); + loadUser(view, params); + }); + }); + }); } function resetEasyPassword() { var msg = Globalize.translate("PinCodeResetConfirmation"); - require(["confirm"], function(confirm) { - confirm(msg, Globalize.translate("HeaderPinCodeReset")).then(function() { + + require(["confirm"], function (confirm) { + confirm(msg, Globalize.translate("HeaderPinCodeReset")).then(function () { var userId = params.userId; - loading.show(), ApiClient.resetEasyPassword(userId).then(function() { - loading.hide(), Dashboard.alert({ + loading.show(); + ApiClient.resetEasyPassword(userId).then(function () { + loading.hide(); + Dashboard.alert({ message: Globalize.translate("PinCodeResetComplete"), title: Globalize.translate("HeaderPinCodeReset") - }), loadUser(view, params) - }) - }) - }) + }); + loadUser(view, params); + }); + }); + }); } - view.querySelector(".updatePasswordForm").addEventListener("submit", onSubmit), view.querySelector(".localAccessForm").addEventListener("submit", onLocalAccessSubmit), view.querySelector("#btnResetEasyPassword").addEventListener("click", resetEasyPassword), view.querySelector("#btnResetPassword").addEventListener("click", resetPassword), view.addEventListener("viewshow", function() { - loadUser(view, params) - }) - } + + view.querySelector(".updatePasswordForm").addEventListener("submit", onSubmit); + view.querySelector(".localAccessForm").addEventListener("submit", onLocalAccessSubmit); + view.querySelector("#btnResetEasyPassword").addEventListener("click", resetEasyPassword); + view.querySelector("#btnResetPassword").addEventListener("click", resetPassword); + view.addEventListener("viewshow", function () { + loadUser(view, params); + }); + }; }); diff --git a/src/controllers/wizardfinishpage.js b/src/controllers/wizardfinishpage.js index 180af64b58..8242a16cb4 100644 --- a/src/controllers/wizardfinishpage.js +++ b/src/controllers/wizardfinishpage.js @@ -6,7 +6,7 @@ define(["loading"], function (loading) { ApiClient.ajax({ url: ApiClient.getUrl("Startup/Complete"), type: "POST" - }).then(function() { + }).then(function () { loading.hide(); window.location.href = "index.html"; }); From af2b49ac303d36de2c107a0eeb98968679609cce Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Wed, 6 Nov 2019 19:25:24 +0300 Subject: [PATCH 05/42] change directory for almada and requrie,js --- src/scripts/apploader.js | 2 +- webpack.common.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scripts/apploader.js b/src/scripts/apploader.js index 2328f88968..4b5d2e8eec 100644 --- a/src/scripts/apploader.js +++ b/src/scripts/apploader.js @@ -20,7 +20,7 @@ } injectScriptElement( - self.Promise ? "./bower_components/alameda.js" : "./bower_components/require.js", + self.Promise ? "./libraries/alameda.js" : "./libraries/require.js", function() { // onload of require library injectScriptElement("./scripts/site.js"); diff --git a/webpack.common.js b/webpack.common.js index 6e82da181e..75d8d311db 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -23,7 +23,7 @@ module.exports = { Assets.map(asset => { return { from: path.resolve(__dirname, `./node_modules/${asset}`), - to: path.resolve(__dirname, './dist/bower_components') + to: path.resolve(__dirname, './dist/libraries') }; }) ) From 863eb067c22b45a1416800d3dc2667d896dbf12a Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Thu, 7 Nov 2019 03:02:32 +0300 Subject: [PATCH 06/42] move assets to webpack.common.js --- assets.js | 6 ------ webpack.common.js | 7 ++++--- 2 files changed, 4 insertions(+), 9 deletions(-) delete mode 100644 assets.js diff --git a/assets.js b/assets.js deleted file mode 100644 index 98ec18c227..0000000000 --- a/assets.js +++ /dev/null @@ -1,6 +0,0 @@ -const JS = [ - 'alameda/alameda.js', - 'requirejs/require.js' -]; - -module.exports = [...JS]; diff --git a/webpack.common.js b/webpack.common.js index 75d8d311db..f0d03bc4cd 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -1,9 +1,10 @@ const path = require("path"); const { CleanWebpackPlugin} = require("clean-webpack-plugin"); const CopyPlugin = require("copy-webpack-plugin"); - -// assets.js -const Assets = require('./assets'); +const Assets = [ + "alameda/alameda.js", + "requirejs/require.js" +]; module.exports = { context: path.resolve(__dirname, "src"), From 321da7ae3ede9bdbc60fc86be39366388860a20d Mon Sep 17 00:00:00 2001 From: DJSweder Date: Fri, 8 Nov 2019 08:20:51 +0000 Subject: [PATCH 07/42] Translated using Weblate (Czech) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/cs/ --- src/strings/cs.json | 88 ++++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 33 deletions(-) diff --git a/src/strings/cs.json b/src/strings/cs.json index 3d03fc9455..5d53076d31 100644 --- a/src/strings/cs.json +++ b/src/strings/cs.json @@ -13,7 +13,7 @@ "AllChannels": "Všechny kanály", "AllEpisodes": "Všechny epizody", "AllLanguages": "Všechny jazyky", - "AllowHWTranscodingHelp": "Pokud nastavíte, povolíte tuneru překódování v reálném čase. Může snížit zátěž překódovávání požadované Jellyfin serverem.", + "AllowHWTranscodingHelp": "Povolit tuneru překódování v reálném čase. Může snížit zátěž překódovávání požadované Jellyfin serverem.", "AlwaysPlaySubtitles": "Vždy zobrazit titulky", "AlwaysPlaySubtitlesHelp": "Titulky odpovídající jazykové předvolbě se načtou bez ohledu na jazyk audia.", "Anytime": "Kdykoliv", @@ -30,7 +30,7 @@ "BirthDateValue": "Narozen: {0}", "BirthLocation": "Místo narození", "BirthPlaceValue": "Místo narození: {0}", - "BookLibraryHelp": "Audio a textové knihy jsou podporovány. Přečtěte si {0}pravidla pro názvy knih v Jellyfin{1}.", + "BookLibraryHelp": "Audio a textové knihy jsou podporovány. Přečtěte si {0}pravidla pro názvy knih {1}.", "Books": "Knihy", "Box": "Pouzdro", "BoxRear": "Zadní část pouzdra", @@ -157,7 +157,7 @@ "Dislike": "Nemám rád", "Display": "Zobrazení", "DisplayMissingEpisodesWithinSeasons": "Zobrazit chybějící epizody", - "DisplayMissingEpisodesWithinSeasonsHelp": "Toto musí být zapnuto pro knihovny TV v nastavení Jellyfin serveru.", + "DisplayMissingEpisodesWithinSeasonsHelp": "Toto musí být zapnuto pro knihovny TV v nastavení serveru.", "DisplayModeHelp": "Zvolte typ obrazovky, na které používáte Jellyfin.", "DoNotRecord": "Nenahrávat", "Down": "Dolů", @@ -522,7 +522,7 @@ "LabelEnableDlnaClientDiscoveryInterval": "Čas pro vyhledání klienta (sekund)", "LabelEnableDlnaClientDiscoveryIntervalHelp": "Určuje dobu trvání v sekundách mezi SSDP vyhledávání prováděných pomocí Jellyfin.", "LabelEnableDlnaDebugLogging": "Povolit DLNA protokolování (pro ladění)", - "LabelEnableDlnaDebugLoggingHelp": "Toto nastavení vytváří velmi velké soubory se záznamy a doporučuje se pouze v případě problémů.", + "LabelEnableDlnaDebugLoggingHelp": "Vytváří velké soubory se záznamy a doporučuje se používat pouze pro potřeby odstraňování problémů.", "LabelEnableDlnaPlayTo": "Povolit DLNA přehrávání", "LabelEnableDlnaPlayToHelp": "Jellyfin dokáže detekovat zařízení v rámci vaší sítě a nabízí možnost jeho dálkového ovládání.", "LabelEnableDlnaServer": "Povolit Dlna Server", @@ -611,9 +611,9 @@ "LabelMethod": "Metoda:", "LabelMinBackdropDownloadWidth": "Maximální šířka pro stažení pozadí:", "LabelMinResumeDuration": "Minimální doba trvání:", - "LabelMinResumeDurationHelp": "Videa kratší než tato délka nebudou pozastavitelné", + "LabelMinResumeDurationHelp": "Videa kratší než tato délka nebudou pozastavitelné.", "LabelMinResumePercentage": "Minimální procento pro přerušení:", - "LabelMinResumePercentageHelp": "Tituly budou označeny jako \"nepřehráno\", pokud budou zastaveny před tímto časem", + "LabelMinResumePercentageHelp": "Tituly budou označeny jako \"nepřehráno\", pokud budou zastaveny před tímto časem.", "LabelMinScreenshotDownloadWidth": "Minimální šířka screenshotu obrazovky:", "LabelModelDescription": "Popis modelu", "LabelModelName": "Název modelu", @@ -1027,7 +1027,7 @@ "PlaybackErrorNotAllowed": "V současné době nejste oprávněni přehrávat tento obsah. Pro více informací se obraťte se na správce systému.", "PlaybackErrorPlaceHolder": "Chcete-li toto video přehrát, vložte disk.", "Played": "Přehráno", - "Playlists": "Playlisty", + "Playlists": "Seznamy skladeb", "PleaseAddAtLeastOneFolder": "Přidejte prosím nejméně jednu složku do této knihovny pomocí tlačítka Přidat.", "PleaseConfirmPluginInstallation": "Pro potvrzení, že jste si přečetli text výše a chcete pokračovat v instalaci zásuvných modulů, klikněte na tlačítko OK.", "PleaseEnterNameOrId": "Prosím, zadejte název nebo externí Id.", @@ -1230,7 +1230,7 @@ "AllowMediaConversion": "Povolit konverzi médií", "AllowMediaConversionHelp": "Povolit nebo zakázat přístup k funkci konverze médií.", "AllowOnTheFlySubtitleExtraction": "Povolit extrahování titulků za běhu", - "AllowOnTheFlySubtitleExtractionHelp": "Vložené titulky mohou být extrahovány z videa a dodávány do aplikace Jellyfin ve formě prostého textu, aby se zabránilo překódování videa. V některých systémech to může trvat dlouho a způsobit zasekávání přehrávání videa. Při vypnutí funkce budou během překódování obsažené titulky vypáleny do obrazu, pokud je klientské zařízení nativně nepodporuje.", + "AllowOnTheFlySubtitleExtractionHelp": "Vložené titulky mohou být extrahovány z videa a dodávány do aplikací ve formě prostého textu, aby se zabránilo překódování videa. V některých systémech to může trvat dlouho a způsobit zasekávání přehrávání videa. Při vypnutí funkce budou během překódování obsažené titulky vypáleny do obrazu, pokud je klientské zařízení nativně nepodporuje.", "AllowRemoteAccess": "Povolit vzdálené připojení na server Jellyfin.", "AllowRemoteAccessHelp": "Pokud není zapnuto, všechna vzdálená připojení budou blokována.", "AllowSeasonalThemesHelp": "Pokud je povoleno, sezónní motivy občas přepíšou nastavení vašeho motivu.", @@ -1249,7 +1249,7 @@ "Blacklist": "Blacklist", "BobAndWeaveWithHelp": "Bob and weave (vyšší kvalita, ale pomalejší)", "Browse": "Procházet", - "BurnSubtitlesHelp": "Určuje, zda má server vypalovat titulky při převodu videa v závislosti na formátu titulků. Vynechání vypalování titulků zlepší výkon serveru. Chcete-li vypálit grafické formáty (např. VOBSUB, PGS, SUB / IDX atd.), stejně jako některé titulky ASS / SSA, vyberte možnost Auto", + "BurnSubtitlesHelp": "Určuje, zda má server vypalovat titulky při převodu videa v závislosti na formátu titulků. Vynechání vypalování titulků zlepší výkon serveru. Chcete-li vypálit grafické formáty (VOBSUB, PGS, SUB / IDX atd.) a některé titulky ASS / SSA, vyberte možnost Auto.", "ButtonInfo": "Info", "ButtonMenu": "Menu", "ButtonOk": "Ok", @@ -1304,7 +1304,7 @@ "HandledByProxy": "Zpracováno reverzním proxy", "HeaderAddLocalUser": "Přidat místního uživatele", "HeaderAllowMediaDeletionFrom": "Povolit smazání médií z", - "HeaderAppearsOn": "Appears On", + "HeaderAppearsOn": "Objeví se", "HeaderAudio": "Audio", "HeaderBlockItemsWithNoRating": "Blokovat položky s žádnými nebo nerozpoznanými informacemi o hodnocení:", "HeaderCameraUploadHelp": "Aplikace Jellyfin mohou automaticky nahrávat fotografie z mobilních zařízení do serveru Jellyfin.", @@ -1322,8 +1322,8 @@ "HeaderImageOptions": "Volby obrázku", "HeaderInviteWithJellyfinConnect": "Pozvat s Jellyfin Connect", "HeaderKodiMetadataHelp": "Chcete-li povolit nebo zakázat Nfo metadata, upravte nastavení knihovny v sekci ukládání metadat.", - "HeaderLiveTV": "Live TV", - "HeaderLiveTv": "Live TV", + "HeaderLiveTV": "Živá TV", + "HeaderLiveTv": "Živá TV", "HeaderLiveTvTunerSetup": "Nastavení tuneru Live TV", "HeaderMenu": "Menu", "HeaderNewDevices": "Nové zařízení", @@ -1350,7 +1350,7 @@ "LabelAlbum": "Album:", "LabelAllowedRemoteAddresses": "Filtr vzdálené IP adresy:", "LabelAllowedRemoteAddressesMode": "Režim filtru vzdálené IP adresy:", - "LabelAudioCodec": "Audio: {0}", + "LabelAudioCodec": "Audio kodek:", "LabelAutomaticallyRefreshInternetMetadataEvery": "Automaticky aktualizovat metadata z internetu:", "LabelBlockContentWithTags": "Blokovat položky s tagy:", "LabelBurnSubtitles": "Vypálit titulky:", @@ -1369,8 +1369,8 @@ "LabelEnableHardwareDecodingFor": "Povolit hardwarové dekódování pro:", "LabelHomeNetworkQuality": "Kvalita na domácí síti:", "LabelInternetQuality": "Kvalita na internetu:", - "LabelKodiMetadataUser": "Uložení dat sledování uživatele do nfo pro:", - "LabelKodiMetadataUserHelp": "Povolte toto nastavení pro uložení dat sledování do souborů NFO pro jiné aplikace, které chcete používat.", + "LabelKodiMetadataUser": "Uložit data sledování uživatele do NFO souboru pro:", + "LabelKodiMetadataUserHelp": "Uložit sledovaná data o přehrávání pro využití dalšími aplikacemi.", "LabelLanNetworks": "Sítě LAN:", "LabelLimit": "Limit:", "LabelMaxStreamingBitrate": "Maximální kvalita streamování:", @@ -1383,7 +1383,7 @@ "LabelSecureConnectionsMode": "Režim zabezpečeného připojení:", "LabelServerHost": "Host:", "LabelSimultaneousConnectionLimit": "Limit současně běžících streamů:", - "LabelSkin": "Skin:", + "LabelSkin": "Vzhled:", "LabelSortBy": "Řadit podle:", "LabelSortOrder": "Pořadí řazení:", "LabelSpecialSeasonsDisplayName": "Zobrazovaný název pro zvláštní sezónu:", @@ -1395,14 +1395,14 @@ "LabelTypeText": "Text", "LabelUrl": "URL:", "LabelUserAgent": "User agent:", - "LabelUserRemoteClientBitrateLimitHelp": "Toto přepíše výchozí globální hodnotu nastavenou v nastavení přehrávání serveru.", + "LabelUserRemoteClientBitrateLimitHelp": "Přepíše výchozí globální hodnotu nastavenou v nastavení přehrávání serveru.", "LabelVideo": "Video:", - "LabelVideoCodec": "Video: {0}", - "LeaveBlankToNotSetAPassword": "Volitelné - ponechat prázdné pro nastavení bez hesla", + "LabelVideoCodec": "Video kodek:", + "LeaveBlankToNotSetAPassword": "Můžete ponechat prázdné pro nastavení bez hesla.", "LetterButtonAbbreviation": "A", "LinkApi": "API", "LinksValue": "Odkazy: {0}", - "LiveTV": "Live TV", + "LiveTV": "Živá TV", "LiveTvFeatureDescription": "Streamujte televizní vysílání do libovolné aplikace Jellyfin s kompatibilním televizním tunerem instalovaným na serveru Jellyfin.", "Logo": "Logo", "ManageLibrary": "Spravovat knihovnu", @@ -1411,7 +1411,7 @@ "MediaInfoStreamTypeAudio": "Audio", "MediaInfoStreamTypeData": "Data", "MediaInfoStreamTypeVideo": "Video", - "AuthProviderHelp": "Vyberte poskytovatele ověřování, který bude použit k ověření hesla tohoto uživatele", + "AuthProviderHelp": "Vyberte poskytovatele ověřování, který bude použit k ověření hesla tohoto uživatele.", "HeaderFavoriteMovies": "Oblíbená videa", "HeaderFavoriteShows": "Oblíbené seriály", "HeaderFavoriteEpisodes": "Oblíbené epizody", @@ -1420,7 +1420,7 @@ "HeaderFavoriteSongs": "Oblíbená hudba", "HeaderRestartingServer": "Restartování serveru", "LabelAuthProvider": "Poskytovatel ověření:", - "LabelServerNameHelp": "Tento název bude použit k identifikaci tohoto serveru. Pokud zůstane prázdné, bude použit název počítače.", + "LabelServerNameHelp": "Tento název bude použit k identifikaci serveru a bude výchozí pro název počítače serveru.", "LabelPasswordResetProvider": "Poskytovatel obnovy hesla:", "LabelServerName": "Název serveru:", "LabelTranscodePath": "Cesta pro překódování:", @@ -1439,16 +1439,16 @@ "MessageNoCollectionsAvailable": "Kolekce vám umožní vychutnat si osobní seskupení filmů, seriálů a hudebních alb. Chcete-li je začít vytvářet, klikněte na tlačítko +.", "MessagePleaseWait": "Prosím, čekejte. Může to trvat několik minut.", "Metadata": "Metadata", - "MovieLibraryHelp": "Podívejte se na {0}průvodce pojmenováním filmů Jellyfin{1}.", + "MovieLibraryHelp": "Podívejte se na {0}průvodce pojmenováním filmů{1}.", "Never": "Nikdy", "NextUp": "Další", "NoNewDevicesFound": "Nebyla nalezena žádná nová zařízení. Chcete-li přidat nový tuner, zavřete tento dialog a zadejte informace o zařízení ručně.", - "OnlyImageFormats": "Pouze obrazové formáty (VOBSUB, PGS, SUB/IDX, atd.)", + "OnlyImageFormats": "Pouze obrazové formáty (VOBSUB, PGS, SUB, atd.)", "Option3D": "3D", "OptionAlbum": "Album", "OptionAllowMediaPlaybackTranscodingHelp": "Omezení přístupu k překódování může způsobit selhání přehrávání v aplikacích Jellyfin kvůli nepodporovaným formátům médií.", "OptionAllowSyncTranscoding": "Povolit stahování a synchronizaci médií, které vyžaduje překódování", - "OptionBluray": "Bluray", + "OptionBluray": "Blu-ray", "OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)", "OptionDownloadBannerImage": "Banner", "OptionDownloadBoxImage": "Box", @@ -1456,7 +1456,7 @@ "OptionIsHD": "HD", "OptionIsSD": "SD", "OptionLoginAttemptsBeforeLockout": "Určuje, kolik chybných pokusů o přihlášení lze provést před zablokováním.", - "OptionLoginAttemptsBeforeLockoutHelp": "0 znamená zdědění výchozí hodnoty 3 pro non-admin a 5 pro admin, -1 deaktivuje uzamykání", + "OptionLoginAttemptsBeforeLockoutHelp": "0 znamená zdědění výchozí hodnoty 3 pokusů pro běžné uživatele a 5 pro administrátory. Nastavení na -1 deaktivuje funkci.", "OptionMax": "Max", "OptionProfileAudio": "Audio", "OptionProfileVideo": "Video", @@ -1489,14 +1489,14 @@ "Sort": "Třídit", "StatsForNerds": "Statistiky pro šprty", "SubtitleAppearanceSettingsAlsoPassedToCastDevices": "Tato nastavení platí také pro jakékoli přehrávání na Chromecastu spuštěné tímto zařízením.", - "SubtitleAppearanceSettingsDisclaimer": "Tato nastavení se nevztahuje na grafické titulky (PGS, DVD atd.) nebo titulky, které mají vlastní vložené styly (ASS / SSA).", + "SubtitleAppearanceSettingsDisclaimer": "Tato nastavení se nevztahuje na grafické titulky (PGS, DVD atd.) nebo ASS/SSA titulky, které mají vlastní vložené styly.", "SubtitleDownloadersHelp": "Povolte a zařaďte preferované stahovače titulků v pořadí podle priority.", "SubtitleSettings": "Nastavení titulků", "SubtitleSettingsIntro": "Chcete-li nastavit výchozí vzhled a jazyk titulků, zastavte přehrávání videa a klepněte na ikonu uživatele v pravé horní části aplikace.", "TV": "TV", "TabDirectPlay": "Přímé přehrávání", "TabInfo": "Info", - "TabLiveTV": "Live TV", + "TabLiveTV": "Živá TV", "TabMetadata": "Metadata", "TabPlaylist": "Playlist", "TabServer": "Server", @@ -1504,10 +1504,10 @@ "ThemeSongs": "Tematická hudba", "ThemeVideos": "Tematická videa", "Trailers": "Trailery", - "TvLibraryHelp": "Podívejte se na {0}průvodce pojmenováním TV Jellyfin{1}.", + "TvLibraryHelp": "Podívejte se na {0}průvodce pojmenováním TV pořadů{1}.", "Uniform": "Uniformní", "Unplayed": "Nepřehrané", - "UserAgentHelp": "V případě potřeby zadejte vlastní hlavičku user agenta http.", + "UserAgentHelp": "Zadejte vlastní HTTP hlavičku user agenta.", "ValueMinutes": "{0} min", "ValueOneAlbum": "1 album", "ValueOneSong": "1 skladba", @@ -1518,8 +1518,8 @@ "HeaderHome": "Domů", "DashboardOperatingSystem": "Operační systém: {0}", "DashboardArchitecture": "Architektura: {0}", - "LaunchWebAppOnStartup": "Spusťte webovou aplikaci Jellyfin ve svém webovém prohlížeči po nastartování Jellyfin serveru", - "LaunchWebAppOnStartupHelp": "Toto otevře se webovou aplikaci ve vašem výchozím webovém prohlížeči, když se spustí server Jellyfin. K tomu nedochází při použití funkce restartování serveru.", + "LaunchWebAppOnStartup": "Spustit webové rozhraní po spustění serveru", + "LaunchWebAppOnStartupHelp": "Otevře se webový klient ve vašem výchozím webovém prohlížeči, když server se spustí. K tomu nedochází při použití funkce restartování serveru.", "MessageNoServersAvailable": "Pomocí automatického zjišťování nebyly nalezeny žádné servery.", "OptionBanner": "Banner", "OptionList": "Seznam", @@ -1532,5 +1532,27 @@ "MusicArtist": "Interpret", "MusicVideo": "Videoklip", "SubtitleOffset": "Nastavení titulků", - "TabNetworking": "Vytváření sítí" + "TabNetworking": "Vytváření sítí", + "MusicLibraryHelp": "Prostudujte si {0}průvodce pojmenováním hudby{1}.", + "MoreMediaInfo": "Informace o médiu", + "LabelVideoBitrate": "Datový tok videa:", + "LabelTranscodingProgress": "Průběh překódování:", + "LabelTranscodingFramerate": "Snimková frekvence pro překódování:", + "LabelSize": "Velikost:", + "LabelPleaseRestart": "Změny se projeví až po ručním obnovení webového klienta.", + "LabelPlayMethod": "Způsob přehrání:", + "LabelPlayer": "Přehrávač:", + "LabelFolder": "Složka:", + "LabelBaseUrlHelp": "Zde můžete přidat vlastní podsložku aby bylo možné přistupovat na server z unikátnější adresy.", + "LabelBaseUrl": "Výchozí URL:", + "LabelBitrate": "Datový tok:", + "LabelAudioSampleRate": "Vzorkovací frekvence zvuku:", + "LabelAudioChannels": "Počet kanálů zvuku:", + "LabelAudioBitrate": "Datový tok zvuku:", + "LabelAudioBitDepth": "Bitová hloubka zvuku:", + "HeaderFavoriteBooks": "Oblíbené knihy", + "FetchingData": "Načtení dalších dat", + "CopyStreamURLSuccess": "Úspěšně zkopírovaná URL.", + "CopyStreamURL": "Kopírovat URL adresu streamu", + "ButtonAddImage": "Přidat obrázek" } From 3896c18e2646f99d35d0c3c1eb468495ca168350 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Sat, 9 Nov 2019 11:48:52 +0300 Subject: [PATCH 08/42] Make navigation and playback control TV-friendly --- src/components/emby-slider/emby-slider.css | 4 + src/components/emby-slider/emby-slider.js | 118 +++++++++++++++++++++ src/controllers/videoosd.js | 19 ++++ src/videoosd.html | 2 +- 4 files changed, 142 insertions(+), 1 deletion(-) diff --git a/src/components/emby-slider/emby-slider.css b/src/components/emby-slider/emby-slider.css index bd258d3bc5..b173f5c511 100644 --- a/src/components/emby-slider/emby-slider.css +++ b/src/components/emby-slider/emby-slider.css @@ -87,6 +87,10 @@ _:-ms-input-placeholder { transform: scale(1.6); } +.mdl-slider.show-focus:focus::-webkit-slider-thumb { + transform: scale(1.6); +} + .slider-no-webkit-thumb::-webkit-slider-thumb { opacity: 0 !important; } diff --git a/src/components/emby-slider/emby-slider.js b/src/components/emby-slider/emby-slider.js index 1ca1448ea1..c1d58d59a3 100644 --- a/src/components/emby-slider/emby-slider.js +++ b/src/components/emby-slider/emby-slider.js @@ -19,6 +19,11 @@ define(['browser', 'dom', 'layoutManager', 'css!./emby-slider', 'registerElement function updateValues() { + // Do not update values when dragging with keyboard to keep current progress for reference + if (!!this.keyboardDragging) { + return; + } + var range = this; var value = range.value; @@ -82,6 +87,9 @@ define(['browser', 'dom', 'layoutManager', 'css!./emby-slider', 'registerElement if (!layoutManager.mobile) { this.classList.add('mdl-slider-hoverthumb'); } + if (layoutManager.tv) { + this.classList.add('show-focus'); + } var containerElement = this.parentNode; containerElement.classList.add('mdl-slider-container'); @@ -177,6 +185,116 @@ define(['browser', 'dom', 'layoutManager', 'css!./emby-slider', 'registerElement } }; + /** + * Keyboard dragging timeout. + * After this delay "change" event will be fired. + */ + var KeyboardDraggingTimeout = 1000; + + /** + * Keyboard dragging timer. + */ + var keyboardDraggingTimer; + + /** + * Start keyboard dragging. + * + * @param {Object} elem slider itself + */ + function startKeyboardDragging(elem) { + + elem.keyboardDragging = true; + + clearTimeout(keyboardDraggingTimer); + + keyboardDraggingTimer = setTimeout(function () { + finishKeyboardDragging(elem); + }, KeyboardDraggingTimeout); + } + + /** + * Finish keyboard dragging. + * + * @param {Object} elem slider itself + */ + function finishKeyboardDragging(elem) { + + clearTimeout(keyboardDraggingTimer); + keyboardDraggingTimer = undefined; + + elem.keyboardDragging = false; + + var event = new Event('change', { + bubbles: true, + cancelable: false + }); + elem.dispatchEvent(event); + } + + /** + * Do step by delta. + * + * @param {Object} elem slider itself + * @param {number} delta step amount + */ + function stepKeyboard(elem, delta) { + + startKeyboardDragging(elem); + + elem.value = Math.max(elem.min, Math.min(elem.max, parseFloat(elem.value) + delta)); + + var event = new Event('input', { + bubbles: true, + cancelable: false + }); + elem.dispatchEvent(event); + } + + /** + * Handle KeyDown event + */ + function onKeyDown(e) { + + switch (e.key) { + case 'ArrowLeft': + case 'Left': + stepKeyboard(this, -this.keyboardStepDown || -1); + e.preventDefault(); + e.stopPropagation(); + break; + + case 'ArrowRight': + case 'Right': + stepKeyboard(this, this.keyboardStepUp || 1); + e.preventDefault(); + e.stopPropagation(); + break; + } + } + + /** + * Enable keyboard dragging. + */ + EmbySliderPrototype.enableKeyboardDragging = function () { + + if (!this.keyboardDraggingEnabled) { + this.addEventListener('keydown', onKeyDown); + this.keyboardDraggingEnabled = true; + } + } + + /** + * Set steps for keyboard input. + * + * @param {number} stepDown step to reduce + * @param {number} stepUp step to increase + */ + EmbySliderPrototype.setKeyboardSteps = function (stepDown, stepUp) { + + this.keyboardStepDown = stepDown || stepUp || 1; + this.keyboardStepUp = stepUp || stepDown || 1; + } + function setRange(elem, startPercent, endPercent) { var style = elem.style; diff --git a/src/controllers/videoosd.js b/src/controllers/videoosd.js index b610886963..81e819e4e0 100644 --- a/src/controllers/videoosd.js +++ b/src/controllers/videoosd.js @@ -770,6 +770,10 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks; nowPlayingPositionSlider.setIsClear(isProgressClear); + if (nowPlayingItem.RunTimeTicks) { + nowPlayingPositionSlider.setKeyboardSteps(userSettings.skipBackLength() * 1000000 / nowPlayingItem.RunTimeTicks, userSettings.skipForwardLength() * 1000000 / nowPlayingItem.RunTimeTicks); + } + if (-1 === supportedCommands.indexOf("ToggleFullscreen") || player.isLocalPlayer && layoutManager.tv && playbackManager.isFullscreen(player)) { view.querySelector(".btnFullscreen").classList.add("hide"); } else { @@ -1070,12 +1074,21 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med } } + /** + * Keys used for keyboard navigation. + */ + var NavigationKeys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"]; + function onWindowKeyDown(e) { if (!currentVisibleMenu && 32 === e.keyCode) { playbackManager.playPause(currentPlayer); return void showOsd(); } + if (layoutManager.tv && NavigationKeys.indexOf(e.key) != -1) { + return void showOsd(); + } + switch (e.key) { case "k": playbackManager.playPause(currentPlayer); @@ -1237,6 +1250,12 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med var transitionEndEventName = dom.whichTransitionEvent(); var headerElement = document.querySelector(".skinHeader"); var osdBottomElement = document.querySelector(".videoOsdBottom-maincontrols"); + + if (layoutManager.tv) { + nowPlayingPositionSlider.classList.add("focusable"); + nowPlayingPositionSlider.enableKeyboardDragging(); + } + view.addEventListener("viewbeforeshow", function (e) { headerElement.classList.add("osdHeader"); Emby.Page.setTransparency("full"); diff --git a/src/videoosd.html b/src/videoosd.html index 0f4be75916..34c73a3019 100644 --- a/src/videoosd.html +++ b/src/videoosd.html @@ -31,7 +31,7 @@
-
+
From d260cf5390390c0ae16069a3b0fadab875b2966c Mon Sep 17 00:00:00 2001 From: Sander Lambrechts Date: Fri, 8 Nov 2019 22:23:56 +0000 Subject: [PATCH 09/42] Translated using Weblate (Dutch) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/ --- src/strings/nl.json | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/strings/nl.json b/src/strings/nl.json index 38f529af9d..6388edb647 100644 --- a/src/strings/nl.json +++ b/src/strings/nl.json @@ -18,11 +18,11 @@ "AllEpisodes": "Alle afleveringen", "AllLanguages": "Alle talen", "AllLibraries": "Alle bibliotheken", - "AllowHWTranscodingHelp": "Wanneer ingeschakeld zal de tuner streams direct transcoderen. Dit kan helpen de transcodering vereist door Jellyfin Server te verlagen.", + "AllowHWTranscodingHelp": "Direct transcoderen toestaan door de tuner. Dit kan helpen om de transcodering te verlagen die vereist is door de server.", "AllowMediaConversion": "Mediaconversie toestaan", "AllowMediaConversionHelp": "Toegang verlenen of weigeren tot de mediaconversie functie.", "AllowOnTheFlySubtitleExtraction": "Directe ondertitel extractie toestaan", - "AllowOnTheFlySubtitleExtractionHelp": "Ingebakken ondertitels kunnen uit de video's gehaald worden en als tekst bezorgd worden aan de Jellyfin apps om transcodering te helpen voorkomen. Op sommige systemen kan dit een lange tijd duren en dit er voor zorgen dat het afspelen van video stopt tijdens de extractie. Schakel dit uit om ingebakken ondertiteling in de video te laten branden met transcodering als deze niet standaard ondersteund worden door het afspeelapparaat.", + "AllowOnTheFlySubtitleExtractionHelp": "Ingebakken ondertitels kunnen uit de video's gehaald worden en als tekst bezorgd worden aan de clients om transcodering te helpen voorkomen. Op sommige systemen kan dit een lange tijd duren en dit er voor zorgen dat het afspelen van video stopt tijdens de extractie. Schakel dit uit om ingebakken ondertiteling in de video te laten branden met transcodering als deze niet standaard ondersteund worden door het afspeelapparaat.", "AllowRemoteAccess": "Externe verbindingen met deze Jellyfin Server toestaan.", "AllowRemoteAccessHelp": "Indien niet aangevinkt worden alle externe verbindingen geblokkeerd.", "AllowedRemoteAddressesHelp": "Komma-gescheiden lijst van IP-adressen of IP/netmask adressen voor netwerken die op afstand verbinding mogen maken. Indien blanco, worden alle externe adressen toegestaan.", @@ -44,7 +44,7 @@ "BirthDateValue": "Geboren: {0}", "BirthLocation": "Geboorte Locatie", "BirthPlaceValue": "Geboorte plaats: {0})", - "BookLibraryHelp": "Audio- en tekstboeken worden ondersteund. Bekijk de {0}Jellyfin Boeken naamgeving{1}.", + "BookLibraryHelp": "Audio- en tekstboeken worden ondersteund. Bekijk de {0}boeken naamgevingsgids{1}.", "Books": "Boeken", "BoxRear": "Hoes (achterkant)", "Browse": "Bladeren", @@ -722,7 +722,7 @@ "LabelSerialNumber": "Serienummer", "LabelSeriesRecordingPath": "Serieopname pad (optioneel):", "LabelServerHost": "Server:", - "LabelServerHostHelp": "192.168.1.100 of https://myserver.com", + "LabelServerHostHelp": "192.168.1.100:8096 of https://mijnserver.nl", "LabelSimultaneousConnectionLimit": "Gelijktijdige streams limiet:", "LabelSkipBackLength": "Terugspoellengte", "LabelSkipForwardLength": "Vooruitspoellengte", @@ -1293,7 +1293,7 @@ "HeaderSync": "Synchronisatie", "HeaderTV": "TV", "HeaderTopPlugins": "Top Plugins", - "AuthProviderHelp": "Selecteer een Authentication Provider om de gebruiker's wachtwoord te verifiëren ", + "AuthProviderHelp": "Selecteer een Authenticatie Provider om het wachtwoord van deze gebruiker te verifiëren", "HeaderFavoriteMovies": "Favoriete Films", "HeaderFavoriteShows": "Favoriete shows", "HeaderFavoriteEpisodes": "Favoriete afleveringen", @@ -1328,5 +1328,6 @@ "LabelProtocolInfo": "Protocol info:", "LabelServerName": "Server naam:", "LabelSkin": "Skin:", - "ButtonAddImage": "Voeg afbeelding toe" + "ButtonAddImage": "Voeg afbeelding toe", + "LabelSize": "Grootte:" } From 9c47f8fc1c5ec9a99fdb2742097c6ed1ffc57488 Mon Sep 17 00:00:00 2001 From: nextlooper42 Date: Fri, 8 Nov 2019 15:53:51 +0000 Subject: [PATCH 10/42] Translated using Weblate (Slovak) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sk/ --- src/strings/sk.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/strings/sk.json b/src/strings/sk.json index 7c0048db2f..14b75e053e 100644 --- a/src/strings/sk.json +++ b/src/strings/sk.json @@ -957,7 +957,7 @@ "HeaderSelectCertificatePath": "Vybrať cestu k certifikátu", "HeaderSortOrder": "Poradie zoradzovania", "HeaderSpecialEpisodeInfo": "Informácie o špeciálnej epizóde", - "HeaderSpecialFeatures": "Špeciálne funkcie", + "HeaderSpecialFeatures": "Bonusové materiály", "HeaderSubtitleDownloads": "Sťahovanie titulkov", "HeaderTags": "Tagy", "HeaderVideoType": "Typ videa", @@ -976,7 +976,7 @@ "OptionDownloadPrimaryImage": "Primárne", "OptionDvd": "DVD", "OptionExtractChapterImage": "Povoliť extrakciu obrázkov z videa", - "OptionHasSpecialFeatures": "Špeciálne funkcie", + "OptionHasSpecialFeatures": "Bonusové materiály", "OptionHasTrailer": "Ukážka/Trailer", "OptionIsHD": "HD", "OptionIsSD": "SD", From d11e93b0dafccc92d89143068337802a410059a9 Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 11 Nov 2019 01:39:06 +0900 Subject: [PATCH 11/42] redirect to select server if no credentials found --- src/bower_components/apiclient/connectionmanager.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bower_components/apiclient/connectionmanager.js b/src/bower_components/apiclient/connectionmanager.js index dcb8f28bc8..9ccb3aa087 100644 --- a/src/bower_components/apiclient/connectionmanager.js +++ b/src/bower_components/apiclient/connectionmanager.js @@ -659,6 +659,11 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory return result; }); } + + return Promise.resolve({ + Servers: servers, + State: "ServerSelection" + }); }; self.connectToServer = function (server, options) { From 105891b40932d717064c9b5f0eb866991b560513 Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 11 Nov 2019 01:45:01 +0900 Subject: [PATCH 12/42] move more dependencies to webpack --- package.json | 7 +- .../document-register-element/basic.html | 12 - .../build/document-register-element.js | 246 --- src/bower_components/fetch/fetch.js | 263 --- .../native-promise-only/lib/npo.src.js | 373 ---- .../native-promise-only/test_adapter.js | 21 - .../ResizeObserver.js | 939 ---------- .../webcomponentsjs/webcomponents-lite.min.js | 1571 ----------------- src/bundle.js | 20 + src/scripts/site.js | 17 +- webpack.common.js | 4 +- 11 files changed, 40 insertions(+), 3433 deletions(-) delete mode 100644 src/bower_components/document-register-element/basic.html delete mode 100644 src/bower_components/document-register-element/build/document-register-element.js delete mode 100644 src/bower_components/fetch/fetch.js delete mode 100644 src/bower_components/native-promise-only/lib/npo.src.js delete mode 100644 src/bower_components/native-promise-only/test_adapter.js delete mode 100644 src/bower_components/resize-observer-polyfill/ResizeObserver.js delete mode 100644 src/bower_components/webcomponentsjs/webcomponents-lite.min.js diff --git a/package.json b/package.json index 051102239b..8eea3ca247 100644 --- a/package.json +++ b/package.json @@ -18,16 +18,21 @@ }, "dependencies": { "alameda": "^1.3.0", + "document-register-element": "^0.5.4", "flv.js": "^1.5.0", "hls.js": "^0.12.4", "howler": "^2.1.2", "jquery": "^3.4.1", "jstree": "^3.3.7", "libjass": "^0.11.0", + "native-promise-only": "^0.8.0-a", "requirejs": "^2.3.5", + "resize-observer-polyfill": "^1.5.1", "shaka-player": "^2.5.5", "sortablejs": "^1.9.0", - "swiper": "^3.4.2" + "swiper": "^3.4.2", + "webcomponents.js-2": "^0.7.24", + "whatwg-fetch": "^1.1.1" }, "scripts": { "serve": "webpack-dev-server --config webpack.dev.js --open", diff --git a/src/bower_components/document-register-element/basic.html b/src/bower_components/document-register-element/basic.html deleted file mode 100644 index 713a029e4c..0000000000 --- a/src/bower_components/document-register-element/basic.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - testing my-element - - - - - - some content - - \ No newline at end of file diff --git a/src/bower_components/document-register-element/build/document-register-element.js b/src/bower_components/document-register-element/build/document-register-element.js deleted file mode 100644 index 57fe40a366..0000000000 --- a/src/bower_components/document-register-element/build/document-register-element.js +++ /dev/null @@ -1,246 +0,0 @@ -/*! (C) WebReflection Mit Style License */ -(function(e, t, n, r) { - "use strict"; - - function rt(e, t) { - for (var n = 0, r = e.length; n < r; n++) vt(e[n], t) - } - - function it(e) { - for (var t = 0, n = e.length, r; t < n; t++) r = e[t], nt(r, b[ot(r)]) - } - - function st(e) { - return function(t) { - j(t) && (vt(t, e), rt(t.querySelectorAll(w), e)) - } - } - - function ot(e) { - var t = e.getAttribute("is"), - n = e.nodeName.toUpperCase(), - r = S.call(y, t ? v + t.toUpperCase() : d + n); - return t && -1 < r && !ut(n, t) ? -1 : r - } - - function ut(e, t) { - return -1 < w.indexOf(e + '[is="' + t + '"]') - } - - function at(e) { - var t = e.currentTarget, - n = e.attrChange, - r = e.attrName, - i = e.target; - Q && (!i || i === t) && t.attributeChangedCallback && r !== "style" && e.prevValue !== e.newValue && t.attributeChangedCallback(r, n === e[a] ? null : e.prevValue, n === e[l] ? null : e.newValue) - } - - function ft(e) { - var t = st(e); - return function(e) { - X.push(t, e.target) - } - } - - function lt(e) { - K && (K = !1, e.currentTarget.removeEventListener(h, lt)), rt((e.target || t).querySelectorAll(w), e.detail === o ? o : s), B && pt() - } - - function ct(e, t) { - var n = this; - q.call(n, e, t), G.call(n, { - target: n - }) - } - - function ht(e, t) { - D(e, t), et ? et.observe(e, z) : (J && (e.setAttribute = ct, e[i] = Z(e), e.addEventListener(p, G)), e.addEventListener(c, at)), e.createdCallback && Q && (e.created = !0, e.createdCallback(), e.created = !1) - } - - function pt() { - for (var e, t = 0, n = F.length; t < n; t++) e = F[t], E.contains(e) || (n--, F.splice(t--, 1), vt(e, o)) - } - - function dt(e) { - throw new Error("A " + e + " type is already registered") - } - - function vt(e, t) { - var n, r = ot(e); - 1 < r && (tt(e, b[r]), r = 0, t === s && !e[s] ? (e[o] = !1, e[s] = !0, r = 1, B && S.call(F, e) < 0 && F.push(e)) : t === o && !e[o] && (e[s] = !1, e[o] = !0, r = 1), r && (n = e[t + "Callback"]) && n.call(e)) - } - if (r in t) return; - var i = "__" + r + (Math.random() * 1e5 >> 0), - s = "attached", - o = "detached", - u = "extends", - a = "ADDITION", - f = "MODIFICATION", - l = "REMOVAL", - c = "DOMAttrModified", - h = "DOMContentLoaded", - p = "DOMSubtreeModified", - d = "<", - v = "=", - m = /^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/, - g = ["ANNOTATION-XML", "COLOR-PROFILE", "FONT-FACE", "FONT-FACE-SRC", "FONT-FACE-URI", "FONT-FACE-FORMAT", "FONT-FACE-NAME", "MISSING-GLYPH"], - y = [], - b = [], - w = "", - E = t.documentElement, - S = y.indexOf || function(e) { - for (var t = this.length; t-- && this[t] !== e;); - return t - }, - x = n.prototype, - T = x.hasOwnProperty, - N = x.isPrototypeOf, - C = n.defineProperty, - k = n.getOwnPropertyDescriptor, - L = n.getOwnPropertyNames, - A = n.getPrototypeOf, - O = n.setPrototypeOf, - M = !!n.__proto__, - _ = n.create || function mt(e) { - return e ? (mt.prototype = e, new mt) : this - }, - D = O || (M ? function(e, t) { - return e.__proto__ = t, e - } : L && k ? function() { - function e(e, t) { - for (var n, r = L(t), i = 0, s = r.length; i < s; i++) n = r[i], T.call(e, n) || C(e, n, k(t, n)) - } - return function(t, n) { - do e(t, n); while ((n = A(n)) && !N.call(n, t)); - return t - } - }() : function(e, t) { - for (var n in t) e[n] = t[n]; - return e - }), - P = e.MutationObserver || e.WebKitMutationObserver, - H = (e.HTMLElement || e.Element || e.Node).prototype, - B = !N.call(H, E), - j = B ? function(e) { - return e.nodeType === 1 - } : function(e) { - return N.call(H, e) - }, - F = B && [], - I = H.cloneNode, - q = H.setAttribute, - R = H.removeAttribute, - U = t.createElement, - z = P && { - attributes: !0, - characterData: !0, - attributeOldValue: !0 - }, - W = P || function(e) { - J = !1, E.removeEventListener(c, W) - }, - X, V = e.requestAnimationFrame || e.webkitRequestAnimationFrame || e.mozRequestAnimationFrame || e.msRequestAnimationFrame || function(e) { - setTimeout(e, 10) - }, - $ = !1, - J = !0, - K = !0, - Q = !0, - G, Y, Z, et, tt, nt; - O || M ? (tt = function(e, t) { - N.call(t, e) || ht(e, t) - }, nt = ht) : (tt = function(e, t) { - e[i] || (e[i] = n(!0), ht(e, t)) - }, nt = tt), B ? (J = !1, function() { - var e = k(H, "addEventListener"), - t = e.value, - n = function(e) { - var t = new CustomEvent(c, { - bubbles: !0 - }); - t.attrName = e, t.prevValue = this.getAttribute(e), t.newValue = null, t[l] = t.attrChange = 2, R.call(this, e), this.dispatchEvent(t) - }, - r = function(e, t) { - var n = this.hasAttribute(e), - r = n && this.getAttribute(e), - i = new CustomEvent(c, { - bubbles: !0 - }); - q.call(this, e, t), i.attrName = e, i.prevValue = n ? r : null, i.newValue = t, n ? i[f] = i.attrChange = 1 : i[a] = i.attrChange = 0, this.dispatchEvent(i) - }, - s = function(e) { - var t = e.currentTarget, - n = t[i], - r = e.propertyName, - s; - n.hasOwnProperty(r) && (n = n[r], s = new CustomEvent(c, { - bubbles: !0 - }), s.attrName = n.name, s.prevValue = n.value || null, s.newValue = n.value = t[r] || null, s.prevValue == null ? s[a] = s.attrChange = 0 : s[f] = s.attrChange = 1, t.dispatchEvent(s)) - }; - e.value = function(e, o, u) { - e === c && this.attributeChangedCallback && this.setAttribute !== r && (this[i] = { - className: { - name: "class", - value: this.className - } - }, this.setAttribute = r, this.removeAttribute = n, t.call(this, "propertychange", s)), t.call(this, e, o, u) - }, C(H, "addEventListener", e) - }()) : P || (E.addEventListener(c, W), E.setAttribute(i, 1), E.removeAttribute(i), J && (G = function(e) { - var t = this, - n, r, s; - if (t === e.target) { - n = t[i], t[i] = r = Z(t); - for (s in r) { - if (!(s in n)) return Y(0, t, s, n[s], r[s], a); - if (r[s] !== n[s]) return Y(1, t, s, n[s], r[s], f) - } - for (s in n) - if (!(s in r)) return Y(2, t, s, n[s], r[s], l) - } - }, Y = function(e, t, n, r, i, s) { - var o = { - attrChange: e, - currentTarget: t, - attrName: n, - prevValue: r, - newValue: i - }; - o[s] = e, at(o) - }, Z = function(e) { - for (var t, n, r = {}, i = e.attributes, s = 0, o = i.length; s < o; s++) t = i[s], n = t.name, n !== "setAttribute" && (r[n] = t.value); - return r - })), t[r] = function(n, r) { - c = n.toUpperCase(), $ || ($ = !0, P ? (et = function(e, t) { - function n(e, t) { - for (var n = 0, r = e.length; n < r; t(e[n++])); - } - return new P(function(r) { - for (var i, s, o, u = 0, a = r.length; u < a; u++) i = r[u], i.type === "childList" ? (n(i.addedNodes, e), n(i.removedNodes, t)) : (s = i.target, Q && s.attributeChangedCallback && i.attributeName !== "style" && (o = s.getAttribute(i.attributeName), o !== i.oldValue && s.attributeChangedCallback(i.attributeName, i.oldValue, o))) - }) - }(st(s), st(o)), et.observe(t, { - childList: !0, - subtree: !0 - })) : (X = [], V(function E() { - while (X.length) X.shift().call(null, X.shift()); - V(E) - }), t.addEventListener("DOMNodeInserted", ft(s)), t.addEventListener("DOMNodeRemoved", ft(o))), t.addEventListener(h, lt), t.addEventListener("readystatechange", lt), t.createElement = function(e, n) { - var r = U.apply(t, arguments), - i = "" + e, - s = S.call(y, (n ? v : d) + (n || i).toUpperCase()), - o = -1 < s; - return n && (r.setAttribute("is", n = n.toLowerCase()), o && (o = ut(i.toUpperCase(), n))), Q = !t.createElement.innerHTMLHelper, o && nt(r, b[s]), r - }, H.cloneNode = function(e) { - var t = I.call(this, !!e), - n = ot(t); - return -1 < n && nt(t, b[n]), e && it(t.querySelectorAll(w)), t - }), -2 < S.call(y, v + c) + S.call(y, d + c) && dt(n); - if (!m.test(c) || -1 < S.call(g, c)) throw new Error("The type " + n + " is invalid"); - var i = function() { - return f ? t.createElement(l, c) : t.createElement(l) - }, - a = r || x, - f = T.call(a, u), - l = f ? r[u].toUpperCase() : c, - c, p; - return f && -1 < S.call(y, d + l) && dt(l), p = y.push((f ? v : d) + c) - 1, w = w.concat(w.length ? "," : "", f ? l + '[is="' + n.toLowerCase() + '"]' : l), i.prototype = b[p] = T.call(a, "prototype") ? a.prototype : _(H), rt(t.querySelectorAll(w), s), i - } -})(window, document, Object, "registerElement"); \ No newline at end of file diff --git a/src/bower_components/fetch/fetch.js b/src/bower_components/fetch/fetch.js deleted file mode 100644 index cd40b3ed2d..0000000000 --- a/src/bower_components/fetch/fetch.js +++ /dev/null @@ -1,263 +0,0 @@ -! function(self) { - "use strict"; - - function normalizeName(name) { - if ("string" != typeof name && (name = String(name)), /[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) throw new TypeError("Invalid character in header field name"); - return name.toLowerCase() - } - - function normalizeValue(value) { - return "string" != typeof value && (value = String(value)), value - } - - function iteratorFor(items) { - var iterator = { - next: function() { - var value = items.shift(); - return { - done: void 0 === value, - value: value - } - } - }; - return support.iterable && (iterator[Symbol.iterator] = function() { - return iterator - }), iterator - } - - function Headers(headers) { - this.map = {}, headers instanceof Headers ? headers.forEach(function(value, name) { - this.append(name, value) - }, this) : headers && Object.getOwnPropertyNames(headers).forEach(function(name) { - this.append(name, headers[name]) - }, this) - } - - function consumed(body) { - if (body.bodyUsed) return Promise.reject(new TypeError("Already read")); - body.bodyUsed = !0 - } - - function fileReaderReady(reader) { - return new Promise(function(resolve, reject) { - reader.onload = function() { - resolve(reader.result) - }, reader.onerror = function() { - reject(reader.error) - } - }) - } - - function readBlobAsArrayBuffer(blob) { - var reader = new FileReader, - promise = fileReaderReady(reader); - return reader.readAsArrayBuffer(blob), promise - } - - function readBlobAsText(blob) { - var reader = new FileReader, - promise = fileReaderReady(reader); - return reader.readAsText(blob), promise - } - - function readArrayBufferAsText(buf) { - for (var view = new Uint8Array(buf), chars = new Array(view.length), i = 0; i < view.length; i++) chars[i] = String.fromCharCode(view[i]); - return chars.join("") - } - - function bufferClone(buf) { - if (buf.slice) return buf.slice(0); - var view = new Uint8Array(buf.byteLength); - return view.set(new Uint8Array(buf)), view.buffer - } - - function Body() { - return this.bodyUsed = !1, this._initBody = function(body) { - if (this._bodyInit = body, body) - if ("string" == typeof body) this._bodyText = body; - else if (support.blob && Blob.prototype.isPrototypeOf(body)) this._bodyBlob = body; - else if (support.formData && FormData.prototype.isPrototypeOf(body)) this._bodyFormData = body; - else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) this._bodyText = body.toString(); - else if (support.arrayBuffer && support.blob && isDataView(body)) this._bodyArrayBuffer = bufferClone(body.buffer), this._bodyInit = new Blob([this._bodyArrayBuffer]); - else { - if (!support.arrayBuffer || !ArrayBuffer.prototype.isPrototypeOf(body) && !isArrayBufferView(body)) throw new Error("unsupported BodyInit type"); - this._bodyArrayBuffer = bufferClone(body) - } else this._bodyText = ""; - this.headers.get("content-type") || ("string" == typeof body ? this.headers.set("content-type", "text/plain;charset=UTF-8") : this._bodyBlob && this._bodyBlob.type ? this.headers.set("content-type", this._bodyBlob.type) : support.searchParams && URLSearchParams.prototype.isPrototypeOf(body) && this.headers.set("content-type", "application/x-www-form-urlencoded;charset=UTF-8")) - }, support.blob && (this.blob = function() { - var rejected = consumed(this); - if (rejected) return rejected; - if (this._bodyBlob) return Promise.resolve(this._bodyBlob); - if (this._bodyArrayBuffer) return Promise.resolve(new Blob([this._bodyArrayBuffer])); - if (this._bodyFormData) throw new Error("could not read FormData body as blob"); - return Promise.resolve(new Blob([this._bodyText])) - }, this.arrayBuffer = function() { - return this._bodyArrayBuffer ? consumed(this) || Promise.resolve(this._bodyArrayBuffer) : this.blob().then(readBlobAsArrayBuffer) - }), this.text = function() { - var rejected = consumed(this); - if (rejected) return rejected; - if (this._bodyBlob) return readBlobAsText(this._bodyBlob); - if (this._bodyArrayBuffer) return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer)); - if (this._bodyFormData) throw new Error("could not read FormData body as text"); - return Promise.resolve(this._bodyText) - }, support.formData && (this.formData = function() { - return this.text().then(decode) - }), this.json = function() { - return this.text().then(JSON.parse) - }, this - } - - function normalizeMethod(method) { - var upcased = method.toUpperCase(); - return methods.indexOf(upcased) > -1 ? upcased : method - } - - function Request(input, options) { - options = options || {}; - var body = options.body; - if ("string" == typeof input) this.url = input; - else { - if (input.bodyUsed) throw new TypeError("Already read"); - this.url = input.url, this.credentials = input.credentials, options.headers || (this.headers = new Headers(input.headers)), this.method = input.method, this.mode = input.mode, body || null == input._bodyInit || (body = input._bodyInit, input.bodyUsed = !0) - } - if (this.credentials = options.credentials || this.credentials || "omit", !options.headers && this.headers || (this.headers = new Headers(options.headers)), this.method = normalizeMethod(options.method || this.method || "GET"), this.mode = options.mode || this.mode || null, this.referrer = null, ("GET" === this.method || "HEAD" === this.method) && body) throw new TypeError("Body not allowed for GET or HEAD requests"); - this._initBody(body) - } - - function decode(body) { - var form = new FormData; - return body.trim().split("&").forEach(function(bytes) { - if (bytes) { - var split = bytes.split("="), - name = split.shift().replace(/\+/g, " "), - value = split.join("=").replace(/\+/g, " "); - form.append(decodeURIComponent(name), decodeURIComponent(value)) - } - }), form - } - - function parseHeaders(rawHeaders) { - var headers = new Headers; - return rawHeaders.split("\r\n").forEach(function(line) { - var parts = line.split(":"), - key = parts.shift().trim(); - if (key) { - var value = parts.join(":").trim(); - headers.append(key, value) - } - }), headers - } - - function Response(bodyInit, options) { - options || (options = {}), this.type = "default", this.status = "status" in options ? options.status : 200, this.ok = this.status >= 200 && this.status < 300, this.statusText = "statusText" in options ? options.statusText : "OK", this.headers = new Headers(options.headers), this.url = options.url || "", this._initBody(bodyInit) - } - if (!self.fetch) { - var support = { - searchParams: "URLSearchParams" in self, - iterable: "Symbol" in self && "iterator" in Symbol, - blob: "FileReader" in self && "Blob" in self && function() { - try { - return new Blob, !0 - } catch (e) { - return !1 - } - }(), - formData: "FormData" in self, - arrayBuffer: "ArrayBuffer" in self - }; - if (support.arrayBuffer) var viewClasses = ["[object Int8Array]", "[object Uint8Array]", "[object Uint8ClampedArray]", "[object Int16Array]", "[object Uint16Array]", "[object Int32Array]", "[object Uint32Array]", "[object Float32Array]", "[object Float64Array]"], - isDataView = function(obj) { - return obj && DataView.prototype.isPrototypeOf(obj) - }, - isArrayBufferView = ArrayBuffer.isView || function(obj) { - return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1 - }; - Headers.prototype.append = function(name, value) { - name = normalizeName(name), value = normalizeValue(value); - var list = this.map[name]; - list || (list = [], this.map[name] = list), list.push(value) - }, Headers.prototype.delete = function(name) { - delete this.map[normalizeName(name)] - }, Headers.prototype.get = function(name) { - var values = this.map[normalizeName(name)]; - return values ? values[0] : null - }, Headers.prototype.getAll = function(name) { - return this.map[normalizeName(name)] || [] - }, Headers.prototype.has = function(name) { - return this.map.hasOwnProperty(normalizeName(name)) - }, Headers.prototype.set = function(name, value) { - this.map[normalizeName(name)] = [normalizeValue(value)] - }, Headers.prototype.forEach = function(callback, thisArg) { - Object.getOwnPropertyNames(this.map).forEach(function(name) { - this.map[name].forEach(function(value) { - callback.call(thisArg, value, name, this) - }, this) - }, this) - }, Headers.prototype.keys = function() { - var items = []; - return this.forEach(function(value, name) { - items.push(name) - }), iteratorFor(items) - }, Headers.prototype.values = function() { - var items = []; - return this.forEach(function(value) { - items.push(value) - }), iteratorFor(items) - }, Headers.prototype.entries = function() { - var items = []; - return this.forEach(function(value, name) { - items.push([name, value]) - }), iteratorFor(items) - }, support.iterable && (Headers.prototype[Symbol.iterator] = Headers.prototype.entries); - var methods = ["DELETE", "GET", "HEAD", "OPTIONS", "POST", "PUT"]; - Request.prototype.clone = function() { - return new Request(this, { - body: this._bodyInit - }) - }, Body.call(Request.prototype), Body.call(Response.prototype), Response.prototype.clone = function() { - return new Response(this._bodyInit, { - status: this.status, - statusText: this.statusText, - headers: new Headers(this.headers), - url: this.url - }) - }, Response.error = function() { - var response = new Response(null, { - status: 0, - statusText: "" - }); - return response.type = "error", response - }; - var redirectStatuses = [301, 302, 303, 307, 308]; - Response.redirect = function(url, status) { - if (-1 === redirectStatuses.indexOf(status)) throw new RangeError("Invalid status code"); - return new Response(null, { - status: status, - headers: { - location: url - } - }) - }, self.Headers = Headers, self.Request = Request, self.Response = Response, self.fetch = function(input, init) { - return new Promise(function(resolve, reject) { - var request = new Request(input, init), - xhr = new XMLHttpRequest; - xhr.onload = function() { - var options = { - status: xhr.status, - statusText: xhr.statusText, - headers: parseHeaders(xhr.getAllResponseHeaders() || "") - }; - options.url = "responseURL" in xhr ? xhr.responseURL : options.headers.get("X-Request-URL"); - var body = "response" in xhr ? xhr.response : xhr.responseText; - resolve(new Response(body, options)) - }, xhr.onerror = function() { - reject(new TypeError("Network request failed")) - }, xhr.ontimeout = function() { - reject(new TypeError("Network request failed")) - }, xhr.open(request.method, request.url, !0), "include" === request.credentials && (xhr.withCredentials = !0), "responseType" in xhr && support.blob && (xhr.responseType = "blob"), request.headers.forEach(function(value, name) { - xhr.setRequestHeader(name, value) - }), xhr.send(void 0 === request._bodyInit ? null : request._bodyInit) - }) - }, self.fetch.polyfill = !0 - } -}("undefined" != typeof self ? self : this); \ No newline at end of file diff --git a/src/bower_components/native-promise-only/lib/npo.src.js b/src/bower_components/native-promise-only/lib/npo.src.js deleted file mode 100644 index 1c8cb07867..0000000000 --- a/src/bower_components/native-promise-only/lib/npo.src.js +++ /dev/null @@ -1,373 +0,0 @@ -/*! Native Promise Only - v0.8.0-a (c) Kyle Simpson - MIT License: http://getify.mit-license.org -*/ - -(function UMD(name,context,definition){ - // special form of UMD for polyfilling across evironments - context[name] = definition(); - if (typeof module != "undefined" && module.exports) { module.exports = context[name]; } - else if (typeof define == "function" && define.amd) { define(function $AMD$(){ return context[name]; }); } -})("Promise",typeof global != "undefined" ? global : this,function DEF(){ - /*jshint validthis:true */ - "use strict"; - - var builtInProp, cycle, scheduling_queue, - ToString = Object.prototype.toString, - timer = (typeof setImmediate != "undefined") ? - function timer(fn) { return setImmediate(fn); } : - setTimeout - ; - - // dammit, IE8. - try { - Object.defineProperty({},"x",{}); - builtInProp = function builtInProp(obj,name,val,config) { - return Object.defineProperty(obj,name,{ - value: val, - writable: true, - configurable: config !== false - }); - }; - } - catch (err) { - builtInProp = function builtInProp(obj,name,val) { - obj[name] = val; - return obj; - }; - } - - // Note: using a queue instead of array for efficiency - scheduling_queue = (function Queue() { - var first, last, item; - - function Item(fn,self) { - this.fn = fn; - this.self = self; - this.next = void 0; - } - - return { - add: function add(fn,self) { - item = new Item(fn,self); - if (last) { - last.next = item; - } - else { - first = item; - } - last = item; - item = void 0; - }, - drain: function drain() { - var f = first; - first = last = cycle = void 0; - - while (f) { - f.fn.call(f.self); - f = f.next; - } - } - }; - })(); - - function schedule(fn,self) { - scheduling_queue.add(fn,self); - if (!cycle) { - cycle = timer(scheduling_queue.drain); - } - } - - // promise duck typing - function isThenable(o) { - var _then, o_type = typeof o; - - if (o != null && - ( - o_type == "object" || o_type == "function" - ) - ) { - _then = o.then; - } - return typeof _then == "function" ? _then : false; - } - - function notify() { - for (var i=0; i 0) { - schedule(notify,self); - } - } - } - catch (err) { - reject.call(new MakeDefWrapper(self),err); - } - } - - function reject(msg) { - var self = this; - - // already triggered? - if (self.triggered) { return; } - - self.triggered = true; - - // unwrap - if (self.def) { - self = self.def; - } - - self.msg = msg; - self.state = 2; - if (self.chain.length > 0) { - schedule(notify,self); - } - } - - function iteratePromises(Constructor,arr,resolver,rejecter) { - for (var idx=0; idx} arr - * @param {*} key - * @returns {number} - */ - function getIndex(arr, key) { - var result = -1; - - arr.some(function (entry, index) { - if (entry[0] === key) { - result = index; - - return true; - } - - return false; - }); - - return result; - } - - return (function () { - function anonymous() { - this.__entries__ = []; - } - - var prototypeAccessors = { size: { configurable: true } }; - - /** - * @returns {boolean} - */ - prototypeAccessors.size.get = function () { - return this.__entries__.length; - }; - - /** - * @param {*} key - * @returns {*} - */ - anonymous.prototype.get = function (key) { - var index = getIndex(this.__entries__, key); - var entry = this.__entries__[index]; - - return entry && entry[1]; - }; - - /** - * @param {*} key - * @param {*} value - * @returns {void} - */ - anonymous.prototype.set = function (key, value) { - var index = getIndex(this.__entries__, key); - - if (~index) { - this.__entries__[index][1] = value; - } else { - this.__entries__.push([key, value]); - } - }; - - /** - * @param {*} key - * @returns {void} - */ - anonymous.prototype.delete = function (key) { - var entries = this.__entries__; - var index = getIndex(entries, key); - - if (~index) { - entries.splice(index, 1); - } - }; - - /** - * @param {*} key - * @returns {void} - */ - anonymous.prototype.has = function (key) { - return !!~getIndex(this.__entries__, key); - }; - - /** - * @returns {void} - */ - anonymous.prototype.clear = function () { - this.__entries__.splice(0); - }; - - /** - * @param {Function} callback - * @param {*} [ctx=null] - * @returns {void} - */ - anonymous.prototype.forEach = function (callback, ctx) { - var this$1 = this; - if ( ctx === void 0 ) ctx = null; - - for (var i = 0, list = this$1.__entries__; i < list.length; i += 1) { - var entry = list[i]; - - callback.call(ctx, entry[1], entry[0]); - } - }; - - Object.defineProperties( anonymous.prototype, prototypeAccessors ); - - return anonymous; - }()); -})(); - -/** - * Detects whether window and document objects are available in current environment. - */ -var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document; - -// Returns global object of a current environment. -var global$1 = (function () { - if (typeof global !== 'undefined' && global.Math === Math) { - return global; - } - - if (typeof self !== 'undefined' && self.Math === Math) { - return self; - } - - if (typeof window !== 'undefined' && window.Math === Math) { - return window; - } - - // eslint-disable-next-line no-new-func - return Function('return this')(); -})(); - -/** - * A shim for the requestAnimationFrame which falls back to the setTimeout if - * first one is not supported. - * - * @returns {number} Requests' identifier. - */ -var requestAnimationFrame$1 = (function () { - if (typeof requestAnimationFrame === 'function') { - // It's required to use a bounded function because IE sometimes throws - // an "Invalid calling object" error if rAF is invoked without the global - // object on the left hand side. - return requestAnimationFrame.bind(global$1); - } - - return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); }; -})(); - -// Defines minimum timeout before adding a trailing call. -var trailingTimeout = 2; - -/** - * Creates a wrapper function which ensures that provided callback will be - * invoked only once during the specified delay period. - * - * @param {Function} callback - Function to be invoked after the delay period. - * @param {number} delay - Delay after which to invoke callback. - * @returns {Function} - */ -var throttle = function (callback, delay) { - var leadingCall = false, - trailingCall = false, - lastCallTime = 0; - - /** - * Invokes the original callback function and schedules new invocation if - * the "proxy" was called during current request. - * - * @returns {void} - */ - function resolvePending() { - if (leadingCall) { - leadingCall = false; - - callback(); - } - - if (trailingCall) { - proxy(); - } - } - - /** - * Callback invoked after the specified delay. It will further postpone - * invocation of the original function delegating it to the - * requestAnimationFrame. - * - * @returns {void} - */ - function timeoutCallback() { - requestAnimationFrame$1(resolvePending); - } - - /** - * Schedules invocation of the original function. - * - * @returns {void} - */ - function proxy() { - var timeStamp = Date.now(); - - if (leadingCall) { - // Reject immediately following calls. - if (timeStamp - lastCallTime < trailingTimeout) { - return; - } - - // Schedule new call to be in invoked when the pending one is resolved. - // This is important for "transitions" which never actually start - // immediately so there is a chance that we might miss one if change - // happens amids the pending invocation. - trailingCall = true; - } else { - leadingCall = true; - trailingCall = false; - - setTimeout(timeoutCallback, delay); - } - - lastCallTime = timeStamp; - } - - return proxy; -}; - -// Minimum delay before invoking the update of observers. -var REFRESH_DELAY = 20; - -// A list of substrings of CSS properties used to find transition events that -// might affect dimensions of observed elements. -var transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight']; - -// Check if MutationObserver is available. -var mutationObserverSupported = typeof MutationObserver !== 'undefined'; - -/** - * Singleton controller class which handles updates of ResizeObserver instances. - */ -var ResizeObserverController = function() { - this.connected_ = false; - this.mutationEventsAdded_ = false; - this.mutationsObserver_ = null; - this.observers_ = []; - - this.onTransitionEnd_ = this.onTransitionEnd_.bind(this); - this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY); -}; - -/** - * Adds observer to observers list. - * - * @param {ResizeObserverSPI} observer - Observer to be added. - * @returns {void} - */ - - -/** - * Holds reference to the controller's instance. - * - * @private {ResizeObserverController} - */ - - -/** - * Keeps reference to the instance of MutationObserver. - * - * @private {MutationObserver} - */ - -/** - * Indicates whether DOM listeners have been added. - * - * @private {boolean} - */ -ResizeObserverController.prototype.addObserver = function (observer) { - if (!~this.observers_.indexOf(observer)) { - this.observers_.push(observer); - } - - // Add listeners if they haven't been added yet. - if (!this.connected_) { - this.connect_(); - } -}; - -/** - * Removes observer from observers list. - * - * @param {ResizeObserverSPI} observer - Observer to be removed. - * @returns {void} - */ -ResizeObserverController.prototype.removeObserver = function (observer) { - var observers = this.observers_; - var index = observers.indexOf(observer); - - // Remove observer if it's present in registry. - if (~index) { - observers.splice(index, 1); - } - - // Remove listeners if controller has no connected observers. - if (!observers.length && this.connected_) { - this.disconnect_(); - } -}; - -/** - * Invokes the update of observers. It will continue running updates insofar - * it detects changes. - * - * @returns {void} - */ -ResizeObserverController.prototype.refresh = function () { - var changesDetected = this.updateObservers_(); - - // Continue running updates if changes have been detected as there might - // be future ones caused by CSS transitions. - if (changesDetected) { - this.refresh(); - } -}; - -/** - * Updates every observer from observers list and notifies them of queued - * entries. - * - * @private - * @returns {boolean} Returns "true" if any observer has detected changes in - * dimensions of it's elements. - */ -ResizeObserverController.prototype.updateObservers_ = function () { - // Collect observers that have active observations. - var activeObservers = this.observers_.filter(function (observer) { - return observer.gatherActive(), observer.hasActive(); - }); - - // Deliver notifications in a separate cycle in order to avoid any - // collisions between observers, e.g. when multiple instances of - // ResizeObserver are tracking the same element and the callback of one - // of them changes content dimensions of the observed target. Sometimes - // this may result in notifications being blocked for the rest of observers. - activeObservers.forEach(function (observer) { return observer.broadcastActive(); }); - - return activeObservers.length > 0; -}; - -/** - * Initializes DOM listeners. - * - * @private - * @returns {void} - */ -ResizeObserverController.prototype.connect_ = function () { - // Do nothing if running in a non-browser environment or if listeners - // have been already added. - if (!isBrowser || this.connected_) { - return; - } - - // Subscription to the "Transitionend" event is used as a workaround for - // delayed transitions. This way it's possible to capture at least the - // final state of an element. - document.addEventListener('transitionend', this.onTransitionEnd_); - - window.addEventListener('resize', this.refresh); - window.addEventListener('orientationchange', this.refresh); - - if (mutationObserverSupported) { - this.mutationsObserver_ = new MutationObserver(this.refresh); - - this.mutationsObserver_.observe(document, { - attributes: true, - childList: true, - characterData: true, - subtree: true - }); - } else { - document.addEventListener('DOMSubtreeModified', this.refresh); - - this.mutationEventsAdded_ = true; - } - - this.connected_ = true; -}; - -/** - * Removes DOM listeners. - * - * @private - * @returns {void} - */ -ResizeObserverController.prototype.disconnect_ = function () { - // Do nothing if running in a non-browser environment or if listeners - // have been already removed. - if (!isBrowser || !this.connected_) { - return; - } - - document.removeEventListener('transitionend', this.onTransitionEnd_); - window.removeEventListener('resize', this.refresh); - window.removeEventListener('orientationchange', this.refresh); - - if (this.mutationsObserver_) { - this.mutationsObserver_.disconnect(); - } - - if (this.mutationEventsAdded_) { - document.removeEventListener('DOMSubtreeModified', this.refresh); - } - - this.mutationsObserver_ = null; - this.mutationEventsAdded_ = false; - this.connected_ = false; -}; - -/** - * "Transitionend" event handler. - * - * @private - * @param {TransitionEvent} event - * @returns {void} - */ -ResizeObserverController.prototype.onTransitionEnd_ = function (ref) { - var propertyName = ref.propertyName; if ( propertyName === void 0 ) propertyName = ''; - - // Detect whether transition may affect dimensions of an element. - var isReflowProperty = transitionKeys.some(function (key) { - return !!~propertyName.indexOf(key); - }); - - if (isReflowProperty) { - this.refresh(); - } -}; - -/** - * Returns instance of the ResizeObserverController. - * - * @returns {ResizeObserverController} - */ -ResizeObserverController.getInstance = function () { - if (!this.instance_) { - this.instance_ = new ResizeObserverController(); - } - - return this.instance_; -}; - -ResizeObserverController.instance_ = null; - -/** - * Defines non-writable/enumerable properties of the provided target object. - * - * @param {Object} target - Object for which to define properties. - * @param {Object} props - Properties to be defined. - * @returns {Object} Target object. - */ -var defineConfigurable = (function (target, props) { - for (var i = 0, list = Object.keys(props); i < list.length; i += 1) { - var key = list[i]; - - Object.defineProperty(target, key, { - value: props[key], - enumerable: false, - writable: false, - configurable: true - }); - } - - return target; -}); - -/** - * Returns the global object associated with provided element. - * - * @param {Object} target - * @returns {Object} - */ -var getWindowOf = (function (target) { - // Assume that the element is an instance of Node, which means that it - // has the "ownerDocument" property from which we can retrieve a - // corresponding global object. - var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView; - - // Return the local global object if it's not possible extract one from - // provided element. - return ownerGlobal || global$1; -}); - -// Placeholder of an empty content rectangle. -var emptyRect = createRectInit(0, 0, 0, 0); - -/** - * Converts provided string to a number. - * - * @param {number|string} value - * @returns {number} - */ -function toFloat(value) { - return parseFloat(value) || 0; -} - -/** - * Extracts borders size from provided styles. - * - * @param {CSSStyleDeclaration} styles - * @param {...string} positions - Borders positions (top, right, ...) - * @returns {number} - */ -function getBordersSize(styles) { - var positions = [], len = arguments.length - 1; - while ( len-- > 0 ) positions[ len ] = arguments[ len + 1 ]; - - return positions.reduce(function (size, position) { - var value = styles['border-' + position + '-width']; - - return size + toFloat(value); - }, 0); -} - -/** - * Extracts paddings sizes from provided styles. - * - * @param {CSSStyleDeclaration} styles - * @returns {Object} Paddings box. - */ -function getPaddings(styles) { - var positions = ['top', 'right', 'bottom', 'left']; - var paddings = {}; - - for (var i = 0, list = positions; i < list.length; i += 1) { - var position = list[i]; - - var value = styles['padding-' + position]; - - paddings[position] = toFloat(value); - } - - return paddings; -} - -/** - * Calculates content rectangle of provided SVG element. - * - * @param {SVGGraphicsElement} target - Element content rectangle of which needs - * to be calculated. - * @returns {DOMRectInit} - */ -function getSVGContentRect(target) { - var bbox = target.getBBox(); - - return createRectInit(0, 0, bbox.width, bbox.height); -} - -/** - * Calculates content rectangle of provided HTMLElement. - * - * @param {HTMLElement} target - Element for which to calculate the content rectangle. - * @returns {DOMRectInit} - */ -function getHTMLElementContentRect(target) { - - var rect = target.getBoundingClientRect(); - return createRectInit(rect.left, rect.top, rect.width, rect.height); -} - -/** - * Checks whether provided element is a document element (). - * - * @param {Element} target - Element to be checked. - * @returns {boolean} - */ -function isDocumentElement(target) { - return target === getWindowOf(target).document.documentElement; -} - -/** - * Calculates an appropriate content rectangle for provided html or svg element. - * - * @param {Element} target - Element content rectangle of which needs to be calculated. - * @returns {DOMRectInit} - */ -function getContentRect(target) { - if (!isBrowser) { - return emptyRect; - } - - return getHTMLElementContentRect(target); -} - -/** - * Creates rectangle with an interface of the DOMRectReadOnly. - * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly - * - * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions. - * @returns {DOMRectReadOnly} - */ -function createReadOnlyRect(ref) { - var x = ref.x; - var y = ref.y; - var width = ref.width; - var height = ref.height; - - // If DOMRectReadOnly is available use it as a prototype for the rectangle. - var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object; - var rect = Object.create(Constr.prototype); - - // Rectangle's properties are not writable and non-enumerable. - defineConfigurable(rect, { - x: x, y: y, width: width, height: height, - top: y, - right: x + width, - bottom: height + y, - left: x - }); - - return rect; -} - -/** - * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates. - * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit - * - * @param {number} x - X coordinate. - * @param {number} y - Y coordinate. - * @param {number} width - Rectangle's width. - * @param {number} height - Rectangle's height. - * @returns {DOMRectInit} - */ -function createRectInit(x, y, width, height) { - return { x: x, y: y, width: width, height: height }; -} - -/** - * Class that is responsible for computations of the content rectangle of - * provided DOM element and for keeping track of it's changes. - */ -var ResizeObservation = function(target) { - this.broadcastWidth = 0; - this.broadcastHeight = 0; - this.contentRect_ = createRectInit(0, 0, 0, 0); - - this.target = target; -}; - -/** - * Updates content rectangle and tells whether it's width or height properties - * have changed since the last broadcast. - * - * @returns {boolean} - */ - - -/** - * Reference to the last observed content rectangle. - * - * @private {DOMRectInit} - */ - - -/** - * Broadcasted width of content rectangle. - * - * @type {number} - */ -ResizeObservation.prototype.isActive = function () { - var rect = getContentRect(this.target); - - this.contentRect_ = rect; - return rect.width !== this.broadcastWidth || rect.height !== this.broadcastHeight; -}; - -/** - * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data - * from the corresponding properties of the last observed content rectangle. - * - * @returns {DOMRectInit} Last observed content rectangle. - */ -ResizeObservation.prototype.broadcastRect = function () { - var rect = this.contentRect_; - - this.broadcastWidth = rect.width; - this.broadcastHeight = rect.height; - - return rect; -}; - -var ResizeObserverEntry = function(target, rectInit) { - var contentRect = createReadOnlyRect(rectInit); - - // According to the specification following properties are not writable - // and are also not enumerable in the native implementation. - // - // Property accessors are not being used as they'd require to define a - // private WeakMap storage which may cause memory leaks in browsers that - // don't support this type of collections. - defineConfigurable(this, { target: target, contentRect: contentRect }); -}; - -var ResizeObserverSPI = function(callback, controller, callbackCtx) { - this.activeObservations_ = []; - this.observations_ = new MapShim(); - - if (typeof callback !== 'function') { - throw new TypeError('The callback provided as parameter 1 is not a function.'); - } - - this.callback_ = callback; - this.controller_ = controller; - this.callbackCtx_ = callbackCtx; -}; - -/** - * Starts observing provided element. - * - * @param {Element} target - Element to be observed. - * @returns {void} - */ - - -/** - * Registry of the ResizeObservation instances. - * - * @private {Map} - */ - - -/** - * Public ResizeObserver instance which will be passed to the callback - * function and used as a value of it's "this" binding. - * - * @private {ResizeObserver} - */ - -/** - * Collection of resize observations that have detected changes in dimensions - * of elements. - * - * @private {Array} - */ -ResizeObserverSPI.prototype.observe = function (target) { - if (!arguments.length) { - throw new TypeError('1 argument required, but only 0 present.'); - } - - // Do nothing if current environment doesn't have the Element interface. - if (typeof Element === 'undefined' || !(Element instanceof Object)) { - return; - } - - if (!(target instanceof getWindowOf(target).Element)) { - throw new TypeError('parameter 1 is not of type "Element".'); - } - - var observations = this.observations_; - - // Do nothing if element is already being observed. - if (observations.has(target)) { - return; - } - - observations.set(target, new ResizeObservation(target)); - - this.controller_.addObserver(this); - - // Force the update of observations. - this.controller_.refresh(); -}; - -/** - * Stops observing provided element. - * - * @param {Element} target - Element to stop observing. - * @returns {void} - */ -ResizeObserverSPI.prototype.unobserve = function (target) { - if (!arguments.length) { - throw new TypeError('1 argument required, but only 0 present.'); - } - - // Do nothing if current environment doesn't have the Element interface. - if (typeof Element === 'undefined' || !(Element instanceof Object)) { - return; - } - - if (!(target instanceof getWindowOf(target).Element)) { - throw new TypeError('parameter 1 is not of type "Element".'); - } - - var observations = this.observations_; - - // Do nothing if element is not being observed. - if (!observations.has(target)) { - return; - } - - observations.delete(target); - - if (!observations.size) { - this.controller_.removeObserver(this); - } -}; - -/** - * Stops observing all elements. - * - * @returns {void} - */ -ResizeObserverSPI.prototype.disconnect = function () { - this.clearActive(); - this.observations_.clear(); - this.controller_.removeObserver(this); -}; - -/** - * Collects observation instances the associated element of which has changed - * it's content rectangle. - * - * @returns {void} - */ -ResizeObserverSPI.prototype.gatherActive = function () { - var this$1 = this; - - this.clearActive(); - - this.observations_.forEach(function (observation) { - if (observation.isActive()) { - this$1.activeObservations_.push(observation); - } - }); -}; - -/** - * Invokes initial callback function with a list of ResizeObserverEntry - * instances collected from active resize observations. - * - * @returns {void} - */ -ResizeObserverSPI.prototype.broadcastActive = function () { - // Do nothing if observer doesn't have active observations. - if (!this.hasActive()) { - return; - } - - var ctx = this.callbackCtx_; - - // Create ResizeObserverEntry instance for every active observation. - var entries = this.activeObservations_.map(function (observation) { - return new ResizeObserverEntry(observation.target, observation.broadcastRect()); - }); - - this.callback_.call(ctx, entries, ctx); - this.clearActive(); -}; - -/** - * Clears the collection of active observations. - * - * @returns {void} - */ -ResizeObserverSPI.prototype.clearActive = function () { - this.activeObservations_.splice(0); -}; - -/** - * Tells whether observer has active observations. - * - * @returns {boolean} - */ -ResizeObserverSPI.prototype.hasActive = function () { - return this.activeObservations_.length > 0; -}; - -// Registry of internal observers. If WeakMap is not available use current shim -// for the Map collection as it has all required methods and because WeakMap -// can't be fully polyfilled anyway. -var observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim(); - -/** - * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation - * exposing only those methods and properties that are defined in the spec. - */ -var ResizeObserver = function(callback) { - if (!(this instanceof ResizeObserver)) { - throw new TypeError('Cannot call a class as a function.'); - } - if (!arguments.length) { - throw new TypeError('1 argument required, but only 0 present.'); - } - - var controller = ResizeObserverController.getInstance(); - var observer = new ResizeObserverSPI(callback, controller, this); - - observers.set(this, observer); -}; - -// Expose public methods of ResizeObserver. -['observe', 'unobserve', 'disconnect'].forEach(function (method) { - ResizeObserver.prototype[method] = function () { - return (ref = observers.get(this))[method].apply(ref, arguments); - var ref; - }; -}); - -var index = (function () { - // Export existing implementation if available. - if (typeof global$1.ResizeObserver !== 'undefined') { - return global$1.ResizeObserver; - } - - return ResizeObserver; -})(); - -return index; - -}))); diff --git a/src/bower_components/webcomponentsjs/webcomponents-lite.min.js b/src/bower_components/webcomponentsjs/webcomponents-lite.min.js deleted file mode 100644 index 163ef436fc..0000000000 --- a/src/bower_components/webcomponentsjs/webcomponents-lite.min.js +++ /dev/null @@ -1,1571 +0,0 @@ -/** - * @license - * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. - * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt - * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt - * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt - * Code distributed by Google as part of the polymer project is also - * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt - */ -// @version 0.7.24 -! function() { - window.WebComponents = window.WebComponents || { - flags: {} - }; - var e = "webcomponents-lite.js", - t = document.querySelector('script[src*="' + e + '"]'), - n = {}; - if (!n.noOpts) { - if (location.search.slice(1).split("&").forEach(function(e) { - var t, o = e.split("="); - o[0] && (t = o[0].match(/wc-(.+)/)) && (n[t[1]] = o[1] || !0) - }), t) - for (var o, r = 0; o = t.attributes[r]; r++) "src" !== o.name && (n[o.name] = o.value || !0); - if (n.log && n.log.split) { - var i = n.log.split(","); - n.log = {}, i.forEach(function(e) { - n.log[e] = !0 - }) - } else n.log = {} - } - n.register && (window.CustomElements = window.CustomElements || { - flags: {} - }, window.CustomElements.flags.register = n.register), WebComponents.flags = n -}(), -function(e) { - "use strict"; - - function t(e) { - return void 0 !== h[e] - } - - function n() { - s.call(this), this._isInvalid = !0 - } - - function o(e) { - return "" == e && n.call(this), e.toLowerCase() - } - - function r(e) { - var t = e.charCodeAt(0); - return t > 32 && t < 127 && [34, 35, 60, 62, 63, 96].indexOf(t) == -1 ? e : encodeURIComponent(e) - } - - function i(e) { - var t = e.charCodeAt(0); - return t > 32 && t < 127 && [34, 35, 60, 62, 96].indexOf(t) == -1 ? e : encodeURIComponent(e) - } - - function a(e, a, s) { - function c(e) { - g.push(e) - } - var d = a || "scheme start", - l = 0, - u = "", - w = !1, - _ = !1, - g = []; - e: for (; - (e[l - 1] != p || 0 == l) && !this._isInvalid;) { - var b = e[l]; - switch (d) { - case "scheme start": - if (!b || !m.test(b)) { - if (a) { - c("Invalid scheme."); - break e - } - u = "", d = "no scheme"; - continue - } - u += b.toLowerCase(), d = "scheme"; - break; - case "scheme": - if (b && v.test(b)) u += b.toLowerCase(); - else { - if (":" != b) { - if (a) { - if (p == b) break e; - c("Code point not allowed in scheme: " + b); - break e - } - u = "", l = 0, d = "no scheme"; - continue - } - if (this._scheme = u, u = "", a) break e; - t(this._scheme) && (this._isRelative = !0), d = "file" == this._scheme ? "relative" : this._isRelative && s && s._scheme == this._scheme ? "relative or authority" : this._isRelative ? "authority first slash" : "scheme data" - } - break; - case "scheme data": - "?" == b ? (this._query = "?", d = "query") : "#" == b ? (this._fragment = "#", d = "fragment") : p != b && "\t" != b && "\n" != b && "\r" != b && (this._schemeData += r(b)); - break; - case "no scheme": - if (s && t(s._scheme)) { - d = "relative"; - continue - } - c("Missing scheme."), n.call(this); - break; - case "relative or authority": - if ("/" != b || "/" != e[l + 1]) { - c("Expected /, got: " + b), d = "relative"; - continue - } - d = "authority ignore slashes"; - break; - case "relative": - if (this._isRelative = !0, "file" != this._scheme && (this._scheme = s._scheme), p == b) { - this._host = s._host, this._port = s._port, this._path = s._path.slice(), this._query = s._query, this._username = s._username, this._password = s._password; - break e - } - if ("/" == b || "\\" == b) "\\" == b && c("\\ is an invalid code point."), d = "relative slash"; - else if ("?" == b) this._host = s._host, this._port = s._port, this._path = s._path.slice(), this._query = "?", this._username = s._username, this._password = s._password, d = "query"; - else { - if ("#" != b) { - var y = e[l + 1], - E = e[l + 2]; - ("file" != this._scheme || !m.test(b) || ":" != y && "|" != y || p != E && "/" != E && "\\" != E && "?" != E && "#" != E) && (this._host = s._host, this._port = s._port, this._username = s._username, this._password = s._password, this._path = s._path.slice(), this._path.pop()), d = "relative path"; - continue - } - this._host = s._host, this._port = s._port, this._path = s._path.slice(), this._query = s._query, this._fragment = "#", this._username = s._username, this._password = s._password, d = "fragment" - } - break; - case "relative slash": - if ("/" != b && "\\" != b) { - "file" != this._scheme && (this._host = s._host, this._port = s._port, this._username = s._username, this._password = s._password), d = "relative path"; - continue - } - "\\" == b && c("\\ is an invalid code point."), d = "file" == this._scheme ? "file host" : "authority ignore slashes"; - break; - case "authority first slash": - if ("/" != b) { - c("Expected '/', got: " + b), d = "authority ignore slashes"; - continue - } - d = "authority second slash"; - break; - case "authority second slash": - if (d = "authority ignore slashes", "/" != b) { - c("Expected '/', got: " + b); - continue - } - break; - case "authority ignore slashes": - if ("/" != b && "\\" != b) { - d = "authority"; - continue - } - c("Expected authority, got: " + b); - break; - case "authority": - if ("@" == b) { - w && (c("@ already seen."), u += "%40"), w = !0; - for (var L = 0; L < u.length; L++) { - var N = u[L]; - if ("\t" != N && "\n" != N && "\r" != N) - if (":" != N || null !== this._password) { - var M = r(N); - null !== this._password ? this._password += M : this._username += M - } else this._password = ""; - else c("Invalid whitespace in authority.") - } - u = "" - } else { - if (p == b || "/" == b || "\\" == b || "?" == b || "#" == b) { - l -= u.length, u = "", d = "host"; - continue - } - u += b - } - break; - case "file host": - if (p == b || "/" == b || "\\" == b || "?" == b || "#" == b) { - 2 != u.length || !m.test(u[0]) || ":" != u[1] && "|" != u[1] ? 0 == u.length ? d = "relative path start" : (this._host = o.call(this, u), u = "", d = "relative path start") : d = "relative path"; - continue - } - "\t" == b || "\n" == b || "\r" == b ? c("Invalid whitespace in file host.") : u += b; - break; - case "host": - case "hostname": - if (":" != b || _) { - if (p == b || "/" == b || "\\" == b || "?" == b || "#" == b) { - if (this._host = o.call(this, u), u = "", d = "relative path start", a) break e; - continue - } - "\t" != b && "\n" != b && "\r" != b ? ("[" == b ? _ = !0 : "]" == b && (_ = !1), u += b) : c("Invalid code point in host/hostname: " + b) - } else if (this._host = o.call(this, u), u = "", d = "port", "hostname" == a) break e; - break; - case "port": - if (/[0-9]/.test(b)) u += b; - else { - if (p == b || "/" == b || "\\" == b || "?" == b || "#" == b || a) { - if ("" != u) { - var T = parseInt(u, 10); - T != h[this._scheme] && (this._port = T + ""), u = "" - } - if (a) break e; - d = "relative path start"; - continue - } - "\t" == b || "\n" == b || "\r" == b ? c("Invalid code point in port: " + b) : n.call(this) - } - break; - case "relative path start": - if ("\\" == b && c("'\\' not allowed in path."), d = "relative path", "/" != b && "\\" != b) continue; - break; - case "relative path": - if (p != b && "/" != b && "\\" != b && (a || "?" != b && "#" != b)) "\t" != b && "\n" != b && "\r" != b && (u += r(b)); - else { - "\\" == b && c("\\ not allowed in relative path."); - var O; - (O = f[u.toLowerCase()]) && (u = O), ".." == u ? (this._path.pop(), "/" != b && "\\" != b && this._path.push("")) : "." == u && "/" != b && "\\" != b ? this._path.push("") : "." != u && ("file" == this._scheme && 0 == this._path.length && 2 == u.length && m.test(u[0]) && "|" == u[1] && (u = u[0] + ":"), this._path.push(u)), u = "", "?" == b ? (this._query = "?", d = "query") : "#" == b && (this._fragment = "#", d = "fragment") - } - break; - case "query": - a || "#" != b ? p != b && "\t" != b && "\n" != b && "\r" != b && (this._query += i(b)) : (this._fragment = "#", d = "fragment"); - break; - case "fragment": - p != b && "\t" != b && "\n" != b && "\r" != b && (this._fragment += b) - } - l++ - } - } - - function s() { - this._scheme = "", this._schemeData = "", this._username = "", this._password = null, this._host = "", this._port = "", this._path = [], this._query = "", this._fragment = "", this._isInvalid = !1, this._isRelative = !1 - } - - function c(e, t) { - void 0 === t || t instanceof c || (t = new c(String(t))), this._url = e, s.call(this); - var n = e.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, ""); - a.call(this, n, null, t) - } - var d = !1; - if (!e.forceJURL) try { - var l = new URL("b", "http://a"); - l.pathname = "c%20d", d = "http://a/c%20d" === l.href - } catch (u) {} - if (!d) { - var h = Object.create(null); - h.ftp = 21, h.file = 0, h.gopher = 70, h.http = 80, h.https = 443, h.ws = 80, h.wss = 443; - var f = Object.create(null); - f["%2e"] = ".", f[".%2e"] = "..", f["%2e."] = "..", f["%2e%2e"] = ".."; - var p = void 0, - m = /[a-zA-Z]/, - v = /[a-zA-Z0-9\+\-\.]/; - c.prototype = { - toString: function() { - return this.href - }, - get href() { - if (this._isInvalid) return this._url; - var e = ""; - return "" == this._username && null == this._password || (e = this._username + (null != this._password ? ":" + this._password : "") + "@"), this.protocol + (this._isRelative ? "//" + e + this.host : "") + this.pathname + this._query + this._fragment - }, - set href(e) { - s.call(this), a.call(this, e) - }, - get protocol() { - return this._scheme + ":" - }, - set protocol(e) { - this._isInvalid || a.call(this, e + ":", "scheme start") - }, - get host() { - return this._isInvalid ? "" : this._port ? this._host + ":" + this._port : this._host - }, - set host(e) { - !this._isInvalid && this._isRelative && a.call(this, e, "host") - }, - get hostname() { - return this._host - }, - set hostname(e) { - !this._isInvalid && this._isRelative && a.call(this, e, "hostname") - }, - get port() { - return this._port - }, - set port(e) { - !this._isInvalid && this._isRelative && a.call(this, e, "port") - }, - get pathname() { - return this._isInvalid ? "" : this._isRelative ? "/" + this._path.join("/") : this._schemeData - }, - set pathname(e) { - !this._isInvalid && this._isRelative && (this._path = [], a.call(this, e, "relative path start")) - }, - get search() { - return this._isInvalid || !this._query || "?" == this._query ? "" : this._query - }, - set search(e) { - !this._isInvalid && this._isRelative && (this._query = "?", "?" == e[0] && (e = e.slice(1)), a.call(this, e, "query")) - }, - get hash() { - return this._isInvalid || !this._fragment || "#" == this._fragment ? "" : this._fragment - }, - set hash(e) { - this._isInvalid || (this._fragment = "#", "#" == e[0] && (e = e.slice(1)), a.call(this, e, "fragment")) - }, - get origin() { - var e; - if (this._isInvalid || !this._scheme) return ""; - switch (this._scheme) { - case "data": - case "file": - case "javascript": - case "mailto": - return "null" - } - return e = this.host, e ? this._scheme + "://" + e : "" - } - }; - var w = e.URL; - w && (c.createObjectURL = function(e) { - return w.createObjectURL.apply(w, arguments) - }, c.revokeObjectURL = function(e) { - w.revokeObjectURL(e) - }), e.URL = c - } -}(self), "undefined" == typeof WeakMap && ! function() { - var e = Object.defineProperty, - t = Date.now() % 1e9, - n = function() { - this.name = "__st" + (1e9 * Math.random() >>> 0) + (t++ + "__") - }; - n.prototype = { - set: function(t, n) { - var o = t[this.name]; - return o && o[0] === t ? o[1] = n : e(t, this.name, { - value: [t, n], - writable: !0 - }), this - }, - get: function(e) { - var t; - return (t = e[this.name]) && t[0] === e ? t[1] : void 0 - }, - "delete": function(e) { - var t = e[this.name]; - return !(!t || t[0] !== e) && (t[0] = t[1] = void 0, !0) - }, - has: function(e) { - var t = e[this.name]; - return !!t && t[0] === e - } - }, window.WeakMap = n - }(), - function(e) { - function t(e) { - b.push(e), g || (g = !0, m(o)) - } - - function n(e) { - return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(e) || e - } - - function o() { - g = !1; - var e = b; - b = [], e.sort(function(e, t) { - return e.uid_ - t.uid_ - }); - var t = !1; - e.forEach(function(e) { - var n = e.takeRecords(); - r(e), n.length && (e.callback_(n, e), t = !0) - }), t && o() - } - - function r(e) { - e.nodes_.forEach(function(t) { - var n = v.get(t); - n && n.forEach(function(t) { - t.observer === e && t.removeTransientObservers() - }) - }) - } - - function i(e, t) { - for (var n = e; n; n = n.parentNode) { - var o = v.get(n); - if (o) - for (var r = 0; r < o.length; r++) { - var i = o[r], - a = i.options; - if (n === e || a.subtree) { - var s = t(a); - s && i.enqueue(s) - } - } - } - } - - function a(e) { - this.callback_ = e, this.nodes_ = [], this.records_ = [], this.uid_ = ++y - } - - function s(e, t) { - this.type = e, this.target = t, this.addedNodes = [], this.removedNodes = [], this.previousSibling = null, this.nextSibling = null, this.attributeName = null, this.attributeNamespace = null, this.oldValue = null - } - - function c(e) { - var t = new s(e.type, e.target); - return t.addedNodes = e.addedNodes.slice(), t.removedNodes = e.removedNodes.slice(), t.previousSibling = e.previousSibling, t.nextSibling = e.nextSibling, t.attributeName = e.attributeName, t.attributeNamespace = e.attributeNamespace, t.oldValue = e.oldValue, t - } - - function d(e, t) { - return E = new s(e, t) - } - - function l(e) { - return L ? L : (L = c(E), L.oldValue = e, L) - } - - function u() { - E = L = void 0 - } - - function h(e) { - return e === L || e === E - } - - function f(e, t) { - return e === t ? e : L && h(e) ? L : null - } - - function p(e, t, n) { - this.observer = e, this.target = t, this.options = n, this.transientObservedNodes = [] - } - if (!e.JsMutationObserver) { - var m, v = new WeakMap; - if (/Trident|Edge/.test(navigator.userAgent)) m = setTimeout; - else if (window.setImmediate) m = window.setImmediate; - else { - var w = [], - _ = String(Math.random()); - window.addEventListener("message", function(e) { - if (e.data === _) { - var t = w; - w = [], t.forEach(function(e) { - e() - }) - } - }), m = function(e) { - w.push(e), window.postMessage(_, "*") - } - } - var g = !1, - b = [], - y = 0; - a.prototype = { - observe: function(e, t) { - if (e = n(e), !t.childList && !t.attributes && !t.characterData || t.attributeOldValue && !t.attributes || t.attributeFilter && t.attributeFilter.length && !t.attributes || t.characterDataOldValue && !t.characterData) throw new SyntaxError; - var o = v.get(e); - o || v.set(e, o = []); - for (var r, i = 0; i < o.length; i++) - if (o[i].observer === this) { - r = o[i], r.removeListeners(), r.options = t; - break - } r || (r = new p(this, e, t), o.push(r), this.nodes_.push(e)), r.addListeners() - }, - disconnect: function() { - this.nodes_.forEach(function(e) { - for (var t = v.get(e), n = 0; n < t.length; n++) { - var o = t[n]; - if (o.observer === this) { - o.removeListeners(), t.splice(n, 1); - break - } - } - }, this), this.records_ = [] - }, - takeRecords: function() { - var e = this.records_; - return this.records_ = [], e - } - }; - var E, L; - p.prototype = { - enqueue: function(e) { - var n = this.observer.records_, - o = n.length; - if (n.length > 0) { - var r = n[o - 1], - i = f(r, e); - if (i) return void(n[o - 1] = i) - } else t(this.observer); - n[o] = e - }, - addListeners: function() { - this.addListeners_(this.target) - }, - addListeners_: function(e) { - var t = this.options; - t.attributes && e.addEventListener("DOMAttrModified", this, !0), t.characterData && e.addEventListener("DOMCharacterDataModified", this, !0), t.childList && e.addEventListener("DOMNodeInserted", this, !0), (t.childList || t.subtree) && e.addEventListener("DOMNodeRemoved", this, !0) - }, - removeListeners: function() { - this.removeListeners_(this.target) - }, - removeListeners_: function(e) { - var t = this.options; - t.attributes && e.removeEventListener("DOMAttrModified", this, !0), t.characterData && e.removeEventListener("DOMCharacterDataModified", this, !0), t.childList && e.removeEventListener("DOMNodeInserted", this, !0), (t.childList || t.subtree) && e.removeEventListener("DOMNodeRemoved", this, !0) - }, - addTransientObserver: function(e) { - if (e !== this.target) { - this.addListeners_(e), this.transientObservedNodes.push(e); - var t = v.get(e); - t || v.set(e, t = []), t.push(this) - } - }, - removeTransientObservers: function() { - var e = this.transientObservedNodes; - this.transientObservedNodes = [], e.forEach(function(e) { - this.removeListeners_(e); - for (var t = v.get(e), n = 0; n < t.length; n++) - if (t[n] === this) { - t.splice(n, 1); - break - } - }, this) - }, - handleEvent: function(e) { - switch (e.stopImmediatePropagation(), e.type) { - case "DOMAttrModified": - var t = e.attrName, - n = e.relatedNode.namespaceURI, - o = e.target, - r = new d("attributes", o); - r.attributeName = t, r.attributeNamespace = n; - var a = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue; - i(o, function(e) { - if (e.attributes && (!e.attributeFilter || !e.attributeFilter.length || e.attributeFilter.indexOf(t) !== -1 || e.attributeFilter.indexOf(n) !== -1)) return e.attributeOldValue ? l(a) : r - }); - break; - case "DOMCharacterDataModified": - var o = e.target, - r = d("characterData", o), - a = e.prevValue; - i(o, function(e) { - if (e.characterData) return e.characterDataOldValue ? l(a) : r - }); - break; - case "DOMNodeRemoved": - this.addTransientObserver(e.target); - case "DOMNodeInserted": - var s, c, h = e.target; - "DOMNodeInserted" === e.type ? (s = [h], c = []) : (s = [], c = [h]); - var f = h.previousSibling, - p = h.nextSibling, - r = d("childList", e.target.parentNode); - r.addedNodes = s, r.removedNodes = c, r.previousSibling = f, r.nextSibling = p, i(e.relatedNode, function(e) { - if (e.childList) return r - }) - } - u() - } - }, e.JsMutationObserver = a, e.MutationObserver || (e.MutationObserver = a, a._isPolyfilled = !0) - } - }(self), - function() { - function e(e) { - switch (e) { - case "&": - return "&"; - case "<": - return "<"; - case ">": - return ">"; - case " ": - return " " - } - } - - function t(t) { - return t.replace(u, e) - } - var n = "undefined" == typeof HTMLTemplateElement; - /Trident/.test(navigator.userAgent) && ! function() { - var e = document.importNode; - document.importNode = function() { - var t = e.apply(document, arguments); - if (t.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { - var n = document.createDocumentFragment(); - return n.appendChild(t), n - } - return t - } - }(); - var o = function() { - if (!n) { - var e = document.createElement("template"), - t = document.createElement("template"); - t.content.appendChild(document.createElement("div")), e.content.appendChild(t); - var o = e.cloneNode(!0); - return 0 === o.content.childNodes.length || 0 === o.content.firstChild.content.childNodes.length - } - }(), - r = "template", - i = function() {}; - if (n) { - var a = document.implementation.createHTMLDocument("template"), - s = !0, - c = document.createElement("style"); - c.textContent = r + "{display:none;}"; - var d = document.head; - d.insertBefore(c, d.firstElementChild), i.prototype = Object.create(HTMLElement.prototype), i.decorate = function(e) { - if (!e.content) { - e.content = a.createDocumentFragment(); - for (var n; n = e.firstChild;) e.content.appendChild(n); - if (e.cloneNode = function(e) { - return i.cloneNode(this, e) - }, s) try { - Object.defineProperty(e, "innerHTML", { - get: function() { - for (var e = "", n = this.content.firstChild; n; n = n.nextSibling) e += n.outerHTML || t(n.data); - return e - }, - set: function(e) { - for (a.body.innerHTML = e, i.bootstrap(a); this.content.firstChild;) this.content.removeChild(this.content.firstChild); - for (; a.body.firstChild;) this.content.appendChild(a.body.firstChild) - }, - configurable: !0 - }) - } catch (o) { - s = !1 - } - i.bootstrap(e.content) - } - }, i.bootstrap = function(e) { - for (var t, n = e.querySelectorAll(r), o = 0, a = n.length; o < a && (t = n[o]); o++) i.decorate(t) - }, document.addEventListener("DOMContentLoaded", function() { - i.bootstrap(document) - }); - var l = document.createElement; - document.createElement = function() { - "use strict"; - var e = l.apply(document, arguments); - return "template" === e.localName && i.decorate(e), e - }; - var u = /[&\u00A0<>]/g - } - if (n || o) { - var h = Node.prototype.cloneNode; - i.cloneNode = function(e, t) { - var n = h.call(e, !1); - return this.decorate && this.decorate(n), t && (n.content.appendChild(h.call(e.content, !0)), this.fixClonedDom(n.content, e.content)), n - }, i.fixClonedDom = function(e, t) { - if (t.querySelectorAll) - for (var n, o, i = t.querySelectorAll(r), a = e.querySelectorAll(r), s = 0, c = a.length; s < c; s++) o = i[s], n = a[s], this.decorate && this.decorate(o), n.parentNode.replaceChild(o.cloneNode(!0), n) - }; - var f = document.importNode; - Node.prototype.cloneNode = function(e) { - var t = h.call(this, e); - return e && i.fixClonedDom(t, this), t - }, document.importNode = function(e, t) { - if (e.localName === r) return i.cloneNode(e, t); - var n = f.call(document, e, t); - return t && i.fixClonedDom(n, e), n - }, o && (HTMLTemplateElement.prototype.cloneNode = function(e) { - return i.cloneNode(this, e) - }) - } - n && (window.HTMLTemplateElement = i) - }(), - function(e) { - "use strict"; - if (!window.performance || !window.performance.now) { - var t = Date.now(); - window.performance = { - now: function() { - return Date.now() - t - } - } - } - window.requestAnimationFrame || (window.requestAnimationFrame = function() { - var e = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame; - return e ? function(t) { - return e(function() { - t(performance.now()) - }) - } : function(e) { - return window.setTimeout(e, 1e3 / 60) - } - }()), window.cancelAnimationFrame || (window.cancelAnimationFrame = function() { - return window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function(e) { - clearTimeout(e) - } - }()); - var n = function() { - var e = document.createEvent("Event"); - return e.initEvent("foo", !0, !0), e.preventDefault(), e.defaultPrevented - }(); - if (!n) { - var o = Event.prototype.preventDefault; - Event.prototype.preventDefault = function() { - this.cancelable && (o.call(this), Object.defineProperty(this, "defaultPrevented", { - get: function() { - return !0 - }, - configurable: !0 - })) - } - } - var r = /Trident/.test(navigator.userAgent); - if ((!window.CustomEvent || r && "function" != typeof window.CustomEvent) && (window.CustomEvent = function(e, t) { - t = t || {}; - var n = document.createEvent("CustomEvent"); - return n.initCustomEvent(e, Boolean(t.bubbles), Boolean(t.cancelable), t.detail), n - }, window.CustomEvent.prototype = window.Event.prototype), !window.Event || r && "function" != typeof window.Event) { - var i = window.Event; - window.Event = function(e, t) { - t = t || {}; - var n = document.createEvent("Event"); - return n.initEvent(e, Boolean(t.bubbles), Boolean(t.cancelable)), n - }, window.Event.prototype = i.prototype - } - }(window.WebComponents), window.HTMLImports = window.HTMLImports || { - flags: {} - }, - function(e) { - function t(e, t) { - t = t || p, o(function() { - i(e, t) - }, t) - } - - function n(e) { - return "complete" === e.readyState || e.readyState === w - } - - function o(e, t) { - if (n(t)) e && e(); - else { - var r = function() { - "complete" !== t.readyState && t.readyState !== w || (t.removeEventListener(_, r), o(e, t)) - }; - t.addEventListener(_, r) - } - } - - function r(e) { - e.target.__loaded = !0 - } - - function i(e, t) { - function n() { - c == d && e && e({ - allImports: s, - loadedImports: l, - errorImports: u - }) - } - - function o(e) { - r(e), l.push(this), c++, n() - } - - function i(e) { - u.push(this), c++, n() - } - var s = t.querySelectorAll("link[rel=import]"), - c = 0, - d = s.length, - l = [], - u = []; - if (d) - for (var h, f = 0; f < d && (h = s[f]); f++) a(h) ? (l.push(this), c++, n()) : (h.addEventListener("load", o), h.addEventListener("error", i)); - else n() - } - - function a(e) { - return u ? e.__loaded || e["import"] && "loading" !== e["import"].readyState : e.__importParsed - } - - function s(e) { - for (var t, n = 0, o = e.length; n < o && (t = e[n]); n++) c(t) && d(t) - } - - function c(e) { - return "link" === e.localName && "import" === e.rel - } - - function d(e) { - var t = e["import"]; - t ? r({ - target: e - }) : (e.addEventListener("load", r), e.addEventListener("error", r)) - } - var l = "import", - u = Boolean(l in document.createElement("link")), - h = Boolean(window.ShadowDOMPolyfill), - f = function(e) { - return h ? window.ShadowDOMPolyfill.wrapIfNeeded(e) : e - }, - p = f(document), - m = { - get: function() { - var e = window.HTMLImports.currentScript || document.currentScript || ("complete" !== document.readyState ? document.scripts[document.scripts.length - 1] : null); - return f(e) - }, - configurable: !0 - }; - Object.defineProperty(document, "_currentScript", m), Object.defineProperty(p, "_currentScript", m); - var v = /Trident/.test(navigator.userAgent), - w = v ? "complete" : "interactive", - _ = "readystatechange"; - u && (new MutationObserver(function(e) { - for (var t, n = 0, o = e.length; n < o && (t = e[n]); n++) t.addedNodes && s(t.addedNodes) - }).observe(document.head, { - childList: !0 - }), function() { - if ("loading" === document.readyState) - for (var e, t = document.querySelectorAll("link[rel=import]"), n = 0, o = t.length; n < o && (e = t[n]); n++) d(e) - }()), t(function(e) { - window.HTMLImports.ready = !0, window.HTMLImports.readyTime = (new Date).getTime(); - var t = p.createEvent("CustomEvent"); - t.initCustomEvent("HTMLImportsLoaded", !0, !0, e), p.dispatchEvent(t) - }), e.IMPORT_LINK_TYPE = l, e.useNative = u, e.rootDocument = p, e.whenReady = t, e.isIE = v - }(window.HTMLImports), - function(e) { - var t = [], - n = function(e) { - t.push(e) - }, - o = function() { - t.forEach(function(t) { - t(e) - }) - }; - e.addModule = n, e.initializeModules = o - }(window.HTMLImports), window.HTMLImports.addModule(function(e) { - var t = /(url\()([^)]*)(\))/g, - n = /(@import[\s]+(?!url\())([^;]*)(;)/g, - o = { - resolveUrlsInStyle: function(e, t) { - var n = e.ownerDocument, - o = n.createElement("a"); - return e.textContent = this.resolveUrlsInCssText(e.textContent, t, o), e - }, - resolveUrlsInCssText: function(e, o, r) { - var i = this.replaceUrls(e, r, o, t); - return i = this.replaceUrls(i, r, o, n) - }, - replaceUrls: function(e, t, n, o) { - return e.replace(o, function(e, o, r, i) { - var a = r.replace(/["']/g, ""); - return n && (a = new URL(a, n).href), t.href = a, a = t.href, o + "'" + a + "'" + i - }) - } - }; - e.path = o - }), window.HTMLImports.addModule(function(e) { - var t = { - async: !0, - ok: function(e) { - return e.status >= 200 && e.status < 300 || 304 === e.status || 0 === e.status - }, - load: function(n, o, r) { - var i = new XMLHttpRequest; - return (e.flags.debug || e.flags.bust) && (n += "?" + Math.random()), i.open("GET", n, t.async), i.addEventListener("readystatechange", function(e) { - if (4 === i.readyState) { - var n = null; - try { - var a = i.getResponseHeader("Location"); - a && (n = "/" === a.substr(0, 1) ? location.origin + a : a) - } catch (e) { - console.error(e.message) - } - o.call(r, !t.ok(i) && i, i.response || i.responseText, n) - } - }), i.send(), i - }, - loadDocument: function(e, t, n) { - this.load(e, t, n).responseType = "document" - } - }; - e.xhr = t - }), window.HTMLImports.addModule(function(e) { - var t = e.xhr, - n = e.flags, - o = function(e, t) { - this.cache = {}, this.onload = e, this.oncomplete = t, this.inflight = 0, this.pending = {} - }; - o.prototype = { - addNodes: function(e) { - this.inflight += e.length; - for (var t, n = 0, o = e.length; n < o && (t = e[n]); n++) this.require(t); - this.checkDone() - }, - addNode: function(e) { - this.inflight++, this.require(e), this.checkDone() - }, - require: function(e) { - var t = e.src || e.href; - e.__nodeUrl = t, this.dedupe(t, e) || this.fetch(t, e) - }, - dedupe: function(e, t) { - if (this.pending[e]) return this.pending[e].push(t), !0; - return this.cache[e] ? (this.onload(e, t, this.cache[e]), this.tail(), !0) : (this.pending[e] = [t], !1) - }, - fetch: function(e, o) { - if (n.load && console.log("fetch", e, o), e) - if (e.match(/^data:/)) { - var r = e.split(","), - i = r[0], - a = r[1]; - a = i.indexOf(";base64") > -1 ? atob(a) : decodeURIComponent(a), setTimeout(function() { - this.receive(e, o, null, a) - }.bind(this), 0) - } else { - var s = function(t, n, r) { - this.receive(e, o, t, n, r) - }.bind(this); - t.load(e, s) - } - else setTimeout(function() { - this.receive(e, o, { - error: "href must be specified" - }, null) - }.bind(this), 0) - }, - receive: function(e, t, n, o, r) { - this.cache[e] = o; - for (var i, a = this.pending[e], s = 0, c = a.length; s < c && (i = a[s]); s++) this.onload(e, i, o, n, r), this.tail(); - this.pending[e] = null - }, - tail: function() { - --this.inflight, this.checkDone() - }, - checkDone: function() { - this.inflight || this.oncomplete() - } - }, e.Loader = o - }), window.HTMLImports.addModule(function(e) { - var t = function(e) { - this.addCallback = e, this.mo = new MutationObserver(this.handler.bind(this)) - }; - t.prototype = { - handler: function(e) { - for (var t, n = 0, o = e.length; n < o && (t = e[n]); n++) "childList" === t.type && t.addedNodes.length && this.addedNodes(t.addedNodes) - }, - addedNodes: function(e) { - this.addCallback && this.addCallback(e); - for (var t, n = 0, o = e.length; n < o && (t = e[n]); n++) t.children && t.children.length && this.addedNodes(t.children) - }, - observe: function(e) { - this.mo.observe(e, { - childList: !0, - subtree: !0 - }) - } - }, e.Observer = t - }), window.HTMLImports.addModule(function(e) { - function t(e) { - return "link" === e.localName && e.rel === l - } - - function n(e) { - var t = o(e); - return "data:text/javascript;charset=utf-8," + encodeURIComponent(t) - } - - function o(e) { - return e.textContent + r(e) - } - - function r(e) { - var t = e.ownerDocument; - t.__importedScripts = t.__importedScripts || 0; - var n = e.ownerDocument.baseURI, - o = t.__importedScripts ? "-" + t.__importedScripts : ""; - return t.__importedScripts++, "\n//# sourceURL=" + n + o + ".js\n" - } - - function i(e) { - var t = e.ownerDocument.createElement("style"); - return t.textContent = e.textContent, a.resolveUrlsInStyle(t), t - } - var a = e.path, - s = e.rootDocument, - c = e.flags, - d = e.isIE, - l = e.IMPORT_LINK_TYPE, - u = "link[rel=" + l + "]", - h = { - documentSelectors: u, - importsSelectors: [u, "link[rel=stylesheet]:not([type])", "style:not([type])", "script:not([type])", 'script[type="application/javascript"]', 'script[type="text/javascript"]'].join(","), - map: { - link: "parseLink", - script: "parseScript", - style: "parseStyle" - }, - dynamicElements: [], - parseNext: function() { - var e = this.nextToParse(); - e && this.parse(e) - }, - parse: function(e) { - if (this.isParsed(e)) return void(c.parse && console.log("[%s] is already parsed", e.localName)); - var t = this[this.map[e.localName]]; - t && (this.markParsing(e), t.call(this, e)) - }, - parseDynamic: function(e, t) { - this.dynamicElements.push(e), t || this.parseNext() - }, - markParsing: function(e) { - c.parse && console.log("parsing", e), this.parsingElement = e - }, - markParsingComplete: function(e) { - e.__importParsed = !0, this.markDynamicParsingComplete(e), e.__importElement && (e.__importElement.__importParsed = !0, this.markDynamicParsingComplete(e.__importElement)), this.parsingElement = null, c.parse && console.log("completed", e) - }, - markDynamicParsingComplete: function(e) { - var t = this.dynamicElements.indexOf(e); - t >= 0 && this.dynamicElements.splice(t, 1) - }, - parseImport: function(e) { - if (e["import"] = e.__doc, window.HTMLImports.__importsParsingHook && window.HTMLImports.__importsParsingHook(e), e["import"] && (e["import"].__importParsed = !0), this.markParsingComplete(e), e.__resource && !e.__error ? e.dispatchEvent(new CustomEvent("load", { - bubbles: !1 - })) : e.dispatchEvent(new CustomEvent("error", { - bubbles: !1 - })), e.__pending) - for (var t; e.__pending.length;) t = e.__pending.shift(), t && t({ - target: e - }); - this.parseNext() - }, - parseLink: function(e) { - t(e) ? this.parseImport(e) : (e.href = e.href, this.parseGeneric(e)) - }, - parseStyle: function(e) { - var t = e; - e = i(e), t.__appliedElement = e, e.__importElement = t, this.parseGeneric(e) - }, - parseGeneric: function(e) { - this.trackElement(e), this.addElementToDocument(e) - }, - rootImportForElement: function(e) { - for (var t = e; t.ownerDocument.__importLink;) t = t.ownerDocument.__importLink; - return t - }, - addElementToDocument: function(e) { - var t = this.rootImportForElement(e.__importElement || e); - t.parentNode.insertBefore(e, t) - }, - trackElement: function(e, t) { - var n = this, - o = function(r) { - e.removeEventListener("load", o), e.removeEventListener("error", o), t && t(r), n.markParsingComplete(e), n.parseNext() - }; - if (e.addEventListener("load", o), e.addEventListener("error", o), d && "style" === e.localName) { - var r = !1; - if (e.textContent.indexOf("@import") == -1) r = !0; - else if (e.sheet) { - r = !0; - for (var i, a = e.sheet.cssRules, s = a ? a.length : 0, c = 0; c < s && (i = a[c]); c++) i.type === CSSRule.IMPORT_RULE && (r = r && Boolean(i.styleSheet)) - } - r && setTimeout(function() { - e.dispatchEvent(new CustomEvent("load", { - bubbles: !1 - })) - }) - } - }, - parseScript: function(t) { - var o = document.createElement("script"); - o.__importElement = t, o.src = t.src ? t.src : n(t), e.currentScript = t, this.trackElement(o, function(t) { - o.parentNode && o.parentNode.removeChild(o), e.currentScript = null - }), this.addElementToDocument(o) - }, - nextToParse: function() { - return this._mayParse = [], !this.parsingElement && (this.nextToParseInDoc(s) || this.nextToParseDynamic()) - }, - nextToParseInDoc: function(e, n) { - if (e && this._mayParse.indexOf(e) < 0) { - this._mayParse.push(e); - for (var o, r = e.querySelectorAll(this.parseSelectorsForNode(e)), i = 0, a = r.length; i < a && (o = r[i]); i++) - if (!this.isParsed(o)) return this.hasResource(o) ? t(o) ? this.nextToParseInDoc(o.__doc, o) : o : void 0 - } - return n - }, - nextToParseDynamic: function() { - return this.dynamicElements[0] - }, - parseSelectorsForNode: function(e) { - var t = e.ownerDocument || e; - return t === s ? this.documentSelectors : this.importsSelectors - }, - isParsed: function(e) { - return e.__importParsed - }, - needsDynamicParsing: function(e) { - return this.dynamicElements.indexOf(e) >= 0 - }, - hasResource: function(e) { - return !t(e) || void 0 !== e.__doc - } - }; - e.parser = h, e.IMPORT_SELECTOR = u - }), window.HTMLImports.addModule(function(e) { - function t(e) { - return n(e, a) - } - - function n(e, t) { - return "link" === e.localName && e.getAttribute("rel") === t - } - - function o(e) { - return !!Object.getOwnPropertyDescriptor(e, "baseURI") - } - - function r(e, t) { - var n = document.implementation.createHTMLDocument(a); - n._URL = t; - var r = n.createElement("base"); - r.setAttribute("href", t), n.baseURI || o(n) || Object.defineProperty(n, "baseURI", { - value: t - }); - var i = n.createElement("meta"); - return i.setAttribute("charset", "utf-8"), n.head.appendChild(i), n.head.appendChild(r), n.body.innerHTML = e, window.HTMLTemplateElement && HTMLTemplateElement.bootstrap && HTMLTemplateElement.bootstrap(n), n - } - var i = e.flags, - a = e.IMPORT_LINK_TYPE, - s = e.IMPORT_SELECTOR, - c = e.rootDocument, - d = e.Loader, - l = e.Observer, - u = e.parser, - h = { - documents: {}, - documentPreloadSelectors: s, - importsPreloadSelectors: [s].join(","), - loadNode: function(e) { - f.addNode(e) - }, - loadSubtree: function(e) { - var t = this.marshalNodes(e); - f.addNodes(t) - }, - marshalNodes: function(e) { - return e.querySelectorAll(this.loadSelectorsForNode(e)) - }, - loadSelectorsForNode: function(e) { - var t = e.ownerDocument || e; - return t === c ? this.documentPreloadSelectors : this.importsPreloadSelectors - }, - loaded: function(e, n, o, a, s) { - if (i.load && console.log("loaded", e, n), n.__resource = o, n.__error = a, t(n)) { - var c = this.documents[e]; - void 0 === c && (c = a ? null : r(o, s || e), c && (c.__importLink = n, this.bootDocument(c)), this.documents[e] = c), n.__doc = c - } - u.parseNext() - }, - bootDocument: function(e) { - this.loadSubtree(e), this.observer.observe(e), u.parseNext() - }, - loadedAll: function() { - u.parseNext() - } - }, - f = new d(h.loaded.bind(h), h.loadedAll.bind(h)); - if (h.observer = new l, !document.baseURI) { - var p = { - get: function() { - var e = document.querySelector("base"); - return e ? e.href : window.location.href - }, - configurable: !0 - }; - Object.defineProperty(document, "baseURI", p), Object.defineProperty(c, "baseURI", p) - } - e.importer = h, e.importLoader = f - }), window.HTMLImports.addModule(function(e) { - var t = e.parser, - n = e.importer, - o = { - added: function(e) { - for (var o, r, i, a, s = 0, c = e.length; s < c && (a = e[s]); s++) o || (o = a.ownerDocument, r = t.isParsed(o)), i = this.shouldLoadNode(a), i && n.loadNode(a), this.shouldParseNode(a) && r && t.parseDynamic(a, i) - }, - shouldLoadNode: function(e) { - return 1 === e.nodeType && r.call(e, n.loadSelectorsForNode(e)) - }, - shouldParseNode: function(e) { - return 1 === e.nodeType && r.call(e, t.parseSelectorsForNode(e)) - } - }; - n.observer.addCallback = o.added.bind(o); - var r = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector - }), - function(e) { - function t() { - window.HTMLImports.importer.bootDocument(o) - } - var n = e.initializeModules; - e.isIE; - if (!e.useNative) { - n(); - var o = e.rootDocument; - "complete" === document.readyState || "interactive" === document.readyState && !window.attachEvent ? t() : document.addEventListener("DOMContentLoaded", t) - } - }(window.HTMLImports), window.CustomElements = window.CustomElements || { - flags: {} - }, - function(e) { - var t = e.flags, - n = [], - o = function(e) { - n.push(e) - }, - r = function() { - n.forEach(function(t) { - t(e) - }) - }; - e.addModule = o, e.initializeModules = r, e.hasNative = Boolean(document.registerElement), e.isIE = /Trident/.test(navigator.userAgent), e.useNative = !t.register && e.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || window.HTMLImports.useNative) - }(window.CustomElements), window.CustomElements.addModule(function(e) { - function t(e, t) { - n(e, function(e) { - return !!t(e) || void o(e, t) - }), o(e, t) - } - - function n(e, t, o) { - var r = e.firstElementChild; - if (!r) - for (r = e.firstChild; r && r.nodeType !== Node.ELEMENT_NODE;) r = r.nextSibling; - for (; r;) t(r, o) !== !0 && n(r, t, o), r = r.nextElementSibling; - return null - } - - function o(e, n) { - for (var o = e.shadowRoot; o;) t(o, n), o = o.olderShadowRoot - } - - function r(e, t) { - i(e, t, []) - } - - function i(e, t, n) { - if (e = window.wrap(e), !(n.indexOf(e) >= 0)) { - n.push(e); - for (var o, r = e.querySelectorAll("link[rel=" + a + "]"), s = 0, c = r.length; s < c && (o = r[s]); s++) o["import"] && i(o["import"], t, n); - t(e) - } - } - var a = window.HTMLImports ? window.HTMLImports.IMPORT_LINK_TYPE : "none"; - e.forDocumentTree = r, e.forSubtree = t - }), window.CustomElements.addModule(function(e) { - function t(e, t) { - return n(e, t) || o(e, t) - } - - function n(t, n) { - return !!e.upgrade(t, n) || void(n && a(t)) - } - - function o(e, t) { - g(e, function(e) { - if (n(e, t)) return !0 - }) - } - - function r(e) { - L.push(e), E || (E = !0, setTimeout(i)) - } - - function i() { - E = !1; - for (var e, t = L, n = 0, o = t.length; n < o && (e = t[n]); n++) e(); - L = [] - } - - function a(e) { - y ? r(function() { - s(e); - }) : s(e) - } - - function s(e) { - e.__upgraded__ && !e.__attached && (e.__attached = !0, e.attachedCallback && e.attachedCallback()) - } - - function c(e) { - d(e), g(e, function(e) { - d(e) - }) - } - - function d(e) { - y ? r(function() { - l(e) - }) : l(e) - } - - function l(e) { - e.__upgraded__ && e.__attached && (e.__attached = !1, e.detachedCallback && e.detachedCallback()) - } - - function u(e) { - for (var t = e, n = window.wrap(document); t;) { - if (t == n) return !0; - t = t.parentNode || t.nodeType === Node.DOCUMENT_FRAGMENT_NODE && t.host - } - } - - function h(e) { - if (e.shadowRoot && !e.shadowRoot.__watched) { - _.dom && console.log("watching shadow-root for: ", e.localName); - for (var t = e.shadowRoot; t;) m(t), t = t.olderShadowRoot - } - } - - function f(e, n) { - if (_.dom) { - var o = n[0]; - if (o && "childList" === o.type && o.addedNodes && o.addedNodes) { - for (var r = o.addedNodes[0]; r && r !== document && !r.host;) r = r.parentNode; - var i = r && (r.URL || r._URL || r.host && r.host.localName) || ""; - i = i.split("/?").shift().split("/").pop() - } - console.group("mutations (%d) [%s]", n.length, i || "") - } - var a = u(e); - n.forEach(function(e) { - "childList" === e.type && (N(e.addedNodes, function(e) { - e.localName && t(e, a) - }), N(e.removedNodes, function(e) { - e.localName && c(e) - })) - }), _.dom && console.groupEnd() - } - - function p(e) { - for (e = window.wrap(e), e || (e = window.wrap(document)); e.parentNode;) e = e.parentNode; - var t = e.__observer; - t && (f(e, t.takeRecords()), i()) - } - - function m(e) { - if (!e.__observer) { - var t = new MutationObserver(f.bind(this, e)); - t.observe(e, { - childList: !0, - subtree: !0 - }), e.__observer = t - } - } - - function v(e) { - e = window.wrap(e), _.dom && console.group("upgradeDocument: ", e.baseURI.split("/").pop()); - var n = e === window.wrap(document); - t(e, n), m(e), _.dom && console.groupEnd() - } - - function w(e) { - b(e, v) - } - var _ = e.flags, - g = e.forSubtree, - b = e.forDocumentTree, - y = window.MutationObserver._isPolyfilled && _["throttle-attached"]; - e.hasPolyfillMutations = y, e.hasThrottledAttached = y; - var E = !1, - L = [], - N = Array.prototype.forEach.call.bind(Array.prototype.forEach), - M = Element.prototype.createShadowRoot; - M && (Element.prototype.createShadowRoot = function() { - var e = M.call(this); - return window.CustomElements.watchShadow(this), e - }), e.watchShadow = h, e.upgradeDocumentTree = w, e.upgradeDocument = v, e.upgradeSubtree = o, e.upgradeAll = t, e.attached = a, e.takeRecords = p - }), window.CustomElements.addModule(function(e) { - function t(t, o) { - if ("template" === t.localName && window.HTMLTemplateElement && HTMLTemplateElement.decorate && HTMLTemplateElement.decorate(t), !t.__upgraded__ && t.nodeType === Node.ELEMENT_NODE) { - var r = t.getAttribute("is"), - i = e.getRegisteredDefinition(t.localName) || e.getRegisteredDefinition(r); - if (i && (r && i.tag == t.localName || !r && !i["extends"])) return n(t, i, o) - } - } - - function n(t, n, r) { - return a.upgrade && console.group("upgrade:", t.localName), n.is && t.setAttribute("is", n.is), o(t, n), t.__upgraded__ = !0, i(t), r && e.attached(t), e.upgradeSubtree(t, r), a.upgrade && console.groupEnd(), t - } - - function o(e, t) { - Object.__proto__ ? e.__proto__ = t.prototype : (r(e, t.prototype, t["native"]), e.__proto__ = t.prototype) - } - - function r(e, t, n) { - for (var o = {}, r = t; r !== n && r !== HTMLElement.prototype;) { - for (var i, a = Object.getOwnPropertyNames(r), s = 0; i = a[s]; s++) o[i] || (Object.defineProperty(e, i, Object.getOwnPropertyDescriptor(r, i)), o[i] = 1); - r = Object.getPrototypeOf(r) - } - } - - function i(e) { - e.createdCallback && e.createdCallback() - } - var a = e.flags; - e.upgrade = t, e.upgradeWithDefinition = n, e.implementPrototype = o - }), window.CustomElements.addModule(function(e) { - function t(t, o) { - var c = o || {}; - if (!t) throw new Error("document.registerElement: first argument `name` must not be empty"); - if (t.indexOf("-") < 0) throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(t) + "'."); - if (r(t)) throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(t) + "'. The type name is invalid."); - if (d(t)) throw new Error("DuplicateDefinitionError: a type with name '" + String(t) + "' is already registered"); - return c.prototype || (c.prototype = Object.create(HTMLElement.prototype)), c.__name = t.toLowerCase(), c["extends"] && (c["extends"] = c["extends"].toLowerCase()), c.lifecycle = c.lifecycle || {}, c.ancestry = i(c["extends"]), a(c), s(c), n(c.prototype), l(c.__name, c), c.ctor = u(c), c.ctor.prototype = c.prototype, c.prototype.constructor = c.ctor, e.ready && v(document), c.ctor - } - - function n(e) { - if (!e.setAttribute._polyfilled) { - var t = e.setAttribute; - e.setAttribute = function(e, n) { - o.call(this, e, n, t) - }; - var n = e.removeAttribute; - e.removeAttribute = function(e) { - o.call(this, e, null, n) - }, e.setAttribute._polyfilled = !0 - } - } - - function o(e, t, n) { - e = e.toLowerCase(); - var o = this.getAttribute(e); - n.apply(this, arguments); - var r = this.getAttribute(e); - this.attributeChangedCallback && r !== o && this.attributeChangedCallback(e, o, r) - } - - function r(e) { - for (var t = 0; t < y.length; t++) - if (e === y[t]) return !0 - } - - function i(e) { - var t = d(e); - return t ? i(t["extends"]).concat([t]) : [] - } - - function a(e) { - for (var t, n = e["extends"], o = 0; t = e.ancestry[o]; o++) n = t.is && t.tag; - e.tag = n || e.__name, n && (e.is = e.__name) - } - - function s(e) { - if (!Object.__proto__) { - var t = HTMLElement.prototype; - if (e.is) { - var n = document.createElement(e.tag); - t = Object.getPrototypeOf(n) - } - for (var o, r = e.prototype, i = !1; r;) r == t && (i = !0), o = Object.getPrototypeOf(r), o && (r.__proto__ = o), r = o; - i || console.warn(e.tag + " prototype not found in prototype chain for " + e.is), e["native"] = t - } - } - - function c(e) { - return _(N(e.tag), e) - } - - function d(e) { - if (e) return E[e.toLowerCase()] - } - - function l(e, t) { - E[e] = t - } - - function u(e) { - return function() { - return c(e) - } - } - - function h(e, t, n) { - return e === L ? f(t, n) : M(e, t) - } - - function f(e, t) { - e && (e = e.toLowerCase()), t && (t = t.toLowerCase()); - var n = d(t || e); - if (n) { - if (e == n.tag && t == n.is) return new n.ctor; - if (!t && !n.is) return new n.ctor - } - var o; - return t ? (o = f(e), o.setAttribute("is", t), o) : (o = N(e), e.indexOf("-") >= 0 && g(o, HTMLElement), o) - } - - function p(e, t) { - var n = e[t]; - e[t] = function() { - var e = n.apply(this, arguments); - return w(e), e - } - } - var m, v = (e.isIE, e.upgradeDocumentTree), - w = e.upgradeAll, - _ = e.upgradeWithDefinition, - g = e.implementPrototype, - b = e.useNative, - y = ["annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph"], - E = {}, - L = "http://www.w3.org/1999/xhtml", - N = document.createElement.bind(document), - M = document.createElementNS.bind(document); - m = Object.__proto__ || b ? function(e, t) { - return e instanceof t - } : function(e, t) { - if (e instanceof t) return !0; - for (var n = e; n;) { - if (n === t.prototype) return !0; - n = n.__proto__ - } - return !1 - }, p(Node.prototype, "cloneNode"), p(document, "importNode"), document.registerElement = t, document.createElement = f, document.createElementNS = h, e.registry = E, e["instanceof"] = m, e.reservedTagList = y, e.getRegisteredDefinition = d, document.register = document.registerElement - }), - function(e) { - function t() { - i(window.wrap(document)), window.CustomElements.ready = !0; - var e = window.requestAnimationFrame || function(e) { - setTimeout(e, 16) - }; - e(function() { - setTimeout(function() { - window.CustomElements.readyTime = Date.now(), window.HTMLImports && (window.CustomElements.elapsed = window.CustomElements.readyTime - window.HTMLImports.readyTime), document.dispatchEvent(new CustomEvent("WebComponentsReady", { - bubbles: !0 - })) - }) - }) - } - var n = e.useNative, - o = e.initializeModules; - e.isIE; - if (n) { - var r = function() {}; - e.watchShadow = r, e.upgrade = r, e.upgradeAll = r, e.upgradeDocumentTree = r, e.upgradeSubtree = r, e.takeRecords = r, e["instanceof"] = function(e, t) { - return e instanceof t - } - } else o(); - var i = e.upgradeDocumentTree, - a = e.upgradeDocument; - if (window.wrap || (window.ShadowDOMPolyfill ? (window.wrap = window.ShadowDOMPolyfill.wrapIfNeeded, window.unwrap = window.ShadowDOMPolyfill.unwrapIfNeeded) : window.wrap = window.unwrap = function(e) { - return e - }), window.HTMLImports && (window.HTMLImports.__importsParsingHook = function(e) { - e["import"] && a(wrap(e["import"])) - }), "complete" === document.readyState || e.flags.eager) t(); - else if ("interactive" !== document.readyState || window.attachEvent || window.HTMLImports && !window.HTMLImports.ready) { - var s = window.HTMLImports && !window.HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded"; - window.addEventListener(s, t) - } else t() - }(window.CustomElements), - function(e) { - var t = document.createElement("style"); - t.textContent = "body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n"; - var n = document.querySelector("head"); - n.insertBefore(t, n.firstChild) - }(window.WebComponents); \ No newline at end of file diff --git a/src/bundle.js b/src/bundle.js index 86e10aab7d..4643b23f0d 100644 --- a/src/bundle.js +++ b/src/bundle.js @@ -4,6 +4,14 @@ // Use define from require.js not webpack's define var _define = window.define; +// document-register-element +var docRegister = require("document-register-element"); +_define("document-register-element", function() { return docRegister; }); + +// fetch +var fetch = require("whatwg-fetch"); +_define("fetch", function() { return fetch }); + // flvjs var flvjs = require("flv.js"); _define("flvjs", function() { return flvjs; }); @@ -25,6 +33,14 @@ _define("hlsjs", function() { return hlsjs; }); var howler = require("howler"); _define("howler", function() { return howler; }); +// native-promise-only +var nativePromise = require("native-promise-only"); +_define("native-promise-only", function() { return nativePromise; }); + +// resize-observer-polyfill +var resize = require("resize-observer-polyfill"); +_define("resize-observer-polyfill", function() { return resize; }); + // shaka var shaka = require("shaka-player"); _define("shaka", function() { return shaka; }); @@ -38,6 +54,10 @@ _define("swiper", function() { return swiper; }); var sortable = require("sortablejs"); _define("sortable", function() { return sortable; }); +// webcomponents +var webcomponents = require("webcomponents.js-2"); +_define("webcomponents", function() { return webcomponents }); + // libjass var libjass = require("libjass"); require("libjass/libjass.css"); diff --git a/src/scripts/site.js b/src/scripts/site.js index b5fa85ac6c..48eb2d7c2a 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -387,7 +387,7 @@ var AppInfo = {}; return self.ResizeObserver; }); } else { - define("ResizeObserver", [getBowerPath() + "/resize-observer-polyfill/ResizeObserver"], returnFirstDependency); + define("ResizeObserver", ["resize-observer-polyfill"], returnFirstDependency); } } @@ -410,9 +410,9 @@ var AppInfo = {}; if ("registerElement" in document) { define("registerElement", []); } else if (browser.msie) { - define("registerElement", [bowerPath + "/webcomponentsjs/webcomponents-lite.min.js"], returnFirstDependency); + define("registerElement", ["webcomponents"], returnFirstDependency); } else { - define("registerElement", [bowerPath + "/document-register-element/build/document-register-element"], returnFirstDependency); + define("registerElement", ["document-register-element"], returnFirstDependency); } define("imageFetcher", [componentsPath + "/images/imageFetcher"], returnFirstDependency); @@ -632,7 +632,7 @@ var AppInfo = {}; } if (!window.Promise || browser.web0s) { - require([getBowerPath() + "/native-promise-only/lib/npo.src"], init); + require(["native-promise-only"], init); } else { init(); } @@ -681,15 +681,20 @@ var AppInfo = {}; }, bundles: { bundle: [ + "document-register-element", + "fetch", "flvjs", "jstree", "jQuery", "hlsjs", "howler", + "native-promise-only", + "resize-observer-polyfill", "shaka", "swiper", "sortable", - "libjass" + "libjass", + "webcomponents" ] }, urlArgs: urlArgs, @@ -743,7 +748,7 @@ var AppInfo = {}; // also pull out these libs define("page", [bowerPath + "/page"], returnFirstDependency); - define("fetch", [bowerPath + "/fetch/fetch"], returnFirstDependency); + define("fetch", ["fetch"], returnFirstDependency); define("queryString", [bowerPath + "/query-string/index"], function () { return queryString; }); diff --git a/webpack.common.js b/webpack.common.js index f0d03bc4cd..59a1c4e55e 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -1,6 +1,8 @@ const path = require("path"); -const { CleanWebpackPlugin} = require("clean-webpack-plugin"); + +const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const CopyPlugin = require("copy-webpack-plugin"); + const Assets = [ "alameda/alameda.js", "requirejs/require.js" From b12442703979706352b286040a369fa9565b68f7 Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 11 Nov 2019 01:47:28 +0900 Subject: [PATCH 13/42] move remaining libraries to new folder --- src/{bower_components => libraries}/apiclient/apiclient.js | 2 +- .../apiclient/apiclientcore.js | 0 src/{bower_components => libraries}/apiclient/appStorage.js | 0 .../apiclient/connectionmanager.js | 0 .../apiclient/credentialprovider.js | 0 src/{bower_components => libraries}/apiclient/events.js | 0 .../apiclient/localassetmanager.js | 0 src/{bower_components => libraries}/apiclient/package.json | 0 .../apiclient/sync/filerepository.js | 0 .../apiclient/sync/itemrepository.js | 0 .../apiclient/sync/localsync.js | 0 .../apiclient/sync/mediasync.js | 0 .../apiclient/sync/multiserversync.js | 0 .../apiclient/sync/serversync.js | 0 .../apiclient/sync/transfermanager.js | 0 .../apiclient/sync/useractionrepository.js | 0 src/{bower_components => libraries/pagejs}/page.js | 0 src/{bower_components => libraries}/query-string/index.js | 0 src/{bower_components => libraries}/query-string/test.js | 0 src/scripts/site.js | 4 ++-- 20 files changed, 3 insertions(+), 3 deletions(-) rename src/{bower_components => libraries}/apiclient/apiclient.js (99%) rename src/{bower_components => libraries}/apiclient/apiclientcore.js (100%) rename src/{bower_components => libraries}/apiclient/appStorage.js (100%) rename src/{bower_components => libraries}/apiclient/connectionmanager.js (100%) rename src/{bower_components => libraries}/apiclient/credentialprovider.js (100%) rename src/{bower_components => libraries}/apiclient/events.js (100%) rename src/{bower_components => libraries}/apiclient/localassetmanager.js (100%) rename src/{bower_components => libraries}/apiclient/package.json (100%) rename src/{bower_components => libraries}/apiclient/sync/filerepository.js (100%) rename src/{bower_components => libraries}/apiclient/sync/itemrepository.js (100%) rename src/{bower_components => libraries}/apiclient/sync/localsync.js (100%) rename src/{bower_components => libraries}/apiclient/sync/mediasync.js (100%) rename src/{bower_components => libraries}/apiclient/sync/multiserversync.js (100%) rename src/{bower_components => libraries}/apiclient/sync/serversync.js (100%) rename src/{bower_components => libraries}/apiclient/sync/transfermanager.js (100%) rename src/{bower_components => libraries}/apiclient/sync/useractionrepository.js (100%) rename src/{bower_components => libraries/pagejs}/page.js (100%) rename src/{bower_components => libraries}/query-string/index.js (100%) rename src/{bower_components => libraries}/query-string/test.js (100%) diff --git a/src/bower_components/apiclient/apiclient.js b/src/libraries/apiclient/apiclient.js similarity index 99% rename from src/bower_components/apiclient/apiclient.js rename to src/libraries/apiclient/apiclient.js index 98aaed75e3..06d9cf0861 100644 --- a/src/bower_components/apiclient/apiclient.js +++ b/src/libraries/apiclient/apiclient.js @@ -1,5 +1,5 @@ //TODO: (vitorsemeano) modify this lines for webpack -define(["bower_components/apiclient/apiclientcore", "localassetmanager"], function(ApiClient, localassetmanager) { +define(["libraries/apiclient/apiclientcore", "localassetmanager"], function(ApiClient, localassetmanager) { "use strict"; if ("cordova" !== window.appMode && "android" !== window.appMode) { diff --git a/src/bower_components/apiclient/apiclientcore.js b/src/libraries/apiclient/apiclientcore.js similarity index 100% rename from src/bower_components/apiclient/apiclientcore.js rename to src/libraries/apiclient/apiclientcore.js diff --git a/src/bower_components/apiclient/appStorage.js b/src/libraries/apiclient/appStorage.js similarity index 100% rename from src/bower_components/apiclient/appStorage.js rename to src/libraries/apiclient/appStorage.js diff --git a/src/bower_components/apiclient/connectionmanager.js b/src/libraries/apiclient/connectionmanager.js similarity index 100% rename from src/bower_components/apiclient/connectionmanager.js rename to src/libraries/apiclient/connectionmanager.js diff --git a/src/bower_components/apiclient/credentialprovider.js b/src/libraries/apiclient/credentialprovider.js similarity index 100% rename from src/bower_components/apiclient/credentialprovider.js rename to src/libraries/apiclient/credentialprovider.js diff --git a/src/bower_components/apiclient/events.js b/src/libraries/apiclient/events.js similarity index 100% rename from src/bower_components/apiclient/events.js rename to src/libraries/apiclient/events.js diff --git a/src/bower_components/apiclient/localassetmanager.js b/src/libraries/apiclient/localassetmanager.js similarity index 100% rename from src/bower_components/apiclient/localassetmanager.js rename to src/libraries/apiclient/localassetmanager.js diff --git a/src/bower_components/apiclient/package.json b/src/libraries/apiclient/package.json similarity index 100% rename from src/bower_components/apiclient/package.json rename to src/libraries/apiclient/package.json diff --git a/src/bower_components/apiclient/sync/filerepository.js b/src/libraries/apiclient/sync/filerepository.js similarity index 100% rename from src/bower_components/apiclient/sync/filerepository.js rename to src/libraries/apiclient/sync/filerepository.js diff --git a/src/bower_components/apiclient/sync/itemrepository.js b/src/libraries/apiclient/sync/itemrepository.js similarity index 100% rename from src/bower_components/apiclient/sync/itemrepository.js rename to src/libraries/apiclient/sync/itemrepository.js diff --git a/src/bower_components/apiclient/sync/localsync.js b/src/libraries/apiclient/sync/localsync.js similarity index 100% rename from src/bower_components/apiclient/sync/localsync.js rename to src/libraries/apiclient/sync/localsync.js diff --git a/src/bower_components/apiclient/sync/mediasync.js b/src/libraries/apiclient/sync/mediasync.js similarity index 100% rename from src/bower_components/apiclient/sync/mediasync.js rename to src/libraries/apiclient/sync/mediasync.js diff --git a/src/bower_components/apiclient/sync/multiserversync.js b/src/libraries/apiclient/sync/multiserversync.js similarity index 100% rename from src/bower_components/apiclient/sync/multiserversync.js rename to src/libraries/apiclient/sync/multiserversync.js diff --git a/src/bower_components/apiclient/sync/serversync.js b/src/libraries/apiclient/sync/serversync.js similarity index 100% rename from src/bower_components/apiclient/sync/serversync.js rename to src/libraries/apiclient/sync/serversync.js diff --git a/src/bower_components/apiclient/sync/transfermanager.js b/src/libraries/apiclient/sync/transfermanager.js similarity index 100% rename from src/bower_components/apiclient/sync/transfermanager.js rename to src/libraries/apiclient/sync/transfermanager.js diff --git a/src/bower_components/apiclient/sync/useractionrepository.js b/src/libraries/apiclient/sync/useractionrepository.js similarity index 100% rename from src/bower_components/apiclient/sync/useractionrepository.js rename to src/libraries/apiclient/sync/useractionrepository.js diff --git a/src/bower_components/page.js b/src/libraries/pagejs/page.js similarity index 100% rename from src/bower_components/page.js rename to src/libraries/pagejs/page.js diff --git a/src/bower_components/query-string/index.js b/src/libraries/query-string/index.js similarity index 100% rename from src/bower_components/query-string/index.js rename to src/libraries/query-string/index.js diff --git a/src/bower_components/query-string/test.js b/src/libraries/query-string/test.js similarity index 100% rename from src/bower_components/query-string/test.js rename to src/libraries/query-string/test.js diff --git a/src/scripts/site.js b/src/scripts/site.js index 48eb2d7c2a..4ca730fd70 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -308,7 +308,7 @@ var AppInfo = {}; } function getBowerPath() { - return "bower_components"; + return "libraries"; } function getComponentsPath() { @@ -747,7 +747,7 @@ var AppInfo = {}; define("useractionrepository", [bowerPath + "/apiclient/sync/useractionrepository"], returnFirstDependency); // also pull out these libs - define("page", [bowerPath + "/page"], returnFirstDependency); + define("page", [bowerPath + "/pagejs/page"], returnFirstDependency); define("fetch", ["fetch"], returnFirstDependency); define("queryString", [bowerPath + "/query-string/index"], function () { return queryString; From ffd3886372e2f8dbd2899d102173587de8ca11c2 Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 11 Nov 2019 01:59:23 +0900 Subject: [PATCH 14/42] improve some comments --- src/scripts/site.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index 4ca730fd70..e05712c076 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -746,9 +746,10 @@ var AppInfo = {}; define("itemrepository", [bowerPath + "/apiclient/sync/itemrepository"], returnFirstDependency); define("useractionrepository", [bowerPath + "/apiclient/sync/useractionrepository"], returnFirstDependency); - // also pull out these libs + // TODO remove these libraries + // all three have been modified so we need to fix that first define("page", [bowerPath + "/pagejs/page"], returnFirstDependency); - define("fetch", ["fetch"], returnFirstDependency); + define("scroller", [componentsPath + "/scroller"], returnFirstDependency); define("queryString", [bowerPath + "/query-string/index"], function () { return queryString; }); @@ -848,7 +849,6 @@ var AppInfo = {}; define("sortMenu", [componentsPath + "/sortmenu/sortmenu"], returnFirstDependency); define("idb", [componentsPath + "/idb"], returnFirstDependency); define("sanitizefilename", [componentsPath + "/sanitizefilename"], returnFirstDependency); - define("scroller", [componentsPath + "/scroller"], returnFirstDependency); define("toast", [componentsPath + "/toast/toast"], returnFirstDependency); define("scrollHelper", [componentsPath + "/scrollhelper"], returnFirstDependency); define("touchHelper", [componentsPath + "/touchhelper"], returnFirstDependency); From ad8fe23ef80363c73d0fdf8d5b286fff61d27ef3 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com> Date: Mon, 11 Nov 2019 12:28:27 +0300 Subject: [PATCH 15/42] Make login card scalable on focus (#535) * Make login card scalable on focus * Remove focus related classes --- src/components/cardbuilder/card.css | 11 +++--- src/components/cardbuilder/cardBuilder.js | 38 +++++-------------- .../cardbuilder/chaptercardbuilder.js | 27 ++++++------- .../imagedownloader/imagedownloader.js | 16 +++++--- src/components/imageeditor/imageeditor.js | 14 ++++--- .../itemidentifier/itemidentifier.js | 16 +++++--- src/components/themes/appletv/theme.css | 5 ++- src/components/themes/blueradiance/theme.css | 5 ++- src/components/themes/dark/theme.css | 5 ++- src/components/themes/emby/theme.css | 5 ++- src/components/themes/light/theme.css | 5 ++- src/components/themes/purple-haze/theme.css | 5 ++- src/components/themes/wmc/theme.css | 5 ++- src/components/tunerpicker.js | 14 +++++-- src/controllers/livetvstatus.js | 14 +++++-- src/controllers/loginpage.js | 22 ++++++++++- src/controllers/selectserver.js | 20 +++++++--- 17 files changed, 131 insertions(+), 96 deletions(-) diff --git a/src/components/cardbuilder/card.css b/src/components/cardbuilder/card.css index 942e05c77a..874b6d0416 100644 --- a/src/components/cardbuilder/card.css +++ b/src/components/cardbuilder/card.css @@ -26,7 +26,7 @@ button { font-weight: inherit !important; } -.card-nofocustransform { +.card:not(.show-animation) { contain: layout style paint; } @@ -98,20 +98,21 @@ button { contain: layout style; } -.cardBox-withfocuscontent-large { +.card.show-focus:not(.show-animation) .cardBox { margin: .4em; } -.card-focuscontent-large { +.card.show-focus:not(.show-animation) .cardBox.visualCardBox, +.card.show-focus:not(.show-animation) .cardBox:not(.visualCardBox) .cardScalable { border: .5em solid transparent; } -.cardBox-focustransform { +.card.show-animation .cardBox { will-change: transform; transition: transform 200ms ease-out; } -.card:focus > .cardBox-focustransform { +.card.show-animation:focus > .cardBox { transform: scale(1.18, 1.18); } diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index d91802dc71..09ad8f1a6d 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -3,7 +3,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana 'use strict'; var devicePixelRatio = window.devicePixelRatio || 1; - var enableFocusTransfrom = !browser.slow && !browser.edge; + var enableFocusTransform = !browser.slow && !browser.edge; function getCardsHtml(items, options) { if (arguments.length === 1) { @@ -1203,6 +1203,8 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana shape = shape || 'mixedSquare'; } + // TODO move card creation code to Card component + var className = 'card'; if (shape) { @@ -1221,8 +1223,12 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana className += ' card-hoverable'; } - if (!enableFocusTransfrom || !layoutManager.tv) { - className += ' card-nofocustransform'; + if (layoutManager.tv) { + className += ' show-focus'; + + if (enableFocusTransform) { + className += ' show-animation'; + } } var imgInfo = getCardImageUrl(item, apiClient, options, shape); @@ -1250,23 +1256,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana var cardBoxClass = options.cardLayout ? 'cardBox visualCardBox' : 'cardBox'; - if (layoutManager.tv) { - - if (enableFocusTransfrom) { - cardBoxClass += ' cardBox-focustransform cardBox-withfocuscontent'; - } else { - cardBoxClass += ' cardBox-withfocuscontent-large'; - } - - if (options.cardLayout) { - cardBoxClass += ' card-focuscontent'; - - if (!enableFocusTransfrom) { - cardBoxClass += ' card-focuscontent-large'; - } - } - } - var footerCssClass; var progressHtml = indicators.getProgressBarHtml(item); @@ -1385,15 +1374,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana var cardScalableClass = 'cardScalable'; - if (layoutManager.tv && !options.cardLayout) { - - cardScalableClass += ' card-focuscontent'; - - if (!enableFocusTransfrom) { - cardScalableClass += ' card-focuscontent-large'; - } - } - cardImageContainerOpen = '
' + cardImageContainerOpen; cardBoxClose = '
'; cardScalableClose = '
'; diff --git a/src/components/cardbuilder/chaptercardbuilder.js b/src/components/cardbuilder/chaptercardbuilder.js index 900f4befc1..0f42e14584 100644 --- a/src/components/cardbuilder/chaptercardbuilder.js +++ b/src/components/cardbuilder/chaptercardbuilder.js @@ -1,12 +1,20 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browser'], function (datetime, imageLoader, connectionManager, layoutManager, browser) { 'use strict'; + var enableFocusTransform = !browser.slow && !browser.edge; + function buildChapterCardsHtml(item, chapters, options) { + // TODO move card creation code to Card component + var className = 'card itemAction chapterCard'; - if (layoutManager.tv && (browser.animate || browser.edge)) { - className += ' card-focusscale'; + if (layoutManager.tv) { + className += ' show-focus'; + + if (enableFocusTransform) { + className += ' show-animation'; + } } var mediaStreams = ((item.MediaSources || [])[0] || {}).MediaStreams || []; @@ -92,19 +100,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browse var cardBoxCssClass = 'cardBox'; var cardScalableClass = 'cardScalable'; - if (layoutManager.tv) { - var enableFocusTransfrom = !browser.slow && !browser.edge; - - cardScalableClass += ' card-focuscontent'; - - if (enableFocusTransfrom) { - cardBoxCssClass += ' cardBox-focustransform cardBox-withfocuscontent'; - } else { - cardBoxCssClass += ' cardBox-withfocuscontent-large'; - cardScalableClass += ' card-focuscontent-large'; - } - } - var html = '
'; return html; @@ -137,4 +132,4 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browse buildChapterCards: buildChapterCards }; -}); \ No newline at end of file +}); diff --git a/src/components/imagedownloader/imagedownloader.js b/src/components/imagedownloader/imagedownloader.js index 729bce3382..182b72071f 100644 --- a/src/components/imagedownloader/imagedownloader.js +++ b/src/components/imagedownloader/imagedownloader.js @@ -1,6 +1,8 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader', 'browser', 'layoutManager', 'scrollHelper', 'globalize', 'require', 'emby-checkbox', 'paper-icon-button-light', 'emby-button', 'formDialogStyle', 'cardStyle'], function (loading, appHost, dialogHelper, connectionManager, imageLoader, browser, layoutManager, scrollHelper, globalize, require) { 'use strict'; + var enableFocusTransform = !browser.slow && !browser.edge; + var currentItemId; var currentItemType; var currentResolve; @@ -164,6 +166,8 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader' var tagName = layoutManager.tv ? 'button' : 'div'; var enableFooterButtons = !layoutManager.tv; + // TODO move card creation code to Card component + var html = ''; var cssClass = "card scalableCard imageEditorCard"; @@ -196,12 +200,12 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader' if (tagName === 'button') { cssClass += ' btnImageCard'; - if (layoutManager.tv && !browser.slow) { - cardBoxCssClass += ' cardBox-focustransform'; - } - if (layoutManager.tv) { - cardBoxCssClass += ' card-focuscontent cardBox-withfocuscontent'; + cssClass += ' show-focus'; + + if (enableFocusTransform) { + cssClass += ' show-animation'; + } } html += ''; } html += "
"; @@ -188,9 +188,9 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper- var path = lnkPath.getAttribute("data-path"); if (lnkPath.classList.contains("lnkFile")) { content.querySelector("#txtDirectoryPickerPath").value = path; - } else { + } else { refreshDirectoryBrowser(content, path, fileOptions, true) - }; + } } }); @@ -254,10 +254,10 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper- var systemInfo = responses[0]; var initialPath = responses[1]; var dlg = dialogHelper.createDialog({ - size: "medium-tall", - removeOnClose: true, - scrollY: false - }); + size: "medium-tall", + removeOnClose: true, + scrollY: false + }); dlg.classList.add("ui-body-a"); dlg.classList.add("background-theme-a"); dlg.classList.add("directoryPicker"); diff --git a/src/components/dom.js b/src/components/dom.js index ea8902b98e..da03b87428 100644 --- a/src/components/dom.js +++ b/src/components/dom.js @@ -68,7 +68,9 @@ define([], function () { } }); window.addEventListener("test", null, opts); - } catch (e) { } + } catch (e) { + console.log('error checking capture support'); + } function addEventListenerWithOptions(target, type, handler, options) { var optionsOrCapture = options; @@ -116,8 +118,8 @@ define([], function () { return _animationEvent; } - var t, - el = document.createElement("div"); + var t; + var el = document.createElement("div"); var animations = { "animation": "animationend", "OAnimation": "oAnimationEnd", @@ -146,8 +148,8 @@ define([], function () { return _transitionEvent; } - var t, - el = document.createElement("div"); + var t; + var el = document.createElement("div"); var transitions = { "transition": "transitionend", "OTransition": "oTransitionEnd", diff --git a/src/components/emby-input/emby-input.js b/src/components/emby-input/emby-input.js index acc9154318..7d2ea63a0d 100644 --- a/src/components/emby-input/emby-input.js +++ b/src/components/emby-input/emby-input.js @@ -28,11 +28,12 @@ define(['layoutManager', 'browser', 'dom', 'css!./emby-input', 'registerElement' } EmbyInputPrototype.createdCallback = function () { - if (!this.id) { this.id = 'embyinput' + inputId; inputId++; - } if (this.classList.contains('emby-input')) { + } + + if (this.classList.contains('emby-input')) { return; } diff --git a/src/components/emby-progressring/emby-progressring.js b/src/components/emby-progressring/emby-progressring.js index 7148079a19..80c5458528 100644 --- a/src/components/emby-progressring/emby-progressring.js +++ b/src/components/emby-progressring/emby-progressring.js @@ -47,8 +47,7 @@ define(['require', 'css!./emby-progressring', 'registerElement'], function (requ this.querySelector('.animate-25-50-b').style.transform = 'rotate(-90deg)'; this.querySelector('.animate-50-75-b').style.transform = 'rotate(-90deg)'; this.querySelector('.animate-75-100-b').style.transform = 'rotate(-90deg)'; - } - else if (progress >= 25 && progress < 50) { + } else if (progress >= 25 && progress < 50) { angle = -90 + ((progress - 25) / 100) * 360; @@ -57,8 +56,7 @@ define(['require', 'css!./emby-progressring', 'registerElement'], function (requ this.querySelector('.animate-50-75-b').style.transform = 'rotate(-90deg)'; this.querySelector('.animate-75-100-b').style.transform = 'rotate(-90deg)'; - } - else if (progress >= 50 && progress < 75) { + } else if (progress >= 50 && progress < 75) { angle = -90 + ((progress - 50) / 100) * 360; this.querySelector('.animate-0-25-b').style.transform = 'none'; @@ -66,8 +64,7 @@ define(['require', 'css!./emby-progressring', 'registerElement'], function (requ this.querySelector('.animate-50-75-b').style.transform = 'rotate(' + angle + 'deg)'; this.querySelector('.animate-75-100-b').style.transform = 'rotate(-90deg)'; - } - else if (progress >= 75 && progress <= 100) { + } else if (progress >= 75 && progress <= 100) { angle = -90 + ((progress - 75) / 100) * 360; this.querySelector('.animate-0-25-b').style.transform = 'none'; @@ -85,7 +82,6 @@ define(['require', 'css!./emby-progressring', 'registerElement'], function (requ EmbyProgressRing.detachedCallback = function () { - var observer = this.observer; if (observer) { diff --git a/src/components/emby-tabs/emby-tabs.js b/src/components/emby-tabs/emby-tabs.js index 4a0060cf88..9fedf0bfe9 100644 --- a/src/components/emby-tabs/emby-tabs.js +++ b/src/components/emby-tabs/emby-tabs.js @@ -142,7 +142,7 @@ define(['dom', 'scroller', 'browser', 'layoutManager', 'focusManager', 'register tabs.classList.add('scrollX'); tabs.classList.add('hiddenScrollX'); tabs.classList.add('smoothScrollX'); - } + } } EmbyTabs.createdCallback = function () { diff --git a/src/components/emby-textarea/emby-textarea.js b/src/components/emby-textarea/emby-textarea.js index 7dec1f0955..c500db6e1f 100644 --- a/src/components/emby-textarea/emby-textarea.js +++ b/src/components/emby-textarea/emby-textarea.js @@ -14,9 +14,9 @@ define(['layoutManager', 'browser', 'css!./emby-textarea', 'registerElement', 'e * @returns {number} */ self.getOffset = function (textarea) { - var style = window.getComputedStyle(textarea, null), - props = ['paddingTop', 'paddingBottom'], - offset = 0; + var style = window.getComputedStyle(textarea, null); + var props = ['paddingTop', 'paddingBottom']; + var offset = 0; for (var i = 0; i < props.length; i++) { offset += parseInt(style[props[i]]); @@ -43,13 +43,13 @@ define(['layoutManager', 'browser', 'css!./emby-textarea', 'registerElement', 'e textarea.rows = 3; return; } - var newHeight = 0, hasGrown = false; + var newHeight = 0; + var hasGrown = false; if ((textarea.scrollHeight - offset) > self.maxAllowedHeight) { textarea.style.overflowY = 'scroll'; newHeight = self.maxAllowedHeight; - } - else { + } else { textarea.style.overflowY = 'hidden'; textarea.style.height = 'auto'; newHeight = textarea.scrollHeight/* - offset*/; diff --git a/src/components/filtermenu/filtermenu.js b/src/components/filtermenu/filtermenu.js index 89457aa4e6..2f18223d41 100644 --- a/src/components/filtermenu/filtermenu.js +++ b/src/components/filtermenu/filtermenu.js @@ -94,7 +94,8 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', context.querySelector('form').addEventListener('submit', onSubmit); var elems = context.querySelectorAll('.simpleFilter'); - var i, length; + var i; + var length; for (i = 0, length = elems.length; i < length; i++) { @@ -137,7 +138,8 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', function saveValues(context, settings, settingsKey) { var elems = context.querySelectorAll('.simpleFilter'); - var i, length; + var i; + var length; for (i = 0, length = elems.length; i < length; i++) { if (elems[i].tagName === 'INPUT') { diff --git a/src/components/focusManager.js b/src/components/focusManager.js index 8c2f0ad442..ec23a151c2 100644 --- a/src/components/focusManager.js +++ b/src/components/focusManager.js @@ -99,7 +99,7 @@ define(['dom'], function (dom) { return normalizeFocusable(elem, originalElement); } - // Determines if a focusable element can be focused at a given point in time + // Determines if a focusable element can be focused at a given point in time function isCurrentlyFocusableInternal(elem) { // http://stackoverflow.com/questions/19669786/check-if-element-is-visible-in-dom @@ -110,7 +110,7 @@ define(['dom'], function (dom) { return true; } - // Determines if a focusable element can be focused at a given point in time + // Determines if a focusable element can be focused at a given point in time function isCurrentlyFocusable(elem) { if (elem.disabled) { @@ -181,21 +181,18 @@ define(['dom'], function (dom) { if (classList.contains('focuscontainer-left')) { return true; } - } - else if (direction === 1) { + } else if (direction === 1) { if (classList.contains('focuscontainer-x')) { return true; } if (classList.contains('focuscontainer-right')) { return true; } - } - else if (direction === 2) { + } else if (direction === 2) { if (classList.contains('focuscontainer-y')) { return true; } - } - else if (direction === 3) { + } else if (direction === 3) { if (classList.contains('focuscontainer-y')) { return true; } @@ -275,14 +272,14 @@ define(['dom'], function (dom) { var rect = getOffset(activeElement); // Get elements and work out x/y points - var cache = [], - point1x = parseFloat(rect.left) || 0, - point1y = parseFloat(rect.top) || 0, - point2x = parseFloat(point1x + rect.width - 1) || point1x, - point2y = parseFloat(point1y + rect.height - 1) || point1y, - // Shortcuts to help with compression - min = Math.min, - max = Math.max; + var cache = []; + var point1x = parseFloat(rect.left) || 0; + var point1y = parseFloat(rect.top) || 0; + var point2x = parseFloat(point1x + rect.width - 1) || point1x; + var point2y = parseFloat(point1y + rect.height - 1) || point1y; + // Shortcuts to help with compression + var min = Math.min; + var max = Math.max; var sourceMidX = rect.left + (rect.width / 2); var sourceMidY = rect.top + (rect.height / 2); @@ -357,10 +354,10 @@ define(['dom'], function (dom) { break; } - var x = elementRect.left, - y = elementRect.top, - x2 = x + elementRect.width - 1, - y2 = y + elementRect.height - 1; + var x = elementRect.left; + var y = elementRect.top; + var x2 = x + elementRect.width - 1; + var y2 = y + elementRect.height - 1; var intersectX = intersects(point1x, point2x, x, x2); var intersectY = intersects(point1y, point2y, y, y2); @@ -470,7 +467,9 @@ define(['dom'], function (dom) { var elems = container.querySelectorAll(focusableSelector); var list = []; - var i, length, elem; + var i; + var length; + var elem; for (i = 0, length = elems.length; i < length; i++) { @@ -513,32 +512,24 @@ define(['dom'], function (dom) { focusableParent: focusableParent, getFocusableElements: getFocusableElements, moveLeft: function (sourceElement, options) { - var container = options ? options.container : null; var focusableElements = options ? options.focusableElements : null; nav(sourceElement, 0, container, focusableElements); - }, moveRight: function (sourceElement, options) { - var container = options ? options.container : null; var focusableElements = options ? options.focusableElements : null; nav(sourceElement, 1, container, focusableElements); - }, moveUp: function (sourceElement, options) { - var container = options ? options.container : null; var focusableElements = options ? options.focusableElements : null; nav(sourceElement, 2, container, focusableElements); - }, moveDown: function (sourceElement, options) { - var container = options ? options.container : null; var focusableElements = options ? options.focusableElements : null; nav(sourceElement, 3, container, focusableElements); - }, sendText: sendText, isCurrentlyFocusable: isCurrentlyFocusable, diff --git a/src/components/fullscreenManager.js b/src/components/fullscreenManager.js index 360986cc54..8ae31073a2 100644 --- a/src/components/fullscreenManager.js +++ b/src/components/fullscreenManager.js @@ -55,7 +55,7 @@ define(['events', 'dom', 'apphost', 'browser'], function (events, dom, appHost, return document.fullscreen || document.mozFullScreen || document.webkitIsFullScreen || - document.msFullscreenElement || /* IE/Edge syntax */ + document.msFullscreenElement || /* IE/Edge syntax */ document.fullscreenElement || /* Standard syntax */ document.webkitFullscreenElement || /* Chrome, Safari and Opera syntax */ document.mozFullScreenElement; /* Firefox syntax */ diff --git a/src/components/guide/guide-settings.js b/src/components/guide/guide-settings.js index 47eb026db8..9ee43be9f1 100644 --- a/src/components/guide/guide-settings.js +++ b/src/components/guide/guide-settings.js @@ -39,7 +39,8 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectio function save(context) { - var i, length; + var i; + var length; var chkIndicators = context.querySelectorAll('.chkIndicator'); for (i = 0, length = chkIndicators.length; i < length; i++) { @@ -62,7 +63,8 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectio function load(context) { - var i, length; + var i; + var length; var chkIndicators = context.querySelectorAll('.chkIndicator'); for (i = 0, length = chkIndicators.length; i < length; i++) { diff --git a/src/components/guide/guide.js b/src/components/guide/guide.js index d299d7fd7c..1e9484caf8 100644 --- a/src/components/guide/guide.js +++ b/src/components/guide/guide.js @@ -277,7 +277,7 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', var nextDay = new Date(date.getTime() + msPerDay - 2000); // Normally we'd want to just let responsive css handle this, - // but since mobile browsers are often underpowered, + // but since mobile browsers are often underpowered, // it can help performance to get them out of the markup var allowIndicators = dom.getWindowSize().innerWidth >= 600; @@ -392,27 +392,20 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', } function parseDates(program) { - if (!program.StartDateLocal) { try { - program.StartDateLocal = datetime.parseISO8601Date(program.StartDate, { toLocal: true }); - } catch (err) { - + console.log('error parsing timestamp for start date'); } - } if (!program.EndDateLocal) { try { - program.EndDateLocal = datetime.parseISO8601Date(program.EndDate, { toLocal: true }); - } catch (err) { - + console.log('error parsing timestamp for end date'); } - } return null; @@ -424,16 +417,13 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', if (item.Type === 'SeriesTimer') { return ''; - } - else if (item.TimerId || item.SeriesTimerId) { + } else if (item.TimerId || item.SeriesTimerId) { status = item.Status || 'Cancelled'; - } - else if (item.Type === 'Timer') { + } else if (item.Type === 'Timer') { status = item.Status; - } - else { + } else { return ''; } @@ -529,11 +519,9 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', } else if (program.IsMovie) { displayInnerContent = displayMovieContent; accentCssClass = 'movie'; - } - else if (program.IsSeries) { + } else if (program.IsSeries) { displayInnerContent = displaySeriesContent; - } - else { + } else { displayInnerContent = displayMovieContent && displayNewsContent && displaySportsContent && displayKidsContent && displaySeriesContent; } @@ -569,14 +557,11 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', var indicatorHtml = null; if (program.IsLive && options.showLiveIndicator) { indicatorHtml = '' + globalize.translate('Live') + ''; - } - else if (program.IsPremiere && options.showPremiereIndicator) { + } else if (program.IsPremiere && options.showPremiereIndicator) { indicatorHtml = '' + globalize.translate('Premiere') + ''; - } - else if (program.IsSeries && !program.IsRepeat && options.showNewIndicator) { + } else if (program.IsSeries && !program.IsRepeat && options.showNewIndicator) { indicatorHtml = '' + globalize.translate('AttributeNew') + ''; - } - else if (program.IsSeries && program.IsRepeat && options.showRepeatIndicator) { + } else if (program.IsSeries && program.IsRepeat && options.showRepeatIndicator) { indicatorHtml = '' + globalize.translate('Repeat') + ''; } html += indicatorHtml || ''; @@ -614,7 +599,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', return html; } - function renderChannelHeaders(context, channels, apiClient) { var html = ''; @@ -1079,17 +1063,13 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', scrollHelper.toStart(programGrid, programCell, true, true); } - } - - else if (lastFocusDirection === 'right') { + } else if (lastFocusDirection === 'right') { if (programCell) { scrollHelper.toCenter(programGrid, programCell, true, true); } - } - - else if (lastFocusDirection === 'up' || lastFocusDirection === 'down') { + } else if (lastFocusDirection === 'up' || lastFocusDirection === 'down') { var verticalScroller = dom.parentWithClass(target, 'guideVerticalScroller'); if (verticalScroller) { @@ -1195,14 +1175,14 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', dom.addEventListener(programGrid, 'scroll', function (e) { onProgramGridScroll(context, this, timeslotHeaders); }, { - passive: true - }); + passive: true + }); dom.addEventListener(timeslotHeaders, 'scroll', function () { onTimeslotHeadersScroll(context, this); }, { - passive: true - }); + passive: true + }); programGrid.addEventListener('click', onProgramGridClick); diff --git a/src/components/headroom/headroom.js b/src/components/headroom/headroom.js index a3cc5b0435..9c058a8e82 100644 --- a/src/components/headroom/headroom.js +++ b/src/components/headroom/headroom.js @@ -255,8 +255,8 @@ define(['dom', 'layoutManager', 'browser', 'css!./headroom'], function (dom, lay * @return {bool} true if should unpin, false otherwise */ this.shouldUnpin = function (currentScrollY) { - var scrollingDown = currentScrollY > this.lastKnownScrollY, - pastOffset = currentScrollY >= this.offset; + var scrollingDown = currentScrollY > this.lastKnownScrollY; + var pastOffset = currentScrollY >= this.offset; return scrollingDown && pastOffset; }; @@ -267,8 +267,8 @@ define(['dom', 'layoutManager', 'browser', 'css!./headroom'], function (dom, lay * @return {bool} true if should pin, false otherwise */ this.shouldPin = function (currentScrollY) { - var scrollingUp = currentScrollY < this.lastKnownScrollY, - pastOffset = currentScrollY <= this.offset; + var scrollingUp = currentScrollY < this.lastKnownScrollY; + var pastOffset = currentScrollY <= this.offset; return scrollingUp || pastOffset; }; @@ -290,11 +290,9 @@ define(['dom', 'layoutManager', 'browser', 'css!./headroom'], function (dom, lay if (currentScrollY <= (isTv ? 120 : 10)) { this.clear(); - } - else if (this.shouldUnpin(currentScrollY)) { + } else if (this.shouldUnpin(currentScrollY)) { this.unpin(); - } - else if (this.shouldPin(currentScrollY)) { + } else if (this.shouldPin(currentScrollY)) { var toleranceExceeded = Math.abs(currentScrollY - lastKnownScrollY) >= 14; @@ -310,7 +308,6 @@ define(['dom', 'layoutManager', 'browser', 'css!./headroom'], function (dom, lay this.lastKnownScrollY = currentScrollY; }; - if (browser.supportsCssAnimation()) { for (var i = 0, length = this.elems.length; i < length; i++) { this.elems[i].classList.add(this.initialClass); diff --git a/src/components/homescreensettings/homescreensettings.js b/src/components/homescreensettings/homescreensettings.js index 633437d26e..dc7769be36 100644 --- a/src/components/homescreensettings/homescreensettings.js +++ b/src/components/homescreensettings/homescreensettings.js @@ -57,8 +57,7 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa name: globalize.translate('Collections'), value: 'collections' }); - } - else if (type === 'tvshows') { + } else if (type === 'tvshows') { list.push({ name: globalize.translate('Shows'), @@ -78,8 +77,7 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa name: globalize.translate('Favorites'), value: 'favorites' }); - } - else if (type === 'music') { + } else if (type === 'music') { list.push({ name: globalize.translate('Suggestions'), @@ -111,8 +109,7 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa name: globalize.translate('Genres'), value: 'genres' }); - } - else if (type === 'livetv') { + } else if (type === 'livetv') { list.push({ name: globalize.translate('Suggestions'), @@ -256,7 +253,6 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa html += '
'; } - return html; } @@ -384,7 +380,8 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa var viewItems = context.querySelectorAll('.viewItem'); var orderedViews = []; - var i, length; + var i; + var length; for (i = 0, length = viewItems.length; i < length; i++) { orderedViews.push(viewItems[i].getAttribute('data-viewid')); } diff --git a/src/components/homesections/homesections.js b/src/components/homesections/homesections.js index 3fc549e6e4..0c92f34e3d 100644 --- a/src/components/homesections/homesections.js +++ b/src/components/homesections/homesections.js @@ -1,4 +1,4 @@ -define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'layoutManager', 'imageLoader', 'globalize', 'itemShortcuts', 'itemHelper', 'appRouter', 'scripts/imagehelper','paper-icon-button-light', 'emby-itemscontainer', 'emby-scroller', 'emby-button', 'css!./homesections'], function (connectionManager, cardBuilder, appSettings, dom, appHost, layoutManager, imageLoader, globalize, itemShortcuts, itemHelper, appRouter, imageHelper) { +define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'layoutManager', 'imageLoader', 'globalize', 'itemShortcuts', 'itemHelper', 'appRouter', 'scripts/imagehelper', 'paper-icon-button-light', 'emby-itemscontainer', 'emby-scroller', 'emby-button', 'css!./homesections'], function (connectionManager, cardBuilder, appSettings, dom, appHost, layoutManager, imageLoader, globalize, itemShortcuts, itemHelper, appRouter, imageHelper) { 'use strict'; function getDefaultSection(index) { @@ -83,7 +83,8 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la function resume(elem, options) { var elems = elem.querySelectorAll('.itemsContainer'); - var i, length; + var i; + var length; var promises = []; for (i = 0, length = elems.length; i < length; i++) { @@ -567,7 +568,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la html += '' + globalize.translate('Programs') + ''; html += '
'; - } - else { + } else { html += ''; } diff --git a/src/components/imageeditor/imageeditor.js b/src/components/imageeditor/imageeditor.js index 2c649bdd16..fade0dd04c 100644 --- a/src/components/imageeditor/imageeditor.js +++ b/src/components/imageeditor/imageeditor.js @@ -24,8 +24,7 @@ define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager', if (item) { apiClient = connectionManager.getApiClient(item.ServerId); reloadItem(page, item, apiClient, focusContext); - } - else { + } else { apiClient = connectionManager.getApiClient(currentItem.ServerId); apiClient.getItem(apiClient.getCurrentUserId(), currentItem.Id).then(function (item) { @@ -60,7 +59,6 @@ define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager', } } - apiClient.getItemImageInfos(currentItem.Id).then(function (imageInfos) { renderStandardImages(page, apiClient, item, imageInfos, providers); @@ -167,8 +165,7 @@ define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager', } else { html += ''; } - } - else { + } else { if (imageProviders.length) { html += ''; } diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 2a77daa216..a2906cca85 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -70,7 +70,9 @@ define(['lazyLoader', 'imageFetcher', 'layoutManager', 'browser', 'appSettings', } // Use the median - values.sort(function (a, b) { return a - b; }); + values.sort(function (a, b) { + return a - b; + }); var half = Math.floor(values.length / 2); @@ -78,8 +80,7 @@ define(['lazyLoader', 'imageFetcher', 'layoutManager', 'browser', 'appSettings', if (values.length % 2) { result = values[half]; - } - else { + } else { result = (values[half - 1] + values[half]) / 2.0; } diff --git a/src/components/imageuploader/imageuploader.js b/src/components/imageuploader/imageuploader.js index 3a52d7110d..98fcf0ebce 100644 --- a/src/components/imageuploader/imageuploader.js +++ b/src/components/imageuploader/imageuploader.js @@ -150,7 +150,7 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', ' scrollHelper.centerFocus.on(dlg, false); } - // Has to be assigned a z-index after the call to .open() + // Has to be assigned a z-index after the call to .open() dlg.addEventListener('close', function () { if (layoutManager.tv) { diff --git a/src/components/itemcontextmenu.js b/src/components/itemcontextmenu.js index 46a65cabc3..a3aa8cac4f 100644 --- a/src/components/itemcontextmenu.js +++ b/src/components/itemcontextmenu.js @@ -52,8 +52,6 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter", //} } - - if (item.IsFolder || item.Type === "MusicArtist" || item.Type === "MusicGenre") { if (item.CollectionType !== "livetv") { if (options.shuffle !== false) { diff --git a/src/components/itemhelper.js b/src/components/itemhelper.js index f8bdb28ac5..f0b1de4a12 100644 --- a/src/components/itemhelper.js +++ b/src/components/itemhelper.js @@ -250,9 +250,7 @@ define(['apphost', 'globalize'], function (appHost, globalize) { if (item.Type !== 'TvChannel') { return true; } - } - - else if (item.MediaType === 'Audio') { + } else if (item.MediaType === 'Audio') { if (item.Type === 'AudioPodcast') { return true; } diff --git a/src/components/itemidentifier/itemidentifier.js b/src/components/itemidentifier/itemidentifier.js index fa01a4aced..6f28de0b3b 100644 --- a/src/components/itemidentifier/itemidentifier.js +++ b/src/components/itemidentifier/itemidentifier.js @@ -21,7 +21,8 @@ define(["dialogHelper", "loading", "connectionManager", "require", "globalize", ProviderIds: {} }; - var i, length; + var i; + var length; var identifyField = page.querySelectorAll(".identifyField"); var value; for (i = 0, length = identifyField.length; i < length; i++) { @@ -64,8 +65,7 @@ define(["dialogHelper", "loading", "connectionManager", "require", "globalize", if (currentItem && currentItem.Id) { lookupInfo.ItemId = currentItem.Id; - } - else { + } else { lookupInfo.IncludeDisabledProviders = true; } @@ -97,7 +97,8 @@ define(["dialogHelper", "loading", "connectionManager", "require", "globalize", page.querySelector(".dialogContentInner").classList.remove("dialog-content-centered"); var html = ""; - var i, length; + var i; + var length; for (i = 0, length = results.length; i < length; i++) { var result = results[i]; @@ -184,12 +185,10 @@ define(["dialogHelper", "loading", "connectionManager", "require", "globalize", if (currentItemType === "Episode") { cssClass += " backdropCard backdropCard-scalable"; padderClass = "cardPadder-backdrop"; - } - else if (currentItemType === "MusicAlbum" || currentItemType === "MusicArtist") { + } else if (currentItemType === "MusicAlbum" || currentItemType === "MusicArtist") { cssClass += " squareCard squareCard-scalable"; padderClass = "cardPadder-square"; - } - else { + } else { cssClass += " portraitCard portraitCard-scalable"; padderClass = "cardPadder-portrait"; } @@ -452,8 +451,6 @@ define(["dialogHelper", "loading", "connectionManager", "require", "globalize", scrollHelper.centerFocus.on(dlg.querySelector(".formDialogContent"), false); } - - dialogHelper.open(dlg); dlg.querySelector(".btnCancel").addEventListener("click", function (e) { diff --git a/src/components/itemsrefresher.js b/src/components/itemsrefresher.js index d9bef95b4b..46956d2df5 100644 --- a/src/components/itemsrefresher.js +++ b/src/components/itemsrefresher.js @@ -11,8 +11,7 @@ define(['playbackManager', 'serverNotifications', 'events'], function (playbackM if (eventsToMonitor.indexOf('markfavorite') !== -1) { instance.notifyRefreshNeeded(); - } - else if (eventsToMonitor.indexOf('markplayed') !== -1) { + } else if (eventsToMonitor.indexOf('markplayed') !== -1) { instance.notifyRefreshNeeded(); } @@ -115,9 +114,7 @@ define(['playbackManager', 'serverNotifications', 'events'], function (playbackM instance.notifyRefreshNeeded(true); return; } - } - - else if (state.NowPlayingItem && state.NowPlayingItem.MediaType === 'Audio') { + } else if (state.NowPlayingItem && state.NowPlayingItem.MediaType === 'Audio') { if (eventsToMonitor.indexOf('audioplayback') !== -1) { diff --git a/src/components/keyboardnavigation.js b/src/components/keyboardnavigation.js index 7ed74f2201..8c0bb1a3ae 100644 --- a/src/components/keyboardnavigation.js +++ b/src/components/keyboardnavigation.js @@ -8,20 +8,20 @@ define(['inputManager', 'focusManager'], function(inputManager, focusManager) { var capture = true; switch (e.keyCode) { - case 37: // ArrowLeft - inputManager.handle('left'); - break; - case 38: // ArrowUp - inputManager.handle('up'); - break; - case 39: // ArrowRight - inputManager.handle('right'); - break; - case 40: // ArrowDown - inputManager.handle('down'); - break; - default: - capture = false; + case 37: // ArrowLeft + inputManager.handle('left'); + break; + case 38: // ArrowUp + inputManager.handle('up'); + break; + case 39: // ArrowRight + inputManager.handle('right'); + break; + case 40: // ArrowDown + inputManager.handle('down'); + break; + default: + capture = false; } if (capture) { console.log("Disabling default event handling"); @@ -31,6 +31,6 @@ define(['inputManager', 'focusManager'], function(inputManager, focusManager) { } return { - enable: enable, + enable: enable }; }); diff --git a/src/components/lazyloader/lazyloader-intersectionobserver.js b/src/components/lazyloader/lazyloader-intersectionobserver.js index 261ca84261..1935f65a30 100644 --- a/src/components/lazyloader/lazyloader-intersectionobserver.js +++ b/src/components/lazyloader/lazyloader-intersectionobserver.js @@ -45,7 +45,7 @@ define(['require', 'browser'], function (require, browser) { } } }, - observerOptions + observerOptions ); this.observer = observer; diff --git a/src/components/listview/listview.js b/src/components/listview/listview.js index 257551abf6..974cb0ab09 100644 --- a/src/components/listview/listview.js +++ b/src/components/listview/listview.js @@ -9,7 +9,8 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan } var sortBy = (options.sortBy || '').toLowerCase(); - var code, name; + var code; + var name; if (sortBy.indexOf('sortname') === 0) { @@ -85,15 +86,12 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan options.tag = item.AlbumPrimaryImageTag; return apiClient.getScaledImageUrl(item.AlbumId, options); - } - - else if (item.SeriesId && item.SeriesPrimaryImageTag) { + } else if (item.SeriesId && item.SeriesPrimaryImageTag) { options.tag = item.SeriesPrimaryImageTag; return apiClient.getScaledImageUrl(item.SeriesId, options); - } - else if (item.ParentPrimaryImageTag) { + } else if (item.ParentPrimaryImageTag) { options.tag = item.ParentPrimaryImageTag; return apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, options); @@ -209,8 +207,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan if (i === 0) { html += '

'; - } - else { + } else { html += '

'; } html += itemGroupTitle; @@ -349,9 +346,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan if (options.showParentTitle) { if (item.Type === 'Episode') { parentTitle = item.SeriesName; - } - - else if (item.IsSeries || (item.EpisodeTitle && item.Name)) { + } else if (item.IsSeries || (item.EpisodeTitle && item.Name)) { parentTitle = item.Name; } } @@ -375,8 +370,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan } textlines.push(parentTitle || ''); - } - else if (options.showParentTitle) { + } else if (options.showParentTitle) { textlines.push(parentTitle || ''); } @@ -400,8 +394,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan if (!artistItems || !artistItems.length) { showArtist = true; - } - else if (artistItems.length > 1 || containerAlbumArtistIds.indexOf(artistItems[0].Id) === -1) { + } else if (artistItems.length > 1 || containerAlbumArtistIds.indexOf(artistItems[0].Id) === -1) { showArtist = true; } } diff --git a/src/components/loading/loading.js b/src/components/loading/loading.js index ad9aea950a..510f311217 100644 --- a/src/components/loading/loading.js +++ b/src/components/loading/loading.js @@ -45,7 +45,8 @@ define(['components/loading/loadingLegacy', 'browser', 'css!./loading'], functio layer3.classList.add('mdl-spinner__layer-3-active'); layer4.classList.add('mdl-spinner__layer-4-active'); - var i, length; + var i; + var length; for (i = 0, length = circleLefts.length; i < length; i++) { circleLefts[i].classList.add('mdl-spinner__circleLeft-active'); @@ -67,7 +68,8 @@ define(['components/loading/loadingLegacy', 'browser', 'css!./loading'], functio elem.classList.remove('mdl-spinner__layer-3-active'); elem.classList.remove('mdl-spinner__layer-4-active'); - var i, length; + var i; + var length; for (i = 0, length = circleLefts.length; i < length; i++) { circleLefts[i].classList.remove('mdl-spinner__circleLeft-active'); diff --git a/src/components/mediainfo/mediainfo.js b/src/components/mediainfo/mediainfo.js index 441adac3dd..0fb4a1e7be 100644 --- a/src/components/mediainfo/mediainfo.js +++ b/src/components/mediainfo/mediainfo.js @@ -7,16 +7,13 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater if (item.Type === 'SeriesTimer') { return ''; - } - else if (item.TimerId || item.SeriesTimerId) { + } else if (item.TimerId || item.SeriesTimerId) { status = item.Status || 'Cancelled'; - } - else if (item.Type === 'Timer') { + } else if (item.Type === 'Timer') { status = item.Status; - } - else { + } else { return ''; } @@ -36,7 +33,8 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater var html = ''; var miscInfo = []; - var text, date; + var text; + var date; if (item.StartDate && options.programTime !== false) { @@ -58,8 +56,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater } miscInfo.push(text); - } - catch (e) { + } catch (e) { console.log("Error parsing date: " + item.StartDate); } } @@ -107,7 +104,9 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater var miscInfo = []; options = options || {}; - var text, date, minutes; + var text; + var date; + var minutes; var count; var showFolderRuntime = item.Type === "MusicAlbum" || item.MediaType === 'MusicArtist' || item.MediaType === 'Playlist' || item.MediaType === 'MusicGenre'; @@ -124,9 +123,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater if (item.RunTimeTicks) { miscInfo.push(datetime.getDisplayRunningTime(item.RunTimeTicks)); } - } - - else if (item.Type === "PhotoAlbum" || item.Type === "BoxSet") { + } else if (item.Type === "PhotoAlbum" || item.Type === "BoxSet") { count = item.ChildCount; @@ -145,8 +142,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater text = datetime.toLocaleDateString(date); miscInfo.push(text); - } - catch (e) { + } catch (e) { console.log("Error parsing date: " + item.PremiereDate); } } @@ -162,8 +158,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater if (item.RecordAnyChannel) { miscInfo.push(globalize.translate('AllChannels')); - } - else { + } else { miscInfo.push(item.ChannelName || globalize.translate('OneChannel')); } } @@ -180,8 +175,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater text = datetime.getDisplayTime(date); miscInfo.push(text); } - } - catch (e) { + } catch (e) { console.log("Error parsing date: " + item.StartDate); } } @@ -191,8 +185,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater if (item.Status === "Continuing") { miscInfo.push(globalize.translate('SeriesYearToPresent', item.ProductionYear)); - } - else if (item.ProductionYear) { + } else if (item.ProductionYear) { text = item.ProductionYear; @@ -206,8 +199,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater text += "-" + datetime.parseISO8601Date(item.EndDate).getFullYear(); } - } - catch (e) { + } catch (e) { console.log("Error parsing date: " + item.EndDate); } } @@ -223,18 +215,15 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater miscInfo.push({ html: '
' + globalize.translate('Live') + '
' }); - } - else if (item.IsPremiere) { + } else if (item.IsPremiere) { miscInfo.push({ html: '
' + globalize.translate('Premiere') + '
' }); - } - else if (item.IsSeries && !item.IsRepeat) { + } else if (item.IsSeries && !item.IsRepeat) { miscInfo.push({ html: '
' + globalize.translate('AttributeNew') + '
' }); - } - else if (item.IsSeries && item.IsRepeat) { + } else if (item.IsSeries && item.IsRepeat) { miscInfo.push({ html: '
' + globalize.translate('Repeat') + '
' }); @@ -250,20 +239,15 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater if (text) { miscInfo.push(text); } - } - - else if (item.IsMovie && item.ProductionYear && options.originalAirDate !== false) { + } else if (item.IsMovie && item.ProductionYear && options.originalAirDate !== false) { miscInfo.push(item.ProductionYear); - } - - else if (item.PremiereDate && options.originalAirDate !== false) { + } else if (item.PremiereDate && options.originalAirDate !== false) { try { date = datetime.parseISO8601Date(item.PremiereDate); text = globalize.translate('OriginalAirDateValue', datetime.toLocaleDateString(date)); miscInfo.push(text); - } - catch (e) { + } catch (e) { console.log("Error parsing date: " + item.PremiereDate); } } else if (item.ProductionYear) { @@ -277,14 +261,12 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater if (item.ProductionYear) { miscInfo.push(item.ProductionYear); - } - else if (item.PremiereDate) { + } else if (item.PremiereDate) { try { text = datetime.parseISO8601Date(item.PremiereDate).getFullYear(); miscInfo.push(text); - } - catch (e) { + } catch (e) { console.log("Error parsing date: " + item.PremiereDate); } } diff --git a/src/components/medialibrarycreator/medialibrarycreator.js b/src/components/medialibrarycreator/medialibrarycreator.js index 54c13a4ebe..183e22551f 100644 --- a/src/components/medialibrarycreator/medialibrarycreator.js +++ b/src/components/medialibrarycreator/medialibrarycreator.js @@ -151,13 +151,13 @@ define(["loading", "dialogHelper", "dom", "jQuery", "components/libraryoptionsed var xhr = new XMLHttpRequest; xhr.open("GET", "components/medialibrarycreator/medialibrarycreator.template.html", true); xhr.onload = function(e) { - var template = this.response, - dlg = dialogHelper.createDialog({ - size: "medium-tall", - modal: false, - removeOnClose: true, - scrollY: false - }); + var template = this.response; + var dlg = dialogHelper.createDialog({ + size: "medium-tall", + modal: false, + removeOnClose: true, + scrollY: false + }); dlg.classList.add("ui-body-a"); dlg.classList.add("background-theme-a"); dlg.classList.add("dlg-librarycreator"); diff --git a/src/components/metadataeditor/metadataeditor.js b/src/components/metadataeditor/metadataeditor.js index 552c716c1f..8843dc159c 100644 --- a/src/components/metadataeditor/metadataeditor.js +++ b/src/components/metadataeditor/metadataeditor.js @@ -144,7 +144,9 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi AirTime: form.querySelector('#txtAirTime').value, Genres: getListValues(form.querySelector("#listGenres")), Tags: getListValues(form.querySelector("#listTags")), - Studios: getListValues(form.querySelector("#listStudios")).map(function (element) { return { Name: element }; }), + Studios: getListValues(form.querySelector("#listStudios")).map(function (element) { + return { Name: element }; + }), PremiereDate: getDateValue(form, '#txtPremiereDate', 'PremiereDate'), DateCreated: getDateValue(form, '#txtDateAdded', 'DateCreated'), @@ -202,7 +204,9 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi } function getListValues(list) { - return Array.prototype.map.call(list.querySelectorAll('.textValue'), function (el) { return el.textContent; }); + return Array.prototype.map.call(list.querySelectorAll('.textValue'), function (el) { + return el.textContent; + }); } function addElementToList(source, sortCallback) { @@ -439,7 +443,6 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi var html = metadataInfo.ContentTypeOptions.map(function (i) { - return ''; }).join(''); @@ -744,7 +747,9 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi populateListView(context.querySelector('#listGenres'), item.Genres); populatePeople(context, item.People || []); - populateListView(context.querySelector('#listStudios'), (item.Studios || []).map(function (element) { return element.Name || ''; })); + populateListView(context.querySelector('#listStudios'), (item.Studios || []).map(function (element) { + return element.Name || ''; + })); populateListView(context.querySelector('#listTags'), item.Tags); @@ -783,8 +788,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi if (item.Type === 'Series') { context.querySelector('#selectDisplayOrder').value = item.DisplayOrder || ''; - } - else { + } else { context.querySelector('#selectDisplayOrder').value = item.DisplayOrder || ''; } @@ -859,7 +863,9 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi html += ""; var ratings = []; - var i, length, rating; + var i; + var length; + var rating; var currentValueFound = false; @@ -901,7 +907,9 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi items = items || []; if (typeof (sortCallback) === 'undefined') { - items.sort(function (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); }); + items.sort(function (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()); + }); } else { items = sortCallback(items); } diff --git a/src/components/multiselect/multiselect.js b/src/components/multiselect/multiselect.js index d706b76b99..a6a416d528 100644 --- a/src/components/multiselect/multiselect.js +++ b/src/components/multiselect/multiselect.js @@ -241,8 +241,6 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo id: 'refresh' }); - - require(['actionsheet'], function (actionsheet) { actionsheet.show({ items: menuItems, diff --git a/src/components/navdrawer/navdrawer.js b/src/components/navdrawer/navdrawer.js index cbf5c1eebc..69adbd1f5a 100644 --- a/src/components/navdrawer/navdrawer.js +++ b/src/components/navdrawer/navdrawer.js @@ -21,13 +21,13 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function(browser, } function onMenuTouchMove(e) { - var isOpen = self.visible, - touches = getTouches(e), - touch = touches[0] || {}, - endX = touch.clientX || 0, - endY = touch.clientY || 0, - deltaX = endX - (menuTouchStartX || 0), - deltaY = endY - (menuTouchStartY || 0); + var isOpen = self.visible; + var touches = getTouches(e); + var touch = touches[0] || {}; + var endX = touch.clientX || 0; + var endY = touch.clientY || 0; + var deltaX = endX - (menuTouchStartX || 0); + var deltaY = endY - (menuTouchStartY || 0); setVelocity(deltaX), isOpen && 1 !== dragMode && deltaX > 0 && (dragMode = 2), 0 === dragMode && (!isOpen || Math.abs(deltaX) >= 10) && Math.abs(deltaY) < 5 ? (dragMode = 1, scrollContainer.addEventListener("scroll", disableEvent), self.showMask()) : 0 === dragMode && Math.abs(deltaY) >= 5 && (dragMode = 2), 1 === dragMode && (newPos = currentPos + deltaX, self.changeMenuPos()) } @@ -36,12 +36,12 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function(browser, scrollContainer.removeEventListener("scroll", disableEvent); dragMode = 0; - var touches = getTouches(e), - touch = touches[0] || {}, - endX = touch.clientX || 0, - endY = touch.clientY || 0, - deltaX = endX - (menuTouchStartX || 0), - deltaY = endY - (menuTouchStartY || 0); + var touches = getTouches(e); + var touch = touches[0] || {}; + var endX = touch.clientX || 0; + var endY = touch.clientY || 0; + var deltaX = endX - (menuTouchStartX || 0); + var deltaY = endY - (menuTouchStartY || 0); currentPos = deltaX; self.checkMenuState(deltaX, deltaY); @@ -78,15 +78,15 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function(browser, } function onBackgroundTouchStart(e) { - var touches = getTouches(e), - touch = touches[0] || {}; + var touches = getTouches(e); + var touch = touches[0] || {}; backgroundTouchStartX = touch.clientX, backgroundTouchStartTime = (new Date).getTime() } function onBackgroundTouchMove(e) { - var touches = getTouches(e), - touch = touches[0] || {}, - endX = touch.clientX || 0; + var touches = getTouches(e); + var touch = touches[0] || {}; + var endX = touch.clientX || 0; if (endX <= options.width && self.isVisible) { countStart++; var deltaX = endX - (backgroundTouchStartX || 0); @@ -100,10 +100,10 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function(browser, } function onBackgroundTouchEnd(e) { - var touches = getTouches(e), - touch = touches[0] || {}, - endX = touch.clientX || 0, - deltaX = endX - (backgroundTouchStartX || 0); + var touches = getTouches(e); + var touch = touches[0] || {}; + var endX = touch.clientX || 0; + var deltaX = endX - (backgroundTouchStartX || 0); self.checkMenuState(deltaX), countStart = 0 } @@ -111,21 +111,24 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function(browser, var classList = mask.classList; classList.contains("backdrop") || classList.add("hide") } - var self, defaults, mask, newPos = 0, - currentPos = 0, - startPoint = 0, - countStart = 0, - velocity = 0; + var self; + var defaults; + var mask; + var newPos = 0; + var currentPos = 0; + var startPoint = 0; + var countStart = 0; + var velocity = 0; options.target.classList.add("transition"); - var dragMode = 0, - scrollContainer = options.target.querySelector(".mainDrawer-scrollContainer"); + var dragMode = 0; + var scrollContainer = options.target.querySelector(".mainDrawer-scrollContainer"); scrollContainer.classList.add("scrollY"); var TouchMenuLA = function() { self = this, defaults = { width: 260, handleSize: 10, disableMask: !1, - maxMaskOpacity: .5 + maxMaskOpacity: 0.5 }, this.isVisible = !1, this.initialize() }; TouchMenuLA.prototype.initElements = function() { @@ -133,8 +136,11 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function(browser, passive: !0 })) }; - var menuTouchStartX, menuTouchStartY, menuTouchStartTime, edgeContainer = document.querySelector(".mainDrawerHandle"), - isPeeking = !1; + var menuTouchStartX; + var menuTouchStartY; + var menuTouchStartTime; + var edgeContainer = document.querySelector(".mainDrawerHandle"); + var isPeeking = false; TouchMenuLA.prototype.animateToPosition = function(pos) { requestAnimationFrame(function() { options.target.style.transform = pos ? "translateX(" + pos + "px)" : "none" @@ -146,7 +152,7 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function(browser, self.close() }) }, TouchMenuLA.prototype.checkMenuState = function(deltaX, deltaY) { - velocity >= .4 ? deltaX >= 0 || Math.abs(deltaY || 0) >= 70 ? self.open() : self.close() : newPos >= 100 ? self.open() : newPos && self.close() + velocity >= 0.4 ? deltaX >= 0 || Math.abs(deltaY || 0) >= 70 ? self.open() : self.close() : newPos >= 100 ? self.open() : newPos && self.close() }, TouchMenuLA.prototype.open = function() { this.animateToPosition(options.width), currentPos = options.width, this.isVisible = !0, options.target.classList.add("drawer-open"), self.showMask(), self.invoke(options.onChange) }, TouchMenuLA.prototype.close = function() { @@ -154,7 +160,8 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function(browser, }, TouchMenuLA.prototype.toggle = function() { self.isVisible ? self.close() : self.open() }; - var backgroundTouchStartX, backgroundTouchStartTime; + var backgroundTouchStartX; + var backgroundTouchStartTime; TouchMenuLA.prototype.showMask = function() { mask.classList.remove("hide"), mask.offsetWidth, mask.classList.add("backdrop") }, TouchMenuLA.prototype.hideMask = function() { diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index 304eec7e08..62de365d99 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -21,8 +21,7 @@ define(['serverNotifications', 'playbackManager', 'events', 'globalize', 'requir if (notification.close) { notification.close(); - } - else if (notification.cancel) { + } else if (notification.cancel) { notification.cancel(); } }, timeoutMs); @@ -180,15 +179,12 @@ define(['serverNotifications', 'playbackManager', 'events', 'globalize', 'requir if (status === 'completed') { notification.title = globalize.translate('PackageInstallCompleted').replace('{0}', installation.Name + ' ' + installation.Version); notification.vibrate = true; - } - else if (status === 'cancelled') { + } else if (status === 'cancelled') { notification.title = globalize.translate('PackageInstallCancelled').replace('{0}', installation.Name + ' ' + installation.Version); - } - else if (status === 'failed') { + } else if (status === 'failed') { notification.title = globalize.translate('PackageInstallFailed').replace('{0}', installation.Name + ' ' + installation.Version); notification.vibrate = true; - } - else if (status === 'progress') { + } else if (status === 'progress') { notification.title = globalize.translate('InstallingPackage').replace('{0}', installation.Name + ' ' + installation.Version); notification.actions = diff --git a/src/components/nowplayingbar/nowplayingbar.js b/src/components/nowplayingbar/nowplayingbar.js index 9fac61ba1f..d7be482c52 100644 --- a/src/components/nowplayingbar/nowplayingbar.js +++ b/src/components/nowplayingbar/nowplayingbar.js @@ -134,7 +134,8 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } }); - var i, length; + var i; + var length; playPauseButtons = elem.querySelectorAll('.playPauseButton'); for (i = 0, length = playPauseButtons.length; i < length; i++) { playPauseButtons[i].addEventListener('click', onPlayPauseClick); @@ -195,7 +196,6 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', volumeSlider.addEventListener('mousemove', setVolume); volumeSlider.addEventListener('touchmove', setVolume); - positionSlider = elem.querySelector('.nowPlayingBarPositionSlider'); positionSlider.addEventListener('change', function () { @@ -282,8 +282,8 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } function updatePlayPauseState(isPaused) { - - var i, length; + var i; + var length; if (playPauseButtons) { if (isPaused) { @@ -345,8 +345,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', if (repeatMode === 'RepeatAll') { toggleRepeatButtonIcon.innerHTML = "repeat"; toggleRepeatButton.classList.add('repeatButton-active'); - } - else if (repeatMode === 'RepeatOne') { + } else if (repeatMode === 'RepeatOne') { toggleRepeatButtonIcon.innerHTML = "repeat_one"; toggleRepeatButton.classList.add('repeatButton-active'); } else { diff --git a/src/components/playback/autoplaydetect.js b/src/components/playback/autoplaydetect.js index 7a7a73a538..3610eef2ab 100644 --- a/src/components/playback/autoplaydetect.js +++ b/src/components/playback/autoplaydetect.js @@ -48,9 +48,7 @@ define([], function () { } timeout = setTimeout(testAutoplay, 500); - } - - catch (e) { + } catch (e) { reject(); return; } diff --git a/src/components/playback/brightnessosd.js b/src/components/playback/brightnessosd.js index 1797463f29..c949743bec 100644 --- a/src/components/playback/brightnessosd.js +++ b/src/components/playback/brightnessosd.js @@ -103,8 +103,7 @@ define(['events', 'playbackManager', 'dom', 'browser', 'css!./iconosd', 'materia if (iconElement) { if (brightness >= 80) { iconElement.innerHTML = ''; - } - else if (brightness >= 20) { + } else if (brightness >= 20) { iconElement.innerHTML = ''; } else { iconElement.innerHTML = ''; diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js index 63e0bde6c1..7f4b9f519e 100644 --- a/src/components/playback/mediasession.js +++ b/src/components/playback/mediasession.js @@ -158,7 +158,7 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f lastUpdateTime = now; - if (navigator.mediaSession){ + if (navigator.mediaSession) { navigator.mediaSession.metadata = new MediaMetadata({ title: title, artist: artist, @@ -278,7 +278,6 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f } if (navigator.mediaSession) { - navigator.mediaSession.setActionHandler('previoustrack', function () { execute('previousTrack'); }); diff --git a/src/components/playback/nowplayinghelper.js b/src/components/playback/nowplayinghelper.js index d5803b426f..b1af977ab0 100644 --- a/src/components/playback/nowplayinghelper.js +++ b/src/components/playback/nowplayinghelper.js @@ -43,8 +43,7 @@ define([], function () { } else if (nowPlayingItem.Artists && nowPlayingItem.Artists.length) { bottomText = nowPlayingItem.Artists.join(', '); - } - else if (nowPlayingItem.SeriesName || nowPlayingItem.Album) { + } else if (nowPlayingItem.SeriesName || nowPlayingItem.Album) { bottomText = topText; topText = nowPlayingItem.SeriesName || nowPlayingItem.Album; @@ -60,8 +59,7 @@ define([], function () { } else { topItem = null; } - } - else if (nowPlayingItem.ProductionYear && includeNonNameInfo !== false) { + } else if (nowPlayingItem.ProductionYear && includeNonNameInfo !== false) { bottomText = nowPlayingItem.ProductionYear; } diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 13497e1912..23f0d4572e 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -107,8 +107,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla TotalRecordCount: 1 }; }); - } - else { + } else { query.Limit = query.Limit || 300; query.Fields = "Chapters"; @@ -182,8 +181,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (container === 'm4a') { return 'audio/mp4'; } - } - else if (type === 'video') { + } else if (type === 'video') { if (container === 'mkv') { return 'video/x-matroska'; } @@ -212,8 +210,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla var results = regex.exec(url); if (results == null) { return ""; - } - else { + } else { return decodeURIComponent(results[1].replace(/\+/g, " ")); } } @@ -649,13 +646,10 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla // If this is the only way it can be played, then allow it if (!mediaSource.SupportsDirectStream && !mediaSource.SupportsTranscoding) { return Promise.resolve(true); - } - else { + } else { return isHostReachable(mediaSource, apiClient); } - } - - else if (mediaSource.Protocol === 'File') { + } else if (mediaSource.Protocol === 'File') { return new Promise(function (resolve, reject) { @@ -1272,7 +1266,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla var currentMediaSource = self.currentMediaSource(player); var mediaStreams = []; - var i, length; + var i; + var length; for (i = 0, length = currentMediaSource.MediaStreams.length; i < length; i++) { if (currentMediaSource.MediaStreams[i].Type === 'Audio') { mediaStreams.push(currentMediaSource.MediaStreams[i]); @@ -1316,7 +1311,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla var currentMediaSource = self.currentMediaSource(player); var mediaStreams = []; - var i, length; + var i; + var length; for (i = 0, length = currentMediaSource.MediaStreams.length; i < length; i++) { if (currentMediaSource.MediaStreams[i].Type === 'Subtitle') { mediaStreams.push(currentMediaSource.MediaStreams[i]); @@ -1360,7 +1356,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla function isAudioStreamSupported(mediaSource, index, deviceProfile) { var mediaStream; - var i, length; + var i; + var length; var mediaStreams = mediaSource.MediaStreams; for (i = 0, length = mediaStreams.length; i < length; i++) { @@ -1423,8 +1420,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (isAudioStreamSupported(self.currentMediaSource(player), index, profile)) { player.setAudioStreamIndex(index); getPlayerData(player).audioStreamIndex = index; - } - else { + } else { changeStream(player, getCurrentTicks(player), { AudioStreamIndex: index }); getPlayerData(player).audioStreamIndex = index; } @@ -1595,8 +1591,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla // Need to change the transcoded stream to remove subs changeStream(player, getCurrentTicks(player), { SubtitleStreamIndex: -1 }); } - } - else if (!currentStream && newStream) { + } else if (!currentStream && newStream) { if (getDeliveryMethod(newStream) === 'External') { selectedTrackElementIndex = index; @@ -1607,8 +1602,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla // Need to change the transcoded stream to add subs changeStream(player, getCurrentTicks(player), { SubtitleStreamIndex: index }); } - } - else if (currentStream && newStream) { + } else if (currentStream && newStream) { // Switching tracks // We can handle this clientside if the new track is external or the new track is embedded and we're not transcoding @@ -1645,7 +1639,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla player = player || self._currentPlayer; if (player.disableShowingSubtitleOffset) { player.disableShowingSubtitleOffset(); - } + } } self.isShowingSubtitleOffsetEnabled = function(player) { @@ -1674,7 +1668,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla self.canHandleOffsetOnCurrentSubtitle = function(player) { var index = self.getSubtitleStreamIndex(player); - return index !== -1 && self.isSubtitleStreamExternal(index, player); + return index !== -1 && self.isSubtitleStreamExternal(index, player); } self.seek = function (ticks, player) { @@ -1865,17 +1859,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (firstItem.Type === "Program") { promise = getItemsForPlayback(serverId, { - Ids: firstItem.ChannelId, + Ids: firstItem.ChannelId }); - } - else if (firstItem.Type === "Playlist") { + } else if (firstItem.Type === "Playlist") { promise = getItemsForPlayback(serverId, { ParentId: firstItem.Id, SortBy: options.shuffle ? 'Random' : null }); - } - else if (firstItem.Type === "MusicArtist") { + } else if (firstItem.Type === "MusicArtist") { promise = getItemsForPlayback(serverId, { ArtistIds: firstItem.Id, @@ -1885,8 +1877,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla MediaTypes: "Audio" }); - } - else if (firstItem.MediaType === "Photo") { + } else if (firstItem.MediaType === "Photo") { promise = getItemsForPlayback(serverId, { ParentId: firstItem.ParentId, @@ -1915,8 +1906,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return Promise.resolve(result); }); - } - else if (firstItem.Type === "PhotoAlbum") { + } else if (firstItem.Type === "PhotoAlbum") { promise = getItemsForPlayback(serverId, { ParentId: firstItem.Id, @@ -1928,8 +1918,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla Limit: 1000 }); - } - else if (firstItem.Type === "MusicGenre") { + } else if (firstItem.Type === "MusicGenre") { promise = getItemsForPlayback(serverId, { GenreIds: firstItem.Id, @@ -1938,8 +1927,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla SortBy: options.shuffle ? 'Random' : 'SortName', MediaTypes: "Audio" }); - } - else if (firstItem.IsFolder) { + } else if (firstItem.IsFolder) { promise = getItemsForPlayback(serverId, mergePlaybackQueries({ @@ -1951,8 +1939,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla MediaTypes: "Audio,Video" }, queryOptions)); - } - else if (firstItem.Type === "Episode" && items.length === 1 && getPlayer(firstItem, options).supportsProgress !== false) { + } else if (firstItem.Type === "Episode" && items.length === 1 && getPlayer(firstItem, options).supportsProgress !== false) { promise = new Promise(function (resolve, reject) { var apiClient = connectionManager.getApiClient(firstItem.ServerId); @@ -2537,16 +2524,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla playMethod = 'DirectPlay'; - } - - else if (mediaSource.StreamUrl) { + } else if (mediaSource.StreamUrl) { // Only used for audio playMethod = 'Transcode'; mediaUrl = mediaSource.StreamUrl; - } - - else if (mediaSource.SupportsDirectStream) { + } else if (mediaSource.SupportsDirectStream) { directOptions = { Static: true, @@ -2706,9 +2689,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return p.canPlayItem(item, playOptions); } return true; - } - - else if (item.Url && p.canPlayUrl) { + } else if (item.Url && p.canPlayUrl) { return p.canPlayUrl(item.Url); } } @@ -3222,8 +3203,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (displayErrorCode && typeof (displayErrorCode) === 'string') { showPlaybackInfoErrorMessage(self, displayErrorCode, nextItem); - } - else if (nextItem) { + } else if (nextItem) { self.nextTrack(); } } diff --git a/src/components/playback/playbackorientation.js b/src/components/playback/playbackorientation.js index 731d9c3c42..3253d8acdf 100644 --- a/src/components/playback/playbackorientation.js +++ b/src/components/playback/playbackorientation.js @@ -29,8 +29,7 @@ define(['playbackManager', 'layoutManager', 'events'], function (playbackManager // returns a boolean orientationLocked = promise; } - } - catch (err) { + } catch (err) { onOrientationChangeError(err); } } @@ -46,8 +45,7 @@ define(['playbackManager', 'layoutManager', 'events'], function (playbackManager if (unlockOrientation) { try { unlockOrientation(); - } - catch (err) { + } catch (err) { console.log('error unlocking orientation: ' + err); } orientationLocked = false; diff --git a/src/components/playback/playerSelectionMenu.js b/src/components/playback/playerSelectionMenu.js index 2102720e9a..7e4352bcb7 100644 --- a/src/components/playback/playerSelectionMenu.js +++ b/src/components/playback/playerSelectionMenu.js @@ -153,7 +153,6 @@ define(['appSettings', 'events', 'browser', 'loading', 'playbackManager', 'appRo }); } - function disconnectFromPlayer(currentDeviceName) { if (playbackManager.getSupportedCommands().indexOf('EndSession') !== -1) { @@ -193,7 +192,6 @@ define(['appSettings', 'events', 'browser', 'loading', 'playbackManager', 'appRo }); - } else { playbackManager.setDefaultPlayerActive(); @@ -275,8 +273,7 @@ define(['appSettings', 'events', 'browser', 'loading', 'playbackManager', 'appRo dialogHelper.open(dlg).then(function () { if (destination === 'nowplaying') { appRouter.showNowPlaying(); - } - else if (destination === 'disconnectFromPlayer') { + } else if (destination === 'disconnectFromPlayer') { disconnectFromPlayer(currentDeviceName); } }, emptyCallback); diff --git a/src/components/playback/playmethodhelper.js b/src/components/playback/playmethodhelper.js index 58458aa399..4e85f87093 100644 --- a/src/components/playback/playmethodhelper.js +++ b/src/components/playback/playmethodhelper.js @@ -9,14 +9,11 @@ define([], function () { if (session.TranscodingInfo && session.TranscodingInfo.IsVideoDirect) { return 'DirectStream'; - } - else if (session.PlayState.PlayMethod === 'Transcode') { + } else if (session.PlayState.PlayMethod === 'Transcode') { return 'Transcode'; - } - else if (session.PlayState.PlayMethod === 'DirectStream') { + } else if (session.PlayState.PlayMethod === 'DirectStream') { return 'DirectPlay'; - } - else if (session.PlayState.PlayMethod === 'DirectPlay') { + } else if (session.PlayState.PlayMethod === 'DirectPlay') { return 'DirectPlay'; } } diff --git a/src/components/playback/playqueuemanager.js b/src/components/playback/playqueuemanager.js index 2cbaf1d9f4..ed2076a814 100644 --- a/src/components/playback/playqueuemanager.js +++ b/src/components/playback/playqueuemanager.js @@ -58,15 +58,15 @@ define([], function () { function arrayInsertAt(destArray, pos, arrayToInsert) { var args = []; - args.push(pos); // where to insert - args.push(0); // nothing to remove - args = args.concat(arrayToInsert); // add on array to insert - destArray.splice.apply(destArray, args); // splice it in + args.push(pos); // where to insert + args.push(0); // nothing to remove + args = args.concat(arrayToInsert); // add on array to insert + destArray.splice.apply(destArray, args); // splice it in } PlayQueueManager.prototype.queueNext = function (items) { - - var i, length; + var i; + var length; for (i = 0, length = items.length; i < length; i++) { diff --git a/src/components/playerstats/playerstats.js b/src/components/playerstats/playerstats.js index 5e097f2fe2..4179192dd2 100644 --- a/src/components/playerstats/playerstats.js +++ b/src/components/playerstats/playerstats.js @@ -364,8 +364,7 @@ define(['events', 'globalize', 'playbackManager', 'connectionManager', 'playMeth var category = playerStats[i]; if (category.type === 'audio') { category.name = 'Audio Info'; - } - else if (category.type === 'video') { + } else if (category.type === 'video') { category.name = 'Video Info'; } categories.push(category); diff --git a/src/components/recordingcreator/recordingbutton.js b/src/components/recordingcreator/recordingbutton.js index 0a76d3914c..f51f8f2766 100644 --- a/src/components/recordingcreator/recordingbutton.js +++ b/src/components/recordingcreator/recordingbutton.js @@ -46,16 +46,13 @@ define(['globalize', 'connectionManager', 'require', 'loading', 'apphost', 'dom' if (item.Type === 'SeriesTimer') { return ''; - } - else if (item.TimerId || item.SeriesTimerId) { + } else if (item.TimerId || item.SeriesTimerId) { status = item.Status || 'Cancelled'; - } - else if (item.Type === 'Timer') { + } else if (item.Type === 'Timer') { status = item.Status; - } - else { + } else { return ''; } diff --git a/src/components/recordingcreator/recordingcreator.js b/src/components/recordingcreator/recordingcreator.js index b3d16a0dab..614d483b21 100644 --- a/src/components/recordingcreator/recordingcreator.js +++ b/src/components/recordingcreator/recordingcreator.js @@ -40,8 +40,7 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'c maxHeight: imageHeight, tag: item.ImageTags.Primary }); - } - else if (imageTags.Thumb) { + } else if (imageTags.Thumb) { return apiClient.getScaledImageUrl(item.Id, { type: "Thumb", diff --git a/src/components/recordingcreator/recordingeditor.js b/src/components/recordingcreator/recordingeditor.js index 69b8b1023b..3a1d4ba943 100644 --- a/src/components/recordingcreator/recordingeditor.js +++ b/src/components/recordingcreator/recordingeditor.js @@ -95,7 +95,6 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'c currentResolve = resolve; require(['text!./recordingeditor.template.html'], function (template) { - var dialogOptions = { removeOnClose: true, scrollY: false @@ -103,7 +102,6 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'c if (layoutManager.tv) { dialogOptions.size = 'fullscreen'; - } else { } var dlg = dialogHelper.createDialog(dialogOptions); diff --git a/src/components/recordingcreator/recordinghelper.js b/src/components/recordingcreator/recordinghelper.js index 8c56b578c9..4bfd316c73 100644 --- a/src/components/recordingcreator/recordinghelper.js +++ b/src/components/recordingcreator/recordinghelper.js @@ -166,8 +166,7 @@ define(['globalize', 'loading', 'connectionManager'], function (globalize, loadi loading.show(); cancelTimer(apiClient, timerId, true).then(resolve, reject); - } - else if (result === 'cancelseriestimer') { + } else if (result === 'cancelseriestimer') { loading.show(); diff --git a/src/components/recordingcreator/seriesrecordingeditor.js b/src/components/recordingcreator/seriesrecordingeditor.js index 9878081e67..73a98cf5e7 100644 --- a/src/components/recordingcreator/seriesrecordingeditor.js +++ b/src/components/recordingcreator/seriesrecordingeditor.js @@ -139,7 +139,7 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'c context.querySelector('.selectKeepUpTo').innerHTML = html; } - + function onFieldChange(e) { this.querySelector('.btnSubmit').click(); } diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index e586a1e124..562ea7ea35 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -179,15 +179,15 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL if (player) { switch (playbackManager.getRepeatMode(player)) { case "RepeatNone": - playbackManager.setRepeatMode("RepeatAll", player); - break; + playbackManager.setRepeatMode("RepeatAll", player); + break; case "RepeatAll": - playbackManager.setRepeatMode("RepeatOne", player); - break; + playbackManager.setRepeatMode("RepeatOne", player); + break; case "RepeatOne": - playbackManager.setRepeatMode("RepeatNone", player); + playbackManager.setRepeatMode("RepeatNone", player); } } } diff --git a/src/components/sanitizefilename.js b/src/components/sanitizefilename.js index 843ab31f04..d422a95533 100644 --- a/src/components/sanitizefilename.js +++ b/src/components/sanitizefilename.js @@ -34,18 +34,14 @@ define([], function () { // when parsing previous hi-surrogate, 3 is added to byteLength if (prevCodePoint != null && isHighSurrogate(prevCodePoint)) { byteLength += 1; - } - else { + } else { byteLength += 3; } - } - else if (codePoint <= 0x7f) { + } else if (codePoint <= 0x7f) { byteLength += 1; - } - else if (codePoint >= 0x80 && codePoint <= 0x7ff) { + } else if (codePoint >= 0x80 && codePoint <= 0x7ff) { byteLength += 2; - } - else if (codePoint >= 0x800 && codePoint <= 0xffff) { + } else if (codePoint >= 0x800 && codePoint <= 0xffff) { byteLength += 3; } prevCodePoint = codePoint; @@ -77,8 +73,7 @@ define([], function () { if (curByteLength === byteLength) { return string.slice(0, i + 1); - } - else if (curByteLength > byteLength) { + } else if (curByteLength > byteLength) { return string.slice(0, i - segment.length + 1); } } @@ -89,11 +84,11 @@ define([], function () { return { sanitize: function (input, replacement) { var sanitized = input - .replace(illegalRe, replacement) - .replace(controlRe, replacement) - .replace(reservedRe, replacement) - .replace(windowsReservedRe, replacement) - .replace(windowsTrailingRe, replacement); + .replace(illegalRe, replacement) + .replace(controlRe, replacement) + .replace(reservedRe, replacement) + .replace(windowsReservedRe, replacement) + .replace(windowsTrailingRe, replacement); return truncate(sanitized, 255); } }; diff --git a/src/components/scroller.js b/src/components/scroller.js index de0ce6b932..65f33b8e8d 100644 --- a/src/components/scroller.js +++ b/src/components/scroller.js @@ -82,7 +82,7 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc intervactive: null, // Selector for special interactive elements. // Mixed options - speed: 0, // Animations speed in milliseconds. 0 to disable animations. + speed: 0 // Animations speed in milliseconds. 0 to disable animations. }, options); @@ -93,17 +93,14 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc // in cases with firefox, if the smooth scroll api is supported then use that because their implementation is very good if (options.allowNativeScroll === false) { options.enableNativeScroll = false; - } - else if (isSmoothScrollSupported && ((browser.firefox && !layoutManager.tv) || options.allowNativeSmoothScroll)) { + } else if (isSmoothScrollSupported && ((browser.firefox && !layoutManager.tv) || options.allowNativeSmoothScroll)) { // native smooth scroll options.enableNativeScroll = true; - } - else if (options.requireAnimation && (browser.animate || browser.supportsCssAnimation())) { + } else if (options.requireAnimation && (browser.animate || browser.supportsCssAnimation())) { // transform is the only way to guarantee animation options.enableNativeScroll = false; - } - else if (!layoutManager.tv || !browser.animate) { + } else if (!layoutManager.tv || !browser.animate) { options.enableNativeScroll = true; } @@ -211,7 +208,9 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc self.frameResizeObserver.observe(frame); } - self.reload = function () { load(); }; + self.reload = function () { + load(); + }; self.getScrollEventName = function () { return transform ? 'scrollanimate' : 'scroll'; @@ -227,7 +226,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc function nativeScrollTo(container, pos, immediate) { - if (container.scroll) { if (o.horizontal) { @@ -242,8 +240,7 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc behavior: immediate ? 'instant' : 'smooth' }); } - } - else if (!immediate && container.scrollTo) { + } else if (!immediate && container.scrollTo) { if (o.horizontal) { container.scrollTo(Math.round(pos), 0); } else { diff --git a/src/components/search/searchresults.js b/src/components/search/searchresults.js index e42088c066..d979a94693 100644 --- a/src/components/search/searchresults.js +++ b/src/components/search/searchresults.js @@ -56,8 +56,7 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', if (instance.options.collectionType === 'tvshows') { if (query.IncludeArtists) { allowSearch = false; - } - else if (queryIncludeItemTypes === 'Movie' || + } else if (queryIncludeItemTypes === 'Movie' || queryIncludeItemTypes === 'LiveTvProgram' || queryIncludeItemTypes === 'MusicAlbum' || queryIncludeItemTypes === 'Audio' || @@ -69,12 +68,10 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', query.MediaTypes === 'Photo') { allowSearch = false; } - } - else if (instance.options.collectionType === 'movies') { + } else if (instance.options.collectionType === 'movies') { if (query.IncludeArtists) { allowSearch = false; - } - else if (queryIncludeItemTypes === 'Series' || + } else if (queryIncludeItemTypes === 'Series' || queryIncludeItemTypes === 'Episode' || queryIncludeItemTypes === 'LiveTvProgram' || queryIncludeItemTypes === 'MusicAlbum' || @@ -87,23 +84,19 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', query.MediaTypes === 'Photo') { allowSearch = false; } - } - else if (instance.options.collectionType === 'music') { + } else if (instance.options.collectionType === 'music') { if (query.People) { allowSearch = false; - } - else if (queryIncludeItemTypes === 'Series' || + } else if (queryIncludeItemTypes === 'Series' || queryIncludeItemTypes === 'Episode' || queryIncludeItemTypes === 'LiveTvProgram' || queryIncludeItemTypes === 'Movie') { allowSearch = false; } - } - else if (instance.options.collectionType === 'livetv') { + } else if (instance.options.collectionType === 'livetv') { if (query.IncludeArtists || query.IncludePeople) { allowSearch = false; - } - else if (queryIncludeItemTypes === 'Series' || + } else if (queryIncludeItemTypes === 'Series' || queryIncludeItemTypes === 'Episode' || queryIncludeItemTypes === 'MusicAlbum' || queryIncludeItemTypes === 'Audio' || @@ -142,7 +135,7 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', } else if (query.IncludeArtists) { methodName = 'getArtists'; - } + } } return apiClient[methodName](apiClient.getCurrentUserId(), query); @@ -179,19 +172,19 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.movieResults', { - preferThumb: true, - inheritThumb: false, - shape: (enableScrollX() ? 'overflowPortrait' : 'portrait'), - showParentTitleOrTitle: true, - showTitle: false, - centerText: true, - coverImage: true, - overlayText: false, - overlayMoreButton: true, - showAirTime: true, - showAirDateTime: true, - showChannelName: true - }); + preferThumb: true, + inheritThumb: false, + shape: (enableScrollX() ? 'overflowPortrait' : 'portrait'), + showParentTitleOrTitle: true, + showTitle: false, + centerText: true, + coverImage: true, + overlayText: false, + overlayMoreButton: true, + showAirTime: true, + showAirDateTime: true, + showChannelName: true + }); } else { searchType(instance, apiClient, { @@ -205,11 +198,11 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.movieResults', { - showTitle: true, - overlayText: false, - centerText: true, - showYear: true - }); + showTitle: true, + overlayText: false, + centerText: true, + showYear: true + }); } searchType(instance, apiClient, { @@ -223,11 +216,11 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.seriesResults', { - showTitle: true, - overlayText: false, - centerText: true, - showYear: true - }); + showTitle: true, + overlayText: false, + centerText: true, + showYear: true + }); if (instance.options.collectionType === 'livetv') { @@ -246,19 +239,19 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.episodeResults', { - preferThumb: true, - inheritThumb: false, - shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'), - showParentTitleOrTitle: true, - showTitle: false, - centerText: true, - coverImage: true, - overlayText: false, - overlayMoreButton: true, - showAirTime: true, - showAirDateTime: true, - showChannelName: true - }); + preferThumb: true, + inheritThumb: false, + shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'), + showParentTitleOrTitle: true, + showTitle: false, + centerText: true, + coverImage: true, + overlayText: false, + overlayMoreButton: true, + showAirTime: true, + showAirDateTime: true, + showChannelName: true + }); } else { @@ -273,10 +266,10 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.episodeResults', { - coverImage: true, - showTitle: true, - showParentTitle: true - }); + coverImage: true, + showTitle: true, + showParentTitle: true + }); } searchType(instance, apiClient, { @@ -292,20 +285,20 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.sportsResults', { - preferThumb: true, - inheritThumb: false, - shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'), - showParentTitleOrTitle: true, - showTitle: false, - centerText: true, - coverImage: true, - overlayText: false, - overlayMoreButton: true, - showAirTime: true, - showAirDateTime: true, - showChannelName: true + preferThumb: true, + inheritThumb: false, + shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'), + showParentTitleOrTitle: true, + showTitle: false, + centerText: true, + coverImage: true, + overlayText: false, + overlayMoreButton: true, + showAirTime: true, + showAirDateTime: true, + showChannelName: true - }); + }); searchType(instance, apiClient, { searchTerm: value, @@ -320,20 +313,20 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.kidsResults', { - preferThumb: true, - inheritThumb: false, - shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'), - showParentTitleOrTitle: true, - showTitle: false, - centerText: true, - coverImage: true, - overlayText: false, - overlayMoreButton: true, - showAirTime: true, - showAirDateTime: true, - showChannelName: true + preferThumb: true, + inheritThumb: false, + shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'), + showParentTitleOrTitle: true, + showTitle: false, + centerText: true, + coverImage: true, + overlayText: false, + overlayMoreButton: true, + showAirTime: true, + showAirDateTime: true, + showChannelName: true - }); + }); searchType(instance, apiClient, { searchTerm: value, @@ -348,20 +341,20 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.newsResults', { - preferThumb: true, - inheritThumb: false, - shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'), - showParentTitleOrTitle: true, - showTitle: false, - centerText: true, - coverImage: true, - overlayText: false, - overlayMoreButton: true, - showAirTime: true, - showAirDateTime: true, - showChannelName: true + preferThumb: true, + inheritThumb: false, + shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'), + showParentTitleOrTitle: true, + showTitle: false, + centerText: true, + coverImage: true, + overlayText: false, + overlayMoreButton: true, + showAirTime: true, + showAirDateTime: true, + showChannelName: true - }); + }); searchType(instance, apiClient, { searchTerm: value, @@ -379,20 +372,20 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.programResults', { - preferThumb: true, - inheritThumb: false, - shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'), - showParentTitleOrTitle: true, - showTitle: false, - centerText: true, - coverImage: true, - overlayText: false, - overlayMoreButton: true, - showAirTime: true, - showAirDateTime: true, - showChannelName: true + preferThumb: true, + inheritThumb: false, + shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'), + showParentTitleOrTitle: true, + showTitle: false, + centerText: true, + coverImage: true, + overlayText: false, + overlayMoreButton: true, + showAirTime: true, + showAirDateTime: true, + showChannelName: true - }); + }); searchType(instance, apiClient, { searchTerm: value, @@ -406,11 +399,11 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.videoResults', { - showParentTitle: true, - showTitle: true, - overlayText: false, - centerText: true - }); + showParentTitle: true, + showTitle: true, + overlayText: false, + centerText: true + }); searchType(instance, apiClient, { searchTerm: value, @@ -422,9 +415,9 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.peopleResults', { - coverImage: true, - showTitle: true - }); + coverImage: true, + showTitle: true + }); searchType(instance, apiClient, { searchTerm: value, @@ -435,9 +428,9 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', IncludeArtists: true }, context, '.artistResults', { - coverImage: true, - showTitle: true - }); + coverImage: true, + showTitle: true + }); searchType(instance, apiClient, { searchTerm: value, @@ -450,11 +443,11 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.albumResults', { - showParentTitle: true, - showTitle: true, - overlayText: false, - centerText: true - }); + showParentTitle: true, + showTitle: true, + overlayText: false, + centerText: true + }); searchType(instance, apiClient, { searchTerm: value, @@ -467,13 +460,13 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.songResults', { - showParentTitle: true, - showTitle: true, - overlayText: false, - centerText: true, - action: 'play' + showParentTitle: true, + showTitle: true, + overlayText: false, + centerText: true, + action: 'play' - }); + }); searchType(instance, apiClient, { searchTerm: value, @@ -486,11 +479,11 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.photoResults', { - showParentTitle: false, - showTitle: true, - overlayText: false, - centerText: true - }); + showParentTitle: false, + showTitle: true, + overlayText: false, + centerText: true + }); searchType(instance, apiClient, { searchTerm: value, @@ -503,10 +496,10 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.photoAlbumResults', { - showTitle: true, - overlayText: false, - centerText: true - }); + showTitle: true, + overlayText: false, + centerText: true + }); searchType(instance, apiClient, { searchTerm: value, @@ -519,11 +512,11 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.bookResults', { - showTitle: true, - overlayText: false, - centerText: true + showTitle: true, + overlayText: false, + centerText: true - }); + }); searchType(instance, apiClient, { searchTerm: value, @@ -536,10 +529,10 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.audioBookResults', { - showTitle: true, - overlayText: false, - centerText: true - }); + showTitle: true, + overlayText: false, + centerText: true + }); searchType(instance, apiClient, { searchTerm: value, @@ -552,10 +545,10 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }, context, '.playlistResults', { - showTitle: true, - overlayText: false, - centerText: true - }); + showTitle: true, + overlayText: false, + centerText: true + }); } function searchType(instance, apiClient, query, context, section, cardOptions) { diff --git a/src/components/serverNotifications/gamepadtokey.js b/src/components/serverNotifications/gamepadtokey.js index 5dafb2828b..abf3ddb38b 100644 --- a/src/components/serverNotifications/gamepadtokey.js +++ b/src/components/serverNotifications/gamepadtokey.js @@ -22,44 +22,44 @@ require(['apphost'], function (appHost) { "use strict"; - var _GAMEPAD_A_BUTTON_INDEX = 0, - _GAMEPAD_B_BUTTON_INDEX = 1, - _GAMEPAD_DPAD_UP_BUTTON_INDEX = 12, - _GAMEPAD_DPAD_DOWN_BUTTON_INDEX = 13, - _GAMEPAD_DPAD_LEFT_BUTTON_INDEX = 14, - _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX = 15, - _GAMEPAD_A_KEY = "GamepadA", - _GAMEPAD_B_KEY = "GamepadB", - _GAMEPAD_DPAD_UP_KEY = "GamepadDPadUp", - _GAMEPAD_DPAD_DOWN_KEY = "GamepadDPadDown", - _GAMEPAD_DPAD_LEFT_KEY = "GamepadDPadLeft", - _GAMEPAD_DPAD_RIGHT_KEY = "GamepadDPadRight", - _GAMEPAD_LEFT_THUMBSTICK_UP_KEY = "GamepadLeftThumbStickUp", - _GAMEPAD_LEFT_THUMBSTICK_DOWN_KEY = "GamepadLeftThumbStickDown", - _GAMEPAD_LEFT_THUMBSTICK_LEFT_KEY = "GamepadLeftThumbStickLeft", - _GAMEPAD_LEFT_THUMBSTICK_RIGHT_KEY = "GamepadLeftThumbStickRight", - _GAMEPAD_A_KEYCODE = 0, - _GAMEPAD_B_KEYCODE = 27, - _GAMEPAD_DPAD_UP_KEYCODE = 38, - _GAMEPAD_DPAD_DOWN_KEYCODE = 40, - _GAMEPAD_DPAD_LEFT_KEYCODE = 37, - _GAMEPAD_DPAD_RIGHT_KEYCODE = 39, - _GAMEPAD_LEFT_THUMBSTICK_UP_KEYCODE = 38, - _GAMEPAD_LEFT_THUMBSTICK_DOWN_KEYCODE = 40, - _GAMEPAD_LEFT_THUMBSTICK_LEFT_KEYCODE = 37, - _GAMEPAD_LEFT_THUMBSTICK_RIGHT_KEYCODE = 39, - _THUMB_STICK_THRESHOLD = 0.75; + var _GAMEPAD_A_BUTTON_INDEX = 0; + var _GAMEPAD_B_BUTTON_INDEX = 1; + var _GAMEPAD_DPAD_UP_BUTTON_INDEX = 12; + var _GAMEPAD_DPAD_DOWN_BUTTON_INDEX = 13; + var _GAMEPAD_DPAD_LEFT_BUTTON_INDEX = 14; + var _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX = 15; + var _GAMEPAD_A_KEY = "GamepadA"; + var _GAMEPAD_B_KEY = "GamepadB"; + var _GAMEPAD_DPAD_UP_KEY = "GamepadDPadUp"; + var _GAMEPAD_DPAD_DOWN_KEY = "GamepadDPadDown"; + var _GAMEPAD_DPAD_LEFT_KEY = "GamepadDPadLeft"; + var _GAMEPAD_DPAD_RIGHT_KEY = "GamepadDPadRight"; + var _GAMEPAD_LEFT_THUMBSTICK_UP_KEY = "GamepadLeftThumbStickUp"; + var _GAMEPAD_LEFT_THUMBSTICK_DOWN_KEY = "GamepadLeftThumbStickDown"; + var _GAMEPAD_LEFT_THUMBSTICK_LEFT_KEY = "GamepadLeftThumbStickLeft"; + var _GAMEPAD_LEFT_THUMBSTICK_RIGHT_KEY = "GamepadLeftThumbStickRight"; + var _GAMEPAD_A_KEYCODE = 0; + var _GAMEPAD_B_KEYCODE = 27; + var _GAMEPAD_DPAD_UP_KEYCODE = 38; + var _GAMEPAD_DPAD_DOWN_KEYCODE = 40; + var _GAMEPAD_DPAD_LEFT_KEYCODE = 37; + var _GAMEPAD_DPAD_RIGHT_KEYCODE = 39; + var _GAMEPAD_LEFT_THUMBSTICK_UP_KEYCODE = 38; + var _GAMEPAD_LEFT_THUMBSTICK_DOWN_KEYCODE = 40; + var _GAMEPAD_LEFT_THUMBSTICK_LEFT_KEYCODE = 37; + var _GAMEPAD_LEFT_THUMBSTICK_RIGHT_KEYCODE = 39; + var _THUMB_STICK_THRESHOLD = 0.75; - var _leftThumbstickUpPressed = false, - _leftThumbstickDownPressed = false, - _leftThumbstickLeftPressed = false, - _leftThumbstickRightPressed = false, - _dPadUpPressed = false, - _dPadDownPressed = false, - _dPadLeftPressed = false, - _dPadRightPressed = false, - _gamepadAPressed = false, - _gamepadBPressed = false; + var _leftThumbstickUpPressed = false; + var _leftThumbstickDownPressed = false; + var _leftThumbstickLeftPressed = false; + var _leftThumbstickRightPressed = false; + var _dPadUpPressed = false; + var _dPadDownPressed = false; + var _dPadLeftPressed = false; + var _dPadRightPressed = false; + var _gamepadAPressed = false; + var _gamepadBPressed = false; // The set of buttons on the gamepad we listen for. var ProcessedButtons = [ @@ -260,7 +260,9 @@ require(['apphost'], function (appHost) { gamepads = navigator.webkitGetGamepads(); } gamepads = gamepads || []; - var i, j, len; + var i; + var j; + var len; for (i = 0, len = gamepads.length; i < len; i++) { var gamepad = gamepads[i]; if (gamepad) { diff --git a/src/components/serverNotifications/serverNotifications.js b/src/components/serverNotifications/serverNotifications.js index 74c65cd473..ff571b1e1a 100644 --- a/src/components/serverNotifications/serverNotifications.js +++ b/src/components/serverNotifications/serverNotifications.js @@ -18,8 +18,7 @@ define(['connectionManager', 'playbackManager', 'events', 'inputManager', 'focus toast({ title: args.Header, text: args.Text }); }); - } - else { + } else { require(['alert'], function (alert) { alert({ title: args.Header, text: args.Text }); }); @@ -157,11 +156,9 @@ define(['connectionManager', 'playbackManager', 'events', 'inputManager', 'focus if (msg.Data.PlayCommand === "PlayNext") { playbackManager.queueNext({ ids: msg.Data.ItemIds, serverId: serverId }); - } - else if (msg.Data.PlayCommand === "PlayLast") { + } else if (msg.Data.PlayCommand === "PlayLast") { playbackManager.queue({ ids: msg.Data.ItemIds, serverId: serverId }); - } - else { + } else { playbackManager.play({ ids: msg.Data.ItemIds, startPositionTicks: msg.Data.StartPositionTicks, @@ -173,38 +170,29 @@ define(['connectionManager', 'playbackManager', 'events', 'inputManager', 'focus }); } - } - else if (msg.MessageType === "Playstate") { + } else if (msg.MessageType === "Playstate") { if (msg.Data.Command === 'Stop') { inputManager.trigger('stop'); - } - else if (msg.Data.Command === 'Pause') { + } else if (msg.Data.Command === 'Pause') { inputManager.trigger('pause'); - } - else if (msg.Data.Command === 'Unpause') { + } else if (msg.Data.Command === 'Unpause') { inputManager.trigger('play'); - } - else if (msg.Data.Command === 'PlayPause') { + } else if (msg.Data.Command === 'PlayPause') { inputManager.trigger('playpause'); - } - else if (msg.Data.Command === 'Seek') { + } else if (msg.Data.Command === 'Seek') { playbackManager.seek(msg.Data.SeekPositionTicks); - } - else if (msg.Data.Command === 'NextTrack') { + } else if (msg.Data.Command === 'NextTrack') { inputManager.trigger('next'); - } - else if (msg.Data.Command === 'PreviousTrack') { + } else if (msg.Data.Command === 'PreviousTrack') { inputManager.trigger('previous'); } else { notifyApp(); } - } - else if (msg.MessageType === "GeneralCommand") { + } else if (msg.MessageType === "GeneralCommand") { var cmd = msg.Data; processGeneralCommand(cmd, apiClient); - } - else if (msg.MessageType === "UserDataChanged") { + } else if (msg.MessageType === "UserDataChanged") { if (msg.Data.UserId === apiClient.getCurrentUserId()) { @@ -212,8 +200,7 @@ define(['connectionManager', 'playbackManager', 'events', 'inputManager', 'focus events.trigger(serverNotifications, 'UserDataChanged', [apiClient, msg.Data.UserDataList[i]]); } } - } - else { + } else { events.trigger(serverNotifications, msg.MessageType, [apiClient, msg.Data]); } diff --git a/src/components/serverRestartDialog.js b/src/components/serverRestartDialog.js index 6c7e5b7386..4c20183b2a 100644 --- a/src/components/serverRestartDialog.js +++ b/src/components/serverRestartDialog.js @@ -6,9 +6,7 @@ define(['loading', 'events', 'dialogHelper', 'dom', 'layoutManager', 'scrollHelp var currentInstance; function reloadPageWhenServerAvailable(retryCount) { - var apiClient = currentApiClient; - if (!apiClient) { return; } @@ -31,7 +29,6 @@ define(['loading', 'events', 'dialogHelper', 'dom', 'layoutManager', 'scrollHelp function retryReload(retryCount) { setTimeout(function () { - retryCount = retryCount || 0; retryCount++; @@ -42,15 +39,12 @@ define(['loading', 'events', 'dialogHelper', 'dom', 'layoutManager', 'scrollHelp } function startRestart(instance, apiClient, dlg) { - currentApiClient = apiClient; currentDlg = dlg; currentInstance = instance; apiClient.restartServer().then(function () { - setTimeout(reloadPageWhenServerAvailable, 250); - }); } @@ -94,7 +88,8 @@ define(['loading', 'events', 'dialogHelper', 'dom', 'layoutManager', 'scrollHelp dlg.querySelector('.text').innerHTML = globalize.translate('RestartPleaseWaitMessage'); - var i, length; + var i; + var length; var html = ''; for (i = 0, length = configuredButtons.length; i < length; i++) { var item = configuredButtons[i]; @@ -138,12 +133,10 @@ define(['loading', 'events', 'dialogHelper', 'dom', 'layoutManager', 'scrollHelp } function ServerRestartDialog(options) { - this.options = options; } ServerRestartDialog.prototype.show = function () { - var instance = this; loading.show(); @@ -155,7 +148,6 @@ define(['loading', 'events', 'dialogHelper', 'dom', 'layoutManager', 'scrollHelp }; ServerRestartDialog.prototype.destroy = function () { - currentApiClient = null; currentDlg = null; currentInstance = null; diff --git a/src/components/shell.js b/src/components/shell.js index 762039ac42..534a57b027 100644 --- a/src/components/shell.js +++ b/src/components/shell.js @@ -8,7 +8,7 @@ define([], function () { } else { window.open(url, target || '_blank'); } - + }, canExec: false, exec: function (options) { diff --git a/src/components/shortcuts.js b/src/components/shortcuts.js index f6c1e97893..9d2b1847e5 100644 --- a/src/components/shortcuts.js +++ b/src/components/shortcuts.js @@ -128,8 +128,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl if (result.command === 'playallfromhere' || result.command === 'queueallfromhere') { executeAction(card, options.positionTo, result.command); - } - else if (result.updated || result.deleted) { + } else if (result.updated || result.deleted) { notifyRefreshNeeded(card, options.itemsContainer); } }); @@ -204,21 +203,15 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl context: card.getAttribute('data-context'), parentId: card.getAttribute('data-parentid') }); - } - - else if (action === 'programdialog') { + } else if (action === 'programdialog') { showProgramDialog(item); - } - - else if (action === 'instantmix') { + } else if (action === 'instantmix') { playbackManager.instantMix({ Id: playableItemId, ServerId: serverId }); - } - - else if (action === 'play' || action === 'resume') { + } else if (action === 'play' || action === 'resume') { var startPositionTicks = parseInt(card.getAttribute('data-positionticks') || '0'); @@ -227,9 +220,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl startPositionTicks: startPositionTicks, serverId: serverId }); - } - - else if (action === 'queue') { + } else if (action === 'queue') { if (playbackManager.isPlaying()) { playbackManager.queue({ @@ -243,25 +234,15 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl serverId: serverId }); } - } - - else if (action === 'playallfromhere') { + } else if (action === 'playallfromhere') { playAllFromHere(card, serverId); - } - - else if (action === 'queueallfromhere') { + } else if (action === 'queueallfromhere') { playAllFromHere(card, serverId, true); - } - - else if (action === 'setplaylistindex') { + } else if (action === 'setplaylistindex') { playbackManager.setCurrentPlaylistItem(card.getAttribute('data-playlistitemid')); - } - - else if (action === 'record') { + } else if (action === 'record') { onRecordCommand(serverId, id, type, card.getAttribute('data-timerid'), card.getAttribute('data-seriestimerid')); - } - - else if (action === 'menu') { + } else if (action === 'menu') { var options = target.getAttribute('data-playoptions') === 'false' ? { @@ -277,27 +258,17 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl options.positionTo = target; showContextMenu(card, options); - } - - else if (action === 'playmenu') { + } else if (action === 'playmenu') { showPlayMenu(card, target); - } - - else if (action === 'edit') { + } else if (action === 'edit') { getItem(target).then(function (item) { editItem(item, serverId); }); - } - - else if (action === 'playtrailer') { + } else if (action === 'playtrailer') { getItem(target).then(playTrailer); - } - - else if (action === 'addtoplaylist') { + } else if (action === 'addtoplaylist') { getItem(target).then(addToPlaylist); - } - - else if (action === 'custom') { + } else if (action === 'custom') { var customAction = target.getAttribute('data-customaction'); diff --git a/src/components/skinManager.js b/src/components/skinManager.js index 780b8273bb..9f96516422 100644 --- a/src/components/skinManager.js +++ b/src/components/skinManager.js @@ -20,7 +20,7 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr } else { Emby.Page.goHome(); } - }; + } function getThemes() { return [{ @@ -36,7 +36,7 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr isDefaultServerDashboard: true }, { name: "Emby", - id: "emby", + id: "emby" }, { name: "Light", id: "light" @@ -47,7 +47,7 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr name: "Windows Media Center", id: "wmc" }]; - }; + } var skinManager = { getThemes: getThemes, diff --git a/src/components/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index 6bb485a616..a5acd042b3 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -77,8 +77,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f try { appHost.setUserScalable(scalable); - } - catch (err) { + } catch (err) { console.log('error in appHost.setUserScalable: ' + err); } } diff --git a/src/components/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js index 27055f5976..b79bf4ba1a 100644 --- a/src/components/subtitleeditor/subtitleeditor.js +++ b/src/components/subtitleeditor/subtitleeditor.js @@ -192,8 +192,7 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', var lastLanguage = userSettings.get('subtitleeditor-language'); if (lastLanguage) { selectLanguage.value = lastLanguage; - } - else { + } else { apiClient.getCurrentUser().then(function (user) { @@ -347,8 +346,7 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', if (typeof itemId === 'string') { apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(onGetItem); - } - else { + } else { onGetItem(itemId); } } diff --git a/src/components/subtitlesettings/subtitleappearancehelper.js b/src/components/subtitlesettings/subtitleappearancehelper.js index 588f491a67..8a40bd134b 100644 --- a/src/components/subtitlesettings/subtitleappearancehelper.js +++ b/src/components/subtitlesettings/subtitleappearancehelper.js @@ -33,7 +33,7 @@ define([], function () { case 'smaller': list.push({ name: 'font-size', value: '.8em' }); break; - case 'small': + case 'small': list.push({ name: 'font-size', value: 'inherit' }); break; case 'larger': @@ -132,7 +132,6 @@ define([], function () { function applyStyleList(styles, elem) { - for (var i = 0, length = styles.length; i < length; i++) { var style = styles[i]; diff --git a/src/components/subtitlesync/subtitlesync.js b/src/components/subtitlesync/subtitlesync.js index 3389b7bf89..904c612317 100644 --- a/src/components/subtitlesync/subtitlesync.js +++ b/src/components/subtitlesync/subtitlesync.js @@ -25,10 +25,10 @@ define(['playbackManager', 'text!./subtitlesync.template.html', 'css!./subtitles subtitleSyncTextField.addEventListener("keypress", function(event) { - if(event.key === "Enter"){ + if (event.key === "Enter") { // if input key is enter search for float pattern var inputOffset = /[-+]?\d+\.?\d*/g.exec(this.textContent); - if(inputOffset) { + if (inputOffset) { inputOffset = inputOffset[0]; // replace current text by considered offset @@ -48,7 +48,7 @@ define(['playbackManager', 'text!./subtitlesync.template.html', 'css!./subtitles } else { // keep focus to prevent fade with bottom layout this.hasFocus = true; - if(event.key.match(/[+-\d.s]/) === null) { + if (event.key.match(/[+-\d.s]/) === null) { event.preventDefault(); } } @@ -92,14 +92,13 @@ define(['playbackManager', 'text!./subtitlesync.template.html', 'css!./subtitles instance.element = parent; } - function getOffsetFromPercentage(value) { // convert percent to fraction var offset = (value - 50) / 50; // multiply by offset min/max range value (-x to +x) : offset *= 30; return offset.toFixed(1); - }; + } function getPercentageFromOffset(value) { // divide by offset min/max range value (-x to +x) : @@ -108,16 +107,16 @@ define(['playbackManager', 'text!./subtitlesync.template.html', 'css!./subtitles percentValue *= 50; percentValue += 50; return Math.min(100, Math.max(0, percentValue.toFixed())); - }; + } function SubtitleSync(currentPlayer) { player = currentPlayer; init(this); } - SubtitleSync.prototype.destroy = function(){ + SubtitleSync.prototype.destroy = function() { SubtitleSync.prototype.toggle("forceToHide"); - if(player){ + if (player) { playbackManager.disableShowingSubtitleOffset(player); playbackManager.setSubtitleOffset(0, player); } @@ -130,27 +129,30 @@ define(['playbackManager', 'text!./subtitlesync.template.html', 'css!./subtitles SubtitleSync.prototype.toggle = function(action) { - if(player && playbackManager.supportSubtitleOffset(player)){ + if (player && playbackManager.supportSubtitleOffset(player)) { - switch(action) { + switch (action) { case undefined: // if showing subtitle sync is enabled - if(playbackManager.isShowingSubtitleOffsetEnabled(player) && + if (playbackManager.isShowingSubtitleOffsetEnabled(player) && // if there is an external subtitle stream enabled - playbackManager.canHandleOffsetOnCurrentSubtitle(player)){ - // if no subtitle offset is defined - if(!playbackManager.getPlayerSubtitleOffset(player)) { - // set default offset to '0' = 50% - subtitleSyncSlider.value = "50"; - subtitleSyncTextField.textContent = "0s"; - playbackManager.setSubtitleOffset(0, player); - } - // show subtitle sync - subtitleSyncContainer.classList.remove("hide"); - break; // stop here + playbackManager.canHandleOffsetOnCurrentSubtitle(player)) { + // if no subtitle offset is defined + if (!playbackManager.getPlayerSubtitleOffset(player)) { + // set default offset to '0' = 50% + subtitleSyncSlider.value = "50"; + subtitleSyncTextField.textContent = "0s"; + playbackManager.setSubtitleOffset(0, player); + } + // show subtitle sync + subtitleSyncContainer.classList.remove("hide"); + break; // stop here } // else continue and hide case "hide": - if(subtitleSyncTextField.hasFocus){break;} // else continue and hide + // only break if element has focus + if (subtitleSyncTextField.hasFocus) { + break; + } case "forceToHide": subtitleSyncContainer.classList.add("hide"); break; diff --git a/src/components/tabbedview/itemstab.js b/src/components/tabbedview/itemstab.js index ec874c69e9..7381232fc9 100644 --- a/src/components/tabbedview/itemstab.js +++ b/src/components/tabbedview/itemstab.js @@ -246,7 +246,8 @@ define(['playbackManager', 'userSettings', 'alphaPicker', 'alphaNumericShortcuts this.itemsContainer.setAttribute('data-parentid', params.parentId); } - var i, length; + var i; + var length; var btnViewSettings = view.querySelectorAll('.btnViewSettings'); for (i = 0, length = btnViewSettings.length; i < length; i++) { @@ -559,7 +560,6 @@ define(['playbackManager', 'userSettings', 'alphaPicker', 'alphaNumericShortcuts }; ItemsTab.prototype.onPause = function () { - var scroller = this.scroller; if (scroller && scroller.pause) { scroller.pause(); @@ -573,7 +573,6 @@ define(['playbackManager', 'userSettings', 'alphaPicker', 'alphaNumericShortcuts }; ItemsTab.prototype.destroy = function () { - this.view = null; this.itemsContainer = null; this.params = null; @@ -585,6 +584,7 @@ define(['playbackManager', 'userSettings', 'alphaPicker', 'alphaNumericShortcuts this.alphaPicker.destroy(); this.alphaPicker = null; } + this.sortButtons = null; this.btnSortText = null; this.btnSortIcon = null; diff --git a/src/components/tabbedview/tabbedview.js b/src/components/tabbedview/tabbedview.js index bc656bc3e2..33f1c6e6cc 100644 --- a/src/components/tabbedview/tabbedview.js +++ b/src/components/tabbedview/tabbedview.js @@ -101,8 +101,7 @@ define(['backdrop', 'mainTabsManager', 'layoutManager', 'emby-tabs'], function ( if (!currentTabController) { mainTabsManager.selectedTabIndex(this.initialTabIndex); - } - else if (currentTabController && currentTabController.onResume) { + } else if (currentTabController && currentTabController.onResume) { currentTabController.onResume({}); } }; diff --git a/src/components/thememediaplayer.js b/src/components/thememediaplayer.js index 732cbb1cb0..a8298fad37 100644 --- a/src/components/thememediaplayer.js +++ b/src/components/thememediaplayer.js @@ -94,8 +94,7 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playb if (viewOptions.supportsThemeMedia) { // Do nothing here, allow it to keep playing - } - else { + } else { playThemeMedia([], null); } diff --git a/src/components/touchhelper.js b/src/components/touchhelper.js index 66d115046b..0f6d34aace 100644 --- a/src/components/touchhelper.js +++ b/src/components/touchhelper.js @@ -78,11 +78,9 @@ define(['dom', 'events'], function (dom, events) { if (deltaX > swipeXThreshold && Math.abs(deltaY) < swipeXMaxY) { events.trigger(self, 'swiperight', [touchTarget]); - } - else if (deltaX < (0 - swipeXThreshold) && Math.abs(deltaY) < swipeXMaxY) { + } else if (deltaX < (0 - swipeXThreshold) && Math.abs(deltaY) < swipeXMaxY) { events.trigger(self, 'swipeleft', [touchTarget]); - } - else if ((deltaY < (0 - swipeYThreshold) || thresholdYMet) && Math.abs(deltaX) < swipeXMaxY) { + } else if ((deltaY < (0 - swipeYThreshold) || thresholdYMet) && Math.abs(deltaX) < swipeXMaxY) { thresholdYMet = true; @@ -94,8 +92,7 @@ define(['dom', 'events'], function (dom, events) { currentDeltaX: currentDeltaX, currentDeltaY: currentDeltaY }]); - } - else if ((deltaY > swipeYThreshold || thresholdYMet) && Math.abs(deltaX) < swipeXMaxY) { + } else if ((deltaY > swipeYThreshold || thresholdYMet) && Math.abs(deltaX) < swipeXMaxY) { thresholdYMet = true; events.trigger(self, 'swipedown', [touchTarget, { diff --git a/src/components/userdatabuttons/emby-ratingbutton.js b/src/components/userdatabuttons/emby-ratingbutton.js index 40cf033cd5..190424d44d 100644 --- a/src/components/userdatabuttons/emby-ratingbutton.js +++ b/src/components/userdatabuttons/emby-ratingbutton.js @@ -33,8 +33,7 @@ define(['connectionManager', 'serverNotifications', 'events', 'globalize', 'emby var isFavorite = this.getAttribute('data-isfavorite') === 'true'; if (likes === 'true') { likes = true; - } - else if (likes === 'false') { + } else if (likes === 'false') { likes = false; } else { likes = null; @@ -64,7 +63,7 @@ define(['connectionManager', 'serverNotifications', 'events', 'globalize', 'emby if (icon) { icon.innerHTML = ''; - icon.classList.add('ratingbutton-icon-withrating'); + icon.classList.add('ratingbutton-icon-withrating'); } button.classList.add('ratingbutton-withrating'); @@ -73,7 +72,7 @@ define(['connectionManager', 'serverNotifications', 'events', 'globalize', 'emby if (icon) { icon.innerHTML = ''; - icon.classList.remove('ratingbutton-icon-withrating'); + icon.classList.remove('ratingbutton-icon-withrating'); //icon.innerHTML = ''; } button.classList.remove('ratingbutton-withrating'); @@ -82,7 +81,7 @@ define(['connectionManager', 'serverNotifications', 'events', 'globalize', 'emby if (icon) { icon.innerHTML = ''; - icon.classList.remove('ratingbutton-icon-withrating'); + icon.classList.remove('ratingbutton-icon-withrating'); //icon.innerHTML = ''; } button.classList.remove('ratingbutton-withrating'); @@ -91,7 +90,7 @@ define(['connectionManager', 'serverNotifications', 'events', 'globalize', 'emby if (icon) { icon.innerHTML = ''; - icon.classList.remove('ratingbutton-icon-withrating'); + icon.classList.remove('ratingbutton-icon-withrating'); //icon.innerHTML = ''; } button.classList.remove('ratingbutton-withrating'); @@ -152,8 +151,7 @@ define(['connectionManager', 'serverNotifications', 'events', 'globalize', 'emby var isFavorite = this.getAttribute('data-isfavorite') === 'true'; if (likes === 'true') { likes = true; - } - else if (likes === 'false') { + } else if (likes === 'false') { likes = false; } else { likes = null; diff --git a/src/components/viewContainer.js b/src/components/viewContainer.js index ece8da1ed6..c2d060162e 100644 --- a/src/components/viewContainer.js +++ b/src/components/viewContainer.js @@ -42,7 +42,6 @@ define(["browser", "dom", "layoutManager", "css!components/viewManager/viewConta var newViewInfo = normalizeNewView(options, isPluginpage); var newView = newViewInfo.elem; - if (isPluginpage) { require(["legacyDashboard"]); } diff --git a/src/components/viewManager/viewManager.js b/src/components/viewManager/viewManager.js index 23612d5a1e..a8e514e06e 100644 --- a/src/components/viewManager/viewManager.js +++ b/src/components/viewManager/viewManager.js @@ -50,8 +50,7 @@ define(['viewContainer', 'focusManager', 'queryString', 'layoutManager'], functi if (options.autoFocus !== false) { focusManager.autoFocus(view); } - } - else if (!layoutManager.mobile) { + } else if (!layoutManager.mobile) { if (view.activeElement && document.body.contains(view.activeElement) && focusManager.isCurrentlyFocusable(view.activeElement)) { focusManager.focus(view.activeElement); } else { diff --git a/src/components/viewsettings/viewsettings.js b/src/components/viewsettings/viewsettings.js index 617e021115..5195598d99 100644 --- a/src/components/viewsettings/viewsettings.js +++ b/src/components/viewsettings/viewsettings.js @@ -29,7 +29,7 @@ define(['require', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'conne } userSettings.set(settingsKey + '-imageType', context.querySelector('.selectImageType').value); - } + } function centerFocus(elem, horiz, on) { require(['scrollHelper'], function (scrollHelper) { diff --git a/src/components/visibleinviewport.js b/src/components/visibleinviewport.js index 23a2a9d73c..3768740175 100644 --- a/src/components/visibleinviewport.js +++ b/src/components/visibleinviewport.js @@ -22,17 +22,17 @@ define(['dom'], function (dom) { var windowSize = dom.getWindowSize(); - var vpWidth = windowSize.innerWidth, - vpHeight = windowSize.innerHeight; + var vpWidth = windowSize.innerWidth; + var vpHeight = windowSize.innerHeight; // Use this native browser method, if available. - var rec = elem.getBoundingClientRect(), - tViz = rec.top >= 0 && rec.top < vpHeight + thresholdY, - bViz = rec.bottom > 0 && rec.bottom <= vpHeight + thresholdY, - lViz = rec.left >= 0 && rec.left < vpWidth + thresholdX, - rViz = rec.right > 0 && rec.right <= vpWidth + thresholdX, - vVisible = partial ? tViz || bViz : tViz && bViz, - hVisible = partial ? lViz || rViz : lViz && rViz; + var rec = elem.getBoundingClientRect(); + var tViz = rec.top >= 0 && rec.top < vpHeight + thresholdY; + var bViz = rec.bottom > 0 && rec.bottom <= vpHeight + thresholdY; + var lViz = rec.left >= 0 && rec.left < vpWidth + thresholdX; + var rViz = rec.right > 0 && rec.right <= vpWidth + thresholdX; + var vVisible = partial ? tViz || bViz : tViz && bViz; + var hVisible = partial ? lViz || rViz : lViz && rViz; return vVisible && hVisible; } diff --git a/src/components/youtubeplayer/plugin.js b/src/components/youtubeplayer/plugin.js index 1ed95e2110..a2478cd3f4 100644 --- a/src/components/youtubeplayer/plugin.js +++ b/src/components/youtubeplayer/plugin.js @@ -135,7 +135,6 @@ define(['require', 'events', 'browser', 'appRouter', 'loading'], function (requi require(['queryString'], function (queryString) { - instance._currentSrc = options.url; var params = queryString.parse(options.url.split('?')[1]); // 3. This function creates an