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 beaconsComponents โ
1. WaveManager (src/components/WaveManager.jsx) โ
Purpose: Displays incoming wave notifications and handles acceptance/decline actions.
Props:
waves(array): List of incoming wave objectsonAccept(function): Handler for accepting a waveonDecline(function): Handler for declining a waveonOpenChat(function): Handler for opening chat with accepted connection
Wave Object Schema:
{
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 detailsonClose(function): Handler for closing chatonHoldUpLantern(function): Handler for activating beaconmessages(array): Chat message history
Connection Object Schema:
{
id: string,
interest: string,
mood: string,
venue: string,
matchColor: 'amber' | 'purple' | 'blue' | 'green' | 'pink',
timestamp: Date
}Message Object Schema:
{
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:
// 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 detailsmatchColor(string): Color scheme identifieronClose(function): Handler for closing beacon
Color Schemes:
amber: Warm amber/orange gradientpurple: Mystic purple/pink gradientblue: Ocean blue/cyan gradientgreen: Forest green/teal gradientpink: 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:
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
incomingWavestoactiveConnections - TODO: POST to
/api/waves/{id}/accept
handleDeclineWave(waveId)
- Removes wave from
incomingWaves - TODO: POST to
/api/waves/{id}/decline
handleOpenChat(connectionId)
- Sets
activeChatstate - Opens full-screen chat overlay
handleHoldUpLantern()
- Sets
showBeaconto 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 โ
- Geofencing: Verify users are at claimed venue before allowing waves
- Rate Limiting: Prevent spam waves
- Reporting: Add ability to report inappropriate behavior
- Time Windows: Auto-expire connections after venue check-out
- 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 statesChat.stories.jsx: Empty and populated chat statesLanternBeacon.stories.jsx: All 5 color variants
Manual Testing Flow โ
- Run
npm run dev - Click "Simulate Wave" button (dev only)
- Accept wave โ Chat opens
- Send test messages
- Click "Hold Up Lantern" โ Beacon activates
- Test all 5 beacon colors
Unit Tests (TODO) โ
npm testTest 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 โ
- Voice/Video Chat: Upgrade from text to rich media
- Group Meetups: Allow multiple users to join same beacon color
- Venue Check-in Verification: Require QR scan at venue
- Interest Matching Algorithm: Suggest waves based on compatibility
- Post-Meetup Feedback: Optional rating/review system
- Persistent Connections: Allow users to re-connect at different venues
- 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:
{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.