jellyfish-web/src/components/itemcontextmenu.js

598 lines
22 KiB
JavaScript
Raw Normal View History

2019-10-15 21:13:33 +03:00
define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter", "playbackManager", "loading", "appSettings", "browser", "actionsheet"], function (appHost, globalize, connectionManager, itemHelper, appRouter, playbackManager, loading, appSettings, browser, actionsheet) {
"use strict";
2018-10-23 01:05:09 +03:00
function getCommands(options) {
var item = options.item;
2019-12-07 12:20:32 +03:00
var user = options.user;
var canPlay = playbackManager.canPlay(item);
var restrictOptions = (browser.operaTv || browser.web0s) && !user.Policy.IsAdministrator;
var commands = [];
2019-10-15 21:13:33 +03:00
if (canPlay && item.MediaType !== "Photo") {
if (options.play !== false) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("Play"),
id: "resume",
icon: ""
});
}
2019-10-15 21:13:33 +03:00
if (options.playAllFromHere && item.Type !== "Program" && item.Type !== "TvChannel") {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("PlayAllFromHere"),
id: "playallfromhere",
icon: ""
});
}
}
if (playbackManager.canQueue(item)) {
if (options.queue !== false) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("AddToPlayQueue"),
id: "queue",
2019-10-12 21:32:05 +03:00
icon: "playlist_add"
});
}
if (options.queue !== false) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("PlayNext"),
id: "queuenext",
2019-10-12 21:32:05 +03:00
icon: "playlist_add"
});
}
//if (options.queueAllFromHere) {
// commands.push({
2019-10-15 21:13:33 +03:00
// name: globalize.translate("QueueAllFromHere"),
// id: "queueallfromhere"
// });
//}
}
if (item.IsFolder || item.Type === "MusicArtist" || item.Type === "MusicGenre") {
2019-10-15 21:13:33 +03:00
if (item.CollectionType !== "livetv") {
if (options.shuffle !== false) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("Shuffle"),
id: "shuffle",
2019-10-12 21:32:05 +03:00
icon: "shuffle"
});
}
}
}
if (item.MediaType === "Audio" || item.Type === "MusicAlbum" || item.Type === "MusicArtist" || item.Type === "MusicGenre") {
if (options.instantMix !== false && !itemHelper.isLocalItem(item)) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("InstantMix"),
id: "instantmix",
2020-01-11 15:28:19 +09:00
icon: "explore"
});
}
}
if (commands.length) {
commands.push({
divider: true
});
}
if (!restrictOptions) {
if (itemHelper.supportsAddingToCollection(item)) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("AddToCollection"),
id: "addtocollection",
2019-10-12 21:32:05 +03:00
icon: "playlist_add"
});
}
if (itemHelper.supportsAddingToPlaylist(item)) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("AddToPlaylist"),
id: "addtoplaylist",
2019-10-12 21:32:05 +03:00
icon: "playlist_add"
});
}
}
2019-10-15 21:13:33 +03:00
if ((item.Type === "Timer") && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("CancelRecording"),
id: "canceltimer",
2019-10-12 21:32:05 +03:00
icon: "cancel"
});
}
2019-10-15 21:13:33 +03:00
if ((item.Type === "Recording" && item.Status === "InProgress") && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("CancelRecording"),
id: "canceltimer",
2019-10-12 21:32:05 +03:00
icon: "cancel"
});
}
2019-10-15 21:13:33 +03:00
if ((item.Type === "SeriesTimer") && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("CancelSeries"),
id: "cancelseriestimer",
2019-10-12 21:32:05 +03:00
icon: "cancel"
});
}
if (item.CanDelete && options.deleteItem !== false) {
2019-10-15 21:13:33 +03:00
if (item.Type === "Playlist" || item.Type === "BoxSet") {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("Delete"),
id: "delete",
2019-10-12 21:32:05 +03:00
icon: "delete"
});
} else {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("DeleteMedia"),
id: "delete",
2019-10-12 21:32:05 +03:00
icon: "delete"
});
}
}
// Books are promoted to major download Button and therefor excluded in the context menu
2019-10-15 21:13:33 +03:00
if ((item.CanDownload && appHost.supports("filedownload")) && item.Type !== "Book") {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("Download"),
id: "download",
2019-10-12 21:32:05 +03:00
icon: "file_download"
});
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("CopyStreamURL"),
id: "copy-stream",
2019-10-12 21:32:05 +03:00
icon: "content_copy"
});
}
if (commands.length) {
commands.push({
divider: true
});
}
2018-10-23 01:05:09 +03:00
var canEdit = itemHelper.canEdit(user, item);
if (canEdit) {
2019-10-15 21:13:33 +03:00
if (options.edit !== false && item.Type !== "SeriesTimer") {
var text = (item.Type === "Timer" || item.Type === "SeriesTimer") ? globalize.translate("Edit") : globalize.translate("EditMetadata");
commands.push({
name: text,
2019-10-15 21:13:33 +03:00
id: "edit",
2019-10-12 21:32:05 +03:00
icon: "edit"
});
}
}
if (itemHelper.canEditImages(user, item)) {
if (options.editImages !== false) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("EditImages"),
id: "editimages",
2020-01-11 15:33:53 +09:00
icon: "image"
});
}
}
if (canEdit) {
2019-10-15 21:13:33 +03:00
if (item.MediaType === "Video" && item.Type !== "TvChannel" && item.Type !== "Program" && item.LocationType !== "Virtual" && !(item.Type === "Recording" && item.Status !== "Completed")) {
if (options.editSubtitles !== false) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("EditSubtitles"),
id: "editsubtitles",
2019-10-12 21:32:05 +03:00
icon: "closed_caption"
});
}
}
}
if (options.identify !== false) {
if (itemHelper.canIdentify(user, item)) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("Identify"),
id: "identify",
2019-10-12 21:32:05 +03:00
icon: "edit"
});
}
}
if (item.MediaSources) {
if (options.moremediainfo !== false) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("MoreMediaInfo"),
id: "moremediainfo",
2019-10-12 21:32:05 +03:00
icon: "info"
});
}
}
2019-10-15 21:13:33 +03:00
if (item.Type === "Program" && options.record !== false) {
if (item.TimerId) {
commands.push({
2019-10-15 21:13:33 +03:00
name: Globalize.translate("ManageRecording"),
id: "record",
2019-10-12 21:32:05 +03:00
icon: "fiber_manual_record"
});
}
}
2019-10-15 21:13:33 +03:00
if (item.Type === "Program" && options.record !== false) {
if (!item.TimerId) {
commands.push({
2019-10-15 21:13:33 +03:00
name: Globalize.translate("Record"),
id: "record",
2019-10-12 21:32:05 +03:00
icon: "fiber_manual_record"
});
}
}
if (itemHelper.canRefreshMetadata(item, user)) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("RefreshMetadata"),
id: "refresh",
2019-10-12 21:32:05 +03:00
icon: "refresh"
});
}
if (item.PlaylistItemId && options.playlistId) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("RemoveFromPlaylist"),
id: "removefromplaylist",
2019-10-12 21:32:05 +03:00
icon: "remove"
});
}
if (options.collectionId) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("RemoveFromCollection"),
id: "removefromcollection",
2019-10-12 21:32:05 +03:00
icon: "remove"
});
}
if (!restrictOptions) {
if (options.share === true) {
if (itemHelper.canShare(item, user)) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("Share"),
id: "share",
2019-10-12 21:32:05 +03:00
icon: "share"
});
}
}
}
if (options.sync !== false) {
if (itemHelper.canSync(user, item)) {
commands.push({
2019-10-15 21:13:33 +03:00
name: globalize.translate("Sync"),
id: "sync",
2019-10-12 21:32:05 +03:00
icon: "sync"
});
}
}
2019-10-15 21:13:33 +03:00
if (options.openAlbum !== false && item.AlbumId && item.MediaType !== "Photo") {
commands.push({
2019-10-15 21:13:33 +03:00
name: Globalize.translate("ViewAlbum"),
id: "album",
2019-10-12 21:32:05 +03:00
icon: "album"
});
}
if (options.openArtist !== false && item.ArtistItems && item.ArtistItems.length) {
2018-10-23 01:05:09 +03:00
commands.push({
2019-10-15 21:13:33 +03:00
name: Globalize.translate("ViewArtist"),
id: "artist",
2019-10-12 21:32:05 +03:00
icon: "person"
});
2018-10-23 01:05:09 +03:00
}
return commands;
2018-10-23 01:05:09 +03:00
}
function getResolveFunction(resolve, id, changed, deleted) {
return function () {
2018-10-23 01:05:09 +03:00
resolve({
command: id,
updated: changed,
deleted: deleted
});
};
}
2018-10-23 01:05:09 +03:00
function executeCommand(item, id, options) {
var itemId = item.Id;
var serverId = item.ServerId;
var apiClient = connectionManager.getApiClient(serverId);
return new Promise(function (resolve, reject) {
2018-10-23 01:05:09 +03:00
switch (id) {
2019-10-15 21:13:33 +03:00
case "addtocollection":
require(["collectionEditor"], function (collectionEditor) {
new collectionEditor().show({
2019-01-10 15:41:25 +03:00
items: [itemId],
serverId: serverId
}).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
2019-01-10 15:41:25 +03:00
});
break;
2019-10-15 21:13:33 +03:00
case "addtoplaylist":
require(["playlistEditor"], function (playlistEditor) {
new playlistEditor().show({
2019-01-10 15:41:25 +03:00
items: [itemId],
serverId: serverId
}).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
2019-01-10 15:41:25 +03:00
});
break;
2019-10-15 21:13:33 +03:00
case "download":
require(["fileDownloader"], function (fileDownloader) {
2019-01-10 15:41:25 +03:00
var downloadHref = apiClient.getItemDownloadUrl(itemId);
fileDownloader.download([{
url: downloadHref,
itemId: itemId,
serverId: serverId
}]);
getResolveFunction(getResolveFunction(resolve, id), id)();
2019-01-10 15:41:25 +03:00
});
break;
2019-10-15 21:13:33 +03:00
case "copy-stream":
var downloadHref = apiClient.getItemDownloadUrl(itemId);
var textAreaCopy = function () {
var textArea = document.createElement("textarea");
textArea.value = downloadHref;
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
if (document.execCommand("copy")) {
require(["toast"], function (toast) {
toast(globalize.translate("CopyStreamURLSuccess"));
});
} else {
prompt(globalize.translate("CopyStreamURL"), downloadHref);
}
document.body.removeChild(textArea);
};
if (navigator.clipboard === undefined) {
textareaCopy();
} else {
navigator.clipboard.writeText(downloadHref).then(function () {
require(["toast"], function (toast) {
toast(globalize.translate("CopyStreamURLSuccess"));
});
}, textareaCopy);
}
getResolveFunction(resolve, id)();
break;
2019-10-15 21:13:33 +03:00
case "editsubtitles":
require(["subtitleEditor"], function (subtitleEditor) {
subtitleEditor.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
2019-01-10 15:41:25 +03:00
});
break;
2019-10-15 21:13:33 +03:00
case "edit":
editItem(apiClient, item).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
2019-01-10 15:41:25 +03:00
break;
2019-10-15 21:13:33 +03:00
case "editimages":
require(["imageEditor"], function (imageEditor) {
2019-01-10 15:41:25 +03:00
imageEditor.show({
itemId: itemId,
serverId: serverId
}).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
2019-01-10 15:41:25 +03:00
});
break;
2019-10-15 21:13:33 +03:00
case "identify":
require(["itemIdentifier"], function (itemIdentifier) {
itemIdentifier.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
});
break;
2019-10-15 21:13:33 +03:00
case "moremediainfo":
require(["itemMediaInfo"], function (itemMediaInfo) {
itemMediaInfo.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
2019-01-10 15:41:25 +03:00
});
break;
2019-10-15 21:13:33 +03:00
case "refresh":
refresh(apiClient, item);
getResolveFunction(resolve, id)();
2019-01-10 15:41:25 +03:00
break;
2019-10-15 21:13:33 +03:00
case "open":
appRouter.showItem(item);
getResolveFunction(resolve, id)();
2019-01-10 15:41:25 +03:00
break;
2019-10-15 21:13:33 +03:00
case "play":
play(item, false);
getResolveFunction(resolve, id)();
2019-01-10 15:41:25 +03:00
break;
2019-10-15 21:13:33 +03:00
case "resume":
play(item, true);
getResolveFunction(resolve, id)();
2019-01-10 15:41:25 +03:00
break;
2019-10-15 21:13:33 +03:00
case "queue":
play(item, false, true);
getResolveFunction(resolve, id)();
2019-01-10 15:41:25 +03:00
break;
2019-10-15 21:13:33 +03:00
case "queuenext":
play(item, false, true, true);
getResolveFunction(resolve, id)();
2019-01-10 15:41:25 +03:00
break;
2019-10-15 21:13:33 +03:00
case "record":
require(["recordingCreator"], function (recordingCreator) {
recordingCreator.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
2018-10-23 01:05:09 +03:00
});
break;
2019-10-15 21:13:33 +03:00
case "shuffle":
playbackManager.shuffle(item);
getResolveFunction(resolve, id)();
2019-01-10 15:41:25 +03:00
break;
2019-10-15 21:13:33 +03:00
case "instantmix":
playbackManager.instantMix(item);
getResolveFunction(resolve, id)();
2019-01-10 15:41:25 +03:00
break;
2019-10-15 21:13:33 +03:00
case "delete":
deleteItem(apiClient, item).then(getResolveFunction(resolve, id, true, true), getResolveFunction(resolve, id));
2019-01-10 15:41:25 +03:00
break;
2019-10-15 21:13:33 +03:00
case "share":
2019-01-10 15:41:25 +03:00
navigator.share({
title: item.Name,
text: item.Overview,
url: "https://github.com/jellyfin/jellyfin"
});
break;
2019-10-15 21:13:33 +03:00
case "album":
2019-03-18 22:22:48 -07:00
appRouter.showItem(item.AlbumId, item.ServerId);
getResolveFunction(resolve, id)();
break;
2019-10-15 21:13:33 +03:00
case "artist":
2019-03-18 22:22:48 -07:00
appRouter.showItem(item.ArtistItems[0].Id, item.ServerId);
getResolveFunction(resolve, id)();
2019-01-10 15:41:25 +03:00
break;
2019-10-15 21:13:33 +03:00
case "playallfromhere":
2019-03-18 22:22:48 -07:00
getResolveFunction(resolve, id)();
2019-01-10 15:41:25 +03:00
break;
2019-10-15 21:13:33 +03:00
case "queueallfromhere":
2019-01-10 15:41:25 +03:00
getResolveFunction(resolve, id)();
break;
2019-10-15 21:13:33 +03:00
case "removefromplaylist":
2018-10-23 01:05:09 +03:00
apiClient.ajax({
2019-10-15 21:13:33 +03:00
url: apiClient.getUrl("Playlists/" + options.playlistId + "/Items", {
EntryIds: [item.PlaylistItemId].join(",")
2018-10-23 01:05:09 +03:00
}),
2019-10-15 21:13:33 +03:00
type: "DELETE"
}).then(function () {
getResolveFunction(resolve, id, true)();
2018-10-23 01:05:09 +03:00
});
break;
2019-10-15 21:13:33 +03:00
case "removefromcollection":
2018-10-23 01:05:09 +03:00
apiClient.ajax({
type: "DELETE",
url: apiClient.getUrl("Collections/" + options.collectionId + "/Items", {
2019-10-15 21:13:33 +03:00
Ids: [item.Id].join(",")
2018-10-23 01:05:09 +03:00
})
}).then(function () {
getResolveFunction(resolve, id, true)();
2018-10-23 01:05:09 +03:00
});
break;
2019-10-15 21:13:33 +03:00
case "canceltimer":
2018-10-23 01:05:09 +03:00
deleteTimer(apiClient, item, resolve, id);
break;
2019-10-15 21:13:33 +03:00
case "cancelseriestimer":
2018-10-23 01:05:09 +03:00
deleteSeriesTimer(apiClient, item, resolve, id);
break;
default:
reject();
break;
2018-10-23 01:05:09 +03:00
}
});
2018-10-23 01:05:09 +03:00
}
function deleteTimer(apiClient, item, resolve, command) {
2019-10-15 21:13:33 +03:00
require(["recordingHelper"], function (recordingHelper) {
2018-10-23 01:05:09 +03:00
var timerId = item.TimerId || item.Id;
recordingHelper.cancelTimerWithConfirmation(timerId, item.ServerId).then(function () {
getResolveFunction(resolve, command, true)();
});
});
2018-10-23 01:05:09 +03:00
}
function deleteSeriesTimer(apiClient, item, resolve, command) {
2019-10-15 21:13:33 +03:00
require(["recordingHelper"], function (recordingHelper) {
recordingHelper.cancelSeriesTimerWithConfirmation(item.Id, item.ServerId).then(function () {
getResolveFunction(resolve, command, true)();
});
});
2018-10-23 01:05:09 +03:00
}
function play(item, resume, queue, queueNext) {
2019-10-15 21:13:33 +03:00
var method = queue ? (queueNext ? "queueNext" : "queue") : "play";
var startPosition = 0;
if (resume && item.UserData && item.UserData.PlaybackPositionTicks) {
startPosition = item.UserData.PlaybackPositionTicks;
}
2019-10-15 21:13:33 +03:00
if (item.Type === "Program") {
playbackManager[method]({
ids: [item.ChannelId],
startPositionTicks: startPosition,
serverId: item.ServerId
});
} else {
playbackManager[method]({
items: [item],
startPositionTicks: startPosition
});
}
2018-10-23 01:05:09 +03:00
}
function editItem(apiClient, item) {
return new Promise(function (resolve, reject) {
2018-10-23 01:05:09 +03:00
var serverId = apiClient.serverInfo().Id;
2019-10-15 21:13:33 +03:00
if (item.Type === "Timer") {
require(["recordingEditor"], function (recordingEditor) {
recordingEditor.show(item.Id, serverId).then(resolve, reject);
});
2019-10-15 21:13:33 +03:00
} else if (item.Type === "SeriesTimer") {
require(["seriesRecordingEditor"], function (recordingEditor) {
recordingEditor.show(item.Id, serverId).then(resolve, reject);
});
} else {
2019-10-15 21:13:33 +03:00
require(["metadataEditor"], function (metadataEditor) {
metadataEditor.show(item.Id, serverId).then(resolve, reject);
});
}
});
2018-10-23 01:05:09 +03:00
}
function deleteItem(apiClient, item) {
return new Promise(function (resolve, reject) {
2019-10-15 21:13:33 +03:00
require(["deleteHelper"], function (deleteHelper) {
2018-10-23 01:05:09 +03:00
deleteHelper.deleteItem({
item: item,
navigate: false
}).then(function () {
resolve(true);
}, reject);
});
});
2018-10-23 01:05:09 +03:00
}
function refresh(apiClient, item) {
2019-10-15 21:13:33 +03:00
require(["refreshDialog"], function (refreshDialog) {
2018-10-23 01:05:09 +03:00
new refreshDialog({
itemIds: [item.Id],
serverId: apiClient.serverInfo().Id,
2019-10-15 21:13:33 +03:00
mode: item.Type === "CollectionFolder" ? "scan" : null
}).show();
});
2018-10-23 01:05:09 +03:00
}
function show(options) {
var commands = getCommands(options);
if (!commands.length) {
return Promise.reject();
}
return actionsheet.show({
2018-10-23 01:05:09 +03:00
items: commands,
positionTo: options.positionTo,
2019-10-15 21:13:33 +03:00
resolveOnClick: ["share"]
}).then(function (id) {
return executeCommand(options.item, id, options);
});
2018-10-23 01:05:09 +03:00
}
2018-10-23 01:05:09 +03:00
return {
getCommands: getCommands,
show: show
};
});