diff --git a/frontend/src/components/room/RoomParticipantTile.tsx b/frontend/src/components/room/RoomParticipantTile.tsx index e9937b4..d08e07d 100644 --- a/frontend/src/components/room/RoomParticipantTile.tsx +++ b/frontend/src/components/room/RoomParticipantTile.tsx @@ -1,4 +1,4 @@ -import { ScreenShare } from 'lucide-react' +import { Pin, PinOff, ScreenShare } from 'lucide-react' import { Track } from 'livekit-client' import { AudioTrack, @@ -19,6 +19,7 @@ import { type TrackReferenceOrPlaceholder, } from '@livekit/components-react' import { Avatar } from '@/components/ui/Avatar' +import { stageTrackKey } from '@/components/room/stageFocus' /** Метаданные участника из LiveKit access-токена (см. `AccessToken.with_metadata` на backend) — JSON `{"avatar_url": "..."}`; у гостей отсутствуют. */ interface ParticipantMetadata { @@ -43,7 +44,7 @@ function parseAvatarUrl(metadata: string | undefined): string | null { * разметке (см. `node_modules/@livekit/components-react/src/components/participant/ParticipantTile.tsx`, * версия 2.9.23 — источник этой копии). */ -function TileBody({ onStopSharing }: { onStopSharing?: () => void }) { +function TileBody({ onStopSharing, pinnedKey, onTogglePin }: TileControlsProps) { const trackReference = useEnsureTrackRef() const isEncrypted = useIsEncrypted(trackReference.participant) const autoManageSubscription = useFeatureContext()?.autoSubscription @@ -60,6 +61,12 @@ function TileBody({ onStopSharing }: { onStopSharing?: () => void }) { const showSharingChip = Boolean( onStopSharing && trackReference.source === Track.Source.ScreenShare && trackReference.participant.isLocal, ) + // Кнопка закрепления — только там, где сцена умеет закрепление (основное + // окно передаёт `onTogglePin`; в мини-плеере плитка одна, закреплять нечего). + // Ключ плитки берём из её собственного трека: в карусели/гриде плитки + // рендерятся шаблоном без пропсов, снаружи «какая это плитка» не передать. + const tileKey = stageTrackKey(trackReference) + const isPinned = pinnedKey === tileKey return ( <> @@ -106,6 +113,25 @@ function TileBody({ onStopSharing }: { onStopSharing?: () => void }) { + {onTogglePin && ( + + )} {showSharingChip && (