-
Notifications
You must be signed in to change notification settings - Fork 1
bulbs-video lazy loading #171
Changes from 11 commits
4a45106
3904eb0
2b7dd8c
e4a85a3
20d561d
8f073a5
c4b39d8
7608c72
50c4110
710c653
6652c37
1d505d0
c7819ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,6 +94,8 @@ Use this if developing elements within `bulbs-elements` locally | |
$ ./scripts/webpack-dev-server | ||
``` | ||
|
||
You can access the examples site now by visiting [localhost:8080](). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A helpful note. |
||
|
||
## Common Components | ||
|
||
Some components can be used in more than one element. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
import React, { PropTypes } from 'react'; | ||
import { registerReactElement } from 'bulbs-elements/register'; | ||
import BulbsElement from 'bulbs-elements/bulbs-element'; | ||
import { loadOnDemand } from 'bulbs-elements/util' | ||
|
||
import VideoField from './fields/video'; | ||
import VideoRequest from './fields/video-request'; | ||
|
@@ -57,22 +58,26 @@ export default class BulbsVideo extends BulbsElement { | |
} | ||
*/ | ||
render () { | ||
let allProps = { | ||
...this.props, | ||
...this.state, | ||
actions: this.store.actions, | ||
autoplayNext: typeof this.props.twitterHandle === 'string', | ||
disableLazyLoading: typeof this.props.disableLazyLoading === 'string', | ||
disableMetaLink: typeof this.props.disableMetaLink === 'string', | ||
embedded: typeof this.props.embedded === 'string', | ||
enablePosterMeta: typeof this.props.enablePosterMeta === 'string', | ||
muted: typeof this.props.muted === 'string', | ||
noEndcard: typeof this.props.noEndcard === 'string', | ||
}; | ||
|
||
if (!allProps.disableLazyLoading) { | ||
|
||
return loadOnDemand(BulbsVideoRoot)(allProps); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the main change. If the |
||
} | ||
|
||
return ( | ||
<BulbsVideoRoot | ||
{...this.state} | ||
twitterHandle={this.props.twitterHandle} | ||
targetCampaignId={this.props.targetCampaignId} | ||
targetCampaignNumber={this.props.targetCampaignNumber} | ||
targetHostChannel={this.props.targetHostChannel} | ||
targetSpecialCoverage={this.props.targetSpecialCoverage} | ||
autoplayNext={typeof this.props.twitterHandle === 'string'} | ||
embedded={typeof this.props.embedded === 'string'} | ||
enablePosterMeta={typeof this.props.enablePosterMeta === 'string'} | ||
disableMetaLink={typeof this.props.disableMetaLink === 'string'} | ||
muted={typeof this.props.muted === 'string'} | ||
noEndcard={typeof this.props.noEndcard === 'string'} | ||
actions={this.store.actions} | ||
/> | ||
<BulbsVideoRoot {...allProps} /> | ||
); | ||
} | ||
} | ||
|
@@ -87,6 +92,7 @@ Object.assign(BulbsVideo, { | |
propTypes: { | ||
autoplay: PropTypes.string, | ||
autoplayNext: PropTypes.string, | ||
disableLazyLoading: PropTypes.string, | ||
disableMetaLink: PropTypes.string, | ||
embedded: PropTypes.string, | ||
enablePosterMeta: PropTypes.string, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,15 +6,20 @@ describe('<bulbs-video>', () => { | |
let subject; | ||
let props = { | ||
src, | ||
disableLazyLoading: true, | ||
}; | ||
|
||
beforeEach(() => { | ||
BulbsVideo.prototype.setState = sinon.spy(); | ||
fetchMock.mock(src, {}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved this into each context that needs it since we want to delay this instantiation in lazy load tests. |
||
subject = new BulbsVideo(props); | ||
}); | ||
|
||
describe('#initialDispatch', () => { | ||
|
||
beforeEach(() => { | ||
subject = new BulbsVideo(props); | ||
}); | ||
|
||
it('fetches video data', () => { | ||
let spy = sinon.spy(subject.store.actions, 'fetchVideo'); | ||
subject.initialDispatch(); | ||
|
@@ -36,6 +41,10 @@ describe('<bulbs-video>', () => { | |
let resetSpy; | ||
let newSrc; | ||
|
||
beforeEach(() => { | ||
subject = new BulbsVideo(props); | ||
}); | ||
|
||
context('src did not change', () => { | ||
beforeEach(() => { | ||
fetchSpy = sinon.spy(subject.store.actions, 'fetchVideo'); | ||
|
@@ -72,4 +81,43 @@ describe('<bulbs-video>', () => { | |
}); | ||
}); | ||
}); | ||
|
||
describe('lazy loading', () => { | ||
let container; | ||
|
||
beforeEach((done) => { | ||
props.disableLazyLoading = false; | ||
|
||
container = document.createElement('div'); | ||
|
||
container.innerHTML = `<div style="height: 1000px;"></div>`; | ||
document.body.appendChild(container); | ||
setImmediate(() => done()); | ||
}); | ||
|
||
afterEach(() => { | ||
container.innerHTML = ''; | ||
}); | ||
|
||
it('should not load video until it is within viewing threshold', (done) => { | ||
let videoElement = document.createElement('bulbs-video'); | ||
videoElement.setAttribute('src', src); | ||
container.appendChild(videoElement); | ||
|
||
container.firstElementChild.style.height = '0px'; | ||
try { | ||
window.dispatchEvent(new Event('scroll')); | ||
} | ||
catch (error) { | ||
const event = document.createEvent('Event'); | ||
event.initEvent('scroll', false, true); | ||
window.dispatchEvent(event); | ||
} | ||
|
||
requestAnimationFrame(() => { | ||
expect($(container).find('.bulbs-video-root').length).to.equal(1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @collin is this the best way we can test this? Doesn't seem to be the best way to do this, but it works. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I'm not sure of a better way either. |
||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,6 @@ import VideoMetaRoot from '../elements/meta/components/root'; | |
|
||
export default function Cover (props) { | ||
let { video, actions, enablePosterMeta, disableMetaLink } = props; | ||
let imageId = parseInt(video.poster_url.match(/\d+/)[0], 10); | ||
let metaElement; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per @collin, this property is no longer used and was throwing errors during tests. |
||
|
||
if (enablePosterMeta) { | ||
|
@@ -22,7 +21,6 @@ export default function Cover (props) { | |
> | ||
<img | ||
className='bulbs-video-poster' | ||
imageId={imageId} | ||
src={video.poster_url} | ||
/> | ||
<div className='bulbs-video-poster-overlay'> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allows us to use object spread provided in current es-next Stage 3; babel, for some reason, is currently providing this in
stage-2
.