Skip to content

Commit 9dab5ba

Browse files
author
timmydoza
authored
Handle screenshare in grid mode (#683)
* Fix linter error * Update code formatting
1 parent e4e1ffd commit 9dab5ba

File tree

2 files changed

+74
-11
lines changed

2 files changed

+74
-11
lines changed

src/components/Room/Room.test.tsx

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import React from 'react';
22
import { shallow } from 'enzyme';
3+
import { renderHook } from '@testing-library/react-hooks';
34

4-
import Room from './Room';
5+
import Room, { useSetCollaborationViewOnScreenShare } from './Room';
56
import useChatContext from '../../hooks/useChatContext/useChatContext';
67
import useVideoContext from '../../hooks/useVideoContext/useVideoContext';
78
import { useAppState } from '../../state';
@@ -64,3 +65,46 @@ describe('the Room component', () => {
6465
expect(wrapper.find('GridView').exists()).toBe(true);
6566
});
6667
});
68+
69+
describe('the useSetCollaborationViewOnScreenShare hook', () => {
70+
const mockSetIsGridModeActive = jest.fn();
71+
beforeEach(jest.clearAllMocks);
72+
73+
it('should not deactivate grid mode when there is no screen share participant', () => {
74+
renderHook(() =>
75+
useSetCollaborationViewOnScreenShare(undefined, { localParticipant: {} } as any, mockSetIsGridModeActive)
76+
);
77+
expect(mockSetIsGridModeActive).not.toBeCalled();
78+
});
79+
80+
it('should deactivate grid mode when a remote participant shares their screen', () => {
81+
const { rerender } = renderHook(
82+
({ screenShareParticipant }) =>
83+
useSetCollaborationViewOnScreenShare(
84+
screenShareParticipant,
85+
{ localParticipant: {} } as any,
86+
mockSetIsGridModeActive
87+
),
88+
{ initialProps: { screenShareParticipant: undefined } }
89+
);
90+
expect(mockSetIsGridModeActive).not.toBeCalled();
91+
rerender({ screenShareParticipant: {} } as any);
92+
expect(mockSetIsGridModeActive).toBeCalledWith(false);
93+
});
94+
95+
it('should not deactivate grid mode when the local participant shares their screen', () => {
96+
const mockLocalParticipant = {};
97+
const { rerender } = renderHook(
98+
({ screenShareParticipant }) =>
99+
useSetCollaborationViewOnScreenShare(
100+
screenShareParticipant,
101+
{ localParticipant: mockLocalParticipant } as any,
102+
mockSetIsGridModeActive
103+
),
104+
{ initialProps: { screenShareParticipant: undefined } }
105+
);
106+
expect(mockSetIsGridModeActive).not.toBeCalled();
107+
rerender({ screenShareParticipant: mockLocalParticipant } as any);
108+
expect(mockSetIsGridModeActive).not.toBeCalled();
109+
});
110+
});

src/components/Room/Room.tsx

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
import React from 'react';
1+
import React, { useEffect } from 'react';
2+
import BackgroundSelectionDialog from '../BackgroundSelectionDialog/BackgroundSelectionDialog';
3+
import ChatWindow from '../ChatWindow/ChatWindow';
24
import clsx from 'clsx';
5+
import { GridView } from '../GridView/GridView';
6+
import { MobileGridView } from '../MobileGridView/MobileGridView';
7+
import MainParticipant from '../MainParticipant/MainParticipant';
38
import { makeStyles, Theme, useMediaQuery, useTheme } from '@material-ui/core';
4-
import ChatWindow from '../ChatWindow/ChatWindow';
9+
import { Participant, Room as IRoom } from 'twilio-video';
10+
import { ParticipantAudioTracks } from '../ParticipantAudioTracks/ParticipantAudioTracks';
511
import ParticipantList from '../ParticipantList/ParticipantList';
6-
import MainParticipant from '../MainParticipant/MainParticipant';
7-
import BackgroundSelectionDialog from '../BackgroundSelectionDialog/BackgroundSelectionDialog';
12+
import { useAppState } from '../../state';
813
import useChatContext from '../../hooks/useChatContext/useChatContext';
14+
import useScreenShareParticipant from '../../hooks/useScreenShareParticipant/useScreenShareParticipant';
915
import useVideoContext from '../../hooks/useVideoContext/useVideoContext';
10-
import { ParticipantAudioTracks } from '../ParticipantAudioTracks/ParticipantAudioTracks';
11-
import { GridView } from '../GridView/GridView';
12-
import { MobileGridView } from '../MobileGridView/MobileGridView';
13-
import { useAppState } from '../../state';
1416

1517
const useStyles = makeStyles((theme: Theme) => {
1618
const totalMobileSidebarHeight = `${theme.sidebarMobileHeight +
@@ -32,13 +34,30 @@ const useStyles = makeStyles((theme: Theme) => {
3234
};
3335
});
3436

37+
export function useSetCollaborationViewOnScreenShare(
38+
screenShareParticipant: Participant | undefined,
39+
room: IRoom | null,
40+
setIsGridModeActive: React.Dispatch<React.SetStateAction<boolean>>
41+
) {
42+
useEffect(() => {
43+
if (screenShareParticipant && screenShareParticipant !== room!.localParticipant) {
44+
setIsGridModeActive(false);
45+
}
46+
}, [screenShareParticipant, setIsGridModeActive, room]);
47+
}
48+
3549
export default function Room() {
3650
const classes = useStyles();
3751
const { isChatWindowOpen } = useChatContext();
38-
const { isBackgroundSelectionOpen } = useVideoContext();
39-
const { isGridModeActive } = useAppState();
52+
const { isBackgroundSelectionOpen, room } = useVideoContext();
53+
const { isGridModeActive, setIsGridModeActive } = useAppState();
4054
const theme = useTheme();
4155
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
56+
const screenShareParticipant = useScreenShareParticipant();
57+
58+
// Here we switch to collaboration view when a participant starts sharing their screen, but
59+
// the user is still free to switch back to grid mode.
60+
useSetCollaborationViewOnScreenShare(screenShareParticipant, room, setIsGridModeActive);
4261

4362
return (
4463
<div

0 commit comments

Comments
 (0)