Refactor SessionUsersPanel to optimize performance with useMemo for active cameras count, grid columns, grid rows, and active participants filtering. Update useWebRTC to prevent unnecessary state updates for participant stream, audio, video, and speaking state changes. Clean up SessionPage layout for consistency.

This commit is contained in:
2025-10-30 18:07:36 +05:00
parent 5ed01c6f6e
commit af4ca0637a
3 changed files with 70 additions and 45 deletions
+33 -22
View File
@@ -1,3 +1,4 @@
import { useMemo } from "react";
import UserCamera from "./ui/UserCamera";
import UserDevicesControls from "./ui/UserDevicesControls";
import DraggableContainer from "./DraggableContainer";
@@ -32,26 +33,42 @@ function SessionUsersPanel({
updateSpeakingState?.(isSpeaking);
};
// Вычисляем количество камер для grid
const activeCamerasCount =
(localStream ? 8 : 0) +
participants.filter(
(p) => p.stream != null && p.stream.getTracks().length > 0
).length;
// Вычисляем количество камер для grid - мемоизируем для избежания лишних вычислений
const activeCamerasCount = useMemo(
() =>
(localStream ? 1 : 0) +
participants.filter(
(p) => p.stream != null && p.stream.getTracks().length > 0
).length,
[localStream, participants]
);
// Определяем количество колонок в зависимости от количества камер
// 1-2 камеры: 1 колонка (друг под другом), 3-4: 2 колонки, 5-9: 3 колонки, 10-16: 4 колонки, 17-25: 5 колонок
const getGridColumns = (count: number): number => {
if (count <= 2) return 1;
if (count <= 4) return 2;
if (count <= 9) return 3;
if (count <= 16) return 4;
const gridColumns = useMemo(() => {
if (activeCamerasCount <= 2) return 1;
if (activeCamerasCount <= 4) return 2;
if (activeCamerasCount <= 9) return 3;
if (activeCamerasCount <= 16) return 4;
return 5;
};
const gridColumns = getGridColumns(activeCamerasCount);
}, [activeCamerasCount]);
// Вычисляем количество рядов для правильного расчета высоты
const gridRows = Math.ceil(activeCamerasCount / gridColumns);
const gridRows = useMemo(
() => Math.ceil(activeCamerasCount / gridColumns),
[activeCamerasCount, gridColumns]
);
// Фильтруем участников с активными потоками - мемоизируем для избежания лишних фильтраций
const activeParticipants = useMemo(
() =>
participants.filter(
(participant) =>
participant.stream != null &&
participant.stream.getTracks().length > 0
),
[participants]
);
// Рендерим камеры
const camerasContent = (
@@ -75,13 +92,7 @@ function SessionUsersPanel({
)}
{/* Камеры удаленных участников - показываем только если есть поток с активными треками */}
{participants
.filter(
(participant) =>
participant.stream != null &&
participant.stream.getTracks().length > 0
)
.map((participant) => (
{activeParticipants.map((participant) => (
<UserCamera
key={participant.id}
mode={mode}