feat: add stop downloads control

This commit is contained in:
nimbold
2026-06-04 04:44:04 +03:30
parent 86d70a9ca7
commit 28bb90e8c2
3 changed files with 47 additions and 0 deletions
+17
View File
@@ -84,6 +84,15 @@ struct ContentView: View {
}
}
ToolbarItem {
Button {
controller.pauseActiveDownloads(queueID: queueID)
} label: {
Label("Stop Downloads", systemImage: "stop.fill")
}
.disabled(!hasActiveDownloads(in: queueID))
}
ToolbarItemGroup {
if !selectedItems.isEmpty {
if selectedItems.contains(where: { $0.status == .downloading }) {
@@ -173,6 +182,14 @@ struct ContentView: View {
selection = Set(items.map { $0.id })
}
private func hasActiveDownloads(in queueID: UUID?) -> Bool {
if let queueID {
return controller.downloads.contains { $0.status == .downloading && $0.queueID == queueID }
}
return controller.activeCount > 0
}
private func filteredDownloads(for filter: DownloadSidebarFilter) -> [DownloadItem] {
switch filter {
case .all:
+25
View File
@@ -189,6 +189,31 @@ final class DownloadController: ObservableObject {
pumpQueue()
}
func pauseActiveDownloads(queueID: UUID? = nil) {
let targetQueueID = queueID.map(normalizedQueueID)
let activeItems = downloads.filter { item in
item.status == .downloading && (targetQueueID == nil || item.queueID == targetQueueID)
}
guard !activeItems.isEmpty else { return }
for item in activeItems {
activeHandles[item.id]?.cancel()
activeHandles[item.id] = nil
update(item.id) {
$0.status = .paused
$0.message = "Paused. Resume will continue from the partial file."
$0.autoResumeOnLaunch = false
}
automaticRetryCounts[item.id] = nil
}
engineMessage = "Paused \(activeItems.count) active download\(activeItems.count == 1 ? "" : "s")."
saveDownloads()
updateSleepActivity()
pumpQueue()
}
func queue(_ item: DownloadItem) {
activeHandles[item.id]?.cancel()
activeHandles[item.id] = nil
+5
View File
@@ -63,6 +63,11 @@ struct FirelinkApp: App {
controller.startQueue()
}
.keyboardShortcut("r", modifiers: [.command])
Button("Stop Downloads") {
controller.pauseActiveDownloads()
}
.disabled(controller.activeCount == 0)
}
}