mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge pull request #224 from vitorsemeano/webpack_part5
Conversion to webpack - part5 - module resolution, data-require cleaned
This commit is contained in:
commit
a14b2b337c
74 changed files with 1494 additions and 671 deletions
829
src/controllers/dlnaprofile.js
Normal file
829
src/controllers/dlnaprofile.js
Normal file
|
@ -0,0 +1,829 @@
|
|||
define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-input", "emby-checkbox", "listViewStyle", "emby-button"], function ($, loading) {
|
||||
"use strict";
|
||||
|
||||
function loadProfile(page) {
|
||||
loading.show();
|
||||
var promise1 = getProfile();
|
||||
var promise2 = ApiClient.getUsers();
|
||||
Promise.all([promise1, promise2]).then(function (responses) {
|
||||
currentProfile = responses[0];
|
||||
renderProfile(page, currentProfile, responses[1]);
|
||||
loading.hide();
|
||||
});
|
||||
}
|
||||
|
||||
function getProfile() {
|
||||
var id = getParameterByName("id");
|
||||
var url = id ? "Dlna/Profiles/" + id : "Dlna/Profiles/Default";
|
||||
return ApiClient.getJSON(ApiClient.getUrl(url));
|
||||
}
|
||||
|
||||
function renderProfile(page, profile, users) {
|
||||
$("#txtName", page).val(profile.Name);
|
||||
$(".chkMediaType", page).each(function () {
|
||||
this.checked = -1 != (profile.SupportedMediaTypes || "").split(",").indexOf(this.getAttribute("data-value"));
|
||||
});
|
||||
$("#chkEnableAlbumArtInDidl", page).checked(profile.EnableAlbumArtInDidl);
|
||||
$("#chkEnableSingleImageLimit", page).checked(profile.EnableSingleAlbumArtLimit);
|
||||
renderXmlDocumentAttributes(page, profile.XmlRootAttributes || []);
|
||||
var idInfo = profile.Identification || {};
|
||||
renderIdentificationHeaders(page, idInfo.Headers || []);
|
||||
renderSubtitleProfiles(page, profile.SubtitleProfiles || []);
|
||||
$("#txtInfoFriendlyName", page).val(profile.FriendlyName || "");
|
||||
$("#txtInfoModelName", page).val(profile.ModelName || "");
|
||||
$("#txtInfoModelNumber", page).val(profile.ModelNumber || "");
|
||||
$("#txtInfoModelDescription", page).val(profile.ModelDescription || "");
|
||||
$("#txtInfoModelUrl", page).val(profile.ModelUrl || "");
|
||||
$("#txtInfoManufacturer", page).val(profile.Manufacturer || "");
|
||||
$("#txtInfoManufacturerUrl", page).val(profile.ManufacturerUrl || "");
|
||||
$("#txtInfoSerialNumber", page).val(profile.SerialNumber || "");
|
||||
$("#txtIdFriendlyName", page).val(idInfo.FriendlyName || "");
|
||||
$("#txtIdModelName", page).val(idInfo.ModelName || "");
|
||||
$("#txtIdModelNumber", page).val(idInfo.ModelNumber || "");
|
||||
$("#txtIdModelDescription", page).val(idInfo.ModelDescription || "");
|
||||
$("#txtIdModelUrl", page).val(idInfo.ModelUrl || "");
|
||||
$("#txtIdManufacturer", page).val(idInfo.Manufacturer || "");
|
||||
$("#txtIdManufacturerUrl", page).val(idInfo.ManufacturerUrl || "");
|
||||
$("#txtIdSerialNumber", page).val(idInfo.SerialNumber || "");
|
||||
$("#txtIdDeviceDescription", page).val(idInfo.DeviceDescription || "");
|
||||
$("#txtAlbumArtPn", page).val(profile.AlbumArtPn || "");
|
||||
$("#txtAlbumArtMaxWidth", page).val(profile.MaxAlbumArtWidth || "");
|
||||
$("#txtAlbumArtMaxHeight", page).val(profile.MaxAlbumArtHeight || "");
|
||||
$("#txtIconMaxWidth", page).val(profile.MaxIconWidth || "");
|
||||
$("#txtIconMaxHeight", page).val(profile.MaxIconHeight || "");
|
||||
$("#chkIgnoreTranscodeByteRangeRequests", page).checked(profile.IgnoreTranscodeByteRangeRequests);
|
||||
$("#txtMaxAllowedBitrate", page).val(profile.MaxStreamingBitrate || "");
|
||||
$("#txtMusicStreamingTranscodingBitrate", page).val(profile.MusicStreamingTranscodingBitrate || "");
|
||||
$("#chkRequiresPlainFolders", page).checked(profile.RequiresPlainFolders);
|
||||
$("#chkRequiresPlainVideoItems", page).checked(profile.RequiresPlainVideoItems);
|
||||
$("#txtProtocolInfo", page).val(profile.ProtocolInfo || "");
|
||||
$("#txtXDlnaCap", page).val(profile.XDlnaCap || "");
|
||||
$("#txtXDlnaDoc", page).val(profile.XDlnaDoc || "");
|
||||
$("#txtSonyAggregationFlags", page).val(profile.SonyAggregationFlags || "");
|
||||
profile.DirectPlayProfiles = profile.DirectPlayProfiles || [];
|
||||
profile.TranscodingProfiles = profile.TranscodingProfiles || [];
|
||||
profile.ContainerProfiles = profile.ContainerProfiles || [];
|
||||
profile.CodecProfiles = profile.CodecProfiles || [];
|
||||
profile.ResponseProfiles = profile.ResponseProfiles || [];
|
||||
var usersHtml = "<option></option>" + users.map(function (u__w) {
|
||||
return '<option value="' + u__w.Id + '">' + u__w.Name + "</option>";
|
||||
}).join("");
|
||||
$("#selectUser", page).html(usersHtml).val(profile.UserId || "");
|
||||
renderSubProfiles(page, profile);
|
||||
}
|
||||
|
||||
function renderIdentificationHeaders(page, headers) {
|
||||
var index = 0;
|
||||
var html = '<div class="paperList">' + headers.map(function (h__e) {
|
||||
var li = '<div class="listItem">';
|
||||
li += '<i class="md-icon listItemIcon">info</i>';
|
||||
li += '<div class="listItemBody">';
|
||||
li += '<h3 class="listItemBodyText">' + h__e.Name + ": " + (h__e.Value || "") + "</h3>";
|
||||
li += '<div class="listItemBodyText secondary">' + (h__e.Match || "") + "</div>";
|
||||
li += "</div>";
|
||||
li += '<button type="button" is="paper-icon-button-light" class="btnDeleteIdentificationHeader listItemButton" data-index="' + index + '"><i class="md-icon">delete</i></button>';
|
||||
li += "</div>";
|
||||
index++;
|
||||
return li;
|
||||
}).join("") + "</div>";
|
||||
var elem = $(".httpHeaderIdentificationList", page).html(html).trigger("create");
|
||||
$(".btnDeleteIdentificationHeader", elem).on("click", function () {
|
||||
var itemIndex = parseInt(this.getAttribute("data-index"));
|
||||
currentProfile.Identification.Headers.splice(itemIndex, 1);
|
||||
renderIdentificationHeaders(page, currentProfile.Identification.Headers);
|
||||
});
|
||||
}
|
||||
|
||||
function openPopup(elem) {
|
||||
elem.classList.remove("hide");
|
||||
}
|
||||
|
||||
function closePopup(elem) {
|
||||
elem.classList.add("hide");
|
||||
}
|
||||
|
||||
function editIdentificationHeader(page, header) {
|
||||
isSubProfileNew = null == header;
|
||||
header = header || {};
|
||||
currentSubProfile = header;
|
||||
var popup = $("#identificationHeaderPopup", page);
|
||||
$("#txtIdentificationHeaderName", popup).val(header.Name || "");
|
||||
$("#txtIdentificationHeaderValue", popup).val(header.Value || "");
|
||||
$("#selectMatchType", popup).val(header.Match || "Equals");
|
||||
openPopup(popup[0]);
|
||||
}
|
||||
|
||||
function saveIdentificationHeader(page) {
|
||||
currentSubProfile.Name = $("#txtIdentificationHeaderName", page).val();
|
||||
currentSubProfile.Value = $("#txtIdentificationHeaderValue", page).val();
|
||||
currentSubProfile.Match = $("#selectMatchType", page).val();
|
||||
|
||||
if (isSubProfileNew) {
|
||||
currentProfile.Identification = currentProfile.Identification || {};
|
||||
currentProfile.Identification.Headers = currentProfile.Identification.Headers || [];
|
||||
currentProfile.Identification.Headers.push(currentSubProfile);
|
||||
}
|
||||
|
||||
renderIdentificationHeaders(page, currentProfile.Identification.Headers);
|
||||
currentSubProfile = null;
|
||||
closePopup($("#identificationHeaderPopup", page)[0]);
|
||||
}
|
||||
|
||||
function renderXmlDocumentAttributes(page, attribute) {
|
||||
var html = '<div class="paperList">' + attribute.map(function (h__r) {
|
||||
var li = '<div class="listItem">';
|
||||
li += '<i class="md-icon listItemIcon">info</i>';
|
||||
li += '<div class="listItemBody">';
|
||||
li += '<h3 class="listItemBodyText">' + h__r.Name + " = " + (h__r.Value || "") + "</h3>";
|
||||
li += "</div>";
|
||||
li += '<button type="button" is="paper-icon-button-light" class="btnDeleteXmlAttribute listItemButton" data-index="0"><i class="md-icon">delete</i></button>';
|
||||
return li += "</div>";
|
||||
}).join("") + "</div>";
|
||||
var elem = $(".xmlDocumentAttributeList", page).html(html).trigger("create");
|
||||
$(".btnDeleteXmlAttribute", elem).on("click", function () {
|
||||
var itemIndex = parseInt(this.getAttribute("data-index"));
|
||||
currentProfile.XmlRootAttributes.splice(itemIndex, 1);
|
||||
renderXmlDocumentAttributes(page, currentProfile.XmlRootAttributes);
|
||||
});
|
||||
}
|
||||
|
||||
function editXmlDocumentAttribute(page, attribute) {
|
||||
isSubProfileNew = null == attribute;
|
||||
attribute = attribute || {};
|
||||
currentSubProfile = attribute;
|
||||
var popup = $("#xmlAttributePopup", page);
|
||||
$("#txtXmlAttributeName", popup).val(attribute.Name || "");
|
||||
$("#txtXmlAttributeValue", popup).val(attribute.Value || "");
|
||||
openPopup(popup[0]);
|
||||
}
|
||||
|
||||
function saveXmlDocumentAttribute(page) {
|
||||
currentSubProfile.Name = $("#txtXmlAttributeName", page).val();
|
||||
currentSubProfile.Value = $("#txtXmlAttributeValue", page).val();
|
||||
|
||||
if (isSubProfileNew) {
|
||||
currentProfile.XmlRootAttributes.push(currentSubProfile);
|
||||
}
|
||||
|
||||
renderXmlDocumentAttributes(page, currentProfile.XmlRootAttributes);
|
||||
currentSubProfile = null;
|
||||
closePopup($("#xmlAttributePopup", page)[0]);
|
||||
}
|
||||
|
||||
function renderSubtitleProfiles(page, profiles) {
|
||||
var index = 0;
|
||||
var html = '<div class="paperList">' + profiles.map(function (h__t) {
|
||||
var li = '<div class="listItem lnkEditSubProfile" data-index="' + index + '">';
|
||||
li += '<i class="md-icon listItemIcon">info</i>';
|
||||
li += '<div class="listItemBody">';
|
||||
li += '<h3 class="listItemBodyText">' + (h__t.Format || "") + "</h3>";
|
||||
li += "</div>";
|
||||
li += '<button type="button" is="paper-icon-button-light" class="btnDeleteProfile listItemButton" data-index="' + index + '"><i class="md-icon">delete</i></button>';
|
||||
li += "</div>";
|
||||
index++;
|
||||
return li;
|
||||
}).join("") + "</div>";
|
||||
var elem = $(".subtitleProfileList", page).html(html).trigger("create");
|
||||
$(".btnDeleteProfile", elem).on("click", function () {
|
||||
var itemIndex = parseInt(this.getAttribute("data-index"));
|
||||
currentProfile.SubtitleProfiles.splice(itemIndex, 1);
|
||||
renderSubtitleProfiles(page, currentProfile.SubtitleProfiles);
|
||||
});
|
||||
$(".lnkEditSubProfile", elem).on("click", function () {
|
||||
var itemIndex = parseInt(this.getAttribute("data-index"));
|
||||
editSubtitleProfile(page, currentProfile.SubtitleProfiles[itemIndex]);
|
||||
});
|
||||
}
|
||||
|
||||
function editSubtitleProfile(page, profile) {
|
||||
isSubProfileNew = null == profile;
|
||||
profile = profile || {};
|
||||
currentSubProfile = profile;
|
||||
var popup = $("#subtitleProfilePopup", page);
|
||||
$("#txtSubtitleProfileFormat", popup).val(profile.Format || "");
|
||||
$("#selectSubtitleProfileMethod", popup).val(profile.Method || "");
|
||||
$("#selectSubtitleProfileDidlMode", popup).val(profile.DidlMode || "");
|
||||
openPopup(popup[0]);
|
||||
}
|
||||
|
||||
function saveSubtitleProfile(page) {
|
||||
currentSubProfile.Format = $("#txtSubtitleProfileFormat", page).val();
|
||||
currentSubProfile.Method = $("#selectSubtitleProfileMethod", page).val();
|
||||
currentSubProfile.DidlMode = $("#selectSubtitleProfileDidlMode", page).val();
|
||||
|
||||
if (isSubProfileNew) {
|
||||
currentProfile.SubtitleProfiles.push(currentSubProfile);
|
||||
}
|
||||
|
||||
renderSubtitleProfiles(page, currentProfile.SubtitleProfiles);
|
||||
currentSubProfile = null;
|
||||
closePopup($("#subtitleProfilePopup", page)[0]);
|
||||
}
|
||||
|
||||
function renderSubProfiles(page, profile) {
|
||||
renderDirectPlayProfiles(page, profile.DirectPlayProfiles);
|
||||
renderTranscodingProfiles(page, profile.TranscodingProfiles);
|
||||
renderContainerProfiles(page, profile.ContainerProfiles);
|
||||
renderCodecProfiles(page, profile.CodecProfiles);
|
||||
renderResponseProfiles(page, profile.ResponseProfiles);
|
||||
}
|
||||
|
||||
function saveDirectPlayProfile(page) {
|
||||
currentSubProfile.Type = $("#selectDirectPlayProfileType", page).val();
|
||||
currentSubProfile.Container = $("#txtDirectPlayContainer", page).val();
|
||||
currentSubProfile.AudioCodec = $("#txtDirectPlayAudioCodec", page).val();
|
||||
currentSubProfile.VideoCodec = $("#txtDirectPlayVideoCodec", page).val();
|
||||
|
||||
if (isSubProfileNew) {
|
||||
currentProfile.DirectPlayProfiles.push(currentSubProfile);
|
||||
}
|
||||
|
||||
renderSubProfiles(page, currentProfile);
|
||||
currentSubProfile = null;
|
||||
closePopup($("#popupEditDirectPlayProfile", page)[0]);
|
||||
}
|
||||
|
||||
function renderDirectPlayProfiles(page, profiles) {
|
||||
var html = "";
|
||||
html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
|
||||
var currentType;
|
||||
|
||||
for (var i__y = 0, length = profiles.length; i__y < length; i__y++) {
|
||||
var profile = profiles[i__y];
|
||||
|
||||
if (profile.Type !== currentType) {
|
||||
html += '<li data-role="list-divider">' + profile.Type + "</li>";
|
||||
currentType = profile.Type;
|
||||
}
|
||||
|
||||
html += "<li>";
|
||||
html += '<a data-profileindex="' + i__y + '" class="lnkEditSubProfile" is="emby-linkbutton" href="#">';
|
||||
html += "<p>" + Globalize.translate("ValueContainer").replace("{0}", profile.Container || allText) + "</p>";
|
||||
|
||||
if ("Video" == profile.Type) {
|
||||
html += "<p>" + Globalize.translate("ValueVideoCodec").replace("{0}", profile.VideoCodec || allText) + "</p>";
|
||||
html += "<p>" + Globalize.translate("ValueAudioCodec").replace("{0}", profile.AudioCodec || allText) + "</p>";
|
||||
} else {
|
||||
if ("Audio" == profile.Type) {
|
||||
html += "<p>" + Globalize.translate("ValueCodec").replace("{0}", profile.AudioCodec || allText) + "</p>";
|
||||
}
|
||||
}
|
||||
|
||||
html += "</a>";
|
||||
html += '<a is="emby-linkbutton" href="#" data-icon="delete" class="btnDeleteProfile" data-profileindex="' + i__y + '">Delete</a>';
|
||||
html += "</li>";
|
||||
}
|
||||
|
||||
html += "</ul>";
|
||||
var elem = $(".directPlayProfiles", page).html(html).trigger("create");
|
||||
$(".btnDeleteProfile", elem).on("click", function () {
|
||||
var index = this.getAttribute("data-profileindex");
|
||||
deleteDirectPlayProfile(page, index);
|
||||
});
|
||||
$(".lnkEditSubProfile", elem).on("click", function () {
|
||||
var index = parseInt(this.getAttribute("data-profileindex"));
|
||||
editDirectPlayProfile(page, currentProfile.DirectPlayProfiles[index]);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteDirectPlayProfile(page, index) {
|
||||
currentProfile.DirectPlayProfiles.splice(index, 1);
|
||||
renderDirectPlayProfiles(page, currentProfile.DirectPlayProfiles);
|
||||
}
|
||||
|
||||
function editDirectPlayProfile(page, directPlayProfile) {
|
||||
isSubProfileNew = null == directPlayProfile;
|
||||
directPlayProfile = directPlayProfile || {};
|
||||
currentSubProfile = directPlayProfile;
|
||||
var popup = $("#popupEditDirectPlayProfile", page);
|
||||
$("#selectDirectPlayProfileType", popup).val(directPlayProfile.Type || "Video").trigger("change");
|
||||
$("#txtDirectPlayContainer", popup).val(directPlayProfile.Container || "");
|
||||
$("#txtDirectPlayAudioCodec", popup).val(directPlayProfile.AudioCodec || "");
|
||||
$("#txtDirectPlayVideoCodec", popup).val(directPlayProfile.VideoCodec || "");
|
||||
openPopup(popup[0]);
|
||||
}
|
||||
|
||||
function renderTranscodingProfiles(page, profiles) {
|
||||
var html = "";
|
||||
html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
|
||||
var currentType;
|
||||
|
||||
for (var i__u = 0, length = profiles.length; i__u < length; i__u++) {
|
||||
var profile = profiles[i__u];
|
||||
|
||||
if (profile.Type !== currentType) {
|
||||
html += '<li data-role="list-divider">' + profile.Type + "</li>";
|
||||
currentType = profile.Type;
|
||||
}
|
||||
|
||||
html += "<li>";
|
||||
html += '<a data-profileindex="' + i__u + '" class="lnkEditSubProfile" is="emby-linkbutton" href="#">';
|
||||
html += "<p>Protocol: " + (profile.Protocol || "Http") + "</p>";
|
||||
html += "<p>" + Globalize.translate("ValueContainer").replace("{0}", profile.Container || allText) + "</p>";
|
||||
|
||||
if ("Video" == profile.Type) {
|
||||
html += "<p>" + Globalize.translate("ValueVideoCodec").replace("{0}", profile.VideoCodec || allText) + "</p>";
|
||||
html += "<p>" + Globalize.translate("ValueAudioCodec").replace("{0}", profile.AudioCodec || allText) + "</p>";
|
||||
} else {
|
||||
if ("Audio" == profile.Type) {
|
||||
html += "<p>" + Globalize.translate("ValueCodec").replace("{0}", profile.AudioCodec || allText) + "</p>";
|
||||
}
|
||||
}
|
||||
|
||||
html += "</a>";
|
||||
html += '<a is="emby-linkbutton" href="#" data-icon="delete" class="btnDeleteProfile" data-profileindex="' + i__u + '">Delete</a>';
|
||||
html += "</li>";
|
||||
}
|
||||
|
||||
html += "</ul>";
|
||||
var elem = $(".transcodingProfiles", page).html(html).trigger("create");
|
||||
$(".btnDeleteProfile", elem).on("click", function () {
|
||||
var index = this.getAttribute("data-profileindex");
|
||||
deleteTranscodingProfile(page, index);
|
||||
});
|
||||
$(".lnkEditSubProfile", elem).on("click", function () {
|
||||
var index = parseInt(this.getAttribute("data-profileindex"));
|
||||
editTranscodingProfile(page, currentProfile.TranscodingProfiles[index]);
|
||||
});
|
||||
}
|
||||
|
||||
function editTranscodingProfile(page, transcodingProfile) {
|
||||
isSubProfileNew = null == transcodingProfile;
|
||||
transcodingProfile = transcodingProfile || {};
|
||||
currentSubProfile = transcodingProfile;
|
||||
var popup = $("#transcodingProfilePopup", page);
|
||||
$("#selectTranscodingProfileType", popup).val(transcodingProfile.Type || "Video").trigger("change");
|
||||
$("#txtTranscodingContainer", popup).val(transcodingProfile.Container || "");
|
||||
$("#txtTranscodingAudioCodec", popup).val(transcodingProfile.AudioCodec || "");
|
||||
$("#txtTranscodingVideoCodec", popup).val(transcodingProfile.VideoCodec || "");
|
||||
$("#selectTranscodingProtocol", popup).val(transcodingProfile.Protocol || "Http");
|
||||
$("#chkEnableMpegtsM2TsMode", popup).checked(transcodingProfile.EnableMpegtsM2TsMode || false);
|
||||
$("#chkEstimateContentLength", popup).checked(transcodingProfile.EstimateContentLength || false);
|
||||
$("#chkReportByteRangeRequests", popup).checked("Bytes" == transcodingProfile.TranscodeSeekInfo);
|
||||
$(".radioTabButton:first", popup).trigger("click");
|
||||
openPopup(popup[0]);
|
||||
}
|
||||
|
||||
function deleteTranscodingProfile(page, index) {
|
||||
currentProfile.TranscodingProfiles.splice(index, 1);
|
||||
renderTranscodingProfiles(page, currentProfile.TranscodingProfiles);
|
||||
}
|
||||
|
||||
function saveTranscodingProfile(page) {
|
||||
currentSubProfile.Type = $("#selectTranscodingProfileType", page).val();
|
||||
currentSubProfile.Container = $("#txtTranscodingContainer", page).val();
|
||||
currentSubProfile.AudioCodec = $("#txtTranscodingAudioCodec", page).val();
|
||||
currentSubProfile.VideoCodec = $("#txtTranscodingVideoCodec", page).val();
|
||||
currentSubProfile.Protocol = $("#selectTranscodingProtocol", page).val();
|
||||
currentSubProfile.Context = "Streaming";
|
||||
currentSubProfile.EnableMpegtsM2TsMode = $("#chkEnableMpegtsM2TsMode", page).checked();
|
||||
currentSubProfile.EstimateContentLength = $("#chkEstimateContentLength", page).checked();
|
||||
currentSubProfile.TranscodeSeekInfo = $("#chkReportByteRangeRequests", page).checked() ? "Bytes" : "Auto";
|
||||
|
||||
if (isSubProfileNew) {
|
||||
currentProfile.TranscodingProfiles.push(currentSubProfile);
|
||||
}
|
||||
|
||||
renderSubProfiles(page, currentProfile);
|
||||
currentSubProfile = null;
|
||||
closePopup($("#transcodingProfilePopup", page)[0]);
|
||||
}
|
||||
|
||||
function renderContainerProfiles(page, profiles) {
|
||||
var html = "";
|
||||
html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
|
||||
var currentType;
|
||||
|
||||
for (var i__i = 0, length = profiles.length; i__i < length; i__i++) {
|
||||
var profile = profiles[i__i];
|
||||
|
||||
if (profile.Type !== currentType) {
|
||||
html += '<li data-role="list-divider">' + profile.Type + "</li>";
|
||||
currentType = profile.Type;
|
||||
}
|
||||
|
||||
html += "<li>";
|
||||
html += '<a data-profileindex="' + i__i + '" class="lnkEditSubProfile" is="emby-linkbutton" href="#">';
|
||||
html += "<p>" + Globalize.translate("ValueContainer").replace("{0}", profile.Container || allText) + "</p>";
|
||||
|
||||
if (profile.Conditions && profile.Conditions.length) {
|
||||
html += "<p>";
|
||||
html += Globalize.translate("ValueConditions").replace("{0}", profile.Conditions.map(function (c__o) {
|
||||
return c__o.Property;
|
||||
}).join(", "));
|
||||
html += "</p>";
|
||||
}
|
||||
|
||||
html += "</a>";
|
||||
html += '<a is="emby-linkbutton" href="#" data-icon="delete" class="btnDeleteProfile" data-profileindex="' + i__i + '">Delete</a>';
|
||||
html += "</li>";
|
||||
}
|
||||
|
||||
html += "</ul>";
|
||||
var elem = $(".containerProfiles", page).html(html).trigger("create");
|
||||
$(".btnDeleteProfile", elem).on("click", function () {
|
||||
var index = this.getAttribute("data-profileindex");
|
||||
deleteContainerProfile(page, index);
|
||||
});
|
||||
$(".lnkEditSubProfile", elem).on("click", function () {
|
||||
var index = parseInt(this.getAttribute("data-profileindex"));
|
||||
editContainerProfile(page, currentProfile.ContainerProfiles[index]);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteContainerProfile(page, index) {
|
||||
currentProfile.ContainerProfiles.splice(index, 1);
|
||||
renderContainerProfiles(page, currentProfile.ContainerProfiles);
|
||||
}
|
||||
|
||||
function editContainerProfile(page, containerProfile) {
|
||||
isSubProfileNew = null == containerProfile;
|
||||
containerProfile = containerProfile || {};
|
||||
currentSubProfile = containerProfile;
|
||||
var popup = $("#containerProfilePopup", page);
|
||||
$("#selectContainerProfileType", popup).val(containerProfile.Type || "Video").trigger("change");
|
||||
$("#txtContainerProfileContainer", popup).val(containerProfile.Container || "");
|
||||
$(".radioTabButton:first", popup).trigger("click");
|
||||
openPopup(popup[0]);
|
||||
}
|
||||
|
||||
function saveContainerProfile(page) {
|
||||
currentSubProfile.Type = $("#selectContainerProfileType", page).val();
|
||||
currentSubProfile.Container = $("#txtContainerProfileContainer", page).val();
|
||||
|
||||
if (isSubProfileNew) {
|
||||
currentProfile.ContainerProfiles.push(currentSubProfile);
|
||||
}
|
||||
|
||||
renderSubProfiles(page, currentProfile);
|
||||
currentSubProfile = null;
|
||||
closePopup($("#containerProfilePopup", page)[0]);
|
||||
}
|
||||
|
||||
function renderCodecProfiles(page, profiles) {
|
||||
var html = "";
|
||||
html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
|
||||
var currentType;
|
||||
|
||||
for (var i__p = 0, length = profiles.length; i__p < length; i__p++) {
|
||||
var profile = profiles[i__p];
|
||||
var type = profile.Type.replace("VideoAudio", "Video Audio");
|
||||
|
||||
if (type !== currentType) {
|
||||
html += '<li data-role="list-divider">' + type + "</li>";
|
||||
currentType = type;
|
||||
}
|
||||
|
||||
html += "<li>";
|
||||
html += '<a data-profileindex="' + i__p + '" class="lnkEditSubProfile" is="emby-linkbutton" href="#">';
|
||||
html += "<p>" + Globalize.translate("ValueCodec").replace("{0}", profile.Codec || allText) + "</p>";
|
||||
|
||||
if (profile.Conditions && profile.Conditions.length) {
|
||||
html += "<p>";
|
||||
html += Globalize.translate("ValueConditions").replace("{0}", profile.Conditions.map(function (c__a) {
|
||||
return c__a.Property;
|
||||
}).join(", "));
|
||||
html += "</p>";
|
||||
}
|
||||
|
||||
html += "</a>";
|
||||
html += '<a is="emby-linkbutton" href="#" data-icon="delete" class="btnDeleteProfile" data-profileindex="' + i__p + '">Delete</a>';
|
||||
html += "</li>";
|
||||
}
|
||||
|
||||
html += "</ul>";
|
||||
var elem = $(".codecProfiles", page).html(html).trigger("create");
|
||||
$(".btnDeleteProfile", elem).on("click", function () {
|
||||
var index = this.getAttribute("data-profileindex");
|
||||
deleteCodecProfile(page, index);
|
||||
});
|
||||
$(".lnkEditSubProfile", elem).on("click", function () {
|
||||
var index = parseInt(this.getAttribute("data-profileindex"));
|
||||
editCodecProfile(page, currentProfile.CodecProfiles[index]);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteCodecProfile(page, index) {
|
||||
currentProfile.CodecProfiles.splice(index, 1);
|
||||
renderCodecProfiles(page, currentProfile.CodecProfiles);
|
||||
}
|
||||
|
||||
function editCodecProfile(page, codecProfile) {
|
||||
isSubProfileNew = null == codecProfile;
|
||||
codecProfile = codecProfile || {};
|
||||
currentSubProfile = codecProfile;
|
||||
var popup = $("#codecProfilePopup", page);
|
||||
$("#selectCodecProfileType", popup).val(codecProfile.Type || "Video").trigger("change");
|
||||
$("#txtCodecProfileCodec", popup).val(codecProfile.Codec || "");
|
||||
$(".radioTabButton:first", popup).trigger("click");
|
||||
openPopup(popup[0]);
|
||||
}
|
||||
|
||||
function saveCodecProfile(page) {
|
||||
currentSubProfile.Type = $("#selectCodecProfileType", page).val();
|
||||
currentSubProfile.Codec = $("#txtCodecProfileCodec", page).val();
|
||||
|
||||
if (isSubProfileNew) {
|
||||
currentProfile.CodecProfiles.push(currentSubProfile);
|
||||
}
|
||||
|
||||
renderSubProfiles(page, currentProfile);
|
||||
currentSubProfile = null;
|
||||
closePopup($("#codecProfilePopup", page)[0]);
|
||||
}
|
||||
|
||||
function renderResponseProfiles(page, profiles) {
|
||||
var html = "";
|
||||
html += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
|
||||
var currentType;
|
||||
|
||||
for (var i__s = 0, length = profiles.length; i__s < length; i__s++) {
|
||||
var profile = profiles[i__s];
|
||||
|
||||
if (profile.Type !== currentType) {
|
||||
html += '<li data-role="list-divider">' + profile.Type + "</li>";
|
||||
currentType = profile.Type;
|
||||
}
|
||||
|
||||
html += "<li>";
|
||||
html += '<a data-profileindex="' + i__s + '" class="lnkEditSubProfile" is="emby-linkbutton" href="#">';
|
||||
html += "<p>" + Globalize.translate("ValueContainer").replace("{0}", profile.Container || allText) + "</p>";
|
||||
|
||||
if ("Video" == profile.Type) {
|
||||
html += "<p>" + Globalize.translate("ValueVideoCodec").replace("{0}", profile.VideoCodec || allText) + "</p>";
|
||||
html += "<p>" + Globalize.translate("ValueAudioCodec").replace("{0}", profile.AudioCodec || allText) + "</p>";
|
||||
} else {
|
||||
if ("Audio" == profile.Type) {
|
||||
html += "<p>" + Globalize.translate("ValueCodec").replace("{0}", profile.AudioCodec || allText) + "</p>";
|
||||
}
|
||||
}
|
||||
|
||||
if (profile.Conditions && profile.Conditions.length) {
|
||||
html += "<p>";
|
||||
html += Globalize.translate("ValueConditions").replace("{0}", profile.Conditions.map(function (c__d) {
|
||||
return c__d.Property;
|
||||
}).join(", "));
|
||||
html += "</p>";
|
||||
}
|
||||
|
||||
html += "</a>";
|
||||
html += '<a is="emby-linkbutton" href="#" data-icon="delete" class="btnDeleteProfile" data-profileindex="' + i__s + '">Delete</a>';
|
||||
html += "</li>";
|
||||
}
|
||||
|
||||
html += "</ul>";
|
||||
var elem = $(".mediaProfiles", page).html(html).trigger("create");
|
||||
$(".btnDeleteProfile", elem).on("click", function () {
|
||||
var index = this.getAttribute("data-profileindex");
|
||||
deleteResponseProfile(page, index);
|
||||
});
|
||||
$(".lnkEditSubProfile", elem).on("click", function () {
|
||||
var index = parseInt(this.getAttribute("data-profileindex"));
|
||||
editResponseProfile(page, currentProfile.ResponseProfiles[index]);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteResponseProfile(page, index) {
|
||||
currentProfile.ResponseProfiles.splice(index, 1);
|
||||
renderResponseProfiles(page, currentProfile.ResponseProfiles);
|
||||
}
|
||||
|
||||
function editResponseProfile(page, responseProfile) {
|
||||
isSubProfileNew = null == responseProfile;
|
||||
responseProfile = responseProfile || {};
|
||||
currentSubProfile = responseProfile;
|
||||
var popup = $("#responseProfilePopup", page);
|
||||
$("#selectResponseProfileType", popup).val(responseProfile.Type || "Video").trigger("change");
|
||||
$("#txtResponseProfileContainer", popup).val(responseProfile.Container || "");
|
||||
$("#txtResponseProfileAudioCodec", popup).val(responseProfile.AudioCodec || "");
|
||||
$("#txtResponseProfileVideoCodec", popup).val(responseProfile.VideoCodec || "");
|
||||
$(".radioTabButton:first", popup).trigger("click");
|
||||
openPopup(popup[0]);
|
||||
}
|
||||
|
||||
function saveResponseProfile(page) {
|
||||
currentSubProfile.Type = $("#selectResponseProfileType", page).val();
|
||||
currentSubProfile.Container = $("#txtResponseProfileContainer", page).val();
|
||||
currentSubProfile.AudioCodec = $("#txtResponseProfileAudioCodec", page).val();
|
||||
currentSubProfile.VideoCodec = $("#txtResponseProfileVideoCodec", page).val();
|
||||
|
||||
if (isSubProfileNew) {
|
||||
currentProfile.ResponseProfiles.push(currentSubProfile);
|
||||
}
|
||||
|
||||
renderSubProfiles(page, currentProfile);
|
||||
currentSubProfile = null;
|
||||
closePopup($("#responseProfilePopup", page)[0]);
|
||||
}
|
||||
|
||||
function saveProfile(page, profile) {
|
||||
updateProfile(page, profile);
|
||||
var id = getParameterByName("id");
|
||||
|
||||
if (id) {
|
||||
ApiClient.ajax({
|
||||
type: "POST",
|
||||
url: ApiClient.getUrl("Dlna/Profiles/" + id),
|
||||
data: JSON.stringify(profile),
|
||||
contentType: "application/json"
|
||||
}).then(function () {
|
||||
require(["toast"], function (toast) {
|
||||
toast("Settings saved.");
|
||||
});
|
||||
}, Dashboard.processErrorResponse);
|
||||
} else {
|
||||
ApiClient.ajax({
|
||||
type: "POST",
|
||||
url: ApiClient.getUrl("Dlna/Profiles"),
|
||||
data: JSON.stringify(profile),
|
||||
contentType: "application/json"
|
||||
}).then(function () {
|
||||
Dashboard.navigate("dlnaprofiles.html");
|
||||
}, Dashboard.processErrorResponse);
|
||||
}
|
||||
|
||||
loading.hide();
|
||||
}
|
||||
|
||||
function updateProfile(page, profile) {
|
||||
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");
|
||||
}).join(",");
|
||||
profile.Identification = profile.Identification || {};
|
||||
profile.FriendlyName = $("#txtInfoFriendlyName", page).val();
|
||||
profile.ModelName = $("#txtInfoModelName", page).val();
|
||||
profile.ModelNumber = $("#txtInfoModelNumber", page).val();
|
||||
profile.ModelDescription = $("#txtInfoModelDescription", page).val();
|
||||
profile.ModelUrl = $("#txtInfoModelUrl", page).val();
|
||||
profile.Manufacturer = $("#txtInfoManufacturer", page).val();
|
||||
profile.ManufacturerUrl = $("#txtInfoManufacturerUrl", page).val();
|
||||
profile.SerialNumber = $("#txtInfoSerialNumber", page).val();
|
||||
profile.Identification.FriendlyName = $("#txtIdFriendlyName", page).val();
|
||||
profile.Identification.ModelName = $("#txtIdModelName", page).val();
|
||||
profile.Identification.ModelNumber = $("#txtIdModelNumber", page).val();
|
||||
profile.Identification.ModelDescription = $("#txtIdModelDescription", page).val();
|
||||
profile.Identification.ModelUrl = $("#txtIdModelUrl", page).val();
|
||||
profile.Identification.Manufacturer = $("#txtIdManufacturer", page).val();
|
||||
profile.Identification.ManufacturerUrl = $("#txtIdManufacturerUrl", page).val();
|
||||
profile.Identification.SerialNumber = $("#txtIdSerialNumber", page).val();
|
||||
profile.Identification.DeviceDescription = $("#txtIdDeviceDescription", page).val();
|
||||
profile.AlbumArtPn = $("#txtAlbumArtPn", page).val();
|
||||
profile.MaxAlbumArtWidth = $("#txtAlbumArtMaxWidth", page).val();
|
||||
profile.MaxAlbumArtHeight = $("#txtAlbumArtMaxHeight", page).val();
|
||||
profile.MaxIconWidth = $("#txtIconMaxWidth", page).val();
|
||||
profile.MaxIconHeight = $("#txtIconMaxHeight", page).val();
|
||||
profile.RequiresPlainFolders = $("#chkRequiresPlainFolders", page).checked();
|
||||
profile.RequiresPlainVideoItems = $("#chkRequiresPlainVideoItems", page).checked();
|
||||
profile.IgnoreTranscodeByteRangeRequests = $("#chkIgnoreTranscodeByteRangeRequests", page).checked();
|
||||
profile.MaxStreamingBitrate = $("#txtMaxAllowedBitrate", page).val();
|
||||
profile.MusicStreamingTranscodingBitrate = $("#txtMusicStreamingTranscodingBitrate", page).val();
|
||||
profile.ProtocolInfo = $("#txtProtocolInfo", page).val();
|
||||
profile.XDlnaCap = $("#txtXDlnaCap", page).val();
|
||||
profile.XDlnaDoc = $("#txtXDlnaDoc", page).val();
|
||||
profile.SonyAggregationFlags = $("#txtSonyAggregationFlags", page).val();
|
||||
profile.UserId = $("#selectUser", page).val();
|
||||
}
|
||||
|
||||
var currentProfile;
|
||||
var currentSubProfile;
|
||||
var isSubProfileNew;
|
||||
var allText = Globalize.translate("LabelAll");
|
||||
|
||||
$(document).on("pageinit", "#dlnaProfilePage", function () {
|
||||
var page = this;
|
||||
$(".radioTabButton", page).on("click", function () {
|
||||
$(this).siblings().removeClass("ui-btn-active");
|
||||
$(this).addClass("ui-btn-active");
|
||||
var value = "A" == this.tagName ? this.getAttribute("data-value") : this.value;
|
||||
var elem = $("." + value, page);
|
||||
elem.siblings(".tabContent").hide();
|
||||
elem.show();
|
||||
});
|
||||
$("#selectDirectPlayProfileType", page).on("change", function () {
|
||||
if ("Video" == this.value) {
|
||||
$("#fldDirectPlayVideoCodec", page).show();
|
||||
} else {
|
||||
$("#fldDirectPlayVideoCodec", page).hide();
|
||||
}
|
||||
|
||||
if ("Photo" == this.value) {
|
||||
$("#fldDirectPlayAudioCodec", page).hide();
|
||||
} else {
|
||||
$("#fldDirectPlayAudioCodec", page).show();
|
||||
}
|
||||
});
|
||||
$("#selectTranscodingProfileType", page).on("change", function () {
|
||||
if ("Video" == this.value) {
|
||||
$("#fldTranscodingVideoCodec", page).show();
|
||||
$("#fldTranscodingProtocol", page).show();
|
||||
$("#fldEnableMpegtsM2TsMode", page).show();
|
||||
} else {
|
||||
$("#fldTranscodingVideoCodec", page).hide();
|
||||
$("#fldTranscodingProtocol", page).hide();
|
||||
$("#fldEnableMpegtsM2TsMode", page).hide();
|
||||
}
|
||||
|
||||
if ("Photo" == this.value) {
|
||||
$("#fldTranscodingAudioCodec", page).hide();
|
||||
$("#fldEstimateContentLength", page).hide();
|
||||
$("#fldReportByteRangeRequests", page).hide();
|
||||
} else {
|
||||
$("#fldTranscodingAudioCodec", page).show();
|
||||
$("#fldEstimateContentLength", page).show();
|
||||
$("#fldReportByteRangeRequests", page).show();
|
||||
}
|
||||
});
|
||||
$("#selectResponseProfileType", page).on("change", function () {
|
||||
if ("Video" == this.value) {
|
||||
$("#fldResponseProfileVideoCodec", page).show();
|
||||
} else {
|
||||
$("#fldResponseProfileVideoCodec", page).hide();
|
||||
}
|
||||
|
||||
if ("Photo" == this.value) {
|
||||
$("#fldResponseProfileAudioCodec", page).hide();
|
||||
} else {
|
||||
$("#fldResponseProfileAudioCodec", page).show();
|
||||
}
|
||||
});
|
||||
$(".btnAddDirectPlayProfile", page).on("click", function () {
|
||||
editDirectPlayProfile(page);
|
||||
});
|
||||
$(".btnAddTranscodingProfile", page).on("click", function () {
|
||||
editTranscodingProfile(page);
|
||||
});
|
||||
$(".btnAddContainerProfile", page).on("click", function () {
|
||||
editContainerProfile(page);
|
||||
});
|
||||
$(".btnAddCodecProfile", page).on("click", function () {
|
||||
editCodecProfile(page);
|
||||
});
|
||||
$(".btnAddResponseProfile", page).on("click", function () {
|
||||
editResponseProfile(page);
|
||||
});
|
||||
$(".btnAddIdentificationHttpHeader", page).on("click", function () {
|
||||
editIdentificationHeader(page);
|
||||
});
|
||||
$(".btnAddXmlDocumentAttribute", page).on("click", function () {
|
||||
editXmlDocumentAttribute(page);
|
||||
});
|
||||
$(".btnAddSubtitleProfile", page).on("click", function () {
|
||||
editSubtitleProfile(page);
|
||||
});
|
||||
$(".dlnaProfileForm").off("submit", DlnaProfilePage.onSubmit).on("submit", DlnaProfilePage.onSubmit);
|
||||
$(".editDirectPlayProfileForm").off("submit", DlnaProfilePage.onDirectPlayFormSubmit).on("submit", DlnaProfilePage.onDirectPlayFormSubmit);
|
||||
$(".transcodingProfileForm").off("submit", DlnaProfilePage.onTranscodingProfileFormSubmit).on("submit", DlnaProfilePage.onTranscodingProfileFormSubmit);
|
||||
$(".containerProfileForm").off("submit", DlnaProfilePage.onContainerProfileFormSubmit).on("submit", DlnaProfilePage.onContainerProfileFormSubmit);
|
||||
$(".codecProfileForm").off("submit", DlnaProfilePage.onCodecProfileFormSubmit).on("submit", DlnaProfilePage.onCodecProfileFormSubmit);
|
||||
$(".editResponseProfileForm").off("submit", DlnaProfilePage.onResponseProfileFormSubmit).on("submit", DlnaProfilePage.onResponseProfileFormSubmit);
|
||||
$(".identificationHeaderForm").off("submit", DlnaProfilePage.onIdentificationHeaderFormSubmit).on("submit", DlnaProfilePage.onIdentificationHeaderFormSubmit);
|
||||
$(".xmlAttributeForm").off("submit", DlnaProfilePage.onXmlAttributeFormSubmit).on("submit", DlnaProfilePage.onXmlAttributeFormSubmit);
|
||||
$(".subtitleProfileForm").off("submit", DlnaProfilePage.onSubtitleProfileFormSubmit).on("submit", DlnaProfilePage.onSubtitleProfileFormSubmit);
|
||||
}).on("pageshow", "#dlnaProfilePage", function () {
|
||||
var page = this;
|
||||
$("#radioInfo", page).trigger("click");
|
||||
loadProfile(page);
|
||||
});
|
||||
window.DlnaProfilePage = {
|
||||
onSubmit: function () {
|
||||
loading.show();
|
||||
saveProfile($(this).parents(".page"), currentProfile);
|
||||
return false;
|
||||
},
|
||||
onDirectPlayFormSubmit: function () {
|
||||
saveDirectPlayProfile($(this).parents(".page"));
|
||||
return false;
|
||||
},
|
||||
onTranscodingProfileFormSubmit: function () {
|
||||
saveTranscodingProfile($(this).parents(".page"));
|
||||
return false;
|
||||
},
|
||||
onContainerProfileFormSubmit: function () {
|
||||
saveContainerProfile($(this).parents(".page"));
|
||||
return false;
|
||||
},
|
||||
onCodecProfileFormSubmit: function () {
|
||||
saveCodecProfile($(this).parents(".page"));
|
||||
return false;
|
||||
},
|
||||
onResponseProfileFormSubmit: function () {
|
||||
saveResponseProfile($(this).parents(".page"));
|
||||
return false;
|
||||
},
|
||||
onIdentificationHeaderFormSubmit: function () {
|
||||
saveIdentificationHeader($(this).parents(".page"));
|
||||
return false;
|
||||
},
|
||||
onXmlAttributeFormSubmit: function () {
|
||||
saveXmlDocumentAttribute($(this).parents(".page"));
|
||||
return false;
|
||||
},
|
||||
onSubtitleProfileFormSubmit: function () {
|
||||
saveSubtitleProfile($(this).parents(".page"));
|
||||
return false;
|
||||
}
|
||||
};
|
||||
});
|
61
src/controllers/dlnaprofiles.js
Normal file
61
src/controllers/dlnaprofiles.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
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()
|
||||
})
|
||||
}
|
||||
|
||||
function renderUserProfiles(page, profiles) {
|
||||
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
|
||||
}))
|
||||
}
|
||||
|
||||
function renderProfiles(page, element, profiles) {
|
||||
var html = "";
|
||||
profiles.length && (html += '<div class="paperList">');
|
||||
for (var i = 0, length = profiles.length; i < length; i++) {
|
||||
var profile = profiles[i];
|
||||
html += '<div class="listItem listItem-border">', html += '<i class="listItemIcon md-icon">live_tv</i>', html += '<div class="listItemBody two-line">', html += "<a is='emby-linkbutton' style='padding:0;margin:0;' data-ripple='false' class='clearLink' href='dlnaprofile.html?id=" + profile.Id + "'>", html += "<div>" + profile.Name + "</div>", html += "</a>", html += "</div>", "User" == profile.Type && (html += '<button type="button" is="paper-icon-button-light" class="btnDeleteProfile" data-profileid="' + profile.Id + '" title="' + globalize.translate("ButtonDelete") + '"><i class="md-icon">delete</i></button>'), html += "</div>"
|
||||
}
|
||||
profiles.length && (html += "</div>"), element.innerHTML = html, $(".btnDeleteProfile", element).on("click", function() {
|
||||
var id = this.getAttribute("data-profileid");
|
||||
deleteProfile(page, id)
|
||||
})
|
||||
}
|
||||
|
||||
function deleteProfile(page, id) {
|
||||
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)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function getTabs() {
|
||||
return [{
|
||||
href: "dlnasettings.html",
|
||||
name: globalize.translate("TabSettings")
|
||||
}, {
|
||||
href: "dlnaprofiles.html",
|
||||
name: globalize.translate("TabProfiles")
|
||||
}]
|
||||
}
|
||||
|
||||
$(document).on("pageshow", "#dlnaProfilesPage", function() {
|
||||
libraryMenu.setTabs("dlna", 1, getTabs), loadProfiles(this)
|
||||
})
|
||||
});
|
40
src/controllers/dlnasettings.js
Normal file
40
src/controllers/dlnasettings.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
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 '<option value="' + u.Id + '">' + u.Name + "</option>"
|
||||
}).join("");
|
||||
$("#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
|
||||
}
|
||||
|
||||
function getTabs() {
|
||||
return [{
|
||||
href: "dlnasettings.html",
|
||||
name: Globalize.translate("TabSettings")
|
||||
}, {
|
||||
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])
|
||||
})
|
||||
})
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
define(["loading"], function(loading) {
|
||||
define(["loading", "scripts/editorsidebar"], function(loading) {
|
||||
"use strict";
|
||||
|
||||
function reload(context, itemId) {
|
||||
|
|
109
src/controllers/encodingsettings.js
Normal file
109
src/controllers/encodingsettings.js
Normal file
|
@ -0,0 +1,109 @@
|
|||
define(["jQuery", "loading", "globalize", "dom"], function($, loading, globalize, dom) {
|
||||
"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"))
|
||||
});
|
||||
page.querySelector("#chkHardwareEncoding").checked = config.EnableHardwareEncoding;
|
||||
$("#selectVideoDecoder", page).val(config.HardwareAccelerationType);
|
||||
$("#selectThreadCount", page).val(config.EncodingThreadCount);
|
||||
$("#txtDownMixAudioBoost", page).val(config.DownMixAudioBoost);
|
||||
page.querySelector(".txtEncoderPath").value = config.EncoderAppPathDisplay || "";
|
||||
$("#txtTranscodingTempPath", page).val(config.TranscodingTempPath || "");
|
||||
$("#txtVaapiDevice", page).val(config.VaapiDevice || "");
|
||||
page.querySelector("#selectH264Preset").value = config.H264Preset || "";
|
||||
page.querySelector("#txtH264Crf").value = config.H264Crf || "";
|
||||
page.querySelector("#chkEnableSubtitleExtraction").checked = config.EnableSubtitleExtraction || false;
|
||||
page.querySelector("#selectVideoDecoder").dispatchEvent(new CustomEvent("change", {
|
||||
bubbles: true
|
||||
})), loading.hide()
|
||||
}
|
||||
|
||||
function onSaveEncodingPathFailure(response) {
|
||||
loading.hide();
|
||||
var msg = "";
|
||||
msg = globalize.translate("FFmpegSavePathNotFound"), require(["alert"], function(alert) {
|
||||
alert(msg)
|
||||
})
|
||||
}
|
||||
|
||||
function updateEncoder(form) {
|
||||
return ApiClient.getSystemInfo().then(function(systemInfo) {
|
||||
return ApiClient.ajax({
|
||||
url: ApiClient.getUrl("System/MediaEncoder/Path"),
|
||||
type: "POST",
|
||||
data: {
|
||||
Path: form.querySelector(".txtEncoderPath").value,
|
||||
PathType: "Custom"
|
||||
}
|
||||
}).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
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
$(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;
|
||||
picker.show({
|
||||
includeFiles: !0,
|
||||
callback: function(path) {
|
||||
path && $(".txtEncoderPath", page).val(path), picker.close()
|
||||
}
|
||||
})
|
||||
})
|
||||
}), $("#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()
|
||||
},
|
||||
validateWriteable: !0,
|
||||
header: globalize.translate("HeaderSelectTranscodingPath"),
|
||||
instruction: globalize.translate("HeaderSelectTranscodingPathHelp")
|
||||
})
|
||||
})
|
||||
}), $(".encodingSettingsForm").off("submit", onSubmit).on("submit", onSubmit)
|
||||
}).on("pageshow", "#encodingSettingsPage", function() {
|
||||
loading.show();
|
||||
var page = this;
|
||||
ApiClient.getNamedConfiguration("encoding").then(function(config) {
|
||||
ApiClient.getSystemInfo().then(function(systemInfo) {
|
||||
loadPage(page, config, systemInfo);
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
|
@ -167,7 +167,6 @@ define(["appRouter", "cardBuilder", "dom", "globalize", "connectionManager", "ap
|
|||
action: section.action,
|
||||
allowBottomPadding: !enableScrollX(),
|
||||
cardLayout: cardLayout,
|
||||
vibrant: supportsImageAnalysis && cardLayout,
|
||||
leadingButtons: leadingButtons,
|
||||
lines: lines
|
||||
})
|
||||
|
|
26
src/controllers/livetvguideprovider.js
Normal file
26
src/controllers/livetvguideprovider.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
define(["events", "loading"], function(events, loading) {
|
||||
"use strict";
|
||||
|
||||
function onListingsSubmitted() {
|
||||
Dashboard.navigate("livetvstatus.html")
|
||||
}
|
||||
|
||||
function init(page, type, providerId) {
|
||||
var url = "components/tvproviders/" + type + ".js";
|
||||
require([url], function(factory) {
|
||||
var instance = new factory(page, providerId, {});
|
||||
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)
|
||||
})
|
||||
}
|
||||
pageIdOn("pageshow", "liveTvGuideProviderPage", function() {
|
||||
loading.show();
|
||||
var providerId = getParameterByName("id");
|
||||
loadTemplate(this, getParameterByName("type"), providerId)
|
||||
})
|
||||
});
|
79
src/controllers/livetvsettings.js
Normal file
79
src/controllers/livetvsettings.js
Normal file
|
@ -0,0 +1,79 @@
|
|||
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()
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
loading.show();
|
||||
var form = this;
|
||||
return 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
|
||||
}
|
||||
|
||||
function showSaveMessage(recordingPathChanged) {
|
||||
var msg = "";
|
||||
recordingPathChanged && (msg += Globalize.translate("RecordingPathChangeMessage")), msg && require(["alert"], function(alert) {
|
||||
alert(msg)
|
||||
})
|
||||
}
|
||||
$(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;
|
||||
picker.show({
|
||||
callback: function(path) {
|
||||
path && $("#txtRecordingPath", page).val(path), picker.close()
|
||||
},
|
||||
validateWriteable: !0
|
||||
})
|
||||
})
|
||||
}), $("#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()
|
||||
},
|
||||
validateWriteable: !0
|
||||
})
|
||||
})
|
||||
}), $("#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()
|
||||
},
|
||||
validateWriteable: !0
|
||||
})
|
||||
})
|
||||
}), $("#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()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}).on("pageshow", "#liveTvSettingsPage", function() {
|
||||
loading.show();
|
||||
var page = this;
|
||||
ApiClient.getNamedConfiguration("livetv").then(function(config) {
|
||||
loadPage(page, config)
|
||||
})
|
||||
})
|
||||
});
|
249
src/controllers/livetvstatus.js
Normal file
249
src/controllers/livetvstatus.js
Normal file
|
@ -0,0 +1,249 @@
|
|||
define(["jQuery", "globalize", "scripts/taskbutton", "dom", "libraryMenu", "layoutManager", "loading", "listViewStyle", "flexStyles", "emby-itemscontainer", "cardStyle", "material-icons", "emby-button"], function($, globalize, taskButton, dom, libraryMenu, layoutManager, loading) {
|
||||
"use strict";
|
||||
|
||||
function getDeviceHtml(device) {
|
||||
var padderClass, html = "",
|
||||
cssClass = "card scalableCard",
|
||||
cardBoxCssClass = "cardBox visualCardBox";
|
||||
return cssClass += " backdropCard backdropCard-scalable", padderClass = "cardPadder-backdrop", layoutManager.tv && (cssClass += " card-focusscale", cardBoxCssClass += " cardBox-focustransform"), cardBoxCssClass += " card-focuscontent", html += '<div type="button" class="' + cssClass + '" data-id="' + device.Id + '">', html += '<div class="' + cardBoxCssClass + '">', html += '<div class="cardScalable visualCardBox-cardScalable">', html += '<div class="' + padderClass + '"></div>', html += '<div class="cardContent searchImage">', html += '<div class="cardImageContainer coveredImage"><i class="cardImageIcon md-icon">dvr</i></div>', html += "</div>", html += "</div>", html += '<div class="cardFooter visualCardBox-cardFooter">', html += '<button is="paper-icon-button-light" class="itemAction btnCardOptions autoSize" data-action="menu"><i class="md-icon">more_horiz</i></button>', html += '<div class="cardText">' + (device.FriendlyName || getTunerName(device.Type)) + "</div>", html += '<div class="cardText cardText-secondary">', html += device.Url || " ", html += "</div>", html += "</div>", html += "</div>", html += "</div>"
|
||||
}
|
||||
|
||||
function renderDevices(page, devices) {
|
||||
var html = devices.map(getDeviceHtml).join("");
|
||||
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({
|
||||
type: "DELETE",
|
||||
url: ApiClient.getUrl("LiveTv/TunerHosts", {
|
||||
Id: id
|
||||
})
|
||||
}).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()
|
||||
}
|
||||
|
||||
function submitAddDeviceForm(page) {
|
||||
page.querySelector(".dlgAddDevice").close(), loading.show(), ApiClient.ajax({
|
||||
type: "POST",
|
||||
url: ApiClient.getUrl("LiveTv/TunerHosts"),
|
||||
data: JSON.stringify({
|
||||
Type: $("#selectTunerDeviceType", page).val(),
|
||||
Url: $("#txtDevicePath", page).val()
|
||||
}),
|
||||
contentType: "application/json"
|
||||
}).then(function() {
|
||||
reload(page)
|
||||
}, function() {
|
||||
Dashboard.alert({
|
||||
message: globalize.translate("ErrorAddingTunerDevice")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function renderProviders(page, providers) {
|
||||
var html = "";
|
||||
if (providers.length) {
|
||||
html += '<div class="paperList">';
|
||||
for (var i = 0, length = providers.length; i < length; i++) {
|
||||
var provider = providers[i];
|
||||
html += '<div class="listItem">', html += '<i class="listItemIcon md-icon">dvr</i>', html += '<div class="listItemBody two-line">', html += '<a is="emby-linkbutton" style="display:block;padding:0;margin:0;text-align:left;" class="clearLink" href="' + getProviderConfigurationUrl(provider.Type) + "&id=" + provider.Id + '">', html += '<h3 class="listItemBodyText">', html += getProviderName(provider.Type), html += "</h3>", html += '<div class="listItemBodyText secondary">', html += provider.Path || provider.ListingsId || "", html += "</div>", html += "</a>", html += "</div>", html += '<button type="button" is="paper-icon-button-light" class="btnOptions" data-id="' + provider.Id + '"><i class="md-icon listItemAside">more_horiz</i></button>', html += "</div>"
|
||||
}
|
||||
html += "</div>"
|
||||
}
|
||||
var elem = $(".providerList", page).html(html);
|
||||
$(".btnOptions", elem).on("click", function() {
|
||||
var id = this.getAttribute("data-id");
|
||||
showProviderOptions(page, id, this)
|
||||
})
|
||||
}
|
||||
|
||||
function showProviderOptions(page, providerId, button) {
|
||||
var items = [];
|
||||
items.push({
|
||||
name: globalize.translate("ButtonDelete"),
|
||||
id: "delete"
|
||||
}), items.push({
|
||||
name: globalize.translate("MapChannels"),
|
||||
id: "map"
|
||||
}), require(["actionsheet"], function(actionsheet) {
|
||||
actionsheet.show({
|
||||
items: items,
|
||||
positionTo: button
|
||||
}).then(function(id) {
|
||||
switch (id) {
|
||||
case "delete":
|
||||
deleteProvider(page, providerId);
|
||||
break;
|
||||
case "map":
|
||||
mapChannels(page, providerId)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function mapChannels(page, providerId) {
|
||||
require(["components/channelmapper/channelmapper"], function(channelmapper) {
|
||||
new channelmapper({
|
||||
serverId: ApiClient.serverInfo().Id,
|
||||
providerId: providerId
|
||||
}).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({
|
||||
type: "DELETE",
|
||||
url: ApiClient.getUrl("LiveTv/ListingProviders", {
|
||||
Id: id
|
||||
})
|
||||
}).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"
|
||||
}
|
||||
}
|
||||
|
||||
function getProviderName(providerId) {
|
||||
switch (providerId = providerId.toLowerCase()) {
|
||||
case "schedulesdirect":
|
||||
return "Schedules Direct";
|
||||
case "xmltv":
|
||||
return "Xml TV";
|
||||
case "emby":
|
||||
return "Emby Guide";
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
function getProviderConfigurationUrl(providerId) {
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
||||
function addProvider(button) {
|
||||
var menuItems = [];
|
||||
menuItems.push({
|
||||
name: "Schedules Direct",
|
||||
id: "SchedulesDirect"
|
||||
}), menuItems.push({
|
||||
name: "Xml TV",
|
||||
id: "xmltv"
|
||||
}), menuItems.push({
|
||||
name: globalize.translate("ButtonOther"),
|
||||
id: "other"
|
||||
}), require(["actionsheet"], function(actionsheet) {
|
||||
actionsheet.show({
|
||||
items: menuItems,
|
||||
positionTo: button,
|
||||
callback: function(id) {
|
||||
"other" == id ? Dashboard.alert({
|
||||
message: globalize.translate("ForAdditionalLiveTvOptions")
|
||||
}) : Dashboard.navigate(getProviderConfigurationUrl(id))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function addDevice(button) {
|
||||
Dashboard.navigate("livetvtuner.html")
|
||||
}
|
||||
|
||||
function showDeviceMenu(button, tunerDeviceId) {
|
||||
var items = [];
|
||||
items.push({
|
||||
name: globalize.translate("ButtonDelete"),
|
||||
id: "delete"
|
||||
}), items.push({
|
||||
name: globalize.translate("ButtonEdit"),
|
||||
id: "edit"
|
||||
}), require(["actionsheet"], function(actionsheet) {
|
||||
actionsheet.show({
|
||||
items: items,
|
||||
positionTo: button
|
||||
}).then(function(id) {
|
||||
switch (id) {
|
||||
case "delete":
|
||||
deleteDevice(dom.parentWithClass(button, "page"), tunerDeviceId);
|
||||
break;
|
||||
case "edit":
|
||||
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)
|
||||
}
|
||||
}
|
||||
$(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() {
|
||||
var page = this;
|
||||
reload(page), taskButton({
|
||||
mode: "on",
|
||||
progressElem: page.querySelector(".refreshGuideProgress"),
|
||||
taskKey: "RefreshGuide",
|
||||
button: page.querySelector(".btnRefresh")
|
||||
})
|
||||
}).on("pagehide", "#liveTvStatusPage", function() {
|
||||
var page = this;
|
||||
taskButton({
|
||||
mode: "off",
|
||||
progressElem: page.querySelector(".refreshGuideProgress"),
|
||||
taskKey: "RefreshGuide",
|
||||
button: page.querySelector(".btnRefresh")
|
||||
})
|
||||
})
|
||||
});
|
308
src/controllers/medialibrarypage.js
Normal file
308
src/controllers/medialibrarypage.js
Normal file
|
@ -0,0 +1,308 @@
|
|||
define(["jQuery", "apphost", "scripts/taskbutton", "loading", "libraryMenu", "globalize", "dom", "indicators", "cardStyle", "emby-itemrefreshindicator"], function($, appHost, taskButton, loading, libraryMenu, globalize, dom, indicators) {
|
||||
"use strict";
|
||||
|
||||
function changeCollectionType(page, virtualFolder) {
|
||||
require(["alert"], function(alert) {
|
||||
alert({
|
||||
title: globalize.translate("HeaderChangeFolderType"),
|
||||
text: globalize.translate("HeaderChangeFolderTypeHelp")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function addVirtualFolder(page) {
|
||||
require(["medialibrarycreator"], function(medialibrarycreator) {
|
||||
(new medialibrarycreator).show({
|
||||
collectionTypeOptions: getCollectionTypeOptions().filter(function(f) {
|
||||
return !f.hidden
|
||||
}),
|
||||
refresh: shouldRefreshLibraryAfterChanges(page)
|
||||
}).then(function(hasChanges) {
|
||||
hasChanges && reloadLibrary(page)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function editVirtualFolder(page, virtualFolder) {
|
||||
require(["medialibraryeditor"], function(medialibraryeditor) {
|
||||
(new medialibraryeditor).show({
|
||||
refresh: shouldRefreshLibraryAfterChanges(page),
|
||||
library: virtualFolder
|
||||
}).then(function(hasChanges) {
|
||||
hasChanges && reloadLibrary(page)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function deleteVirtualFolder(page, virtualFolder) {
|
||||
var msg = globalize.translate("MessageAreYouSureYouWishToRemoveMediaFolder");
|
||||
virtualFolder.Locations.length && (msg += "<br/><br/>" + globalize.translate("MessageTheFollowingLocationWillBeRemovedFromLibrary") + "<br/><br/>", msg += virtualFolder.Locations.join("<br/>")), require(["confirm"], function(confirm) {
|
||||
confirm(msg, globalize.translate("HeaderRemoveMediaFolder")).then(function() {
|
||||
var refreshAfterChange = shouldRefreshLibraryAfterChanges(page);
|
||||
ApiClient.removeVirtualFolder(virtualFolder.Name, refreshAfterChange).then(function() {
|
||||
reloadLibrary(page)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function refreshVirtualFolder(page, virtualFolder) {
|
||||
require(["refreshDialog"], function(refreshDialog) {
|
||||
new refreshDialog({
|
||||
itemIds: [virtualFolder.ItemId],
|
||||
serverId: ApiClient.serverId(),
|
||||
mode: "scan"
|
||||
}).show()
|
||||
})
|
||||
}
|
||||
|
||||
function renameVirtualFolder(page, virtualFolder) {
|
||||
require(["prompt"], function(prompt) {
|
||||
prompt({
|
||||
label: globalize.translate("LabelNewName"),
|
||||
confirmText: globalize.translate("ButtonRename")
|
||||
}).then(function(newName) {
|
||||
if (newName && newName != virtualFolder.Name) {
|
||||
var refreshAfterChange = shouldRefreshLibraryAfterChanges(page);
|
||||
ApiClient.renameVirtualFolder(virtualFolder.Name, newName, refreshAfterChange).then(function() {
|
||||
reloadLibrary(page)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function showCardMenu(page, elem, virtualFolders) {
|
||||
var card = dom.parentWithClass(elem, "card"),
|
||||
index = parseInt(card.getAttribute("data-index")),
|
||||
virtualFolder = virtualFolders[index],
|
||||
menuItems = [];
|
||||
menuItems.push({
|
||||
name: globalize.translate("ButtonChangeContentType"),
|
||||
id: "changetype",
|
||||
ironIcon: "videocam"
|
||||
}), menuItems.push({
|
||||
name: globalize.translate("ButtonEditImages"),
|
||||
id: "editimages",
|
||||
ironIcon: "photo"
|
||||
}), menuItems.push({
|
||||
name: globalize.translate("ManageLibrary"),
|
||||
id: "edit",
|
||||
ironIcon: "folder_open"
|
||||
}), menuItems.push({
|
||||
name: globalize.translate("ButtonRemove"),
|
||||
id: "delete",
|
||||
ironIcon: "remove"
|
||||
}), menuItems.push({
|
||||
name: globalize.translate("ButtonRename"),
|
||||
id: "rename",
|
||||
ironIcon: "mode_edit"
|
||||
}), menuItems.push({
|
||||
name: globalize.translate("ScanLibrary"),
|
||||
id: "refresh",
|
||||
ironIcon: "refresh"
|
||||
}), require(["actionsheet"], function(actionsheet) {
|
||||
actionsheet.show({
|
||||
items: menuItems,
|
||||
positionTo: elem,
|
||||
callback: function(resultId) {
|
||||
switch (resultId) {
|
||||
case "changetype":
|
||||
changeCollectionType(page, virtualFolder);
|
||||
break;
|
||||
case "edit":
|
||||
editVirtualFolder(page, virtualFolder);
|
||||
break;
|
||||
case "editimages":
|
||||
editImages(page, virtualFolder);
|
||||
break;
|
||||
case "rename":
|
||||
renameVirtualFolder(page, virtualFolder);
|
||||
break;
|
||||
case "delete":
|
||||
deleteVirtualFolder(page, virtualFolder);
|
||||
break;
|
||||
case "refresh":
|
||||
refreshVirtualFolder(page, virtualFolder)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function reloadLibrary(page) {
|
||||
loading.show(), ApiClient.getVirtualFolders().then(function(result) {
|
||||
reloadVirtualFolders(page, result)
|
||||
})
|
||||
}
|
||||
|
||||
function shouldRefreshLibraryAfterChanges(page) {
|
||||
return "mediaLibraryPage" === page.id
|
||||
}
|
||||
|
||||
function reloadVirtualFolders(page, virtualFolders) {
|
||||
var html = "";
|
||||
virtualFolders.push({
|
||||
Name: globalize.translate("ButtonAddMediaLibrary"),
|
||||
icon: "add_circle",
|
||||
Locations: [],
|
||||
showType: !1,
|
||||
showLocations: !1,
|
||||
showMenu: !1,
|
||||
showNameWithIcon: !0
|
||||
});
|
||||
for (var i = 0, length = virtualFolders.length; i < length; i++) {
|
||||
var virtualFolder = virtualFolders[i];
|
||||
html += getVirtualFolderHtml(page, virtualFolder, i)
|
||||
}
|
||||
var divVirtualFolders = page.querySelector("#divVirtualFolders");
|
||||
divVirtualFolders.innerHTML = html, divVirtualFolders.classList.add("itemsContainer"), divVirtualFolders.classList.add("vertical-wrap"), $(".btnCardMenu", divVirtualFolders).on("click", function() {
|
||||
showCardMenu(page, this, virtualFolders)
|
||||
}), divVirtualFolders.querySelector(".addLibrary").addEventListener("click", function() {
|
||||
addVirtualFolder(page)
|
||||
}), $(".editLibrary", divVirtualFolders).on("click", function() {
|
||||
var card = $(this).parents(".card")[0],
|
||||
index = parseInt(card.getAttribute("data-index")),
|
||||
virtualFolder = virtualFolders[index];
|
||||
virtualFolder.ItemId && editVirtualFolder(page, virtualFolder)
|
||||
}), loading.hide()
|
||||
}
|
||||
|
||||
function editImages(page, virtualFolder) {
|
||||
require(["imageEditor"], function(imageEditor) {
|
||||
imageEditor.show({
|
||||
itemId: virtualFolder.ItemId,
|
||||
serverId: ApiClient.serverId()
|
||||
}).then(function() {
|
||||
reloadLibrary(page)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function getLink(text, url) {
|
||||
return globalize.translate(text, '<a is="emby-linkbutton" class="button-link" href="' + url + '" target="_blank" data-autohide="true">', "</a>")
|
||||
}
|
||||
|
||||
function getCollectionTypeOptions() {
|
||||
return [{
|
||||
name: "",
|
||||
value: ""
|
||||
}, {
|
||||
name: globalize.translate("FolderTypeMovies"),
|
||||
value: "movies",
|
||||
message: getLink("MovieLibraryHelp", "https://jellyfin.readthedocs.io/en/latest/media/movies/")
|
||||
}, {
|
||||
name: globalize.translate("FolderTypeMusic"),
|
||||
value: "music",
|
||||
message: getLink("MovieLibraryHelp", "https://jellyfin.readthedocs.io/en/latest/media/music/")
|
||||
}, {
|
||||
name: globalize.translate("FolderTypeTvShows"),
|
||||
value: "tvshows",
|
||||
message: getLink("TvLibraryHelp", "https://jellyfin.readthedocs.io/en/latest/media/shows/")
|
||||
}, {
|
||||
name: globalize.translate("FolderTypeBooks"),
|
||||
value: "books",
|
||||
message: getLink("BookLibraryHelp", "https://web.archive.org/web/20181216120305/https://github.com/MediaBrowser/Wiki/wiki/Book-naming")
|
||||
}, {
|
||||
name: globalize.translate("OptionHomeVideos"),
|
||||
value: "homevideos"
|
||||
}, {
|
||||
name: globalize.translate("FolderTypeMusicVideos"),
|
||||
value: "musicvideos"
|
||||
}, {
|
||||
name: globalize.translate("FolderTypeUnset"),
|
||||
value: "mixed",
|
||||
message: globalize.translate("MessageUnsetContentHelp")
|
||||
}]
|
||||
}
|
||||
|
||||
function getIcon(type) {
|
||||
switch (type) {
|
||||
case "movies":
|
||||
return "local_movies";
|
||||
case "music":
|
||||
return "library_music";
|
||||
case "photos":
|
||||
return "photo";
|
||||
case "livetv":
|
||||
case "tvshows":
|
||||
return "live_tv";
|
||||
case "trailers":
|
||||
return "local_movies";
|
||||
case "homevideos":
|
||||
case "musicvideos":
|
||||
return "video_library";
|
||||
case "books":
|
||||
case "channels":
|
||||
case "playlists":
|
||||
default:
|
||||
return "folder"
|
||||
}
|
||||
}
|
||||
|
||||
function getVirtualFolderHtml(page, virtualFolder, index) {
|
||||
var html = "",
|
||||
style = "";
|
||||
page.classList.contains("wizardPage") && (style += "min-width:33.3%;"), html += '<div class="card backdropCard scalableCard backdropCard-scalable" style="' + style + '" data-index="' + index + '" data-id="' + virtualFolder.ItemId + '">', html += '<div class="cardBox visualCardBox">', html += '<div class="cardScalable visualCardBox-cardScalable">', html += '<div class="cardPadder cardPadder-backdrop"></div>', html += '<div class="cardContent">';
|
||||
var imgUrl = "";
|
||||
virtualFolder.PrimaryImageItemId && (imgUrl = ApiClient.getScaledImageUrl(virtualFolder.PrimaryImageItemId, {
|
||||
type: "Primary"
|
||||
}));
|
||||
var hasCardImageContainer;
|
||||
if (imgUrl ? (html += '<div class="cardImageContainer editLibrary" style="cursor:pointer;background-image:url(\'' + imgUrl + "');\">", hasCardImageContainer = !0) : virtualFolder.showNameWithIcon || (html += '<div class="cardImageContainer editLibrary" style="cursor:pointer;">', html += '<i class="cardImageIcon-small md-icon">' + (virtualFolder.icon || getIcon(virtualFolder.CollectionType)) + "</i>", hasCardImageContainer = !0), hasCardImageContainer) {
|
||||
html += '<div class="cardIndicators backdropCardIndicators">';
|
||||
html += '<div is="emby-itemrefreshindicator"' + (virtualFolder.RefreshProgress || virtualFolder.RefreshStatus && "Idle" !== virtualFolder.RefreshStatus ? "" : ' class="hide"') + ' data-progress="' + (virtualFolder.RefreshProgress || 0) + '" data-status="' + virtualFolder.RefreshStatus + '"></div>', html += "</div>", html += "</div>"
|
||||
}
|
||||
if (!imgUrl && virtualFolder.showNameWithIcon && (html += '<h3 class="cardImageContainer addLibrary" style="position:absolute;top:0;left:0;right:0;bottom:0;cursor:pointer;flex-direction:column;">', html += '<i class="cardImageIcon-small md-icon">' + (virtualFolder.icon || getIcon(virtualFolder.CollectionType)) + "</i>", virtualFolder.showNameWithIcon && (html += '<div style="margin:1em 0;position:width:100%;">', html += virtualFolder.Name, html += "</div>"), html += "</h3>"), html += "</div>", html += "</div>", html += '<div class="cardFooter visualCardBox-cardFooter">', !1 !== virtualFolder.showMenu) {
|
||||
html += '<div style="text-align:right; float:right;padding-top:5px;">', html += '<button type="button" is="paper-icon-button-light" class="btnCardMenu autoSize"><i class="md-icon"></i></button>', html += "</div>"
|
||||
}
|
||||
html += "<div class='cardText'>", virtualFolder.showNameWithIcon ? html += " " : html += virtualFolder.Name, html += "</div>";
|
||||
var typeName = getCollectionTypeOptions().filter(function(t) {
|
||||
return t.value == virtualFolder.CollectionType
|
||||
})[0];
|
||||
return typeName = typeName ? typeName.name : globalize.translate("FolderTypeUnset"), html += "<div class='cardText cardText-secondary'>", !1 === virtualFolder.showType ? html += " " : html += typeName, html += "</div>", !1 === virtualFolder.showLocations ? (html += "<div class='cardText cardText-secondary'>", html += " ", html += "</div>") : virtualFolder.Locations.length && 1 == virtualFolder.Locations.length ? (html += "<div class='cardText cardText-secondary'>", html += virtualFolder.Locations[0], html += "</div>") : (html += "<div class='cardText cardText-secondary'>", html += globalize.translate("NumLocationsValue", virtualFolder.Locations.length), html += "</div>"), html += "</div>", html += "</div>", html += "</div>"
|
||||
}
|
||||
|
||||
function getTabs() {
|
||||
return [{
|
||||
href: "library.html",
|
||||
name: globalize.translate("HeaderLibraries")
|
||||
}, {
|
||||
href: "librarydisplay.html",
|
||||
name: globalize.translate("TabDisplay")
|
||||
}, {
|
||||
href: "metadataimages.html",
|
||||
name: globalize.translate("TabMetadata")
|
||||
}, {
|
||||
href: "metadatanfo.html",
|
||||
name: globalize.translate("TabNfoSettings")
|
||||
}, {
|
||||
href: "librarysettings.html",
|
||||
name: globalize.translate("TabAdvanced")
|
||||
}]
|
||||
}
|
||||
window.WizardLibraryPage = {
|
||||
next: function() {
|
||||
Dashboard.navigate("wizardsettings.html")
|
||||
}
|
||||
}, pageClassOn("pageshow", "mediaLibraryPage", function() {
|
||||
reloadLibrary(this)
|
||||
}), pageIdOn("pageshow", "mediaLibraryPage", function() {
|
||||
libraryMenu.setTabs("librarysetup", 0, getTabs);
|
||||
var page = this;
|
||||
taskButton({
|
||||
mode: "on",
|
||||
progressElem: page.querySelector(".refreshProgress"),
|
||||
taskKey: "RefreshLibrary",
|
||||
button: page.querySelector(".btnRefresh")
|
||||
})
|
||||
}), pageIdOn("pagebeforehide", "mediaLibraryPage", function() {
|
||||
var page = this;
|
||||
taskButton({
|
||||
mode: "off",
|
||||
progressElem: page.querySelector(".refreshProgress"),
|
||||
taskKey: "RefreshLibrary",
|
||||
button: page.querySelector(".btnRefresh")
|
||||
})
|
||||
})
|
||||
});
|
66
src/controllers/metadataimagespage.js
Normal file
66
src/controllers/metadataimagespage.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
define(["jQuery", "dom", "loading", "libraryMenu", "listViewStyle"], function($, dom, loading, libraryMenu) {
|
||||
"use strict";
|
||||
|
||||
function populateLanguages(select) {
|
||||
return ApiClient.getCultures().then(function(languages) {
|
||||
var html = "";
|
||||
html += "<option value=''></option>";
|
||||
for (var i = 0, length = languages.length; i < length; i++) {
|
||||
var culture = languages[i];
|
||||
html += "<option value='" + culture.TwoLetterISOLanguageName + "'>" + culture.DisplayName + "</option>"
|
||||
}
|
||||
select.innerHTML = html
|
||||
})
|
||||
}
|
||||
|
||||
function populateCountries(select) {
|
||||
return ApiClient.getCountries().then(function(allCountries) {
|
||||
var html = "";
|
||||
html += "<option value=''></option>";
|
||||
for (var i = 0, length = allCountries.length; i < length; i++) {
|
||||
var culture = allCountries[i];
|
||||
html += "<option value='" + culture.TwoLetterISORegionName + "'>" + culture.DisplayName + "</option>"
|
||||
}
|
||||
select.innerHTML = html
|
||||
})
|
||||
}
|
||||
|
||||
function loadPage(page) {
|
||||
var promises = [ApiClient.getServerConfiguration(), populateLanguages(page.querySelector("#selectLanguage")), populateCountries(page.querySelector("#selectCountry"))];
|
||||
Promise.all(promises).then(function(responses) {
|
||||
var config = responses[0];
|
||||
page.querySelector("#selectLanguage").value = config.PreferredMetadataLanguage || "", page.querySelector("#selectCountry").value = config.MetadataCountryCode || "", loading.hide()
|
||||
})
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
var form = this;
|
||||
return loading.show(), ApiClient.getServerConfiguration().then(function(config) {
|
||||
config.PreferredMetadataLanguage = form.querySelector("#selectLanguage").value, config.MetadataCountryCode = form.querySelector("#selectCountry").value, ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult)
|
||||
}), !1
|
||||
}
|
||||
|
||||
function getTabs() {
|
||||
return [{
|
||||
href: "library.html",
|
||||
name: Globalize.translate("HeaderLibraries")
|
||||
}, {
|
||||
href: "librarydisplay.html",
|
||||
name: Globalize.translate("TabDisplay")
|
||||
}, {
|
||||
href: "metadataimages.html",
|
||||
name: Globalize.translate("TabMetadata")
|
||||
}, {
|
||||
href: "metadatanfo.html",
|
||||
name: Globalize.translate("TabNfoSettings")
|
||||
}, {
|
||||
href: "librarysettings.html",
|
||||
name: Globalize.translate("TabAdvanced")
|
||||
}]
|
||||
}
|
||||
$(document).on("pageinit", "#metadataImagesConfigurationPage", function() {
|
||||
$(".metadataImagesConfigurationForm").off("submit", onSubmit).on("submit", onSubmit)
|
||||
}).on("pageshow", "#metadataImagesConfigurationPage", function() {
|
||||
libraryMenu.setTabs("metadata", 2, getTabs), loading.show(), loadPage(this)
|
||||
})
|
||||
});
|
60
src/controllers/metadatanfo.js
Normal file
60
src/controllers/metadatanfo.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
define(["jQuery", "loading", "libraryMenu"], function($, loading, libraryMenu) {
|
||||
"use strict";
|
||||
|
||||
function loadPage(page, config, users) {
|
||||
var html = '<option value="" selected="selected">' + Globalize.translate("OptionNone") + "</option>";
|
||||
html += users.map(function(user) {
|
||||
return '<option value="' + user.Id + '">' + user.Name + "</option>"
|
||||
}).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
|
||||
}
|
||||
|
||||
function showConfirmMessage(config) {
|
||||
var msg = [];
|
||||
msg.push(Globalize.translate("MetadataSettingChangeHelp")), require(["alert"], function(alert) {
|
||||
alert({
|
||||
text: msg.join("<br/><br/>")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function getTabs() {
|
||||
return [{
|
||||
href: "library.html",
|
||||
name: Globalize.translate("HeaderLibraries")
|
||||
}, {
|
||||
href: "librarydisplay.html",
|
||||
name: Globalize.translate("TabDisplay")
|
||||
}, {
|
||||
href: "metadataimages.html",
|
||||
name: Globalize.translate("TabMetadata")
|
||||
}, {
|
||||
href: "metadatanfo.html",
|
||||
name: Globalize.translate("TabNfoSettings")
|
||||
}, {
|
||||
href: "librarysettings.html",
|
||||
name: Globalize.translate("TabAdvanced")
|
||||
}]
|
||||
}
|
||||
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])
|
||||
})
|
||||
})
|
||||
});
|
|
@ -41,7 +41,6 @@ define(["browser", "layoutManager", "userSettings", "inputManager", "loading", "
|
|||
overlayPlayButton: !supportsImageAnalysis,
|
||||
allowBottomPadding: !enableScrollX(),
|
||||
cardLayout: supportsImageAnalysis,
|
||||
vibrant: supportsImageAnalysis,
|
||||
coverImage: !0
|
||||
}), imageLoader.lazyChildren(elem), loading.hide()
|
||||
})
|
||||
|
@ -78,7 +77,6 @@ define(["browser", "layoutManager", "userSettings", "inputManager", "loading", "
|
|||
overlayMoreButton: !supportsImageAnalysis,
|
||||
allowBottomPadding: !enableScrollX(),
|
||||
cardLayout: supportsImageAnalysis,
|
||||
vibrant: supportsImageAnalysis,
|
||||
coverImage: !0
|
||||
}), imageLoader.lazyChildren(itemsContainer)
|
||||
})
|
||||
|
@ -115,7 +113,6 @@ define(["browser", "layoutManager", "userSettings", "inputManager", "loading", "
|
|||
overlayMoreButton: !supportsImageAnalysis,
|
||||
allowBottomPadding: !enableScrollX(),
|
||||
cardLayout: supportsImageAnalysis,
|
||||
vibrant: supportsImageAnalysis,
|
||||
coverImage: !0
|
||||
}), imageLoader.lazyChildren(itemsContainer)
|
||||
})
|
||||
|
|
85
src/controllers/notificationsetting.js
Normal file
85
src/controllers/notificationsetting.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
define(["jQuery", "emby-checkbox", "fnchecked"], function($) {
|
||||
"use strict";
|
||||
|
||||
function fillItems(elem, items, cssClass, idPrefix, currentList, isEnabledList) {
|
||||
var html = '<div class="checkboxList paperList" style="padding: .5em 1em;">';
|
||||
html += items.map(function(u) {
|
||||
var isChecked = isEnabledList ? -1 != currentList.indexOf(u.Id) : -1 == currentList.indexOf(u.Id),
|
||||
checkedHtml = isChecked ? ' checked="checked"' : "";
|
||||
return '<label><input is="emby-checkbox" class="' + cssClass + '" type="checkbox" data-itemid="' + u.Id + '"' + checkedHtml + "/><span>" + u.Name + "</span></label>"
|
||||
}).join(""), html += "</div>", 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")
|
||||
})
|
||||
}
|
||||
|
||||
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
|
||||
})[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
|
||||
}
|
||||
var notificationsConfigurationKey = "notifications";
|
||||
$(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)
|
||||
})
|
||||
});
|
34
src/controllers/playbackconfiguration.js
Normal file
34
src/controllers/playbackconfiguration.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
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()
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
function getTabs() {
|
||||
return [{
|
||||
href: "playbackconfiguration.html",
|
||||
name: Globalize.translate("TabResumeSettings")
|
||||
}, {
|
||||
href: "streamingsettings.html",
|
||||
name: Globalize.translate("TabStreaming")
|
||||
}]
|
||||
}
|
||||
$(document).on("pageinit", "#playbackConfigurationPage", function() {
|
||||
$(".playbackConfigurationForm").off("submit", onSubmit).on("submit", onSubmit)
|
||||
}).on("pageshow", "#playbackConfigurationPage", function() {
|
||||
libraryMenu.setTabs("playback", 0, getTabs), loading.show();
|
||||
var page = this;
|
||||
ApiClient.getServerConfiguration().then(function(config) {
|
||||
loadPage(page, config)
|
||||
})
|
||||
})
|
||||
});
|
72
src/controllers/serversecurity.js
Normal file
72
src/controllers/serversecurity.js
Normal file
|
@ -0,0 +1,72 @@
|
|||
define(["datetime", "loading", "libraryMenu", "dom", "globalize", "emby-button"], function(datetime, loading, libraryMenu, dom, globalize) {
|
||||
"use strict";
|
||||
|
||||
function revoke(page, key) {
|
||||
require(["confirm"], function(confirm) {
|
||||
confirm(globalize.translate("MessageConfirmRevokeApiKey"), globalize.translate("HeaderConfirmRevokeApiKey")).then(function() {
|
||||
loading.show(), ApiClient.ajax({
|
||||
type: "DELETE",
|
||||
url: ApiClient.getUrl("Auth/Keys/" + key)
|
||||
}).then(function() {
|
||||
loadData(page)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function renderKeys(page, keys) {
|
||||
var rows = keys.map(function(item) {
|
||||
var html = "";
|
||||
html += '<tr class="detailTableBodyRow detailTableBodyRow-shaded">', html += '<td class="detailTableBodyCell">', html += '<button type="button" is="emby-button" data-token="' + item.AccessToken + '" class="raised raised-mini btnRevoke" data-mini="true" title="' + globalize.translate("ButtonRevoke") + '" style="margin:0;">' + globalize.translate("ButtonRevoke") + "</button>", html += "</td>", html += '<td class="detailTableBodyCell" style="vertical-align:middle;">', html += item.AccessToken, html += "</td>", html += '<td class="detailTableBodyCell" style="vertical-align:middle;">', html += item.AppName || "", html += "</td>", html += '<td class="detailTableBodyCell" style="vertical-align:middle;">';
|
||||
var date = datetime.parseISO8601Date(item.DateCreated, !0);
|
||||
return html += datetime.toLocaleDateString(date) + " " + datetime.getDisplayTime(date), html += "</td>", html += "</tr>"
|
||||
}).join("");
|
||||
page.querySelector(".resultBody").innerHTML = rows, loading.hide()
|
||||
}
|
||||
|
||||
function loadData(page) {
|
||||
loading.show(), ApiClient.getJSON(ApiClient.getUrl("Auth/Keys")).then(function(result) {
|
||||
renderKeys(page, result.Items)
|
||||
})
|
||||
}
|
||||
|
||||
function showNewKeyPrompt(page) {
|
||||
require(["prompt"], function(prompt) {
|
||||
prompt({
|
||||
title: globalize.translate("HeaderNewApiKey"),
|
||||
label: globalize.translate("LabelAppName"),
|
||||
description: globalize.translate("LabelAppNameExample")
|
||||
}).then(function(value) {
|
||||
ApiClient.ajax({
|
||||
type: "POST",
|
||||
url: ApiClient.getUrl("Auth/Keys", {
|
||||
App: value
|
||||
})
|
||||
}).then(function() {
|
||||
loadData(page)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function getTabs() {
|
||||
return [{
|
||||
href: "dashboardhosting.html",
|
||||
name: globalize.translate("TabHosting")
|
||||
}, {
|
||||
href: "serversecurity.html",
|
||||
name: globalize.translate("TabSecurity")
|
||||
}]
|
||||
}
|
||||
pageIdOn("pageinit", "serverSecurityPage", function() {
|
||||
var page = this;
|
||||
page.querySelector(".btnNewKey").addEventListener("click", function() {
|
||||
showNewKeyPrompt(page)
|
||||
}), page.querySelector(".tblApiKeys").addEventListener("click", function(e) {
|
||||
var btnRevoke = dom.parentWithClass(e.target, "btnRevoke");
|
||||
btnRevoke && revoke(page, btnRevoke.getAttribute("data-token"))
|
||||
})
|
||||
}), pageIdOn("pagebeforeshow", "serverSecurityPage", function() {
|
||||
libraryMenu.setTabs("adminadvanced", 1, getTabs), loadData(this)
|
||||
})
|
||||
});
|
47
src/controllers/streamingsettings.js
Normal file
47
src/controllers/streamingsettings.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
define(["jQuery", "libraryMenu", "loading"], function($, libraryMenu, loading) {
|
||||
"use strict";
|
||||
|
||||
function loadPage(page, config) {
|
||||
$("#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
|
||||
}
|
||||
|
||||
function getTabs() {
|
||||
return [{
|
||||
href: "playbackconfiguration.html",
|
||||
name: Globalize.translate("TabResumeSettings")
|
||||
}, {
|
||||
href: "streamingsettings.html",
|
||||
name: Globalize.translate("TabStreaming")
|
||||
}]
|
||||
}
|
||||
$(document).on("pageinit", "#streamingSettingsPage", function() {
|
||||
var page = this;
|
||||
$("#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()
|
||||
},
|
||||
validateWriteable: !0,
|
||||
header: Globalize.translate("HeaderSelectTranscodingPath"),
|
||||
instruction: Globalize.translate("HeaderSelectTranscodingPathHelp")
|
||||
})
|
||||
})
|
||||
}), $(".streamingSettingsForm").off("submit", onSubmit).on("submit", onSubmit)
|
||||
}).on("pageshow", "#streamingSettingsPage", function() {
|
||||
loading.show(), libraryMenu.setTabs("playback", 1, getTabs);
|
||||
var page = this;
|
||||
ApiClient.getServerConfiguration().then(function(config) {
|
||||
loadPage(page, config)
|
||||
})
|
||||
})
|
||||
});
|
154
src/controllers/useredit.js
Normal file
154
src/controllers/useredit.js
Normal file
|
@ -0,0 +1,154 @@
|
|||
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 += '<label><input type="checkbox" is="emby-checkbox" class="chkFolder" data-id="' + folder.Id + '" ' + checkedAttribute + "><span>" + folder.Name + "</span></label>";
|
||||
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 += '<label><input type="checkbox" is="emby-checkbox" class="chkFolder" data-id="' + folder.Id + '" ' + checkedAttribute + "><span>" + folder.Name + "</span></label>";
|
||||
$(".deleteAccess", page).html(html).trigger("create"), $("#chkEnableDeleteAllFolders", page).checked(user.Policy.EnableContentDeletion).trigger("change")
|
||||
})
|
||||
}
|
||||
|
||||
function loadAuthProviders(page, user, providers) {
|
||||
providers.length > 1 && !user.Policy.IsAdministrator ? page.querySelector(".fldSelectLoginProvider").classList.remove("hide") : page.querySelector(".fldSelectLoginProvider").classList.add("hide");
|
||||
var currentProviderId = user.Policy.AuthenticationProviderId;
|
||||
page.querySelector(".selectLoginProvider").innerHTML = providers.map(function(provider) {
|
||||
var selected = provider.Id === currentProviderId || providers.length < 2 ? " selected" : "";
|
||||
return '<option value="' + provider.Id + '"' + selected + ">" + provider.Name + "</option>"
|
||||
})
|
||||
}
|
||||
|
||||
function loadPasswordResetProviders(page, user, providers) {
|
||||
if (providers.length > 1 && !user.Policy.IsAdministrator) {
|
||||
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 '<option value="' + provider.Id + '"' + selected + ">" + provider.Name + "</option>"
|
||||
})
|
||||
}
|
||||
|
||||
function loadUser(page, user) {
|
||||
currentUser = user;
|
||||
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("Library/MediaFolders", {
|
||||
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);
|
||||
libraryMenu.setTitle(user.Name);
|
||||
page.querySelector(".username").innerHTML = user.Name;
|
||||
$("#txtUserName", page).val(user.Name);
|
||||
$("#chkIsAdmin", page).checked(user.Policy.IsAdministrator);
|
||||
$("#chkDisabled", page).checked(user.Policy.IsDisabled);
|
||||
$("#chkIsHidden", page).checked(user.Policy.IsHidden);
|
||||
$("#chkRemoteControlSharedDevices", page).checked(user.Policy.EnableSharedDeviceControl);
|
||||
$("#chkEnableRemoteControlOtherUsers", page).checked(user.Policy.EnableRemoteControlOfOtherUsers);
|
||||
$("#chkEnableDownloading", page).checked(user.Policy.EnableContentDownloading);
|
||||
$("#chkManageLiveTv", page).checked(user.Policy.EnableLiveTvManagement);
|
||||
$("#chkEnableLiveTvAccess", page).checked(user.Policy.EnableLiveTvAccess);
|
||||
$("#chkEnableMediaPlayback", page).checked(user.Policy.EnableMediaPlayback);
|
||||
$("#chkEnableAudioPlaybackTranscoding", page).checked(user.Policy.EnableAudioPlaybackTranscoding);
|
||||
$("#chkEnableVideoPlaybackTranscoding", page).checked(user.Policy.EnableVideoPlaybackTranscoding);
|
||||
$("#chkEnableVideoPlaybackRemuxing", page).checked(user.Policy.EnablePlaybackRemuxing);
|
||||
$("#chkRemoteAccess", page).checked(null == user.Policy.EnableRemoteAccess || user.Policy.EnableRemoteAccess);
|
||||
$("#chkEnableSyncTranscoding", page).checked(user.Policy.EnableSyncTranscoding);
|
||||
$("#chkEnableConversion", page).checked(user.Policy.EnableMediaConversion || false);
|
||||
$("#chkEnableSharing", page).checked(user.Policy.EnablePublicSharing);
|
||||
$("#txtRemoteClientBitrateLimit", page).val(user.Policy.RemoteClientBitrateLimit / 1e6 || "");
|
||||
$("#txtLoginAttemptsBeforeLockout", page).val(user.Policy.LoginAttemptsBeforeLockout || "0");
|
||||
loading.hide();
|
||||
}
|
||||
|
||||
function onSaveComplete(page, user) {
|
||||
Dashboard.navigate("userprofiles.html");
|
||||
loading.hide();
|
||||
require(["toast"], function(toast) {
|
||||
toast(Globalize.translate("SettingsSaved"));
|
||||
});
|
||||
}
|
||||
|
||||
function saveUser(user, page) {
|
||||
user.Name = $("#txtUserName", page).val();
|
||||
user.Policy.IsAdministrator = $("#chkIsAdmin", page).checked();
|
||||
user.Policy.IsHidden = $("#chkIsHidden", page).checked();
|
||||
user.Policy.IsDisabled = $("#chkDisabled", page).checked();
|
||||
user.Policy.EnableRemoteControlOfOtherUsers = $("#chkEnableRemoteControlOtherUsers", page).checked();
|
||||
user.Policy.EnableLiveTvManagement = $("#chkManageLiveTv", page).checked();
|
||||
user.Policy.EnableLiveTvAccess = $("#chkEnableLiveTvAccess", page).checked();
|
||||
user.Policy.EnableSharedDeviceControl = $("#chkRemoteControlSharedDevices", page).checked();
|
||||
user.Policy.EnableMediaPlayback = $("#chkEnableMediaPlayback", page).checked();
|
||||
user.Policy.EnableAudioPlaybackTranscoding = $("#chkEnableAudioPlaybackTranscoding", page).checked();
|
||||
user.Policy.EnableVideoPlaybackTranscoding = $("#chkEnableVideoPlaybackTranscoding", page).checked();
|
||||
user.Policy.EnablePlaybackRemuxing = $("#chkEnableVideoPlaybackRemuxing", page).checked();
|
||||
user.Policy.EnableContentDownloading = $("#chkEnableDownloading", page).checked();
|
||||
user.Policy.EnableSyncTranscoding = $("#chkEnableSyncTranscoding", page).checked();
|
||||
user.Policy.EnableMediaConversion = $("#chkEnableConversion", page).checked();
|
||||
user.Policy.EnablePublicSharing = $("#chkEnableSharing", page).checked();
|
||||
user.Policy.EnableRemoteAccess = $("#chkRemoteAccess", page).checked();
|
||||
user.Policy.RemoteClientBitrateLimit = parseInt(1e6 * parseFloat($("#txtRemoteClientBitrateLimit", page).val() || "0"));
|
||||
user.Policy.LoginAttemptsBeforeLockout = parseInt($("#txtLoginAttemptsBeforeLockout", page).val() || "0");
|
||||
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")
|
||||
});
|
||||
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
|
||||
}
|
||||
|
||||
function getUser() {
|
||||
var userId = getParameterByName("userId");
|
||||
return ApiClient.getUser(userId)
|
||||
}
|
||||
|
||||
function loadData(page) {
|
||||
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);
|
||||
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)
|
||||
})
|
||||
});
|
112
src/controllers/userlibraryaccess.js
Normal file
112
src/controllers/userlibraryaccess.js
Normal file
|
@ -0,0 +1,112 @@
|
|||
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)
|
||||
}
|
||||
|
||||
function loadMediaFolders(page, user, mediaFolders) {
|
||||
var html = "";
|
||||
html += '<h3 class="checkboxListLabel">' + Globalize.translate("HeaderLibraries") + "</h3>", html += '<div class="checkboxList paperList checkboxList-paperList">';
|
||||
for (var i = 0, length = mediaFolders.length; i < length; i++) {
|
||||
var folder = mediaFolders[i],
|
||||
isChecked = user.Policy.EnableAllFolders || -1 != user.Policy.EnabledFolders.indexOf(folder.Id),
|
||||
checkedAttribute = isChecked ? ' checked="checked"' : "";
|
||||
html += '<label><input type="checkbox" is="emby-checkbox" class="chkFolder" data-id="' + folder.Id + '" ' + checkedAttribute + "><span>" + folder.Name + "</span></label>"
|
||||
}
|
||||
html += "</div>", page.querySelector(".folderAccess").innerHTML = html;
|
||||
var chkEnableAllFolders = page.querySelector("#chkEnableAllFolders");
|
||||
chkEnableAllFolders.checked = user.Policy.EnableAllFolders, triggerChange(chkEnableAllFolders)
|
||||
}
|
||||
|
||||
function loadChannels(page, user, channels) {
|
||||
var html = "";
|
||||
html += '<h3 class="checkboxListLabel">' + Globalize.translate("HeaderChannels") + "</h3>", html += '<div class="checkboxList paperList checkboxList-paperList">';
|
||||
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 += '<label><input type="checkbox" is="emby-checkbox" class="chkChannel" data-id="' + folder.Id + '" ' + checkedAttribute + "><span>" + folder.Name + "</span></label>"
|
||||
}
|
||||
html += "</div>", $(".channelAccess", page).show().html(html), channels.length ? $(".channelAccessContainer", page).show() : $(".channelAccessContainer", page).hide(), $("#chkEnableAllChannels", page).checked(user.Policy.EnableAllChannels).trigger("change")
|
||||
}
|
||||
|
||||
function loadDevices(page, user, devices) {
|
||||
var html = "";
|
||||
html += '<h3 class="checkboxListLabel">' + Globalize.translate("HeaderDevices") + "</h3>", html += '<div class="checkboxList paperList checkboxList-paperList">';
|
||||
for (var i = 0, length = devices.length; i < length; i++) {
|
||||
var device = devices[i],
|
||||
checkedAttribute = user.Policy.EnableAllDevices || -1 != user.Policy.EnabledDevices.indexOf(device.Id) ? ' checked="checked"' : "";
|
||||
html += '<label><input type="checkbox" is="emby-checkbox" class="chkDevice" data-id="' + device.Id + '" ' + checkedAttribute + "><span>" + device.Name + " - " + device.AppName + "</span></label>"
|
||||
}
|
||||
html += "</div>", $(".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()
|
||||
}
|
||||
|
||||
function onSaveComplete(page) {
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
var page = $(this).parents(".page");
|
||||
loading.show();
|
||||
var userId = getParameterByName("userId");
|
||||
return ApiClient.getUser(userId).then(function(result) {
|
||||
saveUser(result, page)
|
||||
}), !1
|
||||
}
|
||||
$(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() {
|
||||
var page = this;
|
||||
loading.show();
|
||||
var promise1, userId = getParameterByName("userId");
|
||||
if (userId) promise1 = ApiClient.getUser(userId);
|
||||
else {
|
||||
var deferred = $.Deferred();
|
||||
deferred.resolveWith(null, [{
|
||||
Configuration: {}
|
||||
}]), 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)
|
||||
})
|
||||
})
|
||||
});
|
76
src/controllers/usernew.js
Normal file
76
src/controllers/usernew.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function($, loading) {
|
||||
"use strict";
|
||||
|
||||
function loadMediaFolders(page, mediaFolders) {
|
||||
var html = "";
|
||||
html += '<h3 class="checkboxListLabel">' + Globalize.translate("HeaderLibraries") + "</h3>", html += '<div class="checkboxList paperList" style="padding:.5em 1em;">';
|
||||
for (var i = 0, length = mediaFolders.length; i < length; i++) {
|
||||
var folder = mediaFolders[i];
|
||||
html += '<label><input type="checkbox" is="emby-checkbox" class="chkFolder" data-id="' + folder.Id + '" checked="checked"/><span>' + folder.Name + "</span></label>"
|
||||
}
|
||||
html += "</div>", $(".folderAccess", page).html(html).trigger("create"), $("#chkEnableAllFolders", page).checked(!0).trigger("change")
|
||||
}
|
||||
|
||||
function loadChannels(page, channels) {
|
||||
var html = "";
|
||||
html += '<h3 class="checkboxListLabel">' + Globalize.translate("HeaderChannels") + "</h3>", html += '<div class="checkboxList paperList" style="padding:.5em 1em;">';
|
||||
for (var i = 0, length = channels.length; i < length; i++) {
|
||||
var folder = channels[i];
|
||||
html += '<label><input type="checkbox" is="emby-checkbox" class="chkChannel" data-id="' + folder.Id + '" checked="checked"/><span>' + folder.Name + "</span></label>"
|
||||
}
|
||||
html += "</div>", $(".channelAccess", page).show().html(html).trigger("create"), channels.length ? $(".channelAccessContainer", page).show() : $(".channelAccessContainer", page).hide(), $("#chkEnableAllChannels", page).checked(!0).trigger("change")
|
||||
}
|
||||
|
||||
function loadUser(page) {
|
||||
$("#txtUserName", page).val(""), loading.show();
|
||||
var promise4 = ApiClient.getJSON(ApiClient.getUrl("Library/MediaFolders", {
|
||||
IsHidden: !1
|
||||
})),
|
||||
promise5 = ApiClient.getJSON(ApiClient.getUrl("Channels"));
|
||||
Promise.all([promise4, promise5]).then(function(responses) {
|
||||
loadMediaFolders(page, responses[0].Items), loadChannels(page, responses[1].Items), loading.hide()
|
||||
})
|
||||
}
|
||||
|
||||
function saveUser(page) {
|
||||
var name = $("#txtUserName", page).val();
|
||||
ApiClient.createUser(name).then(function(user) {
|
||||
user.Policy.EnableAllFolders = $("#chkEnableAllFolders", page).checked(), user.Policy.EnabledFolders = user.Policy.EnableAllFolders ? [] : $(".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 = user.Policy.EnableAllChannels ? [] : $(".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() {
|
||||
Dashboard.navigate("useredit.html?userId=" + user.Id)
|
||||
})
|
||||
}, function(response) {
|
||||
400 == response.status ? Dashboard.alert({
|
||||
message: page.querySelector(".labelNewUserNameHelp").innerHTML
|
||||
}) : require(["toast"], function(toast) {
|
||||
toast(Globalize.translate("DefaultErrorMessage"))
|
||||
}), loading.hide()
|
||||
})
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
var page = $(this).parents(".page")[0];
|
||||
return loading.show(), saveUser(page), !1
|
||||
}
|
||||
|
||||
function loadData(page) {
|
||||
loadUser(page)
|
||||
}
|
||||
$(document).on("pageinit", "#newUserPage", function() {
|
||||
var page = this;
|
||||
$("#chkEnableAllChannels", page).on("change", function() {
|
||||
this.checked ? $(".channelAccessListContainer", page).hide() : $(".channelAccessListContainer", page).show()
|
||||
}), $("#chkEnableAllFolders", page).on("change", function() {
|
||||
this.checked ? $(".folderAccessListContainer", page).hide() : $(".folderAccessListContainer", page).show()
|
||||
}), $(".newUserProfileForm").off("submit", onSubmit).on("submit", onSubmit)
|
||||
}).on("pageshow", "#newUserPage", function() {
|
||||
loadData(this)
|
||||
})
|
||||
});
|
185
src/controllers/userparentalcontrol.js
Normal file
185
src/controllers/userparentalcontrol.js
Normal file
|
@ -0,0 +1,185 @@
|
|||
define(["jQuery", "datetime", "loading", "libraryMenu", "listViewStyle", "paper-icon-button-light"], function($, datetime, loading, libraryMenu) {
|
||||
"use strict";
|
||||
|
||||
function populateRatings(allParentalRatings, page) {
|
||||
var html = "";
|
||||
html += "<option value=''></option>";
|
||||
var i, length, rating, 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
|
||||
}
|
||||
}
|
||||
ratings.push({
|
||||
Name: rating.Name,
|
||||
Value: rating.Value
|
||||
})
|
||||
}
|
||||
for (i = 0, length = ratings.length; i < length; i++) rating = ratings[i], html += "<option value='" + rating.Value + "'>" + rating.Name + "</option>";
|
||||
$("#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 += '<h3 class="checkboxListLabel">' + Globalize.translate("HeaderBlockItemsWithNoRating") + "</h3>", html += '<div class="checkboxList paperList checkboxList-paperList">';
|
||||
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 += '<label><input type="checkbox" is="emby-checkbox" class="chkUnratedItem" data-itemtype="' + item.value + '" type="checkbox"' + checkedAttribute + "><span>" + item.name + "</span></label>"
|
||||
}
|
||||
html += "</div>", $(".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);
|
||||
var ratingValue = "";
|
||||
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)
|
||||
}
|
||||
$("#selectMaxParentalRating", page).val(ratingValue), user.Policy.IsAdministrator ? $(".accessScheduleSection", page).hide() : $(".accessScheduleSection", page).show(), renderAccessSchedule(page, user.Policy.AccessSchedules || []), loading.hide()
|
||||
}
|
||||
|
||||
function loadBlockedTags(page, tags) {
|
||||
var html = tags.map(function(h) {
|
||||
var li = '<div class="listItem">';
|
||||
return li += '<div class="listItemBody">', li += '<h3 class="listItemBodyText">', li += h, li += "</h3>", li += "</div>", li += '<button type="button" is="paper-icon-button-light" class="blockedTag btnDeleteTag listItemButton" data-tag="' + h + '"><i class="md-icon">delete</i></button>', li += "</div>"
|
||||
}).join("");
|
||||
html && (html = '<div class="paperList">' + html + "</div>");
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
||||
function deleteAccessSchedule(page, schedules, index) {
|
||||
schedules.splice(index, 1), renderAccessSchedule(page, schedules)
|
||||
}
|
||||
|
||||
function renderAccessSchedule(page, schedules) {
|
||||
var html = "",
|
||||
index = 0;
|
||||
html += schedules.map(function(a) {
|
||||
var itemHtml = "";
|
||||
return itemHtml += '<div class="liSchedule listItem" data-day="' + a.DayOfWeek + '" data-start="' + a.StartHour + '" data-end="' + a.EndHour + '">', itemHtml += '<div class="listItemBody two-line">', itemHtml += '<h3 class="listItemBodyText">', itemHtml += Globalize.translate("Option" + a.DayOfWeek), itemHtml += "</h3>", itemHtml += '<div class="listItemBodyText secondary">' + getDisplayTime(a.StartHour) + " - " + getDisplayTime(a.EndHour) + "</div>", itemHtml += "</div>", itemHtml += '<button type="button" is="paper-icon-button-light" class="btnDelete listItemButton" data-index="' + index + '"><i class="md-icon">delete</i></button>', itemHtml += "</div>", index++, itemHtml
|
||||
}).join("");
|
||||
var accessScheduleList = page.querySelector(".accessScheduleList");
|
||||
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"))
|
||||
})
|
||||
}
|
||||
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
function showSchedulePopup(page, schedule, index) {
|
||||
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)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function getSchedulesFromPage(page) {
|
||||
return $(".liSchedule", page).map(function() {
|
||||
return {
|
||||
DayOfWeek: this.getAttribute("data-day"),
|
||||
StartHour: this.getAttribute("data-start"),
|
||||
EndHour: this.getAttribute("data-end")
|
||||
}
|
||||
}).get()
|
||||
}
|
||||
|
||||
function getBlockedTagsFromPage(page) {
|
||||
return $(".blockedTag", page).map(function() {
|
||||
return this.getAttribute("data-tag")
|
||||
}).get()
|
||||
}
|
||||
|
||||
function showBlockedTagPopup(page) {
|
||||
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))
|
||||
})
|
||||
})
|
||||
}
|
||||
window.UserParentalControlPage = {
|
||||
onSubmit: function() {
|
||||
var page = $(this).parents(".page");
|
||||
loading.show();
|
||||
var userId = getParameterByName("userId");
|
||||
return ApiClient.getUser(userId).then(function(result) {
|
||||
saveUser(result, page)
|
||||
}), !1
|
||||
}
|
||||
}, $(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() {
|
||||
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])
|
||||
})
|
||||
})
|
||||
});
|
268
src/controllers/userprofilespage.js
Normal file
268
src/controllers/userprofilespage.js
Normal file
|
@ -0,0 +1,268 @@
|
|||
define(["loading", "dom", "globalize", "humanedate", "paper-icon-button-light", "cardStyle", "emby-button", "indicators", "flexStyles"], function (loading, dom, globalize) {
|
||||
"use strict";
|
||||
|
||||
function deleteUser(page, id) {
|
||||
var msg = globalize.translate("DeleteUserConfirmation");
|
||||
|
||||
require(["confirm"], function (confirm) {
|
||||
confirm({
|
||||
title: globalize.translate("DeleteUser"),
|
||||
text: msg,
|
||||
confirmText: globalize.translate("ButtonDelete"),
|
||||
primary: "cancel"
|
||||
}).then(function () {
|
||||
loading.show();
|
||||
ApiClient.deleteUser(id).then(function () {
|
||||
loadData(page);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function showUserMenu(elem) {
|
||||
var card = dom.parentWithClass(elem, "card");
|
||||
var page = dom.parentWithClass(card, "page");
|
||||
var userId = card.getAttribute("data-userid");
|
||||
var menuItems = [];
|
||||
menuItems.push({
|
||||
name: globalize.translate("ButtonOpen"),
|
||||
id: "open",
|
||||
ironIcon: "mode-edit"
|
||||
});
|
||||
menuItems.push({
|
||||
name: globalize.translate("ButtonLibraryAccess"),
|
||||
id: "access",
|
||||
ironIcon: "lock"
|
||||
});
|
||||
menuItems.push({
|
||||
name: globalize.translate("ButtonParentalControl"),
|
||||
id: "parentalcontrol",
|
||||
ironIcon: "person"
|
||||
});
|
||||
menuItems.push({
|
||||
name: globalize.translate("ButtonDelete"),
|
||||
id: "delete",
|
||||
ironIcon: "delete"
|
||||
});
|
||||
|
||||
require(["actionsheet"], function (actionsheet) {
|
||||
actionsheet.show({
|
||||
items: menuItems,
|
||||
positionTo: card,
|
||||
callback: function (id) {
|
||||
switch (id) {
|
||||
case "open":
|
||||
Dashboard.navigate("useredit.html?userId=" + userId);
|
||||
break;
|
||||
|
||||
case "access":
|
||||
Dashboard.navigate("userlibraryaccess.html?userId=" + userId);
|
||||
break;
|
||||
|
||||
case "parentalcontrol":
|
||||
Dashboard.navigate("userparentalcontrol.html?userId=" + userId);
|
||||
break;
|
||||
|
||||
case "delete":
|
||||
deleteUser(page, userId);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getUserHtml(user, addConnectIndicator) {
|
||||
var html = "";
|
||||
var cssClass = "card squareCard scalableCard squareCard-scalable";
|
||||
|
||||
if (user.Policy.IsDisabled) {
|
||||
cssClass += " grayscale";
|
||||
}
|
||||
|
||||
html += "<div data-userid='" + user.Id + "' class='" + cssClass + "'>";
|
||||
html += '<div class="cardBox visualCardBox">';
|
||||
html += '<div class="cardScalable visualCardBox-cardScalable">';
|
||||
html += '<div class="cardPadder cardPadder-square"></div>';
|
||||
html += '<a is="emby-linkbutton" class="cardContent" href="useredit.html?userId=' + user.Id + '">';
|
||||
var imgUrl;
|
||||
|
||||
if (user.PrimaryImageTag) {
|
||||
imgUrl = ApiClient.getUserImageUrl(user.Id, {
|
||||
width: 300,
|
||||
tag: user.PrimaryImageTag,
|
||||
type: "Primary"
|
||||
});
|
||||
}
|
||||
|
||||
var imageClass = "cardImage";
|
||||
|
||||
if (user.Policy.IsDisabled) {
|
||||
imageClass += " disabledUser";
|
||||
}
|
||||
|
||||
if (imgUrl) {
|
||||
html += '<div class="' + imageClass + '" style="background-image:url(\'' + imgUrl + "');\">";
|
||||
} else {
|
||||
html += '<div class="' + imageClass + ' flex align-items-center justify-content-center">';
|
||||
html += '<i class="md-icon cardImageIcon">person</i>';
|
||||
}
|
||||
|
||||
html += "</div>";
|
||||
html += "</a>";
|
||||
html += "</div>";
|
||||
html += '<div class="cardFooter visualCardBox-cardFooter">';
|
||||
html += '<div class="cardText flex align-items-center">';
|
||||
html += '<div class="flex-grow" style="overflow:hidden;text-overflow:ellipsis;">';
|
||||
html += user.Name;
|
||||
html += "</div>";
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnUserMenu flex-shrink-zero"><i class="md-icon">more_horiz</i></button>';
|
||||
html += "</div>";
|
||||
html += '<div class="cardText cardText-secondary">';
|
||||
var lastSeen = getLastSeenText(user.LastActivityDate);
|
||||
html += "" != lastSeen ? lastSeen : " ";
|
||||
html += "</div>";
|
||||
html += "</div>";
|
||||
html += "</div>";
|
||||
return html + "</div>";
|
||||
}
|
||||
|
||||
function getLastSeenText(lastActivityDate) {
|
||||
if (lastActivityDate) {
|
||||
return "Last seen " + humane_date(lastActivityDate);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function getUserSectionHtml(users, addConnectIndicator) {
|
||||
return users.map(function (u__q) {
|
||||
return getUserHtml(u__q, addConnectIndicator);
|
||||
}).join("");
|
||||
}
|
||||
|
||||
function renderUsers(page, users) {
|
||||
page.querySelector(".localUsers").innerHTML = getUserSectionHtml(users, true);
|
||||
}
|
||||
|
||||
function showPendingUserMenu(elem) {
|
||||
var menuItems = [];
|
||||
menuItems.push({
|
||||
name: globalize.translate("ButtonCancel"),
|
||||
id: "delete",
|
||||
ironIcon: "delete"
|
||||
});
|
||||
|
||||
require(["actionsheet"], function (actionsheet) {
|
||||
var card = dom.parentWithClass(elem, "card");
|
||||
var page = dom.parentWithClass(card, "page");
|
||||
var id = card.getAttribute("data-id");
|
||||
actionsheet.show({
|
||||
items: menuItems,
|
||||
positionTo: card,
|
||||
callback: function (menuItemId) {
|
||||
switch (menuItemId) {
|
||||
case "delete":
|
||||
cancelAuthorization(page, id);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getPendingUserHtml(user) {
|
||||
var html = "";
|
||||
html += "<div data-id='" + user.Id + "' class='card squareCard scalableCard squareCard-scalable'>";
|
||||
html += '<div class="cardBox cardBox-bottompadded visualCardBox">';
|
||||
html += '<div class="cardScalable visualCardBox-cardScalable">';
|
||||
html += '<div class="cardPadder cardPadder-square"></div>';
|
||||
html += '<a class="cardContent cardImageContainer" is="emby-linkbutton" href="#">';
|
||||
|
||||
if (user.ImageUrl) {
|
||||
html += '<div class="cardImage" style="background-image:url(\'' + user.ImageUrl + "');\">";
|
||||
html += "</div>";
|
||||
} else {
|
||||
html += '<i class="cardImageIcon md-icon"></i>';
|
||||
}
|
||||
|
||||
html += "</a>";
|
||||
html += "</div>";
|
||||
html += '<div class="cardFooter visualCardBox-cardFooter">';
|
||||
html += '<div class="cardText" style="text-align:right; float:right;padding:0;">';
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnUserMenu"><i class="md-icon">more_horiz</i></button>';
|
||||
html += "</div>";
|
||||
html += '<div class="cardText" style="padding-top:10px;padding-bottom:10px;">';
|
||||
html += user.UserName;
|
||||
html += "</div>";
|
||||
html += "</div>";
|
||||
html += "</div>";
|
||||
return html + "</div>";
|
||||
}
|
||||
|
||||
function renderPendingGuests(page, users) {
|
||||
if (users.length) {
|
||||
page.querySelector(".sectionPendingGuests").classList.remove("hide");
|
||||
} else {
|
||||
page.querySelector(".sectionPendingGuests").classList.add("hide");
|
||||
}
|
||||
|
||||
page.querySelector(".pending").innerHTML = users.map(getPendingUserHtml).join("");
|
||||
}
|
||||
|
||||
// TODO cvium: maybe reuse for invitation system
|
||||
function cancelAuthorization(page, id) {
|
||||
loading.show();
|
||||
ApiClient.ajax({
|
||||
type: "DELETE",
|
||||
url: ApiClient.getUrl("Connect/Pending", {
|
||||
Id: id
|
||||
})
|
||||
}).then(function () {
|
||||
loadData(page);
|
||||
});
|
||||
}
|
||||
|
||||
function loadData(page) {
|
||||
loading.show();
|
||||
ApiClient.getUsers().then(function (users) {
|
||||
renderUsers(page, users);
|
||||
loading.hide();
|
||||
});
|
||||
// TODO cvium
|
||||
renderPendingGuests(page, []);
|
||||
// ApiClient.getJSON(ApiClient.getUrl("Connect/Pending")).then(function (pending) {
|
||||
//
|
||||
// });
|
||||
}
|
||||
|
||||
function showInvitePopup(page) {
|
||||
require(["components/guestinviter/guestinviter"], function (guestinviter) {
|
||||
guestinviter.show().then(function () {
|
||||
loadData(page);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
pageIdOn("pageinit", "userProfilesPage", function () {
|
||||
var page = this;
|
||||
page.querySelector(".btnAddUser").addEventListener("click", function() {
|
||||
Dashboard.navigate("usernew.html");
|
||||
});
|
||||
page.querySelector(".localUsers").addEventListener("click", function (e__e) {
|
||||
var btnUserMenu = dom.parentWithClass(e__e.target, "btnUserMenu");
|
||||
|
||||
if (btnUserMenu) {
|
||||
showUserMenu(btnUserMenu);
|
||||
}
|
||||
});
|
||||
page.querySelector(".pending").addEventListener("click", function (e__r) {
|
||||
var btnUserMenu = dom.parentWithClass(e__r.target, "btnUserMenu");
|
||||
|
||||
if (btnUserMenu) {
|
||||
showPendingUserMenu(btnUserMenu);
|
||||
}
|
||||
});
|
||||
});
|
||||
pageIdOn("pagebeforeshow", "userProfilesPage", function () {
|
||||
loadData(this);
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue