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

@@ -19,9 +19,8 @@ import { useObservableEagerState } from "observable-hooks";
import { SpotlightExpandedLayout as SpotlightExpandedLayoutModel } from "../state/CallViewModel";
import { CallLayout, GridTileModel, SpotlightTileModel } from "./CallLayout";
import { DragCallback } from "./Grid";
import { DragCallback, useLayout } from "./Grid";
import styles from "./SpotlightExpandedLayout.module.css";
import { useReactiveState } from "../useReactiveState";
/**
* An implementation of the "expanded spotlight" layout, in which the spotlight
@@ -29,27 +28,21 @@ import { useReactiveState } from "../useReactiveState";
*/
export const makeSpotlightExpandedLayout: CallLayout<
SpotlightExpandedLayoutModel
> = ({ minBounds, pipAlignment }) => ({
> = ({ pipAlignment }) => ({
scrollingOnTop: true,
fixed: forwardRef(function SpotlightExpandedLayoutFixed(
{ model, Slot },
ref,
) {
const { width, height } = useObservableEagerState(minBounds);
const [generation] = useReactiveState<number>(
(prev) => (prev === undefined ? 0 : prev + 1),
[width, height, model.spotlight],
);
useLayout();
const spotlightTileModel: SpotlightTileModel = useMemo(
() => ({ type: "spotlight", vms: model.spotlight, maximised: true }),
[model.spotlight],
);
return (
<div ref={ref} data-generation={generation} className={styles.layer}>
<div ref={ref} className={styles.layer}>
<Slot
className={styles.spotlight}
id="spotlight"
@@ -63,14 +56,9 @@ export const makeSpotlightExpandedLayout: CallLayout<
{ model, Slot },
ref,
) {
const { width, height } = useObservableEagerState(minBounds);
useLayout();
const pipAlignmentValue = useObservableEagerState(pipAlignment);
const [generation] = useReactiveState<number>(
(prev) => (prev === undefined ? 0 : prev + 1),
[width, height, model.pip === undefined, pipAlignmentValue],
);
const pipTileModel: GridTileModel | undefined = useMemo(
() => model.pip && { type: "grid", vm: model.pip },
[model.pip],
@@ -86,7 +74,7 @@ export const makeSpotlightExpandedLayout: CallLayout<
);
return (
<div ref={ref} data-generation={generation} className={styles.layer}>
<div ref={ref} className={styles.layer}>
{pipTileModel && (
<Slot
className={styles.pip}