Skip to content

feat: Add Beacon - integrated favorites + map tracking UI#1

Open
rpuneet wants to merge 9 commits into
mainfrom
app/beacon
Open

feat: Add Beacon - integrated favorites + map tracking UI#1
rpuneet wants to merge 9 commits into
mainfrom
app/beacon

Conversation

@rpuneet

@rpuneet rpuneet commented Jan 26, 2026

Copy link
Copy Markdown
Owner

Summary

  • New BeaconView with integrated favorites list and map view
  • Periodic location announcements to mutual favorites (60s interval)
  • Improved map performance with cached annotations
  • Green color scheme and "bitchat/Beacon" branding
  • Fixed duplicate locations bug with normalized storage keys

Features

  • LocationAnnounce message type for passive location broadcasts (devices broadcast every 60s)
  • BeaconMapPin with UWB/BLE/GPS tracking method indicators
  • BeaconFavoriteRow with Track (zoom to person) and Message (open DM) actions
  • MapPingWave animation - 8 waves, radar-style effect
  • Direct chat opening from Beacon favorites list

Technical Changes

  • Added locationAnnounce = 0x30 to NoisePayloadType
  • Added LocationAnnounce struct with binary encoding
  • PeerLocation initializer from LocationAnnounce
  • TrackingService: startLocationAnnouncements(), handleLocationAnnounce()
  • BLEService: sendLocationAnnounce(), receive handler
  • NostrTransport: sendLocationAnnounce() for relay delivery
  • Normalized storage keys to prevent duplicate peer entries

Test plan

  • Open Beacon view - should show map with favorites list
  • Tap favorites star - Beacon should expand with map
  • Verify location broadcasts every 60 seconds (check logs)
  • Tap Track button - map should zoom to that person
  • Tap Message button - should open private chat
  • Verify map pins show correct tracking method (UWB/BLE/GPS)
  • Test via Nostr relay - disconnect BLE, locations should update via relay

🤖 Generated with Claude Code

rpuneet and others added 2 commits January 26, 2026 15:02
- Add requestFreshLocation() method to LocationStateManager that triggers
  one-shot GPS request with callback and 3-second timeout
- Update handleTrackRequest in BLEService to use new location request
  method instead of simple 2-second delay
- Add notification posting when location updates for callback support
- Enhance debug logging throughout tracking flow with exact coordinates
- Add UWB PeerID normalization for consistent dictionary lookups
- Include tracking UI components: GroupTrackingView, TrackingView,
  TrackingMapView, HotColdIndicator, DirectionalArrow
- Add TrackingService for coordinating peer location tracking
- Add UWBTrackingManager for Ultra-Wideband precision tracking
- Add SignalFusion for combining GPS, UWB, and BLE distance estimates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## Summary
- New BeaconView with integrated favorites list and map view
- Periodic location announcements to mutual favorites (60s interval)
- Improved map performance with cached annotations
- Green color scheme and "bitchat/Beacon" branding
- Fixed duplicate locations bug with normalized storage keys

## Features
- LocationAnnounce message type for passive location broadcasts
- BeaconMapPin with UWB/BLE/GPS tracking method indicators
- BeaconFavoriteRow with Track and Message actions
- MapPingWave animation (8 waves, radar-style effect)
- Direct chat opening from Beacon favorites list

## Technical Changes
- Added locationAnnounce = 0x30 to NoisePayloadType
- Added LocationAnnounce struct with binary encoding
- PeerLocation initializer from LocationAnnounce
- TrackingService: startLocationAnnouncements(), handleLocationAnnounce()
- BLEService: sendLocationAnnounce(), receive handler
- NostrTransport: sendLocationAnnounce() for relay delivery
- Normalized storage keys to prevent duplicate peer entries

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CODE_SIGN_ALLOW_ENTITLEMENTS_MODIFICATION = YES;
CODE_SIGN_ENTITLEMENTS = bitchatShareExtension/bitchatShareExtension.entitlements;
CODE_SIGN_STYLE = "$(CODE_SIGN_STYLE)";
DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)";

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use variables here and not hardcode values

CODE_SIGN_ENTITLEMENTS = bitchat/bitchat.entitlements;
CODE_SIGN_STYLE = "$(CODE_SIGN_STYLE)";
DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)";
DEVELOPMENT_TEAM = 7S3523UWB4;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dev team should not be hardcoded

CODE_SIGN_ENTITLEMENTS = bitchat/bitchat.entitlements;
CODE_SIGN_STYLE = "$(CODE_SIGN_STYLE)";
DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)";
DEVELOPMENT_TEAM = 7S3523UWB4;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

development team should not be hardcoded

COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)";
DEVELOPMENT_TEAM = 7S3523UWB4;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dev team should not be hardcoded

Comment thread bitchat/Models/CommandInfo.swift Outdated
if isGeoPublic || isGeoDM {
return baseCommands + [.favorite, .unfavorite]

static func all(isGeoPublic: Bool, isGeoDM: Bool, isPrivateChat: Bool = false) -> [CommandInfo] {

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isnt isGeoDM same as isPrivateChat?


// Rate limiting
static let maxHandshakesPerMinute = 10
// Note: Mesh relays can duplicate handshake packets, and periodic tracking

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's not change this or other settings

Comment thread bitchat/Nostr/NostrIdentityBridge.swift Outdated
// Generate new Nostr identity
let nostrIdentity = try NostrIdentity.generate()

SecureLogger.warning("🔑 Nostr identity GENERATED (keychain was empty): \(nostrIdentity.npub)", category: .session)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert all changes in this file

Comment thread bitchat/Nostr/NostrRelayManager.swift Outdated
private func flushPendingSubscriptions(for relayUrl: String) {
guard let map = pendingSubscriptions[relayUrl], !map.isEmpty else { return }
guard let connection = connections[relayUrl] else { return }
guard let map = pendingSubscriptions[relayUrl], !map.isEmpty else {

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly debug logs let's revert changes here as well.

Comment thread bitchat/Services/BLE/BLEService.swift Outdated
// Use testnet UUID for debug builds, mainnet for release
#if DEBUG
static let serviceUUID = CBUUID(string: "F47B5E2D-4A9E-4C5A-9B3F-8E1D2C3A4B5A") // testnet
static let serviceUUID = CBUUID(string: "E47B5E2D-4A9E-4C5A-9B3F-8E1D2C3A4B5D") // testnet

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sure we don't change the debug testate uuid

object: nil
)
#endif

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't need this change extra space / tabs change here.

rpuneet and others added 7 commits January 26, 2026 15:18
- Revert CommandInfo.swift changes (keep original function signature)
- Revert NoiseSecurityConstants.swift (keep original rate limits)
- Revert NostrIdentityBridge.swift (remove debug logs)
- Revert NostrRelayManager.swift (remove debug logs)
- Revert BLEService.swift testnet UUID to original value
- Remove debug log lines using non-existent methods
- Wrap BeaconSheetView in #if os(iOS) for macOS compatibility
- Add macOS fallback to GroupTrackingView in ContentView

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Simplified BeaconFavoriteRow to match MeshPeerList style:
  - Status dot + name + tracking badge + action buttons
  - Removed avatar circles for cleaner look
- Changed header icon from star to beacon icon (location.north.circle.fill)
- Changed color scheme to green tones
- Removed tracking button from private chat headers
- Removed associated showTrackingSheet state and sheet

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add drawer-style UI with handle for expand/collapse
- Match People section styling: lowercase "beacon" header, X close button
- Add search functionality to filter friends when drawer is expanded
- Show "friends" count and "online" count in header
- Update friend rows with connection icon, name, and tracking details
- Add smooth spring animations for drawer state changes
- Handle .wifi transport case in connection icon switch
- Remove chat button, keep "tap to find" for tracking detail

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move close and ping buttons to top of map
- Add status indicator (pinging/online count) in top bar
- Replace sheet with in-map tracking overlay when selecting friend
- Show directional arrow + hot/cold indicator for UWB tracking
- Show GPS location with accuracy for non-UWB tracking
- Add tracking details grid (connection type, ping, GPS, signal strength)
- Remove #if os(iOS) conditionals for consistent macOS/iOS UI
- Tap to toggle selection (show/hide overlay)
- Change friend row chevron to indicate selection state

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename to "track" title (matches "people" section style)
- Add ping icon in header (like QR icon position in People)
- Show "X online" status (like "#mesh X active")
- Remove redundant "friends/online" counts from drawer
- Simplify drawer to just list of favorites
- Redesign popup with:
  - Calibrated direction arrow (UWB) or location icon (GPS)
  - Staleness indicator ("just now", "5s ago", "2m ago")
  - Colored icons with values only (no labels) - minimal/clean
  - Hot/cold color coding for UWB distance
- Consistent UI between macOS and iOS

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove #if os(iOS) conditional that was showing different
GroupTrackingView on macOS. Now both platforms use BeaconSheetView
for consistent UI.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add minWidth/minHeight (420x520) to BeaconSheetView on macOS
- Add minHeight to map section
- Add maxWidth/maxHeight infinity to main container
- Matches People section sheet sizing pattern

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant