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

Add permission check for removing playlist item

This commit is contained in:
Bill Thornton 2024-05-06 01:51:40 -04:00
parent 3e62933461
commit 6c226ba59f
2 changed files with 57 additions and 28 deletions

View file

@ -280,11 +280,11 @@ export function getCommands(options) {
});
}
if (item.PlaylistItemId && options.playlistId) {
if (item.PlaylistItemId && options.playlistId && options.canEditPlaylist) {
commands.push({
name: globalize.translate('RemoveFromPlaylist'),
id: 'removefromplaylist',
icon: 'remove'
icon: 'playlist_remove'
});
}
@ -292,7 +292,7 @@ export function getCommands(options) {
commands.push({
name: globalize.translate('RemoveFromCollection'),
id: 'removefromcollection',
icon: 'remove'
icon: 'playlist_remove'
});
}
@ -696,6 +696,6 @@ export function show(options) {
}
export default {
getCommands: getCommands,
show: show
getCommands,
show
};

View file

@ -2,6 +2,7 @@
* Module shortcuts.
* @module components/shortcuts
*/
import { getPlaylistsApi } from '@jellyfin/sdk/lib/utils/api/playlists-api';
import { playbackManager } from './playback/playbackmanager';
import inputManager from '../scripts/inputManager';
@ -12,6 +13,7 @@ import recordingHelper from './recordingcreator/recordinghelper';
import ServerConnections from './ServerConnections';
import toast from './toast/toast';
import * as userSettings from '../scripts/settings/userSettings';
import { toApi } from 'utils/jellyfin-apiclient/compat';
function playAllFromHere(card, serverId, queue) {
const parent = card.parentNode;
@ -100,7 +102,7 @@ function notifyRefreshNeeded(childElement, itemsContainer) {
}
}
function showContextMenu(card, options) {
function showContextMenu(card, options = {}) {
getItem(card).then(item => {
const playlistId = card.getAttribute('data-playlistid');
const collectionId = card.getAttribute('data-collectionid');
@ -110,28 +112,55 @@ function showContextMenu(card, options) {
item.PlaylistItemId = elem ? elem.getAttribute('data-playlistitemid') : null;
}
import('./itemContextMenu').then((itemContextMenu) => {
ServerConnections.getApiClient(item.ServerId).getCurrentUser().then(user => {
itemContextMenu.show(Object.assign({
item: item,
const apiClient = ServerConnections.getApiClient(item.ServerId);
const api = toApi(apiClient);
Promise.all([
// Import the item menu component
import('./itemContextMenu'),
// Fetch the current user
apiClient.getCurrentUser(),
// Fetch playlist perms if item is a child of a playlist
playlistId ?
getPlaylistsApi(api)
.getPlaylistUser({
playlistId,
userId: apiClient.getCurrentUserId()
})
.then(({ data }) => data)
.catch(() => {
// If a user doesn't have access, then the request will 404 and throw
return { CanEdit: false };
}) :
// Not a playlist item
Promise.resolve({ CanEdit: false })
])
.then(([
itemContextMenu,
user,
playlistPerms
]) => {
return itemContextMenu.show({
item,
play: true,
queue: true,
playAllFromHere: item.Type === 'Season' || !item.IsFolder,
queueAllFromHere: !item.IsFolder,
playlistId: playlistId,
collectionId: collectionId,
user: user
}, 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);
}
})
.catch(() => { /* no-op */ });
});
});
playlistId,
canEditPlaylist: !!playlistPerms.CanEdit,
collectionId,
user,
...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);
}
})
.catch(() => { /* no-op */ });
});
}
@ -406,8 +435,8 @@ export function getShortcutAttributesHtml(item, serverId) {
}
export default {
on: on,
off: off,
onClick: onClick,
getShortcutAttributesHtml: getShortcutAttributesHtml
on,
off,
onClick,
getShortcutAttributesHtml
};