jellyfin-web/dashboard-ui/scripts/editorsidebar.js

468 lines
12 KiB
JavaScript
Raw Normal View History

2016-06-18 13:31:22 -07:00
define(['datetime', 'jQuery', 'material-icons'], function (datetime, $) {
2016-10-22 22:11:46 -07:00
'use strict';
2014-02-21 14:44:10 -07:00
2014-12-20 18:23:56 -07:00
function getNode(item, folderState, selected) {
2014-02-21 14:44:10 -07:00
var htmlName = getNodeInnerHtml(item);
2014-12-20 18:23:56 -07:00
var node = {
id: item.Id,
text: htmlName,
state: {
opened: item.IsFolder && folderState == 'open',
selected: selected
},
2014-12-20 18:23:56 -07:00
li_attr: {}
};
if (item.IsFolder) {
node.children = [
{
text: 'Loading...',
icon: false
}];
node.icon = false;
}
else {
node.icon = false;
}
if (node.state.opened) {
node.li_attr.loadedFromServer = true;
}
2014-12-20 22:57:06 -07:00
if (selected) {
selectedNodeId = item.Id;
}
2014-12-20 18:23:56 -07:00
return node;
}
2014-07-16 20:17:14 -07:00
function getNodeInnerHtml(item) {
2014-07-16 20:17:14 -07:00
2014-02-21 14:44:10 -07:00
var name = item.Name;
// Channel number
if (item.Number) {
name = item.Number + " - " + name;
}
if (item.IndexNumber != null && item.Type != "Season") {
name = item.IndexNumber + " - " + name;
}
var cssClass = "editorNode";
if (item.LocationType == "Offline") {
cssClass += " offlineEditorNode";
}
var htmlName = "<div class='" + cssClass + "'>";
if (item.LockData) {
2016-06-18 13:31:22 -07:00
htmlName += '<i class="md-icon">lock</i>';
2014-02-21 14:44:10 -07:00
}
htmlName += name;
if (!item.ImageTags || !item.ImageTags.Primary) {
2014-07-16 20:17:14 -07:00
htmlName += '<img src="css/images/editor/missingprimaryimage.png" title="' + Globalize.translate('MissingPrimaryImage') + '" />';
2014-02-21 14:44:10 -07:00
}
if (!item.BackdropImageTags || !item.BackdropImageTags.length) {
2014-03-17 18:45:41 -07:00
if (item.Type !== "Episode" && item.Type !== "Season" && item.MediaType !== "Audio" && item.Type !== "TvChannel" && item.Type !== "MusicAlbum") {
2014-07-16 20:17:14 -07:00
htmlName += '<img src="css/images/editor/missingbackdrop.png" title="' + Globalize.translate('MissingBackdropImage') + '" />';
2014-02-21 14:44:10 -07:00
}
}
if (!item.ImageTags || !item.ImageTags.Logo) {
if (item.Type == "Movie" || item.Type == "Trailer" || item.Type == "Series" || item.Type == "MusicArtist" || item.Type == "BoxSet") {
2014-07-16 20:17:14 -07:00
htmlName += '<img src="css/images/editor/missinglogo.png" title="' + Globalize.translate('MissingLogoImage') + '" />';
2014-02-21 14:44:10 -07:00
}
}
if (item.Type == "Episode" && item.LocationType == "Virtual") {
try {
2016-05-05 21:50:06 -07:00
if (item.PremiereDate && (new Date().getTime() >= datetime.parseISO8601Date(item.PremiereDate, true).getTime())) {
2014-07-16 20:17:14 -07:00
htmlName += '<img src="css/images/editor/missing.png" title="' + Globalize.translate('MissingEpisode') + '" />';
2014-02-21 14:44:10 -07:00
}
} catch (err) {
}
}
htmlName += "</div>";
return htmlName;
2014-02-21 14:44:10 -07:00
}
2014-12-20 18:23:56 -07:00
function loadChildrenOfRootNode(page, scope, callback) {
2014-02-21 14:44:10 -07:00
2015-12-14 08:43:03 -07:00
ApiClient.getLiveTvChannels({ limit: 0 }).then(function (result) {
2014-02-21 14:44:10 -07:00
var nodes = [];
2014-12-20 18:23:56 -07:00
nodes.push({
id: 'MediaFolders',
text: Globalize.translate('HeaderMediaFolders'),
state: {
opened: true
},
li_attr: {
itemtype: 'mediafolders',
loadedFromServer: true
},
icon: false
});
2014-02-21 14:44:10 -07:00
2014-06-10 10:36:06 -07:00
if (result.TotalRecordCount) {
2014-02-21 14:44:10 -07:00
2014-12-20 18:23:56 -07:00
nodes.push({
id: 'livetv',
text: Globalize.translate('HeaderLiveTV'),
state: {
opened: false
},
li_attr: {
itemtype: 'livetv'
},
children: [
{
text: 'Loading...',
icon: false
}],
icon: false
});
}
2014-03-02 19:17:12 -07:00
2014-12-20 18:23:56 -07:00
callback.call(scope, nodes);
2014-03-02 19:17:12 -07:00
2014-12-20 22:57:06 -07:00
nodesToLoad.push('MediaFolders');
2014-02-21 14:44:10 -07:00
});
}
function loadLiveTvChannels(service, openItems, callback) {
2016-05-11 15:08:19 -07:00
ApiClient.getLiveTvChannels({
ServiceName: service,
AddCurrentProgram: false
}).then(function (result) {
2014-02-21 14:44:10 -07:00
var nodes = result.Items.map(function (i) {
var state = openItems.indexOf(i.Id) == -1 ? 'closed' : 'open';
2014-12-20 18:23:56 -07:00
return getNode(i, state, false);
2014-02-21 14:44:10 -07:00
});
callback(nodes);
});
}
2014-12-20 22:57:06 -07:00
function loadMediaFolders(page, scope, openItems, callback) {
2014-06-07 12:46:24 -07:00
2015-12-14 08:43:03 -07:00
ApiClient.getJSON(ApiClient.getUrl("Library/MediaFolders")).then(function (result) {
2014-06-07 12:46:24 -07:00
2014-12-20 18:23:56 -07:00
var nodes = result.Items.map(function (n) {
2014-06-07 12:46:24 -07:00
2014-12-20 18:23:56 -07:00
var state = openItems.indexOf(n.Id) == -1 ? 'closed' : 'open';
2014-06-07 12:46:24 -07:00
2014-12-20 18:23:56 -07:00
return getNode(n, state, false);
2014-06-07 12:46:24 -07:00
});
2014-12-20 22:57:06 -07:00
callback.call(scope, nodes);
2014-06-07 12:46:24 -07:00
2014-12-20 18:23:56 -07:00
for (var i = 0, length = nodes.length; i < length; i++) {
if (nodes[i].state.opened) {
2014-12-20 22:57:06 -07:00
nodesToLoad.push(nodes[i].id);
2014-12-20 18:23:56 -07:00
}
}
2014-06-07 12:46:24 -07:00
});
}
2014-12-20 18:23:56 -07:00
function loadNode(page, scope, node, openItems, selectedId, currentUser, callback) {
var id = node.id;
2014-02-21 14:44:10 -07:00
2014-12-20 18:23:56 -07:00
if (id == '#') {
2014-02-21 14:44:10 -07:00
2014-12-20 18:23:56 -07:00
loadChildrenOfRootNode(page, scope, callback);
2014-02-21 14:44:10 -07:00
return;
}
2014-12-20 18:23:56 -07:00
if (id == 'livetv') {
2014-02-21 14:44:10 -07:00
loadLiveTvChannels(id, openItems, callback);
return;
}
2014-12-20 18:23:56 -07:00
if (id == 'MediaFolders') {
2014-06-07 12:46:24 -07:00
2014-12-20 22:57:06 -07:00
loadMediaFolders(page, scope, openItems, callback);
2014-06-07 12:46:24 -07:00
return;
}
2014-02-21 14:44:10 -07:00
var query = {
ParentId: id,
Fields: 'Settings'
};
2014-12-20 18:23:56 -07:00
var itemtype = node.li_attr.itemtype;
2014-02-21 14:44:10 -07:00
if (itemtype != "Season" && itemtype != "Series") {
query.SortBy = "SortName";
}
2015-12-14 08:43:03 -07:00
ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) {
2014-02-21 14:44:10 -07:00
2014-12-20 18:23:56 -07:00
var nodes = result.Items.map(function (n) {
2014-02-21 14:44:10 -07:00
2014-12-20 18:23:56 -07:00
var state = openItems.indexOf(n.Id) == -1 ? 'closed' : 'open';
2014-02-21 14:44:10 -07:00
2014-12-20 18:23:56 -07:00
return getNode(n, state, n.Id == selectedId);
2014-02-21 14:44:10 -07:00
});
2014-12-20 18:23:56 -07:00
callback.call(scope, nodes);
2014-02-21 14:44:10 -07:00
2014-12-20 18:23:56 -07:00
for (var i = 0, length = nodes.length; i < length; i++) {
if (nodes[i].state.opened) {
2014-02-21 14:44:10 -07:00
2014-12-20 22:57:06 -07:00
nodesToLoad.push(nodes[i].id);
2014-12-20 18:23:56 -07:00
}
2014-02-21 14:44:10 -07:00
}
});
}
2016-05-17 10:44:17 -07:00
function scrollToNode(id) {
2014-02-21 14:44:10 -07:00
2016-05-17 10:44:17 -07:00
var elem = $('#' + id)[0];
2014-02-21 14:44:10 -07:00
if (elem) {
2015-01-22 23:15:15 -07:00
// commenting out for now because it's causing the whole window to scroll in chrome
2015-07-15 04:26:47 -07:00
elem.scrollIntoView();
2014-02-21 14:44:10 -07:00
}
}
function initializeTree(page, currentUser, openItems, selectedId) {
2015-12-14 08:43:03 -07:00
require(['jstree'], function () {
2015-05-08 20:48:43 -07:00
initializeTreeInternal(page, currentUser, openItems, selectedId);
});
}
2015-06-29 11:45:42 -07:00
function onNodeSelect(event, data) {
var node = data.node;
2014-12-20 22:57:06 -07:00
2015-06-29 11:45:42 -07:00
var eventData = {
id: node.id,
itemType: node.li_attr.itemtype
};
2014-12-20 22:57:06 -07:00
2015-06-29 11:45:42 -07:00
if (eventData.itemType != 'livetv' && eventData.itemType != 'mediafolders') {
$(this).trigger('itemclicked', [eventData]);
}
}
2014-02-21 14:44:10 -07:00
2015-06-29 11:45:42 -07:00
function onNodeOpen(event, data) {
2014-02-21 14:44:10 -07:00
2015-06-29 11:45:42 -07:00
var page = $(this).parents('.page')[0];
var node = data.node;
2014-02-21 14:44:10 -07:00
2015-06-29 11:45:42 -07:00
if (node.children && node.children) {
loadNodesToLoad(page, node);
}
2014-02-21 14:44:10 -07:00
2015-06-29 11:45:42 -07:00
if (node.li_attr && node.id != '#' && !node.li_attr.loadedFromServer) {
2014-02-21 14:44:10 -07:00
2015-06-29 11:45:42 -07:00
node.li_attr.loadedFromServer = true;
2014-02-21 14:44:10 -07:00
2015-06-29 11:45:42 -07:00
$.jstree.reference(".libraryTree", page).load_node(node.id, loadNodeCallback);
}
}
2014-02-21 14:44:10 -07:00
2015-06-29 11:45:42 -07:00
function onNodeLoad(event, data) {
2014-12-20 18:23:56 -07:00
2015-06-29 11:45:42 -07:00
var page = $(this).parents('.page')[0];
var node = data.node;
2014-02-21 14:44:10 -07:00
2015-06-29 11:45:42 -07:00
if (node.children && node.children) {
loadNodesToLoad(page, node);
}
2014-02-21 14:44:10 -07:00
2015-06-29 11:45:42 -07:00
if (node.li_attr && node.id != '#' && !node.li_attr.loadedFromServer) {
2014-12-20 18:23:56 -07:00
2015-06-29 11:45:42 -07:00
node.li_attr.loadedFromServer = true;
2014-12-20 18:23:56 -07:00
2015-06-29 11:45:42 -07:00
$.jstree.reference(".libraryTree", page).load_node(node.id, loadNodeCallback);
}
}
2014-12-20 22:57:06 -07:00
2015-06-29 11:45:42 -07:00
function initializeTreeInternal(page, currentUser, openItems, selectedId) {
2014-12-20 18:23:56 -07:00
2015-06-29 11:45:42 -07:00
nodesToLoad = [];
selectedNodeId = null;
2014-12-20 18:23:56 -07:00
2015-06-29 11:45:42 -07:00
$.jstree.destroy();
2014-12-20 22:57:06 -07:00
2015-06-29 11:45:42 -07:00
$('.libraryTree', page).jstree({
2014-12-20 22:57:06 -07:00
2015-06-29 11:45:42 -07:00
"plugins": ["wholerow"],
2014-12-20 22:57:06 -07:00
2015-06-29 11:45:42 -07:00
core: {
2014-12-20 22:57:06 -07:00
2015-06-29 11:45:42 -07:00
check_callback: true,
data: function (node, callback) {
2014-12-20 22:57:06 -07:00
2015-06-29 11:45:42 -07:00
loadNode(page, this, node, openItems, selectedId, currentUser, callback);
},
2014-12-20 22:57:06 -07:00
2015-06-29 11:45:42 -07:00
themes: {
variant: 'large'
}
2014-12-20 18:23:56 -07:00
}
2015-06-29 11:45:42 -07:00
}).off('select_node.jstree', onNodeSelect).on('select_node.jstree', onNodeSelect).off('open_node.jstree', onNodeOpen).on('open_node.jstree', onNodeOpen).off('load_node.jstree', onNodeLoad).on('load_node.jstree', onNodeLoad);
2014-02-21 14:44:10 -07:00
}
2014-07-16 20:17:14 -07:00
2014-12-20 22:57:06 -07:00
function loadNodesToLoad(page, node) {
var children = node.children;
for (var i = 0, length = children.length; i < length; i++) {
var child = children[i];
if (nodesToLoad.indexOf(child) != -1) {
nodesToLoad = nodesToLoad.filter(function (n) {
return n != child;
});
$.jstree.reference(".libraryTree", page).load_node(child, loadNodeCallback);
}
}
}
function loadNodeCallback(node) {
if (selectedNodeId && node.children && node.children.indexOf(selectedNodeId) != -1) {
2015-05-08 20:48:43 -07:00
setTimeout(function () {
2016-05-17 10:44:17 -07:00
scrollToNode(selectedNodeId);
2014-12-20 22:57:06 -07:00
}, 500);
}
}
var nodesToLoad = [];
var selectedNodeId;
function updateEditorNode(page, item) {
var elem = $('#' + item.Id + '>a', page)[0];
if (elem == null) {
return;
}
$('.editorNode', elem).remove();
$(elem).append(getNodeInnerHtml(item));
2014-07-16 20:17:14 -07:00
if (item.IsFolder) {
var tree = jQuery.jstree._reference(".libraryTree");
var currentNode = tree._get_node(null, false);
tree.refresh(currentNode);
}
}
$(document).on('itemsaved', ".metadataEditorPage", function (e, item) {
updateEditorNode(this, item);
2014-02-21 14:44:10 -07:00
2015-09-01 15:04:54 -07:00
}).on('pagebeforeshow', ".metadataEditorPage", function () {
2016-04-18 11:01:50 -07:00
require(['css!css/metadataeditor.css']);
2015-09-01 15:04:54 -07:00
2015-08-31 23:22:46 -07:00
}).on('pagebeforeshow', ".metadataEditorPage", function () {
2014-02-21 14:44:10 -07:00
var page = this;
2015-12-14 08:43:03 -07:00
Dashboard.getCurrentUser().then(function (user) {
2014-02-21 14:44:10 -07:00
2015-09-02 09:57:54 -07:00
var id = getCurrentItemId();
2014-02-21 14:44:10 -07:00
if (id) {
2015-12-14 08:43:03 -07:00
ApiClient.getAncestorItems(id, user.Id).then(function (ancestors) {
2014-02-21 14:44:10 -07:00
var ids = ancestors.map(function (i) {
return i.Id;
});
initializeTree(page, user, ids, id);
});
} else {
initializeTree(page, user, []);
}
});
}).on('pagebeforehide', ".metadataEditorPage", function () {
var page = this;
2015-06-29 11:45:42 -07:00
$('.libraryTree', page).off('select_node.jstree', onNodeSelect).off('open_node.jstree', onNodeOpen).off('load_node.jstree', onNodeLoad);
2014-02-21 14:44:10 -07:00
});
2016-03-15 22:33:31 -07:00
var itemId;
function setCurrentItemId(id) {
itemId = id;
}
2015-09-02 09:57:54 -07:00
function getCurrentItemId() {
2014-02-21 14:44:10 -07:00
2016-03-15 22:33:31 -07:00
if (itemId) {
return itemId;
}
2015-12-14 08:43:03 -07:00
var url = window.location.hash || window.location.href;
2014-02-21 14:44:10 -07:00
2015-09-02 09:57:54 -07:00
return getParameterByName('id', url);
}
2014-02-21 14:44:10 -07:00
2015-09-02 09:57:54 -07:00
window.MetadataEditor = {
2016-05-05 21:50:06 -07:00
getItemPromise: function () {
2015-09-02 09:57:54 -07:00
var currentItemId = getCurrentItemId();
2014-02-21 14:44:10 -07:00
if (currentItemId) {
return ApiClient.getItem(Dashboard.getCurrentUserId(), currentItemId);
}
return ApiClient.getRootFolder(Dashboard.getCurrentUserId());
2015-09-02 09:57:54 -07:00
},
2016-03-15 22:33:31 -07:00
getCurrentItemId: getCurrentItemId,
setCurrentItemId: setCurrentItemId
2015-09-02 09:57:54 -07:00
};
2014-02-21 14:44:10 -07:00
2016-03-16 14:30:49 -07:00
});