Skip to content

Commit 4f61690

Browse files
author
Prash
committed
feat(soudcheck): Allow toggle for devices, add local storage support
1 parent 163d413 commit 4f61690

File tree

12 files changed

+90
-17
lines changed

12 files changed

+90
-17
lines changed

src/client/config/index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import stunServers from './stun'
22
const config = {
3-
iceServers: stunServers.map(url => ({ urls: url }))
3+
iceServers: stunServers.map(url => ({ urls: url })),
4+
localStorage: {
5+
gumConstraints: 'gum',
6+
auth: 'auth',
7+
code: 'code'
8+
}
49
}
510

611
export default config

src/client/redux/ducks/soundcheck.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ const soundcheckReducer = (state = initialState, action) => {
4545
devices: keyBy(action.devices, device => `${device.kind}-${device.deviceId}`),
4646
defaultAudioInputId: findDefaultDevice('audioinput', action.devices),
4747
defaultVideoInputId: findDefaultDevice('videoinput', action.devices),
48-
defaultAudioOutputId: findDefaultDevice('audiooutput', action.devices)
48+
defaultAudioOutputId: findDefaultDevice('audiooutput', action.devices),
49+
audioEnabled: action.audioEnabled,
50+
videoEnabled: action.videoEnabled
4951
}
5052
case UPDATE_SOUNDCHECK_SUCCESS:
5153
return {

src/client/redux/sagas/room.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,18 @@ import { call, put, fork, takeLatest } from 'redux-saga/effects'
22
import { INITIALIZE, INITIALIZE_SUCCESS, INITIALIZE_FAILED, SHUTDOWN } from '../ducks/room'
33
import { SOCKET_INITIALIZE, SOCKET_DESTROY } from '../ducks/socket'
44
import { getUserMedia } from '../../utils/navigator'
5+
import { getLocalStorage } from '../../utils/window'
6+
import config from '../../config'
57

68
function* initialize (action) {
79
try {
8-
const stream = yield call(getUserMedia)
10+
const constraints = getLocalStorage(config.localStorage.gumConstraints)
11+
let stream
12+
if (constraints) {
13+
stream = yield call(getUserMedia, constraints)
14+
} else {
15+
stream = yield call(getUserMedia)
16+
}
917
yield put({
1018
type: INITIALIZE_SUCCESS,
1119
roomId: action.roomId,

src/client/redux/sagas/session.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
AUTHENTICATE_FAILED
66
} from '../ducks/session'
77
import axios from 'axios'
8+
import config from '../../config'
89
import { goToUrl, setLocalStorage } from '../../utils/window'
910

1011
function* authenticate (action) {
@@ -14,8 +15,8 @@ function* authenticate (action) {
1415
}))
1516
const auth = response.data.auth
1617
const code = response.data.code || action.code
17-
setLocalStorage('auth', auth)
18-
setLocalStorage('invite-code', code)
18+
setLocalStorage(config.localStorage.auth, auth)
19+
setLocalStorage(config.localStorage.code, code)
1920
yield put({
2021
type: AUTHENTICATE_SUCCESS,
2122
code,

src/client/redux/sagas/soundcheck.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
11
import { put, fork, takeLatest, call, select } from 'redux-saga/effects'
22
import {
3-
INITIALIZE_SOUNDCHECK,
4-
INITIALIZE_SOUNDCHECK_SUCCESS,
3+
INITIALIZE_SOUNDCHECK,
4+
INITIALIZE_SOUNDCHECK_SUCCESS,
55
INITIALIZE_SOUNDCHECK_FAILED,
66
UPDATE_SOUNDCHECK,
77
UPDATE_SOUNDCHECK_FAILED,
88
UPDATE_SOUNDCHECK_SUCCESS
99
} from '../ducks/soundcheck'
1010
import { INITIALIZE_SUCCESS } from '../ducks/room'
1111
import { getDevices, getUserMedia } from '../../utils/navigator'
12+
import { setLocalStorage, getLocalStorage } from '../../utils/window'
13+
import config from '../../config'
1214

1315
function* soundcheckInitialize () {
1416
try {
1517
const devices = yield getDevices()
18+
const constraints = getLocalStorage(config.localStorage.gumConstraints)
19+
let audioEnabled = true
20+
let videoEnabled = true
21+
if (constraints) {
22+
audioEnabled = constraints.audio && constraints.audio !== false
23+
videoEnabled = constraints.video && constraints.video !== false
24+
}
1625
yield put({
1726
type: INITIALIZE_SOUNDCHECK_SUCCESS,
18-
devices
27+
devices,
28+
audioEnabled,
29+
videoEnabled
1930
})
2031
} catch (err) {
2132
console.log('Error initializing soundcheck')
@@ -71,11 +82,13 @@ function* soundcheckUpdate ({ audioInput, audioOutput, videoInput, audioEnabled,
7182
console.log('scheck-updatesaga: constraints', constraints)
7283
const stream = yield call(getUserMedia, constraints)
7384
console.log('scheck-updatasaga: stream', stream, roomId, stream.getVideoTracks())
85+
setLocalStorage(config.localStorage.gumConstraints, constraints)
7486
yield put({
7587
type: INITIALIZE_SUCCESS,
7688
roomId,
7789
stream
7890
})
91+
// @todo: TODO: Pass stream updates to all users
7992
} catch (err) {
8093
console.log('Error initializing soundcheck')
8194
console.error(err)

src/client/redux/selectors/auth.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createSelector } from 'reselect'
22
import { isTokenValid } from '../../utils/jwt'
33
import { getLocalStorage } from '../../utils/window'
4+
import config from '../../config'
45

56
const authSelector = state => state.session && state.session.auth
67

@@ -9,7 +10,7 @@ export const getAuth = createSelector(
910
auth => {
1011
if (auth) return auth
1112
try {
12-
return JSON.parse(getLocalStorage('auth') || null)
13+
return getLocalStorage(config.localStorage.auth)
1314
} catch (error) {
1415
console.error(error)
1516
}

src/client/ui-components/soundcheck/index.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,21 @@ class Soundcheck extends Component {
2323
}
2424
}
2525

26+
componentWillReceiveProps (nextProps) {
27+
if (this.props !== nextProps) {
28+
if (this.state.audioEnabled !== nextProps.audioEnabled) {
29+
this.setState({
30+
audioEnabled: nextProps.audioEnabled
31+
})
32+
}
33+
if (this.state.videoEnabled !== nextProps.videoEnabled) {
34+
this.setState({
35+
videoEnabled: nextProps.videoEnabled
36+
})
37+
}
38+
}
39+
}
40+
2641
onDeviceChanged (stateProperty, event) {
2742
event.preventDefault()
2843
this.setState({
@@ -47,8 +62,8 @@ class Soundcheck extends Component {
4762
return (
4863
<FormGroup>
4964
<FormControl
50-
componentClass="select"
51-
placeholder="Select source"
65+
componentClass='select'
66+
placeholder='Select source'
5267
selected={selectedKey}
5368
onChange={onChange}
5469
>
@@ -71,6 +86,18 @@ class Soundcheck extends Component {
7186
if (!this.props.devices) return null
7287
return (
7388
<div>
89+
<Row>
90+
<Col md={5}>
91+
Media Type
92+
</Col>
93+
<Col md={5}>
94+
Device
95+
</Col>
96+
<Col md={2}>
97+
On / Off
98+
</Col>
99+
</Row>
100+
<br />
74101
<Row>
75102
<Col md={5}>
76103
Video Input Source

src/client/ui-components/soundcheck/soundcheck-wrapper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class SoundcheckWrapper extends Component {
2020
onHide={this.props.onClose}
2121
>
2222
<Modal.Header closeButton>
23-
Soundcheck
23+
Audio / Video Settings
2424
</Modal.Header>
2525
<Modal.Body>
2626
<Soundcheck

src/client/ui-components/video-container/index.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ class VideoContainer extends Component {
1515
this.playStream = this.playStream.bind(this)
1616
}
1717

18-
componentWillReceiveProps (nextProps) {
19-
// console.log('new', nextProps)
20-
}
21-
2218
playStream (event) {
2319
event.preventDefault()
2420
event.target.play()
@@ -49,6 +45,7 @@ class VideoContainer extends Component {
4945
}}
5046
disableMute={this.props.users[userId].disableMute}
5147
muted={this.props.users[userId].muted}
48+
height={750}
5249
/>
5350
</Col>
5451
))}

src/client/ui-components/video/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { Component } from 'react'
22
import PropTypes from 'prop-types'
33
import { Button, ButtonGroup } from 'react-bootstrap'
4+
import { getRandomAvatarUrl } from '../../utils/room'
45
import './index.css'
56

67
class VideoPlayer extends Component {
@@ -44,6 +45,7 @@ class VideoPlayer extends Component {
4445
</span>
4546
}
4647
<video
48+
poster={getRandomAvatarUrl()}
4749
className='video'
4850
ref={el => { this.videoRef = el }}
4951
muted={this.props.muted}

src/client/utils/room.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,20 @@ import { toLower } from 'lodash'
55

66
export const urlSafe = (text) => slug(text)
77
export const generateName = (addRandomId = true) => urlSafe(toLower(`${faker.hacker.adjective()}-${faker.random.word()}${addRandomId ? `-${cuid.slug()}` : ''}`))
8+
9+
/**
10+
* Get random avatar url to show in video posters
11+
* @param {*} key unique id
12+
* @param {*} features { face: { eyes: [], nose, mouth }, color: HEXWITHOUTHASH}
13+
*/
14+
export const getRandomAvatarUrl = (
15+
key,
16+
features
17+
) => {
18+
const AVATAR_URL_PREFIX = `https://api.adorable.io`
19+
// const ALT_URL_PREFIX = `https://randomuser.me/api/portraits/lego` // lego/[1-9].jpg
20+
if (!features) {
21+
return `${AVATAR_URL_PREFIX}/avatars/285/${key || cuid.slug()}.png`
22+
}
23+
return `${AVATAR_URL_PREFIX}/avatars/face/${features.eyes}/${features.nose}/${features.mouth}/${features.color || 'eeee'}`
24+
}

src/client/utils/window.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export const getLocalStorage = (key) => window.localStorage.getItem(key)
1+
export const getLocalStorage = (key) => JSON.parse(window.localStorage.getItem(key) || null)
22
export const setLocalStorage = (key, val) => window.localStorage.setItem(key, JSON.stringify(val))
33
export const existsInLocalStorage = (key) => window.localStorage.getItem(key) !== undefined
44
export const clearLocalStorage = (key) => window.localStorage.clear()

0 commit comments

Comments
 (0)