blob: e268ba2c0f5f472361f5af6b5b20fee1253ea937 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
import SwiftUI
extension EnvironmentValues {
@Entry var appState: AppState = AppState.shared
}
@Observable
final class AppState {
static let shared = AppState()
private init() {
}
var bonjourState = BonjourState()
var activeHotline: HotlineState? = nil
var activeServerState: ServerState? = nil
var cloudKitReady: Bool = false
// MARK: - Transfers
/// All active transfers across all servers
/// Transfers persist even if you disconnect from the server
var transfers: [TransferInfo] = []
@ObservationIgnored private var transferClients: [UUID: HotlineTransferClient] = [:]
/// Track download tasks by reference number for cancellation
@ObservationIgnored private var transferTasks: [UUID: Task<Void, Never>] = [:]
/// Add a transfer to the transfer list
@MainActor
func addTransfer(_ transfer: TransferInfo) {
self.transfers.append(transfer)
}
/// Cancel a transfer by transfer ID
@MainActor
func cancelTransfer(id: UUID) {
guard let transferIndex = self.transfers.firstIndex(where: { $0.id == id }) else {
return
}
// Cancel the task if it exists
if let task = self.transferTasks[id] {
task.cancel()
self.transferTasks.removeValue(forKey: id)
}
if let client = self.transferClients[id] {
client.cancel()
self.transferClients.removeValue(forKey: id)
}
// Remove from transfers list
self.transfers.remove(at: transferIndex)
}
/// Cancel specified transfers
@MainActor
func cancelTransfers(ids: [UUID]) {
for transferID in ids {
self.cancelTransfer(id: transferID)
}
}
/// Cancel all active transfers
@MainActor
func cancelAllTransfers() {
for (_, task) in self.transferTasks {
task.cancel()
}
self.transferTasks.removeAll()
for (_, client) in self.transferClients {
client.cancel()
}
self.transferClients.removeAll()
// Clear transfers
self.transfers.removeAll()
}
/// Remove all completed transfers
@MainActor
func sweepTransfers() {
for t in self.transfers {
if t.done {
self.cancelTransfer(id: t.id)
}
}
}
/// Register a transfer task
@MainActor
func registerTransferTask(_ task: Task<Void, Never>, transferID: UUID) {
self.transferTasks[transferID] = task
}
@MainActor
func registerTransferTask(_ task: Task<Void, Never>, transferID: UUID, client: HotlineTransferClient) {
self.transferTasks[transferID] = task
self.transferClients[transferID] = client
}
/// Unregister a download task (called on completion/failure)
@MainActor
func unregisterTransferTask(for transferID: UUID) {
self.transferTasks.removeValue(forKey: transferID)
self.transferClients.removeValue(forKey: transferID)
}
}
|