UI improvements and rename rooms to channels

- Changed system messages from green to grey with consistent 12pt font
- Fixed text wrapping to flow naturally under timestamps
- Changed default nickname to anonXXXX format
- Replaced text with icon representations in status bar
- Added icons to sidebar section headers
- Made autocomplete UI consistent between commands and @mentions
- Added welcome message for new users (3 second delay)
- Changed sidebar header to 'YOUR NETWORK'
- Added command aliases (/join, /msg)
- Implemented /hug and /slap commands with haptic feedback
- Improved command help display with alphabetization
- Renamed 'rooms' to 'channels' throughout entire codebase
This commit is contained in:
jack
2025-07-08 01:42:35 +02:00
parent d3c1b77015
commit 9794f3ebdc
15 changed files with 1548 additions and 1163 deletions
+13 -13
View File
@@ -227,7 +227,7 @@ extension BitchatMessage {
var data = Data()
// Message format:
// - Flags: 1 byte (bit 0: isRelay, bit 1: isPrivate, bit 2: hasOriginalSender, bit 3: hasRecipientNickname, bit 4: hasSenderPeerID, bit 5: hasMentions, bit 6: hasRoom, bit 7: isEncrypted)
// - Flags: 1 byte (bit 0: isRelay, bit 1: isPrivate, bit 2: hasOriginalSender, bit 3: hasRecipientNickname, bit 4: hasSenderPeerID, bit 5: hasMentions, bit 6: hasChannel, bit 7: isEncrypted)
// - Timestamp: 8 bytes (seconds since epoch)
// - ID length: 1 byte
// - ID: variable
@@ -240,7 +240,7 @@ extension BitchatMessage {
// - Recipient nickname length + data
// - Sender peer ID length + data
// - Mentions array
// - Room hashtag
// - Channel hashtag
var flags: UInt8 = 0
if isRelay { flags |= 0x01 }
@@ -249,7 +249,7 @@ extension BitchatMessage {
if recipientNickname != nil { flags |= 0x08 }
if senderPeerID != nil { flags |= 0x10 }
if mentions != nil && !mentions!.isEmpty { flags |= 0x20 }
if room != nil { flags |= 0x40 }
if channel != nil { flags |= 0x40 }
if isEncrypted { flags |= 0x80 }
data.append(flags)
@@ -323,10 +323,10 @@ extension BitchatMessage {
}
}
// Room hashtag
if let room = room, let roomData = room.data(using: .utf8) {
data.append(UInt8(min(roomData.count, 255)))
data.append(roomData.prefix(255))
// Channel hashtag
if let channel = channel, let channelData = channel.data(using: .utf8) {
data.append(UInt8(min(channelData.count, 255)))
data.append(channelData.prefix(255))
}
return data
@@ -354,7 +354,7 @@ extension BitchatMessage {
let hasRecipientNickname = (flags & 0x08) != 0
let hasSenderPeerID = (flags & 0x10) != 0
let hasMentions = (flags & 0x20) != 0
let hasRoom = (flags & 0x40) != 0
let hasChannel = (flags & 0x40) != 0
let isEncrypted = (flags & 0x80) != 0
// Timestamp
@@ -465,12 +465,12 @@ extension BitchatMessage {
}
}
// Room
var room: String? = nil
if hasRoom && offset < dataCopy.count {
// Channel
var channel: String? = nil
if hasChannel && offset < dataCopy.count {
let length = Int(dataCopy[offset]); offset += 1
if offset + length <= dataCopy.count {
room = String(data: dataCopy[offset..<offset+length], encoding: .utf8)
channel = String(data: dataCopy[offset..<offset+length], encoding: .utf8)
offset += length
}
}
@@ -486,7 +486,7 @@ extension BitchatMessage {
recipientNickname: recipientNickname,
senderPeerID: senderPeerID,
mentions: mentions,
room: room,
channel: channel,
encryptedContent: encryptedContent,
isEncrypted: isEncrypted
)
+13 -13
View File
@@ -72,8 +72,8 @@ enum MessageType: UInt8 {
case fragmentStart = 0x05
case fragmentContinue = 0x06
case fragmentEnd = 0x07
case roomAnnounce = 0x08 // Announce password-protected room status
case roomRetention = 0x09 // Announce room retention status
case channelAnnounce = 0x08 // Announce password-protected channel status
case channelRetention = 0x09 // Announce channel retention status
case deliveryAck = 0x0A // Acknowledge message received
case deliveryStatusRequest = 0x0B // Request delivery status update
case readReceipt = 0x0C // Message has been read/viewed
@@ -220,12 +220,12 @@ struct BitchatMessage: Codable, Equatable {
let recipientNickname: String?
let senderPeerID: String?
let mentions: [String]? // Array of mentioned nicknames
let room: String? // Room hashtag (e.g., "#general")
let channel: String? // Channel hashtag (e.g., "#general")
let encryptedContent: Data? // For password-protected rooms
let isEncrypted: Bool // Flag to indicate if content is encrypted
var deliveryStatus: DeliveryStatus? // Delivery tracking
init(id: String? = nil, sender: String, content: String, timestamp: Date, isRelay: Bool, originalSender: String? = nil, isPrivate: Bool = false, recipientNickname: String? = nil, senderPeerID: String? = nil, mentions: [String]? = nil, room: String? = nil, encryptedContent: Data? = nil, isEncrypted: Bool = false, deliveryStatus: DeliveryStatus? = nil) {
init(id: String? = nil, sender: String, content: String, timestamp: Date, isRelay: Bool, originalSender: String? = nil, isPrivate: Bool = false, recipientNickname: String? = nil, senderPeerID: String? = nil, mentions: [String]? = nil, channel: String? = nil, encryptedContent: Data? = nil, isEncrypted: Bool = false, deliveryStatus: DeliveryStatus? = nil) {
self.id = id ?? UUID().uuidString
self.sender = sender
self.content = content
@@ -236,7 +236,7 @@ struct BitchatMessage: Codable, Equatable {
self.recipientNickname = recipientNickname
self.senderPeerID = senderPeerID
self.mentions = mentions
self.room = room
self.channel = channel
self.encryptedContent = encryptedContent
self.isEncrypted = isEncrypted
self.deliveryStatus = deliveryStatus ?? (isPrivate ? .sending : nil)
@@ -248,10 +248,10 @@ protocol BitchatDelegate: AnyObject {
func didConnectToPeer(_ peerID: String)
func didDisconnectFromPeer(_ peerID: String)
func didUpdatePeerList(_ peers: [String])
func didReceiveRoomLeave(_ room: String, from peerID: String)
func didReceivePasswordProtectedRoomAnnouncement(_ room: String, isProtected: Bool, creatorID: String?, keyCommitment: String?)
func didReceiveRoomRetentionAnnouncement(_ room: String, enabled: Bool, creatorID: String?)
func decryptRoomMessage(_ encryptedContent: Data, room: String) -> String?
func didReceiveChannelLeave(_ channel: String, from peerID: String)
func didReceivePasswordProtectedChannelAnnouncement(_ channel: String, isProtected: Bool, creatorID: String?, keyCommitment: String?)
func didReceiveChannelRetentionAnnouncement(_ channel: String, enabled: Bool, creatorID: String?)
func decryptChannelMessage(_ encryptedContent: Data, channel: String) -> String?
// Optional method to check if a fingerprint belongs to a favorite peer
func isFavorite(fingerprint: String) -> Bool
@@ -268,19 +268,19 @@ extension BitchatDelegate {
return false
}
func didReceiveRoomLeave(_ room: String, from peerID: String) {
func didReceiveChannelLeave(_ channel: String, from peerID: String) {
// Default empty implementation
}
func didReceivePasswordProtectedRoomAnnouncement(_ room: String, isProtected: Bool, creatorID: String?, keyCommitment: String?) {
func didReceivePasswordProtectedChannelAnnouncement(_ channel: String, isProtected: Bool, creatorID: String?, keyCommitment: String?) {
// Default empty implementation
}
func didReceiveRoomRetentionAnnouncement(_ room: String, enabled: Bool, creatorID: String?) {
func didReceiveChannelRetentionAnnouncement(_ channel: String, enabled: Bool, creatorID: String?) {
// Default empty implementation
}
func decryptRoomMessage(_ encryptedContent: Data, room: String) -> String? {
func decryptChannelMessage(_ encryptedContent: Data, channel: String) -> String? {
// Default returns nil (unable to decrypt)
return nil
}