fix(room): очередь поднятых рук — компактный поповер вместо панели во весь экран

HandQueuePanel рендерился как боковая панель на весь экран на мобильном
(.chat-panel, унаследовано от чата) — для короткого списка поднятых рук это
избыточно, история переписки тут ни при чём. Переделано в HandQueueMenu —
тот же самодостаточный поповер над кнопкой, что и «Вид» (StageViewMenu):
своё состояние открытия, закрытие по клику вне/Escape, .tb-menu вместо
боковой панели. Кнопка «Очередь» больше не получает open-состояние
пропсами сверху — сама решает, открыта ли, и сама проверяет
useIsOrganizer().

Список внутри растёт вместе с очередью (компактно при 1–2 поднятых руках),
но не бесконечно — после ~10 строк упирается в max-height и скроллится
дальше.
This commit is contained in:
2026-08-02 04:58:56 +03:00
parent 826b7639b1
commit d7ae462ed5
5 changed files with 115 additions and 103 deletions

View File

@@ -16,7 +16,6 @@ import { RoomTopbar } from '@/components/room/RoomTopbar'
import { RoomStage } from '@/components/room/RoomStage'
import { RoomToolbar } from '@/components/room/RoomToolbar'
import { ChatPanel } from '@/components/room/ChatPanel'
import { HandQueuePanel } from '@/components/room/HandQueuePanel'
import { ForcedMuteWatcher } from '@/components/room/ForcedMuteWatcher'
import { DeviceSettingsDialog } from '@/components/room/DeviceSettingsDialog'
import { loadAudioOutputDeviceId } from '@/lib/audioOutputDevice'
@@ -147,11 +146,6 @@ export function RoomPage() {
// изначально JoinOut.chat_enabled был true (рассинхрон с админкой в моменте).
const chatVisible = Boolean(joinState?.chatEnabled) && !chat.unavailable
// Панель очереди поднятых рук — открыта/закрыта организатором (задача B1).
// Саму видимость кнопки/панели решает `useIsOrganizer()` внутри
// `RoomToolbar`/`HandQueuePanel` (эти компоненты — дети `LiveKitRoom`, а
// `RoomPage` — нет, `useLocalParticipant` здесь не вызвать).
const [handQueueOpen, setHandQueueOpen] = useState(false)
// Identity участников с поднятой рукой — множеством, для дешёвого `.has()`
// на каждой плитке сцены (см. `RoomParticipantTile`).
const raisedHandIdentities = useMemo(
@@ -304,13 +298,6 @@ export function RoomPage() {
onClose={() => setChatOpen(false)}
/>
)}
{handQueueOpen && (
<HandQueuePanel
queue={chat.handQueue}
onLower={(identity) => chat.lowerHand(identity)}
onClose={() => setHandQueueOpen(false)}
/>
)}
</div>
<RoomToolbar
chatVisible={chatVisible}
@@ -327,8 +314,7 @@ export function RoomPage() {
handQueue={chat.handQueue}
onRaiseHand={chat.raiseHand}
onLowerHand={() => chat.lowerHand()}
handQueueOpen={handQueueOpen}
onToggleHandQueue={() => setHandQueueOpen((open) => !open)}
onLowerHandById={(identity) => chat.lowerHand(identity)}
layoutMode={layoutMode}
onLayoutModeChange={handleLayoutModeChange}
hideOthers={hideOthers}