diff --git a/react/actions/publish.js b/react/actions/publish.js index 9c90e2b0..22d1fb42 100644 --- a/react/actions/publish.js +++ b/react/actions/publish.js @@ -86,8 +86,9 @@ export function updateThumbnailSelectedFile (file) { }; }; -export function startPublish () { +export function startPublish (history) { return { type: actions.PUBLISH_START, + data: { history }, }; } diff --git a/react/api/publishApi.js b/react/api/publishApi.js index e3d9939f..e69de29b 100644 --- a/react/api/publishApi.js +++ b/react/api/publishApi.js @@ -1,7 +0,0 @@ -import Request from 'utils/request'; -const { site: { host } } = require('../../config/speechConfig.js'); - -export function publish () { - // const url = `${host}/api/file/availability/${name}/${claimId}`; - -} diff --git a/react/containers/PublishForm/index.js b/react/containers/PublishForm/index.js index 1eb77195..8077973f 100644 --- a/react/containers/PublishForm/index.js +++ b/react/containers/PublishForm/index.js @@ -1,38 +1,16 @@ import {connect} from 'react-redux'; -import {clearFile, updateError, updatePublishStatus, startPublish} from 'actions/publish'; +import {clearFile, startPublish} from 'actions/publish'; import View from './view'; const mapStateToProps = ({ channel, publish }) => { return { - loggedInChannel : channel.loggedInChannel, - file : publish.file, - claim : publish.claim, - title : publish.metadata.title, - thumbnail : publish.metadata.thumbnail, - description : publish.metadata.description, - license : publish.metadata.license, - nsfw : publish.metadata.nsfw, - publishInChannel : publish.publishInChannel, - selectedChannel : publish.selectedChannel, - fileError : publish.error.file, - urlError : publish.error.url, - publishSubmitError: publish.error.publishSubmit, + file: publish.file, }; }; -const mapDispatchToProps = dispatch => { - return { - onFileClear: () => { - dispatch(clearFile()); - }, - onPublishStatusChange: (status, message) => { - dispatch(updatePublishStatus(status, message)); - }, - onPublishSubmitError: (value) => { - dispatch(updateError('publishSubmit', value)); - }, - startPublish, - }; +const mapDispatchToProps = { + clearFile, + startPublish, }; export default connect(mapStateToProps, mapDispatchToProps)(View); diff --git a/react/containers/PublishForm/view.jsx b/react/containers/PublishForm/view.jsx index b8e40476..362a343e 100644 --- a/react/containers/PublishForm/view.jsx +++ b/react/containers/PublishForm/view.jsx @@ -6,9 +6,15 @@ import PublishUrlInput from 'containers/PublishUrlInput'; import PublishThumbnailInput from 'containers/PublishThumbnailInput'; import PublishMetadataInputs from 'containers/PublishMetadataInputs'; import ChannelSelect from 'containers/ChannelSelect'; -import * as publishStates from 'constants/publish_claim_states'; class PublishForm extends React.Component { + constructor (props) { + super(props) + this.onPublishSubmit = this.onPublishSubmit.bind(this); + } + onPublishSubmit () { + this.props.startPublish(this.props.history); + } render () { return (
@@ -39,10 +45,10 @@ class PublishForm extends React.Component {
- +
- +

By clicking 'Publish', you affirm that you have the rights to publish this content to the LBRY network, and that you understand the properties of publishing it to a decentralized, user-controlled network. Read more.

diff --git a/react/sagas/publish.js b/react/sagas/publish.js index b582ab20..ca189576 100644 --- a/react/sagas/publish.js +++ b/react/sagas/publish.js @@ -1,70 +1,11 @@ import { call, put, select, takeLatest } from 'redux-saga/effects'; import * as actions from 'constants/publish_action_types'; -import { updateError } from 'actions/publish'; -// import { publish } from 'api/fileApi'; -import { selectPublishState } from '../selectors/publish'; -import { selectChannelState } from '../selectors/channel'; -import * as publishStates from '../constants/publish_claim_states'; - -const validateChannelSelection = (publishInChannel, selectedChannel, loggedInChannel) => { - console.log('validating channel selection'); - // make sure all required data is provided - return new Promise((resolve, reject) => { - // if publishInChannel is true, is a channel selected & logged in? - if (publishInChannel && (selectedChannel !== loggedInChannel.name)) { - return reject('Log in to a channel or select Anonymous'); - } - resolve(); - }); -} - -const validatePublishParams = (file, claim, urlError) => { - console.log('validating publish params'); - // make sure all required data is provided - return new Promise((resolve, reject) => { - // is there a file? - if (!file) { - return reject('Please choose a file'); - } - // is there a claim chosen? - if (!claim) { - return reject('Please enter a URL'); - } - if (urlError) { - return reject('Fix the url'); - } - resolve(); - }); -} - -const createPublishMetadata = (claim, { type }, { title, thumbnail, description, license, nsfw }, publishInChannel, selectedChannel) => { - let metadata = { - name: claim, - title, - thumbnail, - description, - license, - nsfw, - type, - }; - if (publishInChannel) { - metadata['channelName'] = selectedChannel; - } - return metadata; -} - -const createPublishFormData = (file, metadata) => { - var fd = new FormData(); - // append file - fd.append('file', file); - // append metadata - for (var key in metadata) { - if (metadata.hasOwnProperty(key)) { - fd.append(key, metadata[key]); - } - } - return fd; -} +import * as publishStates from 'constants/publish_claim_states'; +import { updateError, updatePublishStatus, clearFile } from 'actions/publish'; +import { selectPublishState } from 'selectors/publish'; +import { selectChannelState } from 'selectors/channel'; +import { validateChannelSelection, validatePublishParams } from 'utils/validate'; +import { createPublishMetadata, createPublishFormData } from 'utils/publish'; const makePublishRequest = (fd) => { console.log('making publish request'); @@ -72,62 +13,65 @@ const makePublishRequest = (fd) => { const uri = '/api/claim/publish'; const xhr = new XMLHttpRequest(); xhr.upload.addEventListener('loadstart', () => { - this.props.onPublishStatusChange(publishStates.LOAD_START, 'upload started'); + put(updatePublishStatus(publishStates.LOAD_START, 'upload started')); }); xhr.upload.addEventListener('progress', (e) => { if (e.lengthComputable) { const percentage = Math.round((e.loaded * 100) / e.total); console.log('progress:', percentage); - this.props.onPublishStatusChange(publishStates.LOADING, `${percentage}%`); + put(updatePublishStatus(publishStates.LOADING, `${percentage}%`)); } }, false); xhr.upload.addEventListener('load', () => { console.log('loaded 100%'); - this.props.onPublishStatusChange(publishStates.PUBLISHING, null); + put(updatePublishStatus(publishStates.PUBLISHING, null)); }, false); xhr.open('POST', uri, true); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { const response = JSON.parse(xhr.response); - console.log('publish response:', response); + // console.log('publish response:', response); if ((xhr.status === 200) && response.success) { - this.props.history.push(`/${response.data.claimId}/${response.data.name}`); - this.props.onFileClear(); + resolve(response); } else { - this.props.onPublishStatusChange(publishStates.FAILED, response.message); + reject(new Error(response.message)); } } }; // Initiate a multipart/form-data upload xhr.send(fd); }); -} +}; -function * publishFile () { +function * publishFile (action) { + const { history } = action.data; console.log('publishing file'); const { publishInChannel, selectedChannel, file, claim, metadata, error: { url: urlError } } = yield select(selectPublishState); const { loggedInChannel } = yield select(selectChannelState); // validate the channel selection try { - yield call(validateChannelSelection, publishInChannel, selectedChannel, loggedInChannel); + validateChannelSelection(publishInChannel, selectedChannel, loggedInChannel); } catch (error) { - return yield put(updateError('channel', error)); + return yield put(updateError('channel', error.message)); }; // validate publish parameters try { - yield call(validatePublishParams, file, claim, urlError); + validatePublishParams(file, claim, urlError); } catch (error) { - return yield put(updateError('publishSubmit', error)); + return yield put(updateError('publishSubmit', error.message)); } // create metadata const publishMetadata = createPublishMetadata(claim, file, metadata, publishInChannel, selectedChannel); // create form data const publishFormData = createPublishFormData(file, publishMetadata); // make the publish request + let response; try { - yield call(makePublishRequest, publishFormData); + response = yield call(makePublishRequest, publishFormData); + yield put(clearFile()); + history.push(`/${response.data.claimId}/${response.data.name}`); } catch (error) { - return yield put(updateError('publishSubmit', error)); + return yield put(updatePublishStatus(publishStates.FAILED, error.message)); } }; diff --git a/react/utils/browserHistory.js b/react/utils/browserHistory.js new file mode 100644 index 00000000..e69de29b diff --git a/react/utils/publish.js b/react/utils/publish.js new file mode 100644 index 00000000..4a41c5e3 --- /dev/null +++ b/react/utils/publish.js @@ -0,0 +1,28 @@ +export const createPublishMetadata = (claim, { type }, { title, thumbnail, description, license, nsfw }, publishInChannel, selectedChannel) => { + let metadata = { + name: claim, + title, + thumbnail, + description, + license, + nsfw, + type, + }; + if (publishInChannel) { + metadata['channelName'] = selectedChannel; + } + return metadata; +}; + +export const createPublishFormData = (file, metadata) => { + let fd = new FormData(); + // append file + fd.append('file', file); + // append metadata + for (let key in metadata) { + if (metadata.hasOwnProperty(key)) { + fd.append(key, metadata[key]); + } + } + return fd; +}; diff --git a/react/utils/validate.js b/react/utils/validate.js new file mode 100644 index 00000000..1209cdfe --- /dev/null +++ b/react/utils/validate.js @@ -0,0 +1,19 @@ +export const validateChannelSelection = (publishInChannel, selectedChannel, loggedInChannel) => { + console.log('validating channel selection'); + if (publishInChannel && (selectedChannel !== loggedInChannel.name)) { + throw new Error('Log in to a channel or select Anonymous'); + } +}; + +export const validatePublishParams = (file, claim, urlError) => { + console.log('validating publish params'); + if (!file) { + throw new Error('Please choose a file'); + } + if (!claim) { + throw new Error('Please enter a URL'); + } + if (urlError) { + throw new Error('Fix the url'); + } +};