Skip to content

Commit

Permalink
Implement Go Room Type Support and a Design Refresh (#316)
Browse files Browse the repository at this point in the history
* Update settings menu with new styles

* Add dominant speaker border color to ParticipantStrip

* Change app layout so participant list is on the right

* Rename ParticipantStrip to ParticipantList

* Don't show the localParticipant's screen share

* Fix problems with displaying video thumbnails with the correct aspect ratio

* Change objectFit of videoTracks

* Add some new icons

* Update fonts in Menu

* Move useScreenShareToggle to VideoContext

* Add tooltip back to ScreenShareButton

* Change MainParticipant so that videoPriority doesnt change when the main participant doesnt change

* Add screen share banner to MenuBar

* Change layout when there is a remote participant sharing their screen

* Small adjustments

* Update pin icon

* Update AudioLevelIndicator to use new icons

* Remove unneeded theme from login page

* Add new Audio icons

* Update video icons

* Change all fill-rule attributes to fillRule

* Add color for dominant speaker border

* Increase sidebar width

* Remove test code from MenuBar

* Add avatar icon to participants with no video

* Create IntroContainer component

* Add IntroContainer component to login page

* Remove unneeded styles from the login page

* Fix networkQualityTests

* Rename NewtorkQualityLevel to NetworkQualityLevel

* Pass isLocalParticipant as prop instead of using useVideoContext

* Add isLocalParticipant to local participant

* Update ParticipantInfo tests

* Update MainParticipantInfo tests

* Update tests for ParticipantList

* update Publication tests

* Update useScreenShareToggleTests

* Add prop to AudioLevelIndicator to change fill

* Apply new designs to device selection dialog

* Remove displayName from menu

* Move buttons into menubar folder

* Remove testing code

* Add color to mic off icon in AudioLevelIndicator

* Move AvatarIcon to new location

* Remove unused variable

* Fix AudioLevelIndicator tests

* Fix ParticipantInfo components

* Fix MainParticipant tests

* Clean up tests for AudioLevelIndicator

* Fix VideoTrack tests

* Fix test for Buttons

* Fix tests for Menu component

* Delete tests for MenuBar component

The pre-join experience will be completemly changed in a future PR, and these MenuBar tests will not be needed. Because of this, I'm removing them instead of fixing them.

* Remove green border from dominant speaker

* Fix issue with scroll container

* Improve color of disabled screenshare button

* Move and update LocalVideoPreview component

* Update Audio and Video toggle buttons to accept new classNames

* Add RoomName and DeviceSelection screens

* Remove Logout option from Menu

* Cleanup Menu Component

* Remove unneeded code from MenuBar component

* Add UserMenu to IntroContainer

* Add subContent container to IntroContainer

* Create useGetPreflightTokens
Install nanoid
Install SDK branch with preflight

* Create usePreflightTest and add types

* Create getNetworkCondition function and tests

* Add SuccessIcon and ProgressIndicator

* Create PreflightTest component

* Add PreflightTest to PreJoinScreens

* Move Icons to icon directory

* Add screenShare icon to participantInfo

* Pass isLocalParticipant to ParticipantInfo

* Fix Button tests as icons have been moved to new directory

* Fix ParticipantList tests

* Fix ParticipantTracks tests

* Fix ParticipantInfo tests

* Fix VideoProvider tests

* Add icons to preflighttest

* Add isTurnRequired to PreflightTestReport

* Adding preflight dependency

* update lock file

* Update lockfile

* lockfile

* Fixing signin if using passcode auth

* Change swoosh svg from React component to svg file

* Apply basic mobile styles to prejoin screens

* Fix in-room grid layout for mobile

* Create MobileTopMenuBar component

* Add mobile styles to MenuBar to hide buttons

* AHOYAPPS-733 Pass LocalTracks to ConnectOptions and disable audio/video toggling.

* Update FlipCameraButton with new icon and text

* Use better variable names

* Remove extra form element from LoginPage

* Update LoginPage tests

* Update LocalVideoPreview tests

* Update menu tests

* Add tests for IntroContainer

* Update tests for UserMenu

* Add new tests for MenuBar component

* Add tests for PreJoinScreens component

* Add tests to RoomNameScreen

* Add tests for the DeviceSelectionScreen

* Add tests for App.tsx

* Add test for PreJoinScreens component

* AHOYAPPS-733 Incorporating feedback from @tmendoza.

* Use better variable names in getNetworkCondition

* Use better variable names in useGetPreflightTokens

* Update progressIndicator style

* Add tests for ProgressIndicator

* Fix issue in PreJoinScreens and add test

* Update MainParticipant so it adds the isLocalParitcipant prop

* Add tests for useGetPreflightTokens hook

* Change rendering and unmounting logic for PreflightTest component

* Fix issue in PreJoinScreens and write test

* Add localTracks to dependency array in useRoom hook

* Update tests for useRoom

* Add tests for usePreflightTest hook

* Add tests for PreflightTest component

* Add tests for DeviceSelectionScreen

* Fix type declaration for the preflightTest

* Remove ensureMediaPermissions as it appears to be unnecessary

* Create custom SnackBar component

* Create component for MediaError snackbars

* Acquire media on deviceSelectionPage, not app load

* Fix small issue in error dialog

* Move deviceHooks file and add new hooks

* Disable toggle buttons when there are no devices

* Adjust paths

* Fix issue in snackbar

* Add error cases to MediaErrorSnackBar

* Apply style improvements to the preJoin screens

* Adjust menuBar padding and screenShareButton hover state

* Adjust EndCallButton hover state

* Remove SettingsDialog

* Decouple DeviceSelector and ConnectionOptions dialogs

* Add spacing to DialogActions

* Add consistent styles to the AboutDialog

* Add consistent styles to the ConnectionOptions dialog

* Pass isLocalParticipant to ParticipantTracks

* Add deviceSelector to Menu component

* Add settings menu to the deviceSelection screen

* Apply mobile styles to device selection menu

* Make about dialog scrollable again

* Hide screenshare button on mobile

* Adjust spacing in buttons

* Make connectionOptions scrollable

* Move swoosh svg to a TS file.
This prevents the browser from requesting the same svg file whenever it needed to be displayed.

* Fix problems with mobile CSS grid

* Add useVideoTrackDimensions hook and add it to video track

* Add height variable to MobileTopBar

* Adjust video preview size in settings modal

* Improve mobile spacing for preflightTest

* Adjust input styles
Adjust mobile footer height

* Adjust room name input styles

* Adjust settings dropdown position

* Adjust mobile header styles

* Add support for 'go' rooms

* Update test language

* Add tests for useVideoTrackDimensions

* Fix tests for DeviceSelectionScreen

* Fix connectionOptions tests

* Update preflightTest snapshots

* Fix menu tests

* Update videoTrack tests

* Reorder imports

* Add tests for settingsMenu

* Fix mobile background when logged out

* Add logout logo for passcode auth

* Improve styles for passcode login page

* Fix some tests

* Fix getLocalTracks tests

* Update tests for PreJoinScreen component

* Add tests for MediaErrorSnackBar

* Add more tests for MediaErrorSnackBar

* Rename SnackBar to Snackbar

* Renaming files to get around MacOS case insensitivity

* Renaming files to get around macOS case insensitivity

* Add tests for Snackbar component

* Add more space to the PreflightTest result

* Update MediaError cases

* Update device error copy

* Add more tests for deviceHooks

* Remove BandwidthWarning component

* Remove bandwidth warning from MainParticipantInfo and fix bug

* Remove Bandwidth warning from the ParticipantInfo component and update tests

* Add reconnecting ui to Participants

* Update reconnecting snackbar to match new styles

* Fix various styling bugs

* Small fixes

* Fix mobile styles

* Update logic used to display participants in participantList

* Fix tests

* Move Button components up a level

* Move AboutDialog, ConnectionOptionsDialog, and DeviceSelectionDialog to component/ directory

* Move LocalAudioLevelIndicator up a level

* Rename useMainSpeaker to useMainParticipant

* Move status icons to icon folder

* Rename disableAudio to videoOnly

* Move SettingsIcon into icons directory

* Disable pinch-to-zoom on mobile

* Draw Avatars on top of switchedOff video

* Adjust spacing of ParticipantList on mobile

* Render AvatarIcon in LocalVideoPreview when there are no tracks

* Add extra test to the preJoinScreens component

* Update settingsMenu so it doesn't render bandwidth settings in go or p2p rooms

* Instal 2.8.0 beta version of twilio-video SDK

* Supress eventemitter warning

* Don't render flip camera button when there are less than 2 video input devices

* Add question issue template

* Add info about go rooms to readme

* Update image in readme

* Add the AudioLevelIndicator to the  MainParticipantInfo component

* Fix cypress tests

* Update changelog

* Bump version

Co-authored-by: csantos <[email protected]>
Co-authored-by: Manjesh Malavalli <[email protected]>
  • Loading branch information
3 people authored Sep 30, 2020
1 parent e4cf720 commit 62b5ce6
Show file tree
Hide file tree
Showing 167 changed files with 6,159 additions and 3,072 deletions.
14 changes: 14 additions & 0 deletions .github/ISSUE_TEMPLATE/question.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
name: Question
about: Ask a question about the video app
title: ''
labels: question
assignees: ''

---

**Question**
Ask a question about the video app here.

**Additional context**
Add any other context or screenshots about the your question here. The more detail, the better.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
## 0.2.0

This release contains support for the Programmable Video Go room type and an overhauled UI/UX experience.

### Go Room Type

The Go room type provides a similar peer-to-peer video app experience except for a smaller limit of two participants. If more than two participants join a room with this room type, then the video app will present an error. To learn more about Go, please visit the [Twilio blog](https://www.twilio.com/blog/announcing-twilio-video-webrtc-go).

### Design Refresh

The user journey was redesigned from the ground up. Users are now presented with an updated “lobby” experience prior to joining the room. Users can select their audio and video devices, configure their connection settings, and leverage a new beta [Video JS SDK Preflight API](https://github.com/twilio/twilio-video.js/blob/preflight_api/CHANGELOG.md#280-beta1-september-28-2020) to determine if their network connection is suitable to provide an optimal video app experience.

Users are then presented with an updated “in room” experience. All of the media and room controls have been moved to a dedicated toolbar at the bottom of the page and the primary view remains the dominant speaker or the participant sharing their screen. In general the experience feels similar to before with just much more polish!

Additionally, all the UI/UX improvements have been implemented on mobile web browsers as well.

## 0.1.0

This release marks the first iteration of the Twilio Video Collaboration App: a canonical multi-party collaboration video application built with Programmable Video. This application demonstrates the capabilities of Programmable Video and serves as a reference to developers building video apps.
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This application demonstrates a multi-party video application built with [twilio
* There is no cost associated with deploying the app
* When using the app, you will be charged [$0.01 / video participant minute](https://www.twilio.com/video/pricing).

![App Preview](https://user-images.githubusercontent.com/12685223/76361972-c035b700-62e5-11ea-8f9d-0bb24bd73fd4.png)
![App Preview](https://user-images.githubusercontent.com/12685223/94631109-cfca1c80-0284-11eb-8b72-c97276cf34e4.png)

## Prerequisites

Expand Down Expand Up @@ -91,6 +91,8 @@ After running the command [to deploy a Twilio Access Token Server](https://githu

*Peer-to-peer* - Although up to ten participants can join a room using the Peer-to-peer (P2P) room type, it is ideal for a one to one video experience. The NQL indicators, bandwidth profiles, and dominant speaker cannot be used with this room type. Thus, they are not demonstrated in the video app. Also, the VP8 video codec with simulcast disabled and 720p minimum video capturing dimensions are also set by default in order to provide an optimal one to one video app experience. If more than ten participants join a room with this room type, then the video app will present an error.

*Go* - The Go room type provides a similar Peer-to-peer video app experience except for a smaller limit of two participants. If more than two participants join a room with this room type, then the video app will present an error.

If the max number of participants is exceeded, then the video app will present an error for all room types.

## Features
Expand Down
2 changes: 1 addition & 1 deletion cypress.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"video": false,
"defaultCommandTimeout": 10000,
"defaultCommandTimeout": 30000,
"baseUrl": "http://localhost:3000",
"reporter": "cypress-multi-reporters",
"reporterOptions": {
Expand Down
33 changes: 19 additions & 14 deletions cypress/integration/twilio-video.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@ context('A video app user', () => {
describe('before entering a room', () => {
it('should see their audio level indicator moving in the media device panel', () => {
cy.visit('/');

cy.get('#input-user-name').type('testuser');
cy.get('#input-room-name').type(getRoomName());
cy.get('[type="submit"]').click();

cy.get('clipPath rect')
.invoke('attr', 'y')
.should('be', 21);
.should('be', 14);
cy.get('clipPath rect')
.invoke('attr', 'y')
.should('be.lessThan', 21);
.should('be.lessThan', 14);
});
});

Expand All @@ -34,7 +39,7 @@ context('A video app user', () => {
});

it('should be inside the correct room', () => {
cy.get('header').should('contain', ROOM_NAME);
cy.get('footer').should('contain', ROOM_NAME);
cy.getParticipant('testuser').should('contain', 'testuser');
});

Expand All @@ -53,10 +58,10 @@ context('A video app user', () => {
cy.getParticipant('test1')
.get('clipPath rect')
.invoke('attr', 'y')
.should('be', 21);
.should('be', 14);
cy.get('clipPath rect')
.invoke('attr', 'y')
.should('be.lessThan', 21);
.should('be.lessThan', 14);
});

it('should see other participants disconnect when they close their browser', () => {
Expand Down Expand Up @@ -158,32 +163,32 @@ context('A video app user', () => {
it('should see participant "test1" when they are the dominant speaker', () => {
cy.task('toggleParticipantAudio', 'test2');
cy.task('toggleParticipantAudio', 'test3');
cy.getParticipant('test2').find('[data-cy-audio-mute-icon]');
cy.getParticipant('test3').find('[data-cy-audio-mute-icon]');
cy.getParticipant('test2').find('[data-test-audio-mute-icon]');
cy.getParticipant('test3').find('[data-test-audio-mute-icon]');
cy.getParticipant('test1').shouldBeSameVideoAs('[data-cy-main-participant]');
});

it('should see participant "test2" when they are the dominant speaker', () => {
cy.task('toggleParticipantAudio', 'test1');
cy.task('toggleParticipantAudio', 'test2');
cy.getParticipant('test1').find('[data-cy-audio-mute-icon]');
cy.getParticipant('test3').find('[data-cy-audio-mute-icon]');
cy.getParticipant('test1').find('[data-test-audio-mute-icon]');
cy.getParticipant('test3').find('[data-test-audio-mute-icon]');
cy.getParticipant('test2').shouldBeSameVideoAs('[data-cy-main-participant]');
});

it('should see participant "test3" when they are the dominant speaker', () => {
cy.task('toggleParticipantAudio', 'test2');
cy.task('toggleParticipantAudio', 'test3');
cy.getParticipant('test1').find('[data-cy-audio-mute-icon]');
cy.getParticipant('test2').find('[data-cy-audio-mute-icon]');
cy.getParticipant('test1').find('[data-test-audio-mute-icon]');
cy.getParticipant('test2').find('[data-test-audio-mute-icon]');
cy.getParticipant('test3').shouldBeSameVideoAs('[data-cy-main-participant]');
});

it('should see participant "test3" when there is no dominant speaker', () => {
cy.task('toggleParticipantAudio', 'test3');
cy.getParticipant('test1').find('[data-cy-audio-mute-icon]');
cy.getParticipant('test2').find('[data-cy-audio-mute-icon]');
cy.getParticipant('test3').find('[data-cy-audio-mute-icon]');
cy.getParticipant('test1').find('[data-test-audio-mute-icon]');
cy.getParticipant('test2').find('[data-test-audio-mute-icon]');
cy.getParticipant('test3').find('[data-test-audio-mute-icon]');
cy.getParticipant('test3').shouldBeSameVideoAs('[data-cy-main-participant]');
});
});
Expand Down
15 changes: 7 additions & 8 deletions cypress/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const participants = {};
module.exports = (on, config) => {
const participantFunctions = {
addParticipant: async ({ name, roomName, color }) => {
const args = ['--use-fake-ui-for-media-stream', '--use-fake-device-for-media-stream'];
const args = ['--use-fake-ui-for-media-stream', '--use-fake-device-for-media-stream', `--window-size=1920,1080`];

if (color) {
args.push(`--use-file-for-fake-video-capture=cypress/fixtures/${color}.y4m`);
Expand All @@ -20,28 +20,27 @@ module.exports = (on, config) => {
});
const page = (participants[name] = await browser.newPage()); // keep track of this participant for future use
await page.goto(config.baseUrl);
await page.type('#menu-name', name);
await page.type('#menu-room', roomName);
await page.type('#input-user-name', name);
await page.type('#input-room-name', roomName);
await page.click('[type="submit"]');
await page.waitForSelector('[data-cy-join-now]:not([disabled])');
await page.click('[data-cy-join-now]');
await page.waitForSelector('[data-cy-main-participant] video');
return Promise.resolve(null);
},
toggleParticipantAudio: async name => {
const page = participants[name];
await page.click('body'); // To make controls reappear
await page.click('[data-cy-audio-toggle]');
return Promise.resolve(null);
},
shareParticipantScreen: async name => {
const page = participants[name];
await page.click('body');
await page.click('[title="Share Screen"]');
await page.click('[data-cy-share-screen]');
return Promise.resolve(null);
},
removeParticipant: async name => {
const page = participants[name];
await page.click('body');
await page.click('[title="End Call"]');
await page.click('[data-cy-disconnect]');
await page.close();
delete participants[name];
return Promise.resolve(null);
Expand Down
11 changes: 6 additions & 5 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ import detectSound from './detectSound';

Cypress.Commands.add('joinRoom', (username, roomname) => {
cy.visit('/');
cy.get('#menu-name').type(username);
cy.get('#menu-room').type(roomname);
cy.get('#input-user-name').type(username);
cy.get('#input-room-name').type(roomname);
cy.get('[type="submit"]').click();
cy.get('[data-cy-join-now]').click();
cy.get('[data-cy-main-participant]');
});

Cypress.Commands.add('leaveRoom', () => {
cy.wait(500);
cy.get('body').click(); // Makes controls reappear
cy.get('[title="End Call"]').click();
cy.get('footer [data-cy-disconnect]').click();
cy.task('removeAllParticipants');
cy.get('#menu-room');
cy.get('[type="submit"]');
});

Cypress.Commands.add('shouldBeColor', { prevSubject: 'element' }, (subject, color) => {
Expand Down Expand Up @@ -56,7 +57,7 @@ Cypress.Commands.add('shouldBeMakingSound', { prevSubject: 'element' }, subject
}
);
});

cy.window()
.then(win => {
const participantIdentity = subject.attr('data-cy-participant');
Expand Down
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ module.exports = {
snapshotSerializers: ['enzyme-to-json/serializer'],
setupFiles: ['<rootDir>/src/setupTests.ts'],
reporters: ['default', 'jest-junit'],

// We don't need to test the static JSX in the icons folder, so let's exclude it from our test coverage report
coveragePathIgnorePatterns: ['node_modules', 'src/icons'],
};
39 changes: 27 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
{
"name": "twilio-video-app-react",
"version": "0.1.0",
"version": "0.2.0",
"private": true,
"license": "Apache-2.0",
"dependencies": {
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@primer/octicons-react": "^9.4.0",
"@types/d3-timer": "^1.0.9",
"@types/fscreen": "^1.0.1",
"@types/jest": "^24.9.1",
Expand All @@ -25,14 +24,15 @@
"husky": "^3.1.0",
"lint-staged": "^9.5.0",
"lodash.throttle": "^4.1.1",
"nanoid": "^3.1.12",
"prettier": "^1.19.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2",
"react-scripts": "^3.4.3",
"strip-color": "^0.1.0",
"twilio": "^3.39.3",
"twilio-video": "^2.7.2",
"twilio-video": "2.8.0-beta.1",
"typescript": "^3.8.3"
},
"devDependencies": {
Expand Down
9 changes: 3 additions & 6 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,400,500,700&display=swap" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="A collaboration application built with the twilio-video.js SDK and React.js"
/>
<meta name="description" content="A collaboration application built with the twilio-video.js SDK and React.js" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Expand Down
Loading

0 comments on commit 62b5ce6

Please sign in to comment.