- Added delay to ensure messages are loaded before checking
- Fixed logic to check if message is FROM the other person (not TO them)
- Added onAppear handler to send read receipts when view loads
- Added detailed logging to debug the flow
- Now correctly identifies received messages that need read receipts
- Changed back to bold blue double checkmarks for read status
- Send read receipts for both 'sent' and 'delivered' status messages
- Added onChange handler to send read receipts whenever switching to a private chat
- Made markPrivateMessagesAsRead public so it can be called from views
- This ensures read receipts are sent when opening a chat from notifications or any other way
- Read receipts were being sent to the current ephemeral peer ID instead of the message's senderPeerID
- This caused read receipts to be lost when peer IDs changed between sessions
- Now using message.senderPeerID consistently for all read receipt sending
- Added detailed logging to track which peer ID receives the read receipt
- Add logging to track what delivery status is shown in UI
- Add logging when green/blue checkmarks appear
- Force complete dictionary reassignment to trigger SwiftUI updates
- Add diagnostics to understand why blue checkmarks aren't showing
- Use message ID instead of index for ForEach to trigger proper updates
- Add explicit objectWillChange.send() when updating delivery status
- Fix scroll-to-bottom logic to use message IDs
- This should make blue checkmarks appear when read receipts are received
- Add detailed logging to track read receipt generation
- Handle messages that don't have delivery status (older messages)
- Send read receipts for all unread messages when opening chat
- Track message IDs through the delivery process
- Log ACK generation and processing
- Log status updates in ChatViewModel
- Log read receipt generation and sending
- Added ReadReceipt structure and .readReceipt message type
- Added .read delivery status with blue checkmarks in UI
- Send read receipts when viewing a private chat
- Send read receipts immediately for new messages if chat is open
- Update message status from delivered to read when receipt received
- Pass message ID from ChatViewModel to BluetoothMeshService
- Preserve original message ID when creating ACK messages
- Move delivery tracking to ChatViewModel for consistent IDs
- Update project.yml to match current project structure
- Delete LoggingService.swift
- Remove all bitchatLog() function calls throughout the codebase
- Update Xcode project to remove LoggingService references
- Clean up debug logging statements from all services and views
- Implement room-wide message retention controlled by room owners
- Change username format from <name> to <@name> throughout UI
- Fix text alignment in chat messages (consistent font sizes)
- Add comprehensive technical whitepaper with Mermaid diagrams
- Update README with current features and commands
- Add retention status indicators and announcements
- Update command help text to use short versions (/j, /m)
- Load saved messages for saved rooms during app initialization
- Messages are now restored when reopening the app
- Rooms marked as saved will show their message history immediately
- Add bookmark icon button in room header to toggle save status
- Use bookmark.fill when room is saved, bookmark when not
- Button shows yellow when saved, default color when not
- Integrate with existing /save command functionality
- Add savedRooms published property for reactive UI updates
- Replace /list with /rooms showing all discovered rooms with join status
- Remove /discover command (merged into /rooms)
- Rename /favorite to /save for clarity
- Make room-specific commands (/transfer, /pass, /save) only appear in room context
- Remove voice notes from app info (feature doesn't exist)
- Remove Commands line from app info screen
- Show checkmark (✓) for joined rooms in /rooms output
- Add KeychainManager for secure password storage
- Implement MessageRetentionService for encrypted local storage of favorite room messages
- Add MessageRetryService for automatic retry of failed messages
- Add /favorite command to toggle room retention
- Add /discover command to find active rooms
- Fix all force unwrapped optionals in BluetoothMeshService
- Update app info screen with new features
- Integrate all services with proper cleanup on panic
- Add key commitment scheme for immediate password verification
- Implement ownership transfer with /transfer command
- Add password change functionality with /pass command
- Include room metadata in initialization messages
- Remove /help command and rename /changepass to /pass
- Make room names tappable to show sidebar
- Remove spaces in person/room counter display
- Update UI to show lock icons and orange colors for protected rooms
- Fix password verification to work with empty rooms
- Add comprehensive tests for new functionality
This update significantly improves the security and usability of
password-protected rooms by allowing immediate verification without
waiting for encrypted messages.
- Add lock icon to room header for password management
- Change "leave" to "leave room" for clarity
- Fix bug where non-members appeared in room member list
- Only process room messages if user has joined the room
- Initialize room data structures on app launch
- Prevent auto-join when just mentioning a room
- Room creators can set/remove passwords for their rooms
- Passwords are used to derive encryption keys via PBKDF2
- All messages in password-protected rooms are encrypted with AES-GCM
- Room protection status is announced to all peers
- Password and room data persists across app launches
- Visual lock indicators for password-protected rooms
- Password prompts when joining protected rooms
- Only room creators can modify password settings
- Encrypted messages show placeholder text if password is unknown
- Send leave notifications when users exit rooms
- Update room member lists when peers leave rooms
- Change current user icon from dot to person.fill
- Handle room-specific leave messages via protocol
- Maintain backwards compatibility for general peer disconnection
- Add conditional compilation to LoggingService
- macOS continues to write logs to Documents/Logs
- iOS uses /dev/null to prevent disk writes
- Remove room auto-join on mention (only join when sending to room)
- Create LoggingService that writes to Documents/Logs directory
- Log to both console and file with timestamps
- Replace debug print statements with bitchatLog()
- Add log file location display in AppInfoView
- Enable opening log file in Finder on macOS
- Track room member operations and view state
- Persist logs for debugging room member display issues
- Add blue hashtag icon in main header when there are unread room messages
- Remove member count from room title for cleaner look
- Add debug logging to diagnose room member list issue
- Fix room field not being copied when creating messageWithPeerID in BluetoothMeshService
- This was causing all room messages to appear in main chat
- Fix room member tracking by ensuring senderPeerID is included
- Change room color from orange to blue to differentiate from private messages
- Clean up room members when peers disconnect to fix member count
- Add debug logging to track room field through message flow
- Log when sending messages with room context
- Log when receiving room vs main chat messages
- Helps diagnose if room field is being properly transmitted
- Fix header to show "x people / y rooms" count
- Add proper leave room functionality that cleans up data
- Track and display room members in sidebar
- Show "IN #ROOM" header when viewing a room
- Only show peers who have sent messages to current room
- Add leave button in room header alongside main button
- Ensure senderPeerID is set for room member tracking
- Add room field to BitchatMessage structure
- Update BinaryProtocol to encode/decode room information
- Create room management in ChatViewModel (join/leave/switch rooms)
- Add BluetoothMeshService support for room messages
- Implement rooms UI in sidebar with unread counts
- Create clickable hashtags in messages to join rooms
- Add room persistence across app restarts
- Filter message display by current room selection
- Added public domain headers to all test files
- Updated Info.plist with required App Store keys:
- ITSAppUsesNonExemptEncryption = NO
- LSApplicationCategoryType = Social Networking
- UIRequiresFullScreen = YES
- Created proper Assets.xcassets structure
- Configured AppIcon.appiconset with all icon references
- Removed last TODO comment
- Created comprehensive App Store submission checklist
- Updated project.yml to include Assets.xcassets
The app is now ready for App Store submission. All debug code has been removed,
icons are configured, and privacy/security compliance is documented.
- Added LICENSE file with Unlicense (public domain dedication)
- Added public domain headers to all main source files
- Updated README to mention public domain status
- All code is free and unencumbered, released into the public domain
Anyone is free to use this code for any purpose without restriction.
- Add thread safety lock for activePeers Set access
- Force UI update when peer list changes with objectWillChange
- Add debug logging to track peer additions/removals
- This fixes the 'alone :/' display when peers are actually connected
- Add tracking to prevent sending cached messages multiple times to the same peer
- Only cache messages for offline favorites, not online ones
- Sort messages by timestamp when adding to ensure proper chronological order
- Clean up tracking sets when peers disconnect to allow re-sending on reconnect
- Cache our own messages when sending to offline favorites
- Update favorite online notification text to "wanna get in there?"
- Remove 'Is Connectable' and 'Manufacturer Data' keys from BLE ads
- Only use allowed keys: service UUIDs and local name
- Prevent duplicate fingerprint registrations in favorites
- Comment out unused fragment type string variable
The warnings about advertisement keys should no longer appear.
- Change message cache timeout from 5 minutes to 12 hours for regular peers
- Add indefinite message storage for favorite peers with 1000 message limit
- Cache relayed messages for offline favorites
- Automatically send cached messages when favorites come online
- Use public key fingerprints to identify favorites persistently
- Add isFavorite delegate method to check favorites by fingerprint
- Only show peers in UI who have announced (have nicknames)
- Filter out peers without nicknames from getAllConnectedPeerIDs()
- Send announces proactively when app starts, not just on connection
- Send announces immediately when nickname changes via saveNickname()
- Send announces when Bluetooth services become available
- Send announces multiple times (0.5s, 1s, 2s) for reliability
- Add sendBroadcastAnnounce() method for proactive announcing
This ensures peers always see proper nicknames, never 'person-xxx'
- Make sender names tappable in messages to start private chat
- Add star button in private chat header to favorite/unfavorite peers
- Refactor message view to separate timestamp, sender, and content
- Add helper methods for formatting different parts of messages
- Own sender name is not tappable (only other users)
- Voice notes remain tappable to play/pause
- Add macOS support to NotificationService
- Use NSApplication.shared.isActive to check app state on macOS
- Move notification logic outside of iOS-only block in ChatViewModel
- Notifications now work for both mentions and private messages on macOS
- Keep haptic feedback iOS-only as it's not available on macOS
- Add favorites functionality for peers with persistent storage
- Star icon to toggle favorites in sidebar
- Favorites appear at top of peer list
- Storage persists across app launches using peer ID
- Add local notifications for mentions and private messages
- Notifications appear when app is in background
- Separate notification types for mentions vs private messages
- Request notification permissions on app launch
- Fix sidebar header alignment to match main toolbar (44pt)
- Add background color to sidebar header for visual consistency
- Improve voice note fragment transmission
- Send fragments in batches of 5 with delays to prevent congestion
- Better logging to debug fragment transmission issues
- Reduce delay between fragments from 50ms to batch-based timing
- Fix other UI issues
- Ensure mic recording ripples originate from mic button
- Update sidebar to swipe from right edge smoothly
- Added voice note support to BitchatMessage with audio data and duration
- Updated binary protocol to encode/decode voice notes (flag 0x40)
- Created AudioRecordingService for recording up to 10s voice clips
- Created AudioPlaybackService for playing voice notes
- Added microphone permission to Info.plist and project.yml
- Implemented push-to-talk UI with mic button in ContentView
- Voice notes use AAC compression at 16kHz/32kbps for small file sizes
- Added play/pause buttons for voice notes in message list
- Voice notes display as '🎤 Voice note (X.Xs)' in chat
- Platform-specific audio session handling for iOS/macOS
- Added autocomplete state tracking in ChatViewModel
- Implemented updateAutocomplete() to parse @ mentions and show suggestions
- Added completeNickname() to handle nickname completion
- Created autocomplete UI overlay above input field
- Shows list of matching nicknames when typing @
- Highlights selected suggestion
- Clicking suggestion completes the mention
- Move peer dropdown next to bitchat title
- Add immediate peer announcement on connection
- Fix iOS menu chevron visibility with platform-specific styling
- Force UI updates for join/leave messages
- Add peers to active list immediately on connection
- Remove all announcement delays for instant name resolution
- Remove self-notification when sending private messages
- Clear unread indicator when viewing active chat
- Properly update UI when private messages are sent/received
- Prevent duplicate messages in chat history
- Use objectWillChange to force SwiftUI updates
- Fix header bar height to prevent bouncing when switching views
- Add in-app notification banner for incoming private messages
- Show orange notification that slides down from top
- Tap notification to jump directly to private chat
- Use medium haptic feedback for private messages (iOS)
- Auto-dismiss notifications after 3 seconds
- Implement 1:1 private messaging with IRC-style interface
- Add private message type to protocol with routing through mesh
- Show orange notification dot for unread private messages
- Fix peer list not showing connected peers
- Update peer nicknames immediately on first message
- Auto-exit private chat when peer disconnects
- Improve join/leave channel messages visibility
- Make send button larger for better UX
- Center and color private chat header in orange