From 9bef06f466e3c9daa489870a5665c194f66e0fe7 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Sun, 9 Oct 2022 14:15:07 +0200 Subject: [PATCH 1/5] Add DownloadAll for season and series --- src/components/itemContextMenu.js | 50 +++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index 15980b23ad..9472874158 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -141,6 +141,14 @@ import toast from './toast/toast'; }); } + if (item.Type === 'Season' || item.Type == 'Series') { + commands.push({ + name: 'Download All', + id: 'downloadall', + icon: 'file_download' + }); + } + if (item.CanDelete && options.deleteItem !== false) { if (item.Type === 'Playlist' || item.Type === 'BoxSet') { commands.push({ @@ -347,6 +355,48 @@ import toast from './toast/toast'; getResolveFunction(getResolveFunction(resolve, id), id)(); }); break; + case 'downloadall': { + const downloadEpisodes = episodes => { + import('../scripts/fileDownloader').then((fileDownloader) => { + const downloads = episodes.map(episode => { + const downloadHref = apiClient.getItemDownloadUrl(episode.Id); + return { + url: downloadHref, + itemId: episode.Id, + serverId: serverId, + title: episode.Name, + filename: episode.Path.replace(/^.*[\\/]/, '') + }; + }); + + fileDownloader.download(downloads); + }); + }; + const downloadSeasons = seasons => { + Promise.all(seasons.map(seasonItem => { + return apiClient.getEpisodes(seasonItem.SeriesId, { + seasonId: seasonItem.Id, + userId: options.user.Id, + Fields: 'CanDownload,Path' + }); + } + )).then(seasons => { + downloadEpisodes([].concat.apply([], seasons.map(season => season.Items))); + }); + }; + + 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)); + } + + getResolveFunction(getResolveFunction(resolve, id), id)(); + break; + } case 'copy-stream': { const downloadHref = apiClient.getItemDownloadUrl(itemId); copy(downloadHref).then(() => { From e834ae3f413e5a614f0b307af20ffdb29070ed94 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Wed, 12 Oct 2022 07:15:09 +0200 Subject: [PATCH 2/5] Use downloadFiles from NatvieShell Try to pass batched downloads to natvie shell as list The new downloadFiles function is TBD in shell implementations. --- src/scripts/shell.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/scripts/shell.js b/src/scripts/shell.js index b21d658f9f..cbcd9f8859 100644 --- a/src/scripts/shell.js +++ b/src/scripts/shell.js @@ -42,6 +42,10 @@ export default { * @returns true on success */ downloadFiles(items) { + if (window.NativeShell?.downloadFiles) { + window.NativeShell.downloadFiles(items); + return true; + } if (window.NativeShell?.downloadFile) { items.forEach(item => { window.NativeShell.downloadFile(item); From 17eede9062b07c66e8c2dfd8e84e5a9de6121dd0 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Fri, 14 Oct 2022 19:46:21 +0200 Subject: [PATCH 3/5] Add DownloadAll to translations --- src/components/itemContextMenu.js | 2 +- src/strings/en-us.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index 9472874158..6dc4d68b34 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -143,7 +143,7 @@ import toast from './toast/toast'; if (item.Type === 'Season' || item.Type == 'Series') { commands.push({ - name: 'Download All', + name: globalize.translate('DownloadAll'), id: 'downloadall', icon: 'file_download' }); diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 906a76f1f5..aa21e8fc1c 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -208,6 +208,7 @@ "DoNotRecord": "Do not record", "Down": "Down", "Download": "Download", + "DownloadAll": "Download All", "DownloadsValue": "{0} downloads", "DrmChannelsNotImported": "Channels with DRM will not be imported.", "DropShadow": "Drop Shadow", From d54a89d10a0eb87cdf23d66bd7c02680a80cab12 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Sat, 29 Oct 2022 12:45:24 +0200 Subject: [PATCH 4/5] Integrate review feedback * Add ignore statement for linter * Don't shadow variable names --- src/components/itemContextMenu.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index 6dc4d68b34..a0da775eaf 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -324,6 +324,7 @@ import toast from './toast/toast'; const apiClient = ServerConnections.getApiClient(serverId); return new Promise(function (resolve, reject) { + // eslint-disable-next-line sonarjs/max-switch-cases switch (id) { case 'addtocollection': import('./collectionEditor/collectionEditor').then(({default: CollectionEditor}) => { @@ -380,8 +381,8 @@ import toast from './toast/toast'; Fields: 'CanDownload,Path' }); } - )).then(seasons => { - downloadEpisodes([].concat.apply([], seasons.map(season => season.Items))); + )).then(seasonData => { + downloadEpisodes([].concat.apply([], seasonData.map(season => season.Items))); }); }; From 1eafb235e2d11c7fc665acc73ffcc5b59fed55d8 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 4 Jan 2023 23:40:01 -0500 Subject: [PATCH 5/5] Use array.flat instead of concat.apply --- src/components/itemContextMenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index a0da775eaf..e1c1545b69 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -382,7 +382,7 @@ import toast from './toast/toast'; }); } )).then(seasonData => { - downloadEpisodes([].concat.apply([], seasonData.map(season => season.Items))); + downloadEpisodes(seasonData.map(season => season.Items).flat()); }); };