diff --git a/spotizerr-ui/src/components/SearchResultCard.tsx b/spotizerr-ui/src/components/SearchResultCard.tsx
index a471228..317d3d6 100644
--- a/spotizerr-ui/src/components/SearchResultCard.tsx
+++ b/spotizerr-ui/src/components/SearchResultCard.tsx
@@ -35,7 +35,7 @@ export const SearchResultCard = ({ id, name, subtitle, imageUrl, type, onDownloa
className="absolute bottom-2 right-2 p-2 bg-button-success hover:bg-button-success-hover text-button-success-text rounded-full transition-opacity shadow-lg opacity-0 group-hover:opacity-100 duration-300 z-10"
title={`Download ${type}`}
>
-
+
)}
diff --git a/spotizerr-ui/src/contexts/QueueProvider.tsx b/spotizerr-ui/src/contexts/QueueProvider.tsx
index 632e19b..b9799b8 100644
--- a/spotizerr-ui/src/contexts/QueueProvider.tsx
+++ b/spotizerr-ui/src/contexts/QueueProvider.tsx
@@ -343,26 +343,51 @@ export function QueueProvider({ children }: { children: ReactNode }) {
try {
const taskIds = activeItems.map((item) => item.taskId!);
- await apiClient.post("/prgs/cancel/all", { task_ids: taskIds });
+ const response = await apiClient.post("/prgs/cancel/all", { task_ids: taskIds });
+
+ // Get the list of successfully cancelled task IDs from response
+ const cancelledTaskIds = response.data.task_ids || taskIds; // Fallback to all if response is different
- activeItems.forEach((item) => stopPolling(item.id));
+ activeItems.forEach((item) => {
+ if (cancelledTaskIds.includes(item.taskId)) {
+ stopPolling(item.taskId!);
+ }
+ });
+ // Immediately update UI to show cancelled status for all cancelled tasks
setItems((prev) =>
prev.map((item) =>
- taskIds.includes(item.taskId!)
+ cancelledTaskIds.includes(item.taskId!)
? {
...item,
status: "cancelled",
+ last_line: {
+ ...item.last_line,
+ status_info: {
+ ...item.last_line?.status_info,
+ status: "cancelled",
+ error: "Task cancelled by user",
+ timestamp: Date.now() / 1000,
+ }
+ }
}
: item,
),
);
- toast.info("Cancelled all active downloads.");
+
+ // Schedule removal for all cancelled tasks
+ activeItems.forEach((item) => {
+ if (cancelledTaskIds.includes(item.taskId)) {
+ scheduleCancelledTaskRemoval(item.id);
+ }
+ });
+
+ toast.info(`Cancelled ${cancelledTaskIds.length} active downloads.`);
} catch (error) {
console.error("Failed to cancel all tasks:", error);
toast.error("Failed to cancel all downloads.");
}
- }, [items, stopPolling]);
+ }, [items, stopPolling, scheduleCancelledTaskRemoval]);
const clearAllPolls = useCallback(() => {
Object.values(pollingIntervals.current).forEach(clearInterval);