feat(room): очередь поднятых рук видна всем + отключаемый модуль
Раньше HandQueueMenu.tsx рендерился только организатору — теперь очередь видит любой участник, но опустить чужую руку по-прежнему может только организатор (сервер это уже проверял, менял только фронт). Кнопка «Опустить» показывается у записи, только если это своя рука или пользователь — организатор. Модуль «поднятие руки» (кнопка «Рука» + очередь целиком) — отключаемый в админке (instance_settings.hand_queue, дефолт enabled=true, как у chat_enabled). Настройка едет участнику в JoinOut ещё до входа в комнату; выключенный модуль гасит кнопки и на фронте, и на бэке — raise_hand/lower_hand отклоняются кодом hand_queue_disabled, если модуль выключен, даже если у клиента на руках старый JoinOut.
This commit is contained in:
@@ -146,6 +146,7 @@ export function JoinPage() {
|
||||
title: resolved.title,
|
||||
conferenceId: data.conference_id,
|
||||
chatEnabled: data.chat_enabled,
|
||||
handQueueEnabled: data.hand_queue_enabled,
|
||||
publishQualityCap: data.publish_quality_cap,
|
||||
stageMaxTiles: data.stage_max_tiles,
|
||||
},
|
||||
|
||||
@@ -43,6 +43,7 @@ export function LobbyPage() {
|
||||
title: conference.title,
|
||||
conferenceId: conference.join.conference_id,
|
||||
chatEnabled: conference.join.chat_enabled,
|
||||
handQueueEnabled: conference.join.hand_queue_enabled,
|
||||
publishQualityCap: conference.join.publish_quality_cap,
|
||||
stageMaxTiles: conference.join.stage_max_tiles,
|
||||
number: conference.number,
|
||||
|
||||
@@ -55,6 +55,8 @@ interface RoomJoinState {
|
||||
number?: string
|
||||
/** `JoinOut.chat_enabled` — при `false` кнопка чата и панель не рендерятся. */
|
||||
chatEnabled?: boolean
|
||||
/** `JoinOut.hand_queue_enabled` — при `false` кнопка «Рука» и очередь не рендерятся. */
|
||||
handQueueEnabled?: boolean
|
||||
/**
|
||||
* Рычаги нагрузки медиа (`JoinOut.publish_quality_cap`/`stage_max_tiles`,
|
||||
* `instance_settings.media_limits`) — приезжают вместе с токеном, ДО
|
||||
@@ -208,6 +210,7 @@ export function RoomPage() {
|
||||
title: info.title,
|
||||
conferenceId: result.conference_id,
|
||||
chatEnabled: result.chat_enabled,
|
||||
handQueueEnabled: result.hand_queue_enabled,
|
||||
publishQualityCap: result.publish_quality_cap,
|
||||
stageMaxTiles: result.stage_max_tiles,
|
||||
})
|
||||
@@ -260,10 +263,16 @@ export function RoomPage() {
|
||||
const chatVisible = Boolean(joinState?.chatEnabled) && !chat.unavailable
|
||||
|
||||
// Identity участников с поднятой рукой — множеством, для дешёвого `.has()`
|
||||
// на каждой плитке сцены (см. `RoomParticipantTile`).
|
||||
// на каждой плитке сцены (см. `RoomParticipantTile`). Выключенный модуль
|
||||
// (`handQueueEnabled=false`) гасит и эти значки — иначе на плитке мог бы
|
||||
// повиснуть индикатор от руки, поднятой до отключения модуля (сервер
|
||||
// хранит очередь в Redis независимо от тоггла, см. `services/hand_queue.py`).
|
||||
const raisedHandIdentities = useMemo(
|
||||
() => new Set(chat.handQueue.map((entry) => entry.identity)),
|
||||
[chat.handQueue],
|
||||
() =>
|
||||
joinState?.handQueueEnabled
|
||||
? new Set(chat.handQueue.map((entry) => entry.identity))
|
||||
: new Set<string>(),
|
||||
[chat.handQueue, joinState?.handQueueEnabled],
|
||||
)
|
||||
|
||||
// Корневой контейнер комнаты — цель для fullscreen и источник video-элемента
|
||||
@@ -528,6 +537,7 @@ export function RoomPage() {
|
||||
pipSupported={pip.supported}
|
||||
pipActive={pip.active}
|
||||
onTogglePiP={pip.toggle}
|
||||
handQueueEnabled={Boolean(joinState.handQueueEnabled)}
|
||||
handQueue={chat.handQueue}
|
||||
onRaiseHand={chat.raiseHand}
|
||||
onLowerHand={() => chat.lowerHand()}
|
||||
|
||||
Reference in New Issue
Block a user