fix(lotus): Wave-1 audit fixes (EC1–EC6)
CI / Build embedded bundle (push) Successful in 1m0s
CI / Publish to Gitea npm registry (push) Has been skipped

- EC1: lotusQuality — track + clearTimeout the 500ms settle re-apply per room
  (was leaking a timer that fired on torn-down rooms).
- EC2/EC3: lotusQuality + lotusAudioInject drive off vm.allConnections$ instead
  of the remote-gated livekitRoomItems$ (were no-ops when alone), matching
  lotusDenoise.
- EC4: lotusDecorations resets its roster to {} on teardown so a decoration from
  a previous call can't render on a shared user in the next one.
- EC5: hoisted a stable useSyncExternalStore subscribe fn (was re-subscribing
  every tile render).
- EC6: lotusFocus only sets the spotlight when the userId field is present
  (a partial payload no longer clears the pin).

tsc clean. Needs a republish to ship.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Lotus CI
2026-07-02 20:13:01 -04:00
co-authored by Claude Opus 4.8
parent 02666c0c04
commit 0ffe247929
4 changed files with 52 additions and 17 deletions
+7 -2
View File
@@ -28,8 +28,13 @@ export function startLotusFocus(vm: CallViewModel): () => void {
// Always reply so the host transport doesn't time out.
void w.api.transport.reply(ev.detail, {});
const data = ev.detail.data as { userId?: unknown } | undefined;
const userId = typeof data?.userId === "string" ? data.userId : null;
vm.setManualSpotlight(userId);
// Mirror deafen's partial-payload semantics: a payload that OMITS `userId`
// must keep the current spotlight, not clear it. Only act when the key is
// actually present — an explicit `null` clears, a string pins that user.
if (data && "userId" in data) {
const userId = typeof data.userId === "string" ? data.userId : null;
vm.setManualSpotlight(userId);
}
};
w.lazyActions.on(LotusWidgetActions.FocusParticipant, handler);