- Increase max TTL from 5 to 7 hops for long-distance delivery
- Keep TTL higher in larger networks (6 for small, 5 for medium, 4 for large)
- Increase relay probabilities (85% at 30 users, 70% at 50 users, min 40%)
- Smart relay: always relay if TTL >= 4 or few peers connected
- Boost relay probability by 15% for private messages (they're important)
- Clean up excessive logging while keeping duplicate detection warnings
- Ensure messages can travel 300m+ by maintaining higher relay rates
- Track exact message content and timestamps to detect duplicates
- Log when duplicate messages are received within 5 seconds
- Delay sending cached messages by 0.5s to ensure connection is established
- Log all incoming message IDs and types for debugging
- Add warning when same message is received multiple times
- 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?"
- Filter cached messages by recipient (only send to intended peer)
- Remove messages from cache after successful delivery
- Stop caching broadcast messages (they're not targeted)
- Add safety check to never cache broadcasts
- Messages are now delivered exactly once per recipient
The store-and-forward system now correctly:
1. Stores only private messages for specific recipients
2. Delivers only to the intended recipient when they connect
3. Removes messages after delivery to prevent duplicates
4. Preserves original timestamps throughout the process
- Check characteristic write properties before all writes
- Add proper error handling for specific BLE error codes
- Rediscover services on invalid handle errors
- Increase delay between key exchange and announce
- Reduce connection flooding by spacing out initial messages
The ATT Error 242 was caused by writing too quickly after
connection establishment. Adding delays gives the connection
time to stabilize.
- Add peripheral state checks before all write operations
- Fix 'can only accept commands while connected' errors
- Check characteristic write properties to avoid ATT errors
- Preserve original timestamps in store-and-forward messages
- Only log crypto errors once per peer to reduce noise
- Store-and-forward now correctly maintains message ordering
The timestamp preservation ensures messages appear in the correct
chronological order even when delivered later via store-and-forward.
- Replace problematic messageQueue.sync with NSLock for peerNicknames
- Prevents deadlock when accessing from within messageQueue
- Add thread-safe access to all peerNicknames read/write operations
- Fixes EXC_BREAKPOINT crash from recursive queue access
The previous approach using messageQueue.sync caused deadlock when
getAllConnectedPeerIDs was called from within the messageQueue itself.
- Fix NSInvalidArgumentException crash by adding thread-safe access to peerNicknames
- Fix 'can only accept commands while connected' by checking peripheral state
- Add safety checks for characteristic write properties
- Clean up disconnected peripherals from tracking
- Prevent type confusion in getAllConnectedPeerIDs
These fixes address the crash when accessing peerNicknames dictionary
which could be corrupted by concurrent access from multiple threads.
- Add default RSSI value (-60) for connected peers without RSSI data
- Transfer RSSI from peripheral discovery to peer after key exchange
- Fixes red dot showing for nearby devices that can't report RSSI
- Centrals (phones acting as servers) now show green by default
- 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.
- Probabilistic flooding: Relay probability adapts to network size (30-100%)
- Bloom filter duplicate detection: O(1) lookups with 4096-bit filter
- Connection pooling: Reuse connections with exponential backoff
- Adaptive TTL: Reduces hops based on network size (2-5)
- Message aggregation framework: 100ms batching window
- BLE advertisements: Include network size/battery hints
These optimizations improve capacity from ~20-30 to ~50-100 users while
maintaining privacy (no routing tables) and simplicity. The system now
adapts automatically to network conditions without configuration.
Trade-offs: Slightly higher CPU for bloom filter, probabilistic relay
may miss edge cases, but overall much better scaling behavior.
- Single tap logo shows comprehensive app info and features
- Triple tap logo triggers panic mode (instant data wipe)
- Implement adaptive Bluetooth scanning based on battery level
- Remove hardcoded development team ID for security
- Fix store-and-forward description (12h for all, indefinite for favorites)
- Add technical debt remediation plan
- Fix macOS compatibility issues with navigation
- 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'
- Fix fragment processing bug where fragments were logged but not handled
- Remove redundant 'Processing fragment directly' check that prevented handling
- Make macOS sidebar narrower (300px max or 40% of width, whichever is smaller)
- iOS sidebar remains at 70% width for better touch interaction
- 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 recipient ID to private message packets for proper routing
- Private messages now correctly include recipientID field
- Add comprehensive debug logging for private message flow
- Messages are now properly delivered to intended recipients
- Add asterisk after bitchat text in header
- Fix mic button gesture handling by removing Button wrapper
- Use direct gesture on ZStack for more reliable touch detection
- Add debug logging for recording start/stop
- Fix notification delivery on iOS
- Change from checking .background to checking != .active
- Notifications now work when app is inactive or background
- Add NSUserNotificationsUsageDescription to Info.plist
- Improve voice note fragment transmission
- Reduce fragment size from 400 to 200 bytes for better reliability
- Simplify fragment timing from batch-based to linear 100ms delays
- Lower packet size threshold from 512 to 400 bytes for fragmentation
- Add peripheral connection state checking before writes
- Better error logging throughout transmission pipeline
- Add comprehensive debug logging for troubleshooting
- Log audio file size and duration
- Log peripheral connection states during broadcast
- Log fragment send progress with timing info
- 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
- Implemented compact binary encoding for packets and messages
- Reduced packet size significantly (13-byte fixed header + variable payload)
- Optimized for BLE's limited MTU with smaller message sizes
- Added BinaryProtocol.swift with encode/decode functions
- Updated all message types to use binary serialization
- Maintains all existing functionality with better performance
- Remove frame constraint on peer status view
- Add fixedSize() to menu label for compact layout
- Reduce internal spacing in menu label from 4 to 2 points
- 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
- Change 'nick:' to 'name:' in the UI
- Replace 'peer/peers' with 'person/people' throughout
- Update 'No peers connected' to 'No people connected'
- Fix menu layout with fixedSize()
- Update debug messages to use 'people' instead of 'peers'
- 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