Merge branch 'master' into 348-multiple-wallet-addresses

This commit is contained in:
Bill Bittner 2018-03-12 11:36:30 -07:00 committed by GitHub
commit 6297faac79
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 244 additions and 276 deletions

View file

@ -1,7 +1,7 @@
# Spee.ch
Spee.ch is a web app that reads and publishes images and videos to and from the [LBRY](https://lbry.io/) blockchain.
## how to run this repository locally
## How to run this repository locally
* start mysql
* install mysql
* create a database called `lbry`
@ -9,8 +9,6 @@ Spee.ch is a web app that reads and publishes images and videos to and from the
* start lbrynet daemon
* install the [`lbry`](https://github.com/lbryio/lbry) daemon
* start the `lbry` daemon
* start spee.ch-sync
* install and run this [`speech-sync`](https://github.com/billbitt/spee.ch-sync) tool
* start spee.ch
* clone this repo
* run `npm install`
@ -20,6 +18,9 @@ Spee.ch is a web app that reads and publishes images and videos to and from the
* build the app by running `npm run build-prod`
* to start the server, run `npm run start`
* visit [localhost:3000](http://localhost:3000)
* start spee.ch-sync (optional, recommended)
* Note: this tool will decode blocks from the `lbry` blockchain and update the Claim and Certificate tables in mysql with all the claims from the blockchain. This is not necessary if you only want to host and resolve content published through your version of spee.ch, but it is required if you want to retrieve and host other content from the lbry network.
* install and run this [`speech-sync`](https://github.com/billbitt/spee.ch-sync) tool
## Tests
* Spee.ch uses `mocha` with `chai` for testing.
@ -30,19 +31,19 @@ Spee.ch is a web app that reads and publishes images and videos to and from the
#### GET
* /api/claim/resolve/:name/:claimId
* example: `curl https://spee.ch/api/claim/resolve/doitlive/xyz`
* example: `curl https://spee.ch/api/claim/resolve/doitlive/xyz`
* /api/claim/list/:name
* example: `curl https://spee.ch/api/claim/list/doitlive`
* /api/claim/availability/:name (
* returns `true`/`false` for whether a name is available through spee.ch
* example: `curl https://spee.ch/api/claim/availability/doitlive`
* /api/channel/availability/:name (
* returns `true`/`false` for whether a channel is available through spee.ch
* example: `curl https://spee.ch/api/channel/availability/@CoolChannel`
* example: `curl https://spee.ch/api/claim/list/doitlive`
* /api/claim/availability/:name
* returns the name if it is available
* example: `curl https://spee.ch/api/claim/availability/doitlive`
* /api/channel/availability/:name
* returns the name if it is available
* example: `curl https://spee.ch/api/channel/availability/@CoolChannel`
#### POST
* /api/claim/publish
* example: `curl -X POST -F 'name=MyPictureName' -F 'file=@/path/to/myPicture.jpeg' https://spee.ch/api/claim/publish`
* example: `curl -F 'name=MyPictureName' -F 'file=@/path/to/myPicture.jpeg' https://spee.ch/api/claim/publish`
* Parameters:
* `name`
* `file` (must be type .mp4, .jpeg, .jpg, .gif, or .png)
@ -54,5 +55,5 @@ Spee.ch is a web app that reads and publishes images and videos to and from the
* `channelName`(optional)
* `channelPassword` (optional,; required if `channelName` is provided)
## bugs
## Bugs
If you find a bug or experience a problem, please report your issue here on github and find us in the lbry discord!

View file

@ -20,17 +20,17 @@ module.exports = {
uploadDirectory: null, // enter file path to where uploads/publishes should be stored
},
site: {
title: 'Spee.ch',
name : 'Spee.ch',
host : 'https://spee.ch',
description: 'Open-source, decentralized image and video sharing.'
title : 'Spee.ch',
name : 'Spee.ch',
host : 'https://spee.ch',
description: 'Open-source, decentralized image and video sharing.',
},
publish: {
primaryClaimAddress : null, // choose any address from your lbry wallet
additionalClaimAddresses: [], // // optional: add previously used claim addresses
thumbnailChannel : '@channelName', // create a channel to use for thumbnail images
thumbnailChannelId : 'xyz123...', // the channel_id (claim id) for the channel above
}
},
claim: {
defaultTitle : 'Spee.ch',
defaultThumbnail : 'https://spee.ch/assets/img/video_thumb_default.png',

View file

@ -158,6 +158,13 @@ a, a:visited {
color: #4156C5;
}
.link--secondary, .link--secondary:visited {
font-size: medium;
margin: 0px;
padding: 0.3em;
color: #9b9b9b;
}
.link--nav {
color: black;
border-bottom: 2px solid white;
@ -461,6 +468,10 @@ button {
color: #9b9b9b;
}
.button--wide {
width: 100%;
}
/* TABLES */
table {

View file

@ -1,7 +1,7 @@
import React from 'react';
const ActiveStatusBar = () => {
return <span className="progress-bar progress-bar--active">| </span>;
}
return <span className='progress-bar progress-bar--active'>| </span>;
};
export default ActiveStatusBar;

View file

@ -1,165 +0,0 @@
import React from 'react';
import { Link } from 'react-router-dom';
class AssetInfo extends React.Component {
constructor (props) {
super(props);
this.state = {
showDetails: false,
};
this.toggleDetails = this.toggleDetails.bind(this);
this.copyToClipboard = this.copyToClipboard.bind(this);
}
toggleDetails () {
if (this.state.showDetails) {
return this.setState({showDetails: false});
}
this.setState({showDetails: true});
}
copyToClipboard (event) {
var elementToCopy = event.target.dataset.elementtocopy;
var element = document.getElementById(elementToCopy);
element.select();
try {
document.execCommand('copy');
} catch (err) {
this.setState({error: 'Oops, unable to copy'});
}
}
render () {
const { asset: { shortId, claimData : { channelName, certificateId, description, name, claimId, fileExt, contentType, thumbnail, host } } } = this.props;
return (
<div>
{channelName &&
<div className="row row--padded row--wide row--no-top">
<div className="column column--2 column--med-10">
<span className="text">Channel:</span>
</div>
<div className="column column--8 column--med-10">
<span className="text"><Link to={`/${channelName}:${certificateId}`}>{channelName}</Link></span>
</div>
</div>
}
{description &&
<div className="row row--padded row--wide row--no-top">
<span className="text">{description}</span>
</div>
}
<div className="row row--padded row--wide row--no-top">
<div id="show-short-link">
<div className="column column--2 column--med-10">
<Link className="link--primary" to={`/${shortId}/${name}.${fileExt}`}><span
className="text">Link:</span></Link>
</div>
<div className="column column--8 column--med-10">
<div className="row row--short row--wide">
<div className="column column--7">
<div className="input-error" id="input-error-copy-short-link" hidden="true">error here</div>
<input type="text" id="short-link" className="input-disabled input-text--full-width" readOnly
spellCheck="false"
value={`${host}/${shortId}/${name}.${fileExt}`}
onClick={this.select}/>
</div>
<div className="column column--1"> </div>
<div className="column column--2">
<button className="button--primary" data-elementtocopy="short-link"
onClick={this.copyToClipboard}>copy
</button>
</div>
</div>
</div>
</div>
<div id="show-embed-code">
<div className="column column--2 column--med-10">
<span className="text">Embed:</span>
</div>
<div className="column column--8 column--med-10">
<div className="row row--short row--wide">
<div className="column column--7">
<div className="input-error" id="input-error-copy-embed-text" hidden="true">error here</div>
{(contentType === 'video/mp4') ? (
<input type="text" id="embed-text" className="input-disabled input-text--full-width" readOnly
onClick={this.select} spellCheck="false"
value={`<video width="100%" controls poster="${thumbnail}" src="${host}/${claimId}/${name}.${fileExt}"/></video>`}/>
) : (
<input type="text" id="embed-text" className="input-disabled input-text--full-width" readOnly
onClick={this.select} spellCheck="false"
value={`<img src="${host}/${claimId}/${name}.${fileExt}"/>`}
/>
)}
</div>
<div className="column column--1"> </div>
<div className="column column--2">
<button className="button--primary" data-elementtocopy="embed-text"
onClick={this.copyToClipboard}>copy
</button>
</div>
</div>
</div>
</div>
</div>
<div id="show-share-buttons">
<div className="row row--padded row--wide row--no-top">
<div className="column column--2 column--med-10">
<span className="text">Share:</span>
</div>
<div className="column column--7 column--med-10">
<div
className="row row--short row--wide flex-container--row flex-container--space-between-bottom flex-container--wrap">
<a className="link--primary" target="_blank"
href={`https://twitter.com/intent/tweet?text=${host}/${shortId}/${name}`}>twitter</a>
<a className="link--primary" target="_blank"
href={`https://www.facebook.com/sharer/sharer.php?u=${host}/${shortId}/${name}`}>facebook</a>
<a className="link--primary" target="_blank"
href={`http://tumblr.com/widgets/share/tool?canonicalUrl=${host}/${shortId}/${name}`}>tumblr</a>
<a className="link--primary" target="_blank"
href={`https://www.reddit.com/submit?url=${host}/${shortId}/${name}&title=${name}`}>reddit</a>
</div>
</div>
</div>
</div>
{ this.state.showDetails &&
<div>
<div className="row--padded row--wide row--no-top">
<div>
<div className="column column--2 column--med-10">
<span className="text">Claim Name:</span>
</div><div className="column column--8 column--med-10">
{name}
</div>
</div>
<div>
<div className="column column--2 column--med-10">
<span className="text">Claim Id:</span>
</div><div className="column column--8 column--med-10">
{claimId}
</div>
</div>
<div>
<div className="column column--2 column--med-10">
<span className="text">File Type:</span>
</div><div className="column column--8 column--med-10">
{contentType ? `${contentType}` : 'unknown'}
</div>
</div>
</div>
<div className="row--padded row--wide row--no-top">
<div className="column column--10">
<a target="_blank" href="https://lbry.io/dmca">Report</a>
</div>
</div>
</div>
}
<div className="row row--wide">
<button className="button--secondary" onClick={this.toggleDetails}>{this.state.showDetails ? 'less' : 'more'}</button>
</div>
</div>
);
}
};
export default AssetInfo;

View file

@ -2,31 +2,32 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
class ExpandingTextarea extends Component {
constructor (props) {
super(props);
this._handleChange = this._handleChange.bind(this);
}
componentDidMount () {
this.adjustTextarea({});
}
render () {
const { onChange, ...rest } = this.props;
return (
<textarea
{ ...rest }
ref={x => this.el = x}
onChange={ this._handleChange.bind(this) }
/>
);
}
_handleChange (event) {
const { onChange } = this.props;
if (onChange) onChange(event);
this.adjustTextarea(event);
}
adjustTextarea ({ target = this.el }) {
target.style.height = 0;
target.style.height = `${target.scrollHeight}px`;
}
render () {
const { ...rest } = this.props;
return (
<textarea
{...rest}
ref={x => this.el = x}
onChange={this._handleChange}
/>
);
}
}
ExpandingTextarea.propTypes = {

View file

@ -1,7 +1,7 @@
import React from 'react';
const InactiveStatusBar = () => {
return <span className="progress-bar progress-bar--inactive">| </span>;
}
return <span className='progress-bar progress-bar--inactive'>| </span>;
};
export default InactiveStatusBar;

View file

@ -3,20 +3,20 @@ import { Link } from 'react-router-dom';
function Logo () {
return (
<svg version="1.1" id="Layer_1" x="0px" y="0px" height="24px" viewBox="0 0 80 31" enableBackground="new 0 0 80 31" className="nav-bar-logo">
<Link to="/">
<svg version='1.1' id='Layer_1' x='0px' y='0px' height='24px' viewBox='0 0 80 31' enableBackground='new 0 0 80 31' className='nav-bar-logo'>
<Link to='/'>
<title>Logo</title>
<desc>Spee.ch logo</desc>
<g id="About">
<g id="Publish-Form-V2-_x28_filled_x29_" transform="translate(-42.000000, -23.000000)">
<g id="Group-17" transform="translate(42.000000, 22.000000)">
<text transform="matrix(1 0 0 1 0 20)" fontSize="25" fontFamily="Roboto">Spee&lt;h</text>
<g id="Group-16" transform="translate(0.000000, 30.000000)">
<path id="Line-8" fill="none" stroke="#09F911" strokeWidth="1" strokeLinecap="square" d="M0.5,1.5h15"/>
<path id="Line-8-Copy" fill="none" stroke="#029D74" strokeWidth="1" strokeLinecap="square" d="M16.5,1.5h15"/>
<path id="Line-8-Copy-2" fill="none" stroke="#E35BD8" strokeWidth="1" strokeLinecap="square" d="M32.5,1.5h15"/>
<path id="Line-8-Copy-3" fill="none" stroke="#4156C5" strokeWidth="1" strokeLinecap="square" d="M48.5,1.5h15"/>
<path id="Line-8-Copy-4" fill="none" stroke="#635688" strokeWidth="1" strokeLinecap="square" d="M64.5,1.5h15"/>
<g id='About'>
<g id='Publish-Form-V2-_x28_filled_x29_' transform='translate(-42.000000, -23.000000)'>
<g id='Group-17' transform='translate(42.000000, 22.000000)'>
<text transform='matrix(1 0 0 1 0 20)' fontSize='25' fontFamily='Roboto'>Spee&lt;h</text>
<g id='Group-16' transform='translate(0.000000, 30.000000)'>
<path id='Line-8' fill='none' stroke='#09F911' strokeWidth='1' strokeLinecap='square' d='M0.5,1.5h15' />
<path id='Line-8-Copy' fill='none' stroke='#029D74' strokeWidth='1' strokeLinecap='square' d='M16.5,1.5h15' />
<path id='Line-8-Copy-2' fill='none' stroke='#E35BD8' strokeWidth='1' strokeLinecap='square' d='M32.5,1.5h15' />
<path id='Line-8-Copy-3' fill='none' stroke='#4156C5' strokeWidth='1' strokeLinecap='square' d='M48.5,1.5h15' />
<path id='Line-8-Copy-4' fill='none' stroke='#635688' strokeWidth='1' strokeLinecap='square' d='M64.5,1.5h15' />
</g>
</g>
</g>

View file

@ -2,8 +2,8 @@ import React from 'react';
function NavBarChannelDropdown ({ channelName, handleSelection, defaultSelection, VIEW, LOGOUT }) {
return (
<select type="text" id="nav-bar-channel-select" className="select select--arrow link--nav" onChange={handleSelection} value={defaultSelection}>
<option id="nav-bar-channel-select-channel-option">{channelName}</option>
<select type='text' id='nav-bar-channel-select' className='select select--arrow link--nav' onChange={handleSelection} value={defaultSelection}>
<option id='nav-bar-channel-select-channel-option'>{channelName}</option>
<option value={VIEW}>View</option>
<option value={LOGOUT}>Logout</option>
</select>

View file

@ -4,13 +4,13 @@ import PropTypes from 'prop-types';
function UrlMiddle ({publishInChannel, selectedChannel, loggedInChannelName, loggedInChannelShortId}) {
if (publishInChannel) {
if (selectedChannel === loggedInChannelName) {
return <span id="url-channel" className="url-text--secondary">{loggedInChannelName}:{loggedInChannelShortId} /</span>;
return <span id='url-channel' className='url-text--secondary'>{loggedInChannelName}:{loggedInChannelShortId} /</span>;
}
return <span id="url-channel-placeholder" className="url-text--secondary tooltip">@channel<span
className="tooltip-text">Select a channel below</span> /</span>;
return <span id='url-channel-placeholder' className='url-text--secondary tooltip'>@channel<span
className='tooltip-text'>Select a channel below</span> /</span>;
}
return (
<span id="url-no-channel-placeholder" className="url-text--secondary tooltip">xyz<span className="tooltip-text">This will be a random id</span> /</span>
<span id='url-no-channel-placeholder' className='url-text--secondary tooltip'>xyz<span className='tooltip-text'>This will be a random id</span> /</span>
);
}

View file

@ -0,0 +1,123 @@
import React from 'react';
import { Link } from 'react-router-dom';
class AssetInfo extends React.Component {
constructor (props) {
super(props);
this.copyToClipboard = this.copyToClipboard.bind(this);
}
copyToClipboard (event) {
var elementToCopy = event.target.dataset.elementtocopy;
var element = document.getElementById(elementToCopy);
element.select();
try {
document.execCommand('copy');
} catch (err) {
this.setState({error: 'Oops, unable to copy'});
}
}
render () {
const { asset: { shortId, claimData : { channelName, certificateId, description, name, claimId, fileExt, contentType, thumbnail, host } } } = this.props;
return (
<div>
{channelName &&
<div className='row row--padded row--wide row--no-top'>
<div className='column column--2 column--med-10'>
<span className='text'>Channel:</span>
</div>
<div className='column column--8 column--med-10'>
<span className='text'><Link to={`/${channelName}:${certificateId}`}>{channelName}</Link></span>
</div>
</div>
}
{description &&
<div className='row row--padded row--wide row--no-top'>
<span className='text'>{description}</span>
</div>
}
<div id='show-share-buttons'>
<div className='row row--padded row--wide row--no-top'>
<div className='column column--2 column--med-10'>
<span className='text'>Share:</span>
</div>
<div className='column column--8 column--med-10'>
<div
className='row row--short row--wide flex-container--row flex-container--space-between-bottom flex-container--wrap'>
<a className='link--primary' target='_blank' href={`https://twitter.com/intent/tweet?text=${host}/${shortId}/${name}`}>twitter</a>
<a className='link--primary' target='_blank' href={`https://www.facebook.com/sharer/sharer.php?u=${host}/${shortId}/${name}`}>facebook</a>
<a className='link--primary' target='_blank' href={`http://tumblr.com/widgets/share/tool?canonicalUrl=${host}/${shortId}/${name}`}>tumblr</a>
<a className='link--primary' target='_blank' href={`https://www.reddit.com/submit?url=${host}/${shortId}/${name}&title=${name}`}>reddit</a>
</div>
</div>
</div>
</div>
<div className='row row--padded row--wide row--no-top'>
<div id='show-short-link'>
<div className='column column--2 column--med-10'>
<span className='text'>Link:</span>
</div>
<div className='column column--8 column--med-10'>
<div className='row row--short row--wide'>
<div className='column column--7'>
<div className='input-error' id='input-error-copy-short-link' hidden='true'>error here</div>
<input type='text' id='short-link' className='input-disabled input-text--full-width' readOnly
spellCheck='false'
value={`${host}/${shortId}/${name}.${fileExt}`}
onClick={this.select} />
</div>
<div className='column column--1' />
<div className='column column--2'>
<button className='button--primary button--wide' data-elementtocopy='short-link'
onClick={this.copyToClipboard}>copy
</button>
</div>
</div>
</div>
</div>
<div id='show-embed-code'>
<div className='column column--2 column--med-10'>
<span className='text'>Embed:</span>
</div>
<div className='column column--8 column--med-10'>
<div className='row row--short row--wide'>
<div className='column column--7'>
<div className='input-error' id='input-error-copy-embed-text' hidden='true'>error here</div>
{(contentType === 'video/mp4') ? (
<input type='text' id='embed-text' className='input-disabled input-text--full-width' readOnly
onClick={this.select} spellCheck='false'
value={`<video width="100%" controls poster="${thumbnail}" src="${host}/${claimId}/${name}.${fileExt}"/></video>`} />
) : (
<input type='text' id='embed-text' className='input-disabled input-text--full-width' readOnly
onClick={this.select} spellCheck='false'
value={`<img src="${host}/${claimId}/${name}.${fileExt}"/>`}
/>
)}
</div>
<div className='column column--1' />
<div className='column column--2'>
<button className='button--primary button--wide' data-elementtocopy='embed-text'
onClick={this.copyToClipboard}>copy
</button>
</div>
</div>
</div>
</div>
</div>
<div className='flex-container--row flex-container--space-between-bottom'>
<Link className='link--primary' to={`/${shortId}/${name}.${fileExt}`}><span
className='text'>Direct Link</span></Link>
<a className='link--primary' href={`${host}/${claimId}/${name}.${fileExt}`} download={name}>Download</a>
<a className='link--primary' target='_blank' href='https://lbry.io/dmca'>Report</a>
</div>
</div>
);
}
};
export default AssetInfo;

View file

@ -3,9 +3,7 @@ import View from './view';
import { selectAsset } from 'selectors/show';
const mapStateToProps = ({ show }) => {
// select title
const { claimData: { title } } = selectAsset(show);
// return props
return {
title,
};

View file

@ -3,7 +3,7 @@ import React from 'react';
const AssetTitle = ({ title }) => {
return (
<div>
<span className="text--large">{title}</span>
<span className='text--large'>{title}</span>
</div>
);
};

View file

@ -24,7 +24,7 @@ class ChannelClaimsDisplay extends React.Component {
render () {
const { channel: { claimsData: { claims, currentPage, totalPages } } } = this.props;
return (
<div className="row row--tall">
<div className='row row--tall'>
{(claims.length > 0) ? (
<div>
{claims.map((claim, index) => <AssetPreview

View file

@ -54,15 +54,15 @@ class NavBar extends React.Component {
}
render () {
return (
<div className="row row--wide nav-bar">
<div className="row row--padded row--short flex-container--row flex-container--space-between-center">
<div className='row row--wide nav-bar'>
<div className='row row--padded row--short flex-container--row flex-container--space-between-center'>
<Logo />
<div className="nav-bar--center">
<span className="nav-bar-tagline">Open-source, decentralized image and video sharing.</span>
<div className='nav-bar--center'>
<span className='nav-bar-tagline'>Open-source, decentralized image and video sharing.</span>
</div>
<div className="nav-bar--right">
<NavLink className="nav-bar-link link--nav" activeClassName="link--nav-active" to="/" exact={true}>Publish</NavLink>
<NavLink className="nav-bar-link link--nav" activeClassName="link--nav-active" to="/about">About</NavLink>
<div className='nav-bar--right'>
<NavLink className='nav-bar-link link--nav' activeClassName='link--nav-active' to='/' exact>Publish</NavLink>
<NavLink className='nav-bar-link link--nav' activeClassName='link--nav-active' to='/about'>About</NavLink>
{ this.props.channelName ? (
<NavBarChannelDropdown
channelName={this.props.channelName}
@ -72,7 +72,7 @@ class NavBar extends React.Component {
LOGOUT={LOGOUT}
/>
) : (
<NavLink id="nav-bar-login-link" className="nav-bar-link link--nav" activeClassName="link--nav-active" to="/login">Channel</NavLink>
<NavLink id='nav-bar-login-link' className='nav-bar-link link--nav' activeClassName='link--nav-active' to='/login'>Channel</NavLink>
)}
</div>
</div>

View file

@ -24,48 +24,48 @@ class PublishMetadataInputs extends React.Component {
}
render () {
return (
<div id="publish-details" className="row row--padded row--no-top row--wide">
{this.props.showMetadataInputs && (
<div>
<div className="row row--no-top">
<div className="column column--3 column--med-10 align-content-top">
<label htmlFor="publish-license" className="label">Description:</label>
</div><div className="column column--7 column--sml-10">
<ExpandingTextArea
id="publish-description"
className="textarea textarea--primary textarea--full-width"
rows={1}
maxLength={2000}
style={{ maxHeight: 200 }}
name="description"
placeholder="Optional description"
value={this.props.description}
onChange={this.handleInput} />
<div id='publish-details' className='row row--padded row--no-top row--wide'>
{this.props.showMetadataInputs && (
<div>
<div className='row row--no-top'>
<div className='column column--3 column--med-10 align-content-top'>
<label htmlFor='publish-license' className='label'>Description:</label>
</div><div className='column column--7 column--sml-10'>
<ExpandingTextArea
id='publish-description'
className='textarea textarea--primary textarea--full-width'
rows={1}
maxLength={2000}
style={{ maxHeight: 200 }}
name='description'
placeholder='Optional description'
value={this.props.description}
onChange={this.handleInput} />
</div>
</div>
</div>
<div className="row row--no-top">
<div className="column column--3 column--med-10">
<label htmlFor="publish-license" className="label">License:</label>
</div><div className="column column--7 column--sml-10">
<select type="text" name="license" id="publish-license" className="select select--primary" onChange={this.handleSelect}>
<option value=" ">Unspecified</option>
<option value="Public Domain">Public Domain</option>
<option value="Creative Commons">Creative Commons</option>
</select>
<div className='row row--no-top'>
<div className='column column--3 column--med-10'>
<label htmlFor='publish-license' className='label'>License:</label>
</div><div className='column column--7 column--sml-10'>
<select type='text' name='license' id='publish-license' className='select select--primary' onChange={this.handleSelect}>
<option value=' '>Unspecified</option>
<option value='Public Domain'>Public Domain</option>
<option value='Creative Commons'>Creative Commons</option>
</select>
</div>
</div>
</div>
<div className="row row--no-top">
<div className="column column--3">
<label htmlFor="publish-nsfw" className="label">Mature:</label>
</div><div className="column column--7">
<input className="input-checkbox" type="checkbox" id="publish-nsfw" name="nsfw" value={this.props.nsfw} onChange={this.handleInput} />
<div className='row row--no-top'>
<div className='column column--3'>
<label htmlFor='publish-nsfw' className='label'>Mature:</label>
</div><div className='column column--7'>
<input className='input-checkbox' type='checkbox' id='publish-nsfw' name='nsfw' value={this.props.nsfw} onChange={this.handleInput} />
</div>
</div>
</div>
</div>
)}
<button className="button--secondary" onClick={this.toggleShowInputs}>{this.props.showMetadataInputs ? 'less' : 'more'}</button>
)}
<button className='button--secondary' onClick={this.toggleShowInputs}>{this.props.showMetadataInputs ? 'less' : 'more'}</button>
</div>
);
}

View file

@ -12,7 +12,7 @@ class PublishTitleInput extends React.Component {
}
render () {
return (
<input type="text" id="publish-title" className="input-text text--large input-text--full-width" name="title" placeholder="Give your post a title..." onChange={this.handleInput} value={this.props.title}/>
<input type='text' id='publish-title' className='input-text text--large input-text--full-width' name='title' placeholder='Give your post a title...' onChange={this.handleInput} value={this.props.title} />
);
}
}

View file

@ -2,15 +2,15 @@ import React from 'react';
import SEO from 'components/SEO';
import NavBar from 'containers/NavBar';
import ErrorPage from 'components/ErrorPage';
import AssetTitle from 'components/AssetTitle';
import AssetDisplay from 'components/AssetDisplay';
import AssetInfo from 'components/AssetInfo';
import AssetTitle from 'containers/AssetTitle';
import AssetDisplay from 'containers/AssetDisplay';
import AssetInfo from 'containers/AssetInfo';
class ShowAssetDetails extends React.Component {
render () {
const { asset } = this.props;
if (asset) {
const { name } = asset.claimData;
const { claimData: { name } } = asset;
return (
<div>
<SEO pageTitle={`${name} - details`} asset={asset} />
@ -29,7 +29,6 @@ class ShowAssetDetails extends React.Component {
</div>
</div>
</div>
}
</div>
);
};

View file

@ -1,7 +1,7 @@
import React from 'react';
import SEO from 'components/SEO';
import { Link } from 'react-router-dom';
import AssetDisplay from 'components/AssetDisplay';
import AssetDisplay from 'containers/AssetDisplay';
class ShowLite extends React.Component {
render () {

View file

@ -1,8 +1,8 @@
import React from 'react';
import ErrorPage from 'components/ErrorPage';
import ShowAssetLite from 'components/ShowAssetLite';
import ShowAssetDetails from 'components/ShowAssetDetails';
import ShowChannel from 'components/ShowChannel';
import ShowAssetLite from 'containers/ShowAssetLite';
import ShowAssetDetails from 'containers/ShowAssetDetails';
import ShowChannel from 'containers/ShowChannel';
import { CHANNEL, ASSET_LITE, ASSET_DETAILS } from 'constants/show_request_types';