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 3c7918d66..a3ce22fe9 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 03e0f68a9..16cf3fe36 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 000000000..98ec18c22 --- /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 bcbdd3dac..051102239 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 4ac0f7496..000000000 --- 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 71ac94c3b..000000000 --- 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 9067ae607..2328f8896 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 05b2b0cb4..6e82da181 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 0ecb65ab7..7930d6927 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 6d596632b..55b670f54 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 3315e304e..448ffa29a 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 229befded..de86ffc2b 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 e704b964a..cfe7efbe7 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 94d7eb70e..36f2cf88a 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 b4e320e6e..e9239693d 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 95350120c..ae708bcd4 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 cc4693096..fbb3af120 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 bb5e70695..aba741d64 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 0319d59a7..f3dfd2706 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 ac010a9b3..e0f8ea4ef 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 e7dccc7be..47b1c899b 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 0ab31f291..b1dd70ebd 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 fed9b7214..d2adcb2da 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 f9653fe26..a88f49d18 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 6991f63ca..37416dd3b 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 aac181859..d15ebd244 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 cc2eda505..3e310a17a 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 3c8b3f410..f7c2f1baa 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 f82b150a2..ed3ae2408 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 24ece42db..3ee56a2a9 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 5acd9f326..9c95cfa91 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 4fc51467e..509b7f521 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 40617cdb9..a58917f22 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 422257e33..2b11071c7 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 d268be299..03cad1a90 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 43082e684..55a86d4be 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 1de17ae83..20049837d 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 1e83f11f3..d5bd96d34 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 78fd601fd..80197b01c 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 e0a5947ca..b4e30602f 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 2bab76773..82c0b6a12 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 2d1fdda63..3e6229861 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 8a562c532..ac45d9a15 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 b28385169..5159f635f 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 f66afcdb2..ed1efc0a6 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 511ace73a..964896077 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 5dee7c5f5..fc3371833 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 f03abe75f..4806195ed 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 a9333ba5a..70e6adaf6 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 7f1b9b3f1..6fcdb2a79 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 35a780949..76c704f7e 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 32838c6de..7dae03cb3 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 b188a8b31..b260ef575 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 385ab69ca..80ecb13f0 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 2b43215c9..fb3b8112d 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 1f783631f..42d9d89f7 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 e9559155e..956b8fa6f 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 006f41e6c..2a1ed56bf 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 9de1461b3..1386e76a3 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 ac832a915..adccd9823 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 bfa33401f..3c000a8e7 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 9d6a79a5e..162e6fcb3 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 6f19a6842..6c8503445 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 4b4440f96..f91e874a8 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 a7147ddda..5794d5872 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 6bac0011d..d9fa2ab99 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 856470948..f2463ad8d 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 81d949e1a..205265efc 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 0709e8dae..fb6a3f94c 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 8352e90c3..38418f519 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 10fa6fc4f..ec80679f8 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 381dc8cea..2a862912d 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 d1eef004f..30ca06327 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 180af64b5..8242a16cb 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 2328f8896..4b5d2e8ee 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 6e82da181..75d8d311d 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 98ec18c22..000000000 --- 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 75d8d311d..f0d03bc4c 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 3d03fc945..5d53076d3 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 bd258d3bc..b173f5c51 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 1ca1448ea..c1d58d59a 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 b61088696..81e819e4e 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 0f4be7591..34c73a301 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 38f529af9..6388edb64 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 7c0048db2..14b75e053 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 dcb8f28bc..9ccb3aa08 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 051102239..8eea3ca24 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 713a029e4..000000000 --- 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 57fe40a36..000000000 --- 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 cd40b3ed2..000000000 --- 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 1c8cb0786..000000000 --- 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 163ef436f..000000000 --- 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 86e10aab7..4643b23f0 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 b5fa85ac6..48eb2d7c2 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 f0d03bc4c..59a1c4e55 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 98aaed75e..06d9cf086 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 48eb2d7c2..4ca730fd7 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 4ca730fd7..e05712c07 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 942e05c77..874b6d041 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 d91802dc7..09ad8f1a6 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 900f4befc..0f42e1458 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 729bce338..182b72071 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 ea8902b98..da03b8742 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 acc915431..7d2ea63a0 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 7148079a1..80c545852 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 4a0060cf8..9fedf0bfe 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 7dec1f095..c500db6e1 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 89457aa4e..2f18223d4 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 8c2f0ad44..ec23a151c 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 360986cc5..8ae31073a 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 47eb026db..9ee43be9f 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 d299d7fd7..1e9484caf 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 a3cc5b043..9c058a8e8 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 633437d26..dc7769be3 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 3fc549e6e..0c92f34e3 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 2c649bdd1..fade0dd04 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 2a77daa21..a2906cca8 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 3a52d7110..98fcf0ebc 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 46a65cabc..a3aa8cac4 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 f8bdb28ac..f0b1de4a1 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 fa01a4ace..6f28de0b3 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 d9bef95b4..46956d2df 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 7ed74f220..8c0bb1a3a 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 261ca8426..1935f65a3 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 257551abf..974cb0ab0 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 ad9aea950..510f31121 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 441adac3d..0fb4a1e7b 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 54c13a4eb..183e22551 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 552c716c1..8843dc159 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 d706b76b9..a6a416d52 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 cbf5c1eeb..69adbd1f5 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 304eec7e0..62de365d9 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 9fac61ba1..d7be482c5 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 7a7a73a53..3610eef2a 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 1797463f2..c949743be 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 63e0bde6c..7f4b9f519 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 d5803b426..b1af977ab 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 13497e191..23f0d4572 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 731d9c3c4..3253d8acd 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 2102720e9..7e4352bcb 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 58458aa39..4e85f8709 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 2cbaf1d9f..ed2076a81 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 5e097f2fe..4179192dd 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 0a76d3914..f51f8f276 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 b3d16a0da..614d483b2 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 69b8b1023..3a1d4ba94 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 8c56b578c..4bfd316c7 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 9878081e6..73a98cf5e 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 e586a1e12..562ea7ea3 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 843ab31f0..d422a9553 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 de0ce6b93..65f33b8e8 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 e42088c06..d979a9469 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 5dafb2828..abf3ddb38 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 74c65cd47..ff571b1e1 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 6c7e5b738..4c20183b2 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 762039ac4..534a57b02 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 f6c1e9789..9d2b1847e 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 780b8273b..9f9651642 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 6bb485a61..a5acd042b 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 27055f597..b79bf4ba1 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 588f491a6..8a40bd134 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 3389b7bf8..904c61231 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 ec874c69e..7381232fc 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 bc656bc3e..33f1c6e6c 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 732cbb1cb..a8298fad3 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 66d115046..0f6d34aac 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 40cf033cd..190424d44 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 ece8da1ed..c2d060162 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 23612d5a1..a8e514e06 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 617e02111..5195598d9 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 23a2a9d73..376874017 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 1ed95e211..a2478cd3f 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