Skip to content

Commit 3ab70fa

Browse files
author
Nir Maoz
authored
Reload video on props change (#200)
1 parent b73593a commit 3ab70fa

File tree

7 files changed

+58
-25
lines changed

7 files changed

+58
-25
lines changed

bundlewatch.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const bundlewatchConfig = {
22
files: [
33
{
44
path: './dist/cloudinary-react.js',
5-
maxSize: '44kb'
5+
maxSize: '44.5kb'
66
}
77
],
88
defaultCompression: 'gzip',

e2e-test/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
]
3636
},
3737
"devDependencies": {
38+
"typescript": "^3.7.2",
3839
"cypress": "^4.9.0",
3940
"start-server-and-test": "^1.11.0"
4041
}

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
"mocha": "^8.0.1",
5555
"npm-run-all": "^4.1.5",
5656
"react-dom": "^16.3.3",
57+
"sinon": "^9.2.1",
58+
"sinon-chai": "^3.5.0",
5759
"webpack": "4.27.1",
5860
"webpack-cli": "^3.1.2"
5961
},

src/components/CloudinaryComponent/CloudinaryComponent.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {PureComponent} from 'react';
1+
import React, {PureComponent, createRef} from 'react';
22
import PropTypes from 'prop-types';
33
import {Transformation, Util} from 'cloudinary-core';
44
import {CloudinaryContextType} from '../CloudinaryContext/CloudinaryContextType';
@@ -43,6 +43,7 @@ function only(source, keys = []) {
4343
class CloudinaryComponent extends PureComponent {
4444
constructor(props, context) {
4545
super(props, context);
46+
this.element = createRef();
4647
}
4748

4849
render() {
@@ -158,6 +159,23 @@ class CloudinaryComponent extends PureComponent {
158159
return CloudinaryComponent.normalizeOptions(context, props);
159160
};
160161

162+
/**
163+
* Attach both this.element and props.innerRef as ref to the given element
164+
* @param element - the element to attach a ref to
165+
*/
166+
attachRef = (element) => {
167+
const {innerRef} = this.props;
168+
this.element.current = element;
169+
170+
if (innerRef) {
171+
if (innerRef instanceof Function) {
172+
innerRef(element);
173+
} else {
174+
innerRef.current = element;
175+
}
176+
}
177+
};
178+
161179
static contextType = CloudinaryContextType;
162180
}
163181

src/components/Image/Image.js

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ const RESPONSIVE_OVERRIDE_WARNING = [
1818
class Image extends CloudinaryComponent {
1919
constructor(props, context) {
2020
super(props, context);
21-
this.imgElement = createRef();
2221
this.placeholderElement = createRef();
2322
this.state = {isLoaded: false}
2423
this.listenerRemovers = [];
@@ -33,7 +32,7 @@ class Image extends CloudinaryComponent {
3332
console.warn(RESPONSIVE_OVERRIDE_WARNING);
3433
}
3534

36-
return responsive && this.imgElement && this.imgElement.current;
35+
return responsive && this.element && this.element.current;
3736
}
3837

3938
/**
@@ -95,7 +94,7 @@ class Image extends CloudinaryComponent {
9594
// Handle lazy loading
9695
if (this.shouldLazyLoad()) {
9796
// Will set this.state.isInView = true when in view
98-
Util.detectIntersection(this.imgElement.current, this.onIntersect);
97+
Util.detectIntersection(this.element.current, this.onIntersect);
9998
} else {
10099
// Handle responsive only if lazy loading wasn't requested or already handled
101100
if (this.isResponsive()) {
@@ -109,29 +108,12 @@ class Image extends CloudinaryComponent {
109108
}
110109

111110
// Make original image responsive
112-
const removeImgListener = makeElementResponsive(this.imgElement.current, options);
111+
const removeImgListener = makeElementResponsive(this.element.current, options);
113112
this.listenerRemovers.push(removeImgListener);
114113
}
115114
}
116115
}
117116

118-
/**
119-
* Attach both this.imgElement and props.innerRef as ref to the given element
120-
* @param imgElement - the element to attach a ref to
121-
*/
122-
attachRef = (imgElement) => {
123-
const {innerRef} = this.props;
124-
this.imgElement.current = imgElement;
125-
126-
if (innerRef) {
127-
if (innerRef instanceof Function) {
128-
innerRef(imgElement);
129-
} else {
130-
innerRef.current = imgElement;
131-
}
132-
}
133-
};
134-
135117
shouldLazyLoad = () => {
136118
const {loading} = this.getExtendedProps();
137119
const {isInView} = this.state;

src/components/Video/Video.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,24 @@ class Video extends CloudinaryComponent {
9898
return {sources, tagAttributes};
9999
};
100100

101+
reloadVideo = () => {
102+
if (this.element && this.element.current){
103+
this.element.current.load();
104+
}
105+
}
106+
107+
componentDidUpdate() {
108+
// Load video on props change
109+
this.reloadVideo();
110+
}
111+
112+
113+
101114
/**
102115
* Render a video element
103116
*/
104117
render() {
105-
const {innerRef, fallback, children} = this.props;
118+
const {fallback, children} = this.props;
106119

107120
const {
108121
tagAttributes, // Attributes of this video element
@@ -111,7 +124,7 @@ class Video extends CloudinaryComponent {
111124

112125
return (
113126
<video
114-
ref={innerRef}
127+
ref={this.attachRef}
115128
{...tagAttributes}>
116129
{sources}
117130
{fallback}

test/VideoTest.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import React from 'react';
2+
import sinon from 'sinon';
3+
import sinonChai from 'sinon-chai'
24
import chai, {expect} from 'chai';
35
import {shallow, mount} from 'enzyme';
46
import cloudinary from './cloudinary-proxy';
7+
chai.use(sinonChai);
8+
59
const {Video, Transformation} = cloudinary;
610
chai.use(require('chai-string'));
711

@@ -199,4 +203,17 @@ describe('Video', () => {
199203
expect(video.prop('data-testid')).to.equal("testing");
200204
expect(video.prop('datatestid')).to.equal(undefined);
201205
});
206+
it('reloads video on props change', () => {
207+
const tag = shallow(
208+
<Video cloudName='demo' publicId='dog'/>
209+
);
210+
211+
//detect calls for reloadVideo()
212+
sinon.spy(tag.instance(), 'reloadVideo');
213+
214+
expect(tag.instance().reloadVideo).to.not.have.been.called;
215+
216+
tag.setProps({publicId: "cat"});
217+
expect(tag.instance().reloadVideo).to.have.been.called;
218+
})
202219
});

0 commit comments

Comments
 (0)