Skip to content

Commit

Permalink
feat: add support for manualReloadFromPropChanges prop (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
bc-paul authored Jan 31, 2020
1 parent 53e8b85 commit 756af85
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 5 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ This library has [the same support characteristics as the Brightcove Player Load
- [Props](#props)
- [`attrs`](#attrs)
- [`baseUrl`](#baseurl)
- [`manualReloadFromPropChanges`](#manualreloadfrompropchanges)
- [Other Props](#other-props)
- [Effects of Prop Changes](#effects-of-prop-changes)
- [View the Demo](#view-the-demo)
Expand Down Expand Up @@ -96,6 +97,14 @@ Used to override the base URL for the Brightcove Player being embedded.

Most users will never need this prop. By default, players are loaded from Brightcove's player CDN (`players.brightcove.net`).

### `manualReloadFromPropChanges`

Type: `boolean`

Used to specify if reloading the player after prop changes will be handled manually. This can be done by calling `refToReactPlayerLoader.loadPlayer()`.

See [Effects of Prop Changes](#effects-of-prop-changes) below for the effects of prop changes.

### Other Props

All props not specified above are passed to the [Brightcove Player Loader](https://github.com/brightcove/player-loader#parameters) with a few differences:
Expand All @@ -119,7 +128,7 @@ The following props will update the player's state _without_ a reload:
- `playlistVideoId`
- `videoId`

All other prop changes will cause a complete dispose/reload.
All other prop changes, excluding props that are `function`'s, will cause a complete dispose/reload.

## View the Demo

Expand Down
29 changes: 25 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,18 @@ class ReactPlayerLoader extends React.Component {
* @param {Object} [props.attrs]
* Used to set attributes on the component element that contains the
* embedded Brightcove Player.
*
* @param {boolean} [props.manualReloadFromPropChanges]
* Used to specify if reloading the player after prop changes will be handled manually.
*
*/
constructor(props) {
super(props);
this.refNode = null;
this.setRefNode = ref => {
this.refNode = ref;
};
this.loadPlayer = this.loadPlayer.bind(this);
}

/**
Expand Down Expand Up @@ -123,6 +128,7 @@ class ReactPlayerLoader extends React.Component {
// Delete props that are not meant to be passed to player-loader.
delete options.attrs;
delete options.baseUrl;
delete options.manualReloadFromPropChanges;

// If a base URL is provided, it should only apply to this player load.
// This means we need to back up the original base URL and restore it
Expand Down Expand Up @@ -325,17 +331,32 @@ class ReactPlayerLoader extends React.Component {
const previous = prevProps[key];
const current = this.props[key];

// Do not compare functions
if (typeof current === 'function') {
return acc;
}

if (typeof current === 'object' && current !== null) {
if (JSON.stringify(current) !== JSON.stringify(previous)) {
acc[key] = true;
}

return acc;
}

if (current !== previous) {
acc[key] = true;
}

return acc;
}, {});

// Dispose and recreate the player if any changed keys cannot be handled.
if (Object.keys(changes).some(k => UPDATEABLE_PROPS.indexOf(k) === -1)) {
this.loadPlayer();
return;
if (!this.props.manualReloadFromPropChanges) {
// Dispose and recreate the player if any changed keys cannot be handled.
if (Object.keys(changes).some(k => UPDATEABLE_PROPS.indexOf(k) === -1)) {
this.loadPlayer();
return;
}
}

this.updatePlayer(changes);
Expand Down
62 changes: 62 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -623,4 +623,66 @@ QUnit.module('ReactPlayerLoader', {

rerender = render(React.createElement(ReactPlayerLoader, props)).rerender;
});

QUnit.test('loadPlayer() method reloads player', function(assert) {
const done = assert.async(2);

const props = {
accountId: '1',
applicationId: 'foo',
onSuccess: ({ref, type}) => {
assert.ok(true, 'the success callback was called');
done();
}
};

const reactPlayerLoader = ReactDOM.render(
React.createElement(ReactPlayerLoader, props),
this.fixture
);

reactPlayerLoader.loadPlayer();
});

QUnit.test('set manualReloadFromPropChanges to true', function(assert) {
const done = assert.async(2);
let rerender;
const props = {
accountId: '1',
applicationId: 'foo',
manualReloadFromPropChanges: true,
onSuccess: ({ref, type}) => {
if (props.applicationId !== 'bar') {
props.applicationId = 'bar';
done();
}
rerender(React.createElement(ReactPlayerLoader, props));
assert.ok(true, 'the success callback was called');
done();
}
};

rerender = render(React.createElement(ReactPlayerLoader, props)).rerender;
});

QUnit.test('set manualReloadFromPropChanges to false', function(assert) {
const done = assert.async(3);
let rerender;
const props = {
accountId: '1',
applicationId: 'foo',
manualReloadFromPropChanges: false,
onSuccess: ({ref, type}) => {
if (props.applicationId !== 'bar') {
props.applicationId = 'bar';
done();
}
rerender(React.createElement(ReactPlayerLoader, props));
assert.ok(true, 'the success callback was called');
done();
}
};

rerender = render(React.createElement(ReactPlayerLoader, props)).rerender;
});
});

0 comments on commit 756af85

Please sign in to comment.