';
-
var imgUrl = DashboardPage.getNowPlayingImageUrl(nowPlayingItem);
+
if (imgUrl) {
html += '
";
@@ -243,8 +246,8 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
html += '
';
html += '
';
-
var clientImage = DashboardPage.getClientImage(session);
+
if (clientImage) {
html += clientImage;
}
@@ -261,28 +264,36 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
html += '
';
}
- html += '
'
+ html += '
';
var nowPlayingName = DashboardPage.getNowPlayingName(session);
html += '
';
html += nowPlayingName.html;
html += "
";
html += '
' + DashboardPage.getSessionNowPlayingTime(session) + "
";
- html += '
'
+ html += '
';
if (nowPlayingItem && nowPlayingItem.RunTimeTicks) {
var percent = 100 * (session.PlayState.PositionTicks || 0) / nowPlayingItem.RunTimeTicks;
- html += indicators.getProgressHtml(percent, { containerClass: "playbackProgress" });
+ html += indicators.getProgressHtml(percent, {
+ containerClass: "playbackProgress"
+ });
} else {
// need to leave the element in just in case the device starts playback
- html += indicators.getProgressHtml(0, { containerClass: "playbackProgress hide" });
+ html += indicators.getProgressHtml(0, {
+ containerClass: "playbackProgress hide"
+ });
}
if (session.TranscodingInfo && session.TranscodingInfo.CompletionPercentage) {
var percent = session.TranscodingInfo.CompletionPercentage.toFixed(1);
- html += indicators.getProgressHtml(percent, { containerClass: "transcodingProgress" });
+ html += indicators.getProgressHtml(percent, {
+ containerClass: "transcodingProgress"
+ });
} else {
// same issue as playbackProgress element above
- html += indicators.getProgressHtml(0, { containerClass: "transcodingProgress hide" });
+ html += indicators.getProgressHtml(0, {
+ containerClass: "transcodingProgress hide"
+ });
}
html += "
";
@@ -317,6 +328,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
parentElement.insertAdjacentHTML("beforeend", html);
var deadSessionElem = parentElement.querySelector(".deadSession");
+
if (deadSessionElem) {
deadSessionElem.parentNode.removeChild(deadSessionElem);
}
@@ -340,9 +352,9 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
for (var i = 0, length = tasks.length; i < length; i++) {
var task = tasks[i];
-
html += "
";
html += task.Name + " ";
+
if (task.State === "Running") {
var progress = (task.CurrentProgressPercentage || 0).toFixed(1);
html += '';
@@ -373,19 +385,24 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
var html = "";
var showTranscodingInfo = false;
var displayPlayMethod = playMethodHelper.getDisplayPlayMethod(session);
+
if (displayPlayMethod === "DirectStream") {
html += globalize.translate("DirectStreaming");
} else if (displayPlayMethod === "Transcode") {
html += globalize.translate("Transcoding");
+
if (session.TranscodingInfo && session.TranscodingInfo.Framerate) {
html += " (" + session.TranscodingInfo.Framerate + " fps)";
}
+
showTranscodingInfo = true;
} else if (displayPlayMethod === "DirectPlay") {
html += globalize.translate("DirectPlaying");
}
+
if (showTranscodingInfo) {
var line = [];
+
if (session.TranscodingInfo) {
if (session.TranscodingInfo.Bitrate) {
if (session.TranscodingInfo.Bitrate > 1e6) {
@@ -493,6 +510,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
},
getUsersHtml: function (session) {
var html = [];
+
if (session.UserId) {
html.push(session.UserName);
}
@@ -516,8 +534,8 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
},
updateSession: function (row, session) {
row.classList.remove("deadSession");
-
var nowPlayingItem = session.NowPlayingItem;
+
if (nowPlayingItem) {
row.classList.add("playingSession");
} else {
@@ -537,6 +555,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
}
var btnSessionPlayPause = row.querySelector(".btnSessionPlayPause");
+
if (session.ServerId && nowPlayingItem && session.SupportsRemoteControl && session.DeviceId !== connectionManager.deviceId()) {
btnSessionPlayPause.classList.remove("hide");
row.querySelector(".btnSessionStop").classList.remove("hide");
@@ -565,19 +584,29 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
}
var playbackProgressElem = row.querySelector(".playbackProgress");
+
if (nowPlayingItem && nowPlayingItem.RunTimeTicks) {
var percent = 100 * (session.PlayState.PositionTicks || 0) / nowPlayingItem.RunTimeTicks;
- playbackProgressElem.outerHTML = indicators.getProgressHtml(percent, { containerClass: "playbackProgress" });
+ playbackProgressElem.outerHTML = indicators.getProgressHtml(percent, {
+ containerClass: "playbackProgress"
+ });
} else {
- playbackProgressElem.outerHTML = indicators.getProgressHtml(0, { containerClass: "playbackProgress hide" });
+ playbackProgressElem.outerHTML = indicators.getProgressHtml(0, {
+ containerClass: "playbackProgress hide"
+ });
}
var transcodingProgress = row.querySelector(".transcodingProgress");
+
if (session.TranscodingInfo && session.TranscodingInfo.CompletionPercentage) {
var percent = session.TranscodingInfo.CompletionPercentage.toFixed(1);
- transcodingProgress.outerHTML = indicators.getProgressHtml(percent, { containerClass: "transcodingProgress" });
+ transcodingProgress.outerHTML = indicators.getProgressHtml(percent, {
+ containerClass: "transcodingProgress"
+ });
} else {
- transcodingProgress.outerHTML = indicators.getProgressHtml(0, { containerClass: "transcodingProgress hide" });
+ transcodingProgress.outerHTML = indicators.getProgressHtml(0, {
+ containerClass: "transcodingProgress hide"
+ });
}
var imgUrl = DashboardPage.getNowPlayingImageUrl(nowPlayingItem) || "";
@@ -815,10 +844,13 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
view.addEventListener("viewdestroy", function () {
var page = this;
var userActivityLog = page.userActivityLog;
+
if (userActivityLog) {
userActivityLog.destroy();
}
+
var serverActivityLog = page.serverActivityLog;
+
if (serverActivityLog) {
serverActivityLog.destroy();
}
diff --git a/src/controllers/device.js b/src/controllers/device.js
index e704b964aa..cfe7efbe73 100644
--- a/src/controllers/device.js
+++ b/src/controllers/device.js
@@ -1,23 +1,25 @@
-define(["loading", "libraryMenu", "dom", "emby-input", "emby-button"], function(loading, libraryMenu, dom) {
+define(["loading", "libraryMenu", "dom", "emby-input", "emby-button"], function (loading, libraryMenu, dom) {
"use strict";
function load(page, device, deviceOptions) {
- page.querySelector("#txtCustomName", page).value = deviceOptions.CustomName || "", page.querySelector(".reportedName", page).innerHTML = device.Name || ""
+ page.querySelector("#txtCustomName", page).value = deviceOptions.CustomName || "";
+ page.querySelector(".reportedName", page).innerHTML = device.Name || "";
}
function loadData() {
var page = this;
loading.show();
- var id = getParameterByName("id"),
- promise1 = ApiClient.getJSON(ApiClient.getUrl("Devices/Info", {
- Id: id
- })),
- promise2 = ApiClient.getJSON(ApiClient.getUrl("Devices/Options", {
- Id: id
- }));
- Promise.all([promise1, promise2]).then(function(responses) {
- load(page, responses[0], responses[1]), loading.hide()
- })
+ var id = getParameterByName("id");
+ var promise1 = ApiClient.getJSON(ApiClient.getUrl("Devices/Info", {
+ Id: id
+ }));
+ var promise2 = ApiClient.getJSON(ApiClient.getUrl("Devices/Options", {
+ Id: id
+ }));
+ Promise.all([promise1, promise2]).then(function (responses) {
+ load(page, responses[0], responses[1]);
+ loading.hide();
+ });
}
function save(page) {
@@ -31,14 +33,18 @@ define(["loading", "libraryMenu", "dom", "emby-input", "emby-button"], function(
CustomName: page.querySelector("#txtCustomName").value
}),
contentType: "application/json"
- }).then(Dashboard.processServerConfigurationUpdateResult)
+ }).then(Dashboard.processServerConfigurationUpdateResult);
}
function onSubmit(e) {
var form = this;
- return save(dom.parentWithClass(form, "page")), e.preventDefault(), !1
+ save(dom.parentWithClass(form, "page"));
+ e.preventDefault();
+ return false;
}
- return function(view, params) {
- view.querySelector("form").addEventListener("submit", onSubmit), view.addEventListener("viewshow", loadData)
- }
-});
\ No newline at end of file
+
+ return function (view, params) {
+ view.querySelector("form").addEventListener("submit", onSubmit);
+ view.addEventListener("viewshow", loadData);
+ };
+});
diff --git a/src/controllers/devices.js b/src/controllers/devices.js
index 94d7eb70ea..36f2cf88a6 100644
--- a/src/controllers/devices.js
+++ b/src/controllers/devices.js
@@ -1,61 +1,73 @@
-define(["loading", "dom", "libraryMenu", "globalize", "scripts/imagehelper", "humanedate", "emby-button", "emby-itemscontainer", "cardStyle"], function(loading, dom, libraryMenu, globalize, imageHelper) {
+define(["loading", "dom", "libraryMenu", "globalize", "scripts/imagehelper", "humanedate", "emby-button", "emby-itemscontainer", "cardStyle"], function (loading, dom, libraryMenu, globalize, imageHelper) {
"use strict";
function canDelete(deviceId) {
- return deviceId !== ApiClient.deviceId()
+ return deviceId !== ApiClient.deviceId();
}
function deleteDevice(page, id) {
var msg = globalize.translate("DeleteDeviceConfirmation");
- require(["confirm"], function(confirm) {
+
+ require(["confirm"], function (confirm) {
confirm({
text: msg,
title: globalize.translate("HeaderDeleteDevice"),
confirmText: globalize.translate("ButtonDelete"),
primary: "delete"
- }).then(function() {
- loading.show(), ApiClient.ajax({
+ }).then(function () {
+ loading.show();
+ ApiClient.ajax({
type: "DELETE",
url: ApiClient.getUrl("Devices", {
Id: id
})
- }).then(function() {
- loadData(page)
- })
- })
- })
+ }).then(function () {
+ loadData(page);
+ });
+ });
+ });
}
function showDeviceMenu(view, btn, deviceId) {
var menuItems = [];
- canEdit && menuItems.push({
- name: globalize.translate("Edit"),
- id: "open",
- ironIcon: "mode-edit"
- }), canDelete(deviceId) && menuItems.push({
- name: globalize.translate("Delete"),
- id: "delete",
- ironIcon: "delete"
- }), require(["actionsheet"], function(actionsheet) {
+
+ if (canEdit) {
+ menuItems.push({
+ name: globalize.translate("Edit"),
+ id: "open",
+ ironIcon: "mode-edit"
+ });
+ }
+
+ if (canDelete(deviceId)) {
+ menuItems.push({
+ name: globalize.translate("Delete"),
+ id: "delete",
+ ironIcon: "delete"
+ });
+ }
+
+ require(["actionsheet"], function (actionsheet) {
actionsheet.show({
items: menuItems,
positionTo: btn,
- callback: function(id) {
+ callback: function (id) {
switch (id) {
case "open":
Dashboard.navigate("device.html?id=" + deviceId);
break;
+
case "delete":
- deleteDevice(view, deviceId)
+ deleteDevice(view, deviceId);
}
}
- })
- })
+ });
+ });
}
function load(page, devices) {
var html = "";
- html += devices.map(function(device) {
+ html += devices.map(function (device) {
var deviceHtml = "";
deviceHtml += "";
deviceHtml += '
";
deviceHtml += '";
deviceHtml += "
";
+
if (device.LastUserName) {
deviceHtml += device.LastUserName;
deviceHtml += ", " + humaneDate(device.DateLastActivity);
}
+
deviceHtml += " ";
deviceHtml += "
";
deviceHtml += "
";
@@ -99,17 +117,24 @@ define(["loading", "dom", "libraryMenu", "globalize", "scripts/imagehelper", "hu
}
function loadData(page) {
- loading.show(), ApiClient.getJSON(ApiClient.getUrl("Devices")).then(function(result) {
- load(page, result.Items), loading.hide()
- })
+ loading.show();
+ ApiClient.getJSON(ApiClient.getUrl("Devices")).then(function (result) {
+ load(page, result.Items);
+ loading.hide();
+ });
}
+
var canEdit = ApiClient.isMinServerVersion("3.4.1.31");
- return function(view, params) {
- view.querySelector(".devicesList").addEventListener("click", function(e) {
+ return function (view, params) {
+ view.querySelector(".devicesList").addEventListener("click", function (e) {
var btnDeviceMenu = dom.parentWithClass(e.target, "btnDeviceMenu");
- btnDeviceMenu && showDeviceMenu(view, btnDeviceMenu, btnDeviceMenu.getAttribute("data-id"))
- }), view.addEventListener("viewshow", function() {
- loadData(this)
- })
- }
+
+ if (btnDeviceMenu) {
+ showDeviceMenu(view, btnDeviceMenu, btnDeviceMenu.getAttribute("data-id"));
+ }
+ });
+ view.addEventListener("viewshow", function () {
+ loadData(this);
+ });
+ };
});
diff --git a/src/controllers/dlnaprofile.js b/src/controllers/dlnaprofile.js
index b4e320e6e4..e9239693d8 100644
--- a/src/controllers/dlnaprofile.js
+++ b/src/controllers/dlnaprofile.js
@@ -65,8 +65,8 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in
profile.ContainerProfiles = profile.ContainerProfiles || [];
profile.CodecProfiles = profile.CodecProfiles || [];
profile.ResponseProfiles = profile.ResponseProfiles || [];
- var usersHtml = " " + users.map(function (u__w) {
- return '' + u__w.Name + " ";
+ var usersHtml = " " + users.map(function (u) {
+ return '' + u.Name + " ";
}).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 += '
delete ';
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 += '
delete ';
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 += "";
- html += '
';
+ html += ' ';
html += "" + Globalize.translate("ValueContainer").replace("{0}", profile.Container || allText) + "
";
if ("Video" == profile.Type) {
@@ -560,14 +560,14 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in
if (profile.Conditions && profile.Conditions.length) {
html += "";
- html += Globalize.translate("ValueConditions").replace("{0}", profile.Conditions.map(function (c__d) {
- return c__d.Property;
+ html += Globalize.translate("ValueConditions").replace("{0}", profile.Conditions.map(function (c) {
+ return c.Property;
}).join(", "));
html += "
";
}
html += " ";
- html += '
delete ';
+ html += '
delete ';
html += "
";
}
@@ -649,8 +649,8 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in
profile.Name = $("#txtName", page).val();
profile.EnableAlbumArtInDidl = $("#chkEnableAlbumArtInDidl", page).checked();
profile.EnableSingleAlbumArtLimit = $("#chkEnableSingleImageLimit", page).checked();
- profile.SupportedMediaTypes = $(".chkMediaType:checked", page).get().map(function (c__f) {
- return c__f.getAttribute("data-value");
+ profile.SupportedMediaTypes = $(".chkMediaType:checked", page).get().map(function (c) {
+ return c.getAttribute("data-value");
}).join(",");
profile.Identification = profile.Identification || {};
profile.FriendlyName = $("#txtInfoFriendlyName", page).val();
diff --git a/src/controllers/dlnaprofiles.js b/src/controllers/dlnaprofiles.js
index 95350120c5..ae708bcd4e 100644
--- a/src/controllers/dlnaprofiles.js
+++ b/src/controllers/dlnaprofiles.js
@@ -1,48 +1,75 @@
-define(["jQuery", "globalize", "loading", "libraryMenu", "listViewStyle", "emby-button"], function($, globalize, loading, libraryMenu) {
+define(["jQuery", "globalize", "loading", "libraryMenu", "listViewStyle", "emby-button"], function ($, globalize, loading, libraryMenu) {
"use strict";
function loadProfiles(page) {
- loading.show(), ApiClient.getJSON(ApiClient.getUrl("Dlna/ProfileInfos")).then(function(result) {
- renderUserProfiles(page, result), renderSystemProfiles(page, result), loading.hide()
- })
+ loading.show();
+ ApiClient.getJSON(ApiClient.getUrl("Dlna/ProfileInfos")).then(function (result) {
+ renderUserProfiles(page, result);
+ renderSystemProfiles(page, result);
+ loading.hide();
+ });
}
function renderUserProfiles(page, profiles) {
- renderProfiles(page, page.querySelector(".customProfiles"), profiles.filter(function(p) {
- return "User" == p.Type
- }))
+ renderProfiles(page, page.querySelector(".customProfiles"), profiles.filter(function (p) {
+ return "User" == p.Type;
+ }));
}
function renderSystemProfiles(page, profiles) {
- renderProfiles(page, page.querySelector(".systemProfiles"), profiles.filter(function(p) {
- return "System" == p.Type
- }))
+ renderProfiles(page, page.querySelector(".systemProfiles"), profiles.filter(function (p) {
+ return "System" == p.Type;
+ }));
}
function renderProfiles(page, element, profiles) {
var html = "";
- profiles.length && (html += '');
+
+ if (profiles.length) {
+ html += '
';
+ }
+
for (var i = 0, length = profiles.length; i < length; i++) {
var profile = profiles[i];
- html += '
', html += '
live_tv ', html += '
", "User" == profile.Type && (html += '
delete '), html += "
"
+ html += '
';
+ html += '
live_tv ';
+ html += '
";
+
+ if ("User" == profile.Type) {
+ html += '
delete ';
+ }
+
+ html += "
";
}
- profiles.length && (html += "
"), element.innerHTML = html, $(".btnDeleteProfile", element).on("click", function() {
+
+ if (profiles.length) {
+ html += "
";
+ }
+
+ element.innerHTML = html;
+ $(".btnDeleteProfile", element).on("click", function () {
var id = this.getAttribute("data-profileid");
- deleteProfile(page, id)
- })
+ deleteProfile(page, id);
+ });
}
function deleteProfile(page, id) {
- require(["confirm"], function(confirm) {
- confirm(globalize.translate("MessageConfirmProfileDeletion"), globalize.translate("HeaderConfirmProfileDeletion")).then(function() {
- loading.show(), ApiClient.ajax({
+ require(["confirm"], function (confirm) {
+ confirm(globalize.translate("MessageConfirmProfileDeletion"), globalize.translate("HeaderConfirmProfileDeletion")).then(function () {
+ loading.show();
+ ApiClient.ajax({
type: "DELETE",
url: ApiClient.getUrl("Dlna/Profiles/" + id)
- }).then(function() {
- loading.hide(), loadProfiles(page)
- })
- })
- })
+ }).then(function () {
+ loading.hide();
+ loadProfiles(page);
+ });
+ });
+ });
}
function getTabs() {
@@ -52,10 +79,11 @@ define(["jQuery", "globalize", "loading", "libraryMenu", "listViewStyle", "emby-
}, {
href: "dlnaprofiles.html",
name: globalize.translate("TabProfiles")
- }]
+ }];
}
- $(document).on("pageshow", "#dlnaProfilesPage", function() {
- libraryMenu.setTabs("dlna", 1, getTabs), loadProfiles(this)
- })
-});
\ No newline at end of file
+ $(document).on("pageshow", "#dlnaProfilesPage", function () {
+ libraryMenu.setTabs("dlna", 1, getTabs);
+ loadProfiles(this);
+ });
+});
diff --git a/src/controllers/dlnasettings.js b/src/controllers/dlnasettings.js
index cc4693096a..fbb3af1205 100644
--- a/src/controllers/dlnasettings.js
+++ b/src/controllers/dlnasettings.js
@@ -1,20 +1,34 @@
-define(["jQuery", "loading", "libraryMenu", "fnchecked"], function($, loading, libraryMenu) {
+define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, libraryMenu) {
"use strict";
function loadPage(page, config, users) {
- page.querySelector("#chkEnablePlayTo").checked = config.EnablePlayTo, page.querySelector("#chkEnableDlnaDebugLogging").checked = config.EnableDebugLog, $("#txtClientDiscoveryInterval", page).val(config.ClientDiscoveryIntervalSeconds), $("#chkEnableServer", page).checked(config.EnableServer), $("#chkBlastAliveMessages", page).checked(config.BlastAliveMessages), $("#txtBlastInterval", page).val(config.BlastAliveMessageIntervalSeconds);
- var usersHtml = users.map(function(u) {
- return '' + u.Name + " "
+ 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 '' + u.Name + " ";
}).join("");
- $("#selectUser", page).html(usersHtml).val(config.DefaultUserId || ""), loading.hide()
+ $("#selectUser", page).html(usersHtml).val(config.DefaultUserId || "");
+ loading.hide();
}
function onSubmit() {
loading.show();
var form = this;
- return ApiClient.getNamedConfiguration("dlna").then(function(config) {
- config.EnablePlayTo = form.querySelector("#chkEnablePlayTo").checked, config.EnableDebugLog = form.querySelector("#chkEnableDlnaDebugLogging").checked, config.ClientDiscoveryIntervalSeconds = $("#txtClientDiscoveryInterval", form).val(), config.EnableServer = $("#chkEnableServer", form).checked(), config.BlastAliveMessages = $("#chkBlastAliveMessages", form).checked(), config.BlastAliveMessageIntervalSeconds = $("#txtBlastInterval", form).val(), config.DefaultUserId = $("#selectUser", form).val(), ApiClient.updateNamedConfiguration("dlna", config).then(Dashboard.processServerConfigurationUpdateResult)
- }), !1
+ ApiClient.getNamedConfiguration("dlna").then(function (config) {
+ config.EnablePlayTo = form.querySelector("#chkEnablePlayTo").checked;
+ config.EnableDebugLog = form.querySelector("#chkEnableDlnaDebugLogging").checked;
+ config.ClientDiscoveryIntervalSeconds = $("#txtClientDiscoveryInterval", form).val();
+ config.EnableServer = $("#chkEnableServer", form).checked();
+ config.BlastAliveMessages = $("#chkBlastAliveMessages", form).checked();
+ config.BlastAliveMessageIntervalSeconds = $("#txtBlastInterval", form).val();
+ config.DefaultUserId = $("#selectUser", form).val();
+ ApiClient.updateNamedConfiguration("dlna", config).then(Dashboard.processServerConfigurationUpdateResult);
+ });
+ return false;
}
function getTabs() {
@@ -24,17 +38,19 @@ define(["jQuery", "loading", "libraryMenu", "fnchecked"], function($, loading, l
}, {
href: "dlnaprofiles.html",
name: Globalize.translate("TabProfiles")
- }]
+ }];
}
- $(document).on("pageinit", "#dlnaSettingsPage", function() {
- $(".dlnaSettingsForm").off("submit", onSubmit).on("submit", onSubmit)
- }).on("pageshow", "#dlnaSettingsPage", function() {
- libraryMenu.setTabs("dlna", 0, getTabs), loading.show();
- var page = this,
- promise1 = ApiClient.getNamedConfiguration("dlna"),
- promise2 = ApiClient.getUsers();
- Promise.all([promise1, promise2]).then(function(responses) {
- loadPage(page, responses[0], responses[1])
- })
- })
-});
\ No newline at end of file
+
+ $(document).on("pageinit", "#dlnaSettingsPage", function () {
+ $(".dlnaSettingsForm").off("submit", onSubmit).on("submit", onSubmit);
+ }).on("pageshow", "#dlnaSettingsPage", function () {
+ libraryMenu.setTabs("dlna", 0, getTabs);
+ loading.show();
+ var page = this;
+ var promise1 = ApiClient.getNamedConfiguration("dlna");
+ var promise2 = ApiClient.getUsers();
+ Promise.all([promise1, promise2]).then(function (responses) {
+ loadPage(page, responses[0], responses[1]);
+ });
+ });
+});
diff --git a/src/controllers/edititemmetadata.js b/src/controllers/edititemmetadata.js
index bb5e70695a..aba741d64c 100644
--- a/src/controllers/edititemmetadata.js
+++ b/src/controllers/edititemmetadata.js
@@ -1,17 +1,31 @@
-define(["loading", "scripts/editorsidebar"], function(loading) {
+define(["loading", "scripts/editorsidebar"], function (loading) {
"use strict";
function reload(context, itemId) {
- loading.show(), itemId ? require(["metadataEditor"], function(metadataEditor) {
- metadataEditor.embed(context.querySelector(".editPageInnerContent"), itemId, ApiClient.serverInfo().Id)
- }) : (context.querySelector(".editPageInnerContent").innerHTML = "", loading.hide())
+ loading.show();
+
+ if (itemId) {
+ require(["metadataEditor"], function (metadataEditor) {
+ metadataEditor.embed(context.querySelector(".editPageInnerContent"), itemId, ApiClient.serverInfo().Id);
+ });
+ } else {
+ context.querySelector(".editPageInnerContent").innerHTML = "";
+ loading.hide();
+ }
}
- return function(view, params) {
- view.addEventListener("viewshow", function() {
- reload(this, MetadataEditor.getCurrentItemId())
- }), MetadataEditor.setCurrentItemId(null), view.querySelector(".libraryTree").addEventListener("itemclicked", function(event) {
+
+ return function (view, params) {
+ view.addEventListener("viewshow", function () {
+ reload(this, MetadataEditor.getCurrentItemId());
+ });
+ MetadataEditor.setCurrentItemId(null);
+ view.querySelector(".libraryTree").addEventListener("itemclicked", function (event) {
var data = event.detail;
- data.id != MetadataEditor.getCurrentItemId() && (MetadataEditor.setCurrentItemId(data.id), reload(view, data.id))
- })
- }
-});
\ No newline at end of file
+
+ if (data.id != MetadataEditor.getCurrentItemId()) {
+ MetadataEditor.setCurrentItemId(data.id);
+ reload(view, data.id);
+ }
+ });
+ };
+});
diff --git a/src/controllers/encodingsettings.js b/src/controllers/encodingsettings.js
index 0319d59a79..f3dfd2706e 100644
--- a/src/controllers/encodingsettings.js
+++ b/src/controllers/encodingsettings.js
@@ -1,9 +1,9 @@
-define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function($, loading, globalize, dom, libraryMenu) {
+define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function ($, loading, globalize, dom, libraryMenu) {
"use strict";
function loadPage(page, config, systemInfo) {
- Array.prototype.forEach.call(page.querySelectorAll(".chkDecodeCodec"), function(c) {
- c.checked = -1 !== (config.HardwareDecodingCodecs || []).indexOf(c.getAttribute("data-codec"))
+ Array.prototype.forEach.call(page.querySelectorAll(".chkDecodeCodec"), function (c) {
+ c.checked = -1 !== (config.HardwareDecodingCodecs || []).indexOf(c.getAttribute("data-codec"));
});
page.querySelector("#chkHardwareEncoding").checked = config.EnableHardwareEncoding;
$("#selectVideoDecoder", page).val(config.HardwareAccelerationType);
@@ -17,19 +17,22 @@ define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function($, loa
page.querySelector("#chkEnableSubtitleExtraction").checked = config.EnableSubtitleExtraction || false;
page.querySelector("#selectVideoDecoder").dispatchEvent(new CustomEvent("change", {
bubbles: true
- })), loading.hide()
+ }));
+ loading.hide();
}
function onSaveEncodingPathFailure(response) {
loading.hide();
var msg = "";
- msg = globalize.translate("FFmpegSavePathNotFound"), require(["alert"], function(alert) {
- alert(msg)
- })
+ msg = globalize.translate("FFmpegSavePathNotFound");
+
+ require(["alert"], function (alert) {
+ alert(msg);
+ });
}
function updateEncoder(form) {
- return ApiClient.getSystemInfo().then(function(systemInfo) {
+ return ApiClient.getSystemInfo().then(function (systemInfo) {
return ApiClient.ajax({
url: ApiClient.getUrl("System/MediaEncoder/Path"),
type: "POST",
@@ -37,37 +40,67 @@ define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function($, loa
Path: form.querySelector(".txtEncoderPath").value,
PathType: "Custom"
}
- }).then(Dashboard.processServerConfigurationUpdateResult, onSaveEncodingPathFailure)
- })
+ }).then(Dashboard.processServerConfigurationUpdateResult, onSaveEncodingPathFailure);
+ });
}
function onSubmit() {
- var form = this,
- onDecoderConfirmed = function() {
- loading.show(), ApiClient.getNamedConfiguration("encoding").then(function(config) {
- config.DownMixAudioBoost = $("#txtDownMixAudioBoost", form).val(), config.TranscodingTempPath = $("#txtTranscodingTempPath", form).val(), config.EncodingThreadCount = $("#selectThreadCount", form).val(), config.HardwareAccelerationType = $("#selectVideoDecoder", form).val(), config.VaapiDevice = $("#txtVaapiDevice", form).val(), config.H264Preset = form.querySelector("#selectH264Preset").value, config.H264Crf = parseInt(form.querySelector("#txtH264Crf").value || "0"), config.EnableSubtitleExtraction = form.querySelector("#chkEnableSubtitleExtraction").checked, config.HardwareDecodingCodecs = Array.prototype.map.call(Array.prototype.filter.call(form.querySelectorAll(".chkDecodeCodec"), function(c) {
- return c.checked
- }), function(c) {
- return c.getAttribute("data-codec")
- }), config.EnableHardwareEncoding = form.querySelector("#chkHardwareEncoding").checked, ApiClient.updateNamedConfiguration("encoding", config).then(function() {
- updateEncoder(form)
- })
- })
- };
- return $("#selectVideoDecoder", form).val() ? require(["alert"], function(alert) {
- alert({
- title: globalize.translate("TitleHardwareAcceleration"),
- text: globalize.translate("HardwareAccelerationWarning")
- }).then(onDecoderConfirmed)
- }) : onDecoderConfirmed(), !1
+ var form = this;
+
+ var onDecoderConfirmed = function () {
+ loading.show();
+ ApiClient.getNamedConfiguration("encoding").then(function (config) {
+ config.DownMixAudioBoost = $("#txtDownMixAudioBoost", form).val();
+ config.TranscodingTempPath = $("#txtTranscodingTempPath", form).val();
+ config.EncodingThreadCount = $("#selectThreadCount", form).val();
+ config.HardwareAccelerationType = $("#selectVideoDecoder", form).val();
+ config.VaapiDevice = $("#txtVaapiDevice", form).val();
+ config.H264Preset = form.querySelector("#selectH264Preset").value;
+ config.H264Crf = parseInt(form.querySelector("#txtH264Crf").value || "0");
+ config.EnableSubtitleExtraction = form.querySelector("#chkEnableSubtitleExtraction").checked;
+ config.HardwareDecodingCodecs = Array.prototype.map.call(Array.prototype.filter.call(form.querySelectorAll(".chkDecodeCodec"), function (c) {
+ return c.checked;
+ }), function (c) {
+ return c.getAttribute("data-codec");
+ });
+ config.EnableHardwareEncoding = form.querySelector("#chkHardwareEncoding").checked;
+ ApiClient.updateNamedConfiguration("encoding", config).then(function () {
+ updateEncoder(form);
+ });
+ });
+ };
+
+ if ($("#selectVideoDecoder", form).val()) {
+ require(["alert"], function (alert) {
+ alert({
+ title: globalize.translate("TitleHardwareAcceleration"),
+ text: globalize.translate("HardwareAccelerationWarning")
+ }).then(onDecoderConfirmed);
+ });
+ } else {
+ onDecoderConfirmed();
+ }
+
+ return false;
}
function setDecodingCodecsVisible(context, value) {
value = value || "";
var any;
- Array.prototype.forEach.call(context.querySelectorAll(".chkDecodeCodec"), function(c) {
- -1 === c.getAttribute("data-types").split(",").indexOf(value) ? dom.parentWithTag(c, "LABEL").classList.add("hide") : (dom.parentWithTag(c, "LABEL").classList.remove("hide"), any = !0)
- }), any ? context.querySelector(".decodingCodecsList").classList.remove("hide") : context.querySelector(".decodingCodecsList").classList.add("hide")
+ Array.prototype.forEach.call(context.querySelectorAll(".chkDecodeCodec"), function (c) {
+ if (-1 === c.getAttribute("data-types").split(",").indexOf(value)) {
+ dom.parentWithTag(c, "LABEL").classList.add("hide");
+ } else {
+ dom.parentWithTag(c, "LABEL").classList.remove("hide");
+ any = true;
+ }
+ });
+
+ if (any) {
+ context.querySelector(".decodingCodecsList").classList.remove("hide");
+ } else {
+ context.querySelector(".decodingCodecsList").classList.add("hide");
+ }
}
function getTabs() {
@@ -80,44 +113,69 @@ define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function($, loa
}, {
href: "streamingsettings.html",
name: Globalize.translate("TabStreaming")
- }]
+ }];
}
- $(document).on("pageinit", "#encodingSettingsPage", function() {
+ $(document).on("pageinit", "#encodingSettingsPage", function () {
var page = this;
- page.querySelector("#selectVideoDecoder").addEventListener("change", function() {
- "vaapi" == this.value ? (page.querySelector(".fldVaapiDevice").classList.remove("hide"), page.querySelector("#txtVaapiDevice").setAttribute("required", "required")) : (page.querySelector(".fldVaapiDevice").classList.add("hide"), page.querySelector("#txtVaapiDevice").removeAttribute("required")), this.value ? page.querySelector(".hardwareAccelerationOptions").classList.remove("hide") : page.querySelector(".hardwareAccelerationOptions").classList.add("hide"), setDecodingCodecsVisible(page, this.value)
- }), $("#btnSelectEncoderPath", page).on("click.selectDirectory", function() {
- require(["directorybrowser"], function(directoryBrowser) {
- var picker = new directoryBrowser;
+ page.querySelector("#selectVideoDecoder").addEventListener("change", function () {
+ if ("vaapi" == this.value) {
+ page.querySelector(".fldVaapiDevice").classList.remove("hide");
+ page.querySelector("#txtVaapiDevice").setAttribute("required", "required");
+ } else {
+ page.querySelector(".fldVaapiDevice").classList.add("hide");
+ page.querySelector("#txtVaapiDevice").removeAttribute("required");
+ }
+
+ if (this.value) {
+ page.querySelector(".hardwareAccelerationOptions").classList.remove("hide");
+ } else {
+ page.querySelector(".hardwareAccelerationOptions").classList.add("hide");
+ }
+
+ setDecodingCodecsVisible(page, this.value);
+ });
+ $("#btnSelectEncoderPath", page).on("click.selectDirectory", function () {
+ require(["directorybrowser"], function (directoryBrowser) {
+ var picker = new directoryBrowser();
picker.show({
- includeFiles: !0,
- callback: function(path) {
- path && $(".txtEncoderPath", page).val(path), picker.close()
+ includeFiles: true,
+ callback: function (path) {
+ if (path) {
+ $(".txtEncoderPath", page).val(path);
+ }
+
+ picker.close();
}
- })
- })
- }), $("#btnSelectTranscodingTempPath", page).on("click.selectDirectory", function() {
- require(["directorybrowser"], function(directoryBrowser) {
- var picker = new directoryBrowser;
+ });
+ });
+ });
+ $("#btnSelectTranscodingTempPath", page).on("click.selectDirectory", function () {
+ require(["directorybrowser"], function (directoryBrowser) {
+ var picker = new directoryBrowser();
picker.show({
- callback: function(path) {
- path && $("#txtTranscodingTempPath", page).val(path), picker.close()
+ callback: function (path) {
+ if (path) {
+ $("#txtTranscodingTempPath", page).val(path);
+ }
+
+ picker.close();
},
- validateWriteable: !0,
+ validateWriteable: true,
header: globalize.translate("HeaderSelectTranscodingPath"),
instruction: globalize.translate("HeaderSelectTranscodingPathHelp")
- })
- })
- }), $(".encodingSettingsForm").off("submit", onSubmit).on("submit", onSubmit)
- }).on("pageshow", "#encodingSettingsPage", function() {
+ });
+ });
+ });
+ $(".encodingSettingsForm").off("submit", onSubmit).on("submit", onSubmit);
+ }).on("pageshow", "#encodingSettingsPage", function () {
loading.show();
libraryMenu.setTabs("playback", 0, getTabs);
var page = this;
- ApiClient.getNamedConfiguration("encoding").then(function(config) {
- ApiClient.getSystemInfo().then(function(systemInfo) {
+ ApiClient.getNamedConfiguration("encoding").then(function (config) {
+ ApiClient.getSystemInfo().then(function (systemInfo) {
loadPage(page, config, systemInfo);
- })
- })
- })
+ });
+ });
+ });
});
diff --git a/src/controllers/forgotpassword.js b/src/controllers/forgotpassword.js
index ac010a9b34..e0f8ea4ef8 100644
--- a/src/controllers/forgotpassword.js
+++ b/src/controllers/forgotpassword.js
@@ -1,37 +1,53 @@
-define([], function() {
+define([], function () {
"use strict";
function processForgotPasswordResult(result) {
- if ("ContactAdmin" == result.Action) return void Dashboard.alert({
- message: Globalize.translate("MessageContactAdminToResetPassword"),
- title: Globalize.translate("HeaderForgotPassword")
- });
- if ("InNetworkRequired" == result.Action) return void Dashboard.alert({
- message: Globalize.translate("MessageForgotPasswordInNetworkRequired"),
- title: Globalize.translate("HeaderForgotPassword")
- });
+ if ("ContactAdmin" == result.Action) {
+ return void Dashboard.alert({
+ message: Globalize.translate("MessageContactAdminToResetPassword"),
+ title: Globalize.translate("HeaderForgotPassword")
+ });
+ }
+
+ if ("InNetworkRequired" == result.Action) {
+ return void Dashboard.alert({
+ message: Globalize.translate("MessageForgotPasswordInNetworkRequired"),
+ title: Globalize.translate("HeaderForgotPassword")
+ });
+ }
+
if ("PinCode" == result.Action) {
var msg = Globalize.translate("MessageForgotPasswordFileCreated");
- return msg += " ", msg += " ", msg += "Enter PIN here to finish Password Reset " ,msg += " ",msg += result.PinFile, msg += " ", void Dashboard.alert({
+ msg += " ";
+ msg += " ";
+ msg += "Enter PIN here to finish Password Reset ";
+ msg += " ";
+ msg += result.PinFile;
+ msg += " ";
+ return void Dashboard.alert({
message: msg,
title: Globalize.translate("HeaderForgotPassword"),
- callback: function() {
- Dashboard.navigate("forgotpasswordpin.html")
+ callback: function () {
+ Dashboard.navigate("forgotpasswordpin.html");
}
- })
+ });
}
}
- return function(view, params) {
+
+ return function (view, params) {
function onSubmit(e) {
- return ApiClient.ajax({
+ ApiClient.ajax({
type: "POST",
url: ApiClient.getUrl("Users/ForgotPassword"),
dataType: "json",
data: {
EnteredUsername: view.querySelector("#txtName").value
}
- }).then(processForgotPasswordResult), e.preventDefault(), !1
+ }).then(processForgotPasswordResult);
+ e.preventDefault();
+ return false;
}
- view.querySelector("form").addEventListener("submit", onSubmit)
- }
+
+ view.querySelector("form").addEventListener("submit", onSubmit);
+ };
});
diff --git a/src/controllers/forgotpasswordpin.js b/src/controllers/forgotpasswordpin.js
index e7dccc7be1..47b1c899b9 100644
--- a/src/controllers/forgotpasswordpin.js
+++ b/src/controllers/forgotpasswordpin.js
@@ -1,33 +1,41 @@
-define([], function() {
+define([], function () {
"use strict";
function processForgotPasswordResult(result) {
if (result.Success) {
var msg = Globalize.translate("MessagePasswordResetForUsers");
- return msg += " ", msg += " ", msg += result.UsersReset.join(" "), void Dashboard.alert({
+ msg += " ";
+ msg += " ";
+ msg += result.UsersReset.join(" ");
+ return void Dashboard.alert({
message: msg,
title: Globalize.translate("HeaderPasswordReset"),
- callback: function() {
- window.location.href = "index.html"
+ callback: function () {
+ window.location.href = "index.html";
}
- })
+ });
}
+
Dashboard.alert({
message: Globalize.translate("MessageInvalidForgotPasswordPin"),
title: Globalize.translate("HeaderPasswordReset")
- })
+ });
}
- return function(view, params) {
+
+ return function (view, params) {
function onSubmit(e) {
- return ApiClient.ajax({
+ ApiClient.ajax({
type: "POST",
url: ApiClient.getUrl("Users/ForgotPassword/Pin"),
dataType: "json",
data: {
Pin: view.querySelector("#txtPin").value
}
- }).then(processForgotPasswordResult), e.preventDefault(), !1
+ }).then(processForgotPasswordResult);
+ e.preventDefault();
+ return false;
}
- view.querySelector("form").addEventListener("submit", onSubmit)
- }
-});
\ No newline at end of file
+
+ view.querySelector("form").addEventListener("submit", onSubmit);
+ };
+});
diff --git a/src/controllers/home.js b/src/controllers/home.js
index 0ab31f291d..b1dd70ebd6 100644
--- a/src/controllers/home.js
+++ b/src/controllers/home.js
@@ -1,4 +1,4 @@
-define(["tabbedView", "globalize", "require", "emby-tabs", "emby-button", "emby-scroller"], function(TabbedView, globalize, require) {
+define(["tabbedView", "globalize", "require", "emby-tabs", "emby-button", "emby-scroller"], function (TabbedView, globalize, require) {
"use strict";
function getTabs() {
@@ -6,47 +6,70 @@ define(["tabbedView", "globalize", "require", "emby-tabs", "emby-button", "emby-
name: globalize.translate("Home")
}, {
name: globalize.translate("Favorites")
- }]
+ }];
}
function getDefaultTabIndex() {
- return 0
+ return 0;
}
function getRequirePromise(deps) {
- return new Promise(function(resolve, reject) {
- require(deps, resolve)
- })
+ return new Promise(function (resolve, reject) {
+ require(deps, resolve);
+ });
}
function getTabController(index) {
- if (null == index) throw new Error("index cannot be null");
+ if (null == index) {
+ throw new Error("index cannot be null");
+ }
+
var depends = [];
+
switch (index) {
case 0:
depends.push("controllers/hometab");
break;
+
case 1:
- depends.push("controllers/favorites")
+ depends.push("controllers/favorites");
}
+
var instance = this;
- return getRequirePromise(depends).then(function(controllerFactory) {
+ return getRequirePromise(depends).then(function (controllerFactory) {
var controller = instance.tabControllers[index];
+
if (!controller) {
- controller = new controllerFactory(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params), instance.tabControllers[index] = controller
+ controller = new controllerFactory(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params);
+ instance.tabControllers[index] = controller;
}
- return controller
- })
+
+ return controller;
+ });
}
function HomeView(view, params) {
- TabbedView.call(this, view, params)
+ TabbedView.call(this, view, params);
}
- return Object.assign(HomeView.prototype, TabbedView.prototype), HomeView.prototype.getTabs = getTabs, HomeView.prototype.getDefaultTabIndex = getDefaultTabIndex, HomeView.prototype.getTabController = getTabController, HomeView.prototype.setTitle = function() {
- Emby.Page.setTitle(null)
- }, HomeView.prototype.onPause = function() {
- TabbedView.prototype.onPause.call(this), document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader")
- }, HomeView.prototype.onResume = function(options) {
- TabbedView.prototype.onResume.call(this, options), document.querySelector(".skinHeader").classList.add("noHomeButtonHeader")
- }, HomeView
-});
\ No newline at end of file
+
+ Object.assign(HomeView.prototype, TabbedView.prototype);
+ HomeView.prototype.getTabs = getTabs;
+ HomeView.prototype.getDefaultTabIndex = getDefaultTabIndex;
+ HomeView.prototype.getTabController = getTabController;
+
+ HomeView.prototype.setTitle = function () {
+ Emby.Page.setTitle(null);
+ };
+
+ HomeView.prototype.onPause = function () {
+ TabbedView.prototype.onPause.call(this);
+ document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader");
+ };
+
+ HomeView.prototype.onResume = function (options) {
+ TabbedView.prototype.onResume.call(this, options);
+ document.querySelector(".skinHeader").classList.add("noHomeButtonHeader");
+ };
+
+ return HomeView;
+});
diff --git a/src/controllers/hometab.js b/src/controllers/hometab.js
index fed9b72146..d2adcb2da2 100644
--- a/src/controllers/hometab.js
+++ b/src/controllers/hometab.js
@@ -1,35 +1,74 @@
-define(["userSettings", "loading", "connectionManager", "apphost", "layoutManager", "focusManager", "homeSections", "emby-itemscontainer"], function(userSettings, loading, connectionManager, appHost, layoutManager, focusManager, homeSections) {
+define(["userSettings", "loading", "connectionManager", "apphost", "layoutManager", "focusManager", "homeSections", "emby-itemscontainer"], function (userSettings, loading, connectionManager, appHost, layoutManager, focusManager, homeSections) {
"use strict";
function HomeTab(view, params) {
- this.view = view, this.params = params, this.apiClient = connectionManager.currentApiClient(), this.sectionsContainer = view.querySelector(".sections"), view.querySelector(".sections").addEventListener("settingschange", onHomeScreenSettingsChanged.bind(this))
+ this.view = view;
+ this.params = params;
+ this.apiClient = connectionManager.currentApiClient();
+ this.sectionsContainer = view.querySelector(".sections");
+ view.querySelector(".sections").addEventListener("settingschange", onHomeScreenSettingsChanged.bind(this));
}
function onHomeScreenSettingsChanged() {
- this.sectionsRendered = !1, this.paused || this.onResume({
- refresh: !0
- })
+ this.sectionsRendered = false;
+
+ if (!this.paused) {
+ this.onResume({
+ refresh: true
+ });
+ }
}
- return HomeTab.prototype.onResume = function(options) {
+
+ HomeTab.prototype.onResume = function (options) {
if (this.sectionsRendered) {
var sectionsContainer = this.sectionsContainer;
- return sectionsContainer ? homeSections.resume(sectionsContainer, options) : Promise.resolve()
+
+ if (sectionsContainer) {
+ return homeSections.resume(sectionsContainer, options);
+ }
+
+ return Promise.resolve();
}
+
loading.show();
- var view = this.view,
- apiClient = this.apiClient;
- return this.destroyHomeSections(), this.sectionsRendered = !0, apiClient.getCurrentUser().then(function(user) {
- return homeSections.loadSections(view.querySelector(".sections"), apiClient, user, userSettings).then(function() {
- options.autoFocus && focusManager.autoFocus(view), loading.hide()
- })
- })
- }, HomeTab.prototype.onPause = function() {
+ var view = this.view;
+ var apiClient = this.apiClient;
+ this.destroyHomeSections();
+ this.sectionsRendered = true;
+ return apiClient.getCurrentUser().then(function (user) {
+ return homeSections.loadSections(view.querySelector(".sections"), apiClient, user, userSettings).then(function () {
+ if (options.autoFocus) {
+ focusManager.autoFocus(view);
+ }
+
+ loading.hide();
+ });
+ });
+ };
+
+ HomeTab.prototype.onPause = function () {
var sectionsContainer = this.sectionsContainer;
- sectionsContainer && homeSections.pause(sectionsContainer)
- }, HomeTab.prototype.destroy = function() {
- this.view = null, this.params = null, this.apiClient = null, this.destroyHomeSections(), this.sectionsContainer = null
- }, HomeTab.prototype.destroyHomeSections = function() {
+
+ if (sectionsContainer) {
+ homeSections.pause(sectionsContainer);
+ }
+ };
+
+ HomeTab.prototype.destroy = function () {
+ this.view = null;
+ this.params = null;
+ this.apiClient = null;
+ this.destroyHomeSections();
+ this.sectionsContainer = null;
+ };
+
+ HomeTab.prototype.destroyHomeSections = function () {
var sectionsContainer = this.sectionsContainer;
- sectionsContainer && homeSections.destroySections(sectionsContainer)
- }, HomeTab
-});
\ No newline at end of file
+
+ if (sectionsContainer) {
+ homeSections.destroySections(sectionsContainer);
+ }
+ };
+
+ return HomeTab;
+});
diff --git a/src/controllers/installedplugins.js b/src/controllers/installedplugins.js
index f9653fe260..a88f49d186 100644
--- a/src/controllers/installedplugins.js
+++ b/src/controllers/installedplugins.js
@@ -1,21 +1,22 @@
-define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button"], function(loading, libraryMenu, dom, globalize) {
+define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button"], function (loading, libraryMenu, dom, globalize) {
"use strict";
function deletePlugin(page, uniqueid, name) {
var msg = globalize.translate("UninstallPluginConfirmation").replace("{0}", name);
- require(["confirm"], function(confirm) {
+
+ require(["confirm"], function (confirm) {
confirm({
title: globalize.translate("UninstallPluginHeader"),
text: msg,
primary: "delete",
confirmText: globalize.translate("UninstallPluginHeader")
- }).then(function() {
+ }).then(function () {
loading.show();
- ApiClient.uninstallPlugin(uniqueid).then(function() {
+ ApiClient.uninstallPlugin(uniqueid).then(function () {
reloadList(page);
});
- })
- })
+ });
+ });
}
function showNoConfigurationMessage() {
@@ -31,23 +32,24 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button"
}
function getPluginCardHtml(plugin, pluginConfigurationPages) {
- var configPage = pluginConfigurationPages.filter(function(pluginConfigurationPage) {
- return pluginConfigurationPage.PluginId == plugin.Id;
+ var configPage = pluginConfigurationPages.filter(function (pluginConfigurationPage) {
+ return pluginConfigurationPage.PluginId == plugin.Id;
})[0];
var configPageUrl = configPage ? Dashboard.getConfigurationPageUrl(configPage.Name) : null;
-
var html = "";
html += "";
html += '
';
html += '
";
html += '";
}
+
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 03e0f68a9b..5d614d638c 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 '
" + v.Name + " "
- }).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 '
" + v.Name + " ";
+ }).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()), '
" + (v.DisplayTitle || titleParts.join(" ")) + " "
- }).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 '
" + (v.DisplayTitle || titleParts.join(" ")) + " ";
+ }).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 '
" + v.DisplayTitle + " "
- }).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 '
" + v.DisplayTitle + " ";
+ }).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 = '
' + globalize.translate("Off") + " " + tracks.map(function(v) {
- return selected = v.Index === selectedId ? " selected" : "", '
" + v.DisplayTitle + " "
- }).join(""), page.querySelector(".selectSubtitlesContainer").classList.remove("hide")
- } else select.innerHTML = "", page.querySelector(".selectSubtitlesContainer").classList.add("hide")
+ select.innerHTML = '
' + globalize.translate("Off") + " " + tracks.map(function (v) {
+ selected = v.Index === selectedId ? " selected" : "";
+ return '
" + v.DisplayTitle + " ";
+ }).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 = "";
+ }
}
}
@@ -399,7 +709,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");
}
@@ -407,145 +717,339 @@ 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 += '
", 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 +1059,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 +1075,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 +1095,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 +1108,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: "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 +1497,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 +1774,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 += '
' + globalize.translate("ButtonMore") + "
"), html
+
+ if (limit && items.length > limit) {
+ html += '
' + globalize.translate("ButtonMore") + "
";
+ }
+
+ 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/librarydisplay.js b/src/controllers/librarydisplay.js
index 5ee86a4563..10a0eb945b 100644
--- a/src/controllers/librarydisplay.js
+++ b/src/controllers/librarydisplay.js
@@ -60,11 +60,11 @@ define(["globalize", "loading", "libraryMenu", "emby-checkbox", "emby-button", "
libraryMenu.setTabs("librarysetup", 1, getTabs);
loadData();
ApiClient.getSystemInfo().then(function(info) {
- if ("Windows" === info.OperatingSystem) {
- view.querySelector(".fldSaveMetadataHidden").classList.remove("hide");
- } else {
- view.querySelector(".fldSaveMetadataHidden").classList.add("hide");
- }
+ if ("Windows" === info.OperatingSystem) {
+ view.querySelector(".fldSaveMetadataHidden").classList.remove("hide");
+ } else {
+ view.querySelector(".fldSaveMetadataHidden").classList.add("hide");
+ }
});
});
}
diff --git a/src/controllers/list.js b/src/controllers/list.js
index aac1818592..d15ebd2444 100644
--- a/src/controllers/list.js
+++ b/src/controllers/list.js
@@ -1,4 +1,4 @@
-define(["globalize", "listView", "layoutManager", "userSettings", "focusManager", "cardBuilder", "loading", "connectionManager", "alphaNumericShortcuts", "scroller", "playbackManager", "alphaPicker", "emby-itemscontainer", "emby-scroller"], function(globalize, listView, layoutManager, userSettings, focusManager, cardBuilder, loading, connectionManager, AlphaNumericShortcuts, scroller, playbackManager, alphaPicker) {
+define(["globalize", "listView", "layoutManager", "userSettings", "focusManager", "cardBuilder", "loading", "connectionManager", "alphaNumericShortcuts", "scroller", "playbackManager", "alphaPicker", "emby-itemscontainer", "emby-scroller"], function (globalize, listView, layoutManager, userSettings, focusManager, cardBuilder, loading, connectionManager, AlphaNumericShortcuts, scroller, playbackManager, alphaPicker) {
"use strict";
function getInitialLiveTvQuery(instance, params) {
@@ -8,83 +8,303 @@ define(["globalize", "listView", "layoutManager", "userSettings", "focusManager"
Fields: "ChannelInfo,PrimaryImageAspectRatio",
Limit: 300
};
- return "Recordings" === params.type ? query.IsInProgress = !1 : query.HasAired = !1, params.genreId && (query.GenreIds = params.genreId), "true" === params.IsMovie ? query.IsMovie = !0 : "false" === params.IsMovie && (query.IsMovie = !1), "true" === params.IsSeries ? query.IsSeries = !0 : "false" === params.IsSeries && (query.IsSeries = !1), "true" === params.IsNews ? query.IsNews = !0 : "false" === params.IsNews && (query.IsNews = !1), "true" === params.IsSports ? query.IsSports = !0 : "false" === params.IsSports && (query.IsSports = !1), "true" === params.IsKids ? query.IsKids = !0 : "false" === params.IsKids && (query.IsKids = !1), "true" === params.IsAiring ? query.IsAiring = !0 : "false" === params.IsAiring && (query.IsAiring = !1), modifyQueryWithFilters(instance, query)
+
+ if ("Recordings" === params.type) {
+ query.IsInProgress = false;
+ } else {
+ query.HasAired = false;
+ }
+
+ if (params.genreId) {
+ query.GenreIds = params.genreId;
+ }
+
+ if ("true" === params.IsMovie) {
+ query.IsMovie = true;
+ } else if ("false" === params.IsMovie) {
+ query.IsMovie = false;
+ }
+
+ if ("true" === params.IsSeries) {
+ query.IsSeries = true;
+ } else if ("false" === params.IsSeries) {
+ query.IsSeries = false;
+ }
+
+ if ("true" === params.IsNews) {
+ query.IsNews = true;
+ } else if ("false" === params.IsNews) {
+ query.IsNews = false;
+ }
+
+ if ("true" === params.IsSports) {
+ query.IsSports = true;
+ } else if ("false" === params.IsSports) {
+ query.IsSports = false;
+ }
+
+ if ("true" === params.IsKids) {
+ query.IsKids = true;
+ } else if ("false" === params.IsKids) {
+ query.IsKids = false;
+ }
+
+ if ("true" === params.IsAiring) {
+ query.IsAiring = true;
+ } else if ("false" === params.IsAiring) {
+ query.IsAiring = false;
+ }
+
+ return modifyQueryWithFilters(instance, query);
}
function modifyQueryWithFilters(instance, query) {
var sortValues = instance.getSortValues();
- query.SortBy || (query.SortBy = sortValues.sortBy, query.SortOrder = sortValues.sortOrder), query.Fields = query.Fields ? query.Fields + ",PrimaryImageAspectRatio" : "PrimaryImageAspectRatio", query.ImageTypeLimit = 1;
- var hasFilters, queryFilters = [],
- filters = instance.getFilters();
- return filters.IsPlayed && (queryFilters.push("IsPlayed"), hasFilters = !0), filters.IsUnplayed && (queryFilters.push("IsUnplayed"), hasFilters = !0), filters.IsFavorite && (queryFilters.push("IsFavorite"), hasFilters = !0), filters.IsResumable && (queryFilters.push("IsResumable"), hasFilters = !0), filters.VideoTypes && (hasFilters = !0, query.VideoTypes = filters.VideoTypes), filters.GenreIds && (hasFilters = !0, query.GenreIds = filters.GenreIds), filters.Is4K && (query.Is4K = !0, hasFilters = !0), filters.IsHD && (query.IsHD = !0, hasFilters = !0), filters.IsSD && (query.IsHD = !1, hasFilters = !0), filters.Is3D && (query.Is3D = !0, hasFilters = !0), filters.HasSubtitles && (query.HasSubtitles = !0, hasFilters = !0), filters.HasTrailer && (query.HasTrailer = !0, hasFilters = !0), filters.HasSpecialFeature && (query.HasSpecialFeature = !0, hasFilters = !0), filters.HasThemeSong && (query.HasThemeSong = !0, hasFilters = !0), filters.HasThemeVideo && (query.HasThemeVideo = !0, hasFilters = !0), query.Filters = queryFilters.length ? queryFilters.join(",") : null, instance.setFilterStatus(hasFilters), instance.alphaPicker && (query.NameStartsWithOrGreater = instance.alphaPicker.value()), query
+
+ if (!query.SortBy) {
+ query.SortBy = sortValues.sortBy;
+ query.SortOrder = sortValues.sortOrder;
+ }
+
+ query.Fields = query.Fields ? query.Fields + ",PrimaryImageAspectRatio" : "PrimaryImageAspectRatio";
+ query.ImageTypeLimit = 1;
+ var hasFilters;
+ var queryFilters = [];
+ var filters = instance.getFilters();
+
+ if (filters.IsPlayed) {
+ queryFilters.push("IsPlayed");
+ hasFilters = true;
+ }
+
+ if (filters.IsUnplayed) {
+ queryFilters.push("IsUnplayed");
+ hasFilters = true;
+ }
+
+ if (filters.IsFavorite) {
+ queryFilters.push("IsFavorite");
+ hasFilters = true;
+ }
+
+ if (filters.IsResumable) {
+ queryFilters.push("IsResumable");
+ hasFilters = true;
+ }
+
+ if (filters.VideoTypes) {
+ hasFilters = true;
+ query.VideoTypes = filters.VideoTypes;
+ }
+
+ if (filters.GenreIds) {
+ hasFilters = true;
+ query.GenreIds = filters.GenreIds;
+ }
+
+ if (filters.Is4K) {
+ query.Is4K = true;
+ hasFilters = true;
+ }
+
+ if (filters.IsHD) {
+ query.IsHD = true;
+ hasFilters = true;
+ }
+
+ if (filters.IsSD) {
+ query.IsHD = false;
+ hasFilters = true;
+ }
+
+ if (filters.Is3D) {
+ query.Is3D = true;
+ hasFilters = true;
+ }
+
+ if (filters.HasSubtitles) {
+ query.HasSubtitles = true;
+ hasFilters = true;
+ }
+
+ if (filters.HasTrailer) {
+ query.HasTrailer = true;
+ hasFilters = true;
+ }
+
+ if (filters.HasSpecialFeature) {
+ query.HasSpecialFeature = true;
+ hasFilters = true;
+ }
+
+ if (filters.HasThemeSong) {
+ query.HasThemeSong = true;
+ hasFilters = true;
+ }
+
+ if (filters.HasThemeVideo) {
+ query.HasThemeVideo = true;
+ hasFilters = true;
+ }
+
+ query.Filters = queryFilters.length ? queryFilters.join(",") : null;
+ instance.setFilterStatus(hasFilters);
+
+ if (instance.alphaPicker) {
+ query.NameStartsWithOrGreater = instance.alphaPicker.value();
+ }
+
+ return query;
}
function updateSortText(instance) {
var btnSortText = instance.btnSortText;
+
if (btnSortText) {
- for (var options = instance.getSortMenuOptions(), values = instance.getSortValues(), sortBy = values.sortBy, i = 0, length = options.length; i < length; i++)
+ var options = instance.getSortMenuOptions();
+ var values = instance.getSortValues();
+ var sortBy = values.sortBy;
+
+ for (var i = 0, length = options.length; i < length; i++) {
if (sortBy === options[i].value) {
btnSortText.innerHTML = globalize.translate("SortByValue", options[i].name);
- break
- } var btnSortIcon = instance.btnSortIcon;
- btnSortIcon && (btnSortIcon.innerHTML = "Descending" === values.sortOrder ? "" : "")
+ break;
+ }
+ }
+
+ var btnSortIcon = instance.btnSortIcon;
+
+ if (btnSortIcon) {
+ btnSortIcon.innerHTML = "Descending" === values.sortOrder ? "" : "";
+ }
}
}
function updateItemsContainerForViewType(instance) {
- "list" === instance.getViewSettings().imageType ? (instance.itemsContainer.classList.remove("vertical-wrap"), instance.itemsContainer.classList.add("vertical-list")) : (instance.itemsContainer.classList.add("vertical-wrap"), instance.itemsContainer.classList.remove("vertical-list"))
+ if ("list" === instance.getViewSettings().imageType) {
+ instance.itemsContainer.classList.remove("vertical-wrap");
+ instance.itemsContainer.classList.add("vertical-list");
+ } else {
+ instance.itemsContainer.classList.add("vertical-wrap");
+ instance.itemsContainer.classList.remove("vertical-list");
+ }
}
function updateAlphaPickerState(instance, numItems) {
if (instance.alphaPicker) {
var alphaPicker = instance.alphaPickerElement;
+
if (alphaPicker) {
var values = instance.getSortValues();
- null == numItems && (numItems = 100), "SortName" === values.sortBy && "Ascending" === values.sortOrder && numItems > 40 ? (alphaPicker.classList.remove("hide"), layoutManager.tv ? instance.itemsContainer.parentNode.classList.add("padded-left-withalphapicker") : instance.itemsContainer.parentNode.classList.add("padded-right-withalphapicker")) : (alphaPicker.classList.add("hide"), instance.itemsContainer.parentNode.classList.remove("padded-left-withalphapicker"), instance.itemsContainer.parentNode.classList.remove("padded-right-withalphapicker"))
+
+ if (null == numItems) {
+ numItems = 100;
+ }
+
+ if ("SortName" === values.sortBy && "Ascending" === values.sortOrder && numItems > 40) {
+ alphaPicker.classList.remove("hide");
+
+ if (layoutManager.tv) {
+ instance.itemsContainer.parentNode.classList.add("padded-left-withalphapicker");
+ } else {
+ instance.itemsContainer.parentNode.classList.add("padded-right-withalphapicker");
+ }
+ } else {
+ alphaPicker.classList.add("hide");
+ instance.itemsContainer.parentNode.classList.remove("padded-left-withalphapicker");
+ instance.itemsContainer.parentNode.classList.remove("padded-right-withalphapicker");
+ }
}
}
}
function getItems(instance, params, item, sortBy, startIndex, limit) {
var apiClient = connectionManager.getApiClient(params.serverId);
- if (instance.queryRecursive = !1, "Recordings" === params.type) return apiClient.getLiveTvRecordings(getInitialLiveTvQuery(instance, params));
- if ("Programs" === params.type) return "true" === params.IsAiring ? apiClient.getLiveTvRecommendedPrograms(getInitialLiveTvQuery(instance, params)) : apiClient.getLiveTvPrograms(getInitialLiveTvQuery(instance, params));
- if ("nextup" === params.type) return apiClient.getNextUpEpisodes(modifyQueryWithFilters(instance, {
- Limit: limit,
- Fields: "PrimaryImageAspectRatio,SeriesInfo,DateCreated,BasicSyncInfo",
- UserId: apiClient.getCurrentUserId(),
- ImageTypeLimit: 1,
- EnableImageTypes: "Primary,Backdrop,Thumb",
- EnableTotalRecordCount: !1,
- SortBy: sortBy
- }));
+
+ instance.queryRecursive = false;
+ if ("Recordings" === params.type) {
+ return apiClient.getLiveTvRecordings(getInitialLiveTvQuery(instance, params));
+ }
+
+ if ("Programs" === params.type) {
+ if ("true" === params.IsAiring) {
+ return apiClient.getLiveTvRecommendedPrograms(getInitialLiveTvQuery(instance, params));
+ }
+
+ return apiClient.getLiveTvPrograms(getInitialLiveTvQuery(instance, params));
+ }
+
+ if ("nextup" === params.type) {
+ return apiClient.getNextUpEpisodes(modifyQueryWithFilters(instance, {
+ Limit: limit,
+ Fields: "PrimaryImageAspectRatio,SeriesInfo,DateCreated,BasicSyncInfo",
+ UserId: apiClient.getCurrentUserId(),
+ ImageTypeLimit: 1,
+ EnableImageTypes: "Primary,Backdrop,Thumb",
+ EnableTotalRecordCount: false,
+ SortBy: sortBy
+ }));
+ }
+
if (!item) {
- instance.queryRecursive = !0;
+ instance.queryRecursive = true;
var method = "getItems";
- return "MusicArtist" === params.type ? method = "getArtists" : "Person" === params.type && (method = "getPeople"), apiClient[method](apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, {
+
+ if ("MusicArtist" === params.type) {
+ method = "getArtists";
+ } else if ("Person" === params.type) {
+ method = "getPeople";
+ }
+
+ return apiClient[method](apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, {
StartIndex: startIndex,
Limit: limit,
Fields: "PrimaryImageAspectRatio,SortName",
ImageTypeLimit: 1,
IncludeItemTypes: "MusicArtist" === params.type || "Person" === params.type ? null : params.type,
- Recursive: !0,
+ Recursive: true,
IsFavorite: "true" === params.IsFavorite || null,
ArtistIds: params.artistId || null,
SortBy: sortBy
- }))
+ }));
}
+
if ("Genre" === item.Type || "MusicGenre" === item.Type || "Studio" === item.Type || "Person" === item.Type) {
- instance.queryRecursive = !0;
+ instance.queryRecursive = true;
var query = {
StartIndex: startIndex,
Limit: limit,
Fields: "PrimaryImageAspectRatio,SortName",
- Recursive: !0,
+ Recursive: true,
parentId: params.parentId,
SortBy: sortBy
};
- return "Studio" === item.Type ? query.StudioIds = item.Id : "Genre" === item.Type || "MusicGenre" === item.Type ? query.GenreIds = item.Id : "Person" === item.Type && (query.PersonIds = item.Id), "MusicGenre" === item.Type ? query.IncludeItemTypes = "MusicAlbum" : "GameGenre" === item.Type ? query.IncludeItemTypes = "Game" : "movies" === item.CollectionType ? query.IncludeItemTypes = "Movie" : "tvshows" === item.CollectionType ? query.IncludeItemTypes = "Series" : "Genre" === item.Type ? query.IncludeItemTypes = "Movie,Series,Video" : "Person" === item.Type && (query.IncludeItemTypes = params.type), apiClient.getItems(apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, query))
+
+ if ("Studio" === item.Type) {
+ query.StudioIds = item.Id;
+ } else if ("Genre" === item.Type || "MusicGenre" === item.Type) {
+ query.GenreIds = item.Id;
+ } else if ("Person" === item.Type) {
+ query.PersonIds = item.Id;
+ }
+
+ if ("MusicGenre" === item.Type) {
+ query.IncludeItemTypes = "MusicAlbum";
+ } else if ("GameGenre" === item.Type) {
+ query.IncludeItemTypes = "Game";
+ } else if ("movies" === item.CollectionType) {
+ query.IncludeItemTypes = "Movie";
+ } else if ("tvshows" === item.CollectionType) {
+ query.IncludeItemTypes = "Series";
+ } else if ("Genre" === item.Type) {
+ query.IncludeItemTypes = "Movie,Series,Video";
+ } else if ("Person" === item.Type) {
+ query.IncludeItemTypes = params.type;
+ }
+
+ return apiClient.getItems(apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, query));
}
+
return apiClient.getItems(apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, {
StartIndex: startIndex,
Limit: limit,
@@ -92,35 +312,44 @@ define(["globalize", "listView", "layoutManager", "userSettings", "focusManager"
ImageTypeLimit: 1,
ParentId: item.Id,
SortBy: sortBy
- }))
+ }));
}
function getItem(params) {
- if ("Recordings" === params.type) return Promise.resolve(null);
- if ("Programs" === params.type) return Promise.resolve(null);
- if ("nextup" === params.type) return Promise.resolve(null);
- var apiClient = connectionManager.getApiClient(params.serverId),
- itemId = params.genreId || params.musicGenreId || params.studioId || params.personId || params.parentId;
- return itemId ? apiClient.getItem(apiClient.getCurrentUserId(), itemId) : Promise.resolve(null)
+ if ("Recordings" === params.type || "Programs" === params.type || "nextup" === params.type) {
+ return Promise.resolve(null);
+ }
+
+ var apiClient = connectionManager.getApiClient(params.serverId);
+ var itemId = params.genreId || params.musicGenreId || params.studioId || params.personId || params.parentId;
+
+ if (itemId) {
+ return apiClient.getItem(apiClient.getCurrentUserId(), itemId);
+ }
+
+ return Promise.resolve(null);
}
function showViewSettingsMenu() {
var instance = this;
- require(["viewSettings"], function(ViewSettings) {
- (new ViewSettings).show({
+
+ require(["viewSettings"], function (ViewSettings) {
+ new ViewSettings().show({
settingsKey: instance.getSettingsKey(),
settings: instance.getViewSettings(),
visibleSettings: instance.getVisibleViewSettings()
- }).then(function() {
- updateItemsContainerForViewType(instance), instance.itemsContainer.refreshItems()
- })
- })
+ }).then(function () {
+ updateItemsContainerForViewType(instance);
+ instance.itemsContainer.refreshItems();
+ });
+ });
}
function showFilterMenu() {
var instance = this;
- require(["filterMenu"], function(FilterMenu) {
- (new FilterMenu).show({
+
+ require(["filterMenu"], function (FilterMenu) {
+ new FilterMenu().show({
settingsKey: instance.getSettingsKey(),
settings: instance.getFilters(),
visibleSettings: instance.getVisibleFilters(),
@@ -129,201 +358,497 @@ define(["globalize", "listView", "layoutManager", "userSettings", "focusManager"
itemTypes: instance.getItemTypes(),
serverId: instance.params.serverId,
filterMenuOptions: instance.getFilterMenuOptions()
- }).then(function() {
- instance.itemsContainer.refreshItems()
- })
- })
+ }).then(function () {
+ instance.itemsContainer.refreshItems();
+ });
+ });
}
function showSortMenu() {
var instance = this;
- require(["sortMenu"], function(SortMenu) {
- (new SortMenu).show({
+
+ require(["sortMenu"], function (SortMenu) {
+ new SortMenu().show({
settingsKey: instance.getSettingsKey(),
settings: instance.getSortValues(),
onChange: instance.itemsContainer.refreshItems.bind(instance.itemsContainer),
serverId: instance.params.serverId,
sortOptions: instance.getSortMenuOptions()
- }).then(function() {
- updateSortText(instance), updateAlphaPickerState(instance), instance.itemsContainer.refreshItems()
- })
- })
+ }).then(function () {
+ updateSortText(instance);
+ updateAlphaPickerState(instance);
+ instance.itemsContainer.refreshItems();
+ });
+ });
}
function onNewItemClick() {
var instance = this;
- require(["playlistEditor"], function(playlistEditor) {
- (new playlistEditor).show({
+
+ require(["playlistEditor"], function (playlistEditor) {
+ new playlistEditor().show({
items: [],
serverId: instance.params.serverId
- })
- })
+ });
+ });
}
function hideOrShowAll(elems, hide) {
- for (var i = 0, length = elems.length; i < length; i++) hide ? elems[i].classList.add("hide") : elems[i].classList.remove("hide")
+ for (var i = 0, length = elems.length; i < length; i++) {
+ if (hide) {
+ elems[i].classList.add("hide");
+ } else {
+ elems[i].classList.remove("hide");
+ }
+ }
}
function bindAll(elems, eventName, fn) {
- for (var i = 0, length = elems.length; i < length; i++) elems[i].addEventListener(eventName, fn)
+ for (var i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener(eventName, fn);
+ }
}
function ItemsView(view, params) {
function fetchData() {
- return getItems(self, params, self.currentItem).then(function(result) {
- return null == self.totalItemCount && (self.totalItemCount = result.Items ? result.Items.length : result.length), updateAlphaPickerState(self, self.totalItemCount), result
- })
+ return getItems(self, params, self.currentItem).then(function (result) {
+ if (null == self.totalItemCount) {
+ self.totalItemCount = result.Items ? result.Items.length : result.length;
+ }
+
+ updateAlphaPickerState(self, self.totalItemCount);
+ return result;
+ });
}
function getItemsHtml(items) {
var settings = self.getViewSettings();
- if ("list" === settings.imageType) return listView.getListViewHtml({
- items: items
- });
- var shape, preferThumb, preferDisc, preferLogo, defaultShape, item = self.currentItem,
- lines = settings.showTitle ? 2 : 0;
- "banner" === settings.imageType ? shape = "banner" : "disc" === settings.imageType ? (shape = "square", preferDisc = !0) : "logo" === settings.imageType ? (shape = "backdrop", preferLogo = !0) : "thumb" === settings.imageType ? (shape = "backdrop", preferThumb = !0) : "nextup" === params.type ? (shape = "backdrop", preferThumb = "thumb" === settings.imageType) : "Programs" === params.type || "Recordings" === params.type ? (shape = "true" === params.IsMovie ? "portrait" : "autoVertical", preferThumb = "true" !== params.IsMovie && "auto", defaultShape = "true" === params.IsMovie ? "portrait" : "backdrop") : shape = "autoVertical";
+
+ if ("list" === settings.imageType) {
+ return listView.getListViewHtml({
+ items: items
+ });
+ }
+
+ var shape;
+ var preferThumb;
+ var preferDisc;
+ var preferLogo;
+ var defaultShape;
+ var item = self.currentItem;
+ var lines = settings.showTitle ? 2 : 0;
+
+ if ("banner" === settings.imageType) {
+ shape = "banner";
+ } else if ("disc" === settings.imageType) {
+ shape = "square";
+ preferDisc = true;
+ } else if ("logo" === settings.imageType) {
+ shape = "backdrop";
+ preferLogo = true;
+ } else if ("thumb" === settings.imageType) {
+ shape = "backdrop";
+ preferThumb = true;
+ } else if ("nextup" === params.type) {
+ shape = "backdrop";
+ preferThumb = "thumb" === settings.imageType;
+ } else if ("Programs" === params.type || "Recordings" === params.type) {
+ shape = "true" === params.IsMovie ? "portrait" : "autoVertical";
+ preferThumb = "true" !== params.IsMovie ? "auto" : false;
+ defaultShape = "true" === params.IsMovie ? "portrait" : "backdrop";
+ } else {
+ shape = "autoVertical";
+ }
+
var posterOptions = {
shape: shape,
showTitle: settings.showTitle,
showYear: settings.showTitle,
- centerText: !0,
- coverImage: !0,
+ centerText: true,
+ coverImage: true,
preferThumb: preferThumb,
preferDisc: preferDisc,
preferLogo: preferLogo,
- overlayPlayButton: !1,
- overlayMoreButton: !0,
+ overlayPlayButton: false,
+ overlayMoreButton: true,
overlayText: !settings.showTitle,
defaultShape: defaultShape,
action: "Audio" === params.type ? "playallfromhere" : null
};
- if ("nextup" === params.type) posterOptions.showParentTitle = settings.showTitle;
- else if ("Person" === params.type) posterOptions.showYear = !1, posterOptions.showParentTitle = !1, lines = 1;
- else if ("Audio" === params.type) posterOptions.showParentTitle = settings.showTitle;
- else if ("MusicAlbum" === params.type) posterOptions.showParentTitle = settings.showTitle;
- else if ("Episode" === params.type) posterOptions.showParentTitle = settings.showTitle;
- else if ("MusicArtist" === params.type) posterOptions.showYear = !1, lines = 1;
- else if ("Programs" === params.type) {
+
+ if ("nextup" === params.type) {
+ posterOptions.showParentTitle = settings.showTitle;
+ } else if ("Person" === params.type) {
+ posterOptions.showYear = false;
+ posterOptions.showParentTitle = false;
+ lines = 1;
+ } else if ("Audio" === params.type) {
+ posterOptions.showParentTitle = settings.showTitle;
+ } else if ("MusicAlbum" === params.type) {
+ posterOptions.showParentTitle = settings.showTitle;
+ } else if ("Episode" === params.type) {
+ posterOptions.showParentTitle = settings.showTitle;
+ } else if ("MusicArtist" === params.type) {
+ posterOptions.showYear = false;
+ lines = 1;
+ } else if ("Programs" === params.type) {
lines = settings.showTitle ? 1 : 0;
var showParentTitle = settings.showTitle && "true" !== params.IsMovie;
- showParentTitle && lines++;
+
+ if (showParentTitle) {
+ lines++;
+ }
+
var showAirTime = settings.showTitle && "Recordings" !== params.type;
- showAirTime && lines++;
+
+ if (showAirTime) {
+ lines++;
+ }
+
var showYear = settings.showTitle && "true" === params.IsMovie && "Recordings" === params.type;
- showYear && lines++, posterOptions = Object.assign(posterOptions, {
+
+ if (showYear) {
+ lines++;
+ }
+
+ posterOptions = Object.assign(posterOptions, {
inheritThumb: "Recordings" === params.type,
context: "livetv",
showParentTitle: showParentTitle,
showAirTime: showAirTime,
showAirDateTime: showAirTime,
- overlayPlayButton: !1,
- overlayMoreButton: !0,
+ overlayPlayButton: false,
+ overlayMoreButton: true,
showYear: showYear,
- coverImage: !0
- })
- } else posterOptions.showParentTitle = settings.showTitle;
- return posterOptions.lines = lines, posterOptions.items = items, item && "folders" === item.CollectionType && (posterOptions.context = "folders"), cardBuilder.getCardsHtml(posterOptions)
+ coverImage: true
+ });
+ } else {
+ posterOptions.showParentTitle = settings.showTitle;
+ }
+
+ posterOptions.lines = lines;
+ posterOptions.items = items;
+
+ if (item && "folders" === item.CollectionType) {
+ posterOptions.context = "folders";
+ }
+
+ return cardBuilder.getCardsHtml(posterOptions);
}
function initAlphaPicker() {
self.scroller = view.querySelector(".scrollFrameY");
var alphaPickerElement = self.alphaPickerElement;
- layoutManager.tv ? (alphaPickerElement.classList.add("alphaPicker-fixed-left"), alphaPickerElement.classList.add("focuscontainer-left"), self.itemsContainer.parentNode.classList.add("padded-left-withalphapicker")) : (alphaPickerElement.classList.add("alphaPicker-fixed-right"), alphaPickerElement.classList.add("focuscontainer-right"), self.itemsContainer.parentNode.classList.add("padded-right-withalphapicker")), self.alphaPicker = new alphaPicker({
+
+ if (layoutManager.tv) {
+ alphaPickerElement.classList.add("alphaPicker-fixed-left");
+ alphaPickerElement.classList.add("focuscontainer-left");
+ self.itemsContainer.parentNode.classList.add("padded-left-withalphapicker");
+ } else {
+ alphaPickerElement.classList.add("alphaPicker-fixed-right");
+ alphaPickerElement.classList.add("focuscontainer-right");
+ self.itemsContainer.parentNode.classList.add("padded-right-withalphapicker");
+ }
+
+ self.alphaPicker = new alphaPicker({
element: alphaPickerElement,
itemsContainer: layoutManager.tv ? self.itemsContainer : null,
itemClass: "card",
valueChangeEvent: layoutManager.tv ? null : "click"
- }), self.alphaPicker.on("alphavaluechanged", onAlphaPickerValueChanged)
+ });
+ self.alphaPicker.on("alphavaluechanged", onAlphaPickerValueChanged);
}
function onAlphaPickerValueChanged() {
self.alphaPicker.value();
- self.itemsContainer.refreshItems()
+ self.itemsContainer.refreshItems();
}
function setTitle(item) {
- Emby.Page.setTitle(getTitle(item) || ""), item && "playlists" === item.CollectionType ? hideOrShowAll(view.querySelectorAll(".btnNewItem"), !1) : hideOrShowAll(view.querySelectorAll(".btnNewItem"), !0)
+ Emby.Page.setTitle(getTitle(item) || "");
+
+ if (item && "playlists" === item.CollectionType) {
+ hideOrShowAll(view.querySelectorAll(".btnNewItem"), false);
+ } else {
+ hideOrShowAll(view.querySelectorAll(".btnNewItem"), true);
+ }
}
function getTitle(item) {
- return "Recordings" === params.type ? globalize.translate("Recordings") : "Programs" === params.type ? "true" === params.IsMovie ? globalize.translate("Movies") : "true" === params.IsSports ? globalize.translate("Sports") : "true" === params.IsKids ? globalize.translate("HeaderForKids") : "true" === params.IsAiring ? globalize.translate("HeaderOnNow") : "true" === params.IsSeries ? globalize.translate("Shows") : "true" === params.IsNews ? globalize.translate("News") : globalize.translate("Programs") : "nextup" === params.type ? globalize.translate("NextUp") : "favoritemovies" === params.type ? globalize.translate("FavoriteMovies") : item ? item.Name : "Movie" === params.type ? globalize.translate("Movies") : "Series" === params.type ? globalize.translate("Shows") : "Season" === params.type ? globalize.translate("Seasons") : "Episode" === params.type ? globalize.translate("Episodes") : "MusicArtist" === params.type ? globalize.translate("Artists") : "MusicAlbum" === params.type ? globalize.translate("Albums") : "Audio" === params.type ? globalize.translate("Songs") : "Video" === params.type ? globalize.translate("Videos") : void 0
+ if ("Recordings" === params.type) {
+ return globalize.translate("Recordings");
+ }
+
+ if ("Programs" === params.type) {
+ if ("true" === params.IsMovie) {
+ return globalize.translate("Movies");
+ }
+
+ if ("true" === params.IsSports) {
+ return globalize.translate("Sports");
+ }
+
+ if ("true" === params.IsKids) {
+ return globalize.translate("HeaderForKids");
+ }
+
+ if ("true" === params.IsAiring) {
+ return globalize.translate("HeaderOnNow");
+ }
+
+ if ("true" === params.IsSeries) {
+ return globalize.translate("Shows");
+ }
+
+ if ("true" === params.IsNews) {
+ return globalize.translate("News");
+ }
+
+ return globalize.translate("Programs");
+ }
+
+ if ("nextup" === params.type) {
+ return globalize.translate("NextUp");
+ }
+
+ if ("favoritemovies" === params.type) {
+ return globalize.translate("FavoriteMovies");
+ }
+
+ if (item) {
+ return item.Name;
+ }
+
+ if ("Movie" === params.type) {
+ return globalize.translate("Movies");
+ }
+
+ if ("Series" === params.type) {
+ return globalize.translate("Shows");
+ }
+
+ if ("Season" === params.type) {
+ return globalize.translate("Seasons");
+ }
+
+ if ("Episode" === params.type) {
+ return globalize.translate("Episodes");
+ }
+
+ if ("MusicArtist" === params.type) {
+ return globalize.translate("Artists");
+ }
+
+ if ("MusicAlbum" === params.type) {
+ return globalize.translate("Albums");
+ }
+
+ if ("Audio" === params.type) {
+ return globalize.translate("Songs");
+ }
+
+ if ("Video" === params.type) {
+ return globalize.translate("Videos");
+ }
+
+ return void 0;
}
function play() {
var currentItem = self.currentItem;
- if (currentItem && !self.hasFilters) return void playbackManager.play({
- items: [currentItem]
- });
- getItems(self, self.params, currentItem, null, null, 300).then(function(result) {
+
+ if (currentItem && !self.hasFilters) {
playbackManager.play({
- items: result.Items
- })
- })
+ items: [currentItem]
+ });
+ } else {
+ getItems(self, self.params, currentItem, null, null, 300).then(function (result) {
+ playbackManager.play({
+ items: result.Items
+ });
+ });
+ }
}
function queue() {
var currentItem = self.currentItem;
- if (currentItem && !self.hasFilters) return void playbackManager.queue({
- items: [currentItem]
- });
- getItems(self, self.params, currentItem, null, null, 300).then(function(result) {
+
+ if (currentItem && !self.hasFilters) {
playbackManager.queue({
- items: result.Items
- })
- })
+ items: [currentItem]
+ });
+ } else {
+ getItems(self, self.params, currentItem, null, null, 300).then(function (result) {
+ playbackManager.queue({
+ items: result.Items
+ });
+ });
+ }
}
function shuffle() {
var currentItem = self.currentItem;
- if (currentItem && !self.hasFilters) return void playbackManager.shuffle(currentItem);
- getItems(self, self.params, currentItem, "Random", null, 300).then(function(result) {
- playbackManager.play({
- items: result.Items
- })
- })
+
+ if (currentItem && !self.hasFilters) {
+ playbackManager.shuffle(currentItem);
+ } else {
+ getItems(self, self.params, currentItem, "Random", null, 300).then(function (result) {
+ playbackManager.play({
+ items: result.Items
+ });
+ });
+ }
}
+
var self = this;
- self.params = params, this.itemsContainer = view.querySelector(".itemsContainer"), params.parentId ? this.itemsContainer.setAttribute("data-parentid", params.parentId) : "nextup" === params.type ? this.itemsContainer.setAttribute("data-monitor", "videoplayback") : "favoritemovies" === params.type ? this.itemsContainer.setAttribute("data-monitor", "markfavorite") : "Programs" === params.type && this.itemsContainer.setAttribute("data-refreshinterval", "300000");
- var i, length, btnViewSettings = view.querySelectorAll(".btnViewSettings");
- for (i = 0, length = btnViewSettings.length; i < length; i++) btnViewSettings[i].addEventListener("click", showViewSettingsMenu.bind(this));
+ self.params = params;
+ this.itemsContainer = view.querySelector(".itemsContainer");
+
+ if (params.parentId) {
+ this.itemsContainer.setAttribute("data-parentid", params.parentId);
+ } else if ("nextup" === params.type) {
+ this.itemsContainer.setAttribute("data-monitor", "videoplayback");
+ } else if ("favoritemovies" === params.type) {
+ this.itemsContainer.setAttribute("data-monitor", "markfavorite");
+ } else if ("Programs" === params.type) {
+ this.itemsContainer.setAttribute("data-refreshinterval", "300000");
+ }
+
+ var i;
+ var length;
+ var btnViewSettings = view.querySelectorAll(".btnViewSettings");
+
+ for (i = 0, length = btnViewSettings.length; i < length; i++) {
+ btnViewSettings[i].addEventListener("click", showViewSettingsMenu.bind(this));
+ }
+
var filterButtons = view.querySelectorAll(".btnFilter");
this.filterButtons = filterButtons;
var hasVisibleFilters = this.getVisibleFilters().length;
+
for (i = 0, length = filterButtons.length; i < length; i++) {
var btnFilter = filterButtons[i];
- btnFilter.addEventListener("click", showFilterMenu.bind(this)), hasVisibleFilters ? btnFilter.classList.remove("hide") : btnFilter.classList.add("hide")
+ btnFilter.addEventListener("click", showFilterMenu.bind(this));
+
+ if (hasVisibleFilters) {
+ btnFilter.classList.remove("hide");
+ } else {
+ btnFilter.classList.add("hide");
+ }
}
+
var sortButtons = view.querySelectorAll(".btnSort");
+
for (this.sortButtons = sortButtons, i = 0, length = sortButtons.length; i < length; i++) {
var sortButton = sortButtons[i];
- sortButton.addEventListener("click", showSortMenu.bind(this)), "nextup" !== params.type && sortButton.classList.remove("hide")
+ sortButton.addEventListener("click", showSortMenu.bind(this));
+
+ if ("nextup" !== params.type) {
+ sortButton.classList.remove("hide");
+ }
}
- this.btnSortText = view.querySelector(".btnSortText"), this.btnSortIcon = view.querySelector(".btnSortIcon"), bindAll(view.querySelectorAll(".btnNewItem"), "click", onNewItemClick.bind(this)), this.alphaPickerElement = view.querySelector(".alphaPicker"), self.itemsContainer.fetchData = fetchData, self.itemsContainer.getItemsHtml = getItemsHtml, view.addEventListener("viewshow", function(e) {
+
+ this.btnSortText = view.querySelector(".btnSortText");
+ this.btnSortIcon = view.querySelector(".btnSortIcon");
+ bindAll(view.querySelectorAll(".btnNewItem"), "click", onNewItemClick.bind(this));
+ this.alphaPickerElement = view.querySelector(".alphaPicker");
+ self.itemsContainer.fetchData = fetchData;
+ self.itemsContainer.getItemsHtml = getItemsHtml;
+ view.addEventListener("viewshow", function (e) {
var isRestored = e.detail.isRestored;
- isRestored || (loading.show(), updateSortText(self), updateItemsContainerForViewType(self)), setTitle(null), getItem(params).then(function(item) {
- setTitle(item), self.currentItem = item;
+
+ if (!isRestored) {
+ loading.show();
+ updateSortText(self);
+ updateItemsContainerForViewType(self);
+ }
+
+ setTitle(null);
+ getItem(params).then(function (item) {
+ setTitle(item);
+ self.currentItem = item;
var refresh = !isRestored;
self.itemsContainer.resume({
refresh: refresh
- }).then(function() {
- loading.hide(), refresh && focusManager.autoFocus(self.itemsContainer)
- }), isRestored || item && "PhotoAlbum" !== item.Type && initAlphaPicker();
+ }).then(function () {
+ loading.hide();
+
+ if (refresh) {
+ focusManager.autoFocus(self.itemsContainer);
+ }
+ });
+
+ if (!isRestored && item && "PhotoAlbum" !== item.Type) {
+ initAlphaPicker();
+ }
+
var itemType = item ? item.Type : null;
- "MusicGenre" === itemType || "Programs" !== params.type && "Channel" !== itemType ? hideOrShowAll(view.querySelectorAll(".btnPlay"), !1) : hideOrShowAll(view.querySelectorAll(".btnPlay"), !0), "MusicGenre" === itemType || "Programs" !== params.type && "nextup" !== params.type && "Channel" !== itemType ? hideOrShowAll(view.querySelectorAll(".btnShuffle"), !1) : hideOrShowAll(view.querySelectorAll(".btnShuffle"), !0), item && playbackManager.canQueue(item) ? hideOrShowAll(view.querySelectorAll(".btnQueue"), !1) : hideOrShowAll(view.querySelectorAll(".btnQueue"), !0)
- }), isRestored || (bindAll(view.querySelectorAll(".btnPlay"), "click", play), bindAll(view.querySelectorAll(".btnQueue"), "click", queue), bindAll(view.querySelectorAll(".btnShuffle"), "click", shuffle)), this.alphaNumericShortcuts = new AlphaNumericShortcuts({
+
+ if ("MusicGenre" === itemType || "Programs" !== params.type && "Channel" !== itemType) {
+ hideOrShowAll(view.querySelectorAll(".btnPlay"), false);
+ } else {
+ hideOrShowAll(view.querySelectorAll(".btnPlay"), true);
+ }
+
+ if ("MusicGenre" === itemType || "Programs" !== params.type && "nextup" !== params.type && "Channel" !== itemType) {
+ hideOrShowAll(view.querySelectorAll(".btnShuffle"), false);
+ } else {
+ hideOrShowAll(view.querySelectorAll(".btnShuffle"), true);
+ }
+
+ if (item && playbackManager.canQueue(item)) {
+ hideOrShowAll(view.querySelectorAll(".btnQueue"), false);
+ } else {
+ hideOrShowAll(view.querySelectorAll(".btnQueue"), true);
+ }
+ });
+
+ if (!isRestored) {
+ bindAll(view.querySelectorAll(".btnPlay"), "click", play);
+ bindAll(view.querySelectorAll(".btnQueue"), "click", queue);
+ bindAll(view.querySelectorAll(".btnShuffle"), "click", shuffle);
+ }
+
+ this.alphaNumericShortcuts = new AlphaNumericShortcuts({
itemsContainer: self.itemsContainer
- })
- }), view.addEventListener("viewhide", function(e) {
+ });
+ });
+ view.addEventListener("viewhide", function (e) {
var itemsContainer = self.itemsContainer;
- itemsContainer && itemsContainer.pause();
+
+ if (itemsContainer) {
+ itemsContainer.pause();
+ }
+
var alphaNumericShortcuts = self.alphaNumericShortcuts;
- alphaNumericShortcuts && (alphaNumericShortcuts.destroy(), self.alphaNumericShortcuts = null)
- }), view.addEventListener("viewdestroy", function() {
- self.listController && self.listController.destroy(), self.alphaPicker && (self.alphaPicker.off("alphavaluechanged", onAlphaPickerValueChanged), self.alphaPicker.destroy()), self.currentItem = null, self.scroller = null, self.itemsContainer = null, self.filterButtons = null, self.sortButtons = null, self.btnSortText = null, self.btnSortIcon = null, self.alphaPickerElement = null
- })
+
+ if (alphaNumericShortcuts) {
+ alphaNumericShortcuts.destroy();
+ self.alphaNumericShortcuts = null;
+ }
+ });
+ view.addEventListener("viewdestroy", function () {
+ if (self.listController) {
+ self.listController.destroy();
+ }
+
+ if (self.alphaPicker) {
+ self.alphaPicker.off("alphavaluechanged", onAlphaPickerValueChanged);
+ self.alphaPicker.destroy();
+ }
+
+ self.currentItem = null;
+ self.scroller = null;
+ self.itemsContainer = null;
+ self.filterButtons = null;
+ self.sortButtons = null;
+ self.btnSortText = null;
+ self.btnSortIcon = null;
+ self.alphaPickerElement = null;
+ });
}
- return ItemsView.prototype.getFilters = function() {
+
+ ItemsView.prototype.getFilters = function () {
var basekey = this.getSettingsKey();
return {
IsPlayed: "true" === userSettings.getFilter(basekey + "-filter-IsPlayed"),
@@ -342,87 +867,211 @@ define(["globalize", "listView", "layoutManager", "userSettings", "focusManager"
HasThemeSong: userSettings.getFilter(basekey + "-filter-HasThemeSong"),
HasThemeVideo: userSettings.getFilter(basekey + "-filter-HasThemeVideo"),
GenreIds: userSettings.getFilter(basekey + "-filter-GenreIds")
- }
- }, ItemsView.prototype.getSortValues = function() {
+ };
+ };
+
+ ItemsView.prototype.getSortValues = function () {
var basekey = this.getSettingsKey();
return {
sortBy: userSettings.getFilter(basekey + "-sortby") || this.getDefaultSortBy(),
sortOrder: "Descending" === userSettings.getFilter(basekey + "-sortorder") ? "Descending" : "Ascending"
+ };
+ };
+
+ ItemsView.prototype.getDefaultSortBy = function () {
+ var params = this.params;
+ var sortNameOption = this.getNameSortOption(params);
+
+ if (params.type) {
+ return sortNameOption.value;
}
- }, ItemsView.prototype.getDefaultSortBy = function() {
- var params = this.params,
- sortNameOption = this.getNameSortOption(params);
- return params.type ? sortNameOption.value : "IsFolder," + sortNameOption.value
- }, ItemsView.prototype.getSortMenuOptions = function() {
- var sortBy = [],
- params = this.params;
- "Programs" === params.type && sortBy.push({
- name: globalize.translate("AirDate"),
- value: "StartDate,SortName"
- });
+
+ return "IsFolder," + sortNameOption.value;
+ };
+
+ ItemsView.prototype.getSortMenuOptions = function () {
+ var sortBy = [];
+ var params = this.params;
+
+ if ("Programs" === params.type) {
+ sortBy.push({
+ name: globalize.translate("AirDate"),
+ value: "StartDate,SortName"
+ });
+ }
+
var option = this.getNameSortOption(params);
- return option && sortBy.push(option), option = this.getCommunityRatingSortOption(), option && sortBy.push(option), option = this.getCriticRatingSortOption(), option && sortBy.push(option), "Programs" !== params.type && sortBy.push({
- name: globalize.translate("DateAdded"),
- value: "DateCreated,SortName"
- }), option = this.getDatePlayedSortOption(), option && sortBy.push(option), params.type || (option = this.getNameSortOption(params), sortBy.push({
- name: globalize.translate("Folders"),
- value: "IsFolder," + option.value
- })), sortBy.push({
+
+ if (option) {
+ sortBy.push(option);
+ }
+
+ option = this.getCommunityRatingSortOption();
+
+ if (option) {
+ sortBy.push(option);
+ }
+
+ option = this.getCriticRatingSortOption();
+
+ if (option) {
+ sortBy.push(option);
+ }
+
+ if ("Programs" !== params.type) {
+ sortBy.push({
+ name: globalize.translate("DateAdded"),
+ value: "DateCreated,SortName"
+ });
+ }
+
+ option = this.getDatePlayedSortOption();
+
+ if (option) {
+ sortBy.push(option);
+ }
+
+ if (!params.type) {
+ option = this.getNameSortOption(params);
+ sortBy.push({
+ name: globalize.translate("Folders"),
+ value: "IsFolder," + option.value
+ });
+ }
+
+ sortBy.push({
name: globalize.translate("ParentalRating"),
value: "OfficialRating,SortName"
- }), option = this.getPlayCountSortOption(), option && sortBy.push(option), sortBy.push({
+ });
+ option = this.getPlayCountSortOption();
+
+ if (option) {
+ sortBy.push(option);
+ }
+
+ sortBy.push({
name: globalize.translate("ReleaseDate"),
value: "ProductionYear,PremiereDate,SortName"
- }), sortBy.push({
+ });
+ sortBy.push({
name: globalize.translate("Runtime"),
value: "Runtime,SortName"
- }), sortBy
- }, ItemsView.prototype.getNameSortOption = function(params) {
- return "Episode" === params.type ? {
- name: globalize.translate("Name"),
- value: "SeriesName,SortName"
- } : {
+ });
+ return sortBy;
+ };
+
+ ItemsView.prototype.getNameSortOption = function (params) {
+ if ("Episode" === params.type) {
+ return {
+ name: globalize.translate("Name"),
+ value: "SeriesName,SortName"
+ };
+ }
+
+ return {
name: globalize.translate("Name"),
value: "SortName"
+ };
+ };
+
+ ItemsView.prototype.getPlayCountSortOption = function () {
+ if ("Programs" === this.params.type) {
+ return null;
}
- }, ItemsView.prototype.getPlayCountSortOption = function() {
- return "Programs" === this.params.type ? null : {
+
+ return {
name: globalize.translate("PlayCount"),
value: "PlayCount,SortName"
+ };
+ };
+
+ ItemsView.prototype.getDatePlayedSortOption = function () {
+ if ("Programs" === this.params.type) {
+ return null;
}
- }, ItemsView.prototype.getDatePlayedSortOption = function() {
- return "Programs" === this.params.type ? null : {
+
+ return {
name: globalize.translate("DatePlayed"),
value: "DatePlayed,SortName"
+ };
+ };
+
+ ItemsView.prototype.getCriticRatingSortOption = function () {
+ if ("Programs" === this.params.type) {
+ return null;
}
- }, ItemsView.prototype.getCriticRatingSortOption = function() {
- return "Programs" === this.params.type ? null : {
+
+ return {
name: globalize.translate("CriticRating"),
value: "CriticRating,SortName"
- }
- }, ItemsView.prototype.getCommunityRatingSortOption = function() {
+ };
+ };
+
+ ItemsView.prototype.getCommunityRatingSortOption = function () {
return {
name: globalize.translate("CommunityRating"),
value: "CommunityRating,SortName"
+ };
+ };
+
+ ItemsView.prototype.getVisibleFilters = function () {
+ var filters = [];
+ var params = this.params;
+
+ if (!("nextup" === params.type)) {
+ if ("Programs" === params.type) {
+ filters.push("Genres");
+ } else {
+ params.type;
+ filters.push("IsUnplayed");
+ filters.push("IsPlayed");
+
+ if (!params.IsFavorite) {
+ filters.push("IsFavorite");
+ }
+
+ filters.push("IsResumable");
+ filters.push("VideoType");
+ filters.push("HasSubtitles");
+ filters.push("HasTrailer");
+ filters.push("HasSpecialFeature");
+ filters.push("HasThemeSong");
+ filters.push("HasThemeVideo");
+ }
}
- }, ItemsView.prototype.getVisibleFilters = function() {
- var filters = [],
- params = this.params;
- return "nextup" === params.type || ("Programs" === params.type ? filters.push("Genres") : (params.type, filters.push("IsUnplayed"), filters.push("IsPlayed"), params.IsFavorite || filters.push("IsFavorite"), filters.push("IsResumable"), filters.push("VideoType"), filters.push("HasSubtitles"), filters.push("HasTrailer"), filters.push("HasSpecialFeature"), filters.push("HasThemeSong"), filters.push("HasThemeVideo"))), filters
- }, ItemsView.prototype.setFilterStatus = function(hasFilters) {
+
+ return filters;
+ };
+
+ ItemsView.prototype.setFilterStatus = function (hasFilters) {
this.hasFilters = hasFilters;
var filterButtons = this.filterButtons;
- if (filterButtons.length)
+
+ if (filterButtons.length) {
for (var i = 0, length = filterButtons.length; i < length; i++) {
- var btnFilter = filterButtons[i],
- bubble = btnFilter.querySelector(".filterButtonBubble");
+ var btnFilter = filterButtons[i];
+ var bubble = btnFilter.querySelector(".filterButtonBubble");
+
if (!bubble) {
- if (!hasFilters) continue;
- btnFilter.insertAdjacentHTML("afterbegin", '
!
'), btnFilter.classList.add("btnFilterWithBubble"), bubble = btnFilter.querySelector(".filterButtonBubble")
+ if (!hasFilters) {
+ continue;
+ }
+
+ btnFilter.insertAdjacentHTML("afterbegin", '
!
');
+ btnFilter.classList.add("btnFilterWithBubble");
+ bubble = btnFilter.querySelector(".filterButtonBubble");
+ }
+
+ if (hasFilters) {
+ bubble.classList.remove("hide");
+ } else {
+ bubble.classList.add("hide");
}
- hasFilters ? bubble.classList.remove("hide") : bubble.classList.add("hide")
}
- }, ItemsView.prototype.getFilterMenuOptions = function() {
+ }
+ };
+
+ ItemsView.prototype.getFilterMenuOptions = function () {
var params = this.params;
return {
IsAiring: params.IsAiring,
@@ -432,31 +1081,126 @@ define(["globalize", "listView", "layoutManager", "userSettings", "focusManager"
IsNews: params.IsNews,
IsSeries: params.IsSeries,
Recursive: this.queryRecursive
+ };
+ };
+
+ ItemsView.prototype.getVisibleViewSettings = function () {
+ var item = (this.params, this.currentItem);
+ var fields = ["showTitle"];
+
+ if (!item || "PhotoAlbum" !== item.Type && "ChannelFolderItem" !== item.Type) {
+ fields.push("imageType");
}
- }, ItemsView.prototype.getVisibleViewSettings = function() {
- var item = (this.params, this.currentItem),
- fields = ["showTitle"];
- return (!item || "PhotoAlbum" !== item.Type && "ChannelFolderItem" !== item.Type) && fields.push("imageType"), fields.push("viewType"), fields
- }, ItemsView.prototype.getViewSettings = function() {
- var basekey = this.getSettingsKey(),
- params = this.params,
- item = this.currentItem,
- showTitle = userSettings.get(basekey + "-showTitle");
- "true" === showTitle ? showTitle = !0 : "false" === showTitle ? showTitle = !1 : "Programs" === params.type || "Recordings" === params.type || "Person" === params.type || "nextup" === params.type || "Audio" === params.type || "MusicAlbum" === params.type || "MusicArtist" === params.type ? showTitle = !0 : item && "PhotoAlbum" !== item.Type && (showTitle = !0);
+
+ fields.push("viewType");
+ return fields;
+ };
+
+ ItemsView.prototype.getViewSettings = function () {
+ var basekey = this.getSettingsKey();
+ var params = this.params;
+ var item = this.currentItem;
+ var showTitle = userSettings.get(basekey + "-showTitle");
+
+ if ("true" === showTitle) {
+ showTitle = true;
+ } else if ("false" === showTitle) {
+ showTitle = false;
+ } else if ("Programs" === params.type || "Recordings" === params.type || "Person" === params.type || "nextup" === params.type || "Audio" === params.type || "MusicAlbum" === params.type || "MusicArtist" === params.type) {
+ showTitle = true;
+ } else if (item && "PhotoAlbum" !== item.Type) {
+ showTitle = true;
+ }
+
var imageType = userSettings.get(basekey + "-imageType");
- return imageType || "nextup" === params.type && (imageType = "thumb"), {
+
+ if (!imageType && "nextup" === params.type) {
+ imageType = "thumb";
+ }
+
+ return {
showTitle: showTitle,
showYear: "false" !== userSettings.get(basekey + "-showYear"),
imageType: imageType || "primary",
viewType: userSettings.get(basekey + "-viewType") || "images"
- }
- }, ItemsView.prototype.getItemTypes = function() {
+ };
+ };
+
+ ItemsView.prototype.getItemTypes = function () {
var params = this.params;
- return "nextup" === params.type ? ["Episode"] : "Programs" === params.type ? ["Program"] : []
- }, ItemsView.prototype.getSettingsKey = function() {
+
+ if ("nextup" === params.type) {
+ return ["Episode"];
+ }
+
+ if ("Programs" === params.type) {
+ return ["Program"];
+ }
+
+ return [];
+ };
+
+ ItemsView.prototype.getSettingsKey = function () {
var values = [];
values.push("items");
var params = this.params;
- return params.type ? values.push(params.type) : params.parentId && values.push(params.parentId), params.IsAiring && values.push("IsAiring"), params.IsMovie && values.push("IsMovie"), params.IsKids && values.push("IsKids"), params.IsSports && values.push("IsSports"), params.IsNews && values.push("IsNews"), params.IsSeries && values.push("IsSeries"), params.IsFavorite && values.push("IsFavorite"), params.genreId && values.push("Genre"), params.musicGenreId && values.push("MusicGenre"), params.studioId && values.push("Studio"), params.personId && values.push("Person"), params.parentId && values.push("Folder"), values.join("-")
- }, ItemsView
+
+ if (params.type) {
+ values.push(params.type);
+ } else if (params.parentId) {
+ values.push(params.parentId);
+ }
+
+ if (params.IsAiring) {
+ values.push("IsAiring");
+ }
+
+ if (params.IsMovie) {
+ values.push("IsMovie");
+ }
+
+ if (params.IsKids) {
+ values.push("IsKids");
+ }
+
+ if (params.IsSports) {
+ values.push("IsSports");
+ }
+
+ if (params.IsNews) {
+ values.push("IsNews");
+ }
+
+ if (params.IsSeries) {
+ values.push("IsSeries");
+ }
+
+ if (params.IsFavorite) {
+ values.push("IsFavorite");
+ }
+
+ if (params.genreId) {
+ values.push("Genre");
+ }
+
+ if (params.musicGenreId) {
+ values.push("MusicGenre");
+ }
+
+ if (params.studioId) {
+ values.push("Studio");
+ }
+
+ if (params.personId) {
+ values.push("Person");
+ }
+
+ if (params.parentId) {
+ values.push("Folder");
+ }
+
+ return values.join("-");
+ };
+
+ return ItemsView;
});
diff --git a/src/controllers/livetv/livetvchannels.js b/src/controllers/livetv/livetvchannels.js
index cc2eda5053..3e310a17a3 100644
--- a/src/controllers/livetv/livetvchannels.js
+++ b/src/controllers/livetv/livetvchannels.js
@@ -1,89 +1,119 @@
-define(["cardBuilder", "imageLoader", "libraryBrowser", "loading", "events", "emby-itemscontainer"], function(cardBuilder, imageLoader, libraryBrowser, loading, events) {
+define(["cardBuilder", "imageLoader", "libraryBrowser", "loading", "events", "emby-itemscontainer"], function (cardBuilder, imageLoader, libraryBrowser, loading, events) {
"use strict";
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
function getPageData() {
- return pageData || (pageData = {
- query: {
- StartIndex: 0,
- Limit: 100,
- Fields: "PrimaryImageAspectRatio"
- }
- }), pageData
+ if (!pageData) {
+ pageData = {
+ query: {
+ StartIndex: 0,
+ Limit: 100,
+ Fields: "PrimaryImageAspectRatio"
+ }
+ };
+ }
+
+ return pageData;
}
function getQuery() {
- return getPageData().query
+ return getPageData().query;
}
function getChannelsHtml(channels) {
return cardBuilder.getCardsHtml({
items: channels,
shape: "square",
- showTitle: !0,
- lazy: !0,
- cardLayout: !0,
- showDetailsMenu: !0,
- showCurrentProgram: !0,
- showCurrentProgramTime: !0
- })
+ showTitle: true,
+ lazy: true,
+ cardLayout: true,
+ showDetailsMenu: true,
+ showCurrentProgram: true,
+ showCurrentProgramTime: true
+ });
}
function renderChannels(context, result) {
function onNextPageClick() {
- if (isLoading) return;
- query.StartIndex += query.Limit, reloadItems(context)
+ if (isLoading) {
+ return;
+ }
+
+ query.StartIndex += query.Limit;
+ reloadItems(context);
}
function onPreviousPageClick() {
- if (isLoading) return;
- query.StartIndex -= query.Limit, reloadItems(context)
+ if (isLoading) {
+ return;
+ }
+
+ query.StartIndex -= query.Limit;
+ reloadItems(context);
}
+
var query = getQuery();
context.querySelector(".paging").innerHTML = libraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
- showLimit: !1,
- updatePageSizeSetting: !1,
- filterButton: !1
+ showLimit: false,
+ updatePageSizeSetting: false,
+ filterButton: false
});
- var html = getChannelsHtml(result.Items),
- elem = context.querySelector("#items");
- elem.innerHTML = html, imageLoader.lazyChildren(elem);
- var i, length, elems;
- for (elems = context.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick);
- for (elems = context.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick)
+ var html = getChannelsHtml(result.Items);
+ var elem = context.querySelector("#items");
+ elem.innerHTML = html;
+ imageLoader.lazyChildren(elem);
+ var i;
+ var length;
+ var elems;
+
+ for (elems = context.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onNextPageClick);
+ }
+
+ for (elems = context.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onPreviousPageClick);
+ }
}
function showFilterMenu(context) {
- require(["components/filterdialog/filterdialog"], function(filterDialogFactory) {
+ require(["components/filterdialog/filterdialog"], function (filterDialogFactory) {
var filterDialog = new filterDialogFactory({
query: getQuery(),
mode: "livetvchannels",
serverId: ApiClient.serverId()
});
- events.on(filterDialog, "filterchange", function() {
- reloadItems(context)
- }), filterDialog.show()
- })
+ events.on(filterDialog, "filterchange", function () {
+ reloadItems(context);
+ });
+ filterDialog.show();
+ });
}
function reloadItems(context, save) {
loading.show();
isLoading = true;
- var query = getQuery(),
- apiClient = ApiClient;
- query.UserId = apiClient.getCurrentUserId(), apiClient.getLiveTvChannels(query).then(function(result) {
+ var query = getQuery();
+ var apiClient = ApiClient;
+ query.UserId = apiClient.getCurrentUserId();
+ apiClient.getLiveTvChannels(query).then(function (result) {
renderChannels(context, result);
loading.hide();
isLoading = false;
- })
+ });
}
- var pageData, self = this, isLoading = false;
- tabContent.querySelector(".btnFilter").addEventListener("click", function() {
- showFilterMenu(tabContent)
- }), self.renderTab = function() {
- reloadItems(tabContent)
- }
- }
+
+ var pageData;
+ var self = this;
+ var isLoading = false;
+ tabContent.querySelector(".btnFilter").addEventListener("click", function () {
+ showFilterMenu(tabContent);
+ });
+
+ self.renderTab = function () {
+ reloadItems(tabContent);
+ };
+ };
});
diff --git a/src/controllers/livetv/livetvguide.js b/src/controllers/livetv/livetvguide.js
index 3c8b3f4109..f7c2f1baaa 100644
--- a/src/controllers/livetv/livetvguide.js
+++ b/src/controllers/livetv/livetvguide.js
@@ -1,16 +1,29 @@
-define(["tvguide"], function(tvguide) {
+define(["tvguide"], function (tvguide) {
"use strict";
- return function(view, params, tabContent) {
- var guideInstance, self = this;
- self.renderTab = function() {
- guideInstance || (guideInstance = new tvguide({
- element: tabContent,
- serverId: ApiClient.serverId()
- }))
- }, self.onShow = function() {
- guideInstance && guideInstance.resume()
- }, self.onHide = function() {
- guideInstance && guideInstance.pause()
- }
- }
-});
\ No newline at end of file
+
+ return function (view, params, tabContent) {
+ var guideInstance;
+ var self = this;
+
+ self.renderTab = function () {
+ if (!guideInstance) {
+ guideInstance = new tvguide({
+ element: tabContent,
+ serverId: ApiClient.serverId()
+ });
+ }
+ };
+
+ self.onShow = function () {
+ if (guideInstance) {
+ guideInstance.resume();
+ }
+ };
+
+ self.onHide = function () {
+ if (guideInstance) {
+ guideInstance.pause();
+ }
+ };
+ };
+});
diff --git a/src/controllers/livetv/livetvrecordings.js b/src/controllers/livetv/livetvrecordings.js
index f82b150a21..ed3ae24087 100644
--- a/src/controllers/livetv/livetvrecordings.js
+++ b/src/controllers/livetv/livetvrecordings.js
@@ -1,69 +1,106 @@
-define(["layoutManager", "loading", "cardBuilder", "apphost", "imageLoader", "scripts/livetvcomponents", "listViewStyle", "emby-itemscontainer"], function(layoutManager, loading, cardBuilder, appHost, imageLoader) {
+define(["layoutManager", "loading", "cardBuilder", "apphost", "imageLoader", "scripts/livetvcomponents", "listViewStyle", "emby-itemscontainer"], function (layoutManager, loading, cardBuilder, appHost, imageLoader) {
"use strict";
function renderRecordings(elem, recordings, cardOptions, scrollX) {
- recordings.length ? elem.classList.remove("hide") : elem.classList.add("hide");
+ if (recordings.length) {
+ elem.classList.remove("hide");
+ } else {
+ elem.classList.add("hide");
+ }
+
var recordingItems = elem.querySelector(".recordingItems");
- scrollX ? (recordingItems.classList.add("scrollX"), recordingItems.classList.add("hiddenScrollX"), recordingItems.classList.remove("vertical-wrap")) : (recordingItems.classList.remove("scrollX"), recordingItems.classList.remove("hiddenScrollX"), recordingItems.classList.add("vertical-wrap"));
+
+ if (scrollX) {
+ recordingItems.classList.add("scrollX");
+ recordingItems.classList.add("hiddenScrollX");
+ recordingItems.classList.remove("vertical-wrap");
+ } else {
+ recordingItems.classList.remove("scrollX");
+ recordingItems.classList.remove("hiddenScrollX");
+ recordingItems.classList.add("vertical-wrap");
+ }
+
appHost.supports("imageanalysis");
recordingItems.innerHTML = cardBuilder.getCardsHtml(Object.assign({
items: recordings,
shape: scrollX ? "autooverflow" : "auto",
defaultShape: scrollX ? "overflowBackdrop" : "backdrop",
- showTitle: !0,
- showParentTitle: !0,
- coverImage: !0,
- cardLayout: !1,
- centerText: !0,
+ showTitle: true,
+ showParentTitle: true,
+ coverImage: true,
+ cardLayout: false,
+ centerText: true,
allowBottomPadding: !scrollX,
preferThumb: "auto",
- overlayText: !1
- }, cardOptions || {})), imageLoader.lazyChildren(recordingItems)
+ overlayText: false
+ }, cardOptions || {}));
+ imageLoader.lazyChildren(recordingItems);
}
function renderLatestRecordings(context, promise) {
- promise.then(function(result) {
+ promise.then(function (result) {
renderRecordings(context.querySelector("#latestRecordings"), result.Items, {
- showYear: !0,
+ showYear: true,
lines: 2
- }, !1), loading.hide()
- })
+ }, false);
+ loading.hide();
+ });
}
function renderRecordingFolders(context, promise) {
- promise.then(function(result) {
+ promise.then(function (result) {
renderRecordings(context.querySelector("#recordingFolders"), result.Items, {
- showYear: !1,
- showParentTitle: !1
- }, !1)
- })
+ showYear: false,
+ showParentTitle: false
+ }, false);
+ });
}
function onMoreClick(e) {
- var type = this.getAttribute("data-type"),
- serverId = ApiClient.serverId();
+ var type = this.getAttribute("data-type");
+ var serverId = ApiClient.serverId();
+
switch (type) {
case "latest":
- Dashboard.navigate("list.html?type=Recordings&serverId=" + serverId)
+ Dashboard.navigate("list.html?type=Recordings&serverId=" + serverId);
}
}
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
function enableFullRender() {
- return (new Date).getTime() - lastFullRender > 3e5
+ return new Date().getTime() - lastFullRender > 300000;
}
- var foldersPromise, latestPromise, self = this,
- lastFullRender = 0;
- for (var moreButtons = tabContent.querySelectorAll(".more"), i = 0, length = moreButtons.length; i < length; i++) moreButtons[i].addEventListener("click", onMoreClick);
- self.preRender = function() {
- enableFullRender() && (latestPromise = ApiClient.getLiveTvRecordings({
- UserId: Dashboard.getCurrentUserId(),
- Limit: 12,
- Fields: "CanDelete,PrimaryImageAspectRatio,BasicSyncInfo",
- EnableTotalRecordCount: !1,
- EnableImageTypes: "Primary,Thumb,Backdrop"
- }), foldersPromise = ApiClient.getRecordingFolders(Dashboard.getCurrentUserId()))
- }, self.renderTab = function() {
- enableFullRender() && (loading.show(), renderLatestRecordings(tabContent, latestPromise), renderRecordingFolders(tabContent, foldersPromise), lastFullRender = (new Date).getTime())
+
+ var foldersPromise;
+ var latestPromise;
+ var self = this;
+ var lastFullRender = 0;
+ var moreButtons = tabContent.querySelectorAll(".more");
+
+ for (var i = 0, length = moreButtons.length; i < length; i++) {
+ moreButtons[i].addEventListener("click", onMoreClick);
}
- }
-});
\ No newline at end of file
+
+ self.preRender = function () {
+ if (enableFullRender()) {
+ latestPromise = ApiClient.getLiveTvRecordings({
+ UserId: Dashboard.getCurrentUserId(),
+ Limit: 12,
+ Fields: "CanDelete,PrimaryImageAspectRatio,BasicSyncInfo",
+ EnableTotalRecordCount: false,
+ EnableImageTypes: "Primary,Thumb,Backdrop"
+ });
+ foldersPromise = ApiClient.getRecordingFolders(Dashboard.getCurrentUserId());
+ }
+ };
+
+ self.renderTab = function () {
+ if (enableFullRender()) {
+ loading.show();
+ renderLatestRecordings(tabContent, latestPromise);
+ renderRecordingFolders(tabContent, foldersPromise);
+ lastFullRender = new Date().getTime();
+ }
+ };
+ };
+});
diff --git a/src/controllers/livetv/livetvschedule.js b/src/controllers/livetv/livetvschedule.js
index 24ece42dbe..3ee56a2a95 100644
--- a/src/controllers/livetv/livetvschedule.js
+++ b/src/controllers/livetv/livetvschedule.js
@@ -1,27 +1,50 @@
-define(["layoutManager", "cardBuilder", "apphost", "imageLoader", "loading", "scripts/livetvcomponents", "emby-button", "emby-itemscontainer"], function(layoutManager, cardBuilder, appHost, imageLoader, loading) {
+define(["layoutManager", "cardBuilder", "apphost", "imageLoader", "loading", "scripts/livetvcomponents", "emby-button", "emby-itemscontainer"], function (layoutManager, cardBuilder, appHost, imageLoader, loading) {
"use strict";
function enableScrollX() {
- return !layoutManager.desktop
+ return !layoutManager.desktop;
}
function renderRecordings(elem, recordings, cardOptions) {
- recordings.length ? elem.classList.remove("hide") : elem.classList.add("hide");
+ if (recordings.length) {
+ elem.classList.remove("hide");
+ } else {
+ elem.classList.add("hide");
+ }
+
var recordingItems = elem.querySelector(".recordingItems");
- enableScrollX() ? (recordingItems.classList.add("scrollX"), layoutManager.tv && recordingItems.classList.add("smoothScrollX"), recordingItems.classList.add("hiddenScrollX"), recordingItems.classList.remove("vertical-wrap")) : (recordingItems.classList.remove("scrollX"), recordingItems.classList.remove("smoothScrollX"), recordingItems.classList.remove("hiddenScrollX"), recordingItems.classList.add("vertical-wrap"));
- var supportsImageAnalysis = appHost.supports("imageanalysis"),
- cardLayout = appHost.preferVisualCards || supportsImageAnalysis;
- cardLayout = !1, recordingItems.innerHTML = cardBuilder.getCardsHtml(Object.assign({
+
+ if (enableScrollX()) {
+ recordingItems.classList.add("scrollX");
+
+ if (layoutManager.tv) {
+ recordingItems.classList.add("smoothScrollX");
+ }
+
+ recordingItems.classList.add("hiddenScrollX");
+ recordingItems.classList.remove("vertical-wrap");
+ } else {
+ recordingItems.classList.remove("scrollX");
+ recordingItems.classList.remove("smoothScrollX");
+ recordingItems.classList.remove("hiddenScrollX");
+ recordingItems.classList.add("vertical-wrap");
+ }
+
+ var supportsImageAnalysis = appHost.supports("imageanalysis");
+ var cardLayout = appHost.preferVisualCards || supportsImageAnalysis;
+ cardLayout = false;
+ recordingItems.innerHTML = cardBuilder.getCardsHtml(Object.assign({
items: recordings,
shape: enableScrollX() ? "autooverflow" : "auto",
- showTitle: !0,
- showParentTitle: !0,
- coverImage: !0,
+ showTitle: true,
+ showParentTitle: true,
+ coverImage: true,
cardLayout: cardLayout,
centerText: !cardLayout,
allowBottomPadding: !enableScrollX(),
preferThumb: "auto"
- }, cardOptions || {})), imageLoader.lazyChildren(recordingItems)
+ }, cardOptions || {}));
+ imageLoader.lazyChildren(recordingItems);
}
function getBackdropShape() {
@@ -29,52 +52,72 @@ define(["layoutManager", "cardBuilder", "apphost", "imageLoader", "loading", "sc
}
function renderActiveRecordings(context, promise) {
- promise.then(function(result) {
+ promise.then(function (result) {
renderRecordings(context.querySelector("#activeRecordings"), result.Items, {
shape: enableScrollX() ? "autooverflow" : "auto",
defaultShape: getBackdropShape(),
- showParentTitle: !1,
- showParentTitleOrTitle: !0,
- showTitle: !1,
- showAirTime: !0,
- showAirEndTime: !0,
- showChannelName: !0,
- coverImage: !0,
- overlayText: !1,
- overlayMoreButton: !0
- })
- })
+ showParentTitle: false,
+ showParentTitleOrTitle: true,
+ showTitle: false,
+ showAirTime: true,
+ showAirEndTime: true,
+ showChannelName: true,
+ coverImage: true,
+ overlayText: false,
+ overlayMoreButton: true
+ });
+ });
}
function renderTimers(context, timers, options) {
- LiveTvHelpers.getTimersHtml(timers, options).then(function(html) {
+ LiveTvHelpers.getTimersHtml(timers, options).then(function (html) {
var elem = context;
- html ? elem.classList.remove("hide") : elem.classList.add("hide"), elem.querySelector(".recordingItems").innerHTML = html, imageLoader.lazyChildren(elem)
- })
+
+ if (html) {
+ elem.classList.remove("hide");
+ } else {
+ elem.classList.add("hide");
+ }
+
+ elem.querySelector(".recordingItems").innerHTML = html;
+ imageLoader.lazyChildren(elem);
+ });
}
function renderUpcomingRecordings(context, promise) {
- promise.then(function(result) {
- renderTimers(context.querySelector("#upcomingRecordings"), result.Items), loading.hide()
- })
+ promise.then(function (result) {
+ renderTimers(context.querySelector("#upcomingRecordings"), result.Items);
+ loading.hide();
+ });
}
- return function(view, params, tabContent) {
- var activeRecordingsPromise, upcomingRecordingsPromise, self = this;
- tabContent.querySelector("#upcomingRecordings .recordingItems").addEventListener("timercancelled", function() {
- self.preRender(), self.renderTab()
- }), self.preRender = function() {
+
+ return function (view, params, tabContent) {
+ var activeRecordingsPromise;
+ var upcomingRecordingsPromise;
+ var self = this;
+ tabContent.querySelector("#upcomingRecordings .recordingItems").addEventListener("timercancelled", function () {
+ self.preRender();
+ self.renderTab();
+ });
+
+ self.preRender = function () {
activeRecordingsPromise = ApiClient.getLiveTvRecordings({
UserId: Dashboard.getCurrentUserId(),
- IsInProgress: !0,
+ IsInProgress: true,
Fields: "CanDelete,PrimaryImageAspectRatio,BasicSyncInfo",
- EnableTotalRecordCount: !1,
+ EnableTotalRecordCount: false,
EnableImageTypes: "Primary,Thumb,Backdrop"
- }), upcomingRecordingsPromise = ApiClient.getLiveTvTimers({
- IsActive: !1,
- IsScheduled: !0
- })
- }, self.renderTab = function() {
- loading.show(), renderActiveRecordings(tabContent, activeRecordingsPromise), renderUpcomingRecordings(tabContent, upcomingRecordingsPromise)
- }
- }
-});
\ No newline at end of file
+ });
+ upcomingRecordingsPromise = ApiClient.getLiveTvTimers({
+ IsActive: false,
+ IsScheduled: true
+ });
+ };
+
+ self.renderTab = function () {
+ loading.show();
+ renderActiveRecordings(tabContent, activeRecordingsPromise);
+ renderUpcomingRecordings(tabContent, upcomingRecordingsPromise);
+ };
+ };
+});
diff --git a/src/controllers/livetv/livetvseriestimers.js b/src/controllers/livetv/livetvseriestimers.js
index 5acd9f326c..9c95cfa91f 100644
--- a/src/controllers/livetv/livetvseriestimers.js
+++ b/src/controllers/livetv/livetvseriestimers.js
@@ -1,4 +1,4 @@
-define(["datetime", "cardBuilder", "imageLoader", "apphost", "loading", "paper-icon-button-light", "emby-button"], function(datetime, cardBuilder, imageLoader, appHost, loading) {
+define(["datetime", "cardBuilder", "imageLoader", "apphost", "loading", "paper-icon-button-light", "emby-button"], function (datetime, cardBuilder, imageLoader, appHost, loading) {
"use strict";
function renderTimers(context, timers) {
@@ -8,36 +8,44 @@ define(["datetime", "cardBuilder", "imageLoader", "apphost", "loading", "paper-i
items: timers,
shape: "auto",
defaultShape: "portrait",
- showTitle: !0,
- cardLayout: !1,
+ showTitle: true,
+ cardLayout: false,
preferThumb: "auto",
- coverImage: !0,
- overlayText: !1,
- showSeriesTimerTime: !0,
- showSeriesTimerChannel: !0,
- centerText: !0,
- overlayMoreButton: !0,
+ coverImage: true,
+ overlayText: false,
+ showSeriesTimerTime: true,
+ showSeriesTimerChannel: true,
+ centerText: true,
+ overlayMoreButton: true,
lines: 3
});
var elem = context.querySelector("#items");
- elem.innerHTML = html, imageLoader.lazyChildren(elem), loading.hide()
+ elem.innerHTML = html;
+ imageLoader.lazyChildren(elem);
+ loading.hide();
}
function reload(context, promise) {
- loading.show(), promise.then(function(result) {
- renderTimers(context, result.Items)
- })
+ loading.show();
+ promise.then(function (result) {
+ renderTimers(context, result.Items);
+ });
}
+
var query = {
SortBy: "SortName",
SortOrder: "Ascending"
};
- return function(view, params, tabContent) {
- var timersPromise, self = this;
- self.preRender = function() {
- timersPromise = ApiClient.getLiveTvSeriesTimers(query)
- }, self.renderTab = function() {
- reload(tabContent, timersPromise)
- }
- }
-});
\ No newline at end of file
+ return function (view, params, tabContent) {
+ var timersPromise;
+ var self = this;
+
+ self.preRender = function () {
+ timersPromise = ApiClient.getLiveTvSeriesTimers(query);
+ };
+
+ self.renderTab = function () {
+ reload(tabContent, timersPromise);
+ };
+ };
+});
diff --git a/src/controllers/livetv/livetvsuggested.js b/src/controllers/livetv/livetvsuggested.js
index 4fc51467e6..509b7f521c 100644
--- a/src/controllers/livetv/livetvsuggested.js
+++ b/src/controllers/livetv/livetvsuggested.js
@@ -23,6 +23,7 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize",
if (enableScrollX()) {
return 12;
}
+
return 9;
}
@@ -150,15 +151,22 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize",
}
function getTabs() {
- return [
- { name: globalize.translate("Programs") },
- { name: globalize.translate("TabGuide") },
- { name: globalize.translate("TabChannels") },
- { name: globalize.translate("TabRecordings") },
- { name: globalize.translate("HeaderSchedule") },
- { name: globalize.translate("TabSeries") },
- { name: globalize.translate("ButtonSearch"), cssClass: "searchTabButton" }
- ];
+ return [{
+ name: globalize.translate("Programs")
+ }, {
+ name: globalize.translate("TabGuide")
+ }, {
+ name: globalize.translate("TabChannels")
+ }, {
+ name: globalize.translate("TabRecordings")
+ }, {
+ name: globalize.translate("HeaderSchedule")
+ }, {
+ name: globalize.translate("TabSeries")
+ }, {
+ name: globalize.translate("ButtonSearch"),
+ cssClass: "searchTabButton"
+ }];
}
function setScrollClasses(elem, scrollX) {
@@ -183,6 +191,7 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize",
if (userSettings.get("landing-" + folderId) === "guide") {
return 1;
}
+
return 0;
}
@@ -220,21 +229,27 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize",
switch (index) {
case 0:
break;
+
case 1:
depends.push("controllers/livetv/livetvguide");
break;
+
case 2:
depends.push("controllers/livetv/livetvchannels");
break;
+
case 3:
depends.push("controllers/livetv/livetvrecordings");
break;
+
case 4:
depends.push("controllers/livetv/livetvschedule");
break;
+
case 5:
depends.push("controllers/livetv/livetvseriestimers");
break;
+
case 6:
depends.push("scripts/searchtab");
}
@@ -251,6 +266,7 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize",
if (!controller) {
tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
+
if (0 === index) {
controller = self;
} else if (6 === index) {
@@ -260,6 +276,7 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize",
} else {
controller = new controllerFactory(view, params, tabContent);
}
+
tabControllers[index] = controller;
if (controller.initTab) {
@@ -347,15 +364,18 @@ define(["layoutManager", "userSettings", "inputManager", "loading", "globalize",
});
view.addEventListener("viewshow", function (evt) {
isViewRestored = evt.detail.isRestored;
+
if (!isViewRestored) {
mainTabsManager.selectedTabIndex(initialTabIndex);
}
+
inputManager.on(window, onInputCommand);
});
- view.addEventListener("viewbeforehide", function (e__u) {
+ view.addEventListener("viewbeforehide", function (e) {
if (currentTabController && currentTabController.onHide) {
currentTabController.onHide();
}
+
inputManager.off(window, onInputCommand);
});
view.addEventListener("viewdestroy", function (evt) {
diff --git a/src/controllers/livetvguideprovider.js b/src/controllers/livetvguideprovider.js
index 40617cdb90..a58917f22d 100644
--- a/src/controllers/livetvguideprovider.js
+++ b/src/controllers/livetvguideprovider.js
@@ -1,26 +1,30 @@
-define(["events", "loading"], function(events, loading) {
+define(["events", "loading"], function (events, loading) {
"use strict";
function onListingsSubmitted() {
- Dashboard.navigate("livetvstatus.html")
+ Dashboard.navigate("livetvstatus.html");
}
function init(page, type, providerId) {
var url = "components/tvproviders/" + type + ".js";
- require([url], function(factory) {
+
+ require([url], function (factory) {
var instance = new factory(page, providerId, {});
- events.on(instance, "submitted", onListingsSubmitted), instance.init()
- })
+ events.on(instance, "submitted", onListingsSubmitted);
+ instance.init();
+ });
}
function loadTemplate(page, type, providerId) {
- require(["text!./components/tvproviders/" + type + ".template.html"], function(html) {
- page.querySelector(".providerTemplate").innerHTML = Globalize.translateDocument(html), init(page, type, providerId)
- })
+ require(["text!./components/tvproviders/" + type + ".template.html"], function (html) {
+ page.querySelector(".providerTemplate").innerHTML = Globalize.translateDocument(html);
+ init(page, type, providerId);
+ });
}
- pageIdOn("pageshow", "liveTvGuideProviderPage", function() {
+
+ pageIdOn("pageshow", "liveTvGuideProviderPage", function () {
loading.show();
var providerId = getParameterByName("id");
- loadTemplate(this, getParameterByName("type"), providerId)
- })
-});
\ No newline at end of file
+ loadTemplate(this, getParameterByName("type"), providerId);
+ });
+});
diff --git a/src/controllers/livetvsettings.js b/src/controllers/livetvsettings.js
index 422257e33d..2b11071c75 100644
--- a/src/controllers/livetvsettings.js
+++ b/src/controllers/livetvsettings.js
@@ -1,79 +1,127 @@
-define(["jQuery", "loading", "fnchecked", "emby-button"], function($, loading) {
+define(["jQuery", "loading", "fnchecked", "emby-button"], function ($, loading) {
"use strict";
function loadPage(page, config) {
- $(".liveTvSettingsForm", page).show(), $(".noLiveTvServices", page).hide(), $("#selectGuideDays", page).val(config.GuideDays || ""), $("#txtPrePaddingMinutes", page).val(config.PrePaddingSeconds / 60), $("#txtPostPaddingMinutes", page).val(config.PostPaddingSeconds / 60), page.querySelector("#txtRecordingPath").value = config.RecordingPath || "", page.querySelector("#txtMovieRecordingPath").value = config.MovieRecordingPath || "", page.querySelector("#txtSeriesRecordingPath").value = config.SeriesRecordingPath || "", page.querySelector("#txtPostProcessor").value = config.RecordingPostProcessor || "", page.querySelector("#txtPostProcessorArguments").value = config.RecordingPostProcessorArguments || "", loading.hide()
+ $(".liveTvSettingsForm", page).show();
+ $(".noLiveTvServices", page).hide();
+ $("#selectGuideDays", page).val(config.GuideDays || "");
+ $("#txtPrePaddingMinutes", page).val(config.PrePaddingSeconds / 60);
+ $("#txtPostPaddingMinutes", page).val(config.PostPaddingSeconds / 60);
+ page.querySelector("#txtRecordingPath").value = config.RecordingPath || "";
+ page.querySelector("#txtMovieRecordingPath").value = config.MovieRecordingPath || "";
+ page.querySelector("#txtSeriesRecordingPath").value = config.SeriesRecordingPath || "";
+ page.querySelector("#txtPostProcessor").value = config.RecordingPostProcessor || "";
+ page.querySelector("#txtPostProcessorArguments").value = config.RecordingPostProcessorArguments || "";
+ loading.hide();
}
function onSubmit() {
loading.show();
var form = this;
- return ApiClient.getNamedConfiguration("livetv").then(function(config) {
+ ApiClient.getNamedConfiguration("livetv").then(function (config) {
config.GuideDays = $("#selectGuideDays", form).val() || null;
- var recordingPath = form.querySelector("#txtRecordingPath").value || null,
- movieRecordingPath = form.querySelector("#txtMovieRecordingPath").value || null,
- seriesRecordingPath = form.querySelector("#txtSeriesRecordingPath").value || null,
- recordingPathChanged = recordingPath != config.RecordingPath || movieRecordingPath != config.MovieRecordingPath || seriesRecordingPath != config.SeriesRecordingPath;
- config.RecordingPath = recordingPath, config.MovieRecordingPath = movieRecordingPath, config.SeriesRecordingPath = seriesRecordingPath, config.RecordingEncodingFormat = "mkv", config.PrePaddingSeconds = 60 * $("#txtPrePaddingMinutes", form).val(), config.PostPaddingSeconds = 60 * $("#txtPostPaddingMinutes", form).val(), config.RecordingPostProcessor = $("#txtPostProcessor", form).val(), config.RecordingPostProcessorArguments = $("#txtPostProcessorArguments", form).val(), ApiClient.updateNamedConfiguration("livetv", config).then(function() {
- Dashboard.processServerConfigurationUpdateResult(), showSaveMessage(recordingPathChanged)
- })
- }), !1
+ var recordingPath = form.querySelector("#txtRecordingPath").value || null;
+ var movieRecordingPath = form.querySelector("#txtMovieRecordingPath").value || null;
+ var seriesRecordingPath = form.querySelector("#txtSeriesRecordingPath").value || null;
+ var recordingPathChanged = recordingPath != config.RecordingPath || movieRecordingPath != config.MovieRecordingPath || seriesRecordingPath != config.SeriesRecordingPath;
+ config.RecordingPath = recordingPath;
+ config.MovieRecordingPath = movieRecordingPath;
+ config.SeriesRecordingPath = seriesRecordingPath;
+ config.RecordingEncodingFormat = "mkv";
+ config.PrePaddingSeconds = 60 * $("#txtPrePaddingMinutes", form).val();
+ config.PostPaddingSeconds = 60 * $("#txtPostPaddingMinutes", form).val();
+ config.RecordingPostProcessor = $("#txtPostProcessor", form).val();
+ config.RecordingPostProcessorArguments = $("#txtPostProcessorArguments", form).val();
+ ApiClient.updateNamedConfiguration("livetv", config).then(function () {
+ Dashboard.processServerConfigurationUpdateResult();
+ showSaveMessage(recordingPathChanged);
+ });
+ });
+ return false;
}
function showSaveMessage(recordingPathChanged) {
var msg = "";
- recordingPathChanged && (msg += Globalize.translate("RecordingPathChangeMessage")), msg && require(["alert"], function(alert) {
- alert(msg)
- })
+
+ if (recordingPathChanged) {
+ msg += Globalize.translate("RecordingPathChangeMessage");
+ }
+
+ if (msg) {
+ require(["alert"], function (alert) {
+ alert(msg);
+ });
+ }
}
- $(document).on("pageinit", "#liveTvSettingsPage", function() {
+
+ $(document).on("pageinit", "#liveTvSettingsPage", function () {
var page = this;
- $(".liveTvSettingsForm").off("submit", onSubmit).on("submit", onSubmit), $("#btnSelectRecordingPath", page).on("click.selectDirectory", function() {
- require(["directorybrowser"], function(directoryBrowser) {
- var picker = new directoryBrowser;
+ $(".liveTvSettingsForm").off("submit", onSubmit).on("submit", onSubmit);
+ $("#btnSelectRecordingPath", page).on("click.selectDirectory", function () {
+ require(["directorybrowser"], function (directoryBrowser) {
+ var picker = new directoryBrowser();
picker.show({
- callback: function(path) {
- path && $("#txtRecordingPath", page).val(path), picker.close()
+ callback: function (path) {
+ if (path) {
+ $("#txtRecordingPath", page).val(path);
+ }
+
+ picker.close();
},
- validateWriteable: !0
- })
- })
- }), $("#btnSelectMovieRecordingPath", page).on("click.selectDirectory", function() {
- require(["directorybrowser"], function(directoryBrowser) {
- var picker = new directoryBrowser;
+ validateWriteable: true
+ });
+ });
+ });
+ $("#btnSelectMovieRecordingPath", page).on("click.selectDirectory", function () {
+ require(["directorybrowser"], function (directoryBrowser) {
+ var picker = new directoryBrowser();
picker.show({
- callback: function(path) {
- path && $("#txtMovieRecordingPath", page).val(path), picker.close()
+ callback: function (path) {
+ if (path) {
+ $("#txtMovieRecordingPath", page).val(path);
+ }
+
+ picker.close();
},
- validateWriteable: !0
- })
- })
- }), $("#btnSelectSeriesRecordingPath", page).on("click.selectDirectory", function() {
- require(["directorybrowser"], function(directoryBrowser) {
- var picker = new directoryBrowser;
+ validateWriteable: true
+ });
+ });
+ });
+ $("#btnSelectSeriesRecordingPath", page).on("click.selectDirectory", function () {
+ require(["directorybrowser"], function (directoryBrowser) {
+ var picker = new directoryBrowser();
picker.show({
- callback: function(path) {
- path && $("#txtSeriesRecordingPath", page).val(path), picker.close()
+ callback: function (path) {
+ if (path) {
+ $("#txtSeriesRecordingPath", page).val(path);
+ }
+
+ picker.close();
},
- validateWriteable: !0
- })
- })
- }), $("#btnSelectPostProcessorPath", page).on("click.selectDirectory", function() {
- require(["directorybrowser"], function(directoryBrowser) {
- var picker = new directoryBrowser;
+ validateWriteable: true
+ });
+ });
+ });
+ $("#btnSelectPostProcessorPath", page).on("click.selectDirectory", function () {
+ require(["directorybrowser"], function (directoryBrowser) {
+ var picker = new directoryBrowser();
picker.show({
- includeFiles: !0,
- callback: function(path) {
- path && $("#txtPostProcessor", page).val(path), picker.close()
+ includeFiles: true,
+ callback: function (path) {
+ if (path) {
+ $("#txtPostProcessor", page).val(path);
+ }
+
+ picker.close();
}
- })
- })
- })
- }).on("pageshow", "#liveTvSettingsPage", function() {
+ });
+ });
+ });
+ }).on("pageshow", "#liveTvSettingsPage", function () {
loading.show();
var page = this;
- ApiClient.getNamedConfiguration("livetv").then(function(config) {
- loadPage(page, config)
- })
- })
-});
\ No newline at end of file
+ ApiClient.getNamedConfiguration("livetv").then(function (config) {
+ loadPage(page, config);
+ });
+ });
+});
diff --git a/src/controllers/livetvstatus.js b/src/controllers/livetvstatus.js
index d268be2991..c25487fd32 100644
--- a/src/controllers/livetvstatus.js
+++ b/src/controllers/livetvstatus.js
@@ -1,42 +1,81 @@
-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", "browser", "listViewStyle", "flexStyles", "emby-itemscontainer", "cardStyle", "material-icons", "emby-button"], function ($, globalize, taskButton, dom, libraryMenu, layoutManager, loading, browser) {
"use strict";
+ var enableFocusTransform = !browser.slow && !browser.edge;
+
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 += "
"
+ var padderClass;
+ var html = "";
+ var cssClass = "card scalableCard";
+ var cardBoxCssClass = "cardBox visualCardBox";
+ cssClass += " backdropCard backdropCard-scalable";
+ padderClass = "cardPadder-backdrop";
+
+ // TODO move card creation code to Card component
+
+ if (layoutManager.tv) {
+ cssClass += " show-focus";
+
+ if (enableFocusTransform) {
+ cssClass += " show-animation";
+ }
+ }
+
+ html += '
';
+ html += '
';
+ html += '
';
+ html += '
';
+ html += '
';
+ html += '
dvr
';
+ html += "
";
+ 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 +83,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 += '
dvr ', html += '
", html += '
more_horiz ', html += "
"
+ html += '
';
+ html += '
dvr ';
+ html += '
";
+ html += '
more_horiz ';
+ 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 +131,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 +206,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 +222,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 +236,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 +262,73 @@ define(["jQuery", "globalize", "scripts/taskbutton", "dom", "libraryMenu", "layo
items.push({
name: globalize.translate("ButtonDelete"),
id: "delete"
- }), items.push({
+ });
+ items.push({
name: globalize.translate("ButtonEdit"),
id: "edit"
- }), require(["actionsheet"], function(actionsheet) {
+ });
+
+ require(["actionsheet"], function (actionsheet) {
actionsheet.show({
items: items,
positionTo: button
- }).then(function(id) {
+ }).then(function (id) {
switch (id) {
case "delete":
deleteDevice(dom.parentWithClass(button, "page"), tunerDeviceId);
break;
+
case "edit":
- Dashboard.navigate("livetvtuner.html?id=" + tunerDeviceId)
+ Dashboard.navigate("livetvtuner.html?id=" + tunerDeviceId);
}
- })
- })
+ });
+ });
}
function onDevicesListClick(e) {
var card = dom.parentWithClass(e.target, "card");
+
if (card) {
- var id = card.getAttribute("data-id"),
- btnCardOptions = dom.parentWithClass(e.target, "btnCardOptions");
- btnCardOptions ? showDeviceMenu(btnCardOptions, id) : Dashboard.navigate("livetvtuner.html?id=" + id)
+ var id = card.getAttribute("data-id");
+ var btnCardOptions = dom.parentWithClass(e.target, "btnCardOptions");
+
+ if (btnCardOptions) {
+ showDeviceMenu(btnCardOptions, id);
+ } else {
+ Dashboard.navigate("livetvtuner.html?id=" + id);
+ }
}
}
- $(document).on("pageinit", "#liveTvStatusPage", function() {
+
+ $(document).on("pageinit", "#liveTvStatusPage", function () {
var page = this;
- $(".btnAddDevice", page).on("click", function() {
- addDevice(this)
- }), $(".formAddDevice", page).on("submit", function() {
- return submitAddDeviceForm(page), !1
- }), $(".btnAddProvider", page).on("click", function() {
- addProvider(this)
- }), page.querySelector(".devicesList").addEventListener("click", onDevicesListClick)
- }).on("pageshow", "#liveTvStatusPage", function() {
+ $(".btnAddDevice", page).on("click", function () {
+ addDevice(this);
+ });
+ $(".formAddDevice", page).on("submit", function () {
+ submitAddDeviceForm(page);
+ return false;
+ });
+ $(".btnAddProvider", page).on("click", function () {
+ addProvider(this);
+ });
+ page.querySelector(".devicesList").addEventListener("click", onDevicesListClick);
+ }).on("pageshow", "#liveTvStatusPage", function () {
var page = this;
- reload(page), taskButton({
+ reload(page);
+ taskButton({
mode: "on",
progressElem: page.querySelector(".refreshGuideProgress"),
taskKey: "RefreshGuide",
button: page.querySelector(".btnRefresh")
- })
- }).on("pagehide", "#liveTvStatusPage", function() {
+ });
+ }).on("pagehide", "#liveTvStatusPage", function () {
var page = this;
taskButton({
mode: "off",
progressElem: page.querySelector(".refreshGuideProgress"),
taskKey: "RefreshGuide",
button: page.querySelector(".btnRefresh")
- })
- })
+ });
+ });
});
diff --git a/src/controllers/livetvtuner.js b/src/controllers/livetvtuner.js
index 43082e6844..55a86d4be7 100644
--- a/src/controllers/livetvtuner.js
+++ b/src/controllers/livetvtuner.js
@@ -1,4 +1,4 @@
-define(["globalize", "loading", "libraryMenu", "dom", "emby-input", "emby-button", "emby-checkbox", "emby-select"], function(globalize, loading, libraryMenu, dom) {
+define(["globalize", "loading", "libraryMenu", "dom", "emby-input", "emby-button", "emby-checkbox", "emby-select"], function (globalize, loading, libraryMenu, dom) {
"use strict";
function isM3uVariant(type) {
@@ -6,17 +6,16 @@ define(["globalize", "loading", "libraryMenu", "dom", "emby-input", "emby-button
}
function fillTypes(view, currentId) {
- return ApiClient.getJSON(ApiClient.getUrl("LiveTv/TunerHosts/Types")).then(function(types) {
+ return ApiClient.getJSON(ApiClient.getUrl("LiveTv/TunerHosts/Types")).then(function (types) {
var selectType = view.querySelector(".selectType");
var html = "";
- html += types.map(function(tuner) {
+ html += types.map(function (tuner) {
return '
' + tuner.Name + " ";
}).join("");
html += '
';
html += globalize.translate("TabOther");
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/loginpage.js b/src/controllers/loginpage.js
index 8344dde9cd..ef54d20bf7 100644
--- a/src/controllers/loginpage.js
+++ b/src/controllers/loginpage.js
@@ -1,6 +1,8 @@
-define(["apphost", "appSettings", "dom", "connectionManager", "loading", "cardStyle", "emby-checkbox"], function(appHost, appSettings, dom, connectionManager, loading) {
+define(["apphost", "appSettings", "dom", "connectionManager", "loading", "layoutManager", "browser", "cardStyle", "emby-checkbox"], function(appHost, appSettings, dom, connectionManager, loading, layoutManager, browser) {
"use strict";
+ var enableFocusTransform = !browser.slow && !browser.edge;
+
function authenticateUserByName(page, apiClient, username, password) {
loading.show();
apiClient.authenticateUserByName(username, password).then(function(result) {
@@ -60,7 +62,23 @@ define(["apphost", "appSettings", "dom", "connectionManager", "loading", "cardSt
var html = "";
for (var i = 0; i < users.length; i++) {
var user = users[i];
- html += '
';
+
+ // TODO move card creation code to Card component
+
+ var cssClass = "card squareCard scalableCard squareCard-scalable";
+
+ if (layoutManager.tv) {
+ cssClass += " show-focus";
+
+ if (enableFocusTransform) {
+ cssClass += " show-animation";
+ }
+ }
+
+ var cardBoxCssClass = "cardBox cardBox-bottompadded";
+
+ html += '
';
+ html += '';
html += '
';
html += '
';
html += '
';
diff --git a/src/controllers/metadatanfo.js b/src/controllers/metadatanfo.js
index 1de17ae836..20049837dd 100644
--- a/src/controllers/metadatanfo.js
+++ b/src/controllers/metadatanfo.js
@@ -1,30 +1,45 @@
-define(["jQuery", "loading", "libraryMenu"], function($, loading, libraryMenu) {
+define(["jQuery", "loading", "libraryMenu"], function ($, loading, libraryMenu) {
"use strict";
function loadPage(page, config, users) {
var html = '
' + Globalize.translate("OptionNone") + " ";
- html += users.map(function(user) {
- return '
' + user.Name + " "
- }).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 '
' + user.Name + " ";
+ }).join("");
+ $("#selectUser", page).html(html).val(config.UserId || "");
+ $("#selectReleaseDateFormat", page).val(config.ReleaseDateFormat);
+ page.querySelector("#chkSaveImagePaths").checked = config.SaveImagePathsInNfo;
+ page.querySelector("#chkEnablePathSubstitution").checked = config.EnablePathSubstitution;
+ page.querySelector("#chkEnableExtraThumbs").checked = config.EnableExtraThumbsDuplication;
+ loading.hide();
}
function onSubmit() {
loading.show();
var form = this;
- return ApiClient.getNamedConfiguration(metadataKey).then(function(config) {
- config.UserId = $("#selectUser", form).val() || null, config.ReleaseDateFormat = $("#selectReleaseDateFormat", form).val(), config.SaveImagePathsInNfo = form.querySelector("#chkSaveImagePaths").checked, config.EnablePathSubstitution = form.querySelector("#chkEnablePathSubstitution").checked, config.EnableExtraThumbsDuplication = form.querySelector("#chkEnableExtraThumbs").checked, ApiClient.updateNamedConfiguration(metadataKey, config).then(function() {
- Dashboard.processServerConfigurationUpdateResult(), showConfirmMessage(config)
- })
- }), !1
+ ApiClient.getNamedConfiguration(metadataKey).then(function (config) {
+ config.UserId = $("#selectUser", form).val() || null;
+ config.ReleaseDateFormat = $("#selectReleaseDateFormat", form).val();
+ config.SaveImagePathsInNfo = form.querySelector("#chkSaveImagePaths").checked;
+ config.EnablePathSubstitution = form.querySelector("#chkEnablePathSubstitution").checked;
+ config.EnableExtraThumbsDuplication = form.querySelector("#chkEnableExtraThumbs").checked;
+ ApiClient.updateNamedConfiguration(metadataKey, config).then(function () {
+ Dashboard.processServerConfigurationUpdateResult();
+ showConfirmMessage(config);
+ });
+ });
+ return false;
}
function showConfirmMessage(config) {
var msg = [];
- msg.push(Globalize.translate("MetadataSettingChangeHelp")), require(["alert"], function(alert) {
+ msg.push(Globalize.translate("MetadataSettingChangeHelp"));
+
+ require(["alert"], function (alert) {
alert({
text: msg.join("
")
- })
- })
+ });
+ });
}
function getTabs() {
@@ -40,19 +55,20 @@ define(["jQuery", "loading", "libraryMenu"], function($, loading, libraryMenu) {
}, {
href: "metadatanfo.html",
name: Globalize.translate("TabNfoSettings")
- }]
+ }];
}
var metadataKey = "xbmcmetadata";
- $(document).on("pageinit", "#metadataNfoPage", function() {
- $(".metadataNfoForm").off("submit", onSubmit).on("submit", onSubmit)
- }).on("pageshow", "#metadataNfoPage", function() {
- libraryMenu.setTabs("metadata", 3, getTabs), loading.show();
- var page = this,
- promise1 = ApiClient.getUsers(),
- promise2 = ApiClient.getNamedConfiguration(metadataKey);
- Promise.all([promise1, promise2]).then(function(responses) {
- loadPage(page, responses[1], responses[0])
- })
- })
-});
\ No newline at end of file
+ $(document).on("pageinit", "#metadataNfoPage", function () {
+ $(".metadataNfoForm").off("submit", onSubmit).on("submit", onSubmit);
+ }).on("pageshow", "#metadataNfoPage", function () {
+ libraryMenu.setTabs("metadata", 3, getTabs);
+ loading.show();
+ var page = this;
+ var promise1 = ApiClient.getUsers();
+ var promise2 = ApiClient.getNamedConfiguration(metadataKey);
+ Promise.all([promise1, promise2]).then(function (responses) {
+ loadPage(page, responses[1], responses[0]);
+ });
+ });
+});
diff --git a/src/controllers/movies/moviecollections.js b/src/controllers/movies/moviecollections.js
index 1e83f11f3c..d5bd96d349 100644
--- a/src/controllers/movies/moviecollections.js
+++ b/src/controllers/movies/moviecollections.js
@@ -1,9 +1,11 @@
-define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function(loading, events, libraryBrowser, imageLoader, listView, cardBuilder, appHost) {
+define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder, appHost) {
"use strict";
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
function getPageData(context) {
- var key = getSavedQueryKey(context),
- pageData = data[key];
+ var key = getSavedQueryKey(context);
+ var pageData = data[key];
+
if (!pageData) {
pageData = data[key] = {
query: {
@@ -22,153 +24,223 @@ define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardB
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
}
+
return pageData;
}
function getQuery(context) {
- return getPageData(context).query
+ return getPageData(context).query;
}
function getSavedQueryKey(context) {
- return context.savedQueryKey || (context.savedQueryKey = libraryBrowser.getSavedQueryKey("moviecollections")), context.savedQueryKey
+ if (!context.savedQueryKey) {
+ context.savedQueryKey = libraryBrowser.getSavedQueryKey("moviecollections");
+ }
+
+ return context.savedQueryKey;
}
function onViewStyleChange() {
- var viewStyle = self.getCurrentViewStyle(),
- itemsContainer = tabContent.querySelector(".itemsContainer");
- "List" == viewStyle ? (itemsContainer.classList.add("vertical-list"), itemsContainer.classList.remove("vertical-wrap")) : (itemsContainer.classList.remove("vertical-list"), itemsContainer.classList.add("vertical-wrap")), itemsContainer.innerHTML = ""
+ var viewStyle = self.getCurrentViewStyle();
+ var itemsContainer = tabContent.querySelector(".itemsContainer");
+
+ if ("List" == viewStyle) {
+ itemsContainer.classList.add("vertical-list");
+ itemsContainer.classList.remove("vertical-wrap");
+ } else {
+ itemsContainer.classList.remove("vertical-list");
+ itemsContainer.classList.add("vertical-wrap");
+ }
+
+ itemsContainer.innerHTML = "";
}
function reloadItems(page) {
loading.show();
isLoading = true;
var query = getQuery(page);
- ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function(result) {
+ ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) {
function onNextPageClick() {
- if (isLoading) return;
- query.StartIndex += query.Limit, reloadItems(tabContent)
+ if (isLoading) {
+ return;
+ }
+
+ query.StartIndex += query.Limit;
+ reloadItems(tabContent);
}
function onPreviousPageClick() {
- if (isLoading) return;
- query.StartIndex -= query.Limit, reloadItems(tabContent)
+ if (isLoading) {
+ return;
+ }
+
+ query.StartIndex -= query.Limit;
+ reloadItems(tabContent);
}
+
window.scrollTo(0, 0);
- var html, pagingHtml = libraryBrowser.getQueryPagingHtml({
- startIndex: query.StartIndex,
- limit: query.Limit,
- totalRecordCount: result.TotalRecordCount,
- showLimit: !1,
- updatePageSizeSetting: !1,
- addLayoutButton: !1,
- sortButton: !1,
- filterButton: !1
- }),
- viewStyle = self.getCurrentViewStyle();
- html = "Thumb" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "backdrop",
- preferThumb: !0,
- context: "movies",
- overlayPlayButton: !0,
- centerText: !0,
- showTitle: !0
- }) : "ThumbCard" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "backdrop",
- preferThumb: !0,
- context: "movies",
- lazy: !0,
- cardLayout: !0,
- showTitle: !0
- }) : "Banner" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "banner",
- preferBanner: !0,
- context: "movies",
- lazy: !0
- }) : "List" == viewStyle ? listView.getListViewHtml({
- items: result.Items,
- context: "movies",
- sortBy: query.SortBy
- }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "auto",
- context: "movies",
- showTitle: !0,
- centerText: !1,
- cardLayout: !0
- }) : cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "auto",
- context: "movies",
- centerText: !0,
- overlayPlayButton: !0,
- showTitle: !0
+ var html;
+ var pagingHtml = libraryBrowser.getQueryPagingHtml({
+ startIndex: query.StartIndex,
+ limit: query.Limit,
+ totalRecordCount: result.TotalRecordCount,
+ showLimit: false,
+ updatePageSizeSetting: false,
+ addLayoutButton: false,
+ sortButton: false,
+ filterButton: false
});
- var i, length, elems = tabContent.querySelectorAll(".paging");
- for (i = 0, length = elems.length; i < length; i++) elems[i].innerHTML = pagingHtml;
- for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick);
- for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick);
- result.Items.length || (html = '
' + Globalize.translate("MessageNoCollectionsAvailable") + "
");
+ var viewStyle = self.getCurrentViewStyle();
+ if (viewStyle == "Thumb") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "backdrop",
+ preferThumb: true,
+ context: "movies",
+ overlayPlayButton: true,
+ centerText: true,
+ showTitle: true
+ });
+ } else if (viewStyle == "ThumbCard") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "backdrop",
+ preferThumb: true,
+ context: "movies",
+ lazy: true,
+ cardLayout: true,
+ showTitle: true
+ });
+ } else if (viewStyle == "Banner") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "banner",
+ preferBanner: true,
+ context: "movies",
+ lazy: true
+ });
+ } else if (viewStyle == "List") {
+ html = listView.getListViewHtml({
+ items: result.Items,
+ context: "movies",
+ sortBy: query.SortBy
+ });
+ } else if (viewStyle == "PosterCard") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "auto",
+ context: "movies",
+ showTitle: true,
+ centerText: false,
+ cardLayout: true
+ });
+ } else {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "auto",
+ context: "movies",
+ centerText: true,
+ overlayPlayButton: true,
+ showTitle: true
+ });
+ }
+ var i;
+ var length;
+ var elems = tabContent.querySelectorAll(".paging");
+
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].innerHTML = pagingHtml;
+ }
+
+ elems = tabContent.querySelectorAll(".btnNextPage");
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onNextPageClick);
+ }
+
+ elems = tabContent.querySelectorAll(".btnPreviousPage");
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onPreviousPageClick);
+ }
+
+ if (!result.Items.length) {
+ html = '
' + Globalize.translate("MessageNoCollectionsAvailable") + "
";
+ }
+
var itemsContainer = tabContent.querySelector(".itemsContainer");
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
loading.hide();
isLoading = false;
- })
+ });
}
- var self = this,
- pageSize = 100,
- data = {},
- isLoading = false;
- self.getCurrentViewStyle = function() {
- return getPageData(tabContent).view
- },
- function(tabContent) {
- tabContent.querySelector(".btnSort").addEventListener("click", function(e) {
- libraryBrowser.showSortMenu({
- items: [{
- name: Globalize.translate("OptionNameSort"),
- id: "SortName"
- }, {
- name: Globalize.translate("OptionImdbRating"),
- id: "CommunityRating,SortName"
- }, {
- name: Globalize.translate("OptionDateAdded"),
- id: "DateCreated,SortName"
- }, {
- name: Globalize.translate("OptionParentalRating"),
- id: "OfficialRating,SortName"
- }, {
- name: Globalize.translate("OptionReleaseDate"),
- id: "PremiereDate,SortName"
- }],
- callback: function() {
- getQuery(tabContent).StartIndex = 0, reloadItems(tabContent)
- },
- query: getQuery(tabContent),
- button: e.target
- })
+
+ var self = this;
+ var pageSize = 100;
+ var data = {};
+ var isLoading = false;
+
+ self.getCurrentViewStyle = function () {
+ return getPageData(tabContent).view;
+ };
+
+ function initPage(tabContent) {
+ tabContent.querySelector(".btnSort").addEventListener("click", function (e) {
+ libraryBrowser.showSortMenu({
+ items: [{
+ name: Globalize.translate("OptionNameSort"),
+ id: "SortName"
+ }, {
+ name: Globalize.translate("OptionImdbRating"),
+ id: "CommunityRating,SortName"
+ }, {
+ name: Globalize.translate("OptionDateAdded"),
+ id: "DateCreated,SortName"
+ }, {
+ name: Globalize.translate("OptionParentalRating"),
+ id: "OfficialRating,SortName"
+ }, {
+ name: Globalize.translate("OptionReleaseDate"),
+ id: "PremiereDate,SortName"
+ }],
+ callback: function () {
+ getQuery(tabContent).StartIndex = 0;
+ reloadItems(tabContent);
+ },
+ query: getQuery(tabContent),
+ button: e.target
});
- var btnSelectView = tabContent.querySelector(".btnSelectView");
- btnSelectView.addEventListener("click", function(e) {
- libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard,Thumb,ThumbCard".split(","))
- }), btnSelectView.addEventListener("layoutchange", function(e) {
- var viewStyle = e.detail.viewStyle;
- getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), getQuery(tabContent).StartIndex = 0, onViewStyleChange(), reloadItems(tabContent)
- }), tabContent.querySelector(".btnNewCollection").addEventListener("click", function() {
- require(["collectionEditor"], function(collectionEditor) {
- var serverId = ApiClient.serverInfo().Id;
- (new collectionEditor).show({
- items: [],
- serverId: serverId
- })
- })
- })
- }(tabContent), onViewStyleChange(), self.renderTab = function() {
- reloadItems(tabContent)
- }, self.destroy = function() {}
- }
+ });
+ var btnSelectView = tabContent.querySelector(".btnSelectView");
+ btnSelectView.addEventListener("click", function (e) {
+ libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard,Thumb,ThumbCard".split(","));
+ });
+ btnSelectView.addEventListener("layoutchange", function (e) {
+ var viewStyle = e.detail.viewStyle;
+ getPageData(tabContent).view = viewStyle;
+ libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle);
+ getQuery(tabContent).StartIndex = 0;
+ onViewStyleChange();
+ reloadItems(tabContent);
+ });
+ tabContent.querySelector(".btnNewCollection").addEventListener("click", function () {
+ require(["collectionEditor"], function (collectionEditor) {
+ var serverId = ApiClient.serverInfo().Id;
+ new collectionEditor().show({
+ items: [],
+ serverId: serverId
+ });
+ });
+ });
+ }
+
+ initPage(tabContent);
+ onViewStyleChange();
+
+ self.renderTab = function () {
+ reloadItems(tabContent);
+ };
+
+ self.destroy = function () {};
+ };
});
diff --git a/src/controllers/movies/moviegenres.js b/src/controllers/movies/moviegenres.js
index 78fd601fd7..80197b01cc 100644
--- a/src/controllers/movies/moviegenres.js
+++ b/src/controllers/movies/moviegenres.js
@@ -1,139 +1,204 @@
-define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader", "apphost", "globalize", "appRouter", "dom", "emby-button"], function(layoutManager, loading, libraryBrowser, cardBuilder, lazyLoader, appHost, globalize, appRouter, dom) {
+define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader", "apphost", "globalize", "appRouter", "dom", "emby-button"], function (layoutManager, loading, libraryBrowser, cardBuilder, lazyLoader, appHost, globalize, appRouter, dom) {
"use strict";
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
function getPageData() {
- var key = getSavedQueryKey(),
- pageData = data[key];
- return pageData || (pageData = data[key] = {
- query: {
- SortBy: "SortName",
- SortOrder: "Ascending",
- IncludeItemTypes: "Movie",
- Recursive: !0,
- EnableTotalRecordCount: !1
- },
- view: "Poster"
- }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData
+ var key = getSavedQueryKey();
+ var pageData = data[key];
+
+ if (!pageData) {
+ pageData = data[key] = {
+ query: {
+ SortBy: "SortName",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "Movie",
+ Recursive: true,
+ EnableTotalRecordCount: false
+ },
+ view: "Poster"
+ };
+ pageData.query.ParentId = params.topParentId;
+ libraryBrowser.loadSavedQueryValues(key, pageData.query);
+ }
+
+ return pageData;
}
function getQuery() {
- return getPageData().query
+ return getPageData().query;
}
function getSavedQueryKey() {
- return libraryBrowser.getSavedQueryKey("moviegenres")
+ return libraryBrowser.getSavedQueryKey("moviegenres");
}
function getPromise() {
loading.show();
var query = getQuery();
- return ApiClient.getGenres(ApiClient.getCurrentUserId(), query)
+ return ApiClient.getGenres(ApiClient.getCurrentUserId(), query);
}
function enableScrollX() {
- return !layoutManager.desktop
+ return !layoutManager.desktop;
}
function getThumbShape() {
- return enableScrollX() ? "overflowBackdrop" : "backdrop"
+ return enableScrollX() ? "overflowBackdrop" : "backdrop";
}
function getPortraitShape() {
- return enableScrollX() ? "overflowPortrait" : "portrait"
+ return enableScrollX() ? "overflowPortrait" : "portrait";
}
function fillItemsContainer(elem) {
- var id = elem.getAttribute("data-id"),
- viewStyle = self.getCurrentViewStyle(),
- limit = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? 5 : 9;
- enableScrollX() && (limit = 10);
- var enableImageTypes = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? "Primary,Backdrop,Thumb" : "Primary",
- query = {
- SortBy: "SortName",
- SortOrder: "Ascending",
- IncludeItemTypes: "Movie",
- Recursive: !0,
- Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo",
- ImageTypeLimit: 1,
- EnableImageTypes: enableImageTypes,
- Limit: limit,
- GenreIds: id,
- EnableTotalRecordCount: !1,
- ParentId: params.topParentId
- };
- ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function(result) {
+ var id = elem.getAttribute("data-id");
+ var viewStyle = self.getCurrentViewStyle();
+ var limit = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? 5 : 9;
+
+ if (enableScrollX()) {
+ limit = 10;
+ }
+
+ var enableImageTypes = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? "Primary,Backdrop,Thumb" : "Primary";
+ var query = {
+ SortBy: "SortName",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "Movie",
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo",
+ ImageTypeLimit: 1,
+ EnableImageTypes: enableImageTypes,
+ Limit: limit,
+ GenreIds: id,
+ EnableTotalRecordCount: false,
+ ParentId: params.topParentId
+ };
+ ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) {
var supportsImageAnalysis = appHost.supports("imageanalysis");
- "Thumb" == viewStyle ? cardBuilder.buildCards(result.Items, {
- itemsContainer: elem,
- shape: getThumbShape(),
- preferThumb: !0,
- showTitle: !0,
- scalable: !0,
- centerText: !0,
- overlayMoreButton: !0,
- allowBottomPadding: !1
- }) : "ThumbCard" == viewStyle ? cardBuilder.buildCards(result.Items, {
- itemsContainer: elem,
- shape: getThumbShape(),
- preferThumb: !0,
- showTitle: !0,
- scalable: !0,
- centerText: !1,
- cardLayout: !0,
- showYear: !0
- }) : "PosterCard" == viewStyle ? cardBuilder.buildCards(result.Items, {
- itemsContainer: elem,
- shape: getPortraitShape(),
- showTitle: !0,
- scalable: !0,
- centerText: !1,
- cardLayout: !0,
- showYear: !0
- }) : "Poster" == viewStyle && cardBuilder.buildCards(result.Items, {
- itemsContainer: elem,
- shape: getPortraitShape(),
- scalable: !0,
- overlayMoreButton: !0,
- allowBottomPadding: !1
- }), result.Items.length >= query.Limit && tabContent.querySelector(".btnMoreFromGenre" + id + " i").classList.remove("hide")
- })
+
+ if (viewStyle == "Thumb") {
+ cardBuilder.buildCards(result.Items, {
+ itemsContainer: elem,
+ shape: getThumbShape(),
+ preferThumb: true,
+ showTitle: true,
+ scalable: true,
+ centerText: true,
+ overlayMoreButton: true,
+ allowBottomPadding: false
+ });
+ } else if (viewStyle == "ThumbCard") {
+ cardBuilder.buildCards(result.Items, {
+ itemsContainer: elem,
+ shape: getThumbShape(),
+ preferThumb: true,
+ showTitle: true,
+ scalable: true,
+ centerText: false,
+ cardLayout: true,
+ showYear: true
+ });
+ } else if (viewStyle == "PosterCard") {
+ cardBuilder.buildCards(result.Items, {
+ itemsContainer: elem,
+ shape: getPortraitShape(),
+ showTitle: true,
+ scalable: true,
+ centerText: false,
+ cardLayout: true,
+ showYear: true
+ });
+ } else if (viewStyle == "Poster") {
+ cardBuilder.buildCards(result.Items, {
+ itemsContainer: elem,
+ shape: getPortraitShape(),
+ scalable: true,
+ overlayMoreButton: true,
+ allowBottomPadding: false
+ });
+ }
+ if (result.Items.length >= query.Limit) {
+ tabContent.querySelector(".btnMoreFromGenre" + id + " i").classList.remove("hide");
+ }
+ });
}
function reloadItems(context, promise) {
var query = getQuery();
- promise.then(function(result) {
- for (var elem = context.querySelector("#items"), html = "", items = result.Items, i = 0, length = items.length; i < length; i++) {
+ promise.then(function (result) {
+ var elem = context.querySelector("#items");
+ var html = "";
+ var items = result.Items;
+
+ for (var i = 0, length = items.length; i < length; i++) {
var item = items[i];
- if (html += '
', html += '
", enableScrollX()) {
+
+ html += '
';
+ html += '
";
+ if (enableScrollX()) {
var scrollXClass = "scrollX hiddenScrollX";
- layoutManager.tv && (scrollXClass += " smoothScrollX"), html += '
"
+
+ if (layoutManager.tv) {
+ scrollXClass += "smoothScrollX";
+ }
+
+ html += '
";
}
- elem.innerHTML = html, lazyLoader.lazyChildren(elem, fillItemsContainer), libraryBrowser.saveQueryValues(getSavedQueryKey(), query), loading.hide()
- })
+
+ elem.innerHTML = html;
+ lazyLoader.lazyChildren(elem, fillItemsContainer);
+ libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
+ loading.hide();
+ });
}
function fullyReload() {
- self.preRender(), self.renderTab()
+ self.preRender();
+ self.renderTab();
}
- var self = this,
- data = {};
- self.getViewStyles = function() {
- return "Poster,PosterCard,Thumb,ThumbCard".split(",")
- }, self.getCurrentViewStyle = function() {
- return getPageData(tabContent).view
- }, self.setCurrentViewStyle = function(viewStyle) {
- getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), fullyReload()
- }, self.enableViewSelection = !0;
+
+ var self = this;
+ var data = {};
+
+ self.getViewStyles = function () {
+ return "Poster,PosterCard,Thumb,ThumbCard".split(",");
+ };
+
+ self.getCurrentViewStyle = function () {
+ return getPageData(tabContent).view;
+ };
+
+ self.setCurrentViewStyle = function (viewStyle) {
+ getPageData(tabContent).view = viewStyle;
+ libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle);
+ fullyReload();
+ };
+
+ self.enableViewSelection = true;
var promise;
- self.preRender = function() {
- promise = getPromise()
- }, self.renderTab = function() {
- reloadItems(tabContent, promise)
- }
- }
-});
\ No newline at end of file
+
+ self.preRender = function () {
+ promise = getPromise();
+ };
+
+ self.renderTab = function () {
+ reloadItems(tabContent, promise);
+ };
+ };
+});
diff --git a/src/controllers/movies/movies.js b/src/controllers/movies/movies.js
index e0a5947ca6..b4e30602fd 100644
--- a/src/controllers/movies/movies.js
+++ b/src/controllers/movies/movies.js
@@ -1,7 +1,7 @@
-define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser", "alphaPicker", "listView", "cardBuilder", "emby-itemscontainer"],
- function(loading, layoutManager, userSettings, events, libraryBrowser, alphaPicker, listView, cardBuilder) {
+define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser", "alphaPicker", "listView", "cardBuilder", "emby-itemscontainer"], function (loading, layoutManager, userSettings, events, libraryBrowser, alphaPicker, listView, cardBuilder) {
"use strict";
- return function(view, params, tabContent, options) {
+
+ return function (view, params, tabContent, options) {
function onViewStyleChange() {
if (self.getCurrentViewStyle() == "List") {
itemsContainer.classList.add("vertical-list");
@@ -10,103 +10,141 @@ define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser",
itemsContainer.classList.remove("vertical-list");
itemsContainer.classList.add("vertical-wrap");
}
+
itemsContainer.innerHTML = "";
}
function updateFilterControls() {
- self.alphaPicker && self.alphaPicker.value(query.NameStartsWithOrGreater)
+ if (self.alphaPicker) {
+ self.alphaPicker.value(query.NameStartsWithOrGreater);
+ }
}
function fetchData() {
isLoading = true;
loading.show();
- return ApiClient.getItems(ApiClient.getCurrentUserId(), query)
+ return ApiClient.getItems(ApiClient.getCurrentUserId(), query);
}
function afterRefresh(result) {
function onNextPageClick() {
- if (isLoading) return;
+ if (isLoading) {
+ return;
+ }
+
query.StartIndex += query.Limit;
itemsContainer.refreshItems();
}
function onPreviousPageClick() {
- if (isLoading) return;
+ if (isLoading) {
+ return;
+ }
+
query.StartIndex -= query.Limit;
itemsContainer.refreshItems();
}
+
window.scrollTo(0, 0);
updateFilterControls();
- var i, length, elems, pagingHtml = libraryBrowser.getQueryPagingHtml({
- startIndex: query.StartIndex,
- limit: query.Limit,
- totalRecordCount: result.TotalRecordCount,
- showLimit: !1,
- updatePageSizeSetting: !1,
- addLayoutButton: !1,
- sortButton: !1,
- filterButton: !1
- });
- for (elems = tabContent.querySelectorAll(".paging"), i = 0, length = elems.length; i < length; i++)
+ var pagingHtml = libraryBrowser.getQueryPagingHtml({
+ startIndex: query.StartIndex,
+ limit: query.Limit,
+ totalRecordCount: result.TotalRecordCount,
+ showLimit: false,
+ updatePageSizeSetting: false,
+ addLayoutButton: false,
+ sortButton: false,
+ filterButton: false
+ });
+ var i;
+ var length;
+ var elems = tabContent.querySelectorAll(".paging");
+
+ for (i = 0, length = elems.length; i < length; i++) {
elems[i].innerHTML = pagingHtml;
- for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++)
+ }
+
+ elems = tabContent.querySelectorAll(".btnNextPage");
+ for (i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener("click", onNextPageClick);
- for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++)
- elems[i].addEventListener("click", onPreviousPageClick)
+ }
+
+ elems = tabContent.querySelectorAll(".btnPreviousPage");
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onPreviousPageClick);
+ }
+
isLoading = false;
loading.hide();
}
function getItemsHtml(items) {
+ var html;
var viewStyle = self.getCurrentViewStyle();
- return "Thumb" == viewStyle ? cardBuilder.getCardsHtml({
- items: items,
- shape: "backdrop",
- preferThumb: !0,
- context: "movies",
- lazy: !0,
- overlayPlayButton: !0,
- showTitle: !0,
- showYear: !0,
- centerText: !0
- }) : "ThumbCard" == viewStyle ? cardBuilder.getCardsHtml({
- items: items,
- shape: "backdrop",
- preferThumb: !0,
- context: "movies",
- lazy: !0,
- cardLayout: !0,
- showTitle: !0,
- showYear: !0,
- centerText: !0
- }) : "Banner" == viewStyle ? cardBuilder.getCardsHtml({
- items: items,
- shape: "banner",
- preferBanner: !0,
- context: "movies",
- lazy: !0
- }) : "List" == viewStyle ? listView.getListViewHtml({
- items: items,
- context: "movies",
- sortBy: query.SortBy
- }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({
- items: items,
- shape: "portrait",
- context: "movies",
- showTitle: !0,
- showYear: !0,
- centerText: !0,
- lazy: !0,
- cardLayout: !0
- }) : cardBuilder.getCardsHtml({
- items: items,
- shape: "portrait",
- context: "movies",
- overlayPlayButton: !0,
- showTitle: !0,
- showYear: !0,
- centerText: !0
- })
+
+ if (viewStyle == "Thumb") {
+ html = cardBuilder.getCardsHtml({
+ items: items,
+ shape: "backdrop",
+ preferThumb: true,
+ context: "movies",
+ lazy: true,
+ overlayPlayButton: true,
+ showTitle: true,
+ showYear: true,
+ centerText: true
+ });
+ } else if (viewStyle == "ThumbCard") {
+ html = cardBuilder.getCardsHtml({
+ items: items,
+ shape: "backdrop",
+ preferThumb: true,
+ context: "movies",
+ lazy: true,
+ cardLayout: true,
+ showTitle: true,
+ showYear: true,
+ centerText: true
+ });
+ } else if (viewStyle == "Banner") {
+ html = cardBuilder.getCardsHtml({
+ items: items,
+ shape: "banner",
+ preferBanner: true,
+ context: "movies",
+ lazy: true
+ });
+ } else if (viewStyle == "List") {
+ html = listView.getListViewHtml({
+ items: items,
+ context: "movies",
+ sortBy: query.SortBy
+ });
+ } else if (viewStyle == "PosterCard") {
+ html = cardBuilder.getCardsHtml({
+ items: items,
+ shape: "portrait",
+ context: "movies",
+ showTitle: true,
+ showYear: true,
+ centerText: true,
+ lazy: true,
+ cardLayout: true
+ });
+ } else {
+ html = cardBuilder.getCardsHtml({
+ items: items,
+ shape: "portrait",
+ context: "movies",
+ overlayPlayButton: true,
+ showTitle: true,
+ showYear: true,
+ centerText: true
+ });
+ }
+
+ return html;
}
function initPage(tabContent) {
@@ -114,8 +152,9 @@ define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser",
itemsContainer.getItemsHtml = getItemsHtml;
itemsContainer.afterRefresh = afterRefresh;
var alphaPickerElement = tabContent.querySelector(".alphaPicker");
+
if (alphaPickerElement) {
- alphaPickerElement.addEventListener("alphavaluechanged", function(e) {
+ alphaPickerElement.addEventListener("alphavaluechanged", function (e) {
var newValue = e.detail.value;
query.NameStartsWithOrGreater = newValue;
query.StartIndex = 0;
@@ -125,109 +164,132 @@ define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser",
element: alphaPickerElement,
valueChangeEvent: "click"
});
+
if (layoutManager.desktop || layoutManager.mobile) {
alphaPickerElement.classList.add("alphabetPicker-right");
itemsContainer.classList.remove("padded-left-withalphapicker");
itemsContainer.classList.add("padded-right-withalphapicker");
}
}
+
var btnFilter = tabContent.querySelector(".btnFilter");
- btnFilter && btnFilter.addEventListener("click", function() {
- self.showFilterMenu()
- });
+
+ if (btnFilter) {
+ btnFilter.addEventListener("click", function () {
+ self.showFilterMenu();
+ });
+ }
var btnSort = tabContent.querySelector(".btnSort");
- btnSort && btnSort.addEventListener("click", function(e) {
- libraryBrowser.showSortMenu({
- items: [{
- name: Globalize.translate("OptionNameSort"),
- id: "SortName,ProductionYear"
- }, {
- name: Globalize.translate("OptionImdbRating"),
- id: "CommunityRating,SortName,ProductionYear"
- }, {
- name: Globalize.translate("OptionCriticRating"),
- id: "CriticRating,SortName,ProductionYear"
- }, {
- name: Globalize.translate("OptionDateAdded"),
- id: "DateCreated,SortName,ProductionYear"
- }, {
- name: Globalize.translate("OptionDatePlayed"),
- id: "DatePlayed,SortName,ProductionYear"
- }, {
- name: Globalize.translate("OptionParentalRating"),
- id: "OfficialRating,SortName,ProductionYear"
- }, {
- name: Globalize.translate("OptionPlayCount"),
- id: "PlayCount,SortName,ProductionYear"
- }, {
- name: Globalize.translate("OptionReleaseDate"),
- id: "PremiereDate,SortName,ProductionYear"
- }, {
- name: Globalize.translate("OptionRuntime"),
- id: "Runtime,SortName,ProductionYear"
- }],
- callback: function() {
- query.StartIndex = 0, userSettings.saveQuerySettings(savedQueryKey, query), itemsContainer.refreshItems()
- },
- query: query,
- button: e.target
- })
- });
+
+ if (btnSort) {
+ btnSort.addEventListener("click", function (e) {
+ libraryBrowser.showSortMenu({
+ items: [{
+ name: Globalize.translate("OptionNameSort"),
+ id: "SortName,ProductionYear"
+ }, {
+ name: Globalize.translate("OptionImdbRating"),
+ id: "CommunityRating,SortName,ProductionYear"
+ }, {
+ name: Globalize.translate("OptionCriticRating"),
+ id: "CriticRating,SortName,ProductionYear"
+ }, {
+ name: Globalize.translate("OptionDateAdded"),
+ id: "DateCreated,SortName,ProductionYear"
+ }, {
+ name: Globalize.translate("OptionDatePlayed"),
+ id: "DatePlayed,SortName,ProductionYear"
+ }, {
+ name: Globalize.translate("OptionParentalRating"),
+ id: "OfficialRating,SortName,ProductionYear"
+ }, {
+ name: Globalize.translate("OptionPlayCount"),
+ id: "PlayCount,SortName,ProductionYear"
+ }, {
+ name: Globalize.translate("OptionReleaseDate"),
+ id: "PremiereDate,SortName,ProductionYear"
+ }, {
+ name: Globalize.translate("OptionRuntime"),
+ id: "Runtime,SortName,ProductionYear"
+ }],
+ callback: function () {
+ query.StartIndex = 0;
+ userSettings.saveQuerySettings(savedQueryKey, query);
+ itemsContainer.refreshItems();
+ },
+ query: query,
+ button: e.target
+ });
+ });
+ }
var btnSelectView = tabContent.querySelector(".btnSelectView");
- btnSelectView.addEventListener("click", function(e) {
- libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "Banner,List,Poster,PosterCard,Thumb,ThumbCard".split(","))
- }), btnSelectView.addEventListener("layoutchange", function(e) {
+ btnSelectView.addEventListener("click", function (e) {
+ libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "Banner,List,Poster,PosterCard,Thumb,ThumbCard".split(","));
+ });
+ btnSelectView.addEventListener("layoutchange", function (e) {
var viewStyle = e.detail.viewStyle;
userSettings.set(savedViewKey, viewStyle);
query.StartIndex = 0;
onViewStyleChange();
itemsContainer.refreshItems();
- })
+ });
}
- var self = this,
- itemsContainer = tabContent.querySelector(".itemsContainer"),
- savedQueryKey = params.topParentId + "-" + options.mode,
- savedViewKey = savedQueryKey + "-view",
- query = {
- SortBy: "SortName,ProductionYear",
- SortOrder: "Ascending",
- IncludeItemTypes: "Movie",
- Recursive: !0,
- Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo",
- ImageTypeLimit: 1,
- EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
- StartIndex: 0,
- Limit: 100,
- ParentId: params.topParentId
- },
- isLoading = false;
- if (options.mode === "favorites") query.IsFavorite = true;
+
+ var self = this;
+ var itemsContainer = tabContent.querySelector(".itemsContainer");
+ var savedQueryKey = params.topParentId + "-" + options.mode;
+ var savedViewKey = savedQueryKey + "-view";
+ var query = {
+ SortBy: "SortName,ProductionYear",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "Movie",
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo",
+ ImageTypeLimit: 1,
+ EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
+ StartIndex: 0,
+ Limit: 100,
+ ParentId: params.topParentId
+ };
+ var isLoading = false;
+
+ if (options.mode === "favorites") {
+ query.IsFavorite = true;
+ }
+
query = userSettings.loadQuerySettings(savedQueryKey, query);
- self.showFilterMenu = function() {
- require(["components/filterdialog/filterdialog"], function(filterDialogFactory) {
+
+ self.showFilterMenu = function () {
+ require(["components/filterdialog/filterdialog"], function (filterDialogFactory) {
var filterDialog = new filterDialogFactory({
query: query,
mode: "movies",
serverId: ApiClient.serverId()
});
- events.on(filterDialog, "filterchange", function() {
- query.StartIndex = 0, itemsContainer.refreshItems()
- }), filterDialog.show()
- })
+ events.on(filterDialog, "filterchange", function () {
+ query.StartIndex = 0;
+ itemsContainer.refreshItems();
+ });
+ filterDialog.show();
+ });
};
- self.getCurrentViewStyle = function() {
- return userSettings.get(savedViewKey) || "Poster"
+
+ self.getCurrentViewStyle = function () {
+ return userSettings.get(savedViewKey) || "Poster";
};
- self.initTab = function() {
+
+ self.initTab = function () {
initPage(tabContent);
onViewStyleChange();
};
- self.renderTab = function() {
+
+ self.renderTab = function () {
itemsContainer.refreshItems();
updateFilterControls();
};
- self.destroy = function() {
- itemsContainer = null
- }
- }
+
+ self.destroy = function () {
+ itemsContainer = null;
+ };
+ };
});
diff --git a/src/controllers/movies/moviesrecommended.js b/src/controllers/movies/moviesrecommended.js
index 2bab767735..82c0b6a12d 100644
--- a/src/controllers/movies/moviesrecommended.js
+++ b/src/controllers/movies/moviesrecommended.js
@@ -1,16 +1,16 @@
-define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu", "mainTabsManager", "cardBuilder", "dom", "imageLoader", "playbackManager", "emby-itemscontainer", "emby-tabs", "emby-button"], function(events, layoutManager, inputManager, userSettings, libraryMenu, mainTabsManager, cardBuilder, dom, imageLoader, playbackManager) {
+define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu", "mainTabsManager", "cardBuilder", "dom", "imageLoader", "playbackManager", "emby-itemscontainer", "emby-tabs", "emby-button"], function (events, layoutManager, inputManager, userSettings, libraryMenu, mainTabsManager, cardBuilder, dom, imageLoader, playbackManager) {
"use strict";
function enableScrollX() {
- return !layoutManager.desktop
+ return !layoutManager.desktop;
}
function getPortraitShape() {
- return enableScrollX() ? "overflowPortrait" : "portrait"
+ return enableScrollX() ? "overflowPortrait" : "portrait";
}
function getThumbShape() {
- return enableScrollX() ? "overflowBackdrop" : "backdrop"
+ return enableScrollX() ? "overflowBackdrop" : "backdrop";
}
function loadLatest(page, userId, parentId) {
@@ -21,118 +21,168 @@ define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu"
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
- EnableTotalRecordCount: !1
+ EnableTotalRecordCount: false
};
- ApiClient.getJSON(ApiClient.getUrl("Users/" + userId + "/Items/Latest", options)).then(function(items) {
- var allowBottomPadding = !enableScrollX(),
- container = page.querySelector("#recentlyAddedItems");
+ ApiClient.getJSON(ApiClient.getUrl("Users/" + userId + "/Items/Latest", options)).then(function (items) {
+ var allowBottomPadding = !enableScrollX();
+ var container = page.querySelector("#recentlyAddedItems");
cardBuilder.buildCards(items, {
itemsContainer: container,
shape: getPortraitShape(),
- scalable: !0,
- overlayPlayButton: !0,
+ scalable: true,
+ overlayPlayButton: true,
allowBottomPadding: allowBottomPadding,
- showTitle: !0,
- showYear: !0,
- centerText: !0
- })
- })
+ showTitle: true,
+ showYear: true,
+ centerText: true
+ });
+ });
}
function loadResume(page, userId, parentId) {
- var screenWidth = dom.getWindowSize().innerWidth,
- options = {
- SortBy: "DatePlayed",
- SortOrder: "Descending",
- IncludeItemTypes: "Movie",
- Filters: "IsResumable",
- Limit: screenWidth >= 1920 ? 5 : screenWidth >= 1600 ? 5 : 3,
- Recursive: !0,
- Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo",
- CollapseBoxSetItems: !1,
- ParentId: parentId,
- ImageTypeLimit: 1,
- EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
- EnableTotalRecordCount: !1
- };
- ApiClient.getItems(userId, options).then(function(result) {
- result.Items.length ? page.querySelector("#resumableSection").classList.remove("hide") : page.querySelector("#resumableSection").classList.add("hide");
- var allowBottomPadding = !enableScrollX(),
- container = page.querySelector("#resumableItems");
+ var screenWidth = dom.getWindowSize().innerWidth;
+ var options = {
+ SortBy: "DatePlayed",
+ SortOrder: "Descending",
+ IncludeItemTypes: "Movie",
+ Filters: "IsResumable",
+ Limit: screenWidth >= 1920 ? 5 : screenWidth >= 1600 ? 5 : 3,
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo",
+ CollapseBoxSetItems: false,
+ ParentId: parentId,
+ ImageTypeLimit: 1,
+ EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
+ EnableTotalRecordCount: false
+ };
+ ApiClient.getItems(userId, options).then(function (result) {
+ if (result.Items.length) {
+ page.querySelector("#resumableSection").classList.remove("hide");
+ } else {
+ page.querySelector("#resumableSection").classList.add("hide");
+ }
+
+ var allowBottomPadding = !enableScrollX();
+ var container = page.querySelector("#resumableItems");
cardBuilder.buildCards(result.Items, {
itemsContainer: container,
- preferThumb: !0,
+ preferThumb: true,
shape: getThumbShape(),
- scalable: !0,
- overlayPlayButton: !0,
+ scalable: true,
+ overlayPlayButton: true,
allowBottomPadding: allowBottomPadding,
- cardLayout: !1,
- showTitle: !0,
- showYear: !0,
- centerText: !0
- })
- })
+ cardLayout: false,
+ showTitle: true,
+ showYear: true,
+ centerText: true
+ });
+ });
}
function getRecommendationHtml(recommendation) {
- var html = "",
- title = "";
+ var html = "";
+ var title = "";
+
switch (recommendation.RecommendationType) {
case "SimilarToRecentlyPlayed":
title = Globalize.translate("RecommendationBecauseYouWatched").replace("{0}", recommendation.BaselineItemName);
break;
+
case "SimilarToLikedItem":
title = Globalize.translate("RecommendationBecauseYouLike").replace("{0}", recommendation.BaselineItemName);
break;
+
case "HasDirectorFromRecentlyPlayed":
case "HasLikedDirector":
title = Globalize.translate("RecommendationDirectedBy").replace("{0}", recommendation.BaselineItemName);
break;
+
case "HasActorFromRecentlyPlayed":
case "HasLikedActor":
- title = Globalize.translate("RecommendationStarring").replace("{0}", recommendation.BaselineItemName)
+ title = Globalize.translate("RecommendationStarring").replace("{0}", recommendation.BaselineItemName);
+ break;
}
- html += '
', html += '
' + title + " ";
- var allowBottomPadding = !0;
- return enableScrollX() ? (allowBottomPadding = !1, html += '
') : html += '
', html += cardBuilder.getCardsHtml(recommendation.Items, {
+
+ html += '
';
+ html += '
' + title + " ";
+ var allowBottomPadding = true;
+
+ if (enableScrollX()) {
+ allowBottomPadding = false;
+ html += '
"
+ });
+ html += "
";
+ html += "
";
+ return html;
}
function loadSuggestions(page, userId, parentId) {
- var screenWidth = dom.getWindowSize().innerWidth,
- url = ApiClient.getUrl("Movies/Recommendations", {
- userId: userId,
- categoryLimit: 6,
- ItemLimit: screenWidth >= 1920 ? 8 : screenWidth >= 1600 ? 8 : screenWidth >= 1200 ? 6 : 5,
- Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo",
- ImageTypeLimit: 1,
- EnableImageTypes: "Primary,Backdrop,Banner,Thumb"
- });
- ApiClient.getJSON(url).then(function(recommendations) {
- if (!recommendations.length) return page.querySelector(".noItemsMessage").classList.remove("hide"), void(page.querySelector(".recommendations").innerHTML = "");
+ var screenWidth = dom.getWindowSize().innerWidth;
+ var url = ApiClient.getUrl("Movies/Recommendations", {
+ userId: userId,
+ categoryLimit: 6,
+ ItemLimit: screenWidth >= 1920 ? 8 : screenWidth >= 1600 ? 8 : screenWidth >= 1200 ? 6 : 5,
+ Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo",
+ ImageTypeLimit: 1,
+ EnableImageTypes: "Primary,Backdrop,Banner,Thumb"
+ });
+ ApiClient.getJSON(url).then(function (recommendations) {
+ if (!recommendations.length) {
+ page.querySelector(".noItemsMessage").classList.remove("hide");
+ page.querySelector(".recommendations").innerHTML = "";
+ return;
+ }
+
var html = recommendations.map(getRecommendationHtml).join("");
page.querySelector(".noItemsMessage").classList.add("hide");
var recs = page.querySelector(".recommendations");
- recs.innerHTML = html, imageLoader.lazyChildren(recs)
- })
+ recs.innerHTML = html;
+ imageLoader.lazyChildren(recs);
+ });
}
function setScrollClasses(elem, scrollX) {
- scrollX ? (elem.classList.add("hiddenScrollX"), layoutManager.tv && elem.classList.add("smoothScrollX"), elem.classList.add("scrollX"), elem.classList.remove("vertical-wrap")) : (elem.classList.remove("hiddenScrollX"), elem.classList.remove("smoothScrollX"), elem.classList.remove("scrollX"), elem.classList.add("vertical-wrap"))
+ if (scrollX) {
+ elem.classList.add("hiddenScrollX");
+
+ if (layoutManager.tv) {
+ elem.classList.add("smoothScrollX");
+ }
+
+ elem.classList.add("scrollX");
+ elem.classList.remove("vertical-wrap");
+ } else {
+ elem.classList.remove("hiddenScrollX");
+ elem.classList.remove("smoothScrollX");
+ elem.classList.remove("scrollX");
+ elem.classList.add("vertical-wrap");
+ }
}
function initSuggestedTab(page, tabContent) {
- for (var containers = tabContent.querySelectorAll(".itemsContainer"), i = 0, length = containers.length; i < length; i++) setScrollClasses(containers[i], enableScrollX())
+ var containers = tabContent.querySelectorAll(".itemsContainer");
+
+ for (var i = 0, length = containers.length; i < length; i++) {
+ setScrollClasses(containers[i], enableScrollX());
+ }
}
function loadSuggestionsTab(view, params, tabContent) {
- var parentId = params.topParentId,
- userId = ApiClient.getCurrentUserId();
- console.log("loadSuggestionsTab"), loadResume(tabContent, userId, parentId), loadLatest(tabContent, userId, parentId), loadSuggestions(tabContent, userId, parentId)
+ var parentId = params.topParentId;
+ var userId = ApiClient.getCurrentUserId();
+ console.log("loadSuggestionsTab");
+ loadResume(tabContent, userId, parentId);
+ loadLatest(tabContent, userId, parentId);
+ loadSuggestions(tabContent, userId, parentId);
}
function getTabs() {
@@ -151,126 +201,196 @@ define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu"
}, {
name: Globalize.translate("ButtonSearch"),
cssClass: "searchTabButton"
- }]
+ }];
}
function getDefaultTabIndex(folderId) {
switch (userSettings.get("landing-" + folderId)) {
case "suggestions":
return 1;
+
case "favorites":
return 3;
+
case "collections":
return 4;
+
case "genres":
return 5;
+
default:
- return 0
+ return 0;
}
}
- return function(view, params) {
+
+ return function (view, params) {
function onBeforeTabChange(e) {
- preLoadTab(view, parseInt(e.detail.selectedTabIndex))
+ preLoadTab(view, parseInt(e.detail.selectedTabIndex));
}
function onTabChange(e) {
var newIndex = parseInt(e.detail.selectedTabIndex);
- loadTab(view, newIndex)
+ loadTab(view, newIndex);
}
function getTabContainers() {
- return view.querySelectorAll(".pageTabContent")
+ return view.querySelectorAll(".pageTabContent");
}
function initTabs() {
- mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange)
+ mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange);
}
function getTabController(page, index, callback) {
var depends = [];
+
switch (index) {
case 0:
depends.push("controllers/movies/movies");
break;
+
case 1:
break;
+
case 2:
depends.push("controllers/movies/movietrailers");
break;
+
case 3:
depends.push("controllers/movies/movies");
break;
+
case 4:
depends.push("controllers/movies/moviecollections");
break;
+
case 5:
depends.push("controllers/movies/moviegenres");
break;
+
case 6:
- depends.push("scripts/searchtab")
+ depends.push("scripts/searchtab");
}
- require(depends, function(controllerFactory) {
+
+ require(depends, function (controllerFactory) {
var tabContent;
- index === suggestionsTabIndex && (tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"), self.tabContent = tabContent);
+
+ if (index === suggestionsTabIndex) {
+ tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
+ self.tabContent = tabContent;
+ }
+
var controller = tabControllers[index];
- controller || (tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"), controller = index === suggestionsTabIndex ? self : 6 === index ? new controllerFactory(view, tabContent, {
- collectionType: "movies",
- parentId: params.topParentId
- }) : 0 === index || 3 === index ? new controllerFactory(view, params, tabContent, {
- mode: index ? "favorites" : "movies"
- }) : new controllerFactory(view, params, tabContent), tabControllers[index] = controller, controller.initTab && controller.initTab()), callback(controller)
- })
+
+ if (!controller) {
+ tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
+
+ if (index === suggestionsTabIndex) {
+ controller = self;
+ } else if (index === 6) {
+ controller = new controllerFactory(view, tabContent, {
+ collectionType: "movies",
+ parentId: params.topParentId
+ });
+ } else if (index == 0 || index == 3) {
+ controller = new controllerFactory(view, params, tabContent, {
+ mode: index ? "favorites" : "movies"
+ });
+ } else {
+ controller = new controllerFactory(view, params, tabContent);
+ }
+
+ tabControllers[index] = controller;
+
+ if (controller.initTab) {
+ controller.initTab();
+ }
+ }
+
+ callback(controller);
+ });
}
function preLoadTab(page, index) {
- getTabController(page, index, function(controller) {
- -1 == renderedTabs.indexOf(index) && controller.preRender && controller.preRender()
- })
+ getTabController(page, index, function (controller) {
+ if (renderedTabs.indexOf(index) == -1 && controller.preRender) {
+ controller.preRender();
+ }
+ });
}
function loadTab(page, index) {
- currentTabIndex = index, getTabController(page, index, function(controller) {
- initialTabIndex = null, -1 == renderedTabs.indexOf(index) && (renderedTabs.push(index), controller.renderTab())
- })
+ currentTabIndex = index;
+ getTabController(page, index, function (controller) {
+ initialTabIndex = null;
+
+ if (renderedTabs.indexOf(index) == -1) {
+ renderedTabs.push(index);
+ controller.renderTab();
+ }
+ });
}
function onPlaybackStop(e, state) {
- state.NowPlayingItem && "Video" == state.NowPlayingItem.MediaType && (renderedTabs = [], mainTabsManager.getTabsElement().triggerTabChange())
+ if (state.NowPlayingItem && state.NowPlayingItem.MediaType == "Video") {
+ renderedTabs = [];
+ mainTabsManager.getTabsElement().triggerTabChange();
+ }
}
function onInputCommand(e) {
switch (e.detail.command) {
case "search":
- e.preventDefault(), Dashboard.navigate("search.html?collectionType=movies&parentId=" + params.topParentId)
+ e.preventDefault();
+ Dashboard.navigate("search.html?collectionType=movies&parentId=" + params.topParentId);
}
}
- var isViewRestored, self = this,
- currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)),
- initialTabIndex = currentTabIndex,
- suggestionsTabIndex = 1;
- self.initTab = function() {
+
+ var isViewRestored;
+ var self = this;
+ var currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId));
+ var initialTabIndex = currentTabIndex;
+ var suggestionsTabIndex = 1;
+
+ self.initTab = function () {
var tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
initSuggestedTab(view, tabContent);
- }, self.renderTab = function() {
- var tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
- loadSuggestionsTab(view, params, tabContent)
};
- var tabControllers = [],
- renderedTabs = [];
- view.addEventListener("viewshow", function(e) {
+
+ self.renderTab = function () {
+ var tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
+ loadSuggestionsTab(view, params, tabContent);
+ };
+
+ var tabControllers = [];
+ var renderedTabs = [];
+ view.addEventListener("viewshow", function (e) {
if (isViewRestored = e.detail.isRestored, initTabs(), !view.getAttribute("data-title")) {
var parentId = params.topParentId;
- parentId ? ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function(item) {
- view.setAttribute("data-title", item.Name), libraryMenu.setTitle(item.Name)
- }) : (view.setAttribute("data-title", Globalize.translate("TabMovies")), libraryMenu.setTitle(Globalize.translate("TabMovies")))
+
+ if (parentId) {
+ ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function (item) {
+ view.setAttribute("data-title", item.Name);
+ libraryMenu.setTitle(item.Name);
+ });
+ } else {
+ view.setAttribute("data-title", Globalize.translate("TabMovies"));
+ libraryMenu.setTitle(Globalize.translate("TabMovies"));
+ }
}
- events.on(playbackManager, "playbackstop", onPlaybackStop), inputManager.on(window, onInputCommand)
- }), view.addEventListener("viewbeforehide", function(e) {
- inputManager.off(window, onInputCommand)
- }), view.addEventListener("viewdestroy", function(e) {
- tabControllers.forEach(function(t) {
- t.destroy && t.destroy()
- })
- })
- }
-});
\ No newline at end of file
+
+ events.on(playbackManager, "playbackstop", onPlaybackStop);
+ inputManager.on(window, onInputCommand);
+ });
+ view.addEventListener("viewbeforehide", function (e) {
+ inputManager.off(window, onInputCommand);
+ });
+ view.addEventListener("viewdestroy", function (e) {
+ tabControllers.forEach(function (t) {
+ if (t.destroy) {
+ t.destroy();
+ }
+ });
+ });
+ };
+});
diff --git a/src/controllers/movies/movietrailers.js b/src/controllers/movies/movietrailers.js
index 2d1fdda63c..3e62298613 100644
--- a/src/controllers/movies/movietrailers.js
+++ b/src/controllers/movies/movietrailers.js
@@ -1,185 +1,261 @@
-define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function(layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) {
+define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) {
"use strict";
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
function getPageData(context) {
- var key = getSavedQueryKey(context),
- pageData = data[key];
- return pageData || (pageData = data[key] = {
- query: {
- SortBy: "SortName",
- SortOrder: "Ascending",
- IncludeItemTypes: "Trailer",
- Recursive: !0,
- Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo",
- ImageTypeLimit: 1,
- EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
- StartIndex: 0,
- Limit: pageSize
- },
- view: libraryBrowser.getSavedView(key) || "Poster"
- }, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData
+ var key = getSavedQueryKey(context);
+ var pageData = data[key];
+
+ if (!pageData) {
+ pageData = data[key] = {
+ query: {
+ SortBy: "SortName",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "Trailer",
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo",
+ ImageTypeLimit: 1,
+ EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
+ StartIndex: 0,
+ Limit: pageSize
+ },
+ view: libraryBrowser.getSavedView(key) || "Poster"
+ };
+ libraryBrowser.loadSavedQueryValues(key, pageData.query);
+ }
+
+ return pageData;
}
function getQuery(context) {
- return getPageData(context).query
+ return getPageData(context).query;
}
function getSavedQueryKey(context) {
- return context.savedQueryKey || (context.savedQueryKey = libraryBrowser.getSavedQueryKey("trailers")), context.savedQueryKey
+ if (!context.savedQueryKey) {
+ context.savedQueryKey = libraryBrowser.getSavedQueryKey("trailers");
+ }
+
+ return context.savedQueryKey;
}
function reloadItems() {
loading.show();
isLoading = true;
var query = getQuery(tabContent);
- ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function(result) {
+ ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) {
function onNextPageClick() {
- if (isLoading) return;
- query.StartIndex += query.Limit, reloadItems()
+ if (isLoading) {
+ return;
+ }
+
+ query.StartIndex += query.Limit;
+ reloadItems();
}
function onPreviousPageClick() {
- if (isLoading) return;
- query.StartIndex -= query.Limit, reloadItems()
+ if (isLoading) {
+ return;
+ }
+
+ query.StartIndex -= query.Limit;
+ reloadItems();
}
- window.scrollTo(0, 0), updateFilterControls(tabContent);
- var html, pagingHtml = libraryBrowser.getQueryPagingHtml({
- startIndex: query.StartIndex,
- limit: query.Limit,
- totalRecordCount: result.TotalRecordCount,
- showLimit: !1,
- updatePageSizeSetting: !1,
- addLayoutButton: !1,
- sortButton: !1,
- filterButton: !1
- }),
- viewStyle = self.getCurrentViewStyle();
- html = "Thumb" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "backdrop",
- preferThumb: !0,
- context: "movies",
- overlayPlayButton: !0
- }) : "ThumbCard" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "backdrop",
- preferThumb: !0,
- context: "movies",
- cardLayout: !0,
- showTitle: !0,
- showYear: !0,
- centerText: !0
- }) : "Banner" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "banner",
- preferBanner: !0,
- context: "movies"
- }) : "List" == viewStyle ? listView.getListViewHtml({
- items: result.Items,
- context: "movies",
- sortBy: query.SortBy
- }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "portrait",
- context: "movies",
- showTitle: !0,
- showYear: !0,
- centerText: !0,
- cardLayout: !0
- }) : cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "portrait",
- context: "movies",
- centerText: !0,
- overlayPlayButton: !0,
- showTitle: !0,
- showYear: !0
+
+ window.scrollTo(0, 0);
+ updateFilterControls(tabContent);
+ var pagingHtml = libraryBrowser.getQueryPagingHtml({
+ startIndex: query.StartIndex,
+ limit: query.Limit,
+ totalRecordCount: result.TotalRecordCount,
+ showLimit: false,
+ updatePageSizeSetting: false,
+ addLayoutButton: false,
+ sortButton: false,
+ filterButton: false
});
- var i, length, elems = tabContent.querySelectorAll(".paging");
- for (i = 0, length = elems.length; i < length; i++) elems[i].innerHTML = pagingHtml;
- for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick);
- for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick);
- result.Items.length || (html = '
' + Globalize.translate("MessageNoTrailersFound") + "
");
+ var html;
+ var viewStyle = self.getCurrentViewStyle();
+
+ if (viewStyle == "Thumb") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "backdrop",
+ preferThumb: true,
+ context: "movies",
+ overlayPlayButton: true
+ });
+ } else if (viewStyle == "ThumbCard") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "backdrop",
+ preferThumb: true,
+ context: "movies",
+ cardLayout: true,
+ showTitle: true,
+ showYear: true,
+ centerText: true
+ });
+ } else if (viewStyle == "Banner") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "banner",
+ preferBanner: true,
+ context: "movies"
+ });
+ } else if (viewStyle == "List") {
+ html = listView.getListViewHtml({
+ items: result.Items,
+ context: "movies",
+ sortBy: query.SortBy
+ });
+ } else if (viewStyle == "PosterCard") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "portrait",
+ context: "movies",
+ showTitle: true,
+ showYear: true,
+ cardLayout: true,
+ centerText: true
+ });
+ } else {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "portrait",
+ context: "movies",
+ centerText: true,
+ overlayPlayButton: true,
+ showTitle: true,
+ showYear: true
+ });
+ }
+
+ var i;
+ var length;
+ var elems = tabContent.querySelectorAll(".paging");
+
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].innerHTML = pagingHtml;
+ }
+
+ elems = tabContent.querySelectorAll(".btnNextPage");
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onNextPageClick);
+ }
+
+ elems = tabContent.querySelectorAll(".btnPreviousPage");
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onPreviousPageClick);
+ }
+
+ if (!result.Items.length) {
+ html = '
' + Globalize.translate("MessageNoTrailersFound") + "
";
+ }
+
var itemsContainer = tabContent.querySelector(".itemsContainer");
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(tabContent), query);
loading.hide();
isLoading = false;
- })
+ });
}
function updateFilterControls(tabContent) {
var query = getQuery(tabContent);
- self.alphaPicker.value(query.NameStartsWithOrGreater)
+ self.alphaPicker.value(query.NameStartsWithOrGreater);
}
- var self = this,
- pageSize = 100,
- data = {},
- isLoading = false;
- self.showFilterMenu = function() {
- require(["components/filterdialog/filterdialog"], function(filterDialogFactory) {
- var filterDialog = new filterDialogFactory({
- query: getQuery(tabContent),
- mode: "movies",
- serverId: ApiClient.serverId()
- });
- events.on(filterDialog, "filterchange", function() {
- getQuery(tabContent).StartIndex = 0, reloadItems()
- }), filterDialog.show()
- })
- }, self.getCurrentViewStyle = function() {
- return getPageData(tabContent).view
- },
- function(tabContent) {
- var alphaPickerElement = tabContent.querySelector(".alphaPicker");
- if (alphaPickerElement.addEventListener("alphavaluechanged", function(e) {
- var newValue = e.detail.value,
- query = getQuery(tabContent);
- query.NameStartsWithOrGreater = newValue, query.StartIndex = 0, reloadItems()
- }), self.alphaPicker = new alphaPicker({
- element: alphaPickerElement,
- valueChangeEvent: "click"
- }), layoutManager.desktop || layoutManager.mobile) {
- tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right");
- var itemsContainer = tabContent.querySelector(".itemsContainer");
- itemsContainer.classList.remove("padded-left-withalphapicker"), itemsContainer.classList.add("padded-right-withalphapicker")
- }
- tabContent.querySelector(".btnFilter").addEventListener("click", function() {
- self.showFilterMenu()
- }), tabContent.querySelector(".btnSort").addEventListener("click", function(e) {
- libraryBrowser.showSortMenu({
- items: [{
- name: Globalize.translate("OptionNameSort"),
- id: "SortName"
- }, {
- name: Globalize.translate("OptionImdbRating"),
- id: "CommunityRating,SortName"
- }, {
- name: Globalize.translate("OptionDateAdded"),
- id: "DateCreated,SortName"
- }, {
- name: Globalize.translate("OptionDatePlayed"),
- id: "DatePlayed,SortName"
- }, {
- name: Globalize.translate("OptionParentalRating"),
- id: "OfficialRating,SortName"
- }, {
- name: Globalize.translate("OptionPlayCount"),
- id: "PlayCount,SortName"
- }, {
- name: Globalize.translate("OptionReleaseDate"),
- id: "PremiereDate,SortName"
- }],
- callback: function() {
- getQuery(tabContent).StartIndex = 0, reloadItems()
- },
- query: getQuery(tabContent),
- button: e.target
- })
- })
- }(tabContent), self.renderTab = function() {
- reloadItems(), updateFilterControls(tabContent)
- }, self.destroy = function() {}
- }
+
+ var self = this;
+ var pageSize = 100;
+ var data = {};
+ var isLoading = false;
+
+ self.showFilterMenu = function () {
+ require(["components/filterdialog/filterdialog"], function (filterDialogFactory) {
+ var filterDialog = new filterDialogFactory({
+ query: getQuery(tabContent),
+ mode: "movies",
+ serverId: ApiClient.serverId()
+ });
+ events.on(filterDialog, "filterchange", function () {
+ getQuery(tabContent).StartIndex = 0;
+ reloadItems();
+ });
+ filterDialog.show();
+ });
+ };
+
+ self.getCurrentViewStyle = function () {
+ return getPageData(tabContent).view;
+ };
+
+ function initPage(tabContent) {
+ var alphaPickerElement = tabContent.querySelector(".alphaPicker");
+ alphaPickerElement.addEventListener("alphavaluechanged", function (e) {
+ var newValue = e.detail.value;
+ var query = getQuery(tabContent);
+ query.NameStartsWithOrGreater = newValue;
+ query.StartIndex = 0;
+ reloadItems();
+ });
+ self.alphaPicker = new alphaPicker({
+ element: alphaPickerElement,
+ valueChangeEvent: "click"
+ });
+
+ if (layoutManager.desktop || layoutManager.mobile) {
+ tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right");
+ var itemsContainer = tabContent.querySelector(".itemsContainer");
+ itemsContainer.classList.remove("padded-left-withalphapicker");
+ itemsContainer.classList.add("padded-right-withalphapicker");
+ }
+
+ tabContent.querySelector(".btnFilter").addEventListener("click", function () {
+ self.showFilterMenu();
+ });
+ tabContent.querySelector(".btnSort").addEventListener("click", function (e) {
+ libraryBrowser.showSortMenu({
+ items: [{
+ name: Globalize.translate("OptionNameSort"),
+ id: "SortName"
+ }, {
+ name: Globalize.translate("OptionImdbRating"),
+ id: "CommunityRating,SortName"
+ }, {
+ name: Globalize.translate("OptionDateAdded"),
+ id: "DateCreated,SortName"
+ }, {
+ name: Globalize.translate("OptionDatePlayed"),
+ id: "DatePlayed,SortName"
+ }, {
+ name: Globalize.translate("OptionParentalRating"),
+ id: "OfficialRating,SortName"
+ }, {
+ name: Globalize.translate("OptionPlayCount"),
+ id: "PlayCount,SortName"
+ }, {
+ name: Globalize.translate("OptionReleaseDate"),
+ id: "PremiereDate,SortName"
+ }],
+ callback: function () {
+ getQuery(tabContent).StartIndex = 0;
+ reloadItems();
+ },
+ query: getQuery(tabContent),
+ button: e.target
+ });
+ });
+ }
+
+ initPage(tabContent);
+
+ self.renderTab = function () {
+ reloadItems();
+ updateFilterControls(tabContent);
+ };
+
+ self.destroy = function () {};
+ };
});
diff --git a/src/controllers/music/musicalbums.js b/src/controllers/music/musicalbums.js
index 8a562c532d..ac45d9a15b 100644
--- a/src/controllers/music/musicalbums.js
+++ b/src/controllers/music/musicalbums.js
@@ -1,190 +1,275 @@
-define(["layoutManager", "playbackManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function(layoutManager, playbackManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) {
+define(["layoutManager", "playbackManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function (layoutManager, playbackManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) {
"use strict";
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
function playAll() {
- ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function(item) {
+ ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function (item) {
playbackManager.play({
items: [item]
- })
- })
+ });
+ });
}
function shuffle() {
- ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function(item) {
+ ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function (item) {
getQuery();
- playbackManager.shuffle(item, null)
- })
+ playbackManager.shuffle(item, null);
+ });
}
function getPageData() {
var key = getSavedQueryKey();
- return pageData || (pageData = {
- query: {
- SortBy: "SortName",
- SortOrder: "Ascending",
- IncludeItemTypes: "MusicAlbum",
- Recursive: !0,
- Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo",
- ImageTypeLimit: 1,
- EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
- StartIndex: 0,
- Limit: pageSize
- },
- view: libraryBrowser.getSavedView(key) || "Poster"
- }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData
+
+ if (!pageData) {
+ pageData = {
+ query: {
+ SortBy: "SortName",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "MusicAlbum",
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo",
+ ImageTypeLimit: 1,
+ EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
+ StartIndex: 0,
+ Limit: pageSize
+ },
+ view: libraryBrowser.getSavedView(key) || "Poster"
+ };
+ pageData.query.ParentId = params.topParentId;
+ libraryBrowser.loadSavedQueryValues(key, pageData.query);
+ }
+
+ return pageData;
}
function getQuery() {
- return getPageData().query
+ return getPageData().query;
}
function getSavedQueryKey() {
- return savedQueryKey || (savedQueryKey = libraryBrowser.getSavedQueryKey("musicalbums")), savedQueryKey
+ if (!savedQueryKey) {
+ savedQueryKey = libraryBrowser.getSavedQueryKey("musicalbums");
+ }
+
+ return savedQueryKey;
}
function onViewStyleChange() {
- var viewStyle = self.getCurrentViewStyle(),
- itemsContainer = tabContent.querySelector(".itemsContainer");
- "List" == viewStyle ? (itemsContainer.classList.add("vertical-list"), itemsContainer.classList.remove("vertical-wrap")) : (itemsContainer.classList.remove("vertical-list"), itemsContainer.classList.add("vertical-wrap")), itemsContainer.innerHTML = ""
+ var viewStyle = self.getCurrentViewStyle();
+ var itemsContainer = tabContent.querySelector(".itemsContainer");
+
+ if ("List" == viewStyle) {
+ itemsContainer.classList.add("vertical-list");
+ itemsContainer.classList.remove("vertical-wrap");
+ } else {
+ itemsContainer.classList.remove("vertical-list");
+ itemsContainer.classList.add("vertical-wrap");
+ }
+
+ itemsContainer.innerHTML = "";
}
function reloadItems(page) {
loading.show();
isLoading = true;
var query = getQuery();
- ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function(result) {
+ ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) {
function onNextPageClick() {
- if (isLoading) return;
- query.StartIndex += query.Limit, reloadItems(tabContent)
+ if (isLoading) {
+ return;
+ }
+
+ query.StartIndex += query.Limit;
+ reloadItems(tabContent);
}
function onPreviousPageClick() {
- if (isLoading) return;
- query.StartIndex -= query.Limit, reloadItems(tabContent)
+ if (isLoading) {
+ return;
+ }
+
+ query.StartIndex -= query.Limit;
+ reloadItems(tabContent);
}
- window.scrollTo(0, 0), updateFilterControls(page);
- var html, pagingHtml = libraryBrowser.getQueryPagingHtml({
- startIndex: query.StartIndex,
- limit: query.Limit,
- totalRecordCount: result.TotalRecordCount,
- showLimit: !1,
- updatePageSizeSetting: !1,
- addLayoutButton: !1,
- sortButton: !1,
- filterButton: !1
- }),
- viewStyle = self.getCurrentViewStyle();
- html = "List" == viewStyle ? listView.getListViewHtml({
- items: result.Items,
- context: "music",
- sortBy: query.SortBy,
- addToListButton: !0
- }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "square",
- context: "music",
- showTitle: !0,
- coverImage: !0,
- showParentTitle: !0,
- lazy: !0,
- cardLayout: !0
- }) : cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "square",
- context: "music",
- showTitle: !0,
- showParentTitle: !0,
- lazy: !0,
- centerText: !0,
- overlayPlayButton: !0
+
+ window.scrollTo(0, 0);
+ updateFilterControls(page);
+ var html;
+ var pagingHtml = libraryBrowser.getQueryPagingHtml({
+ startIndex: query.StartIndex,
+ limit: query.Limit,
+ totalRecordCount: result.TotalRecordCount,
+ showLimit: false,
+ updatePageSizeSetting: false,
+ addLayoutButton: false,
+ sortButton: false,
+ filterButton: false
});
- var i, length, elems = tabContent.querySelectorAll(".paging");
- for (i = 0, length = elems.length; i < length; i++) elems[i].innerHTML = pagingHtml;
- for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick);
- for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick);
+ var viewStyle = self.getCurrentViewStyle();
+ if (viewStyle == "List") {
+ html = listView.getListViewHtml({
+ items: result.Items,
+ context: "music",
+ sortBy: query.SortBy,
+ addToListButton: true
+ });
+ } else if (viewStyle == "PosterCard") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "square",
+ context: "music",
+ showTitle: true,
+ coverImage: true,
+ showParentTitle: true,
+ lazy: true,
+ cardLayout: true
+ });
+ } else {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "square",
+ context: "music",
+ showTitle: true,
+ showParentTitle: true,
+ lazy: true,
+ centerText: true,
+ overlayPlayButton: true
+ });
+ }
+ var i;
+ var length;
+ var elems = tabContent.querySelectorAll(".paging");
+
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].innerHTML = pagingHtml;
+ }
+
+ elems = tabContent.querySelectorAll(".btnNextPage");
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onNextPageClick);
+ }
+
+ elems = tabContent.querySelectorAll(".btnPreviousPage");
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onPreviousPageClick);
+ }
+
var itemsContainer = tabContent.querySelector(".itemsContainer");
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
loading.hide();
isLoading = false;
- })
+ });
}
function updateFilterControls(tabContent) {
var query = getQuery();
- self.alphaPicker.value(query.NameStartsWithOrGreater)
+ self.alphaPicker.value(query.NameStartsWithOrGreater);
}
- var savedQueryKey, pageData, self = this,
- pageSize = 100,
- isLoading = false;
- self.showFilterMenu = function() {
- require(["components/filterdialog/filterdialog"], function(filterDialogFactory) {
- var filterDialog = new filterDialogFactory({
- query: getQuery(),
- mode: "albums",
- serverId: ApiClient.serverId()
- });
- events.on(filterDialog, "filterchange", function() {
- getQuery().StartIndex = 0, reloadItems(tabContent)
- }), filterDialog.show()
- })
- }, self.getCurrentViewStyle = function() {
- return getPageData().view
- },
- function(tabContent) {
- var alphaPickerElement = tabContent.querySelector(".alphaPicker");
- if (alphaPickerElement.addEventListener("alphavaluechanged", function(e) {
- var newValue = e.detail.value,
- query = getQuery();
- query.NameStartsWithOrGreater = newValue, query.StartIndex = 0, reloadItems(tabContent)
- }), self.alphaPicker = new alphaPicker({
- element: alphaPickerElement,
- valueChangeEvent: "click"
- }), layoutManager.desktop || layoutManager.mobile) {
- tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right");
- var itemsContainer = tabContent.querySelector(".itemsContainer");
- itemsContainer.classList.remove("padded-left-withalphapicker"), itemsContainer.classList.add("padded-right-withalphapicker")
- }
- tabContent.querySelector(".btnFilter").addEventListener("click", function() {
- self.showFilterMenu()
- }), tabContent.querySelector(".btnSort").addEventListener("click", function(e) {
- libraryBrowser.showSortMenu({
- items: [{
- name: Globalize.translate("OptionNameSort"),
- id: "SortName"
- }, {
- name: Globalize.translate("OptionAlbumArtist"),
- id: "AlbumArtist,SortName"
- }, {
- name: Globalize.translate("OptionCommunityRating"),
- id: "CommunityRating,SortName"
- }, {
- name: Globalize.translate("OptionCriticRating"),
- id: "CriticRating,SortName"
- }, {
- name: Globalize.translate("OptionDateAdded"),
- id: "DateCreated,SortName"
- }, {
- name: Globalize.translate("OptionReleaseDate"),
- id: "ProductionYear,PremiereDate,SortName"
- }],
- callback: function() {
- getQuery().StartIndex = 0, reloadItems(tabContent)
- },
- query: getQuery(),
- button: e.target
- })
+
+ var savedQueryKey;
+ var pageData;
+ var self = this;
+ var pageSize = 100;
+ var isLoading = false;
+
+ self.showFilterMenu = function () {
+ require(["components/filterdialog/filterdialog"], function (filterDialogFactory) {
+ var filterDialog = new filterDialogFactory({
+ query: getQuery(),
+ mode: "albums",
+ serverId: ApiClient.serverId()
});
- var btnSelectView = tabContent.querySelector(".btnSelectView");
- btnSelectView.addEventListener("click", function(e) {
- libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard".split(","))
- }), btnSelectView.addEventListener("layoutchange", function(e) {
- var viewStyle = e.detail.viewStyle;
- getPageData().view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle), getQuery().StartIndex = 0, onViewStyleChange(), reloadItems(tabContent)
- }), tabContent.querySelector(".btnPlayAll").addEventListener("click", playAll), tabContent.querySelector(".btnShuffle").addEventListener("click", shuffle)
- }(tabContent), onViewStyleChange(), self.renderTab = function() {
- reloadItems(tabContent), updateFilterControls(tabContent)
- }, self.destroy = function() {}
- }
+ events.on(filterDialog, "filterchange", function () {
+ getQuery().StartIndex = 0;
+ reloadItems(tabContent);
+ });
+ filterDialog.show();
+ });
+ };
+
+ self.getCurrentViewStyle = function () {
+ return getPageData().view;
+ };
+
+ function initPage(tabContent) {
+ var alphaPickerElement = tabContent.querySelector(".alphaPicker");
+
+ alphaPickerElement.addEventListener("alphavaluechanged", function (e) {
+ var newValue = e.detail.value;
+ var query = getQuery();
+ query.NameStartsWithOrGreater = newValue;
+ query.StartIndex = 0;
+ reloadItems(tabContent);
+ });
+ self.alphaPicker = new alphaPicker({
+ element: alphaPickerElement,
+ valueChangeEvent: "click"
+ });
+ if (layoutManager.desktop || layoutManager.mobile) {
+ tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right");
+ var itemsContainer = tabContent.querySelector(".itemsContainer");
+ itemsContainer.classList.remove("padded-left-withalphapicker");
+ itemsContainer.classList.add("padded-right-withalphapicker");
+ }
+
+ tabContent.querySelector(".btnFilter").addEventListener("click", function () {
+ self.showFilterMenu();
+ });
+ tabContent.querySelector(".btnSort").addEventListener("click", function (e) {
+ libraryBrowser.showSortMenu({
+ items: [{
+ name: Globalize.translate("OptionNameSort"),
+ id: "SortName"
+ }, {
+ name: Globalize.translate("OptionAlbumArtist"),
+ id: "AlbumArtist,SortName"
+ }, {
+ name: Globalize.translate("OptionCommunityRating"),
+ id: "CommunityRating,SortName"
+ }, {
+ name: Globalize.translate("OptionCriticRating"),
+ id: "CriticRating,SortName"
+ }, {
+ name: Globalize.translate("OptionDateAdded"),
+ id: "DateCreated,SortName"
+ }, {
+ name: Globalize.translate("OptionReleaseDate"),
+ id: "ProductionYear,PremiereDate,SortName"
+ }],
+ callback: function () {
+ getQuery().StartIndex = 0;
+ reloadItems(tabContent);
+ },
+ query: getQuery(),
+ button: e.target
+ });
+ });
+ var btnSelectView = tabContent.querySelector(".btnSelectView");
+ btnSelectView.addEventListener("click", function (e) {
+ libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard".split(","));
+ });
+ btnSelectView.addEventListener("layoutchange", function (e) {
+ var viewStyle = e.detail.viewStyle;
+ getPageData().view = viewStyle;
+ libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle);
+ getQuery().StartIndex = 0;
+ onViewStyleChange();
+ reloadItems(tabContent);
+ });
+ tabContent.querySelector(".btnPlayAll").addEventListener("click", playAll);
+ tabContent.querySelector(".btnShuffle").addEventListener("click", shuffle);
+ }
+
+ initPage(tabContent);
+ onViewStyleChange();
+
+ self.renderTab = function () {
+ reloadItems(tabContent);
+ updateFilterControls(tabContent);
+ };
+
+ self.destroy = function () {};
+ };
});
diff --git a/src/controllers/music/musicartists.js b/src/controllers/music/musicartists.js
index b28385169d..5159f635f8 100644
--- a/src/controllers/music/musicartists.js
+++ b/src/controllers/music/musicartists.js
@@ -1,144 +1,226 @@
-define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function(layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) {
+define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) {
"use strict";
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
function getPageData(context) {
- var key = getSavedQueryKey(context),
- pageData = data[key];
- return pageData || (pageData = data[key] = {
- query: {
- SortBy: "SortName",
- SortOrder: "Ascending",
- Recursive: !0,
- Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo",
- StartIndex: 0,
- ImageTypeLimit: 1,
- EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
- Limit: 100
- },
- view: libraryBrowser.getSavedView(key) || "Poster"
- }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData
+ var key = getSavedQueryKey(context);
+ var pageData = data[key];
+
+ if (!pageData) {
+ pageData = data[key] = {
+ query: {
+ SortBy: "SortName",
+ SortOrder: "Ascending",
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo",
+ StartIndex: 0,
+ ImageTypeLimit: 1,
+ EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
+ Limit: 100
+ },
+ view: libraryBrowser.getSavedView(key) || "Poster"
+ };
+ pageData.query.ParentId = params.topParentId;
+ libraryBrowser.loadSavedQueryValues(key, pageData.query);
+ }
+
+ return pageData;
}
function getQuery(context) {
- return getPageData(context).query
+ return getPageData(context).query;
}
function getSavedQueryKey(context) {
- return context.savedQueryKey || (context.savedQueryKey = libraryBrowser.getSavedQueryKey(self.mode)), context.savedQueryKey
+ if (!context.savedQueryKey) {
+ context.savedQueryKey = libraryBrowser.getSavedQueryKey(self.mode);
+ }
+
+ return context.savedQueryKey;
}
function onViewStyleChange() {
- var viewStyle = self.getCurrentViewStyle(),
- itemsContainer = tabContent.querySelector(".itemsContainer");
- "List" == viewStyle ? (itemsContainer.classList.add("vertical-list"), itemsContainer.classList.remove("vertical-wrap")) : (itemsContainer.classList.remove("vertical-list"), itemsContainer.classList.add("vertical-wrap")), itemsContainer.innerHTML = ""
+ var viewStyle = self.getCurrentViewStyle();
+ var itemsContainer = tabContent.querySelector(".itemsContainer");
+
+ if ("List" == viewStyle) {
+ itemsContainer.classList.add("vertical-list");
+ itemsContainer.classList.remove("vertical-wrap");
+ } else {
+ itemsContainer.classList.remove("vertical-list");
+ itemsContainer.classList.add("vertical-wrap");
+ }
+
+ itemsContainer.innerHTML = "";
}
function reloadItems(page) {
loading.show();
isLoading = true;
var query = getQuery(page);
- ("albumartists" == self.mode ? ApiClient.getAlbumArtists(ApiClient.getCurrentUserId(), query) : ApiClient.getArtists(ApiClient.getCurrentUserId(), query)).then(function(result) {
+ var promise = self.mode == 'albumartists' ?
+ ApiClient.getAlbumArtists(ApiClient.getCurrentUserId(), query) :
+ ApiClient.getArtists(ApiClient.getCurrentUserId(), query);
+ promise.then(function (result) {
function onNextPageClick() {
- if (isLoading) return;
- query.StartIndex += query.Limit, reloadItems(tabContent)
+ if (isLoading) {
+ return;
+ }
+
+ query.StartIndex += query.Limit;
+ reloadItems(tabContent);
}
function onPreviousPageClick() {
- if (isLoading) return;
- query.StartIndex -= query.Limit, reloadItems(tabContent)
+ if (isLoading) {
+ return;
+ }
+
+ query.StartIndex -= query.Limit;
+ reloadItems(tabContent);
}
- window.scrollTo(0, 0), updateFilterControls(page);
- var html, pagingHtml = libraryBrowser.getQueryPagingHtml({
- startIndex: query.StartIndex,
- limit: query.Limit,
- totalRecordCount: result.TotalRecordCount,
- showLimit: !1,
- updatePageSizeSetting: !1,
- addLayoutButton: !1,
- sortButton: !1,
- filterButton: !1
- }),
- viewStyle = self.getCurrentViewStyle();
- html = "List" == viewStyle ? listView.getListViewHtml({
- items: result.Items,
- sortBy: query.SortBy
- }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "square",
- context: "music",
- showTitle: !0,
- coverImage: !0,
- cardLayout: !0
- }) : cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "square",
- context: "music",
- showTitle: !0,
- coverImage: !0,
- lazy: !0,
- centerText: !0,
- overlayPlayButton: !0
+
+ window.scrollTo(0, 0);
+ updateFilterControls(page);
+ var html;
+ var pagingHtml = libraryBrowser.getQueryPagingHtml({
+ startIndex: query.StartIndex,
+ limit: query.Limit,
+ totalRecordCount: result.TotalRecordCount,
+ showLimit: false,
+ updatePageSizeSetting: false,
+ addLayoutButton: false,
+ sortButton: false,
+ filterButton: false
});
- var i, length, elems = tabContent.querySelectorAll(".paging");
- for (i = 0, length = elems.length; i < length; i++) elems[i].innerHTML = pagingHtml;
- for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick);
- for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick);
+ var viewStyle = self.getCurrentViewStyle();
+ if (viewStyle == "List") {
+ html = listView.getListViewHtml({
+ items: result.Items,
+ sortBy: query.SortBy
+ });
+ } else if (viewStyle == "PosterCard") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "square",
+ context: "music",
+ showTitle: true,
+ coverImage: true,
+ cardLayout: true
+ });
+ } else {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "square",
+ context: "music",
+ showTitle: true,
+ coverImage: true,
+ lazy: true,
+ centerText: true,
+ overlayPlayButton: true
+ });
+ }
+ var i;
+ var length;
+ var elems = tabContent.querySelectorAll(".paging");
+
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].innerHTML = pagingHtml;
+ }
+
+ elems = tabContent.querySelectorAll(".btnNextPage");
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onNextPageClick);
+ }
+
+ elems = tabContent.querySelectorAll(".btnPreviousPage");
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onPreviousPageClick);
+ }
+
var itemsContainer = tabContent.querySelector(".itemsContainer");
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
loading.hide();
isLoading = false;
- })
+ });
}
function updateFilterControls(tabContent) {
var query = getQuery(tabContent);
- self.alphaPicker.value(query.NameStartsWithOrGreater)
+ self.alphaPicker.value(query.NameStartsWithOrGreater);
}
- var self = this,
- data = {},
- isLoading = false;
- self.showFilterMenu = function() {
- require(["components/filterdialog/filterdialog"], function(filterDialogFactory) {
- var filterDialog = new filterDialogFactory({
- query: getQuery(tabContent),
- mode: self.mode,
- serverId: ApiClient.serverId()
- });
- events.on(filterDialog, "filterchange", function() {
- getQuery(tabContent).StartIndex = 0, reloadItems(tabContent)
- }), filterDialog.show()
- })
- }, self.getCurrentViewStyle = function() {
- return getPageData(tabContent).view
- },
- function(tabContent) {
- var alphaPickerElement = tabContent.querySelector(".alphaPicker");
- if (alphaPickerElement.addEventListener("alphavaluechanged", function(e) {
- var newValue = e.detail.value,
- query = getQuery(tabContent);
- query.NameStartsWithOrGreater = newValue, query.StartIndex = 0, reloadItems(tabContent)
- }), self.alphaPicker = new alphaPicker({
- element: alphaPickerElement,
- valueChangeEvent: "click"
- }), layoutManager.desktop || layoutManager.mobile) {
- tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right");
- var itemsContainer = tabContent.querySelector(".itemsContainer");
- itemsContainer.classList.remove("padded-left-withalphapicker"), itemsContainer.classList.add("padded-right-withalphapicker")
- }
- tabContent.querySelector(".btnFilter").addEventListener("click", function() {
- self.showFilterMenu()
+
+ var self = this;
+ var data = {};
+ var isLoading = false;
+
+ self.showFilterMenu = function () {
+ require(["components/filterdialog/filterdialog"], function (filterDialogFactory) {
+ var filterDialog = new filterDialogFactory({
+ query: getQuery(tabContent),
+ mode: self.mode,
+ serverId: ApiClient.serverId()
});
- var btnSelectView = tabContent.querySelector(".btnSelectView");
- btnSelectView.addEventListener("click", function(e) {
- libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard".split(","))
- }), btnSelectView.addEventListener("layoutchange", function(e) {
- var viewStyle = e.detail.viewStyle;
- getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), getQuery(tabContent).StartIndex = 0, onViewStyleChange(), reloadItems(tabContent)
- })
- }(tabContent), onViewStyleChange(), self.renderTab = function() {
- reloadItems(tabContent), updateFilterControls(tabContent)
- }, self.destroy = function() {}
- }
+ events.on(filterDialog, "filterchange", function () {
+ getQuery(tabContent).StartIndex = 0;
+ reloadItems(tabContent);
+ });
+ filterDialog.show();
+ });
+ };
+
+ self.getCurrentViewStyle = function () {
+ return getPageData(tabContent).view;
+ };
+
+ function initPage(tabContent) {
+ var alphaPickerElement = tabContent.querySelector(".alphaPicker");
+
+ alphaPickerElement.addEventListener("alphavaluechanged", function (e) {
+ var newValue = e.detail.value;
+ var query = getQuery(tabContent);
+ query.NameStartsWithOrGreater = newValue;
+ query.StartIndex = 0;
+ reloadItems(tabContent);
+ });
+ self.alphaPicker = new alphaPicker({
+ element: alphaPickerElement,
+ valueChangeEvent: "click"
+ });
+ if (layoutManager.desktop || layoutManager.mobile) {
+ tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right");
+ var itemsContainer = tabContent.querySelector(".itemsContainer");
+ itemsContainer.classList.remove("padded-left-withalphapicker");
+ itemsContainer.classList.add("padded-right-withalphapicker");
+ }
+
+ tabContent.querySelector(".btnFilter").addEventListener("click", function () {
+ self.showFilterMenu();
+ });
+ var btnSelectView = tabContent.querySelector(".btnSelectView");
+ btnSelectView.addEventListener("click", function (e) {
+ libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard".split(","));
+ });
+ btnSelectView.addEventListener("layoutchange", function (e) {
+ var viewStyle = e.detail.viewStyle;
+ getPageData(tabContent).view = viewStyle;
+ libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle);
+ getQuery(tabContent).StartIndex = 0;
+ onViewStyleChange();
+ reloadItems(tabContent);
+ });
+ }
+
+ initPage(tabContent);
+ onViewStyleChange();
+
+ self.renderTab = function () {
+ reloadItems(tabContent);
+ updateFilterControls(tabContent);
+ };
+
+ self.destroy = function () {};
+ };
});
diff --git a/src/controllers/music/musicgenres.js b/src/controllers/music/musicgenres.js
index f66afcdb20..cf0052f5b1 100644
--- a/src/controllers/music/musicgenres.js
+++ b/src/controllers/music/musicgenres.js
@@ -1,91 +1,126 @@
-define(["libraryBrowser", "cardBuilder", "apphost", "imageLoader", "loading"], function(libraryBrowser, cardBuilder, appHost, imageLoader, loading) {
+define(["libraryBrowser", "cardBuilder", "apphost", "imageLoader", "loading"], function (libraryBrowser, cardBuilder, appHost, imageLoader, loading) {
"use strict";
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
function getPageData() {
- var key = getSavedQueryKey(),
- pageData = data[key];
- return pageData || (pageData = data[key] = {
- query: {
- SortBy: "SortName",
- SortOrder: "Ascending",
- Recursive: !0,
- Fields: "PrimaryImageAspectRatio,ItemCounts",
- StartIndex: 0
- },
- view: libraryBrowser.getSavedView(key) || "Poster"
- }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData
+ var key = getSavedQueryKey();
+ var pageData = data[key];
+
+ if (!pageData) {
+ pageData = data[key] = {
+ query: {
+ SortBy: "SortName",
+ SortOrder: "Ascending",
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,ItemCounts",
+ StartIndex: 0
+ },
+ view: libraryBrowser.getSavedView(key) || "Poster"
+ };
+ pageData.query.ParentId = params.topParentId;
+ libraryBrowser.loadSavedQueryValues(key, pageData.query);
+ }
+
+ return pageData;
}
function getQuery() {
- return getPageData().query
+ return getPageData().query;
}
function getSavedQueryKey() {
- return libraryBrowser.getSavedQueryKey("genres")
+ return libraryBrowser.getSavedQueryKey("genres");
}
function getPromise() {
loading.show();
var query = getQuery();
- return ApiClient.getGenres(ApiClient.getCurrentUserId(), query)
+ return ApiClient.getGenres(ApiClient.getCurrentUserId(), query);
}
function reloadItems(context, promise) {
var query = getQuery();
- promise.then(function(result) {
- var html = "",
- viewStyle = self.getCurrentViewStyle();
- "Thumb" == viewStyle ? html = cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "backdrop",
- preferThumb: !0,
- context: "music",
- centerText: !0,
- overlayMoreButton: !0,
- showTitle: !0
- }) : "ThumbCard" == viewStyle ? html = cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "backdrop",
- preferThumb: !0,
- context: "music",
- cardLayout: !0,
- showTitle: !0
- }) : "PosterCard" == viewStyle ? html = cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "auto",
- context: "music",
- cardLayout: !0,
- showTitle: !0
- }) : "Poster" == viewStyle && (html = cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "auto",
- context: "music",
- centerText: !0,
- overlayMoreButton: !0,
- showTitle: !0
- }));
+ promise.then(function (result) {
+ var html = "";
+ var viewStyle = self.getCurrentViewStyle();
+
+ if (viewStyle == "Thumb") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "backdrop",
+ preferThumb: true,
+ context: 'music',
+ centerText: true,
+ overlayMoreButton: true,
+ showTitle: true
+ });
+ } else if (viewStyle == "ThumbCard") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "backdrop",
+ preferThumb: true,
+ context: 'music',
+ cardLayout: true,
+ showTitle: true
+ });
+ } else if (viewStyle == "PosterCard") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "auto",
+ context: 'music',
+ cardLayout: true,
+ showTitle: true
+ });
+ } else if (viewStyle == "Poster") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "auto",
+ context: 'music',
+ centerText: true,
+ overlayMoreButton: true,
+ showTitle: true
+ });
+ }
+
var elem = context.querySelector("#items");
- elem.innerHTML = html, imageLoader.lazyChildren(elem), libraryBrowser.saveQueryValues(getSavedQueryKey(), query), loading.hide()
- })
+ elem.innerHTML = html;
+ imageLoader.lazyChildren(elem);
+ libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
+ loading.hide();
+ });
}
function fullyReload() {
- self.preRender(), self.renderTab()
+ self.preRender();
+ self.renderTab();
}
- var self = this,
- data = {};
- self.getViewStyles = function() {
- return "Poster,PosterCard,Thumb,ThumbCard".split(",")
- }, self.getCurrentViewStyle = function() {
- return getPageData(tabContent).view
- }, self.setCurrentViewStyle = function(viewStyle) {
- getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), fullyReload()
- }, self.enableViewSelection = !0;
+
+ var self = this;
+ var data = {};
+
+ self.getViewStyles = function () {
+ return "Poster,PosterCard,Thumb,ThumbCard".split(",");
+ };
+
+ self.getCurrentViewStyle = function () {
+ return getPageData(tabContent).view;
+ };
+
+ self.setCurrentViewStyle = function (viewStyle) {
+ getPageData(tabContent).view = viewStyle;
+ libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle);
+ fullyReload();
+ };
+
+ self.enableViewSelection = true;
var promise;
- self.preRender = function() {
- promise = getPromise()
- }, self.renderTab = function() {
- reloadItems(tabContent, promise)
- }
- }
-});
\ No newline at end of file
+
+ self.preRender = function () {
+ promise = getPromise();
+ };
+
+ self.renderTab = function () {
+ reloadItems(tabContent, promise);
+ };
+ };
+});
diff --git a/src/controllers/music/musicplaylists.js b/src/controllers/music/musicplaylists.js
index 511ace73a7..964896077b 100644
--- a/src/controllers/music/musicplaylists.js
+++ b/src/controllers/music/musicplaylists.js
@@ -1,64 +1,81 @@
-define(["libraryBrowser", "cardBuilder", "apphost", "imageLoader", "loading"], function(libraryBrowser, cardBuilder, appHost, imageLoader, loading) {
+define(["libraryBrowser", "cardBuilder", "apphost", "imageLoader", "loading"], function (libraryBrowser, cardBuilder, appHost, imageLoader, loading) {
"use strict";
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
function getPageData() {
- var key = getSavedQueryKey(),
- pageData = data[key];
- return pageData || (pageData = data[key] = {
- query: {
- SortBy: "SortName",
- SortOrder: "Ascending",
- IncludeItemTypes: "Playlist",
- Recursive: !0,
- Fields: "PrimaryImageAspectRatio,SortName,CanDelete",
- StartIndex: 0
- },
- view: libraryBrowser.getSavedView(key) || "Poster"
- }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData
+ var key = getSavedQueryKey();
+ var pageData = data[key];
+
+ if (!pageData) {
+ pageData = data[key] = {
+ query: {
+ SortBy: "SortName",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "Playlist",
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,SortName,CanDelete",
+ StartIndex: 0
+ },
+ view: libraryBrowser.getSavedView(key) || "Poster"
+ };
+ pageData.query.ParentId = params.topParentId;
+ libraryBrowser.loadSavedQueryValues(key, pageData.query);
+ }
+
+ return pageData;
}
function getQuery() {
- return getPageData().query
+ return getPageData().query;
}
function getSavedQueryKey() {
- return libraryBrowser.getSavedQueryKey("genres")
+ return libraryBrowser.getSavedQueryKey("genres");
}
function getPromise() {
loading.show();
var query = getQuery();
- return ApiClient.getItems(ApiClient.getCurrentUserId(), query)
+ return ApiClient.getItems(ApiClient.getCurrentUserId(), query);
}
function reloadItems(context, promise) {
var query = getQuery();
- promise.then(function(result) {
+ promise.then(function (result) {
var html = "";
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: "square",
- showTitle: !0,
- coverImage: !0,
- centerText: !0,
- overlayPlayButton: !0,
- allowBottomPadding: !0,
- cardLayout: !1
+ showTitle: true,
+ coverImage: true,
+ centerText: true,
+ overlayPlayButton: true,
+ allowBottomPadding: true,
+ cardLayout: false
});
var elem = context.querySelector("#items");
- elem.innerHTML = html, imageLoader.lazyChildren(elem), libraryBrowser.saveQueryValues(getSavedQueryKey(), query), loading.hide()
- })
+ elem.innerHTML = html;
+ imageLoader.lazyChildren(elem);
+ libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
+ loading.hide();
+ });
}
- var self = this,
- data = {};
- self.getCurrentViewStyle = function() {
- return getPageData(tabContent).view
+
+ var self = this;
+ var data = {};
+
+ self.getCurrentViewStyle = function () {
+ return getPageData(tabContent).view;
};
+
var promise;
- self.preRender = function() {
- promise = getPromise()
- }, self.renderTab = function() {
- reloadItems(tabContent, promise)
- }
- }
-});
\ No newline at end of file
+
+ self.preRender = function () {
+ promise = getPromise();
+ };
+
+ self.renderTab = function () {
+ reloadItems(tabContent, promise);
+ };
+ };
+});
diff --git a/src/controllers/music/musicrecommended.js b/src/controllers/music/musicrecommended.js
index 5dee7c5f52..fc3371833d 100644
--- a/src/controllers/music/musicrecommended.js
+++ b/src/controllers/music/musicrecommended.js
@@ -1,49 +1,65 @@
-define(["browser", "layoutManager", "userSettings", "inputManager", "loading", "cardBuilder", "dom", "apphost", "imageLoader", "libraryMenu", "playbackManager", "mainTabsManager", "scrollStyles", "emby-itemscontainer", "emby-tabs", "emby-button", "flexStyles"], function(browser, layoutManager, userSettings, inputManager, loading, cardBuilder, dom, appHost, imageLoader, libraryMenu, playbackManager, mainTabsManager) {
+define(["browser", "layoutManager", "userSettings", "inputManager", "loading", "cardBuilder", "dom", "apphost", "imageLoader", "libraryMenu", "playbackManager", "mainTabsManager", "scrollStyles", "emby-itemscontainer", "emby-tabs", "emby-button", "flexStyles"], function (browser, layoutManager, userSettings, inputManager, loading, cardBuilder, dom, appHost, imageLoader, libraryMenu, playbackManager, mainTabsManager) {
"use strict";
function itemsPerRow() {
var screenWidth = dom.getWindowSize().innerWidth;
- return screenWidth >= 1920 ? 9 : screenWidth >= 1200 ? 12 : screenWidth >= 1e3 ? 10 : 8
+
+ if (screenWidth >= 1920) {
+ return 9;
+ }
+
+ if (screenWidth >= 1200) {
+ return 12;
+ }
+
+ if (screenWidth >= 1000) {
+ return 10;
+ }
+
+ return 8;
}
function enableScrollX() {
- return !layoutManager.desktop
+ return !layoutManager.desktop;
}
function getSquareShape() {
- return enableScrollX() ? "overflowSquare" : "square"
+ return enableScrollX() ? "overflowSquare" : "square";
}
function loadLatest(page, parentId) {
loading.show();
- var userId = ApiClient.getCurrentUserId(),
- options = {
- IncludeItemTypes: "Audio",
- Limit: enableScrollX() ? 3 * itemsPerRow() : 2 * itemsPerRow(),
- Fields: "PrimaryImageAspectRatio,BasicSyncInfo",
- ParentId: parentId,
- ImageTypeLimit: 1,
- EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
- EnableTotalRecordCount: !1
- };
- ApiClient.getJSON(ApiClient.getUrl("Users/" + userId + "/Items/Latest", options)).then(function(items) {
- var elem = page.querySelector("#recentlyAddedSongs"),
- supportsImageAnalysis = appHost.supports("imageanalysis");
- supportsImageAnalysis = !1, elem.innerHTML = cardBuilder.getCardsHtml({
+ var userId = ApiClient.getCurrentUserId();
+ var options = {
+ IncludeItemTypes: "Audio",
+ Limit: enableScrollX() ? 3 * itemsPerRow() : 2 * itemsPerRow(),
+ Fields: "PrimaryImageAspectRatio,BasicSyncInfo",
+ ParentId: parentId,
+ ImageTypeLimit: 1,
+ EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
+ EnableTotalRecordCount: false
+ };
+ ApiClient.getJSON(ApiClient.getUrl("Users/" + userId + "/Items/Latest", options)).then(function (items) {
+ var elem = page.querySelector("#recentlyAddedSongs");
+ var supportsImageAnalysis = appHost.supports("imageanalysis");
+ supportsImageAnalysis = false;
+ elem.innerHTML = cardBuilder.getCardsHtml({
items: items,
- showUnplayedIndicator: !1,
- showLatestItemsPopup: !1,
+ showUnplayedIndicator: false,
+ showLatestItemsPopup: false,
shape: getSquareShape(),
- showTitle: !0,
- showParentTitle: !0,
- lazy: !0,
+ showTitle: true,
+ showParentTitle: true,
+ lazy: true,
centerText: !supportsImageAnalysis,
overlayPlayButton: !supportsImageAnalysis,
allowBottomPadding: !enableScrollX(),
cardLayout: supportsImageAnalysis,
- coverImage: !0
- }), imageLoader.lazyChildren(elem), loading.hide()
- })
+ coverImage: true
+ });
+ imageLoader.lazyChildren(elem);
+ loading.hide();
+ });
}
function loadRecentlyPlayed(page, parentId) {
@@ -52,34 +68,42 @@ define(["browser", "layoutManager", "userSettings", "inputManager", "loading", "
SortOrder: "Descending",
IncludeItemTypes: "Audio",
Limit: itemsPerRow(),
- Recursive: !0,
+ Recursive: true,
Fields: "PrimaryImageAspectRatio,AudioInfo",
Filters: "IsPlayed",
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
- EnableTotalRecordCount: !1
+ EnableTotalRecordCount: false
};
- ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function(result) {
+ ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) {
var elem = page.querySelector("#recentlyPlayed");
- result.Items.length ? elem.classList.remove("hide") : elem.classList.add("hide");
- var itemsContainer = elem.querySelector(".itemsContainer"),
- supportsImageAnalysis = appHost.supports("imageanalysis");
- supportsImageAnalysis = !1, itemsContainer.innerHTML = cardBuilder.getCardsHtml({
+
+ if (result.Items.length) {
+ elem.classList.remove("hide");
+ } else {
+ elem.classList.add("hide");
+ }
+
+ var itemsContainer = elem.querySelector(".itemsContainer");
+ var supportsImageAnalysis = appHost.supports("imageanalysis");
+ supportsImageAnalysis = false;
+ itemsContainer.innerHTML = cardBuilder.getCardsHtml({
items: result.Items,
- showUnplayedIndicator: !1,
+ showUnplayedIndicator: false,
shape: getSquareShape(),
- showTitle: !0,
- showParentTitle: !0,
+ showTitle: true,
+ showParentTitle: true,
action: "instantmix",
- lazy: !0,
+ lazy: true,
centerText: !supportsImageAnalysis,
overlayMoreButton: !supportsImageAnalysis,
allowBottomPadding: !enableScrollX(),
cardLayout: supportsImageAnalysis,
- coverImage: !0
- }), imageLoader.lazyChildren(itemsContainer)
- })
+ coverImage: true
+ });
+ imageLoader.lazyChildren(itemsContainer);
+ });
}
function loadFrequentlyPlayed(page, parentId) {
@@ -88,40 +112,53 @@ define(["browser", "layoutManager", "userSettings", "inputManager", "loading", "
SortOrder: "Descending",
IncludeItemTypes: "Audio",
Limit: itemsPerRow(),
- Recursive: !0,
+ Recursive: true,
Fields: "PrimaryImageAspectRatio,AudioInfo",
Filters: "IsPlayed",
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
- EnableTotalRecordCount: !1
+ EnableTotalRecordCount: false
};
- ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function(result) {
+ ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) {
var elem = page.querySelector("#topPlayed");
- result.Items.length ? elem.classList.remove("hide") : elem.classList.add("hide");
- var itemsContainer = elem.querySelector(".itemsContainer"),
- supportsImageAnalysis = appHost.supports("imageanalysis");
- supportsImageAnalysis = !1, itemsContainer.innerHTML = cardBuilder.getCardsHtml({
+
+ if (result.Items.length) {
+ elem.classList.remove("hide");
+ } else {
+ elem.classList.add("hide");
+ }
+
+ var itemsContainer = elem.querySelector(".itemsContainer");
+ var supportsImageAnalysis = appHost.supports("imageanalysis");
+ supportsImageAnalysis = false;
+ itemsContainer.innerHTML = cardBuilder.getCardsHtml({
items: result.Items,
- showUnplayedIndicator: !1,
+ showUnplayedIndicator: false,
shape: getSquareShape(),
- showTitle: !0,
- showParentTitle: !0,
+ showTitle: true,
+ showParentTitle: true,
action: "instantmix",
- lazy: !0,
+ lazy: true,
centerText: !supportsImageAnalysis,
overlayMoreButton: !supportsImageAnalysis,
allowBottomPadding: !enableScrollX(),
cardLayout: supportsImageAnalysis,
- coverImage: !0
- }), imageLoader.lazyChildren(itemsContainer)
- })
+ coverImage: true
+ });
+ imageLoader.lazyChildren(itemsContainer);
+ });
}
function loadSuggestionsTab(page, tabContent, parentId) {
- console.log("loadSuggestionsTab"), loadLatest(tabContent, parentId), loadRecentlyPlayed(tabContent, parentId), loadFrequentlyPlayed(tabContent, parentId), require(["components/favoriteitems"], function(favoriteItems) {
- favoriteItems.render(tabContent, ApiClient.getCurrentUserId(), parentId, ["favoriteArtists", "favoriteAlbums", "favoriteSongs"])
- })
+ console.log("loadSuggestionsTab");
+ loadLatest(tabContent, parentId);
+ loadRecentlyPlayed(tabContent, parentId);
+ loadFrequentlyPlayed(tabContent, parentId);
+
+ require(["components/favoriteitems"], function (favoriteItems) {
+ favoriteItems.render(tabContent, ApiClient.getCurrentUserId(), parentId, ["favoriteArtists", "favoriteAlbums", "favoriteSongs"]);
+ });
}
function getTabs() {
@@ -142,135 +179,227 @@ define(["browser", "layoutManager", "userSettings", "inputManager", "loading", "
}, {
name: Globalize.translate("ButtonSearch"),
cssClass: "searchTabButton"
- }]
+ }];
}
function getDefaultTabIndex(folderId) {
switch (userSettings.get("landing-" + folderId)) {
case "albums":
return 1;
+
case "albumartists":
return 2;
+
case "artists":
return 3;
+
case "playlists":
return 4;
+
case "songs":
return 5;
+
case "genres":
return 6;
+
default:
- return 0
+ return 0;
}
}
- return function(view, params) {
+
+ return function (view, params) {
function reload() {
loading.show();
var tabContent = view.querySelector(".pageTabContent[data-index='0']");
- loadSuggestionsTab(view, tabContent, params.topParentId)
+ loadSuggestionsTab(view, tabContent, params.topParentId);
}
function enableScrollX() {
- return browser.mobile
+ return browser.mobile;
}
function setScrollClasses(elem, scrollX) {
- scrollX ? (elem.classList.add("hiddenScrollX"), layoutManager.tv && elem.classList.add("smoothScrollX"), elem.classList.add("scrollX"), elem.classList.remove("vertical-wrap")) : (elem.classList.remove("hiddenScrollX"), elem.classList.remove("smoothScrollX"), elem.classList.remove("scrollX"), elem.classList.add("vertical-wrap"))
+ if (scrollX) {
+ elem.classList.add("hiddenScrollX");
+
+ if (layoutManager.tv) {
+ elem.classList.add("smoothScrollX");
+ }
+
+ elem.classList.add("scrollX");
+ elem.classList.remove("vertical-wrap");
+ } else {
+ elem.classList.remove("hiddenScrollX");
+ elem.classList.remove("smoothScrollX");
+ elem.classList.remove("scrollX");
+ elem.classList.add("vertical-wrap");
+ }
}
function onBeforeTabChange(e) {
- preLoadTab(view, parseInt(e.detail.selectedTabIndex))
+ preLoadTab(view, parseInt(e.detail.selectedTabIndex));
}
function onTabChange(e) {
- loadTab(view, parseInt(e.detail.selectedTabIndex))
+ loadTab(view, parseInt(e.detail.selectedTabIndex));
}
function getTabContainers() {
- return view.querySelectorAll(".pageTabContent")
+ return view.querySelectorAll(".pageTabContent");
}
function initTabs() {
- mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange)
+ mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange);
}
function getTabController(page, index, callback) {
var depends = [];
+
switch (index) {
case 0:
break;
+
case 1:
depends.push("controllers/music/musicalbums");
break;
+
case 2:
case 3:
depends.push("controllers/music/musicartists");
break;
+
case 4:
depends.push("controllers/music/musicplaylists");
break;
+
case 5:
depends.push("controllers/music/songs");
break;
+
case 6:
depends.push("controllers/music/musicgenres");
break;
+
case 7:
- depends.push("scripts/searchtab")
+ depends.push("scripts/searchtab");
}
- require(depends, function(controllerFactory) {
+
+ require(depends, function (controllerFactory) {
var tabContent;
- 0 == index && (tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"), self.tabContent = tabContent);
+
+ if (0 == index) {
+ tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
+ self.tabContent = tabContent;
+ }
+
var controller = tabControllers[index];
- controller || (tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"), controller = 0 === index ? self : 7 === index ? new controllerFactory(view, tabContent, {
- collectionType: "music",
- parentId: params.topParentId
- }) : new controllerFactory(view, params, tabContent), 2 == index ? controller.mode = "albumartists" : 3 == index && (controller.mode = "artists"), tabControllers[index] = controller, controller.initTab && controller.initTab()), callback(controller)
- })
+
+ if (!controller) {
+ tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
+
+ if (index === 0) {
+ controller = self;
+ } else if (index === 7) {
+ controller = new controllerFactory(view, tabContent, {
+ collectionType: "music",
+ parentId: params.topParentId
+ });
+ } else {
+ controller = new controllerFactory(view, params, tabContent);
+ }
+
+ if (index == 2) {
+ controller.mode = "albumartists";
+ } else if (index == 3) {
+ controller.mode = "artists";
+ }
+
+ tabControllers[index] = controller;
+ if (controller.initTab) {
+ controller.initTab();
+ }
+ }
+
+ callback(controller);
+ });
}
function preLoadTab(page, index) {
- getTabController(page, index, function(controller) {
- -1 == renderedTabs.indexOf(index) && controller.preRender && controller.preRender()
- })
+ getTabController(page, index, function (controller) {
+ if (renderedTabs.indexOf(index) == -1 && controller.preRender) {
+ controller.preRender();
+ }
+ });
}
function loadTab(page, index) {
- currentTabIndex = index, getTabController(page, index, function(controller) {
- initialTabIndex = null, -1 == renderedTabs.indexOf(index) && (renderedTabs.push(index), controller.renderTab())
- })
+ currentTabIndex = index;
+ getTabController(page, index, function (controller) {
+ initialTabIndex = null;
+
+ if (renderedTabs.indexOf(index) == -1) {
+ renderedTabs.push(index);
+ controller.renderTab();
+ }
+ });
}
function onInputCommand(e) {
switch (e.detail.command) {
case "search":
- e.preventDefault(), Dashboard.navigate("search.html?collectionType=music&parentId=" + params.topParentId)
+ e.preventDefault();
+ Dashboard.navigate("search.html?collectionType=music&parentId=" + params.topParentId);
}
}
- var isViewRestored, self = this,
- currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)),
- initialTabIndex = currentTabIndex;
- self.initTab = function() {
- for (var tabContent = view.querySelector(".pageTabContent[data-index='0']"), containers = tabContent.querySelectorAll(".itemsContainer"), i = 0, length = containers.length; i < length; i++) setScrollClasses(containers[i], enableScrollX())
- }, self.renderTab = function() {
- reload()
- };
- var tabControllers = [],
- renderedTabs = [];
- view.addEventListener("viewshow", function(e) {
- if (isViewRestored = e.detail.isRestored, initTabs(), !view.getAttribute("data-title")) {
- var parentId = params.topParentId;
- parentId ? ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function(item) {
- view.setAttribute("data-title", item.Name), libraryMenu.setTitle(item.Name)
- }) : (view.setAttribute("data-title", Globalize.translate("TabMusic")), libraryMenu.setTitle(Globalize.translate("TabMusic")))
+
+ var isViewRestored;
+ var self = this;
+ var currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId));
+ var initialTabIndex = currentTabIndex;
+
+ self.initTab = function () {
+ var tabContent = view.querySelector(".pageTabContent[data-index='0']");
+ var containers = tabContent.querySelectorAll(".itemsContainer");
+
+ for (var i = 0, length = containers.length; i < length; i++) {
+ setScrollClasses(containers[i], enableScrollX());
}
- inputManager.on(window, onInputCommand)
- }), view.addEventListener("viewbeforehide", function(e) {
- inputManager.off(window, onInputCommand)
- }), view.addEventListener("viewdestroy", function(e) {
- tabControllers.forEach(function(t) {
- t.destroy && t.destroy()
- })
- })
- }
-});
\ No newline at end of file
+ };
+
+ self.renderTab = function () {
+ reload();
+ };
+
+ var tabControllers = [];
+ var renderedTabs = [];
+ view.addEventListener("viewshow", function (e) {
+ isViewRestored = e.detail.isRestored;
+ initTabs();
+ if (!view.getAttribute("data-title")) {
+ var parentId = params.topParentId;
+
+ if (parentId) {
+ ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function (item) {
+ view.setAttribute("data-title", item.Name);
+ libraryMenu.setTitle(item.Name);
+ });
+ } else {
+ view.setAttribute("data-title", Globalize.translate("TabMusic"));
+ libraryMenu.setTitle(Globalize.translate("TabMusic"));
+ }
+ }
+
+ inputManager.on(window, onInputCommand);
+ });
+ view.addEventListener("viewbeforehide", function (e) {
+ inputManager.off(window, onInputCommand);
+ });
+ view.addEventListener("viewdestroy", function (e) {
+ tabControllers.forEach(function (t) {
+ if (t.destroy) {
+ t.destroy();
+ }
+ });
+ });
+ };
+});
diff --git a/src/controllers/music/songs.js b/src/controllers/music/songs.js
index f03abe75ff..4806195edd 100644
--- a/src/controllers/music/songs.js
+++ b/src/controllers/music/songs.js
@@ -1,135 +1,185 @@
-define(["events", "libraryBrowser", "imageLoader", "listView", "loading", "emby-itemscontainer"], function(events, libraryBrowser, imageLoader, listView, loading) {
+define(["events", "libraryBrowser", "imageLoader", "listView", "loading", "emby-itemscontainer"], function (events, libraryBrowser, imageLoader, listView, loading) {
"use strict";
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
function getPageData(context) {
- var key = getSavedQueryKey(context),
- pageData = data[key];
- return pageData || (pageData = data[key] = {
- query: {
- SortBy: "Album,SortName",
- SortOrder: "Ascending",
- IncludeItemTypes: "Audio",
- Recursive: !0,
- Fields: "AudioInfo,ParentId",
- Limit: 100,
- StartIndex: 0,
- ImageTypeLimit: 1,
- EnableImageTypes: "Primary"
- }
- }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData
+ var key = getSavedQueryKey(context);
+ var pageData = data[key];
+
+ if (!pageData) {
+ pageData = data[key] = {
+ query: {
+ SortBy: "Album,SortName",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "Audio",
+ Recursive: true,
+ Fields: "AudioInfo,ParentId",
+ Limit: 100,
+ StartIndex: 0,
+ ImageTypeLimit: 1,
+ EnableImageTypes: "Primary"
+ }
+ };
+ pageData.query.ParentId = params.topParentId;
+ libraryBrowser.loadSavedQueryValues(key, pageData.query);
+ }
+
+ return pageData;
}
function getQuery(context) {
- return getPageData(context).query
+ return getPageData(context).query;
}
function getSavedQueryKey(context) {
- return context.savedQueryKey || (context.savedQueryKey = libraryBrowser.getSavedQueryKey("songs")), context.savedQueryKey
+ if (!context.savedQueryKey) {
+ context.savedQueryKey = libraryBrowser.getSavedQueryKey("songs");
+ }
+
+ return context.savedQueryKey;
}
function reloadItems(page) {
loading.show();
isLoading = true;
var query = getQuery(page);
- ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function(result) {
+ ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) {
function onNextPageClick() {
- if (isLoading) return;
- query.StartIndex += query.Limit, reloadItems(tabContent)
+ if (isLoading) {
+ return;
+ }
+
+ query.StartIndex += query.Limit;
+ reloadItems(tabContent);
}
function onPreviousPageClick() {
- if (isLoading) return;
- query.StartIndex -= query.Limit, reloadItems(tabContent)
+ if (isLoading) {
+ return;
+ }
+
+ query.StartIndex -= query.Limit;
+ reloadItems(tabContent);
}
+
window.scrollTo(0, 0);
- var i, length, pagingHtml = libraryBrowser.getQueryPagingHtml({
- startIndex: query.StartIndex,
- limit: query.Limit,
- totalRecordCount: result.TotalRecordCount,
- showLimit: !1,
- updatePageSizeSetting: !1,
- addLayoutButton: !1,
- sortButton: !1,
- filterButton: !1
- }),
- html = listView.getListViewHtml({
- items: result.Items,
- action: "playallfromhere",
- smallIcon: !0,
- artist: !0,
- addToListButton: !0
- }),
- elems = tabContent.querySelectorAll(".paging");
- for (i = 0, length = elems.length; i < length; i++) elems[i].innerHTML = pagingHtml;
- for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick);
- for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick);
+ var i;
+ var length;
+ var pagingHtml = libraryBrowser.getQueryPagingHtml({
+ startIndex: query.StartIndex,
+ limit: query.Limit,
+ totalRecordCount: result.TotalRecordCount,
+ showLimit: false,
+ updatePageSizeSetting: false,
+ addLayoutButton: false,
+ sortButton: false,
+ filterButton: false
+ });
+ var html = listView.getListViewHtml({
+ items: result.Items,
+ action: "playallfromhere",
+ smallIcon: true,
+ artist: true,
+ addToListButton: true
+ });
+ var elems = tabContent.querySelectorAll(".paging");
+
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].innerHTML = pagingHtml;
+ }
+
+ elems = tabContent.querySelectorAll(".btnNextPage");
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onNextPageClick);
+ }
+
+ elems = tabContent.querySelectorAll(".btnPreviousPage");
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onPreviousPageClick);
+ }
+
var itemsContainer = tabContent.querySelector(".itemsContainer");
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
loading.hide();
isLoading = false;
- })
+ });
}
- var self = this,
- data = {},
- isLoading = false;
- self.showFilterMenu = function() {
- require(["components/filterdialog/filterdialog"], function(filterDialogFactory) {
- var filterDialog = new filterDialogFactory({
- query: getQuery(tabContent),
- mode: "songs",
- serverId: ApiClient.serverId()
- });
- events.on(filterDialog, "filterchange", function() {
- getQuery(tabContent).StartIndex = 0, reloadItems(tabContent)
- }), filterDialog.show()
- })
- }, self.getCurrentViewStyle = function() {
- return getPageData(tabContent).view
- },
- function(tabContent) {
- tabContent.querySelector(".btnFilter").addEventListener("click", function() {
- self.showFilterMenu()
- }), tabContent.querySelector(".btnSort").addEventListener("click", function(e) {
- libraryBrowser.showSortMenu({
- items: [{
- name: Globalize.translate("OptionTrackName"),
- id: "Name"
- }, {
- name: Globalize.translate("OptionAlbum"),
- id: "Album,SortName"
- }, {
- name: Globalize.translate("OptionAlbumArtist"),
- id: "AlbumArtist,Album,SortName"
- }, {
- name: Globalize.translate("OptionArtist"),
- id: "Artist,Album,SortName"
- }, {
- name: Globalize.translate("OptionDateAdded"),
- id: "DateCreated,SortName"
- }, {
- name: Globalize.translate("OptionDatePlayed"),
- id: "DatePlayed,SortName"
- }, {
- name: Globalize.translate("OptionPlayCount"),
- id: "PlayCount,SortName"
- }, {
- name: Globalize.translate("OptionReleaseDate"),
- id: "PremiereDate,AlbumArtist,Album,SortName"
- }, {
- name: Globalize.translate("OptionRuntime"),
- id: "Runtime,AlbumArtist,Album,SortName"
- }],
- callback: function() {
- getQuery(tabContent).StartIndex = 0, reloadItems(tabContent)
- },
- query: getQuery(tabContent),
- button: e.target
- })
- })
- }(tabContent), self.renderTab = function() {
- reloadItems(tabContent)
- }, self.destroy = function() {}
- }
+
+ var self = this;
+ var data = {};
+ var isLoading = false;
+
+ self.showFilterMenu = function () {
+ require(["components/filterdialog/filterdialog"], function (filterDialogFactory) {
+ var filterDialog = new filterDialogFactory({
+ query: getQuery(tabContent),
+ mode: "songs",
+ serverId: ApiClient.serverId()
+ });
+ events.on(filterDialog, "filterchange", function () {
+ getQuery(tabContent).StartIndex = 0;
+ reloadItems(tabContent);
+ });
+ filterDialog.show();
+ });
+ };
+
+ self.getCurrentViewStyle = function () {
+ return getPageData(tabContent).view;
+ };
+
+ function initPage(tabContent) {
+ tabContent.querySelector(".btnFilter").addEventListener("click", function () {
+ self.showFilterMenu();
+ });
+ tabContent.querySelector(".btnSort").addEventListener("click", function (e) {
+ libraryBrowser.showSortMenu({
+ items: [{
+ name: Globalize.translate("OptionTrackName"),
+ id: "Name"
+ }, {
+ name: Globalize.translate("OptionAlbum"),
+ id: "Album,SortName"
+ }, {
+ name: Globalize.translate("OptionAlbumArtist"),
+ id: "AlbumArtist,Album,SortName"
+ }, {
+ name: Globalize.translate("OptionArtist"),
+ id: "Artist,Album,SortName"
+ }, {
+ name: Globalize.translate("OptionDateAdded"),
+ id: "DateCreated,SortName"
+ }, {
+ name: Globalize.translate("OptionDatePlayed"),
+ id: "DatePlayed,SortName"
+ }, {
+ name: Globalize.translate("OptionPlayCount"),
+ id: "PlayCount,SortName"
+ }, {
+ name: Globalize.translate("OptionReleaseDate"),
+ id: "PremiereDate,AlbumArtist,Album,SortName"
+ }, {
+ name: Globalize.translate("OptionRuntime"),
+ id: "Runtime,AlbumArtist,Album,SortName"
+ }],
+ callback: function () {
+ getQuery(tabContent).StartIndex = 0;
+ reloadItems(tabContent);
+ },
+ query: getQuery(tabContent),
+ button: e.target
+ });
+ });
+ }
+
+ initPage(tabContent);
+
+ self.renderTab = function () {
+ reloadItems(tabContent);
+ };
+
+ self.destroy = function () {};
+ };
});
diff --git a/src/controllers/networking.js b/src/controllers/networking.js
index ef19732ee4..a6e42967a4 100644
--- a/src/controllers/networking.js
+++ b/src/controllers/networking.js
@@ -72,8 +72,8 @@ define(["loading", "libraryMenu", "globalize", "emby-checkbox", "emby-select"],
}
function validateHttps(form) {
- var certPath = form.querySelector("#txtCertificatePath").value || null,
- httpsMode = form.querySelector("#selectHttpsMode").value;
+ var certPath = form.querySelector("#txtCertificatePath").value || null;
+ var httpsMode = form.querySelector("#selectHttpsMode").value;
return "enabled" !== httpsMode && "required" !== httpsMode || certPath ? Promise.resolve() : new Promise(function(resolve, reject) {
return alertText({
title: globalize.translate("TitleHostingSettings"),
diff --git a/src/controllers/notificationsetting.js b/src/controllers/notificationsetting.js
index a9333ba5a3..70e6adaf61 100644
--- a/src/controllers/notificationsetting.js
+++ b/src/controllers/notificationsetting.js
@@ -1,85 +1,122 @@
-define(["jQuery", "emby-checkbox", "fnchecked"], function($) {
+define(["jQuery", "emby-checkbox", "fnchecked"], function ($) {
"use strict";
function fillItems(elem, items, cssClass, idPrefix, currentList, isEnabledList) {
var html = '
';
- html += items.map(function(u) {
- var isChecked = isEnabledList ? -1 != currentList.indexOf(u.Id) : -1 == currentList.indexOf(u.Id),
- checkedHtml = isChecked ? ' checked="checked"' : "";
- return '" + u.Name + " "
- }).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 '
" + u.Name + " ";
+ }).join("");
+ html += "
";
+ elem.html(html).trigger("create");
}
function reload(page) {
- var type = getParameterByName("type"),
- promise1 = ApiClient.getUsers(),
- promise2 = ApiClient.getNamedConfiguration(notificationsConfigurationKey),
- promise3 = ApiClient.getJSON(ApiClient.getUrl("Notifications/Types")),
- promise4 = ApiClient.getJSON(ApiClient.getUrl("Notifications/Services"));
- Promise.all([promise1, promise2, promise3, promise4]).then(function(responses) {
- var users = responses[0],
- notificationOptions = responses[1],
- types = responses[2],
- services = responses[3],
- notificationConfig = notificationOptions.Options.filter(function(n) {
- return n.Type == type
- })[0],
- typeInfo = types.filter(function(n) {
- return n.Type == type
- })[0] || {};
- typeInfo.IsBasedOnUserEvent ? $(".monitorUsers", page).show() : $(".monitorUsers", page).hide(), $(".notificationType", page).html(typeInfo.Name || "Unknown Notification"), notificationConfig || (notificationConfig = {
- DisabledMonitorUsers: [],
- SendToUsers: [],
- DisabledServices: [],
- SendToUserMode: "Admins"
- }), fillItems($(".monitorUsersList", page), users, "chkMonitor", "chkMonitor", notificationConfig.DisabledMonitorUsers), fillItems($(".sendToUsersList", page), users, "chkSendTo", "chkSendTo", notificationConfig.SendToUsers, !0), fillItems($(".servicesList", page), services, "chkService", "chkService", notificationConfig.DisabledServices), $("#chkEnabled", page).checked(notificationConfig.Enabled || !1), $("#selectUsers", page).val(notificationConfig.SendToUserMode).trigger("change")
- })
+ var type = getParameterByName("type");
+ var promise1 = ApiClient.getUsers();
+ var promise2 = ApiClient.getNamedConfiguration(notificationsConfigurationKey);
+ var promise3 = ApiClient.getJSON(ApiClient.getUrl("Notifications/Types"));
+ var promise4 = ApiClient.getJSON(ApiClient.getUrl("Notifications/Services"));
+ Promise.all([promise1, promise2, promise3, promise4]).then(function (responses) {
+ var users = responses[0];
+ var notificationOptions = responses[1];
+ var types = responses[2];
+ var services = responses[3];
+ var notificationConfig = notificationOptions.Options.filter(function (n) {
+ return n.Type == type;
+ })[0];
+ var typeInfo = types.filter(function (n) {
+ return n.Type == type;
+ })[0] || {};
+
+ if (typeInfo.IsBasedOnUserEvent) {
+ $(".monitorUsers", page).show();
+ } else {
+ $(".monitorUsers", page).hide();
+ }
+
+ $(".notificationType", page).html(typeInfo.Name || "Unknown Notification");
+
+ if (!notificationConfig) {
+ notificationConfig = {
+ DisabledMonitorUsers: [],
+ SendToUsers: [],
+ DisabledServices: [],
+ SendToUserMode: "Admins"
+ };
+ }
+
+ fillItems($(".monitorUsersList", page), users, "chkMonitor", "chkMonitor", notificationConfig.DisabledMonitorUsers);
+ fillItems($(".sendToUsersList", page), users, "chkSendTo", "chkSendTo", notificationConfig.SendToUsers, true);
+ fillItems($(".servicesList", page), services, "chkService", "chkService", notificationConfig.DisabledServices);
+ $("#chkEnabled", page).checked(notificationConfig.Enabled || false);
+ $("#selectUsers", page).val(notificationConfig.SendToUserMode).trigger("change");
+ });
}
function save(page) {
- var type = getParameterByName("type"),
- promise1 = ApiClient.getNamedConfiguration(notificationsConfigurationKey),
- promise2 = ApiClient.getJSON(ApiClient.getUrl("Notifications/Types"));
- Promise.all([promise1, promise2]).then(function(responses) {
- var notificationOptions = responses[0],
- types = responses[1],
- notificationConfig = notificationOptions.Options.filter(function(n) {
- return n.Type == type
- })[0];
- notificationConfig || (notificationConfig = {
- Type: type
- }, notificationOptions.Options.push(notificationConfig));
- types.filter(function(n) {
- return n.Type == type
+ var type = getParameterByName("type");
+ var promise1 = ApiClient.getNamedConfiguration(notificationsConfigurationKey);
+ var promise2 = ApiClient.getJSON(ApiClient.getUrl("Notifications/Types"));
+ Promise.all([promise1, promise2]).then(function (responses) {
+ var notificationOptions = responses[0];
+ var types = responses[1];
+ var notificationConfig = notificationOptions.Options.filter(function (n) {
+ return n.Type == type;
})[0];
- notificationConfig.Enabled = $("#chkEnabled", page).checked(), notificationConfig.SendToUserMode = $("#selectUsers", page).val(), notificationConfig.DisabledMonitorUsers = $(".chkMonitor", page).get().filter(function(c) {
- return !c.checked
- }).map(function(c) {
- return c.getAttribute("data-itemid")
- }), notificationConfig.SendToUsers = $(".chkSendTo", page).get().filter(function(c) {
- return c.checked
- }).map(function(c) {
- return c.getAttribute("data-itemid")
- }), notificationConfig.DisabledServices = $(".chkService", page).get().filter(function(c) {
- return !c.checked
- }).map(function(c) {
- return c.getAttribute("data-itemid")
- }), ApiClient.updateNamedConfiguration(notificationsConfigurationKey, notificationOptions).then(function(r) {
- Dashboard.processServerConfigurationUpdateResult(), Dashboard.navigate("notificationsettings.html")
- })
- })
+
+ if (!notificationConfig) {
+ notificationConfig = {
+ Type: type
+ };
+ notificationOptions.Options.push(notificationConfig);
+ }
+
+ types.filter(function (n) {
+ return n.Type == type;
+ })[0];
+ notificationConfig.Enabled = $("#chkEnabled", page).checked();
+ notificationConfig.SendToUserMode = $("#selectUsers", page).val();
+ notificationConfig.DisabledMonitorUsers = $(".chkMonitor", page).get().filter(function (c) {
+ return !c.checked;
+ }).map(function (c) {
+ return c.getAttribute("data-itemid");
+ });
+ notificationConfig.SendToUsers = $(".chkSendTo", page).get().filter(function (c) {
+ return c.checked;
+ }).map(function (c) {
+ return c.getAttribute("data-itemid");
+ });
+ notificationConfig.DisabledServices = $(".chkService", page).get().filter(function (c) {
+ return !c.checked;
+ }).map(function (c) {
+ return c.getAttribute("data-itemid");
+ });
+ ApiClient.updateNamedConfiguration(notificationsConfigurationKey, notificationOptions).then(function (r) {
+ Dashboard.processServerConfigurationUpdateResult();
+ Dashboard.navigate("notificationsettings.html");
+ });
+ });
}
function onSubmit() {
- return save($(this).parents(".page")), !1
+ save($(this).parents(".page"));
+ return false;
}
+
var notificationsConfigurationKey = "notifications";
- $(document).on("pageinit", "#notificationSettingPage", function() {
+ $(document).on("pageinit", "#notificationSettingPage", function () {
var page = this;
- $("#selectUsers", page).on("change", function() {
- "Custom" == this.value ? $(".selectCustomUsers", page).show() : $(".selectCustomUsers", page).hide()
- }), $(".notificationSettingForm").off("submit", onSubmit).on("submit", onSubmit)
- }).on("pageshow", "#notificationSettingPage", function() {
- reload(this)
- })
-});
\ No newline at end of file
+ $("#selectUsers", page).on("change", function () {
+ if ("Custom" == this.value) {
+ $(".selectCustomUsers", page).show();
+ } else {
+ $(".selectCustomUsers", page).hide();
+ }
+ });
+ $(".notificationSettingForm").off("submit", onSubmit).on("submit", onSubmit);
+ }).on("pageshow", "#notificationSettingPage", function () {
+ reload(this);
+ });
+});
diff --git a/src/controllers/nowplayingpage.js b/src/controllers/nowplayingpage.js
index 7f1b9b3f11..6fcdb2a79c 100644
--- a/src/controllers/nowplayingpage.js
+++ b/src/controllers/nowplayingpage.js
@@ -1,11 +1,22 @@
-define(["components/remotecontrol/remotecontrol", "libraryMenu", "emby-button"], function(remotecontrolFactory, libraryMenu) {
+define(["components/remotecontrol/remotecontrol", "libraryMenu", "emby-button"], function (remotecontrolFactory, libraryMenu) {
"use strict";
- return function(view, params) {
- var remoteControl = new remotecontrolFactory;
- remoteControl.init(view, view.querySelector(".remoteControlContent")), view.addEventListener("viewshow", function(e) {
- libraryMenu.setTransparentMenu(!0), remoteControl && remoteControl.onShow()
- }), view.addEventListener("viewbeforehide", function(e) {
- libraryMenu.setTransparentMenu(!1), remoteControl && remoteControl.destroy()
- })
- }
-});
\ No newline at end of file
+
+ return function (view, params) {
+ var remoteControl = new remotecontrolFactory();
+ remoteControl.init(view, view.querySelector(".remoteControlContent"));
+ view.addEventListener("viewshow", function (e) {
+ libraryMenu.setTransparentMenu(true);
+
+ if (remoteControl) {
+ remoteControl.onShow();
+ }
+ });
+ view.addEventListener("viewbeforehide", function (e) {
+ libraryMenu.setTransparentMenu(false);
+
+ if (remoteControl) {
+ remoteControl.destroy();
+ }
+ });
+ };
+});
diff --git a/src/controllers/playbackconfiguration.js b/src/controllers/playbackconfiguration.js
index 35a780949d..76c704f7eb 100644
--- a/src/controllers/playbackconfiguration.js
+++ b/src/controllers/playbackconfiguration.js
@@ -1,16 +1,25 @@
-define(["jQuery", "loading", "libraryMenu"], function($, loading, libraryMenu) {
+define(["jQuery", "loading", "libraryMenu"], function ($, loading, libraryMenu) {
"use strict";
function loadPage(page, config) {
- $("#txtMinResumePct", page).val(config.MinResumePct), $("#txtMaxResumePct", page).val(config.MaxResumePct), $("#txtMinResumeDuration", page).val(config.MinResumeDurationSeconds), loading.hide()
+ $("#txtMinResumePct", page).val(config.MinResumePct);
+ $("#txtMaxResumePct", page).val(config.MaxResumePct);
+ $("#txtMinResumeDuration", page).val(config.MinResumeDurationSeconds);
+ loading.hide();
}
function onSubmit() {
loading.show();
var form = this;
- return ApiClient.getServerConfiguration().then(function(config) {
- config.MinResumePct = $("#txtMinResumePct", form).val(), config.MaxResumePct = $("#txtMaxResumePct", form).val(), config.MinResumeDurationSeconds = $("#txtMinResumeDuration", form).val(), ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult)
- }), !1
+ ApiClient.getServerConfiguration().then(function (config) {
+ config.MinResumePct = $('#txtMinResumePct', form).val();
+ config.MaxResumePct = $('#txtMaxResumePct', form).val();
+ config.MinResumeDurationSeconds = $('#txtMinResumeDuration', form).val();
+
+ ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult);
+ });
+
+ return false;
}
function getTabs() {
@@ -23,17 +32,17 @@ define(["jQuery", "loading", "libraryMenu"], function($, loading, libraryMenu) {
}, {
href: "streamingsettings.html",
name: Globalize.translate("TabStreaming")
- }]
+ }];
}
- $(document).on("pageinit", "#playbackConfigurationPage", function() {
+ $(document).on("pageinit", "#playbackConfigurationPage", function () {
$(".playbackConfigurationForm").off("submit", onSubmit).on("submit", onSubmit)
- }).on("pageshow", "#playbackConfigurationPage", function() {
+ }).on("pageshow", "#playbackConfigurationPage", function () {
loading.show();
libraryMenu.setTabs("playback", 1, getTabs);
var page = this;
- ApiClient.getServerConfiguration().then(function(config) {
- loadPage(page, config)
- })
- })
-});
\ No newline at end of file
+ ApiClient.getServerConfiguration().then(function (config) {
+ loadPage(page, config);
+ });
+ });
+});
diff --git a/src/controllers/scheduledtaskpage.js b/src/controllers/scheduledtaskpage.js
index 32838c6de3..7a3e1dbcd6 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 '
' + o.name + " "
- }).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 '
' + o.name + ' ';
+ }).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 += '
delete ', html += "
"
+
+ html += "
";
+ html += '
delete ';
+ 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 == 0.25) {
+ return "Every 15 minutes";
+ }
+ if (hours == 0.5) {
+ return "Every 30 minutes";
+ }
+ if (hours == 0.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/scheduledtaskspage.js b/src/controllers/scheduledtaskspage.js
index bbc2d24317..87297dbcf3 100644
--- a/src/controllers/scheduledtaskspage.js
+++ b/src/controllers/scheduledtaskspage.js
@@ -137,7 +137,8 @@ define(["jQuery", "loading", "events", "globalize", "serverNotifications", "huma
pollInterval && clearInterval(pollInterval);
}
- var pollInterval, serverId = ApiClient.serverId();
+ var pollInterval;
+ var serverId = ApiClient.serverId();
$(".divScheduledTasks", view).on("click", ".btnStartTask", function() {
var button = this;
diff --git a/src/controllers/searchpage.js b/src/controllers/searchpage.js
index b188a8b318..b260ef5751 100644
--- a/src/controllers/searchpage.js
+++ b/src/controllers/searchpage.js
@@ -1,21 +1,36 @@
-define(["focusManager", "searchFields", "searchResults", "events"], function(focusManager, SearchFields, SearchResults, events) {
+define(["focusManager", "searchFields", "searchResults", "events"], function (focusManager, SearchFields, SearchResults, events) {
"use strict";
- return function(view, params) {
+
+ return function (view, params) {
function onSearch(e, value) {
- self.searchResults.search(value)
+ self.searchResults.search(value);
}
+
var self = this;
- view.addEventListener("viewshow", function() {
- self.searchFields || (self.searchFields = new SearchFields({
- element: view.querySelector(".searchFields")
- }), self.searchResults = new SearchResults({
- element: view.querySelector(".searchResults"),
- serverId: params.serverId || ApiClient.serverId(),
- parentId: params.parentId,
- collectionType: params.collectionType
- }), events.on(self.searchFields, "search", onSearch))
- }), view.addEventListener("viewdestroy", function() {
- self.searchFields && (self.searchFields.destroy(), self.searchFields = null), self.searchResults && (self.searchResults.destroy(), self.searchResults = null)
- })
- }
-});
\ No newline at end of file
+ view.addEventListener("viewshow", function () {
+ if (!self.searchFields) {
+ self.searchFields = new SearchFields({
+ element: view.querySelector(".searchFields")
+ });
+ self.searchResults = new SearchResults({
+ element: view.querySelector(".searchResults"),
+ serverId: params.serverId || ApiClient.serverId(),
+ parentId: params.parentId,
+ collectionType: params.collectionType
+ });
+ events.on(self.searchFields, "search", onSearch);
+ }
+ });
+ view.addEventListener("viewdestroy", function () {
+ if (self.searchFields) {
+ self.searchFields.destroy();
+ self.searchFields = null;
+ }
+
+ if (self.searchResults) {
+ self.searchResults.destroy();
+ self.searchResults = null;
+ }
+ });
+ };
+});
diff --git a/src/controllers/selectserver.js b/src/controllers/selectserver.js
index 385ab69ca2..255f685572 100644
--- a/src/controllers/selectserver.js
+++ b/src/controllers/selectserver.js
@@ -1,50 +1,66 @@
-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", "browser", "material-icons", "flexStyles", "emby-scroller", "emby-itemscontainer", "cardStyle", "emby-button"], function (loading, appRouter, layoutManager, appSettings, appHost, focusManager, connectionManager, globalize, actionSheet, dom, browser) {
"use strict";
+ var enableFocusTransform = !browser.slow && !browser.edge;
+
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 html = items.map(function (item) {
+ var cardImageContainer;
+
+ if (item.showIcon) {
+ cardImageContainer = '
' + item.icon + " ";
+ } else {
+ cardImageContainer = '
';
+ }
+
+ // TODO move card creation code to Card component
+
+ var cssClass = "card overflowSquareCard loginSquareCard scalableCard overflowSquareCard-scalable";
+
+ if (layoutManager.tv) {
+ cssClass += " show-focus";
+
+ if (enableFocusTransform) {
+ cssClass += " show-animation";
}
- var cardBoxCssClass = "cardBox";
- if (layoutManager.tv) {
- cardBoxCssClass += " cardBox-focustransform";
- }
- var innerOpening = '
';
- var cardContainer = '';
- cardContainer += '
';
- cardContainer += innerOpening;
- cardContainer += '';
- cardContainer += '
';
- cardContainer += '
';
- cardContainer += '
';
- cardContainer += '
';
- cardContainer += cardImageContainer;
- cardContainer += '
';
- cardContainer += '
';
- cardContainer += '
';
- cardContainer += ' ';
- return cardContainer;
+ }
+
+ var cardBoxCssClass = "cardBox";
+
+ var innerOpening = '
';
+ var cardContainer = '';
+ cardContainer += '
';
+ cardContainer += innerOpening;
+ cardContainer += '';
+ cardContainer += '
';
+ cardContainer += '
';
+ cardContainer += '
';
+ cardContainer += '
';
+ cardContainer += cardImageContainer;
+ cardContainer += '
';
+ cardContainer += '
';
+ cardContainer += '
';
+ cardContainer += ' ';
+ return cardContainer;
}).join("");
var itemsContainer = view.querySelector(".servers");
+
if (!items.length) {
html = '
' + globalize.translate("MessageNoServersAvailable") + "
";
}
+
itemsContainer.innerHTML = html;
loading.hide();
}
@@ -73,7 +89,7 @@ define(["loading", "appRouter", "layoutManager", "appSettings", "apphost", "focu
}
function alertTextWithOptions(options) {
- require(["alert"], function(alert) {
+ require(["alert"], function (alert) {
alert(options);
});
}
@@ -82,38 +98,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 +152,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 +180,29 @@ define(["loading", "appRouter", "layoutManager", "appSettings", "apphost", "focu
var servers;
updatePageStyle(view, params);
-
- view.addEventListener("viewshow", function(e) {
+ view.addEventListener("viewshow", function (e) {
var isRestored = e.detail.isRestored;
appRouter.setTitle(null);
- if (!isRestored) loadServers();
+
+ if (!isRestored) {
+ loadServers();
+ }
});
- view.querySelector(".servers").addEventListener("click", function(e) {
+ view.querySelector(".servers").addEventListener("click", function (e) {
var card = dom.parentWithClass(e.target, "card");
+
if (card) {
var url = card.getAttribute("data-url");
+
if (url) {
appRouter.show(url);
} else {
var id = card.getAttribute("data-id");
- onServerClick(servers.filter(function(s) {
+ onServerClick(servers.filter(function (s) {
return s.Id === id;
})[0]);
}
}
- })
- }
+ });
+ };
});
diff --git a/src/controllers/serveractivity.js b/src/controllers/serveractivity.js
index 2b43215c93..fb3b8112dc 100644
--- a/src/controllers/serveractivity.js
+++ b/src/controllers/serveractivity.js
@@ -1,14 +1,31 @@
-define(["components/activitylog", "globalize"], function(ActivityLog, globalize) {
+define(["components/activitylog", "globalize"], function (ActivityLog, globalize) {
"use strict";
- return function(view, params) {
+
+ return function (view, params) {
var activityLog;
- "false" !== params.useractivity ? (view.querySelector(".activityItems").setAttribute("data-useractivity", "true"), view.querySelector(".sectionTitle").innerHTML = globalize.translate("HeaderActivity")) : (view.querySelector(".activityItems").setAttribute("data-useractivity", "false"), view.querySelector(".sectionTitle").innerHTML = globalize.translate("Alerts")), view.addEventListener("viewshow", function() {
- activityLog || (activityLog = new ActivityLog({
- serverId: ApiClient.serverId(),
- element: view.querySelector(".activityItems")
- }))
- }), view.addEventListener("viewdestroy", function() {
- activityLog && activityLog.destroy(), activityLog = null
- })
- }
-});
\ No newline at end of file
+
+ if (params.useractivity !== "false") {
+ view.querySelector(".activityItems").setAttribute("data-useractivity", "true");
+ view.querySelector(".sectionTitle").innerHTML = globalize.translate("HeaderActivity");
+ } else {
+ view.querySelector(".activityItems").setAttribute("data-useractivity", "false");
+ view.querySelector(".sectionTitle").innerHTML = globalize.translate("Alerts");
+ }
+
+ view.addEventListener("viewshow", function () {
+ if (!activityLog) {
+ activityLog = new ActivityLog({
+ serverId: ApiClient.serverId(),
+ element: view.querySelector(".activityItems")
+ });
+ }
+ });
+ view.addEventListener("viewdestroy", function () {
+ if (activityLog) {
+ activityLog.destroy();
+ }
+
+ activityLog = null;
+ });
+ };
+});
diff --git a/src/controllers/shows/episodes.js b/src/controllers/shows/episodes.js
index 1f783631fb..42d9d89f7a 100644
--- a/src/controllers/shows/episodes.js
+++ b/src/controllers/shows/episodes.js
@@ -1,169 +1,233 @@
-define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "emby-itemscontainer"], function(loading, events, libraryBrowser, imageLoader, listView, cardBuilder) {
+define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "emby-itemscontainer"], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder) {
"use strict";
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
function getPageData(context) {
- var key = getSavedQueryKey(context),
- pageData = data[key];
- return pageData || (pageData = data[key] = {
- query: {
- SortBy: "SeriesSortName,SortName",
- SortOrder: "Ascending",
- IncludeItemTypes: "Episode",
- Recursive: !0,
- Fields: "PrimaryImageAspectRatio,MediaSourceCount,UserData",
- IsMissing: !1,
- ImageTypeLimit: 1,
- EnableImageTypes: "Primary,Backdrop,Thumb",
- StartIndex: 0,
- Limit: pageSize
- },
- view: libraryBrowser.getSavedView(key) || "Poster"
- }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData
+ var key = getSavedQueryKey(context);
+ var pageData = data[key];
+
+ if (!pageData) {
+ pageData = data[key] = {
+ query: {
+ SortBy: "SeriesSortName,SortName",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "Episode",
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,MediaSourceCount,UserData",
+ IsMissing: false,
+ ImageTypeLimit: 1,
+ EnableImageTypes: "Primary,Backdrop,Thumb",
+ StartIndex: 0,
+ Limit: pageSize
+ },
+ view: libraryBrowser.getSavedView(key) || "Poster"
+ };
+ pageData.query.ParentId = params.topParentId;
+ libraryBrowser.loadSavedQueryValues(key, pageData.query);
+ }
+
+ return pageData;
}
function getQuery(context) {
- return getPageData(context).query
+ return getPageData(context).query;
}
function getSavedQueryKey(context) {
- return context.savedQueryKey || (context.savedQueryKey = libraryBrowser.getSavedQueryKey("episodes")), context.savedQueryKey
+ if (!context.savedQueryKey) {
+ context.savedQueryKey = libraryBrowser.getSavedQueryKey("episodes");
+ }
+
+ return context.savedQueryKey;
}
function onViewStyleChange() {
- var viewStyle = self.getCurrentViewStyle(),
- itemsContainer = tabContent.querySelector(".itemsContainer");
- "List" == viewStyle ? (itemsContainer.classList.add("vertical-list"), itemsContainer.classList.remove("vertical-wrap")) : (itemsContainer.classList.remove("vertical-list"), itemsContainer.classList.add("vertical-wrap")), itemsContainer.innerHTML = ""
+ var viewStyle = self.getCurrentViewStyle();
+ var itemsContainer = tabContent.querySelector(".itemsContainer");
+
+ if ("List" == viewStyle) {
+ itemsContainer.classList.add("vertical-list");
+ itemsContainer.classList.remove("vertical-wrap");
+ } else {
+ itemsContainer.classList.remove("vertical-list");
+ itemsContainer.classList.add("vertical-wrap");
+ }
+
+ itemsContainer.innerHTML = "";
}
function reloadItems(page) {
loading.show();
isLoading = true;
var query = getQuery(page);
- ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function(result) {
+ ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) {
function onNextPageClick() {
- if (isLoading) return;
+ if (isLoading) {
+ return;
+ }
+
query.StartIndex += query.Limit;
- reloadItems(tabContent)
+ reloadItems(tabContent);
}
function onPreviousPageClick() {
- if (isLoading) return;
+ if (isLoading) {
+ return;
+ }
+
query.StartIndex -= query.Limit;
- reloadItems(tabContent)
+ reloadItems(tabContent);
}
window.scrollTo(0, 0);
- var html, pagingHtml = libraryBrowser.getQueryPagingHtml({
- startIndex: query.StartIndex,
- limit: query.Limit,
- totalRecordCount: result.TotalRecordCount,
- showLimit: !1,
- updatePageSizeSetting: !1,
- addLayoutButton: !1,
- sortButton: !1,
- filterButton: !1
- }),
- viewStyle = self.getCurrentViewStyle(),
- itemsContainer = tabContent.querySelector(".itemsContainer");
- html = "List" == viewStyle ? listView.getListViewHtml({
- items: result.Items,
- sortBy: query.SortBy,
- showParentTitle: !0
- }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "backdrop",
- showTitle: !0,
- showParentTitle: !0,
- scalable: !0,
- cardLayout: !0
- }) : cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "backdrop",
- showTitle: !0,
- showParentTitle: !0,
- overlayText: !1,
- centerText: !0,
- scalable: !0,
- overlayPlayButton: !0
+ var html;
+ var pagingHtml = libraryBrowser.getQueryPagingHtml({
+ startIndex: query.StartIndex,
+ limit: query.Limit,
+ totalRecordCount: result.TotalRecordCount,
+ showLimit: false,
+ updatePageSizeSetting: false,
+ addLayoutButton: false,
+ sortButton: false,
+ filterButton: false
});
- var i, length, elems;
- for (elems = tabContent.querySelectorAll(".paging"), i = 0, length = elems.length; i < length; i++)
+ var viewStyle = self.getCurrentViewStyle();
+ var itemsContainer = tabContent.querySelector(".itemsContainer");
+ if (viewStyle == "List") {
+ html = listView.getListViewHtml({
+ items: result.Items,
+ sortBy: query.SortBy,
+ showParentTitle: true
+ });
+ } else if (viewStyle == "PosterCard") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "backdrop",
+ showTitle: true,
+ showParentTitle: true,
+ scalable: true,
+ cardLayout: true
+ });
+ } else {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "backdrop",
+ showTitle: true,
+ showParentTitle: true,
+ overlayText: false,
+ centerText: true,
+ scalable: true,
+ overlayPlayButton: true
+ });
+ }
+ var i;
+ var length;
+ var elems;
+
+ elems = tabContent.querySelectorAll(".paging");
+ for (i = 0, length = elems.length; i < length; i++) {
elems[i].innerHTML = pagingHtml;
- for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++)
+ }
+
+ elems = tabContent.querySelectorAll(".btnNextPage");
+ for (i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener("click", onNextPageClick);
- for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++)
+ }
+
+ elems = tabContent.querySelectorAll(".btnPreviousPage");
+ for (i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener("click", onPreviousPageClick);
+ }
+
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
loading.hide();
isLoading = false;
- })
+ });
}
- var self = this,
- pageSize = 100,
- data = {},
- isLoading = false;
- self.showFilterMenu = function() {
- require(["components/filterdialog/filterdialog"], function(filterDialogFactory) {
- var filterDialog = new filterDialogFactory({
- query: getQuery(tabContent),
- mode: "episodes",
- serverId: ApiClient.serverId()
- });
- events.on(filterDialog, "filterchange", function() {
- reloadItems(tabContent)
- }), filterDialog.show()
- })
- }, self.getCurrentViewStyle = function() {
- return getPageData(tabContent).view
- },
- function(tabContent) {
- tabContent.querySelector(".btnFilter").addEventListener("click", function() {
- self.showFilterMenu()
- }), tabContent.querySelector(".btnSort").addEventListener("click", function(e) {
- libraryBrowser.showSortMenu({
- items: [{
- name: Globalize.translate("OptionNameSort"),
- id: "SeriesSortName,SortName"
- }, {
- name: Globalize.translate("OptionTvdbRating"),
- id: "CommunityRating,SeriesSortName,SortName"
- }, {
- name: Globalize.translate("OptionDateAdded"),
- id: "DateCreated,SeriesSortName,SortName"
- }, {
- name: Globalize.translate("OptionPremiereDate"),
- id: "PremiereDate,SeriesSortName,SortName"
- }, {
- name: Globalize.translate("OptionDatePlayed"),
- id: "DatePlayed,SeriesSortName,SortName"
- }, {
- name: Globalize.translate("OptionParentalRating"),
- id: "OfficialRating,SeriesSortName,SortName"
- }, {
- name: Globalize.translate("OptionPlayCount"),
- id: "PlayCount,SeriesSortName,SortName"
- }, {
- name: Globalize.translate("OptionRuntime"),
- id: "Runtime,SeriesSortName,SortName"
- }],
- callback: function() {
- reloadItems(tabContent)
- },
- query: getQuery(tabContent),
- button: e.target
- })
+
+ var self = this;
+ var pageSize = 100;
+ var data = {};
+ var isLoading = false;
+
+ self.showFilterMenu = function () {
+ require(["components/filterdialog/filterdialog"], function (filterDialogFactory) {
+ var filterDialog = new filterDialogFactory({
+ query: getQuery(tabContent),
+ mode: "episodes",
+ serverId: ApiClient.serverId()
});
- var btnSelectView = tabContent.querySelector(".btnSelectView");
- btnSelectView.addEventListener("click", function(e) {
- libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard".split(","))
- }), btnSelectView.addEventListener("layoutchange", function(e) {
- var viewStyle = e.detail.viewStyle;
- getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), onViewStyleChange(), reloadItems(tabContent)
- })
- }(tabContent), onViewStyleChange(), self.renderTab = function() {
- reloadItems(tabContent)
- }, self.destroy = function() {}
- }
+ events.on(filterDialog, "filterchange", function () {
+ reloadItems(tabContent);
+ });
+ filterDialog.show();
+ });
+ };
+
+ self.getCurrentViewStyle = function () {
+ return getPageData(tabContent).view;
+ };
+
+ function initPage(tabContent) {
+ tabContent.querySelector(".btnFilter").addEventListener("click", function () {
+ self.showFilterMenu();
+ });
+ tabContent.querySelector(".btnSort").addEventListener("click", function (e) {
+ libraryBrowser.showSortMenu({
+ items: [{
+ name: Globalize.translate("OptionNameSort"),
+ id: "SeriesSortName,SortName"
+ }, {
+ name: Globalize.translate("OptionTvdbRating"),
+ id: "CommunityRating,SeriesSortName,SortName"
+ }, {
+ name: Globalize.translate("OptionDateAdded"),
+ id: "DateCreated,SeriesSortName,SortName"
+ }, {
+ name: Globalize.translate("OptionPremiereDate"),
+ id: "PremiereDate,SeriesSortName,SortName"
+ }, {
+ name: Globalize.translate("OptionDatePlayed"),
+ id: "DatePlayed,SeriesSortName,SortName"
+ }, {
+ name: Globalize.translate("OptionParentalRating"),
+ id: "OfficialRating,SeriesSortName,SortName"
+ }, {
+ name: Globalize.translate("OptionPlayCount"),
+ id: "PlayCount,SeriesSortName,SortName"
+ }, {
+ name: Globalize.translate("OptionRuntime"),
+ id: "Runtime,SeriesSortName,SortName"
+ }],
+ callback: function () {
+ reloadItems(tabContent);
+ },
+ query: getQuery(tabContent),
+ button: e.target
+ });
+ });
+ var btnSelectView = tabContent.querySelector(".btnSelectView");
+ btnSelectView.addEventListener("click", function (e) {
+ libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "List,Poster,PosterCard".split(","));
+ });
+ btnSelectView.addEventListener("layoutchange", function (e) {
+ var viewStyle = e.detail.viewStyle;
+ getPageData(tabContent).view = viewStyle;
+ libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle);
+ onViewStyleChange();
+ reloadItems(tabContent);
+ });
+ }
+
+ initPage(tabContent);
+ onViewStyleChange();
+
+ self.renderTab = function () {
+ reloadItems(tabContent);
+ };
+
+ self.destroy = function () {};
+ };
});
diff --git a/src/controllers/shows/tvgenres.js b/src/controllers/shows/tvgenres.js
index e9559155e1..956b8fa6fa 100644
--- a/src/controllers/shows/tvgenres.js
+++ b/src/controllers/shows/tvgenres.js
@@ -1,139 +1,200 @@
-define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader", "apphost", "globalize", "appRouter", "dom", "emby-button"], function(layoutManager, loading, libraryBrowser, cardBuilder, lazyLoader, appHost, globalize, appRouter, dom) {
+define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader", "apphost", "globalize", "appRouter", "dom", "emby-button"], function (layoutManager, loading, libraryBrowser, cardBuilder, lazyLoader, appHost, globalize, appRouter, dom) {
"use strict";
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
function getPageData() {
- var key = getSavedQueryKey(),
- pageData = data[key];
- return pageData || (pageData = data[key] = {
- query: {
- SortBy: "SortName",
- SortOrder: "Ascending",
- IncludeItemTypes: "Series",
- Recursive: !0,
- EnableTotalRecordCount: !1
- },
- view: "Poster"
- }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData
+ var key = getSavedQueryKey();
+ var pageData = data[key];
+
+ if (!pageData) {
+ pageData = data[key] = {
+ query: {
+ SortBy: "SortName",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "Series",
+ Recursive: true,
+ EnableTotalRecordCount: false
+ },
+ view: "Poster"
+ };
+ pageData.query.ParentId = params.topParentId;
+ libraryBrowser.loadSavedQueryValues(key, pageData.query);
+ }
+
+ return pageData;
}
function getQuery() {
- return getPageData().query
+ return getPageData().query;
}
function getSavedQueryKey() {
- return libraryBrowser.getSavedQueryKey("seriesgenres")
+ return libraryBrowser.getSavedQueryKey("seriesgenres");
}
function getPromise() {
loading.show();
var query = getQuery();
- return ApiClient.getGenres(ApiClient.getCurrentUserId(), query)
+ return ApiClient.getGenres(ApiClient.getCurrentUserId(), query);
}
function enableScrollX() {
- return !layoutManager.desktop
+ return !layoutManager.desktop;
}
function getThumbShape() {
- return enableScrollX() ? "overflowBackdrop" : "backdrop"
+ return enableScrollX() ? "overflowBackdrop" : "backdrop";
}
function getPortraitShape() {
- return enableScrollX() ? "overflowPortrait" : "portrait"
+ return enableScrollX() ? "overflowPortrait" : "portrait";
}
function fillItemsContainer(elem) {
- var id = elem.getAttribute("data-id"),
- viewStyle = self.getCurrentViewStyle(),
- limit = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? 5 : 9;
- enableScrollX() && (limit = 10);
- var enableImageTypes = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? "Primary,Backdrop,Thumb" : "Primary",
- query = {
- SortBy: "SortName",
- SortOrder: "Ascending",
- IncludeItemTypes: "Series",
- Recursive: !0,
- Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo",
- ImageTypeLimit: 1,
- EnableImageTypes: enableImageTypes,
- Limit: limit,
- GenreIds: id,
- EnableTotalRecordCount: !1,
- ParentId: params.topParentId
- };
- ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function(result) {
+ var id = elem.getAttribute("data-id");
+ var viewStyle = self.getCurrentViewStyle();
+ var limit = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? 5 : 9;
+
+ if (enableScrollX()) {
+ limit = 10;
+ }
+
+ var enableImageTypes = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? "Primary,Backdrop,Thumb" : "Primary";
+ var query = {
+ SortBy: "SortName",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "Series",
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo",
+ ImageTypeLimit: 1,
+ EnableImageTypes: enableImageTypes,
+ Limit: limit,
+ GenreIds: id,
+ EnableTotalRecordCount: false,
+ ParentId: params.topParentId
+ };
+ ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) {
var supportsImageAnalysis = appHost.supports("imageanalysis");
- "Thumb" == viewStyle ? cardBuilder.buildCards(result.Items, {
- itemsContainer: elem,
- shape: getThumbShape(),
- preferThumb: !0,
- showTitle: !0,
- scalable: !0,
- centerText: !0,
- overlayMoreButton: !0,
- allowBottomPadding: !1
- }) : "ThumbCard" == viewStyle ? cardBuilder.buildCards(result.Items, {
- itemsContainer: elem,
- shape: getThumbShape(),
- preferThumb: !0,
- showTitle: !0,
- scalable: !0,
- centerText: !1,
- cardLayout: !0,
- showYear: !0
- }) : "PosterCard" == viewStyle ? cardBuilder.buildCards(result.Items, {
- itemsContainer: elem,
- shape: getPortraitShape(),
- showTitle: !0,
- scalable: !0,
- centerText: !1,
- cardLayout: !0,
- showYear: !0
- }) : "Poster" == viewStyle && cardBuilder.buildCards(result.Items, {
- itemsContainer: elem,
- shape: getPortraitShape(),
- scalable: !0,
- overlayMoreButton: !0,
- allowBottomPadding: !1
- }), result.Items.length >= query.Limit && tabContent.querySelector(".btnMoreFromGenre" + id + " i").classList.remove("hide")
- })
+
+ if (viewStyle == "Thumb") {
+ cardBuilder.buildCards(result.Items, {
+ itemsContainer: elem,
+ shape: getThumbShape(),
+ preferThumb: true,
+ showTitle: true,
+ scalable: true,
+ centerText: true,
+ overlayMoreButton: true,
+ allowBottomPadding: false
+ });
+ } else if (viewStyle == "ThumbCard") {
+ cardBuilder.buildCards(result.Items, {
+ itemsContainer: elem,
+ shape: getThumbShape(),
+ preferThumb: true,
+ showTitle: true,
+ scalable: true,
+ centerText: false,
+ cardLayout: true,
+ showYear: true
+ });
+ } else if (viewStyle == "PosterCard") {
+ cardBuilder.buildCards(result.Items, {
+ itemsContainer: elem,
+ shape: getPortraitShape(),
+ showTitle: true,
+ scalable: true,
+ centerText: false,
+ cardLayout: true,
+ showYear: true
+ });
+ } else if (viewStyle == "Poster") {
+ cardBuilder.buildCards(result.Items, {
+ itemsContainer: elem,
+ shape: getPortraitShape(),
+ scalable: true,
+ overlayMoreButton: true,
+ allowBottomPadding: false
+ });
+ }
+ if (result.Items.length >= query.Limit) {
+ tabContent.querySelector(".btnMoreFromGenre" + id + " i").classList.remove("hide");
+ }
+ });
}
function reloadItems(context, promise) {
var query = getQuery();
- promise.then(function(result) {
- for (var elem = context.querySelector("#items"), html = "", items = result.Items, i = 0, length = items.length; i < length; i++) {
+ promise.then(function (result) {
+ var elem = context.querySelector("#items");
+ var html = "";
+ var items = result.Items;
+
+ for (var i = 0, length = items.length; i < length; i++) {
var item = items[i];
- if (html += '
', html += '
", enableScrollX()) {
+ html += '
';
+ html += '
";
+ if (enableScrollX()) {
var scrollXClass = "scrollX hiddenScrollX";
- layoutManager.tv && (scrollXClass += " smoothScrollX"), html += '
"
+ if (layoutManager.tv) {
+ scrollXClass += "smoothScrollX";
+ }
+ html += '
";
}
- elem.innerHTML = html, lazyLoader.lazyChildren(elem, fillItemsContainer), libraryBrowser.saveQueryValues(getSavedQueryKey(), query), loading.hide()
- })
+
+ elem.innerHTML = html;
+ lazyLoader.lazyChildren(elem, fillItemsContainer);
+ libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
+ loading.hide();
+ });
}
function fullyReload() {
- self.preRender(), self.renderTab()
+ self.preRender();
+ self.renderTab();
}
- var self = this,
- data = {};
- self.getViewStyles = function() {
- return "Poster,PosterCard,Thumb,ThumbCard".split(",")
- }, self.getCurrentViewStyle = function() {
- return getPageData(tabContent).view
- }, self.setCurrentViewStyle = function(viewStyle) {
- getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), fullyReload()
- }, self.enableViewSelection = !0;
+
+ var self = this;
+ var data = {};
+
+ self.getViewStyles = function () {
+ return "Poster,PosterCard,Thumb,ThumbCard".split(",");
+ };
+
+ self.getCurrentViewStyle = function () {
+ return getPageData(tabContent).view;
+ };
+
+ self.setCurrentViewStyle = function (viewStyle) {
+ getPageData(tabContent).view = viewStyle;
+ libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle);
+ fullyReload();
+ };
+
+ self.enableViewSelection = true;
var promise;
- self.preRender = function() {
- promise = getPromise()
- }, self.renderTab = function() {
- reloadItems(tabContent, promise)
- }
- }
-});
\ No newline at end of file
+
+ self.preRender = function () {
+ promise = getPromise();
+ };
+
+ self.renderTab = function () {
+ reloadItems(tabContent, promise);
+ };
+ };
+});
diff --git a/src/controllers/shows/tvlatest.js b/src/controllers/shows/tvlatest.js
index 006f41e6ce..2a1ed56bf4 100644
--- a/src/controllers/shows/tvlatest.js
+++ b/src/controllers/shows/tvlatest.js
@@ -1,52 +1,60 @@
-define(["loading", "components/groupedcards", "cardBuilder", "apphost", "imageLoader"], function(loading, groupedcards, cardBuilder, appHost, imageLoader) {
+define(["loading", "components/groupedcards", "cardBuilder", "apphost", "imageLoader"], function (loading, groupedcards, cardBuilder, appHost, imageLoader) {
"use strict";
function getLatestPromise(context, params) {
loading.show();
- var userId = ApiClient.getCurrentUserId(),
- parentId = params.topParentId,
- options = {
- IncludeItemTypes: "Episode",
- Limit: 30,
- Fields: "PrimaryImageAspectRatio,BasicSyncInfo",
- ParentId: parentId,
- ImageTypeLimit: 1,
- EnableImageTypes: "Primary,Backdrop,Thumb"
- };
- return ApiClient.getJSON(ApiClient.getUrl("Users/" + userId + "/Items/Latest", options))
+ var userId = ApiClient.getCurrentUserId();
+ var parentId = params.topParentId;
+ var options = {
+ IncludeItemTypes: "Episode",
+ Limit: 30,
+ Fields: "PrimaryImageAspectRatio,BasicSyncInfo",
+ ParentId: parentId,
+ ImageTypeLimit: 1,
+ EnableImageTypes: "Primary,Backdrop,Thumb"
+ };
+ return ApiClient.getJSON(ApiClient.getUrl("Users/" + userId + "/Items/Latest", options));
}
function loadLatest(context, params, promise) {
- promise.then(function(items) {
+ promise.then(function (items) {
var html = "";
appHost.supports("imageanalysis");
html += cardBuilder.getCardsHtml({
items: items,
shape: "backdrop",
- preferThumb: !0,
- showTitle: !0,
- showSeriesYear: !0,
- showParentTitle: !0,
- overlayText: !1,
- cardLayout: !1,
- showUnplayedIndicator: !1,
- showChildCountIndicator: !0,
- centerText: !0,
- lazy: !0,
- overlayPlayButton: !0,
+ preferThumb: true,
+ showTitle: true,
+ showSeriesYear: true,
+ showParentTitle: true,
+ overlayText: false,
+ cardLayout: false,
+ showUnplayedIndicator: false,
+ showChildCountIndicator: true,
+ centerText: true,
+ lazy: true,
+ overlayPlayButton: true,
lines: 2
});
var elem = context.querySelector("#latestEpisodes");
- elem.innerHTML = html, imageLoader.lazyChildren(elem), loading.hide()
- })
+ elem.innerHTML = html;
+ imageLoader.lazyChildren(elem);
+ loading.hide();
+ });
}
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
var self = this;
var latestPromise;
- self.preRender = function() {
- latestPromise = getLatestPromise(view, params)
- }, self.renderTab = function() {
- loadLatest(tabContent, params, latestPromise)
- }, tabContent.querySelector("#latestEpisodes").addEventListener("click", groupedcards.onItemsContainerClick)
- }
-});
\ No newline at end of file
+
+ self.preRender = function () {
+ latestPromise = getLatestPromise(view, params);
+ };
+
+ self.renderTab = function () {
+ loadLatest(tabContent, params, latestPromise);
+ };
+
+ tabContent.querySelector("#latestEpisodes").addEventListener("click", groupedcards.onItemsContainerClick);
+ };
+});
diff --git a/src/controllers/shows/tvrecommended.js b/src/controllers/shows/tvrecommended.js
index 9de1461b3d..1386e76a31 100644
--- a/src/controllers/shows/tvrecommended.js
+++ b/src/controllers/shows/tvrecommended.js
@@ -1,4 +1,4 @@
-define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "dom", "userSettings", "cardBuilder", "playbackManager", "mainTabsManager", "scrollStyles", "emby-itemscontainer", "emby-button"], function(events, inputManager, libraryMenu, layoutManager, loading, dom, userSettings, cardBuilder, playbackManager, mainTabsManager) {
+define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "dom", "userSettings", "cardBuilder", "playbackManager", "mainTabsManager", "scrollStyles", "emby-itemscontainer", "emby-button"], function (events, inputManager, libraryMenu, layoutManager, loading, dom, userSettings, cardBuilder, playbackManager, mainTabsManager) {
"use strict";
function getTabs() {
@@ -19,30 +19,51 @@ define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "do
}, {
name: Globalize.translate("ButtonSearch"),
cssClass: "searchTabButton"
- }]
+ }];
}
function getDefaultTabIndex(folderId) {
switch (userSettings.get("landing-" + folderId)) {
case "suggestions":
return 1;
+
case "latest":
return 2;
+
case "favorites":
return 1;
+
case "genres":
return 4;
+
default:
- return 0
+ return 0;
}
}
function setScrollClasses(elem, scrollX) {
- scrollX ? (elem.classList.add("hiddenScrollX"), layoutManager.tv && elem.classList.add("smoothScrollX"), elem.classList.add("scrollX"), elem.classList.remove("vertical-wrap")) : (elem.classList.remove("hiddenScrollX"), elem.classList.remove("smoothScrollX"), elem.classList.remove("scrollX"), elem.classList.add("vertical-wrap"))
+ if (scrollX) {
+ elem.classList.add("hiddenScrollX");
+
+ if (layoutManager.tv) {
+ elem.classList.add("smoothScrollX");
+ }
+
+ elem.classList.add("scrollX");
+ elem.classList.remove("vertical-wrap");
+ } else {
+ elem.classList.remove("hiddenScrollX");
+ elem.classList.remove("smoothScrollX");
+ elem.classList.remove("scrollX");
+ elem.classList.add("vertical-wrap");
+ }
}
- return function(view, params) {
+
+ return function (view, params) {
function reload() {
- loading.show(), loadResume(), loadNextUp()
+ loading.show();
+ loadResume();
+ loadNextUp();
}
function loadNextUp() {
@@ -52,178 +73,263 @@ define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "do
UserId: ApiClient.getCurrentUserId(),
ImageTypeLimit: 1,
EnableImageTypes: "Primary,Backdrop,Thumb",
- EnableTotalRecordCount: !1
+ EnableTotalRecordCount: false
};
- query.ParentId = libraryMenu.getTopParentId(), ApiClient.getNextUpEpisodes(query).then(function(result) {
- result.Items.length ? view.querySelector(".noNextUpItems").classList.add("hide") : view.querySelector(".noNextUpItems").classList.remove("hide");
+ query.ParentId = libraryMenu.getTopParentId();
+ ApiClient.getNextUpEpisodes(query).then(function (result) {
+ if (result.Items.length) {
+ view.querySelector(".noNextUpItems").classList.add("hide");
+ } else {
+ view.querySelector(".noNextUpItems").classList.remove("hide");
+ }
+
var container = view.querySelector("#nextUpItems");
cardBuilder.buildCards(result.Items, {
itemsContainer: container,
- preferThumb: !0,
+ preferThumb: true,
shape: "backdrop",
- scalable: !0,
- showTitle: !0,
- showParentTitle: !0,
- overlayText: !1,
- centerText: !0,
- overlayPlayButton: !0,
- cardLayout: !1
- }), loading.hide()
- })
+ scalable: true,
+ showTitle: true,
+ showParentTitle: true,
+ overlayText: false,
+ centerText: true,
+ overlayPlayButton: true,
+ cardLayout: false
+ });
+ loading.hide();
+ });
}
function enableScrollX() {
- return !layoutManager.desktop
+ return !layoutManager.desktop;
}
function getThumbShape() {
- return enableScrollX() ? "overflowBackdrop" : "backdrop"
+ return enableScrollX() ? "overflowBackdrop" : "backdrop";
}
function loadResume() {
- var parentId = libraryMenu.getTopParentId(),
- screenWidth = dom.getWindowSize().innerWidth,
- limit = screenWidth >= 1600 ? 5 : 6,
- options = {
- SortBy: "DatePlayed",
- SortOrder: "Descending",
- IncludeItemTypes: "Episode",
- Filters: "IsResumable",
- Limit: limit,
- Recursive: !0,
- Fields: "PrimaryImageAspectRatio,SeriesInfo,UserData,BasicSyncInfo",
- ExcludeLocationTypes: "Virtual",
- ParentId: parentId,
- ImageTypeLimit: 1,
- EnableImageTypes: "Primary,Backdrop,Thumb",
- EnableTotalRecordCount: !1
- };
- ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function(result) {
- result.Items.length ? view.querySelector("#resumableSection").classList.remove("hide") : view.querySelector("#resumableSection").classList.add("hide");
- var allowBottomPadding = !enableScrollX(),
- container = view.querySelector("#resumableItems");
+ var parentId = libraryMenu.getTopParentId();
+ var screenWidth = dom.getWindowSize().innerWidth;
+ var limit = screenWidth >= 1600 ? 5 : 6;
+ var options = {
+ SortBy: "DatePlayed",
+ SortOrder: "Descending",
+ IncludeItemTypes: "Episode",
+ Filters: "IsResumable",
+ Limit: limit,
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,SeriesInfo,UserData,BasicSyncInfo",
+ ExcludeLocationTypes: "Virtual",
+ ParentId: parentId,
+ ImageTypeLimit: 1,
+ EnableImageTypes: "Primary,Backdrop,Thumb",
+ EnableTotalRecordCount: false
+ };
+ ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) {
+ if (result.Items.length) {
+ view.querySelector("#resumableSection").classList.remove("hide");
+ } else {
+ view.querySelector("#resumableSection").classList.add("hide");
+ }
+
+ var allowBottomPadding = !enableScrollX();
+ var container = view.querySelector("#resumableItems");
cardBuilder.buildCards(result.Items, {
itemsContainer: container,
- preferThumb: !0,
+ preferThumb: true,
shape: getThumbShape(),
- scalable: !0,
- showTitle: !0,
- showParentTitle: !0,
- overlayText: !1,
- centerText: !0,
- overlayPlayButton: !0,
+ scalable: true,
+ showTitle: true,
+ showParentTitle: true,
+ overlayText: false,
+ centerText: true,
+ overlayPlayButton: true,
allowBottomPadding: allowBottomPadding,
- cardLayout: !1
- })
- })
+ cardLayout: false
+ });
+ });
}
function onBeforeTabChange(e) {
- preLoadTab(view, parseInt(e.detail.selectedTabIndex))
+ preLoadTab(view, parseInt(e.detail.selectedTabIndex));
}
function onTabChange(e) {
var newIndex = parseInt(e.detail.selectedTabIndex);
- loadTab(view, newIndex)
+ loadTab(view, newIndex);
}
function getTabContainers() {
- return view.querySelectorAll(".pageTabContent")
+ return view.querySelectorAll(".pageTabContent");
}
function initTabs() {
- mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange)
+ mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange);
}
function getTabController(page, index, callback) {
var depends = [];
+
switch (index) {
case 0:
depends.push("controllers/shows/tvshows");
break;
+
case 1:
break;
+
case 2:
depends.push("controllers/shows/tvlatest");
break;
+
case 3:
depends.push("controllers/shows/tvupcoming");
break;
+
case 4:
depends.push("controllers/shows/tvgenres");
break;
+
case 5:
depends.push("controllers/shows/tvstudios");
break;
+
case 6:
depends.push("controllers/shows/episodes");
break;
+
case 7:
- depends.push("scripts/searchtab")
+ depends.push("scripts/searchtab");
}
- require(depends, function(controllerFactory) {
+
+ require(depends, function (controllerFactory) {
var tabContent;
- 1 === index && (tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"), self.tabContent = tabContent);
+
+ if (index === 1) {
+ tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
+ self.tabContent = tabContent;
+ }
+
var controller = tabControllers[index];
- controller || (tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"), controller = 1 === index ? self : 7 === index ? new controllerFactory(view, tabContent, {
- collectionType: "tvshows",
- parentId: params.topParentId
- }) : new controllerFactory(view, params, tabContent), tabControllers[index] = controller, controller.initTab && controller.initTab()), callback(controller)
- })
+
+ if (!controller) {
+ tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
+
+ if (index === 1) {
+ controller = self;
+ } else if (index === 7) {
+ controller = new controllerFactory(view, tabContent, {
+ collectionType: "tvshows",
+ parentId: params.topParentId
+ });
+ } else {
+ controller = new controllerFactory(view, params, tabContent);
+ }
+
+ tabControllers[index] = controller;
+
+ if (controller.initTab) {
+ controller.initTab();
+ }
+ }
+
+ callback(controller);
+ });
}
function preLoadTab(page, index) {
- getTabController(page, index, function(controller) {
- -1 == renderedTabs.indexOf(index) && controller.preRender && controller.preRender()
- })
+ getTabController(page, index, function (controller) {
+ if (renderedTabs.indexOf(index) == -1 && controller.preRender) {
+ controller.preRender();
+ }
+ });
}
function loadTab(page, index) {
- currentTabIndex = index, getTabController(page, index, function(controller) {
- initialTabIndex = null, -1 == renderedTabs.indexOf(index) && (renderedTabs.push(index), controller.renderTab())
- })
+ currentTabIndex = index;
+ getTabController(page, index, function (controller) {
+ initialTabIndex = null;
+
+ if (renderedTabs.indexOf(index) == -1) {
+ renderedTabs.push(index);
+ controller.renderTab();
+ }
+ });
}
function onPlaybackStop(e, state) {
- state.NowPlayingItem && "Video" == state.NowPlayingItem.MediaType && (renderedTabs = [], mainTabsManager.getTabsElement().triggerTabChange())
+ if (state.NowPlayingItem && state.NowPlayingItem.MediaType == "Video") {
+ renderedTabs = [];
+ mainTabsManager.getTabsElement().triggerTabChange();
+ }
}
function onWebSocketMessage(e, data) {
var msg = data;
- "UserDataChanged" === msg.MessageType && msg.Data.UserId == ApiClient.getCurrentUserId() && (renderedTabs = [])
+
+ if (msg.MessageType === "UserDataChanged" && msg.Data.UserId == ApiClient.getCurrentUserId()) {
+ renderedTabs = [];
+ }
}
function onInputCommand(e) {
switch (e.detail.command) {
case "search":
- e.preventDefault(), Dashboard.navigate("search.html?collectionType=tv&parentId=" + params.topParentId)
+ e.preventDefault();
+ Dashboard.navigate("search.html?collectionType=tv&parentId=" + params.topParentId);
}
}
- var isViewRestored, self = this,
- currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)),
- initialTabIndex = currentTabIndex;
- self.initTab = function() {
+
+ var isViewRestored;
+ var self = this;
+ var currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId));
+ var initialTabIndex = currentTabIndex;
+
+ self.initTab = function () {
var tabContent = self.tabContent;
setScrollClasses(tabContent.querySelector("#resumableItems"), enableScrollX());
- }, self.renderTab = function() {
- reload()
};
- var tabControllers = [],
- renderedTabs = [];
- setScrollClasses(view.querySelector("#resumableItems"), enableScrollX()), view.addEventListener("viewshow", function(e) {
- if (isViewRestored = e.detail.isRestored, initTabs(), !view.getAttribute("data-title")) {
+
+ self.renderTab = function () {
+ reload();
+ };
+
+ var tabControllers = [];
+ var renderedTabs = [];
+ setScrollClasses(view.querySelector("#resumableItems"), enableScrollX());
+ view.addEventListener("viewshow", function (e) {
+ isViewRestored = e.detail.isRestored;
+ initTabs();
+ if (!view.getAttribute("data-title")) {
var parentId = params.topParentId;
- parentId ? ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function(item) {
- view.setAttribute("data-title", item.Name), libraryMenu.setTitle(item.Name)
- }) : (view.setAttribute("data-title", Globalize.translate("TabShows")), libraryMenu.setTitle(Globalize.translate("TabShows")))
+
+ if (parentId) {
+ ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function (item) {
+ view.setAttribute("data-title", item.Name);
+ libraryMenu.setTitle(item.Name);
+ });
+ } else {
+ view.setAttribute("data-title", Globalize.translate("TabShows"));
+ libraryMenu.setTitle(Globalize.translate("TabShows"));
+ }
}
- events.on(playbackManager, "playbackstop", onPlaybackStop), events.on(ApiClient, "message", onWebSocketMessage), inputManager.on(window, onInputCommand)
- }), view.addEventListener("viewbeforehide", function(e) {
- inputManager.off(window, onInputCommand), events.off(playbackManager, "playbackstop", onPlaybackStop), events.off(ApiClient, "message", onWebSocketMessage)
- }), view.addEventListener("viewdestroy", function(e) {
- tabControllers.forEach(function(t) {
- t.destroy && t.destroy()
- })
- })
- }
+
+ events.on(playbackManager, "playbackstop", onPlaybackStop);
+ events.on(ApiClient, "message", onWebSocketMessage);
+ inputManager.on(window, onInputCommand);
+ });
+ view.addEventListener("viewbeforehide", function (e) {
+ inputManager.off(window, onInputCommand);
+ events.off(playbackManager, "playbackstop", onPlaybackStop);
+ events.off(ApiClient, "message", onWebSocketMessage);
+ });
+ view.addEventListener("viewdestroy", function (e) {
+ tabControllers.forEach(function (t) {
+ if (t.destroy) {
+ t.destroy();
+ }
+ });
+ });
+ };
});
diff --git a/src/controllers/shows/tvshows.js b/src/controllers/shows/tvshows.js
index ac832a915e..adccd98234 100644
--- a/src/controllers/shows/tvshows.js
+++ b/src/controllers/shows/tvshows.js
@@ -1,199 +1,284 @@
-define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "alphaPicker", "emby-itemscontainer"], function(layoutManager, loading, events, libraryBrowser, imageLoader, listView, cardBuilder, alphaPicker) {
+define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "alphaPicker", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, listView, cardBuilder, alphaPicker) {
"use strict";
- return function(view, params, tabContent) {
+
+ return function (view, params, tabContent) {
function getPageData(context) {
- var key = getSavedQueryKey(context),
- pageData = data[key];
- return pageData || (pageData = data[key] = {
- query: {
- SortBy: "SortName",
- SortOrder: "Ascending",
- IncludeItemTypes: "Series",
- Recursive: !0,
- Fields: "PrimaryImageAspectRatio,BasicSyncInfo",
- ImageTypeLimit: 1,
- EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
- StartIndex: 0,
- Limit: pageSize
- },
- view: libraryBrowser.getSavedView(key) || "Poster"
- }, pageData.query.ParentId = params.topParentId, libraryBrowser.loadSavedQueryValues(key, pageData.query)), pageData
+ var key = getSavedQueryKey(context);
+ var pageData = data[key];
+
+ if (!pageData) {
+ pageData = data[key] = {
+ query: {
+ SortBy: "SortName",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "Series",
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,BasicSyncInfo",
+ ImageTypeLimit: 1,
+ EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
+ StartIndex: 0,
+ Limit: pageSize
+ },
+ view: libraryBrowser.getSavedView(key) || "Poster"
+ };
+ pageData.query.ParentId = params.topParentId;
+ libraryBrowser.loadSavedQueryValues(key, pageData.query);
+ }
+
+ return pageData;
}
function getQuery(context) {
- return getPageData(context).query
+ return getPageData(context).query;
}
function getSavedQueryKey(context) {
- return context.savedQueryKey || (context.savedQueryKey = libraryBrowser.getSavedQueryKey("series")), context.savedQueryKey
+ if (!context.savedQueryKey) {
+ context.savedQueryKey = libraryBrowser.getSavedQueryKey("series");
+ }
+
+ return context.savedQueryKey;
}
function onViewStyleChange() {
- var viewStyle = self.getCurrentViewStyle(),
- itemsContainer = tabContent.querySelector(".itemsContainer");
- "List" == viewStyle ? (itemsContainer.classList.add("vertical-list"), itemsContainer.classList.remove("vertical-wrap")) : (itemsContainer.classList.remove("vertical-list"), itemsContainer.classList.add("vertical-wrap")), itemsContainer.innerHTML = ""
+ var viewStyle = self.getCurrentViewStyle();
+ var itemsContainer = tabContent.querySelector(".itemsContainer");
+
+ if ("List" == viewStyle) {
+ itemsContainer.classList.add("vertical-list");
+ itemsContainer.classList.remove("vertical-wrap");
+ } else {
+ itemsContainer.classList.remove("vertical-list");
+ itemsContainer.classList.add("vertical-wrap");
+ }
+
+ itemsContainer.innerHTML = "";
}
function reloadItems(page) {
loading.show();
isLoading = true;
var query = getQuery(page);
- ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function(result) {
+ ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) {
function onNextPageClick() {
- if (isLoading) return;
+ if (isLoading) {
+ return;
+ }
+
query.StartIndex += query.Limit;
reloadItems(tabContent);
}
function onPreviousPageClick() {
- if (isLoading) return;
+ if (isLoading) {
+ return;
+ }
+
query.StartIndex -= query.Limit;
reloadItems(tabContent);
}
- window.scrollTo(0, 0), updateFilterControls(page);
- var html, pagingHtml = libraryBrowser.getQueryPagingHtml({
- startIndex: query.StartIndex,
- limit: query.Limit,
- totalRecordCount: result.TotalRecordCount,
- showLimit: !1,
- updatePageSizeSetting: !1,
- addLayoutButton: !1,
- sortButton: !1,
- filterButton: !1
- }),
- viewStyle = self.getCurrentViewStyle();
- html = "Thumb" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "backdrop",
- preferThumb: !0,
- context: "tvshows",
- overlayMoreButton: !0,
- showTitle: !0,
- centerText: !0
- }) : "ThumbCard" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "backdrop",
- preferThumb: !0,
- context: "tvshows",
- cardLayout: !0,
- showTitle: !0,
- showYear: !0,
- centerText: !0
- }) : "Banner" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "banner",
- preferBanner: !0,
- context: "tvshows"
- }) : "List" == viewStyle ? listView.getListViewHtml({
- items: result.Items,
- context: "tvshows",
- sortBy: query.SortBy
- }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "portrait",
- context: "tvshows",
- showTitle: !0,
- showYear: !0,
- centerText: !0,
- cardLayout: !0
- }) : cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "portrait",
- context: "tvshows",
- centerText: !0,
- lazy: !0,
- overlayMoreButton: !0,
- showTitle: !0,
- showYear: !0
+
+ window.scrollTo(0, 0);
+ updateFilterControls(page);
+ var html;
+ var pagingHtml = libraryBrowser.getQueryPagingHtml({
+ startIndex: query.StartIndex,
+ limit: query.Limit,
+ totalRecordCount: result.TotalRecordCount,
+ showLimit: false,
+ updatePageSizeSetting: false,
+ addLayoutButton: false,
+ sortButton: false,
+ filterButton: false
});
- var i, length, elems = tabContent.querySelectorAll(".paging");
- for (i = 0, length = elems.length; i < length; i++) elems[i].innerHTML = pagingHtml;
- for (elems = tabContent.querySelectorAll(".btnNextPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onNextPageClick);
- for (elems = tabContent.querySelectorAll(".btnPreviousPage"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("click", onPreviousPageClick);
+ var viewStyle = self.getCurrentViewStyle();
+ if (viewStyle == "Thumb") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "backdrop",
+ preferThumb: true,
+ context: "tvshows",
+ overlayMoreButton: true,
+ showTitle: true,
+ centerText: true
+ });
+ } else if (viewStyle == "ThumbCard") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "backdrop",
+ preferThumb: true,
+ context: "tvshows",
+ cardLayout: true,
+ showTitle: true,
+ showYear: true,
+ centerText: true
+ });
+ } else if (viewStyle == "Banner") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "banner",
+ preferBanner: true,
+ context: "tvshows"
+ });
+ } else if (viewStyle == "List") {
+ html = listView.getListViewHtml({
+ items: result.Items,
+ context: "tvshows",
+ sortBy: query.SortBy
+ });
+ } else if (viewStyle == "PosterCard") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "portrait",
+ context: "tvshows",
+ showTitle: true,
+ showYear: true,
+ centerText: true,
+ cardLayout: true
+ });
+ } else {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "portrait",
+ context: "tvshows",
+ centerText: true,
+ lazy: true,
+ overlayMoreButton: true,
+ showTitle: true,
+ showYear: true
+ });
+ }
+ var i;
+ var length;
+ var elems = tabContent.querySelectorAll(".paging");
+
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].innerHTML = pagingHtml;
+ }
+
+ elems = tabContent.querySelectorAll(".btnNextPage");
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onNextPageClick);
+ }
+
+ elems = tabContent.querySelectorAll(".btnPreviousPage");
+ for (i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener("click", onPreviousPageClick);
+ }
+
var itemsContainer = tabContent.querySelector(".itemsContainer");
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
loading.hide();
isLoading = false;
- })
+ });
}
function updateFilterControls(tabContent) {
var query = getQuery(tabContent);
- self.alphaPicker.value(query.NameStartsWithOrGreater)
+ self.alphaPicker.value(query.NameStartsWithOrGreater);
}
- var self = this,
- pageSize = 100,
- data = {},
- isLoading = false;
- self.showFilterMenu = function() {
- require(["components/filterdialog/filterdialog"], function(filterDialogFactory) {
- var filterDialog = new filterDialogFactory({
- query: getQuery(tabContent),
- mode: "series",
- serverId: ApiClient.serverId()
- });
- events.on(filterDialog, "filterchange", function() {
- getQuery(tabContent).StartIndex = 0, reloadItems(tabContent)
- }), filterDialog.show()
- })
- }, self.getCurrentViewStyle = function() {
- return getPageData(tabContent).view
- },
- function(tabContent) {
- var alphaPickerElement = tabContent.querySelector(".alphaPicker");
- if (alphaPickerElement.addEventListener("alphavaluechanged", function(e) {
- var newValue = e.detail.value,
- query = getQuery(tabContent);
- query.NameStartsWithOrGreater = newValue, query.StartIndex = 0, reloadItems(tabContent)
- }), self.alphaPicker = new alphaPicker({
- element: alphaPickerElement,
- valueChangeEvent: "click"
- }), layoutManager.desktop || layoutManager.mobile) {
- tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right");
- var itemsContainer = tabContent.querySelector(".itemsContainer");
- itemsContainer.classList.remove("padded-left-withalphapicker"), itemsContainer.classList.add("padded-right-withalphapicker")
- }
- tabContent.querySelector(".btnFilter").addEventListener("click", function() {
- self.showFilterMenu()
- }), tabContent.querySelector(".btnSort").addEventListener("click", function(e) {
- libraryBrowser.showSortMenu({
- items: [{
- name: Globalize.translate("OptionNameSort"),
- id: "SortName"
- }, {
- name: Globalize.translate("OptionImdbRating"),
- id: "CommunityRating,SortName"
- }, {
- name: Globalize.translate("OptionDateAdded"),
- id: "DateCreated,SortName"
- }, {
- name: Globalize.translate("OptionDatePlayed"),
- id: "DatePlayed,SortName"
- }, {
- name: Globalize.translate("OptionParentalRating"),
- id: "OfficialRating,SortName"
- }, {
- name: Globalize.translate("OptionReleaseDate"),
- id: "PremiereDate,SortName"
- }],
- callback: function() {
- getQuery(tabContent).StartIndex = 0, reloadItems(tabContent)
- },
- query: getQuery(tabContent),
- button: e.target
- })
+
+ var self = this;
+ var pageSize = 100;
+ var data = {};
+ var isLoading = false;
+
+ self.showFilterMenu = function () {
+ require(["components/filterdialog/filterdialog"], function (filterDialogFactory) {
+ var filterDialog = new filterDialogFactory({
+ query: getQuery(tabContent),
+ mode: "series",
+ serverId: ApiClient.serverId()
});
- var btnSelectView = tabContent.querySelector(".btnSelectView");
- btnSelectView.addEventListener("click", function(e) {
- libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "Banner,List,Poster,PosterCard,Thumb,ThumbCard".split(","))
- }), btnSelectView.addEventListener("layoutchange", function(e) {
- var viewStyle = e.detail.viewStyle;
- getPageData(tabContent).view = viewStyle, libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle), getQuery(tabContent).StartIndex = 0, onViewStyleChange(), reloadItems(tabContent)
- })
- }(tabContent), onViewStyleChange(), self.renderTab = function() {
- reloadItems(tabContent), updateFilterControls(tabContent)
- }, self.destroy = function() {}
- }
+ events.on(filterDialog, "filterchange", function () {
+ getQuery(tabContent).StartIndex = 0;
+ reloadItems(tabContent);
+ });
+ filterDialog.show();
+ });
+ };
+
+ self.getCurrentViewStyle = function () {
+ return getPageData(tabContent).view;
+ };
+
+ function initPage(tabContent) {
+ var alphaPickerElement = tabContent.querySelector(".alphaPicker");
+
+ alphaPickerElement.addEventListener("alphavaluechanged", function (e) {
+ var newValue = e.detail.value;
+ var query = getQuery(tabContent);
+ query.NameStartsWithOrGreater = newValue;
+ query.StartIndex = 0;
+ reloadItems(tabContent);
+ });
+ self.alphaPicker = new alphaPicker({
+ element: alphaPickerElement,
+ valueChangeEvent: "click"
+ });
+ if (layoutManager.desktop || layoutManager.mobile) {
+ tabContent.querySelector(".alphaPicker").classList.add("alphabetPicker-right");
+ var itemsContainer = tabContent.querySelector(".itemsContainer");
+ itemsContainer.classList.remove("padded-left-withalphapicker");
+ itemsContainer.classList.add("padded-right-withalphapicker");
+ }
+
+ tabContent.querySelector(".btnFilter").addEventListener("click", function () {
+ self.showFilterMenu();
+ });
+ tabContent.querySelector(".btnSort").addEventListener("click", function (e) {
+ libraryBrowser.showSortMenu({
+ items: [{
+ name: Globalize.translate("OptionNameSort"),
+ id: "SortName"
+ }, {
+ name: Globalize.translate("OptionImdbRating"),
+ id: "CommunityRating,SortName"
+ }, {
+ name: Globalize.translate("OptionDateAdded"),
+ id: "DateCreated,SortName"
+ }, {
+ name: Globalize.translate("OptionDatePlayed"),
+ id: "DatePlayed,SortName"
+ }, {
+ name: Globalize.translate("OptionParentalRating"),
+ id: "OfficialRating,SortName"
+ }, {
+ name: Globalize.translate("OptionReleaseDate"),
+ id: "PremiereDate,SortName"
+ }],
+ callback: function () {
+ getQuery(tabContent).StartIndex = 0;
+ reloadItems(tabContent);
+ },
+ query: getQuery(tabContent),
+ button: e.target
+ });
+ });
+ var btnSelectView = tabContent.querySelector(".btnSelectView");
+ btnSelectView.addEventListener("click", function (e) {
+ libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), "Banner,List,Poster,PosterCard,Thumb,ThumbCard".split(","));
+ });
+ btnSelectView.addEventListener("layoutchange", function (e) {
+ var viewStyle = e.detail.viewStyle;
+ getPageData(tabContent).view = viewStyle;
+ libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle);
+ getQuery(tabContent).StartIndex = 0;
+ onViewStyleChange();
+ reloadItems(tabContent);
+ });
+ }
+
+ initPage(tabContent);
+ onViewStyleChange();
+
+ self.renderTab = function () {
+ reloadItems(tabContent);
+ updateFilterControls(tabContent);
+ };
+
+ self.destroy = function () {};
+ };
});
diff --git a/src/controllers/shows/tvstudios.js b/src/controllers/shows/tvstudios.js
index bfa33401f4..3c000a8e72 100644
--- a/src/controllers/shows/tvstudios.js
+++ b/src/controllers/shows/tvstudios.js
@@ -1,52 +1,65 @@
-define(["loading", "libraryBrowser", "cardBuilder", "apphost"], function(loading, libraryBrowser, cardBuilder, appHost) {
+define(["loading", "libraryBrowser", "cardBuilder", "apphost"], function (loading, libraryBrowser, cardBuilder, appHost) {
"use strict";
function getQuery(params) {
- var key = getSavedQueryKey(),
- pageData = data[key];
- return pageData || (pageData = data[key] = {
- query: {
- SortBy: "SortName",
- SortOrder: "Ascending",
- IncludeItemTypes: "Series",
- Recursive: !0,
- Fields: "DateCreated,PrimaryImageAspectRatio",
- StartIndex: 0
- }
- }, pageData.query.ParentId = params.topParentId), pageData.query
+ var key = getSavedQueryKey();
+ var pageData = data[key];
+
+ if (!pageData) {
+ pageData = data[key] = {
+ query: {
+ SortBy: "SortName",
+ SortOrder: "Ascending",
+ IncludeItemTypes: "Series",
+ Recursive: true,
+ Fields: "DateCreated,PrimaryImageAspectRatio",
+ StartIndex: 0
+ }
+ };
+ pageData.query.ParentId = params.topParentId;
+ }
+
+ return pageData.query;
}
function getSavedQueryKey() {
- return libraryBrowser.getSavedQueryKey("studios")
+ return libraryBrowser.getSavedQueryKey("studios");
}
function getPromise(context, params) {
var query = getQuery(params);
- return loading.show(), ApiClient.getStudios(ApiClient.getCurrentUserId(), query)
+ loading.show();
+ return ApiClient.getStudios(ApiClient.getCurrentUserId(), query);
}
function reloadItems(context, params, promise) {
- promise.then(function(result) {
+ promise.then(function (result) {
var elem = context.querySelector("#items");
cardBuilder.buildCards(result.Items, {
itemsContainer: elem,
shape: "backdrop",
- preferThumb: !0,
- showTitle: !0,
- scalable: !0,
- centerText: !0,
- overlayMoreButton: !0,
+ preferThumb: true,
+ showTitle: true,
+ scalable: true,
+ centerText: true,
+ overlayMoreButton: true,
context: "tvshows"
- }), loading.hide()
- })
+ });
+ loading.hide();
+ });
}
+
var data = {};
- return function(view, params, tabContent) {
- var promise, self = this;
- self.preRender = function() {
- promise = getPromise(view, params)
- }, self.renderTab = function() {
- reloadItems(tabContent, params, promise)
- }
- }
-});
\ No newline at end of file
+ return function (view, params, tabContent) {
+ var promise;
+ var self = this;
+
+ self.preRender = function () {
+ promise = getPromise(view, params);
+ };
+
+ self.renderTab = function () {
+ reloadItems(tabContent, params, promise);
+ };
+ };
+});
diff --git a/src/controllers/shows/tvupcoming.js b/src/controllers/shows/tvupcoming.js
index 9d6a79a5ef..f85278195f 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,131 @@ 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) {
+ console.log('error parsing timestamp for upcoming tv shows');
+ }
+ }
+
+ 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 += '
";
}
- elem.innerHTML = html, imageLoader.lazyChildren(elem)
+
+ elem.innerHTML = html;
+ imageLoader.lazyChildren(elem);
}
- return function(view, params, tabContent) {
- var upcomingPromise, self = this;
- self.preRender = function() {
- upcomingPromise = getUpcomingPromise(view, params)
- }, self.renderTab = function() {
- loadUpcoming(tabContent, params, upcomingPromise)
- }
- }
-});
\ No newline at end of file
+
+ return function (view, params, tabContent) {
+ var upcomingPromise;
+ var self = this;
+
+ self.preRender = function () {
+ upcomingPromise = getUpcomingPromise(view, params);
+ };
+
+ self.renderTab = function () {
+ loadUpcoming(tabContent, params, upcomingPromise);
+ };
+ };
+});
diff --git a/src/controllers/streamingsettings.js b/src/controllers/streamingsettings.js
index 6f19a68422..6c85034458 100644
--- a/src/controllers/streamingsettings.js
+++ b/src/controllers/streamingsettings.js
@@ -1,16 +1,19 @@
-define(["jQuery", "libraryMenu", "loading"], function($, libraryMenu, loading) {
+define(["jQuery", "libraryMenu", "loading"], function ($, libraryMenu, loading) {
"use strict";
function loadPage(page, config) {
- $("#txtRemoteClientBitrateLimit", page).val(config.RemoteClientBitrateLimit / 1e6 || ""), loading.hide()
+ $("#txtRemoteClientBitrateLimit", page).val(config.RemoteClientBitrateLimit / 1e6 || "");
+ loading.hide();
}
function onSubmit() {
loading.show();
var form = this;
- return ApiClient.getServerConfiguration().then(function(config) {
- config.RemoteClientBitrateLimit = parseInt(1e6 * parseFloat($("#txtRemoteClientBitrateLimit", form).val() || "0")), ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult)
- }), !1
+ ApiClient.getServerConfiguration().then(function (config) {
+ config.RemoteClientBitrateLimit = parseInt(1e6 * parseFloat($("#txtRemoteClientBitrateLimit", form).val() || "0"));
+ ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult);
+ });
+ return false;
}
function getTabs() {
@@ -23,30 +26,35 @@ define(["jQuery", "libraryMenu", "loading"], function($, libraryMenu, loading) {
}, {
href: "streamingsettings.html",
name: Globalize.translate("TabStreaming")
- }]
+ }];
}
- $(document).on("pageinit", "#streamingSettingsPage", function() {
+ $(document).on("pageinit", "#streamingSettingsPage", function () {
var page = this;
- $("#btnSelectTranscodingTempPath", page).on("click.selectDirectory", function() {
- require(["directorybrowser"], function(directoryBrowser) {
- var picker = new directoryBrowser;
+ $("#btnSelectTranscodingTempPath", page).on("click.selectDirectory", function () {
+ require(["directorybrowser"], function (directoryBrowser) {
+ var picker = new directoryBrowser();
picker.show({
- callback: function(path) {
- path && $("#txtTranscodingTempPath", page).val(path), picker.close()
+ callback: function (path) {
+ if (path) {
+ $("#txtTranscodingTempPath", page).val(path);
+ }
+
+ picker.close();
},
- validateWriteable: !0,
+ validateWriteable: true,
header: Globalize.translate("HeaderSelectTranscodingPath"),
instruction: Globalize.translate("HeaderSelectTranscodingPathHelp")
- })
- })
- }), $(".streamingSettingsForm").off("submit", onSubmit).on("submit", onSubmit)
- }).on("pageshow", "#streamingSettingsPage", function() {
+ });
+ });
+ });
+ $(".streamingSettingsForm").off("submit", onSubmit).on("submit", onSubmit);
+ }).on("pageshow", "#streamingSettingsPage", function () {
loading.show();
libraryMenu.setTabs("playback", 2, getTabs);
var page = this;
- ApiClient.getServerConfiguration().then(function(config) {
- loadPage(page, config)
- })
- })
-});
\ No newline at end of file
+ ApiClient.getServerConfiguration().then(function (config) {
+ loadPage(page, config);
+ });
+ });
+});
diff --git a/src/controllers/user/display.js b/src/controllers/user/display.js
index 4b4440f96a..f91e874a89 100644
--- a/src/controllers/user/display.js
+++ b/src/controllers/user/display.js
@@ -1,28 +1,49 @@
-define(["displaySettings", "userSettingsBuilder", "userSettings"], function(DisplaySettings, userSettingsBuilder, currentUserSettings) {
+define(["displaySettings", "userSettingsBuilder", "userSettings"], function (DisplaySettings, userSettingsBuilder, currentUserSettings) {
"use strict";
- return function(view, params) {
+
+ return function (view, params) {
function onBeforeUnload(e) {
- hasChanges && (e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?")
+ if (hasChanges) {
+ e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?";
+ }
}
- var settingsInstance, hasChanges, userId = params.userId || ApiClient.getCurrentUserId(),
- userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder;
- view.addEventListener("viewshow", function() {
- window.addEventListener("beforeunload", onBeforeUnload), settingsInstance ? settingsInstance.loadData() : settingsInstance = new DisplaySettings({
- serverId: ApiClient.serverId(),
- userId: userId,
- element: view.querySelector(".settingsContainer"),
- userSettings: userSettings,
- enableSaveButton: !1,
- enableSaveConfirmation: !1
- })
- }), view.addEventListener("change", function() {
- hasChanges = !0
- }), view.addEventListener("viewbeforehide", function() {
- window.removeEventListener("beforeunload", onBeforeUnload), hasChanges = !1, settingsInstance && settingsInstance.submit()
- }), view.addEventListener("viewdestroy", function() {
- settingsInstance && (settingsInstance.destroy(), settingsInstance = null)
- }), view.addEventListener("viewdestroy", function() {
- settingsInstance && (settingsInstance.destroy(), settingsInstance = null)
- })
- }
-});
\ No newline at end of file
+
+ var settingsInstance;
+ var hasChanges;
+ var userId = params.userId || ApiClient.getCurrentUserId();
+ var userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder();
+ view.addEventListener("viewshow", function () {
+ window.addEventListener("beforeunload", onBeforeUnload);
+
+ if (settingsInstance) {
+ settingsInstance.loadData();
+ } else {
+ settingsInstance = new DisplaySettings({
+ serverId: ApiClient.serverId(),
+ userId: userId,
+ element: view.querySelector(".settingsContainer"),
+ userSettings: userSettings,
+ enableSaveButton: false,
+ enableSaveConfirmation: false
+ });
+ }
+ });
+ view.addEventListener("change", function () {
+ hasChanges = true;
+ });
+ view.addEventListener("viewbeforehide", function () {
+ window.removeEventListener("beforeunload", onBeforeUnload);
+ hasChanges = false;
+
+ if (settingsInstance) {
+ settingsInstance.submit();
+ }
+ });
+ view.addEventListener("viewdestroy", function () {
+ if (settingsInstance) {
+ settingsInstance.destroy();
+ settingsInstance = null;
+ }
+ });
+ };
+});
diff --git a/src/controllers/user/home.js b/src/controllers/user/home.js
index a7147ddda3..5794d58723 100644
--- a/src/controllers/user/home.js
+++ b/src/controllers/user/home.js
@@ -1,26 +1,48 @@
-define(["homescreenSettings", "userSettingsBuilder", "dom", "globalize", "loading", "userSettings", "listViewStyle"], function(HomescreenSettings, userSettingsBuilder, dom, globalize, loading, currentUserSettings) {
+define(["homescreenSettings", "userSettingsBuilder", "dom", "globalize", "loading", "userSettings", "listViewStyle"], function (HomescreenSettings, userSettingsBuilder, dom, globalize, loading, currentUserSettings) {
"use strict";
- return function(view, params) {
+
+ return function (view, params) {
function onBeforeUnload(e) {
- hasChanges && (e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?")
+ if (hasChanges) {
+ e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?";
+ }
}
- var homescreenSettingsInstance, hasChanges, userId = params.userId || ApiClient.getCurrentUserId(),
- userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder;
- view.addEventListener("viewshow", function() {
- window.addEventListener("beforeunload", onBeforeUnload), homescreenSettingsInstance ? homescreenSettingsInstance.loadData() : homescreenSettingsInstance = new HomescreenSettings({
- serverId: ApiClient.serverId(),
- userId: userId,
- element: view.querySelector(".homeScreenSettingsContainer"),
- userSettings: userSettings,
- enableSaveButton: !1,
- enableSaveConfirmation: !1
- })
- }), view.addEventListener("change", function() {
- hasChanges = !0
- }), view.addEventListener("viewbeforehide", function() {
- hasChanges = !1, homescreenSettingsInstance && homescreenSettingsInstance.submit()
- }), view.addEventListener("viewdestroy", function() {
- homescreenSettingsInstance && (homescreenSettingsInstance.destroy(), homescreenSettingsInstance = null)
- })
- }
-});
\ No newline at end of file
+
+ var homescreenSettingsInstance;
+ var hasChanges;
+ var userId = params.userId || ApiClient.getCurrentUserId();
+ var userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder();
+ view.addEventListener("viewshow", function () {
+ window.addEventListener("beforeunload", onBeforeUnload);
+
+ if (homescreenSettingsInstance) {
+ homescreenSettingsInstance.loadData();
+ } else {
+ homescreenSettingsInstance = new HomescreenSettings({
+ serverId: ApiClient.serverId(),
+ userId: userId,
+ element: view.querySelector(".homeScreenSettingsContainer"),
+ userSettings: userSettings,
+ enableSaveButton: false,
+ enableSaveConfirmation: false
+ });
+ }
+ });
+ view.addEventListener("change", function () {
+ hasChanges = true;
+ });
+ view.addEventListener("viewbeforehide", function () {
+ hasChanges = false;
+
+ if (homescreenSettingsInstance) {
+ homescreenSettingsInstance.submit();
+ }
+ });
+ view.addEventListener("viewdestroy", function () {
+ if (homescreenSettingsInstance) {
+ homescreenSettingsInstance.destroy();
+ homescreenSettingsInstance = null;
+ }
+ });
+ };
+});
diff --git a/src/controllers/user/menu.js b/src/controllers/user/menu.js
index 6bac0011d2..d9fa2ab998 100644
--- a/src/controllers/user/menu.js
+++ b/src/controllers/user/menu.js
@@ -18,7 +18,7 @@ define(["apphost", "connectionManager", "listViewStyle", "emby-button"], functio
page.querySelector(".lnkSubtitlePreferences").setAttribute("href", "mypreferencessubtitles.html?userId=" + userId);
if (appHost.supports("multiserver")) {
- page.querySelector(".selectServer").classList.remove("hide")
+ page.querySelector(".selectServer").classList.remove("hide");
} else {
page.querySelector(".selectServer").classList.add("hide");
}
@@ -35,6 +35,6 @@ define(["apphost", "connectionManager", "listViewStyle", "emby-button"], functio
page.querySelector(".adminSection").classList.add("hide");
}
});
- })
- }
+ });
+ };
});
diff --git a/src/controllers/user/playback.js b/src/controllers/user/playback.js
index 856470948a..f2463ad8df 100644
--- a/src/controllers/user/playback.js
+++ b/src/controllers/user/playback.js
@@ -1,26 +1,48 @@
-define(["playbackSettings", "userSettingsBuilder", "dom", "globalize", "loading", "userSettings", "listViewStyle"], function(PlaybackSettings, userSettingsBuilder, dom, globalize, loading, currentUserSettings) {
+define(["playbackSettings", "userSettingsBuilder", "dom", "globalize", "loading", "userSettings", "listViewStyle"], function (PlaybackSettings, userSettingsBuilder, dom, globalize, loading, currentUserSettings) {
"use strict";
- return function(view, params) {
+
+ return function (view, params) {
function onBeforeUnload(e) {
- hasChanges && (e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?")
+ if (hasChanges) {
+ e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?";
+ }
}
- var settingsInstance, hasChanges, userId = params.userId || ApiClient.getCurrentUserId(),
- userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder;
- view.addEventListener("viewshow", function() {
- window.addEventListener("beforeunload", onBeforeUnload), settingsInstance ? settingsInstance.loadData() : settingsInstance = new PlaybackSettings({
- serverId: ApiClient.serverId(),
- userId: userId,
- element: view.querySelector(".settingsContainer"),
- userSettings: userSettings,
- enableSaveButton: !1,
- enableSaveConfirmation: !1
- })
- }), view.addEventListener("change", function() {
- hasChanges = !0
- }), view.addEventListener("viewbeforehide", function() {
- hasChanges = !1, settingsInstance && settingsInstance.submit()
- }), view.addEventListener("viewdestroy", function() {
- settingsInstance && (settingsInstance.destroy(), settingsInstance = null)
- })
- }
-});
\ No newline at end of file
+
+ var settingsInstance;
+ var hasChanges;
+ var userId = params.userId || ApiClient.getCurrentUserId();
+ var userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder();
+ view.addEventListener("viewshow", function () {
+ window.addEventListener("beforeunload", onBeforeUnload);
+
+ if (settingsInstance) {
+ settingsInstance.loadData();
+ } else {
+ settingsInstance = new PlaybackSettings({
+ serverId: ApiClient.serverId(),
+ userId: userId,
+ element: view.querySelector(".settingsContainer"),
+ userSettings: userSettings,
+ enableSaveButton: false,
+ enableSaveConfirmation: false
+ });
+ }
+ });
+ view.addEventListener("change", function () {
+ hasChanges = true;
+ });
+ view.addEventListener("viewbeforehide", function () {
+ hasChanges = false;
+
+ if (settingsInstance) {
+ settingsInstance.submit();
+ }
+ });
+ view.addEventListener("viewdestroy", function () {
+ if (settingsInstance) {
+ settingsInstance.destroy();
+ settingsInstance = null;
+ }
+ });
+ };
+});
diff --git a/src/controllers/user/subtitles.js b/src/controllers/user/subtitles.js
index 81d949e1a9..205265efcd 100644
--- a/src/controllers/user/subtitles.js
+++ b/src/controllers/user/subtitles.js
@@ -1,26 +1,48 @@
-define(["subtitleSettings", "userSettingsBuilder", "userSettings"], function(SubtitleSettings, userSettingsBuilder, currentUserSettings) {
+define(["subtitleSettings", "userSettingsBuilder", "userSettings"], function (SubtitleSettings, userSettingsBuilder, currentUserSettings) {
"use strict";
- return function(view, params) {
+
+ return function (view, params) {
function onBeforeUnload(e) {
- hasChanges && (e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?")
+ if (hasChanges) {
+ e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?";
+ }
}
- var subtitleSettingsInstance, hasChanges, userId = params.userId || ApiClient.getCurrentUserId(),
- userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder;
- view.addEventListener("viewshow", function() {
- window.addEventListener("beforeunload", onBeforeUnload), subtitleSettingsInstance ? subtitleSettingsInstance.loadData() : subtitleSettingsInstance = new SubtitleSettings({
- serverId: ApiClient.serverId(),
- userId: userId,
- element: view.querySelector(".settingsContainer"),
- userSettings: userSettings,
- enableSaveButton: !1,
- enableSaveConfirmation: !1
- })
- }), view.addEventListener("change", function() {
- hasChanges = !0
- }), view.addEventListener("viewbeforehide", function() {
- hasChanges = !1, subtitleSettingsInstance && subtitleSettingsInstance.submit()
- }), view.addEventListener("viewdestroy", function() {
- subtitleSettingsInstance && (subtitleSettingsInstance.destroy(), subtitleSettingsInstance = null)
- })
- }
-});
\ No newline at end of file
+
+ var subtitleSettingsInstance;
+ var hasChanges;
+ var userId = params.userId || ApiClient.getCurrentUserId();
+ var userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder();
+ view.addEventListener("viewshow", function () {
+ window.addEventListener("beforeunload", onBeforeUnload);
+
+ if (subtitleSettingsInstance) {
+ subtitleSettingsInstance.loadData();
+ } else {
+ subtitleSettingsInstance = new SubtitleSettings({
+ serverId: ApiClient.serverId(),
+ userId: userId,
+ element: view.querySelector(".settingsContainer"),
+ userSettings: userSettings,
+ enableSaveButton: false,
+ enableSaveConfirmation: false
+ });
+ }
+ });
+ view.addEventListener("change", function () {
+ hasChanges = true;
+ });
+ view.addEventListener("viewbeforehide", function () {
+ hasChanges = false;
+
+ if (subtitleSettingsInstance) {
+ subtitleSettingsInstance.submit();
+ }
+ });
+ view.addEventListener("viewdestroy", function () {
+ if (subtitleSettingsInstance) {
+ subtitleSettingsInstance.destroy();
+ subtitleSettingsInstance = null;
+ }
+ });
+ };
+});
diff --git a/src/controllers/useredit.js b/src/controllers/useredit.js
index 0709e8dae9..fb6a3f94cd 100644
--- a/src/controllers/useredit.js
+++ b/src/controllers/useredit.js
@@ -1,53 +1,84 @@
-define(["jQuery", "loading", "libraryMenu", "fnchecked"], function($, loading, libraryMenu) {
+define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, libraryMenu) {
"use strict";
function loadDeleteFolders(page, user, mediaFolders) {
ApiClient.getJSON(ApiClient.getUrl("Channels", {
- SupportsMediaDeletion: !0
- })).then(function(channelsResult) {
- var i, length, folder, isChecked, checkedAttribute, html = "";
- for (i = 0, length = mediaFolders.length; i < length; i++) folder = mediaFolders[i], isChecked = user.Policy.EnableContentDeletion || -1 != user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id), checkedAttribute = isChecked ? ' checked="checked"' : "", html += '
" + folder.Name + " ";
- 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 += '
" + folder.Name + " ";
- $(".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 += '
" + folder.Name + " ";
+ }
+
+ 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 += '
" + folder.Name + " ";
+ }
+
+ $(".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 '
" + provider.Name + " "
- })
+ return '
" + provider.Name + " ";
+ });
}
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 '
" + provider.Name + " "
- })
+ page.querySelector(".selectPasswordResetProvider").innerHTML = providers.map(function (provider) {
+ var selected = provider.Id === currentProviderId || providers.length < 2 ? " selected" : "";
+ return '
" + provider.Name + " ";
+ });
}
function loadUser(page, user) {
currentUser = user;
- ApiClient.getJSON(ApiClient.getUrl("Auth/Providers")).then(function(providers) {
- loadAuthProviders(page, user, providers)
+ ApiClient.getJSON(ApiClient.getUrl("Auth/Providers")).then(function (providers) {
+ loadAuthProviders(page, user, providers);
});
- ApiClient.getJSON(ApiClient.getUrl("Auth/PasswordResetProviders")).then(function(providers) {
- loadPasswordResetProviders(page, user, providers)
+ ApiClient.getJSON(ApiClient.getUrl("Auth/PasswordResetProviders")).then(function (providers) {
+ loadPasswordResetProviders(page, user, providers);
});
ApiClient.getJSON(ApiClient.getUrl("Library/MediaFolders", {
- IsHidden: false
- })).then(function(folders) {
- loadDeleteFolders(page, user, folders.Items)
+ IsHidden: false
+ })).then(function (folders) {
+ loadDeleteFolders(page, user, folders.Items);
});
+
if (user.Policy.IsDisabled) {
$(".disabledUserBanner", page).show();
} else {
$(".disabledUserBanner", page).hide();
}
+
$("#txtUserName", page).prop("disabled", "").removeAttr("disabled");
$("#fldConnectInfo", page).show();
$(".lnkEditUserPreferences", page).attr("href", "mypreferencesmenu.html?userId=" + user.Id);
@@ -78,7 +109,8 @@ define(["jQuery", "loading", "libraryMenu", "fnchecked"], function($, loading, l
function onSaveComplete(page, user) {
Dashboard.navigate("userprofiles.html");
loading.hide();
- require(["toast"], function(toast) {
+
+ require(["toast"], function (toast) {
toast(Globalize.translate("SettingsSaved"));
});
}
@@ -106,45 +138,59 @@ define(["jQuery", "loading", "libraryMenu", "fnchecked"], function($, loading, l
user.Policy.AuthenticationProviderId = page.querySelector(".selectLoginProvider").value;
user.Policy.PasswordResetProviderId = page.querySelector(".selectPasswordResetProvider").value;
user.Policy.EnableContentDeletion = $("#chkEnableDeleteAllFolders", page).checked();
- user.Policy.EnableContentDeletionFromFolders = user.Policy.EnableContentDeletion ? [] : $(".chkFolder", page).get().filter(function(c) {
- return c.checked
- }).map(function(c) {
- return c.getAttribute("data-id")
+ user.Policy.EnableContentDeletionFromFolders = user.Policy.EnableContentDeletion ? [] : $(".chkFolder", page).get().filter(function (c) {
+ return c.checked;
+ }).map(function (c) {
+ return c.getAttribute("data-id");
+ });
+ ApiClient.updateUser(user).then(function () {
+ ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () {
+ onSaveComplete(page, user);
+ });
});
- ApiClient.updateUser(user).then(function() {
- ApiClient.updateUserPolicy(user.Id, user.Policy).then(function() {
- onSaveComplete(page, user)
- })
- })
}
function onSubmit() {
var page = $(this).parents(".page")[0];
- return loading.show(), getUser().then(function(result) {
- saveUser(result, page)
- }), !1
+ loading.show();
+ getUser().then(function (result) {
+ saveUser(result, page);
+ });
+ return false;
}
function getUser() {
var userId = getParameterByName("userId");
- return ApiClient.getUser(userId)
+ return ApiClient.getUser(userId);
}
function loadData(page) {
- loading.show(), getUser().then(function(user) {
- loadUser(page, user)
- })
+ loading.show();
+ getUser().then(function (user) {
+ loadUser(page, user);
+ });
}
+
var currentUser;
- $(document).on("pageinit", "#editUserPage", function() {
- $(".editUserProfileForm").off("submit", onSubmit).on("submit", onSubmit), this.querySelector(".sharingHelp").innerHTML = Globalize.translate("OptionAllowLinkSharingHelp", 30);
+ $(document).on("pageinit", "#editUserPage", function () {
+ $(".editUserProfileForm").off("submit", onSubmit).on("submit", onSubmit);
+ this.querySelector(".sharingHelp").innerHTML = Globalize.translate("OptionAllowLinkSharingHelp", 30);
var page = this;
- $("#chkEnableDeleteAllFolders", this).on("change", function() {
- this.checked ? $(".deleteAccess", page).hide() : $(".deleteAccess", page).show()
- }), ApiClient.getServerConfiguration().then(function(config) {
- config.EnableRemoteAccess ? page.querySelector(".fldRemoteAccess").classList.remove("hide") : page.querySelector(".fldRemoteAccess").classList.add("hide")
- })
- }).on("pagebeforeshow", "#editUserPage", function() {
- loadData(this)
- })
+ $("#chkEnableDeleteAllFolders", this).on("change", function () {
+ if (this.checked) {
+ $(".deleteAccess", page).hide();
+ } else {
+ $(".deleteAccess", page).show();
+ }
+ });
+ ApiClient.getServerConfiguration().then(function (config) {
+ if (config.EnableRemoteAccess) {
+ page.querySelector(".fldRemoteAccess").classList.remove("hide");
+ } else {
+ page.querySelector(".fldRemoteAccess").classList.add("hide");
+ }
+ });
+ }).on("pagebeforeshow", "#editUserPage", function () {
+ loadData(this);
+ });
});
diff --git a/src/controllers/userlibraryaccess.js b/src/controllers/userlibraryaccess.js
index 8352e90c3e..38418f5190 100644
--- a/src/controllers/userlibraryaccess.js
+++ b/src/controllers/userlibraryaccess.js
@@ -1,112 +1,178 @@
-define(["jQuery", "loading", "libraryMenu", "fnchecked"], function($, loading, libraryMenu) {
+define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, libraryMenu) {
"use strict";
function triggerChange(select) {
var evt = document.createEvent("HTMLEvents");
- evt.initEvent("change", !1, !0), select.dispatchEvent(evt)
+ evt.initEvent("change", false, true);
+ select.dispatchEvent(evt);
}
function loadMediaFolders(page, user, mediaFolders) {
var html = "";
- html += '
' + Globalize.translate("HeaderLibraries") + " ", html += '
";
+ 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 += '" + folder.Name + " "
+ var folder = channels[i];
+ var isChecked = user.Policy.EnableAllChannels || -1 != user.Policy.EnabledChannels.indexOf(folder.Id);
+ var checkedAttribute = isChecked ? ' checked="checked"' : "";
+ html += '" + folder.Name + " ";
}
- 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 += '
", $(".deviceAccess", page).show().html(html), $("#chkEnableAllDevices", page).checked(user.Policy.EnableAllDevices).trigger("change"), user.Policy.IsAdministrator ? page.querySelector(".deviceAccessContainer").classList.add("hide") : page.querySelector(".deviceAccessContainer").classList.remove("hide")
}
function loadUser(page, user, loggedInUser, mediaFolders, channels, devices) {
- page.querySelector(".username").innerHTML = user.Name, libraryMenu.setTitle(user.Name), loadChannels(page, user, channels), loadMediaFolders(page, user, mediaFolders), loadDevices(page, user, devices), loading.hide()
+ page.querySelector(".username").innerHTML = user.Name;
+ libraryMenu.setTitle(user.Name);
+ loadChannels(page, user, channels);
+ loadMediaFolders(page, user, mediaFolders);
+ loadDevices(page, user, devices);
+ loading.hide();
}
function onSaveComplete(page) {
- loading.hide(), require(["toast"], function(toast) {
- toast(Globalize.translate("SettingsSaved"))
- })
+ loading.hide();
+
+ require(["toast"], function (toast) {
+ toast(Globalize.translate("SettingsSaved"));
+ });
}
function saveUser(user, page) {
- user.Policy.EnableAllFolders = $("#chkEnableAllFolders", page).checked(), user.Policy.EnabledFolders = user.Policy.EnableAllFolders ? [] : $(".chkFolder", page).get().filter(function(c) {
- return c.checked
- }).map(function(c) {
- return c.getAttribute("data-id")
- }), user.Policy.EnableAllChannels = $("#chkEnableAllChannels", page).checked(), user.Policy.EnabledChannels = user.Policy.EnableAllChannels ? [] : $(".chkChannel", page).get().filter(function(c) {
- return c.checked
- }).map(function(c) {
- return c.getAttribute("data-id")
- }), user.Policy.EnableAllDevices = $("#chkEnableAllDevices", page).checked(), user.Policy.EnabledDevices = user.Policy.EnableAllDevices ? [] : $(".chkDevice", page).get().filter(function(c) {
- return c.checked
- }).map(function(c) {
- return c.getAttribute("data-id")
- }), user.Policy.BlockedChannels = null, user.Policy.BlockedMediaFolders = null, ApiClient.updateUserPolicy(user.Id, user.Policy).then(function() {
- onSaveComplete(page)
- })
+ user.Policy.EnableAllFolders = $("#chkEnableAllFolders", page).checked();
+ user.Policy.EnabledFolders = user.Policy.EnableAllFolders ? [] : $(".chkFolder", page).get().filter(function (c) {
+ return c.checked;
+ }).map(function (c) {
+ return c.getAttribute("data-id");
+ });
+ user.Policy.EnableAllChannels = $("#chkEnableAllChannels", page).checked();
+ user.Policy.EnabledChannels = user.Policy.EnableAllChannels ? [] : $(".chkChannel", page).get().filter(function (c) {
+ return c.checked;
+ }).map(function (c) {
+ return c.getAttribute("data-id");
+ });
+ user.Policy.EnableAllDevices = $("#chkEnableAllDevices", page).checked();
+ user.Policy.EnabledDevices = user.Policy.EnableAllDevices ? [] : $(".chkDevice", page).get().filter(function (c) {
+ return c.checked;
+ }).map(function (c) {
+ return c.getAttribute("data-id");
+ });
+ user.Policy.BlockedChannels = null;
+ user.Policy.BlockedMediaFolders = null;
+ ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () {
+ onSaveComplete(page);
+ });
}
function onSubmit() {
var page = $(this).parents(".page");
loading.show();
var userId = getParameterByName("userId");
- return ApiClient.getUser(userId).then(function(result) {
- saveUser(result, page)
- }), !1
+ ApiClient.getUser(userId).then(function (result) {
+ saveUser(result, page);
+ });
+ return false;
}
- $(document).on("pageinit", "#userLibraryAccessPage", function() {
+
+ $(document).on("pageinit", "#userLibraryAccessPage", function () {
var page = this;
- $("#chkEnableAllDevices", page).on("change", function() {
- this.checked ? $(".deviceAccessListContainer", page).hide() : $(".deviceAccessListContainer", page).show()
- }), $("#chkEnableAllChannels", page).on("change", function() {
- this.checked ? $(".channelAccessListContainer", page).hide() : $(".channelAccessListContainer", page).show()
- }), page.querySelector("#chkEnableAllFolders").addEventListener("change", function() {
- this.checked ? page.querySelector(".folderAccessListContainer").classList.add("hide") : page.querySelector(".folderAccessListContainer").classList.remove("hide")
- }), $(".userLibraryAccessForm").off("submit", onSubmit).on("submit", onSubmit)
- }).on("pageshow", "#userLibraryAccessPage", function() {
+ $("#chkEnableAllDevices", page).on("change", function () {
+ if (this.checked) {
+ $(".deviceAccessListContainer", page).hide();
+ } else {
+ $(".deviceAccessListContainer", page).show();
+ }
+ });
+ $("#chkEnableAllChannels", page).on("change", function () {
+ if (this.checked) {
+ $(".channelAccessListContainer", page).hide();
+ } else {
+ $(".channelAccessListContainer", page).show();
+ }
+ });
+ page.querySelector("#chkEnableAllFolders").addEventListener("change", function () {
+ if (this.checked) {
+ page.querySelector(".folderAccessListContainer").classList.add("hide");
+ } else {
+ page.querySelector(".folderAccessListContainer").classList.remove("hide");
+ }
+ });
+ $(".userLibraryAccessForm").off("submit", onSubmit).on("submit", onSubmit);
+ }).on("pageshow", "#userLibraryAccessPage", function () {
var page = this;
loading.show();
- var promise1, userId = getParameterByName("userId");
- if (userId) promise1 = ApiClient.getUser(userId);
- else {
+ var promise1;
+ var userId = getParameterByName("userId");
+
+ if (userId) {
+ promise1 = ApiClient.getUser(userId);
+ } else {
var deferred = $.Deferred();
deferred.resolveWith(null, [{
Configuration: {}
- }]), promise1 = deferred.promise()
+ }]);
+ promise1 = deferred.promise();
}
- var promise2 = Dashboard.getCurrentUser(),
- promise4 = ApiClient.getJSON(ApiClient.getUrl("Library/MediaFolders", {
- IsHidden: !1
- })),
- promise5 = ApiClient.getJSON(ApiClient.getUrl("Channels")),
- promise6 = ApiClient.getJSON(ApiClient.getUrl("Devices"));
- Promise.all([promise1, promise2, promise4, promise5, promise6]).then(function(responses) {
- loadUser(page, responses[0], responses[1], responses[2].Items, responses[3].Items, responses[4].Items)
- })
- })
-});
\ No newline at end of file
+
+ var promise2 = Dashboard.getCurrentUser();
+ var promise4 = ApiClient.getJSON(ApiClient.getUrl("Library/MediaFolders", {
+ IsHidden: false
+ }));
+ var promise5 = ApiClient.getJSON(ApiClient.getUrl("Channels"));
+ var promise6 = ApiClient.getJSON(ApiClient.getUrl("Devices"));
+ Promise.all([promise1, promise2, promise4, promise5, promise6]).then(function (responses) {
+ loadUser(page, responses[0], responses[1], responses[2].Items, responses[3].Items, responses[4].Items);
+ });
+ });
+});
diff --git a/src/controllers/usernew.js b/src/controllers/usernew.js
index 10fa6fc4f3..ec80679f8c 100644
--- a/src/controllers/usernew.js
+++ b/src/controllers/usernew.js
@@ -1,14 +1,16 @@
-define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function($, loading) {
+define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function ($, loading) {
"use strict";
function loadMediaFolders(page, mediaFolders) {
var html = "";
html += '
' + Globalize.translate("HeaderLibraries") + " ";
html += '
';
+
for (var i = 0; i < mediaFolders.length; i++) {
var folder = mediaFolders[i];
html += '' + folder.Name + " ";
}
+
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 += '' + folder.Name + " ";
}
+
html += "
";
$(".channelAccess", page).show().html(html).trigger("create");
+
if (channels.length) {
$(".channelAccessContainer", page).show();
} else {
$(".channelAccessContainer", page).hide();
}
+
$("#chkEnableAllChannels", page).checked(true).trigger("change");
}
@@ -37,46 +43,51 @@ define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function($, loading)
$("#txtPassword", page).val("");
loading.show();
var promiseFolders = ApiClient.getJSON(ApiClient.getUrl("Library/MediaFolders", {
- IsHidden: false
+ IsHidden: false
}));
var promiseChannels = ApiClient.getJSON(ApiClient.getUrl("Channels"));
- Promise.all([promiseFolders, promiseChannels]).then(function(responses) {
+ Promise.all([promiseFolders, promiseChannels]).then(function (responses) {
loadMediaFolders(page, responses[0].Items);
loadChannels(page, responses[1].Items);
loading.hide();
- })
+ });
}
function saveUser(page) {
var user = {};
user.Name = $("#txtUsername", page).val();
user.Password = $("#txtPassword", page).val();
- ApiClient.createUser(user).then(function(user) {
+ ApiClient.createUser(user).then(function (user) {
user.Policy.EnableAllFolders = $("#chkEnableAllFolders", page).checked();
user.Policy.EnabledFolders = [];
+
if (!user.Policy.EnableAllFolders) {
- user.Policy.EnabledFolders = $(".chkFolder", page).get().filter(function(i) {
- return i.checked
- }).map(function(i) {
+ user.Policy.EnabledFolders = $(".chkFolder", page).get().filter(function (i) {
+ return i.checked;
+ }).map(function (i) {
return i.getAttribute("data-id");
});
}
+
user.Policy.EnableAllChannels = $("#chkEnableAllChannels", page).checked();
user.Policy.EnabledChannels = [];
+
if (!user.Policy.EnableAllChannels) {
- user.Policy.EnabledChannels = $(".chkChannel", page).get().filter(function(i) {
- return i.checked
- }).map(function(i) {
+ user.Policy.EnabledChannels = $(".chkChannel", page).get().filter(function (i) {
+ return i.checked;
+ }).map(function (i) {
return i.getAttribute("data-id");
});
}
- ApiClient.updateUserPolicy(user.Id, user.Policy).then(function() {
+
+ ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () {
Dashboard.navigate("useredit.html?userId=" + user.Id);
});
- }, function(response) {
- require(["toast"], function(toast) {
+ }, function (response) {
+ require(["toast"], function (toast) {
toast(Globalize.translate("DefaultErrorMessage"));
});
+
loading.hide();
});
}
@@ -92,16 +103,16 @@ define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function($, loading)
loadUser(page);
}
- $(document).on("pageinit", "#newUserPage", function() {
+ $(document).on("pageinit", "#newUserPage", function () {
var page = this;
- $("#chkEnableAllChannels", page).on("change", function() {
+ $("#chkEnableAllChannels", page).on("change", function () {
if (this.checked) {
$(".channelAccessListContainer", page).hide();
} else {
$(".channelAccessListContainer", page).show();
}
});
- $("#chkEnableAllFolders", page).on("change", function() {
+ $("#chkEnableAllFolders", page).on("change", function () {
if (this.checked) {
$(".folderAccessListContainer", page).hide();
} else {
@@ -109,7 +120,7 @@ define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function($, loading)
}
});
$(".newUserProfileForm").off("submit", onSubmit).on("submit", onSubmit);
- }).on("pageshow", "#newUserPage", function() {
+ }).on("pageshow", "#newUserPage", function () {
loadData(this);
});
-});
\ No newline at end of file
+});
diff --git a/src/controllers/userparentalcontrol.js b/src/controllers/userparentalcontrol.js
index 381dc8cea9..2a862912d5 100644
--- a/src/controllers/userparentalcontrol.js
+++ b/src/controllers/userparentalcontrol.js
@@ -1,185 +1,271 @@
-define(["jQuery", "datetime", "loading", "libraryMenu", "listViewStyle", "paper-icon-button-light"], function($, datetime, loading, libraryMenu) {
+define(["jQuery", "datetime", "loading", "libraryMenu", "listViewStyle", "paper-icon-button-light"], function ($, datetime, loading, libraryMenu) {
"use strict";
function populateRatings(allParentalRatings, page) {
var html = "";
html += "
";
- var i, length, rating, ratings = [];
+ var i;
+ var length;
+ var rating;
+ var ratings = [];
+
for (i = 0, length = allParentalRatings.length; i < length; i++) {
if (rating = allParentalRatings[i], ratings.length) {
var lastRating = ratings[ratings.length - 1];
+
if (lastRating.Value === rating.Value) {
lastRating.Name += "/" + rating.Name;
- continue
+ continue;
}
}
+
ratings.push({
Name: rating.Name,
Value: rating.Value
- })
+ });
}
- for (i = 0, length = ratings.length; i < length; i++) rating = ratings[i], html += "
" + rating.Name + " ";
- $("#selectMaxParentalRating", page).html(html)
+
+ for (i = 0, length = ratings.length; i < length; i++) {
+ rating = ratings[i];
+ html += "
" + rating.Name + " ";
+ }
+
+ $("#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 += '" + item.name + " "
+ var item = items[i];
+ var checkedAttribute = -1 != user.Policy.BlockUnratedItems.indexOf(item.value) ? ' checked="checked"' : "";
+ html += '" + item.name + " ";
}
- 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 += '
delete ', li += "
"
+ li += '
';
+ li += '
';
+ li += h;
+ li += " ";
+ li += "";
+ li += '
delete ';
+ 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 += '
delete ', itemHtml += "
", index++, itemHtml
+ itemHtml += '
';
+ itemHtml += '
';
+ itemHtml += '
';
+ itemHtml += Globalize.translate("Option" + a.DayOfWeek);
+ itemHtml += " ";
+ itemHtml += '
' + getDisplayTime(a.StartHour) + " - " + getDisplayTime(a.EndHour) + "
";
+ itemHtml += "
";
+ itemHtml += '
delete ';
+ itemHtml += "
";
+ index++;
+ return itemHtml;
}).join("");
var accessScheduleList = page.querySelector(".accessScheduleList");
- accessScheduleList.innerHTML = html, $(".btnDelete", accessScheduleList).on("click", function() {
- deleteAccessSchedule(page, schedules, parseInt(this.getAttribute("data-index")))
- })
+ accessScheduleList.innerHTML = html;
+ $(".btnDelete", accessScheduleList).on("click", function () {
+ deleteAccessSchedule(page, schedules, parseInt(this.getAttribute("data-index")));
+ });
}
function onSaveComplete(page) {
- loading.hide(), require(["toast"], function(toast) {
- toast(Globalize.translate("SettingsSaved"))
- })
+ loading.hide();
+
+ require(["toast"], function (toast) {
+ toast(Globalize.translate("SettingsSaved"));
+ });
}
function saveUser(user, page) {
- user.Policy.MaxParentalRating = $("#selectMaxParentalRating", page).val() || null, user.Policy.BlockUnratedItems = $(".chkUnratedItem", page).get().filter(function(i) {
- return i.checked
- }).map(function(i) {
- return i.getAttribute("data-itemtype")
- }), user.Policy.AccessSchedules = getSchedulesFromPage(page), user.Policy.BlockedTags = getBlockedTagsFromPage(page), ApiClient.updateUserPolicy(user.Id, user.Policy).then(function() {
- onSaveComplete(page)
- })
+ user.Policy.MaxParentalRating = $("#selectMaxParentalRating", page).val() || null;
+ user.Policy.BlockUnratedItems = $(".chkUnratedItem", page).get().filter(function (i) {
+ return i.checked;
+ }).map(function (i) {
+ return i.getAttribute("data-itemtype");
+ });
+ user.Policy.AccessSchedules = getSchedulesFromPage(page);
+ user.Policy.BlockedTags = getBlockedTagsFromPage(page);
+ ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () {
+ onSaveComplete(page);
+ });
}
function getDisplayTime(hours) {
- var minutes = 0,
- pct = hours % 1;
- return pct && (minutes = parseInt(60 * pct)), datetime.getDisplayTime(new Date(2e3, 1, 1, hours, minutes, 0, 0))
+ var minutes = 0;
+ var pct = hours % 1;
+
+ if (pct) {
+ minutes = parseInt(60 * pct);
+ }
+
+ return datetime.getDisplayTime(new Date(2000, 1, 1, hours, minutes, 0, 0));
}
function showSchedulePopup(page, schedule, index) {
- schedule = schedule || {}, require(["components/accessschedule/accessschedule"], function(accessschedule) {
+ schedule = schedule || {};
+
+ require(["components/accessschedule/accessschedule"], function (accessschedule) {
accessschedule.show({
schedule: schedule
- }).then(function(updatedSchedule) {
- var schedules = getSchedulesFromPage(page); - 1 == index && (index = schedules.length), schedules[index] = updatedSchedule, renderAccessSchedule(page, schedules)
- })
- })
+ }).then(function (updatedSchedule) {
+ var schedules = getSchedulesFromPage(page);
+
+ if (-1 == index) {
+ index = schedules.length;
+ }
+
+ schedules[index] = updatedSchedule;
+ renderAccessSchedule(page, schedules);
+ });
+ });
}
function getSchedulesFromPage(page) {
- return $(".liSchedule", page).map(function() {
+ return $(".liSchedule", page).map(function () {
return {
DayOfWeek: this.getAttribute("data-day"),
StartHour: this.getAttribute("data-start"),
EndHour: this.getAttribute("data-end")
- }
- }).get()
+ };
+ }).get();
}
function getBlockedTagsFromPage(page) {
- return $(".blockedTag", page).map(function() {
- return this.getAttribute("data-tag")
- }).get()
+ return $(".blockedTag", page).map(function () {
+ return this.getAttribute("data-tag");
+ }).get();
}
function showBlockedTagPopup(page) {
- require(["prompt"], function(prompt) {
+ require(["prompt"], function (prompt) {
prompt({
label: Globalize.translate("LabelTag")
- }).then(function(value) {
- var tags = getBlockedTagsFromPage(page); - 1 == tags.indexOf(value) && (tags.push(value), loadBlockedTags(page, tags))
- })
- })
+ }).then(function (value) {
+ var tags = getBlockedTagsFromPage(page);
+
+ if (-1 == tags.indexOf(value)) {
+ tags.push(value);
+ loadBlockedTags(page, tags);
+ }
+ });
+ });
}
+
window.UserParentalControlPage = {
- onSubmit: function() {
+ onSubmit: function () {
var page = $(this).parents(".page");
loading.show();
var userId = getParameterByName("userId");
- return ApiClient.getUser(userId).then(function(result) {
- saveUser(result, page)
- }), !1
+ ApiClient.getUser(userId).then(function (result) {
+ saveUser(result, page);
+ });
+ return false;
}
- }, $(document).on("pageinit", "#userParentalControlPage", function() {
+ };
+ $(document).on("pageinit", "#userParentalControlPage", function () {
var page = this;
- $(".btnAddSchedule", page).on("click", function() {
- showSchedulePopup(page, {}, -1)
- }), $(".btnAddBlockedTag", page).on("click", function() {
- showBlockedTagPopup(page)
- }), $(".userParentalControlForm").off("submit", UserParentalControlPage.onSubmit).on("submit", UserParentalControlPage.onSubmit)
- }).on("pageshow", "#userParentalControlPage", function() {
+ $(".btnAddSchedule", page).on("click", function () {
+ showSchedulePopup(page, {}, -1);
+ });
+ $(".btnAddBlockedTag", page).on("click", function () {
+ showBlockedTagPopup(page);
+ });
+ $(".userParentalControlForm").off("submit", UserParentalControlPage.onSubmit).on("submit", UserParentalControlPage.onSubmit);
+ }).on("pageshow", "#userParentalControlPage", function () {
var page = this;
loading.show();
- var userId = getParameterByName("userId"),
- promise1 = ApiClient.getUser(userId),
- promise2 = ApiClient.getParentalRatings();
- Promise.all([promise1, promise2]).then(function(responses) {
- loadUser(page, responses[0], responses[1])
- })
- })
+ var userId = getParameterByName("userId");
+ var promise1 = ApiClient.getUser(userId);
+ var promise2 = ApiClient.getParentalRatings();
+ Promise.all([promise1, promise2]).then(function (responses) {
+ loadUser(page, responses[0], responses[1]);
+ });
+ });
});
diff --git a/src/controllers/userpasswordpage.js b/src/controllers/userpasswordpage.js
index d1eef004f6..30ca063278 100644
--- a/src/controllers/userpasswordpage.js
+++ b/src/controllers/userpasswordpage.js
@@ -1,101 +1,183 @@
-define(["loading", "libraryMenu", "emby-button"], function(loading, libraryMenu) {
+define(["loading", "libraryMenu", "emby-button"], function (loading, libraryMenu) {
"use strict";
function loadUser(page, params) {
var userid = params.userId;
- ApiClient.getUser(userid).then(function(user) {
- Dashboard.getCurrentUser().then(function(loggedInUser) {
- libraryMenu.setTitle(user.Name), page.querySelector(".username").innerHTML = user.Name;
- var showPasswordSection = !0,
- showLocalAccessSection = !1;
- "Guest" == user.ConnectLinkType ? (page.querySelector(".localAccessSection").classList.add("hide"), showPasswordSection = !1) : user.HasConfiguredPassword ? (page.querySelector("#btnResetPassword").classList.remove("hide"), page.querySelector("#fldCurrentPassword").classList.remove("hide"), showLocalAccessSection = !0) : (page.querySelector("#btnResetPassword").classList.add("hide"), page.querySelector("#fldCurrentPassword").classList.add("hide")), showPasswordSection && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess) ? page.querySelector(".passwordSection").classList.remove("hide") : page.querySelector(".passwordSection").classList.add("hide"), showLocalAccessSection && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess) ? page.querySelector(".localAccessSection").classList.remove("hide") : page.querySelector(".localAccessSection").classList.add("hide");
+ ApiClient.getUser(userid).then(function (user) {
+ Dashboard.getCurrentUser().then(function (loggedInUser) {
+ libraryMenu.setTitle(user.Name);
+ page.querySelector(".username").innerHTML = user.Name;
+ var showPasswordSection = true;
+ var showLocalAccessSection = false;
+
+ if ("Guest" == user.ConnectLinkType) {
+ page.querySelector(".localAccessSection").classList.add("hide");
+ showPasswordSection = false;
+ } else if (user.HasConfiguredPassword) {
+ page.querySelector("#btnResetPassword").classList.remove("hide");
+ page.querySelector("#fldCurrentPassword").classList.remove("hide");
+ showLocalAccessSection = true;
+ } else {
+ page.querySelector("#btnResetPassword").classList.add("hide");
+ page.querySelector("#fldCurrentPassword").classList.add("hide");
+ }
+
+ if (showPasswordSection && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess)) {
+ page.querySelector(".passwordSection").classList.remove("hide");
+ } else {
+ page.querySelector(".passwordSection").classList.add("hide");
+ }
+
+ if (showLocalAccessSection && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess)) {
+ page.querySelector(".localAccessSection").classList.remove("hide");
+ } else {
+ page.querySelector(".localAccessSection").classList.add("hide");
+ }
+
var txtEasyPassword = page.querySelector("#txtEasyPassword");
- txtEasyPassword.value = "", user.HasConfiguredEasyPassword ? (txtEasyPassword.placeholder = "******", page.querySelector("#btnResetEasyPassword").classList.remove("hide")) : (txtEasyPassword.removeAttribute("placeholder"), txtEasyPassword.placeholder = "", page.querySelector("#btnResetEasyPassword").classList.add("hide")), page.querySelector(".chkEnableLocalEasyPassword").checked = user.Configuration.EnableLocalPassword
- })
- }), page.querySelector("#txtCurrentPassword").value = "", page.querySelector("#txtNewPassword").value = "", page.querySelector("#txtNewPasswordConfirm").value = ""
+ txtEasyPassword.value = "";
+
+ if (user.HasConfiguredEasyPassword) {
+ txtEasyPassword.placeholder = "******";
+ page.querySelector("#btnResetEasyPassword").classList.remove("hide");
+ } else {
+ txtEasyPassword.removeAttribute("placeholder");
+ txtEasyPassword.placeholder = "";
+ page.querySelector("#btnResetEasyPassword").classList.add("hide");
+ }
+
+ page.querySelector(".chkEnableLocalEasyPassword").checked = user.Configuration.EnableLocalPassword;
+ });
+ });
+ page.querySelector("#txtCurrentPassword").value = "";
+ page.querySelector("#txtNewPassword").value = "";
+ page.querySelector("#txtNewPasswordConfirm").value = "";
}
- return function(view, params) {
+
+ return function (view, params) {
function saveEasyPassword() {
- var userId = params.userId,
- easyPassword = view.querySelector("#txtEasyPassword").value;
- easyPassword ? ApiClient.updateEasyPassword(userId, easyPassword).then(function() {
- onEasyPasswordSaved(userId)
- }) : onEasyPasswordSaved(userId)
+ var userId = params.userId;
+ var easyPassword = view.querySelector("#txtEasyPassword").value;
+
+ if (easyPassword) {
+ ApiClient.updateEasyPassword(userId, easyPassword).then(function () {
+ onEasyPasswordSaved(userId);
+ });
+ } else {
+ onEasyPasswordSaved(userId);
+ }
}
function onEasyPasswordSaved(userId) {
- ApiClient.getUser(userId).then(function(user) {
- user.Configuration.EnableLocalPassword = view.querySelector(".chkEnableLocalEasyPassword").checked, ApiClient.updateUserConfiguration(user.Id, user.Configuration).then(function() {
- loading.hide(), require(["toast"], function(toast) {
- toast(Globalize.translate("MessageSettingsSaved"))
- }), loadUser(view, params)
- })
- })
+ ApiClient.getUser(userId).then(function (user) {
+ user.Configuration.EnableLocalPassword = view.querySelector(".chkEnableLocalEasyPassword").checked;
+ ApiClient.updateUserConfiguration(user.Id, user.Configuration).then(function () {
+ loading.hide();
+
+ require(["toast"], function (toast) {
+ toast(Globalize.translate("MessageSettingsSaved"));
+ });
+
+ loadUser(view, params);
+ });
+ });
}
function savePassword() {
- var userId = params.userId,
- currentPassword = view.querySelector("#txtCurrentPassword").value,
- newPassword = view.querySelector("#txtNewPassword").value;
+ var userId = params.userId;
+ var currentPassword = view.querySelector("#txtCurrentPassword").value;
+ var newPassword = view.querySelector("#txtNewPassword").value;
+
if (view.querySelector("#fldCurrentPassword").classList.contains("hide")) {
// Firefox does not respect autocomplete=off, so clear it if the field is supposed to be hidden (and blank)
// This should only happen when user.HasConfiguredPassword is false, but this information is not passed on
currentPassword = "";
}
- ApiClient.updateUserPassword(userId, currentPassword, newPassword).then(function() {
- loading.hide(), require(["toast"], function(toast) {
- toast(Globalize.translate("PasswordSaved"))
- }), loadUser(view, params)
- }, function() {
- loading.hide(), Dashboard.alert({
+
+ ApiClient.updateUserPassword(userId, currentPassword, newPassword).then(function () {
+ loading.hide();
+
+ require(["toast"], function (toast) {
+ toast(Globalize.translate("PasswordSaved"));
+ });
+
+ loadUser(view, params);
+ }, function () {
+ loading.hide();
+ Dashboard.alert({
title: Globalize.translate("HeaderLoginFailure"),
message: Globalize.translate("MessageInvalidUser")
- })
- })
+ });
+ });
}
function onSubmit(e) {
var form = this;
- return form.querySelector("#txtNewPassword").value != form.querySelector("#txtNewPasswordConfirm").value ? require(["toast"], function(toast) {
- toast(Globalize.translate("PasswordMatchError"))
- }) : (loading.show(), savePassword()), e.preventDefault(), !1
+
+ if (form.querySelector("#txtNewPassword").value != form.querySelector("#txtNewPasswordConfirm").value) {
+ require(["toast"], function (toast) {
+ toast(Globalize.translate("PasswordMatchError"));
+ });
+ } else {
+ loading.show();
+ savePassword();
+ }
+
+ e.preventDefault();
+ return false;
}
function onLocalAccessSubmit(e) {
- return loading.show(), saveEasyPassword(), e.preventDefault(), !1
+ loading.show();
+ saveEasyPassword();
+ e.preventDefault();
+ return false;
}
function resetPassword() {
var msg = Globalize.translate("PasswordResetConfirmation");
- require(["confirm"], function(confirm) {
- confirm(msg, Globalize.translate("PasswordResetHeader")).then(function() {
+
+ require(["confirm"], function (confirm) {
+ confirm(msg, Globalize.translate("PasswordResetHeader")).then(function () {
var userId = params.userId;
- loading.show(), ApiClient.resetUserPassword(userId).then(function() {
- loading.hide(), Dashboard.alert({
+ loading.show();
+ ApiClient.resetUserPassword(userId).then(function () {
+ loading.hide();
+ Dashboard.alert({
message: Globalize.translate("PasswordResetComplete"),
title: Globalize.translate("PasswordResetHeader")
- }), loadUser(view, params)
- })
- })
- })
+ });
+ loadUser(view, params);
+ });
+ });
+ });
}
function resetEasyPassword() {
var msg = Globalize.translate("PinCodeResetConfirmation");
- require(["confirm"], function(confirm) {
- confirm(msg, Globalize.translate("HeaderPinCodeReset")).then(function() {
+
+ require(["confirm"], function (confirm) {
+ confirm(msg, Globalize.translate("HeaderPinCodeReset")).then(function () {
var userId = params.userId;
- loading.show(), ApiClient.resetEasyPassword(userId).then(function() {
- loading.hide(), Dashboard.alert({
+ loading.show();
+ ApiClient.resetEasyPassword(userId).then(function () {
+ loading.hide();
+ Dashboard.alert({
message: Globalize.translate("PinCodeResetComplete"),
title: Globalize.translate("HeaderPinCodeReset")
- }), loadUser(view, params)
- })
- })
- })
+ });
+ loadUser(view, params);
+ });
+ });
+ });
}
- view.querySelector(".updatePasswordForm").addEventListener("submit", onSubmit), view.querySelector(".localAccessForm").addEventListener("submit", onLocalAccessSubmit), view.querySelector("#btnResetEasyPassword").addEventListener("click", resetEasyPassword), view.querySelector("#btnResetPassword").addEventListener("click", resetPassword), view.addEventListener("viewshow", function() {
- loadUser(view, params)
- })
- }
+
+ view.querySelector(".updatePasswordForm").addEventListener("submit", onSubmit);
+ view.querySelector(".localAccessForm").addEventListener("submit", onLocalAccessSubmit);
+ view.querySelector("#btnResetEasyPassword").addEventListener("click", resetEasyPassword);
+ view.querySelector("#btnResetPassword").addEventListener("click", resetPassword);
+ view.addEventListener("viewshow", function () {
+ loadUser(view, params);
+ });
+ };
});
diff --git a/src/controllers/videoosd.js b/src/controllers/videoosd.js
index b610886963..2dcb0db82e 100644
--- a/src/controllers/videoosd.js
+++ b/src/controllers/videoosd.js
@@ -467,34 +467,34 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
switch (e.detail.command) {
case "left":
- if ("osd" === currentVisibleMenu) {
- showOsd();
- } else {
- if (!currentVisibleMenu) {
- e.preventDefault();
- playbackManager.rewind(player);
+ if ("osd" === currentVisibleMenu) {
+ showOsd();
+ } else {
+ if (!currentVisibleMenu) {
+ e.preventDefault();
+ playbackManager.rewind(player);
+ }
}
- }
- break;
+ break;
case "right":
- if ("osd" === currentVisibleMenu) {
- showOsd();
- } else if (!currentVisibleMenu) {
- e.preventDefault();
- playbackManager.fastForward(player);
- }
+ if ("osd" === currentVisibleMenu) {
+ showOsd();
+ } else if (!currentVisibleMenu) {
+ e.preventDefault();
+ playbackManager.fastForward(player);
+ }
- break;
+ break;
case "pageup":
- playbackManager.nextChapter(player);
- break;
+ playbackManager.nextChapter(player);
+ break;
case "pagedown":
- playbackManager.previousChapter(player);
- break;
+ playbackManager.previousChapter(player);
+ break;
case "up":
case "down":
@@ -508,16 +508,16 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
case "rewind":
case "next":
case "previous":
- showOsd();
- break;
+ showOsd();
+ break;
case "record":
- onRecordingCommand();
- showOsd();
- break;
+ onRecordingCommand();
+ showOsd();
+ break;
case "togglestats":
- toggleStats();
+ toggleStats();
}
}
@@ -770,6 +770,11 @@ 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 {
@@ -847,7 +852,6 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
var volumeSlider = view.querySelector('.osdVolumeSliderContainer');
var progressElement = volumeSlider.querySelector('.mdl-slider-background-lower');
-
if (-1 === supportedCommands.indexOf("Mute")) {
showMuteButton = false;
}
@@ -1057,7 +1061,7 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
var player = currentPlayer;
if (subtitleSyncOverlay) {
subtitleSyncOverlay.toggle(action);
- } else if(player){
+ } else if (player) {
subtitleSyncOverlay = new SubtitleSync(player);
}
});
@@ -1070,62 +1074,73 @@ 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();
+ showOsd();
+ return;
+ }
+
+ if (layoutManager.tv && NavigationKeys.indexOf(e.key) != -1) {
+ showOsd();
+ return;
}
switch (e.key) {
case "k":
playbackManager.playPause(currentPlayer);
showOsd();
- break;
+ break;
case "l":
case "ArrowRight":
case "Right":
playbackManager.fastForward(currentPlayer);
showOsd();
- break;
+ break;
case "j":
case "ArrowLeft":
case "Left":
playbackManager.rewind(currentPlayer);
showOsd();
- break;
+ break;
case "f":
- if (!e.ctrlKey && !e.metaKey) {
- playbackManager.toggleFullscreen(currentPlayer);
- showOsd();
- }
- break;
+ if (!e.ctrlKey && !e.metaKey) {
+ playbackManager.toggleFullscreen(currentPlayer);
+ showOsd();
+ }
+ break;
case "m":
- playbackManager.toggleMute(currentPlayer);
- showOsd();
- break;
+ playbackManager.toggleMute(currentPlayer);
+ showOsd();
+ break;
case "NavigationLeft":
case "GamepadDPadLeft":
case "GamepadLeftThumbstickLeft":
// Ignores gamepad events that are always triggered, even when not focused.
- if (document.hasFocus()) {
- playbackManager.rewind(currentPlayer);
- showOsd();
- }
- break;
+ if (document.hasFocus()) {
+ playbackManager.rewind(currentPlayer);
+ showOsd();
+ }
+ break;
case "NavigationRight":
case "GamepadDPadRight":
case "GamepadLeftThumbstickRight":
// Ignores gamepad events that are always triggered, even when not focused.
- if (document.hasFocus()) {
- playbackManager.fastForward(currentPlayer);
- showOsd();
- }
+ if (document.hasFocus()) {
+ playbackManager.fastForward(currentPlayer);
+ showOsd();
+ }
}
}
@@ -1237,6 +1252,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");
@@ -1253,7 +1274,7 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
dom.addEventListener(window, "keydown", onWindowKeyDown, {
passive: true
});
- } catch(e) {
+ } catch (e) {
require(['appRouter'], function(appRouter) {
appRouter.showDirect('/');
});
@@ -1312,24 +1333,24 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
switch (pointerType) {
case "touch":
- if (now - lastPointerDown > 300) {
- lastPointerDown = now;
- toggleOsd();
- }
+ if (now - lastPointerDown > 300) {
+ lastPointerDown = now;
+ toggleOsd();
+ }
- break;
+ break;
case "mouse":
- if (!e.button) {
- playbackManager.playPause(currentPlayer);
- showOsd();
- }
+ if (!e.button) {
+ playbackManager.playPause(currentPlayer);
+ showOsd();
+ }
- break;
+ break;
default:
- playbackManager.playPause(currentPlayer);
- showOsd();
+ playbackManager.playPause(currentPlayer);
+ showOsd();
}
}, {
passive: true
@@ -1339,14 +1360,16 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
dom.addEventListener(view, "dblclick", onDoubleClick, {});
} else {
var options = { passive: true };
- dom.addEventListener(view, "dblclick", function () { playbackManager.toggleFullscreen(currentPlayer); }, options);
+ dom.addEventListener(view, "dblclick", function () {
+ playbackManager.toggleFullscreen(currentPlayer);
+ }, options);
}
view.querySelector(".buttonMute").addEventListener("click", function () {
playbackManager.toggleMute(currentPlayer);
});
nowPlayingVolumeSlider.addEventListener("change", function () {
- if(volumeSliderTimer){
+ if (volumeSliderTimer) {
// interupt and remove existing timer
clearTimeout(volumeSliderTimer);
volumeSliderTimer = null;
@@ -1354,10 +1377,10 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
playbackManager.setVolume(this.value, currentPlayer);
});
nowPlayingVolumeSlider.addEventListener("mousemove", function () {
- if(!volumeSliderTimer){
+ if (!volumeSliderTimer) {
var that = this;
// register new timer
- volumeSliderTimer = setTimeout(function(){
+ volumeSliderTimer = setTimeout(function() {
playbackManager.setVolume(that.value, currentPlayer);
// delete timer after completion
volumeSliderTimer = null;
@@ -1365,10 +1388,10 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
}
});
nowPlayingVolumeSlider.addEventListener("touchmove", function () {
- if(!volumeSliderTimer){
+ if (!volumeSliderTimer) {
var that = this;
// register new timer
- volumeSliderTimer = setTimeout(function(){
+ volumeSliderTimer = setTimeout(function() {
playbackManager.setVolume(that.value, currentPlayer);
// delete timer after completion
volumeSliderTimer = null;
diff --git a/src/controllers/wizardfinishpage.js b/src/controllers/wizardfinishpage.js
index 417b2425a5..8242a16cb4 100644
--- a/src/controllers/wizardfinishpage.js
+++ b/src/controllers/wizardfinishpage.js
@@ -1,22 +1,18 @@
-define(["loading"], function(loading) {
+define(["loading"], function (loading) {
"use strict";
function onFinish() {
- loading.show(), ApiClient.ajax({
+ loading.show();
+ ApiClient.ajax({
url: ApiClient.getUrl("Startup/Complete"),
type: "POST"
- }).then(function() {
- Dashboard.navigate("dashboard.html");
+ }).then(function () {
loading.hide();
+ window.location.href = "index.html";
});
}
- return function(view, params) {
+
+ return function (view, params) {
view.querySelector(".btnWizardNext").addEventListener("click", onFinish);
- view.addEventListener("viewshow", function() {
- document.querySelector(".skinHeader").classList.add("noHomeButtonHeader")
- });
- view.addEventListener("viewhide", function() {
- document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader")
- });
};
});
diff --git a/src/controllers/wizardremoteaccess.js b/src/controllers/wizardremoteaccess.js
index 6856e0074f..554a417e57 100644
--- a/src/controllers/wizardremoteaccess.js
+++ b/src/controllers/wizardremoteaccess.js
@@ -1,31 +1,39 @@
-define(["loading", "emby-checkbox", "emby-button", "emby-select"], function(loading) {
+define(["loading", "emby-checkbox", "emby-button", "emby-select"], function (loading) {
"use strict";
function save(page) {
loading.show();
- var apiClient = ApiClient,
- config = {};
- config.EnableRemoteAccess = page.querySelector("#chkRemoteAccess").checked, config.EnableAutomaticPortMapping = page.querySelector("#chkEnableUpnp").checked, apiClient.ajax({
+ var apiClient = ApiClient;
+ var config = {};
+ config.EnableRemoteAccess = page.querySelector("#chkRemoteAccess").checked;
+ config.EnableAutomaticPortMapping = page.querySelector("#chkEnableUpnp").checked;
+ apiClient.ajax({
type: "POST",
data: config,
url: apiClient.getUrl("Startup/RemoteAccess")
- }).then(function() {
- loading.hide(), navigateToNextPage()
- })
+ }).then(function () {
+ loading.hide();
+ navigateToNextPage();
+ });
}
function navigateToNextPage() {
- Dashboard.navigate("wizardfinish.html")
+ Dashboard.navigate("wizardfinish.html");
}
function onSubmit(e) {
- return save(this), e.preventDefault(), !1
- }
- return function(view, params) {
- view.querySelector(".wizardSettingsForm").addEventListener("submit", onSubmit), view.addEventListener("viewshow", function() {
- document.querySelector(".skinHeader").classList.add("noHomeButtonHeader")
- }), view.addEventListener("viewhide", function() {
- document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader")
- })
+ save(this);
+ e.preventDefault();
+ return false;
}
+
+ return function (view, params) {
+ view.querySelector(".wizardSettingsForm").addEventListener("submit", onSubmit);
+ view.addEventListener("viewshow", function () {
+ document.querySelector(".skinHeader").classList.add("noHomeButtonHeader");
+ });
+ view.addEventListener("viewhide", function () {
+ document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader");
+ });
+ };
});
diff --git a/src/controllers/wizardsettings.js b/src/controllers/wizardsettings.js
index 6303d95efa..487f068a40 100644
--- a/src/controllers/wizardsettings.js
+++ b/src/controllers/wizardsettings.js
@@ -1,67 +1,84 @@
-define(["loading", "emby-checkbox", "emby-button", "emby-select"], function(loading) {
+define(["loading", "emby-checkbox", "emby-button", "emby-select"], function (loading) {
"use strict";
function save(page) {
loading.show();
var apiClient = ApiClient;
- apiClient.getJSON(apiClient.getUrl("Startup/Configuration")).then(function(config) {
- config.PreferredMetadataLanguage = page.querySelector("#selectLanguage").value, config.MetadataCountryCode = page.querySelector("#selectCountry").value, apiClient.ajax({
+ apiClient.getJSON(apiClient.getUrl("Startup/Configuration")).then(function (config) {
+ config.PreferredMetadataLanguage = page.querySelector("#selectLanguage").value;
+ config.MetadataCountryCode = page.querySelector("#selectCountry").value;
+ apiClient.ajax({
type: "POST",
data: config,
url: apiClient.getUrl("Startup/Configuration")
- }).then(function() {
- loading.hide(), navigateToNextPage()
- })
- })
+ }).then(function () {
+ loading.hide();
+ navigateToNextPage();
+ });
+ });
}
function populateLanguages(select, languages) {
var html = "";
html += "
";
+
for (var i = 0, length = languages.length; i < length; i++) {
var culture = languages[i];
- html += "
" + culture.DisplayName + " "
+ html += "
" + culture.DisplayName + " ";
}
- select.innerHTML = html
+
+ select.innerHTML = html;
}
function populateCountries(select, allCountries) {
var html = "";
html += "
";
+
for (var i = 0, length = allCountries.length; i < length; i++) {
var culture = allCountries[i];
- html += "
" + culture.DisplayName + " "
+ html += "
" + culture.DisplayName + " ";
}
- select.innerHTML = html
+
+ select.innerHTML = html;
}
function reloadData(page, config, cultures, countries) {
- populateLanguages(page.querySelector("#selectLanguage"), cultures), populateCountries(page.querySelector("#selectCountry"), countries), page.querySelector("#selectLanguage").value = config.PreferredMetadataLanguage, page.querySelector("#selectCountry").value = config.MetadataCountryCode, loading.hide()
+ populateLanguages(page.querySelector("#selectLanguage"), cultures);
+ populateCountries(page.querySelector("#selectCountry"), countries);
+ page.querySelector("#selectLanguage").value = config.PreferredMetadataLanguage;
+ page.querySelector("#selectCountry").value = config.MetadataCountryCode;
+ loading.hide();
}
function reload(page) {
loading.show();
- var apiClient = ApiClient,
- promise1 = apiClient.getJSON(apiClient.getUrl("Startup/Configuration")),
- promise2 = apiClient.getCultures(),
- promise3 = apiClient.getCountries();
- Promise.all([promise1, promise2, promise3]).then(function(responses) {
- reloadData(page, responses[0], responses[1], responses[2])
- })
+ var apiClient = ApiClient;
+ var promise1 = apiClient.getJSON(apiClient.getUrl("Startup/Configuration"));
+ var promise2 = apiClient.getCultures();
+ var promise3 = apiClient.getCountries();
+ Promise.all([promise1, promise2, promise3]).then(function (responses) {
+ reloadData(page, responses[0], responses[1], responses[2]);
+ });
}
function navigateToNextPage() {
- Dashboard.navigate("wizardremoteaccess.html")
+ Dashboard.navigate("wizardremoteaccess.html");
}
function onSubmit(e) {
- return save(this), e.preventDefault(), !1
+ save(this);
+ e.preventDefault();
+ return false;
}
- return function(view, params) {
- view.querySelector(".wizardSettingsForm").addEventListener("submit", onSubmit), view.addEventListener("viewshow", function() {
- document.querySelector(".skinHeader").classList.add("noHomeButtonHeader"), reload(this)
- }), view.addEventListener("viewhide", function() {
- document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader")
- })
- }
-});
\ No newline at end of file
+
+ return function (view, params) {
+ view.querySelector(".wizardSettingsForm").addEventListener("submit", onSubmit);
+ view.addEventListener("viewshow", function () {
+ document.querySelector(".skinHeader").classList.add("noHomeButtonHeader");
+ reload(this);
+ });
+ view.addEventListener("viewhide", function () {
+ document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader");
+ });
+ };
+});
diff --git a/src/controllers/wizardstart.js b/src/controllers/wizardstart.js
index 568ef15b2b..1c2917b9ec 100644
--- a/src/controllers/wizardstart.js
+++ b/src/controllers/wizardstart.js
@@ -1,41 +1,48 @@
-define(["jQuery", "loading", "emby-button", "emby-select"], function($, loading) {
+define(["jQuery", "loading", "emby-button", "emby-select"], function ($, loading) {
"use strict";
function loadPage(page, config, languageOptions) {
- $("#selectLocalizationLanguage", page).html(languageOptions.map(function(l) {
- return '
' + l.Name + " "
- })).val(config.UICulture), loading.hide()
+ $("#selectLocalizationLanguage", page).html(languageOptions.map(function (l) {
+ return '
' + l.Name + " ";
+ })).val(config.UICulture);
+ loading.hide();
}
function save(page) {
loading.show();
var apiClient = ApiClient;
- apiClient.getJSON(apiClient.getUrl("Startup/Configuration")).then(function(config) {
- config.UICulture = $("#selectLocalizationLanguage", page).val(), apiClient.ajax({
+ apiClient.getJSON(apiClient.getUrl("Startup/Configuration")).then(function (config) {
+ config.UICulture = $("#selectLocalizationLanguage", page).val();
+ apiClient.ajax({
type: "POST",
data: config,
url: apiClient.getUrl("Startup/Configuration")
- }).then(function() {
- Dashboard.navigate("wizarduser.html")
- })
- })
+ }).then(function () {
+ Dashboard.navigate("wizarduser.html");
+ });
+ });
}
function onSubmit() {
- return save($(this).parents(".page")), !1
+ save($(this).parents(".page"));
+ return false;
}
- return function(view, params) {
- $(".wizardStartForm", view).on("submit", onSubmit), view.addEventListener("viewshow", function() {
- document.querySelector(".skinHeader").classList.add("noHomeButtonHeader"), loading.show();
- var page = this,
- apiClient = ApiClient,
- promise1 = apiClient.getJSON(apiClient.getUrl("Startup/Configuration")),
- promise2 = apiClient.getJSON(apiClient.getUrl("Localization/Options"));
- Promise.all([promise1, promise2]).then(function(responses) {
- loadPage(page, responses[0], responses[1])
- })
- }), view.addEventListener("viewhide", function() {
- document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader")
- })
- }
-});
\ No newline at end of file
+
+ return function (view, params) {
+ $(".wizardStartForm", view).on("submit", onSubmit);
+ view.addEventListener("viewshow", function () {
+ document.querySelector(".skinHeader").classList.add("noHomeButtonHeader");
+ loading.show();
+ var page = this;
+ var apiClient = ApiClient;
+ var promise1 = apiClient.getJSON(apiClient.getUrl("Startup/Configuration"));
+ var promise2 = apiClient.getJSON(apiClient.getUrl("Localization/Options"));
+ Promise.all([promise1, promise2]).then(function (responses) {
+ loadPage(page, responses[0], responses[1]);
+ });
+ });
+ view.addEventListener("viewhide", function () {
+ document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader");
+ });
+ };
+});
diff --git a/src/controllers/wizarduserpage.js b/src/controllers/wizarduserpage.js
index a3654edf0e..d29be37c13 100644
--- a/src/controllers/wizarduserpage.js
+++ b/src/controllers/wizarduserpage.js
@@ -1,4 +1,4 @@
-define(["loading", "globalize", "dashboardcss", "emby-input", "emby-button", "emby-button"], function(loading, globalize) {
+define(["loading", "globalize", "dashboardcss", "emby-input", "emby-button", "emby-button"], function (loading, globalize) {
"use strict";
function getApiClient() {
@@ -30,13 +30,15 @@ define(["loading", "globalize", "dashboardcss", "emby-input", "emby-button", "em
function onSubmit(e) {
var form = this;
+
if (form.querySelector("#txtManualPassword").value != form.querySelector("#txtPasswordConfirm").value) {
- require(["toast"], function(toast) {
+ require(["toast"], function (toast) {
toast(Globalize.translate("PasswordMatchError"));
});
} else {
submit(form);
}
+
e.preventDefault();
return false;
}
@@ -45,20 +47,21 @@ define(["loading", "globalize", "dashboardcss", "emby-input", "emby-button", "em
loading.show();
var page = this;
var apiClient = getApiClient();
- apiClient.getJSON(apiClient.getUrl("Startup/User")).then(function(user) {
+ apiClient.getJSON(apiClient.getUrl("Startup/User")).then(function (user) {
page.querySelector("#txtUsername").value = user.Name || "";
page.querySelector("#txtManualPassword").value = user.Password || "";
loading.hide();
- })
- }
- return function(view, params) {
- view.querySelector(".wizardUserForm").addEventListener("submit", onSubmit);
- view.addEventListener("viewshow", function() {
- document.querySelector(".skinHeader").classList.add("noHomeButtonHeader")
});
- view.addEventListener("viewhide", function() {
- document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader")
+ }
+
+ return function (view, params) {
+ view.querySelector(".wizardUserForm").addEventListener("submit", onSubmit);
+ view.addEventListener("viewshow", function () {
+ document.querySelector(".skinHeader").classList.add("noHomeButtonHeader");
+ });
+ view.addEventListener("viewhide", function () {
+ document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader");
});
view.addEventListener("viewshow", onViewShow);
- }
+ };
});
diff --git a/src/index.html b/src/index.html
index bc9c7b64c5..d95784a3dc 100644
--- a/src/index.html
+++ b/src/index.html
@@ -98,8 +98,8 @@
-
-
+
+
diff --git a/src/bower_components/apiclient/apiclient.js b/src/libraries/apiclient/apiclient.js
similarity index 99%
rename from src/bower_components/apiclient/apiclient.js
rename to src/libraries/apiclient/apiclient.js
index 98aaed75e3..06d9cf0861 100644
--- a/src/bower_components/apiclient/apiclient.js
+++ b/src/libraries/apiclient/apiclient.js
@@ -1,5 +1,5 @@
//TODO: (vitorsemeano) modify this lines for webpack
-define(["bower_components/apiclient/apiclientcore", "localassetmanager"], function(ApiClient, localassetmanager) {
+define(["libraries/apiclient/apiclientcore", "localassetmanager"], function(ApiClient, localassetmanager) {
"use strict";
if ("cordova" !== window.appMode && "android" !== window.appMode) {
diff --git a/src/bower_components/apiclient/apiclientcore.js b/src/libraries/apiclient/apiclientcore.js
similarity index 100%
rename from src/bower_components/apiclient/apiclientcore.js
rename to src/libraries/apiclient/apiclientcore.js
diff --git a/src/bower_components/apiclient/appStorage.js b/src/libraries/apiclient/appStorage.js
similarity index 100%
rename from src/bower_components/apiclient/appStorage.js
rename to src/libraries/apiclient/appStorage.js
diff --git a/src/libraries/apiclient/connectionmanager.js b/src/libraries/apiclient/connectionmanager.js
new file mode 100644
index 0000000000..9ccb3aa087
--- /dev/null
+++ b/src/libraries/apiclient/connectionmanager.js
@@ -0,0 +1,809 @@
+define(["events", "apiclient", "appStorage"], function (events, apiClientFactory, appStorage) {
+ "use strict";
+
+ function getServerAddress(server, mode) {
+ switch (mode) {
+ case ConnectionMode.Local:
+ return server.LocalAddress;
+
+ case ConnectionMode.Manual:
+ return server.ManualAddress;
+
+ case ConnectionMode.Remote:
+ return server.RemoteAddress;
+
+ default:
+ return server.ManualAddress || server.LocalAddress || server.RemoteAddress;
+ }
+ }
+
+ function paramsToString(params) {
+ var values = [];
+
+ for (var key in params) {
+ var value = params[key];
+
+ if (null !== value && void 0 !== value && "" !== value) {
+ values.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
+ }
+ }
+
+ return values.join("&");
+ }
+
+ function resolveFailure(instance, resolve) {
+ resolve({
+ State: "Unavailable",
+ });
+ }
+
+ function mergeServers(credentialProvider, list1, list2) {
+ for (var i = 0, length = list2.length; i < length; i++) {
+ credentialProvider.addOrUpdateServer(list1, list2[i]);
+ }
+
+ return list1;
+ }
+
+ function updateServerInfo(server, systemInfo) {
+ server.Name = systemInfo.ServerName;
+ if (systemInfo.Id) {
+ server.Id = systemInfo.Id;
+ }
+
+ if (systemInfo.LocalAddress) {
+ server.LocalAddress = systemInfo.LocalAddress;
+ }
+ }
+
+ function getEmbyServerUrl(baseUrl, handler) {
+ return baseUrl + "/" + handler;
+ }
+
+ function getFetchPromise(request) {
+ var headers = request.headers || {};
+
+ if ("json" === request.dataType) {
+ headers.accept = "application/json";
+ }
+
+ var fetchRequest = {
+ headers: headers,
+ method: request.type,
+ credentials: "same-origin"
+ };
+ var contentType = request.contentType;
+
+ if (request.data) {
+ if ("string" == typeof request.data) {
+ fetchRequest.body = request.data;
+ } else {
+ fetchRequest.body = paramsToString(request.data);
+ contentType = contentType || "application/x-www-form-urlencoded; charset=UTF-8";
+ }
+ }
+
+ if (contentType) {
+ headers["Content-Type"] = contentType;
+ }
+
+ if (request.timeout) {
+ return fetchWithTimeout(request.url, fetchRequest, request.timeout);
+ }
+
+ return fetch(request.url, fetchRequest);
+ }
+
+ function fetchWithTimeout(url, options, timeoutMs) {
+ console.log("fetchWithTimeout: timeoutMs: " + timeoutMs + ", url: " + url);
+ return new Promise(function (resolve, reject) {
+ var timeout = setTimeout(reject, timeoutMs);
+ options = options || {};
+ options.credentials = "same-origin";
+ fetch(url, options).then(function (response) {
+ clearTimeout(timeout);
+ console.log("fetchWithTimeout: succeeded connecting to url: " + url);
+ resolve(response);
+ }, function (error) {
+ clearTimeout(timeout);
+ console.log("fetchWithTimeout: timed out connecting to url: " + url);
+ reject();
+ });
+ });
+ }
+
+ function ajax(request) {
+ if (!request) {
+ throw new Error("Request cannot be null");
+ }
+
+ request.headers = request.headers || {};
+ console.log("ConnectionManager requesting url: " + request.url);
+ return getFetchPromise(request).then(function (response) {
+ console.log("ConnectionManager response status: " + response.status + ", url: " + request.url);
+
+ if (response.status < 400) {
+ if ("json" === request.dataType || "application/json" === request.headers.accept) {
+ return response.json();
+ }
+
+ return response;
+ }
+
+ return Promise.reject(response);
+ }, function (err) {
+ console.log("ConnectionManager request failed to url: " + request.url);
+ throw err;
+ });
+ }
+
+ function replaceAll(originalString, strReplace, strWith) {
+ var reg = new RegExp(strReplace, "ig");
+ return originalString.replace(reg, strWith);
+ }
+
+ function normalizeAddress(address) {
+ address = address.trim();
+
+ if (0 !== address.toLowerCase().indexOf("http")) {
+ address = "http://" + address;
+ }
+
+ address = replaceAll(address, "Http:", "http:");
+ address = replaceAll(address, "Https:", "https:");
+
+ return address;
+ }
+
+ function stringEqualsIgnoreCase(str1, str2) {
+ return (str1 || "").toLowerCase() === (str2 || "").toLowerCase();
+ }
+
+ function compareVersions(a, b) {
+ a = a.split(".");
+ b = b.split(".");
+
+ for (var i = 0, length = Math.max(a.length, b.length); i < length; i++) {
+ var aVal = parseInt(a[i] || "0");
+ var bVal = parseInt(b[i] || "0");
+
+ if (aVal < bVal) {
+ return -1;
+ }
+
+ if (aVal > bVal) {
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+
+ var defaultTimeout = 20000;
+ var ConnectionMode = {
+ Local: 0,
+ Remote: 1,
+ Manual: 2
+ };
+
+ var ConnectionManager = function (credentialProvider, appName, appVersion, deviceName, deviceId, capabilities, devicePixelRatio) {
+
+ function onAuthenticated(apiClient, result, options, saveCredentials) {
+ var credentials = credentialProvider.credentials();
+ var servers = credentials.Servers.filter(function (s) {
+ return s.Id === result.ServerId;
+ });
+ var server = servers.length ? servers[0] : apiClient.serverInfo();
+
+ if (false !== options.updateDateLastAccessed) {
+ server.DateLastAccessed = new Date().getTime();
+ }
+
+ server.Id = result.ServerId;
+
+ if (saveCredentials) {
+ server.UserId = result.User.Id;
+ server.AccessToken = result.AccessToken;
+ } else {
+ server.UserId = null;
+ server.AccessToken = null;
+ }
+
+ credentialProvider.addOrUpdateServer(credentials.Servers, server);
+ credentialProvider.credentials(credentials);
+ apiClient.enableAutomaticBitrateDetection = options.enableAutomaticBitrateDetection;
+ apiClient.serverInfo(server);
+ afterConnected(apiClient, options);
+ return onLocalUserSignIn(server, apiClient.serverAddress(), result.User);
+ }
+
+ function afterConnected(apiClient, options) {
+ options = options || {};
+
+ if (false !== options.reportCapabilities) {
+ apiClient.reportCapabilities(capabilities);
+ }
+
+ apiClient.enableAutomaticBitrateDetection = options.enableAutomaticBitrateDetection;
+
+ if (false !== options.enableWebSocket) {
+ console.log("calling apiClient.ensureWebSocket");
+ apiClient.ensureWebSocket();
+ }
+ }
+
+ function onLocalUserSignIn(server, serverUrl, user) {
+ self._getOrAddApiClient(server, serverUrl);
+
+ var promise = self.onLocalUserSignedIn ? self.onLocalUserSignedIn.call(self, user) : Promise.resolve();
+ return promise.then(function () {
+ events.trigger(self, "localusersignedin", [user])
+ })
+ }
+
+ function validateAuthentication(server, serverUrl) {
+ return ajax({
+ type: "GET",
+ url: getEmbyServerUrl(serverUrl, "System/Info"),
+ dataType: "json",
+ headers: {
+ "X-MediaBrowser-Token": server.AccessToken
+ }
+ }).then(function (systemInfo) {
+ updateServerInfo(server, systemInfo);
+ return Promise.resolve();
+ }, function () {
+ server.UserId = null;
+ server.AccessToken = null;
+ return Promise.resolve();
+ });
+ }
+
+ function getImageUrl(localUser) {
+ if (localUser && localUser.PrimaryImageTag) {
+ return {
+ url: self.getApiClient(localUser).getUserImageUrl(localUser.Id, {
+ tag: localUser.PrimaryImageTag,
+ type: "Primary"
+ }),
+ supportsParams: true
+ };
+ }
+
+ return {
+ url: null,
+ supportsParams: false
+ };
+ }
+
+ function logoutOfServer(apiClient) {
+ var serverInfo = apiClient.serverInfo() || {};
+ var logoutInfo = {
+ serverId: serverInfo.Id
+ };
+ return apiClient.logout().then(function () {
+ events.trigger(self, "localusersignedout", [logoutInfo]);
+ }, function () {
+ events.trigger(self, "localusersignedout", [logoutInfo]);
+ });
+ }
+
+ function findServers() {
+ return new Promise(function (resolve, reject) {
+ var onFinish = function (foundServers) {
+ var servers = foundServers.map(function (foundServer) {
+ var info = {
+ Id: foundServer.Id,
+ LocalAddress: convertEndpointAddressToManualAddress(foundServer) || foundServer.Address,
+ Name: foundServer.Name
+ };
+ info.LastConnectionMode = info.ManualAddress ? ConnectionMode.Manual : ConnectionMode.Local;
+ return info;
+ });
+ resolve(servers);
+ };
+
+ if (window.NativeShell && typeof window.NativeShell.findServers === 'function') {
+ window.NativeShell.findServers(1e3).then(onFinish, function () {
+ onFinish([]);
+ });
+ } else {
+ resolve([]);
+ }
+ });
+ }
+
+ function convertEndpointAddressToManualAddress(info) {
+ if (info.Address && info.EndpointAddress) {
+ var address = info.EndpointAddress.split(":")[0];
+ var parts = info.Address.split(":");
+
+ if (parts.length > 1) {
+ var portString = parts[parts.length - 1];
+
+ if (!isNaN(parseInt(portString))) {
+ address += ":" + portString;
+ }
+ }
+
+ return normalizeAddress(address);
+ }
+
+ return null;
+ }
+
+ function getTryConnectPromise(url, connectionMode, state, resolve, reject) {
+ console.log("getTryConnectPromise " + url);
+ ajax({
+ url: getEmbyServerUrl(url, "system/info/public"),
+ timeout: defaultTimeout,
+ type: "GET",
+ dataType: "json"
+ }).then(function (result) {
+ if (!state.resolved) {
+ state.resolved = true;
+ console.log("Reconnect succeeded to " + url);
+ resolve({
+ url: url,
+ connectionMode: connectionMode,
+ data: result
+ });
+ }
+ }, function () {
+ if (!state.resolved) {
+ console.log("Reconnect failed to " + url);
+
+ if (++state.rejects >= state.numAddresses) {
+ reject();
+ }
+ }
+ });
+ }
+
+ function tryReconnect(serverInfo) {
+ var addresses = [];
+ var addressesStrings = [];
+
+ if (!serverInfo.manualAddressOnly && serverInfo.LocalAddress && -1 === addressesStrings.indexOf(serverInfo.LocalAddress)) {
+ addresses.push({
+ url: serverInfo.LocalAddress,
+ mode: ConnectionMode.Local,
+ timeout: 0
+ });
+ addressesStrings.push(addresses[addresses.length - 1].url);
+ }
+
+ if (serverInfo.ManualAddress && -1 === addressesStrings.indexOf(serverInfo.ManualAddress)) {
+ addresses.push({
+ url: serverInfo.ManualAddress,
+ mode: ConnectionMode.Manual,
+ timeout: 100
+ });
+ addressesStrings.push(addresses[addresses.length - 1].url);
+ }
+
+ if (!serverInfo.manualAddressOnly && serverInfo.RemoteAddress && -1 === addressesStrings.indexOf(serverInfo.RemoteAddress)) {
+ addresses.push({
+ url: serverInfo.RemoteAddress,
+ mode: ConnectionMode.Remote,
+ timeout: 200
+ });
+ addressesStrings.push(addresses[addresses.length - 1].url);
+ }
+
+ console.log("tryReconnect: " + addressesStrings.join("|"));
+ return new Promise(function (resolve, reject) {
+ var state = {};
+ state.numAddresses = addresses.length;
+ state.rejects = 0;
+ addresses.map(function (url) {
+ setTimeout(function () {
+ if (!state.resolved) {
+ getTryConnectPromise(url.url, url.mode, state, resolve, reject);
+ }
+ }, url.timeout);
+ });
+ });
+ }
+
+ function onSuccessfulConnection(server, systemInfo, connectionMode, serverUrl, options, resolve) {
+ var credentials = credentialProvider.credentials();
+ options = options || {};
+
+ if (false !== options.enableAutoLogin) {
+ afterConnectValidated(server, credentials, systemInfo, connectionMode, serverUrl, true, options, resolve);
+ }
+ }
+
+ function afterConnectValidated(server, credentials, systemInfo, connectionMode, serverUrl, verifyLocalAuthentication, options, resolve) {
+ options = options || {};
+ if (false === options.enableAutoLogin) {
+ server.UserId = null;
+ server.AccessToken = null;
+ } else if (verifyLocalAuthentication && server.AccessToken && false !== options.enableAutoLogin) {
+ return void validateAuthentication(server, serverUrl).then(function () {
+ afterConnectValidated(server, credentials, systemInfo, connectionMode, serverUrl, false, options, resolve);
+ });
+ }
+
+ updateServerInfo(server, systemInfo);
+ server.LastConnectionMode = connectionMode;
+
+ if (false !== options.updateDateLastAccessed) {
+ server.DateLastAccessed = new Date().getTime();
+ }
+
+ credentialProvider.addOrUpdateServer(credentials.Servers, server);
+ credentialProvider.credentials(credentials);
+ var result = {
+ Servers: []
+ };
+ result.ApiClient = self._getOrAddApiClient(server, serverUrl);
+ result.ApiClient.setSystemInfo(systemInfo);
+ result.State = server.AccessToken && false !== options.enableAutoLogin ? "SignedIn" : "ServerSignIn";
+ result.Servers.push(server);
+ result.ApiClient.enableAutomaticBitrateDetection = options.enableAutomaticBitrateDetection;
+ result.ApiClient.updateServerInfo(server, serverUrl);
+
+ var resolveActions = function () {
+ resolve(result);
+ events.trigger(self, "connected", [result]);
+ };
+
+ if ("SignedIn" === result.State) {
+ afterConnected(result.ApiClient, options);
+ result.ApiClient.getCurrentUser().then(function (user) {
+ onLocalUserSignIn(server, serverUrl, user).then(resolveActions, resolveActions);
+ }, resolveActions);
+ } else {
+ resolveActions();
+ }
+ }
+
+ console.log("Begin ConnectionManager constructor");
+ var self = this;
+ this._apiClients = [];
+ self._minServerVersion = "3.2.33";
+
+ self.appVersion = function () {
+ return appVersion;
+ };
+
+ self.appName = function () {
+ return appName;
+ };
+
+ self.capabilities = function () {
+ return capabilities;
+ };
+
+ self.deviceId = function () {
+ return deviceId;
+ };
+
+ self.credentialProvider = function () {
+ return credentialProvider;
+ };
+
+ self.getServerInfo = function (id) {
+ return credentialProvider.credentials().Servers.filter(function (s) {
+ return s.Id === id;
+ })[0];
+ };
+
+ self.getLastUsedServer = function () {
+ var servers = credentialProvider.credentials().Servers;
+ servers.sort(function (a, b) {
+ return (b.DateLastAccessed || 0) - (a.DateLastAccessed || 0);
+ });
+
+ if (servers.length) {
+ return servers[0];
+ }
+
+ return null;
+ };
+
+ self.addApiClient = function (apiClient) {
+ self._apiClients.push(apiClient);
+
+ var existingServers = credentialProvider.credentials().Servers.filter(function (s) {
+ return stringEqualsIgnoreCase(s.ManualAddress, apiClient.serverAddress()) || stringEqualsIgnoreCase(s.LocalAddress, apiClient.serverAddress()) || stringEqualsIgnoreCase(s.RemoteAddress, apiClient.serverAddress());
+ });
+ var existingServer = existingServers.length ? existingServers[0] : apiClient.serverInfo();
+
+ existingServer.DateLastAccessed = new Date().getTime();
+ existingServer.LastConnectionMode = ConnectionMode.Manual;
+ existingServer.ManualAddress = apiClient.serverAddress();
+ if (apiClient.manualAddressOnly) {
+ existingServer.manualAddressOnly = true;
+ }
+ apiClient.serverInfo(existingServer);
+ apiClient.onAuthenticated = function (instance, result) {
+ return onAuthenticated(instance, result, {}, true);
+ };
+ if (!existingServers.length) {
+ var credentials = credentialProvider.credentials();
+ credentials.Servers = [existingServer];
+ credentialProvider.credentials(credentials);
+ }
+
+ events.trigger(self, "apiclientcreated", [apiClient]);
+ };
+
+ self.clearData = function () {
+ console.log("connection manager clearing data");
+ var credentials = credentialProvider.credentials();
+ credentials.Servers = [];
+ credentialProvider.credentials(credentials);
+ };
+
+ self._getOrAddApiClient = function (server, serverUrl) {
+ var apiClient = self.getApiClient(server.Id);
+
+ if (!apiClient) {
+ apiClient = new apiClientFactory(serverUrl, appName, appVersion, deviceName, deviceId, devicePixelRatio);
+ self._apiClients.push(apiClient);
+ apiClient.serverInfo(server);
+ apiClient.onAuthenticated = function (instance, result) {
+ return onAuthenticated(instance, result, {}, true);
+ };
+
+ events.trigger(self, "apiclientcreated", [apiClient]);
+ }
+
+ console.log("returning instance from getOrAddApiClient");
+ return apiClient;
+ };
+
+ self.getOrCreateApiClient = function (serverId) {
+ var credentials = credentialProvider.credentials();
+ var servers = credentials.Servers.filter(function (s) {
+ return stringEqualsIgnoreCase(s.Id, serverId);
+ });
+
+ if (!servers.length) {
+ throw new Error("Server not found: " + serverId);
+ }
+
+ var server = servers[0];
+ return self._getOrAddApiClient(server, getServerAddress(server, server.LastConnectionMode));
+ };
+
+ self.user = function (apiClient) {
+ return new Promise(function (resolve, reject) {
+ function onLocalUserDone(e) {
+ if (apiClient && apiClient.getCurrentUserId()) {
+ apiClient.getCurrentUser().then(function (u) {
+ localUser = u;
+ var image = getImageUrl(localUser);
+ resolve({
+ localUser: localUser,
+ name: localUser ? localUser.Name : null,
+ imageUrl: image.url,
+ supportsImageParams: image.supportsParams,
+ });
+ }, onLocalUserDone);
+ }
+ }
+ var localUser;
+ if (apiClient && apiClient.getCurrentUserId()) {
+ onLocalUserDone();
+ }
+ });
+ };
+
+ self.logout = function () {
+ console.log("begin connectionManager loguot");
+ var promises = [];
+
+ for (var i = 0, length = self._apiClients.length; i < length; i++) {
+ var apiClient = self._apiClients[i];
+
+ if (apiClient.accessToken()) {
+ promises.push(logoutOfServer(apiClient));
+ }
+ }
+
+ return Promise.all(promises).then(function () {
+ var credentials = credentialProvider.credentials();
+ var servers = credentials.Servers.filter(function (u) {
+ return "Guest" !== u.UserLinkType;
+ });
+
+ for (var j = 0, numServers = servers.length; j < numServers; j++) {
+ var server = servers[j];
+ server.UserId = null;
+ server.AccessToken = null;
+ server.ExchangeToken = null;
+ }
+ });
+ };
+
+ self.getSavedServers = function () {
+ var credentials = credentialProvider.credentials();
+ var servers = credentials.Servers.slice(0);
+ servers.sort(function (a, b) {
+ return (b.DateLastAccessed || 0) - (a.DateLastAccessed || 0);
+ });
+ return servers;
+ };
+
+ self.getAvailableServers = function () {
+ console.log("Begin getAvailableServers");
+ var credentials = credentialProvider.credentials();
+ return Promise.all([findServers()]).then(function (responses) {
+ var foundServers = responses[0];
+ var servers = credentials.Servers.slice(0);
+ mergeServers(credentialProvider, servers, foundServers);
+ servers.sort(function (a, b) {
+ return (b.DateLastAccessed || 0) - (a.DateLastAccessed || 0);
+ });
+ credentials.Servers = servers;
+ credentialProvider.credentials(credentials);
+ return servers;
+ });
+ };
+
+ self.connectToServers = function (servers, options) {
+ console.log("Begin connectToServers, with " + servers.length + " servers");
+ var firstServer = servers.length ? servers[0] : null;
+
+ if (firstServer) {
+ return self.connectToServer(firstServer, options).then(function (result) {
+ if ("Unavailable" === result.State) {
+ result.State = "ServerSelection";
+ }
+
+ console.log("resolving connectToServers with result.State: " + result.State);
+ return result;
+ });
+ }
+
+ return Promise.resolve({
+ Servers: servers,
+ State: "ServerSelection"
+ });
+ };
+
+ self.connectToServer = function (server, options) {
+ console.log("begin connectToServer");
+ return new Promise(function (resolve, reject) {
+ options = options || {};
+ tryReconnect(server).then(function (result) {
+ var serverUrl = result.url;
+ var connectionMode = result.connectionMode;
+ result = result.data;
+
+ if (1 === compareVersions(self.minServerVersion(), result.Version)) {
+ console.log("minServerVersion requirement not met. Server version: " + result.Version);
+ resolve({
+ State: "ServerUpdateNeeded",
+ Servers: [server]
+ });
+ } else {
+ if (server.Id && result.Id !== server.Id) {
+ console.log("http request succeeded, but found a different server Id than what was expected");
+ resolveFailure(self, resolve);
+ } else {
+ onSuccessfulConnection(server, result, connectionMode, serverUrl, options, resolve);
+ }
+ }
+ }, function () {
+ resolveFailure(self, resolve);
+ });
+ });
+ };
+
+ self.connectToAddress = function (address, options) {
+ function onFail() {
+ console.log("connectToAddress " + address + " failed");
+ return Promise.resolve({
+ State: "Unavailable",
+ });
+ }
+
+ if (!address) {
+ return Promise.reject();
+ }
+
+ address = normalizeAddress(address);
+ var instance = this;
+ var server = {
+ ManualAddress: address,
+ LastConnectionMode: ConnectionMode.Manual
+ };
+ return self.connectToServer(server, options).catch(onFail);
+ };
+
+ self.deleteServer = function (serverId) {
+ if (!serverId) {
+ throw new Error("null serverId");
+ }
+
+ var server = credentialProvider.credentials().Servers.filter(function (s) {
+ return s.Id === serverId;
+ });
+ server = server.length ? server[0] : null;
+ return new Promise(function (resolve, reject) {
+ function onDone() {
+ var credentials = credentialProvider.credentials();
+ credentials.Servers = credentials.Servers.filter(function (s) {
+ return s.Id !== serverId;
+ });
+ credentialProvider.credentials(credentials);
+ resolve();
+ }
+
+ if (!server.ConnectServerId) {
+ return void onDone();
+ }
+ });
+ };
+ };
+
+ ConnectionManager.prototype.connect = function (options) {
+ console.log("Begin connect");
+ var instance = this;
+ return instance.getAvailableServers().then(function (servers) {
+ return instance.connectToServers(servers, options);
+ });
+ };
+
+ ConnectionManager.prototype.getApiClients = function () {
+ var servers = this.getSavedServers();
+
+ for (var i = 0, length = servers.length; i < length; i++) {
+ var server = servers[i];
+
+ if (server.Id) {
+ this._getOrAddApiClient(server, getServerAddress(server, server.LastConnectionMode));
+ }
+ }
+
+ return this._apiClients;
+ };
+
+ ConnectionManager.prototype.getApiClient = function (item) {
+ if (!item) {
+ throw new Error("item or serverId cannot be null");
+ }
+
+ if (item.ServerId) {
+ item = item.ServerId;
+ }
+
+ return this._apiClients.filter(function (a) {
+ var serverInfo = a.serverInfo();
+ return !serverInfo || serverInfo.Id === item;
+ })[0];
+ };
+
+ ConnectionManager.prototype.minServerVersion = function (val) {
+ if (val) {
+ this._minServerVersion = val;
+ }
+
+ return this._minServerVersion;
+ };
+
+ ConnectionManager.prototype.handleMessageReceived = function (msg) {
+ var serverId = msg.ServerId;
+
+ if (serverId) {
+ var apiClient = this.getApiClient(serverId);
+
+ if (apiClient) {
+ if ("string" == typeof msg.Data) {
+ try {
+ msg.Data = JSON.parse(msg.Data);
+ } catch (err) {}
+ }
+
+ apiClient.handleMessageReceived(msg);
+ }
+ }
+ };
+
+ return ConnectionManager;
+});
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/login.html b/src/login.html
index c70064ed95..629f434313 100644
--- a/src/login.html
+++ b/src/login.html
@@ -6,14 +6,17 @@
${HeaderPleaseSignIn}
-
-
-
";
}
// add buttons to navigation drawer
navDrawerScrollContainer.innerHTML = html;
-
// bind logout button click to method
var btnLogout = navDrawerScrollContainer.querySelector(".btnLogout");
+
if (btnLogout) {
btnLogout.addEventListener("click", onLogoutClick);
}
@@ -250,6 +234,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
pageUrls = pageUrls.split("|");
selected = pageUrls.filter(isUrlInCurrentView).length > 0;
}
+
if (selected) {
link.classList.add("navMenuOption-selected");
var title = "";
@@ -377,6 +362,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
function addPluginPagesToMainMenu(links, pluginItems, section) {
for (var i = 0, length = pluginItems.length; i < length; i++) {
var pluginItem = pluginItems[i];
+
if (pluginItem.EnableInMainMenu && pluginItem.MenuSection === section) {
links.push({
name: pluginItem.DisplayName,
@@ -416,15 +402,14 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
return getToolsMenuLinks(apiClient).then(function (items) {
var item;
var menuHtml = "";
-
menuHtml += '
';
+
for (var i = 0; i < items.length; i++) {
item = items[i];
if (item.href) {
menuHtml += getToolsLinkHtml(item);
- }
- else if (item.name) {
+ } else if (item.name) {
menuHtml += '";
@@ -460,8 +445,8 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
for (var i = 0, length = items.length; i < length; i++) {
var view = items[i];
-
list.push(view);
+
if ("livetv" == view.CollectionType) {
view.ImageTags = {};
view.icon = "live_tv";
@@ -484,8 +469,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
if (elem) {
if (show) {
elem.classList.remove("hide");
- }
- else {
+ } else {
elem.classList.add("hide");
}
}
@@ -503,15 +487,13 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
// FIXME: Potentially the same as above
if (user.Policy.EnableContentDownloading) {
showBySelector(".lnkSyncToOtherDevices", true);
- }
- else {
+ } else {
showBySelector(".lnkSyncToOtherDevices", false);
}
if (user.Policy.EnableContentDownloading && appHost.supports("sync")) {
showBySelector(".libraryMenuDownloads", true);
- }
- else {
+ } else {
showBySelector(".libraryMenuDownloads", false);
}
@@ -529,9 +511,11 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
html += items.map(function (i) {
var icon = i.icon || imageHelper.getLibraryIcon(i.CollectionType);
var itemId = i.Id;
+
if (i.onclick) {
i.onclick;
}
+
return '";
}).join("");
libraryMenuOptions.innerHTML = html;
@@ -592,23 +576,17 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
if (isChannelsPage && "channels" === itemId) {
lnkMediaFolder.classList.add("navMenuOption-selected");
- }
- else if (isLiveTvPage && "livetv" === itemId) {
+ } else if (isLiveTvPage && "livetv" === itemId) {
lnkMediaFolder.classList.add("navMenuOption-selected");
- }
- else if (isEditorPage && "editor" === itemId) {
+ } else if (isEditorPage && "editor" === itemId) {
lnkMediaFolder.classList.add("navMenuOption-selected");
- }
- else if (isMySyncPage && "manageoffline" === itemId && -1 != window.location.href.toString().indexOf("mode=download")) {
+ } else if (isMySyncPage && "manageoffline" === itemId && -1 != window.location.href.toString().indexOf("mode=download")) {
lnkMediaFolder.classList.add("navMenuOption-selected");
- }
- else if (isMySyncPage && "syncotherdevices" === itemId && -1 == window.location.href.toString().indexOf("mode=download")) {
+ } else if (isMySyncPage && "syncotherdevices" === itemId && -1 == window.location.href.toString().indexOf("mode=download")) {
lnkMediaFolder.classList.add("navMenuOption-selected");
- }
- else if (id && itemId == id) {
+ } else if (id && itemId == id) {
lnkMediaFolder.classList.add("navMenuOption-selected");
- }
- else {
+ } else {
lnkMediaFolder.classList.remove("navMenuOption-selected");
}
}
@@ -667,8 +645,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
if (title) {
LibraryMenu.setTitle(title);
- }
- else if (page.classList.contains("standalonePage")) {
+ } else if (page.classList.contains("standalonePage")) {
LibraryMenu.setDefaultTitle();
}
}
@@ -697,6 +674,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
function refreshLibraryDrawer(user) {
loadNavDrawer();
currentDrawerType = "library";
+
if (user) {
Promise.resolve(user);
} else {
@@ -729,9 +707,11 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
return new Promise(function (resolve, reject) {
require(["navdrawer"], function (navdrawer) {
navDrawerInstance = new navdrawer(getNavDrawerOptions());
+
if (!layoutManager.tv) {
navDrawerElement.classList.remove("hide");
}
+
resolve(navDrawerInstance);
});
});
@@ -747,7 +727,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 +852,20 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
html += '';
html += '';
html += '';
-
- if (!layoutManager.mobile) {
- 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();
})();
diff --git a/src/scripts/livetvcomponents.js b/src/scripts/livetvcomponents.js
index dee3a92bd1..4215de4cbe 100644
--- a/src/scripts/livetvcomponents.js
+++ b/src/scripts/livetvcomponents.js
@@ -1,57 +1,95 @@
-define(["layoutManager", "datetime", "cardBuilder", "apphost"], function(layoutManager, datetime, cardBuilder, appHost) {
+define(["layoutManager", "datetime", "cardBuilder", "apphost"], function (layoutManager, datetime, cardBuilder, appHost) {
"use strict";
function enableScrollX() {
- return !layoutManager.desktop
+ return !layoutManager.desktop;
}
function getBackdropShape() {
- return enableScrollX() ? "overflowBackdrop" : "backdrop"
+ return enableScrollX() ? "overflowBackdrop" : "backdrop";
}
function getTimersHtml(timers, options) {
options = options || {};
- var i, length, items = timers.map(function(t) {
- return t.Type = "Timer", t
- }),
- groups = [],
- currentGroupName = "",
- currentGroup = [];
+ var i;
+ var length;
+ var items = timers.map(function (t) {
+ t.Type = "Timer";
+ return t;
+ });
+ var groups = [];
+ var currentGroupName = "";
+ var currentGroup = [];
+
for (i = 0, length = items.length; i < length; i++) {
- var item = items[i],
- dateText = "";
- if (!1 !== options.indexByDate && item.StartDate) try {
- var premiereDate = datetime.parseISO8601Date(item.StartDate, !0);
- dateText = datetime.toLocaleDateString(premiereDate, {
- weekday: "long",
- month: "short",
- day: "numeric"
- })
- } catch (err) {}
- dateText != currentGroupName ? (currentGroup.length && groups.push({
+ var item = items[i];
+ var dateText = "";
+
+ if (options.indexByDate !== false && item.StartDate) {
+ try {
+ var premiereDate = datetime.parseISO8601Date(item.StartDate, true);
+ dateText = datetime.toLocaleDateString(premiereDate, {
+ weekday: "long",
+ month: "short",
+ day: "numeric"
+ });
+ } catch (err) {
+ console.log("Error parsing premiereDate:" + item.StartDate + "; error: " + err);
+ }
+ }
+
+ if (dateText != currentGroupName) {
+ if (currentGroup.length) {
+ groups.push({
+ name: currentGroupName,
+ items: currentGroup
+ });
+ }
+
+ currentGroupName = dateText;
+ currentGroup = [item];
+ } else {
+ currentGroup.push(item);
+ }
+ }
+
+ if (currentGroup.length) {
+ groups.push({
name: currentGroupName,
items: currentGroup
- }), currentGroupName = dateText, currentGroup = [item]) : currentGroup.push(item)
+ });
}
- currentGroup.length && groups.push({
- name: currentGroupName,
- items: currentGroup
- });
+
var html = "";
+
for (i = 0, length = groups.length; i < length; i++) {
- var group = groups[i],
- supportsImageAnalysis = appHost.supports("imageanalysis"),
- cardLayout = appHost.preferVisualCards || supportsImageAnalysis;
- if (cardLayout = !0, group.name && (html += '
', html += '
' + group.name + " "), enableScrollX()) {
+ var group = groups[i];
+ var supportsImageAnalysis = appHost.supports("imageanalysis");
+ var cardLayout = appHost.preferVisualCards || supportsImageAnalysis;
+
+ cardLayout = true;
+ if (group.name) {
+ html += '
';
+ html += '
' + group.name + " ";
+ }
+ if (enableScrollX()) {
var scrollXClass = "scrollX hiddenScrollX";
- layoutManager.tv && (scrollXClass += " smoothScrollX"), html += '
";
+ }
}
- return Promise.resolve(html)
+
+ return Promise.resolve(html);
}
+
window.LiveTvHelpers = {
getTimersHtml: getTimersHtml
- }
-});
\ No newline at end of file
+ };
+});
diff --git a/src/scripts/playlistedit.js b/src/scripts/playlistedit.js
index ef0615e2ba..32a3a960a4 100644
--- a/src/scripts/playlistedit.js
+++ b/src/scripts/playlistedit.js
@@ -1,39 +1,50 @@
-define(["listView"], function(listView) {
+define(["listView"], function (listView) {
"use strict";
function getFetchPlaylistItemsFn(itemId) {
- return function() {
+ return function () {
var query = {
Fields: "PrimaryImageAspectRatio,UserData",
EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
UserId: ApiClient.getCurrentUserId()
};
- return ApiClient.getJSON(ApiClient.getUrl("Playlists/" + itemId + "/Items", query))
- }
+ return ApiClient.getJSON(ApiClient.getUrl("Playlists/" + itemId + "/Items", query));
+ };
}
function getItemsHtmlFn(itemId) {
- return function(items) {
+ return function (items) {
return listView.getListViewHtml({
items: items,
- showIndex: !1,
- showRemoveFromPlaylist: !0,
- playFromHere: !0,
+ showIndex: false,
+ showRemoveFromPlaylist: true,
+ playFromHere: true,
action: "playallfromhere",
- smallIcon: !0,
- dragHandle: !0,
+ smallIcon: true,
+ dragHandle: true,
playlistId: itemId
- })
- }
+ });
+ };
}
function init(page, item) {
var elem = page.querySelector("#childrenContent .itemsContainer");
- elem.classList.add("vertical-list"), elem.classList.remove("vertical-wrap"), elem.enableDragReordering(!0), elem.fetchData = getFetchPlaylistItemsFn(item.Id), elem.getItemsHtml = getItemsHtmlFn(item.Id)
+ elem.classList.add("vertical-list");
+ elem.classList.remove("vertical-wrap");
+ elem.enableDragReordering(true);
+ elem.fetchData = getFetchPlaylistItemsFn(item.Id);
+ elem.getItemsHtml = getItemsHtmlFn(item.Id);
}
+
window.PlaylistViewer = {
- render: function(page, item) {
- page.playlistInit || (page.playlistInit = !0, init(page, item)), page.querySelector("#childrenContent").classList.add("verticalSection-extrabottompadding"), page.querySelector("#childrenContent .itemsContainer").refreshItems()
+ render: function (page, item) {
+ if (!page.playlistInit) {
+ page.playlistInit = true;
+ init(page, item);
+ }
+
+ page.querySelector("#childrenContent").classList.add("verticalSection-extrabottompadding");
+ page.querySelector("#childrenContent .itemsContainer").refreshItems();
}
- }
-});
\ No newline at end of file
+ };
+});
diff --git a/src/scripts/playlists.js b/src/scripts/playlists.js
index ee9fac6c58..91c49017da 100644
--- a/src/scripts/playlists.js
+++ b/src/scripts/playlists.js
@@ -1,124 +1,186 @@
-define(["loading", "listView", "cardBuilder", "libraryMenu", "libraryBrowser", "apphost", "imageLoader", "emby-itemscontainer"], function(loading, listView, cardBuilder, libraryMenu, libraryBrowser, appHost, imageLoader) {
+define(["loading", "listView", "cardBuilder", "libraryMenu", "libraryBrowser", "apphost", "imageLoader", "emby-itemscontainer"], function (loading, listView, cardBuilder, libraryMenu, libraryBrowser, appHost, imageLoader) {
"use strict";
- return function(view, params) {
+
+ return function (view, params) {
function getPageData(context) {
- var key = getSavedQueryKey(context),
- pageData = data[key];
- return pageData || (pageData = data[key] = {
- query: {
- SortBy: "SortName",
- SortOrder: "Ascending",
- IncludeItemTypes: "Playlist",
- Recursive: !0,
- Fields: "PrimaryImageAspectRatio,SortName,CumulativeRunTimeTicks,CanDelete",
- StartIndex: 0,
- Limit: 100
- },
- view: libraryBrowser.getSavedView(key) || "Poster"
- }, pageData.query.ParentId = libraryMenu.getTopParentId(), 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: "Playlist",
+ Recursive: true,
+ Fields: "PrimaryImageAspectRatio,SortName,CumulativeRunTimeTicks,CanDelete",
+ StartIndex: 0,
+ Limit: 100
+ },
+ view: libraryBrowser.getSavedView(key) || "Poster"
+ };
+ pageData.query.ParentId = libraryMenu.getTopParentId();
+ 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()), context.savedQueryKey
+ if (!context.savedQueryKey) {
+ context.savedQueryKey = libraryBrowser.getSavedQueryKey();
+ }
+
+ return context.savedQueryKey;
}
function showLoadingMessage() {
- loading.show()
+ loading.show();
}
function hideLoadingMessage() {
- loading.hide()
+ loading.hide();
}
function onViewStyleChange() {
- var viewStyle = getPageData(view).view,
- itemsContainer = view.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 = getPageData(view).view;
+ var itemsContainer = view.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() {
showLoadingMessage();
- var query = getQuery(view),
- promise1 = ApiClient.getItems(Dashboard.getCurrentUserId(), query),
- promise2 = Dashboard.getCurrentUser();
- Promise.all([promise1, promise2]).then(function(responses) {
+ var query = getQuery(view);
+ var promise1 = ApiClient.getItems(Dashboard.getCurrentUserId(), query);
+ var promise2 = Dashboard.getCurrentUser();
+ Promise.all([promise1, promise2]).then(function (responses) {
var result = responses[0];
responses[1];
window.scrollTo(0, 0);
- var html = "",
- viewStyle = getPageData(view).view;
+ var html = "";
+ var viewStyle = getPageData(view).view;
view.querySelector(".listTopPaging").innerHTML = libraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
- viewButton: !1,
- showLimit: !1,
- updatePageSizeSetting: !1,
- addLayoutButton: !0,
+ viewButton: false,
+ showLimit: false,
+ updatePageSizeSetting: false,
+ addLayoutButton: true,
layouts: "List,Poster,PosterCard,Thumb,ThumbCard",
currentLayout: viewStyle
- }), result.TotalRecordCount ? (html = "List" == viewStyle ? listView.getListViewHtml({
- items: result.Items,
- sortBy: query.SortBy
- }) : "PosterCard" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "square",
- coverImage: !0,
- showTitle: !0,
- cardLayout: !0
- }) : "Thumb" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "backdrop",
- showTitle: !0,
- centerText: !0,
- preferThumb: !0,
- overlayPlayButton: !0
- }) : "ThumbCard" == viewStyle ? cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "backdrop",
- showTitle: !0,
- preferThumb: !0,
- cardLayout: !0
- }) : cardBuilder.getCardsHtml({
- items: result.Items,
- shape: "square",
- showTitle: !0,
- coverImage: !0,
- centerText: !0,
- overlayPlayButton: !0
- }), view.querySelector(".noItemsMessage").classList.add("hide")) : view.querySelector(".noItemsMessage").classList.remove("hide");
+ });
+
+ if (result.TotalRecordCount) {
+ if (viewStyle == "List") {
+ html = listView.getListViewHtml({
+ items: result.Items,
+ sortBy: query.SortBy
+ });
+ } else if (viewStyle == "PosterCard") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "square",
+ coverImage: true,
+ showTitle: true,
+ cardLayout: true
+ });
+ } else if (viewStyle == "Thumb") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "backdrop",
+ showTitle: true,
+ centerText: true,
+ preferThumb: true,
+ overlayPlayButton: true
+ });
+ } else if (viewStyle == "ThumbCard") {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "backdrop",
+ showTitle: true,
+ preferThumb: true,
+ cardLayout: true
+ });
+ } else {
+ html = cardBuilder.getCardsHtml({
+ items: result.Items,
+ shape: "square",
+ showTitle: true,
+ coverImage: true,
+ centerText: true,
+ overlayPlayButton: true
+ });
+ }
+ view.querySelector(".noItemsMessage").classList.add("hide");
+ } else {
+ view.querySelector(".noItemsMessage").classList.remove("hide");
+ }
+
var elem = view.querySelector(".itemsContainer");
- elem.innerHTML = html, imageLoader.lazyChildren(elem);
+ elem.innerHTML = html;
+ imageLoader.lazyChildren(elem);
var btnNextPage = view.querySelector(".btnNextPage");
- btnNextPage && btnNextPage.addEventListener("click", function() {
- query.StartIndex += query.Limit, reloadItems()
- });
+
+ if (btnNextPage) {
+ btnNextPage.addEventListener("click", function () {
+ query.StartIndex += query.Limit;
+ reloadItems();
+ });
+ }
+
var btnPreviousPage = view.querySelector(".btnPreviousPage");
- btnPreviousPage && btnPreviousPage.addEventListener("click", function() {
- query.StartIndex -= query.Limit, reloadItems()
- });
+
+ if (btnPreviousPage) {
+ btnPreviousPage.addEventListener("click", function () {
+ query.StartIndex -= query.Limit;
+ reloadItems();
+ });
+ }
+
var btnChangeLayout = view.querySelector(".btnChangeLayout");
- btnChangeLayout && btnChangeLayout.addEventListener("layoutchange", function(e) {
- var layout = e.detail.viewStyle;
- getPageData(view).view = layout, libraryBrowser.saveViewSetting(getSavedQueryKey(view), layout), onViewStyleChange(), reloadItems()
- }), libraryBrowser.saveQueryValues(getSavedQueryKey(view), query), hideLoadingMessage()
- })
+
+ if (btnChangeLayout) {
+ btnChangeLayout.addEventListener("layoutchange", function (e) {
+ var layout = e.detail.viewStyle;
+ getPageData(view).view = layout;
+ libraryBrowser.saveViewSetting(getSavedQueryKey(view), layout);
+ onViewStyleChange();
+ reloadItems();
+ });
+ }
+
+ libraryBrowser.saveQueryValues(getSavedQueryKey(view), query);
+ hideLoadingMessage();
+ });
}
+
var data = {};
- view.addEventListener("viewbeforeshow", function() {
- reloadItems()
- }), view.querySelector(".btnNewPlaylist").addEventListener("click", function() {
- require(["playlistEditor"], function(playlistEditor) {
+ view.addEventListener("viewbeforeshow", function () {
+ reloadItems();
+ });
+ view.querySelector(".btnNewPlaylist").addEventListener("click", function () {
+ require(["playlistEditor"], function (playlistEditor) {
var serverId = ApiClient.serverInfo().Id;
- (new playlistEditor).show({
+ new playlistEditor().show({
items: [],
serverId: serverId
- })
- })
- }), onViewStyleChange()
- }
-});
\ No newline at end of file
+ });
+ });
+ });
+ onViewStyleChange();
+ };
+});
diff --git a/src/scripts/routes.js b/src/scripts/routes.js
index 680a99a80b..a72e7e0566 100644
--- a/src/scripts/routes.js
+++ b/src/scripts/routes.js
@@ -447,6 +447,6 @@ define([
defineRoute({
path: "/",
isDefaultRoute: true,
- autoFocus: false,
+ autoFocus: false
});
});
diff --git a/src/scripts/searchtab.js b/src/scripts/searchtab.js
index 538770e42e..c0852bfc77 100644
--- a/src/scripts/searchtab.js
+++ b/src/scripts/searchtab.js
@@ -1,30 +1,54 @@
-define(["searchFields", "searchResults", "events"], function(SearchFields, SearchResults, events) {
+define(["searchFields", "searchResults", "events"], function (SearchFields, SearchResults, events) {
"use strict";
function init(instance, tabContent, options) {
- tabContent.innerHTML = '
', instance.searchFields = new SearchFields({
+ tabContent.innerHTML = '
';
+ instance.searchFields = new SearchFields({
element: tabContent.querySelector(".searchFields")
- }), instance.searchResults = new SearchResults({
+ });
+ instance.searchResults = new SearchResults({
element: tabContent.querySelector(".searchResults"),
serverId: ApiClient.serverId(),
parentId: options.parentId,
collectionType: options.collectionType
- }), events.on(instance.searchFields, "search", function(e, value) {
- instance.searchResults.search(value)
- })
+ });
+ events.on(instance.searchFields, "search", function (e, value) {
+ instance.searchResults.search(value);
+ });
}
function SearchTab(view, tabContent, options) {
var self = this;
- options = options || {}, init(this, tabContent, options), self.preRender = function() {}, self.renderTab = function() {
+ options = options || {};
+ init(this, tabContent, options);
+
+ self.preRender = function () {};
+
+ self.renderTab = function () {
var searchFields = this.searchFields;
- searchFields && searchFields.focus()
- }
+
+ if (searchFields) {
+ searchFields.focus();
+ }
+ };
}
- return SearchTab.prototype.destroy = function() {
+
+ SearchTab.prototype.destroy = function () {
var searchFields = this.searchFields;
- searchFields && searchFields.destroy(), this.searchFields = null;
+
+ if (searchFields) {
+ searchFields.destroy();
+ }
+
+ this.searchFields = null;
var searchResults = this.searchResults;
- searchResults && searchResults.destroy(), this.searchResults = null
- }, SearchTab
-});
\ No newline at end of file
+
+ if (searchResults) {
+ searchResults.destroy();
+ }
+
+ this.searchResults = null;
+ };
+
+ return SearchTab;
+});
diff --git a/src/scripts/site.js b/src/scripts/site.js
index b5fa85ac6c..e05712c076 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() {
@@ -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,
@@ -741,9 +746,10 @@ var AppInfo = {};
define("itemrepository", [bowerPath + "/apiclient/sync/itemrepository"], returnFirstDependency);
define("useractionrepository", [bowerPath + "/apiclient/sync/useractionrepository"], returnFirstDependency);
- // also pull out these libs
- define("page", [bowerPath + "/page"], returnFirstDependency);
- define("fetch", [bowerPath + "/fetch/fetch"], returnFirstDependency);
+ // TODO remove these libraries
+ // all three have been modified so we need to fix that first
+ define("page", [bowerPath + "/pagejs/page"], returnFirstDependency);
+ define("scroller", [componentsPath + "/scroller"], returnFirstDependency);
define("queryString", [bowerPath + "/query-string/index"], function () {
return queryString;
});
@@ -843,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);
diff --git a/src/scripts/taskbutton.js b/src/scripts/taskbutton.js
index d41cf7b5c2..f9774167c0 100644
--- a/src/scripts/taskbutton.js
+++ b/src/scripts/taskbutton.js
@@ -1,48 +1,119 @@
-define(["events", "userSettings", "serverNotifications", "connectionManager", "emby-button"], function(events, userSettings, serverNotifications, connectionManager) {
+define(["events", "userSettings", "serverNotifications", "connectionManager", "emby-button"], function (events, userSettings, serverNotifications, connectionManager) {
"use strict";
- return function(options) {
+
+ return function (options) {
function pollTasks() {
connectionManager.getApiClient(serverId).getScheduledTasks({
- IsEnabled: !0
- }).then(updateTasks)
+ IsEnabled: true
+ }).then(updateTasks);
}
function updateTasks(tasks) {
- var task = tasks.filter(function(t) {
- return t.Key == options.taskKey
+ var task = tasks.filter(function (t) {
+ return t.Key == options.taskKey;
})[0];
- if (options.panel && (task ? options.panel.classList.remove("hide") : options.panel.classList.add("hide")), task) {
- "Idle" == task.State ? button.removeAttribute("disabled") : button.setAttribute("disabled", "disabled"), button.setAttribute("data-taskid", task.Id);
- var progress = (task.CurrentProgressPercentage || 0).toFixed(1);
- if (options.progressElem && (options.progressElem.value = progress, "Running" == task.State ? options.progressElem.classList.remove("hide") : options.progressElem.classList.add("hide")), options.lastResultElem) {
- var lastResult = task.LastExecutionResult ? task.LastExecutionResult.Status : "";
- "Failed" == lastResult ? options.lastResultElem.html('
(' + Globalize.translate("LabelFailed") + ") ") : "Cancelled" == lastResult ? options.lastResultElem.html('
(' + Globalize.translate("LabelCancelled") + ") ") : "Aborted" == lastResult ? options.lastResultElem.html('
' + Globalize.translate("LabelAbortedByServerShutdown") + " ") : options.lastResultElem.html(lastResult)
+
+ if (options.panel) {
+ if (task) {
+ options.panel.classList.remove('hide');
+ } else {
+ options.panel.classList.add('hide');
+ }
+ }
+
+ if (!task) {
+ return;
+ }
+
+ if (task.State == 'Idle') {
+ button.removeAttribute("disabled");
+ } else {
+ button.setAttribute("disabled", "disabled");
+ }
+
+ button.setAttribute("data-taskid", task.Id);
+ var progress = (task.CurrentProgressPercentage || 0).toFixed(1);
+
+ if (options.progressElem) {
+ options.progressElem.value = progress;
+
+ if (task.State == 'Running') {
+ options.progressElem.classList.remove('hide');
+ } else {
+ options.progressElem.classList.add('hide');
+ }
+ }
+
+ if (options.lastResultElem) {
+ var lastResult = task.LastExecutionResult ? task.LastExecutionResult.Status : '';
+
+ if (lastResult == "Failed") {
+ options.lastResultElem.html('
(' + Globalize.translate('LabelFailed') + ') ');
+ } else if (lastResult == "Cancelled") {
+ options.lastResultElem.html('
(' + Globalize.translate('LabelCancelled') + ') ');
+ } else if (lastResult == "Aborted") {
+ options.lastResultElem.html('
' + Globalize.translate('LabelAbortedByServerShutdown') + ' ');
+ } else {
+ options.lastResultElem.html(lastResult);
}
}
}
function onScheduledTaskMessageConfirmed(id) {
- connectionManager.getApiClient(serverId).startScheduledTask(id).then(pollTasks)
+ connectionManager.getApiClient(serverId).startScheduledTask(id).then(pollTasks);
}
function onButtonClick() {
- onScheduledTaskMessageConfirmed(this.getAttribute("data-taskid"))
+ onScheduledTaskMessageConfirmed(this.getAttribute("data-taskid"));
}
function onScheduledTasksUpdate(e, apiClient, info) {
- apiClient.serverId() === serverId && updateTasks(info)
+ if (apiClient.serverId() === serverId) {
+ updateTasks(info);
+ }
}
+ var pollInterval;
+ var button = options.button;
+ var serverId = ApiClient.serverId();
+
function onPollIntervalFired() {
- connectionManager.getApiClient(serverId).isMessageChannelOpen() || pollTasks()
+ if (!connectionManager.getApiClient(serverId).isMessageChannelOpen()) {
+ pollTasks();
+ }
}
- var pollInterval, button = options.button,
- serverId = ApiClient.serverId();
- options.panel && options.panel.classList.add("hide"), "off" == options.mode ? (button.removeEventListener("click", onButtonClick), events.off(serverNotifications, "ScheduledTasksInfo", onScheduledTasksUpdate), function() {
- connectionManager.getApiClient(serverId).sendMessage("ScheduledTasksInfoStop"), pollInterval && clearInterval(pollInterval)
- }()) : (button.addEventListener("click", onButtonClick), pollTasks(), function() {
+
+ function startInterval() {
var apiClient = connectionManager.getApiClient(serverId);
- pollInterval && clearInterval(pollInterval), apiClient.sendMessage("ScheduledTasksInfoStart", "1000,1000"), pollInterval = setInterval(onPollIntervalFired, 1e4)
- }(), events.on(serverNotifications, "ScheduledTasksInfo", onScheduledTasksUpdate))
- }
-});
\ No newline at end of file
+
+ if (pollInterval) {
+ clearInterval(pollInterval);
+ }
+ apiClient.sendMessage("ScheduledTasksInfoStart", "1000,1000");
+ pollInterval = setInterval(onPollIntervalFired, 5000);
+ }
+
+ function stopInterval() {
+ connectionManager.getApiClient(serverId).sendMessage("ScheduledTasksInfoStop");
+
+ if (pollInterval) {
+ clearInterval(pollInterval);
+ }
+ }
+
+ if (options.panel) {
+ options.panel.classList.add("hide");
+ }
+
+ if (options.mode == 'off') {
+ button.removeEventListener("click", onButtonClick);
+ events.off(serverNotifications, "ScheduledTasksInfo", onScheduledTasksUpdate);
+ stopInterval();
+ } else {
+ button.addEventListener("click", onButtonClick);
+ pollTasks();
+ startInterval();
+ events.on(serverNotifications, "ScheduledTasksInfo", onScheduledTasksUpdate);
+ }
+ };
+});
diff --git a/src/scripts/themeloader.js b/src/scripts/themeloader.js
index eb783b132d..ea7ff57f9a 100644
--- a/src/scripts/themeloader.js
+++ b/src/scripts/themeloader.js
@@ -1,15 +1,27 @@
-define(["userSettings", "skinManager", "connectionManager", "events"], function(userSettings, skinManager, connectionManager, events) {
+define(["userSettings", "skinManager", "connectionManager", "events"], function (userSettings, skinManager, connectionManager, events) {
"use strict";
+
var currentViewType;
- pageClassOn("viewbeforeshow", "page", function() {
- var classList = this.classList,
- viewType = classList.contains("type-interior") || classList.contains("wizardPage") ? "a" : "b";
+ pageClassOn("viewbeforeshow", "page", function () {
+ var classList = this.classList;
+ var viewType = classList.contains("type-interior") || classList.contains("wizardPage") ? "a" : "b";
+
if (viewType !== currentViewType) {
currentViewType = viewType;
- var theme, context;
- "a" === viewType ? (theme = userSettings.dashboardTheme(), context = "serverdashboard") : theme = userSettings.theme(), skinManager.setTheme(theme, context)
+ var theme;
+ var context;
+
+ if ("a" === viewType) {
+ theme = userSettings.dashboardTheme();
+ context = "serverdashboard";
+ } else {
+ theme = userSettings.theme();
+ }
+
+ skinManager.setTheme(theme, context);
}
- }), events.on(connectionManager, "localusersignedin", function(e, user) {
- currentViewType = null
- })
-});
\ No newline at end of file
+ });
+ events.on(connectionManager, "localusersignedin", function (e, user) {
+ currentViewType = null;
+ });
+});
diff --git a/src/scripts/userpassword.js b/src/scripts/userpassword.js
index 41dc290248..52e06e6cec 100644
--- a/src/scripts/userpassword.js
+++ b/src/scripts/userpassword.js
@@ -1,20 +1,30 @@
-define(["jQuery", "loading", "libraryMenu"], function($, loading, libraryMenu) {
+define(["jQuery", "loading", "libraryMenu"], function ($, loading, libraryMenu) {
"use strict";
function loadUser(page, user) {
- libraryMenu.setTitle(user.Name), "Guest" == user.ConnectLinkType ? $(".connectMessage", page).show() : $(".connectMessage", page).hide(), loading.hide()
+ libraryMenu.setTitle(user.Name);
+
+ if ("Guest" == user.ConnectLinkType) {
+ $(".connectMessage", page).show();
+ } else {
+ $(".connectMessage", page).hide();
+ }
+
+ loading.hide();
}
function loadData(page) {
loading.show();
var userId = getParameterByName("userId");
- ApiClient.getUser(userId).then(function(user) {
- loadUser(page, user)
- })
+ ApiClient.getUser(userId).then(function (user) {
+ loadUser(page, user);
+ });
}
- $(document).on("pageinit", "#userPasswordPage", function() {
- $(".adminUpdatePasswordForm").off("submit", UpdatePasswordPage.onSubmit).on("submit", UpdatePasswordPage.onSubmit), $(".adminLocalAccessForm").off("submit", UpdatePasswordPage.onLocalAccessSubmit).on("submit", UpdatePasswordPage.onLocalAccessSubmit)
- }).on("pagebeforeshow", "#userPasswordPage", function() {
- loadData(this)
- })
-});
\ No newline at end of file
+
+ $(document).on("pageinit", "#userPasswordPage", function () {
+ $(".adminUpdatePasswordForm").off("submit", UpdatePasswordPage.onSubmit).on("submit", UpdatePasswordPage.onSubmit);
+ $(".adminLocalAccessForm").off("submit", UpdatePasswordPage.onLocalAccessSubmit).on("submit", UpdatePasswordPage.onLocalAccessSubmit);
+ }).on("pagebeforeshow", "#userPasswordPage", function () {
+ loadData(this);
+ });
+});
diff --git a/src/scripts/wizardagreement.js b/src/scripts/wizardagreement.js
index 77c12fb664..148b0ef39a 100644
--- a/src/scripts/wizardagreement.js
+++ b/src/scripts/wizardagreement.js
@@ -1,17 +1,27 @@
-define(["dom", "emby-button"], function(dom) {
+define(["dom", "emby-button"], function (dom) {
"use strict";
function onSubmit(e) {
- return dom.parentWithClass(this, "page").querySelector(".chkAccept").checked ? Dashboard.navigate("wizardfinish.html") : Dashboard.alert({
- message: Globalize.translate("MessagePleaseAcceptTermsOfServiceBeforeContinuing"),
- title: ""
- }), e.preventDefault(), !1
+ if (dom.parentWithClass(this, "page").querySelector(".chkAccept").checked) {
+ Dashboard.navigate("wizardfinish.html");
+ } else {
+ Dashboard.alert({
+ message: Globalize.translate("MessagePleaseAcceptTermsOfServiceBeforeContinuing"),
+ title: ""
+ });
+ }
+
+ e.preventDefault();
+ return false;
}
- return function(view, params) {
- view.querySelector(".wizardAgreementForm").addEventListener("submit", onSubmit), view.addEventListener("viewshow", function() {
- document.querySelector(".skinHeader").classList.add("noHomeButtonHeader")
- }), view.addEventListener("viewhide", function() {
- document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader")
- })
- }
-});
\ No newline at end of file
+
+ return function (view, params) {
+ view.querySelector(".wizardAgreementForm").addEventListener("submit", onSubmit);
+ view.addEventListener("viewshow", function () {
+ document.querySelector(".skinHeader").classList.add("noHomeButtonHeader");
+ });
+ view.addEventListener("viewhide", function () {
+ document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader");
+ });
+ };
+});
diff --git a/src/strings/bg-bg.json b/src/strings/bg-bg.json
index ce12e70563..c7ce361903 100644
--- a/src/strings/bg-bg.json
+++ b/src/strings/bg-bg.json
@@ -59,7 +59,7 @@
"ButtonPlay": "Пускане",
"ButtonPreviousTrack": "Предишна пътека",
"ButtonProfile": "Профил",
- "ButtonQuickStartGuide": "Ръководство за бързо започване",
+ "ButtonQuickStartGuide": "Първи стъпки",
"ButtonRefresh": "Опресняване",
"ButtonRefreshGuideData": "Обновяване на данните в справочника",
"ButtonRemove": "Премахване",
@@ -78,7 +78,7 @@
"ButtonSignIn": "Вписване",
"ButtonSignOut": "Отписване",
"ButtonSort": "Подреждане",
- "ButtonStop": "Стоп",
+ "ButtonStop": "Спиране",
"ButtonSubmit": "Подаване",
"ButtonSubtitles": "Субтитри",
"ButtonUninstall": "Деинсталиране",
@@ -108,13 +108,13 @@
"Display": "Показване",
"Download": "Изтегляне",
"DownloadsValue": "{0} изтегляния",
- "EasyPasswordHelp": "Вашият лесен пин код е използван за офлайн достъп със съвместими Jellyfin приложения, както и за влизане през същата мрежа.",
+ "EasyPasswordHelp": "Вашият лесен пин-код се използва за достъп извън линия със съвместими приложения, както и за влизане през същата мрежа.",
"Edit": "Редактиране",
"EditImages": "Редактиране на изображенията",
"EditMetadata": "Редактиране на метаданните",
"EditSubtitles": "Редактиране на субтитрите",
"EnableBackdrops": "Фонове",
- "EnableCinemaMode": "Включване на режим \"Киносалон\"",
+ "EnableCinemaMode": "Режим \"Киносалон\"",
"EnableThemeSongs": "Тематични песни",
"Ended": "Приключило",
"EndsAtValue": "Свършва на {0}",
@@ -209,7 +209,7 @@
"HeaderLiveTv": "Телевизия на живо",
"HeaderMedia": "Медия",
"HeaderMediaFolders": "Медийни папки",
- "HeaderMediaInfo": "Данни",
+ "HeaderMediaInfo": "Сведения",
"HeaderMetadataSettings": "Настройки на метаданните",
"HeaderMoreLikeThis": "Подобни",
"HeaderMovies": "Филми",
@@ -248,7 +248,7 @@
"HeaderSecondsValue": "{0} секунди",
"HeaderSelectPath": "Изберете път",
"HeaderSendMessage": "Изпращане на съобщение",
- "HeaderSeries": "Series:",
+ "HeaderSeries": "Сериал",
"HeaderServerSettings": "Настройки на сървъра",
"HeaderSettings": "Настройки",
"HeaderSetupLibrary": "Настройте своите медийни библиотеки",
@@ -256,7 +256,7 @@
"HeaderSortOrder": "Ред на подреждане",
"HeaderSpecialFeatures": "Специални функции",
"HeaderStartNow": "Пускане веднага",
- "HeaderStatus": "Състояние:",
+ "HeaderStatus": "Състояние",
"HeaderSubtitleAppearance": "Облик на субтитрите",
"HeaderSystemDlnaProfiles": "Системни профили",
"HeaderTags": "Етикети",
@@ -289,7 +289,7 @@
"LabelAlbumArtPN": "ПН на албумното изкуство:",
"LabelAlbumArtists": "Изпълнители на албума:",
"LabelAllowServerAutoRestart": "Разрешаване на сървъра автоматично да се пуска повторно за прилагане на обновления",
- "LabelAllowServerAutoRestartHelp": "Сървърът ще се рестартира само през свободното си време, когато няма активни потребители.",
+ "LabelAllowServerAutoRestartHelp": "Сървърът ще се пуска наново само през ненатоварено време, когато няма активни потребители.",
"LabelAppName": "Име",
"LabelArtists": "Изпълнители:",
"LabelArtistsHelp": "Отделете няколко с ;",
@@ -299,7 +299,7 @@
"LabelCertificatePassword": "Парола на сертификата:",
"LabelCertificatePasswordHelp": "Ако сертификатът ви изисква парола, моля, въведете я тук.",
"LabelCollection": "Колекция:",
- "LabelCommunityRating": "Обществена оценка",
+ "LabelCommunityRating": "Обществена оценка:",
"LabelContentType": "Тип на съдържанието:",
"LabelCountry": "Държава:",
"LabelCriticRating": "Оценка на критиците:",
@@ -333,7 +333,7 @@
"LabelEnableDlnaClientDiscoveryIntervalHelp": "Определя времетраенето в секунди между SSDP търсения направени от Jellyfin.",
"LabelEnableDlnaDebugLogging": "Включване на журналите за грешки на ДЛНА",
"LabelEnableDlnaPlayTo": "Включване на функцията \"възпроизвеждане с ДЛНА\"",
- "LabelEnableDlnaPlayToHelp": "Емби може да засича устройства в мрежата ви и да предлага възможност за дистанционен контрол.",
+ "LabelEnableDlnaPlayToHelp": "Засичане на устройства в мрежата ви и предлагане на възможност за дистанционно управление.",
"LabelEnableDlnaServer": "Включване на ДЛНА-сървър",
"LabelEnableDlnaServerHelp": "Разрешава на UPnP устройства в мрежата да разглеждат и пускат Jellyfin съдържание.",
"LabelEnableRealtimeMonitor": "Активиране на наблюдение в реално време",
@@ -414,7 +414,7 @@
"LabelPublicHttpPortHelp": "Публичният порт, който да бъде съпоставен с локалния HTTP порт.",
"LabelPublicHttpsPort": "Публичен HTTPS порт:",
"LabelPublicHttpsPortHelp": "Публичният порт, който да бъде съпоставен с локалния HTTPS порт.",
- "LabelReadHowYouCanContribute": "Научете как можете да допринесете",
+ "LabelReadHowYouCanContribute": "Научете как можете да допринесете.",
"LabelRecordingPath": "Път за запис по подразбиране:",
"LabelReleaseDate": "Дата на издаване:",
"LabelRemoteClientBitrateLimit": "Ограничение на интернетното излъчване (мбит/сек):",
@@ -428,7 +428,7 @@
"LabelSkipIfAudioTrackPresent": "Да се пропусне, ако звуковата пътечка по подразбиране съвпада с езика",
"LabelSkipIfGraphicalSubsPresent": "Да се пропусне, ако файлът съдържа вградени субтитри",
"LabelSortBy": "Подреждане по:",
- "LabelSortOrder": "Ред на подреждане",
+ "LabelSortOrder": "Ред на подреждане:",
"LabelSource": "Източник:",
"LabelSpecialSeasonsDisplayName": "Име на сезона със специални епизоди:",
"LabelStartWhenPossible": "Започвай, когато е възможно:",
@@ -460,7 +460,7 @@
"LabelYoureDone": "Готови сте!",
"Large": "Голям",
"LatestFromLibrary": "Последни {0}",
- "LibraryAccessHelp": "Изберете медийните папки, които да споделите с потребителя. Администраторите ще могат да редактират всички папки, използвайки управлението на метаданни.",
+ "LibraryAccessHelp": "Изберете библиотеките, които да споделите с потребителя. Администраторите ще могат да редактират всички папки, използвайки управлението на метаданни.",
"Like": "Харесване",
"LinksValue": "Препратки: {0}",
"List": "Списък",
@@ -487,7 +487,7 @@
"MessageAlreadyInstalled": "Версията вече е инсталирана.",
"MessageAreYouSureYouWishToRemoveMediaFolder": "Сигурни ли сте, че искате да премахнете медийната папка?",
"MessageConfirmRestart": "Наистина ли искате да пуснете сървъра наново?",
- "MessageConfirmShutdown": "Наистина ли искате да спрете Jellyfin сървърът?",
+ "MessageConfirmShutdown": "Наистина ли искате да загасите сървъра?",
"MessageNoAvailablePlugins": "Няма налични приставки.",
"MessageNoPluginsInstalled": "Нямате инсталирани приставки.",
"MessageNothingHere": "Тук няма нищо.",
@@ -501,7 +501,7 @@
"Mobile": "Мобилно устройство",
"Monday": "Понеделник",
"MoreFromValue": "Още от {0}",
- "MoreUsersCanBeAddedLater": "Повече потребители могат да бъдат добавени по-късно от главния панел.",
+ "MoreUsersCanBeAddedLater": "Можете да добавите още потребители от таблото.",
"Movies": "Филми",
"Mute": "Заглушаване",
"MySubtitles": "Моите субтитри",
@@ -578,7 +578,7 @@
"OptionHasTrailer": "Трейлър",
"OptionHideUser": "Скриване на потребителя от страниците за вход",
"OptionHideUserFromLoginHelp": "Полезно за частни или скрити администраторски профили. Потребителят ще трябва да влезе ръчно чрез въвеждане на потребителско име и парола.",
- "OptionHomeVideos": "Домашни клипове и снимки",
+ "OptionHomeVideos": "Снимки",
"OptionImdbRating": "Оценка в IMDb",
"OptionIsHD": "ВК",
"OptionIsSD": "СК",
@@ -608,7 +608,7 @@
"OptionSpecialEpisode": "Специални",
"OptionSunday": "Неделя",
"OptionThursday": "Четвъртък",
- "OptionTrackName": "Име на песента:",
+ "OptionTrackName": "Име на песента",
"OptionTuesday": "Вторник",
"OptionUnairedEpisode": "Неизлъчени епизоди",
"OptionUnplayed": "Непускано",
@@ -672,7 +672,7 @@
"ShowAdvancedSettings": "Разширени настройки",
"ShowTitle": "Показване на заглавието",
"ShowYear": "Показване на годината",
- "Shows": "Предавания",
+ "Shows": "Сериали",
"Shuffle": "Пускане в разбъркан ред",
"Small": "Малък",
"Smart": "Умни",
@@ -757,7 +757,7 @@
"Unmute": "Без заглушаване",
"Unplayed": "Непускано",
"Upload": "Качване",
- "UserProfilesIntro": "Емби включва вградена поддръжка на потребителски профили, които позволяват на всеки потребител да има свои настройки на картината, място на пускане и родителски настройки.",
+ "UserProfilesIntro": "Джелифин включва поддръжка на потребителски профили със самостоятелни настройки на картината, пускането и родителските настройки.",
"ValueAlbumCount": "{0} албума",
"ValueAudioCodec": "Звуков кодек: {0}",
"ValueCodec": "Кодек: {0}",
@@ -784,9 +784,9 @@
"Watched": "Изгледано",
"Wednesday": "Сряда",
"WelcomeToProject": "Добре дошли в Емби!",
- "WizardCompleted": "Това е всичко от което се нуждаем за момента. Емби започна да събира данни за медийната ви библиотека. Разгледайте някои от нашите приложения, после натиснете
Готово , за да видите
таблото на сървъра .",
+ "WizardCompleted": "Това е всичко, от което се нуждаем за момента. Джелифин започва да събира данни за библиотеката ви. Разгледайте някои от нашите приложения, после натиснете
Готово , за да видите
таблото на сървъра .",
"Writer": "Писател",
- "AllowMediaConversion": "Разрешаване на медиини преобразувания",
+ "AllowMediaConversion": "Разрешаване на медийни преобразувания",
"AllLanguages": "Всички езици",
"AllEpisodes": "Всички епизоди",
"AllComplexFormats": "Всички комплексни формати (ASS, SSA, VOBSUB, PGS, SUB/IDX, и т.н.)",
@@ -794,5 +794,44 @@
"Alerts": "Известия",
"AdditionalNotificationServices": "Разгледайте каталога с добавки за допълнителни услуги за известяване.",
"AddToPlayQueue": "Добавяне към опашка",
- "AccessRestrictedTryAgainLater": "Достъпът е временно ограничен. Моля опитайте отново по-късно."
+ "AccessRestrictedTryAgainLater": "Достъпът е временно ограничен. Моля, опитайте отново по-късно.",
+ "HeaderFavoriteSongs": "Любими песни",
+ "HeaderFavoriteShows": "Любими сериали",
+ "HeaderFavoriteEpisodes": "Любими епизоди",
+ "HeaderFavoriteArtists": "Любими изпълнители",
+ "HeaderFavoriteAlbums": "Любими албуми",
+ "Folders": "Папки",
+ "No": "Не",
+ "Yes": "Да",
+ "MediaInfoStreamTypeSubtitle": "Субтитри",
+ "MediaInfoStreamTypeEmbeddedImage": "Вградено изображение",
+ "MediaInfoStreamTypeData": "Данни",
+ "MediaInfoStreamTypeAudio": "Звук",
+ "MediaInfoContainer": "Контейнер",
+ "MediaInfoInterlaced": "Презредово",
+ "MediaInfoForced": "Принудително",
+ "MediaInfoLayout": "Подредба",
+ "MusicVideo": "Музикален клип",
+ "MediaInfoStreamTypeVideo": "Видео",
+ "LabelVideo": "Видео:",
+ "HeaderVideoTypes": "Видове видеа",
+ "HeaderVideoType": "Вид на видеото",
+ "EnableExternalVideoPlayers": "Външни възпроизводители",
+ "HeaderLoginFailure": "Неуспешно вписване",
+ "Metadata": "Метаданни",
+ "ReplaceAllMetadata": "Заменяне на всички метаданни",
+ "ReplaceExistingImages": "Заменяне на текущите изображения",
+ "Channels": "Канали",
+ "Categories": "Категории",
+ "ButtonViewWebsite": "Преглед на сайта",
+ "ButtonUp": "Нагоре",
+ "ButtonTrailer": "Предварителен откъс",
+ "ButtonStart": "Пускане",
+ "ButtonSelectView": "Изберете изглед",
+ "ButtonSelectServer": "Изберете сървър",
+ "ButtonRepeat": "Повтаряне",
+ "ButtonNetwork": "Мрежа",
+ "ButtonFullscreen": "На цял екран",
+ "ButtonDown": "Надолу",
+ "ButtonConnect": "Свързване"
}
diff --git a/src/strings/cs.json b/src/strings/cs.json
index 3d03fc9455..d6b39c7de4 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",
@@ -149,7 +149,7 @@
"Desktop": "PC",
"DeviceAccessHelp": "Platí pouze pro zařízení, která mohou být jednoznačně identifikována. Těmto zařízením nebude bráněno v přístupu. Filtrování přístupu uživatelských zařízení bude bránit v užívání nových zařízení, dokud nebudou schváleny.",
"DirectPlaying": "Přímé přehrání",
- "DirectStreamHelp1": "Médium je kompatibilní se zařízením, pokud jde o rozlišení a typ média (H.264, AC3, atd.), ale je v nekompatibilním kontejneru (.mkv, .avi, .wmv, atd.). Video bude za běhu přebaleno než bude streamováno do zařízení.",
+ "DirectStreamHelp1": "Médium je kompatibilní se zařízením, pokud jde o rozlišení a typ média (H.264, AC3, atd.), ale je v nekompatibilním kontejneru (.mkv, .avi, .wmv, atd.). Video bude za běhu přebaleno, než bude streamováno do zařízení.",
"DirectStreaming": "Přímé streamování",
"Director": "Režisér",
"Disc": "Disk",
@@ -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ů",
@@ -168,23 +168,23 @@
"Downloads": "Stahování",
"DrmChannelsNotImported": "Kanál s DRM nebude importován.",
"DropShadow": "Vrhat stín",
- "EasyPasswordHelp": "Váš PIN kód je snadné používat pro přístup v režimu offline s podporovanými Jellyfin aplikacemi, a může být také použit pro snadné přihlášení v lokální síti.",
+ "EasyPasswordHelp": "Váš PIN kód je snadné používat pro přístup v režimu offline s podporovanými Jellyfin aplikacemi, může být také použit pro snadné přihlášení v lokální síti.",
"Edit": "Upravit",
"EditImages": "Editace obrázků",
"EditSubtitles": "Editovat titulky",
"EnableBackdrops": "Povolit pozadí",
"EnableBackdropsHelp": "Pokud je povoleno, pozadí je zobrazeno pro některé stránky při procházení vaší knihovny.",
- "EnableCinemaMode": "Povolit Cinema Mód",
- "EnableColorCodedBackgrounds": "Aktivovat barevně označené pozadí",
- "EnableDisplayMirroring": "Povolit zrcadlení obrazu",
- "EnableExternalVideoPlayers": "Povolit externí video přehrávače",
- "EnableNextVideoInfoOverlay": "Povolit informaci o následujícím videu během přehrávání",
- "EnablePhotos": "Povolit fotky",
- "EnablePhotosHelp": "Fotografie budou detekovány a zobrazeny spolu s dalšími multimediálními soubory.",
- "EnableThemeSongs": "Povolit tématickou hudbu na pozadí",
- "EnableThemeSongsHelp": "Pokud povolíte, bude při procházení knihovny na pozadí přehrávána tématická melodie.",
- "EnableThemeVideos": "Povolit tématické video",
- "EnableThemeVideosHelp": "Pokud povolíte, bude při procházení knihovny přehráváno tématické video na pozadí.",
+ "EnableCinemaMode": "Režim Cinema",
+ "EnableColorCodedBackgrounds": "Barevně označené pozadí",
+ "EnableDisplayMirroring": "Zrcadlení obrazu",
+ "EnableExternalVideoPlayers": "Externí video přehrávače",
+ "EnableNextVideoInfoOverlay": "Zobrazit informaci o následujícím videu během přehrávání",
+ "EnablePhotos": "Zobrazit fotky",
+ "EnablePhotosHelp": "Obrázky budou detekovány a zobrazeny spolu s dalšími multimediálními soubory.",
+ "EnableThemeSongs": "Tématická hudba na pozadí",
+ "EnableThemeSongsHelp": "Přehrát tématickou hudbu na pozadí při procházení knihovny.",
+ "EnableThemeVideos": "Tématická videa",
+ "EnableThemeVideosHelp": "Přehrát tématické video na pozadí při procházení knihovny.",
"Ended": "Ukončeno",
"EndsAtValue": "Končí v {0}",
"Episodes": "Epizody",
@@ -193,7 +193,7 @@
"ErrorAddingTunerDevice": "Došlo k chybě při přidání zařízení tuneru. Prosím, ujistěte se, že je přístupný a zkuste to znovu.",
"ErrorAddingXmlTvFile": "Nastala chyba při přístupu k XmlTV souboru. Ujistěte se, že soubor existuje, a zkuste znovu spustit.",
"ErrorDeletingItem": "Nastala chyba při mazání položky z Jellyfin Serveru. Zkontrolujte prosím, že Jellyfin Server má oprávnění k zápisu do složky médií a zkuste to prosím znovu.",
- "ErrorGettingTvLineups": "Došlo k chybě při stahování tv lineups. Ujistěte se prosím, že zadané informace jsou správné, a zkuste to znovu.",
+ "ErrorGettingTvLineups": "Došlo k chybě při stahování TV sestav. Ujistěte se prosím, že zadané informace jsou správné a zkuste to znovu.",
"ErrorMessageStartHourGreaterThanEnd": "Čas ukončení musí být větší než čas startu.",
"ErrorMessageUsernameInUse": "Uživatelské jméno se již používá. Prosím, vyberte nový název a zkuste to znovu.",
"ErrorPleaseSelectLineup": "Vyberte prosím sestavu a zkuste to znovu. Pokud nejsou k dispozici žádné sestavy, zkontrolujte, zda je vaše uživatelské jméno, heslo a poštovní směrovací číslo správné.",
@@ -202,7 +202,7 @@
"ErrorSavingTvProvider": "Při ukládání poskytovatele TV došlo k chybě. Prosím, ujistěte se, že je přístupný a zkuste to znovu.",
"ExitFullscreen": "Opustit celou obrazovku",
"ExtraLarge": "Extra velký",
- "ExtractChapterImagesHelp": "Extrakce obrázků kapitol umožní klientům zobrazit menu pro výběr scény. Tento proces může být náročný na cpu a může vyžadovat několik GB prostoru. Úloha je standardně spuštěna při analýze videí v nočních hodinách. Není doporučeno spouštět tuto úlohu během standardních hodin, kdy je server vytížen.",
+ "ExtractChapterImagesHelp": "Extrakce obrázků kapitol umožní klientům zobrazit menu pro výběr scény. Tento proces může být náročný na zdroje a může vyžadovat několik GB prostoru. Úloha je standardně spuštěna při analýze videí v nočních hodinách. Není doporučeno spouštět tuto úlohu během standardních hodin, kdy je server vytížen.",
"FFmpegSavePathNotFound": "Nepodařilo se nám najít FFmpeg pomocí cesty, kterou jste zadali. FFprobe je také zapotřebí a musí existovat ve stejné složce. Tyto aplikace jsou obvykle instalovány společně ve stejné složce. Zkontrolujte cestu a zkuste to znovu.",
"FastForward": "Rychle vpřed",
"Favorite": "Oblíbené",
@@ -214,7 +214,7 @@
"FolderTypeBooks": "Knihy",
"FolderTypeMovies": "Filmy",
"FolderTypeMusic": "Hudba",
- "FolderTypeMusicVideos": "Hudební klipy",
+ "FolderTypeMusicVideos": "Hudební videa",
"FolderTypeTvShows": "TV",
"FolderTypeUnset": "Nenastaveno (smíšený obsah)",
"FormatValue": "Formát: {0}",
@@ -468,7 +468,7 @@
"LabelBirthDate": "Datum narození:",
"LabelBirthYear": "Rok narození:",
"LabelBlastMessageInterval": "Doba zobrazení zprávy (v sekundách)",
- "LabelBlastMessageIntervalHelp": "Určuje dobu trvání v sekundách mezi serverovým zobrazením aktuálních zpráv.",
+ "LabelBlastMessageIntervalHelp": "Určuje dobu trvání v sekundách mezi zobrazením aktuálních zpráv.",
"LabelCachePath": "Složka pro cache:",
"LabelCachePathHelp": "Zadejte vlastní umístění pro serverové dočasné soubory, jako jsou obrázky. Ponechte prázdné, pokud chcete použít výchozí nastavení serveru.",
"LabelCancelled": "Zrušeno",
@@ -479,8 +479,8 @@
"LabelCountry": "Země:",
"LabelCriticRating": "Hodnocení kritiků:",
"LabelCurrentPassword": "Aktuální heslo:",
- "LabelCustomCss": "Vlastní css:",
- "LabelCustomCssHelp": "Aplikovat vaše uživatelské úpravy CSS do webového rozhraní.",
+ "LabelCustomCss": "Vlastní CSS:",
+ "LabelCustomCssHelp": "Aplikovat vaše vlastní styly do webového rozhraní.",
"LabelCustomDeviceDisplayName": "Jméno pro zobrazení:",
"LabelCustomDeviceDisplayNameHelp": "Nahradit vlastním názvem zobrazení nebo ponechte prázdné, aby název byl určen zařízením.",
"LabelCustomRating": "Vlastní hodnocení:",
@@ -506,7 +506,7 @@
"LabelDisplayOrder": "Pořadí zobrazení:",
"LabelDisplaySpecialsWithinSeasons": "Zobraz speciální epizody dle odvysílaných sezón",
"LabelDownMixAudioScale": "Zesílení audia při downmix:",
- "LabelDownMixAudioScaleHelp": "Zvýšit audio při dowwmix. Nastavte na 1 pro zachování původní hlasitosti.",
+ "LabelDownMixAudioScaleHelp": "Zvýšit hlasitost při downmixování. Nastavte na 1 pro zachování původní hlasitosti.",
"LabelDownloadInternetMetadata": "Stáhnout přebal a metadata z Internetu",
"LabelDownloadInternetMetadataHelp": "Jellyfin server může stahovat informace o vašich médiích, aby umožnil vylepšené prezentace.",
"LabelDownloadLanguages": "Stahované jazyky:",
@@ -522,11 +522,11 @@
"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",
- "LabelEnableDlnaServerHelp": "Povolit UPnP průchod zařízení v síti pro přehrání obsahu Jellyfin.",
+ "LabelEnableDlnaPlayToHelp": "Umí 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",
+ "LabelEnableDlnaServerHelp": "Umožňuje zařízením UPnP v síti procházet a přehrávat obsah.",
"LabelEnableRealtimeMonitor": "Povolit sledování v reálném čase",
"LabelEnableRealtimeMonitorHelp": "Změny budou zpracovány okamžitě, v podporovaných souborových systémech.",
"LabelEnableSingleImageInDidlLimit": "Limit na jednotlivé vložení obrázku",
@@ -537,7 +537,7 @@
"LabelEveryXMinutes": "Každý:",
"LabelExternalPlayers": "Externí přehrávače:",
"LabelExtractChaptersDuringLibraryScan": "Extrakce obrázků kapitol během prohledávání vaší knihovny",
- "LabelExtractChaptersDuringLibraryScanHelp": "Jestliže povolíte, budou snímky kapitol extrahovány při pravidelném prohledávání vaší knihovny. Pokud zakážete budou snímky extrahovány během naplánované úlohy pro extrakci snímků z kapitol, což umožní, při pravidelném prohledávání vaší knihovny, dokončit skenování rychleji.",
+ "LabelExtractChaptersDuringLibraryScanHelp": "Vytvářejte obrázky kapitol při importu videí během skenování knihovny. Jinak budou obrázky extrahovány během naplánované úlohy, což umožňuje rychlejší dokončení běžného skenování knihovny.",
"LabelFailed": "Selhání",
"LabelFileOrUrl": "Soubor nebo URL:",
"LabelFinish": "Dokončit",
@@ -554,10 +554,10 @@
"LabelH264Crf": "H264 kódování CRF:",
"LabelH264EncodingPreset": "Přednastavení H264 kódování:",
"LabelHardwareAccelerationType": "Hardwarová akcelerace:",
- "LabelHardwareAccelerationTypeHelp": "Dostupné jen na podporovaných systémech.",
+ "LabelHardwareAccelerationTypeHelp": "Toto je experimentální funkce dostupná pouze v podporovaných systémech.",
"LabelHomeScreenSectionValue": "Sekce domovské obrazovky {0}:",
- "LabelHttpsPort": "Lokální https port:",
- "LabelHttpsPortHelp": "Tcp port, se kterým by Jellyfin https server měl být svázán.",
+ "LabelHttpsPort": "Lokální HTTPS port:",
+ "LabelHttpsPortHelp": "Číslo portu TCP, ke kterému by se měl připojit HTTPS server Jellyfin.",
"LabelIconMaxHeight": "Maximální výška ikon:",
"LabelIconMaxHeightHelp": "Maximální rozlišení ikon nabízené prostřednictvím upnp:icon.",
"LabelIconMaxWidth": "Maximální šířka ikon:",
@@ -567,11 +567,11 @@
"LabelImageType": "Typ obrázku:",
"LabelImportOnlyFavoriteChannels": "Zamezit označení kanálů jako oblíbené",
"LabelInNetworkSignInWithEasyPassword": "Povolit přihlášení snadným PIN kódem uvnitř lokální sítě",
- "LabelInNetworkSignInWithEasyPasswordHelp": "Pokud povolíte, budete moci používat k přihlášení snadný PIN kód k Jellyfin aplikacím z vaší domácí sítě. Běžné heslo bude jen třeba pro vzdálené připojení mimo domov. Pokud ponecháte PIN kód prázdný, nebudete potřebovat heslo ve vaší domácí síti.",
+ "LabelInNetworkSignInWithEasyPasswordHelp": "Pomocí jednoduchého kódu PIN se přihlaste ke klientům v místní síti. Vaše běžné heslo bude potřeba pouze mimo domov. Pokud je kód PIN ponechán prázdný, nebudete potřebovat heslo v domácí síti.",
"LabelKeepUpTo": "Aktualizovat k:",
"LabelKidsCategories": "Dětské kategorie:",
"LabelKodiMetadataDateFormat": "Formát data vydání:",
- "LabelKodiMetadataDateFormatHelp": "Všechny datumy uvnitř NFO budou čteny a zapisovány ve vybraném formátu.",
+ "LabelKodiMetadataDateFormatHelp": "Všechna data v souborech NFO budou analyzována pomocí tohoto formátu.",
"LabelKodiMetadataEnableExtraThumbs": "Kopírovat extrafanart do extrathumbs",
"LabelKodiMetadataEnableExtraThumbsHelp": "Stažené obrázky mohou být uloženy do obou extrafanart a extrathumbs. Pro zajištění maximální kompatibility se vzhledem Kodi.",
"LabelKodiMetadataEnablePathSubstitution": "Povolit nahrazení adresářových cest",
@@ -582,11 +582,11 @@
"LabelLastResult": "Poslední výsledky:",
"LabelLimitIntrosToUnwatchedContent": "Přehrávat trailery pouze u nezhlédnutého obsahu",
"LabelLineup": "Hlavní linie:",
- "LabelLocalHttpServerPortNumber": "Lokální http port:",
- "LabelLocalHttpServerPortNumberHelp": "Tcp port, se kterým by Jellyfin http server měl být svázán.",
+ "LabelLocalHttpServerPortNumber": "Lokální HTTP port:",
+ "LabelLocalHttpServerPortNumberHelp": "Číslo portu TCP, ke kterému by se měl připojit HTTP server Jellyfin.",
"LabelLockItemToPreventChanges": "Uzamknout položku pro zabránění budoucích změn",
"LabelLoginDisclaimer": "Zřeknutí se následujících práv při přihlášení:",
- "LabelLoginDisclaimerHelp": "Toto se zobrazí ve spodní části přihlašovací stránky.",
+ "LabelLoginDisclaimerHelp": "Zpráva, která se zobrazí v dolní části přihlašovací stránky.",
"LabelLogs": "Záznamy:",
"LabelManufacturer": "Výrobce",
"LabelManufacturerUrl": "Web výrobce",
@@ -595,7 +595,7 @@
"LabelMaxChromecastBitrate": "Maximální datový tok pro Chromecast:",
"LabelMaxParentalRating": "Maximální povolené rodičovské hodnocení:",
"LabelMaxResumePercentage": "Maximální procento pro přerušení:",
- "LabelMaxResumePercentageHelp": "Tituly budou označeny jako \"přehráno\", pokud budou zastaveny po tomto čase",
+ "LabelMaxResumePercentageHelp": "Tituly se považují za plně přehrané, pokud jsou po této době zastaveny.",
"LabelMaxScreenshotsPerItem": "Maximální počet screenshotů:",
"LabelMaxStreamingBitrateHelp": "Zadejte maximální datový tok pro streamování.",
"LabelMessageText": "Text zprávy:",
@@ -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",
@@ -622,7 +622,7 @@
"LabelMonitorUsers": "Sledování aktivity z:",
"LabelMovieCategories": "Filmové kategorie:",
"LabelMoviePrefix": "Předpona filmu:",
- "LabelMoviePrefixHelp": "Je-li prefix aplikován na filmové tituly, zadejte jej zde, aby jej Jellyfin správně zpracoval.",
+ "LabelMoviePrefixHelp": "Pokud je v názvech filmů použita předpona, zadejte ji sem, aby ji server mohl správně zpracovat.",
"LabelMovieRecordingPath": "Složka pro nahrávání filmů (volitelné):",
"LabelMusicStreamingTranscodingBitrate": "Datový tok pro překódování hudby:",
"LabelMusicStreamingTranscodingBitrateHelp": "Zadejte maximální datový tok pro streamování hudby",
@@ -665,10 +665,10 @@
"LabelProtocol": "Protokol:",
"LabelProtocolInfo": "Protokol info:",
"LabelProtocolInfoHelp": "Hodnota, která se použije při odpovědi na požadavek GetProtocolInfo ze zařízení.",
- "LabelPublicHttpPort": "Veřejný http port:",
- "LabelPublicHttpPortHelp": "Veřejný port, na který by měl být mapován lokální http port.",
- "LabelPublicHttpsPort": "Veřejný https port:",
- "LabelPublicHttpsPortHelp": "Veřejný port, na který by měl být mapován lokální https port.",
+ "LabelPublicHttpPort": "Veřejný HTTP port:",
+ "LabelPublicHttpPortHelp": "Číslo veřejného portu, které by mělo být mapováno na místní port HTTP.",
+ "LabelPublicHttpsPort": "Veřejný HTTPS port:",
+ "LabelPublicHttpsPortHelp": "Číslo veřejného portu, které by mělo být mapováno na místní port HTTPS.",
"LabelReadHowYouCanContribute": "Zjistěte, jak můžete přispět.",
"LabelRecord": "Záznam:",
"LabelRecordingPath": "Standardní složka pro nahrávání:",
@@ -690,7 +690,7 @@
"LabelSerialNumber": "Sériové číslo",
"LabelSeries": "Seriály:",
"LabelSeriesRecordingPath": "Složka pro nahrávání seriálů (volitelné):",
- "LabelServerHostHelp": "192.168.1.100 nebo https://mujserver.cz",
+ "LabelServerHostHelp": "192.168.1.100:8096 nebo https://mujserver.cz",
"LabelSkipBackLength": "Délka posunu zpět:",
"LabelSkipForwardLength": "Délka posunu vpřed:",
"LabelSkipIfAudioTrackPresent": "Přeskočit, pokud výchozí zvuková stopa odpovídá jazyku stahování",
@@ -722,7 +722,7 @@
"LabelTrackNumber": "Číslo stopy:",
"LabelTranscodingAudioCodec": "Audio kodek:",
"LabelTranscodingContainer": "Obal:",
- "LabelTranscodingTempPathHelp": "Tato složka obsahuje soubory potřebné pro překódování videí. Zadejte vlastní cestu, nebo ponechte prázdné pro použití výchozí datové složky serveru.",
+ "LabelTranscodingTempPathHelp": "Určete vlastní cestu pro překódované soubory odesílané klientům. Chcete-li použít výchozí nastavení serveru, ponechte pole prázdné.",
"LabelTranscodingThreadCount": "Počet vláken pro překódování:",
"LabelTranscodingThreadCountHelp": "Zadejte maximální počet vláken pro překódování. Snížením počtu vláken se sníží využití procesoru, ale převod nemusí být dostatečně rychlý pro plynulé přehrávání.",
"LabelTranscodingVideoCodec": "Video kodek:",
@@ -741,9 +741,9 @@
"LabelVersion": "Verze:",
"LabelVersionInstalled": "{0} instalováno",
"LabelVersionNumber": "Verze {0}",
- "LabelXDlnaCap": "Zachytávací zařízení X-Dlna:",
+ "LabelXDlnaCap": "Zachytávací zařízení X-DLNA:",
"LabelXDlnaCapHelp": "Určuje obsah prvku X_DLNACAP ve jmenném prostoru urn:schemas-dlna-org:device-1-0.",
- "LabelXDlnaDoc": "Dokumentace X-Dlna:",
+ "LabelXDlnaDoc": "Dokumentace X-DLNA:",
"LabelXDlnaDocHelp": "Určuje obsah prvku X_DLNADOC ve jmenném prostoru urn:schemas-dlna-org:device-1-0.",
"LabelYear": "Rok:",
"LabelYourFirstName": "Vaše jméno:",
@@ -754,7 +754,7 @@
"Large": "Velký",
"LatestFromLibrary": "Nejnovější {0}",
"LearnHowYouCanContribute": "Zjistěte, jak můžete přispět.",
- "LibraryAccessHelp": "Vyberte složky médií, které chcete sdílet s tímto uživatelem. Administrátoři budou moci editovat všechny složky pomocí správce metadat.",
+ "LibraryAccessHelp": "Vyberte knihovny, které chcete sdílet s tímto uživatelem. Administrátoři budou moci editovat všechny složky pomocí správce metadat.",
"Like": "Mám rád",
"List": "Seznam",
"Live": "Živě",
@@ -798,30 +798,30 @@
"MessageConfirmRemoveMediaLocation": "Jste si jist, že chcete odstranit toto umístění?",
"MessageConfirmRestart": "Jste si jist, že chcete restartovat Jellyfin server?",
"MessageConfirmRevokeApiKey": "Jste si jisti, že chcete odvolat tento klíč API? Připojení k aplikaci k Jellyfin Server bude násilně ukončeno.",
- "MessageConfirmShutdown": "Jste si jist, že chcete vypnout Jellyfin server?",
+ "MessageConfirmShutdown": "Jste si jisti, že chcete server vypnout?",
"MessageContactAdminToResetPassword": "Kontaktujte, prosím, vašeho systémového administrátora k obnovení vašeho hesla.",
"MessageCreateAccountAt": "Vytvořit účet v {0}",
"MessageDeleteTaskTrigger": "Opravdu si přejete odebrat spouštění úlohy?",
"MessageDirectoryPickerBSDInstruction": "Pro BSD, budete možná muset nakonfigurovat úložiště přímo ve Vašem FreeNAS Jail aby k nim Jellyfin povolil přístup.",
"MessageDirectoryPickerInstruction": "Síťové cesty lze zadat ručně v případě, že tlačítko 'Síť' nedokáže automaticky lokalizovat vaše zařízení. Například, {0} nebo {1}.",
- "MessageDirectoryPickerLinuxInstruction": "Pro Linux na Arch Linux, CentOS, Debian, Fedora, openSUSE nebo Ubuntu, je nutné přiřadit oprávnění uživatelům k úložištím systému Jellyfin alespoň pro čtení.",
+ "MessageDirectoryPickerLinuxInstruction": "Pro systémy Linux jako Arch Linux, CentOS, Debian, Fedora, openSUSE nebo Ubuntu musíte udělit uživateli služby oprávnění alespoň pro čtení.",
"MessageDownloadQueued": "Stažení zařazeno.",
"MessageFileReadError": "Došlo k chybě při čtení souboru. Prosím zkuste to znovu.",
"MessageForgotPasswordFileCreated": "Následující soubor byl vytvořen na serveru a obsahuje pokyny, jak postupovat:",
"MessageForgotPasswordInNetworkRequired": "Zkuste to prosím znovu uvnitř vaší domácí sítě pro zahájení procesu resetování hesla.",
- "MessageInstallPluginFromApp": "Tento zásuvný modul musí být instalován z aplikace, který jej používá.",
- "MessageInvalidForgotPasswordPin": "Neplatný zadádní pinu. Prosím zkuste to znovu.",
+ "MessageInstallPluginFromApp": "Tento plugin musí být nainstalován z aplikace, kterou chcete použít.",
+ "MessageInvalidForgotPasswordPin": "Neplatné zadání pin kódu. Prosím, zkuste to znovu.",
"MessageInvalidUser": "Neplatné uživatelské jméno nebo heslo. Zkuste znovu.",
"MessageItemSaved": "Položka uložena.",
"MessageItemsAdded": "Položky přidány.",
- "MessageLeaveEmptyToInherit": "Při ponechání prázdné položky bude zděděno nastavení z položky nadřazené nebo z globální defaultní hodnoty.",
+ "MessageLeaveEmptyToInherit": "Chcete-li zdědit nastavení od nadřazené položky nebo globální výchozí hodnoty, ponechte prázdné.",
"MessageNoAvailablePlugins": "Nejsou dostupné žádné zásuvné moduly.",
"MessageNoMovieSuggestionsAvailable": "Žádné návrhy nejsou v současnosti k dispozici. Začněte sledovat a hodnotit filmy, a pak se vám doporučení zobrazí.",
"MessageNoPluginsInstalled": "Nemáte instalovány žádné zásuvné moduly.",
"MessageNoTrailersFound": "Nebyly nalezeny žádné ukázky z filmů (trailery). Nainstalujte trailer kanál pro lepší zážitek z filmu přidáním knihovny internetových trailerů.",
"MessageNothingHere": "Tady nic není.",
"MessagePasswordResetForUsers": "Obnovení hesla bylo provedeno následujícími uživateli. Nyní se mohou přihlásit pomocí kódů PIN, které byly použity k provedení resetu.",
- "MessagePlayAccessRestricted": "Přehrávání tohoto obsahu je momentálně omezeno. Pro více informací kontaktujte prosím Vašeho správce Jellyfin Serveru.",
+ "MessagePlayAccessRestricted": "Přehrávání tohoto obsahu je aktuálně omezeno. Další informace získáte od správce serveru.",
"MessagePleaseEnsureInternetMetadata": "Prosím zkontrolujte, zda máte povoleno stahování metadat z internetu.",
"MessagePleaseRestart": "Pro dokončení aktualizací, prosím, restartujte.",
"MessagePleaseRestartServerToFinishUpdating": "Restartujte, prosím, server pro aplikaci aktualizací.",
@@ -829,7 +829,7 @@
"MessagePluginInstallDisclaimer": "Zasuvné moduly vytvořené členy Jellyfin komunity jsou skvělý způsob, jak zvýšit svůj Jellyfin prožitek pomocí doplňkových funkcí :-) Před instalací, se prosím seznamte se všemi dopady, které mohou mít na Jellyfin Server, jako je například delší prohledávání knihovny, další zpracování na pozadí, a snížení stability systému.",
"MessageReenableUser": "Viz níže pro znovuzapnutí",
"MessageSettingsSaved": "Nastavení uloženo.",
- "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Následující umístění médií budou odstraněna z knihovny Jellyfin:",
+ "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Z vaší knihovny budou odstraněny následující zdroje médií:",
"MessageUnableToConnectToServer": "Nejsme schopni se připojit k vybranému serveru právě teď. Prosím, ujistěte se, že je spuštěn a zkuste to znovu.",
"MessageUnsetContentHelp": "Obsah je zobrazen pomocí prostých složek. Pro dosažení nejlepších výsledků pomocí správce metadat nastavte typy obsahu pod-složek.",
"MessageYouHaveVersionInstalled": "V současné době máte instalovánu verzi {0}.",
@@ -841,7 +841,7 @@
"MissingEpisode": "Chybí epizoda.",
"MissingLogoImage": "Nedostupný obrázek loga.",
"MissingPrimaryImage": "Nedostupný primární obrázek.",
- "Mobile": "Mobil / Tablet",
+ "Mobile": "Mobilní",
"Monday": "Pondělí",
"MoreFromValue": "Více z {0}",
"MoreUsersCanBeAddedLater": "Další uživatele můžete přidat později na Hlavní nabídce.",
@@ -883,7 +883,7 @@
"OptionAllowMediaPlayback": "Povolit přehrávání médií",
"OptionAllowRemoteControlOthers": "Povolit vzdálené ovládání ostatních uživatelů",
"OptionAllowRemoteSharedDevices": "Povolit vzdálené ovládání sdílených zařízení",
- "OptionAllowRemoteSharedDevicesHelp": "DLNA zařízení jsou považovány za sdílené, dokud je uživatel nezačne omezovat.",
+ "OptionAllowRemoteSharedDevicesHelp": "DLNA zařízení jsou považována za sdílená, dokud je uživatel nezačne omezovat.",
"OptionAllowUserToManageServer": "Povolit tomuto uživateli správu serveru",
"OptionAllowVideoPlaybackRemuxing": "Umožní přehrávání videa, která vyžaduje konverzi bez opětovného překódování",
"OptionAllowVideoPlaybackTranscoding": "Povolit přehrávání videa, které vyžaduje překódování",
@@ -916,12 +916,12 @@
"OptionDisableUserHelp": "Pokud není povoleno, server nedovolí tomuto uživateli žádné připojení. Existující připojení bude okamžitě přerušeno.",
"OptionDislikes": "Nelíbí se",
"OptionDisplayFolderView": "Zobrazit složku s originálním zobrazením složek médií",
- "OptionDisplayFolderViewHelp": "Pokud je povoleno, Jellyfin aplikace zobrazí skupinu složek vedle knihovny médií. To je užitečné, pokud chcete mít pohled na originální složky medií.",
+ "OptionDisplayFolderViewHelp": "Zobrazte složky vedle vašich ostatních knihoven médií. To může být užitečné, pokud si přejete mít prosté zobrazení složky.",
"OptionDownloadArtImage": "Obal",
"OptionDownloadBackImage": "Zadek",
"OptionDownloadDiscImage": "Disk",
"OptionDownloadImagesInAdvance": "Stáhnout obrázky pokročilejším způsobem",
- "OptionDownloadImagesInAdvanceHelp": "Ve výchozím nastavení jsou sekundární obrázky staženy, jen při požádání aplikace Jellyfin. Povolením této možnosti se stáhnou všechny obrázky v předstihu, jakmile jsou nová média načtena do knihovny.",
+ "OptionDownloadImagesInAdvanceHelp": "Ve výchozím nastavení se většina obrázků stahuje pouze na žádost aplikace Jellyfin. Povolte tuto možnost pro stažení všech obrázků předem, když se importují nová média. To může způsobit výrazně delší skenování knihovny.",
"OptionDownloadMenuImage": "Nabídka",
"OptionDownloadPrimaryImage": "Primární",
"OptionDownloadThumbImage": "Miniatura",
@@ -932,7 +932,7 @@
"OptionEnableAccessToAllLibraries": "Povolit přístup ke všem knihovnám",
"OptionEnableAutomaticServerUpdates": "Povolit automatickou aktualizaci serveru",
"OptionEnableExternalContentInSuggestions": "Aktivovat externí obsah v návrzích",
- "OptionEnableExternalContentInSuggestionsHelp": "Povolit internetové upoutávky a živé televizní programy, které mají být zahrnuty do navrženého obsahu.",
+ "OptionEnableExternalContentInSuggestionsHelp": "Povolit zahrnutí internetových upoutávek a živých televizních programů do navrhovaného obsahu.",
"OptionEnableForAllTuners": "Povolit pro všechna zařízení tunerů",
"OptionEnableM2tsMode": "Povolit M2ts mód",
"OptionEnableM2tsModeHelp": "Povolit režim M2TS při kódování do MPEGTS.",
@@ -951,8 +951,8 @@
"OptionHasTrailer": "Ukázka/trailer",
"OptionHideUser": "Skrýt tohoto uživatele z přihlašovacích obrazovek",
"OptionHideUserFromLoginHelp": "Vhodné pro soukromé a administrátorské účty. Pro přihlášení musí uživatel manuálně zadat uživatelské jméno a heslo.",
- "OptionHlsSegmentedSubtitles": "Segmentování Hls titulků",
- "OptionHomeVideos": "Domácí videa a fotky",
+ "OptionHlsSegmentedSubtitles": "Segmentované titulky HLS",
+ "OptionHomeVideos": "Fotky",
"OptionIgnoreTranscodeByteRangeRequests": "Ignorovat požadavky na překódování rozsahy bajtů",
"OptionIgnoreTranscodeByteRangeRequestsHelp": "Pokud je povoleno, budou tyto žádosti nadále plněny, ale budou ignorovány hlavičky bytových rozsahů.",
"OptionImdbRating": "Hodnocení IMDb",
@@ -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.",
@@ -1183,7 +1183,7 @@
"Unrated": "Nehodnoceno",
"Up": "Nahoru",
"Upload": "Nahrát",
- "UserProfilesIntro": "Jellyfin obsahuje zabudovanou podporu uživatelských profilů, umožňující každému uživateli mít své vlastní nastavení zobrazení, stav přehrání a rodičovské kontroly.",
+ "UserProfilesIntro": "Jellyfin zahrnuje podporu uživatelských profilů s podrobným nastavením zobrazení, stavem přehrávání a rodičovskou kontrolou.",
"ValueAlbumCount": "{0} alb",
"ValueAudioCodec": "Audio kodeky: {0}",
"ValueCodec": "Kodek: {0}",
@@ -1209,13 +1209,13 @@
"Watched": "Shlédnuto",
"Wednesday": "Středa",
"WelcomeToProject": "Vítejte v Jellyfin!",
- "WizardCompleted": "To je vše, co nyní potřebujeme. Jellyfin začala shromažďovat informace o vaší knihovně médií. Podívejte se na některé z našich aplikací, a potom klepněte na tlačítko
Dokončit pro zobrazení
Server Dashboard .",
+ "WizardCompleted": "To je vše, co nyní potřebujeme. Jellyfin začala shromažďovat informace o vaší knihovně médií. Podívejte se na některé z našich aplikací, a potom klepněte na tlačítko
Dokončit pro zobrazení
hlavního panelu .",
"Writer": "Napsal",
- "XmlDocumentAttributeListHelp": "Tyto atributy jsou aplikovány na kořenového elementu každé xml odpovědi.",
+ "XmlDocumentAttributeListHelp": "Tyto atributy jsou použity na kořenový prvek každé XML odpovědi.",
"XmlTvKidsCategoriesHelp": "Programy s těmito kategoriemi budou zobrazeny jako programy pro děti. Více kategorií oddělte \"|\".",
"XmlTvMovieCategoriesHelp": "Programy s těmito kategoriemi budou zobrazeny jako filmy. Více kategorií oddělte \"|\".",
"XmlTvNewsCategoriesHelp": "Programy s těmito kategoriemi budou zobrazeny jako zpravodajské pořady. Více kategorií oddělte \"|\".",
- "XmlTvPathHelp": "Cesta ke XML tv souboru. Jellyfin bude číst tento soubor a pravidelně kontrolovat dostupnost aktualizací. Jste zodpovědný za vytváření a aktualizaci souboru.",
+ "XmlTvPathHelp": "Cesta k souboru XML TV. Jellyfin tento soubor načte a pravidelně jej kontroluje, zda neobsahuje aktualizace. Jste zodpovědní za vytvoření a aktualizaci souboru.",
"XmlTvSportsCategoriesHelp": "Programy s těmito kategoriemi budou zobrazeny jako sportovní pořady. Více kategorií oddělte \"|\".",
"Yes": "Ano",
"Yesterday": "Včera",
@@ -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"
}
diff --git a/src/strings/de.json b/src/strings/de.json
index eb158e5eaa..c57acd0d73 100644
--- a/src/strings/de.json
+++ b/src/strings/de.json
@@ -22,11 +22,11 @@
"AllLanguages": "Alle Sprachen",
"AllLibraries": "Alle Bibliotheken",
"AllowDeletionFromAll": "Erlaube Medienlöschung in allen Bibliotheken",
- "AllowHWTranscodingHelp": "Wenn aktiviert, übernimmt der Tuner die Transkodierung in Echtzeit. Das hilft eventuell die Transkodierung auf dem Jellyfin Servers zu reduzieren. (Spart Hardwareressourcen)",
+ "AllowHWTranscodingHelp": "Erlaube dem Tuner die Transkodierung in Echtzeit. Das hilft eventuell die Transkodierung auf dem Jellyfin Servers zu reduzieren. (Spart Hardwareressourcen)",
"AllowMediaConversion": "Erlaube Medienkonvertierung",
"AllowMediaConversionHelp": "Erlaube oder unterbinde Zugriff auf die Medienkonvertierung.",
"AllowOnTheFlySubtitleExtraction": "Erlaube Untertitelextraktion \"on-the-fly\"",
- "AllowOnTheFlySubtitleExtractionHelp": "Eingebettete Untertitel können aus Videos extrahiert und in Textformat an Jellyfin gesendet werden um Transkodieren zu vermeiden. Auf manchen Systemen kann dieser Vorgang eine lange Zeit in Anspruch nehmen und die Videowiedergabe zum Halten bringen während der Extraktion. Deaktiviere diese Option um eingebettete Untertitel während des Videotranskodierens einbrennen zu lassen, wenn sie nicht nativ vom Client unterstützt werden.",
+ "AllowOnTheFlySubtitleExtractionHelp": "Eingebettete Untertitel können aus Videos extrahiert und in Textformat an Clients gesendet werden um Transkodieren zu vermeiden. Auf manchen Systemen kann dieser Vorgang eine lange Zeit in Anspruch nehmen und die Videowiedergabe zum Halten bringen während der Extraktion. Deaktiviere diese Option um eingebettete Untertitel während der Videotranskodierung einbrennen zu lassen, wenn sie nicht nativ vom Client unterstützt werden.",
"AllowRemoteAccess": "Erlaube externe Verbindungen zu diesem Jellyfin Server.",
"AllowRemoteAccessHelp": "Wenn deaktiviert werden alle externen Verbindungen blockiert.",
"AllowSeasonalThemes": "Erlaube automatische Jahreszeitenmotive",
@@ -55,7 +55,7 @@
"BirthLocation": "Geburtsort",
"BirthPlaceValue": "Geburtsort: {0}",
"BobAndWeaveWithHelp": "Bob & Weave (höhere Qualität, aber langsamer)",
- "BookLibraryHelp": "Hörbücher und E-Books werden unterstützt. Schaue in den {0}Jellyfin Book Naming Guide {1}.",
+ "BookLibraryHelp": "Hörbücher und E-Books werden unterstützt. Schaue in den {0}Book Naming Guide {1}.",
"Books": "Bücher",
"BoxRear": "Box (Rückseite)",
"Browse": "Blättern",
@@ -165,7 +165,7 @@
"DeleteImageConfirmation": "Möchtest du dieses Bild wirklich löschen?",
"DeleteMedia": "Medien löschen",
"DeleteUser": "Benutzer löschen",
- "DeleteUserConfirmation": "Möchtest du {0} wirklich löschen?",
+ "DeleteUserConfirmation": "Möchtest du den Benutzer wirklich löschen?",
"Depressed": "Gedrückt",
"Descending": "Absteigend",
"DetectingDevices": "Suche Geräte",
@@ -422,7 +422,7 @@
"HeaderSelectServerCachePathHelp": "Suche oder gib den Pfad für die Speicherung von Server Cache Dateien an. Das Verzeichnis muss beschreibbar sein.",
"HeaderSelectTranscodingPath": "Wähle Pfad für temporäre Transkodierdateien",
"HeaderSelectTranscodingPathHelp": "Suche oder gib den Pfad für die Speicherung von temporären Transkodierdateien an. Das Verzeichnis muss beschreibbar sein.",
- "HeaderSendMessage": "sende Nachricht",
+ "HeaderSendMessage": "Nachricht senden",
"HeaderSeries": "Serien",
"HeaderSeriesOptions": "Serienoptionen",
"HeaderSeriesStatus": "Serienstatus",
@@ -1401,7 +1401,7 @@
"Thumb": "Miniaturansicht",
"TitleSupport": "Hilfe",
"Whitelist": "Erlaubt",
- "AuthProviderHelp": "Auswählen eines Authentifizierungsanbieter, der zur Authentifizierung des Passworts dieses Benutzes verwendet werden soll",
+ "AuthProviderHelp": "Auswählen eines Authentifizierungsanbieter, der zur Authentifizierung des Passworts dieses Benutzes verwendet werden soll.",
"Features": "Features",
"HeaderFavoriteBooks": "Lieblingsbücher",
"HeaderFavoriteMovies": "Lieblingsfilme",
@@ -1437,5 +1437,29 @@
"HeaderTypeImageFetchers": "{0} Bildquellen",
"LabelBitrate": "Bitrate:",
"LabelAudioBitrate": "Tonbitrate:",
- "ButtonAddImage": "Bild hinzufügen"
+ "ButtonAddImage": "Bild hinzufügen",
+ "LabelSize": "Größe:",
+ "LabelTranscodes": "Transkoder:",
+ "LabelTranscodingProgress": "Transcodierungsfortschritt:",
+ "LabelAudioBitDepth": "Audio-Bittiefe:",
+ "LabelPleaseRestart": "Die Änderungen werden nach dem manuellen Neuladen des Webclients wirksam.",
+ "LabelVideoBitrate": "Video-Bitrate:",
+ "LabelTranscodingFramerate": "Transcodierrate:",
+ "LabelAudioSampleRate": "Audio-Abtastrate:",
+ "LabelBaseUrl": "Basis URL:",
+ "LabelBaseUrlHelp": "Du kannst hier ein benutzerdefiniertes Unterverzeichnis hinzufügen, um über eine eindeutige URL auf den Server zuzugreifen.",
+ "LabelFolder": "Ordner:",
+ "LabelPasswordResetProvider": "Anbieter zum Zurücksetzen des Passwortes:",
+ "LabelPlayMethod": "Spielmethode:",
+ "DashboardOperatingSystem": "Betriebssystem: {O}",
+ "DashboardArchitecture": "Architektur: {0}",
+ "LabelVideoCodec": "Videocodec:",
+ "LaunchWebAppOnStartup": "Das Webinterface öffnen, wenn der Server startet",
+ "LaunchWebAppOnStartupHelp": "Öffne den Webclient in Standard-Webbrowser, wenn der Server zum ersten Mal gestartet wird. Dies tritt bei Verwendung der Neustart-Serverfunktion nicht auf.",
+ "MusicArtist": "Interpret",
+ "MusicAlbum": "Musikalbum",
+ "MoreMediaInfo": "Medieninformation",
+ "MessageNoServersAvailable": "Die automatische Serversuche konnte keinen Server finden.",
+ "LabelPlayer": "Player:",
+ "MediaInfoCodecTag": "Codec Tag"
}
diff --git a/src/strings/fr.json b/src/strings/fr.json
index 67e50642f5..e0b5528c5b 100644
--- a/src/strings/fr.json
+++ b/src/strings/fr.json
@@ -19,11 +19,11 @@
"AllLanguages": "Toutes les langues",
"AllLibraries": "Toutes les médiathèques",
"AllowDeletionFromAll": "Autoriser la suppression de média depuis toutes les médiathèques",
- "AllowHWTranscodingHelp": "Si l'option est activée, permet au tuner TV de transcoder les flux à la volée. Cela peut aider à réduire le transcodage requis par le serveur Jellyfin.",
+ "AllowHWTranscodingHelp": "Autoriser le tuner TV à transcoder les flux à la volée. Cela peut aider à réduire le transcodage requis par le serveur.",
"AllowMediaConversion": "Autoriser la conversion des médias",
"AllowMediaConversionHelp": "Autoriser ou refuser l'accès à la fonctionnalité de conversion des médias.",
"AllowOnTheFlySubtitleExtraction": "Autoriser l'extraction des sous-titres à la volée",
- "AllowOnTheFlySubtitleExtractionHelp": "Les sous-titres intégrés peuvent être extraits des vidéos et distribués aux applications Jellyfin au format texte pour éviter le transcodage. Sur certains systèmes, cela peut prendre du temps et arrêter la lecture de la vidéo pendant le processus d'extraction. Désactivez cette option pour graver les sous-titres avec un transcodage quand l'appareil ne les prend pas en charge nativement.",
+ "AllowOnTheFlySubtitleExtractionHelp": "Les sous-titres intégrés peuvent être extraits des vidéos et distribués aux clients au format texte pour éviter le transcodage. Sur certains systèmes, cela peut prendre du temps et arrêter la lecture de la vidéo pendant le processus d'extraction. Désactivez cette option pour graver les sous-titres avec un transcodage quand l'appareil ne les prend pas en charge nativement.",
"AllowRemoteAccess": "Autoriser les connexions distantes à ce serveur Jellyfin.",
"AllowRemoteAccessHelp": "Si l'option est désactivée, toutes les connexions distantes seront bloquées.",
"AllowedRemoteAddressesHelp": "Liste d'adresses IP ou d'IP/masque de sous-réseau séparées par des virgules qui seront autorisées à se connecter à distance. Si la liste est vide, toutes les adresses distantes seront autorisées.",
@@ -45,13 +45,13 @@
"BirthLocation": "Lieu de naissance",
"BirthPlaceValue": "Lieu de naissance : {0}",
"Blacklist": "Liste noire",
- "BookLibraryHelp": "Les livres audios et numériques sont supportés. Consultez le {0}Guide de nommage pour livre de Jellyfin{1}.",
+ "BookLibraryHelp": "Les livres audios et numériques sont supportés. Consultez le {0}Guide de nommage pour livres{1}.",
"Books": "Livres",
"Box": "Boîtier",
"BoxRear": "Dos de boîtier",
"Browse": "Parcourir",
"BrowsePluginCatalogMessage": "Explorer notre catalogue des plugins pour voir les plugins disponibles.",
- "BurnSubtitlesHelp": "Détermine si le serveur doit graver les sous-titres lors de la conversion vidéo en fonction du format des sous-titres. Éviter la gravure des sous-titres améliorera les performances du serveur. Sélectionnez Auto pour graver les formats basés sur l'image (par exemple, VOBSUB, PGS, SUB/IDX etc) ainsi que certains sous-titres ASS/SSA.",
+ "BurnSubtitlesHelp": "Détermine si le serveur doit incruster les sous-titres lors de la conversion vidéo en fonction du format de sous-titre. Éviter l'incrustation des sous-titres améliorera les performances du serveur. Sélectionnez Auto pour incruster les formats basés sur l'image (VOBSUB, PGS, SUB/IDX etc) ainsi que certains sous-titres ASS/SSA.",
"ButtonAdd": "Ajouter",
"ButtonAddMediaLibrary": "Ajouter une médiathèque",
"ButtonAddScheduledTaskTrigger": "Ajouter un déclencheur",
@@ -172,7 +172,7 @@
"DetectingDevices": "Détection des appareils",
"DeviceAccessHelp": "Ceci ne s'applique qu'aux appareils qui peuvent être identifiés de manière unique et n'empêchera pas l'accès par navigateur. Le filtrage de l'accès aux appareil par utilisateur empêchera l'utilisation de nouveaux appareils jusqu'à ce qu'ils soient approuvés ici.",
"DirectPlaying": "Lecture directe",
- "DirectStreamHelp1": "Le média est compatible avec l'appareil en ce qui concerne la résolution et le type de média (H.264, AC3 etc), mais se trouve dans un conteneur de fichiers incompatible (.mkv, .avi, .wmv etc). La vidéo sera rempaquetée à la volée avant d'être diffusée à l'appareil.",
+ "DirectStreamHelp1": "Le média est compatible avec l'appareil en ce qui concerne la résolution et le type de média (H.264, AC3,etc), mais se trouve dans un conteneur de fichiers incompatible (mkv, avi, wmv, etc). La vidéo sera rempaquetée à la volée avant d'être diffusée à l'appareil.",
"DirectStreamHelp2": "Le streaming en direct d'un fichier utilise très peu de puissance de traitement sans perte de qualité vidéo.",
"DirectStreaming": "Streaming direct",
"Director": "Réalisateur(trice)",
@@ -186,7 +186,7 @@
"DisplayInMyMedia": "Afficher sur l’écran d’accueil",
"DisplayInOtherHomeScreenSections": "Afficher dans les sections de l’écran d’accueil comme Ajouts récents et Reprendre",
"DisplayMissingEpisodesWithinSeasons": "Afficher les épisodes manquants dans les saisons",
- "DisplayMissingEpisodesWithinSeasonsHelp": "Cette option doit aussi être activée pour les médiathèques TV dans les paramètres du serveur Jellyfin.",
+ "DisplayMissingEpisodesWithinSeasonsHelp": "Cette option doit aussi être activée pour les médiathèques TV dans les paramètres du serveur.",
"DisplayModeHelp": "Sélectionner le type d'écran sur lequel vous utilisez Jellyfin.",
"DoNotRecord": "Ne pas enregistrer",
"Down": "Bas",
@@ -194,29 +194,29 @@
"DownloadsValue": "{0} téléchargements",
"DrmChannelsNotImported": "Les chaînes avec DRM ne seront pas importées.",
"DropShadow": "Ombre portée",
- "EasyPasswordHelp": "Votre code Easy PIN est utilisé pour l'accès hors ligne par les applications Jellyfin compatibles. Il peut également servir à simplifier votre connexion depuis votre réseau local.",
+ "EasyPasswordHelp": "Votre code Easy PIN est utilisé pour l'accès hors ligne par les clients compatibles. Il peut également servir à simplifier votre connexion depuis votre réseau local.",
"Edit": "Modifier",
"EditImages": "Modifier les images",
"EditMetadata": "Éditer les métadonnées",
"EditSubtitles": "Modifier les sous-titres",
- "EnableBackdrops": "Activer les images d'arrière-plans",
- "EnableBackdropsHelp": "Si activé, les images d'arrière-plan seront affichées sur certaines pages pendant la navigation dans la médiathèque.",
- "EnableCinemaMode": "Activer le mode cinéma",
- "EnableColorCodedBackgrounds": "Activer les fonds avec code couleur",
- "EnableDisplayMirroring": "Activer le partage d'écran",
- "EnableExternalVideoPlayers": "Activer les lecteurs vidéo externes",
+ "EnableBackdrops": "Images d'arrière-plan",
+ "EnableBackdropsHelp": "Afficher les images d'arrière-plan sur certaines pages pendant la navigation dans la médiathèque.",
+ "EnableCinemaMode": "Mode cinéma",
+ "EnableColorCodedBackgrounds": "Fonds avec code couleur",
+ "EnableDisplayMirroring": "Affichage en mirroir",
+ "EnableExternalVideoPlayers": "Lecteurs vidéo externes",
"EnableExternalVideoPlayersHelp": "Une liste des lecteurs externes sera affichée au lancement de la lecture d'une vidéo.",
"EnableHardwareEncoding": "Activer l'encodage matériel",
- "EnableNextVideoInfoOverlay": "Activer les informations de la vidéo suivante pendant la lecture",
+ "EnableNextVideoInfoOverlay": "Afficher les informations de la vidéo suivante pendant la lecture",
"EnableNextVideoInfoOverlayHelp": "À la fin d'une vidéo, afficher les informations sur la vidéo suivante dans la file d'attente.",
- "EnablePhotos": "Activer les photos",
- "EnablePhotosHelp": "Les photos seront détectées et affichées avec les autres fichiers multimédia.",
+ "EnablePhotos": "Afficher les photos",
+ "EnablePhotosHelp": "Les images seront détectées et affichées avec les autres fichiers multimédia.",
"EnableStreamLooping": "Reboucler les streaming en direct",
"EnableStreamLoopingHelp": "Activez cette option si les streaming en direct ne contiennent que quelques secondes de données et doivent être redemandés continuellement. N'activez pas cette option sans raison car elle peut causer des problèmes.",
- "EnableThemeSongs": "Activer les thèmes musicaux",
- "EnableThemeSongsHelp": "Si activé, les thèmes musicaux seront lus en arrière-plan pendant la navigation dans la médiathèque.",
- "EnableThemeVideos": "Activer les thèmes vidéos",
- "EnableThemeVideosHelp": "Si activé, les thèmes vidéos seront lus en arrière-plan tout en parcourant la médiathèque.",
+ "EnableThemeSongs": "Thèmes musicaux",
+ "EnableThemeSongsHelp": "Lire les thèmes musicaux en arrière-plan pendant la navigation dans la médiathèque.",
+ "EnableThemeVideos": "Thèmes vidéos",
+ "EnableThemeVideosHelp": "Lire les thèmes vidéos en arrière-plan tout en parcourant la médiathèque.",
"Ended": "Terminé",
"EndsAtValue": "Se termine à {0}",
"Episodes": "Épisodes",
@@ -231,8 +231,8 @@
"ErrorSavingTvProvider": "Une erreur est survenue lors de la sauvegarde du fournisseur TV. Assurez-vous qu'il est accessible et réessayez.",
"EveryNDays": "Tous les {0} jours",
"ExitFullscreen": "Sortir du plein écran",
- "ExtraLarge": "Très grand",
- "ExtractChapterImagesHelp": "L'extraction d'images de chapitre permettra aux applications Jellyfin d'afficher des menus visuels pour la sélection des scènes. Le processus peut être long et consommateur de ressources processeur et peut nécessiter de nombreux gigaoctets de stockage. Il s'exécute quand des vidéos sont découvertes et également comme tâche planifiée. La planification peut être modifiée dans les options du planificateur de tache. Il n'est pas conseillé d'exécuter cette tâche pendant les heures d'usage intensif.",
+ "ExtraLarge": "Très Grand",
+ "ExtractChapterImagesHelp": "L'extraction d'images de chapitre permettra aux applications d'afficher des menus visuels pour la sélection des scènes. Le processus peut être long, consommateur de ressources et peut nécessiter de nombreux gigaoctets de stockage. Il s'exécute lorsque des vidéos sont découvertes et également comme tâche planifiée. La planification peut être modifiée dans les options du planificateur de tâches. Il n'est pas conseillé d'exécuter cette tâche pendant les heures d'usage intensif.",
"FFmpegSavePathNotFound": "Nous ne pouvons pas localiser FFmpeg en utilisant le chemin que vous avez saisi. FFprobe est également nécessaire et doit exister dans le même dossier. Ces composants sont généralement regroupés dans le même téléchargement. Veuillez vérifier le chemin et essayer à nouveau.",
"FastForward": "Avance rapide",
"Favorite": "Favori",
@@ -307,7 +307,7 @@
"HeaderContainerProfile": "Profil de conteneur",
"HeaderContainerProfileHelp": "Les profils de conteneur indiquent les limites d'un appareil lors de la lecture de formats spécifiques. Si la limite s'applique au média, ce dernier sera transcodé, même si le format est configuré pour la lecture directe.",
"HeaderContinueListening": "Reprendre l'écoute",
- "HeaderContinueWatching": "Reprendre",
+ "HeaderContinueWatching": "Continuer à regarder",
"HeaderCustomDlnaProfiles": "Profils personnalisés",
"HeaderDateIssued": "Date de publication",
"HeaderDefaultRecordingSettings": "Paramètres d'enregistrement par défaut",
@@ -503,7 +503,7 @@
"LabelAll": "Tout",
"LabelAllowHWTranscoding": "Autoriser le transcodage matériel",
"LabelAllowServerAutoRestart": "Autoriser le redémarrage automatique du serveur pour appliquer les mises à jour",
- "LabelAllowServerAutoRestartHelp": "Le serveur ne redémarrera que pendant les périodes d'inactivité, quand aucun utilisateur n'est connecté.",
+ "LabelAllowServerAutoRestartHelp": "Le serveur ne redémarrera que pendant les périodes d'inactivité quand aucun utilisateur n'est connecté.",
"LabelAllowedRemoteAddresses": "Filtre d'adresse IP distante :",
"LabelAllowedRemoteAddressesMode": "Type de filtre des adresses IP distantes :",
"LabelAppName": "Nom de l'application",
@@ -517,7 +517,7 @@
"LabelBirthDate": "Date de naissance :",
"LabelBirthYear": "Année de naissance :",
"LabelBlastMessageInterval": "Intervalle des messages de présence (secondes)",
- "LabelBlastMessageIntervalHelp": "Détermine la durée en secondes entre les messages de présence du serveur.",
+ "LabelBlastMessageIntervalHelp": "Détermine la durée en secondes entre les messages de présence.",
"LabelBlockContentWithTags": "Bloquer les éléments avec les étiquettes :",
"LabelBurnSubtitles": "Graver les sous-titres :",
"LabelCache": "Cache :",
@@ -536,7 +536,7 @@
"LabelCustomCertificatePath": "Chemin vers le certificat SSL personnalisé :",
"LabelCustomCertificatePathHelp": "Chemin vers un fichier PKCS #12 contenant un certificat et une clé privée pour activer le support TLS sur un domaine utilisateur.",
"LabelCustomCss": "CSS personnalisée :",
- "LabelCustomCssHelp": "Appliquez votre propre feuille de styles CSS personnalisée à l'interface web.",
+ "LabelCustomCssHelp": "Appliquez votre propre feuille de styles personnalisée à l'interface web.",
"LabelCustomDeviceDisplayName": "Nom d'affichage :",
"LabelCustomDeviceDisplayNameHelp": "Entrez un nom d'affichage personnalisé ou laissez vide pour utiliser le nom rapporté par l'appareil.",
"LabelCustomRating": "Note personnalisée :",
@@ -561,7 +561,7 @@
"LabelDisplayOrder": "Ordre d'affichage :",
"LabelDisplaySpecialsWithinSeasons": "Afficher les épisodes spéciaux avec leur saison de diffusion",
"LabelDownMixAudioScale": "Booster l'audio lors du downmix :",
- "LabelDownMixAudioScaleHelp": "Augmente le volume de l'audio quand on diminue le nombre de canaux. Mettre à 1 pour préserver la valeur originale du volume.",
+ "LabelDownMixAudioScaleHelp": "Augmente le volume de l'audio quand on diminue le nombre de canaux. Une valeur de 1 préserve le volume original.",
"LabelDownloadLanguages": "Téléchargement des langues :",
"LabelDropImageHere": "Faites glisser l'image ici, ou cliquez pour parcourir vos fichiers.",
"LabelDropShadow": "Ombre portée :",
@@ -576,11 +576,11 @@
"LabelEnableDlnaClientDiscoveryInterval": "Intervalle de découverte des clients (secondes)",
"LabelEnableDlnaClientDiscoveryIntervalHelp": "Détermine la durée en secondes entre les recherches SSDP exécutées par Jellyfin.",
"LabelEnableDlnaDebugLogging": "Activer le débogage DLNA dans le journal d'événements",
- "LabelEnableDlnaDebugLoggingHelp": "Ceci va générer de gros fichiers de journal d'événements et ne devrait être utiliser que pour des diagnostics d'erreur.",
+ "LabelEnableDlnaDebugLoggingHelp": "Génère de gros fichiers de journal d'événements et ne devrait être utilisé que pour des diagnostics d'erreur.",
"LabelEnableDlnaPlayTo": "Activer la lecture en DLNA",
- "LabelEnableDlnaPlayToHelp": "Jellyfin peut détecter les appareils de votre réseau et offre la possibilité de les contrôler à distance.",
+ "LabelEnableDlnaPlayToHelp": "Détecter les appareils de votre réseau et offrir la possibilité de les contrôler à distance.",
"LabelEnableDlnaServer": "Activer le serveur DLNA",
- "LabelEnableDlnaServerHelp": "Autorise les appareils UPnP de votre réseau à parcourir et à lire le contenu d'Jellyfin.",
+ "LabelEnableDlnaServerHelp": "Autorise les appareils UPnP de votre réseau à parcourir et à lire le contenu.",
"LabelEnableHardwareDecodingFor": "Activer le décodage matériel pour :",
"LabelEnableRealtimeMonitor": "Activer la surveillance en temps réel",
"LabelEnableRealtimeMonitorHelp": "Les modifications des fichiers seront traitées immédiatement, sur les systèmes de fichiers qui le permettent.",
@@ -591,7 +591,7 @@
"LabelEvent": "Évènement :",
"LabelEveryXMinutes": "Tous les :",
"LabelExtractChaptersDuringLibraryScan": "Extraire les images des chapitres pendant l'actualisation de la médiathèque",
- "LabelExtractChaptersDuringLibraryScanHelp": "Si l'option est activée, les images des chapitres seront extraites lors de l'importation de vidéos pendant l'actualisation de la médiathèque. Sinon elles seront extraites pendant la tâche planifiée des images des chapitres, permettant de terminer plus rapidement les actualisations de la médiathèque.",
+ "LabelExtractChaptersDuringLibraryScanHelp": "Générer les images des chapitres lors de l'importation de vidéos pendant l'actualisation de la médiathèque. Sinon elles seront extraites pendant la tâche planifiée des images des chapitres, permettant de terminer plus rapidement les actualisations de la médiathèque.",
"LabelFailed": "Échoué",
"LabelFileOrUrl": "Fichier ou URL :",
"LabelFinish": "Terminer",
@@ -599,17 +599,17 @@
"LabelForgotPasswordUsernameHelp": "Saisissez votre nom d'utilisateur, si vous vous en souvenez.",
"LabelFormat": "Format :",
"LabelFriendlyName": "Nom d'affichage :",
- "LabelServerNameHelp": "Ce nom sera utilisé pour identifier le serveur. Sinon le nom d'ordinateur sera utilisé.",
+ "LabelServerNameHelp": "Ce nom sera utilisé pour identifier le serveur. La valeur par défaut est le nom d'ordinateur du serveur.",
"LabelGroupMoviesIntoCollections": "Grouper les films en collections",
"LabelGroupMoviesIntoCollectionsHelp": "Dans l'affichage des listes de films, les films faisant partie d'une collection seront affichés comme un élément groupé.",
"LabelH264Crf": "CRF d'encodage H264 :",
"LabelH264EncodingPreset": "Profil d'encodage H264 :",
"LabelHardwareAccelerationType": "Accélération matérielle :",
- "LabelHardwareAccelerationTypeHelp": "Disponible uniquement sur les systèmes supportés.",
+ "LabelHardwareAccelerationTypeHelp": "Fonctionnalité expérimentale disponible uniquement sur les systèmes supportés.",
"LabelHomeNetworkQuality": "Qualité du réseau local :",
"LabelHomeScreenSectionValue": "Section {0} de l'accueil :",
- "LabelHttpsPort": "Numéro de port https local :",
- "LabelHttpsPortHelp": "Le port TCP que le serveur https d'Jellyfin doit utiliser.",
+ "LabelHttpsPort": "Numéro de port HTTPS local :",
+ "LabelHttpsPortHelp": "Le port TCP que le serveur HTTP de Jellyfin doit utiliser.",
"LabelIconMaxHeight": "Hauteur maximum des icônes :",
"LabelIconMaxHeightHelp": "Résolution maximum des icônes exposée par upnp:icon.",
"LabelIconMaxWidth": "Largeur maximum des icônes :",
@@ -619,25 +619,25 @@
"LabelImageType": "Type d'image :",
"LabelImportOnlyFavoriteChannels": "Restreindre aux chaînes ajoutées aux favoris",
"LabelInNetworkSignInWithEasyPassword": "Activer l'authentification simplifiée dans les réseaux domestiques avec mon code Easy PIN",
- "LabelInNetworkSignInWithEasyPasswordHelp": "Si vous activez cette option, vous pourrez utiliser votre code Easy PIN pour vous connecter aux applications Jellyfin depuis l'intérieur de votre réseau local. Votre mot de passe habituel ne sera requis que depuis l'extérieur. Si le code PIN n'est pas défini, vous n'aurez pas besoin de mot de passe depuis l'intérieur de votre réseau local.",
+ "LabelInNetworkSignInWithEasyPasswordHelp": "Utilisez votre code Easy PIN pour vous connecter aux applications depuis l'intérieur de votre réseau local. Votre mot de passe habituel ne sera requis que depuis l'extérieur. Si le code PIN n'est pas défini, vous n'aurez pas besoin de mot de passe depuis l'intérieur de votre réseau local.",
"LabelInternetQuality": "Qualité d'internet :",
"LabelKeepUpTo": "Garder jusqu'à :",
"LabelKidsCategories": "Catégories jeunesse :",
"LabelKodiMetadataDateFormat": "Format de la date de sortie :",
- "LabelKodiMetadataDateFormatHelp": "Toutes les dates des NFO seront lues et écrites en utilisant ce format.",
- "LabelKodiMetadataEnableExtraThumbs": "Copier les extrafanart dans les extrathumbs",
+ "LabelKodiMetadataDateFormatHelp": "Toutes les dates des fichiers NFO seront lues en utilisant ce format.",
+ "LabelKodiMetadataEnableExtraThumbs": "Copier les extrafanart vers le champ extrathumbs",
"LabelKodiMetadataEnableExtraThumbsHelp": "Pendant le téléchargement, les images peuvent être enregistrées en tant qu'extrafanart et extrathumbs pour améliorer la compatibilité avec le skin Kodi.",
"LabelKodiMetadataEnablePathSubstitution": "Activer la substitution des chemins",
"LabelKodiMetadataEnablePathSubstitutionHelp": "Active la substitution du chemin des images en utilisant les paramètres de substitution des chemins du serveur.",
"LabelKodiMetadataSaveImagePaths": "Enregistrer le chemin des images dans les fichiers NFO",
"LabelKodiMetadataSaveImagePathsHelp": "Ceci est recommandé si les noms des fichiers d'images ne sont pas conformes aux recommandations de Kodi.",
- "LabelKodiMetadataUser": "Enregistrer les données de visionnage utilisateur dans les NFO pour :",
- "LabelKodiMetadataUserHelp": "Activez cette option pour enregistrer les données de lecture dans des fichiers NFO afin que d'autres applications les utilisent.",
+ "LabelKodiMetadataUser": "Enregistrer les données de visionnage utilisateur dans les fichiers NFO pour :",
+ "LabelKodiMetadataUserHelp": "Enregistrer les données de lecture dans des fichiers NFO afin que d'autres applications les utilisent.",
"LabelLanNetworks": "Réseaux LAN :",
"LabelLanguage": "Langue :",
"LabelLineup": "Programmation :",
- "LabelLocalHttpServerPortNumber": "Numéro de port http local :",
- "LabelLocalHttpServerPortNumberHelp": "Le port TCP que le serveur http d'Jellyfin doit utiliser.",
+ "LabelLocalHttpServerPortNumber": "Numéro de port HTTP local :",
+ "LabelLocalHttpServerPortNumberHelp": "Le port TCP que le serveur HTTP de Jellyfin doit utiliser.",
"LabelLockItemToPreventChanges": "Verrouiller cet élément pour éviter de futures modifications",
"LabelLoginDisclaimer": "Avertissement sur la page d'accueil :",
"LabelLoginDisclaimerHelp": "Le slogan sera affiché en bas de la page de connexion.",
@@ -649,7 +649,7 @@
"LabelMaxChromecastBitrate": "Qualité maximum pour Chromecast :",
"LabelMaxParentalRating": "Classification parentale maximale :",
"LabelMaxResumePercentage": "Pourcentage maximum pour reprendre :",
- "LabelMaxResumePercentageHelp": "Les médias sont considérés comme lus si arrêtés après ce temps",
+ "LabelMaxResumePercentageHelp": "Les médias sont considérés comme lus si arrêtés après ce temps.",
"LabelMaxScreenshotsPerItem": "Nombre maximum de captures d'écran par élément :",
"LabelMaxStreamingBitrate": "Qualité maximum de streaming :",
"LabelMaxStreamingBitrateHelp": "Spécifiez le débit maximum lors du streaming.",
@@ -667,9 +667,9 @@
"LabelMethod": "Méthode :",
"LabelMinBackdropDownloadWidth": "Largeur minimum d'image d'arrière-plan à télécharger :",
"LabelMinResumeDuration": "Temps de reprise minimum :",
- "LabelMinResumeDurationHelp": "La plus courte durée de vidéo vous permettant d'enregistrer la progression et d'en reprendre la lecture",
+ "LabelMinResumeDurationHelp": "La plus courte durée de vidéo vous permettant d'enregistrer la progression et d'en reprendre la lecture.",
"LabelMinResumePercentage": "Pourcentage minimum pour reprendre :",
- "LabelMinResumePercentageHelp": "Les médias seront considérés comme non lus si arrêtés avant ce temps",
+ "LabelMinResumePercentageHelp": "Les médias seront considérés comme non lus si arrêtés avant ce temps.",
"LabelMinScreenshotDownloadWidth": "Largeur minimum de capture d'écran à télécharger :",
"LabelModelDescription": "Description de modèle",
"LabelModelName": "Nom de modèle",
@@ -678,7 +678,7 @@
"LabelMonitorUsers": "Surveiller les activités de :",
"LabelMovieCategories": "Catégories de films :",
"LabelMoviePrefix": "Préfixe de film :",
- "LabelMoviePrefixHelp": "Si un préfixe est appliqué aux titres de film, précisez-le ici afin qu'Jellyfin puisse le gérer convenablement.",
+ "LabelMoviePrefixHelp": "Si un préfixe est appliqué aux titres de film, précisez-le ici afin que le serveur puisse le gérer convenablement.",
"LabelMovieRecordingPath": "Chemin d'enregistrement des films (optionnel) :",
"LabelMusicStreamingTranscodingBitrate": "Débit du transcodage de la musique :",
"LabelMusicStreamingTranscodingBitrateHelp": "Spécifiez le débit maximum pendant la diffusion de musique",
@@ -724,10 +724,10 @@
"LabelProtocol": "Protocole :",
"LabelProtocolInfo": "Informations sur le protocole :",
"LabelProtocolInfoHelp": "La valeur qui sera utilisée pour répondre aux requêtes GetProtocolInfo de l'appareil.",
- "LabelPublicHttpPort": "Numéro de port http public :",
- "LabelPublicHttpPortHelp": "Le numéro de port public à mapper sur le port http local.",
- "LabelPublicHttpsPort": "Numéro de port https public :",
- "LabelPublicHttpsPortHelp": "Le numéro de port public à mapper sur le port https local.",
+ "LabelPublicHttpPort": "Numéro de port HTTP public :",
+ "LabelPublicHttpPortHelp": "Le numéro de port public à mapper sur le port HTTP local.",
+ "LabelPublicHttpsPort": "Numéro de port HTTPS public :",
+ "LabelPublicHttpsPortHelp": "Le numéro de port public à mapper sur le port HTTPS local.",
"LabelReadHowYouCanContribute": "Voir comment vous pouvez contribuer.",
"LabelReasonForTranscoding": "Raison du transcodage :",
"LabelRecord": "Enregistrer :",
@@ -752,7 +752,7 @@
"LabelSerialNumber": "Numéro de série",
"LabelSeriesRecordingPath": "Chemin d'enregistrement des séries (optionnel) :",
"LabelServerHost": "Nom d'hôte :",
- "LabelServerHostHelp": "192.168.1.1 ou https://monserveur.com",
+ "LabelServerHostHelp": "192.168.1.1:8096 ou https://monserveur.com",
"LabelSimultaneousConnectionLimit": "Limite de flux simultanée :",
"LabelSkin": "Habillage :",
"LabelSkipBackLength": "Durée des sauts en arrière :",
@@ -792,7 +792,7 @@
"LabelTrackNumber": "Numéro de piste :",
"LabelTranscodingAudioCodec": "Codec audio :",
"LabelTranscodingContainer": "Conteneur :",
- "LabelTranscodingTempPathHelp": "Ce dossier contient les fichiers temporaires utilisés par le transcodeur. Spécifiez un chemin personnalisé ou laissez vide pour utiliser le chemin par défaut dans le dossier de données du serveur.",
+ "LabelTranscodingTempPathHelp": "Spécifiez un chemin personnalisé pour les fichiers transcodés envoyés aux clients. Laissez vide pour utiliser le chemin par défaut du serveur.",
"LabelTranscodingThreadCount": "Nombre de threads de transcodage :",
"LabelTranscodingThreadCountHelp": "Sélectionnez le nombre maximum de threads à utiliser pour le transcodage. La réduction de cette valeur réduira l'utilisation du processeur mais pourrait ne pas suffire pour maintenir une lecture fluide.",
"LabelTranscodingVideoCodec": "Codec vidéo :",
@@ -807,7 +807,7 @@
"LabelUserAgent": "User agent :",
"LabelUserLibrary": "Médiathèque de l'utilisateur :",
"LabelUserLibraryHelp": "Sélectionnez quelle médiathèque afficher sur l'appareil. Laissez vide pour hériter des paramètres par défaut.",
- "LabelUserRemoteClientBitrateLimitHelp": "Cela va écraser les valeurs globales par défaut configurés dans les paramètres de lecture vidéo du serveur.",
+ "LabelUserRemoteClientBitrateLimitHelp": "Écraser les valeurs globales par défaut configurés dans les paramètres de lecture vidéo du serveur.",
"LabelUsername": "Nom d'utilisateur :",
"LabelVaapiDevice": "Appareil VA API :",
"LabelVaapiDeviceHelp": "Ceci est le nœud de rendu qui est utilisé pour l'accélération matérielle.",
@@ -815,9 +815,9 @@
"LabelVersion": "Version :",
"LabelVersionInstalled": "{0} installé(s)",
"LabelVideo": "Vidéo :",
- "LabelXDlnaCap": "Cap X-Dlna :",
+ "LabelXDlnaCap": "Cap X-DLNA :",
"LabelXDlnaCapHelp": "Détermine le contenu de l'élément X_DLNACAP dans l'espace de nom urn:schemas-dlna-org:device-1-0.",
- "LabelXDlnaDoc": "Doc X-Dlna :",
+ "LabelXDlnaDoc": "Doc X-DLNA :",
"LabelXDlnaDocHelp": "Détermine le contenu de l'élément X_DLNADOC dans l'espace de nom urn:schemas-dlna-org:device-1-0.",
"LabelYear": "Année :",
"LabelYourFirstName": "Votre prénom :",
@@ -829,7 +829,7 @@
"Large": "Grand",
"LatestFromLibrary": "{0}, ajouts récents",
"LearnHowYouCanContribute": "Voir comment vous pouvez contribuer.",
- "LibraryAccessHelp": "Sélectionnez les dossiers multimédia à partager avec cet utilisateur. Les administrateurs pourront modifier tous les dossiers en utilisant le gestionnaire de métadonnées.",
+ "LibraryAccessHelp": "Sélectionnez les bibliothèques à partager avec cet utilisateur. Les administrateurs pourront modifier tous les dossiers en utilisant le gestionnaire de métadonnées.",
"Like": "J'aime",
"LinksValue": "Liens: {0}",
"List": "Liste",
@@ -876,13 +876,13 @@
"MessageConfirmRemoveMediaLocation": "Voulez-vous vraiment supprimer cet emplacement ?",
"MessageConfirmRestart": "Voulez-vous vraiment redémarrer le serveur Jellyfin ?",
"MessageConfirmRevokeApiKey": "Voulez-vous vraiment révoquer cette clé API ? La connexion de l'application au serveur Jellyfin sera brutalement interrompue.",
- "MessageConfirmShutdown": "Voulez-vous vraiment éteindre le serveur Jellyfin ?",
+ "MessageConfirmShutdown": "Voulez-vous vraiment éteindre le serveur ?",
"MessageContactAdminToResetPassword": "Veuillez contacter votre administrateur système pour réinitialiser votre mot de passe.",
"MessageCreateAccountAt": "Créer un compte sur {0}",
"MessageDeleteTaskTrigger": "Voulez-vous vraiment supprimer ce déclencheur de tâche ?",
"MessageDirectoryPickerBSDInstruction": "Sur BSD, vous devrez peut-être configurer le stockage de votre jail FreeNAS pour autoriser Jellyfin à y accéder.",
"MessageDirectoryPickerInstruction": "Les chemins réseaux peuvent être saisis manuellement dans le cas où l'utilisation du bouton Réseau ne parvient pas à localiser vos appareils. Par exemple, {0} ou {1}.",
- "MessageDirectoryPickerLinuxInstruction": "Pour Linux sur Arch Linux, CentOS, Debian, Fedora, OpenSuse ou Ubuntu, vous devez au moins autoriser l'accès en lecture à vos répertoires de stockage pour l'utilisateur Jellyfin .",
+ "MessageDirectoryPickerLinuxInstruction": "Pour Linux sur Arch Linux, CentOS, Debian, Fedora, OpenSuse ou Ubuntu, vous devez au moins autoriser l'accès en lecture à vos répertoires de stockage pour l'utilisateur de service .",
"MessageDownloadQueued": "Téléchargement mis en file d'attente.",
"MessageEnablingOptionLongerScans": "Activer cette option peut accroître la durée d'actualisation de la médiathèque.",
"MessageFileReadError": "Une erreur est survenue lors de la lecture du fichier. Veuillez réessayer.",
@@ -893,21 +893,21 @@
"MessageInvalidUser": "Nom d'utilisateur ou mot de passe incorrect. Réessayez.",
"MessageItemSaved": "Élément enregistré.",
"MessageItemsAdded": "Éléments ajoutés.",
- "MessageLeaveEmptyToInherit": "Laisser vide pour hériter des paramètres de l'élément parent, ou de la valeur globale par défaut.",
+ "MessageLeaveEmptyToInherit": "Laisser vide pour hériter des paramètres de l'élément parent ou de la valeur globale par défaut.",
"MessageNoAvailablePlugins": "Aucune extension disponible.",
"MessageNoMovieSuggestionsAvailable": "Aucune suggestion de film n'est actuellement disponible. Commencez à regarder et à noter vos films pour avoir des suggestions.",
"MessageNoPluginsInstalled": "Vous n'avez aucune extension installée.",
"MessageNoTrailersFound": "Aucune bande-annonce trouvée. Installez la chaîne Trailers pour améliorer votre expérience, par l'ajout d'une médiathèque de bandes-annonces disponibles sur Internet.",
"MessageNothingHere": "Il n'y a rien ici.",
"MessagePasswordResetForUsers": "Les mot de passes de ces utilisateurs ont été réinitialisés. Ils peuvent maintenant se connecter avec le code PIN utilisé pour la réinitialisation.",
- "MessagePlayAccessRestricted": "La lecture de ce contenu est actuellement restreinte. Contactez l'administrateur de votre serveur Jellyfin pour plus d'informations.",
+ "MessagePlayAccessRestricted": "La lecture de ce contenu est actuellement restreinte. Contactez l'administrateur de votre serveur pour plus d'informations.",
"MessagePleaseEnsureInternetMetadata": "Veuillez vous assurer que le téléchargement des métadonnées depuis Internet est activé.",
"MessagePleaseWait": "Veuillez patienter. Ceci peut prendre quelques minutes.",
"MessagePluginConfigurationRequiresLocalAccess": "Pour configurer cette extension, veuillez vous connecter directement à votre serveur local.",
"MessagePluginInstallDisclaimer": "Les extensions développées par les membres de la communauté Jellyfin sont une excellente manière d'améliorer votre expérience Jellyfin avec de nouvelles fonctionnalités. Avant toute installation, veuillez prendre connaissance de l'impact qu'elles peuvent avoir sur le serveur Jellyfin, comme l'augmentation de la durée d'actualisation de la médiathèque, de nouvelles tâches de fond, ou un système moins stable.",
"MessageReenableUser": "Voir ci-dessous pour le réactiver",
"MessageSettingsSaved": "Paramètres enregistrés.",
- "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Ces emplacements de média vont être supprimés de votre médiathèque Jellyfin :",
+ "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Ces emplacements de média vont être supprimés de votre médiathèque :",
"MessageUnableToConnectToServer": "Nous sommes dans l'impossibilité de nous connecter au serveur sélectionné. Veuillez vérifier qu'il est opérationnel et réessayez.",
"MessageUnsetContentHelp": "Le contenu sera affiché sous forme de dossiers. Pour un résultat optimal, utilisez le gestionnaire de métadonnées pour définir le type de contenu des sous-dossiers.",
"MessageYouHaveVersionInstalled": "Actuellement , vous avez la version {0} installée.",
@@ -916,13 +916,13 @@
"MetadataSettingChangeHelp": "Les modifications des paramètres des métadonnées auront une incidence sur le nouveau contenu ajouté. Pour actualiser le contenu existant, ouvrez l'écran des détails et cliquez sur le bouton Actualiser, ou effectuez des actualisations en masse en utilisant le gestionnaire de métadonnées.",
"MinutesAfter": "minutes après",
"MinutesBefore": "minutes avant",
- "Mobile": "Mobile / Tablette",
+ "Mobile": "Mobile",
"Monday": "Lundi",
"MoreFromValue": "Plus de {0}",
"MoreUsersCanBeAddedLater": "D'autres utilisateurs pourront être ajoutés ultérieurement à partir du tableau de bord.",
"MoveLeft": "Déplacer à gauche",
"MoveRight": "Déplacer à droite",
- "MovieLibraryHelp": "Consultez le {0}guide Jellyfin pour nommer les films{1}.",
+ "MovieLibraryHelp": "Consultez le {0}guide de nommage des films{1}.",
"Movies": "Films",
"Mute": "Couper le son",
"MySubtitles": "Mes sous-titres",
@@ -949,7 +949,7 @@
"OneChannel": "Une chaîne",
"OnlyForcedSubtitles": "Seulement les sous-titres forcés",
"OnlyForcedSubtitlesHelp": "Seuls les sous-titres marqués comme forcés seront chargés.",
- "OnlyImageFormats": "Seulement les formats image (VOBSUB, PGS, SUB/IDX etc)",
+ "OnlyImageFormats": "Seulement les formats image (VOBSUB, PGS, SUB, etc)",
"OptionAdminUsers": "Administrateurs",
"OptionAlbumArtist": "Artiste de l'album",
"OptionAllUsers": "Tous les utilisateurs",
@@ -995,7 +995,7 @@
"OptionDisableUserHelp": "Si désactivé, le serveur n'autorisera pas de connexion de cet utilisateur. Les connexions existantes seront interrompues.",
"OptionDislikes": "Pas aimés",
"OptionDisplayFolderView": "Afficher une vue de dossiers pour montrer les dossiers multimédia en intégralité",
- "OptionDisplayFolderViewHelp": "Les applications Jellyfin vont afficher une catégorie Dossiers à côté de votre médiathèque. C'est utile si vous souhaitez avoir une vue complète des dossiers.",
+ "OptionDisplayFolderViewHelp": "Afficher les dossier au côté de votre médiathèque. Cela peut être utile si vous souhaitez avoir une vue complète des dossiers.",
"OptionDownloadBackImage": "Dos",
"OptionDownloadBannerImage": "Bannière",
"OptionDownloadBoxImage": "Boîtier",
@@ -1030,8 +1030,8 @@
"OptionHasTrailer": "Bande-annonce",
"OptionHideUser": "Ne pas afficher cet utilisateur dans les écrans de connexion",
"OptionHideUserFromLoginHelp": "Recommandé pour les comptes administrateurs privés ou cachés. L'utilisateur devra s'authentifier manuellement en saisissant son nom d'utilisateur et son mot de passe.",
- "OptionHlsSegmentedSubtitles": "Sous-titres segmentés HIs",
- "OptionHomeVideos": "Vidéos et photos personnelles",
+ "OptionHlsSegmentedSubtitles": "Sous-titres segmentés HLS",
+ "OptionHomeVideos": "Photos",
"OptionIgnoreTranscodeByteRangeRequests": "Ignore les requêtes de transcodage de plage d'octets",
"OptionIgnoreTranscodeByteRangeRequestsHelp": "Si l'option est activée, ces requêtes seront honorées mais l'en-tête de plage d'octets sera ignoré.",
"OptionImdbRating": "Note IMDb",
@@ -1206,7 +1206,7 @@
"SortName": "Trier par nom",
"StopRecording": "Arrêter l'enregistrement",
"SubtitleAppearanceSettingsAlsoPassedToCastDevices": "Ces paramètres s'appliquent également à toute lecture Chromecast démarrée par cet appareil.",
- "SubtitleAppearanceSettingsDisclaimer": "Ces paramètres ne s'appliqueront pas aux sous-titres graphiques (PGS, DVD etc) ou aux sous-titres qui ont leurs propres styles incorporés (ASS/SSA).",
+ "SubtitleAppearanceSettingsDisclaimer": "Ces paramètres ne s'appliqueront pas aux sous-titres graphiques (PGS, DVD etc) ou aux sous-titres ASS/SSA qui incorporent leurs propres styles.",
"SubtitleDownloadersHelp": "Activer et ranger vos outils de téléchargement de sous-titres favoris par ordre de priorité.",
"Subtitles": "Sous-titres",
"Sunday": "Dimanche",
@@ -1272,7 +1272,7 @@
"Trailers": "Bandes-annonces",
"Transcoding": "Transcodage",
"Tuesday": "Mardi",
- "TvLibraryHelp": "Consultez le {0}guide Jellyfin pour nommer les émissions{1}.",
+ "TvLibraryHelp": "Consultez le {0}guide de nommage des émissions{1}.",
"Uniform": "Uniforme",
"UninstallPluginConfirmation": "Êtes-vous sûr de vouloir désinstaller {0} ?",
"UninstallPluginHeader": "Désinstaller Plug-in",
@@ -1281,8 +1281,8 @@
"Unrated": "Non noté",
"Up": "Haut",
"Upload": "Envoyer",
- "UserAgentHelp": "Fournissez un en-tête http user agent personnalisé, si nécessaire.",
- "UserProfilesIntro": "Jellyfin supporte nativement les profils utilisateurs, permettant à chaque utilisateur d'avoir ses propres préférences d'affichage, sauvegarde de l'état de lecture et contrôle parental.",
+ "UserAgentHelp": "Fournissez un en-tête HTTP user-agent personnalisé.",
+ "UserProfilesIntro": "Jellyfin supporte les profils utilisateurs avec des paramètres granulaires d'affichage, de sauvegarde de l'état de lecture et de contrôle parental.",
"ValueAudioCodec": "Codec Audio : {0}",
"ValueCodec": "Codec : {0}",
"ValueConditions": "Conditions : {0}",
@@ -1312,7 +1312,7 @@
"Wednesday": "Mercredi",
"WelcomeToProject": "Bienvenue dans Jellyfin !",
"Whitelist": "Liste blanche",
- "WizardCompleted": "C'est tout ce dont nous avons besoin pour l'instant. Jellyfin a commencé à collecter les informations de votre médiathèque. Jetez un coup d'œil à quelques-unes de nos applications, puis cliquez sur
Terminer pour consulter le
Tableau de bord du serveur .",
+ "WizardCompleted": "C'est tout ce dont nous avons besoin pour l'instant. Jellyfin a commencé à collecter les informations de votre médiathèque. Jetez un coup d'œil à quelques-unes de nos applications, puis cliquez sur
Terminer pour consulter le
Tableau de bord .",
"Writer": "Scénariste",
"XmlDocumentAttributeListHelp": "Ces attributs sont appliqués à l'élément racine de chaque réponse XML.",
"XmlTvKidsCategoriesHelp": "Les programmes avec ces catégories seront affichés en tant que programmes jeunesse. S'il y en a plusieurs, séparez-les avec '|'.",
@@ -1344,7 +1344,7 @@
"Images": "Images",
"LabelAudio": "Audio :",
"LabelVersionNumber": "Version {0}",
- "LeaveBlankToNotSetAPassword": "Facultatif - laissez vide pour ne pas définir de mot de passe",
+ "LeaveBlankToNotSetAPassword": "Laissez vide pour ne pas définir de mot de passe.",
"Logo": "Logo",
"MediaInfoCodec": "Codec",
"Menu": "Menu",
@@ -1399,14 +1399,14 @@
"MediaInfoStreamTypeData": "Données",
"MediaInfoStreamTypeSubtitle": "Sous-titres",
"MediaInfoStreamTypeVideo": "Video",
- "AuthProviderHelp": "Sélectionner un fournisseur d'authentification pour authentifier le mot de passe de cet utilisateur",
+ "AuthProviderHelp": "Sélectionner un fournisseur d'authentification pour authentifier le mot de passe de cet utilisateur.",
"PasswordResetProviderHelp": "Choisissez un Fournisseur de réinitialisation de mot de passe à utiliser lorsqu'un utilisateur demande la réinitialisation de son mot de passe",
"HeaderHome": "Accueil",
"LabelUserLoginAttemptsBeforeLockout": "Tentatives de connexion erronées avant blocage de l'utilisateur :",
"DashboardOperatingSystem": "Système d'Exploitation: {0}",
"DashboardArchitecture": "Architecture: {0}",
- "LaunchWebAppOnStartup": "Démarrer Jellyfin dans mon navigateur quand le serveur Jellyfin est lancé",
- "LaunchWebAppOnStartupHelp": "Cette fonction ouvrira l'application Jellyfin dans votre navigateur internet quand le serveur Jellyfin sera démarré la première fois. Cela ne se produira pas quand le serveur redémarre.",
+ "LaunchWebAppOnStartup": "Démarrer l'interface web dans mon navigateur quand le serveur est démarré",
+ "LaunchWebAppOnStartupHelp": "Ouvrir l'application dans votre navigateur internet quand le serveur est démarré pour la première fois. Cela ne se produira pas quand le serveur redémarre.",
"MediaInfoStreamTypeEmbeddedImage": "Image intégrée",
"MessageNoCollectionsAvailable": "Les collections vous permettent de profiter de groupes personnalisés de Films, de Séries et d'Albums. Cliquer sur le bouton + pour démarrer la création de collections.",
"MessageNoServersAvailable": "Aucun serveur n'a été trouvé en utilisant la recherche automatique de serveur.",
@@ -1423,9 +1423,32 @@
"MusicAlbum": "Album de musique",
"MusicArtist": "Artiste musical",
"MusicVideo": "Clip musical",
- "OptionLoginAttemptsBeforeLockoutHelp": "0 signifie la règle par défaut soit 5 pour les admin et 3 pour les autres. -1 désactive le blocage",
+ "OptionLoginAttemptsBeforeLockoutHelp": "Une valeur de 0 signifie la règle par défaut soit 3 essais pour les utilisateurs et 5 pour les administrateurs. Une valeur à -1 désactive le blocage.",
"TabNetworking": "Réseau",
"PlaybackData": "Données de lecture",
"OptionThumbCard": "Vignette (cadre)",
- "SubtitleOffset": "Décalage des sous-titres"
+ "SubtitleOffset": "Décalage des sous-titres",
+ "ButtonAddImage": "Ajouter une image",
+ "LabelSize": "Taille :",
+ "LabelFolder": "Répertoire :",
+ "LabelBitrate": "Débit :",
+ "LabelAudioBitrate": "Débit audio :",
+ "LabelAudioBitDepth": "Profondeur de bit audio :",
+ "MusicLibraryHelp": "Consultez le {0}guide de nommage de musique{1}.",
+ "MoreMediaInfo": "Informations du Média",
+ "LabelVideoCodec": "Codec vidéo :",
+ "LabelVideoBitrate": "Débit vidéo :",
+ "LabelTranscodingProgress": "Progression du transcodage :",
+ "LabelTranscodingFramerate": "Taux de rafraîchissement du transcodage :",
+ "LabelPleaseRestart": "Les changements prendront effet lors d'un rechargement manuel du client web.",
+ "LabelPlayMethod": "Méthode de lecture :",
+ "LabelPlayer": "Lecteur :",
+ "LabelBaseUrl": "Adresse d'origine :",
+ "LabelAudioSampleRate": "Taux d’échantillonnage audio :",
+ "LabelAudioCodec": "Codec audio :",
+ "LabelAudioChannels": "Canaux audio :",
+ "HeaderFavoriteBooks": "Livres Favoris",
+ "FetchingData": "Récupération de données additionnelles",
+ "CopyStreamURLSuccess": "URL copié avec succès.",
+ "CopyStreamURL": "Copier l'URL du flux"
}
diff --git a/src/strings/he.json b/src/strings/he.json
index bf17cc4e7f..15b1e8df32 100644
--- a/src/strings/he.json
+++ b/src/strings/he.json
@@ -509,5 +509,31 @@
"Writer": "כותב",
"Albums": "אלבומים",
"Artists": "אמנים",
- "Books": "ספרים"
+ "Books": "ספרים",
+ "Absolute": "מוחלט",
+ "AccessRestrictedTryAgainLater": "הגישה כרגע מוגבלת. אנא נסה שוב מאוחר יותר.",
+ "AddedOnValue": "נוסף {0}",
+ "Blacklist": "רשימה שחורה",
+ "Banner": "באנר",
+ "Auto": "אוטומטי",
+ "Art": "אומנות",
+ "AnyLanguage": "כל שפה",
+ "AllowMediaConversion": "אפשר המרת מדיה",
+ "AllLanguages": "כל השפות",
+ "Alerts": "התראות",
+ "Box": "קופסה",
+ "BirthPlaceValue": "מיקום לידה: {0}",
+ "BirthDateValue": "תאריך לידה: {0}",
+ "Backdrop": "רקע",
+ "AuthProviderHelp": "בחר ספק אימות שישמש לאימות הסיסמה של משתמש זה.",
+ "Audio": "שמע",
+ "AspectRatio": "יחס גובה-רוחב",
+ "AlwaysPlaySubtitlesHelp": "כתוביות תואמות להעדפת שפה יטענו ללא קשר לשפת השמע.",
+ "AlwaysPlaySubtitles": "הפעל כתוביות תמיד",
+ "AllowRemoteAccessHelp": "אם לא מסומן, כל החיבורים המרוחקים ייחסמו.",
+ "AllowRemoteAccess": "אפשר חיבור מרוחק לשרת Jellyfin זה.",
+ "AllowMediaConversionHelp": "אפשר או חסום גישה להמרת מדיה.",
+ "Aired": "שודר",
+ "AirDate": "תאריך שידור",
+ "Yesterday": "אתמול"
}
diff --git a/src/strings/hu.json b/src/strings/hu.json
index f2b6e1220f..ea50446071 100644
--- a/src/strings/hu.json
+++ b/src/strings/hu.json
@@ -34,7 +34,7 @@
"ButtonEdit": "Szerkesztés",
"ButtonEditImages": "Képek szerkesztése",
"ButtonFilter": "Szűrő",
- "ButtonForgotPassword": "Elfelejtett jelszó",
+ "ButtonForgotPassword": "Elfelejtett Jelszó",
"ButtonGotIt": "Értettem",
"ButtonHelp": "Segítség",
"ButtonHome": "Kezdőlap",
@@ -117,7 +117,7 @@
"FolderTypeMovies": "Filmek",
"FolderTypeMusic": "Zenék",
"FolderTypeMusicVideos": "Zenei Videók",
- "FolderTypeTvShows": "Műsorok",
+ "FolderTypeTvShows": "TV Műsorok",
"FolderTypeUnset": "Vegyes Tartalom",
"Folders": "Könyvtárak",
"Friday": "Péntek",
@@ -267,7 +267,7 @@
"LabelGroupMoviesIntoCollections": "Filmek csoportosítása gyűjteményekbe",
"LabelH264EncodingPreset": "H264 enkóder beállítások:",
"LabelHardwareAccelerationType": "Hardveres gyorsítás:",
- "LabelHardwareAccelerationTypeHelp": "Csak támogatott rendszereken érhető el.",
+ "LabelHardwareAccelerationTypeHelp": "Ez egy kísérleti szolgáltatás, amely csak a támogatott rendszereken érhető el.",
"LabelHomeScreenSectionValue": "Kezdőképernyő blokk {0}:",
"LabelImageType": "Kép típusa:",
"LabelKodiMetadataDateFormat": "Megjelenési dátum formátuma:",
@@ -312,7 +312,7 @@
"LabelSelectUsers": "Felhasználó kiválasztása:",
"LabelSelectVersionToInstall": "Válaszd ki a telepíteni kívánt verziót:",
"LabelSendNotificationToUsers": "Értesítés küldése a következőknek:",
- "LabelServerHostHelp": "192.168.1.100 vagy https://myserver.com",
+ "LabelServerHostHelp": "192.168.1.100:8096 vagy https://myserver.com",
"LabelSortBy": "Rendezés:",
"LabelSortOrder": "Sorrend:",
"LabelSortTitle": "ABC szerinti cím:",
@@ -362,7 +362,7 @@
"MediaInfoSampleRate": "Mintavételi ráta",
"MessageAlreadyInstalled": "Ez a verzió már telepítve van.",
"MessageConfirmRestart": "Biztosan újra szeretnéd indítani a Jellyfin Szervert?",
- "MessageConfirmShutdown": "Biztosan le akarod állítani a Jellyfin Szervert?",
+ "MessageConfirmShutdown": "Biztosan le akarod állítani a Szervert?",
"MessageItemsAdded": "Elem hozzáadva.",
"MessageNoPluginsInstalled": "Nincs bővítmény telepítve.",
"MessageNothingHere": "Nincs itt semmi.",
@@ -372,7 +372,7 @@
"MetadataManager": "Metaadat Manager",
"Monday": "Hétfő",
"MoreFromValue": "Még több {0}",
- "MoreUsersCanBeAddedLater": "Több felhasználót a vezérlőpultban adhatsz hozzá.",
+ "MoreUsersCanBeAddedLater": "Később további felhasználókat vehetsz fel a Vezérlőpultban.",
"Movies": "Filmek",
"Mute": "Némít",
"MySubtitles": "Feliratok",
@@ -421,7 +421,7 @@
"OptionHasThemeVideo": "Filmzene",
"OptionHasTrailer": "Filmelőzetes",
"OptionHideUser": "Felhasználó elrejtése a bejelentkezési képernyőn",
- "OptionHomeVideos": "Házi videók és fényképek",
+ "OptionHomeVideos": "Fényképek",
"OptionImdbRating": "IMDb értékelés",
"OptionLikes": "Kedveltek",
"OptionMissingEpisode": "Hiányzó Epizódok",
@@ -527,7 +527,7 @@
"TabMusicVideos": "Zenei Videók",
"TabMyPlugins": "Telepített bővítmények",
"TabNetworks": "Csatornák",
- "TabNfoSettings": "NFO beállítások",
+ "TabNfoSettings": "NFO Beállítások",
"TabNotifications": "Értesítések",
"TabOther": "Egyéb",
"TabParentalControl": "Szülői Felügyelet",
@@ -607,7 +607,7 @@
"AlwaysPlaySubtitlesHelp": "A nyelvi beállításoknak megfelelő feliratok az audió nyelvétől függetlenül kerülnek betöltésre.",
"Artists": "Előadók",
"Blacklist": "Feketelista",
- "BookLibraryHelp": "Az audió- és szövegkönyvek támogatottak. Nézd meg a {0} Jellyfin Könyvelnevezési útmutatót {1}.",
+ "BookLibraryHelp": "Az audió- és szövegkönyvek támogatottak. Nézd meg a {0} könyvelnevezési útmutatót {1}.",
"BrowsePluginCatalogMessage": "Böngéssz a Bővítmény katalógusunkban a rendelkezésre álló bővítmények megtekintéséhez.",
"AddItemToCollectionHelp": "Adj elemeket a gyűjteményekhez, ehhez keresed meg őket, majd kattints jobb egérgombbal, vagy kattints a menüre és add hozzá a gyűjteményhez.",
"AllowedRemoteAddressesHelp": "Vesszővel válaszd el az IP-címek vagy IP / netmask címek listáját annak a hálózatnak amelyből távolról csatlakozhatnak. Ha üresen marad, az összes távoli cím megengedett.",
@@ -689,8 +689,8 @@
"ErrorMessageStartHourGreaterThanEnd": "A befejezési időnek nagyobbnak kell lennie mint a kezdési idő.",
"ErrorSavingTvProvider": "Hiba történt a TV szolgáltató mentésekor. Kérlek győződj meg róla, hogy elérhető és próbálkozz meg újra.",
"EveryNDays": "Minden {0} nap",
- "ExtraLarge": "Extra nagy",
- "ExtractChapterImagesHelp": "A fejezetképek kivonása lehetővé teszi, hogy a Jellyfin alkalmazások grafikus jelenetválasztási menüket jelenítsenek meg. A folyamat lehet lassú, CPU intenzív és több gigabájt területet igényelhet. A kivonás akkor történik, amikor új videók kerülnek a Médiatárba, valamint egy éjszakai ütemezett feladatként. Az ütemezés konfigurálható az Ütemezett Feladatok menüpontban. Nem ajánlott ezt a feladatot a csúcshasználati órákban futtatni.",
+ "ExtraLarge": "Extra NAGY",
+ "ExtractChapterImagesHelp": "A fejezetképek kivonása lehetővé teszi, hogy az alkalmazások grafikus jelenetválasztási menüket jelenítsenek meg. A folyamat lehet lassú, erőforrás igényes, és több gigabájt területet igényelhet. A kivonás akkor történik, amikor új videók kerülnek a Médiatárba, valamint egy éjszakai ütemezett feladatként. Az ütemezés konfigurálható az Ütemezett Feladatok menüpontban. Nem ajánlott ezt a feladatot a csúcshasználati órákban futtatni.",
"Extras": "Extrák",
"FFmpegSavePathNotFound": "Nem található az FFmpeg a megadott útvonalon. FFprobe is szükséges, és ugyanabban a mappában kell lennie. Ezek az összetevők általában ugyanabban a csomagban találhatók. Kérlek ellenőrizd a megadott útvonalat és próbáld meg újra.",
"File": "Fájl",
@@ -710,7 +710,7 @@
"HeaderActivity": "Tevékenység",
"HeaderAdditionalParts": "További részek",
"HeaderAdmin": "Adminisztrátor",
- "HeaderAlbumArtists": "Album Előadók",
+ "HeaderAlbumArtists": "Album előadók",
"HeaderAlert": "Figyelem",
"HeaderAllowMediaDeletionFrom": "Média törlés engedélyezése",
"HeaderApiKey": "API Kulcs",
@@ -845,7 +845,7 @@
"LabelBindToLocalNetworkAddressHelp": "Opcionális. A helyi IP cím felülbírálása a http szerverhez való csatlakozáshoz. Ha üres marad, a szerver minden elérhető címhez kötődik. Az érték megváltoztatásához a Jellyfin Szerver újraindítása szükséges.",
"LabelBirthDate": "Születési dátum:",
"LabelBlastMessageInterval": "Élő üzenetintervallum (másodperc)",
- "LabelBlastMessageIntervalHelp": "Meghatározza az időtartamot másodpercben a szerver üzenetei között.",
+ "LabelBlastMessageIntervalHelp": "Meghatározza másodpercben az üzenetek közötti időtartamot.",
"LabelBlockContentWithTags": "Blokkolja a címkével ellátott elemeket:",
"LabelCache": "Gyorsítótár:",
"LabelCachePathHelp": "Adj meg egy egyéni helyet a szerver gyorsítótár fájljainak, például a képeknek. Hagyd üresen az alapértelmezett beállításához.",
@@ -879,44 +879,44 @@
"LabelEnableDlnaDebugLogging": "DLNA hibakeresési naplózás engedélyezése",
"LabelEnableDlnaDebugLoggingHelp": "Ez nagy naplófájlokat hoz létre és csak hibaelhárítás céljából használható.",
"LabelEnableDlnaPlayTo": "DLNA Play To engedélyezése",
- "LabelEnableDlnaPlayToHelp": "A Jellyfin képes érzékelni a hálózaton belüli eszközöket, és képes a távoli vezérlésükre.",
- "LabelEnableDlnaServer": "Dlna szerver engedélyezése",
- "LabelEnableDlnaServerHelp": "Lehetővé teszi a hálózaton található UPnP eszközöknek, hogy a Jellyfin tartalmát böngésszék és lejátszák.",
+ "LabelEnableDlnaPlayToHelp": "Felismerheti a hálózaton belüli eszközöket, és lehetővé teszi azok távvezérlését.",
+ "LabelEnableDlnaServer": "DLNA szerver engedélyezése",
+ "LabelEnableDlnaServerHelp": "Lehetővé teszi a hálózaton található UPnP eszközöknek, hogy böngésszenek és lejátszanak tartalmat.",
"LabelEnableSingleImageInDidlLimit": "Korlátozás egyetlen beágyazott képre",
"LabelEnableSingleImageInDidlLimitHelp": "Néhány eszköz nem jeleníti meg megfelelően, ha több kép van beágyazva a Didl-be.",
"LabelEndDate": "Befejezés dátuma:",
"LabelExtractChaptersDuringLibraryScan": "Fejezet képek készítése a könyvtár beolvasása során",
- "LabelExtractChaptersDuringLibraryScanHelp": "Ha engedélyezve van, a fejezetképek elkészítése a könyvtár beolvasása során történik meg. Ha le van tiltva, akkor az elkészítés az Ütemezett feladatokban meghatározott időben készül el, ami lehetővé teszi a könyvtárbeolvasás gyorsítását.",
+ "LabelExtractChaptersDuringLibraryScanHelp": "A fejezetképek elkészítése a könyvtár beolvasása során történik meg. Ellenkező esetben az elkészítés az Ütemezett feladatokban meghatározott időben készül el, ami lehetővé teszi a könyvtárbeolvasás gyorsítását.",
"LabelFailed": "Sikertelen",
"LabelFileOrUrl": "Fájl vagy URL:",
"LabelFont": "Betűtípus:",
"LabelFormat": "Formátum:",
"LabelFriendlyName": "Könnyen megjegyezhető név:",
- "LabelServerNameHelp": "Ez a név kerül a Szerver azonosítására. Ha üresen marad, a számítógép neve kerül felhasználásra.",
+ "LabelServerNameHelp": "Ez a név kerül a Szerver azonosítására és alapértelmezetten a számítógép neve kerül felhasználásra.",
"LabelGroupMoviesIntoCollectionsHelp": "A filmlisták megjelenítésekor a gyűjteményhez tartozó filmek egy csoportos elemként jelennek meg.",
"LabelH264Crf": "H264 enkóder CRF:",
"LabelHomeNetworkQuality": "Otthoni hálózat minősége:",
- "LabelHttpsPort": "Helyi https port száma:",
+ "LabelHttpsPort": "Helyi HTTPS port száma:",
"LabelImageFetchersHelp": "Engedélyezd és rangsorold az előnyben részesített képletöltőket prioritásuk sorrendjében.",
"LabelImportOnlyFavoriteChannels": "Csak a kedvencként megjelölt csatornákra korlátozza",
"LabelInNetworkSignInWithEasyPassword": "Engedélyezze a hálózaton belüli bejelentkezést az egyszerű PIN kóddal",
- "LabelInNetworkSignInWithEasyPasswordHelp": "Ha engedélyezve van, akkor az egyszerű PIN kódod segítségével beléphetsz a Jellyfin alkalmazásokba az otthoni hálózaton belül. A szokásos jelszót csak akkor kell használni, ha az otthoni hálózaton kívül vagy. Ha a PIN kód üres, akkor nem lesz szükség jelszóra az otthoni hálózaton belül.",
+ "LabelInNetworkSignInWithEasyPasswordHelp": "Az egyszerű PIN kódod segítségével beléphetsz az alkalmazásokból az otthoni hálózaton belül. A szokásos jelszót csak akkor kell használni, ha az otthoni hálózaton kívül vagy. Ha a PIN kód üres, akkor nem lesz szükség jelszóra az otthoni hálózaton belül.",
"LabelInternetQuality": "Internet minősége:",
"LabelKidsCategories": "Gyermek kategóriák:",
- "LabelKodiMetadataDateFormatHelp": "Az nfo-n belüli összes dátum ezzel a formátummal lesz írva és olvasva.",
- "LabelKodiMetadataEnableExtraThumbs": "Másolja az extrafanartot extrathumbs-ba",
+ "LabelKodiMetadataDateFormatHelp": "Az NFO-n belüli összes dátum ezzel a formátummal lesz kezelve.",
+ "LabelKodiMetadataEnableExtraThumbs": "Másolja az extrafanartot extrathumbs mezőbe",
"LabelKodiMetadataEnableExtraThumbsHelp": "A képek letöltésekor mind az extrafanart, mind az extrathumbs-ba menthetőek a maximális Kodi skin kompatibilitáshoz.",
"LabelKodiMetadataEnablePathSubstitution": "Útvonal helyettesítés engedélyezése",
"LabelKodiMetadataEnablePathSubstitutionHelp": "Lehetővé teszi a képútvonalak helyettesítését a szerver útvonal helyettesítési beállításaival.",
"LabelKodiMetadataSaveImagePaths": "A képek útvonalának mentése az nfo fájlokban",
"LabelKodiMetadataSaveImagePathsHelp": "Ez akkor ajánlott, ha olyan képfájlnevek vannak amelyek nem felelnek meg a Kodi irányelveinek.",
"LabelLanNetworks": "LAN hálózatok:",
- "LabelLocalHttpServerPortNumber": "Helyi http port száma:",
+ "LabelLocalHttpServerPortNumber": "Helyi HTTP port száma:",
"LabelLockItemToPreventChanges": "Az elem zárolása a jövőbeni változások elkerülése érdekében",
"LabelLoginDisclaimer": "Bejelentkezési nyilatkozat:",
- "LabelLoginDisclaimerHelp": "Ez a bejelentkezési oldal alján jelenik meg.",
+ "LabelLoginDisclaimerHelp": "Ez az üzenet a bejelentkezési oldal alján jelenik meg.",
"LabelManufacturer": "Gyártó",
- "LabelManufacturerUrl": "Gyártó url címe",
+ "LabelManufacturerUrl": "Gyártó URL címe",
"LabelMatchType": "Egyezés típusa:",
"LabelMaxBackdropsPerItem": "A hátterek maximális száma elemenként:",
"LabelMaxChromecastBitrate": "Chromecast streaming minősége:",
@@ -931,7 +931,7 @@
"LabelModelUrl": "Modell URL",
"LabelMovieCategories": "Film kategóriák:",
"LabelMoviePrefix": "Film előtag:",
- "LabelMoviePrefixHelp": "Ha a filmcímekhez előtagot használsz írd be ide, hogy Jellyfin megfelelően kezelje.",
+ "LabelMoviePrefixHelp": "Ha a filmcímekhez előtagot használsz, írd be ide, hogy a szerver megfelelően kezelje.",
"LabelMovieRecordingPath": "Filmfelvételi útvonal (opcionális):",
"LabelMusicStreamingTranscodingBitrate": "Zene átkódolási bitráta:",
"LabelNewName": "Új név:",
@@ -947,10 +947,10 @@
"LabelProtocol": "Protokoll:",
"LabelProtocolInfo": "Protokoll adatok:",
"LabelProtocolInfoHelp": "Az az érték, amelyet a készülék a GetProtocolInfo kérésekre válaszol.",
- "LabelPublicHttpPort": "Nyilvános http portszám:",
- "LabelPublicHttpPortHelp": "A nyilvános port száma, amelyet a helyi http portra kell átirányítani.",
- "LabelPublicHttpsPort": "Nyilvános https port száma:",
- "LabelPublicHttpsPortHelp": "A nyilvános port száma, amelyet a helyi https portra kell átirányítani.",
+ "LabelPublicHttpPort": "Nyilvános HTTP portszám:",
+ "LabelPublicHttpPortHelp": "A nyilvános port száma, amelyet a helyi HTTP portra kell átirányítani.",
+ "LabelPublicHttpsPort": "Nyilvános HTTPS port száma:",
+ "LabelPublicHttpsPortHelp": "A nyilvános port száma, amelyet a helyi HTTPS portra kell átirányítani.",
"LabelReadHowYouCanContribute": "Ismerd meg, hogyan járulhatsz hozzá.",
"LabelReasonForTranscoding": "Az átkódolás oka:",
"LabelRemoteClientBitrateLimit": "Internetes streaming bitráta limit (Mbps):",
@@ -970,7 +970,7 @@
"OptionDateAddedFileTime": "Használja a fájl létrehozásának dátumát",
"LabelMinBackdropDownloadWidth": "A letöltendő háttérkép minimális szélessége:",
"LabelMinResumeDuration": "A folytatás minimum időtartama:",
- "LabelMinResumeDurationHelp": "A rövidebb videó hosszúság másodpercben, melynél a lejátszás helye mentésre kerül, így később folytatható lesz",
+ "LabelMinResumeDurationHelp": "A rövidebb videó hosszúság másodpercben, melynél a lejátszás helye mentésre kerül, így később folytatható lesz.",
"LabelMinResumePercentage": "Minimum folytatás százalékban:",
"LabelMinScreenshotDownloadWidth": "Minimális képernyőkép letöltési szélesség:",
"LabelPreferredSubtitleLanguage": "Alapértelmezett feliratnyelv:",
@@ -988,14 +988,14 @@
"LabelTextBackgroundColor": "Szöveg háttérszín:",
"LabelTextColor": "Szöveg szín:",
"LabelTextSize": "Szövegméret:",
- "LabelTranscodingTempPathHelp": "Ez a mappa az átkódoló által használt munkafájlokat tartalmazza. Adj meg egyéni útvonalat, vagy hagyd üresen a szerver alapértelmezetten beálíltásához.",
+ "LabelTranscodingTempPathHelp": "Ez a mappa az átkódoló által használt munkafájlokat tartalmazza. Adj meg egyéni útvonalat, vagy hagyd üresen a szerver alapértelmezetten beállításához.",
"LabelTranscodingThreadCount": "Átkódolási CPU szálak száma:",
"LabelTranscodingThreadCountHelp": "Válaszd ki az átkódolás során használni kívánt szálak maximális számát. A szálszám csökkentése csökkenti a processzor használatát, de lehet nem lesz képes elég gyorsan átalakítani a folyamatos lejátszási élményhez.",
"LabelTunerIpAddress": "Tuner IP címe:",
"LabelTypeText": "Szöveg",
"LabelUserLibrary": "Felhasználói könyvtár:",
"LabelUserLibraryHelp": "Válaszd ki, hogy melyik felhasználói könyvtárat jelenítse meg az eszközön. Hagyd üresen az alapértelmezett beállításhoz.",
- "LabelUserRemoteClientBitrateLimitHelp": "Ez felülbírálja a szerver lejátszási beállításaiban megadott alapértelmezett globális értéket.",
+ "LabelUserRemoteClientBitrateLimitHelp": "A szerver lejátszási beállításaiban megadott alapértelmezett globális érték felülbírálása.",
"LabelVaapiDevice": "VA API eszköz:",
"LabelValue": "Érték:",
"LabelZipCode": "Irányítószám:",
@@ -1003,8 +1003,8 @@
"LabelffmpegPathHelp": "Az ffmpeg alkalmazásfájl elérési útja, vagy az őt tartalmazó mappa.",
"Large": "Nagy",
"LearnHowYouCanContribute": "Ismerd meg, hogyan járulhatsz hozzá.",
- "LeaveBlankToNotSetAPassword": "Választható - hagyd üresen a jelszó nélküli beállításhoz",
- "LibraryAccessHelp": "Válaszd ki azokat a média mappákat amelyeket megosztani kívánsz ezzel a felhasználóval. A rendszergazdák a Metaadat Manager segítségével szerkeszthetik az összes mappát.",
+ "LeaveBlankToNotSetAPassword": "Ha nem szeretnél jelszót beállítani, hagyd ezt a mezőt üresen.",
+ "LibraryAccessHelp": "Válaszd ki azokat a könyvtárakat amelyeket megosztani kívánsz ezzel a felhasználóval. A rendszergazdák a Metaadat Manager segítségével szerkeszthetik az összes mappát.",
"LinksValue": "Linkek: {0}",
"List": "Lista",
"LiveTV": "Élő TV",
@@ -1036,7 +1036,7 @@
"MessageEnablingOptionLongerScans": "Ennek az opciónak a bekapcsolása jelentősen hosszabb könyvtárbeolvasást eredményezhet.",
"MessageImageFileTypeAllowed": "Csak JPEG és PNG fájlok támogatottak.",
"MessageImageTypeNotSelected": "Kérlek válaszd ki a kép típusát a legördülő menüből.",
- "MessageInstallPluginFromApp": "Ezt a bővítményt telepíteni kell abban az alkalmazásban, amelyikkel használni kívánod.",
+ "MessageInstallPluginFromApp": "Ezt a bővítményt azon alkalmazásból kell telepíteni, amelyben használni kívánod.",
"MessageInvalidForgotPasswordPin": "Érvénytelen vagy lejárt PIN kódot írtál be. Kérlek próbáld újra.",
"MessageInvalidUser": "Érvénytelen felhasználónév vagy jelszó. Kérlek próbáld újra.",
"MessageItemSaved": "Elem mentve.",
@@ -1060,21 +1060,21 @@
"MessageForgotPasswordInNetworkRequired": "Kérlek próbáld meg újra a jelszó visszaállítási folyamatot az otthoni hálózatban.",
"MessageNoMovieSuggestionsAvailable": "Jelenleg nincsenek filmajánlatok. Kezdj el nézni és értékelni a filmeket, majd térj vissza, hogy megtekinthesd az ajánlásokat.",
"MessagePasswordResetForUsers": "A következő felhasználók jelszavai visszaálltak. Most már bejelentkezhetnek a visszaállításhoz használt PIN kódokkal.",
- "MessagePlayAccessRestricted": "A tartalom lejátszása jelenleg korlátozott. További információért fordulj a Jellyfin Szerver üzemeltetőjéhez.",
+ "MessagePlayAccessRestricted": "A tartalom lejátszása jelenleg korlátozott. További információért fordulj a Szerver üzemeltetőjéhez.",
"MessagePleaseWait": "Kérlek várj. Ez eltarthat egy percet.",
"MessagePluginConfigurationRequiresLocalAccess": "A bővítmény beállításához jelentkezz be közvetlenül a helyi szerverre.",
"MessagePluginInstallDisclaimer": "A Jellyfin közösség tagjai által készített bővítmények nagyszerű módot adnak a Jellyfin élményének, funkcióinak bővítéséhez. Telepítés előtt kérlek vedd figyelembe a Jellyfin szerverre gyakorolt hatásokat, mint például a hosszabb könyvtárvizsgálatokat, a további háttérfeldolgozást, vagy akár a rendszer stabilitásának csökkenését.",
"MessageReenableUser": "Az újra engedélyezéshez lásd lentebb",
- "MessageTheFollowingLocationWillBeRemovedFromLibrary": "A következő médiahelyek eltávolításra kerülnek a Jellyfin könyvtárából:",
+ "MessageTheFollowingLocationWillBeRemovedFromLibrary": "A következő médiahelyek eltávolításra kerülnek a könyvtáradból:",
"MessageUnableToConnectToServer": "Jelenleg nem tudunk csatlakozni a kiválasztott szerverhez. Győződj meg róla, hogy fut és próbáld meg újra.",
"MessageUnsetContentHelp": "A tartalom sima mappákként jelenik meg. A legjobb eredmény eléréséhez használd a Metaadat kezelőt az almappák tartalmi típusainak beállításához.",
"MessageYouHaveVersionInstalled": "Jelenleg a(z) {0} verzió van telepítve.",
"MinutesAfter": "perc múlva",
"MinutesBefore": "perccel korábban",
- "Mobile": "Mobil / Tablet",
+ "Mobile": "Mobil",
"MoveLeft": "Mozgás balra",
"MoveRight": "Mozgás jobbra",
- "MovieLibraryHelp": "Tekintsd át a {0} Jellyfin film elnevezési útmutatót {1}.",
+ "MovieLibraryHelp": "Tekintsd át a {0} film elnevezési útmutatót {1}.",
"Never": "Soha",
"NewCollectionHelp": "A gyűjtemények lehetővé teszik, hogy személyre szabott csoportokat hozz létre filmekből és más könyvtártartalomból.",
"News": "Hírek",
@@ -1088,7 +1088,7 @@
"NoSubtitlesHelp": "A feliratok alapértelmezés szerint nem lesznek betöltve. Lejátszás közben kézzel is bekapcsolhatók.",
"Off": "Ki",
"OneChannel": "Egy csatorna",
- "OnlyImageFormats": "Csak képformátumok (VOBSUB, PGS, SUB / IDX stb.)",
+ "OnlyImageFormats": "Csak képformátumok (VOBSUB, PGS, SUB stb.)",
"Option3D": "3D",
"OptionAlbum": "Album",
"OptionAlbumArtist": "Album előadó",
@@ -1097,7 +1097,7 @@
"OptionAllowLinkSharingHelp": "Csak a médiaadatokat tartalmazó weboldalak oszthatók meg. A médiafájlok soha nem oszthatók meg nyilvánosan. A megosztás időlimithez van kötve, és lejár {0} nap elteltével.",
"OptionAllowManageLiveTv": "Élő TV felvételkezelés engedélyezése",
"OptionAllowMediaPlaybackTranscodingHelp": "Az átkódoláshoz való hozzáférés korlátozása lejátszási hibákat okozhat a Jellyfin alkalmazásokban a nem támogatott médiaformátumok miatt.",
- "OptionAllowRemoteSharedDevicesHelp": "A DLNA eszközöket megosztottnak tekintjük, amíg a felhasználó nem kezdi meg a vezérlést.",
+ "OptionAllowRemoteSharedDevicesHelp": "A DLNA eszközöket mindaddig megosztottnak tekintjük, amíg a felhasználó meg nem kezdi azok irányítását.",
"OptionAllowSyncTranscoding": "Engedélyezze a média letöltését és szinkronizálását, amely átkódolást igényel",
"OptionAllowVideoPlaybackRemuxing": "Olyan videólejátszás engedélyezése, amely átalakítást igényel újrakódolás nélkül",
"OptionAllowVideoPlaybackTranscoding": "Engedélyezze az átkódolást igénylő videó lejátszást",
@@ -1116,14 +1116,14 @@
"OptionDateAddedImportTime": "Használja a könyvtárba beolvasási dátumot",
"OptionDisableUserHelp": "Ha letiltod, a szerver nem engedélyezi a felhasználó csatlakozását. A meglévő kapcsolatok hirtelen megszűnnek.",
"OptionDisplayFolderView": "Az egyszerű média mappák mappanézetének megjelenítése",
- "OptionDisplayFolderViewHelp": "Ha engedélyezve van, a Jellyfin alkalmazások megjelenítik a Mappák kategóriát a médiakönyvtár mellett. Ez akkor hasznos, ha egyszerű mappa nézeteket szeretnél látni.",
+ "OptionDisplayFolderViewHelp": "Jelenítse meg a mappákat a többi médiakönyvtár mellett. Ez hasznos lehet, ha egyszerű mappa nézeteket szeretnél látni.",
"OptionDownloadImagesInAdvance": "Képek előzetes letöltése",
"OptionDownloadImagesInAdvanceHelp": "Alapértelmezés szerint a legtöbb kép csak akkor töltődik le, ha azt egy Jellyfin alkalmazás kéri. Engedélyezd ezt az opciót az összes kép előzetes letöltéséhez, mikor új médiát importál. Ez jelentősen hosszabb könyvtár vizsgálatot eredményezhet.",
"OptionDownloadPrimaryImage": "Elsődleges",
"OptionDvd": "DVD",
"OptionEmbedSubtitles": "Beágyazva tárolóba",
"OptionEnableExternalContentInSuggestions": "Külső tartalom engedélyezése a javaslatokban",
- "OptionEnableExternalContentInSuggestionsHelp": "Engedélyezze az internetes előzeteseket és az élő tv műsorokat a javasolt tartalomban.",
+ "OptionEnableExternalContentInSuggestionsHelp": "Engedélyezze az internetes előzeteseket és az élő TV műsorokat a javasolt tartalomban.",
"OptionEnableForAllTuners": "Engedélyezze az összes tuner eszközre",
"PlayNextEpisodeAutomatically": "A következő epizód automatikus lejátszása",
"ShowAdvancedSettings": "Speciális beállítások megjelenítése",
@@ -1232,7 +1232,7 @@
"Sports": "Sport",
"StopRecording": "Felvétel leállítása",
"SubtitleAppearanceSettingsAlsoPassedToCastDevices": "Ezek a beállítások a készülék által elindított összes Chromecast lejátszásra is vonatkoznak.",
- "SubtitleAppearanceSettingsDisclaimer": "Ezek a beállítások nem vonatkoznak a grafikus feliratokra (PGS, DVD, stb.) Vagy a saját stílusokkal ellátott feliratokra (ASS / SSA).",
+ "SubtitleAppearanceSettingsDisclaimer": "Ezek a beállítások nem vonatkoznak a grafikus feliratokra (PGS, DVD, stb.) vagy a saját stílusokat tartalmazó feliratokra (ASS / SSA).",
"SubtitleDownloadersHelp": "Engedélyezd és rangsorold az előnyben részesített feliratok letöltőket sorrendben.",
"SystemDlnaProfilesHelp": "A rendszerprofilok csak olvashatóak. A rendszerprofil módosításai egy új egyéni profilba kerülnek.",
"TV": "TV",
@@ -1249,7 +1249,7 @@
"TrackCount": "{0} szám",
"Trailers": "Előzetesek",
"Transcoding": "Átkódolás",
- "TvLibraryHelp": "Tekintsd át a {0} Jellyfin TV elnevezési útmutatót {1}.",
+ "TvLibraryHelp": "Tekintsd át a {0} TV elnevezési útmutatót {1}.",
"Uniform": "Egyforma",
"Unplayed": "Nem játszott",
"Unrated": "Besorolatlan",
@@ -1272,17 +1272,17 @@
"ViewAlbum": "Album megtekintése",
"ViewArtist": "Művész megtekintése",
"Whitelist": "Fehérlista",
- "WizardCompleted": "Ez most minden amire szükség volt. A Jellyfin megkezdte a médiakönyvtáraddal kapcsolatos információk gyűjtését. Nézz meg néhány alkalmazásunkat, majd kattints a
Befejezés gombra a
Szerver Vezérlőpult megtekintéséhez.",
+ "WizardCompleted": "Ez most minden amire szükség volt. A Jellyfin megkezdte a médiakönyvtáraddal kapcsolatos információk gyűjtését. Nézz meg néhány alkalmazásunkat, majd kattints a
Befejezés gombra a
Vezérlőpult megtekintéséhez.",
"XmlTvKidsCategoriesHelp": "Az ilyen kategóriákkal rendelkező programok gyerekeknek szóló programokként jelennek meg. Válaszd el őket a '|' elválasztóval.",
"XmlTvMovieCategoriesHelp": "Az ilyen kategóriákkal rendelkező programok filmként jelennek meg. Válaszd el őket a '|' elválasztóval.",
"XmlTvNewsCategoriesHelp": "Az ezekhez a kategóriákhoz tartozó programok hírprogramként jelennek meg. Válaszd el őket a '|' elválasztóval.",
- "XmlTvPathHelp": "Az xml tv-fájl elérési útvonala. A Jellyfin elolvassa ezt a fájlt és rendszeresen ellenőrzi a frissítéseket. Te vagy a felelős a fájl létrehozásáért és frissítéséért.",
+ "XmlTvPathHelp": "Az XML TV fájl elérési útvonala. A Jellyfin elolvassa ezt a fájlt és rendszeresen ellenőrzi a frissítéseket. Te vagy a felelős a fájl létrehozásáért és frissítéséért.",
"XmlTvSportsCategoriesHelp": "Az ilyen kategóriákkal rendelkező programok sportprogramként jelennek meg. Válaszd el őket a '|' elválasztóval.",
"Yes": "Igen",
"LabelMaxResumePercentage": "Maximum folytatás százalékban:",
- "LabelMaxResumePercentageHelp": "A címeket teljesen lejátszottnak tekintjük, ha ezen idő után fejezed be",
+ "LabelMaxResumePercentageHelp": "A címeket teljesen lejátszottnak tekintjük, ha ezen idő után fejezed be.",
"LabelMaxStreamingBitrateHelp": "Adj meg egy maximum bitrátát a streameléshez.",
- "LabelMinResumePercentageHelp": "A címeket nem lejátszottnak tekintjük, ha ez alatt az idő alatt fejezed be",
+ "LabelMinResumePercentageHelp": "A címeket nem lejátszottnak tekintjük, ha ez alatt az idő alatt fejezed be.",
"LabelMusicStreamingTranscodingBitrateHelp": "Határozz meg egy streamelési max bitrátát a zenékhez",
"DashboardVersionNumber": "Verzió: {0}",
"DashboardServerName": "Szerver: {0}",
@@ -1294,13 +1294,13 @@
"LabelUserAgent": "Felhasználó ügynök:",
"LabelUserLoginAttemptsBeforeLockout": "Sikertelen bejelentkezési kísérletek a felhasználó zárolása előtt:",
"DashboardOperatingSystem": "Operációs rendszer: {0}",
- "DashboardArchitecture": "Rendszer típusa: {0}",
- "LaunchWebAppOnStartup": "Indítsa el a Jellyfin webes alkalmazást a böngészőben, amikor a Jellyfin Szerver elindul",
+ "DashboardArchitecture": "Platform: {0}",
+ "LaunchWebAppOnStartup": "Indítsa el a webes felületet a szerver indításakor",
"MessageNoCollectionsAvailable": "A gyűjtemények lehetővé teszik Filmek, Sorozatok és Albumok egyéni csoportosítását. A gyűjtemények létrehozásához kattints a + gombra.",
"MessageNoServersAvailable": "Az automatikus kiszolgálókeresés nem talált szervert.",
"OptionLoginAttemptsBeforeLockout": "Meghatározza, hogy hány érvénytelen bejelentkezési kísérlet történhet zárolás előtt.",
"TabNetworking": "Hálózat",
- "HeaderFavoriteArtists": "Kedvenc Előadók",
+ "HeaderFavoriteArtists": "Kedvenc előadók",
"SmallCaps": "Kiskapitális",
"AllowOnTheFlySubtitleExtractionHelp": "A beágyazott feliratokat ki lehet távolítani a videókból és elküldeni a Jellyfin alkalmazásoknak sima szöveg formátumba, hogy ne legyen átkódolás. Néhány eszközön ez hosszú ideig is eltarthat, valamint a videó lejátszás megakadhat az eltávolítási folyamat futása közben. Ezt kikapcsolva a beágyazott feliratok videó átkódolással beégetésre kerülnek azon kliens eszközökre melyek nem támogatják a külső feliratokat.",
"Art": "ClearArt",
@@ -1321,10 +1321,10 @@
"HeaderContinueListening": "Folyamatban lévő zenék",
"HeaderDeleteTaskTrigger": "Feladatvezérlő törlése",
"HeaderFavoriteMovies": "Kedvenc Filmek",
- "HeaderFavoriteShows": "Kedvenc Sorozatok",
- "HeaderFavoriteEpisodes": "Kedvenc Epizódok",
- "HeaderFavoriteAlbums": "Kedvenc Albumok",
- "HeaderFavoriteSongs": "Kedvenc Dalok",
+ "HeaderFavoriteShows": "Kedvenc sorozatok",
+ "HeaderFavoriteEpisodes": "Kedvenc epizódok",
+ "HeaderFavoriteAlbums": "Kedvenc albumok",
+ "HeaderFavoriteSongs": "Kedvenc dalok",
"HeaderFavoriteVideos": "Kedvenc Videók",
"HeaderGuideProviders": "TV műsorújság Szolgáltatók",
"HeaderHome": "Kezdőlap",
@@ -1343,7 +1343,7 @@
"LabelDateAddedBehavior": "Új tartalom esetén alkalmazandó hozzáadás dátuma mód:",
"LabelDateAddedBehaviorHelp": "Ha egy metaadat érték jelen van, akkor mindig az lesz előnyben részesítve ezen opciók előtt.",
"LabelDownMixAudioScale": "Hangkiemelés átkódolás esetén:",
- "LabelDownMixAudioScaleHelp": "Hangkiemelés átkódoláskor. Állítsd 1-re az eredeti hangerő érték megőrzéséhez.",
+ "LabelDownMixAudioScaleHelp": "Hangkiemelés átkódoláskor. Az egy érték az eredeti hangerő értékének felel meg.",
"LabelEmbedAlbumArtDidl": "Albumborító beágyazása a Didl-be",
"LabelEmbedAlbumArtDidlHelp": "Néhány eszköz ezt a megoldást részesíti előnyben az albumborítók esetében. Mások esetlegesen lejátszási hibát jeleznek, ha ez az opció engedélyezve van.",
"LabelEnableBlastAliveMessages": "Blast alive üzenetek",
@@ -1354,11 +1354,11 @@
"LabelIconMaxWidthHelp": "Ikon maximális szélesség, mely az upnp:icon keresztül kiajánlásra kerül.",
"LabelIdentificationFieldHelp": "Kis-és nagybetű különbséget figyelmen kívül hagyó szöveg vagy reguláris kifejezés.",
"LabelKeepUpTo": "Őrizd meg:",
- "LabelKodiMetadataUser": "Mentsd el a következő felhasználó megtekintési adatát az nfo-ba:",
- "LabelKodiMetadataUserHelp": "Ha ezt engedélyezed, akkor a kiválasztott felhasználó megtekintési adata elmentésre kerül az NFO fájlokba, melyet azután más alkalmazások használhatnak.",
+ "LabelKodiMetadataUser": "Mentsd el a következő felhasználó megtekintési adatát az NFO-ba:",
+ "LabelKodiMetadataUserHelp": "A kiválasztott felhasználó megtekintési adata elmentésre kerül az NFO fájlokba, melyet azután más alkalmazások használhatnak.",
"LabelLocalHttpServerPortNumberHelp": "A TCP port száma, melyen a Jellyfin HTTP szerver figyel.",
- "UserAgentHelp": "Adj meg egy egyedi http user-agent fejlécet, amennyiben szükséges.",
- "XmlDocumentAttributeListHelp": "Ezek a tulajdonságok minden xml válaszüzenet gyökér elemére alkalmazásra kerülnek.",
+ "UserAgentHelp": "Adj meg egy egyedi HTTP user-agent fejlécet.",
+ "XmlDocumentAttributeListHelp": "Ezek a tulajdonságok minden XML válaszüzenet gyökér elemére alkalmazásra kerülnek.",
"Thumb": "Thumb",
"MediaInfoStreamTypeData": "Adat",
"MediaInfoStreamTypeEmbeddedImage": "Beágyazott kép",
@@ -1371,5 +1371,10 @@
"HeaderFavoriteBooks": "Kedvenc Könyvek",
"CopyStreamURLSuccess": "URL másolása sikeres.",
"CopyStreamURL": "Stream URL másolása",
- "PlaybackData": "Lejátszási adatok"
+ "PlaybackData": "Lejátszási adatok",
+ "ButtonAddImage": "Kép hozzáadása",
+ "LabelPasswordResetProvider": "Jelszó Visszaállítási Szolgáltató:",
+ "FetchingData": "További adatok lekérése",
+ "LabelBaseUrl": "Alap URL:",
+ "Depressed": "Nyomott"
}
diff --git a/src/strings/ko.json b/src/strings/ko.json
index f226872953..845f02a025 100644
--- a/src/strings/ko.json
+++ b/src/strings/ko.json
@@ -1278,5 +1278,6 @@
"DisplayInOtherHomeScreenSections": "보고 있는 것이나 최신 미디어 등을 홈 페이지에 표시합니다",
"DisplayMissingEpisodesWithinSeasonsHelp": "서버 환경설정에서도 TV 라이브러리가 활성화되어있어야 합니다.",
"ErrorAddingMediaPathToVirtualFolder": "미디어 경로를 추가하는 데에 오류가 발생했습니다. 경로를 다시 확인하거나 Jellyfin 서버가 해당 경로에 접근할 수 있는지 확인해 주세요.",
- "ErrorGettingTvLineups": "TV 구성을 다운로드 하는 중에 오류가 발생하였습니다. 정보가 맞는지 확인한 후 다시 시도해 주세요."
+ "ErrorGettingTvLineups": "TV 구성을 다운로드 하는 중에 오류가 발생하였습니다. 정보가 맞는지 확인한 후 다시 시도해 주세요.",
+ "BoxRear": "상자 (후면)"
}
diff --git a/src/strings/ms.json b/src/strings/ms.json
index 018b767a2b..ab81fbf9b5 100644
--- a/src/strings/ms.json
+++ b/src/strings/ms.json
@@ -10,10 +10,10 @@
"ParentalRating": "Parental Rating",
"SettingsSaved": "Seting Disimpan",
"Absolute": "Mutlak",
- "AccessRestrictedTryAgainLater": "Akses pada masa ini terhad. Sila cuba sebentar lagi.",
+ "AccessRestrictedTryAgainLater": "Akses pada masa ini dihalang. Sila cuba sebentar lagi.",
"Actor": "Pelakon",
"Add": "Tambah",
- "AddItemToCollectionHelp": "Tambah item ke koleksi melalui mencari mereka dan menggunakan menu klik kanan atau ketik mereka untuk menambahkannya ke koleksi.",
+ "AddItemToCollectionHelp": "Tambah item ke koleksi melalui carian dan menggunakan menu klik kanan atau ketik menu tersebut untuk menambahkannya ke koleksi.",
"AddToCollection": "Tambah pada koleksi",
"AddToPlayQueue": "Tambah ke giliran main",
"AddToPlaylist": "Tambah pada senarai main",
@@ -71,5 +71,31 @@
"ButtonBack": "Kembali",
"ButtonCancel": "Batalkan",
"ButtonChangeServer": "Tukar pelayan",
- "ButtonConnect": "Sambung"
+ "ButtonConnect": "Sambung",
+ "ButtonLibraryAccess": "Akses pustaka",
+ "ButtonLearnMore": "Ketahui lebih lanjut",
+ "ButtonInfo": "Info",
+ "ButtonHome": "Mula",
+ "ButtonHelp": "Pertolongan",
+ "ButtonGuide": "Panduan",
+ "ButtonGotIt": "Terima",
+ "ButtonFullscreen": "Paparan skrin penuh",
+ "ButtonForgotPassword": "Lupa Kata Laluan",
+ "ButtonFilter": "Tapisan",
+ "ButtonEditOtherUserPreferences": "Edit profil, gambar dan keutamaan peribadi pengguna ini",
+ "ButtonEditImages": "Edit gambar-gambar",
+ "ButtonEdit": "Edit",
+ "ButtonDownload": "Muat turun",
+ "ButtonDown": "Bawah",
+ "ButtonDeleteImage": "Buang gambar",
+ "ButtonDelete": "Buang",
+ "ButtonAddScheduledTaskTrigger": "Tambah Pencetus",
+ "ButtonAddImage": "Tambah gambar",
+ "BurnSubtitlesHelp": "Menentukan sama ada pelayan perlu membakar subtitle ke skrin apabila menukar video bergantung kepada format sarikata. Menghindari pembakaran sari kata ke skrin akan meningkatkan prestasi pelayan. Pilih Auto untuk membakar format berasaskan imej (VOBSUB, PGS, SUB / IDX, dll) dan subtitle ASS / SSA tertentu.",
+ "BrowsePluginCatalogMessage": "Semak imbas katalog plugin kami untuk melihat plugin yang tersedia.",
+ "BoxRear": "Kotak (belakang)",
+ "BookLibraryHelp": "Buku audio dan teks disokong. Semak {0}panduan penamaan buku{1}.",
+ "Banner": "Sepanduk",
+ "AuthProviderHelp": "Pilih Pembekal Pengesahan yang akan digunakan untuk mengesahkan kata laluan pengguna ini.",
+ "AllowedRemoteAddressesHelp": "Senarai pemisah koma atau entri IP/netmask untuk rangkaian yang dibenarkan bagi menyambung secarajauh. Jika dibiarkan kosong, semua alamat jauh akan dibenarkan."
}
diff --git a/src/strings/nb.json b/src/strings/nb.json
index bab746ffeb..cfef5d43e2 100644
--- a/src/strings/nb.json
+++ b/src/strings/nb.json
@@ -1448,5 +1448,6 @@
"DropShadow": "Underskygge",
"Depressed": "Nedtrykt",
"Features": "Med",
- "LabelParentNumber": "Foreldrenummer:"
+ "LabelParentNumber": "Foreldrenummer:",
+ "OptionResElement": "res element"
}
diff --git a/src/strings/nl.json b/src/strings/nl.json
index 9f31521cd5..6388edb647 100644
--- a/src/strings/nl.json
+++ b/src/strings/nl.json
@@ -18,11 +18,11 @@
"AllEpisodes": "Alle afleveringen",
"AllLanguages": "Alle talen",
"AllLibraries": "Alle bibliotheken",
- "AllowHWTranscodingHelp": "Wanneer ingeschakeld zal de tuner streams direct transcoderen. Dit kan helpen de transcodering vereist door Jellyfin Server te verlagen.",
+ "AllowHWTranscodingHelp": "Direct transcoderen toestaan door de tuner. Dit kan helpen om de transcodering te verlagen die vereist is door de server.",
"AllowMediaConversion": "Mediaconversie toestaan",
"AllowMediaConversionHelp": "Toegang verlenen of weigeren tot de mediaconversie functie.",
"AllowOnTheFlySubtitleExtraction": "Directe ondertitel extractie toestaan",
- "AllowOnTheFlySubtitleExtractionHelp": "Ingebakken ondertitels kunnen uit de video's gehaald worden en als tekst bezorgd worden aan de Jellyfin apps om transcodering te helpen voorkomen. Op sommige systemen kan dit een lange tijd duren en dit er voor zorgen dat het afspelen van video stopt tijdens de extractie. Schakel dit uit om ingebakken ondertiteling in de video te laten branden met transcodering als deze niet standaard ondersteund worden door het afspeelapparaat.",
+ "AllowOnTheFlySubtitleExtractionHelp": "Ingebakken ondertitels kunnen uit de video's gehaald worden en als tekst bezorgd worden aan de clients om transcodering te helpen voorkomen. Op sommige systemen kan dit een lange tijd duren en dit er voor zorgen dat het afspelen van video stopt tijdens de extractie. Schakel dit uit om ingebakken ondertiteling in de video te laten branden met transcodering als deze niet standaard ondersteund worden door het afspeelapparaat.",
"AllowRemoteAccess": "Externe verbindingen met deze Jellyfin Server toestaan.",
"AllowRemoteAccessHelp": "Indien niet aangevinkt worden alle externe verbindingen geblokkeerd.",
"AllowedRemoteAddressesHelp": "Komma-gescheiden lijst van IP-adressen of IP/netmask adressen voor netwerken die op afstand verbinding mogen maken. Indien blanco, worden alle externe adressen toegestaan.",
@@ -44,7 +44,7 @@
"BirthDateValue": "Geboren: {0}",
"BirthLocation": "Geboorte Locatie",
"BirthPlaceValue": "Geboorte plaats: {0})",
- "BookLibraryHelp": "Audio- en tekstboeken worden ondersteund. Bekijk de {0}Jellyfin Boeken naamgeving{1}.",
+ "BookLibraryHelp": "Audio- en tekstboeken worden ondersteund. Bekijk de {0}boeken naamgevingsgids{1}.",
"Books": "Boeken",
"BoxRear": "Hoes (achterkant)",
"Browse": "Bladeren",
@@ -722,7 +722,7 @@
"LabelSerialNumber": "Serienummer",
"LabelSeriesRecordingPath": "Serieopname pad (optioneel):",
"LabelServerHost": "Server:",
- "LabelServerHostHelp": "192.168.1.100 of https://myserver.com",
+ "LabelServerHostHelp": "192.168.1.100:8096 of https://mijnserver.nl",
"LabelSimultaneousConnectionLimit": "Gelijktijdige streams limiet:",
"LabelSkipBackLength": "Terugspoellengte",
"LabelSkipForwardLength": "Vooruitspoellengte",
@@ -1293,7 +1293,7 @@
"HeaderSync": "Synchronisatie",
"HeaderTV": "TV",
"HeaderTopPlugins": "Top Plugins",
- "AuthProviderHelp": "Selecteer een Authentication Provider om de gebruiker's wachtwoord te verifiëren ",
+ "AuthProviderHelp": "Selecteer een Authenticatie Provider om het wachtwoord van deze gebruiker te verifiëren",
"HeaderFavoriteMovies": "Favoriete Films",
"HeaderFavoriteShows": "Favoriete shows",
"HeaderFavoriteEpisodes": "Favoriete afleveringen",
@@ -1327,5 +1327,7 @@
"LabelProfileVideoCodecs": "Video codecs:",
"LabelProtocolInfo": "Protocol info:",
"LabelServerName": "Server naam:",
- "LabelSkin": "Skin:"
+ "LabelSkin": "Skin:",
+ "ButtonAddImage": "Voeg afbeelding toe",
+ "LabelSize": "Grootte:"
}
diff --git a/src/strings/pt-pt.json b/src/strings/pt-pt.json
index e6628fbd89..510993c0b8 100644
--- a/src/strings/pt-pt.json
+++ b/src/strings/pt-pt.json
@@ -90,7 +90,7 @@
"Director": "Realizador",
"EasyPasswordHelp": "O código PIN é utilizado para acesso off-line em clientes suportados e pode ser usado para um acesso fácil dentro da rede.",
"Edit": "Editar",
- "EnableCinemaMode": "Ativar modo cinema",
+ "EnableCinemaMode": "Modo cinema",
"Ended": "Terminado",
"ErrorAddingMediaPathToVirtualFolder": "Ocorreu um erro ao adicionar a localização dos seus ficheiros. Por favor, assegure-se que o local é valido e que o processo do Jellyfin Server tenha acesso a essa localização.",
"ErrorGettingTvLineups": "Ocorreu um erro ao transferir a programação de TV. Por favor, certifique-se que a sua informação está correta e tente novamente.",
@@ -340,20 +340,18 @@
"LabelEpisodeNumber": "Número do episódio:",
"LabelEvent": "Evento:",
"LabelEveryXMinutes": "A cada:",
- "LabelExtractChaptersDuringLibraryScan": "Extrair imagens dos capítulos durante o rastreamento da biblioteca",
- "LabelExtractChaptersDuringLibraryScanHelp": "Se ativado, as imagens dos capítulos serão extraídas quando os vídeos forem importados durante a pesquisa na biblioteca. Se desativado, elas serão extraídas durante a tarefa agendada de imagens dos capítulos, permitindo que a pesquisa na biblioteca seja mais rápida.",
"LabelExtractChaptersDuringLibraryScan": "Extrair imagens dos capítulos durante a atualização da biblioteca",
- "LabelExtractChaptersDuringLibraryScanHelp": "Se ativado, as imagens dos capítulos serão extraídas quando os vídeos forem importados durante a atualização da biblioteca. Se desativado, serão extraídas durante a tarefa agendada de extração de imagens dos capítulos, permitindo que a atualização da biblioteca seja mais rápida.",
+ "LabelExtractChaptersDuringLibraryScanHelp": "Gerar imagens dos capítulos quando os vídeos forem importados durante a atualização da biblioteca. Caso contrário, serão geradas durante a tarefa agendada de extração de imagens dos capítulos, permitindo que a atualização da biblioteca seja mais rápida.",
"LabelFailed": "Falhou",
"LabelFinish": "Terminar",
"LabelForgotPasswordUsernameHelp": "Introduza o seu nome de utilizador, se se recordar.",
"LabelFormat": "Formato:",
"LabelFriendlyName": "Nome amigável:",
- "LabelServerNameHelp": "Este nome será utilizado para identificar o servidor. Se não for preenchido, será usado o nome do computador.",
+ "LabelServerNameHelp": "Este nome será utilizado para identificar o servidor. Por defeito, é usado o nome do computador.",
"LabelGroupMoviesIntoCollections": "Agrupar filmes em coleções",
"LabelGroupMoviesIntoCollectionsHelp": "Ao mostrar listas de filmes, filmes que pertençam a uma coleção serão mostrados como um único item agrupado.",
"LabelHardwareAccelerationType": "Aceleração por hardware:",
- "LabelHardwareAccelerationTypeHelp": "Disponível apenas em sistemas suportados.",
+ "LabelHardwareAccelerationTypeHelp": "Esta funcionalidade é experimental e está disponível apenas em sistemas suportados.",
"LabelHttpsPort": "Número do porto HTTPS local:",
"LabelHttpsPortHelp": "Número do porto TCP em que o servidor HTTPS do Jellyfin ficará à escuta.",
"LabelIconMaxHeight": "Altura máxima do ícone:",
@@ -364,10 +362,10 @@
"LabelImageType": "Tipo de imagem:",
"LabelImportOnlyFavoriteChannels": "Restringir a canais marcados como favoritos",
"LabelInNetworkSignInWithEasyPassword": "Ativar acesso dentro da rede com código PIN",
- "LabelInNetworkSignInWithEasyPasswordHelp": "Se ativado, poderá utilizar um código PIN para entrar no Jellyfin dentro da rede. A palavra-passe só será necessária fora da rede. Se o código PIN for deixado em branco, não será necessária autenticação dentro da rede.",
+ "LabelInNetworkSignInWithEasyPasswordHelp": "Utilizar um código PIN para entrar no Jellyfin dentro da rede. A palavra-passe só será necessária fora da rede. Se o código PIN for deixado em branco, não será necessária autenticação dentro da rede.",
"LabelKodiMetadataDateFormat": "Formato da data de lançamento:",
- "LabelKodiMetadataDateFormatHelp": "Todas as datas dentro dos nfo's serão lidas e gravadas usando este formato.",
- "LabelKodiMetadataEnableExtraThumbs": "Copiar extrafanart para extrathumbs",
+ "LabelKodiMetadataDateFormatHelp": "Todas as datas presentes em ficheiros NFO serão analisadas utilizando este formato.",
+ "LabelKodiMetadataEnableExtraThumbs": "Copiar o parâmetro extrafanart para extrathumbs",
"LabelKodiMetadataEnableExtraThumbsHelp": "Ao transferir imagens, estas podem ser guardadas como extrafanart e extrathumbs para uma maior compatibilidade com os temas Kodi.",
"LabelKodiMetadataEnablePathSubstitution": "Ativar substituição de local",
"LabelKodiMetadataEnablePathSubstitutionHelp": "Ativa a substituição do local das imagens usando as opções de substituição de caminho no servidor.",
@@ -380,8 +378,8 @@
"LabelLockItemToPreventChanges": "Bloquear este item para evitar alterações futuras",
"LabelLoginDisclaimer": "Aviso legal de login:",
"LabelLoginDisclaimerHelp": "Este aviso será mostrado na parte inferior da página de login.",
- "LabelManufacturer": "Fabricante:",
- "LabelManufacturerUrl": "URL do fabricante:",
+ "LabelManufacturer": "Fabricante",
+ "LabelManufacturerUrl": "URL do Fabricante",
"LabelMatchType": "Tipo de correspondência:",
"LabelMaxBackdropsPerItem": "Número máximo de imagens de fundo por item:",
"LabelMaxParentalRating": "Controlo parental máximo permitido:",
@@ -408,7 +406,7 @@
"LabelModelUrl": "URL do modelo",
"LabelMonitorUsers": "Monitorizar atividade de:",
"LabelMusicStreamingTranscodingBitrate": "Taxa de transcodificação de música:",
- "LabelMusicStreamingTranscodingBitrateHelp": "Defina a taxa máxima ao fazer transmissão de música.",
+ "LabelMusicStreamingTranscodingBitrateHelp": "Defina a taxa máxima ao fazer transmissão de música",
"LabelName": "Nome:",
"LabelNewPassword": "Nova palavra-passe:",
"LabelNewPasswordConfirm": "Confirmar nova palavra-passe:",
@@ -455,7 +453,7 @@
"LabelSendNotificationToUsers": "Enviar notificação para:",
"LabelSerialNumber": "Número de série",
"LabelServerHost": "Servidor:",
- "LabelServerHostHelp": "192.168.1.100 ou https://omeudominio.com",
+ "LabelServerHostHelp": "192.168.1.100:8096 ou https://omeudominio.com",
"LabelSkipIfAudioTrackPresent": "Ignorar no caso de o idioma da faixa de áudio principal coincidir com o idioma de transferência",
"LabelSkipIfAudioTrackPresentHelp": "Desmarque esta opção para garantir que todos os vídeos têm legendas, independentemente do idioma do áudio.",
"LabelSkipIfGraphicalSubsPresent": "Ignorar se o vídeo já possuir legendas integradas",
@@ -475,7 +473,7 @@
"LabelTimeLimitHours": "Limite de tempo (horas):",
"LabelTranscodingAudioCodec": "Codec de áudio:",
"LabelTranscodingContainer": "Contentor:",
- "LabelTranscodingTempPathHelp": "Esta pasta contém ficheiros ativos utilizados pelo transcodificador. Indique uma localização personalizada ou deixe em branco para utilizar o caminho por defeito.",
+ "LabelTranscodingTempPathHelp": "Indique uma localização personalizada para os ficheiros de transcodificação em utilização, ou deixe em branco para utilizar o caminho por defeito.",
"LabelTranscodingThreadCount": "Número de threads de transcodificação:",
"LabelTranscodingThreadCountHelp": "Indique o número máximo de threads a ser utilizado para transcodificação. Reduzir o número de threads diminuirá a utilização do CPU, mas pode não converter rápido o suficiente para uma experiência de reprodução suave.",
"LabelTranscodingVideoCodec": "Codec do vídeo:",
@@ -505,7 +503,7 @@
"MessageConfirmRecordingCancellation": "Cancelar a gravação?",
"MessageConfirmRestart": "Tem a certeza de que deseja reiniciar o Servidor Jellyfin?",
"MessageConfirmRevokeApiKey": "Tem a certeza de que deseja revogar esta chave da API? A ligação da aplicação ao Servidor Jellyfin vai ser terminada de imediato.",
- "MessageConfirmShutdown": "Tem a certeza de que deseja encerrar o Servidor Jellyfin?",
+ "MessageConfirmShutdown": "Tem a certeza de que deseja encerrar o servidor?",
"MessageDeleteTaskTrigger": "Tem a certeza de que deseja remover o agendamento desta tarefa?",
"MessageDirectoryPickerBSDInstruction": "Num sistema operativo BSD, é necessário configurar o disco Jail FreeNAS para permitir o acesso do Servidor Jellyfin.",
"MessageDirectoryPickerInstruction": "As localizações de rede podem ser escritas manualmente caso o botão \"Rede\" não consiga encontrar os dispositivos. Por exemplo, {0} ou {1}.",
@@ -546,7 +544,7 @@
"OptionAllowMediaPlaybackTranscodingHelp": "Restringir o acesso à transcodificação pode causar falhas de reprodução nas aplicações do Jellyfin devido a formatos multimédia não suportados.",
"OptionAllowRemoteControlOthers": "Permitir controlo remoto de outros utilizadores",
"OptionAllowRemoteSharedDevices": "Permitir controlo remoto de dispositivos compartilhados",
- "OptionAllowRemoteSharedDevicesHelp": "Dispositivos DLNA são considerados compartilhados até que um utilizador comece a controlá-lo.",
+ "OptionAllowRemoteSharedDevicesHelp": "Dispositivos DLNA são considerados como partilhados até que um utilizador comece a controlá-lo.",
"OptionAllowUserToManageServer": "Permitir a este utilizador gerir o servidor",
"OptionAllowVideoPlaybackTranscoding": "Permitir reprodução de vídeo que necessite de transcodificação",
"OptionArtist": "Artista",
@@ -599,7 +597,7 @@
"OptionHasThemeVideo": "Vídeo de Tema",
"OptionHideUser": "Ocultar este utilizador nos formulários de início de sessão",
"OptionHideUserFromLoginHelp": "Útil para contas de administrador privadas ou ocultas. O utilizador necessita de entrar manualmente, introduzindo o seu nome de utilizador e palavra-passe.",
- "OptionHlsSegmentedSubtitles": "Legendas segmentadas hls",
+ "OptionHlsSegmentedSubtitles": "Legendas segmentadas HLS",
"OptionIgnoreTranscodeByteRangeRequests": "Ignorar requisições de extensão do byte de transcodificação",
"OptionIgnoreTranscodeByteRangeRequestsHelp": "Se ativadas, estas requisições serão honradas mas irão ignorar o cabeçalho da extensão do byte.",
"OptionImdbRating": "Classificação no IMDb",
@@ -742,7 +740,7 @@
"UninstallPluginConfirmation": "Tem a certeza de que deseja desinstalar {0}?",
"UninstallPluginHeader": "Desinstalar Extensão",
"Unmute": "Ativar som",
- "UserProfilesIntro": "O Jellyfin inclui suporte nativo de perfis de utilizadores, permitindo que cada utilizador tenha as suas configurações de visualização, estado da reprodução e controlos parentais.",
+ "UserProfilesIntro": "O Jellyfin suporta perfis de utilizadores, permitindo que cada utilizador tenha as suas configurações de visualização, estado da reprodução e controlos parentais.",
"ValueAudioCodec": "Codec de Áudio: {0}",
"ValueConditions": "Condições: {0}",
"ValueSpecialEpisodeName": "Especial - {0}",
@@ -751,9 +749,9 @@
"ValueVideoCodec": "Codec de Vídeo: {0}",
"Wednesday": "Quarta",
"WelcomeToProject": "Bem-vindo ao Jellyfin!",
- "WizardCompleted": "É tudo, de momento. O Jellyfin iniciou a recolha de informações da sua biblioteca multimédia. Conheça algumas das nossas aplicações e, de seguida, clique
Terminar para ver o
Painel Principal do Servidor.",
+ "WizardCompleted": "É tudo, de momento. O Jellyfin iniciou a recolha de informações da sua biblioteca multimédia. Conheça algumas das nossas aplicações e, de seguida, clique
Terminar para ver o
Painel Principal .",
"Writer": "Escritor",
- "XmlDocumentAttributeListHelp": "Estes atributos são aplicados ao elemento principal de cada resposta xml.",
+ "XmlDocumentAttributeListHelp": "Estes atributos são aplicados ao elemento principal de cada resposta XML.",
"AccessRestrictedTryAgainLater": "Acesso restrito. Por favor, tente mais tarde.",
"AddItemToCollectionHelp": "Adicione itens às coleções pesquisando-os e utilizando o respetivo menu de toque ou clique direito para os adicionar a uma coleção.",
"AddToCollection": "Adicionar à coleção",
@@ -834,7 +832,7 @@
"Browse": "Procurar",
"BoxRear": "Caixa (verso)",
"Box": "Caixa",
- "BookLibraryHelp": "Livros de texto e áudio são suportados. Consulte o Guia de Nomenclatura de Livros Jellyfin {1}.",
+ "BookLibraryHelp": "Livros de texto e áudio são suportados. Consulte o guia de nomenclatura de livros{1}.",
"BirthLocation": "Local de nascimento",
"AsManyAsPossible": "Tantos quanto possível",
"Art": "Capa",
@@ -880,13 +878,13 @@
"GenreValue": "Género: {0}",
"General": "Geral",
"FormatValue": "Formato: {0}",
- "FolderTypeUnset": "Conteúdo misto",
+ "FolderTypeUnset": "Conteúdo Misto",
"Filters": "Filtros",
"File": "Ficheiro",
"Favorite": "Favoritos",
"FFmpegSavePathNotFound": "Não foi possível encontrar o binário FFmpeg na localização que introduziu. O binário FFprobe também é necessário, e deve estar na mesma pasta. Estes componentes são, por norma, instalados em conjunto. Por favor, verifique o caminho da localização e tente de novo.",
"Extras": "Extras",
- "ExtraLarge": "Extra grande",
+ "ExtraLarge": "Extra Grande",
"EveryNDays": "A cada {0} dias",
"ErrorSavingTvProvider": "Ocorreu um erro ao guardar o provedor do serviços de TV. Por favor, garanta que está acessível e tente de novo.",
"ErrorMessageStartHourGreaterThanEnd": "A hora de fim deve ser superior à hora de início.",
@@ -895,15 +893,15 @@
"ErrorAddingXmlTvFile": "Ocorreu um erro ao aceder ao ficheiro XmlTV. Por favor, garanta que o ficheiro está acessível e tente de novo.",
"Episodes": "Episódios",
"EndsAtValue": "Termina às {0}",
- "EnablePhotosHelp": "Fotografias serão detetadas e mostradas em conjunto com outros ficheiros multimédia.",
- "EnablePhotos": "Ativar fotografias",
+ "EnablePhotosHelp": "Imagens serão detetadas e mostradas em conjunto com outros ficheiros multimédia.",
+ "EnablePhotos": "Mostrar fotografias",
"EnableNextVideoInfoOverlayHelp": "No final de um vídeo, mostrar informação sobre o próximo vídeo da lista de reprodução.",
- "EnableNextVideoInfoOverlay": "Ativar informação sobre o próximo vídeo durante a reprodução",
+ "EnableNextVideoInfoOverlay": "Mostrar informação sobre o próximo vídeo durante a reprodução",
"EnableHardwareEncoding": "Ativar codificação por hardware",
"EnableExternalVideoPlayersHelp": "O menu de um reprodutor externo será mostrado no início da reprodução de vídeo.",
- "EnableExternalVideoPlayers": "Ativar reprodutores de vídeo externos",
- "EnableDisplayMirroring": "Ativar espelho de ecrã",
- "EnableColorCodedBackgrounds": "Ativar código de cores para o fundo",
+ "EnableExternalVideoPlayers": "Reprodutores de vídeo externos",
+ "EnableDisplayMirroring": "Duplicação de ecrã",
+ "EnableColorCodedBackgrounds": "Código de cores para o fundo",
"EditSubtitles": "Editar legendas",
"EditMetadata": "Editar metadados",
"EditImages": "Editar imagens",
@@ -912,7 +910,7 @@
"Download": "Transferir",
"DoNotRecord": "Não gravar",
"DisplayModeHelp": "Selecione o tipo de ecrã onde o Jellyfin será utilizado.",
- "DisplayMissingEpisodesWithinSeasonsHelp": "Deve também ser ativado para as bibliotecas de TV no Painel Principal do Servidor Jellyfin.",
+ "DisplayMissingEpisodesWithinSeasonsHelp": "Deve também ser ativado para as bibliotecas de TV nas configurações do servidor.",
"DisplayMissingEpisodesWithinSeasons": "Mostrar episódios em falta numa série",
"DisplayInOtherHomeScreenSections": "Mostrar no ecrã principal em secções como multimédia recente ou continue a ver",
"DisplayInMyMedia": "Mostrar no ecrã principal",
@@ -931,7 +929,7 @@
"MessageContactAdminToResetPassword": "Por favor, contacte o Administrador de sistema para repôr a sua password.",
"MessageConfirmRemoveMediaLocation": "Tem a certeza de que deseja remover esta localização?",
"MessageConfirmDeleteTunerDevice": "Tem a certeza de que deseja remover este dispositivo?",
- "UserAgentHelp": "Forneça um user-agent HTTP personalizado, se necessário.",
+ "UserAgentHelp": "Forneça um user-agent HTTP personalizado.",
"OptionProtocolHttp": "HTTP",
"OptionProtocolHls": "Emissão HTTP em direto",
"LabelHomeScreenSectionValue": "Secção {0} do Painel Principal:",
@@ -969,7 +967,7 @@
"Items": "Itens",
"InstallingPackage": "A instalar {0}",
"HttpsRequiresCert": "Para ativar ligações seguras, é necessário fornecer um certificado SSL confiável. Forneça um certificado SSL ou desative as ligações seguras.",
- "DirectStreamHelp1": "O tipo de multimédia (H.264, AC3, etc.) e a sua resolução são compatíveis com o dispositivo, no entanto, o formato (.mkv, .avi, .wmv, etc.) não é. O conteúdo é reempacotado em tempo real antes de ser enviado para o dispositivo.",
+ "DirectStreamHelp1": "O tipo de multimédia (H.264, AC3, etc.) e a sua resolução são compatíveis com o dispositivo, no entanto, o formato (mkv, avi, wmv, etc.) não é. O conteúdo é reempacotado em tempo real antes de ser enviado para o dispositivo.",
"DirectPlaying": "Reprodução direta",
"Backdrop": "Imagem de Fundo",
"SortChannelsBy": "Ordenar canais por:",
@@ -1050,9 +1048,9 @@
"Display": "Visualização",
"ManageLibrary": "Gerir biblioteca",
"HeaderLibraryOrder": "Ordenação da Biblioteca",
- "EnableThemeVideosHelp": "Se ativado, serão reproduzidos vídeos do tema em plano de fundo durante a navegação pela Biblioteca.",
- "EnableThemeSongsHelp": "Se ativado, serão reproduzidas músicas do tema em plano de fundo durante a navegação pela Biblioteca.",
- "EnableBackdropsHelp": "Se ativado, serão mostradas imagens de fundo em algumas páginas durante a navegação pela Biblioteca.",
+ "EnableThemeVideosHelp": "Reproduzir vídeos do tema em plano de fundo durante a navegação pela Biblioteca.",
+ "EnableThemeSongsHelp": "Reproduzir músicas do tema em plano de fundo durante a navegação pela Biblioteca.",
+ "EnableBackdropsHelp": "Mostrar imagens de fundo em algumas páginas durante a navegação pela Biblioteca.",
"MediaInfoSize": "Tamanho",
"LabelTextSize": "Tamanho do Texto:",
"HeaderSubtitleAppearance": "Aparência das Legendas",
@@ -1082,5 +1080,103 @@
"HeaderMovies": "Filmes",
"DirectorsValue": "Realização: {0}",
"DirectorValue": "Realizador: {0}",
- "ButtonOff": "Desligado"
+ "ButtonOff": "Desligado",
+ "ButtonAddImage": "Adicionar Imagem",
+ "LabelOriginalTitle": "Título original:",
+ "LabelPostProcessorArgumentsHelp": "Utilizar o caminho {path} como caminho para o ficheiro de gravação.",
+ "Hide": "Esconder",
+ "LabelBaseUrl": "URL Base:",
+ "LabelNewName": "Novo nome:",
+ "HeaderUploadImage": "Enviar Imagem",
+ "EnableThemeSongs": "Músicas do tema",
+ "EnableThemeVideos": "Vídeos do tema",
+ "HeaderMoreLikeThis": "Mais Como Este",
+ "HeaderRecordingPostProcessing": "Pós-Processamento de Gravações",
+ "Descending": "Descendente",
+ "CopyStreamURLSuccess": "URL copiado com sucesso.",
+ "ErrorAddingListingsToSchedulesDirect": "Ocorreu um erro ao adicionar o alinhamento à sua conta Schedules Direct. As contas Schedules Direct permitem apenas um número limitado de alinhamentos. Poderá ser necessário iniciar sessão na sua conta e remover outras listagens antes de prosseguir.",
+ "HeaderFavoriteBooks": "Livros Favoritos",
+ "HeaderStopRecording": "Parar Gravação",
+ "HeaderVideoQuality": "Qualidade do Vídeo",
+ "HeaderVideoType": "Tipo de Vídeo",
+ "LabelFolder": "Pasta:",
+ "LabelOptionalNetworkPath": "(Opcional) Pasta partilhada de rede:",
+ "ColorSpace": "Espaço de cores",
+ "HeaderMyMediaSmall": "A Minha Multimédia (pequeno)",
+ "HeaderNewDevices": "Novos Dispositivos",
+ "HeaderRecordingOptions": "Opções de Gravação",
+ "HeaderSortOrder": "Direção de Ordenação",
+ "LabelBaseUrlHelp": "Pode adicionar uma sub-pasta personalizada aqui para aceder ao servidor através de um URL mais direto.",
+ "LabelMoviePrefixHelp": "Se aplicar um prefixo aos títulos dos filmes, introduza-o aqui para que o servidor consiga tratá-los corretamente.",
+ "LabelPleaseRestart": "As alterações produzirão efeito depois de recarregar a página web.",
+ "LabelRecordingPathHelp": "Especifique a localização por defeito para guardar as gravações. Se for deixado em branco, será utilizada a pasta base do servidor.",
+ "ColorTransfer": "Transferência de cores",
+ "ExtractChapterImagesHelp": "Extrair imagens do capítulo permite aos clientes apresentar menus de seleção de cenas com gráficos. O processo poderá ser lento e exigente em recursos, bem como ocupar múltiplos gigabytes em disco. Este processo é corrido quando novos vídeos são encontrados e também através de uma tarefa agendada noturna. É possível configurar a hora de execução para que, idealmente, não coincida com horas de maior utilização.",
+ "Features": "Funcionalidades",
+ "HeaderMusicQuality": "Qualidade da Música",
+ "HeaderMyDevice": "O Meu Dispositivo",
+ "HeaderSortBy": "Ordenar Por",
+ "LabelOptionalNetworkPathHelp": "Se esta pasta estiver partilhada na rede, fornecer o caminho de rede pode permitir aos clientes aceder diretamente aos ficheiros multimédia.",
+ "LabelPersonRoleHelp": "Exemplo: motorista da carrinha de gelados",
+ "LabelPlayer": "Reprodutor:",
+ "LabelServerName": "Nome do servidor:",
+ "LabelSize": "Tamanho:",
+ "LabelLanNetworks": "Redes locais (LAN):",
+ "HeaderOtherItems": "Outros Itens",
+ "HeaderPhotoAlbums": "Álbuns de Fotografias",
+ "HeaderSeasons": "Temporadas",
+ "HeaderSecondsValue": "{0} Segundos",
+ "HeaderSeriesOptions": "Opções da Série",
+ "HeaderSeriesStatus": "Estado da Série",
+ "HeaderTracks": "Faixas",
+ "HeaderTuners": "Sintonizadores",
+ "Horizontal": "Horizontal",
+ "LabelAudioBitrate": "Taxa de bits de áudio:",
+ "LabelAudioChannels": "Canais de áudio:",
+ "LabelAudioCodec": "Codec de áudio:",
+ "LabelAudioSampleRate": "Taxa de amostragem de áudio:",
+ "LabelBitrate": "Taxa de bits:",
+ "LabelCache": "Cache:",
+ "LabelDiscNumber": "Número do disco:",
+ "LabelInternetQuality": "Qualidade para a Internet:",
+ "LabelKidsCategories": "Categorias para crianças:",
+ "LabelMovieCategories": "Categorias para filmes:",
+ "LabelMoviePrefix": "Prefixo para filmes:",
+ "LabelMovieRecordingPath": "Caminho para gravação de filmes (opcional):",
+ "LabelNewsCategories": "Categorias para notícias:",
+ "LabelNumber": "Número:",
+ "LabelPlayMethod": "Método de reprodução:",
+ "LabelPostProcessor": "Aplicação de pós-processamento:",
+ "LabelPostProcessorArguments": "Argumentos de linha de comandos para a aplicação de pós-processamento:",
+ "LabelPreferredSubtitleLanguage": "Idioma preferencial das legendas:",
+ "LabelProfileCodecs": "Codecs:",
+ "LabelReasonForTranscoding": "Razão para transcodificação:",
+ "LabelScreensaver": "Proteção de Ecrã:",
+ "LabelSecureConnectionsMode": "Modo de ligação segura:",
+ "LabelSeriesRecordingPath": "Caminho para gravação de séries (opcional):",
+ "ColorPrimaries": "Cores primárias",
+ "MessageInvalidForgotPasswordPin": "Foi inserido um código PIN inválido ou expirado. Por favor, tente de novo.",
+ "MessageImageTypeNotSelected": "Por favor, selecione um tipo de imagem da lista.",
+ "MessageImageFileTypeAllowed": "Apenas são suportados ficheiros JPEG ou PNG.",
+ "MessageForgotPasswordInNetworkRequired": "Por favor, volte a tentar o processo de recuperação de palavra-passe quando se encontrar dentro da sua rede local.",
+ "MessageForgotPasswordFileCreated": "Foi criado no servidor o ficheiro abaixo que contém instruções de como prosseguir:",
+ "MessageDownloadQueued": "Transferência pendente.",
+ "MessageCreateAccountAt": "Criar uma conta em {0}",
+ "MessageConfirmDeleteGuideProvider": "Tem a certeza de que pretende eliminar este provedor de programação de TV ?",
+ "MessageAlreadyInstalled": "Esta versão já se encontra instalada.",
+ "Menu": "Menu",
+ "MediaIsBeingConverted": "O conteúdo está a ser convertido num formato compatível com o dispositivo que o está a reproduzir.",
+ "MediaInfoStreamTypeVideo": "Vídeo",
+ "MediaInfoStreamTypeSubtitle": "Legenda",
+ "MediaInfoStreamTypeEmbeddedImage": "Imagem Integrada",
+ "MediaInfoStreamTypeData": "Dados",
+ "MediaInfoStreamTypeAudio": "Áudio",
+ "MediaInfoSoftware": "Software",
+ "MediaInfoTimestamp": "Data e Hora",
+ "MediaInfoSampleRate": "Taxa de Amostragem",
+ "MediaInfoResolution": "Resolução",
+ "MediaInfoProfile": "Perfil",
+ "MediaInfoPixelFormat": "Formato de Píxeis",
+ "MediaInfoPath": "Caminho",
+ "MediaInfoLevel": "Nível"
}
diff --git a/src/strings/sk.json b/src/strings/sk.json
index 7c0048db2f..14b75e053e 100644
--- a/src/strings/sk.json
+++ b/src/strings/sk.json
@@ -957,7 +957,7 @@
"HeaderSelectCertificatePath": "Vybrať cestu k certifikátu",
"HeaderSortOrder": "Poradie zoradzovania",
"HeaderSpecialEpisodeInfo": "Informácie o špeciálnej epizóde",
- "HeaderSpecialFeatures": "Špeciálne funkcie",
+ "HeaderSpecialFeatures": "Bonusové materiály",
"HeaderSubtitleDownloads": "Sťahovanie titulkov",
"HeaderTags": "Tagy",
"HeaderVideoType": "Typ videa",
@@ -976,7 +976,7 @@
"OptionDownloadPrimaryImage": "Primárne",
"OptionDvd": "DVD",
"OptionExtractChapterImage": "Povoliť extrakciu obrázkov z videa",
- "OptionHasSpecialFeatures": "Špeciálne funkcie",
+ "OptionHasSpecialFeatures": "Bonusové materiály",
"OptionHasTrailer": "Ukážka/Trailer",
"OptionIsHD": "HD",
"OptionIsSD": "SD",
diff --git a/src/strings/sl-si.json b/src/strings/sl-si.json
index b38437061a..25f611793a 100644
--- a/src/strings/sl-si.json
+++ b/src/strings/sl-si.json
@@ -614,5 +614,44 @@
"LabelAirsAfterSeason": "Predvajanje po sezoni:",
"LabelAirsBeforeSeason": "Predvajanje pred sezono:",
"LabelAlbumArtists": "Izvajalci albuma:",
- "LabelAll": "Vse"
+ "LabelAll": "Vse",
+ "LabelCustomRating": "Prilagojena ocena:",
+ "LabelDashboardTheme": "Tema pregledne plošče strežnika:",
+ "LabelBirthDate": "Datum rojstva:",
+ "LabelCache": "Predpomnilnik:",
+ "LabelCachePath": "Pot predpomnilnika:",
+ "LabelCancelled": "Prekinjeno",
+ "LabelCertificatePassword": "Geslo certifikata:",
+ "LabelCertificatePasswordHelp": "V kolikor vaš certifikat potrebuje geslo ga prosimo vnesite tukaj.",
+ "LabelChannels": "Kanali:",
+ "LabelCommunityRating": "Ocena skupnosti:",
+ "LabelCriticRating": "Ocena kritikov:",
+ "LabelCustomCertificatePathHelp": "Pot do PKCS #12 datoteke, ki vsebuje certifikat in zasebni ključ, za omogočanje TLS povezave na domenah po meri.",
+ "LabelCustomCss": "CSS po meri:",
+ "LabelCustomCssHelp": "Določite vaš lasten stil spletnega vmesnika.",
+ "LabelCustomDeviceDisplayName": "Prikazano ime:",
+ "LabelCustomDeviceDisplayNameHelp": "Določi prikazano ime naprave. Pusti prazno za uporabo imena kot ga sporoči naprava sama.",
+ "LabelDefaultScreen": "Privzeti zaslon:",
+ "LabelDateAdded": "Datum dodajanja:",
+ "LabelDateAddedBehavior": "Vedenje datuma dodajanja za nove vsebine:",
+ "LabelDateAddedBehaviorHelp": "V kolikor so prisotni ustrezni metapodatki bodo ti vedno uporabljeni najprej.",
+ "LabelDateTimeLocale": "Lokacija datuma/časa:",
+ "LabelDefaultUser": "Privzeti uporabnik:",
+ "LabelDeviceDescription": "Opis naprave",
+ "LabelDiscNumber": "Številka diska:",
+ "LabelDisplayLanguage": "Jezik prikaza:",
+ "LabelDisplayLanguageHelp": "Prevajanje Jellyfin strežnika je tekoči projekt.",
+ "LabelBirthYear": "Letnica rojstva:",
+ "LabelBlastMessageIntervalHelp": "Določi dolžino intervala v sekundah med pošiljanjem sporočil o dostopnosti.",
+ "LabelBurnSubtitles": "Vžgi podnapise:",
+ "LabelCachePathHelp": "Določi lokacijo po meri za predpomnjene podatke, na primer slike. Pusti prazno za uporabo privzete lokacije.",
+ "LabelCollection": "Zbirka:",
+ "LabelCustomCertificatePath": "Lokacija certifikata ssl po meri:",
+ "LabelDidlMode": "DIDL način:",
+ "LabelDisplayMissingEpisodesWithinSeasons": "Prikaži manjkajoče epizode znotraj sezon",
+ "LabelDay": "Dan:",
+ "LabelDeathDate": "Datum smrti:",
+ "LabelBitrate": "Bitna hitrost:",
+ "LabelBlastMessageInterval": "Interval sporočila o dostopnosti (sekunde)",
+ "LabelDefaultUserHelp": "Določi knjižnica katerega uporabnika bo prikazana na povezanih napravah. To lahko preglasite s profili za posamezno napravo."
}
diff --git a/src/strings/sv.json b/src/strings/sv.json
index 914de21eb5..fbdb0c3272 100644
--- a/src/strings/sv.json
+++ b/src/strings/sv.json
@@ -1312,5 +1312,6 @@
"HeaderFavoriteBooks": "Favoritböcker",
"FormatValue": "Format: {0}",
"CopyStreamURLSuccess": "URL har kopierats.",
- "CopyStreamURL": "Kopiera Stream URL"
+ "CopyStreamURL": "Kopiera Stream URL",
+ "FetchingData": "Hämtar ytterligare data"
}
diff --git a/src/strings/tr.json b/src/strings/tr.json
index 347d7f5652..f517eb10e9 100644
--- a/src/strings/tr.json
+++ b/src/strings/tr.json
@@ -288,5 +288,272 @@
"AllLanguages": "Bütün diller",
"AllowMediaConversion": "Medya dönüşümüne izin ver",
"AddItemToCollectionHelp": "Ögeleri koleksiyona eklemek için arama yapın ve üzerine sağ tıklayın veya sekme menüsünden koleksiyona ekleyin.",
- "AllowHWTranscodingHelp": "Ayarlayıcının anında akışları dönüştürmesine izin verin. Bu, sunucunun gerektirdiği kodlamanın azaltılmasına yardımcı olabilir."
+ "AllowHWTranscodingHelp": "Ayarlayıcının anında akışları dönüştürmesine izin verin. Bu, sunucunun gerektirdiği kodlamanın azaltılmasına yardımcı olabilir.",
+ "ColorSpace": "Renk Uzayı",
+ "ButtonConnect": "Bağlan",
+ "ColorTransfer": "Renk transferi",
+ "ButtonPreviousTrack": "Önceki parça",
+ "ButtonProfile": "Profil",
+ "ButtonRefresh": "Yenile",
+ "ButtonRename": "Yeniden Adlandır",
+ "ButtonRepeat": "Tekrar",
+ "ButtonResume": "Devam Et",
+ "ButtonRevoke": "geri al",
+ "ChannelNumber": "Kanal Numarası",
+ "ContinueWatching": "İzlemeye devam et",
+ "CriticRating": "Kritik değerlendirme",
+ "CustomDlnaProfilesHelp": "Yeni bir cihazı hedeflemek veya bir sistem profilini geçersiz kılmak için özel bir profil oluşturun.",
+ "Descending": "Azalan",
+ "DetectingDevices": "Cihazları tespit",
+ "DirectPlaying": "Doğrudan oynatma",
+ "CommunityRating": "Topluluk değerlendirmesi",
+ "Composer": "Besteci",
+ "ConfigureDateAdded": "Eklenen tarihin, Kitaplık ayarları altındaki Jellyfin Sunucu kontrol panelinde nasıl belirleneceğini yapılandırın",
+ "ConfirmDeleteImage": "Resmi Sil?",
+ "ButtonResetEasyPassword": "Kolay pin kodunu sıfırla",
+ "ColorPrimaries": "Renk primerleri",
+ "DirectStreamHelp2": "Doğrudan Akış, video kalitesinde herhangi bir kayıp olmadan çok az işlem gücü kullanır.",
+ "DirectStreaming": "Doğrudan akış",
+ "Director": "yönetmen",
+ "DirectorValue": "Yönetmen: {0}",
+ "DirectorsValue": "Yöneticiler: {0}",
+ "Disabled": "Deaktif",
+ "DisplayModeHelp": "Jellyfin’i çalıştırdığınız ekran türünü seçin.",
+ "DoNotRecord": "Kaydetme",
+ "Down": "Aşağı",
+ "Download": "İndir",
+ "DownloadsValue": "{0} indirme",
+ "EditImages": "Resimleri düzenle",
+ "EditMetadata": "Meta verileri düzenle",
+ "EditSubtitles": "Altyazıları düzenle",
+ "EnableBackdropsHelp": "Kütüphaneye göz atarken arka plandaki bazı sayfaların arka planında görüntüleyin.",
+ "AllowMediaConversionHelp": "Dönüştürme özelliğine erişim izni verme veya reddetme.",
+ "AllowOnTheFlySubtitleExtraction": "Anında altyazı çıkartmaya izin ver",
+ "ButtonSelectServer": "Sunucu Seç",
+ "Disc": "Disk",
+ "ButtonAddImage": "Resim ekle",
+ "ButtonAddScheduledTaskTrigger": "Tetikleyici ekle",
+ "ButtonAddServer": "Sunucu ekle",
+ "ButtonAudioTracks": "Ses Parçalari",
+ "ButtonChangeServer": "Sunucu Değiştir",
+ "ButtonGotIt": "Anladım",
+ "ButtonMore": "Daha",
+ "ButtonOpen": "Açık",
+ "ButtonArrowUp": "Yukarı",
+ "ButtonNetwork": "Ağ",
+ "ButtonDownload": "İndir",
+ "ButtonNextTrack": "Sonraki parça",
+ "ButtonOff": "Kapalı",
+ "ButtonParentalControl": "Ebeveyn Kontrolü",
+ "ButtonArrowDown": "Aşağı",
+ "ButtonArrowLeft": "Sol",
+ "ButtonDown": "Aşağı",
+ "ButtonGuide": "Rehber",
+ "ButtonLearnMore": "Daha fazla bilgi edin",
+ "ButtonLibraryAccess": "Kütüphane erişimi",
+ "ButtonScanAllLibraries": "Tüm Kütüphaneleri Tara",
+ "ButtonSelectView": "Görünüm seç",
+ "ButtonShuffle": "Karıştır",
+ "ButtonShutdown": "Kapat",
+ "ChannelNameOnly": "Yalnızca {0} kanalı",
+ "ConfirmDeleteItems": "Bu öğeleri silmek, onları hem dosya sisteminden hem de medya kitaplığınızdan siler. Devam etmek istediğinize emin misiniz?",
+ "ConfirmDeletion": "Silmeyi onayla",
+ "ConfirmEndPlayerSession": "Jellyfin'i {0} tarihinde kapatmak ister misiniz?",
+ "Connect": "Bağlan",
+ "Disconnect": "Bağlantısız",
+ "Dislike": "Beğenmemek",
+ "Display": "Görüntüle",
+ "DisplayInMyMedia": "Ana ekranda görüntüleme",
+ "DisplayInOtherHomeScreenSections": "En son medya gibi ana ekran bölümlerinde görüntüleyin ve izlemeye devam edin",
+ "EnableBackdrops": "Arka planında",
+ "BurnSubtitlesHelp": "Altyazı formatına bağlı olarak video dönüştürülürken sunucunun altyazılarda yazıp yazmayacağını belirler. Altyazılarda yanmaktan kaçınmak, sunucu performansını iyileştirir. Görüntü tabanlı biçimleri (VOBSUB, PGS, SUB / IDX, vb.) Ve bazı ASS / SSA altyazılarını yazmak için Otomatik'i seçin.",
+ "ConfirmDeleteItem": "Bu öğeyi silmek, onu hem dosya sisteminden hem de medya kütüphanenizden siler. Devam etmek istediğinize emin misiniz?",
+ "ValueSpecialEpisodeName": "Özel -{0}",
+ "DeviceAccessHelp": "Bu, yalnızca benzersiz şekilde tanımlanabilen ve tarayıcı erişimini engellemeyen cihazlar için geçerlidir. Kullanıcı cihazlarına erişimin filtrelenmesi, burada onaylanana kadar yeni cihazları kullanmalarını önler.",
+ "DirectStreamHelp1": "Medya, çözünürlük ve medya türüyle (H.264, AC3, vb.) İlgili cihazla uyumludur, ancak uyumsuz bir dosya konteynerinde (mkv, avi, wmv, vb.) Bulunur. Video, cihaza aktarılmadan önce anında yeniden paketlenecek.",
+ "DisplayMissingEpisodesWithinSeasonsHelp": "Bu, sunucu yapılandırmasındaki TV kütüphaneleri için de etkinleştirilmelidir.",
+ "EasyPasswordHelp": "Kolay pin kodunuz, desteklenen istemcilerde çevrimdışı erişim için kullanılır ve ayrıca ağ içinde oturum açmak için de kullanılabilir.",
+ "ChangingMetadataImageSettingsNewContent": "Meta veri veya resim indirme ayarlarında yapılan değişiklikler yalnızca kitaplığınıza eklenen yeni içerikler için geçerli olacaktır. Değişiklikleri mevcut başlıklara uygulamak için meta verilerini el ile yenilemeniz gerekir.",
+ "CinemaModeConfigurationHelp": "Sinema modu, ana özellikten önce fragmanlar ve özel tanıtımlar oynatabilen tiyatro deneyimini doğrudan oturma odanıza getirir.",
+ "Browse": "Gözat",
+ "AllowOnTheFlySubtitleExtractionHelp": "Gömülü alt yazılar, videoların kodlanmasını önlemek için videolardan çıkarılabilir ve istemcilere düz metin olarak gönderilebilir. Bazı sistemlerde bu uzun zaman alabilir ve çıkarma işlemi sırasında video oynatmanın durmasına neden olabilir. İstemci cihaz tarafından doğal olarak desteklenmiyorsa, video kod kodlaması ile birlikte yakılmış gömülü altyazılara sahip olmak için bunu devre dışı bırakın.",
+ "AllowedRemoteAddressesHelp": "Uzaktan bağlanmasına izin verilecek ağlar için virgülle ayrılmış IP adresleri listesi veya IP / ağ maskesi girişleri. Boş bırakılırsa, tüm uzak adreslere izin verilir.",
+ "AlwaysPlaySubtitlesHelp": "Dil tercihi ile eşleşen altyazılar, ses diline bakılmaksızın yüklenir.",
+ "AnyLanguage": "Herhangi bir dil",
+ "Anytime": "İstediğin zaman",
+ "AroundTime": "{0} civarında",
+ "Art": "Sanat",
+ "AsManyAsPossible": "Mümkün olduğunca",
+ "Ascending": "yükselen",
+ "AspectRatio": "Boy oranı",
+ "Audio": "Ses",
+ "AuthProviderHelp": "Bu kullanıcının şifresini doğrulamak için kullanılacak bir Kimlik Doğrulama Sağlayıcısı seçin.",
+ "AutoBasedOnLanguageSetting": "Otomatik (dil ayarına göre)",
+ "Backdrop": "zemin",
+ "Backdrops": "Zeminler",
+ "Banner": "afiş",
+ "BirthDateValue": "Doğan: {0}",
+ "BirthLocation": "Doğum yeri",
+ "BirthPlaceValue": "Doğum yeri: {0}",
+ "Auto": "Oto",
+ "Blacklist": "kara liste",
+ "BoxRear": "Kutu (arka)",
+ "ButtonAddMediaLibrary": "Medya Kitaplığı Ekle",
+ "ButtonSubmit": "Sunmak",
+ "ButtonStart": "Başlat",
+ "ButtonTrailer": "Fragman",
+ "Box": "Kutu",
+ "ButtonViewWebsite": "Web sitesini görüntüle",
+ "CancelRecording": "Kaydı iptal et",
+ "CancelSeries": "Serileri iptal et",
+ "ButtonUninstall": "Kaldır",
+ "ButtonUp": "Yukarı",
+ "ButtonWebsite": "Website",
+ "Categories": "Kategoriler",
+ "DrmChannelsNotImported": "DRM'li kanallar içe aktarılmayacak.",
+ "DropShadow": "Düşen gölge",
+ "CopyStreamURL": "Akış URL’sini kopyala",
+ "DefaultSubtitlesHelp": "Altyazılar, gömülü meta verilerdeki varsayılan ve zorunlu bayraklara göre yüklenir. Birden fazla seçenek olduğunda dil tercihleri göz önünde bulundurulur.",
+ "DeleteDeviceConfirmation": "Bu cihazı silmek istediğinden emin misin? Bir kullanıcı bir sonraki oturum açışında yeniden görünecektir.",
+ "DisplayMissingEpisodesWithinSeasons": "Sezonlardaki eksik bölümleri görüntüleme",
+ "AlwaysPlaySubtitles": "Her zaman altyazıları oynat",
+ "CopyStreamURLSuccess": "URL başarıyla kopyalandı.",
+ "DateAdded": "Ekleme Tarihi",
+ "DatePlayed": "Oynanan tarih",
+ "DeathDateValue": "Öldü: {0}",
+ "Default": "Varsayılan",
+ "DefaultErrorMessage": "İsteğin işlenmesi sırasında bir hata oluştu. Lütfen daha sonra tekrar deneyiniz.",
+ "DefaultMetadataLangaugeDescription": "Bunlar varsayılan ayarlarınızdır ve kitaplık bazında özelleştirilebilir.",
+ "DeleteUserConfirmation": "Bu kullanıcıyı silmek istediğinden emin misin?",
+ "Depressed": "Bunalımlı",
+ "Desktop": "Masaüstü",
+ "HeaderFavoriteShows": "Favori Diziler",
+ "HeaderFavoriteEpisodes": "Favori Bölümler",
+ "BookLibraryHelp": "Ses ve ders kitapları desteklenir. {0} kitap adlandırma kılavuzunu {1} gözden geçirin.",
+ "EnableDisplayMirroring": "Ekran Yansıtma",
+ "EnableExternalVideoPlayers": "Harici video oynatıcılar",
+ "EnableExternalVideoPlayersHelp": "Video oynatmaya başlarken harici bir oynatıcı menüsü görüntülenecektir.",
+ "EnableHardwareEncoding": "Donanım kodlamasını etkinleştir",
+ "EnableNextVideoInfoOverlayHelp": "Bir videonun sonunda, geçerli oynatma listesinde çıkan bir sonraki video hakkındaki bilgileri görüntüleyin.",
+ "EnablePhotos": "Fotoğrafları göster",
+ "EnableNextVideoInfoOverlay": "Oynatma sırasında bir sonraki video bilgisini göster",
+ "EnablePhotosHelp": "Görüntüler diğer medya dosyalarıyla birlikte algılanacak ve gösterilecektir.",
+ "EnableCinemaMode": "Sinema Modu",
+ "EnableColorCodedBackgrounds": "Renk kodlu arka planlar",
+ "HeaderGuideProviders": "TV Rehberi Veri Sağlayıcıları",
+ "HeaderGenres": "Türler",
+ "HeaderForgotPassword": "Parolanızı mı unuttunuz",
+ "HeaderForKids": "Çocuklar için",
+ "HeaderFetcherSettings": "Alıcı Ayarları",
+ "HeaderFetchImages": "Görüntüleri Getir:",
+ "HeaderFeatures": "Özellikleri",
+ "HeaderFeatureAccess": "Özellik Erişimi",
+ "HeaderFavoriteVideos": "Favori Videolar",
+ "HeaderFavoriteMovies": "Favori Filmler",
+ "HeaderFavoriteBooks": "favori kitaplar",
+ "HeaderExternalIds": "Dış kimlikler:",
+ "HeaderError": "Hata",
+ "HeaderEpisodes": "Bölümler",
+ "HeaderEnabledFieldsHelp": "Kilitlemek ve verilerinin değişmesini önlemek için bir alanın işaretini kaldırın.",
+ "HeaderEnabledFields": "Etkin Alanlar",
+ "HeaderEditImages": "Görüntüleri Düzenle",
+ "HeaderDownloadSync": "İndir ve Eşitle",
+ "HeaderDisplay": "Görüntüle",
+ "HeaderDirectPlayProfileHelp": "Aygıtın yerel olarak hangi biçimlerde kullanılabileceğini göstermek için doğrudan oynatma profilleri ekleyin.",
+ "HeaderDirectPlayProfile": "Doğrudan Oyun Profili",
+ "HeaderDevices": "Cihazlar",
+ "HeaderDeveloperInfo": "Geliştirici Bilgisi",
+ "HeaderDetectMyDevices": "Cihazlarımı Algıla",
+ "HeaderDeleteTaskTrigger": "Görev Tetikleyicisini Sil",
+ "HeaderDeleteProvider": "Sağlayıcıyı Sil",
+ "HeaderDeleteItems": "Ürünleri sil",
+ "HeaderDeleteItem": "Öğeyi sil",
+ "HeaderDeleteDevice": "Cihazı Sil",
+ "HeaderDefaultRecordingSettings": "Varsayılan Kayıt Ayarları",
+ "HeaderDateIssued": "Çıkış Tarihi",
+ "HeaderContinueListening": "Dinlemeye Devam Et",
+ "HeaderContainerProfileHelp": "Konteyner profilleri, belirli formatları oynatırken cihazın sınırlamalarını gösterir. Bir sınırlama uygulanırsa, format doğrudan oynatma için yapılandırılmış olsa bile ortam kodlanır.",
+ "HeaderContainerProfile": "Konteyner Profili",
+ "HeaderConnectionFailure": "Bağlantı hatası",
+ "HeaderConnectToServer": "Sunucuya bağlan",
+ "HeaderConfirmRevokeApiKey": "API Anahtarını İptal Et",
+ "HeaderConfirmProfileDeletion": "Profil Silme İşlemini Onayla",
+ "HeaderConfirmPluginInstallation": "Eklenti Yüklemesini Onayla",
+ "HeaderConfigureRemoteAccess": "Uzaktan Erişimi Yapılandırma",
+ "HeaderCodecProfileHelp": "Codec profilleri, belirli kodlayıcıları oynatırken cihazın sınırlamalarını gösterir. Eğer bir sınırlama uygulanırsa, kodeğin doğrudan oynaması için yapılandırılmış olsa bile, ortam kodlanır.",
+ "HeaderChapterImages": "Bölüm Görüntüleri",
+ "HeaderChannelAccess": "Kanal erişimi",
+ "HeaderCastCrew": "Kast ekibi",
+ "HeaderCastAndCrew": "Kast ekibi",
+ "HeaderCancelSeries": "Serileri İptal Et",
+ "HeaderCancelRecording": "Kaydı İptal Et",
+ "HeaderBranding": "dağlama",
+ "HeaderBooks": "Kitaplar",
+ "HeaderBlockItemsWithNoRating": "Tanınmayan veya bilinmeyen derecelendirme bilgisine sahip öğeleri engelle:",
+ "HeaderAudioSettings": "Ses ayarları",
+ "HeaderAudioBooks": "Sesli Kitaplar",
+ "HeaderAppearsOn": "Görünür",
+ "HeaderApp": "Uygulama",
+ "HeaderApiKeysHelp": "Jellyfin Server ile iletişim kurabilmek için harici uygulamaların bir API anahtarına sahip olmaları gerekir. Anahtarlar bir Jellyfin hesabıyla giriş yaparak veya uygulamaya manuel olarak bir anahtar vererek verilir.",
+ "HeaderApiKeys": "API Anahtarları",
+ "HeaderApiKey": "API Anahtarı",
+ "HeaderAllowMediaDeletionFrom": "Medyadan Silinmeye İzin Ver",
+ "HeaderAlert": "Alarm",
+ "HeaderAlbums": "Albümler",
+ "HeaderAdmin": "Yönetici",
+ "HeaderAdditionalParts": "İlave parçalar",
+ "HeaderAddUpdateImage": "Resim Ekle / Güncelle",
+ "HeaderAddToPlaylist": "Oynatma listesine ekle",
+ "HeaderAddToCollection": "Koleksiyona ekle",
+ "HeaderAddScheduledTaskTrigger": "Tetikleyici ekle",
+ "HeaderActivity": "Aktivite",
+ "HeaderActiveDevices": "Aktif Cihazlar",
+ "HeaderAccessScheduleHelp": "Belirli saatlerle erişimi sınırlamak için bir erişim programı oluşturun.",
+ "HeaderAccessSchedule": "Erişim Takvimi",
+ "HardwareAccelerationWarning": "Donanım ivmesini etkinleştirmek bazı ortamlarda dengesizliğe neden olabilir. İşletim sisteminizin ve video sürücülerinizin tamamen güncel olduğundan emin olun. Bunu etkinleştirdikten sonra video oynatmakta zorluk çekiyorsanız, ayarı tekrar Auto (Otomatik) olarak değiştirmeniz gerekecektir.",
+ "HandledByProxy": "Ters proxy tarafından kullanılır",
+ "HDPrograms": "HD programlar",
+ "H264EncodingPresetHelp": "Performansı artırmak için daha hızlı bir değer veya kaliteyi artırmak için daha yavaş bir değer seçin.",
+ "H264CrfHelp": "Sabit Hız Faktörü (CRF), x264 kodlayıcı için varsayılan kalite ayarıdır. Değerleri 0 ile 51 arasında ayarlayabilirsiniz, burada daha düşük değerler daha iyi kaliteyle sonuçlanır (daha yüksek dosya boyutları pahasına). Aklı başında değerleri 18 ila 28 arasındadır. X264 için varsayılan 23, bu nedenle bunu başlangıç noktası olarak kullanabilirsiniz.",
+ "GuideProviderSelectListings": "İlan Seç",
+ "GuideProviderLogin": "Oturum aç",
+ "Guide": "Rehber",
+ "GuestStar": "Konuk sanatçı",
+ "GroupVersions": "Grup versiyonları",
+ "GroupBySeries": "Seriye göre gruplandır",
+ "GenresValue": "Türler: {0}",
+ "GenreValue": "Tür: {0}",
+ "General": "Genel",
+ "Fullscreen": "Tam ekran",
+ "FormatValue": "Biçim: {0}",
+ "FolderTypeUnset": "Karışık içerik",
+ "Filters": "Filtreler",
+ "File": "Dosya",
+ "FetchingData": "Ek veri alınıyor",
+ "Features": "Özellikleri",
+ "Favorite": "Favori",
+ "FastForward": "İleri sar",
+ "FFmpegSavePathNotFound": "Girdiğiniz yolu kullanarak FFmpeg'i bulamıyoruz. FFprobe da gereklidir ve aynı klasörde bulunmalıdır. Bu bileşenler normalde aynı indirmede birlikte paketlenmiştir. Lütfen yolu kontrol edip tekrar deneyin.",
+ "Extras": "Ekstralar",
+ "ExtractChapterImagesHelp": "Bölüm görüntülerini çıkarmak, müşterilerin grafiksel sahne seçim menülerini görüntülemesini sağlar. İşlem yavaş olabilir, kaynak yoğun olabilir ve birkaç gigabaytlık alan gerektirebilir. Videolar keşfedildiğinde ve ayrıca zamanlanmış bir görev olarak çalışır. Zamanlanmış, zamanlanmış görevler alanında yapılandırılabilir. Bu görevi yoğun kullanım saatlerinde yapmanız önerilmez.",
+ "ExtraLarge": "Ekstra büyük",
+ "ExitFullscreen": "Tam ekrandan çık",
+ "EveryNDays": "Her {0} günde",
+ "ErrorSavingTvProvider": "TV sağlayıcısını kaydederken bir hata oluştu. Lütfen erişilebilir olduğundan emin olun ve tekrar deneyin.",
+ "ErrorPleaseSelectLineup": "Lütfen bir grup seçin ve tekrar deneyin. Hiç bir sıralama yoksa, lütfen kullanıcı adınızın, şifrenizin ve posta kodunuzun doğru olup olmadığını kontrol edin.",
+ "ErrorMessageStartHourGreaterThanEnd": "Bitiş saati, başlangıç saatinden büyük olmalıdır.",
+ "ErrorGettingTvLineups": "TV dizilimini indirirken bir hata oluştu. Lütfen bilgilerinizin doğru olduğundan emin olun ve tekrar deneyin.",
+ "ErrorDeletingItem": "Öğe Jellyfin Sunucusundan silinirken bir hata oluştu. Lütfen Jellyfin Server'ın medya klasörüne yazma erişimi olup olmadığını kontrol edin ve tekrar deneyin.",
+ "ErrorAddingXmlTvFile": "XmlTV dosyasına erişilirken bir hata oluştu. Lütfen dosyanın var olduğundan emin olun ve tekrar deneyin.",
+ "ErrorAddingTunerDevice": "Tuner cihazı eklenirken bir hata oluştu. Lütfen erişilebilir olduğundan emin olun ve tekrar deneyin.",
+ "ErrorAddingMediaPathToVirtualFolder": "Medya yolu eklenirken bir hata oluştu. Lütfen yolun geçerli olduğundan ve Jellyfin Server işleminin o konuma erişebildiğinden emin olun.",
+ "ErrorAddingListingsToSchedulesDirect": "Dizilişi Schedules Direct hesabınıza eklerken bir hata oluştu. Schedules Direct, hesap başına yalnızca sınırlı sayıda kadroya izin verir. Devam etmeden önce Schedules Direct web sitesine giriş yapmanız ve başka girişleri hesabınızdan kaldırmanız gerekebilir.",
+ "Episodes": "Bölümler",
+ "EndsAtValue": "{0} konumundaki biter",
+ "EnableThemeVideosHelp": "Kitaplığa göz atarken tema videoları arka planda oynatın.",
+ "EnableThemeVideos": "Tema videoları",
+ "EnableThemeSongsHelp": "Kitaplığa göz atarken tema şarkıları arka planda çalın.",
+ "EnableThemeSongs": "Tema şarkıları",
+ "EnableStreamLoopingHelp": "Canlı akışlar yalnızca birkaç saniye veri içeriyorsa ve sürekli istenmesi gerekiyorsa bunu etkinleştirin. Gerekmediğinde bunu etkinleştirmek sorunlara neden olabilir.",
+ "EnableStreamLooping": "Otomatik döngü canlı akışları"
}
diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json
index 3225feba24..eb3e6a8181 100644
--- a/src/strings/zh-cn.json
+++ b/src/strings/zh-cn.json
@@ -2,20 +2,20 @@
"AccessRestrictedTryAgainLater": "访问目前受限。请稍后再试。",
"Actor": "演员",
"Add": "添加",
- "AddItemToCollectionHelp": "通过搜索并使用鼠标右键单击或点击菜单将项目添加到集合中, 将项添加到集合中。",
+ "AddItemToCollectionHelp": "通过搜索并使用鼠标右键单击或点击菜单将项目添加到集合中, 将项目添加到集合中。",
"AddToCollection": "加入收藏",
"AddToPlayQueue": "添加至播放队列",
"AddToPlaylist": "添加到播放列表",
"AddedOnValue": "已添加 {0}",
- "AdditionalNotificationServices": "浏览插件目录安装额外的通知访问。",
+ "AdditionalNotificationServices": "浏览插件目录来安装额外的通知访问服务。",
"AirDate": "播出日期",
"Aired": "已发布",
"Albums": "专辑",
"Alerts": "警告",
"All": "全部",
"AllChannels": "所有频道",
- "AllComplexFormats": "所有复杂的格式(ASS, SSA, VOBSUB, PGS, SUB/IDX 等)",
- "AllEpisodes": "所有集",
+ "AllComplexFormats": "所有高级特效格式字幕(ASS, SSA, VOBSUB, PGS, SUB/IDX 等)",
+ "AllEpisodes": "所有剧集",
"AllLanguages": "所有语言",
"AllLibraries": "所有媒体库",
"AllowHWTranscodingHelp": "允许调谐器即时转码。这可能有助于减少Jellyfin 媒体服务器的转码工作。",
@@ -48,7 +48,7 @@
"Books": "书籍",
"Browse": "浏览",
"BrowsePluginCatalogMessage": "浏览我们的插件目录来查看现有插件。",
- "BurnSubtitlesHelp": "根据字幕格式确定服务器在转换视频时是否应烧录字幕。避免烧录字幕会提高服务器性能。选择“自动”以烧录基于图像的字幕格式(如 VOBSUB, PGS, SUB/IDX 等)和一些复杂的 ASS/SSA 字幕",
+ "BurnSubtitlesHelp": "根据字幕格式确定服务器在转换视频时是否应压制字幕。避免压制字幕会提高服务器性能。选择“自动”以压制基于图像的字幕格式(如 VOBSUB, PGS, SUB/IDX 等)和一些复杂的 ASS/SSA 字幕。",
"ButtonAdd": "添加",
"ButtonAddMediaLibrary": "添加媒体库",
"ButtonAddScheduledTaskTrigger": "添加触发",
@@ -323,7 +323,7 @@
"HeaderFrequentlyPlayed": "多次播放",
"HeaderGenres": "风格",
"HeaderGuideProviders": "电视指南数据提供方",
- "HeaderHttpHeaders": "HTTP 标头",
+ "HeaderHttpHeaders": "HTTP 头部",
"HeaderIdentification": "身份识别",
"HeaderIdentificationCriteriaHelp": "至少输入一个识别标准。",
"HeaderIdentificationHeader": "身份认证标头",
@@ -498,7 +498,7 @@
"LabelBurnSubtitles": "烧录字幕:",
"LabelCache": "缓存:",
"LabelCachePath": "缓存路径:",
- "LabelCachePathHelp": "指定服务器缓存文件的自定义路径,比如图片。留空将使用服务器默认。",
+ "LabelCachePathHelp": "指定服务器缓存文件(如图片)的自定义路径。留空将使用服务器默认。",
"LabelCancelled": "已取消",
"LabelCertificatePassword": "证书密码:",
"LabelCertificatePasswordHelp": "如果你的证书需要密码,请在此输入它。",
@@ -537,7 +537,7 @@
"LabelDisplayOrder": "显示顺序:",
"LabelDisplaySpecialsWithinSeasons": "显示季中所播出的特集",
"LabelDownMixAudioScale": "缩混音频增强:",
- "LabelDownMixAudioScaleHelp": "缩混音频增强。设置为1,将保留原来的音量·。",
+ "LabelDownMixAudioScaleHelp": "缩混音频增强。值为A将保留原来的音量。",
"LabelDownloadLanguages": "下载语言:",
"LabelDropImageHere": "拖拽或点击选择图像于此处。",
"LabelDropShadow": "阴影:",
@@ -585,7 +585,7 @@
"LabelHomeNetworkQuality": "家庭网络质量:",
"LabelHomeScreenSectionValue": "主屏幕模块{0}:",
"LabelHttpsPort": "本地 HTTPS 端口号:",
- "LabelHttpsPortHelp": "Jellyfin HTTPS 服务器监听的 TCP 端口。",
+ "LabelHttpsPortHelp": "Jellyfin HTTPS 服务器监听端口。",
"LabelIconMaxHeight": "图标最大高度:",
"LabelIconMaxHeightHelp": "通过UPnP显示的图标最大分辨率。",
"LabelIconMaxWidth": "图标最大宽度:",
@@ -595,12 +595,12 @@
"LabelImageType": "图片类型:",
"LabelImportOnlyFavoriteChannels": "限制标记频道为我的最爱",
"LabelInNetworkSignInWithEasyPassword": "启用简易PIN码登录家庭网络",
- "LabelInNetworkSignInWithEasyPasswordHelp": "如果启动该选项,你将可以在你的家庭网络中使用你的简易 PIN 码登录 Jellyfin 应用程序。仅在你使用外部网络时才需要输入常规密码。如果 PIN 码留空,那么在你的家庭网络中,你将不需要输入密码。",
+ "LabelInNetworkSignInWithEasyPasswordHelp": "在你的本地网络中使用简易 PIN 码登录客户端,如果 PIN 码留空,那么在本地网络中则不需要输入密码。外部网络中需要输入常规密码登陆。",
"LabelInternetQuality": "网络质量:",
"LabelKidsCategories": "儿童分类:",
"LabelKodiMetadataDateFormat": "发行日期格式:",
"LabelKodiMetadataDateFormatHelp": "Nfo的所有日期将使用这种格式。",
- "LabelKodiMetadataEnableExtraThumbs": "复制同人画到extrathumbs文件夹",
+ "LabelKodiMetadataEnableExtraThumbs": "复制同人画到extrathumbs目录",
"LabelKodiMetadataEnableExtraThumbsHelp": "为了最大化兼容Kodi皮肤,下载的图片同时保存在 extrafanart 和 extrathumbs 文件夹。",
"LabelKodiMetadataEnablePathSubstitution": "启用路径替换",
"LabelKodiMetadataEnablePathSubstitutionHelp": "允许图像的路径替换使用服务器的路径替换设置。",
@@ -724,7 +724,7 @@
"LabelSerialNumber": "序列号",
"LabelSeriesRecordingPath": "电视剧录制路径 (可选的):",
"LabelServerHost": "主机:",
- "LabelServerHostHelp": "192.168.1.100 或 https://myserver.com",
+ "LabelServerHostHelp": "192.168.1.100:8096 或 https://myserver.com",
"LabelSimultaneousConnectionLimit": "并发流限制:",
"LabelSkin": "皮肤:",
"LabelSkipBackLength": "跳过长度:",
@@ -764,7 +764,7 @@
"LabelTrackNumber": "音轨号码:",
"LabelTranscodingAudioCodec": "音频编解码器:",
"LabelTranscodingContainer": "容器:",
- "LabelTranscodingTempPathHelp": "此文件夹包含用于转码的工作文件。请自定义路径,或留空以使用默认的服务器数据文件夹。",
+ "LabelTranscodingTempPathHelp": "设置转码文件存储目录。留空以使用服务器默认文件夹。",
"LabelTranscodingThreadCount": "转码线程数:",
"LabelTranscodingThreadCountHelp": "选择转码时使用的最大线程数。\n减少线程数量将会降低CPU使用率,可能无法快速进行转换并流畅的播放。",
"LabelTranscodingVideoCodec": "视频编解码器:",
@@ -779,7 +779,7 @@
"LabelUserAgent": "用户代理:",
"LabelUserLibrary": "用户程序库:",
"LabelUserLibraryHelp": "选择一个在设备上显示的用户媒体库。留空则使用默认设置。",
- "LabelUserRemoteClientBitrateLimitHelp": "这将会覆盖服务器“播放”设置中为全局设置的默认值。",
+ "LabelUserRemoteClientBitrateLimitHelp": "覆盖服务器“播放”设置的全局默认值。",
"LabelUsername": "用户名:",
"LabelVaapiDevice": "VA API 设备:",
"LabelVaapiDeviceHelp": "此渲染节点用来硬件加速。",
@@ -801,7 +801,7 @@
"Large": "大",
"LatestFromLibrary": "最新的{0}",
"LearnHowYouCanContribute": "学习如何构建。",
- "LibraryAccessHelp": "选择共享给此用户的媒体文件夹。管理员能使用媒体资料管理器来编辑所有文件夹。",
+ "LibraryAccessHelp": "选择共享给此用户的媒体库。管理员有权使用媒体资料管理器来编辑所有文件夹。",
"Like": "喜欢",
"List": "列表",
"Live": "直播",
@@ -845,20 +845,20 @@
"MessageConfirmRemoveMediaLocation": "你确定要移除此位置?",
"MessageConfirmRestart": "你确定要重启 Jellyfin 服务端?",
"MessageConfirmRevokeApiKey": "你确定你希望撤销这个 API 秘钥吗?这个应用程序与 Jellyfin 服务器的连接将会被立刻中断。",
- "MessageConfirmShutdown": "你确定要关闭 Jellyfin 服务端?",
+ "MessageConfirmShutdown": "你确定要关闭服务端?",
"MessageContactAdminToResetPassword": "请联系你的管理员以重置你的密码。",
"MessageCreateAccountAt": "在 {0} 创建帐户",
"MessageDeleteTaskTrigger": "你确定删除这个任务触发条件?",
"MessageDirectoryPickerBSDInstruction": "对于 BSD 系统,你需要设置包含你的 FreeNAS Jail 虚拟机的存储以允许 Jellyfin 访问它。",
"MessageDirectoryPickerInstruction": "网络按钮无法找到你的设备的情况下,网络路径可以手动输入。 例如, {0} 或者 {1}。",
- "MessageDirectoryPickerLinuxInstruction": "对于 Arch Linux 上的 Linux 或是 CentOS、Debian、Fedora、OpenSuse、Ubuntu 这些系统,你必须授权 Jellyfin 系统用户至少拥有你存储位置的读取权限。",
+ "MessageDirectoryPickerLinuxInstruction": "对于 Arch Linux 上的 Linux 或是 CentOS、Debian、Fedora、OpenSuse、Ubuntu 这些系统,你必须授权系统服务用户访问你存储位置的权限。",
"MessageDownloadQueued": "下载已列队。",
"MessageEnablingOptionLongerScans": "启用此选项可能会大大延长媒体库扫描时间。",
"MessageFileReadError": "读取文件发生错误。",
"MessageForgotPasswordFileCreated": "已在服务器上创建了以下文件, 并包含有关后续步骤说明:",
"MessageForgotPasswordInNetworkRequired": "请连接你的家庭网络后再试一次以开始密码重置流程。",
"MessageInstallPluginFromApp": "这个插件必须从你打算使用的应用程序中安装。",
- "MessageInvalidForgotPasswordPin": "你输入了一个无效的或过期的 pin 码。请再试一次。",
+ "MessageInvalidForgotPasswordPin": "无效的或过期的 pin 码。请再试一次。",
"MessageInvalidUser": "用户名或密码不可用。请重试。",
"MessageItemSaved": "项目已保存。",
"MessageItemsAdded": "项目已添加。",
@@ -868,14 +868,14 @@
"MessageNoPluginsInstalled": "你没有安装插件。",
"MessageNoTrailersFound": "未发现任何预告片。安装 Trailer channel 以通过添加一个网络预告片媒体库来增强你的电影体验。",
"MessageNothingHere": "这里没有可显示的内容。",
- "MessagePasswordResetForUsers": "下列用户的密码已重置。现在,可使用重置时的 PIN 码进行登录。",
+ "MessagePasswordResetForUsers": "下列用户的密码已被重置。他们现在可以用执行复位的pin码登录。",
"MessagePleaseEnsureInternetMetadata": "请确认已启用从网络上下载媒体资料的选项。",
"MessagePleaseWait": "请稍等。这将花费大约1分钟的时间。",
"MessagePluginConfigurationRequiresLocalAccess": "请直接登录你的本地服务器以设置这个插件。",
"MessagePluginInstallDisclaimer": "安装 Jellyfin 社区成员构建的插件来获取额外的功能是增强你的 Jellyfin 体验的一种很好的方式。但在安装之前请意识到他们可能会对你的 Jellyfin 服务器造成的影响,如更长的媒体库扫描时间、额外的背景数据加工、降低系统稳定性等。",
"MessageReenableUser": "请参阅以下以重新启用",
"MessageSettingsSaved": "设置已保存。",
- "MessageTheFollowingLocationWillBeRemovedFromLibrary": "以下媒体路径将从你的 Jellyfin 媒体库移除:",
+ "MessageTheFollowingLocationWillBeRemovedFromLibrary": "以下媒体路径将从你的媒体库移除:",
"MessageUnableToConnectToServer": "现在无法连接所选择的服务器,请确保该服务器目前正在运行。",
"MessageUnsetContentHelp": "内容将显示为纯文件夹。为取得最佳效果, 请使用元数据管理器设置子文件夹的内容类型。",
"MessageYouHaveVersionInstalled": "你目前安装了 {0} 版本。",
@@ -884,13 +884,13 @@
"MetadataSettingChangeHelp": "更改元数据设置将影响添加的新内容。要刷新现有内容, 请打开详细信息屏幕并单击 \"刷新\" 按钮, 或使用元数据管理器执行批量刷新。",
"MinutesAfter": "分钟后",
"MinutesBefore": "分钟前",
- "Mobile": "手机/平板",
+ "Mobile": "移动设备",
"Monday": "星期一",
"MoreFromValue": "更多来自 {0}",
"MoreUsersCanBeAddedLater": "稍后可以在控制台中添加更多用户。",
"MoveLeft": "左移",
"MoveRight": "右移",
- "MovieLibraryHelp": "回顾{0}Jellyfin 电影命名指南{1}。",
+ "MovieLibraryHelp": "回顾{0}电影命名指南{1}。",
"Movies": "电影",
"Mute": "静音",
"MySubtitles": "我的字幕",
@@ -917,7 +917,7 @@
"OneChannel": "一个频道",
"OnlyForcedSubtitles": "只显示强制字幕",
"OnlyForcedSubtitlesHelp": "只有被标记为“强制”的字幕会被加载。",
- "OnlyImageFormats": "仅图像格式(VOBSUB, PGS, SUB/IDX 等)",
+ "OnlyImageFormats": "仅图像格式(VOBSUB, PGS, SUB等)",
"OptionAdminUsers": "管理员",
"OptionAlbum": "专辑",
"OptionAlbumArtist": "专辑艺术家",
@@ -932,7 +932,7 @@
"OptionAllowMediaPlaybackTranscodingHelp": "由于不支持的媒体格式, 限制对代码转换的访问可能会导致 Jellyfin 应用程序中的播放失败。",
"OptionAllowRemoteControlOthers": "允许其他用户全程控制",
"OptionAllowRemoteSharedDevices": "允许远程控制共享的设备",
- "OptionAllowRemoteSharedDevicesHelp": "DLNA 在有用户对它进行控制前设备被视为是共享的。",
+ "OptionAllowRemoteSharedDevicesHelp": "DLNA 设备在用户对他们进行控制前都被视为是共享的。",
"OptionAllowSyncTranscoding": "允许需要转码的媒体下载和同步",
"OptionAllowUserToManageServer": "运行此用户管理服务器",
"OptionAllowVideoPlaybackRemuxing": "允许播放需转换但无需重新编码的视频",
@@ -966,7 +966,7 @@
"OptionDisableUserHelp": "如果禁用该用户,服务器将不允许该用户连接。现有的连接将被终止。",
"OptionDislikes": "不喜欢",
"OptionDisplayFolderView": "显示一个“文件夹”类别用于按文件夹分类浏览你的媒体文件夹",
- "OptionDisplayFolderViewHelp": "如果启用此项,Jellyfin 应用程序将在你的媒体库列表中显示一个“文件夹”类别。如果你有按文件夹分类进行浏览的需求,这个功能将是有帮助的。",
+ "OptionDisplayFolderViewHelp": "在你的媒体库列表中显示文件夹。如果你有按文件夹分类进行浏览的需求,这会非常有用。",
"OptionDownloadArtImage": "艺术图",
"OptionDownloadBackImage": "包装背面",
"OptionDownloadBannerImage": "横幅",
@@ -1149,7 +1149,7 @@
"ServerNameIsRestarting": "Jellyfin Server - {0} 重启中。",
"ServerNameIsShuttingDown": "Jellyfin 服务器 - {0} 正在关闭。",
"ServerRestartNeededAfterPluginInstall": "安装插件后,Jellyfin 服务器需要重启以使插件生效。",
- "ServerUpdateNeeded": "Jellyfin 服务器需要更新,请访问 {0} 以下载最新的版本。",
+ "ServerUpdateNeeded": "Jellyfin 服务器需要更新,请访问 {0} 以下载最新的版本",
"Settings": "设置",
"SettingsSaved": "设置已保存。",
"SettingsWarning": "更改这些值可能会导致不稳定或连接故障。如果您遇到任何问题, 我们建议将它们重新更改为默认值。",
@@ -1356,13 +1356,13 @@
"LabelPasswordResetProvider": "密码重置提供者:",
"LabelPersonRoleHelp": "示例:冰淇淋卡车司机",
"LabelSelectFolderGroups": "自动将下列文件夹中的内容分组到视图中,如电影、音乐、剧集:",
- "LabelSelectFolderGroupsHelp": "未选中的文件夹将显示在自身的视图中",
+ "LabelSelectFolderGroupsHelp": "未选中的文件夹将显示在自身的视图中。",
"LabelUserLoginAttemptsBeforeLockout": "用户被封禁前可尝试的次数:",
"DashboardVersionNumber": "版本:{0}",
"DashboardServerName": "服务器:{0}",
"LabelVideo": "视频:",
"LabelWeb": "网站: ",
- "LeaveBlankToNotSetAPassword": "可选 - 留空以设置无密码",
+ "LeaveBlankToNotSetAPassword": "您可以将此字段留空以设置空密码。",
"LinksValue": "链接:{0}",
"LiveBroadcasts": "直播",
"LiveTV": "电视直播",
@@ -1378,12 +1378,12 @@
"MessageImageFileTypeAllowed": "只支持JPEG和PNG格式的文件。",
"MessageImageTypeNotSelected": "请在下拉菜单中选择图片类型。",
"MessageNoCollectionsAvailable": "分组能够让您享受个性化的视频、剧集和专辑组。点击+按钮开始创建分组。",
- "MessagePlayAccessRestricted": "当前内容无法回放。请联系Jellyfin服务器管理员获取更多信息。",
+ "MessagePlayAccessRestricted": "当前内容无法回放。请联系服务器管理员获取更多信息。",
"Off": "关闭",
"Option3D": "三维",
"OptionDownloadLogoImage": "标志",
"OptionLoginAttemptsBeforeLockout": "确定在锁定之前可以进行多少次不正确的登录尝试。",
- "OptionLoginAttemptsBeforeLockoutHelp": "0 表示默认设置(非管理员 3 次,管理员 5 次),-1 表示不限制次数",
+ "OptionLoginAttemptsBeforeLockoutHelp": "如果值为0,则表示将允许普通用户尝试三次、管理员尝试五次的默认值。将此设置为-1将禁用此功能。",
"PasswordResetProviderHelp": "选择一个密码重置提供者用于密码重置",
"PlaceFavoriteChannelsAtBeginning": "将最喜爱的频道置顶",
"PlayNext": "播放下一个",
@@ -1402,13 +1402,13 @@
"ShowIndicatorsFor": "显示指标:",
"ShowYear": "显示年份",
"Shows": "节目",
- "SkipEpisodesAlreadyInMyLibraryHelp": "将使用季节和剧集编号对剧集进行比较。",
+ "SkipEpisodesAlreadyInMyLibraryHelp": "将使用季和剧集编号对剧集进行比较。",
"Smaller": "更小",
"StatsForNerds": "统计数据",
"SubtitleSettings": "字幕设置",
"SubtitleSettingsIntro": "要配置默认字幕外观和语言设置,请停止视频播放,然后单击应用程序右上角的用户图标。",
"TagsValue": "标签:{0}",
- "Vertical": "垂直的",
+ "Vertical": "垂直",
"VideoRange": "视频范围",
"Depressed": "凹陷",
"Uniform": "轮廓",
@@ -1416,8 +1416,8 @@
"DashboardOperatingSystem": "操作系统:{0}",
"DashboardArchitecture": "架构:{0}",
"GroupVersions": "按版本分组",
- "LaunchWebAppOnStartup": "当 Jellyfin 服务器启动时,在我的 Web 浏览器中打开 Jellyfin Web 应用程序",
- "LaunchWebAppOnStartupHelp": "这个插件已经被成功安装。Jellyfin 服务器需要重启以使该插件生效。",
+ "LaunchWebAppOnStartup": "当启动服务器时,打开Web界面",
+ "LaunchWebAppOnStartupHelp": "这个插件已经被成功安装。 服务器需要重启以使该插件生效。",
"MusicAlbum": "音乐专辑",
"MusicArtist": "音乐艺术家",
"MusicVideo": "音乐视频",
diff --git a/src/strings/zh-tw.json b/src/strings/zh-tw.json
index dc85b350b8..7b428ad51a 100644
--- a/src/strings/zh-tw.json
+++ b/src/strings/zh-tw.json
@@ -1,12 +1,12 @@
{
- "Add": "添加",
+ "Add": "新增",
"All": "全部",
"AllowRemoteAccessHelp": "如果未勾選,所有連線都將被阻擋。",
"Browse": "瀏覽",
- "BrowsePluginCatalogMessage": "瀏覽我們的插件目錄來查看可用的插件。",
- "ButtonAdd": "添加",
+ "BrowsePluginCatalogMessage": "瀏覽我們的插件目錄來查看可用的模組。",
+ "ButtonAdd": "新增",
"ButtonAddServer": "新增伺服器",
- "ButtonAddUser": "添加使用者",
+ "ButtonAddUser": "新增使用者",
"ButtonCancel": "取消",
"ButtonDelete": "刪除",
"ButtonDeleteImage": "刪除圖像",
@@ -29,17 +29,17 @@
"ButtonSearch": "搜尋",
"ButtonSelectDirectory": "選擇目錄",
"ButtonSelectServer": "選擇伺服器",
- "ButtonSignIn": "登錄",
+ "ButtonSignIn": "登入",
"ButtonSignOut": "登出",
"ButtonSort": "排序",
"ConfirmDeleteItem": "刪除此項目時,也會一併從檔案系統及媒體櫃中刪除。確定要刪除嗎?",
"ConfirmDeletion": "確定刪除",
"Continuing": "持續",
- "CustomDlnaProfilesHelp": "為新的設備創建自定義配置或覆蓋原有系統配置。",
+ "CustomDlnaProfilesHelp": "為新的設備新增自訂設定檔或覆蓋原有系統設定。",
"Delete": "刪除",
"DeleteImage": "刪除圖像",
"DeleteImageConfirmation": "你確定要刪除這張圖像?",
- "DeleteUser": "刪除用戶",
+ "DeleteUser": "刪除使用者",
"Dislike": "不喜歡",
"Download": "下載",
"Edit": "編輯",
@@ -63,7 +63,7 @@
"HeaderAutomaticUpdates": "自動更新",
"HeaderCastCrew": "拍攝人員及演員",
"HeaderChannels": "頻道",
- "HeaderCustomDlnaProfiles": "自定義配置",
+ "HeaderCustomDlnaProfiles": "自訂設定檔",
"HeaderDeleteItem": "刪除項目",
"HeaderEasyPinCode": "簡易 PIN 碼",
"HeaderFeatureAccess": "可以使用的功能",
@@ -81,8 +81,8 @@
"HeaderLinks": "鏈接",
"HeaderLiveTV": "電視直播",
"HeaderLiveTv": "電視",
- "HeaderMediaFolders": "媒體文件夾",
- "HeaderMusicVideos": "音樂視頻",
+ "HeaderMediaFolders": "媒體資料夾",
+ "HeaderMusicVideos": "MV",
"HeaderNewRecording": "新錄製",
"HeaderNewUsers": "新使用者",
"HeaderNextUp": "接下來",
@@ -90,7 +90,7 @@
"HeaderParentalRating": "Parental Rating",
"HeaderPaths": "路徑",
"HeaderPlayAll": "全部播放",
- "HeaderPleaseSignIn": "請登錄",
+ "HeaderPleaseSignIn": "請登入",
"HeaderPreferredMetadataLanguage": "首選媒體資料語言",
"HeaderRecentlyPlayed": "最近播放",
"HeaderScenes": "場景",
@@ -99,12 +99,12 @@
"HeaderSeries": "系列",
"HeaderSpecialFeatures": "特色",
"HeaderStatus": "狀態",
- "HeaderSystemDlnaProfiles": "系統配置",
+ "HeaderSystemDlnaProfiles": "系統設定",
"HeaderUsers": "使用者",
"Help": "說明",
"ItemCount": "{0}個項目",
"LabelAllowServerAutoRestart": "允許伺服器自動重新啟動去安裝更新資料",
- "LabelAllowServerAutoRestartHelp": "伺服器只會在沒有活躍用戶及空閒期間重新啟動。",
+ "LabelAllowServerAutoRestartHelp": "伺服器只會在沒有使用者在使用時重新啟動。",
"LabelAudioLanguagePreference": "音頻語言偏好選項:",
"LabelCachePath": "緩存路徑:",
"LabelCollection": "收藏櫃:",
@@ -114,27 +114,27 @@
"LabelDay": "日:",
"LabelDisplayMissingEpisodesWithinSeasons": "顯示節目季度內缺少的單元",
"LabelEnableDlnaClientDiscoveryInterval": "尋找客戶端時間間隔(秒)",
- "LabelEnableDlnaDebugLogging": "記錄DLNA除錯信息到日誌",
- "LabelEnableDlnaDebugLoggingHelp": "這將創建一個非常大的日誌文件,建議只需要進行故障排除時啟動。",
+ "LabelEnableDlnaDebugLogging": "記錄 DLNA 除錯資料到日誌",
+ "LabelEnableDlnaDebugLoggingHelp": "將會建立非常大的日誌檔案,建議在進行故障排除時啟用。",
"LabelEnableDlnaPlayTo": "播放到DLNA設備",
"LabelEnableRealtimeMonitor": "啟用實時監控",
- "LabelEnableRealtimeMonitorHelp": "支持的文件系統上的更改,將會立即處理。",
+ "LabelEnableRealtimeMonitorHelp": "支持的檔案系統上的更改,將會立即處理。",
"LabelEvent": "事件:",
"LabelEveryXMinutes": "每:",
"LabelFinish": "完成",
- "LabelServerNameHelp": "此名稱將用於標識伺服器。如果留空,計算機名稱將被使用。",
+ "LabelServerNameHelp": "名稱將用於辨識服務器,預設是伺服器的電腦名稱。",
"LabelLanguage": "語言:",
"LabelMaxBackdropsPerItem": "每個項目背景的最大數目:",
"LabelMaxParentalRating": "最大允許的家長評級:",
- "LabelMaxResumePercentage": "最大恢復播放百分比:",
- "LabelMaxResumePercentageHelp": "媒體如果在這個時間之後停止,會被認定為已播放",
+ "LabelMaxResumePercentage": "最大繼續播放百分比:",
+ "LabelMaxResumePercentageHelp": "媒體若於該時間後停止,會被認定為已播放。",
"LabelMaxScreenshotsPerItem": "每件物品截圖的最大數量:",
- "LabelMetadataPath": "媒體資料文件夾路徑:",
+ "LabelMetadataPath": "中繼資料資料夾路徑:",
"LabelMinBackdropDownloadWidth": "最小背景下載寬度:",
- "LabelMinResumeDuration": "最少恢復播放時間(秒):",
- "LabelMinResumeDurationHelp": "媒體比這更短不可恢復播放",
- "LabelMinResumePercentage": "最低恢復播放百分比:",
- "LabelMinResumePercentageHelp": "媒體如果在這個時間之前停止,會被定為未播放",
+ "LabelMinResumeDuration": "最小繼續播放時間:",
+ "LabelMinResumeDurationHelp": "以秒為單位的最短影片長度,它將保存播放位置並讓您繼續播放。",
+ "LabelMinResumePercentage": "最低繼續播放百分比:",
+ "LabelMinResumePercentageHelp": "媒體如果在這個時間之前停止,會被認定為未播放。",
"LabelMinScreenshotDownloadWidth": "最小截圖下載寬度:",
"LabelName": "名字:",
"LabelNewPassword": "新密碼:",
@@ -145,24 +145,24 @@
"LabelPrevious": "上一個",
"LabelRefreshMode": "更新模式:",
"LabelSaveLocalMetadata": "將媒體圖像及資料檔存到媒體所在的資料夾",
- "LabelSaveLocalMetadataHelp": "直接保存媒體圖像及資料到媒體所在的文件夾能使編輯工作更容易。",
+ "LabelSaveLocalMetadataHelp": "直接儲存圖片及資料到媒體所在的資料夾能使編輯更容易。",
"LabelTime": "時間:",
"LabelTriggerType": "觸發類型:",
"LabelUser": "使用者:",
"LabelYourFirstName": "你的名字:",
"LabelYoureDone": "完成!",
- "LibraryAccessHelp": "選擇媒體文件夾與這用戶共享。管理員將可以使用媒體資料據管理器編輯所有的媒體文件夾。",
+ "LibraryAccessHelp": "選擇媒體資料夾與此使用者共享。管理員將可以使用中繼資料管理器編輯所有的媒體資料夾。",
"Like": "喜歡",
- "MaxParentalRatingHelp": "具有較高的家長評級內容將從這用戶被隱藏。",
+ "MaxParentalRatingHelp": "具有較高的家長評級內容將從這使用者被隱藏。",
"MessageAreYouSureDeleteSubtitles": "您真的要刪除這個字幕檔嗎?",
"MessageDownloadQueued": "下載已排程。",
"MessageItemsAdded": "已新增項目。",
"MessageNoMovieSuggestionsAvailable": "目前並沒有推薦的電影。開始觀看並對您的電影評分後,我們就會為您推薦您可能會喜歡的內容。",
"MessageNothingHere": "這裡沒有什麼。",
- "MessagePasswordResetForUsers": "下列使用者的密碼已被重新設置。從現時起,該使用者可以使用在密碼重置時所使用之 PIN 代碼進行登入。",
+ "MessagePasswordResetForUsers": "下列使用者的密碼已被重新設置。該使用者現在可以使用在密碼重置時所使用之 PIN 代碼進行登入。",
"MessagePleaseEnsureInternetMetadata": "請確保已啟用從互聯網下載媒體資料。",
"Monday": "星期一",
- "MoreUsersCanBeAddedLater": "往後可以在控制台內添加更多用戶。",
+ "MoreUsersCanBeAddedLater": "也可於控制台內新增使用者。",
"MySubtitles": "我的字幕",
"NewCollection": "新合集",
"NewCollectionHelp": "收藏櫃讓您能夠建立個人化的影音及其他媒體的分類。",
@@ -173,7 +173,7 @@
"OptionAlbumArtist": "專輯歌手",
"OptionAllowBrowsingLiveTv": "允許使用電視",
"OptionAllowManageLiveTv": "允許管理電視節目錄影",
- "OptionAllowUserToManageServer": "允許這用戶管理伺服器",
+ "OptionAllowUserToManageServer": "允許該使用者管理伺服器",
"OptionArtist": "歌手",
"OptionAscending": "升序",
"OptionAutomatic": "自動",
@@ -183,11 +183,11 @@
"OptionContinuing": "持續",
"OptionCriticRating": "評論家評價",
"OptionDaily": "每日",
- "OptionDateAdded": "添加日期",
+ "OptionDateAdded": "新增日期",
"OptionDatePlayed": "播放日期",
"OptionDescending": "降序",
- "OptionDisableUser": "禁用此用戶",
- "OptionDisableUserHelp": "被禁用的用戶將不允許連接伺服器。現有的連接將被即時終止。",
+ "OptionDisableUser": "停用該使用者",
+ "OptionDisableUserHelp": "被停用的使用者將被伺服器封鎖,即便正處於連線狀態也將被中斷。",
"OptionDislikes": "不喜歡",
"OptionDownloadArtImage": "圖像",
"OptionDownloadBackImage": "媒體包裝背面",
@@ -203,7 +203,7 @@
"OptionFriday": "星期五",
"OptionHasSubtitles": "字幕",
"OptionHasThemeSong": "主題曲",
- "OptionHasThemeVideo": "主題視頻",
+ "OptionHasThemeVideo": "主題影片",
"OptionHideUser": "在登入頁面隱藏此使用者",
"OptionImdbRating": "IMDB評分",
"OptionIsHD": "高清",
@@ -279,15 +279,15 @@
"TabNetworks": "網絡",
"TabPassword": "密碼",
"TabPlaylist": "播放清單",
- "TabProfile": "配置",
- "TabProfiles": "配置",
+ "TabProfile": "設定",
+ "TabProfiles": "設定",
"TabRecordings": "錄影",
"TabSeries": "電視劇",
"TabServer": "伺服器",
"TabSettings": "設定",
"TabShows": "節目",
"TabSongs": "歌曲",
- "TabSuggestions": "推薦內容",
+ "TabSuggestions": "建議",
"TabTrailers": "預告",
"TabTranscoding": "轉碼中",
"TabUpcoming": "接下來",
@@ -298,12 +298,12 @@
"Tuesday": "星期二",
"UninstallPluginConfirmation": "你確定要卸載{0}?",
"UninstallPluginHeader": "卸載插件",
- "UserProfilesIntro": "Jellyfin 包含對用戶配置文件的內置支持,使每個用戶都可以擁有自己的顯示設置,播放狀態和家長控制。",
+ "UserProfilesIntro": "Jellyfin 可單獨對使用者進行設定,所有使用者擁有自己的顯示設置,播放狀態和家長控制。",
"Users": "使用者",
"VersionNumber": "版本 {0}",
"Wednesday": "星期三",
"WelcomeToProject": "歡迎使用 Jellyfin!",
- "WizardCompleted": "這就是我們所需要的全部資訊,Jellyfin現在正在收集你的媒體櫃的資料,在這段時間內,不妨參考我們推出的應用程式。按一下
完成 進入
伺服器總覽頁 。",
+ "WizardCompleted": "這就是我們所需的全部資訊,Jellyfin 現在正在收集你的媒體櫃的資料,在這段時間內,不妨參考我們推出的應用程式。按一下
完成 進入
伺服器總覽頁 。",
"Actor": "演員",
"AddToPlayQueue": "加入播放清單",
"AddToPlaylist": "加入播放列表",
@@ -350,19 +350,19 @@
"ButtonAudioTracks": "音軌",
"ButtonBack": "回去",
"ButtonChangeServer": "更換伺服器",
- "AddItemToCollectionHelp": "利用搜尋並使用右鍵或點擊目錄將項目添加到收藏中。",
+ "AddItemToCollectionHelp": "利用搜尋並使用右鍵或點擊目錄將項目新增到收藏中。",
"AddToCollection": "加入收藏",
"AirDate": "播出日期",
"Aired": "已播於",
"AllEpisodes": "所有集數",
- "AllowHWTranscodingHelp": "若啟用,將會允許調諧器同步轉檔,這會減少Jellyfin伺服器轉檔必要。",
+ "AllowHWTranscodingHelp": "若啟用,將會允許調諧器同步轉檔,這會減少 Jellyfin 伺服器轉檔必要。",
"AllowOnTheFlySubtitleExtraction": "允許同步字幕截取",
- "AllowOnTheFlySubtitleExtractionHelp": "可以從影片中提取內建字幕並以純文字的形式給 Jellyfin 應用程式以避免影片轉碼。在某些系統中這個提取的進程可能會花費較長時間並導致視頻播放出現停滯。若禁用這個選項,當內置字幕不被播放端設備支援時,字幕將透過影片轉碼燒進影片中。",
+ "AllowOnTheFlySubtitleExtractionHelp": "可以從影片中提取內建字幕並以純文字的形式給 Jellyfin 應用程式以避免影片轉碼。在某些系統中這個提取的進程可能會花費較長時間並導致影片播放出現停滯。若停用這個選項,當內置字幕不被播放端設備支援時,字幕將透過影片轉碼燒進影片中。",
"AllowedRemoteAddressesHelp": "可以從非本地連線的IP位址,用冒號分隔,若留白,則允許所有IP。",
- "BookLibraryHelp": "支援有聲書和電子書。請瀏覽Jellyfin書籍命名指南。",
+ "BookLibraryHelp": "支援有聲書和電子書。請瀏覽 Jellyfin 書籍命名指南。",
"Box": "盒子",
"BoxRear": "盒子(背面)",
- "BurnSubtitlesHelp": "根據字幕格式決定服務器在轉換視頻時是否燒錄字幕。避免燒錄字幕會提高服務器性能。選擇“自動”以燒錄基於圖像的字幕格式(如 VOBSUB, PGS, SUB/IDX 等)和一些複雜的 ASS/SSA 字幕。",
+ "BurnSubtitlesHelp": "根據字幕格式決定伺服器在轉換影片時是否燒錄字幕。避免燒錄字幕會提高伺服器性能。選擇「自動」以燒錄基於圖片的字幕格式(如 VOBSUB, PGS, SUB/IDX 等)和一些複雜的 ASS/SSA 字幕。",
"ButtonArrowDown": "下",
"ButtonConnect": "連結",
"ButtonDown": "下",
@@ -407,8 +407,8 @@
"CancelRecording": "取消錄影",
"CancelSeries": "取消系列",
"Categories": "類別",
- "ChangingMetadataImageSettingsNewContent": "更改影片詳細資料或媒體圖像像的下載設定僅對以後添加至媒體庫中的新内容生效,若要採用更改,您需要手動刷新數據。",
- "ChannelAccessHelp": "選擇此用戶之共享頻道。管理員將能夠使用資料管理器編輯所有資料夾。",
+ "ChangingMetadataImageSettingsNewContent": "更改影片詳細資料或媒體圖像像的下載設定僅對以後添加至媒體庫中的新内容生效,若要更改已存在的資料,您需要手動更新中繼資料。",
+ "ChannelAccessHelp": "選擇此使用者之共享頻道。管理員將能夠使用資料管理器編輯所有資料夾。",
"ChannelNameOnly": "只在頻道 {0}",
"ChannelNumber": "頻道號碼",
"Channels": "頻道",
@@ -418,14 +418,14 @@
"CloudSyncFeatureDescription": "將您的媒體備份到雲端當作簡單的備份,收藏和轉檔。",
"Collections": "合輯",
"Composer": "作曲家",
- "ConfigureDateAdded": "調整媒體庫設定裡 伺服器怎麼判定「添加日期」",
+ "ConfigureDateAdded": "調整伺服器怎麼判定媒體褲的「新增日期」",
"ConfirmDeleteImage": "刪除圖片?",
"ConfirmDeleteItems": "刪除這些項目會將檔案從系統和媒體庫中刪除。你真的要繼續嗎?",
"ConfirmEndPlayerSession": "您要在 {0} 秒後將 Jellyfin關機嗎?",
"Connect": "連結",
"ContinueWatching": "繼續觀看",
"CriticRating": "影評評分",
- "DateAdded": "添加日期",
+ "DateAdded": "新增日期",
"DatePlayed": "播放日期",
"DeathDateValue": "死於: {0}",
"Default": "預設",
@@ -437,20 +437,20 @@
"CommunityRating": "公眾評分",
"DefaultCameraUploadPathHelp": "請選擇自訂上傳路徑。若留白, 將會使用預設資料夾。如果使用自訂路徑,則還需要在Jellyfin庫設置中作為“媒體庫”添加。",
"DefaultErrorMessage": "處理請求時發生錯誤。請稍後再試。",
- "DefaultMetadataLangaugeDescription": "這些是你的默認設定並可以在你的每個媒體庫中單獨設定。",
- "DefaultSubtitlesHelp": "字幕將基於內建數據中的“默認”標題和“強制”標題來載入。當有多個選項可用時,將根據語言偏好決定。",
- "DeleteDeviceConfirmation": "你確定你要刪除這個裝置嗎?當下一次有用戶用這個裝置登入時,這個裝置會再次出現。",
+ "DefaultMetadataLangaugeDescription": "這些預設設定可以在你的媒體庫中單獨設定。",
+ "DefaultSubtitlesHelp": "字幕將基於內建資料中的「預設」標記和「強制」標記來載入,當有多個選項可用時,將根據語言偏好決定。",
+ "DeleteDeviceConfirmation": "你確定你要刪除這個裝置嗎?當有使用者用這個裝置登入時,這個裝置會再次出現。",
"DeleteMedia": "刪除媒體",
- "DeleteUserConfirmation": "你確定要刪除此用戶?",
+ "DeleteUserConfirmation": "你確定要刪除此使用者?",
"Descending": "降序",
"Desktop": "桌面",
"DetectingDevices": "正在偵測裝置",
- "DeviceAccessHelp": "只適用於用唯一辨識方法的裝置,並不會阻止瀏覽器存取。已過濾的用戶裝置會被拒絕存取,直到他們被批准。",
+ "DeviceAccessHelp": "只適用於用唯一辨識方法的裝置,並不會阻止瀏覽器存取。已過濾的使用者裝置會被拒絕存取,直到他們被批准。",
"DeviceLastUsedByUserName": "最後被 {0} 使用",
"DirectPlayError": "直接播放錯誤",
"DirectPlaying": "直接播放",
- "DirectStreamHelp1": "媒體在畫質和媒體類型(H.264,AC3等)方面與裝置相容,但是在不相容的容器(.mkv,.avi,.wmv等)中。 在影片傳輸到裝置之前,將會重新包裝。",
- "DirectStreamHelp2": "直接串流一個文件就會占用非常少的處理效能並且影片的品質不會有任何損失。",
+ "DirectStreamHelp1": "媒體在畫質和媒體類型(H.264,AC3等)方面與裝置相容。但是在不相容的檔案格式(.mkv,.avi,.wmv等)中,在影片傳輸到裝置之前,將會重新轉檔。",
+ "DirectStreamHelp2": "直接串流檔案會占用非常少的處理效能並且影片的品質不會有任何損失。",
"DirectStreaming": "直接串流",
"Director": "導演",
"DirectorValue": "導演: {0}",
@@ -462,7 +462,7 @@
"DisplayInMyMedia": "在主畫面顯示",
"DisplayInOtherHomeScreenSections": "在“最新媒體”和“繼續觀看“等主畫面區塊中顯示",
"DisplayMissingEpisodesWithinSeasons": "顯示每季缺少的劇集",
- "DisplayMissingEpisodesWithinSeasonsHelp": "必須在 Jellyfin 伺服器的 電視媒體庫設置中啟用該功能。",
+ "DisplayMissingEpisodesWithinSeasonsHelp": "必須在 Jellyfin 伺服器的電視媒體庫設定中啟用該功能。",
"DisplayModeHelp": "選擇您正在運行Jellyfin的螢幕類型。",
"DoNotRecord": "不要錄",
"Down": "下",
@@ -475,59 +475,59 @@
"DrmChannelsNotImported": "受 DMR 保護的頻道將不會被導入。",
"DropShadow": "背景投影",
"DvrFeatureDescription": "使用Jellyfin DVR安排個人直播電視錄製,系列錄製等。",
- "EasyPasswordHelp": "你的簡易 PIN 碼將會用於在支援的 Jellyfin 應用 上進行離線存取,同時也可以被用於連網狀態下的登錄。",
+ "EasyPasswordHelp": "你的簡易 PIN 碼將會用於在支援的 Jellyfin 應用上進行離線存取,同時也可被用於區域網路的登入。",
"EditMetadata": "編輯數據",
"EditSubtitles": "編輯字幕",
- "EnableBackdrops": "啟用背景",
- "EnableBackdropsHelp": "若啟用,當瀏覽媒體庫時背景圖將作為一些頁面的背景。",
- "EnableCinemaMode": "啟用影院模式",
- "EnableColorCodedBackgrounds": "啟用色彩背景",
- "EnableDisplayMirroring": "啟用雙螢幕",
- "EnableExternalVideoPlayers": "啟用外接影片播放器",
- "EnableExternalVideoPlayersHelp": "當你開始播放影片時,將會顯示一個外接播放器目錄。",
+ "EnableBackdrops": "背景",
+ "EnableBackdropsHelp": "瀏覽媒體庫時背景圖將作為頁面的背景。",
+ "EnableCinemaMode": "影院模式",
+ "EnableColorCodedBackgrounds": "色彩背景",
+ "EnableDisplayMirroring": "鏡像顯示器",
+ "EnableExternalVideoPlayers": "外部影片播放器",
+ "EnableExternalVideoPlayersHelp": "當你開始播放影片時,將會顯示外部播放器選單。",
"EnableHardwareEncoding": "啟用硬體編碼",
- "EnableNextVideoInfoOverlay": "在播放時啟用下一個影片資訊",
+ "EnableNextVideoInfoOverlay": "在播放時顯示下一個影片資訊",
"EnableNextVideoInfoOverlayHelp": "在影片結束前,顯示當前播放列表中下一個影片的資訊。",
- "EnablePhotos": "啟用圖片",
- "EnablePhotosHelp": "照片將被偵測到並和其他媒體文件一起顯示。",
+ "EnablePhotos": "顯示圖片",
+ "EnablePhotosHelp": "圖片將被偵測到並和其他媒體檔案一起顯示。",
"EnableStreamLooping": "自動循環播放直播",
"EnableStreamLoopingHelp": "如果直播僅包含了幾秒鐘的數據並且需要被不斷的請求,請啟用此項。如果在沒有相關問題的情況下啟動此項,可能會導致一些問題。",
- "EnableThemeSongs": "啟用主題曲",
- "EnableThemeSongsHelp": "如果啟用,當瀏覽媒體庫時主題曲將作為背景音樂播放。",
+ "EnableThemeSongs": "主題曲",
+ "EnableThemeSongsHelp": "瀏覽媒體庫時主題曲將作為背景音樂播放。",
"EnableThemeVideos": "啟用主題影片",
- "EnableThemeVideosHelp": "如果啟用,當瀏覽媒體庫時主題影片將作為背景影片播放。",
+ "EnableThemeVideosHelp": "瀏覽媒體庫時主題影片將作為背景影片播放。",
"EnterFFmpegLocation": "輸入 FFmpeg 路徑",
"Episodes": "劇集",
"Error": "錯誤",
- "ErrorAddingListingsToSchedulesDirect": "我們將陣容添加到您的Schedules Direct帳戶時出錯。Schedules Direct只允許有限的帳號排序。您可能在繼續前直接登入Schedules Direct 網站和刪除其他清單。",
+ "ErrorAddingListingsToSchedulesDirect": "",
"ErrorAddingGuestAccount1": "新增Jellyfin Connect時發生錯誤。你的賓客有建立Jellyfin帳號嗎?他們可以在 {0} 創建帳號。",
"ErrorAddingGuestAccount2": "若你還是遇到問題,請發送email至 {0} 並附上你和他們的email帳號。",
"ErrorAddingJellyfinConnectAccount1": "新增Jellyfin Connect時發生錯誤。您有建立Jellyfin帳號嗎?您可以在 {0} 創建帳號。",
"ErrorAddingJellyfinConnectAccount2": "若你還是遇到問題,請用發生問題的email帳號發送email至 {0}。",
"ErrorAddingJellyfinConnectAccount3": "這個 Jellyfin 帳號已經被連接至一個本地帳號。一個 Jellyfin帳號 只能同時被連接到一個本機帳號。",
- "ErrorAddingMediaPathToVirtualFolder": "添加媒體路徑時發生錯誤。請確認路徑是否有效,且你的 Jellyfin 伺服器有對該位置的存取權。",
- "ErrorAddingTunerDevice": "添加調諧器設備時發生錯誤。請確認它是否可被存取後再試一次。",
- "ErrorAddingXmlTvFile": "存取 XmlTV 文件時發生錯誤。請確認該文件是否存在然後再試一次。",
+ "ErrorAddingMediaPathToVirtualFolder": "新增媒體路徑時發生錯誤,請確認路徑是否有效,且你的 Jellyfin 伺服器有對該位置的存取權。",
+ "ErrorAddingTunerDevice": "新增調諧器設備時發生錯誤,請確認它是否可被存取後再試一次。",
+ "ErrorAddingXmlTvFile": "存取 XmlTV 文件時發生錯誤。請確認該檔案是否存在後再試一次。",
"ErrorConnectServerUnreachable": "處理請求時發生錯誤。您的伺服器無法與我們位於 {0} 的 Jellyfin Connect伺服器溝通。請確認你的伺服器有網路連結且防火牆或其他安全性程式允許這個程式對外溝通。",
"ErrorDeletingItem": "從Jellyfin伺服器刪除項目時發生錯誤。請確認伺服器有那個磁碟的寫入權限並再試一次。",
- "ErrorGettingTvLineups": "下載電視節目表時發生錯誤。請確認你的資訊是正確的然後再試一次。",
+ "ErrorGettingTvLineups": "下載電視節目表時發生錯誤,請確認你的資訊是正確的然後再試一次。",
"ErrorMessagePasswordNotMatchConfirm": "密碼和密碼確認必須吻合。",
"ErrorMessageStartHourGreaterThanEnd": "結束時間必須在開始時間後。",
"ErrorMessageUsernameInUse": "用戶名已存在。請重新選個名稱再試。",
- "ErrorPleaseSelectLineup": "請選擇一個節目表, 然後再試一次。如果沒有可用的節目表, 請檢查您的用戶名、密碼和郵遞區號是否正確。",
+ "ErrorPleaseSelectLineup": "請選擇節目表,然後再試一次。如果沒有可用的節目表,請檢查您的使用者名稱、密碼和郵遞區號是否正確。",
"ErrorReachingJellyfinConnect": "連接 Jellyfin Connect 伺服器時發生錯誤。請確認你的網絡狀態是否穩定後再試一次。",
"ErrorRemovingJellyfinConnectAccount": "移除 Jellyfin Connect 帳號時發生錯誤。請確認你的網絡狀態是否穩定後再試一次。",
"ErrorSavingTvProvider": "儲存電視供應商時發生錯誤。請確認它是可存取後再試一次。",
"EveryNDays": "每 {0} 天",
"ExitFullscreen": "結束全螢幕",
"ExtraLarge": "特大",
- "ExtractChapterImagesHelp": "提取章節圖像將允許 Jellyfin 應用程式顯示一個圖像形式的場景選擇目錄。這個提取的過程可能會非常緩慢、佔用大量 CPU 資源,並且可能需要幾個GB的硬碟空間。提取將會在影片被偵測到時啟動,同時也可作為一個夜間計劃任務運行。這個任務可以在“計劃任務”選項中進行設置。不建議在尖峰時刻使用時間進行這個任務。",
+ "ExtractChapterImagesHelp": "擷取章節圖片將允許 Jellyfin 顯示圖片形式的章節選單,過程可能會非常緩慢、佔用大量 CPU 資源,並且可能需要幾 GB 的硬碟空間。\n擷取會在影片被偵測到時啟動,同時也可作為一個夜間計劃任務運行,這個任務可以在「計劃任務」選項中進行設定,不建議在尖峰時刻使用時間進行這個任務。",
"Extras": "額外",
"FFmpegSavePathNotFound": "我們無法通過你輸入的路徑找到 FFmpeg。 FFprobe 同樣也是必要且應該被放在同一個資料夾中。他們通常會被打包在一起以供下載。請檢查這個路徑然後再試一次。",
"FastForward": "快轉",
"Favorites": "我的最愛",
"Features": "功能",
- "FileReadCancelled": "文件讀取已取消。",
+ "FileReadCancelled": "檔案讀取已取消。",
"Fill": "填滿",
"Filters": "濾鏡",
"FolderTypeBooks": "書籍",
@@ -548,13 +548,13 @@
"GuestUserNotFound": "未找到用戶。請確保用戶名稱正確後重試,或者嘗試輸入他們的電子郵件地址。",
"Guide": "指南",
"GuideProviderSelectListings": "選擇列表",
- "H264CrfHelp": "The Constant Rate Factor (CRF) 是 x264 編碼器的默認畫質設置。您可以設介於0和51之間的值, 其中較低的值將導致更好的畫質 (以更大的文件大小為代價)。正常值介於18和28之間。 x264 的默認值為 23, 可以將其用作起始點。",
- "H264EncodingPresetHelp": "選擇一個更快的值以提升性能,或者選擇一個更慢的值以提升畫質。",
+ "H264CrfHelp": "The Constant Rate Factor (CRF) 是 x264 編碼器的默認畫質設置。此方法允許編碼器自動分配位元速率來試著達到一定輸出品質。讓每個畫格得到它需要的位元數來保持所需的品質等級。CRF 會得到最佳的位元速率分配結果。",
+ "H264EncodingPresetHelp": "速度越慢則會得到更好的壓縮編碼效率。",
"HDPrograms": "HD節目",
"HandledByProxy": "由反向代理處理",
"HardwareAccelerationWarning": "啟動硬體加速可能在某些環境下導致系統不穩定。請確認你的作業系統和影片驅動程式是最新的。如果你在開啟此項後播放影片產生困難,那麼你需要將此選項設回”自動“。",
"HeaderAccessSchedule": "存取時程",
- "HeaderAccessScheduleHelp": "創建一個存取時程以限制可存取的時段。",
+ "HeaderAccessScheduleHelp": "建立一個存取時程以限制可存取的時段。",
"HeaderActiveDevices": "運行中裝置",
"HeaderActivity": "活動",
"HeaderAddDevice": "新增裝置",
@@ -572,7 +572,7 @@
"HeaderAllowMediaDeletionFrom": "允許從中刪除媒體",
"HeaderApiKey": "API 金鑰",
"HeaderApiKeys": "API 金鑰",
- "HeaderApiKeysHelp": "外部應用程式需要有一個 API 金鑰以用於和 Jellyfin 伺服器溝通。金鑰將在通過 Jellyfin 帳戶登錄時自動發行,或者你可以手動為應用程式生成一個金鑰。",
+ "HeaderApiKeysHelp": "外部應用程式需要有一個 API 金鑰以用於和 Jellyfin 伺服器溝通。金鑰將在通過 Jellyfin 帳戶登入時自動發行,或者你可以手動為應用程式產生一個金鑰。",
"HeaderApp": "應用程式",
"HeaderAppearsOn": "同時出現於",
"HeaderAudio": "音訊",
@@ -596,11 +596,11 @@
"HeaderCinemaMode": "劇院模式",
"HeaderClients": "客戶端",
"HeaderCloudSync": "雲端同步",
- "HeaderCodecProfile": "編碼配置",
- "HeaderCodecProfileHelp": "編碼器的配置文件標明了設備播放特定編碼時的限制。如果在限制之內則媒體將被轉碼,否則編碼器將被配置為直接播放。",
+ "HeaderCodecProfile": "編碼設定檔",
+ "HeaderCodecProfileHelp": "編碼器的設定檔標明了設備播放特定編碼時的限制;如果在限制之內則媒體將被轉碼,否則編碼器將被設定為直接播放。",
"HeaderCollections": "收藏",
"HeaderColumns": "列",
- "HeaderConfigureRemoteAccess": "配置遠端控制",
+ "HeaderConfigureRemoteAccess": "設定遠端控制",
"HeaderConfirm": "確認",
"HeaderConfirmDeletion": "確認刪除",
"HeaderConfirmPluginInstallation": "確認插件安裝",
@@ -613,8 +613,8 @@
"HeaderConfirmation": "確認",
"HeaderConnectToServer": "連結至伺服器",
"HeaderConnectionFailure": "連結失敗",
- "HeaderContainerProfile": "媒體載體配置",
- "HeaderContainerProfileHelp": "媒體載體的配置文件標明了設備播放特定媒體格式時的限制。如果在限制之內則媒體將被轉碼,否則媒體格式將被配置為直接播放。",
+ "HeaderContainerProfile": "影片容器設定檔",
+ "HeaderContainerProfileHelp": "影片容器的設定檔標明了設備播放特定媒體格式時的限制。如果在限制之內則媒體將被轉碼,否則媒體格式將被設定為直接播放。",
"HeaderContinueListening": "繼續聆聽",
"HeaderContinueWatching": "繼續觀賞",
"HeaderConvertYourRecordings": "為你的錄制轉檔",
@@ -622,7 +622,7 @@
"HeaderDashboardUserPassword": "用戶的密碼被管理在每個用戶的私人配置設置中。",
"HeaderDate": "日期",
"HeaderDateIssued": "發布日期",
- "HeaderDefaultRecordingSettings": "默認錄製設定",
+ "HeaderDefaultRecordingSettings": "預設錄製設定",
"HeaderDeleteDevice": "刪除裝置",
"HeaderDeleteImage": "刪除圖片",
"HeaderDeleteItems": "刪除項目",
@@ -634,8 +634,8 @@
"HeaderDevice": "裝置",
"HeaderDeviceAccess": "允許裝置存取",
"HeaderDevices": "裝置",
- "HeaderDirectPlayProfile": "直接播放配置",
- "HeaderDirectPlayProfileHelp": "添加直接播放配置,標明哪些媒體格式設備可以自己處理。",
+ "HeaderDirectPlayProfile": "直接播放設定檔",
+ "HeaderDirectPlayProfileHelp": "新增直接播放設定檔,標明哪些媒體格式設備可以自己處理。",
"HeaderDisplay": "顯示",
"HeaderDownloadSettings": "下載設定",
"HeaderDownloadSubtitlesFor": "下載字幕:",
@@ -845,30 +845,30 @@
"Songs": "歌曲",
"Sync": "同步",
"ValueSpecialEpisodeName": "特典 - {0}",
- "AuthProviderHelp": "選擇用於驗證用戶密碼的身份驗證提供者",
+ "AuthProviderHelp": "選擇用於驗證使用者密碼的身份驗證提供者。",
"HeaderParentalRatings": "家長評級",
"HeaderPendingInvitations": "等待邀請",
- "HeaderProfile": "配置",
- "HeaderProfileInformation": "配置信息",
+ "HeaderProfile": "設定檔",
+ "HeaderProfileInformation": "設定檔信息",
"HeaderProfileServerSettingsHelp": "這些數值將控制 Jellyfin 伺服器如何呈現給設備。",
- "HeaderResponseProfile": "反應配置",
- "HeaderResponseProfileHelp": "當播放某些類型的媒體時,反應配置提供一種方法來發送自定訊息到設備。",
+ "HeaderResponseProfile": "回覆設定檔",
+ "HeaderResponseProfileHelp": "當播放某些類型的媒體時,回覆設定檔提供一種方法來發送自定訊息到設備。",
"HeaderRestartingServer": "重新啟動伺服器",
"HeaderSchedule": "日程表",
"HeaderSelectCertificatePath": "選擇證書路徑",
"HeaderSelectMetadataPath": "選擇數據路徑",
- "HeaderSubtitleProfile": "字幕配置",
- "HeaderSubtitleProfiles": "字幕配置",
- "HeaderSubtitleProfilesHelp": "字幕配置文件描述設備所支援的字幕格式。",
+ "HeaderSubtitleProfile": "字幕設定檔",
+ "HeaderSubtitleProfiles": "字幕設定檔",
+ "HeaderSubtitleProfilesHelp": "字幕設定檔描述設備所支援的字幕格式。",
"HeaderTaskTriggers": "任務觸發",
- "HeaderTranscodingProfile": "轉碼配置",
- "HeaderTranscodingProfileHelp": "添加轉碼配置文件標明哪些媒體格式需要轉碼處理。",
+ "HeaderTranscodingProfile": "轉碼設定",
+ "HeaderTranscodingProfileHelp": "新增轉碼設定檔標明哪些媒體格式需要轉碼處理。",
"HeaderTuners": "調諧器",
"HeaderTypeImageFetchers": "{0} 圖片獲取程序",
"HeaderTypeText": "輸入文字",
"HeaderUpcomingOnTV": "即將播放",
"HeaderUploadImage": "上傳圖片",
- "HeaderUser": "用戶",
+ "HeaderUser": "使用者",
"HeaderVideoQuality": "影片畫質",
"HeaderVideoType": "影片類型",
"HeaderVideoTypes": "影片類型",
@@ -882,7 +882,7 @@
"HideWatchedContentFromLatestMedia": "從最新媒體中隱藏已觀看的內容",
"Home": "首頁",
"Horizontal": "橫向",
- "HttpsRequiresCert": "要啟用安全連線,您需要提供受信任的SSL證書,例如Lets Encrypt。 請提供證書,或停用安全連線。",
+ "HttpsRequiresCert": "要啟用安全連線,您需要提供受信任的SSL證書,如 Lets Encrypt。 請提供證書,或停用安全連線。",
"Identify": "識別",
"Images": "圖片",
"ImportFavoriteChannelsHelp": "如果啟用,只有在調諧器設備中被標記為我的最愛的頻道才會被導入。",
@@ -925,27 +925,27 @@
"LabelBirthDate": "出生日期:",
"LabelBirthYear": "出生年份:",
"LabelBlastMessageInterval": "活動信號的時間間隔(秒)",
- "LabelBlastMessageIntervalHelp": "確定服務器活動消息之間的持續時間(秒)。",
+ "LabelBlastMessageIntervalHelp": "確定伺服器活動消息之間的持續時間(秒)。",
"LabelBlockContentWithTags": "通過標籤鎖定內容:",
"LabelBurnSubtitles": "燒錄字幕:",
"LabelCache": "快取:",
- "LabelCachePathHelp": "選擇指定所需的緩存文件路徑,如圖像。保留空白以使用默認設定。",
+ "LabelCachePathHelp": "選擇指定所需的快取檔案(像是圖片)路徑。保留空白以使用預設設定。",
"LabelCancelled": "已取消",
- "LabelCertificatePassword": "证书密码:",
+ "LabelCertificatePassword": "證書密碼:",
"LabelCertificatePasswordHelp": "如果你的證書需要密碼,請在此輸入它。",
"LabelChannels": "頻道:",
"LabelCommunityRating": "討論區評分:",
"LabelCriticRating": "影評評分:",
- "LabelCustomCertificatePath": "自定 SSL 證書路徑:",
- "LabelCustomCertificatePathHelp": "提供一個包含了證書和金鑰的 PKCS #12 文件的路徑以在一個自定義域名上啟動 TLS 支持。",
+ "LabelCustomCertificatePath": "自訂 SSL 證書路徑:",
+ "LabelCustomCertificatePathHelp": "提供包含證書和金鑰的 PKCS #12 文件的路徑以在自訂域名上啟用 TLS。",
"LabelCustomCss": "自訂 CSS:",
- "LabelCustomCssHelp": "應用自訂 CSS Web 界面。",
+ "LabelCustomCssHelp": "於 Web 介面套用您的自訂樣式。",
"LabelCustomDeviceDisplayName": "顯示名稱:",
"Depressed": "凹陷",
"HeaderHome": "主頁",
- "HeaderSelectMetadataPathHelp": "瀏覽或者鍵入一個文件庫路徑以用於保存原數據。請確保該文件庫可以被寫入。",
- "HeaderSelectServerCachePathHelp": "瀏覽或者鍵入一個文件庫路徑以用於伺服器緩存檔案。請確保該文件庫可以被寫入。",
- "LabelCustomDeviceDisplayNameHelp": "為設備提供一個自訂的顯示名稱,或者留空以使用設備自己報告的名稱。",
+ "HeaderSelectMetadataPathHelp": "瀏覽或者輸入路徑以用於保存中繼資料,請確保資料夾可以寫入。",
+ "HeaderSelectServerCachePathHelp": "瀏覽或者輸入路徑以用於伺服器快取檔案。請確保該資料夾可以被寫入。",
+ "LabelCustomDeviceDisplayNameHelp": "指定自訂的顯示名稱,或者留空以使用設備自己報告的名稱。",
"LabelCustomRating": "自訂分級:",
"LabelDashboardTheme": "儀表板佈景主題:",
"LabelDateAdded": "新增日期:",
@@ -960,5 +960,668 @@
"LabelDisplayLanguage": "顯示語言:",
"LabelDisplayLanguageHelp": "翻譯 Jellyfin 是個進行中的專案。",
"LabelDisplayMode": "顯示模式:",
- "LabelDisplayName": "顯示名稱:"
+ "LabelDisplayName": "顯示名稱:",
+ "MessageNoPluginsInstalled": "您尚未安裝任何模組。",
+ "Mobile": "手機",
+ "Option3D": "3D",
+ "OptionEveryday": "每天",
+ "OptionMax": "最大",
+ "LabelAudioBitDepth": "音訊位元深度:",
+ "LabelBaseUrl": "根路徑:",
+ "LabelIconMaxHeight": "Icon 最高高度:",
+ "LabelHttpsPortHelp": "Jellyfin 的 HTTPS 伺服器應綁定的 TCP 端口。",
+ "LabelIconMaxHeightHelp": "通過 upnp:icon 的圖標最大解析度。",
+ "CopyStreamURL": "複製串流連結",
+ "MediaInfoDefault": "預設",
+ "MediaInfoStreamTypeAudio": "音訊",
+ "LabelDateAddedBehaviorHelp": "如果原本就有中繼資料,則將始終在這些選項之一之前使用它。",
+ "LabelScreensaver": "螢幕保護程式:",
+ "LabelSeasonNumber": "季:",
+ "LabelDropImageHere": "拖移圖片到這裡,或是點擊來選取。",
+ "LabelImageType": "圖片格式:",
+ "LabelIdentificationFieldHelp": "不區分大小寫的子字符串或正則表達式。",
+ "Large": "大",
+ "LabelTranscodingAudioCodec": "音訊編碼:",
+ "MessageSettingsSaved": "設定已儲存.",
+ "LabelTranscodePath": "轉檔路徑:",
+ "LabelTranscodes": "轉檔:",
+ "MinutesAfter": "分後",
+ "LabelVersion": "版本:",
+ "LabelVersionInstalled": "{0} 已安裝",
+ "DashboardVersionNumber": "版本:{0}",
+ "DashboardServerName": "伺服器:{0}",
+ "NoSubtitles": "沒有字幕",
+ "List": "清單",
+ "OptionAllowMediaPlayback": "允許播放媒體",
+ "OneChannel": "單聲道",
+ "RecommendationDirectedBy": "由 {0} 執導",
+ "RefreshQueued": "已排到佇列中。",
+ "ReleaseDate": "釋出日期",
+ "RepeatOne": "單曲重複",
+ "ResumeAt": "從 {0} 繼續播放",
+ "Settings": "設定",
+ "TabAccess": "存取",
+ "TabDevices": "裝置",
+ "TabDirectPlay": "直接播放",
+ "ThemeSongs": "主題曲",
+ "ThemeVideos": "主題曲影片",
+ "Upload": "上傳",
+ "PasswordResetHeader": "重設密碼",
+ "ScanLibrary": "掃描媒體庫",
+ "ValueAudioCodec": "音訊編碼:{0}",
+ "ValueCodec": "編碼:{0}",
+ "ValueSongCount": "{0} 首歌",
+ "LabelFileOrUrl": "檔案或路徑:",
+ "LabelKodiMetadataSaveImagePaths": "在 nfo 檔案中儲存圖片路徑",
+ "LabelLanNetworks": "區域網路:",
+ "LabelMetadataPathHelp": "指定自訂路徑來儲存下載的圖片與中繼資料。",
+ "LabelZipCode": "郵遞區號:",
+ "LabelffmpegPath": "FFmpeg 路徑:",
+ "LearnHowYouCanContribute": "了解如何貢獻。",
+ "Played": "已看過",
+ "RefreshMetadata": "重新抓取中繼資料",
+ "RememberMe": "記住我",
+ "Screenshots": "截圖",
+ "SendMessage": "傳送訊息",
+ "ShowAdvancedSettings": "顯示進階選項",
+ "ShowTitle": "顯示標題",
+ "ShowYear": "顯示年份",
+ "Shuffle": "隨ㄔㄧ",
+ "Smart": "智慧",
+ "HeaderFavoriteBooks": "最愛的書籍",
+ "LabelAudioBitrate": "音訊比特率:",
+ "LabelAudioCodec": "音訊編碼:",
+ "LabelBitrate": "比特率:",
+ "LabelAudioChannels": "音訊聲道:",
+ "LabelAudioSampleRate": "音訊取樣率:",
+ "LabelFont": "字體:",
+ "LabelFolder": "資料夾:",
+ "LabelDisplayOrder": "顯示順序:",
+ "LabelEnableBlastAliveMessages": "活動訊息",
+ "LabelEnableDlnaServer": "啟用 DLNA 伺服器",
+ "LabelEnableDlnaServerHelp": "允許網絡上的 UPnP 設備瀏覽和播放內容。",
+ "LabelEnableHardwareDecodingFor": "為以下啟用硬體解碼:",
+ "LabelEpisodeNumber": "集:",
+ "LabelBaseUrlHelp": "您可以在此處新增自訂路徑來進入伺服器。",
+ "LabelExtractChaptersDuringLibraryScan": "於媒體庫掃描時擷取章節圖片",
+ "LabelHttpsPort": "本地 HTTPS 端口:",
+ "LabelFailed": "失敗",
+ "LabelSubtitles": "字幕:",
+ "LabelSupportedMediaTypes": "支援的媒體類型:",
+ "LabelTextBackgroundColor": "文字背景顏色:",
+ "LabelTextColor": "文字顏色:",
+ "LabelTextSize": "文字大小:",
+ "LabelTheme": "主題:",
+ "LabelTimeLimitHours": "時間限制(小時):",
+ "LabelTitle": "標題:",
+ "LabelTrackNumber": "追蹤編號:",
+ "LabelTranscodingFramerate": "轉檔幀率:",
+ "LabelTranscodingProgress": "轉檔進度:",
+ "LabelType": "類型:",
+ "LabelTypeMetadataDownloaders": "{0} 個中繼資料下載器:",
+ "LabelTypeText": "文本",
+ "LabelUsername": "使用者名稱:",
+ "DashboardOperatingSystem": "作業系統:{0}",
+ "LabelVideo": "影片:",
+ "LabelVideoCodec": "影片編碼:",
+ "LabelYear": "年:",
+ "LatestFromLibrary": "最新 {0}",
+ "Logo": "標誌",
+ "ManageLibrary": "管理媒體庫",
+ "MarkPlayed": "標記為已播放",
+ "MarkUnplayed": "標記為未播放",
+ "MediaInfoBitrate": "比特率",
+ "MediaInfoChannels": "聲道",
+ "MediaInfoCodec": "編碼",
+ "MediaInfoContainer": "影片容器",
+ "MediaInfoExternal": "外部",
+ "MediaInfoForced": "強迫",
+ "MediaInfoFramerate": "幀率",
+ "MediaInfoLanguage": "語言",
+ "MediaInfoLayout": "佈局",
+ "MediaInfoPath": "路徑",
+ "MessageAreYouSureYouWishToRemoveMediaFolder": "您確定要移除此媒體資料夾嗎?",
+ "MessageConfirmDeleteTunerDevice": "您確定要刪除這部裝置嗎?",
+ "MessageConfirmRecordingCancellation": "取消錄製?",
+ "MessageImageFileTypeAllowed": "僅支援 JPEG 和 PNG。",
+ "MessageInvalidUser": "錯誤的使用者名稱或密碼,請再試一次。",
+ "MessageItemSaved": "項目已儲存。",
+ "MessagePleaseWait": "請稍候。",
+ "MinutesBefore": "分前",
+ "MoreMediaInfo": "媒體資訊",
+ "MoveLeft": "移到左邊",
+ "MoveRight": "移到右邊",
+ "MusicAlbum": "專輯",
+ "MusicArtist": "演出者",
+ "MusicVideo": "MV",
+ "Name": "名稱",
+ "NewEpisodes": "新集數",
+ "NewEpisodesOnly": "僅限新集數",
+ "NextUp": "即將播放",
+ "No": "不要",
+ "Off": "關閉",
+ "OptionAdminUsers": "管理員",
+ "OptionAllowRemoteControlOthers": "允許其他使用者遠端控制",
+ "OptionAuto": "自動",
+ "OptionBlockBooks": "書",
+ "OptionBlockChannelContent": "網路頻道內容",
+ "OptionHasTrailer": "預告",
+ "OptionNone": "無",
+ "OptionPosterCard": "海報卡片",
+ "OptionProfileAudio": "音訊",
+ "OptionProfileVideo": "影片",
+ "OptionProfileVideoAudio": "影片與圖片",
+ "OptionReleaseDate": "釋出日期",
+ "OptionWeekends": "假日",
+ "PlayNextEpisodeAutomatically": "自動播放下一集",
+ "RecentlyWatched": "最近觀賞",
+ "RecommendationBecauseYouLike": "因為您喜歡 {0}",
+ "SearchResults": "搜尋結果",
+ "TabPlaylists": "播放清單",
+ "TabPlugins": "模組",
+ "Transcoding": "轉檔",
+ "ValueTimeLimitMultiHour": "時間限制:{0} 小時",
+ "ValueVideoCodec": "影片編碼:{0}",
+ "ViewAlbum": "查看專輯",
+ "LabelKodiMetadataDateFormatHelp": "NFO 檔案中的所有日期都將使用此格式。",
+ "LabelServerHostHelp": "192.168.1.100:8096 或是 https://myserver.com",
+ "LabelServerName": "伺服器名稱:",
+ "LabelTag": "標記:",
+ "LabelTranscodingTempPathHelp": "指定轉檔後的儲存路徑,留空將使用預設值。",
+ "LabelffmpegPathHelp": "路徑指向 FFmpeg,或是包含其的資料夾。",
+ "ManageRecording": "管理錄影",
+ "MessageAlreadyInstalled": "已安裝此版本。",
+ "MessageConfirmRestart": "您確定要重新啟動嗎?",
+ "Metadata": "ˊ中繼資料",
+ "OptionAllUsers": "所有使用者",
+ "OptionHomeVideos": "圖片",
+ "OptionPoster": "海報",
+ "OptionProfilePhoto": "圖片",
+ "OptionRegex": "正則表達式",
+ "OptionThumb": "預覽",
+ "OptionThumbCard": "預覽卡片",
+ "RecommendationBecauseYouWatched": "因為您看過 {0}",
+ "RepeatMode": "重複模式",
+ "Runtime": "運行時間",
+ "TV": "電視",
+ "TabUsers": "使用者",
+ "Trailers": "預告",
+ "LabelImageFetchersHelp": "按優先級啟用並排列您喜歡的圖片抓取器。",
+ "LabelDownMixAudioScale": "縮混時的音訊增強:",
+ "LabelDownMixAudioScaleHelp": "縮混時增強音訊。其中一個音軌將保持原始音量。",
+ "LabelDownloadLanguages": "下載語言:",
+ "LabelDynamicExternalId": "{0} Id:",
+ "LabelEasyPinCode": "簡易代碼:",
+ "LabelEnableAutomaticPortMap": "啟用自動端口映射",
+ "LabelEnableSingleImageInDidlLimit": "限制單個嵌入式圖片",
+ "LabelEndDate": "結束日期:",
+ "LabelLockItemToPreventChanges": "鎖定此項目來避免被更改",
+ "LabelManufacturer": "製造商",
+ "LabelLoginDisclaimerHelp": "顯示在登入頁面底部的訊息。",
+ "LabelManufacturerUrl": "製造商網址",
+ "LabelMaxChromecastBitrate": "Chromecast 串流解析度:",
+ "LabelOriginalTitle": "原始標題:",
+ "LabelSelectUsers": "選擇使用者:",
+ "LabelSelectVersionToInstall": "選擇要安裝的版本:",
+ "LabelSendNotificationToUsers": "傳送通知給:",
+ "LabelSortBy": "排序依:",
+ "LabelVideoBitrate": "影片比特率:",
+ "MediaInfoSize": "大小",
+ "MediaInfoTimestamp": "時間戳",
+ "MediaInfoSoftware": "軟體",
+ "MediaInfoStreamTypeData": "檔案",
+ "MediaInfoStreamTypeEmbeddedImage": "內嵌語言",
+ "MediaInfoStreamTypeSubtitle": "字幕",
+ "MediaInfoStreamTypeVideo": "影片",
+ "Menu": "選單",
+ "MetadataManager": "中繼資料管理器",
+ "NoPluginConfigurationMessage": "這個模組沒有設定選項可供更改。",
+ "NoSubtitlesHelp": "字幕不會自動讀取,但可於播放時手動選取。",
+ "Normal": "正常",
+ "OptionAllowContentDownloading": "允許下載及同步媒體",
+ "OptionAllowLinkSharing": "允許分享到社群媒體",
+ "OptionBlockMusic": "音樂",
+ "OptionBlockTrailers": "預告",
+ "OptionBlockTvShows": "電視節目",
+ "OptionList": "清單",
+ "TabMusicVideos": "MV",
+ "Yesterday": "昨天",
+ "Yes": "是",
+ "ButtonAddImage": "新增圖片",
+ "LabelForgotPasswordUsernameHelp": "假如您還記得的話,請輸入您的使用者名稱。",
+ "LabelFormat": "格式:",
+ "LabelFriendlyName": "好聽的名字:",
+ "LabelGroupMoviesIntoCollections": "將電影分組",
+ "LabelKodiMetadataDateFormat": "釋出日期格式:",
+ "LabelIconMaxWidth": "Icon 最寬寬度:",
+ "LabelGroupMoviesIntoCollectionsHelp": "顯示電影列表時,屬於相同集合的電影將作為分組項目顯示。",
+ "LabelH264EncodingPreset": "H264 解碼品質:",
+ "LabelHardwareAccelerationType": "硬體加速:",
+ "LabelIconMaxWidthHelp": "通過 upnp:icon 的圖標最大解析度。",
+ "LabelImportOnlyFavoriteChannels": "僅限收藏的頻道",
+ "LabelInNetworkSignInWithEasyPassword": "啟用以簡易密碼進行區域網路登入",
+ "LabelH264Crf": "H264 編碼 CRF:",
+ "LabelMaxStreamingBitrate": "最大串流畫質:",
+ "LabelMaxStreamingBitrateHelp": "指定最大串流比特率。",
+ "LabelMessageText": "訊息文字:",
+ "LabelMessageTitle": "訊息標題:",
+ "LabelMetadataDownloadLanguage": "首選下載語言:",
+ "LabelMetadata": "中繼資料:",
+ "LabelMethod": "方法:",
+ "LabelNewName": "新名稱:",
+ "LabelProfileAudioCodecs": "音訊編碼:",
+ "LabelProfileCodecs": "編碼:",
+ "LabelProfileVideoCodecs": "影片編碼:",
+ "Live": "直播",
+ "NumLocationsValue": "{0} 個資料夾",
+ "RemoveFromPlaylist": "從播放清單中移除",
+ "Repeat": "重複",
+ "RepeatAll": "重複全部",
+ "Screenshot": "截圖",
+ "Suggestions": "建議",
+ "TabCodecs": "編碼",
+ "TabContainers": "影片容器",
+ "TabDashboard": "控制台",
+ "TabDisplay": "顯示",
+ "TabFavorites": "最愛",
+ "TabLogs": "日誌",
+ "TabNotifications": "通知",
+ "TabOther": "其他",
+ "TabParentalControl": "家長控制",
+ "TabScheduledTasks": "已排程的任務",
+ "TabStreaming": "串流",
+ "TagsValue": "標記:{0}",
+ "Thumb": "縮圖",
+ "TabResumeSettings": "繼續播放",
+ "ValueAlbumCount": "{0} 張專輯",
+ "ValueContainer": "影片容器:{0}",
+ "ValueEpisodeCount": "{0} 集",
+ "ValueDiscNumber": "光碟#{0}",
+ "ValueMinutes": "{0} 分",
+ "ValueMovieCount": "{0} 部電影",
+ "ValueMusicVideoCount": "{0} 部 MV",
+ "ValueOneAlbum": "1 張專輯",
+ "ValueOneEpisode": "1 集",
+ "ValueOneMovie": "1 部電影",
+ "ValueOneMusicVideo": "1 部 MV",
+ "ValueOneSong": "1 首歌",
+ "ValueSeconds": "{0} 秒",
+ "ValueTimeLimitSingleHour": "時間限制:1 小時",
+ "ViewArtist": "查看演出者",
+ "Watched": "已看過",
+ "Whitelist": "白名單",
+ "Tags": "標記",
+ "OptionProtocolHttp": "HTTP",
+ "TabNfoSettings": "NFO 設定",
+ "FetchingData": "獲取額外資料",
+ "LabelTranscodingVideoCodec": "影片編碼:",
+ "MediaInfoBitDepth": "位元深度",
+ "Mute": "靜音",
+ "MessageConfirmShutdown": "你確定要關閉伺服器嗎?",
+ "Never": "從不",
+ "OptionBlockMovies": "電影",
+ "CopyStreamURLSuccess": "連結複製成功。",
+ "PerfectMatch": "最佳配對",
+ "PictureInPicture": "浮窗播放",
+ "PlayFromBeginning": "從頭開始播放",
+ "PlayNext": "播放下一個",
+ "Next": "下一個",
+ "OptionCaptionInfoExSamsung": "CaptionInfoEx(三星)",
+ "People": "人物",
+ "OptionEnableExternalContentInSuggestions": "在建議中啟用外部內容",
+ "OptionEnableM2tsMode": "啟用 M2ts 模式",
+ "LabelKeepUpTo": "保持:",
+ "LabelKidsCategories": "兒童分類:",
+ "LabelKodiMetadataEnablePathSubstitution": "啟用路徑替換",
+ "LabelKodiMetadataEnableExtraThumbs": "複製 extrafanart 到 extrathumbs 欄位",
+ "LabelMovieCategories": "電影分類:",
+ "LabelMoviePrefix": "電影前綴:",
+ "LabelProfileContainer": "影片容器:",
+ "LabelDropShadow": "陰影:",
+ "LabelSecureConnectionsMode": "安全連接模式:",
+ "LabelTVHomeScreen": "電視模式主畫面:",
+ "LabelTranscodingContainer": "影片容器:",
+ "MovieLibraryHelp": "查看 {0}Jellyfin 電影命名指南{1}。",
+ "None": "無",
+ "LinksValue": "連結:{0}",
+ "OptionAllowMediaPlaybackTranscodingHelp": "由於不支持的媒體格式,限制轉檔可能會導致 Jellyfin 應用程式播放失敗。",
+ "MediaInfoLevel": "等級",
+ "MessageNoTrailersFound": "沒有任何預告片,安裝 Trailer channel 來優化你的電影體驗。",
+ "OptionHasSpecialFeatures": "特色",
+ "RecommendationStarring": "主演 {0}",
+ "Rewind": "倒帶",
+ "RunAtStartup": "開機時啟動",
+ "SubtitleOffset": "字幕偏移",
+ "TabPlayback": "播放",
+ "Unrated": "尚未評等",
+ "Up": "上",
+ "ValueOneSeries": "1 劇集",
+ "Writer": "編劇",
+ "XmlTvMovieCategoriesHelp": "有這些類別的節目會被當作電影。用「|」分隔多個。",
+ "ValueSeriesCount": "{0} 劇集",
+ "LabelHardwareAccelerationTypeHelp": "這個功能只能在支援的系統上使用。",
+ "LabelHomeNetworkQuality": "區域網路畫質:",
+ "LabelHomeScreenSectionValue": "主畫面模塊 {0}:",
+ "LabelMetadataDownloadersHelp": "啟用媒體屬性下載器的優先次序,愈下次序只會用來填補缺少的信息。",
+ "LabelMetadataReaders": "中繼資料閱讀器:",
+ "LabelMetadataSaversHelp": "選取儲存中繼資料的檔案格式。",
+ "LabelModelNumber": "型號",
+ "LabelNewsCategories": "新分類:",
+ "LabelValue": "數值:",
+ "OptionBanner": "橫幅",
+ "OptionDownloadBannerImage": "橫幅",
+ "OptionEnableAccessToAllChannels": "允許存取所有頻道",
+ "OptionEnableAccessToAllLibraries": "允許存取所有媒體庫",
+ "OptionEnableAutomaticServerUpdates": "啟用自動更新",
+ "OptionEnableForAllTuners": "开启所有调谐器",
+ "OptionExtractChapterImage": "開啟章節圖片擷取",
+ "OptionEnableM2tsModeHelp": "當編碼為 MPEGTS 時啟用 M2TS 模式。",
+ "OptionEquals": "等於",
+ "OptionEstimateContentLength": "轉檔時,估計內容長度",
+ "OptionExternallyDownloaded": "外部下載",
+ "OptionHlsSegmentedSubtitles": "HLS 分段字幕",
+ "OptionLoginAttemptsBeforeLockout": "確定在被封鎖之前可以登入失敗幾次。",
+ "OptionRequirePerfectSubtitleMatch": "只下載與我的影片檔案完美匹配的字幕",
+ "PlayCount": "播放次數",
+ "Series": "電視劇",
+ "SeriesCancelled": "電視劇已取消。",
+ "SeriesDisplayOrderHelp": "按播出日期、DVD 順序或編號對劇集進行排序。",
+ "SeriesSettings": "系列設定",
+ "SeriesYearToPresent": "{0} - 現在",
+ "ServerNameIsRestarting": "Jellyfin Server - {0} 重啟中。",
+ "ServerNameIsShuttingDown": "Jellyfin 伺服器 - {0} 正在關閉。",
+ "SimultaneousConnectionLimitHelp": "允許的同時串流的最大數量。輸入 0 表示無限制。",
+ "SkipEpisodesAlreadyInMyLibrary": "不錄製我的媒體庫裡已存在的劇集",
+ "SmallCaps": "小型大寫字母",
+ "SortChannelsBy": "頻道排序方式:",
+ "SortName": "排序名稱",
+ "Sports": "體育",
+ "StopRecording": "停止錄影",
+ "LabelDefaultUserHelp": "確定哪些使用者媒體庫將顯示在連接裝置上。這可以為每個裝置提供不同的使用者設定檔。",
+ "LabelEnableBlastAliveMessagesHelp": "若此伺服器無法被其他 UPnP 裝置偵測到,請啟用此選項。",
+ "LabelEnableDlnaClientDiscoveryIntervalHelp": "由 Jellyfin 決定進行 SSDP 搜尋之間的持續時間(以秒為單位)。",
+ "LabelEnableDlnaPlayToHelp": "偵測您網路裡的設備並遠端控制它們。",
+ "LabelExtractChaptersDuringLibraryScanHelp": "當媒體庫匯入影片並掃描時,將擷取章節圖片。\n否則,章節圖片將在之後的計畫任務中擷取,而媒體庫會更快完成掃描。",
+ "LabelMoviePrefixHelp": "若前綴套用到電影標題,請在此處輸入它來方便伺服器能夠正確處理。",
+ "LabelMovieRecordingPath": "電影錄製路徑(選用):",
+ "LabelNotificationEnabled": "啟用這個通知",
+ "LabelProfileContainersHelp": "以逗號分隔。留空則適用於所有影片容器。",
+ "LabelSelectFolderGroupsHelp": "未選中的資料夾將在其自己的檢視中顯示。",
+ "LabelSerialNumber": "序號",
+ "LabelSeriesRecordingPath": "電視劇錄影路徑(選用):",
+ "LabelServerHost": "主機:",
+ "LabelSimultaneousConnectionLimit": "同時串流限制:",
+ "LabelSize": "大小:",
+ "LabelSkin": "主題:",
+ "LabelSkipBackLength": "跳過長度:",
+ "LabelSkipIfGraphicalSubsPresentHelp": "保留文字版本的字幕會更有效率傳遞,減低影片轉碼的機會。",
+ "LabelStopWhenPossible": "當可能時自動停止:",
+ "LabelStopping": "停止",
+ "LabelTagline": "個性宣言:",
+ "LabelSubtitleDownloaders": "字幕下載器:",
+ "LabelSubtitleFormatHelp": "例如:SRT",
+ "LabelSubtitlePlaybackMode": "字幕模式:",
+ "LabelTranscodingThreadCount": "轉檔執行緒數:",
+ "LabelTunerIpAddress": "調諧器 IP 位址:",
+ "LabelTunerType": "調諧器類型:",
+ "LabelUseNotificationServices": "使用以下服務:",
+ "LabelUserAgent": "使用者代理:",
+ "LabelUserLibrary": "使用者程式庫:",
+ "LabelUserLibraryHelp": "選擇在裝置上顯示的使用者媒體庫,留空則使用預設設定值。",
+ "LabelUserLoginAttemptsBeforeLockout": "使用者被封鎖前可嘗試的次數:",
+ "LabelVaapiDeviceHelp": "此渲染節點用來硬體加速。",
+ "LabelWeb": "網站: ",
+ "LabelXDlnaCapHelp": "決定在 urn:schemas-dlna-org:device-1-0 namespace 中的 X_DLNACAP 元素的內容。",
+ "LabelXDlnaDocHelp": "決定在 urn:schemas-dlna-org:device-1-0 namespace 中的 X-Dlna doc 元素的內容。",
+ "LaunchWebAppOnStartup": "在啟動伺服器時啟動使用者介面",
+ "LabelUserRemoteClientBitrateLimitHelp": "覆蓋伺服器重播設定中設置的預設全域值。",
+ "LabelTranscodingThreadCountHelp": "選擇轉檔時要使用的最大執行緒數,減少執行緒數將降低 CPU 使用率,但轉換速度可能不足以提供流暢的播放體驗。",
+ "LabelXDlnaCap": "X-DLNA 上限:",
+ "LabelXDlnaDoc": "X-DLNA 檔案:",
+ "LeaveBlankToNotSetAPassword": "您可以將此欄位留空來將密碼設定為無。",
+ "LiveTV": "電視直播",
+ "MapChannels": "映射頻道",
+ "MediaInfoAnamorphic": "畸形",
+ "MediaInfoAspectRatio": "長寬比",
+ "MediaInfoCodecTag": "編碼標籤",
+ "MediaInfoInterlaced": "隔行掃描",
+ "MediaInfoPixelFormat": "像素格式",
+ "MediaInfoProfile": "設定檔",
+ "MediaInfoRefFrames": "參考幀",
+ "MediaInfoResolution": "解析度",
+ "MediaIsBeingConverted": "媒體正在轉換為相容播放裝置的格式。",
+ "MessageConfirmDeleteGuideProvider": "您確定要刪除此指南提供者嗎?",
+ "MessageConfirmProfileDeletion": "您確定要刪除這個設定檔嗎?",
+ "MessageConfirmRemoveMediaLocation": "您確定要移除這個位置嗎?",
+ "MessageConfirmRevokeApiKey": "您確定要撤銷這個 API 金鑰嗎?這個應用程式與 Jellyfin 伺服器的連接將立即中斷。",
+ "MessageCreateAccountAt": "在 {0} 建立使用者",
+ "MessageDeleteTaskTrigger": "您確定要刪除這個任務觸發器嗎?",
+ "MessageDirectoryPickerBSDInstruction": "對於 BSD 系統,您需要設定包含您 FreeNAS Jail 虛擬機的儲存以便 Jellyfin 存取。",
+ "MessageDirectoryPickerInstruction": "在網路按鈕無法找到您的裝置的情況下,網路路徑可被手動輸入。例如:{0} 或 {1}。",
+ "MessageDirectoryPickerLinuxInstruction": "使用 Linux on Arch Linux、CentOS、Debian、Fedora、OpenSuse 或 Ubuntu 作業系統,您必須授權使用者至少讀取權限來存取您的儲存路徑。",
+ "MessageEnablingOptionLongerScans": "啟用這個選項可能會延長媒體庫的掃描時間。",
+ "MessageFileReadError": "讀取檔案時發生錯誤。",
+ "MessageForgotPasswordInNetworkRequired": "請檢查您的區域網路後再試一次來開始密碼重置流程。",
+ "MessageForgotPasswordFileCreated": "已在伺服器上建立了以下檔案,並包含有關後續步驟說明:",
+ "MessageNoAvailablePlugins": "沒有可用的模組。",
+ "MessageNoServersAvailable": "無法自動偵測伺服器。",
+ "MessageLeaveEmptyToInherit": "保留為空以繼承父項或全域預設值的設定。",
+ "MessageNoCollectionsAvailable": "分組能夠讓您享受個性化的影片、劇集和專輯。點擊+按鈕開始建立分組。",
+ "MessagePlayAccessRestricted": "此內容的播放受到限制,聯繫您的伺服器管理員以獲取更多訊息。",
+ "MessagePluginConfigurationRequiresLocalAccess": "請直接登入你的本地伺服器以設定這個模組。",
+ "MessagePluginInstallDisclaimer": "安裝 Jellyfin 社區成員建立的模組來獲取額外的功能可以最佳化您的 Jellyfin。但他們可能會對你的 Jellyfin 伺服器造成的影響,如更長的媒體庫掃描時間、額外的背景資料處理和降低系統穩定性等。",
+ "MessageReenableUser": "請參閱以下以重新啟用",
+ "MessageUnableToConnectToServer": "無法連上所選的伺服器,請確保該伺服器正在運作中。",
+ "MessageYouHaveVersionInstalled": "你目前安裝了 {0} 版本。",
+ "MoreFromValue": "更多來自 {0}",
+ "News": "新聞",
+ "NoNewDevicesFound": "找不到裝置,要添加新調諧器,請關閉此對話框並手動輸入裝置訊息。",
+ "OnlyForcedSubtitles": "僅顯示強制字幕",
+ "OnlyImageFormats": "僅圖片格式(VOBSUB、PGS、SUB 等)",
+ "OptionAllowLinkSharingHelp": "只有網頁包含的媒體訊息會被共享,媒體檔案本身不會被公開共享,共享的內容會在 {0} 天後到期。",
+ "OptionAllowRemoteSharedDevices": "允許遠端控制共享裝置",
+ "OptionAllowSyncTranscoding": "允許需要轉檔的媒體下載和同步",
+ "OptionAllowVideoPlaybackRemuxing": "允許播放需轉換但無需重新編碼的影片",
+ "MessageTheFollowingLocationWillBeRemovedFromLibrary": "以下媒體位置將從您的媒體庫中刪除:",
+ "MetadataSettingChangeHelp": "更改中繼資料設定將影響新增的新內容。要重新整理現有內容,請打開詳細訊息視窗並點選「重新整理」按鈕,或使用中繼資料管理器執行批次重新整理。",
+ "MusicLibraryHelp": "查看{0}音樂命名指南{1}。",
+ "OptionAutomaticallyGroupSeries": "自動合併分布在不同資料夾的電視劇",
+ "OptionAutomaticallyGroupSeriesHelp": "分布在這個媒體庫的多個文件夾中的同一部電視劇將會自動整合成一部電視劇。",
+ "OptionDateAddedImportTime": "使用加入媒體庫時的掃描日期",
+ "OptionDisplayFolderView": "顯示「資料夾」類別來瀏覽你的媒體資料夾",
+ "OptionEmbedSubtitles": "在影片容器中嵌入",
+ "OptionDownloadImagesInAdvance": "提前下載圖片",
+ "OptionEnableAccessFromAllDevices": "允許所有裝置存取",
+ "OptionDownloadImagesInAdvanceHelp": "預設情況下,大多數圖片僅在Jellyfin應用程式請求時下載。啟用此選項可於匯入新媒體後提前下載所有圖片,可能會延長的媒體庫掃描時間。",
+ "OptionEnableExternalContentInSuggestionsHelp": "允許將網際網路預告片和直播電視節目包含在建議的內容中。",
+ "OptionHideUserFromLoginHelp": "對私人或隱藏的管理員帳戶很有用,但需手動輸入使用者名稱和密碼登入。",
+ "OptionPlainStorageFolders": "顯示所有資料夾作為一般存儲資料夾",
+ "OptionPlainVideoItems": "顯示所有影片為一般影片項目",
+ "OptionPlainVideoItemsHelp": "所有影片在 DIDL 中顯示為「object.item.videoItem」,而不是一個更具體的類型,如「object.item.videoItem.movie」。",
+ "OptionProtocolHls": "HTTP 直播串流",
+ "OptionReportByteRangeSeekingWhenTranscoding": "轉檔時,回報伺服器支持的位元組查詢",
+ "OptionSaveMetadataAsHidden": "儲存媒體資料和圖片為隱藏文件",
+ "OptionSubstring": "子串",
+ "OptionWeekdays": "工作日",
+ "Overview": "概述",
+ "PackageInstallCancelled": "{0} 安裝被取消。",
+ "PlayAllFromHere": "從這裡開始全部播放",
+ "PleaseAddAtLeastOneFolder": "請點擊新增按鈕,新增至少一個資料夾到這個媒體庫。",
+ "PleaseConfirmPluginInstallation": "點擊「OK」以確認您已經閱讀了上述內容並希望繼續安裝模組。",
+ "PleaseEnterNameOrId": "請輸入一個名稱或一個外部 ID。",
+ "PleaseRestartServerName": "請重啟 Jellyfin 伺服器 - {0}。",
+ "PleaseSelectTwoItems": "請至少選擇 2 個項目。",
+ "PreferEmbeddedTitlesOverFileNames": "優先使用內建的標題而不是檔案名稱",
+ "PreferEmbeddedTitlesOverFileNamesHelp": "這將在沒有網路上的中繼資料或本地中繼資料可用時顯示預設標題。",
+ "PreferredNotRequired": "首選,但非必需",
+ "Premiere": "首映",
+ "Premieres": "首映",
+ "Previous": "上一個",
+ "Primary": "封面圖",
+ "Producer": "監製",
+ "ProductionLocations": "產地",
+ "Programs": "節目",
+ "Quality": "品質",
+ "PackageInstallFailed": "{0} 安裝失敗。",
+ "QueueAllFromHere": "將這裡的全部內容加入佇列",
+ "Raised": "提高",
+ "Rate": "評等",
+ "Recordings": "錄影",
+ "ServerRestartNeededAfterPluginInstall": "安裝模組後,Jellyfin 伺服器需要重啟以使模組生效。",
+ "ShowIndicatorsFor": "顯示指標:",
+ "Sort": "排序",
+ "Studios": "工作室",
+ "TheseSettingsAffectSubtitlesOnThisDevice": "這些設定僅影響該裝置的字幕顯示",
+ "TitleHardwareAcceleration": "硬體加速",
+ "TitleHostingSettings": "主機設定",
+ "Uniform": "輪廓",
+ "Unmute": "取消靜音",
+ "Unplayed": "尚未播放",
+ "TvLibraryHelp": "查看{0}電視命名指南{1}。",
+ "LabelMonitorUsers": "監控活動:",
+ "LabelPleaseRestart": "改動將在手動重啟用戶端後生效。",
+ "LabelProfileCodecsHelp": "以逗號分隔。留空則適用於所有編解碼器。",
+ "OptionPlainStorageFoldersHelp": "如果啟用,所有文件夾在DIDL中顯示為「object.container.storageFolder 」,而不是一個更具體的類型,如「object.container.person.musicArtist」。",
+ "LabelInNetworkSignInWithEasyPasswordHelp": "你可以在你的家庭網路中使用你的簡易 PIN 碼登錄 Jellyfin 應用程式,僅在你使用外部網路時才需要輸入密碼,如果 PIN 碼留空,那麼在你的區域網路中便不需輸入密碼。",
+ "LabelReleaseDate": "釋出日期:",
+ "LabelRemoteClientBitrateLimit": "網際網路串流傳輸位元率限制(Mbps):",
+ "LanNetworksHelp": "",
+ "OptionIgnoreTranscodeByteRangeRequests": "忽略轉檔位元組範圍請求",
+ "OptionIgnoreTranscodeByteRangeRequestsHelp": "如果啟用,這些請求會被兌現,但會忽略的位元組範圍標頭。",
+ "OptionLoginAttemptsBeforeLockoutHelp": "若值為 0,則表示將允許普通使用者嘗試三次、管理員嘗試五次的預設值,設定為 -1 來停用此功能。",
+ "OptionRequirePerfectSubtitleMatchHelp": "",
+ "PluginInstalledMessage": "這個模組安裝成功,但 Jellyfin 伺服器需要重啟以使模組生效。",
+ "RecordingPathChangeMessage": "更改錄製資料夾不會將現有錄製從舊位置遷移到新的,您需要手動移動它們。",
+ "RestartPleaseWaitMessage": "Jellyfin 伺服器將重新啟動,這將花費幾分鐘時間。",
+ "LabelEmbedAlbumArtDidl": "於 Didl 中嵌入專輯封面",
+ "LabelEnableAutomaticPortMapHelp": "自動嘗試映射公共連接埠到 UPnP 本地連接埠。這可能無法用於某些路由器。",
+ "LabelEmbedAlbumArtDidlHelp": "有些裝置使用這個方式來取得專輯封面,啟用這個選項可能導致其他設備播放失敗。",
+ "SettingsWarning": "更改這些值可能會導致不穩定或連線故障。如果您遇到任何問題,建議將它們重新更改為預設值。",
+ "LabelEnableSingleImageInDidlLimitHelp": "若在 Didl 中嵌入多個圖片,某些裝置可能無法正常顯示。",
+ "SortByValue": "排序方式:{0}",
+ "LabelLineup": "排隊:",
+ "LabelLocalHttpServerPortNumber": "本地 HTTP 端口:",
+ "LabelLocalHttpServerPortNumberHelp": "Jellyfin HTTP 伺服器監聽的 TCP 端口。",
+ "SubtitleAppearanceSettingsAlsoPassedToCastDevices": "這些設定也會被套用在任何透過此裝置發起的 Chromecast 播放。",
+ "LabelLoginDisclaimer": "登入字句:",
+ "LabelLogs": "日誌:",
+ "SubtitleDownloadersHelp": "按優先順序啟用並排列您的首選字幕下載程式。",
+ "LabelMatchType": "匹配的類型:",
+ "SystemDlnaProfilesHelp": "系統設定檔案是唯讀的,更改系統設定檔案將被儲存到自訂的新設定檔案。",
+ "LabelNumber": "編號:",
+ "LabelNumberOfGuideDays": "下載電視指南日數:",
+ "OnlyForcedSubtitlesHelp": "只有標記為「強制」的字幕會被載入。",
+ "PackageInstallCompleted": "{0} 安裝完成。",
+ "OptionDisplayFolderViewHelp": "在其他媒體庫旁邊顯示資料夾,對想要一個普通的資料夾檢視很有用。",
+ "LabelReasonForTranscoding": "轉檔原因:",
+ "LabelRecord": "錄影:",
+ "LabelRecordingPath": "預設錄影路徑:",
+ "LabelRecordingPathHelp": "指定用於存儲轉檔的位置,留空將使用伺服器的程式根目錄。",
+ "LabelRemoteClientBitrateLimitHelp": "所有網路裝置都有可選的流位元率限制,這對於防止設備請求比網路連接所能處理的更高的位元率非常有用。這可能會導致伺服器上的 CPU 負載增加,以便將影片轉檔到較低的位元率。",
+ "SmartSubtitlesHelp": "當音訊為外語時,將載入與語言偏好匹配的字幕。",
+ "SubtitleAppearanceSettingsDisclaimer": "這些設定將不會套用在圖形字幕(如 PGS、DVD 等),或者一些有著自己的內建樣式的字幕(ASS/SSA)。",
+ "UserAgentHelp": "提供自訂的使用者代理 HTTP 標頭。",
+ "LabelRuntimeMinutes": "播放時長(分鐘):",
+ "LabelScheduledTaskLastRan": "最後執行 {0},花費時間 {1}。",
+ "LabelSkipForwardLength": "快轉長度:",
+ "LabelSkipIfAudioTrackPresent": "如果預設音軌的語言和下載語言一樣則跳過",
+ "LabelSkipIfAudioTrackPresentHelp": "取消此項,無論音訊語言是否一致,所有影片都會下載字幕。",
+ "LabelSkipIfGraphicalSubsPresent": "跳過有內嵌字幕的影片",
+ "LabelSonyAggregationFlags": "Sony 整合標誌:",
+ "LabelSonyAggregationFlagsHelp": "決定在 urn:schemas-dlna-org:device-1-0 namespace 中的 aggregationFlags 元素的內容。",
+ "LabelSortOrder": "排列順序:",
+ "LabelSortTitle": "短標題:",
+ "LabelSoundEffects": "音效:",
+ "LabelSource": "來源:",
+ "LabelSpecialSeasonsDisplayName": "SP 季顯示名稱:",
+ "LabelSportsCategories": "體育分類:",
+ "LabelStartWhenPossible": "當可能時自動開始:",
+ "LabelVaapiDevice": "VA API 裝置:",
+ "DashboardArchitecture": "結構:{0}",
+ "MediaInfoSampleRate": "採樣率",
+ "MessageContactAdminToResetPassword": "請聯繫您的管理員來重置密碼。",
+ "MessageUnsetContentHelp": "內容將顯示為純資料夾,建議使用中繼資料管理器設置子資料夾的內容類型。",
+ "OptionAllowAudioPlaybackTranscoding": "允許播放需要轉檔的音訊",
+ "OptionCustomUsers": "自訂",
+ "OptionDateAddedFileTime": "使用檔案建立日期",
+ "OptionReportByteRangeSeekingWhenTranscodingHelp": "",
+ "XmlTvNewsCategoriesHelp": "有這些類別的節目會被當作新聞節目。用「|」分隔多個。",
+ "LabelKodiMetadataEnableExtraThumbsHelp": "為了相容 Kodi 主題,下載的圖片將被同時儲存在 extrafanart 和 extrathumbs 資料夾中。",
+ "LabelInternetQuality": "網路畫質:",
+ "LabelKodiMetadataEnablePathSubstitutionHelp": "允許將圖片的路徑以伺服器路徑來替換。",
+ "LabelKodiMetadataSaveImagePathsHelp": "如果您的圖片檔案名稱不符合 Kodi 規範,建議啟用。",
+ "LabelKodiMetadataUser": "儲存這些使用者的觀看資料到 NFO 檔案裏:",
+ "LabelKodiMetadataUserHelp": "儲存觀看資料到 NFO 檔案中以便其他應用程式使用。",
+ "LabelMetadataReadersHelp": "優先排序您的首選資料屬性來源,首個找到的文件將被讀取。",
+ "LabelMetadataSavers": "中繼資料儲存方式:",
+ "LabelModelDescription": "型號描述",
+ "LabelModelName": "型號名稱",
+ "LabelModelUrl": "型號網址",
+ "LabelMusicStreamingTranscodingBitrate": "音樂轉檔比特率:",
+ "LabelMusicStreamingTranscodingBitrateHelp": "指定音樂串流時的最大比特率",
+ "LabelOptionalNetworkPathHelp": "如果這個資料夾在網路上分享,提供網路分享路徑可以供其他 Jellyfin 應用程式直接存取媒體檔案。",
+ "LabelOriginalAspectRatio": "原始長寬比:",
+ "LabelOverview": "內容概述:",
+ "LabelParentalRating": "家長分級:",
+ "LabelPasswordConfirm": "確認密碼:",
+ "LabelPasswordResetProvider": "密碼重設提供者:",
+ "LabelPasswordRecoveryPinCode": "PIN 碼:",
+ "LabelPath": "路徑:",
+ "LabelPersonRole": "角色:",
+ "LabelPersonRoleHelp": "例如:冰淇淋車司機",
+ "LabelPlaceOfBirth": "出生地:",
+ "LabelPlayDefaultAudioTrack": "無論如何都播放預設音軌",
+ "LabelPlayer": "播放器:",
+ "LabelPlayMethod": "播放方式:",
+ "LabelParentNumber": "父編號:",
+ "LabelPostProcessor": "後處理應用程式:",
+ "LabelPostProcessorArguments": "處理器後命令行參數:",
+ "LabelPostProcessorArgumentsHelp": "使用 {path} 作為錄製檔案的路徑。",
+ "LabelPreferredDisplayLanguage": "首選語言:",
+ "LabelPreferredDisplayLanguageHelp": "翻譯 Jellyfin 是一個進行中的項目。",
+ "LabelPreferredSubtitleLanguage": "字幕語言偏好:",
+ "LabelProtocol": "協議:",
+ "LabelProtocolInfo": "協議資訊:",
+ "LabelPublicHttpPort": "公開 HTTP 端口:",
+ "LabelPublicHttpsPort": "公開 HTTPS 端口:",
+ "LabelProtocolInfoHelp": "當響應來自裝置的 GetProtocolInfo(獲取協議訊息)請求時,該值將被使用。",
+ "LabelPublicHttpPortHelp": "公開連接埠應映射到本地 HTTP 連接埠。",
+ "LabelPublicHttpsPortHelp": "公開連接埠應映射到本地 HTTPS 連接埠。",
+ "LabelReadHowYouCanContribute": "了解如何作出貢獻。",
+ "LabelSelectFolderGroups": "自動將以下資料夾中的內容分組到視圖中,例如電影、音樂和電視:",
+ "LabelStatus": "狀態:",
+ "LiveBroadcasts": "直播",
+ "MessageImageTypeNotSelected": "在下拉選單中選取圖片類型。",
+ "RemoveFromCollection": "從收藏移除",
+ "RepeatEpisodes": "重複劇集",
+ "RequiredForAllRemoteConnections": "所有遠端連接都需要",
+ "SaveSubtitlesIntoMediaFolders": "保存字幕到媒體所在資料夾",
+ "SaveSubtitlesIntoMediaFoldersHelp": "將字幕存儲在影片檔案旁邊可以讓管理更方便。",
+ "ScanForNewAndUpdatedFiles": "掃描新的和有修改的文件",
+ "Schedule": "排程",
+ "TabCollections": "收藏",
+ "TabNetworking": "網路",
+ "TitlePlayback": "播放",
+ "ValueConditions": "條件:{0}",
+ "Vertical": "垂直",
+ "VideoRange": "影片範圍",
+ "ViewPlaybackInfo": "查看播放訊息",
+ "XmlTvSportsCategoriesHelp": "有這些類別的節目會被當作體育節目。用「|」分隔多個。",
+ "XmlTvPathHelp": "XML 電視檔案的路徑,Jellyfin 將讀取該檔案並定期檢查其更新,您負責建立和更新檔案。",
+ "MessageInvalidForgotPasswordPin": "簡易代碼錯誤或已過期,請再試一次。",
+ "OptionAllowVideoPlaybackTranscoding": "允許播放需要轉檔的影片",
+ "Small": "小",
+ "Smaller": "更小",
+ "XmlTvKidsCategoriesHelp": "有這些類別的節目會被當作兒童節目。用「|」分隔多個。",
+ "TabResponses": "響應",
+ "LabelDisplaySpecialsWithinSeasons": "顯示劇集季度中的特集",
+ "LabelNumberOfGuideDaysHelp": "下載更多電視指南資料會提供更好時間表查看能力,但將需要更長的下載時間。自動基於頻道數目來選擇。",
+ "LabelOptionalNetworkPath": "(選用)分享的網路資料夾:",
+ "MessageInstallPluginFromApp": "必須從要在其中使用它的應用程式中安裝此模組。",
+ "OptionResElement": "res 元素",
+ "PinCodeResetComplete": "PIN 碼已被重設。",
+ "PinCodeResetConfirmation": "你確定要重設 PIN 碼?",
+ "PasswordResetProviderHelp": "選擇密碼重設提供者以便使用者重設密碼",
+ "PlaceFavoriteChannelsAtBeginning": "將喜愛的頻道置頂",
+ "PlaybackData": "恢復播放資料"
}
diff --git a/src/videoosd.html b/src/videoosd.html
index 0f4be75916..34c73a3019 100644
--- a/src/videoosd.html
+++ b/src/videoosd.html
@@ -31,7 +31,7 @@
-