fix(lotus): Wave-1 audit fixes (EC1–EC6)
- 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:
co-authored by
Claude Opus 4.8
parent
02666c0c04
commit
0ffe247929
@@ -26,15 +26,16 @@ function emit(): void {
|
||||
for (const l of listeners) l();
|
||||
}
|
||||
|
||||
// Stable module-scope subscribe reference, so `useSyncExternalStore` doesn't
|
||||
// re-subscribe (add/remove the listener) on every render of a tile.
|
||||
function subscribe(cb: () => void): () => void {
|
||||
listeners.add(cb);
|
||||
return () => listeners.delete(cb);
|
||||
}
|
||||
|
||||
/** Subscribe a tile avatar to its participant's decoration URL (or undefined). */
|
||||
export function useLotusDecoration(userId: string): string | undefined {
|
||||
return useSyncExternalStore(
|
||||
(cb) => {
|
||||
listeners.add(cb);
|
||||
return () => listeners.delete(cb);
|
||||
},
|
||||
() => decorations[userId],
|
||||
);
|
||||
return useSyncExternalStore(subscribe, () => decorations[userId]);
|
||||
}
|
||||
|
||||
function safeImageUrl(raw: unknown): string | null {
|
||||
@@ -94,8 +95,12 @@ export function startLotusDecorations(): () => void {
|
||||
registrations = 0;
|
||||
unregister?.();
|
||||
unregister = null;
|
||||
// Intentionally keep the last decorations map: a transient remount must
|
||||
// not drop decorations until the host next pushes an update.
|
||||
// Reset the roster once the last registration goes away, so a decoration
|
||||
// pushed in call A can't leak onto a shared user in call B before the
|
||||
// host re-pushes. Notify listeners so any still-mounted tile drops the
|
||||
// now-stale overlay via the render path.
|
||||
decorations = {};
|
||||
emit();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user