mirror of
https://github.com/vector-im/element-call.git
synced 2026-08-29 21:15:19 +00:00
Merge pull request #4158 from element-hq/spotlight-performance
Performance: Avoid re-rendering entire spotlight layout so often
This commit is contained in:
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|||||||
Please see LICENSE in the repository root for full details.
|
Please see LICENSE in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { type ReactNode } from "react";
|
import { type FC, type ReactNode } from "react";
|
||||||
import { useObservableEagerState } from "observable-hooks";
|
import { useObservableEagerState } from "observable-hooks";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
|
||||||
@@ -13,6 +13,9 @@ import { type CallLayout } from "./CallLayout";
|
|||||||
import { type SpotlightLandscapeLayout as SpotlightLandscapeLayoutModel } from "../state/layout-types.ts";
|
import { type SpotlightLandscapeLayout as SpotlightLandscapeLayoutModel } from "../state/layout-types.ts";
|
||||||
import styles from "./SpotlightLandscapeLayout.module.css";
|
import styles from "./SpotlightLandscapeLayout.module.css";
|
||||||
import { useUpdateLayout, useVisibleTiles } from "./Grid";
|
import { useUpdateLayout, useVisibleTiles } from "./Grid";
|
||||||
|
import { type MediaViewModel } from "../state/media/MediaViewModel.ts";
|
||||||
|
import { type Behavior } from "../state/Behavior.ts";
|
||||||
|
import { useBehavior } from "../useBehavior.ts";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of the "spotlight landscape" layout, in which the spotlight
|
* An implementation of the "spotlight landscape" layout, in which the spotlight
|
||||||
@@ -54,16 +57,10 @@ export const makeSpotlightLandscapeLayout: CallLayout<
|
|||||||
useUpdateLayout();
|
useUpdateLayout();
|
||||||
useVisibleTiles(model.setVisibleTiles);
|
useVisibleTiles(model.setVisibleTiles);
|
||||||
useObservableEagerState(minBounds$);
|
useObservableEagerState(minBounds$);
|
||||||
const withIndicators =
|
|
||||||
useObservableEagerState(model.spotlight.media$).length > 1;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref} className={styles.layer}>
|
<div ref={ref} className={styles.layer}>
|
||||||
<div
|
<SpotlightSlot media$={model.spotlight.media$} />
|
||||||
className={classNames(styles.spotlight, {
|
|
||||||
[styles.withIndicators]: withIndicators,
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
<div className={styles.grid}>
|
<div className={styles.grid}>
|
||||||
{model.grid.map((m) => (
|
{model.grid.map((m) => (
|
||||||
<Slot key={m.id} className={styles.slot} id={m.id} model={m} />
|
<Slot key={m.id} className={styles.slot} id={m.id} model={m} />
|
||||||
@@ -73,3 +70,20 @@ export const makeSpotlightLandscapeLayout: CallLayout<
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
interface SpotlightSlotProps {
|
||||||
|
media$: Behavior<MediaViewModel[]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This component isolates the subscription to the spotlight media so that it
|
||||||
|
// can change without causing the whole layout to re-render
|
||||||
|
const SpotlightSlot: FC<SpotlightSlotProps> = ({ media$ }) => {
|
||||||
|
const withIndicators = useBehavior(media$).length > 1;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={classNames(styles.spotlight, {
|
||||||
|
[styles.withIndicators]: withIndicators,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user