Bump Vite 8, matrix-js-sdk, and related deps; fix immer/vanilla-extract imports for new majors. Replace blocking sync error dialog with background recovery on wake/offline, and disable Vite auto-open in dev. Add feature handoff documentation index.
3.4 KiB
3.4 KiB
Voice & video calls — handoff
Summary
Paarrot supports Matrix RTC voice/video calls via MSC3401 (org.matrix.msc3401.call.member) and LiveKit. Calls can be docked in the sidebar, support screen share, remote cursors, mute/deafen, and are wired to the local HTTP API for external control.
User-facing behavior
- Join/start calls from room UI (when homeserver exposes RTC/LiveKit via
.well-known) - Docked call panel in sidebar; full overlay mode
- Mute, deafen, camera, screen share controls
- Call participants shown in room nav (
CallParticipantsIndicator)
Architecture
useCallService (CallProvider)
→ CallService (LiveKit room, Matrix call member state)
→ useRtcConfig: .well-known m.rtc + LiveKit focus
→ UI: CallOverlay, DockedCallPanel, SidebarDockedCallPanel
→ getCallService() global ref for Electron API (paarrot-api.ts)
Key files
| Path | Role |
|---|---|
cinny/src/app/features/call/useCall.ts |
React context, global CallService ref |
cinny/src/app/features/call/CallService.ts |
Core call logic |
cinny/src/app/features/call/types.ts |
CallState, ActiveCall, events |
cinny/src/app/features/call/useRtcConfig.ts |
Homeserver RTC / LiveKit discovery |
cinny/src/app/features/call/CallOverlay.tsx |
Full-screen call UI |
cinny/src/app/features/call/DockedCallPanel.tsx |
Docked UI |
cinny/src/app/features/call/SidebarDockedCallPanel.tsx |
Sidebar variant |
cinny/src/app/features/call/useRemoteCursor.ts |
Screen-share cursor sync |
cinny/src/app/features/call/CallSounds.ts |
Join/leave sounds |
cinny/src/app/features/room-nav/CallParticipantsIndicator.tsx |
Nav badge |
cinny/src/types/matrix/room.ts |
StateEvent.CallMember |
Data model
| Key | Scope | Notes |
|---|---|---|
org.matrix.msc3401.call.member |
Room state | Call membership |
| LiveKit JWT / room | Ephemeral | From homeserver RTC focus |
Call mute/deafen/video state lives in CallService memory, not Matrix account data.
Dependencies
livekit-client(verify in package.json)- Homeserver
.well-knownRTC configuration - Browser/Electron media permissions (mic, camera, screen capture)
- Electron
desktopCapturerfor screen share (main process)
Integration points
- local-api: mute/deafen/status endpoints
- Stream Deck: uses call mute/deafen via API
- Room nav: participant indicators
- Electron main: screen capture IPC if applicable
Testing
Manual
- Use a homeserver with Matrix RTC + LiveKit configured.
- Start voice call in a room; verify audio both ways.
- Toggle mute/deafen; verify API
/statusreflects state. - Screen share; verify remote cursor if enabled.
- Dock/undock call panel.
Automated
- None identified
Known issues & gotchas
callSupportedfalse until.well-knownRTC fetch completes — UI should hide call buttons when unsupportedgetCallService()must be set before API mute actions work- Platform differences: screen capture APIs differ Electron vs browser vs Android
Future work
- Call recording, noise suppression settings
- Better reconnection / call transfer
- MSC3401 spec tracking as it stabilizes
Related docs
- local-api HANDOFF
- Matrix MSC3401 (upstream spec)
Add your extra things here
fetchWellKnownWithRTC,getLiveKitFocus,getLiveKitHomeserverPriorityinuseRtcConfig.ts- Global singleton:
globalCallServiceInstanceinuseCall.tsfor non-React consumers