Out of precaution, also revert the previous GridLayout re-render
optimization to avoid any layout regression alongside the
CarouselLayout revert.
The useSize-based re-render optimization will be reintroduced in a
dedicated small PR and release. That will also be a good occasion to
polish the layout code along the way.
Introduce a tripwire component that listens to
RoomEvent.ActiveSpeakersChanged imperatively and forces a single
re-render of its host only when an active speaker has none of their
tiles within the visible span (maxVisibleTiles). That re-render
re-runs useVisualStableUpdate, which reads live isSpeaking state
and performs the actual tile swap.
Speakers already visible are ignored, so this costs zero React work
in the common case.
This lets us drop the ActiveSpeakersChanged subscription from
useTracks in the StageLayout upstream (updateOnlyOn: []), which was
re-rendering the whole stage on every speaker change.
Move the useSize observer into a leaf component of the GridLayout
tree. That leaf then propagates size changes back into the
GridLayout state through a callback.
This prevents every size change from re-rendering the whole
GridLayout tree, keeping the re-render local to the leaf that
actually observes the size.
Group layout-related components under a single feature directory
to improve structure and readability.
This is a first step toward cleaning up the project and clarifying
the organization of the video call layout.