Commit Graph
841 Commits
Author SHA1 Message Date
jackandGitHub 0a5e4b248f Update README.md 2025-07-31 00:58:57 +02:00
jack b6e6f0f63b Fix unused variable warnings in NostrProtocol.swift
Replace unused variable names with _ to silence compiler warnings:
- ephemeralPubkey calculation (line 40)
- senderPubkey calculation (line 216)
- timestamp formatter strings (lines 452-453, 456-457)
v1.2.0
2025-07-30 23:22:02 +02:00
a97d5c2d5e Implement Nostr NIP-17 for offline messaging and performance optimizations (#358)
* Implement Nostr NIP-17 integration for offline mutual favorite messaging

- Add Nostr relay connectivity and NIP-17 gift-wrapped private messages
- Implement dual transport system: Bluetooth mesh + Nostr relays
- Add favorites persistence with mutual detection and Nostr key exchange
- Support offline messaging for mutual favorites via Nostr relays
- Handle peer identity rotation with automatic favorite key updates
- Fix UI to show all favorites (online and offline) in peer list
- Add proper message routing based on peer availability
- Update peer list icons: 📶 for mesh, 🌐 for Nostr, 🌙 for one-sided
- Fix toolbar display for offline peers in private chat view
- Add network entitlements for macOS and iOS
- Implement automatic noise key updates when peers reconnect

* Implement Nostr NIP-17 for private messaging between mutual favorites

- Add support for NIP-17 gift-wrapped private messages with double encryption
- Enable private messaging via Nostr when mutual favorites are offline
- Fix peer reconnection issues: users now stay in private chat when peer reconnects
- Fix read receipt delivery: send pending receipts when peer comes back online
- Add message ID tracking through Nostr transport for proper delivery acknowledgments
- Update peer noise key mapping when peers reconnect with different IDs
- Check for Nostr messages when app becomes active
- Implement 7-day message retrieval window for better reliability

* Fix private message UI refresh and adjust PEOPLE header spacing

- Fix UI not updating when receiving private messages on mesh
  - Add immediate batch processing for messages in active chat
  - Force UI update when viewing current chat peer
  - Ensure real-time message display without navigation
- Reduce PEOPLE header spacing from 16 to 12 points for tighter UI

* Fix build errors and unused value warnings in Nostr favorites integration

* Implement read receipts via Nostr

- Added sendReadReceipt method to MessageRouter to send receipts via mesh or Nostr
- Added handleReadReceipt to process incoming read receipts from Nostr
- Made ReadReceipt.readerID mutable to allow updates
- Added missing notification names and error cases
- Uncommented and enabled read receipt handling in ChatViewModel
- Read receipts now work seamlessly via both mesh and Nostr transports

* Fix ReadReceipt initialization - use correct constructor

* Implement persistent message deduplication for Nostr

- Added ProcessedMessagesService to track messages across app restarts
- Store processed message IDs and last timestamp in UserDefaults
- Skip already processed messages when receiving from Nostr
- Adjust subscription filter to use smart timestamp (last processed or 24h)
- Prevents duplicate messages when reconnecting to Nostr relays

* Fix peer list UI not updating to Nostr mode on disconnect

- Remove peer from peerNicknames when connection state changes to disconnected
- Ensures UI properly reflects peer disconnection state
- Peer list now correctly shows Nostr mode (🌐) when peer walks out of range

* Update peer count to include Nostr peers and improve UI indicators

- Peer count now shows total peers including those available via Nostr
- Count appears purple when only Nostr peers are connected
- Private message header shows purple globe icon for Nostr transport
- Consistent visual language for Nostr connectivity across the app

* Improve RSSI real-time updates and fix UI flashing

- Reduce RSSI update timer from 10s to 5s and per-peripheral from 5s to 3s
- Add RSSI change detection with 2 dBm threshold for responsive updates
- Always update previous RSSI values to fix gradual change detection bug
- Trigger RSSI read on peer authentication for immediate status
- Fix UI flashing 'nobody around' by removing array clearing on updates
- Add proper cleanup of RSSI tracking on disconnect and peer rotation

* Fix favorite nickname updates and peer list filtering

- Add updateNickname method to FavoritesPersistenceService to update nicknames while preserving favorite status
- Update announce handler to check for existing favorites and update their nicknames
- Remove dead BluetoothMeshService+PublicAPI.swift file
- Move sendFavoriteNotification to main BluetoothMeshService
- Fix peer list to only show connected peers and user's favorites (not peers who favorite the user)
- Remove UI logic for showing peers who favorite us but we don't favorite back

* Remove dead code and fix ghost connections

Phase 1 - Remove abandoned peer ID rotation code:
- Remove previousPeerID property and rotationGracePeriod constant
- Remove grace period logic from isPeerIDOurs()
- Remove previousPeerID handling from announce packets
- Pass nil for previousPeerID in identity announcements

Phase 2 - Fix ghost connections from relayed packets:
- CRITICAL FIX: Only add peers to activePeers if they have a peripheral connection
- Check for peripheral connection before marking peer as active
- Prevents ghost connections when announce packets are relayed
- Log warning when rejecting relayed announce without peripheral

Phase 3 - Begin consolidating redundant peer tracking:
- Create new PeerSession class to unify peer data in one place
- Add helper methods for PeerSession management
- Integrate PeerSession into announce packet handling
- Update authentication state changes to use PeerSession
- Update peripheral mapping and RSSI to sync with PeerSession
- Update disconnect and leave handling to update PeerSession
- Add consolidated getter methods for peer info

This fixes the issue where peers appeared connected without actually having a Bluetooth connection, and begins the migration to a cleaner single-source-of-truth peer tracking system.

* Fix multiple connect messages on peer restart

- Move hasPeripheralConnection check outside sync block to fix scope issue
- Add debug logging to track connect message conditions
- Ensure connect messages only show on first connection or reconnection with peripheral

* Optimize RSSI updates for better battery life

- Add app state tracking to BluetoothMeshService
- Only update RSSI when app is in foreground and peer list is visible
- Add setPeerListVisible method to control RSSI updates
- Remove individual periodic RSSI updates in favor of centralized timer
- Update ContentView to notify mesh service of peer list visibility changes
- Improve battery efficiency by avoiding unnecessary RSSI reads

* Initialize peer list visibility state on view appear

- Ensure RSSI timer state is properly initialized when view loads
- Call setPeerListVisible with initial showSidebar value

* Fix duplicate peers and multiple disconnect messages

- Fixed duplicate peer entries when relay-connected by adding relay-connected peers to connectedNicknames set
- Added deduplication logic for disconnect messages with 2-second window to prevent multiple disconnect notifications for same peer
- Added cleanup for old disconnect notification tracking to prevent memory growth

* Fix peer count indicator color logic

- Show green for any mesh peer (direct Bluetooth or relay connected)
- Show purple only for Nostr-only peers (no mesh connections)
- Show red only when no peers are reachable at all
- Fixed to use meshPeerCount instead of viewModel.isConnected which only checked direct connections

* Fix relay connection issues and peripheral mapping cleanup

- Fixed relay-connected peers being marked as directly connected when receiving identity announce
- Added proper cleanup of temp peripheral mappings when discovering real peer ID
- Fixed disconnect notification deduplication cleanup
- Improved debug logging to show actual connection state (direct/relay/nostr/offline)
- Added debug logging for relay connection detection
- Fixed compiler warning about unused variable

* Fix Unknown peer disconnect notifications and disable faulty relay detection

- Add check to prevent disconnect notifications for Unknown peers that never announced
- Disable relay connection detection until proper relay tracking is implemented
- In a 2-peer network, peers should never show as relay-connected

* Fix RSSI updates and peer visibility after reconnection

- Add updatePeers() call in didUpdatePeerList to refresh RSSI values in UI
- Track version hello times to better detect direct connections
- Allow peers to be marked active if recent version hello received
- Fix thread safety for version hello tracking
- Clean up old version hello times to prevent memory leaks

* Remove RSSI tracking completely and replace with radio icon for mesh connections

* Fix build errors after RSSI removal

- Add missing peripheralID declaration in didDiscover delegate method
- Remove obsolete setPeerListVisible calls from ContentView

* Center private message header elements using ZStack layout

- Replace HStack with ZStack for perfect centering
- Globe/nick/lock cluster now always centered regardless of button sizes
- Back and favorite buttons positioned in overlay HStack

* Fix private chat view showing Unknown when peer reconnects with new ID

- Update FavoritesPersistenceService to notify with both old and new keys
- Handle peer ID changes in ChatViewModel to migrate private chat data
- Update selectedPrivateChatPeer when favorite's noise key changes
- Maintain chat history and unread status across peer ID changes

* Fix read receipts after peer reconnection and replace nos.lol relay

- Updated sendReadReceipt to resolve current peer ID when peers reconnect with new IDs
- Enhanced MessageRouter to check favorites for current noise keys
- Replaced nos.lol relay with relay.snort.social to avoid PoW requirements

* Fix message routing to use Nostr when peers are disconnected

Changed message routing logic to check actual peer connection status using
isPeerConnected() instead of just checking if peer exists in nickname list.
This ensures that offline mutual favorites correctly route messages through
Nostr instead of attempting Bluetooth handshakes.

Also added safety check to prevent starting private chat with ourselves.

* Add debug logging for Nostr timestamp randomization

Added logging to track the random offset being applied to Nostr event
timestamps to debug why messages appear 8-9 minutes in the future.

* Fix Nostr timestamp issue by reducing randomization range

Temporarily reduced the timestamp randomization from +/-15 minutes to +/-1 minute
to address messages appearing 8-9 minutes in the future. Added detailed UTC/local
time logging to help debug the issue.

The random offset should have been evenly distributed but was consistently
showing positive offsets. This change mitigates the issue while we investigate
the root cause.

* Fix message routing for offline favorites and reduce Nostr timestamp randomization

- Fix transport selection to properly detect disconnected peers using isPeerConnected()
- Change from checking peer nicknames to checking actual connection status
- Reduce Nostr timestamp randomization from ±15 minutes to ±1 minute
- Add detailed timestamp logging for debugging

* Improve PM header UI and encryption status display

- Show transport icons (radio/link/globe) in PM header matching peer list
- Always show lock icon if noise session ever established (no handshake icon)
- Change verified icon from shield to checkmark seal
- Use consistent green color (textColor) for PM header and encryption icons

* Update AI_CONTEXT.md with comprehensive Nostr implementation details

- Add Nostr and MessageRouter to architecture diagram
- Document NIP-17 gift wrap implementation
- Explain favorites integration and mutual requirement
- Detail message routing logic and transport selection
- Add security considerations and debugging tips
- Update common tasks with Nostr-specific guidance

* Fix data consistency issues in favorites, chat migration, and bloom filter

- Fix favorites deduplication to use public key instead of nickname
  Prevents losing favorites when multiple peers use same nickname

- Fix private chat migration to use fingerprints instead of nicknames
  Prevents merging unrelated conversations that share nicknames
  Fallback to nickname matching only for legacy data without fingerprints

- Fix bloom filter reset to preserve messages from last 10 minutes
  Prevents duplicate message processing after bloom filter resets
  Keeps processedMessages for 10 minutes while bloom filter resets every 5

* Add mutual favorites internet messaging to app info

* Remove excessive debug/info logging for production readiness

- Removed ~140 debug/info level logs across core services
- Preserved critical logs: errors, warnings, security events, state changes
- Kept logs for: peer join/leave, favorite status, mutual relationships
- Cleaned up verbose logging in: Bluetooth mesh, Nostr, message routing
- Improved performance by reducing log I/O overhead

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Implement performance optimizations and fix build warnings

- Add UI update debouncing (50ms) to prevent excessive SwiftUI refreshes
- Implement memory bounds for processedMessages with LRU eviction
- Add encryption queue cleanup for disconnected peers
- Optimize peer lookups from O(n) to O(1) with indexed dictionary
- Fix multiple compiler warnings (unused variables, missing break statements)
- Optimize peer counting with single-pass reduce operation
- Fix ViewBuilder control flow issue in ContentView
- Fix Dictionary initialization type mismatches with Array wrapper

* Add TTL-based cleanup for Noise handshake sessions

- Add session TTL (5 minutes) and max session limit (50) to NoiseHandshakeCoordinator
- Clean up old established sessions to prevent unbounded memory growth
- Move handshake cleanup timer out of DEBUG conditional for production use
- Run cleanup every 60 seconds in production (vs 30s in debug)
- Clean up crypto state immediately on peer disconnect
- Prevents memory leaks from accumulating Noise sessions

* Pre-compute and store fingerprints in PeerSession for O(1) lookups

- Store fingerprint in PeerSession when peer authenticates
- Update getPeerFingerprint() and getFingerprint() to check PeerSession first
- Replace all noiseService.getPeerFingerprint() calls with optimized version
- Eliminates repeated SHA256 calculations during message processing
- Improves performance for favorite checks and encryption status updates

* Implement exponential backoff for Nostr relay connections

- Add reconnection tracking fields to Relay struct (attempts, timing)
- Replace fixed 5-second delay with exponential backoff (1s → 2s → 4s... max 5min)
- Stop reconnection attempts after 10 failures to prevent infinite retries
- Reset attempt counter on successful connection
- Add utility methods: retryConnection(), getRelayStatuses(), resetAllConnections()
- DNS failures still bypass retry logic as before
- Improves battery life and reduces server load from constant reconnection attempts

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-30 23:14:17 +02:00
Tim JohnsenandGitHub a438c46817 Disable sharing images via extension, not supported at the moment. (#346) 2025-07-29 17:48:50 +02:00
jackandGitHub 41810ad419 Update README.md 2025-07-28 16:49:46 +02:00
jackandGitHub 54fbee786c Update README.md 2025-07-28 16:49:25 +02:00
jackandGitHub e6a5ca4023 Update README.md 2025-07-28 16:48:00 +02:00
jack fe8cb41ff7 Update Xcode project file 2025-07-28 12:18:14 +02:00
4867ddca0d Add comprehensive AI-friendly documentation across core files (#328)
- Created AI_CONTEXT.md as central documentation hub for AI assistants
- Added detailed file-level documentation to all major components
- Documented architecture, design decisions, and security considerations
- Added usage examples and integration guidance
- Improved code discoverability with clear component descriptions

Documentation covers:
- BluetoothMeshService: Core networking and mesh protocol
- BitchatProtocol: Application-layer protocol design
- NoiseProtocol: Cryptographic implementation details
- ChatViewModel: Business logic and state management
- IdentityModels: Three-layer identity architecture
- NoiseEncryptionService: High-level encryption API
- SecureIdentityStateManager: Secure persistence layer
- BinaryProtocol: Low-level wire format

This documentation will significantly improve AI understanding of the codebase structure and enable faster, more accurate assistance with development tasks.

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-07-27 10:18:47 +02:00
e282d077a3 fix iOS app zoom/compat mode issue (issue #236) (#327)
Co-authored-by: kevin <kevin@none>
2025-07-27 08:01:59 +02:00
jackandGitHub 34b2b1eee0 Update README.md 2025-07-26 11:54:39 +02:00
54c7eba8cb Improve code organization and documentation (#325)
* Add MARK headers to improve code organization in major files

* Reorganize peer management functions in BluetoothMeshService

- Removed duplicate getCurrentPeerID(for:) function
- Consolidated peer identity functions in Peer Identity Mapping section
- Moved getPeerFingerprint(), getFingerprint(for:), isPeerIDOurs() to proper location
- Moved getCurrentPeerIDForFingerprint() and getCurrentPeerIDs() from Message Sending section
- Moved notifyPeerIDChange() to Peer Management section

* Consolidate peer management functions in BluetoothMeshService

- Moved getCachedPublicKey() and getCachedSigningKey() from Identity Cache Methods to Peer Connection Management
- Moved getPeerNicknames() and getPeerRSSI() to Peer Connection Management section
- Moved getAllConnectedPeerIDs(), notifyPeerListUpdate(), and cleanupStalePeers() to Peer Connection Management
- Removed duplicate function declarations after consolidation
- Improved code organization by grouping all peer-related functions together

* Consolidate message handling functions in ChatViewModel

- Moved handleHandshakeRequest() from floating location to Message Reception section
- Moved trimMessagesIfNeeded() and trimPrivateChatMessagesIfNeeded() to Message Batching section
- Improved code organization by grouping related message handling functions together
- Removed unnecessary comments from trim functions

* Improve ContentView organization with better documentation

- Added descriptive comments for complex inline computations
- Documented message extraction logic for private vs public chats
- Documented peer data computation and sorting logic
- Improved code readability by explaining complex operations inline
- Note: Attempted to extract complex computations into helper functions, but SwiftUI scope limitations made inline documentation a better approach

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-07-26 00:11:23 +02:00
jackandGitHub 4568951736 Update WHITEPAPER.md 2025-07-25 20:57:19 +02:00
jack 0e78341102 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
2025-07-25 20:29:50 +02:00
jack e57bfad843 Merge branch 'fix/read-receipt-consistency' v1.1 2025-07-25 18:10:10 +02:00
jack 6afef8466a Fix read receipt to use same efficient pattern as delivery ACK
- Modified read receipt to use type marker + binary payload pattern
- Added read receipt type marker handling in noise decryption
- Reduces message size and processing overhead
- Ensures consistency between delivery ACK and read receipt implementations
2025-07-25 18:09:55 +02:00
df83f716d1 Fix lazy handshake behavior and re-enable cover traffic (#323)
* Add encryption export compliance to Info.plist

Set ITSAppUsesNonExemptEncryption to false for TestFlight submission

* Revert "Add encryption export compliance to Info.plist"

This reverts commit 2cfbb1679d.

* fix: prevent spurious handshake requests from rotated peers and cover traffic

- Clean up connection states and pending messages during peer ID rotation
- Filter out rotated peer IDs in keep-alive timer to prevent validation attempts
- Add session check before sending cover traffic dummy messages
- Disable cover traffic by default (was sending without user knowledge)
- Only send screenshot notifications when session exists
- Add logging to track automatic message triggers
- Fix compilation errors (SecureLogger.privacy -> security)

* Fix lazy handshake behavior and re-enable cover traffic

- Re-enable cover traffic for privacy protection
- Start handshake immediately when opening PM conversation
- Remove handshake request system notifications

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-07-25 16:15:43 +02:00
jack 97c2393370 Fix lazy handshake behavior and re-enable cover traffic
- Re-enable cover traffic for privacy protection
- Start handshake immediately when opening PM conversation
- Remove handshake request system notifications
2025-07-25 16:15:12 +02:00
jack 087d3b29ae fix: prevent spurious handshake requests from rotated peers and cover traffic
- Clean up connection states and pending messages during peer ID rotation
- Filter out rotated peer IDs in keep-alive timer to prevent validation attempts
- Add session check before sending cover traffic dummy messages
- Disable cover traffic by default (was sending without user knowledge)
- Only send screenshot notifications when session exists
- Add logging to track automatic message triggers
- Fix compilation errors (SecureLogger.privacy -> security)
2025-07-25 16:15:12 +02:00
jack 21562049ac Revert "Add encryption export compliance to Info.plist"
This reverts commit 2cfbb1679d.
2025-07-25 16:15:12 +02:00
jack 9bac75ef76 Add encryption export compliance to Info.plist
Set ITSAppUsesNonExemptEncryption to false for TestFlight submission
2025-07-25 16:15:12 +02:00
3513228736 Implement handshake request notifications for pending messages (#321)
- Add handshakeRequest packet type (0x25) to notify recipients about queued messages
- Create HandshakeRequest struct with binary encoding for efficient transmission
- Send handshake requests when messages are queued due to missing session
- Display notifications when someone wants to send messages
- Fix verification persistence bug by adding forceSave on app termination
- Update UI to handle optional encryption icons (hide when no handshake attempted)

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-07-25 14:55:26 +02:00
jackandGitHub 07c5e2e097 Delete BUILD_MACOS.md 2025-07-25 14:50:52 +02:00
jack f55694c920 Update WHITEPAPER.md 2025-07-25 12:26:27 +02:00
2e0d9be03e Implement targeted delivery for private messages (#319)
- Add direct delivery for private messages when recipient is connected
- Implement selective relay using 2-3 best RSSI peers as fallback
- Limit TTL to 2 hops for relayed private messages
- Update all private communication types to use targeted delivery:
  - Private messages
  - Read receipts
  - Delivery ACKs
  - Protocol ACKs/NACKs
  - Handshake messages
  - Identity announces (when targeted)
  - Session validation pings
  - Version ACKs
- Add intelligent relay logic to forward messages only when recipient is reachable
- Fall back to broadcast only as last resort when no direct path available

This reduces network traffic by ~90% for private communications, improves battery life, and enhances privacy by limiting message visibility.

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-07-25 09:54:56 +02:00
callebtcandGitHub 9515f759d4 NoiseProtocol update: send nonce in packet (#306)
* send nonce in packet

* sliding window and 8 byte nonce

* do not process encrypted messages that arent addressed to us, same for nacks

* compiler error: remove comma

* nonce window 4 bytes

* clean up logging
2025-07-25 09:46:18 +02:00
809e222a31 Improve BLE connection stability and message reliability (#318)
* Remove sequence numbers from protocol

- Remove sequenceNumber field from BitchatPacket struct
- Update BinaryProtocol to not encode/decode sequence numbers (header size reduced from 17 to 13 bytes)
- Replace sequence-based duplicate detection with content-based using packet ID hash
- Update packet ID generation to use SHA256(senderID + timestamp + type + payload prefix)
- Remove all sequence tracking variables and methods
- Simplify duplicate detection to rely on timestamp and content hashing

* Fix connection stability issues

- Increase peer availability check interval from 5 to 15 seconds
- Fix availability logic to not mark connected peers as unavailable
- Add BLE connection keepalive timer (20s) to prevent iOS timeouts
- Fix missing delivery ACKs by passing peripheral context through Noise decryption
- Reduce identity announce frequency from 2 to 10 seconds minimum
- Remove unnecessary identity announces on connection
- Debounce identity cache keychain saves (2 second delay)
- Add message retry notification handler in ChatViewModel
- Fix version negotiation redundancy by checking existing negotiations
- Keep Noise sessions for already-connected peers

* Fix build errors in message retry handler

- Fix reference to 'displayedMessages' - should be 'messages'
- Fix sendMessage call signature to use individual parameters instead of message object
- Both iOS and macOS builds now succeed

* Fix remaining connection stability issues

- Fix duplicate identity announces with content-based deduplication
- Simplify peripheral mapping with cleaner temp ID to peer ID transitions
- Improve graceful leave detection across peer ID rotations
- Track previousPeerID from announcements to maintain state
- Add time-based cleanup for gracefully left peers

* Fix connection stability issues

- Add special duplicate detection for identity announces
- Simplify peripheral mapping with dedicated structure
- Improve graceful leave detection with peer ID rotation handling
- Track graceful leave timestamps for cleanup
- Transfer states properly during peer ID rotation

* Improve BLE connection stability and message reliability

- Increase peer availability timeout from 5s to 15s to prevent flapping
- Add BLE keepalive timer with 30s interval to maintain connections
- Fix missing delivery ACKs by passing peripheral context through decryption
- Reduce identity announce frequency from 2s to 10s minimum interval
- Add keychain save debouncing with 2s delay to prevent excessive writes
- Implement message retry system for failed deliveries to favorites
- Fix version negotiation redundancy by checking existing state
- Add special duplicate detection for identity announcements
- Implement graceful leave detection with peer ID rotation support
- Simplify peripheral mapping to reduce complexity
- Fix switch statement structure issues causing build errors

These changes significantly improve connection stability, eliminate peer availability flapping, and ensure reliable message delivery.

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-07-25 02:40:51 +02:00
86726d7033 Fix RSSI nil display issue (#316)
* Add comprehensive RSSI debugging logs

- Log RSSI capture during discovery phase
- Log RSSI reading after peripheral connection
- Log didReadRSSI results including validation and retries
- Log getPeerRSSI() calls and dictionary contents
- Log RSSI transfer from temp IDs to real peer IDs
- Add UI logging to trace nil RSSI values in ContentView
- Track RSSI flow from Bluetooth discovery to UI display

* Add detailed logging for RSSI transfer from temp ID to real peer ID

- Log peripheral mapping updates during announce packet handling
- Track connectedPeripherals state before and after mapping
- Log RSSI transfer from peripheralRSSI to peerRSSI
- Identify whether temp ID is found and properly transferred

* Add peripheral lookup fallback for announce packets

- Log whether peripheral is present when announce received
- Add fallback to look up peripheral if not passed as parameter
- This handles cases where announce is received via relay

* Add comprehensive state logging to getPeerRSSI

- Log connectedPeripherals mapping state
- Log peripheralRSSI dictionary contents
- Log UI-side RSSI lookup attempts with dictionary state
- Track exactly what's in the RSSI lookup tables

* Log peer list shown in UI

* Ensure RSSI transfers even when no temp ID mapping exists

* Add debugging for announce packets without peripheral reference

* Fix build errors and add type annotations

* Fix RSSI mapping for relayed announce packets

- Add fallback logic to match unmapped peripherals with announced peers
- Transfer RSSI from temp UUID to real peer ID when single unmapped peripheral exists
- Implement periodic RSSI updates every 10 seconds for all connected peripherals
- Improve RSSI debugging logs to track mapping state

* Fix RSSI mapping condition for single unmapped peripheral

- Remove peerNicknames.count == 0 condition that was preventing mapping
- Map single unmapped peripheral to announcing peer regardless of nickname state
- Remove temp RSSI entries when transferring to real peer ID
- Improve logging to show successful RSSI transfers

* Improve getPeerRSSI to skip temp IDs and check known peers

- Skip temp IDs (non-16 character) when iterating connectedPeripherals
- Add fallback to check peerNicknames for known peers without peripherals
- Check both peerRSSI and peripheralRSSI for known peers
- Improve RSSI lookup coverage for edge cases

* Remove RSSI debug logging and fix build warnings

- Remove all RSSI-related debug logging added during troubleshooting
- Keep functional RSSI tracking code intact
- Fix unused variable warnings in didReadRSSI and updateAllPeripheralRSSI
- Clean up verbose logging while maintaining core functionality

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-07-24 22:22:19 +02:00
jack f4e954b837 Replace commands section with security warning in app info
- Removed COMMANDS section from AppInfoView
- Added WARNING section about unaudited private message security
- Warning displayed at bottom with red styling for visibility
- Users advised not to use for critical situations until audit complete
2025-07-24 20:04:30 +02:00
492f90edd5 Optimize BLE mesh network for robustness and range (#314)
- Fixed relay probability calculation for 2-node networks (0% relay needed)
- Added protocol ACKs to prevent unnecessary retransmissions
- Implemented MessageState for enhanced duplicate detection
- Added exponential backoff for collision avoidance
- Fixed duplicate sends for bidirectional connections
- Resolved packet ID generation issues using immutable fields only
- Implemented smart rate limiting with progressive throttling
- Removed unnecessary debug logging and fixed build warnings
- Optimized message routing to prevent flooding in small networks

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-07-24 19:49:37 +02:00
jack 498bb30d82 Fix iOS keyboard constraint warnings
- Added 0.1s delay before focusing text field on appear
- This gives iOS time to properly layout keyboard views
- Prevents constraint conflict warnings in system keyboard
2025-07-24 15:15:28 +02:00
jack bdbc0a6cfe Fix duplicate disconnect messages when Mac app closes
- Added gracefullyLeftPeers tracking to prevent duplicate disconnect messages
- Show disconnect message immediately when leave announcement is received
- Skip duplicate message when physical disconnect happens after graceful leave
- Fixed API misuse by adding peripheral.state checks before readRSSI() calls
- Added debug logging to track graceful leave flow
2025-07-24 15:11:45 +02:00
jack 439668f745 Fix duplicate ChatViewModel disconnect messages
- Prevent didDisconnectFromPeer delegate call when peer gracefully left
- This prevents duplicate 'rick disconnected' messages in chat UI
2025-07-24 14:58:21 +02:00
jack fbc904a331 Fix duplicate disconnect messages and API misuse errors
- Track peers that gracefully left with 'gracefullyLeftPeers' set
- Only log disconnect message if peer didn't send leave message first
- Add state checks before all peripheral.readRSSI() calls
- Prevents API misuse errors for disconnected peripherals
- Clear gracefullyLeftPeers after 5 seconds to handle race conditions
2025-07-24 14:52:22 +02:00
jack a3773a6b31 Fix build errors: wrap textInputAutocapitalization in iOS conditional
- textInputAutocapitalization is iOS-only API
- Wrapped in #if os(iOS) to fix macOS build
2025-07-24 14:38:16 +02:00
jack ffab7b695c Fix NaN errors and timeout warnings when typing
- Disable iOS autocorrection on text fields to prevent conflicts
- Add NaN validation for all geometry and gesture calculations
- Fix frame calculations to handle invalid geometry values
- Validate translation and velocity values in drag gestures
- Prevent Result accumulator timeout warnings
2025-07-24 14:33:20 +02:00
jackandGitHub eac3531a54 Merge pull request #310 from permissionlesstech/fix/ui-polish
UI Polish and Performance Optimizations
2025-07-24 14:23:41 +02:00
jack cea0579bce Fix build error: move PeerDisplayData struct outside ViewBuilder
- Move struct declaration to top level to avoid ViewBuilder error
- Struct declarations cannot be inside ViewBuilder closures
2025-07-24 13:47:44 +02:00
jack c7f0a5ea02 Implement lazy loading for heavy components
- Add LazyLinkPreviewView wrapper to defer link preview loading
- Only render sidebar content when visible or animating
- Defer expensive computations until components are shown
- Reduces initial render cost and memory usage
2025-07-24 13:46:23 +02:00
jack 2350c48e13 Reduce ForEach overhead with pre-computed data
- Remove unnecessary Array() conversions in messages ForEach
- Optimize URL ForEach to use indices instead of enumerated
- Simplify autocomplete ForEach by removing unneeded enumeration
- Pre-compute all peer display data outside ForEach for sidebar
- Create PeerDisplayData struct to bundle peer properties
- Move sorting and data preparation outside the render loop
2025-07-24 13:43:02 +02:00
jack 7120b11692 Optimize autocomplete with debouncing
- Add 150ms debounce to text field onChange handler
- Prevents excessive autocomplete calculations during rapid typing
- Add timer cleanup in onDisappear
- Works for both main chat and private chat inputs
2025-07-24 13:40:34 +02:00
jack bb6552f4a6 Add more spacing between chat messages
- Increased vertical padding from 1px to 2px per message
- Total spacing between messages now 4px (was 2px)
- Improves readability and visual separation
2025-07-24 13:34:21 +02:00
jack 354d3ff6ce Optimization 5: Fix animation overhead
- Removed redundant animation modifiers (multiple animations on same view)
- Replaced spring animations with simpler easeInOut/easeOut curves
- Spring animations are computationally expensive, now using 0.2s easeInOut
- Added scroll throttling to prevent excessive animations on message updates
- Scroll animations limited to once per 0.5 seconds
- Removed withAnimation wrapper from scrollTo calls
- Simplified drag gesture animations from spring to easeOut

This reduces CPU usage during UI transitions and message updates
2025-07-24 13:30:56 +02:00
jack 8d64920f8e Optimization 4: Batch message updates for better performance
- Added message batching system with 100ms window
- Created pendingMessages array for public messages
- Created pendingPrivateMessages dictionary for private messages
- Added scheduleBatchFlush() to consolidate updates
- Batch all incoming messages from didReceiveMessage
- Batch system messages (connect/disconnect/screenshot)
- Keep immediate updates for user's own sent messages
- Single UI update per batch instead of per message
- Flush pending messages on app background/terminate
- Clear timer on deinit

This reduces UI updates when multiple messages arrive quickly
2025-07-24 13:23:31 +02:00
jack 58876704c3 Bold user's own nickname in chat messages
- Added font weight logic to formatMessageAsText and formatMessage
- User's own @nickname appears bold (weight: .bold)
- Other nicknames remain medium weight
- Helps visually distinguish own messages from others
2025-07-24 13:18:12 +02:00
jack b51000939b Remove RSSI-based sender name coloring in chat messages
- Simplified getSenderColor to always return primary color
- Removed RSSI color calculation logic from formatMessageAsText
- Removed RSSI color calculation logic from formatMessage
- All sender names now use consistent green color
- RSSI information remains visible only in peer list
2025-07-24 13:16:47 +02:00
jack e13380fe27 Set message limit to 1337 and auto-trim oldest messages
- Added maxMessages constant set to 1337
- Added trimMessagesIfNeeded() to remove oldest messages when limit exceeded
- Added trimPrivateChatMessagesIfNeeded() for private chat limits
- Applied trimming after all message append operations:
  - Regular chat messages (sent and received)
  - Private messages (sent and received)
  - System messages (connect/disconnect/screenshot)
  - Message migrations between peer IDs
- Ensures chat history doesn't grow unbounded
2025-07-24 13:14:37 +02:00
jack f9d5a07542 Optimization 3: Add caching for expensive view computations
- Cache getRSSIColor results with key format: "\(rssi)_\(isDark)"
- Cache getEncryptionStatus results with peerID as key
- Add cache invalidation methods for both caches
- Invalidate encryption cache when:
  - Encryption status is updated
  - Fingerprints are verified
  - Peer authentication callbacks trigger
- Invalidate RSSI cache when peer list updates
- Clear all caches in panicClearAllData

This reduces redundant calculations during view updates and improves performance
2025-07-24 13:09:18 +02:00
jack 5d3512dfbc Add 1pt more padding around link preview box
- Increased padding from 9pt to 10pt for better visual spacing
- Improves readability and touch target size
2025-07-24 13:04:43 +02:00
jack 5a0c8f0a26 Add 1pt more padding around link preview box
- Increase top padding from 2pt to 3pt
- Add 1pt horizontal padding for better visual balance
2025-07-24 12:59:46 +02:00