1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00
jellyfin-web/src/components/shortcuts.js

404 lines
14 KiB
JavaScript
Raw Normal View History

2020-06-09 22:14:24 +03:00
/* eslint-disable indent */
/**
* Module shortcuts.
* @module components/shortcuts
*/
2020-08-16 20:24:45 +02:00
import { playbackManager } from './playback/playbackmanager';
2020-08-14 08:46:34 +02:00
import inputManager from '../scripts/inputManager';
2020-08-16 20:24:45 +02:00
import { appRouter } from './appRouter';
2020-08-14 08:46:34 +02:00
import globalize from '../scripts/globalize';
import dom from '../scripts/dom';
import recordingHelper from './recordingcreator/recordinghelper';
import ServerConnections from './ServerConnections';
2020-10-18 14:19:41 +01:00
import toast from './toast/toast';
2018-10-23 01:05:09 +03:00
function playAllFromHere(card, serverId, queue) {
2020-06-09 22:14:24 +03:00
const parent = card.parentNode;
const className = card.classList.length ? (`.${card.classList[0]}`) : '';
const cards = parent.querySelectorAll(`${className}[data-id]`);
2020-06-09 22:14:24 +03:00
const ids = [];
2020-06-09 22:14:24 +03:00
let foundCard = false;
let startIndex;
2020-06-09 22:14:24 +03:00
for (let i = 0, length = cards.length; i < length; i++) {
if (cards[i] === card) {
foundCard = true;
startIndex = i;
}
if (foundCard || !queue) {
ids.push(cards[i].getAttribute('data-id'));
}
}
2020-06-09 22:14:24 +03:00
const itemsContainer = dom.parentWithClass(card, 'itemsContainer');
2018-10-23 01:05:09 +03:00
if (itemsContainer && itemsContainer.fetchData) {
2020-06-09 22:14:24 +03:00
const queryOptions = queue ? { StartIndex: startIndex } : {};
2020-06-09 22:14:24 +03:00
return itemsContainer.fetchData(queryOptions).then(result => {
if (queue) {
return playbackManager.queue({
items: result.Items
});
} else {
return playbackManager.play({
items: result.Items,
startIndex: startIndex
});
}
});
}
if (!ids.length) {
return;
}
if (queue) {
return playbackManager.queue({
ids: ids,
serverId: serverId
});
} else {
return playbackManager.play({
ids: ids,
serverId: serverId,
startIndex: startIndex
});
}
2018-10-23 01:05:09 +03:00
}
function showProgramDialog(item) {
2020-11-07 12:05:09 +00:00
import('./recordingcreator/recordingcreator').then(({default:recordingCreator}) => {
recordingCreator.show(item.Id, item.ServerId);
});
2018-10-23 01:05:09 +03:00
}
function getItem(button) {
button = dom.parentWithAttribute(button, 'data-id');
2020-06-09 22:14:24 +03:00
const serverId = button.getAttribute('data-serverid');
const id = button.getAttribute('data-id');
const type = button.getAttribute('data-type');
const apiClient = ServerConnections.getApiClient(serverId);
if (type === 'Timer') {
return apiClient.getLiveTvTimer(id);
}
if (type === 'SeriesTimer') {
return apiClient.getLiveTvSeriesTimer(id);
}
return apiClient.getItem(apiClient.getCurrentUserId(), id);
2018-10-23 01:05:09 +03:00
}
function notifyRefreshNeeded(childElement, itemsContainer) {
itemsContainer = itemsContainer || dom.parentWithAttribute(childElement, 'is', 'emby-itemscontainer');
if (itemsContainer) {
itemsContainer.notifyRefreshNeeded(true);
}
2018-10-23 01:05:09 +03:00
}
function showContextMenu(card, options) {
2020-06-09 22:14:24 +03:00
getItem(card).then(item => {
const playlistId = card.getAttribute('data-playlistid');
const collectionId = card.getAttribute('data-collectionid');
2018-10-23 01:05:09 +03:00
if (playlistId) {
2020-06-09 22:14:24 +03:00
const elem = dom.parentWithAttribute(card, 'data-playlistitemid');
item.PlaylistItemId = elem ? elem.getAttribute('data-playlistitemid') : null;
2018-10-23 01:05:09 +03:00
}
2020-08-14 08:46:34 +02:00
import('./itemContextMenu').then((itemContextMenu) => {
ServerConnections.getApiClient(item.ServerId).getCurrentUser().then(user => {
2018-10-23 01:05:09 +03:00
itemContextMenu.show(Object.assign({
item: item,
play: true,
queue: true,
2018-10-23 01:05:09 +03:00
playAllFromHere: !item.IsFolder,
queueAllFromHere: !item.IsFolder,
playlistId: playlistId,
collectionId: collectionId,
user: user
2020-06-09 22:14:24 +03:00
}, options || {})).then(result => {
if (result.command === 'playallfromhere' || result.command === 'queueallfromhere') {
executeAction(card, options.positionTo, result.command);
} else if (result.updated || result.deleted) {
notifyRefreshNeeded(card, options.itemsContainer);
}
});
});
});
});
2018-10-23 01:05:09 +03:00
}
function getItemInfoFromCard(card) {
return {
Type: card.getAttribute('data-type'),
Id: card.getAttribute('data-id'),
TimerId: card.getAttribute('data-timerid'),
CollectionType: card.getAttribute('data-collectiontype'),
ChannelId: card.getAttribute('data-channelid'),
SeriesId: card.getAttribute('data-seriesid'),
ServerId: card.getAttribute('data-serverid'),
MediaType: card.getAttribute('data-mediatype'),
IsFolder: card.getAttribute('data-isfolder') === 'true',
2018-10-23 01:05:09 +03:00
UserData: {
PlaybackPositionTicks: parseInt(card.getAttribute('data-positionticks') || '0')
2018-10-23 01:05:09 +03:00
}
};
2018-10-23 01:05:09 +03:00
}
function showPlayMenu(card, target) {
2020-06-09 22:14:24 +03:00
const item = getItemInfoFromCard(card);
2020-08-14 08:46:34 +02:00
import('./playmenu').then((playMenu) => {
2018-10-23 01:05:09 +03:00
playMenu.show({
2018-10-23 01:05:09 +03:00
item: item,
positionTo: target
});
});
2018-10-23 01:05:09 +03:00
}
function sendToast(text) {
2020-10-18 14:19:41 +01:00
toast(text);
2018-10-23 01:05:09 +03:00
}
function executeAction(card, target, action) {
target = target || card;
2020-06-09 22:14:24 +03:00
let id = card.getAttribute('data-id');
if (!id) {
card = dom.parentWithAttribute(card, 'data-id');
id = card.getAttribute('data-id');
}
2020-06-09 22:14:24 +03:00
const item = getItemInfoFromCard(card);
2020-06-09 22:14:24 +03:00
const serverId = item.ServerId;
const type = item.Type;
2020-06-09 22:14:24 +03:00
const playableItemId = type === 'Program' ? item.ChannelId : item.Id;
if (item.MediaType === 'Photo' && action === 'link') {
action = 'play';
}
if (action === 'link') {
appRouter.showItem(item, {
context: card.getAttribute('data-context'),
parentId: card.getAttribute('data-parentid')
});
} else if (action === 'programdialog') {
showProgramDialog(item);
} else if (action === 'instantmix') {
playbackManager.instantMix({
Id: playableItemId,
ServerId: serverId
});
} else if (action === 'play' || action === 'resume') {
2020-06-09 22:14:24 +03:00
const startPositionTicks = parseInt(card.getAttribute('data-positionticks') || '0');
if (playbackManager.canPlay(item)) {
playbackManager.play({
ids: [playableItemId],
startPositionTicks: startPositionTicks,
serverId: serverId
});
} else {
console.warn('Unable to play item', item);
}
} else if (action === 'queue') {
if (playbackManager.isPlaying()) {
playbackManager.queue({
ids: [playableItemId],
serverId: serverId
});
sendToast(globalize.translate('MediaQueued'));
} else {
playbackManager.queue({
ids: [playableItemId],
serverId: serverId
});
}
} else if (action === 'playallfromhere') {
playAllFromHere(card, serverId);
} else if (action === 'queueallfromhere') {
playAllFromHere(card, serverId, true);
} else if (action === 'setplaylistindex') {
playbackManager.setCurrentPlaylistItem(card.getAttribute('data-playlistitemid'));
} else if (action === 'record') {
onRecordCommand(serverId, id, type, card.getAttribute('data-timerid'), card.getAttribute('data-seriestimerid'));
} else if (action === 'menu') {
2020-06-09 22:14:24 +03:00
const options = target.getAttribute('data-playoptions') === 'false' ?
{
shuffle: false,
instantMix: false,
play: false,
playAllFromHere: false,
queue: false,
queueAllFromHere: false
} :
{};
options.positionTo = target;
showContextMenu(card, options);
} else if (action === 'playmenu') {
showPlayMenu(card, target);
} else if (action === 'edit') {
2020-06-09 22:14:24 +03:00
getItem(target).then(item => {
editItem(item, serverId);
});
} else if (action === 'playtrailer') {
getItem(target).then(playTrailer);
} else if (action === 'addtoplaylist') {
getItem(target).then(addToPlaylist);
} else if (action === 'custom') {
2020-06-09 22:14:24 +03:00
const customAction = target.getAttribute('data-customaction');
2020-06-09 22:14:24 +03:00
card.dispatchEvent(new CustomEvent(`action-${customAction}`, {
2018-10-23 01:05:09 +03:00
detail: {
playlistItemId: card.getAttribute('data-playlistitemid')
2018-10-23 01:05:09 +03:00
},
cancelable: false,
bubbles: true
}));
2018-10-23 01:05:09 +03:00
}
}
function addToPlaylist(item) {
import('./playlisteditor/playlisteditor').then(({default: playlistEditor}) => {
new playlistEditor().show({
2018-10-23 01:05:09 +03:00
items: [item.Id],
serverId: item.ServerId
});
});
2018-10-23 01:05:09 +03:00
}
function playTrailer(item) {
const apiClient = ServerConnections.getApiClient(item.ServerId);
2020-06-09 22:14:24 +03:00
apiClient.getLocalTrailers(apiClient.getCurrentUserId(), item.Id).then(trailers => {
playbackManager.play({ items: trailers });
});
2018-10-23 01:05:09 +03:00
}
function editItem(item, serverId) {
const apiClient = ServerConnections.getApiClient(serverId);
2020-06-09 22:14:24 +03:00
return new Promise((resolve, reject) => {
const serverId = apiClient.serverInfo().Id;
if (item.Type === 'Timer') {
if (item.ProgramId) {
import('./recordingcreator/recordingcreator').then(({default: recordingCreator}) => {
recordingCreator.show(item.ProgramId, serverId).then(resolve, reject);
});
} else {
import('./recordingcreator/recordingeditor').then(({default: recordingEditor}) => {
recordingEditor.show(item.Id, serverId).then(resolve, reject);
});
}
} else {
import('./metadataEditor/metadataEditor').then(({default: metadataEditor}) => {
metadataEditor.show(item.Id, serverId).then(resolve, reject);
});
}
});
2018-10-23 01:05:09 +03:00
}
function onRecordCommand(serverId, id, type, timerId, seriesTimerId) {
if (type === 'Program' || timerId || seriesTimerId) {
2020-06-09 22:14:24 +03:00
const programId = type === 'Program' ? id : null;
recordingHelper.toggleRecording(serverId, programId, timerId, seriesTimerId);
2018-10-23 01:05:09 +03:00
}
}
2020-06-09 22:14:24 +03:00
export function onClick(e) {
const card = dom.parentWithClass(e.target, 'itemAction');
2018-10-23 01:05:09 +03:00
if (card) {
2020-06-09 22:14:24 +03:00
let actionElement = card;
let action = actionElement.getAttribute('data-action');
if (!action) {
actionElement = dom.parentWithAttribute(actionElement, 'data-action');
if (actionElement) {
action = actionElement.getAttribute('data-action');
}
}
if (action) {
executeAction(card, actionElement, action);
e.preventDefault();
e.stopPropagation();
return false;
}
2018-10-23 01:05:09 +03:00
}
}
function onCommand(e) {
2020-06-09 22:14:24 +03:00
const cmd = e.detail.command;
if (cmd === 'play' || cmd === 'resume' || cmd === 'record' || cmd === 'menu' || cmd === 'info') {
2020-06-09 22:14:24 +03:00
const target = e.target;
const card = dom.parentWithClass(target, 'itemAction') || dom.parentWithAttribute(target, 'data-id');
if (card) {
e.preventDefault();
e.stopPropagation();
executeAction(card, card, cmd);
}
2018-10-23 01:05:09 +03:00
}
}
2020-06-09 22:14:24 +03:00
export function on(context, options) {
options = options || {};
if (options.click !== false) {
context.addEventListener('click', onClick);
}
if (options.command !== false) {
inputManager.on(context, onCommand);
}
2018-10-23 01:05:09 +03:00
}
2020-06-09 22:14:24 +03:00
export function off(context, options) {
options = options || {};
context.removeEventListener('click', onClick);
if (options.command !== false) {
inputManager.off(context, onCommand);
}
2018-10-23 01:05:09 +03:00
}
2020-06-09 22:14:24 +03:00
export function getShortcutAttributesHtml(item, serverId) {
let html = `data-id="${item.Id}" data-serverid="${serverId || item.ServerId}" data-type="${item.Type}" data-mediatype="${item.MediaType}" data-channelid="${item.ChannelId}" data-isfolder="${item.IsFolder}"`;
2020-06-09 22:14:24 +03:00
const collectionType = item.CollectionType;
if (collectionType) {
2020-06-09 22:14:24 +03:00
html += ` data-collectiontype="${collectionType}"`;
}
return html;
2018-10-23 01:05:09 +03:00
}
2020-06-09 22:14:24 +03:00
/* eslint-enable indent */
export default {
on: on,
off: off,
onClick: onClick,
getShortcutAttributesHtml: getShortcutAttributesHtml
};