Fix issue with screen share

This commit is contained in:
harshithpabbati 2022-01-07 14:17:08 +05:30
parent 1ae4de54f2
commit 3d7ee93fb3
8 changed files with 186 additions and 34 deletions

View File

@ -1,12 +1,17 @@
import React from 'react';
import React, { useEffect } from 'react';
import { useParticipants } from '@custom/shared/contexts/ParticipantsProvider';
import { useUIState, VIEW_MODE_SPEAKER } from '@custom/shared/contexts/UIStateProvider';
import { GridView } from '../GridView/GridView';
import { SpeakerView } from '../SpeakerView';
export const VideoView = () => {
const { viewMode } = useUIState();
const { participants } = useParticipants();
const { viewMode, setIsShowingScreenshare } = useUIState();
const { participants, screens } = useParticipants();
useEffect(() => {
const hasScreens = screens.length > 0;
setIsShowingScreenshare(hasScreens);
}, [screens, setIsShowingScreenshare]);
if (!participants.length) return null;
return viewMode === VIEW_MODE_SPEAKER ? <SpeakerView />: <GridView />;

View File

@ -295,25 +295,25 @@ export const GridView = ({
return (
<div ref={gridRef} className="grid">
<Button
className="page-button prev"
disabled={!(pages > 1 && page > 1)}
type="button"
onClick={handlePrevClick}
>
<IconArrow />
</Button>
{(pages > 1 && page > 1) && (
<Button
className="page-button prev"
type="button"
onClick={handlePrevClick}
>
<IconArrow />
</Button>
)}
<div className="tiles">{tiles}</div>
<Button
className="page-button next"
disabled={!(pages > 1 && page < pages)}
type="button"
onClick={handleNextClick}
>
<IconArrow />
</Button>
{(pages > 1 && page < pages) && (
<Button
className="page-button next"
type="button"
onClick={handleNextClick}
>
<IconArrow />
</Button>
)}
<style jsx>{`
.grid {

View File

@ -0,0 +1,42 @@
import { useState } from 'react';
import Tile from '@custom/shared/components/Tile';
export const ScreenPinTile = ({
height,
hideName = false,
item,
maxWidth,
ratio: initialRatio,
}) => {
const [ratio, setRatio] = useState(initialRatio);
const handleResize = (aspectRatio) => setRatio(aspectRatio);
if (item.isScreenshare) {
return (
<Tile
aspectRatio={initialRatio}
hideName={hideName}
participant={item}
mirrored={false}
style={{
height,
maxWidth,
}}
/>
);
}
return (
<Tile
aspectRatio={ratio}
participant={item}
onVideoResize={handleResize}
style={{
maxHeight: height,
maxWidth: height * ratio,
}}
/>
);
};
export default ScreenPinTile;

View File

@ -0,0 +1,105 @@
import { useMemo, useRef, useState } from 'react';
import { useCallState } from '@custom/shared/contexts/CallProvider';
import { useUIState } from '@custom/shared/contexts/UIStateProvider';
import { useResize } from '@custom/shared/hooks/useResize';
import { useDeepCompareMemo } from 'use-deep-compare';
import { ScreenPinTile } from './ScreenPinTile';
const MAX_SCREENS_AND_PINS = 3;
export const ScreensAndPins = ({ items }) => {
const { showNames } = useCallState();
const { pinnedId, sidebarView } = useUIState();
const viewRef = useRef(null);
const [dimensions, setDimensions] = useState({
width: 1,
height: 1,
});
useResize(() => {
const { width, height } = viewRef.current?.getBoundingClientRect();
setDimensions({
width,
height,
});
}, [viewRef, sidebarView]);
const visibleItems = useDeepCompareMemo(() => {
const isPinnedScreenshare = ({ id, isScreenshare }) =>
isScreenshare && id === pinnedId;
if (items.some(isPinnedScreenshare)) {
return items.filter(isPinnedScreenshare);
}
return items;
}, [items, pinnedId]);
const { height, maxWidth, aspectRatio } = useMemo(() => {
/**
* We're relying on calculating what there is room for
* for the total number of s+p tiles instead of using
* videoTrack.getSettings because (currently) getSettings
* is unreliable in Firefox.
*/
const containerAR = dimensions.width / dimensions.height;
const maxItems = Math.min(visibleItems.length, MAX_SCREENS_AND_PINS);
const cols = Math.min(maxItems, Math.ceil(containerAR));
const rows = Math.ceil(visibleItems.length / cols);
const height = dimensions.height / rows;
const maxWidth = dimensions.width / cols;
return {
height,
maxWidth,
aspectRatio: maxWidth / height,
};
}, [dimensions, visibleItems?.length]);
return (
<div ref={viewRef}>
{visibleItems.map((item) => (
<div
className="tileWrapper"
key={item.id}
style={{
height,
maxWidth,
}}
>
<ScreenPinTile
height={height}
hideName={!showNames}
item={item}
maxWidth={maxWidth}
ratio={aspectRatio}
/>
</div>
))}
<style jsx>{`
div {
align-items: center;
display: flex;
flex-wrap: wrap;
height: 100%;
justify-content: center;
width: 100%;
}
div :global(.tileWrapper) {
background: var(--background);
align-items: center;
display: flex;
flex: none;
justify-content: center;
position: relative;
width: 100%;
}
div :global(.tile .content) {
margin: auto;
max-height: 100%;
max-width: 100%;
}
`}</style>
</div>
);
};
export default ScreensAndPins;

View File

@ -0,0 +1 @@
export { ScreensAndPins } from './ScreensAndPins';

View File

@ -18,10 +18,7 @@ export const SpeakerTile = ({ participant, screenRef }) => {
setScreenHeight(rect.height);
}, [screenRef]);
useResize(() => {
updateRatio();
}, [updateRatio]);
useResize(() => updateRatio(), [updateRatio]);
useEffect(() => updateRatio(), [updateRatio]);
/**

View File

@ -1,13 +1,11 @@
import React, { useEffect, useMemo, useRef } from 'react';
import { Container } from '@custom/basic-call/components/Call/Container';
import Header from '@custom/basic-call/components/Call/Header';
import ParticipantBar from '@custom/shared/components/ParticipantBar/ParticipantBar';
import VideoContainer from '@custom/shared/components/VideoContainer/VideoContainer';
import { useCallState } from '@custom/shared/contexts/CallProvider';
import { useParticipants } from '@custom/shared/contexts/ParticipantsProvider';
import { useTracks } from '@custom/shared/contexts/TracksProvider';
import { useUIState } from '@custom/shared/contexts/UIStateProvider';
import { isScreenId } from '@custom/shared/contexts/participantsState';
import { ScreensAndPins } from './ScreensAndPins';
import { SpeakerTile } from './SpeakerTile';
const SIDEBAR_WIDTH = 186;
@ -40,10 +38,10 @@ export const SpeakerView = () => {
return participants.length > 1 || hasScreenshares;
}, [participants, pinnedId, screens]);
/* const screenShareTiles = useMemo(
const screenShareTiles = useMemo(
() => <ScreensAndPins items={screensAndPinned} />,
[screensAndPinned]
); */
);
const hasScreenshares = useMemo(() => screens.length > 0, [screens]);
@ -80,7 +78,11 @@ export const SpeakerView = () => {
return (
<div className="speaker-view">
<div ref={activeRef} className="active">
<SpeakerTile participant={currentSpeaker} screenRef={activeRef} />
{screensAndPinned.length > 0 ? (
screenShareTiles
) : (
<SpeakerTile screenRef={activeRef} participant={currentSpeaker} />
)}
</div>
{showSidebar && (
<ParticipantBar

View File

@ -10,14 +10,14 @@ export const ViewTray = () => {
const { participants } = useParticipants();
const { viewMode, setPreferredViewMode } = useUIState();
const onClick = () =>
setPreferredViewMode(viewMode === VIEW_MODE_SPEAKER ? VIEW_MODE_GRID: VIEW_MODE_SPEAKER);
const onViewClick = () =>
setPreferredViewMode(viewMode === VIEW_MODE_SPEAKER ? VIEW_MODE_GRID : VIEW_MODE_SPEAKER);
return (
<TrayButton
label={viewMode === VIEW_MODE_GRID ? 'Speaker': 'Grid'}
disabled={participants.length < 2}
onClick={onClick}
onClick={onViewClick}
>
{viewMode === VIEW_MODE_SPEAKER ? <IconGridView />: <IconSpeakerView />}
</TrayButton>