From 391c80ef14d05dde4f6f0bb37e53dfa1fb91b982 Mon Sep 17 00:00:00 2001 From: jack Date: Wed, 23 Jul 2025 21:02:51 +0200 Subject: [PATCH] Fix blank message row and API misuse warnings - Fix blank row appearing when peer disconnects by ensuring display names are never empty - Add validation to prevent system messages with empty content from being displayed - Fix API MISUSE warnings by adding connection state checks before writing to peripherals - Improve write queue processing with additional safety checks - Update activity tracking when processing queued writes These fixes address UI glitches and improve Bluetooth reliability. --- bitchat/Services/BluetoothMeshService.swift | 34 +++++++++++++++------ bitchat/ViewModels/ChatViewModel.swift | 18 ++++++++--- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/bitchat/Services/BluetoothMeshService.swift b/bitchat/Services/BluetoothMeshService.swift index 1b71d279..cb4e11f5 100644 --- a/bitchat/Services/BluetoothMeshService.swift +++ b/bitchat/Services/BluetoothMeshService.swift @@ -201,17 +201,26 @@ class BluetoothMeshService: NSObject { private func writeToPeripheral(_ data: Data, peripheral: CBPeripheral, characteristic: CBCharacteristic, peerID: String? = nil) { let peripheralID = peripheral.identifier.uuidString - if peripheral.state == .connected { - // Direct write if connected - let writeType: CBCharacteristicWriteType = data.count > 512 ? .withResponse : .withoutResponse - peripheral.writeValue(data, for: characteristic, type: writeType) - - // Update activity tracking - updatePeripheralActivity(peripheralID) - } else { + // Double check the peripheral state to avoid API misuse + guard peripheral.state == .connected else { // Queue write for disconnected peripheral queueWrite(data: data, peripheralID: peripheralID, peerID: peerID) + return } + + // Verify characteristic is valid and writable + guard characteristic.properties.contains(.write) || characteristic.properties.contains(.writeWithoutResponse) else { + SecureLogger.log("Characteristic does not support writing for peripheral \(peripheralID)", + category: SecureLogger.session, level: .warning) + return + } + + // Direct write if connected + let writeType: CBCharacteristicWriteType = data.count > 512 ? .withResponse : .withoutResponse + peripheral.writeValue(data, for: characteristic, type: writeType) + + // Update activity tracking + updatePeripheralActivity(peripheralID) } private func queueWrite(data: Data, peripheralID: String, peerID: String?) { @@ -263,10 +272,17 @@ class BluetoothMeshService: NSObject { // Process queued writes with small delay between them for (index, queuedWrite) in queue.enumerated() { DispatchQueue.main.asyncAfter(deadline: .now() + Double(index) * 0.01) { [weak self] in - guard peripheral.state == .connected else { return } + guard let self = self, + peripheral.state == .connected, + characteristic.properties.contains(.write) || characteristic.properties.contains(.writeWithoutResponse) else { + return + } let writeType: CBCharacteristicWriteType = queuedWrite.data.count > 512 ? .withResponse : .withoutResponse peripheral.writeValue(queuedWrite.data, for: characteristic, type: writeType) + + // Update activity tracking + self.updatePeripheralActivity(peripheralID) } } } diff --git a/bitchat/ViewModels/ChatViewModel.swift b/bitchat/ViewModels/ChatViewModel.swift index 9d91caf2..0afbc21c 100644 --- a/bitchat/ViewModels/ChatViewModel.swift +++ b/bitchat/ViewModels/ChatViewModel.swift @@ -1953,9 +1953,11 @@ extension ChatViewModel: BitchatDelegate { } } } else { - // System message - always add - messages.append(finalMessage) - messages.sort { $0.timestamp < $1.timestamp } + // System message - check for empty content before adding + if !finalMessage.content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + messages.append(finalMessage) + messages.sort { $0.timestamp < $1.timestamp } + } } } @@ -2067,9 +2069,12 @@ extension ChatViewModel: BitchatDelegate { // Resolve nickname using helper let displayName = resolveNickname(for: peerID) + // Ensure we have a valid display name + let finalDisplayName = displayName.isEmpty ? "peer" : displayName + let systemMessage = BitchatMessage( sender: "system", - content: "\(displayName) connected", + content: "\(finalDisplayName) connected", timestamp: Date(), isRelay: false, originalSender: nil @@ -2098,9 +2103,12 @@ extension ChatViewModel: BitchatDelegate { // Resolve nickname using helper let displayName = resolveNickname(for: peerID) + // Ensure we have a valid display name + let finalDisplayName = displayName.isEmpty ? "peer" : displayName + let systemMessage = BitchatMessage( sender: "system", - content: "\(displayName) disconnected", + content: "\(finalDisplayName) disconnected", timestamp: Date(), isRelay: false, originalSender: nil