Skip to content

Wave-to-Meet Feature — Implementation Summary

What Was Built

A complete social connection flow for Lantern that enables users to:

  1. Wave at anonymous lanterns they're interested in meeting
  2. Chat anonymously when waves are accepted
  3. Meet up using synchronized color beacons on both phones

Files Created

Components

Storybook Stories

Documentation

Modified Files


How It Works

User Flow

┌──────────────┐
│ User browses │
│   venues     │
└──────┬───────┘

       v
┌──────────────┐       ┌─────────────┐
│ Sees lantern │──────>│ Clicks Wave │
│  with shared │       │    button   │
│  interests   │       └─────┬───────┘
└──────────────┘             │
                             v
                    ┌────────────────┐
                    │ Wave sent to   │
                    │   recipient    │
                    └────────┬───────┘

        ┌────────────────────┴─────────────┐
        v                                  v
┌───────────────┐                 ┌────────────────┐
│   Declined    │                 │   Accepted!    │
└───────────────┘                 └────────┬───────┘

                                           v
                                  ┌────────────────┐
                                  │  Chat opens    │
                                  │  (anonymous)   │
                                  └────────┬───────┘

                                           v
                                  ┌────────────────┐
                                  │ "Hold Up       │
                                  │  Lantern"      │
                                  └────────┬───────┘

                                           v
                                  ┌────────────────┐
                                  │ Both phones    │
                                  │ show matching  │
                                  │ color beacon   │
                                  └────────────────┘

Technical Architecture

State Management (in Dashboard.jsx):

js
const [incomingWaves, setIncomingWaves] = useState([])        // Pending waves
const [activeConnections, setActiveConnections] = useState([]) // Accepted connections
const [activeChat, setActiveChat] = useState(null)            // Current chat view
const [showBeacon, setShowBeacon] = useState(false)           // Beacon visibility

Color Matching: When a wave is accepted, both users receive the same randomly-generated color:

  • Amber (warm glow)
  • Purple (mystic vibe)
  • Blue (ocean feel)
  • Green (forest calm)
  • Pink (rose energy)

The color is stored in the connection object and synchronized via backend.


Testing the Feature

Development Mode

  1. Start dev server: npm run dev
  2. Click "Simulate Wave" button (top-right, dev only)
  3. Accept the wave notification
  4. Chat interface opens
  5. Click "Hold Up Lantern to Meet"
  6. Full-screen color beacon activates

Storybook

bash
npm run storybook

Browse to:

  • Components > WaveManager
  • Components > Chat
  • Components > LanternBeacon

Test all states and color variants.


Backend Integration Needed

Required Endpoints

  1. POST /api/waves - Send wave
  2. POST /api/waves/:id/accept - Accept wave
  3. POST /api/waves/:id/decline - Decline wave
  4. WebSocket /ws/waves - Real-time notifications
  5. POST /api/messages - Send chat message
  6. GET /api/messages?connectionId=x - Fetch messages
  7. GET /api/connections/:id/beacon - Get matching color

See API.md and WAVE_TO_MEET.md for full specs.

Security Considerations

  • Geofencing: Verify users are at same venue
  • Rate limiting: 20 waves/min max
  • Anonymity: No user IDs exposed, only lantern metadata
  • Message encryption: Consider E2E encryption
  • Auto-expiry: Connections expire when users leave venue

Design Decisions

Why Full-Screen Components?

  • Chat: Immersive, focused experience without distractions
  • Beacon: Maximum visibility for color matching in crowded venues

Why Color-Matching Instead of Names?

  • Maintains anonymity until both users decide to reveal identities
  • Works in noisy/crowded environments
  • Fun, unique mechanic that aligns with "Lantern" branding

Why No Persistent Usernames?

Lantern is moment-based, not profile-based. Connections are ephemeral and tied to physical presence.


Future Enhancements

Short-term (MVP+)

  • [ ] Add typing indicators in chat
  • [ ] Add read receipts (optional)
  • [ ] Sound/vibration on wave received
  • [ ] Photo sharing in chat (ephemeral)

Medium-term

  • [ ] Voice messages
  • [ ] Group meetups (3+ people, same beacon color)
  • [ ] Venue check-in QR verification
  • [ ] Post-meetup feedback/ratings

Long-term

  • [ ] Video chat
  • [ ] Persistent friend list (opt-in)
  • [ ] Multi-venue connections
  • [ ] Beacon patterns (pulsing rhythms for differentiation)

Demo Script

For stakeholders/investors:

"Lantern is about real connections at real places. Here's how it works:

  1. You're at a coffee shop and see someone lit their lantern with 'Looking for React dev friends'
  2. You wave at them anonymously—no photos, no profiles
  3. They accept, and a chat opens. Still anonymous.
  4. You decide to meet. Both tap 'Hold Up Lantern'
  5. Both phones glow the same color—let's say purple
  6. You look around the café for someone with a purple phone
  7. You meet naturally, like humans always have

No swiping. No endless messages. Just presence, consent, and real connection."


Questions?

Built with ❤️ for authentic human connection.

Built with VitePress