Setup ESLint and Prettier and apply changes to sources #891
183 changed files with 2122 additions and 2883 deletions
|
@ -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,
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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 => ({});
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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
|
)}
|
||||||
)}
|
/>
|
||||||
/>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
|
@ -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 => ({
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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 }}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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 />
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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 => ({});
|
||||||
|
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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} />
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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} />;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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)),
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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} />;
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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} />
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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()),
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
}
|
};
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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()}
|
||||||
|
|
|
@ -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
Loading…
Reference in a new issue