feat(call): in-call soundboard, quality controls, room call-permissions
Element Call is now consumed as our self-built fork (@lotusguild/element-call-embedded); wire up its previously-dormant capabilities and document the fork as live. Soundboard (P5-15): a call-bar button plays user-uploaded audio clips into the call as a real published track (io.lotus.inject_audio) plus local playback. Clips are uploadable like emoji/sticker packs, stored in io.lotus.soundboard account data (synced across devices). Gated by a Settings toggle + volume. Quality controls (P5-31): per-user mic/screenshare bitrate + screenshare framerate (Settings -> Calls), applied via io.lotus.set_quality clamped to any room cap. Room admins set caps and hard call-permissions (allow_screenshare / allow_camera) in Room Settings -> Voice; the call bar hides blocked buttons. - New: CallSoundboard, useSoundboard, soundboardClips; RoomQuality, useCallQuality, callQuality (+ unit tests). - Optimistic-write RoomQuality admin UI (no stale-state clobber). - Docs: mark EC fork live across README/FEATURES/TODO/BUGS/TESTING; add D2 manual-test steps. Numeric quality caps are client-cooperative; screenshare/camera permissions are hard-enforced server-side (see LotusGuild/matrix voice-limit-guard). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+22
-29
@@ -39,38 +39,31 @@ Implemented and gate-green; confirm each per `LOTUS_TESTING.md`, then delete the
|
||||
|
||||
## 🧩 Element Call source-level items — now actionable via the fork
|
||||
|
||||
> 🔱 **[EC-FORK]** **UPDATE 2026-06-29: the fork is live.** We now own and
|
||||
> 🔱 **[EC-FORK]** **UPDATE 2026-06-30: Phase 2 IMPLEMENTED.** We own and
|
||||
> self-build Element Call (`LotusGuild/element-call` →
|
||||
> `@lotusguild/element-call-embedded`, Phase 1 done & cinny wired). A5/A6/A7
|
||||
> below are **no longer "won't fix"** — they are ordinary source changes. See
|
||||
> [`HANDOFF_ELEMENT_CALL_FORK.md`](./HANDOFF_ELEMENT_CALL_FORK.md) §10 + the Phase
|
||||
> 2 work list. (The iframe is **same-origin** / self-hosted; the old blocker was
|
||||
> that we didn't own EC's compiled source — which we now do.)
|
||||
> `@lotusguild/element-call-embedded@0.20.1-lotus.1`, cinny wired). A5/A6/A7
|
||||
> below are **fixed in the fork** — they are now ⚠️ awaiting **live
|
||||
> verification** (`LOTUS_TESTING.md` §D2), not open work. See
|
||||
> [`HANDOFF_ELEMENT_CALL_FORK.md`](./HANDOFF_ELEMENT_CALL_FORK.md) §10. Delete each
|
||||
> row once verified live.
|
||||
|
||||
The in-call participant grid is rendered **inside EC's app**. Previously a
|
||||
pre-built npm bundle we could only style/place around; now editable source.
|
||||
Items from testing, with their fork-level fix path:
|
||||
The in-call participant grid is rendered **inside EC's app** — now editable source
|
||||
(previously a prebuilt npm bundle we could only style around). Status of the items
|
||||
from testing:
|
||||
|
||||
- **A5 — "Focus camera":** EC supports native tile-pinning. Our bottom-bar "Focus
|
||||
camera" is a programmatic wrapper that **`.click()`s the tile** today
|
||||
(`CallControl.ts` `focusCameraParticipant`), and during a screenshare EC
|
||||
spotlights the shared screen so a camera pin may not override it. **Fork fix:**
|
||||
add an `io.lotus.focus_participant` widget action that pins a participant in
|
||||
EC's layout (coexisting with / overriding the screenshare spotlight); cinny
|
||||
sends it via the widget API and the DOM-click hack is deleted. _Status: Open —
|
||||
Actionable (Phase 2)._
|
||||
- **A6 — avatar decorations in-call:** decorations render on **our** pre-join
|
||||
lobby roster (`CallMemberCard`) but not on EC's in-call video tiles. **Fork
|
||||
fix:** render the decoration APNG inside EC's participant-tile component, fed
|
||||
decoration slugs via widget member data. _Status: Open — Actionable (Phase 2)._
|
||||
- **A7 — mic dead after EC's "Reconnect":** the mid-call "Connection lost /
|
||||
Reconnect" screen is **EC's own** (our load watchdog only covers an initial
|
||||
hung load). After EC reconnects, the mic isn't re-published through our denoise
|
||||
`getUserMedia` shim until a clean End+rejoin. **Fork fix:** move denoise into
|
||||
EC's mic-capture/publish pipeline as a first-class audio stage — EC re-runs it
|
||||
on every (re)publish, so reconnects keep denoise alive natively, and the
|
||||
build-time `index.html` injection is removed. _Status: Open — Actionable
|
||||
(Phase 2); root cause is the `getUserMedia` monkeypatch, not EC itself._
|
||||
- **A5 — "Focus camera": ⚠️ FIXED in fork, awaiting verify (D2-3).** cinny now
|
||||
sends an `io.lotus.focus_participant` widget action that pins a participant in
|
||||
EC's layout (coexisting with / overriding the screenshare spotlight); the old
|
||||
`.click()`-the-tile DOM hack in `CallControl.ts` is deleted.
|
||||
- **A6 — avatar decorations in-call: ⚠️ FIXED in fork, awaiting verify (D2-4).**
|
||||
cinny pushes `io.lotus.decorations` (per-user APNG URLs) and the fork renders
|
||||
them on EC's participant video-tile avatars — not just our pre-join lobby roster.
|
||||
- **A7 — mic dead after EC's "Reconnect": ⚠️ FIXED in fork, awaiting verify
|
||||
(D2-1).** Denoise moved into EC's mic-capture/publish pipeline as a first-class
|
||||
LiveKit `TrackProcessor` (flag `lotusDenoiseSource=1`); EC re-runs it on every
|
||||
(re)publish, so reconnects keep denoise alive natively. The build-time
|
||||
`getUserMedia`/`index.html` injection (the root cause) is removed. **Highest
|
||||
blast radius — everyone's mic; verify D2-1 carefully.**
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user