@@ -128,7 +128,8 @@ export default class CallCard extends React.Component {
128128 meetingMediaAccess : {
129129 isAudioPermitted : meetingMediaAccess ?. isAudioPermitted ,
130130 isVideoPermitted : meetingMediaAccess ?. isVideoPermitted ,
131- }
131+ } ,
132+ showPin2VideosList : false ,
132133 } ;
133134 this . selectedRemoteParticipants = new Set ( ) ;
134135 this . dataChannelRef = React . createRef ( ) ;
@@ -1387,6 +1388,27 @@ export default class CallCard extends React.Component {
13871388 this . call . setConstraints ( constraints ) ;
13881389 }
13891390
1391+ handleVideoPin = ( streamTuple , e ) => {
1392+ // e.preventDefault();
1393+ const checked = e . target . checked ;
1394+ const allRemoteParticipantStreams = this . state . allRemoteParticipantStreams ;
1395+ if ( allRemoteParticipantStreams . filter ( streamTuple => streamTuple . isPinned ) . length >= 2 && checked ) {
1396+ return ;
1397+ }
1398+
1399+ allRemoteParticipantStreams . forEach ( v => {
1400+ if ( streamTuple === v ) {
1401+ v . isPinned = checked ;
1402+ } else {
1403+ v . isPinned = ! ! v . isPinned ;
1404+ }
1405+ } ) ;
1406+
1407+ this . setState ( { allRemoteParticipantStreams : allRemoteParticipantStreams } , ( ) => {
1408+ this . updateListOfParticipantsToRender ( 'Pinned videos changed' ) ;
1409+ } ) ;
1410+ }
1411+
13901412 render ( ) {
13911413 const emojis = [ '👍' , '❤️' , '😂' , '👏' , '😲' ] ;
13921414 const streamCount = this . state . allRemoteParticipantStreams . length ;
@@ -1433,7 +1455,7 @@ export default class CallCard extends React.Component {
14331455 < div className = "ms-Grid-row" >
14341456 {
14351457 this . state . callState === 'Connected' && this . state . isShowParticipants &&
1436- < div className = "ms-Grid-col ms-lg4 " >
1458+ < div className = "ms-Grid-col ms-lg12 " >
14371459 < div >
14381460 { this . state . showAddParticipantPanel &&
14391461 < AddParticipantPopover call = { this . call } />
@@ -1473,47 +1495,46 @@ export default class CallCard extends React.Component {
14731495
14741496 </ div >
14751497 }
1476- < div className = { this . state . isShowParticipants ? "ms-Grid-col ms-lg8" : undefined } >
1477- < div className = "video-grid-row" >
1478- {
1479- ( this . state . callState === 'Connected' ||
1480- this . state . callState === 'LocalHold' ||
1481- this . state . callState === 'RemoteHold' ) &&
1482- this . state . allRemoteParticipantStreams . map ( v =>
1483- < StreamRenderer
1484- key = { `${ utils . getIdentifierText ( v . participant . identifier ) } -${ v . stream . mediaStreamType } -${ v . stream . id } ` }
1485- ref = { v . streamRendererComponentRef }
1486- stream = { v . stream }
1487- remoteParticipant = { v . participant }
1488- dominantSpeakerMode = { this . state . dominantSpeakerMode }
1489- dominantRemoteParticipant = { this . state . dominantRemoteParticipant }
1490- call = { this . call }
1491- showMediaStats = { this . state . logMediaStats }
1492- streamCount = { streamCount }
1493- />
1494- )
1495- }
1496- {
1497- (
1498- this . state . remoteScreenShareStream &&
1499- < StreamRenderer
1500- key = { `${ utils . getIdentifierText ( this . state . remoteScreenShareStream . participant . identifier ) } -${ this . state . remoteScreenShareStream . stream . mediaStreamType } -${ this . state . remoteScreenShareStream . stream . id } ` }
1501- ref = { this . state . remoteScreenShareStream . streamRendererComponentRef }
1502- stream = { this . state . remoteScreenShareStream . stream }
1503- remoteParticipant = { this . state . remoteScreenShareStream . participant }
1504- dominantSpeakerMode = { this . state . dominantSpeakerMode }
1505- dominantRemoteParticipant = { this . state . dominantRemoteParticipant }
1506- call = { this . call }
1507- showMediaStats = { this . state . logMediaStats }
1508- streamCount = { streamCount }
1509- />
1510- )
1511- }
1512- </ div >
1498+ < div >
1499+ {
1500+ this . state . remoteScreenShareStream &&
1501+ < StreamRenderer
1502+ key = { `${ utils . getIdentifierText ( this . state . remoteScreenShareStream . participant . identifier ) } -${ this . state . remoteScreenShareStream . stream . mediaStreamType } -${ this . state . remoteScreenShareStream . stream . id } ` }
1503+ ref = { this . state . remoteScreenShareStream . streamRendererComponentRef }
1504+ stream = { this . state . remoteScreenShareStream . stream }
1505+ remoteParticipant = { this . state . remoteScreenShareStream . participant }
1506+ dominantSpeakerMode = { this . state . dominantSpeakerMode }
1507+ dominantRemoteParticipant = { this . state . dominantRemoteParticipant }
1508+ call = { this . call }
1509+ showMediaStats = { this . state . logMediaStats }
1510+ streamCount = { streamCount }
1511+ />
1512+ }
1513+ </ div >
1514+ < div className = "video-grid-row" >
1515+ {
1516+ ( this . state . callState === 'Connected' ||
1517+ this . state . callState === 'LocalHold' ||
1518+ this . state . callState === 'RemoteHold' ) &&
1519+ this . state . allRemoteParticipantStreams . map ( v =>
1520+ < StreamRenderer
1521+ key = { `${ utils . getIdentifierText ( v . participant . identifier ) } -${ v . stream . mediaStreamType } -${ v . stream . id } ` }
1522+ ref = { v . streamRendererComponentRef }
1523+ stream = { v . stream }
1524+ isPinned = { v . isPinned }
1525+ remoteParticipant = { v . participant }
1526+ dominantSpeakerMode = { this . state . dominantSpeakerMode }
1527+ dominantRemoteParticipant = { this . state . dominantRemoteParticipant }
1528+ call = { this . call }
1529+ showMediaStats = { this . state . logMediaStats }
1530+ streamCount = { streamCount }
1531+ />
1532+ )
1533+ }
15131534 </ div >
15141535 </ div >
15151536 < div className = "ms-Grid-row" >
1516- < div className = "text-center" >
1537+ < div className = "text-center mt-4 " >
15171538 < span className = "in-call-button"
15181539 title = { `${ this . state . canOnVideo ? ( this . state . videoOn ? 'Turn your video off' : 'Turn your video on' ) : 'Video is disabled' } ` }
15191540 variant = "secondary"
@@ -1748,7 +1769,15 @@ export default class CallCard extends React.Component {
17481769 variant = "secondary"
17491770 onClick = { ( ) => this . handleRaiseHand ( ) } >
17501771 < Icon iconName = "HandsFree" className = { this . state . isHandRaised ? "callFeatureEnabled" : `` } />
1751- </ span >
1772+ </ span >
1773+ }
1774+ {
1775+ < span className = "in-call-button"
1776+ title = { `Pin 2 videos` }
1777+ variant = "secondary"
1778+ onClick = { ( ) => this . setState ( { showPin2VideosList : ! this . state . showPin2VideosList } ) } >
1779+ < Icon iconName = "Pinned" />
1780+ </ span >
17521781 }
17531782 < span className = "in-call-button"
17541783 title = 'Like Reaction'
@@ -2076,7 +2105,29 @@ export default class CallCard extends React.Component {
20762105 </ div >
20772106 </ div >
20782107 }
2108+ {
2109+ this . state . showPin2VideosList &&
2110+ < div className = "mt-5" >
2111+ < div >
2112+ < h3 >
2113+ Pin 2 videos
2114+ </ h3 >
2115+ </ div >
2116+ < div >
2117+ { this . state . allRemoteParticipantStreams . map ( ( streamTuple ) => (
2118+ < div key = { utils . getIdentifierText ( streamTuple . participant . identifier ) } >
2119+ < input
2120+ type = "checkbox"
2121+ checked = { streamTuple . isPinned }
2122+ onChange = { ( e ) => this . handleVideoPin ( streamTuple , e ) }
2123+ />
2124+ { utils . getIdentifierText ( streamTuple . participant . identifier ) }
2125+ </ div >
2126+ ) ) }
2127+ </ div >
2128+ </ div >
2129+ }
20792130 </ div >
20802131 ) ;
20812132 }
2082- }
2133+ }
0 commit comments