feat(room): кнопка демонстрации экрана в мини-окне
В Document PiP (Chrome/Edge) своего тулбара нет, и начать демонстрацию, не свернув мини-окно, было нельзя. Кнопка сделана по образцу кнопки микрофона, добавленной в 0.0.15: тот же `useTrackToggle` через `RoomContext`, поэтому она и кнопка основного тулбара — два вида одного состояния и рассинхрону взяться неоткуда. Главный вопрос задачи — пустит ли платформа `getDisplayMedia()`, вызванный из кода основного окна по клику в ДРУГОМ окне. Замер в Chrome 150: после клика в PiP `navigator.userActivation.isActive === true` в обоих окнах, активация доезжает до опенера, вызов проходит, системный пикер выбора экрана открывается отдельным окном поверх всего, а не прячется за заглушкой основного окна. Опции захвата (`SCREEN_SHARE_CAPTURE_OPTIONS`) вынесены из `RoomToolbar` в `lib/screenShareOptions.ts`: кнопок демонстрации теперь две, и разойдись они хотя бы в `audio`, демонстрация получалась бы разной в зависимости от того, откуда её запустили. Фокус в мини-окне не менялся: своя демонстрация показывается по тем же правилам `pickStageFocus`, что и в основном окне. В Safari мини-окно — нативный video-PiP без собственного DOM, кнопке там негде жить; в Firefox мини-окна нет вовсе. Это ограничение платформы.
This commit is contained in:
@@ -13,33 +13,14 @@ import {
|
||||
Video,
|
||||
VideoOff,
|
||||
} from 'lucide-react'
|
||||
import { Track, type ScreenShareCaptureOptions } from 'livekit-client'
|
||||
import { Track } from 'livekit-client'
|
||||
import { DisconnectButton, useLocalParticipant, useTrackToggle } from '@livekit/components-react'
|
||||
import { useToast } from '@/components/ui/ToastProvider'
|
||||
import { useIsCompactViewport } from '@/hooks/useIsCompactViewport'
|
||||
import type { HandQueueEntry } from '@/hooks/useChat'
|
||||
import { StageViewMenu, type StageViewProps } from '@/components/room/StageViewOptions'
|
||||
import { HandQueueMenu } from '@/components/room/HandQueueMenu'
|
||||
|
||||
/**
|
||||
* Опции захвата демонстрации экрана: `audio: true` — звук
|
||||
* вкладки/экрана там, где браузер его отдаёт (Chrome/Edge — вкладка почти
|
||||
* всегда, целый экран — только Windows); `selfBrowserSurface: 'exclude'`
|
||||
* — не предлагать в списке
|
||||
* источников собственную вкладку (зеркальный туннель самой конференции);
|
||||
* `surfaceSwitching: 'include'` — разрешить переключать источник прямо во
|
||||
* время демонстрации, не останавливая её; `systemAudio: 'include'` — не
|
||||
* запрещать захват системного звука при выборе «весь экран». Вынесено в
|
||||
* модульную константу — `useTrackToggle` держит `JSON.stringify(captureOptions)`
|
||||
* в зависимостях внутреннего `useMemo`, инлайновый литерал был бы безвреден,
|
||||
* но константа явнее фиксирует неизменность опций.
|
||||
*/
|
||||
const SCREEN_SHARE_CAPTURE_OPTIONS: ScreenShareCaptureOptions = {
|
||||
audio: true,
|
||||
selfBrowserSurface: 'exclude',
|
||||
surfaceSwitching: 'include',
|
||||
systemAudio: 'include',
|
||||
}
|
||||
import { SCREEN_SHARE_CAPTURE_OPTIONS } from '@/lib/screenShareOptions'
|
||||
|
||||
interface RoomToolbarProps extends StageViewProps {
|
||||
/** Показывать ли кнопку чата — `JoinOut.chat_enabled` И чат не помечен недоступным (close-код 4404). */
|
||||
|
||||
Reference in New Issue
Block a user