cleaned up thumbnail generation and removed extra props

This commit is contained in:
bill bittner 2018-03-02 14:57:25 -08:00
parent c8ae8f3047
commit c9747294ed
6 changed files with 29 additions and 77 deletions

View file

@ -72,16 +72,10 @@ export function toggleMetadataInputs (showMetadataInputs) {
}; };
}; };
export function updateThumbnailClaim (claim, url) { export function onNewThumbnail (file) {
console.log('new thumbnail action created');
return { return {
type: actions.THUMBNAIL_CLAIM_UPDATE, type: actions.THUMBNAIL_NEW,
data: { claim, url },
};
};
export function updateThumbnailSelectedFile (file) {
return {
type: actions.THUMBNAIL_FILE_SELECT,
data: file, data: file,
}; };
}; };

View file

@ -7,6 +7,5 @@ export const PUBLISH_STATUS_UPDATE = 'PUBLISH_STATUS_UPDATE';
export const ERROR_UPDATE = 'ERROR_UPDATE'; export const ERROR_UPDATE = 'ERROR_UPDATE';
export const SELECTED_CHANNEL_UPDATE = 'SELECTED_CHANNEL_UPDATE'; export const SELECTED_CHANNEL_UPDATE = 'SELECTED_CHANNEL_UPDATE';
export const TOGGLE_METADATA_INPUTS = 'TOGGLE_METADATA_INPUTS'; export const TOGGLE_METADATA_INPUTS = 'TOGGLE_METADATA_INPUTS';
export const THUMBNAIL_CLAIM_UPDATE = 'THUMBNAIL_CLAIM_UPDATE'; export const THUMBNAIL_NEW = 'THUMBNAIL_NEW';
export const THUMBNAIL_FILE_SELECT = 'THUMBNAIL_FILE_SELECT';
export const PUBLISH_START = 'PUBLISH_START'; export const PUBLISH_START = 'PUBLISH_START';

View file

@ -5,7 +5,7 @@ import View from './view';
const mapStateToProps = ({ publish }) => { const mapStateToProps = ({ publish }) => {
return { return {
file : publish.file, file : publish.file,
thumbnail: publish.thumbnail.selectedFile, thumbnail: publish.thumbnail,
fileError: publish.error.file, fileError: publish.error.file,
}; };
}; };

View file

@ -1,29 +1,15 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { updateThumbnailClaim, updateThumbnailSelectedFile } from 'actions/publish'; import { onNewThumbnail } from 'actions/publish';
import View from './view'; import View from './view';
const mapStateToProps = ({ publish, site }) => { const mapStateToProps = ({ publish: { file } }) => {
return { return {
host : site.host, file,
// file props
file : publish.file,
claim : publish.claim,
// channel props
thumbnailChannel: publish.thumbnail.channel,
thumbnailClaim : publish.thumbnail.claim,
thumbnailFile : publish.thumbnail.selectedFile,
}; };
}; };
const mapDispatchToProps = dispatch => { const mapDispatchToProps = {
return { onNewThumbnail,
onThumbnailChange: (claim, url) => {
dispatch(updateThumbnailClaim(claim, url));
},
onThumbnailFileSelect: (file) => {
dispatch(updateThumbnailSelectedFile(file));
},
};
}; };
export default connect(mapStateToProps, mapDispatchToProps)(View); export default connect(mapStateToProps, mapDispatchToProps)(View);

View file

@ -7,7 +7,7 @@ function dataURItoBlob(dataURI) {
let mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; let mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array // write the bytes of the string to a typed array
let ia = new Uint8Array(byteString.length); let ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) { for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i); ia[i] = byteString.charCodeAt(i);
} }
return new Blob([ia], {type: mimeString}); return new Blob([ia], {type: mimeString});
@ -23,36 +23,26 @@ class PublishThumbnailInput extends React.Component {
sliderMaxRange: null, sliderMaxRange: null,
sliderValue : null, sliderValue : null,
}; };
this.handleSliderChange = this.handleSliderChange.bind(this);
this.handleVideoLoadedData = this.handleVideoLoadedData.bind(this); this.handleVideoLoadedData = this.handleVideoLoadedData.bind(this);
this.setThumbnailWithSnapshot = this.setThumbnailWithSnapshot.bind(this); this.handleSliderChange = this.handleSliderChange.bind(this);
this.createThumbnail = this.createThumbnail.bind(this);
} }
componentDidMount () { componentDidMount () {
console.log('thumbnail input did mount'); const { file } = this.props;
const { claim, file, host, thumbnailChannel } = this.props;
this.setThumbnailClaimAndUrl(claim, host, thumbnailChannel);
this.setVideoSource(file); this.setVideoSource(file);
} }
componentWillReceiveProps (nextProps) { componentWillReceiveProps (nextProps) {
// if file changes // if file changes
if (nextProps.file !== this.props.file) { if (nextProps.file && nextProps.file !== this.props.file) {
const { file } = nextProps; const { file } = nextProps;
this.setVideoSource(file); this.setVideoSource(file);
}; };
// if claim changes
if (nextProps.claim !== this.props.claim) {
const { claim, host, thumbnailChannel } = nextProps;
this.setThumbnailClaimAndUrl(claim, host, thumbnailChannel);
}
}
setThumbnailClaimAndUrl (claim, host, thumbnailChannel) {
const url = `${host}/${thumbnailChannel}/${claim}-thumb.png`;
this.props.onThumbnailChange(`${claim}-thumb`, url);
} }
setVideoSource (file) { setVideoSource (file) {
const previewReader = new FileReader(); const previewReader = new FileReader();
previewReader.readAsDataURL(file); previewReader.readAsDataURL(file);
previewReader.onloadend = () => { previewReader.onloadend = () => {
console.log('preview reader complete');
this.setState({videoSource: previewReader.result}); this.setState({videoSource: previewReader.result});
}; };
} }
@ -77,22 +67,19 @@ class PublishThumbnailInput extends React.Component {
let video = document.getElementById('video-thumb-player'); let video = document.getElementById('video-thumb-player');
video.currentTime = value / 100; video.currentTime = value / 100;
} }
setThumbnailWithSnapshot () { createThumbnail () {
// take a snapshot // take a snapshot
const snapshot = this.takeSnapShot();
// set the thumbnail in redux store
if (snapshot) {
this.props.onThumbnailFileSelect(snapshot);
}
}
takeSnapShot () {
let video = document.getElementById('video-thumb-player'); let video = document.getElementById('video-thumb-player');
let canvas = document.createElement('canvas'); let canvas = document.createElement('canvas');
canvas.width = video.videoWidth; canvas.width = video.videoWidth;
canvas.height = video.videoHeight; canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height); canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
const dataUri = canvas.toDataURL(); const dataUrl = canvas.toDataURL();
return dataURItoBlob(dataUri); const snapshot = dataURItoBlob(dataUrl)
// set the thumbnail in redux store
if (snapshot) {
this.props.onNewThumbnail(snapshot);
}
} }
render () { render () {
const { error, videoSource, sliderMinRange, sliderMaxRange, sliderValue } = this.state; const { error, videoSource, sliderMinRange, sliderMaxRange, sliderValue } = this.state;
@ -112,7 +99,7 @@ class PublishThumbnailInput extends React.Component {
playsInline playsInline
onLoadedData={this.handleVideoLoadedData} onLoadedData={this.handleVideoLoadedData}
src={videoSource} src={videoSource}
onTimeUpdate={this.setThumbnailWithSnapshot} onSeeked={this.createThumbnail}
/> />
{ {
sliderValue ? ( sliderValue ? (
@ -127,7 +114,7 @@ class PublishThumbnailInput extends React.Component {
/> />
</div> </div>
) : ( ) : (
<p>loading slider... </p> <p className='info-message' >loading... </p>
) )
} }
</div> </div>

View file

@ -25,11 +25,8 @@ const initialState = {
license : '', license : '',
nsfw : false, nsfw : false,
}, },
thumbnail: { thumbnailChannel: publish.thumbnailChannel,
channel : publish.thumbnailChannel, thumbnail : null,
claim : null,
selectedFile: null,
},
}; };
export default function (state = initialState, action) { export default function (state = initialState, action) {
@ -72,20 +69,9 @@ export default function (state = initialState, action) {
return Object.assign({}, state, { return Object.assign({}, state, {
showMetadataInputs: action.data, showMetadataInputs: action.data,
}); });
case actions.THUMBNAIL_CLAIM_UPDATE: case actions.THUMBNAIL_NEW:
return Object.assign({}, state, { return Object.assign({}, state, {
metadata: Object.assign({}, state.metadata, { thumbnail: action.data,
thumbnail: action.data.url,
}),
thumbnail: Object.assign({}, state.thumbnail, {
claim: action.data.claim,
}),
});
case actions.THUMBNAIL_FILE_SELECT:
return Object.assign({}, state, {
thumbnail: Object.assign({}, state.thumbnail, {
selectedFile: action.data,
}),
}); });
default: default:
return state; return state;