Setup ESLint and Prettier and apply changes to sources #891

Merged
IGassmann merged 22 commits from issue/763 into master 2017-12-27 21:22:51 +01:00
183 changed files with 2122 additions and 2883 deletions
Showing only changes of commit e103778b8a - Show all commits

View file

@ -1,6 +1,6 @@
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doShowSnackBar } from "redux/actions/app"; import { doShowSnackBar } from 'redux/actions/app';
import Address from "./view"; import Address from './view';
export default connect(null, { export default connect(null, {
doShowSnackBar, doShowSnackBar,

View file

@ -1,8 +1,8 @@
import React from "react"; import React from 'react';
import PropTypes from "prop-types"; import PropTypes from 'prop-types';
import { clipboard } from "electron"; import { clipboard } from 'electron';
import Link from "component/link"; import Link from 'component/link';
import classnames from "classnames"; import classnames from 'classnames';
export default class Address extends React.PureComponent { export default class Address extends React.PureComponent {
static propTypes = { static propTypes = {
@ -21,8 +21,8 @@ export default class Address extends React.PureComponent {
return ( return (
<div className="form-field form-field--address"> <div className="form-field form-field--address">
<input <input
className={classnames("input-copyable", { className={classnames('input-copyable', {
"input-copyable--with-copy-btn": showCopyButton, 'input-copyable--with-copy-btn': showCopyButton,
})} })}
type="text" type="text"
ref={input => { ref={input => {
@ -32,7 +32,7 @@ export default class Address extends React.PureComponent {
this._inputElem.select(); this._inputElem.select();
}} }}
readOnly="readonly" readOnly="readonly"
value={address || ""} value={address || ''}
/> />
{showCopyButton && ( {showCopyButton && (
<span className="header__item"> <span className="header__item">
@ -41,7 +41,7 @@ export default class Address extends React.PureComponent {
icon="clipboard" icon="clipboard"
onClick={() => { onClick={() => {
clipboard.writeText(address); clipboard.writeText(address);
doShowSnackBar({ message: __("Address copied") }); doShowSnackBar({ message: __('Address copied') });
}} }}
/> />
</span> </span>

View file

@ -1,14 +1,14 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { import {
selectPageTitle, selectPageTitle,
selectHistoryIndex, selectHistoryIndex,
selectActiveHistoryEntry, selectActiveHistoryEntry,
} from "redux/selectors/navigation"; } from 'redux/selectors/navigation';
import { selectUser } from "redux/selectors/user"; import { selectUser } from 'redux/selectors/user';
import { doAlertError } from "redux/actions/app"; import { doAlertError } from 'redux/actions/app';
import { doRecordScroll } from "redux/actions/navigation"; import { doRecordScroll } from 'redux/actions/navigation';
import App from "./view"; import App from './view';
const select = (state, props) => ({ const select = (state, props) => ({
pageTitle: selectPageTitle(state), pageTitle: selectPageTitle(state),

View file

@ -1,10 +1,10 @@
import React from "react"; import React from 'react';
import Router from "component/router/index"; import Router from 'component/router/index';
import Header from "component/header"; import Header from 'component/header';
import Theme from "component/theme"; import Theme from 'component/theme';
import ModalRouter from "modal/modalRouter"; import ModalRouter from 'modal/modalRouter';
import ReactModal from "react-modal"; import ReactModal from 'react-modal';
import throttle from "util/throttle"; import throttle from 'util/throttle';
class App extends React.PureComponent { class App extends React.PureComponent {
constructor() { constructor() {
@ -15,25 +15,25 @@ class App extends React.PureComponent {
componentWillMount() { componentWillMount() {
const { alertError } = this.props; const { alertError } = this.props;
document.addEventListener("unhandledError", event => { document.addEventListener('unhandledError', event => {
alertError(event.detail); alertError(event.detail);
}); });
} }
componentDidMount() { componentDidMount() {
const { recordScroll } = this.props; const { recordScroll } = this.props;
const mainContent = document.getElementById("main-content"); const mainContent = document.getElementById('main-content');
this.mainContent = mainContent; this.mainContent = mainContent;
const scrollListener = () => recordScroll(this.mainContent.scrollTop); const scrollListener = () => recordScroll(this.mainContent.scrollTop);
this.mainContent.addEventListener("scroll", throttle(scrollListener, 750)); this.mainContent.addEventListener('scroll', throttle(scrollListener, 750));
ReactModal.setAppElement("#window"); //fuck this ReactModal.setAppElement('#window'); // fuck this
} }
componentWillUnmount() { componentWillUnmount() {
this.mainContent.removeEventListener("scroll", this.scrollListener); this.mainContent.removeEventListener('scroll', this.scrollListener);
} }
componentWillReceiveProps(props) { componentWillReceiveProps(props) {
@ -50,7 +50,7 @@ class App extends React.PureComponent {
} }
setTitleFromProps(props) { setTitleFromProps(props) {
window.document.title = props.pageTitle || "LBRY"; window.document.title = props.pageTitle || 'LBRY';
} }
render() { render() {

View file

@ -1,6 +1,6 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import CardMedia from "./view"; import CardMedia from './view';
const select = state => ({}); const select = state => ({});
const perform = dispatch => ({}); const perform = dispatch => ({});

View file

@ -1,18 +1,18 @@
import React from "react"; import React from 'react';
class CardMedia extends React.PureComponent { class CardMedia extends React.PureComponent {
static AUTO_THUMB_CLASSES = [ static AUTO_THUMB_CLASSES = [
"purple", 'purple',
"red", 'red',
"pink", 'pink',
"indigo", 'indigo',
"blue", 'blue',
"light-blue", 'light-blue',
"cyan", 'cyan',
"teal", 'teal',
"green", 'green',
"yellow", 'yellow',
"orange", 'orange',
]; ];
componentWillMount() { componentWillMount() {
@ -29,12 +29,7 @@ class CardMedia extends React.PureComponent {
const atClass = this.state.autoThumbClass; const atClass = this.state.autoThumbClass;
if (thumbnail) { if (thumbnail) {
return ( return <div className="card__media" style={{ backgroundImage: `url('${thumbnail}')` }} />;
<div
className="card__media"
style={{ backgroundImage: "url('" + thumbnail + "')" }}
/>
);
} }
return ( return (
@ -42,8 +37,8 @@ class CardMedia extends React.PureComponent {
<div className="card__autothumb__text"> <div className="card__autothumb__text">
{title && {title &&
title title
.replace(/\s+/g, "") .replace(/\s+/g, '')
.substring(0, Math.min(title.replace(" ", "").length, 5)) .substring(0, Math.min(title.replace(' ', '').length, 5))
.toUpperCase()} .toUpperCase()}
</div> </div>
</div> </div>

View file

@ -1,7 +1,7 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { selectUserEmail } from "redux/selectors/user"; import { selectUserEmail } from 'redux/selectors/user';
import CardVerify from "./view"; import CardVerify from './view';
const select = state => ({ const select = state => ({
email: selectUserEmail(state), email: selectUserEmail(state),

View file

@ -1,6 +1,6 @@
import React from "react"; import React from 'react';
import PropTypes from "prop-types"; import PropTypes from 'prop-types';
import Link from "component/link"; import Link from 'component/link';
let scriptLoading = false; let scriptLoading = false;
let scriptLoaded = false; let scriptLoaded = false;
@ -48,8 +48,8 @@ class CardVerify extends React.Component {
scriptLoading = true; scriptLoading = true;
const script = document.createElement("script"); const script = document.createElement('script');
script.src = "https://checkout.stripe.com/checkout.js"; script.src = 'https://checkout.stripe.com/checkout.js';
script.async = 1; script.async = 1;
this.loadPromise = (() => { this.loadPromise = (() => {
@ -69,12 +69,8 @@ class CardVerify extends React.Component {
}; };
}); });
const wrappedPromise = new Promise((accept, cancel) => { const wrappedPromise = new Promise((accept, cancel) => {
promise.then( promise.then(() => (canceled ? cancel({ isCanceled: true }) : accept()));
() => (canceled ? cancel({ isCanceled: true }) : accept()) promise.catch(error => (canceled ? cancel({ isCanceled: true }) : cancel(error)));
);
promise.catch(
error => (canceled ? cancel({ isCanceled: true }) : cancel(error))
);
}); });
return { return {
@ -85,9 +81,7 @@ class CardVerify extends React.Component {
}; };
})(); })();
this.loadPromise.promise this.loadPromise.promise.then(this.onScriptLoaded).catch(this.onScriptError);
.then(this.onScriptLoaded)
.catch(this.onScriptError);
document.body.appendChild(script); document.body.appendChild(script);
} }
@ -119,7 +113,7 @@ class CardVerify extends React.Component {
}; };
onScriptError = (...args) => { onScriptError = (...args) => {
throw new Error("Unable to load credit validation script."); throw new Error('Unable to load credit validation script.');
}; };
onClosed = () => { onClosed = () => {
@ -139,10 +133,10 @@ class CardVerify extends React.Component {
CardVerify.stripeHandler.open({ CardVerify.stripeHandler.open({
allowRememberMe: false, allowRememberMe: false,
closed: this.onClosed, closed: this.onClosed,
description: __("Confirm Identity"), description: __('Confirm Identity'),
email: this.props.email, email: this.props.email,
locale: "auto", locale: 'auto',
panelLabel: "Verify", panelLabel: 'Verify',
token: this.props.token, token: this.props.token,
zipCode: true, zipCode: true,
}); });
@ -151,9 +145,7 @@ class CardVerify extends React.Component {
onClick = () => { onClick = () => {
if (scriptDidError) { if (scriptDidError) {
try { try {
throw new Error( throw new Error('Tried to call onClick, but StripeCheckout failed to load');
"Tried to call onClick, but StripeCheckout failed to load"
);
} catch (x) {} } catch (x) {}
} else if (CardVerify.stripeHandler) { } else if (CardVerify.stripeHandler) {
this.showStripeDialog(); this.showStripeDialog();
@ -168,9 +160,7 @@ class CardVerify extends React.Component {
button="alt" button="alt"
label={this.props.label} label={this.props.label}
icon="icon-lock" icon="icon-lock"
disabled={ disabled={this.props.disabled || this.state.open || this.hasPendingClick}
this.props.disabled || this.state.open || this.hasPendingClick
}
onClick={this.onClick.bind(this)} onClick={this.onClick.bind(this)}
/> />
); );

View file

@ -1,11 +1,11 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { makeSelectClaimForUri } from "redux/selectors/claims"; import { makeSelectClaimForUri } from 'redux/selectors/claims';
import { doNavigate } from "redux/actions/navigation"; import { doNavigate } from 'redux/actions/navigation';
import { doResolveUri } from "redux/actions/content"; import { doResolveUri } from 'redux/actions/content';
import { makeSelectTotalItemsForChannel } from "redux/selectors/content"; import { makeSelectTotalItemsForChannel } from 'redux/selectors/content';
import { makeSelectIsUriResolving } from "redux/selectors/content"; import { makeSelectIsUriResolving } from 'redux/selectors/content';
import ChannelTile from "./view"; import ChannelTile from './view';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),

View file

@ -1,6 +1,6 @@
import React from "react"; import React from 'react';
import CardMedia from "component/cardMedia"; import CardMedia from 'component/cardMedia';
import { TruncatedText, BusyMessage } from "component/common.js"; import { TruncatedText, BusyMessage } from 'component/common.js';
class ChannelTile extends React.PureComponent { class ChannelTile extends React.PureComponent {
componentDidMount() { componentDidMount() {
@ -26,12 +26,12 @@ class ChannelTile extends React.PureComponent {
channelId = claim.claim_id; channelId = claim.claim_id;
} }
let onClick = () => navigate("/show", { uri }); const onClick = () => navigate('/show', { uri });
return ( return (
<section className="file-tile card"> <section className="file-tile card">
<div onClick={onClick} className="card__link"> <div onClick={onClick} className="card__link">
<div className={"card__inner file-tile__row"}> <div className="card__inner file-tile__row">
{channelName && <CardMedia title={channelName} thumbnail={null} />} {channelName && <CardMedia title={channelName} thumbnail={null} />}
<div className="file-tile__content"> <div className="file-tile__content">
<div className="card__title-primary"> <div className="card__title-primary">
@ -40,19 +40,15 @@ class ChannelTile extends React.PureComponent {
</h3> </h3>
</div> </div>
<div className="card__content card__subtext"> <div className="card__content card__subtext">
{isResolvingUri && ( {isResolvingUri && <BusyMessage message={__('Resolving channel')} />}
<BusyMessage message={__("Resolving channel")} />
)}
{totalItems > 0 && ( {totalItems > 0 && (
<span> <span>
This is a channel with {totalItems}{" "} This is a channel with {totalItems} {totalItems === 1 ? ' item' : ' items'}{' '}
{totalItems === 1 ? " item" : " items"} inside of it. inside of it.
</span> </span>
)} )}
{!isResolvingUri && {!isResolvingUri &&
!totalItems && ( !totalItems && <span className="empty">This is an empty channel.</span>}
<span className="empty">This is an empty channel.</span>
)}
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,7 +1,7 @@
import React from "react"; import React from 'react';
import PropTypes from "prop-types"; import PropTypes from 'prop-types';
import { formatCredits, formatFullPrice } from "util/formatCredits"; import { formatCredits, formatFullPrice } from 'util/formatCredits';
import lbry from "../lbry.js"; import lbry from '../lbry.js';
// component/icon.js // component/icon.js
export class Icon extends React.PureComponent { export class Icon extends React.PureComponent {
@ -13,9 +13,9 @@ export class Icon extends React.PureComponent {
render() { render() {
const { fixed, className } = this.props; const { fixed, className } = this.props;
const spanClassName = `icon ${ const spanClassName = `icon ${'fixed' in this.props ? 'icon-fixed-width ' : ''}${
"fixed" in this.props ? "icon-fixed-width " : "" this.props.icon
}${this.props.icon} ${this.props.className || ""}`; } ${this.props.className || ''}`;
return <span className={spanClassName} />; return <span className={spanClassName} />;
} }
} }
@ -31,10 +31,7 @@ export class TruncatedText extends React.PureComponent {
render() { render() {
return ( return (
<span <span className="truncated-text" style={{ WebkitLineClamp: this.props.lines }}>
className="truncated-text"
style={{ WebkitLineClamp: this.props.lines }}
>
{this.props.children} {this.props.children}
</span> </span>
); );
@ -70,14 +67,14 @@ export class CreditAmount extends React.PureComponent {
showFree: PropTypes.bool, showFree: PropTypes.bool,
showFullPrice: PropTypes.bool, showFullPrice: PropTypes.bool,
showPlus: PropTypes.bool, showPlus: PropTypes.bool,
look: PropTypes.oneOf(["indicator", "plain", "fee"]), look: PropTypes.oneOf(['indicator', 'plain', 'fee']),
}; };
static defaultProps = { static defaultProps = {
precision: 2, precision: 2,
label: true, label: true,
showFree: false, showFree: false,
look: "indicator", look: 'indicator',
showFullPrice: false, showFullPrice: false,
showPlus: false, showPlus: false,
}; };
@ -100,13 +97,13 @@ export class CreditAmount extends React.PureComponent {
let amountText; let amountText;
if (this.props.showFree && parseFloat(this.props.amount) === 0) { if (this.props.showFree && parseFloat(this.props.amount) === 0) {
amountText = __("free"); amountText = __('free');
} else { } else {
if (this.props.label) { if (this.props.label) {
const label = const label =
typeof this.props.label === "string" typeof this.props.label === 'string'
? this.props.label ? this.props.label
: parseFloat(amount) == 1 ? __("credit") : __("credits"); : parseFloat(amount) == 1 ? __('credit') : __('credits');
amountText = `${formattedAmount} ${label}`; amountText = `${formattedAmount} ${label}`;
} else { } else {
@ -118,15 +115,12 @@ export class CreditAmount extends React.PureComponent {
} }
return ( return (
<span <span className={`credit-amount credit-amount--${this.props.look}`} title={fullPrice}>
className={`credit-amount credit-amount--${this.props.look}`}
title={fullPrice}
>
<span>{amountText}</span> <span>{amountText}</span>
{this.props.isEstimate ? ( {this.props.isEstimate ? (
<span <span
className="credit-amount__estimate" className="credit-amount__estimate"
title={__("This is an estimate and does not include data fees")} title={__('This is an estimate and does not include data fees')}
> >
* *
</span> </span>
@ -152,7 +146,7 @@ export class Thumbnail extends React.PureComponent {
constructor(props) { constructor(props) {
super(props); super(props);
this._defaultImageUri = lbry.imagePath("default-thumb.svg"); this._defaultImageUri = lbry.imagePath('default-thumb.svg');
this._maxLoadTime = 10000; this._maxLoadTime = 10000;
this._isMounted = false; this._isMounted = false;
@ -177,7 +171,7 @@ export class Thumbnail extends React.PureComponent {
} }
render() { render() {
const className = this.props.className ? this.props.className : "", const className = this.props.className ? this.props.className : '',
otherProps = Object.assign({}, this.props); otherProps = Object.assign({}, this.props);
delete otherProps.className; delete otherProps.className;
return ( return (

View file

@ -1,16 +1,14 @@
import React from "react"; import React from 'react';
import classnames from "classnames"; import classnames from 'classnames';
export default ({ dark, className }) => { export default ({ dark, className }) => (
return ( <div
<div className={classnames(
className={classnames( 'spinner',
"spinner", {
{ 'spinner--dark': dark,
"spinner--dark": dark, },
}, className
className )}
)} />
/> );
);
};

View file

@ -1,14 +1,11 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { makeSelectBlockDate } from "redux/selectors/wallet"; import { makeSelectBlockDate } from 'redux/selectors/wallet';
import { doFetchBlock } from "redux/actions/wallet"; import { doFetchBlock } from 'redux/actions/wallet';
import DateTime from "./view"; import DateTime from './view';
const select = (state, props) => ({ const select = (state, props) => ({
date: date: !props.date && props.block ? makeSelectBlockDate(props.block)(state) : props.date,
!props.date && props.block
? makeSelectBlockDate(props.block)(state)
: props.date,
}); });
const perform = dispatch => ({ const perform = dispatch => ({

View file

@ -1,15 +1,15 @@
import React from "react"; import React from 'react';
class DateTime extends React.PureComponent { class DateTime extends React.PureComponent {
static SHOW_DATE = "date"; static SHOW_DATE = 'date';
static SHOW_TIME = "time"; static SHOW_TIME = 'time';
static SHOW_BOTH = "both"; static SHOW_BOTH = 'both';
static defaultProps = { static defaultProps = {
formatOptions: { formatOptions: {
month: "long", month: 'long',
day: "numeric", day: 'numeric',
year: "numeric", year: 'numeric',
}, },
}; };
@ -37,12 +37,12 @@ class DateTime extends React.PureComponent {
<span> <span>
{date && {date &&
(show == DateTime.SHOW_BOTH || show === DateTime.SHOW_DATE) && (show == DateTime.SHOW_BOTH || show === DateTime.SHOW_DATE) &&
date.toLocaleDateString([locale, "en-US"], formatOptions)} date.toLocaleDateString([locale, 'en-US'], formatOptions)}
{show == DateTime.SHOW_BOTH && " "} {show == DateTime.SHOW_BOTH && ' '}
{date && {date &&
(show == DateTime.SHOW_BOTH || show === DateTime.SHOW_TIME) && (show == DateTime.SHOW_BOTH || show === DateTime.SHOW_TIME) &&
date.toLocaleTimeString()} date.toLocaleTimeString()}
{!date && "..."} {!date && '...'}
</span> </span>
); );
} }

View file

@ -1,17 +1,17 @@
import React from "react"; import React from 'react';
import PropTypes from "prop-types"; import PropTypes from 'prop-types';
const { remote } = require("electron"); const { remote } = require('electron');
class FileSelector extends React.PureComponent { class FileSelector extends React.PureComponent {
static propTypes = { static propTypes = {
type: PropTypes.oneOf(["file", "directory"]), type: PropTypes.oneOf(['file', 'directory']),
initPath: PropTypes.string, initPath: PropTypes.string,
onFileChosen: PropTypes.func, onFileChosen: PropTypes.func,
}; };
static defaultProps = { static defaultProps = {
type: "file", type: 'file',
}; };
constructor(props) { constructor(props) {
@ -28,10 +28,7 @@ class FileSelector extends React.PureComponent {
handleButtonClick() { handleButtonClick() {
remote.dialog.showOpenDialog( remote.dialog.showOpenDialog(
{ {
properties: properties: this.props.type == 'file' ? ['openFile'] : ['openDirectory', 'createDirectory'],
this.props.type == "file"
? ["openFile"]
: ["openDirectory", "createDirectory"],
}, },
paths => { paths => {
if (!paths) { if (!paths) {
@ -60,12 +57,10 @@ class FileSelector extends React.PureComponent {
> >
<span className="button__content"> <span className="button__content">
<span className="button-label"> <span className="button-label">
{this.props.type == "file" {this.props.type == 'file' ? __('Choose File') : __('Choose Directory')}
? __("Choose File")
: __("Choose Directory")}
</span> </span>
</span> </span>
</button>{" "} </button>{' '}
<span className="file-selector__path"> <span className="file-selector__path">
<input <input
className="input-copyable" className="input-copyable"
@ -77,7 +72,7 @@ class FileSelector extends React.PureComponent {
this._inputElem.select(); this._inputElem.select();
}} }}
readOnly="readonly" readOnly="readonly"
value={this.state.path || __("No File Chosen")} value={this.state.path || __('No File Chosen')}
/> />
</span> </span>
</div> </div>

View file

@ -1,10 +1,10 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { makeSelectFileInfoForUri } from "redux/selectors/file_info"; import { makeSelectFileInfoForUri } from 'redux/selectors/file_info';
import { makeSelectCostInfoForUri } from "redux/selectors/cost_info"; import { makeSelectCostInfoForUri } from 'redux/selectors/cost_info';
import { doOpenModal } from "redux/actions/app"; import { doOpenModal } from 'redux/actions/app';
import { makeSelectClaimIsMine } from "redux/selectors/claims"; import { makeSelectClaimIsMine } from 'redux/selectors/claims';
import FileActions from "./view"; import FileActions from './view';
const select = (state, props) => ({ const select = (state, props) => ({
fileInfo: makeSelectFileInfoForUri(props.uri)(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state),

View file

@ -1,7 +1,7 @@
import React from "react"; import React from 'react';
import Link from "component/link"; import Link from 'component/link';
import FileDownloadLink from "component/fileDownloadLink"; import FileDownloadLink from 'component/fileDownloadLink';
import * as modals from "constants/modal_types"; import * as modals from 'constants/modal_types';
class FileActions extends React.PureComponent { class FileActions extends React.PureComponent {
render() { render() {
@ -17,7 +17,7 @@ class FileActions extends React.PureComponent {
<Link <Link
button="text" button="text"
icon="icon-trash" icon="icon-trash"
label={__("Remove")} label={__('Remove')}
className="no-underline" className="no-underline"
onClick={() => openModal(modals.CONFIRM_FILE_REMOVE, { uri })} onClick={() => openModal(modals.CONFIRM_FILE_REMOVE, { uri })}
/> />
@ -28,22 +28,22 @@ class FileActions extends React.PureComponent {
icon="icon-flag" icon="icon-flag"
href={`https://lbry.io/dmca?claim_id=${claimId}`} href={`https://lbry.io/dmca?claim_id=${claimId}`}
className="no-underline" className="no-underline"
label={__("report")} label={__('report')}
/> />
)} )}
<Link <Link
button="primary" button="primary"
icon="icon-gift" icon="icon-gift"
label={__("Support")} label={__('Support')}
navigate="/show" navigate="/show"
className="card__action--right" className="card__action--right"
navigateParams={{ uri, tab: "tip" }} navigateParams={{ uri, tab: 'tip' }}
/> />
{claimIsMine && ( {claimIsMine && (
<Link <Link
button="alt" button="alt"
icon="icon-edit" icon="icon-edit"
label={__("Edit")} label={__('Edit')}
navigate="/publish" navigate="/publish"
className="card__action--right" className="card__action--right"
navigateParams={{ id: claimId }} navigateParams={{ id: claimId }}

View file

@ -1,18 +1,12 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doNavigate } from "redux/actions/navigation"; import { doNavigate } from 'redux/actions/navigation';
import { doResolveUri } from "redux/actions/content"; import { doResolveUri } from 'redux/actions/content';
import { selectShowNsfw } from "redux/selectors/settings"; import { selectShowNsfw } from 'redux/selectors/settings';
import { import { makeSelectClaimForUri, makeSelectMetadataForUri } from 'redux/selectors/claims';
makeSelectClaimForUri, import { makeSelectFileInfoForUri } from 'redux/selectors/file_info';
makeSelectMetadataForUri, import { makeSelectIsUriResolving, selectRewardContentClaimIds } from 'redux/selectors/content';
} from "redux/selectors/claims"; import FileCard from './view';
import { makeSelectFileInfoForUri } from "redux/selectors/file_info";
import {
makeSelectIsUriResolving,
selectRewardContentClaimIds,
} from "redux/selectors/content";
import FileCard from "./view";
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),

View file

@ -1,14 +1,14 @@
import React from "react"; import React from 'react';
import lbryuri from "lbryuri.js"; import lbryuri from 'lbryuri.js';
import CardMedia from "component/cardMedia"; import CardMedia from 'component/cardMedia';
import Link from "component/link"; import Link from 'component/link';
import { TruncatedText } from "component/common"; import { TruncatedText } from 'component/common';
import Icon from "component/icon"; import Icon from 'component/icon';
import FilePrice from "component/filePrice"; import FilePrice from 'component/filePrice';
import UriIndicator from "component/uriIndicator"; import UriIndicator from 'component/uriIndicator';
import NsfwOverlay from "component/nsfwOverlay"; import NsfwOverlay from 'component/nsfwOverlay';
import TruncatedMarkdown from "component/truncatedMarkdown"; import TruncatedMarkdown from 'component/truncatedMarkdown';
import * as icons from "constants/icons"; import * as icons from 'constants/icons';
class FileCard extends React.PureComponent { class FileCard extends React.PureComponent {
constructor(props) { constructor(props) {
@ -59,35 +59,27 @@ class FileCard extends React.PureComponent {
const uri = lbryuri.normalize(this.props.uri); const uri = lbryuri.normalize(this.props.uri);
const title = metadata && metadata.title ? metadata.title : uri; const title = metadata && metadata.title ? metadata.title : uri;
const thumbnail = const thumbnail = metadata && metadata.thumbnail ? metadata.thumbnail : null;
metadata && metadata.thumbnail ? metadata.thumbnail : null;
const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw; const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
const isRewardContent = const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id);
claim && rewardedContentClaimIds.includes(claim.claim_id);
let description = ""; let description = '';
if (isResolvingUri && !claim) { if (isResolvingUri && !claim) {
description = __("Loading..."); description = __('Loading...');
} else if (metadata && metadata.description) { } else if (metadata && metadata.description) {
description = metadata.description; description = metadata.description;
} else if (claim === null) { } else if (claim === null) {
description = __("This address contains no content."); description = __('This address contains no content.');
} }
return ( return (
<section <section
className={ className={`card card--small card--link ${obscureNsfw ? 'card--obscured ' : ''}`}
"card card--small card--link " +
(obscureNsfw ? "card--obscured " : "")
}
onMouseEnter={this.handleMouseOver.bind(this)} onMouseEnter={this.handleMouseOver.bind(this)}
onMouseLeave={this.handleMouseOut.bind(this)} onMouseLeave={this.handleMouseOut.bind(this)}
> >
<div className="card__inner"> <div className="card__inner">
<Link <Link onClick={() => navigate('/show', { uri })} className="card__link">
onClick={() => navigate("/show", { uri })}
className="card__link"
>
<CardMedia title={title} thumbnail={thumbnail} /> <CardMedia title={title} thumbnail={thumbnail} />
<div className="card__title-identity"> <div className="card__title-identity">
<div className="card__title" title={title}> <div className="card__title" title={title}>
@ -95,8 +87,7 @@ class FileCard extends React.PureComponent {
</div> </div>
<div className="card__subtitle"> <div className="card__subtitle">
<span className="card__indicators"> <span className="card__indicators">
<FilePrice uri={uri} />{" "} <FilePrice uri={uri} /> {isRewardContent && <Icon icon={icons.FEATURED} />}{' '}
{isRewardContent && <Icon icon={icons.FEATURED} />}{" "}
{fileInfo && <Icon icon={icons.LOCAL} />} {fileInfo && <Icon icon={icons.LOCAL} />}
</span> </span>
<UriIndicator uri={uri} smallCard /> <UriIndicator uri={uri} smallCard />

View file

@ -1,13 +1,13 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { import {
makeSelectClaimForUri, makeSelectClaimForUri,
makeSelectContentTypeForUri, makeSelectContentTypeForUri,
makeSelectMetadataForUri, makeSelectMetadataForUri,
} from "redux/selectors/claims"; } from 'redux/selectors/claims';
import FileDetails from "./view"; import FileDetails from './view';
import { doOpenFileInFolder } from "redux/actions/file_info"; import { doOpenFileInFolder } from 'redux/actions/file_info';
import { makeSelectFileInfoForUri } from "redux/selectors/file_info"; import { makeSelectFileInfoForUri } from 'redux/selectors/file_info';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),

View file

@ -1,27 +1,20 @@
import React from "react"; import React from 'react';
import ReactMarkdown from "react-markdown"; import ReactMarkdown from 'react-markdown';
import lbry from "lbry.js"; import lbry from 'lbry.js';
import FileActions from "component/fileActions"; import FileActions from 'component/fileActions';
import Link from "component/link"; import Link from 'component/link';
import DateTime from "component/dateTime"; import DateTime from 'component/dateTime';
const path = require("path"); const path = require('path');
class FileDetails extends React.PureComponent { class FileDetails extends React.PureComponent {
render() { render() {
const { const { claim, contentType, fileInfo, metadata, openFolder, uri } = this.props;
claim,
contentType,
fileInfo,
metadata,
openFolder,
uri,
} = this.props;
if (!claim || !metadata) { if (!claim || !metadata) {
return ( return (
<div className="card__content"> <div className="card__content">
<span className="empty">{__("Empty claim or metadata info.")}</span> <span className="empty">{__('Empty claim or metadata info.')}</span>
</div> </div>
); );
} }
@ -29,9 +22,7 @@ class FileDetails extends React.PureComponent {
const { description, language, license } = metadata; const { description, language, license } = metadata;
const mediaType = lbry.getMediaType(contentType); const mediaType = lbry.getMediaType(contentType);
const downloadPath = fileInfo const downloadPath = fileInfo ? path.normalize(fileInfo.download_path) : null;
? path.normalize(fileInfo.download_path)
: null;
return ( return (
<div> <div>
@ -40,33 +31,31 @@ class FileDetails extends React.PureComponent {
<div className="divider__horizontal" /> <div className="divider__horizontal" />
<div className="card__content card__subtext card__subtext--allow-newlines"> <div className="card__content card__subtext card__subtext--allow-newlines">
<ReactMarkdown <ReactMarkdown
source={description || ""} source={description || ''}
escapeHtml={true} escapeHtml
disallowedTypes={["Heading", "HtmlInline", "HtmlBlock"]} disallowedTypes={['Heading', 'HtmlInline', 'HtmlBlock']}
/> />
</div> </div>
<div className="card__content"> <div className="card__content">
<table className="table-standard table-stretch"> <table className="table-standard table-stretch">
<tbody> <tbody>
<tr> <tr>
<td>{__("Content-Type")}</td> <td>{__('Content-Type')}</td>
<td>{mediaType}</td> <td>{mediaType}</td>
</tr> </tr>
<tr> <tr>
<td>{__("Language")}</td> <td>{__('Language')}</td>
<td>{language}</td> <td>{language}</td>
</tr> </tr>
<tr> <tr>
<td>{__("License")}</td> <td>{__('License')}</td>
<td>{license}</td> <td>{license}</td>
</tr> </tr>
{downloadPath && ( {downloadPath && (
<tr> <tr>
<td>{__("Downloaded to")}</td> <td>{__('Downloaded to')}</td>
<td> <td>
<Link onClick={() => openFolder(downloadPath)}> <Link onClick={() => openFolder(downloadPath)}>{downloadPath}</Link>
{downloadPath}
</Link>
</td> </td>
</tr> </tr>
)} )}

View file

@ -1,15 +1,15 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { import {
makeSelectFileInfoForUri, makeSelectFileInfoForUri,
makeSelectDownloadingForUri, makeSelectDownloadingForUri,
makeSelectLoadingForUri, makeSelectLoadingForUri,
} from "redux/selectors/file_info"; } from 'redux/selectors/file_info';
import { makeSelectCostInfoForUri } from "redux/selectors/cost_info"; import { makeSelectCostInfoForUri } from 'redux/selectors/cost_info';
import { doFetchAvailability } from "redux/actions/availability"; import { doFetchAvailability } from 'redux/actions/availability';
import { doOpenFileInShell } from "redux/actions/file_info"; import { doOpenFileInShell } from 'redux/actions/file_info';
import { doPurchaseUri, doStartDownload } from "redux/actions/content"; import { doPurchaseUri, doStartDownload } from 'redux/actions/content';
import FileDownloadLink from "./view"; import FileDownloadLink from './view';
const select = (state, props) => ({ const select = (state, props) => ({
fileInfo: makeSelectFileInfoForUri(props.uri)(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state),

View file

@ -1,6 +1,6 @@
import React from "react"; import React from 'react';
import { Icon, BusyMessage } from "component/common"; import { Icon, BusyMessage } from 'component/common';
import Link from "component/link"; import Link from 'component/link';
class FileDownloadLink extends React.PureComponent { class FileDownloadLink extends React.PureComponent {
componentWillMount() { componentWillMount() {
@ -34,24 +34,14 @@ class FileDownloadLink extends React.PureComponent {
} }
render() { render() {
const { const { fileInfo, downloading, uri, openInShell, purchaseUri, costInfo, loading } = this.props;
fileInfo,
downloading,
uri,
openInShell,
purchaseUri,
costInfo,
loading,
} = this.props;
if (loading || downloading) { if (loading || downloading) {
const progress = const progress =
fileInfo && fileInfo.written_bytes fileInfo && fileInfo.written_bytes
? fileInfo.written_bytes / fileInfo.total_bytes * 100 ? fileInfo.written_bytes / fileInfo.total_bytes * 100
: 0, : 0,
label = fileInfo label = fileInfo ? progress.toFixed(0) + __('% complete') : __('Connecting...'),
? progress.toFixed(0) + __("% complete")
: __("Connecting..."),
labelWithIcon = ( labelWithIcon = (
<span className="button__content"> <span className="button__content">
<Icon icon="icon-download" /> <Icon icon="icon-download" />
@ -63,7 +53,7 @@ class FileDownloadLink extends React.PureComponent {
<div className="faux-button-block file-download button-set-item"> <div className="faux-button-block file-download button-set-item">
<div <div
className="faux-button-block file-download__overlay" className="faux-button-block file-download__overlay"
style={{ width: progress + "%" }} style={{ width: `${progress}%` }}
> >
{labelWithIcon} {labelWithIcon}
</div> </div>
@ -72,24 +62,23 @@ class FileDownloadLink extends React.PureComponent {
); );
} else if (fileInfo === null && !downloading) { } else if (fileInfo === null && !downloading) {
if (!costInfo) { if (!costInfo) {
return <BusyMessage message={__("Fetching cost info")} />; return <BusyMessage message={__('Fetching cost info')} />;
} else {
return (
<Link
button="text"
label={__("Download")}
icon="icon-download"
className="no-underline"
onClick={() => {
purchaseUri(uri);
}}
/>
);
} }
return (
<Link
button="text"
label={__('Download')}
icon="icon-download"
className="no-underline"
onClick={() => {
purchaseUri(uri);
}}
/>
);
} else if (fileInfo && fileInfo.download_path) { } else if (fileInfo && fileInfo.download_path) {
return ( return (
<Link <Link
label={__("Open")} label={__('Open')}
button="text" button="text"
icon="icon-external-link-square" icon="icon-external-link-square"
className="no-underline" className="no-underline"

View file

@ -1,6 +1,6 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import FileList from "./view"; import FileList from './view';
const select = state => ({}); const select = state => ({});

View file

@ -1,23 +1,23 @@
import React from "react"; import React from 'react';
import lbryuri from "lbryuri.js"; import lbryuri from 'lbryuri.js';
import FormField from "component/formField"; import FormField from 'component/formField';
import FileTile from "component/fileTile"; import FileTile from 'component/fileTile';
import { BusyMessage } from "component/common.js"; import { BusyMessage } from 'component/common.js';
class FileList extends React.PureComponent { class FileList extends React.PureComponent {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
sortBy: "date", sortBy: 'date',
}; };
this._sortFunctions = { this._sortFunctions = {
date: function(fileInfos) { date(fileInfos) {
return fileInfos.slice().reverse(); return fileInfos.slice().reverse();
}, },
title: function(fileInfos) { title(fileInfos) {
return fileInfos.slice().sort(function(fileInfo1, fileInfo2) { return fileInfos.slice().sort((fileInfo1, fileInfo2) => {
const title1 = fileInfo1.value const title1 = fileInfo1.value
? fileInfo1.value.stream.metadata.title.toLowerCase() ? fileInfo1.value.stream.metadata.title.toLowerCase()
: fileInfo1.name; : fileInfo1.name;
@ -28,25 +28,21 @@ class FileList extends React.PureComponent {
return -1; return -1;
} else if (title1 > title2) { } else if (title1 > title2) {
return 1; return 1;
} else {
return 0;
} }
return 0;
}); });
}, },
filename: function(fileInfos) { filename(fileInfos) {
return fileInfos return fileInfos.slice().sort(({ file_name: fileName1 }, { file_name: fileName2 }) => {
.slice() const fileName1Lower = fileName1.toLowerCase();
.sort(function({ file_name: fileName1 }, { file_name: fileName2 }) { const fileName2Lower = fileName2.toLowerCase();
const fileName1Lower = fileName1.toLowerCase(); if (fileName1Lower < fileName2Lower) {
const fileName2Lower = fileName2.toLowerCase(); return -1;
if (fileName1Lower < fileName2Lower) { } else if (fileName2Lower > fileName1Lower) {
return -1; return 1;
} else if (fileName2Lower > fileName1Lower) { }
return 1; return 0;
} else { });
return 0;
}
});
}, },
}; };
} }
@ -54,9 +50,8 @@ class FileList extends React.PureComponent {
getChannelSignature(fileInfo) { getChannelSignature(fileInfo) {
if (fileInfo.value) { if (fileInfo.value) {
return fileInfo.value.publisherSignature.certificateId; return fileInfo.value.publisherSignature.certificateId;
} else {
return fileInfo.metadata.publisherSignature.certificateId;
} }
return fileInfo.metadata.publisherSignature.certificateId;
} }
handleSortChanged(event) { handleSortChanged(event) {
@ -71,7 +66,7 @@ class FileList extends React.PureComponent {
const content = []; const content = [];
this._sortFunctions[sortBy](fileInfos).forEach(fileInfo => { this._sortFunctions[sortBy](fileInfos).forEach(fileInfo => {
let uriParams = {}; const uriParams = {};
if (fileInfo.channel_name) { if (fileInfo.channel_name) {
uriParams.channelName = fileInfo.channel_name; uriParams.channelName = fileInfo.channel_name;
@ -89,7 +84,7 @@ class FileList extends React.PureComponent {
uri={uri} uri={uri}
showPrice={false} showPrice={false}
showLocal={false} showLocal={false}
showActions={true} showActions
showEmpty={this.props.fileTileShowEmpty} showEmpty={this.props.fileTileShowEmpty}
/> />
); );
@ -98,10 +93,10 @@ class FileList extends React.PureComponent {
<section className="file-list__header"> <section className="file-list__header">
{fetching && <BusyMessage />} {fetching && <BusyMessage />}
<span className="sort-section"> <span className="sort-section">
{__("Sort by")}{" "} {__('Sort by')}{' '}
<FormField type="select" onChange={this.handleSortChanged.bind(this)}> <FormField type="select" onChange={this.handleSortChanged.bind(this)}>
<option value="date">{__("Date")}</option> <option value="date">{__('Date')}</option>
<option value="title">{__("Title")}</option> <option value="title">{__('Title')}</option>
</FormField> </FormField>
</span> </span>
{content} {content}

View file

@ -1,11 +1,8 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doSearch } from "redux/actions/search"; import { doSearch } from 'redux/actions/search';
import { import { selectIsSearching, makeSelectSearchUris } from 'redux/selectors/search';
selectIsSearching, import FileListSearch from './view';
makeSelectSearchUris,
} from "redux/selectors/search";
import FileListSearch from "./view";
const select = (state, props) => ({ const select = (state, props) => ({
isSearching: selectIsSearching(state), isSearching: selectIsSearching(state),

View file

@ -1,9 +1,9 @@
import React from "react"; import React from 'react';
import FileTile from "component/fileTile"; import FileTile from 'component/fileTile';
import ChannelTile from "component/channelTile"; import ChannelTile from 'component/channelTile';
import Link from "component/link"; import Link from 'component/link';
import { BusyMessage } from "component/common.js"; import { BusyMessage } from 'component/common.js';
import lbryuri from "lbryuri"; import lbryuri from 'lbryuri';
const SearchNoResults = props => { const SearchNoResults = props => {
const { query } = props; const { query } = props;
@ -11,8 +11,8 @@ const SearchNoResults = props => {
return ( return (
<section> <section>
<span className="empty"> <span className="empty">
{(__("No one has checked anything in for %s yet."), query)}{" "} {(__('No one has checked anything in for %s yet.'), query)}{' '}
<Link label={__("Be the first")} navigate="/publish" /> <Link label={__('Be the first')} navigate="/publish" />
</span> </span>
</section> </section>
); );
@ -38,18 +38,14 @@ class FileListSearch extends React.PureComponent {
return ( return (
<div> <div>
{isSearching && {isSearching && !uris && <BusyMessage message={__('Looking up the Dewey Decimals')} />}
!uris && (
<BusyMessage message={__("Looking up the Dewey Decimals")} />
)}
{isSearching && {isSearching && uris && <BusyMessage message={__('Refreshing the Dewey Decimals')} />}
uris && <BusyMessage message={__("Refreshing the Dewey Decimals")} />}
{uris && uris.length {uris && uris.length
? uris.map( ? uris.map(
uri => uri =>
lbryuri.parse(uri).name[0] === "@" ? ( lbryuri.parse(uri).name[0] === '@' ? (
<ChannelTile key={uri} uri={uri} /> <ChannelTile key={uri} uri={uri} />
) : ( ) : (
<FileTile key={uri} uri={uri} /> <FileTile key={uri} uri={uri} />

View file

@ -1,12 +1,12 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doFetchCostInfoForUri } from "redux/actions/cost_info"; import { doFetchCostInfoForUri } from 'redux/actions/cost_info';
import { import {
makeSelectCostInfoForUri, makeSelectCostInfoForUri,
makeSelectFetchingCostInfoForUri, makeSelectFetchingCostInfoForUri,
} from "redux/selectors/cost_info"; } from 'redux/selectors/cost_info';
import { makeSelectClaimForUri } from "redux/selectors/claims"; import { makeSelectClaimForUri } from 'redux/selectors/claims';
import FilePrice from "./view"; import FilePrice from './view';
const select = (state, props) => ({ const select = (state, props) => ({
costInfo: makeSelectCostInfoForUri(props.uri)(state), costInfo: makeSelectCostInfoForUri(props.uri)(state),

View file

@ -1,5 +1,5 @@
import React from "react"; import React from 'react';
import { CreditAmount } from "component/common"; import { CreditAmount } from 'component/common';
class FilePrice extends React.PureComponent { class FilePrice extends React.PureComponent {
componentWillMount() { componentWillMount() {
@ -19,14 +19,12 @@ class FilePrice extends React.PureComponent {
} }
render() { render() {
const { costInfo, look = "indicator", showFullPrice = false } = this.props; const { costInfo, look = 'indicator', showFullPrice = false } = this.props;
const isEstimate = costInfo ? !costInfo.includesData : null; const isEstimate = costInfo ? !costInfo.includesData : null;
if (!costInfo) { if (!costInfo) {
return ( return <span className={`credit-amount credit-amount--${look}`}>???</span>;
<span className={`credit-amount credit-amount--${look}`}>???</span>
);
} }
return ( return (
@ -34,7 +32,7 @@ class FilePrice extends React.PureComponent {
label={false} label={false}
amount={costInfo.cost} amount={costInfo.cost}
isEstimate={isEstimate} isEstimate={isEstimate}
showFree={true} showFree
showFullPrice={showFullPrice} showFullPrice={showFullPrice}
/> />
); );

View file

@ -1,18 +1,12 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doNavigate } from "redux/actions/navigation"; import { doNavigate } from 'redux/actions/navigation';
import { doResolveUri } from "redux/actions/content"; import { doResolveUri } from 'redux/actions/content';
import { import { makeSelectClaimForUri, makeSelectMetadataForUri } from 'redux/selectors/claims';
makeSelectClaimForUri, import { makeSelectFileInfoForUri } from 'redux/selectors/file_info';
makeSelectMetadataForUri, import { selectShowNsfw } from 'redux/selectors/settings';
} from "redux/selectors/claims"; import { makeSelectIsUriResolving, selectRewardContentClaimIds } from 'redux/selectors/content';
import { makeSelectFileInfoForUri } from "redux/selectors/file_info"; import FileTile from './view';
import { selectShowNsfw } from "redux/selectors/settings";
import {
makeSelectIsUriResolving,
selectRewardContentClaimIds,
} from "redux/selectors/content";
import FileTile from "./view";
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),

View file

@ -1,15 +1,15 @@
import React from "react"; import React from 'react';
import * as icons from "constants/icons"; import * as icons from 'constants/icons';
import lbryuri from "lbryuri.js"; import lbryuri from 'lbryuri.js';
import CardMedia from "component/cardMedia"; import CardMedia from 'component/cardMedia';
import { TruncatedText } from "component/common.js"; import { TruncatedText } from 'component/common.js';
import FilePrice from "component/filePrice"; import FilePrice from 'component/filePrice';
import NsfwOverlay from "component/nsfwOverlay"; import NsfwOverlay from 'component/nsfwOverlay';
import Icon from "component/icon"; import Icon from 'component/icon';
class FileTile extends React.PureComponent { class FileTile extends React.PureComponent {
static SHOW_EMPTY_PUBLISH = "publish"; static SHOW_EMPTY_PUBLISH = 'publish';
static SHOW_EMPTY_PENDING = "pending"; static SHOW_EMPTY_PENDING = 'pending';
static defaultProps = { static defaultProps = {
showPrice: true, showPrice: true,
@ -36,11 +36,7 @@ class FileTile extends React.PureComponent {
} }
handleMouseOver() { handleMouseOver() {
if ( if (this.props.obscureNsfw && this.props.metadata && this.props.metadata.nsfw) {
this.props.obscureNsfw &&
this.props.metadata &&
this.props.metadata.nsfw
) {
this.setState({ this.setState({
showNsfwHelp: true, showNsfwHelp: true,
}); });
@ -73,59 +69,49 @@ class FileTile extends React.PureComponent {
const isClaimed = !!claim; const isClaimed = !!claim;
const isClaimable = lbryuri.isClaimable(uri); const isClaimable = lbryuri.isClaimable(uri);
const title = const title =
isClaimed && metadata && metadata.title isClaimed && metadata && metadata.title ? metadata.title : lbryuri.parse(uri).contentName;
? metadata.title const thumbnail = metadata && metadata.thumbnail ? metadata.thumbnail : null;
: lbryuri.parse(uri).contentName;
const thumbnail =
metadata && metadata.thumbnail ? metadata.thumbnail : null;
const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw; const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
const isRewardContent = const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id);
claim && rewardedContentClaimIds.includes(claim.claim_id);
let onClick = () => navigate("/show", { uri }); let onClick = () => navigate('/show', { uri });
let name = ""; let name = '';
if (claim) { if (claim) {
name = claim.name; name = claim.name;
} }
let description = ""; let description = '';
if (isClaimed) { if (isClaimed) {
description = metadata && metadata.description; description = metadata && metadata.description;
} else if (isResolvingUri) { } else if (isResolvingUri) {
description = __("Loading..."); description = __('Loading...');
} else if (showEmpty === FileTile.SHOW_EMPTY_PUBLISH) { } else if (showEmpty === FileTile.SHOW_EMPTY_PUBLISH) {
onClick = () => navigate("/publish", {}); onClick = () => navigate('/publish', {});
description = ( description = (
<span className="empty"> <span className="empty">
{__("This location is unused.")}{" "} {__('This location is unused.')}{' '}
{isClaimable && ( {isClaimable && <span className="button-text">{__('Put something here!')}</span>}
<span className="button-text">{__("Put something here!")}</span>
)}
</span> </span>
); );
} else if (showEmpty === FileTile.SHOW_EMPTY_PENDING) { } else if (showEmpty === FileTile.SHOW_EMPTY_PENDING) {
description = ( description = <span className="empty">{__('This file is pending confirmation.')}</span>;
<span className="empty">
{__("This file is pending confirmation.")}
</span>
);
} }
return ( return (
<section <section
className={"file-tile card " + (obscureNsfw ? "card--obscured " : "")} className={`file-tile card ${obscureNsfw ? 'card--obscured ' : ''}`}
onMouseEnter={this.handleMouseOver.bind(this)} onMouseEnter={this.handleMouseOver.bind(this)}
onMouseLeave={this.handleMouseOut.bind(this)} onMouseLeave={this.handleMouseOut.bind(this)}
> >
<div onClick={onClick} className="card__link"> <div onClick={onClick} className="card__link">
<div className={"card__inner file-tile__row"}> <div className="card__inner file-tile__row">
<CardMedia title={title || name} thumbnail={thumbnail} /> <CardMedia title={title || name} thumbnail={thumbnail} />
<div className="file-tile__content"> <div className="file-tile__content">
<div className="card__title-primary"> <div className="card__title-primary">
<span className="card__indicators"> <span className="card__indicators">
{showPrice && <FilePrice uri={this.props.uri} />}{" "} {showPrice && <FilePrice uri={this.props.uri} />}{' '}
{isRewardContent && <Icon icon={icons.FEATURED} />}{" "} {isRewardContent && <Icon icon={icons.FEATURED} />}{' '}
{showLocal && fileInfo && <Icon icon={icons.LOCAL} />} {showLocal && fileInfo && <Icon icon={icons.LOCAL} />}
</span> </span>
<h3> <h3>
@ -134,9 +120,7 @@ class FileTile extends React.PureComponent {
</div> </div>
{description && ( {description && (
<div className="card__content card__subtext"> <div className="card__content card__subtext">
<TruncatedText lines={!showActions ? 3 : 2}> <TruncatedText lines={!showActions ? 3 : 2}>{description}</TruncatedText>
{description}
</TruncatedText>
</div> </div>
)} )}
</div> </div>

View file

@ -1,11 +1,11 @@
import React from "react"; import React from 'react';
import PropTypes from "prop-types"; import PropTypes from 'prop-types';
import FormField from "component/formField"; import FormField from 'component/formField';
import { Icon } from "component/common.js"; import { Icon } from 'component/common.js';
let formFieldCounter = 0; let formFieldCounter = 0;
export const formFieldNestedLabelTypes = ["radio", "checkbox"]; export const formFieldNestedLabelTypes = ['radio', 'checkbox'];
export function formFieldId() { export function formFieldId() {
return `form-field-${++formFieldCounter}`; return `form-field-${++formFieldCounter}`;
@ -26,11 +26,7 @@ export class Form extends React.PureComponent {
} }
render() { render() {
return ( return <form onSubmit={event => this.handleSubmit(event)}>{this.props.children}</form>;
<form onSubmit={event => this.handleSubmit(event)}>
{this.props.children}
</form>
);
} }
} }
@ -50,7 +46,7 @@ export class FormRow extends React.PureComponent {
this._field = null; this._field = null;
this._fieldRequiredText = __("This field is required"); this._fieldRequiredText = __('This field is required');
this.state = this.getStateFromProps(props); this.state = this.getStateFromProps(props);
} }
@ -63,11 +59,9 @@ export class FormRow extends React.PureComponent {
return { return {
isError: !!props.errorMessage, isError: !!props.errorMessage,
errorMessage: errorMessage:
typeof props.errorMessage === "string" typeof props.errorMessage === 'string'
? props.errorMessage ? props.errorMessage
: props.errorMessage instanceof Error : props.errorMessage instanceof Error ? props.errorMessage.toString() : '',
? props.errorMessage.toString()
: "",
}; };
} }
@ -85,7 +79,7 @@ export class FormRow extends React.PureComponent {
clearError(text) { clearError(text) {
this.setState({ this.setState({
isError: false, isError: false,
errorMessage: "", errorMessage: '',
}); });
} }
@ -116,9 +110,7 @@ export class FormRow extends React.PureComponent {
render() { render() {
const fieldProps = Object.assign({}, this.props), const fieldProps = Object.assign({}, this.props),
elementId = formFieldId(), elementId = formFieldId(),
renderLabelInFormField = formFieldNestedLabelTypes.includes( renderLabelInFormField = formFieldNestedLabelTypes.includes(this.props.type);
this.props.type
);
if (!renderLabelInFormField) { if (!renderLabelInFormField) {
delete fieldProps.label; delete fieldProps.label;
@ -128,26 +120,24 @@ export class FormRow extends React.PureComponent {
delete fieldProps.isFocus; delete fieldProps.isFocus;
return ( return (
<div <div className={`form-row${this.state.isFocus ? ' form-row--focus' : ''}`}>
className={`form-row${this.state.isFocus ? " form-row--focus" : ""}`}
>
{this.props.label && !renderLabelInFormField ? ( {this.props.label && !renderLabelInFormField ? (
<div <div
className={`form-row__label-row ${ className={`form-row__label-row ${
this.props.labelPrefix ? "form-row__label-row--prefix" : "" this.props.labelPrefix ? 'form-row__label-row--prefix' : ''
}`} }`}
> >
<label <label
htmlFor={elementId} htmlFor={elementId}
className={`form-field__label ${ className={`form-field__label ${
this.state.isError ? "form-field__label--error" : " " this.state.isError ? 'form-field__label--error' : ' '
}`} }`}
> >
{this.props.label} {this.props.label}
</label> </label>
</div> </div>
) : ( ) : (
"" ''
)} )}
<FormField <FormField
ref={ref => { ref={ref => {
@ -161,12 +151,12 @@ export class FormRow extends React.PureComponent {
{!this.state.isError && this.props.helper ? ( {!this.state.isError && this.props.helper ? (
<div className="form-field__helper">{this.props.helper}</div> <div className="form-field__helper">{this.props.helper}</div>
) : ( ) : (
"" ''
)} )}
{this.state.isError ? ( {this.state.isError ? (
<div className="form-field__error">{this.state.errorMessage}</div> <div className="form-field__error">{this.state.errorMessage}</div>
) : ( ) : (
"" ''
)} )}
</div> </div>
); );
@ -176,14 +166,14 @@ export class FormRow extends React.PureComponent {
export const Submit = props => { export const Submit = props => {
const { title, label, icon, disabled } = props; const { title, label, icon, disabled } = props;
const className = `${"button-block" + const className = `${'button-block' +
" button-primary" + ' button-primary' +
" button-set-item" + ' button-set-item' +
" button--submit"}${disabled ? " disabled" : ""}`; ' button--submit'}${disabled ? ' disabled' : ''}`;
const content = ( const content = (
<span className="button__content"> <span className="button__content">
{"icon" in props ? <Icon icon={icon} fixed /> : null} {'icon' in props ? <Icon icon={icon} fixed /> : null}
{label ? <span className="button-label">{label}</span> : null} {label ? <span className="button-label">{label}</span> : null}
</span> </span>
); );

View file

@ -1,5 +1,5 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import FormField from "./view"; import FormField from './view';
export default connect(null, null, null, { withRef: true })(FormField); export default connect(null, null, null, { withRef: true })(FormField);

View file

@ -1,11 +1,11 @@
import React from "react"; import React from 'react';
import PropTypes from "prop-types"; import PropTypes from 'prop-types';
import FileSelector from "component/file-selector.js"; import FileSelector from 'component/file-selector.js';
import SimpleMDE from "react-simplemde-editor"; import SimpleMDE from 'react-simplemde-editor';
import { formFieldNestedLabelTypes, formFieldId } from "../form"; import { formFieldNestedLabelTypes, formFieldId } from '../form';
import style from "react-simplemde-editor/dist/simplemde.min.css"; import style from 'react-simplemde-editor/dist/simplemde.min.css';
const formFieldFileSelectorTypes = ["file", "directory"]; const formFieldFileSelectorTypes = ['file', 'directory'];
class FormField extends React.PureComponent { class FormField extends React.PureComponent {
static propTypes = { static propTypes = {
@ -14,10 +14,7 @@ class FormField extends React.PureComponent {
postfix: PropTypes.string, postfix: PropTypes.string,
hasError: PropTypes.bool, hasError: PropTypes.bool,
trim: PropTypes.bool, trim: PropTypes.bool,
regexp: PropTypes.oneOfType([ regexp: PropTypes.oneOfType([PropTypes.instanceOf(RegExp), PropTypes.string]),
PropTypes.instanceOf(RegExp),
PropTypes.string,
]),
}; };
static defaultProps = { static defaultProps = {
@ -27,7 +24,7 @@ class FormField extends React.PureComponent {
constructor(props) { constructor(props) {
super(props); super(props);
this._fieldRequiredText = __("This field is required"); this._fieldRequiredText = __('This field is required');
this._type = null; this._type = null;
this._element = null; this._element = null;
this._extraElementProps = {}; this._extraElementProps = {};
@ -39,22 +36,22 @@ class FormField extends React.PureComponent {
} }
componentWillMount() { componentWillMount() {
if (["text", "number", "radio", "checkbox"].includes(this.props.type)) { if (['text', 'number', 'radio', 'checkbox'].includes(this.props.type)) {
this._element = "input"; this._element = 'input';
this._type = this.props.type; this._type = this.props.type;
} else if (this.props.type == "text-number") { } else if (this.props.type == 'text-number') {
this._element = "input"; this._element = 'input';
this._type = "text"; this._type = 'text';
} else if (this.props.type == "SimpleMDE") { } else if (this.props.type == 'SimpleMDE') {
this._element = SimpleMDE; this._element = SimpleMDE;
this._type = "textarea"; this._type = 'textarea';
this._extraElementProps.options = { this._extraElementProps.options = {
placeholder: this.props.placeholder, placeholder: this.props.placeholder,
hideIcons: ["heading", "image", "fullscreen", "side-by-side"], hideIcons: ['heading', 'image', 'fullscreen', 'side-by-side'],
}; };
} else if (formFieldFileSelectorTypes.includes(this.props.type)) { } else if (formFieldFileSelectorTypes.includes(this.props.type)) {
this._element = "input"; this._element = 'input';
this._type = "hidden"; this._type = 'hidden';
} else { } else {
// Non <input> field, e.g. <select>, <textarea> // Non <input> field, e.g. <select>, <textarea>
this._element = this.props.type; this._element = this.props.type;
@ -66,7 +63,7 @@ class FormField extends React.PureComponent {
* We have to add the webkitdirectory attribute here because React doesn't allow it in JSX * We have to add the webkitdirectory attribute here because React doesn't allow it in JSX
* https://github.com/facebook/react/issues/3468 * https://github.com/facebook/react/issues/3468
*/ */
if (this.props.type == "directory") { if (this.props.type == 'directory') {
this.refs.field.webkitdirectory = true; this.refs.field.webkitdirectory = true;
} }
} }
@ -75,7 +72,7 @@ class FormField extends React.PureComponent {
this.refs.field.value = path; this.refs.field.value = path;
if (this.props.onChange) { if (this.props.onChange) {
// Updating inputs programmatically doesn't generate an event, so we have to make our own // Updating inputs programmatically doesn't generate an event, so we have to make our own
const event = new Event("change", { bubbles: true }); const event = new Event('change', { bubbles: true });
this.refs.field.dispatchEvent(event); // This alone won't generate a React event, but we use it to attach the field as a target this.refs.field.dispatchEvent(event); // This alone won't generate a React event, but we use it to attach the field as a target
this.props.onChange(event); this.props.onChange(event);
} }
@ -91,20 +88,17 @@ class FormField extends React.PureComponent {
clearError() { clearError() {
this.setState({ this.setState({
isError: false, isError: false,
errorMessage: "", errorMessage: '',
}); });
} }
getValue() { getValue() {
if (this.props.type == "checkbox") { if (this.props.type == 'checkbox') {
return this.refs.field.checked; return this.refs.field.checked;
} else if (this.props.type == "SimpleMDE") { } else if (this.props.type == 'SimpleMDE') {
return this.refs.field.simplemde.value(); return this.refs.field.simplemde.value();
} else {
return this.props.trim
? this.refs.field.value.trim()
: this.refs.field.value;
} }
return this.props.trim ? this.refs.field.value.trim() : this.refs.field.value;
} }
getSelectedElement() { getSelectedElement() {
@ -116,9 +110,9 @@ class FormField extends React.PureComponent {
} }
validate() { validate() {
if ("regexp" in this.props) { if ('regexp' in this.props) {
if (!this.getValue().match(this.props.regexp)) { if (!this.getValue().match(this.props.regexp)) {
this.showError(__("Invalid format.")); this.showError(__('Invalid format.'));
} else { } else {
this.clearError(); this.clearError();
} }
@ -133,8 +127,7 @@ class FormField extends React.PureComponent {
render() { render() {
// Pass all unhandled props to the field element // Pass all unhandled props to the field element
const otherProps = Object.assign({}, this.props), const otherProps = Object.assign({}, this.props),
isError = isError = this.state.isError !== null ? this.state.isError : this.props.hasError,
this.state.isError !== null ? this.state.isError : this.props.hasError,
elementId = this.props.elementId ? this.props.elementId : formFieldId(), elementId = this.props.elementId ? this.props.elementId : formFieldId(),
renderElementInsideLabel = renderElementInsideLabel =
this.props.label && formFieldNestedLabelTypes.includes(this.props.type); this.props.label && formFieldNestedLabelTypes.includes(this.props.type);
@ -158,13 +151,8 @@ class FormField extends React.PureComponent {
placeholder={this.props.placeholder} placeholder={this.props.placeholder}
onBlur={() => this.validate()} onBlur={() => this.validate()}
onFocus={() => this.props.onFocus && this.props.onFocus()} onFocus={() => this.props.onFocus && this.props.onFocus()}
className={ className={`form-field__input form-field__input-${this.props.type} ${this.props.className ||
"form-field__input form-field__input-" + ''}${isError ? 'form-field__input--error' : ''}`}
this.props.type +
" " +
(this.props.className || "") +
(isError ? "form-field__input--error" : "")
}
{...otherProps} {...otherProps}
{...this._extraElementProps} {...this._extraElementProps}
> >
@ -173,19 +161,13 @@ class FormField extends React.PureComponent {
); );
return ( return (
<div className={"form-field form-field--" + this.props.type}> <div className={`form-field form-field--${this.props.type}`}>
{this.props.prefix ? ( {this.props.prefix ? <span className="form-field__prefix">{this.props.prefix}</span> : ''}
<span className="form-field__prefix">{this.props.prefix}</span>
) : (
""
)}
{element} {element}
{renderElementInsideLabel && ( {renderElementInsideLabel && (
<label <label
htmlFor={elementId} htmlFor={elementId}
className={ className={`form-field__label ${isError ? 'form-field__label--error' : ''}`}
"form-field__label " + (isError ? "form-field__label--error" : "")
}
> >
{this.props.label} {this.props.label}
</label> </label>
@ -194,20 +176,18 @@ class FormField extends React.PureComponent {
<FileSelector <FileSelector
type={this.props.type} type={this.props.type}
onFileChosen={this.handleFileChosen.bind(this)} onFileChosen={this.handleFileChosen.bind(this)}
{...(this.props.defaultValue {...(this.props.defaultValue ? { initPath: this.props.defaultValue } : {})}
? { initPath: this.props.defaultValue }
: {})}
/> />
) : null} ) : null}
{this.props.postfix ? ( {this.props.postfix ? (
<span className="form-field__postfix">{this.props.postfix}</span> <span className="form-field__postfix">{this.props.postfix}</span>
) : ( ) : (
"" ''
)} )}
{isError && this.state.errorMessage ? ( {isError && this.state.errorMessage ? (
<div className="form-field__error">{this.state.errorMessage}</div> <div className="form-field__error">{this.state.errorMessage}</div>
) : ( ) : (
"" ''
)} )}
</div> </div>
); );

View file

@ -1,5 +1,5 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import FormFieldPrice from "./view"; import FormFieldPrice from './view';
export default connect(null, null)(FormFieldPrice); export default connect(null, null)(FormFieldPrice);

View file

@ -1,18 +1,13 @@
import React from "react"; import React from 'react';
import FormField from "component/formField"; import FormField from 'component/formField';
class FormFieldPrice extends React.PureComponent { class FormFieldPrice extends React.PureComponent {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
amount: amount: props.defaultValue && props.defaultValue.amount ? props.defaultValue.amount : '',
props.defaultValue && props.defaultValue.amount
? props.defaultValue.amount
: "",
currency: currency:
props.defaultValue && props.defaultValue.currency props.defaultValue && props.defaultValue.currency ? props.defaultValue.currency : 'LBC',
? props.defaultValue.currency
: "LBC",
}; };
} }
@ -45,24 +40,20 @@ class FormFieldPrice extends React.PureComponent {
name="amount" name="amount"
min={min} min={min}
placeholder={placeholder || null} placeholder={placeholder || null}
step="any" //Unfortunately, you cannot set a step without triggering validation that enforces a multiple of the step step="any" // Unfortunately, you cannot set a step without triggering validation that enforces a multiple of the step
onChange={event => this.handleFeeAmountChange(event)} onChange={event => this.handleFeeAmountChange(event)}
defaultValue={ defaultValue={defaultValue && defaultValue.amount ? defaultValue.amount : ''}
defaultValue && defaultValue.amount ? defaultValue.amount : ""
}
className="form-field__input--inline" className="form-field__input--inline"
/> />
<FormField <FormField
type="select" type="select"
name="currency" name="currency"
onChange={event => this.handleFeeCurrencyChange(event)} onChange={event => this.handleFeeCurrencyChange(event)}
defaultValue={ defaultValue={defaultValue && defaultValue.currency ? defaultValue.currency : ''}
defaultValue && defaultValue.currency ? defaultValue.currency : ""
}
className="form-field__input--inline" className="form-field__input--inline"
> >
<option value="LBC">{__("LBRY Credits (LBC)")}</option> <option value="LBC">{__('LBRY Credits (LBC)')}</option>
<option value="USD">{__("US Dollars")}</option> <option value="USD">{__('US Dollars')}</option>
</FormField> </FormField>
</span> </span>
); );

View file

@ -1,19 +1,12 @@
import React from "react"; import React from 'react';
import { formatCredits } from "util/formatCredits"; import { formatCredits } from 'util/formatCredits';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { import { selectIsBackDisabled, selectIsForwardDisabled } from 'redux/selectors/navigation';
selectIsBackDisabled, import { selectBalance } from 'redux/selectors/wallet';
selectIsForwardDisabled, import { doNavigate, doHistoryBack, doHistoryForward } from 'redux/actions/navigation';
} from "redux/selectors/navigation"; import Header from './view';
import { selectBalance } from "redux/selectors/wallet"; import { selectIsUpgradeAvailable } from 'redux/selectors/app';
import { import { doDownloadUpgrade } from 'redux/actions/app';
doNavigate,
doHistoryBack,
doHistoryForward,
} from "redux/actions/navigation";
import Header from "./view";
import { selectIsUpgradeAvailable } from "redux/selectors/app";
import { doDownloadUpgrade } from "redux/actions/app";
const select = state => ({ const select = state => ({
isBackDisabled: selectIsBackDisabled(state), isBackDisabled: selectIsBackDisabled(state),

View file

@ -1,6 +1,6 @@
import React from "react"; import React from 'react';
import Link from "component/link"; import Link from 'component/link';
import WunderBar from "component/wunderbar"; import WunderBar from 'component/wunderbar';
export const Header = props => { export const Header = props => {
const { const {
@ -21,7 +21,7 @@ export const Header = props => {
disabled={isBackDisabled} disabled={isBackDisabled}
button="alt button--flat" button="alt button--flat"
icon="icon-arrow-left" icon="icon-arrow-left"
title={__("Back")} title={__('Back')}
/> />
</div> </div>
<div className="header__item"> <div className="header__item">
@ -30,59 +30,55 @@ export const Header = props => {
disabled={isForwardDisabled} disabled={isForwardDisabled}
button="alt button--flat" button="alt button--flat"
icon="icon-arrow-right" icon="icon-arrow-right"
title={__("Forward")} title={__('Forward')}
/> />
</div> </div>
<div className="header__item"> <div className="header__item">
<Link <Link
onClick={() => navigate("/discover")} onClick={() => navigate('/discover')}
button="alt button--flat" button="alt button--flat"
icon="icon-home" icon="icon-home"
title={__("Discover Content")} title={__('Discover Content')}
/> />
</div> </div>
<div className="header__item"> <div className="header__item">
<Link <Link onClick={() => navigate('/subscriptions')} button="alt button--flat" icon="icon-at" />
onClick={() => navigate("/subscriptions")}
button="alt button--flat"
icon="icon-at"
/>
</div> </div>
<div className="header__item header__item--wunderbar"> <div className="header__item header__item--wunderbar">
<WunderBar /> <WunderBar />
</div> </div>
<div className="header__item"> <div className="header__item">
<Link <Link
onClick={() => navigate("/wallet")} onClick={() => navigate('/wallet')}
button="text" button="text"
className="no-underline" className="no-underline"
icon="icon-bank" icon="icon-bank"
label={balance} label={balance}
title={__("Wallet")} title={__('Wallet')}
/> />
</div> </div>
<div className="header__item"> <div className="header__item">
<Link <Link
onClick={() => navigate("/publish")} onClick={() => navigate('/publish')}
button="primary button--flat" button="primary button--flat"
icon="icon-upload" icon="icon-upload"
label={__("Publish")} label={__('Publish')}
/> />
</div> </div>
<div className="header__item"> <div className="header__item">
<Link <Link
onClick={() => navigate("/downloaded")} onClick={() => navigate('/downloaded')}
button="alt button--flat" button="alt button--flat"
icon="icon-folder" icon="icon-folder"
title={__("Downloads and Publishes")} title={__('Downloads and Publishes')}
/> />
</div> </div>
<div className="header__item"> <div className="header__item">
<Link <Link
onClick={() => navigate("/settings")} onClick={() => navigate('/settings')}
button="alt button--flat" button="alt button--flat"
icon="icon-gear" icon="icon-gear"
title={__("Settings")} title={__('Settings')}
/> />
</div> </div>
{isUpgradeAvailable && ( {isUpgradeAvailable && (
@ -90,7 +86,7 @@ export const Header = props => {
onClick={() => downloadUpgrade()} onClick={() => downloadUpgrade()}
button="primary button--flat" button="primary button--flat"
icon="icon-arrow-up" icon="icon-arrow-up"
label={__("Upgrade App")} label={__('Upgrade App')}
/> />
)} )}
</header> </header>

View file

@ -1,5 +1,5 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import Icon from "./view"; import Icon from './view';
export default connect(null, null)(Icon); export default connect(null, null)(Icon);

View file

@ -1,6 +1,6 @@
import React from "react"; import React from 'react';
import PropTypes from "prop-types"; import PropTypes from 'prop-types';
import * as icons from "constants/icons"; import * as icons from 'constants/icons';
export default class Icon extends React.PureComponent { export default class Icon extends React.PureComponent {
static propTypes = { static propTypes = {
@ -15,17 +15,17 @@ export default class Icon extends React.PureComponent {
getIconClass() { getIconClass() {
const { icon } = this.props; const { icon } = this.props;
return icon.startsWith("icon-") ? icon : "icon-" + icon; return icon.startsWith('icon-') ? icon : `icon-${icon}`;
} }
getIconTitle() { getIconTitle() {
switch (this.props.icon) { switch (this.props.icon) {
case icons.FEATURED: case icons.FEATURED:
return __("Watch this and earn rewards."); return __('Watch this and earn rewards.');
case icons.LOCAL: case icons.LOCAL:
return __("You have a copy of this file."); return __('You have a copy of this file.');
default: default:
return ""; return '';
} }
} }
@ -33,8 +33,7 @@ export default class Icon extends React.PureComponent {
const className = this.getIconClass(), const className = this.getIconClass(),
title = this.getIconTitle(); title = this.getIconTitle();
const spanClassName = const spanClassName = `icon ${className}${this.props.fixed ? ' icon-fixed-width ' : ''}`;
"icon " + className + (this.props.fixed ? " icon-fixed-width " : "");
return <span className={spanClassName} title={title} />; return <span className={spanClassName} title={title} />;
} }

View file

@ -1,10 +1,7 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { import { selectUserInvitees, selectUserInviteStatusIsPending } from 'redux/selectors/user';
selectUserInvitees, import InviteList from './view';
selectUserInviteStatusIsPending,
} from "redux/selectors/user";
import InviteList from "./view";
const select = state => ({ const select = state => ({
invitees: selectUserInvitees(state), invitees: selectUserInvitees(state),

View file

@ -1,7 +1,7 @@
import React from "react"; import React from 'react';
import { Icon } from "component/common"; import { Icon } from 'component/common';
import RewardLink from "component/rewardLink"; import RewardLink from 'component/rewardLink';
import rewards from "rewards.js"; import rewards from 'rewards.js';
class InviteList extends React.PureComponent { class InviteList extends React.PureComponent {
render() { render() {
@ -14,7 +14,7 @@ class InviteList extends React.PureComponent {
return ( return (
<section className="card"> <section className="card">
<div className="card__title-primary"> <div className="card__title-primary">
<h3>{__("Invite History")}</h3> <h3>{__('Invite History')}</h3>
</div> </div>
<div className="card__content"> <div className="card__content">
{invitees.length === 0 && ( {invitees.length === 0 && (
@ -24,38 +24,33 @@ class InviteList extends React.PureComponent {
<table className="table-standard table-stretch"> <table className="table-standard table-stretch">
<thead> <thead>
<tr> <tr>
<th>{__("Invitee Email")}</th> <th>{__('Invitee Email')}</th>
<th className="text-center">{__("Invite Status")}</th> <th className="text-center">{__('Invite Status')}</th>
<th className="text-center">{__("Reward")}</th> <th className="text-center">{__('Reward')}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{invitees.map((invitee, index) => { {invitees.map((invitee, index) => (
return ( <tr key={index}>
<tr key={index}> <td>{invitee.email}</td>
<td>{invitee.email}</td> <td className="text-center">
<td className="text-center"> {invitee.invite_accepted ? (
{invitee.invite_accepted ? ( <Icon icon="icon-check" />
<Icon icon="icon-check" /> ) : (
) : ( <span className="empty">{__('unused')}</span>
<span className="empty">{__("unused")}</span> )}
)} </td>
</td> <td className="text-center">
<td className="text-center"> {invitee.invite_reward_claimed ? (
{invitee.invite_reward_claimed ? ( <Icon icon="icon-check" />
<Icon icon="icon-check" /> ) : invitee.invite_reward_claimable ? (
) : invitee.invite_reward_claimable ? ( <RewardLink label={__('claim')} reward_type={rewards.TYPE_REFERRAL} />
<RewardLink ) : (
label={__("claim")} <span className="empty">{__('unclaimable')}</span>
reward_type={rewards.TYPE_REFERRAL} )}
/> </td>
) : ( </tr>
<span className="empty">{__("unclaimable")}</span> ))}
)}
</td>
</tr>
);
})}
</tbody> </tbody>
</table> </table>
)} )}
@ -63,7 +58,7 @@ class InviteList extends React.PureComponent {
<div className="card__content"> <div className="card__content">
<div className="help"> <div className="help">
{__( {__(
"The maximum number of invite rewards is currently limited. Invite reward can only be claimed if the invitee passes the humanness test." 'The maximum number of invite rewards is currently limited. Invite reward can only be claimed if the invitee passes the humanness test.'
)} )}
</div> </div>
</div> </div>

View file

@ -1,15 +1,15 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import InviteNew from "./view"; import InviteNew from './view';
import { import {
selectUserInvitesRemaining, selectUserInvitesRemaining,
selectUserInviteNewIsPending, selectUserInviteNewIsPending,
selectUserInviteNewErrorMessage, selectUserInviteNewErrorMessage,
} from "redux/selectors/user"; } from 'redux/selectors/user';
import rewards from "rewards"; import rewards from 'rewards';
import { makeSelectRewardAmountByType } from "redux/selectors/rewards"; import { makeSelectRewardAmountByType } from 'redux/selectors/rewards';
import { doUserInviteNew } from "redux/actions/user"; import { doUserInviteNew } from 'redux/actions/user';
const select = state => { const select = state => {
const selectReward = makeSelectRewardAmountByType(); const selectReward = makeSelectRewardAmountByType();

View file

@ -1,13 +1,13 @@
import React from "react"; import React from 'react';
import { BusyMessage, CreditAmount } from "component/common"; import { BusyMessage, CreditAmount } from 'component/common';
import { Form, FormRow, Submit } from "component/form.js"; import { Form, FormRow, Submit } from 'component/form.js';
class FormInviteNew extends React.PureComponent { class FormInviteNew extends React.PureComponent {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
email: "", email: '',
}; };
} }
@ -39,7 +39,7 @@ class FormInviteNew extends React.PureComponent {
}} }}
/> />
<div className="form-row-submit"> <div className="form-row-submit">
<Submit label={__("Send Invite")} disabled={isPending} /> <Submit label={__('Send Invite')} disabled={isPending} />
</div> </div>
</Form> </Form>
); );
@ -61,7 +61,7 @@ class InviteNew extends React.PureComponent {
<section className="card"> <section className="card">
<div className="card__title-primary"> <div className="card__title-primary">
<CreditAmount amount={rewardAmount} /> <CreditAmount amount={rewardAmount} />
<h3>{__("Invite a Friend")}</h3> <h3>{__('Invite a Friend')}</h3>
</div> </div>
{/* {/*
<div className="card__content"> <div className="card__content">
@ -71,16 +71,8 @@ class InviteNew extends React.PureComponent {
<p className="empty">{__("You have no invites.")}</p>} <p className="empty">{__("You have no invites.")}</p>}
</div> */} </div> */}
<div className="card__content"> <div className="card__content">
<p> <p>{__("Or an enemy. Or your cousin Jerry, who you're kind of unsure about.")}</p>
{__( <FormInviteNew errorMessage={errorMessage} inviteNew={inviteNew} isPending={isPending} />
"Or an enemy. Or your cousin Jerry, who you're kind of unsure about."
)}
</p>
<FormInviteNew
errorMessage={errorMessage}
inviteNew={inviteNew}
isPending={isPending}
/>
</div> </div>
</section> </section>
); );

View file

@ -1,7 +1,7 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doNavigate } from "redux/actions/navigation"; import { doNavigate } from 'redux/actions/navigation';
import Link from "./view"; import Link from './view';
const perform = dispatch => ({ const perform = dispatch => ({
doNavigate: (path, params) => dispatch(doNavigate(path, params)), doNavigate: (path, params) => dispatch(doNavigate(path, params)),

View file

@ -1,5 +1,5 @@
import React from "react"; import React from 'react';
import Icon from "component/icon"; import Icon from 'component/icon';
const Link = props => { const Link = props => {
const { const {
@ -19,10 +19,10 @@ const Link = props => {
} = props; } = props;
const combinedClassName = const combinedClassName =
(className || "") + (className || '') +
(!className && !button ? "button-text" : "") + // Non-button links get the same look as text buttons (!className && !button ? 'button-text' : '') + // Non-button links get the same look as text buttons
(button ? " button-block button-" + button + " button-set-item" : "") + (button ? ` button-block button-${button} button-set-item` : '') +
(disabled ? " disabled" : ""); (disabled ? ' disabled' : '');
const onClick = const onClick =
!props.onClick && navigate !props.onClick && navigate
@ -36,10 +36,10 @@ const Link = props => {
content = children; content = children;
} else { } else {
content = ( content = (
<span {...("button" in props ? { className: "button__content" } : {})}> <span {...('button' in props ? { className: 'button__content' } : {})}>
{icon ? <Icon icon={icon} fixed={true} /> : null} {icon ? <Icon icon={icon} fixed /> : null}
{label ? <span className="link-label">{label}</span> : null} {label ? <span className="link-label">{label}</span> : null}
{iconRight ? <Icon icon={iconRight} fixed={true} /> : null} {iconRight ? <Icon icon={iconRight} fixed /> : null}
</span> </span>
); );
} }
@ -47,10 +47,10 @@ const Link = props => {
return ( return (
<a <a
className={combinedClassName} className={combinedClassName}
href={href || "javascript:;"} href={href || 'javascript:;'}
title={title} title={title}
onClick={onClick} onClick={onClick}
{...("style" in props ? { style: style } : {})} {...('style' in props ? { style } : {})}
> >
{content} {content}
</a> </a>

View file

@ -1,5 +1,5 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import LinkTransaction from "./view"; import LinkTransaction from './view';
export default connect(null, null)(LinkTransaction); export default connect(null, null)(LinkTransaction);

View file

@ -1,11 +1,11 @@
import React from "react"; import React from 'react';
import Link from "component/link"; import Link from 'component/link';
const LinkTransaction = props => { const LinkTransaction = props => {
const { id } = props; const { id } = props;
const linkProps = Object.assign({}, props); const linkProps = Object.assign({}, props);
linkProps.href = "https://explorer.lbry.io/#!/transaction/" + id; linkProps.href = `https://explorer.lbry.io/#!/transaction/${id}`;
linkProps.label = id.substr(0, 7); linkProps.label = id.substr(0, 7);
return <Link {...linkProps} />; return <Link {...linkProps} />;

View file

@ -1,8 +1,8 @@
import React from "react"; import React from 'react';
import PropTypes from "prop-types"; import PropTypes from 'prop-types';
import lbry from "../lbry.js"; import lbry from '../lbry.js';
import { BusyMessage, Icon } from "./common.js"; import { BusyMessage, Icon } from './common.js';
import Link from "component/link"; import Link from 'component/link';
class LoadScreen extends React.PureComponent { class LoadScreen extends React.PureComponent {
static propTypes = { static propTypes = {
@ -26,7 +26,7 @@ class LoadScreen extends React.PureComponent {
}; };
render() { render() {
const imgSrc = lbry.imagePath("lbry-white-485x160.png"); const imgSrc = lbry.imagePath('lbry-white-485x160.png');
return ( return (
<div className="load-screen"> <div className="load-screen">
<img src={imgSrc} alt="LBRY" /> <img src={imgSrc} alt="LBRY" />
@ -43,7 +43,7 @@ class LoadScreen extends React.PureComponent {
</h3> </h3>
<span <span
className={`load-screen__details ${ className={`load-screen__details ${
this.props.isWarning ? "load-screen__details--warning" : "" this.props.isWarning ? 'load-screen__details--warning' : ''
}`} }`}
> >
{this.props.details} {this.props.details}

View file

@ -1,7 +1,7 @@
import React from "react"; import React from 'react';
import PropTypes from "prop-types"; import PropTypes from 'prop-types';
import { Icon } from "./common.js"; import { Icon } from './common.js';
import Link from "component/link"; import Link from 'component/link';
export class DropDownMenuItem extends React.PureComponent { export class DropDownMenuItem extends React.PureComponent {
static propTypes = { static propTypes = {
@ -12,7 +12,7 @@ export class DropDownMenuItem extends React.PureComponent {
}; };
static defaultProps = { static defaultProps = {
iconPosition: "left", iconPosition: 'left',
}; };
render() { render() {
@ -22,12 +22,12 @@ export class DropDownMenuItem extends React.PureComponent {
<a <a
className="menu__menu-item" className="menu__menu-item"
onClick={this.props.onClick} onClick={this.props.onClick}
href={this.props.href || "javascript:"} href={this.props.href || 'javascript:'}
label={this.props.label} label={this.props.label}
> >
{this.props.iconPosition == "left" ? icon : null} {this.props.iconPosition == 'left' ? icon : null}
{this.props.label} {this.props.label}
{this.props.iconPosition == "left" ? null : icon} {this.props.iconPosition == 'left' ? null : icon}
</a> </a>
); );
} }
@ -47,7 +47,7 @@ export class DropDownMenu extends React.PureComponent {
componentWillUnmount() { componentWillUnmount() {
if (this._isWindowClickBound) { if (this._isWindowClickBound) {
window.removeEventListener("click", this.handleWindowClick, false); window.removeEventListener('click', this.handleWindowClick, false);
} }
} }
@ -57,7 +57,7 @@ export class DropDownMenu extends React.PureComponent {
}); });
if (!this.state.menuOpen && !this._isWindowClickBound) { if (!this.state.menuOpen && !this._isWindowClickBound) {
this._isWindowClickBound = true; this._isWindowClickBound = true;
window.addEventListener("click", this.handleWindowClick, false); window.addEventListener('click', this.handleWindowClick, false);
e.stopPropagation(); e.stopPropagation();
} }
return false; return false;
@ -72,10 +72,7 @@ export class DropDownMenu extends React.PureComponent {
/* this will force "this" to always be the class, even when passed to an event listener */ /* this will force "this" to always be the class, even when passed to an event listener */
handleWindowClick = e => { handleWindowClick = e => {
if ( if (this.state.menuOpen && (!this._menuDiv || !this._menuDiv.contains(e.target))) {
this.state.menuOpen &&
(!this._menuDiv || !this._menuDiv.contains(e.target))
) {
this.setState({ this.setState({
menuOpen: false, menuOpen: false,
}); });
@ -85,7 +82,7 @@ export class DropDownMenu extends React.PureComponent {
render() { render() {
if (!this.state.menuOpen && this._isWindowClickBound) { if (!this.state.menuOpen && this._isWindowClickBound) {
this._isWindowClickBound = false; this._isWindowClickBound = false;
window.removeEventListener("click", this.handleWindowClick, false); window.removeEventListener('click', this.handleWindowClick, false);
} }
return ( return (
<div className="menu-container"> <div className="menu-container">

View file

@ -1,10 +1,10 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doNavigate } from "redux/actions/navigation"; import { doNavigate } from 'redux/actions/navigation';
import NsfwOverlay from "./view"; import NsfwOverlay from './view';
const perform = dispatch => ({ const perform = dispatch => ({
navigateSettings: () => dispatch(doNavigate("/settings")), navigateSettings: () => dispatch(doNavigate('/settings')),
}); });
export default connect(null, perform)(NsfwOverlay); export default connect(null, perform)(NsfwOverlay);

View file

@ -1,21 +1,17 @@
import React from "react"; import React from 'react';
import Link from "component/link"; import Link from 'component/link';
const NsfwOverlay = props => { const NsfwOverlay = props => (
return ( <div className="card-overlay">
<div className="card-overlay"> <p>
<p> {__('This content is Not Safe For Work. To view adult content, please change your')}{' '}
{__( <Link
"This content is Not Safe For Work. To view adult content, please change your" className="button-text"
)}{" "} onClick={() => props.navigateSettings()}
<Link label={__('Settings')}
className="button-text" />.
onClick={() => props.navigateSettings()} </p>
label={__("Settings")} </div>
/>. );
</p>
</div>
);
};
export default NsfwOverlay; export default NsfwOverlay;

View file

@ -1,7 +1,7 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import PublishForm from "./view"; import PublishForm from './view';
import { selectBalance } from "redux/selectors/wallet"; import { selectBalance } from 'redux/selectors/wallet';
const select = state => ({ const select = state => ({
balance: selectBalance(state), balance: selectBalance(state),

View file

@ -1,15 +1,15 @@
import React from "react"; import React from 'react';
import lbryuri from "lbryuri"; import lbryuri from 'lbryuri';
import { FormRow } from "component/form.js"; import { FormRow } from 'component/form.js';
import { BusyMessage } from "component/common"; import { BusyMessage } from 'component/common';
import Link from "component/link"; import Link from 'component/link';
class ChannelSection extends React.PureComponent { class ChannelSection extends React.PureComponent {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
newChannelName: "@", newChannelName: '@',
newChannelBid: 10, newChannelBid: 10,
addingChannel: false, addingChannel: false,
}; };
@ -17,7 +17,7 @@ class ChannelSection extends React.PureComponent {
handleChannelChange(event) { handleChannelChange(event) {
const channel = event.target.value; const channel = event.target.value;
if (channel === "new") this.setState({ addingChannel: true }); if (channel === 'new') this.setState({ addingChannel: true });
else { else {
this.setState({ addingChannel: false }); this.setState({ addingChannel: false });
this.props.handleChannelChange(event.target.value); this.props.handleChannelChange(event.target.value);
@ -25,21 +25,17 @@ class ChannelSection extends React.PureComponent {
} }
handleNewChannelNameChange(event) { handleNewChannelNameChange(event) {
const newChannelName = event.target.value.startsWith("@") const newChannelName = event.target.value.startsWith('@')
? event.target.value ? event.target.value
: "@" + event.target.value; : `@${event.target.value}`;
if ( if (newChannelName.length > 1 && !lbryuri.isValidName(newChannelName.substr(1), false)) {
newChannelName.length > 1 &&
!lbryuri.isValidName(newChannelName.substr(1), false)
) {
this.refs.newChannelName.showError( this.refs.newChannelName.showError(
__("LBRY channel names must contain only letters, numbers and dashes.") __('LBRY channel names must contain only letters, numbers and dashes.')
); );
return; return;
} else {
this.refs.newChannelName.clearError();
} }
this.refs.newChannelName.clearError();
this.setState({ this.setState({
newChannelName, newChannelName,
@ -57,9 +53,7 @@ class ChannelSection extends React.PureComponent {
const { newChannelBid } = this.state; const { newChannelBid } = this.state;
if (newChannelBid > balance) { if (newChannelBid > balance) {
this.refs.newChannelName.showError( this.refs.newChannelName.showError(__('Unable to create channel due to insufficient funds.'));
__("Unable to create channel due to insufficient funds.")
);
return; return;
} }
@ -85,19 +79,17 @@ class ChannelSection extends React.PureComponent {
this.setState({ this.setState({
creatingChannel: false, creatingChannel: false,
}); });
this.refs.newChannelName.showError( this.refs.newChannelName.showError(__('Unable to create channel due to an internal error.'));
__("Unable to create channel due to an internal error.")
);
}; };
this.props.createChannel(newChannelName, amount).then(success, failure); this.props.createChannel(newChannelName, amount).then(success, failure);
} }
render() { render() {
const lbcInputHelp = __( const lbcInputHelp = __(
"This LBC remains yours. It is a deposit to reserve the name and can be undone at any time." 'This LBC remains yours. It is a deposit to reserve the name and can be undone at any time.'
); );
const channel = this.state.addingChannel ? "new" : this.props.channel; const channel = this.state.addingChannel ? 'new' : this.props.channel;
const { fetchingChannels, channels = [] } = this.props; const { fetchingChannels, channels = [] } = this.props;
const channelSelector = ( const channelSelector = (
@ -109,7 +101,7 @@ class ChannelSection extends React.PureComponent {
value={channel} value={channel}
> >
<option key="anonymous" value="anonymous"> <option key="anonymous" value="anonymous">
{__("Anonymous")} {__('Anonymous')}
</option> </option>
{channels.map(({ name }) => ( {channels.map(({ name }) => (
<option key={name} value={name}> <option key={name} value={name}>
@ -117,7 +109,7 @@ class ChannelSection extends React.PureComponent {
</option> </option>
))} ))}
<option key="new" value="new"> <option key="new" value="new">
{__("New channel...")} {__('New channel...')}
</option> </option>
</FormRow> </FormRow>
); );
@ -125,12 +117,10 @@ class ChannelSection extends React.PureComponent {
return ( return (
<section className="card"> <section className="card">
<div className="card__title-primary"> <div className="card__title-primary">
<h4>{__("Channel Name")}</h4> <h4>{__('Channel Name')}</h4>
<div className="card__subtitle"> <div className="card__subtitle">
{__( {__('This is a username or handle that your content can be found under.')}{' '}
"This is a username or handle that your content can be found under." {__('Ex. @Marvel, @TheBeatles, @BooksByJoe')}
)}{" "}
{__("Ex. @Marvel, @TheBeatles, @BooksByJoe")}
</div> </div>
</div> </div>
<div className="card__content"> <div className="card__content">
@ -143,13 +133,13 @@ class ChannelSection extends React.PureComponent {
{this.state.addingChannel && ( {this.state.addingChannel && (
<div className="card__content"> <div className="card__content">
<FormRow <FormRow
label={__("Name")} label={__('Name')}
type="text" type="text"
onChange={this.handleNewChannelNameChange.bind(this)} onChange={this.handleNewChannelNameChange.bind(this)}
value={this.state.newChannelName} value={this.state.newChannelName}
/> />
<FormRow <FormRow
label={__("Deposit")} label={__('Deposit')}
postfix="LBC" postfix="LBC"
step="any" step="any"
min="0" min="0"
@ -163,9 +153,7 @@ class ChannelSection extends React.PureComponent {
<Link <Link
button="primary" button="primary"
label={ label={
!this.state.creatingChannel !this.state.creatingChannel ? __('Create channel') : __('Creating channel...')
? __("Create channel")
: __("Creating channel...")
} }
onClick={this.handleCreateChannelClick.bind(this)} onClick={this.handleCreateChannelClick.bind(this)}
disabled={this.state.creatingChannel} disabled={this.state.creatingChannel}

View file

@ -1,44 +1,44 @@
import React from "react"; import React from 'react';
import lbry from "lbry"; import lbry from 'lbry';
import lbryuri from "lbryuri"; import lbryuri from 'lbryuri';
import FormField from "component/formField"; import FormField from 'component/formField';
import { Form, FormRow, Submit } from "component/form.js"; import { Form, FormRow, Submit } from 'component/form.js';
import Link from "component/link"; import Link from 'component/link';
import FormFieldPrice from "component/formFieldPrice"; import FormFieldPrice from 'component/formFieldPrice';
import Modal from "modal/modal"; import Modal from 'modal/modal';
import { BusyMessage } from "component/common"; import { BusyMessage } from 'component/common';
import ChannelSection from "./internal/channelSection"; import ChannelSection from './internal/channelSection';
class PublishForm extends React.PureComponent { class PublishForm extends React.PureComponent {
constructor(props) { constructor(props) {
super(props); super(props);
this._requiredFields = ["name", "bid", "meta_title", "tosAgree"]; this._requiredFields = ['name', 'bid', 'meta_title', 'tosAgree'];
this._defaultCopyrightNotice = "All rights reserved."; this._defaultCopyrightNotice = 'All rights reserved.';
this._defaultPaidPrice = 0.01; this._defaultPaidPrice = 0.01;
this.state = { this.state = {
id: null, id: null,
uri: null, uri: null,
rawName: "", rawName: '',
name: "", name: '',
bid: 10, bid: 10,
hasFile: false, hasFile: false,
feeAmount: "", feeAmount: '',
feeCurrency: "LBC", feeCurrency: 'LBC',
channel: "anonymous", channel: 'anonymous',
newChannelName: "@", newChannelName: '@',
newChannelBid: 10, newChannelBid: 10,
meta_title: "", meta_title: '',
meta_thumbnail: "", meta_thumbnail: '',
meta_description: "", meta_description: '',
meta_language: "en", meta_language: 'en',
meta_nsfw: "0", meta_nsfw: '0',
licenseType: "", licenseType: '',
copyrightNotice: this._defaultCopyrightNotice, copyrightNotice: this._defaultCopyrightNotice,
otherLicenseDescription: "", otherLicenseDescription: '',
otherLicenseUrl: "", otherLicenseUrl: '',
tosAgree: false, tosAgree: false,
prefillDone: false, prefillDone: false,
uploadProgress: 0.0, uploadProgress: 0.0,
@ -50,7 +50,7 @@ class PublishForm extends React.PureComponent {
isFee: false, isFee: false,
customUrl: false, customUrl: false,
source: null, source: null,
mode: "publish", mode: 'publish',
}; };
} }
@ -65,7 +65,7 @@ class PublishForm extends React.PureComponent {
const { bid } = this.state; const { bid } = this.state;
if (bid > balance) { if (bid > balance) {
this.handlePublishError({ message: "insufficient funds" }); this.handlePublishError({ message: 'insufficient funds' });
return; return;
} }
@ -74,16 +74,16 @@ class PublishForm extends React.PureComponent {
submitting: true, submitting: true,
}); });
let checkFields = this._requiredFields; const checkFields = this._requiredFields;
if (!this.myClaimExists()) { if (!this.myClaimExists()) {
checkFields.unshift("file"); checkFields.unshift('file');
} }
let missingFieldFound = false; let missingFieldFound = false;
for (let fieldName of checkFields) { for (const fieldName of checkFields) {
const field = this.refs[fieldName]; const field = this.refs[fieldName];
if (field) { if (field) {
if (field.getValue() === "" || field.getValue() === false) { if (field.getValue() === '' || field.getValue() === false) {
field.showRequiredError(); field.showRequiredError();
if (!missingFieldFound) { if (!missingFieldFound) {
field.focus(); field.focus();
@ -102,10 +102,10 @@ class PublishForm extends React.PureComponent {
return; return;
} }
let metadata = {}; const metadata = {};
for (let metaField of ["title", "description", "thumbnail", "language"]) { for (const metaField of ['title', 'description', 'thumbnail', 'language']) {
const value = this.state["meta_" + metaField]; const value = this.state[`meta_${metaField}`];
if (value) { if (value) {
metadata[metaField] = value; metadata[metaField] = value;
} }
@ -115,19 +115,19 @@ class PublishForm extends React.PureComponent {
metadata.licenseUrl = this.getLicenseUrl(); metadata.licenseUrl = this.getLicenseUrl();
metadata.nsfw = !!parseInt(this.state.meta_nsfw); metadata.nsfw = !!parseInt(this.state.meta_nsfw);
var doPublish = () => { const doPublish = () => {
var publishArgs = { const publishArgs = {
name: this.state.name, name: this.state.name,
bid: parseFloat(this.state.bid), bid: parseFloat(this.state.bid),
metadata: metadata, metadata,
...(this.state.channel != "new" && this.state.channel != "anonymous" ...(this.state.channel != 'new' && this.state.channel != 'anonymous'
? { channel_name: this.state.channel } ? { channel_name: this.state.channel }
: {}), : {}),
}; };
const { source } = this.state; const { source } = this.state;
if (this.refs.file.getValue() !== "") { if (this.refs.file.getValue() !== '') {
publishArgs.file_path = this.refs.file.getValue(); publishArgs.file_path = this.refs.file.getValue();
} else if (source) { } else if (source) {
publishArgs.sources = source; publishArgs.sources = source;
@ -145,7 +145,7 @@ class PublishForm extends React.PureComponent {
metadata.fee = { metadata.fee = {
currency: this.state.feeCurrency, currency: this.state.feeCurrency,
amount: parseFloat(this.state.feeAmount), amount: parseFloat(this.state.feeAmount),
address: address, address,
}; };
doPublish(); doPublish();
@ -157,18 +157,18 @@ class PublishForm extends React.PureComponent {
handlePublishStarted() { handlePublishStarted() {
this.setState({ this.setState({
modal: "publishStarted", modal: 'publishStarted',
}); });
} }
handlePublishStartedConfirmed() { handlePublishStartedConfirmed() {
this.props.navigate("/published"); this.props.navigate('/published');
} }
handlePublishError(error) { handlePublishError(error) {
this.setState({ this.setState({
submitting: false, submitting: false,
modal: "error", modal: 'error',
errorMessage: error.message, errorMessage: error.message,
}); });
} }
@ -220,13 +220,11 @@ class PublishForm extends React.PureComponent {
myClaimInfo() { myClaimInfo() {
const { id } = this.state; const { id } = this.state;
return Object.values(this.props.myClaims).find( return Object.values(this.props.myClaims).find(claim => claim.claim_id === id);
claim => claim.claim_id === id
);
} }
handleNameChange(event) { handleNameChange(event) {
var rawName = event.target.value; const rawName = event.target.value;
this.setState({ this.setState({
customUrl: Boolean(rawName.length), customUrl: Boolean(rawName.length),
}); });
@ -237,33 +235,31 @@ class PublishForm extends React.PureComponent {
nameChanged(rawName) { nameChanged(rawName) {
if (!rawName) { if (!rawName) {
this.setState({ this.setState({
rawName: "", rawName: '',
name: "", name: '',
uri: "", uri: '',
prefillDone: false, prefillDone: false,
mode: "publish", mode: 'publish',
}); });
return; return;
} }
if (!lbryuri.isValidName(rawName, false)) { if (!lbryuri.isValidName(rawName, false)) {
this.refs.name.showError( this.refs.name.showError(__('LBRY names must contain only letters, numbers and dashes.'));
__("LBRY names must contain only letters, numbers and dashes.")
);
return; return;
} }
let channel = ""; let channel = '';
if (this.state.channel !== "anonymous") channel = this.state.channel; if (this.state.channel !== 'anonymous') channel = this.state.channel;
const name = rawName.toLowerCase(); const name = rawName.toLowerCase();
const uri = lbryuri.build({ contentName: name, channelName: channel }); const uri = lbryuri.build({ contentName: name, channelName: channel });
this.setState({ this.setState({
rawName: rawName, rawName,
name: name, name,
prefillDone: false, prefillDone: false,
mode: "publish", mode: 'publish',
uri, uri,
}); });
@ -282,26 +278,18 @@ class PublishForm extends React.PureComponent {
const { claim_id, name, channel_name, amount } = claimInfo; const { claim_id, name, channel_name, amount } = claimInfo;
const { source, metadata } = claimInfo.value.stream; const { source, metadata } = claimInfo.value.stream;
const { const { license, licenseUrl, title, thumbnail, description, language, nsfw } = metadata;
license,
licenseUrl,
title,
thumbnail,
description,
language,
nsfw,
} = metadata;
let newState = { const newState = {
id: claim_id, id: claim_id,
channel: channel_name || "anonymous", channel: channel_name || 'anonymous',
bid: amount, bid: amount,
meta_title: title, meta_title: title,
meta_thumbnail: thumbnail, meta_thumbnail: thumbnail,
meta_description: description, meta_description: description,
meta_language: language, meta_language: language,
meta_nsfw: nsfw, meta_nsfw: nsfw,
mode: "edit", mode: 'edit',
prefillDone: true, prefillDone: true,
rawName: name, rawName: name,
name, name,
@ -309,21 +297,18 @@ class PublishForm extends React.PureComponent {
}; };
if (license == this._defaultCopyrightNotice) { if (license == this._defaultCopyrightNotice) {
newState.licenseType = "copyright"; newState.licenseType = 'copyright';
newState.copyrightNotice = this._defaultCopyrightNotice; newState.copyrightNotice = this._defaultCopyrightNotice;
} else { } else {
// If the license URL or description matches one of the drop-down options, use that // If the license URL or description matches one of the drop-down options, use that
let licenseType = "other"; // Will be overridden if we find a match let licenseType = 'other'; // Will be overridden if we find a match
for (let option of this._meta_license.getOptions()) { for (const option of this._meta_license.getOptions()) {
if ( if (option.getAttribute('data-url') === licenseUrl || option.text === license) {
option.getAttribute("data-url") === licenseUrl ||
option.text === license
) {
licenseType = option.value; licenseType = option.value;
} }
} }
if (licenseType == "other") { if (licenseType == 'other') {
newState.otherLicenseDescription = license; newState.otherLicenseDescription = license;
newState.otherLicenseUrl = licenseUrl; newState.otherLicenseUrl = licenseUrl;
} }
@ -349,10 +334,7 @@ class PublishForm extends React.PureComponent {
handleFeePrefChange(feeEnabled) { handleFeePrefChange(feeEnabled) {
this.setState({ this.setState({
isFee: feeEnabled, isFee: feeEnabled,
feeAmount: feeAmount: this.state.feeAmount == '' ? this._defaultPaidPrice : this.state.feeAmount,
this.state.feeAmount == ""
? this._defaultPaidPrice
: this.state.feeAmount,
}); });
} }
@ -363,7 +345,7 @@ class PublishForm extends React.PureComponent {
* more complex logic and the final value is determined at submit time. * more complex logic and the final value is determined at submit time.
*/ */
this.setState({ this.setState({
["meta_" + event.target.name]: event.target.value, [`meta_${event.target.name}`]: event.target.value,
}); });
} }
@ -399,7 +381,7 @@ class PublishForm extends React.PureComponent {
handleChannelChange(channelName) { handleChannelChange(channelName) {
this.setState({ this.setState({
mode: "publish", mode: 'publish',
channel: channelName, channel: channelName,
}); });
const nameChanged = () => this.nameChanged(this.state.rawName); const nameChanged = () => this.nameChanged(this.state.rawName);
@ -414,9 +396,9 @@ class PublishForm extends React.PureComponent {
getLicense() { getLicense() {
switch (this.state.licenseType) { switch (this.state.licenseType) {
case "copyright": case 'copyright':
return this.state.copyrightNotice; return this.state.copyrightNotice;
case "other": case 'other':
return this.state.otherLicenseDescription; return this.state.otherLicenseDescription;
default: default:
return this._meta_license.getSelectedElement().text; return this._meta_license.getSelectedElement().text;
@ -425,12 +407,12 @@ class PublishForm extends React.PureComponent {
getLicenseUrl() { getLicenseUrl() {
switch (this.state.licenseType) { switch (this.state.licenseType) {
case "copyright": case 'copyright':
return ""; return '';
case "other": case 'other':
return this.state.otherLicenseUrl; return this.state.otherLicenseUrl;
default: default:
return this._meta_license.getSelectedElement().getAttribute("data-url"); return this._meta_license.getSelectedElement().getAttribute('data-url');
} }
} }
@ -450,8 +432,8 @@ class PublishForm extends React.PureComponent {
const { mode } = this.state; const { mode } = this.state;
if (this.refs.file.getValue()) { if (this.refs.file.getValue()) {
this.setState({ hasFile: true }); this.setState({ hasFile: true });
if (!this.state.customUrl && mode !== "edit") { if (!this.state.customUrl && mode !== 'edit') {
let fileName = this._getFileName(this.refs.file.getValue()); const fileName = this._getFileName(this.refs.file.getValue());
this.nameChanged(fileName); this.nameChanged(fileName);
} }
} else { } else {
@ -460,11 +442,11 @@ class PublishForm extends React.PureComponent {
} }
_getFileName(fileName) { _getFileName(fileName) {
const path = require("path"); const path = require('path');
const extension = path.extname(fileName); const extension = path.extname(fileName);
fileName = path.basename(fileName, extension); fileName = path.basename(fileName, extension);
fileName = fileName.replace(lbryuri.REGEXP_INVALID_URI, ""); fileName = fileName.replace(lbryuri.REGEXP_INVALID_URI, '');
return fileName; return fileName;
} }
@ -474,23 +456,20 @@ class PublishForm extends React.PureComponent {
const claim = this.claim(); const claim = this.claim();
if (prefillDone) { if (prefillDone) {
return __("Existing claim data was prefilled"); return __('Existing claim data was prefilled');
} }
if (uri && resolvingUris.indexOf(uri) !== -1 && claim === undefined) { if (uri && resolvingUris.indexOf(uri) !== -1 && claim === undefined) {
return __("Checking..."); return __('Checking...');
} else if (!name) { } else if (!name) {
return __("Select a URL for this publish."); return __('Select a URL for this publish.');
} else if (!claim) { } else if (!claim) {
return __("This URL is unused."); return __('This URL is unused.');
} else if (this.myClaimExists() && !prefillDone) { } else if (this.myClaimExists() && !prefillDone) {
return ( return (
<span> <span>
{__("You already have a claim with this name.")}{" "} {__('You already have a claim with this name.')}{' '}
<Link <Link label={__('Edit existing claim')} onClick={() => this.handleEditClaim()} />
label={__("Edit existing claim")}
onClick={() => this.handleEditClaim()}
/>
</span> </span>
); );
} else if (claim) { } else if (claim) {
@ -504,20 +483,18 @@ class PublishForm extends React.PureComponent {
)} )}
</span> </span>
); );
} else {
return (
<span>
{__(
'A deposit of at least "%s" credits is required to win "%s". However, you can still get a permanent URL for any amount.',
topClaimValue,
name
)}
</span>
);
} }
} else { return (
return ""; <span>
{__(
'A deposit of at least "%s" credits is required to win "%s". However, you can still get a permanent URL for any amount.',
topClaimValue,
name
)}
</span>
);
} }
return '';
} }
closeModal() { closeModal() {
@ -529,14 +506,12 @@ class PublishForm extends React.PureComponent {
render() { render() {
const { mode, submitting } = this.state; const { mode, submitting } = this.state;
const lbcInputHelp = __( const lbcInputHelp = __('This LBC remains yours and the deposit can be undone at any time.');
"This LBC remains yours and the deposit can be undone at any time."
);
let submitLabel = !submitting ? __("Publish") : __("Publishing..."); let submitLabel = !submitting ? __('Publish') : __('Publishing...');
if (mode === "edit") { if (mode === 'edit') {
submitLabel = !submitting ? __("Update") : __("Updating..."); submitLabel = !submitting ? __('Update') : __('Updating...');
} }
return ( return (
@ -544,10 +519,8 @@ class PublishForm extends React.PureComponent {
<Form onSubmit={this.handleSubmit.bind(this)}> <Form onSubmit={this.handleSubmit.bind(this)}>
<section className="card"> <section className="card">
<div className="card__title-primary"> <div className="card__title-primary">
<h4>{__("Content")}</h4> <h4>{__('Content')}</h4>
<div className="card__subtitle"> <div className="card__subtitle">{__('What are you publishing?')}</div>
{__("What are you publishing?")}
</div>
</div> </div>
<div className="card__content"> <div className="card__content">
<FormRow <FormRow
@ -571,7 +544,7 @@ class PublishForm extends React.PureComponent {
<div className="card__content"> <div className="card__content">
<FormRow <FormRow
ref="meta_title" ref="meta_title"
label={__("Title")} label={__('Title')}
type="text" type="text"
name="title" name="title"
value={this.state.meta_title} value={this.state.meta_title}
@ -584,7 +557,7 @@ class PublishForm extends React.PureComponent {
<div className="card__content"> <div className="card__content">
<FormRow <FormRow
type="text" type="text"
label={__("Thumbnail URL")} label={__('Thumbnail URL')}
name="thumbnail" name="thumbnail"
value={this.state.meta_thumbnail} value={this.state.meta_thumbnail}
placeholder="http://spee.ch/mylogo" placeholder="http://spee.ch/mylogo"
@ -596,11 +569,11 @@ class PublishForm extends React.PureComponent {
<div className="card__content"> <div className="card__content">
<FormRow <FormRow
type="SimpleMDE" type="SimpleMDE"
label={__("Description")} label={__('Description')}
ref="meta_description" ref="meta_description"
name="description" name="description"
value={this.state.meta_description} value={this.state.meta_description}
placeholder={__("Description of your content")} placeholder={__('Description of your content')}
onChange={text => { onChange={text => {
this.handleDescriptionChanged(text); this.handleDescriptionChanged(text);
}} }}
@ -608,7 +581,7 @@ class PublishForm extends React.PureComponent {
</div> </div>
<div className="card__content"> <div className="card__content">
<FormRow <FormRow
label={__("Language")} label={__('Language')}
type="select" type="select"
value={this.state.meta_language} value={this.state.meta_language}
name="language" name="language"
@ -616,19 +589,19 @@ class PublishForm extends React.PureComponent {
this.handleMetadataChange(event); this.handleMetadataChange(event);
}} }}
> >
<option value="en">{__("English")}</option> <option value="en">{__('English')}</option>
<option value="zh">{__("Chinese")}</option> <option value="zh">{__('Chinese')}</option>
<option value="fr">{__("French")}</option> <option value="fr">{__('French')}</option>
<option value="de">{__("German")}</option> <option value="de">{__('German')}</option>
<option value="jp">{__("Japanese")}</option> <option value="jp">{__('Japanese')}</option>
<option value="ru">{__("Russian")}</option> <option value="ru">{__('Russian')}</option>
<option value="es">{__("Spanish")}</option> <option value="es">{__('Spanish')}</option>
</FormRow> </FormRow>
</div> </div>
<div className="card__content"> <div className="card__content">
<FormRow <FormRow
type="select" type="select"
label={__("Maturity")} label={__('Maturity')}
value={this.state.meta_nsfw} value={this.state.meta_nsfw}
name="nsfw" name="nsfw"
onChange={event => { onChange={event => {
@ -636,8 +609,8 @@ class PublishForm extends React.PureComponent {
}} }}
> >
{/* <option value=""></option> */} {/* <option value=""></option> */}
<option value="0">{__("All Ages")}</option> <option value="0">{__('All Ages')}</option>
<option value="1">{__("Adults Only")}</option> <option value="1">{__('Adults Only')}</option>
</FormRow> </FormRow>
</div> </div>
</div> </div>
@ -646,14 +619,12 @@ class PublishForm extends React.PureComponent {
<section className="card"> <section className="card">
<div className="card__title-primary"> <div className="card__title-primary">
<h4>{__("Price")}</h4> <h4>{__('Price')}</h4>
<div className="card__subtitle"> <div className="card__subtitle">{__('How much does this content cost?')}</div>
{__("How much does this content cost?")}
</div>
</div> </div>
<div className="card__content"> <div className="card__content">
<FormRow <FormRow
label={__("Free")} label={__('Free')}
type="radio" type="radio"
name="isFree" name="isFree"
onChange={() => this.handleFeePrefChange(false)} onChange={() => this.handleFeePrefChange(false)}
@ -662,27 +633,26 @@ class PublishForm extends React.PureComponent {
<FormField <FormField
type="radio" type="radio"
name="isFree" name="isFree"
label={!this.state.isFee ? __("Choose price...") : __("Price ")} label={!this.state.isFee ? __('Choose price...') : __('Price ')}
onChange={() => { onChange={() => {
this.handleFeePrefChange(true); this.handleFeePrefChange(true);
}} }}
checked={this.state.isFee} checked={this.state.isFee}
/> />
<span className={!this.state.isFee ? "hidden" : ""}> <span className={!this.state.isFee ? 'hidden' : ''}>
<FormFieldPrice <FormFieldPrice
min="0" min="0"
defaultValue={{ defaultValue={{
amount: this._defaultPaidPrice, amount: this._defaultPaidPrice,
currency: "LBC", currency: 'LBC',
}} }}
onChange={val => this.handleFeeChange(val)} onChange={val => this.handleFeeChange(val)}
/> />
</span> </span>
{this.state.isFee && {this.state.isFee && this.state.feeCurrency.toUpperCase() != 'LBC' ? (
this.state.feeCurrency.toUpperCase() != "LBC" ? (
<div className="form-field__helper"> <div className="form-field__helper">
{__( {__(
"All content fees are charged in LBC. For non-LBC payment methods, the number of credits charged will be adjusted based on the value of LBRY credits at the time of purchase." 'All content fees are charged in LBC. For non-LBC payment methods, the number of credits charged will be adjusted based on the value of LBRY credits at the time of purchase.'
)} )}
</div> </div>
) : null} ) : null}
@ -690,7 +660,7 @@ class PublishForm extends React.PureComponent {
</section> </section>
<section className="card"> <section className="card">
<div className="card__title-primary"> <div className="card__title-primary">
<h4>{__("License")}</h4> <h4>{__('License')}</h4>
</div> </div>
<div className="card__content"> <div className="card__content">
<FormRow <FormRow
@ -703,61 +673,51 @@ class PublishForm extends React.PureComponent {
this.handleLicenseTypeChange(event); this.handleLicenseTypeChange(event);
}} }}
> >
<option>{__("None")}</option> <option>{__('None')}</option>
<option value="publicDomain">{__("Public Domain")}</option> <option value="publicDomain">{__('Public Domain')}</option>
<option <option
value="cc-by" value="cc-by"
data-url="https://creativecommons.org/licenses/by/4.0/legalcode" data-url="https://creativecommons.org/licenses/by/4.0/legalcode"
> >
{__("Creative Commons Attribution 4.0 International")} {__('Creative Commons Attribution 4.0 International')}
</option> </option>
<option <option
value="cc-by-sa" value="cc-by-sa"
data-url="https://creativecommons.org/licenses/by-sa/4.0/legalcode" data-url="https://creativecommons.org/licenses/by-sa/4.0/legalcode"
> >
{__( {__('Creative Commons Attribution-ShareAlike 4.0 International')}
"Creative Commons Attribution-ShareAlike 4.0 International"
)}
</option> </option>
<option <option
value="cc-by-nd" value="cc-by-nd"
data-url="https://creativecommons.org/licenses/by-nd/4.0/legalcode" data-url="https://creativecommons.org/licenses/by-nd/4.0/legalcode"
> >
{__( {__('Creative Commons Attribution-NoDerivatives 4.0 International')}
"Creative Commons Attribution-NoDerivatives 4.0 International"
)}
</option> </option>
<option <option
value="cc-by-nc" value="cc-by-nc"
data-url="https://creativecommons.org/licenses/by-nc/4.0/legalcode" data-url="https://creativecommons.org/licenses/by-nc/4.0/legalcode"
> >
{__( {__('Creative Commons Attribution-NonCommercial 4.0 International')}
"Creative Commons Attribution-NonCommercial 4.0 International"
)}
</option> </option>
<option <option
value="cc-by-nc-sa" value="cc-by-nc-sa"
data-url="https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode" data-url="https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode"
> >
{__( {__('Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International')}
"Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International"
)}
</option> </option>
<option <option
value="cc-by-nc-nd" value="cc-by-nc-nd"
data-url="https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode" data-url="https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode"
> >
{__( {__('Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International')}
"Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International"
)}
</option> </option>
<option value="copyright">{__("Copyrighted...")}</option> <option value="copyright">{__('Copyrighted...')}</option>
<option value="other">{__("Other...")}</option> <option value="other">{__('Other...')}</option>
</FormRow> </FormRow>
{this.state.licenseType == "copyright" ? ( {this.state.licenseType == 'copyright' ? (
<FormRow <FormRow
label={__("Copyright notice")} label={__('Copyright notice')}
type="text" type="text"
name="copyright-notice" name="copyright-notice"
value={this.state.copyrightNotice} value={this.state.copyrightNotice}
@ -767,9 +727,9 @@ class PublishForm extends React.PureComponent {
/> />
) : null} ) : null}
{this.state.licenseType == "other" ? ( {this.state.licenseType == 'other' ? (
<FormRow <FormRow
label={__("License description")} label={__('License description')}
type="text" type="text"
name="other-license-description" name="other-license-description"
value={this.state.otherLicenseDescription} value={this.state.otherLicenseDescription}
@ -779,9 +739,9 @@ class PublishForm extends React.PureComponent {
/> />
) : null} ) : null}
{this.state.licenseType == "other" ? ( {this.state.licenseType == 'other' ? (
<FormRow <FormRow
label={__("License URL")} label={__('License URL')}
type="text" type="text"
name="other-license-url" name="other-license-url"
value={this.state.otherLicenseUrl} value={this.state.otherLicenseUrl}
@ -801,23 +761,18 @@ class PublishForm extends React.PureComponent {
<section className="card"> <section className="card">
<div className="card__title-primary"> <div className="card__title-primary">
<h4>{__("Content URL")}</h4> <h4>{__('Content URL')}</h4>
<div className="card__subtitle"> <div className="card__subtitle">
{__( {__(
"This is the exact address where people find your content (ex. lbry://myvideo)." 'This is the exact address where people find your content (ex. lbry://myvideo).'
)}{" "} )}{' '}
<Link <Link label={__('Learn more')} href="https://lbry.io/faq/naming" />.
label={__("Learn more")}
href="https://lbry.io/faq/naming"
/>.
</div> </div>
</div> </div>
<div className="card__content"> <div className="card__content">
<FormRow <FormRow
prefix={`lbry://${ prefix={`lbry://${
this.state.channel === "anonymous" this.state.channel === 'anonymous' ? '' : `${this.state.channel}/`
? ""
: `${this.state.channel}/`
}`} }`}
type="text" type="text"
ref="name" ref="name"
@ -835,7 +790,7 @@ class PublishForm extends React.PureComponent {
ref="bid" ref="bid"
type="number" type="number"
step="any" step="any"
label={__("Deposit")} label={__('Deposit')}
postfix="LBC" postfix="LBC"
onChange={event => { onChange={event => {
this.handleBidChange(event); this.handleBidChange(event);
@ -847,23 +802,23 @@ class PublishForm extends React.PureComponent {
/> />
</div> </div>
) : ( ) : (
"" ''
)} )}
</section> </section>
<section className="card"> <section className="card">
<div className="card__title-primary"> <div className="card__title-primary">
<h4>{__("Terms of Service")}</h4> <h4>{__('Terms of Service')}</h4>
</div> </div>
<div className="card__content"> <div className="card__content">
<FormRow <FormRow
ref="tosAgree" ref="tosAgree"
label={ label={
<span> <span>
{__("I agree to the")}{" "} {__('I agree to the')}{' '}
<Link <Link
href="https://www.lbry.io/termsofservice" href="https://www.lbry.io/termsofservice"
label={__("LBRY terms of service")} label={__('LBRY terms of service')}
/> />
</span> </span>
} }
@ -878,36 +833,27 @@ class PublishForm extends React.PureComponent {
<div className="card-series-submit"> <div className="card-series-submit">
<Submit <Submit
label={ label={!this.state.submitting ? __('Publish') : __('Publishing...')}
!this.state.submitting ? __("Publish") : __("Publishing...")
}
disabled={ disabled={
this.props.balance <= 0 || this.props.balance <= 0 ||
this.state.submitting || this.state.submitting ||
(this.state.uri && (this.state.uri && this.props.resolvingUris.indexOf(this.state.uri) !== -1) ||
this.props.resolvingUris.indexOf(this.state.uri) !== -1) || (this.claim() && !this.topClaimIsMine() && this.state.bid <= this.topClaimValue())
(this.claim() &&
!this.topClaimIsMine() &&
this.state.bid <= this.topClaimValue())
} }
/> />
<Link <Link button="cancel" onClick={this.props.back} label={__('Cancel')} />
button="cancel"
onClick={this.props.back}
label={__("Cancel")}
/>
</div> </div>
</Form> </Form>
<Modal <Modal
isOpen={this.state.modal == "publishStarted"} isOpen={this.state.modal == 'publishStarted'}
contentLabel={__("File published")} contentLabel={__('File published')}
onConfirmed={event => { onConfirmed={event => {
this.handlePublishStartedConfirmed(event); this.handlePublishStartedConfirmed(event);
}} }}
> >
<p> <p>
{__("Your file has been published to LBRY at the address")}{" "} {__('Your file has been published to LBRY at the address')}{' '}
<code>{this.state.uri}</code>! <code>{this.state.uri}</code>!
</p> </p>
<p> <p>
@ -917,15 +863,14 @@ class PublishForm extends React.PureComponent {
</p> </p>
</Modal> </Modal>
<Modal <Modal
isOpen={this.state.modal == "error"} isOpen={this.state.modal == 'error'}
contentLabel={__("Error publishing file")} contentLabel={__('Error publishing file')}
onConfirmed={event => { onConfirmed={event => {
this.closeModal(event); this.closeModal(event);
}} }}
> >
{__( {__('The following error occurred when attempting to publish your file')}:{' '}
"The following error occurred when attempting to publish your file" {this.state.errorMessage}
)}: {this.state.errorMessage}
</Modal> </Modal>
</main> </main>
); );

View file

@ -1,16 +1,13 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { import {
makeSelectClaimRewardError, makeSelectClaimRewardError,
makeSelectRewardByType, makeSelectRewardByType,
makeSelectIsRewardClaimPending, makeSelectIsRewardClaimPending,
} from "redux/selectors/rewards"; } from 'redux/selectors/rewards';
import { doNavigate } from "redux/actions/navigation"; import { doNavigate } from 'redux/actions/navigation';
import { import { doClaimRewardType, doClaimRewardClearError } from 'redux/actions/rewards';
doClaimRewardType, import RewardLink from './view';
doClaimRewardClearError,
} from "redux/actions/rewards";
import RewardLink from "./view";
const makeSelect = () => { const makeSelect = () => {
const selectIsPending = makeSelectIsRewardClaimPending(); const selectIsPending = makeSelectIsRewardClaimPending();

View file

@ -1,33 +1,23 @@
import React from "react"; import React from 'react';
import Modal from "modal/modal"; import Modal from 'modal/modal';
import Link from "component/link"; import Link from 'component/link';
const RewardLink = props => { const RewardLink = props => {
const { const { reward, button, claimReward, clearError, errorMessage, label, isPending } = props;
reward,
button,
claimReward,
clearError,
errorMessage,
label,
isPending,
} = props;
return ( return (
<div className="reward-link"> <div className="reward-link">
<Link <Link
button={button} button={button}
disabled={isPending} disabled={isPending}
label={ label={isPending ? __('Claiming...') : label || __('Claim Reward')}
isPending ? __("Claiming...") : label ? label : __("Claim Reward")
}
onClick={() => { onClick={() => {
claimReward(reward); claimReward(reward);
}} }}
/> />
{errorMessage ? ( {errorMessage ? (
<Modal <Modal
isOpen={true} isOpen
contentLabel="Reward Claim Error" contentLabel="Reward Claim Error"
className="error-modal" className="error-modal"
onConfirmed={() => { onConfirmed={() => {
@ -37,7 +27,7 @@ const RewardLink = props => {
{errorMessage} {errorMessage}
</Modal> </Modal>
) : ( ) : (
"" ''
)} )}
</div> </div>
); );

View file

@ -1,7 +1,7 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { selectClaimedRewards } from "redux/selectors/rewards"; import { selectClaimedRewards } from 'redux/selectors/rewards';
import RewardListClaimed from "./view"; import RewardListClaimed from './view';
const select = state => ({ const select = state => ({
rewards: selectClaimedRewards(state), rewards: selectClaimedRewards(state),

View file

@ -1,5 +1,5 @@
import React from "react"; import React from 'react';
import LinkTransaction from "component/linkTransaction"; import LinkTransaction from 'component/linkTransaction';
const RewardListClaimed = props => { const RewardListClaimed = props => {
const { rewards } = props; const { rewards } = props;
@ -17,27 +17,23 @@ const RewardListClaimed = props => {
<table className="table-standard table-stretch"> <table className="table-standard table-stretch">
<thead> <thead>
<tr> <tr>
<th>{__("Title")}</th> <th>{__('Title')}</th>
<th>{__("Amount")}</th> <th>{__('Amount')}</th>
<th>{__("Transaction")}</th> <th>{__('Transaction')}</th>
<th>{__("Date")}</th> <th>{__('Date')}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{rewards.map(reward => { {rewards.map(reward => (
return ( <tr key={reward.id}>
<tr key={reward.id}> <td>{reward.reward_title}</td>
<td>{reward.reward_title}</td> <td>{reward.reward_amount}</td>
<td>{reward.reward_amount}</td> <td>
<td> <LinkTransaction id={reward.transaction_id} />
<LinkTransaction id={reward.transaction_id} /> </td>
</td> <td>{reward.created_at.replace('Z', ' ').replace('T', ' ')}</td>
<td> </tr>
{reward.created_at.replace("Z", " ").replace("T", " ")} ))}
</td>
</tr>
);
})}
</tbody> </tbody>
</table> </table>
</div> </div>

View file

@ -1,7 +1,7 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { selectUnclaimedRewardValue } from "redux/selectors/rewards"; import { selectUnclaimedRewardValue } from 'redux/selectors/rewards';
import RewardSummary from "./view"; import RewardSummary from './view';
const select = state => ({ const select = state => ({
unclaimedRewardAmount: selectUnclaimedRewardValue(state), unclaimedRewardAmount: selectUnclaimedRewardValue(state),

View file

@ -1,7 +1,7 @@
// @flow // @flow
import React from "react"; import React from 'react';
import Link from "component/link"; import Link from 'component/link';
import { CreditAmount } from "component/common"; import { CreditAmount } from 'component/common';
type Props = { type Props = {
unclaimedRewardAmount: number, unclaimedRewardAmount: number,
@ -13,29 +13,20 @@ const RewardSummary = (props: Props) => {
return ( return (
<section className="card"> <section className="card">
<div className="card__title-primary"> <div className="card__title-primary">
<h3>{__("Rewards")}</h3> <h3>{__('Rewards')}</h3>
</div> </div>
<div className="card__content"> <div className="card__content">
{unclaimedRewardAmount > 0 ? ( {unclaimedRewardAmount > 0 ? (
<p> <p>
{__("You have")}{" "} {__('You have')} <CreditAmount amount={unclaimedRewardAmount} precision={8} />{' '}
<CreditAmount amount={unclaimedRewardAmount} precision={8} />{" "} {__('in unclaimed rewards')}.
{__("in unclaimed rewards")}.
</p> </p>
) : ( ) : (
<p> <p>{__('There are no rewards available at this time, please check back later')}.</p>
{__(
"There are no rewards available at this time, please check back later"
)}.
</p>
)} )}
</div> </div>
<div className="card__actions"> <div className="card__actions">
<Link <Link button="primary" navigate="/rewards" label={__('Claim Rewards')} />
button="primary"
navigate="/rewards"
label={__("Claim Rewards")}
/>
</div> </div>
</section> </section>
); );

View file

@ -1,5 +1,5 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import RewardTile from "./view"; import RewardTile from './view';
export default connect(null, null)(RewardTile); export default connect(null, null)(RewardTile);

View file

@ -1,8 +1,8 @@
import React from "react"; import React from 'react';
import { CreditAmount, Icon } from "component/common"; import { CreditAmount, Icon } from 'component/common';
import RewardLink from "component/rewardLink"; import RewardLink from 'component/rewardLink';
import Link from "component/link"; import Link from 'component/link';
import rewards from "rewards"; import rewards from 'rewards';
const RewardTile = props => { const RewardTile = props => {
const { reward } = props; const { reward } = props;
@ -19,12 +19,12 @@ const RewardTile = props => {
<div className="card__content">{reward.reward_description}</div> <div className="card__content">{reward.reward_description}</div>
<div className="card__actions "> <div className="card__actions ">
{reward.reward_type == rewards.TYPE_REFERRAL && ( {reward.reward_type == rewards.TYPE_REFERRAL && (
<Link button="alt" navigate="/invite" label={__("Go To Invites")} /> <Link button="alt" navigate="/invite" label={__('Go To Invites')} />
)} )}
{reward.reward_type !== rewards.TYPE_REFERRAL && {reward.reward_type !== rewards.TYPE_REFERRAL &&
(claimed ? ( (claimed ? (
<span> <span>
<Icon icon="icon-check" /> {__("Reward claimed.")} <Icon icon="icon-check" /> {__('Reward claimed.')}
</span> </span>
) : ( ) : (
<RewardLink button="alt" reward_type={reward.reward_type} /> <RewardLink button="alt" reward_type={reward.reward_type} />

View file

@ -1,10 +1,7 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import Router from "./view.jsx"; import Router from './view.jsx';
import { import { selectCurrentPage, selectCurrentParams } from 'redux/selectors/navigation.js';
selectCurrentPage,
selectCurrentParams,
} from "redux/selectors/navigation.js";
const select = state => ({ const select = state => ({
params: selectCurrentParams(state), params: selectCurrentParams(state),

View file

@ -1,23 +1,23 @@
import React from "react"; import React from 'react';
import SettingsPage from "page/settings"; import SettingsPage from 'page/settings';
import HelpPage from "page/help"; import HelpPage from 'page/help';
import ReportPage from "page/report.js"; import ReportPage from 'page/report.js';
import WalletPage from "page/wallet"; import WalletPage from 'page/wallet';
import GetCreditsPage from "../../page/getCredits"; import GetCreditsPage from '../../page/getCredits';
import SendReceivePage from "page/sendCredits"; import SendReceivePage from 'page/sendCredits';
import ShowPage from "page/show"; import ShowPage from 'page/show';
import PublishPage from "page/publish"; import PublishPage from 'page/publish';
import DiscoverPage from "page/discover"; import DiscoverPage from 'page/discover';
import RewardsPage from "page/rewards"; import RewardsPage from 'page/rewards';
import FileListDownloaded from "page/fileListDownloaded"; import FileListDownloaded from 'page/fileListDownloaded';
import FileListPublished from "page/fileListPublished"; import FileListPublished from 'page/fileListPublished';
import TransactionHistoryPage from "page/transactionHistory"; import TransactionHistoryPage from 'page/transactionHistory';
import ChannelPage from "page/channel"; import ChannelPage from 'page/channel';
import SearchPage from "page/search"; import SearchPage from 'page/search';
import AuthPage from "page/auth"; import AuthPage from 'page/auth';
import InvitePage from "page/invite"; import InvitePage from 'page/invite';
import BackupPage from "page/backup"; import BackupPage from 'page/backup';
import SubscriptionsPage from "page/subscriptions"; import SubscriptionsPage from 'page/subscriptions';
const route = (page, routesMap) => { const route = (page, routesMap) => {
const component = routesMap[page]; const component = routesMap[page];

View file

@ -1,15 +1,15 @@
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { import {
createShapeShift, createShapeShift,
shapeShiftInit, shapeShiftInit,
getCoinStats, getCoinStats,
clearShapeShift, clearShapeShift,
getActiveShift, getActiveShift,
} from "redux/actions/shape_shift"; } from 'redux/actions/shape_shift';
import { doShowSnackBar } from "redux/actions/app"; import { doShowSnackBar } from 'redux/actions/app';
import { selectReceiveAddress } from "redux/selectors/wallet"; import { selectReceiveAddress } from 'redux/selectors/wallet';
import { selectShapeShift } from "redux/selectors/shape_shift"; import { selectShapeShift } from 'redux/selectors/shape_shift';
import ShapeShift from "./view"; import ShapeShift from './view';
const select = state => ({ const select = state => ({
receiveAddress: selectReceiveAddress(state), receiveAddress: selectReceiveAddress(state),

View file

@ -1,11 +1,11 @@
// @flow // @flow
import * as React from "react"; import * as React from 'react';
import QRCode from "qrcode.react"; import QRCode from 'qrcode.react';
import * as statuses from "constants/shape_shift"; import * as statuses from 'constants/shape_shift';
import Address from "component/address"; import Address from 'component/address';
import Link from "component/link"; import Link from 'component/link';
import type { Dispatch } from "redux/actions/shape_shift"; import type { Dispatch } from 'redux/actions/shape_shift';
import ShiftMarketInfo from "./market_info"; import ShiftMarketInfo from './market_info';
type Props = { type Props = {
shiftState: ?string, shiftState: ?string,
@ -78,10 +78,10 @@ class ActiveShapeShift extends React.PureComponent<Props> {
{shiftState === statuses.NO_DEPOSITS && ( {shiftState === statuses.NO_DEPOSITS && (
<div> <div>
<p> <p>
Send up to{" "} Send up to{' '}
<span className="credit-amount--bold"> <span className="credit-amount--bold">
{originCoinDepositMax} {shiftCoinType} {originCoinDepositMax} {shiftCoinType}
</span>{" "} </span>{' '}
to the address below. to the address below.
</p> </p>
<ShiftMarketInfo <ShiftMarketInfo
@ -104,41 +104,32 @@ class ActiveShapeShift extends React.PureComponent<Props> {
{shiftState === statuses.RECEIVED && ( {shiftState === statuses.RECEIVED && (
<div className="card__content--extra-vertical-space"> <div className="card__content--extra-vertical-space">
<p> <p>
{__( {__('ShapeShift has received your payment! Sending the funds to your LBRY wallet.')}
"ShapeShift has received your payment! Sending the funds to your LBRY wallet."
)}
</p> </p>
<span className="help"> <span className="help">{__('This can take a while, especially with BTC.')}</span>
{__("This can take a while, especially with BTC.")}
</span>
</div> </div>
)} )}
{shiftState === statuses.COMPLETE && ( {shiftState === statuses.COMPLETE && (
<div className="card__content--extra-vertical-space"> <div className="card__content--extra-vertical-space">
<p> <p>{__('Transaction complete! You should see the new LBC in your wallet.')}</p>
{__(
"Transaction complete! You should see the new LBC in your wallet."
)}
</p>
</div> </div>
)} )}
<div className="card__actions card__actions--only-vertical"> <div className="card__actions card__actions--only-vertical">
<Link <Link
button={shiftState === statuses.COMPLETE ? "primary" : "alt"} button={shiftState === statuses.COMPLETE ? 'primary' : 'alt'}
onClick={clearShapeShift} onClick={clearShapeShift}
label={ label={
shiftState === statuses.COMPLETE || shiftState === statuses.COMPLETE || shiftState === statuses.RECEIVED
shiftState === statuses.RECEIVED ? __('Done')
? __("Done") : __('Cancel')
: __("Cancel")
} }
/> />
{shiftOrderId && ( {shiftOrderId && (
<span className="shapeshift__link"> <span className="shapeshift__link">
<Link <Link
button="text" button="text"
label={__("View the status on Shapeshift.io")} label={__('View the status on Shapeshift.io')}
href={`https://shapeshift.io/#/status/${shiftOrderId}`} href={`https://shapeshift.io/#/status/${shiftOrderId}`}
/> />
</span> </span>
@ -147,8 +138,8 @@ class ActiveShapeShift extends React.PureComponent<Props> {
shiftReturnAddress && ( shiftReturnAddress && (
<div className="shapeshift__actions-help"> <div className="shapeshift__actions-help">
<span className="help"> <span className="help">
If the transaction doesn't go through, ShapeShift will return If the transaction doesn't go through, ShapeShift will return your {shiftCoinType}{' '}
your {shiftCoinType} back to {shiftReturnAddress} back to {shiftReturnAddress}
</span> </span>
</div> </div>
)} )}

View file

@ -1,9 +1,9 @@
import React from "react"; import React from 'react';
import Link from "component/link"; import Link from 'component/link';
import { getExampleAddress } from "util/shape_shift"; import { getExampleAddress } from 'util/shape_shift';
import { Submit, FormRow } from "component/form"; import { Submit, FormRow } from 'component/form';
import type { ShapeShiftFormValues, Dispatch } from "redux/actions/shape_shift"; import type { ShapeShiftFormValues, Dispatch } from 'redux/actions/shape_shift';
import ShiftMarketInfo from "./market_info"; import ShiftMarketInfo from './market_info';
type ShapeShiftFormErrors = { type ShapeShiftFormErrors = {
returnAddress?: string, returnAddress?: string,
@ -50,7 +50,7 @@ export default (props: Props) => {
return ( return (
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<div className="form-field"> <div className="form-field">
<span>{__("Exchange")} </span> <span>{__('Exchange')} </span>
<select <select
className="form-field__input form-field__input-select" className="form-field__input form-field__input-select"
name="originCoin" name="originCoin"
@ -65,7 +65,7 @@ export default (props: Props) => {
</option> </option>
))} ))}
</select> </select>
<span> {__("for LBC")}</span> <span> {__('for LBC')}</span>
<div className="shapeshift__tx-info"> <div className="shapeshift__tx-info">
{!updating && {!updating &&
originCoinDepositMax && ( originCoinDepositMax && (
@ -84,7 +84,7 @@ export default (props: Props) => {
type="text" type="text"
name="returnAddress" name="returnAddress"
placeholder={getExampleAddress(originCoin)} placeholder={getExampleAddress(originCoin)}
label={__("Return address")} label={__('Return address')}
onChange={handleChange} onChange={handleChange}
onBlur={handleBlur} onBlur={handleBlur}
value={values.returnAddress} value={values.returnAddress}
@ -93,14 +93,13 @@ export default (props: Props) => {
/> />
<span className="help"> <span className="help">
<span> <span>
({__("optional but recommended")}) {__("We will return your")}{" "} ({__('optional but recommended')}) {__('We will return your')} {originCoin}{' '}
{originCoin}{" "}
{__("to this address if the transaction doesn't go through.")} {__("to this address if the transaction doesn't go through.")}
</span> </span>
</span> </span>
<div className="card__actions card__actions--only-vertical"> <div className="card__actions card__actions--only-vertical">
<Submit <Submit
label={__("Begin Conversion")} label={__('Begin Conversion')}
disabled={isSubmitting || !!Object.keys(errors).length} disabled={isSubmitting || !!Object.keys(errors).length}
/> />
</div> </div>

View file

@ -1,5 +1,5 @@
// @flow // @flow
import React from "react"; import React from 'react';
type Props = { type Props = {
shapeShiftRate: ?number, shapeShiftRate: ?number,
@ -21,13 +21,13 @@ export default (props: Props) => {
return ( return (
<div> <div>
<span className="help"> <span className="help">
{__("Receive")} {shapeShiftRate} LBC {__('Receive')} {shapeShiftRate} LBC
{" / "} {' / '}
{"1"} {originCoin} {__("less")} {originCoinDepositFee} LBC {__("fee")}. {'1'} {originCoin} {__('less')} {originCoinDepositFee} LBC {__('fee')}.
<br /> <br />
{__("Exchange max")}: {originCoinDepositMax} {originCoin} {__('Exchange max')}: {originCoinDepositMax} {originCoin}
<br /> <br />
{__("Exchange min")}: {originCoinDepositMin} {originCoin} {__('Exchange min')}: {originCoinDepositMin} {originCoin}
</span> </span>
</div> </div>
); );

View file

@ -1,18 +1,18 @@
// @flow // @flow
import * as React from "react"; import * as React from 'react';
import { shell } from "electron"; import { shell } from 'electron';
import { Formik } from "formik"; import { Formik } from 'formik';
import classnames from "classnames"; import classnames from 'classnames';
import * as statuses from "constants/shape_shift"; import * as statuses from 'constants/shape_shift';
import { validateShapeShiftForm } from "util/shape_shift"; import { validateShapeShiftForm } from 'util/shape_shift';
import Link from "component/link"; import Link from 'component/link';
import Spinner from "component/common/spinner"; import Spinner from 'component/common/spinner';
import { BusyMessage } from "component/common"; import { BusyMessage } from 'component/common';
import ShapeShiftForm from "./internal/form"; import ShapeShiftForm from './internal/form';
import ActiveShapeShift from "./internal/active-shift"; import ActiveShapeShift from './internal/active-shift';
import type { ShapeShiftState } from "redux/reducers/shape_shift"; import type { ShapeShiftState } from 'redux/reducers/shape_shift';
import type { Dispatch, ShapeShiftFormValues } from "redux/actions/shape_shift"; import type { Dispatch, ShapeShiftFormValues } from 'redux/actions/shape_shift';
type Props = { type Props = {
shapeShift: ShapeShiftState, shapeShift: ShapeShiftState,
@ -27,10 +27,7 @@ type Props = {
class ShapeShift extends React.PureComponent<Props> { class ShapeShift extends React.PureComponent<Props> {
componentDidMount() { componentDidMount() {
const { const { shapeShiftInit, shapeShift: { hasActiveShift, shiftSupportedCoins } } = this.props;
shapeShiftInit,
shapeShift: { hasActiveShift, shiftSupportedCoins },
} = this.props;
if (!hasActiveShift && !shiftSupportedCoins.length) { if (!hasActiveShift && !shiftSupportedCoins.length) {
// calls shapeshift to see list of supported coins for shifting // calls shapeshift to see list of supported coins for shifting
@ -70,8 +67,8 @@ class ShapeShift extends React.PureComponent<Props> {
const initialFormValues: ShapeShiftFormValues = { const initialFormValues: ShapeShiftFormValues = {
receiveAddress, receiveAddress,
originCoin: "BTC", originCoin: 'BTC',
returnAddress: "", returnAddress: '',
}; };
return ( return (
@ -80,19 +77,17 @@ class ShapeShift extends React.PureComponent<Props> {
// if the markup below changes for the initial render (form.jsx) there will be content jumping // if the markup below changes for the initial render (form.jsx) there will be content jumping
// the styling in shapeshift.scss will need to be updated to the correct min-height // the styling in shapeshift.scss will need to be updated to the correct min-height
<section <section
className={classnames("card shapeshift__wrapper", { className={classnames('card shapeshift__wrapper', {
"shapeshift__initial-wrapper": loading, 'shapeshift__initial-wrapper': loading,
})} })}
> >
<div className="card__title-primary"> <div className="card__title-primary">
<h3>{__("Convert Crypto to LBC")}</h3> <h3>{__('Convert Crypto to LBC')}</h3>
<p className="help"> <p className="help">
{__("Powered by ShapeShift. Read our FAQ")}{" "} {__('Powered by ShapeShift. Read our FAQ')}{' '}
<Link href="https://lbry.io/faq/shapeshift">{__("here")}</Link>. <Link href="https://lbry.io/faq/shapeshift">{__('here')}</Link>.
{hasActiveShift && {hasActiveShift &&
shiftState !== "complete" && ( shiftState !== 'complete' && <span>{__('This will update automatically.')}</span>}
<span>{__("This will update automatically.")}</span>
)}
</p> </p>
</div> </div>

View file

@ -1,8 +1,8 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doRemoveSnackBarSnack } from "redux/actions/app"; import { doRemoveSnackBarSnack } from 'redux/actions/app';
import { selectSnackBarSnacks } from "redux/selectors/app"; import { selectSnackBarSnacks } from 'redux/selectors/app';
import SnackBar from "./view"; import SnackBar from './view';
const perform = dispatch => ({ const perform = dispatch => ({
removeSnack: () => dispatch(doRemoveSnackBarSnack()), removeSnack: () => dispatch(doRemoveSnackBarSnack()),

View file

@ -1,5 +1,5 @@
import React from "react"; import React from 'react';
import Link from "component/link"; import Link from 'component/link';
class SnackBar extends React.PureComponent { class SnackBar extends React.PureComponent {
constructor(props) { constructor(props) {
@ -13,7 +13,7 @@ class SnackBar extends React.PureComponent {
const { snacks, removeSnack } = this.props; const { snacks, removeSnack } = this.props;
if (!snacks.length) { if (!snacks.length) {
this._hideTimeout = null; //should be unmounting anyway, but be safe? this._hideTimeout = null; // should be unmounting anyway, but be safe?
return null; return null;
} }
@ -32,11 +32,7 @@ class SnackBar extends React.PureComponent {
{message} {message}
{linkText && {linkText &&
linkTarget && ( linkTarget && (
<Link <Link navigate={linkTarget} className="snack-bar__action" label={linkText} />
navigate={linkTarget}
className="snack-bar__action"
label={linkText}
/>
)} )}
</div> </div>
); );

View file

@ -1,12 +1,9 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { import { selectCurrentModal, selectDaemonVersionMatched } from 'redux/selectors/app';
selectCurrentModal, import { doCheckDaemonVersion } from 'redux/actions/app';
selectDaemonVersionMatched, import SplashScreen from './view';
} from "redux/selectors/app";
import { doCheckDaemonVersion } from "redux/actions/app";
import SplashScreen from "./view";
const select = state => ({ const select = state => ({
modal: selectCurrentModal(state), modal: selectCurrentModal(state),

View file

@ -1,11 +1,11 @@
import React from "react"; import React from 'react';
import PropTypes from "prop-types"; import PropTypes from 'prop-types';
import lbry from "lbry.js"; import lbry from 'lbry.js';
import LoadScreen from "../load_screen.js"; import LoadScreen from '../load_screen.js';
import ModalIncompatibleDaemon from "modal/modalIncompatibleDaemon"; import ModalIncompatibleDaemon from 'modal/modalIncompatibleDaemon';
import ModalUpgrade from "modal/modalUpgrade"; import ModalUpgrade from 'modal/modalUpgrade';
import ModalDownloading from "modal/modalDownloading"; import ModalDownloading from 'modal/modalDownloading';
import * as modals from "constants/modal_types"; import * as modals from 'constants/modal_types';
export class SplashScreen extends React.PureComponent { export class SplashScreen extends React.PureComponent {
static propTypes = { static propTypes = {
@ -17,8 +17,8 @@ export class SplashScreen extends React.PureComponent {
super(props); super(props);
this.state = { this.state = {
details: __("Starting daemon"), details: __('Starting daemon'),
message: __("Connecting"), message: __('Connecting'),
isRunning: false, isRunning: false,
isLagging: false, isLagging: false,
}; };
@ -32,19 +32,19 @@ export class SplashScreen extends React.PureComponent {
_updateStatusCallback(status) { _updateStatusCallback(status) {
const startupStatus = status.startup_status; const startupStatus = status.startup_status;
if (startupStatus.code == "started") { if (startupStatus.code == 'started') {
// Wait until we are able to resolve a name before declaring // Wait until we are able to resolve a name before declaring
// that we are done. // that we are done.
// TODO: This is a hack, and the logic should live in the daemon // TODO: This is a hack, and the logic should live in the daemon
// to give us a better sense of when we are actually started // to give us a better sense of when we are actually started
this.setState({ this.setState({
message: __("Testing Network"), message: __('Testing Network'),
details: __("Waiting for name resolution"), details: __('Waiting for name resolution'),
isLagging: false, isLagging: false,
isRunning: true, isRunning: true,
}); });
lbry.resolve({ uri: "lbry://one" }).then(() => { lbry.resolve({ uri: 'lbry://one' }).then(() => {
// Only leave the load screen if the daemon version matched; // Only leave the load screen if the daemon version matched;
// otherwise we'll notify the user at the end of the load screen. // otherwise we'll notify the user at the end of the load screen.
@ -54,24 +54,18 @@ export class SplashScreen extends React.PureComponent {
}); });
return; return;
} }
if ( if (status.blockchain_status && status.blockchain_status.blocks_behind > 0) {
status.blockchain_status &&
status.blockchain_status.blocks_behind > 0
) {
const format = const format =
status.blockchain_status.blocks_behind == 1 status.blockchain_status.blocks_behind == 1 ? '%s block behind' : '%s blocks behind';
? "%s block behind"
: "%s blocks behind";
this.setState({ this.setState({
message: __("Blockchain Sync"), message: __('Blockchain Sync'),
details: __(format, status.blockchain_status.blocks_behind), details: __(format, status.blockchain_status.blocks_behind),
isLagging: startupStatus.is_lagging, isLagging: startupStatus.is_lagging,
}); });
} else { } else {
this.setState({ this.setState({
message: __("Network Loading"), message: __('Network Loading'),
details: details: startupStatus.message + (startupStatus.is_lagging ? '' : '...'),
startupStatus.message + (startupStatus.is_lagging ? "" : "..."),
isLagging: startupStatus.is_lagging, isLagging: startupStatus.is_lagging,
}); });
} }
@ -90,9 +84,9 @@ export class SplashScreen extends React.PureComponent {
.catch(() => { .catch(() => {
this.setState({ this.setState({
isLagging: true, isLagging: true,
message: __("Connection Failure"), message: __('Connection Failure'),
details: __( details: __(
"Try closing all LBRY processes and starting again. If this still happens, your anti-virus software or firewall may be preventing LBRY from connecting. Contact hello@lbry.io if you think this is a software bug." 'Try closing all LBRY processes and starting again. If this still happens, your anti-virus software or firewall may be preventing LBRY from connecting. Contact hello@lbry.io if you think this is a software bug.'
), ),
}); });
}); });
@ -104,19 +98,13 @@ export class SplashScreen extends React.PureComponent {
return ( return (
<div> <div>
<LoadScreen <LoadScreen message={message} details={details} isWarning={isLagging} />
message={message}
details={details}
isWarning={isLagging}
/>
{/* Temp hack: don't show any modals on splash screen daemon is running; {/* Temp hack: don't show any modals on splash screen daemon is running;
daemon doesn't let you quit during startup, so the "Quit" buttons daemon doesn't let you quit during startup, so the "Quit" buttons
in the modals won't work. */} in the modals won't work. */}
{modal == "incompatibleDaemon" && {modal == 'incompatibleDaemon' && isRunning && <ModalIncompatibleDaemon />}
isRunning && <ModalIncompatibleDaemon />}
{modal == modals.UPGRADE && isRunning && <ModalUpgrade />} {modal == modals.UPGRADE && isRunning && <ModalUpgrade />}
{modal == modals.DOWNLOADING && {modal == modals.DOWNLOADING && isRunning && <ModalDownloading />}
isRunning && <ModalDownloading />}
</div> </div>
); );
} }

View file

@ -1,11 +1,8 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { import { selectCurrentPage, selectHeaderLinks } from 'redux/selectors/navigation';
selectCurrentPage, import { doNavigate } from 'redux/actions/navigation';
selectHeaderLinks, import SubHeader from './view';
} from "redux/selectors/navigation";
import { doNavigate } from "redux/actions/navigation";
import SubHeader from "./view";
const select = (state, props) => ({ const select = (state, props) => ({
currentPage: selectCurrentPage(state), currentPage: selectCurrentPage(state),

View file

@ -1,20 +1,18 @@
import React from "react"; import React from 'react';
import Link from "component/link"; import Link from 'component/link';
import classnames from "classnames"; import classnames from 'classnames';
const SubHeader = props => { const SubHeader = props => {
const { subLinks, currentPage, navigate, fullWidth, smallMargin } = props; const { subLinks, currentPage, navigate, fullWidth, smallMargin } = props;
const links = []; const links = [];
for (let link of Object.keys(subLinks)) { for (const link of Object.keys(subLinks)) {
links.push( links.push(
<Link <Link
onClick={event => navigate(`/${link}`, event)} onClick={event => navigate(`/${link}`, event)}
key={link} key={link}
className={ className={link == currentPage ? 'sub-header-selected' : 'sub-header-unselected'}
link == currentPage ? "sub-header-selected" : "sub-header-unselected"
}
> >
{subLinks[link]} {subLinks[link]}
</Link> </Link>
@ -23,9 +21,9 @@ const SubHeader = props => {
return ( return (
<nav <nav
className={classnames("sub-header", { className={classnames('sub-header', {
"sub-header--full-width": fullWidth, 'sub-header--full-width': fullWidth,
"sub-header--small-margin": smallMargin, 'sub-header--small-margin': smallMargin,
})} })}
> >
{links} {links}

View file

@ -1,11 +1,8 @@
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { import { doChannelSubscribe, doChannelUnsubscribe } from 'redux/actions/subscriptions';
doChannelSubscribe, import { selectSubscriptions } from 'redux/selectors/subscriptions';
doChannelUnsubscribe,
} from "redux/actions/subscriptions";
import { selectSubscriptions } from "redux/selectors/subscriptions";
import SubscribeButton from "./view"; import SubscribeButton from './view';
const select = (state, props) => ({ const select = (state, props) => ({
subscriptions: selectSubscriptions(state), subscriptions: selectSubscriptions(state),

View file

@ -1,36 +1,27 @@
import React from "react"; import React from 'react';
import Link from "component/link"; import Link from 'component/link';
export default ({
channelName,
uri,
subscriptions,
doChannelSubscribe,
doChannelUnsubscribe
}) => {
export default ({ channelName, uri, subscriptions, doChannelSubscribe, doChannelUnsubscribe }) => {
const isSubscribed = const isSubscribed =
subscriptions subscriptions.map(subscription => subscription.channelName).indexOf(channelName) !== -1;
.map(subscription => subscription.channelName)
.indexOf(channelName) !== -1;
const subscriptionHandler = isSubscribed const subscriptionHandler = isSubscribed ? doChannelUnsubscribe : doChannelSubscribe;
? doChannelUnsubscribe
: doChannelSubscribe;
const subscriptionLabel = isSubscribed ? __("Unsubscribe") : __("Subscribe"); const subscriptionLabel = isSubscribed ? __('Unsubscribe') : __('Subscribe');
return channelName && uri ? ( return channelName && uri ? (
<div className="card__actions"> <div className="card__actions">
<Link <Link
iconRight={isSubscribed ? "" : "at"} iconRight={isSubscribed ? '' : 'at'}
button={isSubscribed ? "alt" : "primary"} button={isSubscribed ? 'alt' : 'primary'}
label={subscriptionLabel} label={subscriptionLabel}
onClick={() => subscriptionHandler({ onClick={() =>
channelName, subscriptionHandler({
uri, channelName,
})} uri,
})
}
/> />
</div> </div>
) : null; ) : null;
} };

View file

@ -1,7 +1,7 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { selectThemePath } from "redux/selectors/settings.js"; import { selectThemePath } from 'redux/selectors/settings.js';
import Theme from "./view"; import Theme from './view';
const select = state => ({ const select = state => ({
themePath: selectThemePath(state), themePath: selectThemePath(state),

View file

@ -1,4 +1,4 @@
import React from "react"; import React from 'react';
const Theme = props => { const Theme = props => {
const { themePath } = props; const { themePath } = props;
@ -7,14 +7,7 @@ const Theme = props => {
return null; return null;
} }
return ( return <link href={themePath} rel="stylesheet" type="text/css" media="screen,print" />;
<link
href={themePath}
rel="stylesheet"
type="text/css"
media="screen,print"
/>
);
}; };
export default Theme; export default Theme;

View file

@ -1,5 +1,5 @@
import React from "react"; import React from 'react';
import PropTypes from "prop-types"; import PropTypes from 'prop-types';
export class ToolTip extends React.PureComponent { export class ToolTip extends React.PureComponent {
static propTypes = { static propTypes = {
@ -29,7 +29,7 @@ export class ToolTip extends React.PureComponent {
render() { render() {
return ( return (
<span className={`tooltip ${this.props.className || ""}`}> <span className={`tooltip ${this.props.className || ''}`}>
<a <a
className="tooltip__link" className="tooltip__link"
onClick={() => { onClick={() => {
@ -39,7 +39,7 @@ export class ToolTip extends React.PureComponent {
{this.props.label} {this.props.label}
</a> </a>
<div <div
className={`tooltip__body ${this.state.showTooltip ? "" : " hidden"}`} className={`tooltip__body ${this.state.showTooltip ? '' : ' hidden'}`}
onMouseOut={() => { onMouseOut={() => {
this.handleTooltipMouseOut(); this.handleTooltipMouseOut();
}} }}

View file

@ -1,10 +1,10 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doNavigate } from "redux/actions/navigation"; import { doNavigate } from 'redux/actions/navigation';
import { doOpenModal } from "redux/actions/app"; import { doOpenModal } from 'redux/actions/app';
import { selectClaimedRewardsByTransactionId } from "redux/selectors/rewards"; import { selectClaimedRewardsByTransactionId } from 'redux/selectors/rewards';
import { selectAllMyClaimsByOutpoint } from "redux/selectors/claims"; import { selectAllMyClaimsByOutpoint } from 'redux/selectors/claims';
import TransactionList from "./view"; import TransactionList from './view';
const select = state => ({ const select = state => ({
rewards: selectClaimedRewardsByTransactionId(state), rewards: selectClaimedRewardsByTransactionId(state),

View file

@ -1,10 +1,10 @@
import React from "react"; import React from 'react';
import LinkTransaction from "component/linkTransaction"; import LinkTransaction from 'component/linkTransaction';
import { CreditAmount } from "component/common"; import { CreditAmount } from 'component/common';
import DateTime from "component/dateTime"; import DateTime from 'component/dateTime';
import Link from "component/link"; import Link from 'component/link';
import lbryuri from "lbryuri"; import lbryuri from 'lbryuri';
import * as txnTypes from "constants/transaction_types"; import * as txnTypes from 'constants/transaction_types';
class TransactionListItem extends React.PureComponent { class TransactionListItem extends React.PureComponent {
abandonClaim() { abandonClaim() {
@ -16,21 +16,10 @@ class TransactionListItem extends React.PureComponent {
getLink(type) { getLink(type) {
if (type == txnTypes.TIP) { if (type == txnTypes.TIP) {
return ( return (
<Link <Link onClick={this.abandonClaim.bind(this)} icon="icon-unlock-alt" title={__('Unlock')} />
onClick={this.abandonClaim.bind(this)}
icon="icon-unlock-alt"
title={__("Unlock")}
/>
);
} else {
return (
<Link
onClick={this.abandonClaim.bind(this)}
icon="icon-trash"
title={__("Revoke")}
/>
); );
} }
return <Link onClick={this.abandonClaim.bind(this)} icon="icon-trash" title={__('Revoke')} />;
} }
capitalize(string) { capitalize(string) {
@ -51,9 +40,9 @@ class TransactionListItem extends React.PureComponent {
} = transaction; } = transaction;
const dateFormat = { const dateFormat = {
month: "short", month: 'short',
day: "numeric", day: 'numeric',
year: "numeric", year: 'numeric',
}; };
return ( return (
@ -61,41 +50,25 @@ class TransactionListItem extends React.PureComponent {
<td> <td>
{date ? ( {date ? (
<div> <div>
<DateTime <DateTime date={date} show={DateTime.SHOW_DATE} formatOptions={dateFormat} />
date={date}
show={DateTime.SHOW_DATE}
formatOptions={dateFormat}
/>
<div className="meta"> <div className="meta">
<DateTime date={date} show={DateTime.SHOW_TIME} /> <DateTime date={date} show={DateTime.SHOW_TIME} />
</div> </div>
</div> </div>
) : ( ) : (
<span className="empty">{__("Pending")}</span> <span className="empty">{__('Pending')}</span>
)} )}
</td> </td>
<td> <td>
<CreditAmount <CreditAmount amount={amount} look="plain" label={false} showPlus precision={8} />
amount={amount}
look="plain"
label={false}
showPlus={true}
precision={8}
/>
<br /> <br />
{fee != 0 && ( {fee != 0 && <CreditAmount amount={fee} look="fee" label={false} precision={8} />}
<CreditAmount amount={fee} look="fee" label={false} precision={8} />
)}
</td> </td>
<td> <td>
{this.capitalize(type)} {isRevokeable && this.getLink(type)} {this.capitalize(type)} {isRevokeable && this.getLink(type)}
</td> </td>
<td> <td>
{reward && ( {reward && <Link navigate="/rewards">{__('Reward: %s', reward.reward_title)}</Link>}
<Link navigate="/rewards">
{__("Reward: %s", reward.reward_title)}
</Link>
)}
{name && {name &&
claimId && ( claimId && (
<Link <Link

View file

@ -1,9 +1,9 @@
import React from "react"; import React from 'react';
import TransactionListItem from "./internal/TransactionListItem"; import TransactionListItem from './internal/TransactionListItem';
import FormField from "component/formField"; import FormField from 'component/formField';
import Link from "component/link"; import Link from 'component/link';
import * as icons from "constants/icons"; import * as icons from 'constants/icons';
import * as modals from "constants/modal_types"; import * as modals from 'constants/modal_types';
class TransactionList extends React.PureComponent { class TransactionList extends React.PureComponent {
constructor(props) { constructor(props) {
@ -39,48 +39,38 @@ class TransactionList extends React.PureComponent {
render() { render() {
const { emptyMessage, rewards, transactions } = this.props; const { emptyMessage, rewards, transactions } = this.props;
let transactionList = transactions.filter( const transactionList = transactions.filter(this.filterTransaction.bind(this));
this.filterTransaction.bind(this)
);
return ( return (
<div> <div>
{(transactionList.length || this.state.filter) && ( {(transactionList.length || this.state.filter) && (
<span className="sort-section"> <span className="sort-section">
{__("Filter")}{" "} {__('Filter')}{' '}
<FormField <FormField type="select" onChange={this.handleFilterChanged.bind(this)}>
type="select" <option value="">{__('All')}</option>
onChange={this.handleFilterChanged.bind(this)} <option value="spend">{__('Spends')}</option>
> <option value="receive">{__('Receives')}</option>
<option value="">{__("All")}</option> <option value="publish">{__('Publishes')}</option>
<option value="spend">{__("Spends")}</option> <option value="channel">{__('Channels')}</option>
<option value="receive">{__("Receives")}</option> <option value="tip">{__('Tips')}</option>
<option value="publish">{__("Publishes")}</option> <option value="support">{__('Supports')}</option>
<option value="channel">{__("Channels")}</option> <option value="update">{__('Updates')}</option>
<option value="tip">{__("Tips")}</option> </FormField>{' '}
<option value="support">{__("Supports")}</option> <Link href="https://lbry.io/faq/transaction-types" icon={icons.HELP_CIRCLE} />
<option value="update">{__("Updates")}</option>
</FormField>{" "}
<Link
href="https://lbry.io/faq/transaction-types"
icon={icons.HELP_CIRCLE}
/>
</span> </span>
)} )}
{!transactionList.length && ( {!transactionList.length && (
<div className="empty"> <div className="empty">{emptyMessage || __('No transactions to list.')}</div>
{emptyMessage || __("No transactions to list.")}
</div>
)} )}
{Boolean(transactionList.length) && ( {Boolean(transactionList.length) && (
<table className="table-standard table-transactions table-stretch"> <table className="table-standard table-transactions table-stretch">
<thead> <thead>
<tr> <tr>
<th>{__("Date")}</th> <th>{__('Date')}</th>
<th>{__("Amount (Fee)")}</th> <th>{__('Amount (Fee)')}</th>
<th>{__("Type")} </th> <th>{__('Type')} </th>
<th>{__("Details")} </th> <th>{__('Details')} </th>
<th>{__("Transaction")}</th> <th>{__('Transaction')}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View file

@ -1,14 +1,14 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doFetchTransactions } from "redux/actions/wallet"; import { doFetchTransactions } from 'redux/actions/wallet';
import { import {
selectBalance, selectBalance,
selectRecentTransactions, selectRecentTransactions,
selectHasTransactions, selectHasTransactions,
selectIsFetchingTransactions, selectIsFetchingTransactions,
} from "redux/selectors/wallet"; } from 'redux/selectors/wallet';
import TransactionListRecent from "./view"; import TransactionListRecent from './view';
const select = state => ({ const select = state => ({
fetchingTransactions: selectIsFetchingTransactions(state), fetchingTransactions: selectIsFetchingTransactions(state),

View file

@ -1,8 +1,8 @@
import React from "react"; import React from 'react';
import { BusyMessage } from "component/common"; import { BusyMessage } from 'component/common';
import Link from "component/link"; import Link from 'component/link';
import TransactionList from "component/transactionList"; import TransactionList from 'component/transactionList';
import * as icons from "constants/icons"; import * as icons from 'constants/icons';
class TransactionListRecent extends React.PureComponent { class TransactionListRecent extends React.PureComponent {
componentWillMount() { componentWillMount() {
@ -15,16 +15,14 @@ class TransactionListRecent extends React.PureComponent {
return ( return (
<section className="card"> <section className="card">
<div className="card__title-primary"> <div className="card__title-primary">
<h3>{__("Recent Transactions")}</h3> <h3>{__('Recent Transactions')}</h3>
</div> </div>
<div className="card__content"> <div className="card__content">
{fetchingTransactions && ( {fetchingTransactions && <BusyMessage message={__('Loading transactions')} />}
<BusyMessage message={__("Loading transactions")} />
)}
{!fetchingTransactions && ( {!fetchingTransactions && (
<TransactionList <TransactionList
transactions={transactions} transactions={transactions}
emptyMessage={__("You have no recent transactions.")} emptyMessage={__('You have no recent transactions.')}
/> />
)} )}
</div> </div>
@ -32,7 +30,7 @@ class TransactionListRecent extends React.PureComponent {
<div className="card__actions card__actions--bottom"> <div className="card__actions card__actions--bottom">
<Link <Link
navigate="/history" navigate="/history"
label={__("Full History")} label={__('Full History')}
icon={icons.HISTORY} icon={icons.HISTORY}
className="no-underline" className="no-underline"
button="text" button="text"

View file

@ -1,5 +1,5 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import TruncatedMarkdown from "./view"; import TruncatedMarkdown from './view';
export default connect()(TruncatedMarkdown); export default connect()(TruncatedMarkdown);

View file

@ -1,7 +1,7 @@
import React from "react"; import React from 'react';
import PropTypes from "prop-types"; import PropTypes from 'prop-types';
import ReactMarkdown from "react-markdown"; import ReactMarkdown from 'react-markdown';
import ReactDOMServer from "react-dom/server"; import ReactDOMServer from 'react-dom/server';
class TruncatedMarkdown extends React.PureComponent { class TruncatedMarkdown extends React.PureComponent {
static propTypes = { static propTypes = {
@ -14,24 +14,21 @@ class TruncatedMarkdown extends React.PureComponent {
transformMarkdown(text) { transformMarkdown(text) {
// render markdown to html string then trim html tag // render markdown to html string then trim html tag
let htmlString = ReactDOMServer.renderToStaticMarkup( const htmlString = ReactDOMServer.renderToStaticMarkup(
<ReactMarkdown source={this.props.children} /> <ReactMarkdown source={this.props.children} />
); );
var txt = document.createElement("textarea"); const txt = document.createElement('textarea');
txt.innerHTML = htmlString; txt.innerHTML = htmlString;
return txt.value.replace(/<(?:.|\n)*?>/gm, ""); return txt.value.replace(/<(?:.|\n)*?>/gm, '');
} }
render() { render() {
let content = const content =
this.props.children && typeof this.props.children === "string" this.props.children && typeof this.props.children === 'string'
? this.transformMarkdown(this.props.children) ? this.transformMarkdown(this.props.children)
: this.props.children; : this.props.children;
return ( return (
<span <span className="truncated-text" style={{ WebkitLineClamp: this.props.lines }}>
className="truncated-text"
style={{ WebkitLineClamp: this.props.lines }}
>
{content} {content}
</span> </span>
); );

View file

@ -1,10 +1,10 @@
import React from "react"; import React from 'react';
import lbryuri from "lbryuri"; import lbryuri from 'lbryuri';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doResolveUri } from "redux/actions/content"; import { doResolveUri } from 'redux/actions/content';
import { makeSelectIsUriResolving } from "redux/selectors/content"; import { makeSelectIsUriResolving } from 'redux/selectors/content';
import { makeSelectClaimForUri } from "redux/selectors/claims"; import { makeSelectClaimForUri } from 'redux/selectors/claims';
import UriIndicator from "./view"; import UriIndicator from './view';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),

View file

@ -1,8 +1,8 @@
import React from "react"; import React from 'react';
import { Icon } from "component/common"; import { Icon } from 'component/common';
import Link from "component/link"; import Link from 'component/link';
import lbryuri from "lbryuri"; import lbryuri from 'lbryuri';
import classnames from "classnames"; import classnames from 'classnames';
class UriIndicator extends React.PureComponent { class UriIndicator extends React.PureComponent {
componentWillMount() { componentWillMount() {
@ -39,9 +39,7 @@ class UriIndicator extends React.PureComponent {
value, value,
} = claim; } = claim;
const channelClaimId = const channelClaimId =
value && value && value.publisherSignature && value.publisherSignature.certificateId;
value.publisherSignature &&
value.publisherSignature.certificateId;
if (!hasSignature || !channelName) { if (!hasSignature || !channelName) {
return <span className="empty">Anonymous</span>; return <span className="empty">Anonymous</span>;
@ -50,34 +48,30 @@ class UriIndicator extends React.PureComponent {
let icon, channelLink, modifier; let icon, channelLink, modifier;
if (signatureIsValid) { if (signatureIsValid) {
modifier = "valid"; modifier = 'valid';
channelLink = link channelLink = link ? lbryuri.build({ channelName, claimId: channelClaimId }, false) : false;
? lbryuri.build({ channelName, claimId: channelClaimId }, false)
: false;
} else { } else {
icon = "icon-times-circle"; icon = 'icon-times-circle';
modifier = "invalid"; modifier = 'invalid';
} }
const inner = ( const inner = (
<span> <span>
<span <span
className={classnames("channel-name", { className={classnames('channel-name', {
"channel-name--small": smallCard, 'channel-name--small': smallCard,
"button-text no-underline": link, 'button-text no-underline': link,
})} })}
> >
{channelName} {channelName}
</span>{" "} </span>{' '}
{!signatureIsValid ? ( {!signatureIsValid ? (
<Icon <Icon
icon={icon} icon={icon}
className={`channel-indicator__icon channel-indicator__icon--${ className={`channel-indicator__icon channel-indicator__icon--${modifier}`}
modifier
}`}
/> />
) : ( ) : (
"" ''
)} )}
</span> </span>
); );
@ -87,11 +81,7 @@ class UriIndicator extends React.PureComponent {
} }
return ( return (
<Link <Link navigate="/show" navigateParams={{ uri: channelLink }} className="no-underline">
navigate="/show"
navigateParams={{ uri: channelLink }}
className="no-underline"
>
{inner} {inner}
</Link> </Link>
); );

View file

@ -1,13 +1,10 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doUserEmailNew, doUserInviteNew } from "redux/actions/user"; import { doUserEmailNew, doUserInviteNew } from 'redux/actions/user';
import { import { selectEmailNewIsPending, selectEmailNewErrorMessage } from 'redux/selectors/user';
selectEmailNewIsPending, import UserEmailNew from './view';
selectEmailNewErrorMessage, import rewards from 'rewards';
} from "redux/selectors/user"; import { makeSelectRewardAmountByType } from 'redux/selectors/rewards';
import UserEmailNew from "./view";
import rewards from "rewards";
import { makeSelectRewardAmountByType } from "redux/selectors/rewards";
const select = state => ({ const select = state => ({
isPending: selectEmailNewIsPending(state), isPending: selectEmailNewIsPending(state),

View file

@ -1,13 +1,13 @@
import React from "react"; import React from 'react';
import { CreditAmount } from "component/common"; import { CreditAmount } from 'component/common';
import { Form, FormRow, Submit } from "component/form.js"; import { Form, FormRow, Submit } from 'component/form.js';
class UserEmailNew extends React.PureComponent { class UserEmailNew extends React.PureComponent {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
email: "", email: '',
}; };
} }
@ -28,18 +28,15 @@ class UserEmailNew extends React.PureComponent {
return ( return (
<div> <div>
<p> <p>
Let us know your email and you'll receive{" "} Let us know your email and you'll receive{' '}
<CreditAmount amount={rewardAmount} label="LBC" />, the blockchain <CreditAmount amount={rewardAmount} label="LBC" />, the blockchain token used by LBRY.
token used by LBRY.
</p> </p>
<p> <p>
{__( {__(
"We'll also let you know about LBRY updates, security issues, and great new content." "We'll also let you know about LBRY updates, security issues, and great new content."
)} )}
</p> </p>
<p> <p>{__("We'll never sell your email, and you can unsubscribe at any time.")}</p>
{__("We'll never sell your email, and you can unsubscribe at any time.")}
</p>
<Form onSubmit={this.handleSubmit.bind(this)}> <Form onSubmit={this.handleSubmit.bind(this)}>
<FormRow <FormRow
type="text" type="text"

View file

@ -1,14 +1,14 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doUserEmailVerify } from "redux/actions/user"; import { doUserEmailVerify } from 'redux/actions/user';
import { import {
selectEmailVerifyIsPending, selectEmailVerifyIsPending,
selectEmailToVerify, selectEmailToVerify,
selectEmailVerifyErrorMessage, selectEmailVerifyErrorMessage,
} from "redux/selectors/user"; } from 'redux/selectors/user';
import UserEmailVerify from "./view"; import UserEmailVerify from './view';
import rewards from "rewards"; import rewards from 'rewards';
import { makeSelectRewardAmountByType } from "redux/selectors/rewards"; import { makeSelectRewardAmountByType } from 'redux/selectors/rewards';
const select = state => ({ const select = state => ({
isPending: selectEmailVerifyIsPending(state), isPending: selectEmailVerifyIsPending(state),

View file

@ -1,14 +1,14 @@
import React from "react"; import React from 'react';
import Link from "component/link"; import Link from 'component/link';
import { CreditAmount } from "component/common"; import { CreditAmount } from 'component/common';
import { Form, FormRow, Submit } from "component/form.js"; import { Form, FormRow, Submit } from 'component/form.js';
class UserEmailVerify extends React.PureComponent { class UserEmailVerify extends React.PureComponent {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
code: "", code: '',
}; };
} }
@ -24,19 +24,13 @@ class UserEmailVerify extends React.PureComponent {
} }
render() { render() {
const { const { cancelButton, errorMessage, email, isPending, rewardAmount } = this.props;
cancelButton,
errorMessage,
email,
isPending,
rewardAmount,
} = this.props;
return ( return (
<Form onSubmit={this.handleSubmit.bind(this)}> <Form onSubmit={this.handleSubmit.bind(this)}>
<p>Please enter the verification code emailed to {email}.</p> <p>Please enter the verification code emailed to {email}.</p>
<FormRow <FormRow
type="text" type="text"
label={__("Verification Code")} label={__('Verification Code')}
name="code" name="code"
value={this.state.code} value={this.state.code}
onChange={event => { onChange={event => {
@ -47,14 +41,13 @@ class UserEmailVerify extends React.PureComponent {
{/* render help separately so it always shows */} {/* render help separately so it always shows */}
<div className="form-field__helper"> <div className="form-field__helper">
<p> <p>
{__("Email")}{" "} {__('Email')} <Link href="mailto:help@lbry.io" label="help@lbry.io" /> or join our{' '}
<Link href="mailto:help@lbry.io" label="help@lbry.io" /> or join our{" "} <Link href="https://chat.lbry.io" label="chat" />{' '}
<Link href="https://chat.lbry.io" label="chat" />{" "} {__('if you encounter any trouble with your code.')}
{__("if you encounter any trouble with your code.")}
</p> </p>
</div> </div>
<div className="form-row-submit"> <div className="form-row-submit">
<Submit label={__("Verify")} disabled={isPending} /> <Submit label={__('Verify')} disabled={isPending} />
{cancelButton} {cancelButton}
</div> </div>
</Form> </Form>

View file

@ -1,14 +1,14 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doNavigate } from "redux/actions/navigation"; import { doNavigate } from 'redux/actions/navigation';
import { doUserIdentityVerify } from "redux/actions/user"; import { doUserIdentityVerify } from 'redux/actions/user';
import rewards from "rewards"; import rewards from 'rewards';
import { makeSelectRewardByType } from "redux/selectors/rewards"; import { makeSelectRewardByType } from 'redux/selectors/rewards';
import { import {
selectIdentityVerifyIsPending, selectIdentityVerifyIsPending,
selectIdentityVerifyErrorMessage, selectIdentityVerifyErrorMessage,
} from "redux/selectors/user"; } from 'redux/selectors/user';
import UserVerify from "./view"; import UserVerify from './view';
const select = (state, props) => { const select = (state, props) => {
const selectReward = makeSelectRewardByType(); const selectReward = makeSelectRewardByType();

View file

@ -1,14 +1,14 @@
import React from "react"; import React from 'react';
import Link from "component/link"; import Link from 'component/link';
import CardVerify from "component/cardVerify"; import CardVerify from 'component/cardVerify';
import lbryio from "lbryio.js"; import lbryio from 'lbryio.js';
class UserVerify extends React.PureComponent { class UserVerify extends React.PureComponent {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
code: "", code: '',
}; };
} }
@ -28,33 +28,27 @@ class UserVerify extends React.PureComponent {
<div> <div>
<section className="card card--form"> <section className="card card--form">
<div className="card__title-primary"> <div className="card__title-primary">
<h1>{__("Final Human Proof")}</h1> <h1>{__('Final Human Proof')}</h1>
</div> </div>
<div className="card__content"> <div className="card__content">
<p> <p>
Finally, please complete <strong>one and only one</strong> of the Finally, please complete <strong>one and only one</strong> of the options below.
options below.
</p> </p>
</div> </div>
</section> </section>
<section className="card card--form"> <section className="card card--form">
<div className="card__title-primary"> <div className="card__title-primary">
<h3>{__("1) Proof via Credit")}</h3> <h3>{__('1) Proof via Credit')}</h3>
</div> </div>
<div className="card__content"> <div className="card__content">
{__( {`${__(
"If you have a valid credit or debit card, you can use it to instantly prove your humanity." 'If you have a valid credit or debit card, you can use it to instantly prove your humanity.'
) + )} ${__('There is no charge at all for this, now or in the future.')} `}
" " +
__("There is no charge at all for this, now or in the future.") +
" "}
</div> </div>
<div className="card__actions"> <div className="card__actions">
{errorMessage && ( {errorMessage && <p className="form-field__error">{errorMessage}</p>}
<p className="form-field__error">{errorMessage}</p>
)}
<CardVerify <CardVerify
label={__("Perform Card Verification")} label={__('Perform Card Verification')}
disabled={isPending} disabled={isPending}
token={this.onToken.bind(this)} token={this.onToken.bind(this)}
stripeKey={lbryio.getStripeToken()} stripeKey={lbryio.getStripeToken()}
@ -62,32 +56,27 @@ class UserVerify extends React.PureComponent {
</div> </div>
<div className="card__content"> <div className="card__content">
<div className="meta"> <div className="meta">
{__( {__('A $1 authorization may temporarily appear with your provider.')}{' '}
"A $1 authorization may temporarily appear with your provider."
)}{" "}
<Link <Link
href="https://lbry.io/faq/identity-requirements" href="https://lbry.io/faq/identity-requirements"
label={__("Read more about why we do this.")} label={__('Read more about why we do this.')}
/> />
</div> </div>
</div> </div>
</section> </section>
<section className="card card--form"> <section className="card card--form">
<div className="card__title-primary"> <div className="card__title-primary">
<h3>{__("2) Proof via YouTube")}</h3> <h3>{__('2) Proof via YouTube')}</h3>
</div> </div>
<div className="card__content"> <div className="card__content">
<p> <p>
{__( {__(
"If you have a YouTube account with subscribers and views, you can sync your account and content to be granted instant verification." 'If you have a YouTube account with subscribers and views, you can sync your account and content to be granted instant verification.'
)} )}
</p> </p>
<p> <p>
{__("Some account minimums apply.")}{" "} {__('Some account minimums apply.')}{' '}
<Link <Link href="https://lbry.io/faq/youtube" label={__('Read more.')} />
href="https://lbry.io/faq/youtube"
label={__("Read more.")}
/>
</p> </p>
</div> </div>
<div className="card__actions"> <div className="card__actions">
@ -95,30 +84,29 @@ class UserVerify extends React.PureComponent {
href="https://api.lbry.io/yt/connect" href="https://api.lbry.io/yt/connect"
button="alt" button="alt"
icon="icon-youtube" icon="icon-youtube"
label={__("YouTube Account Sync")} label={__('YouTube Account Sync')}
/> />
</div> </div>
<div className="card__content"> <div className="card__content">
<div className="meta"> <div className="meta">
This will not automatically refresh after approval. Once you have This will not automatically refresh after approval. Once you have synced your account,
synced your account, just navigate away or click{" "} just navigate away or click <Link navigate="/rewards" label="here" />.
<Link navigate="/rewards" label="here" />.
</div> </div>
</div> </div>
</section> </section>
<section className="card card--form"> <section className="card card--form">
<div className="card__title-primary"> <div className="card__title-primary">
<h3>{__("3) Proof via Chat")}</h3> <h3>{__('3) Proof via Chat')}</h3>
</div> </div>
<div className="card__content"> <div className="card__content">
<p> <p>
{__( {__(
"A moderator capable of approving you is typically available in the #verification channel of our chat room." 'A moderator capable of approving you is typically available in the #verification channel of our chat room.'
)} )}
</p> </p>
<p> <p>
{__( {__(
"This process will likely involve providing proof of a stable and established online or real-life identity." 'This process will likely involve providing proof of a stable and established online or real-life identity.'
)} )}
</p> </p>
</div> </div>
@ -127,27 +115,23 @@ class UserVerify extends React.PureComponent {
href="https://chat.lbry.io" href="https://chat.lbry.io"
button="alt" button="alt"
icon="icon-comments" icon="icon-comments"
label={__("Join LBRY Chat")} label={__('Join LBRY Chat')}
/> />
</div> </div>
</section> </section>
<section className="card card--form"> <section className="card card--form">
<div className="card__title-primary"> <div className="card__title-primary">
<h5>{__("Or, Skip It Entirely")}</h5> <h5>{__('Or, Skip It Entirely')}</h5>
</div> </div>
<div className="card__content"> <div className="card__content">
<p className="meta"> <p className="meta">
{__( {__(
"You can continue without this step, but you will not be eligible to earn rewards." 'You can continue without this step, but you will not be eligible to earn rewards.'
)} )}
</p> </p>
</div> </div>
<div className="card__actions"> <div className="card__actions">
<Link <Link onClick={() => navigate('/discover')} button="alt" label={__('Skip Rewards')} />
onClick={() => navigate("/discover")}
button="alt"
label={__("Skip Rewards")}
/>
</div> </div>
</section> </section>
</div> </div>

View file

@ -1,21 +1,18 @@
import React from "react"; import React from 'react';
import { connect } from "react-redux"; import { connect } from 'react-redux';
import { doChangeVolume } from "redux/actions/app"; import { doChangeVolume } from 'redux/actions/app';
import { selectVolume } from "redux/selectors/app"; import { selectVolume } from 'redux/selectors/app';
import { doPlayUri, doSetPlayingUri } from "redux/actions/content"; import { doPlayUri, doSetPlayingUri } from 'redux/actions/content';
import { import { makeSelectMetadataForUri, makeSelectContentTypeForUri } from 'redux/selectors/claims';
makeSelectMetadataForUri,
makeSelectContentTypeForUri,
} from "redux/selectors/claims";
import { import {
makeSelectFileInfoForUri, makeSelectFileInfoForUri,
makeSelectLoadingForUri, makeSelectLoadingForUri,
makeSelectDownloadingForUri, makeSelectDownloadingForUri,
} from "redux/selectors/file_info"; } from 'redux/selectors/file_info';
import { makeSelectCostInfoForUri } from "redux/selectors/cost_info"; import { makeSelectCostInfoForUri } from 'redux/selectors/cost_info';
import { selectShowNsfw } from "redux/selectors/settings"; import { selectShowNsfw } from 'redux/selectors/settings';
import Video from "./view"; import Video from './view';
import { selectPlayingUri } from "redux/selectors/content"; import { selectPlayingUri } from 'redux/selectors/content';
const select = (state, props) => ({ const select = (state, props) => ({
costInfo: makeSelectCostInfoForUri(props.uri)(state), costInfo: makeSelectCostInfoForUri(props.uri)(state),

View file

@ -1,5 +1,5 @@
import React from "react"; import React from 'react';
import Spinner from "component/common/spinner"; import Spinner from 'component/common/spinner';
const LoadingScreen = ({ status, spinner = true }) => ( const LoadingScreen = ({ status, spinner = true }) => (
<div className="video__loading-screen"> <div className="video__loading-screen">

View file

@ -1,21 +1,18 @@
import React from "react"; import React from 'react';
import Link from "component/link"; import Link from 'component/link';
class VideoPlayButton extends React.PureComponent { class VideoPlayButton extends React.PureComponent {
componentDidMount() { componentDidMount() {
this.keyDownListener = this.onKeyDown.bind(this); this.keyDownListener = this.onKeyDown.bind(this);
document.addEventListener("keydown", this.keyDownListener); document.addEventListener('keydown', this.keyDownListener);
} }
componentWillUnmount() { componentWillUnmount() {
document.removeEventListener("keydown", this.keyDownListener); document.removeEventListener('keydown', this.keyDownListener);
} }
onKeyDown(event) { onKeyDown(event) {
if ( if (event.target.tagName.toLowerCase() !== 'input' && event.code === 'Space') {
"input" !== event.target.tagName.toLowerCase() &&
"Space" === event.code
) {
event.preventDefault(); event.preventDefault();
this.watch(); this.watch();
} }
@ -37,16 +34,13 @@ class VideoPlayButton extends React.PureComponent {
*/ */
const disabled = isLoading || fileInfo === undefined; const disabled = isLoading || fileInfo === undefined;
const icon = const icon = ['audio', 'video'].indexOf(mediaType) !== -1 ? 'icon-play' : 'icon-folder-o';
["audio", "video"].indexOf(mediaType) !== -1
? "icon-play"
: "icon-folder-o";
return ( return (
<Link <Link
button={button ? button : null} button={button || null}
disabled={disabled} disabled={disabled}
label={label ? label : ""} label={label || ''}
className="video__play-button" className="video__play-button"
icon={icon} icon={icon}
onClick={() => this.watch()} onClick={() => this.watch()}

View file

@ -1,12 +1,13 @@
const { remote } = require("electron"); const { remote } = require('electron');
import React from "react";
import { Thumbnail } from "component/common"; import React from 'react';
import player from "render-media"; import { Thumbnail } from 'component/common';
import fs from "fs"; import player from 'render-media';
import LoadingScreen from "./loading-screen"; import fs from 'fs';
import LoadingScreen from './loading-screen';
class VideoPlayer extends React.PureComponent { class VideoPlayer extends React.PureComponent {
static MP3_CONTENT_TYPES = ["audio/mpeg3", "audio/mpeg"]; static MP3_CONTENT_TYPES = ['audio/mpeg3', 'audio/mpeg'];
constructor(props) { constructor(props) {
super(props); super(props);
@ -22,13 +23,7 @@ class VideoPlayer extends React.PureComponent {
componentDidMount() { componentDidMount() {
const container = this.refs.media; const container = this.refs.media;
const { const { contentType, downloadPath, mediaType, changeVolume, volume } = this.props;
contentType,
downloadPath,
mediaType,
changeVolume,
volume,
} = this.props;
const loadedMetadata = e => { const loadedMetadata = e => {
this.setState({ hasMetadata: true, startedPlaying: true }); this.setState({ hasMetadata: true, startedPlaying: true });
this.refs.media.children[0].play(); this.refs.media.children[0].play();
@ -39,10 +34,8 @@ class VideoPlayer extends React.PureComponent {
// Handle fullscreen change for the Windows platform // Handle fullscreen change for the Windows platform
const win32FullScreenChange = e => { const win32FullScreenChange = e => {
const win = remote.BrowserWindow.getFocusedWindow(); const win = remote.BrowserWindow.getFocusedWindow();
if ("win32" === process.platform) { if (process.platform === 'win32') {
win.setMenu( win.setMenu(document.webkitIsFullScreen ? null : remote.Menu.getApplicationMenu());
document.webkitIsFullScreen ? null : remote.Menu.getApplicationMenu()
);
} }
}; };
@ -58,22 +51,15 @@ class VideoPlayer extends React.PureComponent {
); );
} }
document.addEventListener("keydown", this.togglePlayListener); document.addEventListener('keydown', this.togglePlayListener);
const mediaElement = this.refs.media.children[0]; const mediaElement = this.refs.media.children[0];
if (mediaElement) { if (mediaElement) {
mediaElement.addEventListener("click", this.togglePlayListener); mediaElement.addEventListener('click', this.togglePlayListener);
mediaElement.addEventListener( mediaElement.addEventListener('loadedmetadata', loadedMetadata.bind(this), {
"loadedmetadata", once: true,
loadedMetadata.bind(this), });
{ mediaElement.addEventListener('webkitfullscreenchange', win32FullScreenChange.bind(this));
once: true, mediaElement.addEventListener('volumechange', () => {
}
);
mediaElement.addEventListener(
"webkitfullscreenchange",
win32FullScreenChange.bind(this)
);
mediaElement.addEventListener("volumechange", () => {
changeVolume(mediaElement.volume); changeVolume(mediaElement.volume);
}); });
mediaElement.volume = volume; mediaElement.volume = volume;
@ -81,10 +67,10 @@ class VideoPlayer extends React.PureComponent {
} }
componentWillUnmount() { componentWillUnmount() {
document.removeEventListener("keydown", this.togglePlayListener); document.removeEventListener('keydown', this.togglePlayListener);
const mediaElement = this.refs.media.children[0]; const mediaElement = this.refs.media.children[0];
if (mediaElement) { if (mediaElement) {
mediaElement.removeEventListener("click", this.togglePlayListener); mediaElement.removeEventListener('click', this.togglePlayListener);
} }
} }
@ -95,7 +81,7 @@ class VideoPlayer extends React.PureComponent {
// clear the container // clear the container
const { downloadPath } = this.props; const { downloadPath } = this.props;
const audio = document.createElement("audio"); const audio = document.createElement('audio');
audio.autoplay = autoplay; audio.autoplay = autoplay;
audio.controls = true; audio.controls = true;
audio.src = downloadPath; audio.src = downloadPath;
@ -105,8 +91,8 @@ class VideoPlayer extends React.PureComponent {
togglePlay(event) { togglePlay(event) {
// ignore all events except click and spacebar keydown, or input events in a form control // ignore all events except click and spacebar keydown, or input events in a form control
if ( if (
"keydown" === event.type && event.type === 'keydown' &&
("Space" !== event.code || "input" === event.target.tagName.toLowerCase()) (event.code !== 'Space' || event.target.tagName.toLowerCase() === 'input')
) { ) {
return; return;
} }
@ -144,37 +130,33 @@ class VideoPlayer extends React.PureComponent {
return { return {
name: filename, name: filename,
createReadStream: opts => { createReadStream: opts => fs.createReadStream(downloadPath, opts),
return fs.createReadStream(downloadPath, opts);
},
}; };
} }
playableType() { playableType() {
const { mediaType } = this.props; const { mediaType } = this.props;
return ["audio", "video"].indexOf(mediaType) !== -1; return ['audio', 'video'].indexOf(mediaType) !== -1;
} }
render() { render() {
const { mediaType, poster } = this.props; const { mediaType, poster } = this.props;
const { hasMetadata, unplayable } = this.state; const { hasMetadata, unplayable } = this.state;
const noMetadataMessage = "Waiting for metadata."; const noMetadataMessage = 'Waiting for metadata.';
const unplayableMessage = "Sorry, looks like we can't play this file."; const unplayableMessage = "Sorry, looks like we can't play this file.";
const needsMetadata = this.playableType(); const needsMetadata = this.playableType();
return ( return (
<div> <div>
{["audio", "application"].indexOf(mediaType) !== -1 && {['audio', 'application'].indexOf(mediaType) !== -1 &&
(!this.playableType() || hasMetadata) && (!this.playableType() || hasMetadata) &&
!unplayable && <Thumbnail src={poster} className="video-embedded" />} !unplayable && <Thumbnail src={poster} className="video-embedded" />}
{this.playableType() && {this.playableType() &&
!hasMetadata && !hasMetadata &&
!unplayable && <LoadingScreen status={noMetadataMessage} />} !unplayable && <LoadingScreen status={noMetadataMessage} />}
{unplayable && ( {unplayable && <LoadingScreen status={unplayableMessage} spinner={false} />}
<LoadingScreen status={unplayableMessage} spinner={false} />
)}
<div ref="media" className="media" /> <div ref="media" className="media" />
</div> </div>
); );

Some files were not shown because too many files have changed in this diff Show more