updated publish ux/ui
This commit is contained in:
parent
b7b3a78730
commit
4da04d833c
8 changed files with 137 additions and 109 deletions
|
@ -1,7 +1,7 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { updateLoggedInChannel } from 'actions/channel';
|
||||
import View from './view';
|
||||
import {updateSelectedChannel} from '../../actions/publish';
|
||||
import {updateSelectedChannel} from 'actions/publish';
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
|
|
|
@ -119,38 +119,41 @@ class ChannelCreateForm extends React.Component {
|
|||
return (
|
||||
<div>
|
||||
{ !this.state.status ? (
|
||||
<form id="publish-channel-form">
|
||||
<p id="input-error-channel-name" className="info-message-placeholder info-message--failure">{this.state.error}</p>
|
||||
<div className="row row--wide row--short">
|
||||
<div className="column column--3 column--sml-10">
|
||||
<label className="label" htmlFor="new-channel-name">Name:</label>
|
||||
</div><div className="column column--6 column--sml-10">
|
||||
<div className="input-text--primary flex-container--row flex-container--left-bottom span--relative">
|
||||
<form id='publish-channel-form'>
|
||||
<div className='row row--wide row--short'>
|
||||
<div className='column column--3 column--sml-10'>
|
||||
<label className='label' htmlFor='new-channel-name'>Name:</label>
|
||||
</div><div className='column column--6 column--sml-10'>
|
||||
<div className='input-text--primary flex-container--row flex-container--left-bottom span--relative'>
|
||||
<span>@</span>
|
||||
<input type="text" name="channel" id="new-channel-name" className="input-text" placeholder="exampleChannelName" value={this.state.channel} onChange={this.handleChannelInput} />
|
||||
{ (this.state.channel && !this.state.error) && <span id="input-success-channel-name" className="info-message--success span--absolute">{'\u2713'}</span> }
|
||||
{ this.state.error && <span id="input-success-channel-name" className="info-message--failure span--absolute">{'\u2716'}</span> }
|
||||
<input type='text' name='channel' id='new-channel-name' className='input-text' placeholder='exampleChannelName' value={this.state.channel} onChange={this.handleChannelInput} />
|
||||
{ (this.state.channel && !this.state.error) && <span id='input-success-channel-name' className='info-message--success span--absolute'>{'\u2713'}</span> }
|
||||
{ this.state.error && <span id='input-success-channel-name' className='info-message--failure span--absolute'>{'\u2716'}</span> }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row row--wide row--short">
|
||||
<div className="column column--3 column--sml-10">
|
||||
<label className="label" htmlFor="new-channel-password">Password:</label>
|
||||
</div><div className="column column--6 column--sml-10">
|
||||
<div className="input-text--primary">
|
||||
<input type="password" name="password" id="new-channel-password" className="input-text" placeholder="" value={this.state.password} onChange={this.handleInput} />
|
||||
<div className='row row--wide row--short'>
|
||||
<div className='column column--3 column--sml-10'>
|
||||
<label className='label' htmlFor='new-channel-password'>Password:</label>
|
||||
</div><div className='column column--6 column--sml-10'>
|
||||
<div className='input-text--primary'>
|
||||
<input type='password' name='password' id='new-channel-password' className='input-text' placeholder='' value={this.state.password} onChange={this.handleInput} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row row--wide">
|
||||
<button className="button--primary" onClick={this.createChannel}>Create Channel</button>
|
||||
{this.state.error ? (
|
||||
<p className='info-message--failure'>{this.state.error}</p>
|
||||
) : (
|
||||
<p className='info-message'>Choose a name and password for your channel</p>
|
||||
)}
|
||||
<div className='row row--wide'>
|
||||
<button className='button--primary' onClick={this.createChannel}>Create Channel</button>
|
||||
</div>
|
||||
</form>
|
||||
) : (
|
||||
<div>
|
||||
<p className="fine-print">{this.state.status}</p>
|
||||
<ProgressBar size={12}/>
|
||||
<p className='fine-print'>{this.state.status}</p>
|
||||
<ProgressBar size={12} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -26,7 +26,7 @@ class ChannelLoginForm extends React.Component {
|
|||
'Content-Type': 'application/json',
|
||||
}),
|
||||
credentials: 'include',
|
||||
}
|
||||
};
|
||||
request('login', params)
|
||||
.then(({success, channelName, shortChannelId, channelClaimId, message}) => {
|
||||
console.log('loginToChannel success:', success);
|
||||
|
@ -47,30 +47,33 @@ class ChannelLoginForm extends React.Component {
|
|||
}
|
||||
render () {
|
||||
return (
|
||||
<form id="channel-login-form">
|
||||
<p id="login-error-display-element" className="info-message-placeholder info-message--failure">{this.state.error}</p>
|
||||
<div className="row row--wide row--short">
|
||||
<div className="column column--3 column--sml-10">
|
||||
<label className="label" htmlFor="channel-login-name-input">Name:</label>
|
||||
</div><div className="column column--6 column--sml-10">
|
||||
<div className="input-text--primary flex-container--row flex-container--left-bottom">
|
||||
<form id='channel-login-form'>
|
||||
<div className='row row--wide row--short'>
|
||||
<div className='column column--3 column--sml-10'>
|
||||
<label className='label' htmlFor='channel-login-name-input'>Name:</label>
|
||||
</div><div className='column column--6 column--sml-10'>
|
||||
<div className='input-text--primary flex-container--row flex-container--left-bottom'>
|
||||
<span>@</span>
|
||||
<input type="text" id="channel-login-name-input" className="input-text" name="name" placeholder="Your Channel Name" value={this.state.channelName} onChange={this.handleInput}/>
|
||||
<input type='text' id='channel-login-name-input' className='input-text' name='name' placeholder='Your Channel Name' value={this.state.channelName} onChange={this.handleInput} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row row--wide row--short">
|
||||
<div className="column column--3 column--sml-10">
|
||||
<label className="label" htmlFor="channel-login-password-input" >Password:</label>
|
||||
</div><div className="column column--6 column--sml-10">
|
||||
<div className="input-text--primary">
|
||||
<input type="password" id="channel-login-password-input" name="password" className="input-text" placeholder="" value={this.state.channelPassword} onChange={this.handleInput}/>
|
||||
<div className='row row--wide row--short'>
|
||||
<div className='column column--3 column--sml-10'>
|
||||
<label className='label' htmlFor='channel-login-password-input' >Password:</label>
|
||||
</div><div className='column column--6 column--sml-10'>
|
||||
<div className='input-text--primary'>
|
||||
<input type='password' id='channel-login-password-input' name='password' className='input-text' placeholder='' value={this.state.channelPassword} onChange={this.handleInput} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row row--wide">
|
||||
<button className="button--primary" onClick={this.loginToChannel}>Authenticate</button>
|
||||
{ this.state.error ? (
|
||||
<p className='info-message--failure'>{this.state.error}</p>
|
||||
) : (
|
||||
<p className='info-message'>Enter the name and password for your channel</p>
|
||||
)}
|
||||
<div className='row row--wide'>
|
||||
<button className='button--primary' onClick={this.loginToChannel}>Authenticate</button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
|
|
@ -24,24 +24,28 @@ class ChannelSelect extends React.Component {
|
|||
render () {
|
||||
return (
|
||||
<div>
|
||||
<p id="input-error-channel-select" className="info-message-placeholder info-message--failure">{this.props.channelError}</p>
|
||||
<form>
|
||||
<div className="column column--3 column--med-10">
|
||||
<input type="radio" name="anonymous-or-channel" id="anonymous-radio" className="input-radio" value="anonymous" checked={!this.props.publishInChannel} onChange={this.toggleAnonymousPublish}/>
|
||||
<label className="label label--pointer" htmlFor="anonymous-radio">Anonymous</label>
|
||||
<div className='column column--3 column--med-10'>
|
||||
<input type='radio' name='anonymous-or-channel' id='anonymous-radio' className='input-radio' value='anonymous' checked={!this.props.publishInChannel} onChange={this.toggleAnonymousPublish} />
|
||||
<label className='label label--pointer' htmlFor='anonymous-radio'>Anonymous</label>
|
||||
</div>
|
||||
<div className="column column--7 column--med-10">
|
||||
<input type="radio" name="anonymous-or-channel" id="channel-radio" className="input-radio" value="in a channel" checked={this.props.publishInChannel} onChange={this.toggleAnonymousPublish}/>
|
||||
<label className="label label--pointer" htmlFor="channel-radio">In a channel</label>
|
||||
<div className='column column--7 column--med-10'>
|
||||
<input type='radio' name='anonymous-or-channel' id='channel-radio' className='input-radio' value='in a channel' checked={this.props.publishInChannel} onChange={this.toggleAnonymousPublish} />
|
||||
<label className='label label--pointer' htmlFor='channel-radio'>In a channel</label>
|
||||
</div>
|
||||
{ this.props.channelError ? (
|
||||
<p className='info-message--failure'>{this.props.channelError}</p>
|
||||
) : (
|
||||
<p className='info-message'>Publish anonymously or in a channel</p>
|
||||
)}
|
||||
</form>
|
||||
{ this.props.publishInChannel && (
|
||||
<div>
|
||||
<div className="column column--3">
|
||||
<label className="label" htmlFor="channel-name-select">Channel:</label>
|
||||
</div><div className="column column--7">
|
||||
<select type="text" id="channel-name-select" className="select select--arrow" value={this.props.selectedChannel} onChange={this.handleSelection}>
|
||||
{ this.props.loggedInChannelName && <option value={this.props.loggedInChannelName} id="publish-channel-select-channel-option">{this.props.loggedInChannelName}</option> }
|
||||
<div className='column column--3'>
|
||||
<label className='label' htmlFor='channel-name-select'>Channel:</label>
|
||||
</div><div className='column column--7'>
|
||||
<select type='text' id='channel-name-select' className='select select--arrow' value={this.props.selectedChannel} onChange={this.handleSelection}>
|
||||
{ this.props.loggedInChannelName && <option value={this.props.loggedInChannelName} id='publish-channel-select-channel-option'>{this.props.loggedInChannelName}</option> }
|
||||
<option value={states.LOGIN}>Existing</option>
|
||||
<option value={states.CREATE}>New</option>
|
||||
</select>
|
||||
|
|
|
@ -51,10 +51,14 @@ class PublishThumbnailInput extends React.Component {
|
|||
}
|
||||
handleVideoLoadedData (event) {
|
||||
const duration = event.target.duration;
|
||||
const totalMinutes = Math.floor(duration / 60);
|
||||
const totalSeconds = Math.floor(duration % 60);
|
||||
// set the slider
|
||||
this.setState({
|
||||
sliderMaxRange: duration * 100,
|
||||
sliderValue : duration * 100 / 2,
|
||||
totalMinutes,
|
||||
totalSeconds,
|
||||
});
|
||||
// update the current time of the video
|
||||
let video = document.getElementById('video-thumb-player');
|
||||
|
@ -88,15 +92,10 @@ class PublishThumbnailInput extends React.Component {
|
|||
}
|
||||
}
|
||||
render () {
|
||||
const { error, videoSource, sliderMinRange, sliderMaxRange, sliderValue } = this.state;
|
||||
const { error, videoSource, sliderMinRange, sliderMaxRange, sliderValue, totalMinutes, totalSeconds } = this.state;
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
{ error ? (
|
||||
<p className='info-message--failure'>{error}</p>
|
||||
) : (
|
||||
<p className='info-message'>Use slider to set thumbnail:</p>
|
||||
)}
|
||||
<label className='label'>Thumbnail:</label>
|
||||
<video
|
||||
id='video-thumb-player'
|
||||
preload='metadata'
|
||||
|
@ -109,7 +108,12 @@ class PublishThumbnailInput extends React.Component {
|
|||
/>
|
||||
{
|
||||
sliderValue ? (
|
||||
<div className='slide-container'>
|
||||
<div>
|
||||
<div className='flex-container--row flex-container--space-between-center' style={{width: '100%'}}>
|
||||
<span className='info-message'>0'00"</span>
|
||||
<span className='info-message'>{totalMinutes}'{totalSeconds}"</span>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type='range'
|
||||
min={sliderMinRange}
|
||||
|
@ -119,11 +123,16 @@ class PublishThumbnailInput extends React.Component {
|
|||
onChange={this.handleSliderChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<p className='info-message' >loading... </p>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
{ error ? (
|
||||
<p className='info-message--failure'>{error}</p>
|
||||
) : (
|
||||
<p className='info-message'>Use slider to set thumbnail</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,10 +14,14 @@ class PublishUrlInput extends React.Component {
|
|||
}
|
||||
}
|
||||
componentWillReceiveProps ({ claim, fileName }) {
|
||||
if (!claim) {
|
||||
// if a new file was chosen, update the claim name
|
||||
if (fileName !== this.props.fileName) {
|
||||
return this.setClaimName(fileName);
|
||||
}
|
||||
this.checkClaimIsAvailable(claim);
|
||||
// if the claim has updated, check its availability
|
||||
if (claim !== this.props.claim) {
|
||||
this.validateClaim(claim);
|
||||
}
|
||||
}
|
||||
handleInput (event) {
|
||||
let value = event.target.value;
|
||||
|
@ -35,35 +39,42 @@ class PublishUrlInput extends React.Component {
|
|||
const cleanClaimName = this.cleanseInput(fileNameWithoutEnding);
|
||||
this.props.onClaimChange(cleanClaimName);
|
||||
}
|
||||
checkClaimIsAvailable (claim) {
|
||||
validateClaim (claim) {
|
||||
if (!claim) {
|
||||
return this.props.onUrlError('Enter a url above');
|
||||
}
|
||||
request(`/api/claim/availability/${claim}`)
|
||||
.then(() => {
|
||||
.then(response => {
|
||||
console.log('api/claim/availability response:', response);
|
||||
this.props.onUrlError(null);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('api/claim/availability error:', error);
|
||||
this.props.onUrlError(error.message);
|
||||
});
|
||||
}
|
||||
render () {
|
||||
const { claim, loggedInChannelName, loggedInChannelShortId, publishInChannel, selectedChannel, urlError } = this.props;
|
||||
return (
|
||||
<div>
|
||||
<p id='input-error-claim-name' className='info-message-placeholder info-message--failure'>{this.props.urlError}</p>
|
||||
<div className='column column--3 column--sml-10'>
|
||||
<label className='label'>URL:</label>
|
||||
</div><div className='column column--7 column--sml-10 input-text--primary span--relative'>
|
||||
|
||||
<div className='column column--10 column--sml-10'>
|
||||
<div className='input-text--primary span--relative'>
|
||||
<span className='url-text--secondary'>spee.ch / </span>
|
||||
|
||||
<UrlMiddle
|
||||
publishInChannel={this.props.publishInChannel}
|
||||
selectedChannel={this.props.selectedChannel}
|
||||
loggedInChannelName={this.props.loggedInChannelName}
|
||||
loggedInChannelShortId={this.props.loggedInChannelShortId}
|
||||
publishInChannel={publishInChannel}
|
||||
selectedChannel={selectedChannel}
|
||||
loggedInChannelName={loggedInChannelName}
|
||||
loggedInChannelShortId={loggedInChannelShortId}
|
||||
/>
|
||||
|
||||
<input type='text' id='claim-name-input' className='input-text' name='claim' placeholder='your-url-here' onChange={this.handleInput} value={this.props.claim} />
|
||||
{ (this.props.claim && !this.props.urlError) && <span id='input-success-claim-name' className='info-message--success span--absolute'>{'\u2713'}</span> }
|
||||
{ this.props.urlError && <span id='input-success-channel-name' className='info-message--failure span--absolute'>{'\u2716'}</span> }
|
||||
<input type='text' id='claim-name-input' className='input-text' name='claim' placeholder='your-url-here' onChange={this.handleInput} value={claim} />
|
||||
{ (claim && !urlError) && <span id='input-success-claim-name' className='info-message--success span--absolute'>{'\u2713'}</span> }
|
||||
{ urlError && <span id='input-success-channel-name' className='info-message--failure span--absolute'>{'\u2716'}</span> }
|
||||
</div>
|
||||
<div>
|
||||
{ urlError ? (
|
||||
<p id='input-error-claim-name' className='info-message--failure'>{urlError}</p>
|
||||
) : (
|
||||
<p className='info-message'>Choose a custom url</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -19,15 +19,15 @@ module.exports = {
|
|||
}
|
||||
break;
|
||||
case 'image/gif':
|
||||
if (file.size > 50000000) {
|
||||
if (file.size > 30000000) {
|
||||
console.log('file was too big');
|
||||
throw new Error('Sorry, GIFs are limited to 50 megabytes.');
|
||||
throw new Error('Sorry, GIFs are limited to 30 megabytes.');
|
||||
}
|
||||
break;
|
||||
case 'video/mp4':
|
||||
if (file.size > 50000000) {
|
||||
if (file.size > 20000000) {
|
||||
console.log('file was too big');
|
||||
throw new Error('Sorry, videos are limited to 50 megabytes.');
|
||||
throw new Error('Sorry, videos are limited to 20 megabytes.');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -5,9 +5,7 @@ const multipartMiddleware = multipart({uploadDir: files.uploadDirectory});
|
|||
const db = require('../models');
|
||||
const { claimNameIsAvailable, checkChannelAvailability, publish } = require('../controllers/publishController.js');
|
||||
const { getClaimList, resolveUri, getClaim } = require('../helpers/lbryApi.js');
|
||||
|
||||
const { addGetResultsToFileData, createBasicPublishParams, createThumbnailPublishParams, parsePublishApiRequestBody, parsePublishApiRequestFiles, createFileData } = require('../helpers/publishHelpers.js');
|
||||
|
||||
const errorHandlers = require('../helpers/errorHandlers.js');
|
||||
const { sendGAAnonymousPublishTiming, sendGAChannelPublishTiming } = require('../helpers/googleAnalytics.js');
|
||||
const { authenticateUser } = require('../auth/authentication.js');
|
||||
|
|
Loading…
Add table
Reference in a new issue