Skip to content
This repository was archived by the owner on Nov 25, 2022. It is now read-only.

Commit d36dbb3

Browse files
authored
Merge pull request #17 from aiham/dev
Release 0.5.0
2 parents de633fa + 82238d6 commit d36dbb3

File tree

9 files changed

+1042
-782
lines changed

9 files changed

+1042
-782
lines changed

CONTRIBUTING.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ For a contribution to be accepted:
2222

2323
* The test suite must be complete and pass
2424
* Code must follow existing styling conventions
25-
* Commit messages must be descriptive. Related issues should be mentioned by number.
25+
* Commit messages must be descriptive. Related issues should be mentioned by number
26+
* If the contribution includes a change to the dependency list then the `yarn.lock` file must be updated
2627

2728
If the contribution doesn't meet these criteria, a maintainer will discuss it with you on the Issue. You can still continue to add more commits to the branch you have sent the Pull Request from.
2829

README.md

Lines changed: 110 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ There is an example application provided in `example/` and you can run it with t
6161
1. Edit `config.js`:
6262
1. Add your OpenTok API key, Session ID and Token (https://tokbox.com/account/)
6363
1. Add your Chrome Extension ID (https://tokbox.com/developer/guides/screen-sharing/js/)
64-
1. `npm install`
64+
1. `yarn` (or `npm install`)
6565
1. `npm run example`
6666
1. Visit `http://localhost:8000` in your browser
6767

@@ -162,31 +162,44 @@ The `opentok-react` library comprises of:
162162
| apiKey | String | Yes | TokBox API Key
163163
| sessionId | String | Yes | TokBox Session ID
164164
| token | String | Yes | TokBox token
165-
| eventHandlers | Object<Function> | No | Event handlers passed into `session.on`
166-
| onConnect | Function() | No | Invoked when `session.connect` successfully completes
167-
| onError | Function(err) | No | Invoked when `session.connect` fails
165+
| eventHandlers | Object<Function> | No | Event handlers passed into [session.on](https://tokbox.com/developer/sdks/js/reference/Session.html#on)
166+
| onConnect | Function() | No | Invoked when [session.connect](https://tokbox.com/developer/sdks/js/reference/Session.html#connect) successfully completes
167+
| onError | Function(err) | No | Invoked when [session.connect](https://tokbox.com/developer/sdks/js/reference/Session.html#connect) fails
168+
169+
The `OTSession` component manages the connection to an OpenTok [Session](https://tokbox.com/developer/sdks/js/reference/Session.html). It passes the Session instance as the `session` prop to its child components. It is recommended that you nest `OTPublisher` and `OTStreams` inside `OTSession`:
170+
171+
```html
172+
<OTSession apiKey="your-api-key" sessionId="your-session-id" token="your-session-token">
173+
<OTPublisher />
174+
<OTStreams>
175+
<OTSubscriber />
176+
</OTStreams>
177+
</OTSession>
178+
```
168179

169180
### OTPublisher Component
170181

171182
| Prop | Type | Required | Description |
172183
| --- | --- | --- | --- |
173-
| session | [Session](https://tokbox.com/developer/sdks/js/reference/Session.html) | No | OpenTok Session instance
174-
| properties | Object | No | Properties passed into `OT.initPublisher`
175-
| eventHandlers | Object&lt;Function&gt; | No | Event handlers passed into `publisher.on`
176-
| onInit | Function() | No | Invoked when `OT.initPublisher` successfully completes
177-
| onPublish | Function() | No | Invoked when `session.publish` successfully completes
178-
| onError | Function(err) | No | Invoked when either `OT.initPublisher` or `session.publish` fail
184+
| session | [Session](https://tokbox.com/developer/sdks/js/reference/Session.html) | No | OpenTok Session instance. This is auto populated by wrapping `OTPublisher` with `OTSession`
185+
| properties | Object | No | Properties passed into [OT.initPublisher](https://tokbox.com/developer/sdks/js/reference/OT.html#initPublisher)
186+
| eventHandlers | Object&lt;Function&gt; | No | Event handlers passed into [publisher.on](https://tokbox.com/developer/sdks/js/reference/Publisher.html#on)
187+
| onInit | Function() | No | Invoked when [OT.initPublisher](https://tokbox.com/developer/sdks/js/reference/OT.html#initPublisher) successfully completes
188+
| onPublish | Function() | No | Invoked when [session.publish](https://tokbox.com/developer/sdks/js/reference/Session.html#publish) successfully completes
189+
| onError | Function(err) | No | Invoked when either [OT.initPublisher](https://tokbox.com/developer/sdks/js/reference/OT.html#initPublisher) or [session.publish](https://tokbox.com/developer/sdks/js/reference/Session.html#publish) fail
179190

180-
The `OTPublisher` component will initialise a publisher and publish to a specified session upon mounting. You must specify a [Session](https://tokbox.com/developer/sdks/js/reference/Session.html) object using the `session` prop.
191+
The `OTPublisher` component will initialise a publisher and publish to a specified session upon mounting. It will also ensure the Publisher video element is attached to the DOM inside the component rather than appending to the body (which is the Publisher's default behaviour).
181192

182-
```js
183-
class MyApp extends React.Component {
184-
render() {
185-
return (
186-
<OTPublisher session={this.sessionHelper.session} />
187-
);
188-
}
189-
}
193+
```html
194+
<OTSession apiKey="your-api-key" sessionId="your-session-id" token="your-session-token">
195+
<OTPublisher />
196+
</OTSession>
197+
```
198+
199+
If you are not using `OTSession` then you must specify a [Session](https://tokbox.com/developer/sdks/js/reference/Session.html) object using the `session` prop.
200+
201+
```html
202+
<OTPublisher session={this.sessionHelper.session} />
190203
```
191204

192205
Use the `properties` prop to specify a properties object for [OT.initPublisher](https://tokbox.com/developer/sdks/js/reference/OT.html#initPublisher) and the `eventHandlers` prop to specify an object of event handlers for [Publisher#on](https://tokbox.com/developer/sdks/js/reference/Publisher.html#on).
@@ -213,26 +226,34 @@ class MyApp extends React.Component {
213226

214227
render() {
215228
return (
216-
<OTPublisher
217-
session={this.sessionHelper.session}
218-
properties={this.publisherProperties}
219-
eventHandlers={this.publisherEventHandlers}
220-
/>
229+
<OTSession apiKey="your-api-key" sessionId="your-session-id" token="your-session-token">
230+
<OTPublisher
231+
properties={this.publisherProperties}
232+
eventHandlers={this.publisherEventHandlers}
233+
/>
234+
</OTSession>
221235
);
222236
}
223237
}
224238
```
225239

226-
#### TODO
227-
- Describe `getPublisher()` method.
228-
- Explain which properties `OTPublisher` will monitor for changes.
229-
- Explain that this component will not cause publisher to be appended to body.
240+
The `properties` prop is used for initial set up of the Publisher and making changes to it will not update the Publisher, you will instead need to invoke Publisher methods. To facilitate this the Publisher instance is exposed via the `getPublisher()` component method. You should always call this method to get the latest Publisher instance instead of keeping a reference to it as it's possible for the Publisher instance to change, leaving you with a stale reference.
241+
242+
However, for convenience the `OTPublisher` does watch for changes on a few keys of the `properties` object and makes the necessary changes. Currently these are:
243+
244+
| Publisher Property | Action |
245+
| --- | --- |
246+
| videoSource | Destroys and recreates the Publisher with the new video source. This is the only way to change the video source of a Publisher. This is used in the example application to allow the user to toggle between publishing their camera and publishing their screen |
247+
| publishAudio | Calls [publisher.publishAudio()](https://tokbox.com/developer/sdks/js/reference/Publisher.html#publishAudio) to toggle audio on and off |
248+
| publishVideo | Calls [publisher.publishVideo()](https://tokbox.com/developer/sdks/js/reference/Publisher.html#publishVideo) to toggle video on and off |
249+
250+
There are plans to support more Publisher properties but for now you will have to call `getPublisher()` to retrieve the Publisher instance and make the necessary changes yourself.
230251

231252
### OTStreams Component
232253

233254
| Prop | Type | Required | Description |
234255
| --- | --- | --- | --- |
235-
| children | OTSubscriber | Yes | Must only have a single `OTSubscriber` component (or similar component that accepts `session` and `stream` props)
256+
| children | ReactElement | Yes | Must have a single child component that accepts `session` and `stream` props, eg. `OTSubscriber`
236257
| session | [Session](https://tokbox.com/developer/sdks/js/reference/Session.html) | Yes | OpenTok Session instance. This is auto populated by wrapping `OTStreams` with `OTSession`
237258
| streams | Array&lt;[Stream](https://tokbox.com/developer/sdks/js/reference/Stream.html)&gt; | No | Array of OpenTok Stream instances. This is auto populated by wrapping `OTStreams` with `OTSession`
238259

@@ -247,34 +268,73 @@ class MyApp extends React.Component {
247268
| onSubscribe | Function() | No | Invoked when `session.subscribe` successfully completes
248269
| onError | Function(err) | No | Invoked when `session.subscribe` fails
249270

250-
The `OTSubscriber` component will subscribe to a specified stream from a specified session upon mounting. You must provide a [Stream](https://tokbox.com/developer/sdks/js/reference/Stream.html) object using the `stream` prop and a [Session](https://tokbox.com/developer/sdks/js/reference/Session.html) object using the `session` prop.
271+
The `OTSubscriber` component will subscribe to a specified stream from a specified session upon mounting. It will also ensure the Subscriber video element is attached to the DOM inside the component rather than appending to the body (which is the Subscriber's default behaviour).
272+
273+
```html
274+
<OTStreams>
275+
<OTSubscriber />
276+
</OTStreams>
277+
```
278+
279+
If you are not using `OTStreams` then you must provide a [Stream](https://tokbox.com/developer/sdks/js/reference/Stream.html) object using the `stream` prop and a [Session](https://tokbox.com/developer/sdks/js/reference/Session.html) object using the `session` prop.
280+
281+
```js
282+
{this.sessionHelper.streams.map(stream => (
283+
<OTSubscriber
284+
key={stream.id}
285+
session={this.sessionHelper.session}
286+
stream={stream}
287+
/>
288+
))}
289+
```
290+
291+
Use the `properties` prop to specify a properties object for [session.subscribe](https://tokbox.com/developer/sdks/js/reference/Session.html#subscribe) and the `eventHandlers` prop to specify an object of event handlers for [Subscriber#on](https://tokbox.com/developer/sdks/js/reference/Subscriber.html#on).
251292

252293
```js
253294
class MyApp extends React.Component {
295+
constructor(props) {
296+
super(props);
297+
298+
this.subscriberProperties = {
299+
preferredFrameRate: 15,
300+
showControls: false
301+
};
302+
303+
this.subscriberEventHandlers = {
304+
videoDisabled: event => {
305+
console.log('Subscriber video disabled!');
306+
},
307+
videoEnabled: event => {
308+
console.log('Subscriber video enabled!');
309+
}
310+
};
311+
}
312+
254313
render() {
255314
return (
256-
<div>
257-
{this.sessionHelper.streams.map(stream => {
258-
return (
259-
<OTSubscriber
260-
key={stream.id}
261-
session={this.sessionHelper.session}
262-
stream={stream}
263-
/>
264-
);
265-
})}
266-
</div>
315+
<OTSession apiKey="your-api-key" sessionId="your-session-id" token="your-session-token">
316+
<OTStreams>
317+
<OTSubscriber
318+
properties={this.subscriberProperties}
319+
eventHandlers={this.subscriberEventHandlers}
320+
/>
321+
</OTStreams>
322+
</OTSession>
267323
);
268324
}
269325
}
270326
```
271327

272-
#### TODO
273-
- Describe `getSubscriber()` method.
274-
- Describe `properties` prop.
275-
- Describe `eventHandlers` prop.
276-
- Explain which properties `OTPublisher` will monitor for changes.
277-
- Explain that this component will not cause subscriber to be appended to body.
328+
The `properties` prop is used for initial set up of the Subscriber and making changes to it will not update the Subscriber, you will instead need to invoke Subscriber methods. To facilitate this the Subscriber instance is exposed via the `getSubscriber()` component method. You should always call this method to get the latest Subscriber instance instead of keeping a reference to it as it's possible for the Subscriber instance to change, leaving you with a stale reference.
329+
330+
However, for convenience the `OTSubscriber` does watch for changes on a few keys of the `properties` object and makes the necessary changes. Currently these are:
331+
332+
| Subscriber Property | Action |
333+
| --- | --- |
334+
| subscribeToAudio | Calls [subscriber.subscribeToAudio()](https://tokbox.com/developer/sdks/js/reference/Subscriber.html#subscribeToAudio) to toggle audio on and off |
335+
| subscribeToVideo | Calls [subscriber.subscribeToVideo()](https://tokbox.com/developer/sdks/js/reference/Subscriber.html#subscribeToVideo) to toggle video on and off |
336+
337+
There are plans to support more Subscriber properties but for now you will have to call `getSubscriber()` to retrieve the Subscriber instance and make the necessary changes yourself.
278338

279339
### createSession Helper
280340

@@ -313,13 +373,13 @@ Use of this helper is optional and you can instead use the `OTSession` component
313373
| Prop | Type | Required | Description |
314374
| --- | --- | --- | --- |
315375
| opentokClientUrl | String | No | The URL of the OpenTok client script to load. It defaults to `https://static.opentok.com/v2/js/opentok.min.js`.
316-
| loadingDelegate | Element | No | An element that will be displayed while the OpenTok client script is loading. It defaults to an empty `<div />`.
376+
| loadingDelegate | ReactElement | No | An element that will be displayed while the OpenTok client script is loading. It defaults to an empty `<div />`.
317377

318378
In larger applications, one might not want to load the `opentok.js` client with a `<script>` tag all the time. The `preloadScript` higher-order component will do this for you at the appropriate time.
319379

320380
For example, imagine you have a React Router application with the following route structure:
321381

322-
```javascript
382+
```html
323383
<Router>
324384
<Route path="/">
325385
<IndexRoute component="..." />
@@ -344,7 +404,7 @@ export default preloadScript(App);
344404

345405
1. `git clone https://github.com/aiham/opentok-react.git`
346406
1. `cd opentok-react/`
347-
1. `npm install`
407+
1. `yarn` (or `npm install`)
348408
1. Modify code in `src/`
349409
1. `npm run build`
350410
1. Check that files in `dist/` have been updated.

package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "opentok-react",
3-
"version": "0.4.0",
3+
"version": "0.5.0",
44
"description": "React components for OpenTok.js",
55
"main": "dist/index.js",
66
"scripts": {
@@ -27,7 +27,8 @@
2727
"license": "MIT",
2828
"dependencies": {
2929
"lodash": "^4.13.1",
30-
"react": "^15.1.0",
30+
"prop-types": "^15.5.10",
31+
"react": "^15.5.0",
3132
"react-display-name": "^0.2.0",
3233
"scriptjs": "^2.5.8",
3334
"uuid": "^3.0.1"
@@ -56,8 +57,9 @@
5657
"karma-jasmine": "^1.1.0",
5758
"karma-spec-reporter": "^0.0.26",
5859
"opentok-test-scripts": "^3.2.1",
59-
"react-addons-test-utils": "^15.4.1",
60-
"react-dom": "^15.1.0",
60+
"react-addons-test-utils": "^15.5.1",
61+
"react-dom": "^15.5.0",
62+
"react-test-renderer": "^15.5.4",
6163
"travis-multirunner": "^3.1.0",
6264
"watchify": "^3.8.0"
6365
},

src/OTPublisher.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { Component, PropTypes } from 'react';
1+
import React, { Component } from 'react';
2+
import PropTypes from 'prop-types';
23
import once from 'lodash/once';
34
import uuid from 'uuid';
45

src/OTSession.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { Component, PropTypes, Children, cloneElement } from 'react';
1+
import React, { Component, Children, cloneElement } from 'react';
2+
import PropTypes from 'prop-types';
23

34
import createSession from './createSession';
45

@@ -59,7 +60,7 @@ export default class OTSession extends Component {
5960
}
6061

6162
OTSession.propTypes = {
62-
children: React.PropTypes.oneOfType([
63+
children: PropTypes.oneOfType([
6364
PropTypes.element,
6465
PropTypes.arrayOf(PropTypes.element),
6566
]).isRequired,

src/OTStreams.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { PropTypes, Children, cloneElement } from 'react';
1+
import React, { Children, cloneElement } from 'react';
2+
import PropTypes from 'prop-types';
23

34
export default function OTStreams(props) {
45
if (!props.session) {
@@ -27,7 +28,7 @@ OTStreams.propTypes = {
2728
publish: PropTypes.func,
2829
subscribe: PropTypes.func,
2930
}),
30-
streams: PropTypes.arrayOf(React.PropTypes.object),
31+
streams: PropTypes.arrayOf(PropTypes.object),
3132
};
3233

3334
OTStreams.defaultProps = {

src/OTSubscriber.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { Component, PropTypes } from 'react';
1+
import React, { Component } from 'react';
2+
import PropTypes from 'prop-types';
23
import uuid from 'uuid';
34

45
export default class OTSubscriber extends Component {

src/preloadScript.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { Component, PropTypes } from 'react';
1+
import React, { Component } from 'react';
2+
import PropTypes from 'prop-types';
23
import getDisplayName from 'react-display-name';
34
import scriptjs from 'scriptjs';
45

0 commit comments

Comments
 (0)