Introduce a TURN credentials protocol for requesting time-limited relay
server credentials from the relay node, improving NAT traversal for
WebRTC voice connections.
WebRTC layer improvements:
- Add ICE candidate buffering before remote description is set
- Implement automatic ICE restart with configurable max attempts
- Add disconnection timeout with delayed restart recovery
- Add per-peer connection state tracking and callbacks
- Include public STUN servers (Google, Cloudflare) by default
- Add detailed logging throughout the WebRTC lifecycle
Voice store improvements:
- Fetch TURN credentials from relay before establishing connections
- Track per-peer RTCPeerConnectionState with reactive signals
- Derive overall voice quality signal (good/connecting/degraded/failed)
- Evaluate and surface degraded connection state to the UI
- Clean up peer connection states on participant leave
- Fix video toggle resource leak (stop unused audio tracks)
Backend changes:
- Add TurnCredentialRequest/Response protocol types
- Wire turn_credentials behaviour into swarm and node event loop
- Add get_turn_credentials Tauri command
- Propagate errors from voice commands instead of silently dropping
- Add input validation for SDP types in send_voice_sdp
- Handle missing node handle as explicit error in all voice commands
- Add DirectoryResponse::Error variant handling
- Scope Linux WebKitGTK permission grants to UserMediaPermissionRequest
UI improvements:
- Show connection quality indicator in voice channel header
- Add per-peer connection state ring on participant tiles
- Display failed connection warning icon on participant tiles
- Stack muted/deafened indicators vertically to avoid overlap
- Show participant grid in degraded connection state
Also remove unused imports across several frontend components.
- setRelayDiscoverable IPC wrapper in tauri.ts
- relay_discoverable in defaultSettings + toggleRelayDiscoverable function
- Privacy settings: discoverable on relay toggle
- Sign-up: disclosure text about relay username storage
- User directory: WifiOff badge for relay-only (offline) peers
- Improved empty state hint text
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
search_directory falls back to relay when local results < 5.
Relay stubs upserted with INSERT OR IGNORE to preserve existing data.
set_relay_discoverable persists setting and notifies running node.
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
- Introduced a macro `ipc_log!` to log the invocation and result of Tauri IPC commands in the Rust backend.
- Updated existing commands in `dm.rs` and `identity.rs` to use the new logging macro.
- Wrapped the `invoke` function in the frontend to log all IPC calls and their results, including redacting sensitive arguments.
- Refactor DMSearchPanel to utilize a debounced search mechanism with improved filtering options.
- Implement asynchronous message searching with new searchDMMessages API.
- Introduce VirtualMessageList for optimized rendering of messages in DMChatArea.
- Add unread message count indicator in ServerList for better user awareness.
- Enhance message loading logic to support pagination and lazy loading of older messages.
- Update types and stores to accommodate new search filters and message handling.
- Implemented mention support in DMChatArea, allowing users to mention peers in messages.
- Enhanced markdown rendering to support mentions, converting <@peer_id> tokens to display names.
- Updated notification system to handle navigation on notification clicks, directing users to relevant channels or DMs.
- Introduced caching for avatar icons to reduce redundant disk writes.
- Added a MentionList component for displaying mention suggestions.
- Improved styling for mentions in both chat and editor contexts.
- Persisted last viewed channels per community across app restarts.
- Implemented `search_gifs` and `get_trending_gifs` commands in Tauri for GIF retrieval.
- Created a new protocol for GIF requests and responses.
- Added `EmojiPicker` component for emoji selection with recent emoji storage.
- Developed `GifPicker` component for searching and selecting GIFs.
- Introduced emoji data management with recent emoji tracking.
- Added markdown conversion utilities for rendering formatted text.
- Updated Vite configuration to optimize dependencies for Prosemirror.
- Implemented `search_gifs` and `get_trending_gifs` commands in Tauri for GIF retrieval.
- Created a new protocol for GIF requests and responses.
- Added `EmojiPicker` component for emoji selection with recent emoji storage.
- Developed `GifPicker` component for searching and selecting GIFs.
- Introduced emoji data management with recent emoji tracking.
- Added markdown conversion utilities for rendering formatted text.
- Updated Vite configuration to optimize dependencies for Prosemirror.
feat(profile): implement profile announcement and publishing on peer discovery
fix(directory): refresh known peers on modal open for immediate visibility
add separate effect for users without stored identity to play
animation then transition to signup, preventing unnecessary
retry loop meant only for returning users