Skip to content

Commit

Permalink
fix(soundcheck): Fixes on devices change (refresh), \nfeat(routing): …
Browse files Browse the repository at this point in the history
…Add next support

feat(soudcheck)
  • Loading branch information
prashanthr authored May 10, 2018
2 parents 0cbeb85 + 026f881 commit 5cae79a
Show file tree
Hide file tree
Showing 17 changed files with 180 additions and 52 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"peer": "^0.2.8",
"peerjs": "^0.3.14",
"prop-types": "^15.6.0",
"query-string": "^6.1.0",
"react": "^16.2.0",
"react-bootstrap": "^0.32.1",
"react-dom": "^16.2.0",
Expand Down
6 changes: 4 additions & 2 deletions src/client/redux/sagas/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from '../ducks/session'
import axios from 'axios'
import config from '../../config'
import { goToUrl, setLocalStorage } from '../../utils/window'
import { goToUrl, setLocalStorage, getNextUrl } from '../../utils/window'

function* authenticate (action) {
try {
Expand All @@ -22,7 +22,9 @@ function* authenticate (action) {
code,
auth
})
goToUrl('/welcome', 'Welcome')
const next = getNextUrl()
const nextUrl = `/welcome${next || ''}`
goToUrl(nextUrl, 'Welcome')
} catch (error) {
console.log('Error authenticating')
console.error(error)
Expand Down
5 changes: 3 additions & 2 deletions src/client/redux/sagas/soundcheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from '../ducks/soundcheck'
import { INITIALIZE_SUCCESS } from '../ducks/room'
import { getDevices, getUserMedia } from '../../utils/navigator'
import { setLocalStorage, getLocalStorage } from '../../utils/window'
import { setLocalStorage, getLocalStorage, reload } from '../../utils/window'
import config from '../../config'

function* soundcheckInitialize () {
Expand Down Expand Up @@ -88,7 +88,8 @@ function* soundcheckUpdate ({ audioInput, audioOutput, videoInput, audioEnabled,
roomId,
stream
})
// @todo: TODO: Pass stream updates to all users
// reload to refresh stream updates
reload()
} catch (err) {
console.log('Error initializing soundcheck')
console.error(err)
Expand Down
6 changes: 5 additions & 1 deletion src/client/route/protected.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ const Protected = ({ component: Component, exact = false, path, isAuthValid, rou
exact={exact}
path={path}
render={props => {
const pathname = props.location.pathname
const nextUrl = pathname && pathname !== '/'
? `/?next=${encodeURIComponent(pathname)}`
: '/'
return isAuthValid
? <Component {...props} routes={routes} />
: <Redirect to={'/'} />
: <Redirect to={nextUrl} />
}}
/>
)
Expand Down
75 changes: 48 additions & 27 deletions src/client/ui-components/join-or-create-room/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Form, FormGroup, FormControl, Button } from 'react-bootstrap'
import { generateName, urlSafe } from '../../utils/room'
import { goToUrl } from '../../utils/window'
Expand All @@ -24,36 +25,56 @@ export default class JoinOrCreateRoom extends Component {
goToUrl(path, title)
}
render () {
return (
<div>
<Button
bsStyle='primary'
onClick={event => {
event.preventDefault()
this.gotoRoom(generateName())
}}
>
Create New Room
</Button>
<br /><br />
- OR -
<br /><br />
<Form inline>
<FormGroup controlId='room-name'>
<FormControl type='text' size={30} placeholder={generateName(false)} onChange={this.onRoomNameChanged} />
</FormGroup>{' '}
return this.props.roomId
? (
<div>
Join room
&nbsp;
<Button
bsStyle='warning'
bsStyle={'primary'}
onClick={event => {
event.preventDefault()
if (this.state.roomName) {
this.gotoRoom(urlSafe(this.state.roomName))
}
}}>
Join Room
this.gotoRoom(this.props.roomId)
}}
>
{this.props.roomId}
</Button>
</Form>
</div>
)
</div>
)
: (
<div>
<Button
bsStyle='primary'
onClick={event => {
event.preventDefault()
this.gotoRoom(generateName())
}}
>
Create New Room
</Button>
<br /><br />
- OR -
<br /><br />
<Form inline>
<FormGroup controlId='room-name'>
<FormControl type='text' size={30} placeholder={generateName(false)} onChange={this.onRoomNameChanged} />
</FormGroup>{' '}
<Button
bsStyle='warning'
onClick={event => {
event.preventDefault()
if (this.state.roomName) {
this.gotoRoom(urlSafe(this.state.roomName))
}
}}>
Join Room
</Button>
</Form>
</div>
)
}
}

JoinOrCreateRoom.propTypes = {
roomId: PropTypes.string
}
3 changes: 3 additions & 0 deletions src/client/ui-components/modal/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.modal-header {
color: #337ab7;
}
35 changes: 35 additions & 0 deletions src/client/ui-components/modal/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Modal } from 'react-bootstrap'
import './index.css'

class ModalWrapper extends Component {
render () {
return (
<Modal
show={this.props.show}
onHide={this.props.onClose}
>
<Modal.Header
className='modal-header'
closeButton
>
{this.props.header}
</Modal.Header>
<Modal.Body>
{this.props.content}
</Modal.Body>
</Modal>
)
}
}

ModalWrapper.propTypes = {
onClose: PropTypes.func,
show: PropTypes.bool,
content: PropTypes.any,
header: PropTypes.string
}

export default ModalWrapper
3 changes: 3 additions & 0 deletions src/client/ui-components/soundcheck/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.foot-note {
font-size: small;
}
27 changes: 22 additions & 5 deletions src/client/ui-components/soundcheck/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@ import PropTypes from 'prop-types'
import ToggleButton from '../toggle-button'
import { Row, Col, FormControl, FormGroup, Button } from 'react-bootstrap'
import { map, filter, values } from 'lodash'
import { setLocalStorage } from '../../utils/window'
import config from '../../config'
import './index.css'

const getDevices = (devices, kind) => filter(devices, (device, deviceId) => device.kind === kind)
const getVideoInputDevices = devices => getDevices(devices, 'videoinput')
const getAudioInputDevices = devices => getDevices(devices, 'audioinput')
const getAudioOutputDevices = devices => getDevices(devices, 'audiooutput')
const Emoji = ({ emoji, label }) => <span role='img' aria-label={label}>{emoji}</span>

class Soundcheck extends Component {
constructor (props) {
super(props)
this.onDeviceChanged = this.onDeviceChanged.bind(this)
this.onSoundcheckSave = this.onSoundcheckSave.bind(this)
this.onClearSoundcheckCache = this.onClearSoundcheckCache.bind(this)
this.state = {
videoInput: null,
audioInput: null,
Expand Down Expand Up @@ -45,6 +50,10 @@ class Soundcheck extends Component {
})
}

onClearSoundcheckCache () {
setLocalStorage(config.localStorage.gumConstraints, null)
}

onSoundcheckSave (event) {
event.preventDefault()
console.log('device changes', this.state)
Expand Down Expand Up @@ -100,7 +109,7 @@ class Soundcheck extends Component {
<br />
<Row>
<Col md={5}>
Video Input Source
Video Input <Emoji emoji='🎥' label='camera' />
</Col>
<Col md={5}>
{this.renderDropdownMenu(
Expand All @@ -126,7 +135,7 @@ class Soundcheck extends Component {
</Row>
<Row>
<Col md={5}>
Audio Input Source
Audio Input <Emoji emoji='🎙️' label='microphone' />
</Col>
<Col md={5}>
{this.renderDropdownMenu(
Expand All @@ -153,7 +162,7 @@ class Soundcheck extends Component {
</Row>
<Row>
<Col md={5}>
Audio Output Source
Audio Output <Emoji emoji='🔈' label='speaker' />
</Col>
<Col md={5}>
{this.renderDropdownMenu(
Expand All @@ -168,8 +177,16 @@ class Soundcheck extends Component {
<Col md={2} />
</Row>
<Row>
<Col md={5} />
<Col md={5} />
<Col md={5}>
<Button
onClick={this.onClearSoundcheckCache}
>
Clear cache
</Button>
</Col>
<Col md={5} className='foot-note'>
Note: Your page will reload after save
</Col>
<Col md={2}>
<Button
bsStyle='primary'
Expand Down
14 changes: 5 additions & 9 deletions src/client/ui-components/soundcheck/soundcheck-wrapper.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Modal } from 'react-bootstrap'
import Modal from '../modal'
import Soundcheck from './index'
import { connect } from 'react-redux'
import { initializeSoundcheck, onSoundcheckUpdate } from '../../redux/ducks/soundcheck'
Expand All @@ -17,12 +17,9 @@ class SoundcheckWrapper extends Component {
return (
<Modal
show={this.props.show}
onHide={this.props.onClose}
>
<Modal.Header closeButton>
Audio / Video Settings
</Modal.Header>
<Modal.Body>
onClose={this.props.onClose}
header={`Settings - Audio & Video`}
content={
<Soundcheck
devices={this.props.devices}
videoEnabled={this.props.videoEnabled}
Expand All @@ -33,8 +30,7 @@ class SoundcheckWrapper extends Component {
onSoundcheckUpdate={this.props.onSoundcheckUpdate}
onClose={this.props.onClose}
/>
</Modal.Body>
</Modal>
} />
)
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/client/ui-components/toggle-button/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@
}

input:checked + .slider {
background-color: #2196F3;
background-color: #00E676;
}

input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
box-shadow: 0 0 1px #00E676;
}

input:checked + .slider:before {
Expand Down
10 changes: 10 additions & 0 deletions src/client/utils/room.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,13 @@ export const getRandomAvatarUrl = (
}
return `${AVATAR_URL_PREFIX}/avatars/face/${features.eyes}/${features.nose}/${features.mouth}/${features.color || 'eeee'}`
}

export const parseRoomIdFromNextUrl = (nextUrl) => {
return nextUrl
? decodeURIComponent(
nextUrl
.replace('?next=', '')
)
.replace('/room/', '')
: null
}
8 changes: 8 additions & 0 deletions src/client/utils/window.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import { parse } from 'query-string'
export const getNextUrl = () => {
const urlSearch = parse(window.location.search)
return urlSearch && urlSearch.next
? `?next=${encodeURIComponent(urlSearch.next)}`
: null
}
export const getLocalStorage = (key) => JSON.parse(window.localStorage.getItem(key) || null)
export const setLocalStorage = (key, val) => window.localStorage.setItem(key, JSON.stringify(val))
export const existsInLocalStorage = (key) => window.localStorage.getItem(key) !== undefined
Expand All @@ -7,3 +14,4 @@ export const goToUrl = (path, title) => {
window.history.pushState(currentHistoryState, title, path)
window.location.replace(path)
}
export const reload = () => window.location.reload()
1 change: 1 addition & 0 deletions src/client/views/room/index.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.room-toolbar {
margin: auto;
text-align: center;
padding-bottom: 10px;
}
8 changes: 7 additions & 1 deletion src/client/views/welcome/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import React, { Component } from 'react'
import JoinOrCreateRoom from '../../ui-components/join-or-create-room'
import { Row, Col, Grid, Jumbotron } from 'react-bootstrap'
import { getNextUrl } from '../../utils/window'
import { parseRoomIdFromNextUrl } from '../../utils/room'
import './index.css'

class Welcome extends Component {
render () {
const next = getNextUrl()
const roomId = parseRoomIdFromNextUrl(next)
return (
<Grid fluid>
<Jumbotron className='welcome'>
Expand Down Expand Up @@ -43,7 +47,9 @@ class Welcome extends Component {
<br />
<Row>
<Col md={12}>
<JoinOrCreateRoom />
<JoinOrCreateRoom
roomId={roomId}
/>
</Col>
</Row>
</Jumbotron>
Expand Down
Loading

0 comments on commit 5cae79a

Please sign in to comment.