mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 22:25:20 +00:00
Harden attachment transfer bookkeeping
This commit is contained in:
@@ -426,7 +426,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
|
|
||||||
// Delivery tracking
|
// Delivery tracking
|
||||||
private var cancellables = Set<AnyCancellable>()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
private var transferIdToMessageID: [String: String] = [:]
|
private var transferIdToMessageIDs: [String: [String]] = [:]
|
||||||
private var messageIDToTransferId: [String: String] = [:]
|
private var messageIDToTransferId: [String: String] = [:]
|
||||||
|
|
||||||
// MARK: - QR Verification (pending state)
|
// MARK: - QR Verification (pending state)
|
||||||
@@ -2479,6 +2479,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
|
|
||||||
Task.detached(priority: .userInitiated) { [weak self] in
|
Task.detached(priority: .userInitiated) { [weak self] in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
defer { try? FileManager.default.removeItem(at: sourceURL) }
|
||||||
var destinationURL: URL?
|
var destinationURL: URL?
|
||||||
do {
|
do {
|
||||||
let data = try Data(contentsOf: sourceURL)
|
let data = try Data(contentsOf: sourceURL)
|
||||||
@@ -2528,7 +2529,9 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
func cancelMediaSend(messageID: String) {
|
func cancelMediaSend(messageID: String) {
|
||||||
if let transferId = messageIDToTransferId[messageID] {
|
if let transferId = messageIDToTransferId[messageID],
|
||||||
|
let active = transferIdToMessageIDs[transferId]?.first,
|
||||||
|
active == messageID {
|
||||||
meshService.cancelTransfer(transferId)
|
meshService.cancelTransfer(transferId)
|
||||||
}
|
}
|
||||||
clearTransferMapping(for: messageID)
|
clearTransferMapping(for: messageID)
|
||||||
@@ -2629,16 +2632,23 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
private func registerTransfer(transferId: String, messageID: String) {
|
private func registerTransfer(transferId: String, messageID: String) {
|
||||||
transferIdToMessageID[transferId] = messageID
|
transferIdToMessageIDs[transferId, default: []].append(messageID)
|
||||||
messageIDToTransferId[messageID] = transferId
|
messageIDToTransferId[messageID] = transferId
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
private func clearTransferMapping(for messageID: String) {
|
private func clearTransferMapping(for messageID: String) {
|
||||||
if let transferId = messageIDToTransferId.removeValue(forKey: messageID) {
|
guard let transferId = messageIDToTransferId.removeValue(forKey: messageID) else { return }
|
||||||
transferIdToMessageID.removeValue(forKey: transferId)
|
guard var queue = transferIdToMessageIDs[transferId] else { return }
|
||||||
|
if !queue.isEmpty {
|
||||||
|
if queue.first == messageID {
|
||||||
|
queue.removeFirst()
|
||||||
|
} else if let idx = queue.firstIndex(of: messageID) {
|
||||||
|
queue.remove(at: idx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
transferIdToMessageIDs[transferId] = queue.isEmpty ? nil : queue
|
||||||
|
}
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
private func handleMediaSendFailure(messageID: String, reason: String) {
|
private func handleMediaSendFailure(messageID: String, reason: String) {
|
||||||
@@ -2650,17 +2660,17 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
private func handleTransferEvent(_ event: TransferProgressManager.Event) {
|
private func handleTransferEvent(_ event: TransferProgressManager.Event) {
|
||||||
switch event {
|
switch event {
|
||||||
case .started(let id, let total):
|
case .started(let id, let total):
|
||||||
guard let messageID = transferIdToMessageID[id] else { return }
|
guard let messageID = transferIdToMessageIDs[id]?.first else { return }
|
||||||
updateMessageDeliveryStatus(messageID, status: .partiallyDelivered(reached: 0, total: total))
|
updateMessageDeliveryStatus(messageID, status: .partiallyDelivered(reached: 0, total: total))
|
||||||
case .updated(let id, let sent, let total):
|
case .updated(let id, let sent, let total):
|
||||||
guard let messageID = transferIdToMessageID[id] else { return }
|
guard let messageID = transferIdToMessageIDs[id]?.first else { return }
|
||||||
updateMessageDeliveryStatus(messageID, status: .partiallyDelivered(reached: sent, total: total))
|
updateMessageDeliveryStatus(messageID, status: .partiallyDelivered(reached: sent, total: total))
|
||||||
case .completed(let id, _):
|
case .completed(let id, _):
|
||||||
guard let messageID = transferIdToMessageID[id] else { return }
|
guard let messageID = transferIdToMessageIDs[id]?.first else { return }
|
||||||
updateMessageDeliveryStatus(messageID, status: .sent)
|
updateMessageDeliveryStatus(messageID, status: .sent)
|
||||||
clearTransferMapping(for: messageID)
|
clearTransferMapping(for: messageID)
|
||||||
case .cancelled(let id, _, _):
|
case .cancelled(let id, _, _):
|
||||||
guard let messageID = transferIdToMessageID[id] else { return }
|
guard let messageID = transferIdToMessageIDs[id]?.first else { return }
|
||||||
clearTransferMapping(for: messageID)
|
clearTransferMapping(for: messageID)
|
||||||
removeMessage(withID: messageID, cleanupFile: true)
|
removeMessage(withID: messageID, cleanupFile: true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,5 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.files.user-selected.read-only</key>
|
<key>com.apple.security.files.user-selected.read-only</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.assets.movies.read-only</key>
|
|
||||||
<true/>
|
|
||||||
<key>com.apple.security.assets.music.read-only</key>
|
|
||||||
<true/>
|
|
||||||
<key>com.apple.security.assets.pictures.read-only</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
Reference in New Issue
Block a user