Skip to content

Wave-to-Meet Feature

Overview

The Wave-to-Meet feature enables users to initiate connections, chat anonymously, and meet up in person using synchronized color beacons.

User Flow

1. User sees lit lantern → Sends wave 👋
2. Recipient receives wave notification → Accepts/Declines
3. If accepted → Both users can now chat 💬
4. Either user can activate "Hold Up Lantern" → Both phones show matching color 🏮
5. Users find each other in venue using color-matching beacons

Components

1. WaveManager (src/components/WaveManager.jsx)

Purpose: Displays incoming wave notifications and handles acceptance/decline actions.

Props:

  • waves (array): List of incoming wave objects
  • onAccept (function): Handler for accepting a wave
  • onDecline (function): Handler for declining a wave
  • onOpenChat (function): Handler for opening chat with accepted connection

Wave Object Schema:

js
{
  id: string | number,
  interest: string,        // User's stated interest
  mood: string,            // Mood/intention (e.g., "Conversation")
  venue: string,           // Venue name
  time: string,            // Relative time (e.g., "5m ago")
  status: 'pending' | 'accepted',
  connectionId?: string    // Present if status is 'accepted'
}

Features:

  • Slide-up animation for new waves
  • Amber glow effect matching Lantern brand
  • Shows user interest and mood anonymously
  • Persistent "Open Chat" button for accepted waves

2. Chat (src/components/Chat.jsx)

Purpose: Anonymous chat interface for accepted connections with quick access to beacon feature.

Props:

  • connection (object): Connection details
  • onClose (function): Handler for closing chat
  • onHoldUpLantern (function): Handler for activating beacon
  • messages (array): Chat message history

Connection Object Schema:

js
{
  id: string,
  interest: string,
  mood: string,
  venue: string,
  matchColor: 'amber' | 'purple' | 'blue' | 'green' | 'pink',
  timestamp: Date
}

Message Object Schema:

js
{
  id: number | string,
  text: string,
  from: 'me' | 'them',
  timestamp: string    // Formatted time (e.g., "2:45 PM")
}

Features:

  • Full-screen overlay chat interface
  • Gradient purple-to-pink theme (differentiates from amber Lantern branding)
  • Connection info banner showing venue and interest
  • Prominent "Hold Up Lantern to Meet" CTA
  • Auto-scroll to latest messages
  • Real-time message input

Backend Integration Points:

js
// Send message
POST /api/messages
Body: { connectionId, text, timestamp }

// Fetch messages
GET /api/messages?connectionId={id}
Response: { messages: [...] }

3. LanternBeacon (src/components/LanternBeacon.jsx)

Purpose: Full-screen synchronized color beacon for finding connection in person.

Props:

  • connection (object): Connection details
  • matchColor (string): Color scheme identifier
  • onClose (function): Handler for closing beacon

Color Schemes:

  • amber: Warm amber/orange gradient
  • purple: Mystic purple/pink gradient
  • blue: Ocean blue/cyan gradient
  • green: Forest green/teal gradient
  • pink: Rose pink gradient

Features:

  • Full-screen immersive color display
  • Pulsing animation (0.8x to 1.2x scale)
  • Radial glow effect for visibility
  • Auto-hides instructions after 5 seconds
  • Safety reminder at bottom
  • Matching colors ensure both users see identical beacon

Technical Details:

  • 60 FPS pulse animation via setInterval (50ms)
  • CSS gradients + filter effects for glow
  • Brightness modulation for attention
  • Accessible close button

Integration with Dashboard

State Management

Dashboard manages all wave/connection state:

js
const [incomingWaves, setIncomingWaves] = useState([])
const [activeConnections, setActiveConnections] = useState([])
const [activeChat, setActiveChat] = useState(null)
const [showBeacon, setShowBeacon] = useState(false)

Event Handlers

handleSendWave(lanternId)

  • Triggered when user clicks "Wave" on a lantern
  • TODO: POST to /api/waves

handleAcceptWave(waveId)

  • Generates random matching color
  • Creates connection object
  • Moves wave from incomingWaves to activeConnections
  • TODO: POST to /api/waves/{id}/accept

handleDeclineWave(waveId)

  • Removes wave from incomingWaves
  • TODO: POST to /api/waves/{id}/decline

handleOpenChat(connectionId)

  • Sets activeChat state
  • Opens full-screen chat overlay

handleHoldUpLantern()

  • Sets showBeacon to true
  • Displays LanternBeacon with matching color

Backend Requirements

Endpoints

1. Send Wave

POST /api/waves
Body: {
  targetLanternId: string,
  senderLanternId: string
}
Response: {
  waveId: string,
  status: "sent"
}

2. Accept/Decline Wave

POST /api/waves/:waveId/accept
Body: {
  matchColor: string  // Generated on client
}
Response: {
  connectionId: string,
  matchColor: string
}

POST /api/waves/:waveId/decline
Response: { status: "declined" }

3. Real-time Wave Notifications

Recommended: WebSocket or Server-Sent Events (SSE)

WebSocket: /ws/waves
Message format: {
  type: "wave_received",
  wave: { id, interest, mood, venue, time }
}

4. Chat Messages

POST /api/messages
Body: {
  connectionId: string,
  text: string,
  timestamp: string
}

GET /api/messages?connectionId={id}
Response: {
  messages: [{ id, text, from, timestamp }]
}

5. Color Sync

GET /api/connections/:id/beacon
Response: {
  matchColor: string,
  expiresAt: timestamp  // Optional: time-limit beacon availability
}

Security & Privacy Considerations

Anonymity

  • No user names or photos exchanged
  • Only interest/mood visible until connection
  • Messages are connection-scoped (not user-scoped)

Safety Features

  1. Geofencing: Verify users are at claimed venue before allowing waves
  2. Rate Limiting: Prevent spam waves
  3. Reporting: Add ability to report inappropriate behavior
  4. Time Windows: Auto-expire connections after venue check-out
  5. Block List: Allow users to block lanterns

Data Retention

  • Messages: Delete after 24h or connection closure
  • Connections: Expire when either user leaves venue
  • Waves: Auto-decline after 15-30 minutes

Testing

Storybook Stories

  • WaveManager.stories.jsx: All wave notification states
  • Chat.stories.jsx: Empty and populated chat states
  • LanternBeacon.stories.jsx: All 5 color variants

Manual Testing Flow

  1. Run npm run dev
  2. Click "Simulate Wave" button (dev only)
  3. Accept wave → Chat opens
  4. Send test messages
  5. Click "Hold Up Lantern" → Beacon activates
  6. Test all 5 beacon colors

Unit Tests (TODO)

bash
npm test

Test coverage should include:

  • Wave acceptance creates connection
  • Wave decline removes notification
  • Messages send/receive correctly
  • Beacon colors match between users
  • Chat auto-scrolls on new messages

Future Enhancements

  1. Voice/Video Chat: Upgrade from text to rich media
  2. Group Meetups: Allow multiple users to join same beacon color
  3. Venue Check-in Verification: Require QR scan at venue
  4. Interest Matching Algorithm: Suggest waves based on compatibility
  5. Post-Meetup Feedback: Optional rating/review system
  6. Persistent Connections: Allow users to re-connect at different venues
  7. Beacon Patterns: Add pulsing patterns for differentiation (same color, different rhythm)

Demo & Development

Simulate Wave (Development Only)

A "Simulate Wave" button appears in top-right corner during development:

js
{process.env.NODE_ENV === 'development' && (
  <button onClick={simulateIncomingWave}>
    Simulate Wave
  </button>
)}

Remove or comment out before production deployment.


Architecture Diagram

┌─────────────────────────────────────────────────┐
│              Dashboard (Main View)              │
│  ┌───────────────────────────────────────────┐  │
│  │        HomeView / VenueView              │  │
│  │  • Browse venues                          │  │
│  │  • See lit lanterns                       │  │
│  │  • Click "Wave" button ──────────────┐   │  │
│  └───────────────────────────────────────┘   │  │
│                                               │  │
│  ┌──────────────────────────────────────┐    │  │
│  │         WaveManager                  │◄───┘  │
│  │  • Incoming wave notifications       │       │
│  │  • Accept/Decline actions ───────┐   │       │
│  └──────────────────────────────────┘   │       │
│                                          │       │
│  ┌──────────────────────────────────┐   │       │
│  │         Chat Component           │◄──┘       │
│  │  • Anonymous messaging           │           │
│  │  • "Hold Up Lantern" CTA ────┐   │           │
│  └──────────────────────────────┘   │           │
│                                      │           │
│  ┌──────────────────────────────┐   │           │
│  │      LanternBeacon           │◄──┘           │
│  │  • Full-screen color glow    │               │
│  │  • Synchronized matching     │               │
│  └──────────────────────────────┘               │
└─────────────────────────────────────────────────┘

For questions or contributions, see CONTRIBUTING.md.

Built with VitePress