diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index 87655c7187..b05622021f 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -1,3 +1,5 @@ +import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind'; + import browser from '../scripts/browser'; import { copy } from '../scripts/clipboard'; import dom from '../utils/dom'; @@ -10,9 +12,15 @@ import itemHelper, { canEditPlaylist } from './itemHelper'; import { playbackManager } from './playback/playbackmanager'; import toast from './toast/toast'; import * as userSettings from '../scripts/settings/userSettings'; -import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind'; import { AppFeature } from 'constants/appFeature'; +/** Item types that support downloading all children. */ +const DOWNLOAD_ALL_TYPES = [ + BaseItemKind.MusicAlbum, + BaseItemKind.Season, + BaseItemKind.Series +]; + function getDeleteLabel(type) { switch (type) { case BaseItemKind.Series: @@ -172,7 +180,7 @@ export async function getCommands(options) { if (appHost.supports(AppFeature.FileDownload)) { // CanDownload should probably be updated to return true for these items? - if (user.Policy.EnableContentDownloading && (item.Type === 'Season' || item.Type == 'Series')) { + if (user.Policy.EnableContentDownloading && DOWNLOAD_ALL_TYPES.includes(item.Type)) { commands.push({ name: globalize.translate('DownloadAll'), id: 'downloadall', @@ -415,17 +423,17 @@ function executeCommand(item, id, options) { }); break; case 'downloadall': { - const downloadEpisodes = episodes => { + const downloadItems = items => { import('../scripts/fileDownloader').then((fileDownloader) => { - const downloads = episodes.map(episode => { - const downloadHref = apiClient.getItemDownloadUrl(episode.Id); + const downloads = items.map(item => { + const downloadHref = apiClient.getItemDownloadUrl(item.Id); return { url: downloadHref, - item: episode, - itemId: episode.Id, - serverId: serverId, - title: episode.Name, - filename: episode.Path.replace(/^.*[\\/]/, '') + item, + itemId: item.Id, + serverId, + title: item.Name, + filename: item.Path.replace(/^.*[\\/]/, '') }; }); @@ -441,17 +449,25 @@ function executeCommand(item, id, options) { }); } )).then(seasonData => { - downloadEpisodes(seasonData.map(season => season.Items).flat()); + downloadItems(seasonData.map(season => season.Items).flat()); }); }; - if (item.Type === 'Season') { - downloadSeasons([item]); - } else if (item.Type === 'Series') { - apiClient.getSeasons(item.Id, { - userId: options.user.Id, - Fields: 'ItemCounts' - }).then(seasons => downloadSeasons(seasons.Items)); + switch (item.Type) { + case BaseItemKind.MusicAlbum: + apiClient.getItems(options.user.Id, { + ParentId: item.Id, + Fields: 'CanDownload,Path' + }).then(({ Items }) => downloadItems(Items)); + break; + case BaseItemKind.Season: + downloadSeasons([item]); + break; + case BaseItemKind.Series: + apiClient.getSeasons(item.Id, { + userId: options.user.Id, + Fields: 'ItemCounts' + }).then(seasons => downloadSeasons(seasons.Items)); } getResolveFunction(getResolveFunction(resolve, id), id)();