iOS Safari ignores wildcard */* in share_target accept.
List specific MIME types and file extensions so AnyDrop
appears in the iOS share sheet for photos, videos, docs, etc.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Peers (available devices)
2. Pair device + Public link (side by side buttons, modals for details)
3. File drop + Text send (only when a peer is selected)
4. Transfer progress
Removed the always-visible drop zone and join-code input from
PeerList. Pairing and public room now open as overlay modals.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Transfers now survive page refreshes:
- beforeunload warning prevents accidental refresh during transfer
- Sender's files cached in IndexedDB before sending
- Receiver's chunks persisted in IndexedDB as they arrive
- On reconnect, receiver sends transfer-resume with bytes received
- Sender resumes from offset, skipping already-sent data
- Old transfer data auto-cleaned after 1 hour
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a groupId-based pairing system so devices can always see
each other regardless of network. Scan a QR code once from the
other device, and they're permanently linked via a shared group
stored in localStorage. No account, no email — just one-time QR
scan like Bluetooth pairing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The ICE candidate regex was matching the wrong part of the candidate
string. Also, iOS Safari blocks local IP detection via WebRTC (mDNS
obfuscation), so when no peers are found, show a prominent "create
link" button and a join-by-code input for easy cross-network pairing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
iCloud Private Relay hides iPhones' real public IP, breaking
IP-based LAN grouping. Devices now detect their local IP
(192.168.x.x) via WebRTC ICE candidates and send it to the
server. The server groups devices by local subnet as a fallback
when public IPs differ.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Offline push-subscribed devices appear dimmed in peer list
- Tap offline peer to send wake push notification
- Skip self-notification (own deviceId excluded)
- iOS/Android share sheet via Web Share Target API
- Online/offline indicator dot on peer avatars
- Web Push API for offline device notifications (VAPID)
- Custom service worker with push + share target handlers
- iOS/Android share sheet support via Web Share Target API
- Dedicated /share page with one-tap send to nearby peer
- Background tab notifications for incoming transfers
- Persistent deviceId per device
- Web Push API for offline device notifications
- Custom service worker with push event handling
- Local notifications for background tab transfers
- VAPID keys in K8s config
- Persistent deviceId per device
- Users set their own device name and optional profile picture
- Profile persisted in localStorage (no account needed)
- Auto-detect device type from user agent (iPhone, Mac, Android...)
- Server uses client-provided profile instead of generating names
- PeerAvatar shows photo or device icon instead of animal emojis
- ProfileSetup modal on first visit + editable from header