diff --git a/bitchat/Protocols/BinaryProtocol.swift b/bitchat/Protocols/BinaryProtocol.swift index 390ec6ef..6bd21b3d 100644 --- a/bitchat/Protocols/BinaryProtocol.swift +++ b/bitchat/Protocols/BinaryProtocol.swift @@ -168,7 +168,7 @@ struct BinaryProtocol { // Payload length (2 bytes, big-endian) - includes original size if compressed let payloadDataSize = payload.count + (isCompressed ? 2 : 0) - let payloadLength = UInt16(payloadDataSize) + let payloadLength = UInt32(payloadDataSize) data.append(UInt8((payloadLength >> 8) & 0xFF)) diff --git a/bitchat/Services/BLEService.swift b/bitchat/Services/BLEService.swift index 04f2093f..65b0238d 100644 --- a/bitchat/Services/BLEService.swift +++ b/bitchat/Services/BLEService.swift @@ -1582,6 +1582,11 @@ final class BLEService: NSObject { SecureLogger.error("❌ Failed to decode file TLV from \(peerID)", category: .session) return } + // Determine if this is a true direct message; Android may use 0xFF..FF to denote broadcast + let isBroadcastRecipient: Bool = { + guard let rid = packet.recipientID else { return true } + return rid == Data(repeating: 0xFF, count: 8) + }() // Persist to app files in type-specific folder let isAudio = file.mimeType.lowercased().hasPrefix("audio/") let subfolder = isAudio ? "voicenotes/incoming" : "images/incoming" @@ -1606,7 +1611,7 @@ final class BLEService: NSObject { timestamp: ts, isRelay: false, originalSender: nil, - isPrivate: packet.recipientID != nil, + isPrivate: (packet.recipientID != nil) && !isBroadcastRecipient, recipientNickname: nil, senderPeerID: peerID, mentions: nil, diff --git a/bitchat/Views/ContentView.swift b/bitchat/Views/ContentView.swift index 653e60bc..9711940a 100644 --- a/bitchat/Views/ContentView.swift +++ b/bitchat/Views/ContentView.swift @@ -905,8 +905,8 @@ struct ContentView: View { .font(.system(size: 22)) .foregroundColor(isRecordingVoice ? .red : (viewModel.selectedPrivateChatPeer != nil ? Color.orange : textColor)) .padding(.trailing, 12) - .gesture( - LongPressGesture(minimumDuration: 0.2) + .highPriorityGesture( + DragGesture(minimumDistance: 0) .onChanged { _ in if !isRecordingVoice { do { @@ -940,14 +940,14 @@ struct ContentView: View { } ) #else - // Non-iOS: keep send button placeholder - Button(action: sendMessage) { - Image(systemName: "arrow.up.circle.fill") - .font(.system(size: 20)) - .foregroundColor(Color.gray) - } - .buttonStyle(.plain) - .padding(.trailing, 12) + // Non-iOS: keep send button placeholder + Button(action: sendMessage) { + Image(systemName: "arrow.up.circle.fill") + .font(.system(size: 20)) + .foregroundColor(Color.gray) + } + .buttonStyle(.plain) + .padding(.trailing, 12) #endif } else { Button(action: sendMessage) {