added thumbnail input with redux
This commit is contained in:
parent
622b150d1d
commit
ef5c67f293
7 changed files with 97 additions and 116 deletions
|
@ -15,9 +15,9 @@ class Preview extends React.Component {
|
|||
this.previewFile(this.props.file);
|
||||
}
|
||||
}
|
||||
componentWillReceiveProps ({ file }) {
|
||||
console.log('Preview will receive props');
|
||||
this.previewFile(file);
|
||||
componentWillReceiveProps (newProps) {
|
||||
console.log('Preview will receive props', newProps);
|
||||
this.previewFile(newProps.file);
|
||||
}
|
||||
previewFile (file) {
|
||||
console.log('previewFile', file)
|
||||
|
@ -29,7 +29,7 @@ class Preview extends React.Component {
|
|||
that.setState({previewSource: previewReader.result});
|
||||
};
|
||||
} else {
|
||||
that.setState({previewSource: '/assets/img/video_thumb_default.png'});
|
||||
that.setState({previewSource: (this.props.thumbnail || '/assets/img/video_thumb_default.png')});
|
||||
}
|
||||
}
|
||||
render () {
|
||||
|
@ -46,7 +46,8 @@ class Preview extends React.Component {
|
|||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
file: state.file,
|
||||
file : state.file,
|
||||
thumbnail: state.metadata.thumbnail,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -41,12 +41,11 @@ class PublishForm extends React.Component {
|
|||
|
||||
</div>
|
||||
<div className="column column--5 column--sml-10" >
|
||||
|
||||
<div className="row row--padded">
|
||||
|
||||
<PreviewDropzone />
|
||||
{ (this.props.fileType === 'video/mp4') && <PublishThumbnailInput /> }
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="column column--5 column--sml-10 align-content-top">
|
||||
<div id="publish-active-area" className="row row--padded">
|
||||
|
@ -63,6 +62,8 @@ class PublishForm extends React.Component {
|
|||
<ChannelSelector />
|
||||
</div>
|
||||
|
||||
{ (this.props.fileType === 'video/mp4') && <PublishThumbnailInput /> }
|
||||
|
||||
<div className="row row--padded row--no-top row--no-bottom row--wide">
|
||||
<PublishMetadataInputs />
|
||||
</div>
|
||||
|
@ -89,9 +90,8 @@ class PublishForm extends React.Component {
|
|||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
fileType : state.file.type,
|
||||
claim : state.claim,
|
||||
thumbnail: state.thumbnail,
|
||||
fileType: state.file.type,
|
||||
claim : state.claim,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -2,6 +2,14 @@ import React from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { updateMetadata } from '../actions';
|
||||
|
||||
/*
|
||||
const textarea = document.getElementById('publish-description');
|
||||
const limit = 200;
|
||||
textarea.oninput = () => {
|
||||
textarea.style.height = '';
|
||||
textarea.style.height = Math.min(textarea.scrollHeight, limit) + 'px';
|
||||
*/
|
||||
|
||||
class MetadataInputs extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,13 +1,86 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { updateMetadata } from '../actions';
|
||||
|
||||
class ThumbnailInput extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
videoPreviewSrc: null,
|
||||
}
|
||||
this.urlIsAnImage = this.urlIsAnImage.bind(this);
|
||||
this.testImage = this.testImage.bind(this);
|
||||
this.updateVideoThumb = this.updateVideoThumb.bind(this);
|
||||
}
|
||||
urlIsAnImage (url) {
|
||||
return (url.match(/\.(jpeg|jpg|gif|png)$/) != null);
|
||||
}
|
||||
testImage (url, timeoutT) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const timeout = timeoutT || 5000;
|
||||
let timer;
|
||||
let img = new Image();
|
||||
img.onerror = img.onabort = function () {
|
||||
clearTimeout(timer);
|
||||
reject('error');
|
||||
};
|
||||
img.onload = function () {
|
||||
clearTimeout(timer);
|
||||
resolve('success');
|
||||
};
|
||||
timer = setTimeout(function () {
|
||||
// reset .src to invalid URL so it stops previous
|
||||
// loading, but doesn't trigger new load
|
||||
img.src = '//!!!!/test.jpg';
|
||||
reject('timeout');
|
||||
}, timeout);
|
||||
img.src = url;
|
||||
});
|
||||
}
|
||||
updateVideoThumb (event) {
|
||||
var imageUrl = event.target.value;
|
||||
const that = this;
|
||||
if (this.urlIsAnImage(imageUrl)) {
|
||||
this.testImage(imageUrl, 3000)
|
||||
.then(function (result) {
|
||||
if (result === 'success') {
|
||||
that.props.onThumbnailChange('thumbnail', imageUrl);
|
||||
} else if (result === 'timeout') {
|
||||
console.log('could not resolve the provided thumbnail image url');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('encountered an error loading thumbnail image url:', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<h3>thumbnail component</h3>
|
||||
<div className="row row--padded row--wide row--no-top" id="publish-thumbnail">
|
||||
<div className="column column--3 column--sml-10">
|
||||
<label className="label">Thumbnail:</label>
|
||||
</div><div className="column column--6 column--sml-10">
|
||||
<div className="input-text--primary">
|
||||
<input type="text" id="claim-thumbnail-input" className="input-text input-text--full-width" placeholder="https://spee.ch/xyz/example.jpg" value={this.props.thumbnail} onInput={this.updateVideoThumb} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ThumbnailInput;
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
thumbnail: state.metadata.thumbnail,
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
onThumbnailChange: (name, value) => {
|
||||
dispatch(updateMetadata(name, value));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ThumbnailInput);
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
<div class="row row--padded row--no-top row--no-bottom row--wide">
|
||||
<div class="column column--10">
|
||||
<a class="label link--primary" id="publish-details-toggle" href="#" onclick="toggleSection(event)" data-open="false" data-openlabel="[less]" data-closedlabel="[more]" data-slaveelementid="publish-details">[more]</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="publish-details" hidden="true" class="row row--padded row--wide">
|
||||
|
||||
<!-- description input -->
|
||||
<div class="row row--no-top">
|
||||
<div class="column column--3 column--med-10 align-content-top">
|
||||
<label for="publish-license" class="label">Description:</label>
|
||||
</div><div class="column column--7 column--sml-10">
|
||||
<textarea rows="1" id="publish-description" class="textarea textarea--primary textarea--full-width" placeholder="Optional description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row row--no-top">
|
||||
<div class="column column--3 column--med-10">
|
||||
<label for="publish-license" class="label">License:</label>
|
||||
</div><div class="column column--7 column--sml-10">
|
||||
<select type="text" id="publish-license" class="select select--primary">
|
||||
<option value=" ">Unspecified</option>
|
||||
<option value="Public Domain">Public Domain</option>
|
||||
<option value="Creative Commons">Creative Commons</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row row--no-top">
|
||||
<div class="column column--3">
|
||||
<label for="publish-nsfw" class="label">Mature:</label>
|
||||
</div><div class="column column--7">
|
||||
<input class="input-checkbox" type="checkbox" id="publish-nsfw">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
const textarea = document.getElementById('publish-description');
|
||||
const limit = 200;
|
||||
textarea.oninput = () => {
|
||||
textarea.style.height = '';
|
||||
textarea.style.height = Math.min(textarea.scrollHeight, limit) + 'px';
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
|
@ -1,56 +1,5 @@
|
|||
<div class="row row--padded row--wide row--no-top" id="publish-thumbnail" hidden="true">
|
||||
<div class="column column--3 column--sml-10">
|
||||
<label class="label">Thumbnail:</label>
|
||||
</div><div class="column column--6 column--sml-10">
|
||||
<div class="input-text--primary">
|
||||
<input type="text" id="claim-thumbnail-input" class="input-text input-text--full-width" placeholder="https://spee.ch/xyz/example.jpg" value="" oninput="updateVideoThumb(event)">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function urlIsAnImage(url) {
|
||||
return(url.match(/\.(jpeg|jpg|gif|png)$/) != null);
|
||||
}
|
||||
|
||||
function testImage(url, timeoutT) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var timeout = timeoutT || 5000;
|
||||
var timer, img = new Image();
|
||||
img.onerror = img.onabort = function () {
|
||||
clearTimeout(timer);
|
||||
reject("error");
|
||||
};
|
||||
img.onload = function () {
|
||||
clearTimeout(timer);
|
||||
resolve("success");
|
||||
};
|
||||
timer = setTimeout(function () {
|
||||
// reset .src to invalid URL so it stops previous
|
||||
// loading, but doesn't trigger new load
|
||||
img.src = "//!!!!/test.jpg";
|
||||
reject("timeout");
|
||||
}, timeout);
|
||||
img.src = url;
|
||||
});
|
||||
}
|
||||
|
||||
function updateVideoThumb(event){
|
||||
var videoPreview = document.getElementById('asset-preview');
|
||||
var imageUrl = event.target.value;
|
||||
if (urlIsAnImage(imageUrl)){
|
||||
testImage(imageUrl, 3000)
|
||||
.then(function(result) {
|
||||
if (result === 'success'){
|
||||
videoPreview.src = imageUrl;
|
||||
} else if (result === 'timeout') {
|
||||
console.log('could not resolve the provided thumbnail image url');
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.log('encountered an error loading thumbnail image url.')
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
|
Loading…
Reference in a new issue