-
Notifications
You must be signed in to change notification settings - Fork 728
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Video 8473 mobile grid mode #681
Changes from all commits
e30bb3f
4b12bcc
d7fa279
b255bf1
d63937b
5860f60
48290f5
1918f2b
b67069a
9cc5bdf
399942c
b4557c8
5aeb1ed
24547e5
d74ff84
073712d
1c09e4c
49beacf
a2bf2e5
277b4aa
84373a8
49f8e12
2a7e387
b6118c6
b033574
c6bcc0a
6635b6c
fa1f5f0
0970696
96cc3f9
1bc7269
b2864a7
18778b4
83d897d
0b710ea
ce1e6bd
fdb76b8
1647b5c
aebc1cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,15 @@ import { shallow } from 'enzyme'; | |
import useHeight from './hooks/useHeight/useHeight'; | ||
import useRoomState from './hooks/useRoomState/useRoomState'; | ||
|
||
jest.mock('swiper/react/swiper-react.js', () => ({ | ||
Swiper: jest.fn(), | ||
SwiperSlide: jest.fn(), | ||
})); | ||
|
||
jest.mock('swiper', () => ({ | ||
Pagination: jest.fn(), | ||
})); | ||
|
||
Comment on lines
+10
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is clearly needed to make the tests pass, but I can't understand why 😭 . Everything is shallow rendered. Do you have any ideas? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Jest is failing due to a syntax error: |
||
jest.mock('./hooks/useRoomState/useRoomState'); | ||
jest.mock('./hooks/useHeight/useHeight'); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { MobileGridView } from './MobileGridView'; | ||
import { shallow } from 'enzyme'; | ||
import { useAppState } from '../../state'; | ||
import useVideoContext from '../../hooks/useVideoContext/useVideoContext'; | ||
|
||
const mockLocalParticipant = { identity: 'test-local-participant', sid: 0 }; | ||
|
||
jest.mock('swiper/react/swiper-react.js', () => ({ | ||
Swiper: jest.fn(), | ||
SwiperSlide: jest.fn(), | ||
})); | ||
|
||
jest.mock('swiper', () => ({ | ||
Pagination: jest.fn(), | ||
})); | ||
|
||
jest.mock('../../hooks/useVideoContext/useVideoContext'); | ||
jest.mock('../../state'); | ||
|
||
const mockUseVideoContext = useVideoContext as jest.Mock<any>; | ||
const mockUseAppState = useAppState as jest.Mock<any>; | ||
|
||
mockUseAppState.mockImplementation(() => ({ maxGridParticipants: 9 })); | ||
mockUseVideoContext.mockImplementation(() => ({ | ||
room: { | ||
localParticipant: mockLocalParticipant, | ||
participants: [], | ||
}, | ||
})); | ||
|
||
describe('the MobileGridView component', () => { | ||
it('should render correctly when there is only the localParticipant', () => { | ||
const wrapper = shallow(<MobileGridView />); | ||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
|
||
it('should render correctly when there is one participant plus the localParticipant', () => { | ||
mockUseVideoContext.mockImplementation(() => ({ | ||
room: { | ||
localParticipant: mockLocalParticipant, | ||
participants: [{ identity: 'test-participant-1', sid: 1 }], | ||
}, | ||
})); | ||
const wrapper = shallow(<MobileGridView />); | ||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
|
||
it('should render correctly when there are two participants plus the localParticipant', () => { | ||
mockUseVideoContext.mockImplementation(() => ({ | ||
room: { | ||
localParticipant: mockLocalParticipant, | ||
participants: [ | ||
{ identity: 'test-participant-1', sid: 1 }, | ||
{ identity: 'test-participant-2', sid: 2 }, | ||
], | ||
}, | ||
})); | ||
const wrapper = shallow(<MobileGridView />); | ||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
|
||
it('should render correctly when there are 3 or more participants plus the localParticipant', () => { | ||
mockUseVideoContext.mockImplementation(() => ({ | ||
room: { | ||
localParticipant: mockLocalParticipant, | ||
participants: [ | ||
{ identity: 'test-participant-1', sid: 1 }, | ||
{ identity: 'test-participant-2', sid: 2 }, | ||
{ identity: 'test-participant-3', sid: 3 }, | ||
{ identity: 'test-participant-4', sid: 4 }, | ||
], | ||
}, | ||
})); | ||
const wrapper = shallow(<MobileGridView />); | ||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { CSSProperties } from 'react'; | ||
import { makeStyles } from '@material-ui/core'; | ||
import Participant from '../Participant/Participant'; | ||
import useDominantSpeaker from '../../hooks/useDominantSpeaker/useDominantSpeaker'; | ||
import useGridParticipants from '../../hooks/useGridParticipants/useGridParticipants'; | ||
import useVideoContext from '../../hooks/useVideoContext/useVideoContext'; | ||
|
||
import { Swiper, SwiperSlide } from 'swiper/react/swiper-react.js'; | ||
import 'swiper/swiper.min.css'; | ||
import 'swiper/modules/pagination/pagination.min.css'; | ||
import { Pagination } from 'swiper'; | ||
import { Participant as IParticipant } from 'twilio-video'; | ||
|
||
const useStyles = makeStyles({ | ||
participantContainer: { | ||
position: 'absolute', | ||
top: 0, | ||
right: 0, | ||
bottom: 0, | ||
left: 0, | ||
height: '100%', | ||
'& .swiper': { | ||
height: '100%', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here I think we need to specify something so that we can see the inactive pagination dots. Digging through devtools, it looks like we can update the
|
||
'--swiper-pagination-bullet-inactive-color': 'white', | ||
}, | ||
'& .swiper-wrapper': { | ||
height: '100%', | ||
}, | ||
'& .swiper-slide': { | ||
height: '90%', // To leave room for the pagination indicators | ||
paddingBottom: '1em', | ||
}, | ||
}, | ||
swiperSlide: { | ||
display: 'flex', | ||
flexWrap: 'wrap', | ||
alignSelf: 'center', | ||
alignContent: 'flex-start', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if alignContent is needed. Is it doing anything? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't look like it. It was at one point when I was messing around with the CSS, but looks like it is useless now 🙂 |
||
}, | ||
}); | ||
|
||
export function MobileGridView() { | ||
const classes = useStyles(); | ||
const { room } = useVideoContext(); | ||
const participants = useGridParticipants(true); | ||
const dominantSpeaker = useDominantSpeaker(true); | ||
const remoteParticipantCount = participants.length; | ||
|
||
const pages: IParticipant[][] = [[]]; | ||
// Add the localParticipant to the front of the array to ensure they are always the first participant: | ||
pages[0].push(room!.localParticipant); | ||
|
||
for (let i = 0; i < remoteParticipantCount; i++) { | ||
const pageNumber = Math.floor(i / 6); | ||
if (!pages[pageNumber]) { | ||
pages[pageNumber] = []; | ||
} | ||
// Each page should have a max of 6 participants: | ||
if (pages[pageNumber].length < 6) { | ||
pages[pageNumber].push(participants[i]); | ||
} else { | ||
pages[pageNumber + 1] = [participants[i]]; | ||
} | ||
} | ||
|
||
const participantVideoStyles: CSSProperties = { | ||
width: remoteParticipantCount < 3 ? '100%' : '50%', | ||
// The height of each participant's video is determined by the number of participants on the grid | ||
// page. Here the array indices represent a remoteParticipantCount. If the count is 4 or greater, | ||
// the height will be 33.33% | ||
height: ['100%', '50%', '33.33%', '50%', '33.33%'][Math.min(remoteParticipantCount, 4)], | ||
padding: '0.2em', | ||
boxSizing: 'border-box', | ||
}; | ||
|
||
return ( | ||
<div className={classes.participantContainer}> | ||
<Swiper pagination={true} modules={[Pagination]} className="mySwiper"> | ||
{pages.map((page, i) => ( | ||
<SwiperSlide key={i} className={classes.swiperSlide}> | ||
{page.map(participant => ( | ||
<div style={participantVideoStyles} key={participant.sid}> | ||
<Participant | ||
participant={participant} | ||
isLocalParticipant={room!.localParticipant === participant} | ||
isDominantSpeaker={dominantSpeaker === participant} | ||
/> | ||
</div> | ||
))} | ||
</SwiperSlide> | ||
))} | ||
</Swiper> | ||
</div> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there package-lock changes to commit?