mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 03:45:20 +00:00
Trim whitespace from nicknames to prevent display issues
- Added didSet observer to nickname property to trim on every change - Trim nickname when loading from UserDefaults - Update validateAndSaveNickname to properly trim - Trim received nicknames in announce packets - Add custom init/decoder for NoiseIdentityAnnouncement to ensure trimming - Trim nicknames when decoding from binary data
This commit is contained in:
@@ -654,12 +654,27 @@ struct NoiseIdentityAnnouncement: Codable {
|
|||||||
self.peerID = peerID
|
self.peerID = peerID
|
||||||
self.publicKey = publicKey
|
self.publicKey = publicKey
|
||||||
self.signingPublicKey = signingPublicKey
|
self.signingPublicKey = signingPublicKey
|
||||||
self.nickname = nickname
|
// Trim whitespace from nickname
|
||||||
|
self.nickname = nickname.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
self.timestamp = timestamp
|
self.timestamp = timestamp
|
||||||
self.previousPeerID = previousPeerID
|
self.previousPeerID = previousPeerID
|
||||||
self.signature = signature
|
self.signature = signature
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom decoder to ensure nickname is trimmed
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
self.peerID = try container.decode(String.self, forKey: .peerID)
|
||||||
|
self.publicKey = try container.decode(Data.self, forKey: .publicKey)
|
||||||
|
self.signingPublicKey = try container.decode(Data.self, forKey: .signingPublicKey)
|
||||||
|
// Trim whitespace from decoded nickname
|
||||||
|
let rawNickname = try container.decode(String.self, forKey: .nickname)
|
||||||
|
self.nickname = rawNickname.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
self.timestamp = try container.decode(Date.self, forKey: .timestamp)
|
||||||
|
self.previousPeerID = try container.decodeIfPresent(String.self, forKey: .previousPeerID)
|
||||||
|
self.signature = try container.decode(Data.self, forKey: .signature)
|
||||||
|
}
|
||||||
|
|
||||||
func encode() -> Data? {
|
func encode() -> Data? {
|
||||||
return try? JSONEncoder().encode(self)
|
return try? JSONEncoder().encode(self)
|
||||||
}
|
}
|
||||||
@@ -738,9 +753,12 @@ struct NoiseIdentityAnnouncement: Codable {
|
|||||||
|
|
||||||
guard let publicKey = dataCopy.readData(at: &offset),
|
guard let publicKey = dataCopy.readData(at: &offset),
|
||||||
let signingPublicKey = dataCopy.readData(at: &offset),
|
let signingPublicKey = dataCopy.readData(at: &offset),
|
||||||
let nickname = dataCopy.readString(at: &offset),
|
let rawNickname = dataCopy.readString(at: &offset),
|
||||||
let timestamp = dataCopy.readDate(at: &offset) else { return nil }
|
let timestamp = dataCopy.readDate(at: &offset) else { return nil }
|
||||||
|
|
||||||
|
// Trim whitespace from nickname
|
||||||
|
let nickname = rawNickname.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
|
||||||
var previousPeerID: String? = nil
|
var previousPeerID: String? = nil
|
||||||
if hasPreviousPeerID {
|
if hasPreviousPeerID {
|
||||||
// Read previousPeerID using safe method
|
// Read previousPeerID using safe method
|
||||||
|
|||||||
@@ -2592,7 +2592,9 @@ class BluetoothMeshService: NSObject {
|
|||||||
// Note: 0x02 was legacy keyExchange - removed
|
// Note: 0x02 was legacy keyExchange - removed
|
||||||
|
|
||||||
case .announce:
|
case .announce:
|
||||||
if let nickname = String(data: packet.payload, encoding: .utf8) {
|
if let rawNickname = String(data: packet.payload, encoding: .utf8) {
|
||||||
|
// Trim whitespace from received nickname
|
||||||
|
let nickname = rawNickname.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
let senderID = packet.senderID.hexEncodedString()
|
let senderID = packet.senderID.hexEncodedString()
|
||||||
|
|
||||||
SecureLogger.log("handleReceivedPacket: Received announce from \(senderID), peripheral is \(peripheral != nil ? "present" : "nil")", category: SecureLogger.session, level: .debug)
|
SecureLogger.log("handleReceivedPacket: Received announce from \(senderID), peripheral is \(peripheral != nil ? "present" : "nil")", category: SecureLogger.session, level: .debug)
|
||||||
|
|||||||
@@ -25,7 +25,15 @@ class ChatViewModel: ObservableObject {
|
|||||||
private var pendingPrivateMessages: [String: [BitchatMessage]] = [:] // peerID -> messages
|
private var pendingPrivateMessages: [String: [BitchatMessage]] = [:] // peerID -> messages
|
||||||
private var messageBatchTimer: Timer?
|
private var messageBatchTimer: Timer?
|
||||||
private let messageBatchInterval: TimeInterval = 0.1 // 100ms batching window
|
private let messageBatchInterval: TimeInterval = 0.1 // 100ms batching window
|
||||||
@Published var nickname: String = ""
|
@Published var nickname: String = "" {
|
||||||
|
didSet {
|
||||||
|
// Trim whitespace whenever nickname is set
|
||||||
|
let trimmed = nickname.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
if trimmed != nickname {
|
||||||
|
nickname = trimmed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@Published var isConnected = false
|
@Published var isConnected = false
|
||||||
@Published var privateChats: [String: [BitchatMessage]] = [:] // peerID -> messages
|
@Published var privateChats: [String: [BitchatMessage]] = [:] // peerID -> messages
|
||||||
@Published var selectedPrivateChatPeer: String? = nil
|
@Published var selectedPrivateChatPeer: String? = nil
|
||||||
@@ -176,7 +184,8 @@ class ChatViewModel: ObservableObject {
|
|||||||
|
|
||||||
private func loadNickname() {
|
private func loadNickname() {
|
||||||
if let savedNickname = userDefaults.string(forKey: nicknameKey) {
|
if let savedNickname = userDefaults.string(forKey: nicknameKey) {
|
||||||
nickname = savedNickname
|
// Trim whitespace when loading
|
||||||
|
nickname = savedNickname.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
} else {
|
} else {
|
||||||
nickname = "anon\(Int.random(in: 1000...9999))"
|
nickname = "anon\(Int.random(in: 1000...9999))"
|
||||||
saveNickname()
|
saveNickname()
|
||||||
@@ -192,9 +201,14 @@ class ChatViewModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func validateAndSaveNickname() {
|
func validateAndSaveNickname() {
|
||||||
// Check if nickname is empty or just whitespace
|
// Trim whitespace from nickname
|
||||||
if nickname.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
let trimmed = nickname.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
|
||||||
|
// Check if nickname is empty after trimming
|
||||||
|
if trimmed.isEmpty {
|
||||||
nickname = "anon\(Int.random(in: 1000...9999))"
|
nickname = "anon\(Int.random(in: 1000...9999))"
|
||||||
|
} else {
|
||||||
|
nickname = trimmed
|
||||||
}
|
}
|
||||||
saveNickname()
|
saveNickname()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user