diff --git a/frontend/src/Activity/Queue/Queue.js b/frontend/src/Activity/Queue/Queue.js
index c42c384c6..26c52a285 100644
--- a/frontend/src/Activity/Queue/Queue.js
+++ b/frontend/src/Activity/Queue/Queue.js
@@ -282,6 +282,17 @@ class Queue extends Component {
return !!(item && item.movieId);
})
)}
+ allPending={isConfirmRemoveModalOpen && (
+ selectedIds.every((id) => {
+ const item = items.find((i) => i.id === id);
+
+ if (!item) {
+ return false;
+ }
+
+ return item.status === 'delay' || item.status === 'downloadClientUnavailable';
+ })
+ )}
onRemovePress={this.onRemoveSelectedConfirmed}
onModalClose={this.onConfirmRemoveModalClose}
/>
diff --git a/frontend/src/Activity/Queue/QueueRow.js b/frontend/src/Activity/Queue/QueueRow.js
index ea4a8aab7..70a5b15ad 100644
--- a/frontend/src/Activity/Queue/QueueRow.js
+++ b/frontend/src/Activity/Queue/QueueRow.js
@@ -332,6 +332,7 @@ class QueueRow extends Component {
isOpen={isRemoveQueueItemModalOpen}
sourceTitle={title}
canIgnore={!!movie}
+ isPending={isPending}
onRemovePress={this.onRemoveQueueItemModalConfirmed}
onModalClose={this.onRemoveQueueItemModalClose}
/>
diff --git a/frontend/src/Activity/Queue/RemoveQueueItemModal.js b/frontend/src/Activity/Queue/RemoveQueueItemModal.js
index fb039eb8e..2a150520d 100644
--- a/frontend/src/Activity/Queue/RemoveQueueItemModal.js
+++ b/frontend/src/Activity/Queue/RemoveQueueItemModal.js
@@ -66,7 +66,8 @@ class RemoveQueueItemModal extends Component {
const {
isOpen,
sourceTitle,
- canIgnore
+ canIgnore,
+ isPending
} = this.props;
const { remove, blocklist } = this.state;
@@ -89,18 +90,22 @@ class RemoveQueueItemModal extends Component {
{translate('RemoveFromQueueText', [sourceTitle])}
-
- {translate('RemoveFromDownloadClient')}
+ {
+ isPending ?
+ null :
+
+ {translate('RemoveFromDownloadClient')}
-
-
+
+
+ }
{translate('BlocklistRelease')}
@@ -137,6 +142,7 @@ RemoveQueueItemModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
sourceTitle: PropTypes.string.isRequired,
canIgnore: PropTypes.bool.isRequired,
+ isPending: PropTypes.bool.isRequired,
onRemovePress: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired
};
diff --git a/frontend/src/Activity/Queue/RemoveQueueItemsModal.js b/frontend/src/Activity/Queue/RemoveQueueItemsModal.js
index e75456f4c..073e00f04 100644
--- a/frontend/src/Activity/Queue/RemoveQueueItemsModal.js
+++ b/frontend/src/Activity/Queue/RemoveQueueItemsModal.js
@@ -67,7 +67,8 @@ class RemoveQueueItemsModal extends Component {
const {
isOpen,
selectedCount,
- canIgnore
+ canIgnore,
+ allPending
} = this.props;
const { remove, blocklist } = this.state;
@@ -90,18 +91,22 @@ class RemoveQueueItemsModal extends Component {
{translate('AreYouSureYouWantToRemoveSelectedItemsFromQueue', [selectedCount, selectedCount > 1 ? 's' : ''])}
-
- {translate('RemoveFromDownloadClient')}
+ {
+ allPending ?
+ null :
+
+ {translate('RemoveFromDownloadClient')}
-
-
+
+
+ }
@@ -141,6 +146,7 @@ RemoveQueueItemsModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
selectedCount: PropTypes.number.isRequired,
canIgnore: PropTypes.bool.isRequired,
+ allPending: PropTypes.bool.isRequired,
onRemovePress: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired
};
diff --git a/src/NzbDrone.Core/Blocklisting/BlocklistService.cs b/src/NzbDrone.Core/Blocklisting/BlocklistService.cs
index 0a32b2bfe..c22c94a3c 100644
--- a/src/NzbDrone.Core/Blocklisting/BlocklistService.cs
+++ b/src/NzbDrone.Core/Blocklisting/BlocklistService.cs
@@ -17,6 +17,7 @@ public interface IBlocklistService
bool Blocklisted(int movieId, ReleaseInfo release);
PagingSpec Paged(PagingSpec pagingSpec);
List GetByMovieId(int movieId);
+ void Block(RemoteMovie remoteMovie, string message);
void Delete(int id);
void Delete(List ids);
}
@@ -72,6 +73,29 @@ public List GetByMovieId(int movieId)
return _blocklistRepository.BlocklistedByMovie(movieId);
}
+ public void Block(RemoteMovie remoteMovie, string message)
+ {
+ var blocklist = new Blocklist
+ {
+ MovieId = remoteMovie.Movie.Id,
+ SourceTitle = remoteMovie.Release.Title,
+ Quality = remoteMovie.ParsedMovieInfo.Quality,
+ Date = DateTime.UtcNow,
+ PublishedDate = remoteMovie.Release.PublishDate,
+ Size = remoteMovie.Release.Size,
+ Indexer = remoteMovie.Release.Indexer,
+ Protocol = remoteMovie.Release.DownloadProtocol,
+ Message = message
+ };
+
+ if (remoteMovie.Release is TorrentInfo torrentRelease)
+ {
+ blocklist.TorrentInfoHash = torrentRelease.InfoHash;
+ }
+
+ _blocklistRepository.Insert(blocklist);
+ }
+
public void Delete(int id)
{
_blocklistRepository.Delete(id);
diff --git a/src/Radarr.Api.V3/Queue/QueueController.cs b/src/Radarr.Api.V3/Queue/QueueController.cs
index 0d5544249..0fbfec6e9 100644
--- a/src/Radarr.Api.V3/Queue/QueueController.cs
+++ b/src/Radarr.Api.V3/Queue/QueueController.cs
@@ -3,6 +3,7 @@
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Common.Extensions;
+using NzbDrone.Core.Blocklisting;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.Download;
@@ -33,6 +34,7 @@ public class QueueController : RestControllerWithSignalR