Make layout reactivity less brittle

Follow-up to ea2d98179c

This took a couple of iterations to find something that works without creating update loops, but I think that by automatically informing Grid whenever a layout component is re-rendered, we'll have a much easier time ensuring that our layouts are fully reactive.
This commit is contained in:
Robin
2024-07-24 16:57:20 -04:00
parent c74cebcc4b
commit 447bac3280
6 changed files with 80 additions and 92 deletions

View File

@@ -26,7 +26,7 @@ import {
} from "./CallLayout";
import { SpotlightPortraitLayout as SpotlightPortraitLayoutModel } from "../state/CallViewModel";
import styles from "./SpotlightPortraitLayout.module.css";
import { useReactiveState } from "../useReactiveState";
import { useLayout } from "./Grid";
interface GridCSSProperties extends CSSProperties {
"--grid-gap": string;
@@ -48,7 +48,7 @@ export const makeSpotlightPortraitLayout: CallLayout<
{ model, Slot },
ref,
) {
const { width, height } = useObservableEagerState(minBounds);
useLayout();
const tileModel: TileModel = useMemo(
() => ({
type: "spotlight",
@@ -57,13 +57,9 @@ export const makeSpotlightPortraitLayout: CallLayout<
}),
[model.spotlight],
);
const [generation] = useReactiveState<number>(
(prev) => (prev === undefined ? 0 : prev + 1),
[model.grid.length, width, height, model.spotlight],
);
return (
<div ref={ref} data-generation={generation} className={styles.layer}>
<div ref={ref} className={styles.layer}>
<div className={styles.spotlight}>
<Slot className={styles.slot} id="spotlight" model={tileModel} />
</div>
@@ -75,7 +71,8 @@ export const makeSpotlightPortraitLayout: CallLayout<
{ model, Slot },
ref,
) {
const { width, height } = useObservableEagerState(minBounds);
useLayout();
const { width } = useObservableEagerState(minBounds);
const { gap, tileWidth, tileHeight } = arrangeTiles(
width,
0,
@@ -85,15 +82,10 @@ export const makeSpotlightPortraitLayout: CallLayout<
() => model.grid.map((vm) => ({ type: "grid", vm })),
[model.grid],
);
const [generation] = useReactiveState<number>(
(prev) => (prev === undefined ? 0 : prev + 1),
[model.spotlight.length, model.grid, width, height],
);
return (
<div
ref={ref}
data-generation={generation}
className={styles.layer}
style={
{