Basics of conversion to ES6 classes

This commit is contained in:
Alex Liebowitz 2017-05-17 04:10:25 -04:00
parent 3fa4d0dfe7
commit 3e35d44978
19 changed files with 684 additions and 522 deletions

View file

@ -9,23 +9,28 @@ import {CreditAmount, Address} from "../component/common.js";
import {getLocal, getSession, setSession, setLocal} from '../utils.js'; import {getLocal, getSession, setSession, setLocal} from '../utils.js';
const SubmitEmailStage = React.createClass({ class SubmitEmailStage extends React.Component {
getInitialState: function() { constructor(props) {
return { super(props);
this.state = {
rewardType: null, rewardType: null,
email: '', email: '',
submitting: false submitting: false
}; };
}, }
handleEmailChanged: function(event) {
handleEmailChanged(event) {
this.setState({ this.setState({
email: event.target.value, email: event.target.value,
}); });
}, }
onEmailSaved: function(email) {
onEmailSaved(email) {
this.props.setStage("confirm", { email: email }) this.props.setStage("confirm", { email: email })
}, }
handleSubmit: function(event) {
handleSubmit(event) {
event.preventDefault(); event.preventDefault();
this.setState({ this.setState({
@ -42,8 +47,9 @@ const SubmitEmailStage = React.createClass({
} }
this.setState({ submitting: false }); this.setState({ submitting: false });
}); });
}, }
render: function() {
render() {
return ( return (
<section> <section>
<form onSubmit={this.handleSubmit}> <form onSubmit={this.handleSubmit}>
@ -57,23 +63,27 @@ const SubmitEmailStage = React.createClass({
</section> </section>
); );
} }
}); }
const ConfirmEmailStage = React.createClass({ class ConfirmEmailStage extends React.Component {
getInitialState: function() { constructor(props) {
return { super(props);
this.state = {
rewardType: null, rewardType: null,
code: '', code: '',
submitting: false, submitting: false,
errorMessage: null, errorMessage: null,
}; };
}, }
handleCodeChanged: function(event) {
handleCodeChanged(event) {
this.setState({ this.setState({
code: event.target.value, code: event.target.value,
}); });
}, }
handleSubmit: function(event) {
handleSubmit(event) {
event.preventDefault(); event.preventDefault();
this.setState({ this.setState({
submitting: true, submitting: true,
@ -93,8 +103,9 @@ const ConfirmEmailStage = React.createClass({
onSubmitError(new Error("Your email is still not verified.")) //shouldn't happen? onSubmitError(new Error("Your email is still not verified.")) //shouldn't happen?
} }
}, onSubmitError); }, onSubmitError);
}, }
render: function() {
render() {
return ( return (
<section> <section>
<form onSubmit={this.handleSubmit}> <form onSubmit={this.handleSubmit}>
@ -111,25 +122,26 @@ const ConfirmEmailStage = React.createClass({
</section> </section>
); );
} }
}); }
const WelcomeStage = React.createClass({ class WelcomeStage extends React.Component {
propTypes: { constructor(props) {
endAuth: React.PropTypes.func, super(props);
},
getInitialState: function() { this.state = {
return {
hasReward: false, hasReward: false,
rewardAmount: null, rewardAmount: null,
};
} }
},
onRewardClaim: function(reward) { onRewardClaim(reward) {
this.setState({ this.setState({
hasReward: true, hasReward: true,
rewardAmount: reward.amount rewardAmount: reward.amount
}) })
}, }
render: function() {
render() {
return ( return (
!this.state.hasReward ? !this.state.hasReward ?
<Modal type="custom" isOpen={true} contentLabel="Welcome to LBRY" {...this.props}> <Modal type="custom" isOpen={true} contentLabel="Welcome to LBRY" {...this.props}>
@ -156,11 +168,13 @@ const WelcomeStage = React.createClass({
</Modal> </Modal>
); );
} }
}); }
WelcomeStage.propTypes = {
endAuth: React.PropTypes.func,
};
class ErrorStage extends React.Component {
const ErrorStage = React.createClass({ render() {
render: function() {
return ( return (
<section> <section>
<p>An error was encountered that we cannot continue from.</p> <p>An error was encountered that we cannot continue from.</p>
@ -170,29 +184,32 @@ const ErrorStage = React.createClass({
</section> </section>
); );
} }
}); }
const PendingStage = React.createClass({ class PendingStage extends React.Component {
render: function() { render() {
return ( return (
<section> <section>
<p>Preparing for first access <span className="busy-indicator"></span></p> <p>Preparing for first access <span className="busy-indicator"></span></p>
</section> </section>
); );
} }
}); }
const CodeRequiredStage = React.createClass({ class CodeRequiredStage extends React.Component {
_balanceSubscribeId: null, constructor(props) {
getInitialState: function() { super(props);
return {
this._balanceSubscribeId = nullp
this.state = {
balance: 0, balance: 0,
address: getLocal('wallet_address') address: getLocal('wallet_address')
};
} }
},
componentWillMount: function() { componentWillMount() {
this._balanceSubscribeId = lbry.balanceSubscribe((balance) => { this._balanceSubscribeId = lbry.balanceSubscribe((balance) => {
this.setState({ this.setState({
balance: balance balance: balance
@ -205,13 +222,15 @@ const CodeRequiredStage = React.createClass({
this.setState({ address: address }); this.setState({ address: address });
}); });
} }
}, }
componentWillUnmount: function() {
componentWillUnmount() {
if (this._balanceSubscribeId) { if (this._balanceSubscribeId) {
lbry.balanceUnsubscribe(this._balanceSubscribeId) lbry.balanceUnsubscribe(this._balanceSubscribeId)
} }
}, }
render: function() {
render() {
const disabled = this.state.balance < 1; const disabled = this.state.balance < 1;
return ( return (
<div> <div>
@ -234,31 +253,36 @@ const CodeRequiredStage = React.createClass({
</div> </div>
); );
} }
}); }
export const AuthOverlay = React.createClass({ export class AuthOverlay extends React.Component {
_stages: { constructor(props) {
super(props);
this._stages = {
pending: PendingStage, pending: PendingStage,
error: ErrorStage, error: ErrorStage,
nocode: CodeRequiredStage, nocode: CodeRequiredStage,
email: SubmitEmailStage, email: SubmitEmailStage,
confirm: ConfirmEmailStage, confirm: ConfirmEmailStage,
welcome: WelcomeStage welcome: WelcomeStage
}, }
getInitialState: function() {
return { this.state = {
stage: "pending", stage: "pending",
stageProps: {} stageProps: {}
}; };
}, }
setStage: function(stage, stageProps = {}) {
setStage(stage, stageProps = {}) {
this.setState({ this.setState({
stage: stage, stage: stage,
stageProps: stageProps stageProps: stageProps
}) })
}, }
componentWillMount: function() {
componentWillMount() {
lbryio.authenticate().then((user) => { lbryio.authenticate().then((user) => {
if (!user.HasVerifiedEmail) { if (!user.HasVerifiedEmail) {
if (getLocal('auth_bypassed')) { if (getLocal('auth_bypassed')) {
@ -284,8 +308,9 @@ export const AuthOverlay = React.createClass({
} }
})); }));
}) })
}, }
render: function() {
render() {
if (!this.state.stage) { if (!this.state.stage) {
return null; return null;
} }
@ -299,4 +324,4 @@ export const AuthOverlay = React.createClass({
<StageContent setStage={this.setStage} {...this.state.stageProps} /> <StageContent setStage={this.setStage} {...this.state.stageProps} />
); );
} }
}); }

View file

@ -2,65 +2,69 @@ import React from 'react';
import lbry from '../lbry.js'; import lbry from '../lbry.js';
//component/icon.js //component/icon.js
export let Icon = React.createClass({ export class Icon extends React.Component {
propTypes: { static propTypes = {
icon: React.PropTypes.string.isRequired, icon: React.PropTypes.string.isRequired,
className: React.PropTypes.string, className: React.PropTypes.string,
fixed: React.PropTypes.bool, fixed: React.PropTypes.bool,
}, }
render: function() {
static defaultProps = {
lines: null
}
render() {
const {fixed, className, ...other} = this.props; const {fixed, className, ...other} = this.props;
const spanClassName = ('icon ' + ('fixed' in this.props ? 'icon-fixed-width ' : '') + const spanClassName = ('icon ' + ('fixed' in this.props ? 'icon-fixed-width ' : '') +
this.props.icon + ' ' + (this.props.className || '')); this.props.icon + ' ' + (this.props.className || ''));
return <span className={spanClassName} {... other}></span> return <span className={spanClassName} {... other}></span>
} }
}); }
export let TruncatedText = React.createClass({ export class TruncatedText extends React.Component {
propTypes: { static propTypes = {
lines: React.PropTypes.number lines: React.PropTypes.number,
},
getDefaultProps: function() {
return {
lines: null,
} }
},
render: function() { render() {
return <span className="truncated-text" style={{ WebkitLineClamp: this.props.lines }}>{this.props.children}</span>; return <span className="truncated-text" style={{ WebkitLineClamp: this.props.lines }}>{this.props.children}</span>;
} }
}); }
export let BusyMessage = React.createClass({ export class BusyMessage extends React.Component {
propTypes: { static propTypes = {
message: React.PropTypes.string message: React.PropTypes.string,
}, }
render: function() {
render() {
return <span>{this.props.message} <span className="busy-indicator"></span></span> return <span>{this.props.message} <span className="busy-indicator"></span></span>
} }
}); }
export let CurrencySymbol = React.createClass({ export class CurrencySymbol extends React.Component {
render: function() { return <span>LBC</span>; } render() {
}); return <span>LBC</span>;
}
}
export let CreditAmount = React.createClass({ export class CreditAmount extends React.Component {
propTypes: { static propTypes = {
amount: React.PropTypes.number.isRequired, amount: React.PropTypes.number.isRequired,
precision: React.PropTypes.number, precision: React.PropTypes.number,
isEstimate: React.PropTypes.bool, isEstimate: React.PropTypes.bool,
label: React.PropTypes.bool, label: React.PropTypes.bool,
showFree: React.PropTypes.bool, showFree: React.PropTypes.bool,
look: React.PropTypes.oneOf(['indicator', 'plain']), look: React.PropTypes.oneOf(['indicator', 'plain']),
}, }
getDefaultProps: function() {
return { static defaultProps = {
precision: 1, precision: 1,
label: true, label: true,
showFree: false, showFree: false,
look: 'indicator', look: 'indicator',
} }
},
render: function() { render() {
const formattedAmount = lbry.formatCredits(this.props.amount, this.props.precision); const formattedAmount = lbry.formatCredits(this.props.amount, this.props.precision);
let amountText; let amountText;
if (this.props.showFree && parseFloat(formattedAmount) == 0) { if (this.props.showFree && parseFloat(formattedAmount) == 0) {
@ -80,45 +84,56 @@ export let CreditAmount = React.createClass({
</span> </span>
); );
} }
}); }
var addressStyle = { let addressStyle = {
fontFamily: '"Consolas", "Lucida Console", "Adobe Source Code Pro", monospace', fontFamily: '"Consolas", "Lucida Console", "Adobe Source Code Pro", monospace',
}; };
export let Address = React.createClass({ export class Address extends React.Component {
_inputElem: null, static propTypes = {
propTypes: {
address: React.PropTypes.string, address: React.PropTypes.string,
}, }
render: function() {
constructor(props) {
super(props);
this._inputElem = null;
}
render() {
return ( return (
<input className="input-copyable" type="text" ref={(input) => { this._inputElem = input; }} <input className="input-copyable" type="text" ref={(input) => { this._inputElem = input; }}
onFocus={() => { this._inputElem.select(); }} style={addressStyle} readOnly="readonly" value={this.props.address}></input> onFocus={() => { this._inputElem.select(); }} style={addressStyle} readOnly="readonly" value={this.props.address}></input>
); );
} }
}); }
export let Thumbnail = React.createClass({ export class Thumbnail extends React.Component {
_defaultImageUri: lbry.imagePath('default-thumb.svg'), static propTypes = {
_maxLoadTime: 10000,
_isMounted: false,
propTypes: {
src: React.PropTypes.string, src: React.PropTypes.string,
}, }
handleError: function() {
handleError() {
if (this.state.imageUrl != this._defaultImageUri) { if (this.state.imageUrl != this._defaultImageUri) {
this.setState({ this.setState({
imageUri: this._defaultImageUri, imageUri: this._defaultImageUri,
}); });
} }
}, }
getInitialState: function() {
return { constructor(props) {
super(props);
this._defaultImageUri = lbry.imagePath('default-thumb.svg')
this._maxLoadTime = 10000
this._isMounted = false
this.state = {
imageUri: this.props.src || this._defaultImageUri, imageUri: this.props.src || this._defaultImageUri,
}; };
}, }
componentDidMount: function() {
componentDidMount() {
this._isMounted = true; this._isMounted = true;
setTimeout(() => { setTimeout(() => {
if (this._isMounted && !this.refs.img.complete) { if (this._isMounted && !this.refs.img.complete) {
@ -127,14 +142,16 @@ export let Thumbnail = React.createClass({
}); });
} }
}, this._maxLoadTime); }, this._maxLoadTime);
}, }
componentWillUnmount: function() {
componentWillUnmount() {
this._isMounted = false; this._isMounted = false;
}, }
render: function() {
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 <img ref="img" onError={this.handleError} {...otherProps} className={className} src={this.state.imageUri} /> return <img ref="img" onError={this.handleError} {...otherProps} className={className} src={this.state.imageUri} />
}, }
}); }

View file

@ -8,24 +8,28 @@ function formFieldId() {
return "form-field-" + (++formFieldCounter); return "form-field-" + (++formFieldCounter);
} }
export let FormField = React.createClass({ export class FormField extends React.Component {
_fieldRequiredText: 'This field is required', static propTypes = {
_type: null,
_element: null,
propTypes: {
type: React.PropTypes.string.isRequired, type: React.PropTypes.string.isRequired,
prefix: React.PropTypes.string, prefix: React.PropTypes.string,
postfix: React.PropTypes.string, postfix: React.PropTypes.string,
hasError: React.PropTypes.bool hasError: React.PropTypes.bool
}, }
getInitialState: function() {
return { constructor(props) {
super(props);
this._fieldRequiredText = 'This field is required';
this._type = null;
this._element = null;
this.state = {
isError: null, isError: null,
errorMessage: null, errorMessage: null,
};
} }
},
componentWillMount: function() { componentWillMount() {
if (['text', 'number', 'radio', 'checkbox', 'file'].includes(this.props.type)) { if (['text', 'number', 'radio', 'checkbox', 'file'].includes(this.props.type)) {
this._element = 'input'; this._element = 'input';
this._type = this.props.type; this._type = this.props.type;
@ -36,17 +40,20 @@ export let FormField = React.createClass({
// Non <input> field, e.g. <select>, <textarea> // Non <input> field, e.g. <select>, <textarea>
this._element = this.props.type; this._element = this.props.type;
} }
}, }
showError: function(text) {
showError(text) {
this.setState({ this.setState({
isError: true, isError: true,
errorMessage: text, errorMessage: text,
}); });
}, }
focus: function() {
focus() {
this.refs.field.focus(); this.refs.field.focus();
}, }
getValue: function() {
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 == 'file') { } else if (this.props.type == 'file') {
@ -55,11 +62,13 @@ export let FormField = React.createClass({
} else { } else {
return this.refs.field.value; return this.refs.field.value;
} }
}, }
getSelectedElement: function() {
getSelectedElement() {
return this.refs.field.options[this.refs.field.selectedIndex]; return this.refs.field.options[this.refs.field.selectedIndex];
}, }
render: function() {
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 = this.state.isError !== null ? this.state.isError : this.props.hasError, isError = this.state.isError !== null ? this.state.isError : this.props.hasError,
@ -91,45 +100,56 @@ export let FormField = React.createClass({
{ isError && this.state.errorMessage ? <div className="form-field__error">{this.state.errorMessage}</div> : '' } { isError && this.state.errorMessage ? <div className="form-field__error">{this.state.errorMessage}</div> : '' }
</div> </div>
} }
}) }
export let FormRow = React.createClass({ export class FormRow extends React.Component {
_fieldRequiredText: 'This field is required', static propTypes = {
propTypes: { label: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.element]),
label: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.element])
// helper: React.PropTypes.html, // helper: React.PropTypes.html,
}, }
getInitialState: function() {
return { constructor(props) {
super(props);
this._fieldRequiredText = 'This field is required';
this.state = {
isError: false, isError: false,
errorMessage: null, errorMessage: null,
};
} }
},
showError: function(text) { showError(text) {
this.setState({ this.setState({
isError: true, isError: true,
errorMessage: text, errorMessage: text,
}); });
}, }
showRequiredError: function() {
showRequiredError() {
this.showError(this._fieldRequiredText); this.showError(this._fieldRequiredText);
}, }
clearError: function(text) {
clearError(text) {
this.setState({ this.setState({
isError: false, isError: false,
errorMessage: '' errorMessage: ''
}); });
}, }
getValue: function() {
getValue() {
return this.refs.field.getValue(); return this.refs.field.getValue();
}, }
getSelectedElement: function() {
getSelectedElement() {
return this.refs.field.getSelectedElement(); return this.refs.field.getSelectedElement();
}, }
focus: function() {
focus() {
this.refs.field.focus(); this.refs.field.focus();
}, }
render: function() {
render() {
const fieldProps = Object.assign({}, this.props), const fieldProps = Object.assign({}, this.props),
elementId = formFieldId(), elementId = formFieldId(),
renderLabelInFormField = formFieldNestedLabelTypes.includes(this.props.type); renderLabelInFormField = formFieldNestedLabelTypes.includes(this.props.type);
@ -151,4 +171,4 @@ export let FormRow = React.createClass({
{ this.state.isError ? <div className="form-field__error">{this.state.errorMessage}</div> : '' } { this.state.isError ? <div className="form-field__error">{this.state.errorMessage}</div> : '' }
</div> </div>
} }
}) }

View file

@ -3,25 +3,28 @@ 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'
var LoadScreen = React.createClass({ class LoadScreen extends React.Component {
propTypes: { static propTypes = {
message: React.PropTypes.string.isRequired, message: React.PropTypes.string.isRequired,
details: React.PropTypes.string, details: React.PropTypes.string,
isWarning: React.PropTypes.bool, isWarning: React.PropTypes.bool,
},
getDefaultProps: function() {
return {
isWarning: false,
} }
},
getInitialState: function() { constructor(props) {
return { super(props);
this.state = {
message: null, message: null,
details: null, details: null,
isLagging: false, isLagging: false,
};
} }
},
render: function() { static defaultProps = {
isWarning: false,
}
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">
@ -35,7 +38,7 @@ var LoadScreen = React.createClass({
</div> </div>
); );
} }
}); }
export default LoadScreen; export default LoadScreen;

View file

@ -2,19 +2,19 @@ import React from 'react';
import {Icon} from './common.js'; import {Icon} from './common.js';
import Link from 'component/link'; import Link from 'component/link';
export let DropDownMenuItem = React.createClass({ export class DropDownMenuItem extends React.Component {
propTypes: { static propTypes = {
href: React.PropTypes.string, href: React.PropTypes.string,
label: React.PropTypes.string, label: React.PropTypes.string,
icon: React.PropTypes.string, icon: React.PropTypes.string,
onClick: React.PropTypes.func, onClick: React.PropTypes.func,
}, }
getDefaultProps: function() {
return { static defaultProps = {
iconPosition: 'left', iconPosition: 'left',
} }
},
render: function() { render() {
var icon = (this.props.icon ? <Icon icon={this.props.icon} fixed /> : null); var icon = (this.props.icon ? <Icon icon={this.props.icon} fixed /> : null);
return ( return (
@ -26,23 +26,27 @@ export let DropDownMenuItem = React.createClass({
</a> </a>
); );
} }
}); }
export let DropDownMenu = React.createClass({ export class DropDownMenu extends React.Component {
_isWindowClickBound: false, constructor(props) {
_menuDiv: null, super(props);
getInitialState: function() { this._isWindowClickBound = false;
return { this._menuDiv = null;
this.state = {
menuOpen: false, menuOpen: false,
}; };
}, }
componentWillUnmount: function() {
componentWillUnmount() {
if (this._isWindowClickBound) { if (this._isWindowClickBound) {
window.removeEventListener('click', this.handleWindowClick, false); window.removeEventListener('click', this.handleWindowClick, false);
} }
}, }
handleMenuIconClick: function(e) {
handleMenuIconClick(e) {
this.setState({ this.setState({
menuOpen: !this.state.menuOpen, menuOpen: !this.state.menuOpen,
}); });
@ -52,22 +56,25 @@ export let DropDownMenu = React.createClass({
e.stopPropagation(); e.stopPropagation();
} }
return false; return false;
}, }
handleMenuClick: function(e) {
handleMenuClick(e) {
// Event bubbles up to the menu after a link is clicked // Event bubbles up to the menu after a link is clicked
this.setState({ this.setState({
menuOpen: false, menuOpen: false,
}); });
}, }
handleWindowClick: function(e) {
handleWindowClick(e) {
if (this.state.menuOpen && if (this.state.menuOpen &&
(!this._menuDiv || !this._menuDiv.contains(e.target))) { (!this._menuDiv || !this._menuDiv.contains(e.target))) {
this.setState({ this.setState({
menuOpen: false menuOpen: false
}); });
} }
}, }
render: function() {
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);
@ -83,4 +90,4 @@ export let DropDownMenu = React.createClass({
</div> </div>
); );
} }
}); }

View file

@ -1,8 +1,8 @@
import React from 'react'; import React from 'react';
import ReactModal from 'react-modal'; import ReactModal from 'react-modal';
export const ModalPage = React.createClass({ export class ModalPage extends React.Component {
render: function() { render() {
return ( return (
<ReactModal onCloseRequested={this.props.onAborted || this.props.onConfirmed} {...this.props} <ReactModal onCloseRequested={this.props.onAborted || this.props.onConfirmed} {...this.props}
className={(this.props.className || '') + ' modal-page'} className={(this.props.className || '') + ' modal-page'}
@ -13,6 +13,4 @@ export const ModalPage = React.createClass({
</ReactModal> </ReactModal>
); );
} }
}); }
export default ModalPage;

View file

@ -3,8 +3,8 @@ import ReactModal from 'react-modal';
import Link from 'component/link'; import Link from 'component/link';
export const Modal = React.createClass({ export class Modal extends React.Component {
propTypes: { static propTypes = {
type: React.PropTypes.oneOf(['alert', 'confirm', 'custom']), type: React.PropTypes.oneOf(['alert', 'confirm', 'custom']),
overlay: React.PropTypes.bool, overlay: React.PropTypes.bool,
onConfirmed: React.PropTypes.func, onConfirmed: React.PropTypes.func,
@ -13,18 +13,18 @@ export const Modal = React.createClass({
abortButtonLabel: React.PropTypes.string, abortButtonLabel: React.PropTypes.string,
confirmButtonDisabled: React.PropTypes.bool, confirmButtonDisabled: React.PropTypes.bool,
abortButtonDisabled: React.PropTypes.bool, abortButtonDisabled: React.PropTypes.bool,
}, }
getDefaultProps: function() {
return { static defaultProps = {
type: 'alert', type: 'alert',
overlay: true, overlay: true,
confirmButtonLabel: 'OK', confirmButtonLabel: 'OK',
abortButtonLabel: 'Cancel', abortButtonLabel: 'Cancel',
confirmButtonDisabled: false, confirmButtonDisabled: false,
abortButtonDisabled: false, abortButtonDisabled: false,
}; }
},
render: function() { render() {
return ( return (
<ReactModal onCloseRequested={this.props.onAborted || this.props.onConfirmed} {...this.props} <ReactModal onCloseRequested={this.props.onAborted || this.props.onConfirmed} {...this.props}
className={(this.props.className || '') + ' modal'} className={(this.props.className || '') + ' modal'}
@ -43,31 +43,35 @@ export const Modal = React.createClass({
</ReactModal> </ReactModal>
); );
} }
}); }
export const ExpandableModal = React.createClass({ export class ExpandableModal extends React.Component {
propTypes: { static propTypes = {
expandButtonLabel: React.PropTypes.string, expandButtonLabel: React.PropTypes.string,
extraContent: React.PropTypes.element, extraContent: React.PropTypes.element,
}, }
getDefaultProps: function() {
return { static defaultProps = {
confirmButtonLabel: 'OK', confirmButtonLabel: 'OK',
expandButtonLabel: 'Show More...', expandButtonLabel: 'Show More...',
hideButtonLabel: 'Show Less', hideButtonLabel: 'Show Less',
} }
},
getInitialState: function() { constructor(props) {
return { super(props);
this.state = {
expanded: false, expanded: false,
} }
}, }
toggleExpanded: function() {
toggleExpanded() {
this.setState({ this.setState({
expanded: !this.state.expanded, expanded: !this.state.expanded,
}); });
}, }
render: function() {
render() {
return ( return (
<Modal type="custom" {... this.props}> <Modal type="custom" {... this.props}>
{this.props.children} {this.props.children}
@ -82,6 +86,6 @@ export const ExpandableModal = React.createClass({
</Modal> </Modal>
); );
} }
}); }
export default Modal; export default Modal;

View file

@ -1,21 +1,21 @@
import React from 'react'; import React from 'react';
export const Notice = React.createClass({ export class Notice extends React.Component {
propTypes: { static propTypes = {
isError: React.PropTypes.bool, isError: React.PropTypes.bool,
}, }
getDefaultProps: function() {
return { static defaultProps = {
isError: false, isError: false,
}; }
},
render: function() { render() {
return ( return (
<section className={'notice ' + (this.props.isError ? 'notice--error ' : '') + (this.props.className || '')}> <section className={'notice ' + (this.props.isError ? 'notice--error ' : '') + (this.props.className || '')}>
{this.props.children} {this.props.children}
</section> </section>
); );
}, }
}); }
export default Notice; export default Notice;

View file

@ -5,14 +5,25 @@ import Modal from 'component/modal';
import rewards from 'rewards'; import rewards from 'rewards';
import Link from 'component/link' import Link from 'component/link'
export let RewardLink = React.createClass({ export class RewardLink extends React.Component {
propTypes: { static propTypes = {
type: React.PropTypes.string.isRequired, type: React.PropTypes.string.isRequired,
claimed: React.PropTypes.bool, claimed: React.PropTypes.bool,
onRewardClaim: React.PropTypes.func, onRewardClaim: React.PropTypes.func,
onRewardFailure: React.PropTypes.func onRewardFailure: React.PropTypes.func
}, }
refreshClaimable: function() {
constructor(props) {
super(props);
this.state = {
claimable: true,
pending: false,
errorMessage: null
};
}
refreshClaimable() {
switch(this.props.type) { switch(this.props.type) {
case 'new_user': case 'new_user':
this.setState({ claimable: true }); this.setState({ claimable: true });
@ -26,18 +37,13 @@ export let RewardLink = React.createClass({
}.bind(this)); }.bind(this));
return; return;
} }
},
componentWillMount: function() {
this.refreshClaimable();
},
getInitialState: function() {
return {
claimable: true,
pending: false,
errorMessage: null
} }
},
claimReward: function() { componentWillMount() {
this.refreshClaimable();
}
claimReward() {
this.setState({ this.setState({
pending: true pending: true
}) })
@ -55,16 +61,18 @@ export let RewardLink = React.createClass({
pending: false pending: false
}) })
}) })
}, }
clearError: function() {
clearError() {
if (this.props.onRewardFailure) { if (this.props.onRewardFailure) {
this.props.onRewardFailure() this.props.onRewardFailure()
} }
this.setState({ this.setState({
errorMessage: null errorMessage: null
}) })
}, }
render: function() {
render() {
return ( return (
<div className="reward-link"> <div className="reward-link">
{this.props.claimed {this.props.claimed
@ -79,4 +87,4 @@ export let RewardLink = React.createClass({
</div> </div>
); );
} }
}); }

View file

@ -1,18 +1,19 @@
import React from 'react'; import React from 'react';
import lbry from '../lbry.js'; import lbry from '../lbry.js';
export const SnackBar = React.createClass({ export class SnackBar extends React.Component {
constructor(props) {
super(props);
_displayTime: 5, // in seconds this._displayTime = 5; // in seconds
this._hideTimeout = null;
_hideTimeout: null, this.state = {
getInitialState: function() {
return {
snacks: [] snacks: []
};
} }
},
handleSnackReceived: function(event) { handleSnackReceived(event) {
// if (this._hideTimeout) { // if (this._hideTimeout) {
// clearTimeout(this._hideTimeout); // clearTimeout(this._hideTimeout);
// } // }
@ -20,14 +21,17 @@ export const SnackBar = React.createClass({
let snacks = this.state.snacks; let snacks = this.state.snacks;
snacks.push(event.detail); snacks.push(event.detail);
this.setState({ snacks: snacks}); this.setState({ snacks: snacks});
}, }
componentWillMount: function() {
componentWillMount() {
document.addEventListener('globalNotice', this.handleSnackReceived); document.addEventListener('globalNotice', this.handleSnackReceived);
}, }
componentWillUnmount: function() {
componentWillUnmount() {
document.removeEventListener('globalNotice', this.handleSnackReceived); document.removeEventListener('globalNotice', this.handleSnackReceived);
}, }
render: function() {
render() {
if (!this.state.snacks.length) { if (!this.state.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;
@ -51,7 +55,7 @@ export const SnackBar = React.createClass({
<a className="snack-bar__action" href={snack.linkTarget}>{snack.linkText}</a> : ''} <a className="snack-bar__action" href={snack.linkTarget}>{snack.linkText}</a> : ''}
</div> </div>
); );
}, }
}); }
export default SnackBar; export default SnackBar;

View file

@ -2,21 +2,26 @@ import React from 'react';
import lbry from '../lbry.js'; import lbry from '../lbry.js';
import LoadScreen from './load_screen.js'; import LoadScreen from './load_screen.js';
var SplashScreen = React.createClass({ export class SplashScreen extends React.Component {
propTypes: { static propTypes = {
message: React.PropTypes.string, message: React.PropTypes.string,
onLoadDone: React.PropTypes.func, onLoadDone: React.PropTypes.func,
}, }
getInitialState: function() {
return { constructor(props) {
super(props);
this.state = {
details: 'Starting daemon', details: 'Starting daemon',
isLagging: false, isLagging: false,
};
} }
},
updateStatus: function() { updateStatus() {
lbry.status().then(this._updateStatusCallback); lbry.status().then(this._updateStatusCallback);
}, }
_updateStatusCallback: function(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
@ -40,8 +45,9 @@ var SplashScreen = React.createClass({
setTimeout(() => { setTimeout(() => {
this.updateStatus(); this.updateStatus();
}, 500); }, 500);
}, }
componentDidMount: function() {
componentDidMount() {
lbry.connect().then((isConnected) => { lbry.connect().then((isConnected) => {
if (isConnected) { if (isConnected) {
this.updateStatus(); this.updateStatus();
@ -53,10 +59,11 @@ var SplashScreen = React.createClass({
}) })
} }
}) })
}, }
render: function() {
render() {
return <LoadScreen message={this.props.message} details={this.state.details} isWarning={this.state.isLagging} /> return <LoadScreen message={this.props.message} details={this.state.details} isWarning={this.state.isLagging} />
} }
}); }
export default SplashScreen; export default SplashScreen;

View file

@ -1,26 +1,32 @@
import React from 'react'; import React from 'react';
export let ToolTip = React.createClass({ export class ToolTip extends React.Component {
propTypes: { static propTypes = {
body: React.PropTypes.string.isRequired, body: React.PropTypes.string.isRequired,
label: React.PropTypes.string.isRequired label: React.PropTypes.string.isRequired
}, }
getInitialState: function() {
return { constructor(props) {
super(props);
this.state = {
showTooltip: false, showTooltip: false,
}; };
}, }
handleClick: function() {
handleClick() {
this.setState({ this.setState({
showTooltip: !this.state.showTooltip, showTooltip: !this.state.showTooltip,
}); });
}, }
handleTooltipMouseOut: function() {
handleTooltipMouseOut() {
this.setState({ this.setState({
showTooltip: false, showTooltip: false,
}); });
}, }
render: function() {
render() {
return ( return (
<span className={'tooltip ' + (this.props.className || '')}> <span className={'tooltip ' + (this.props.className || '')}>
<a className="tooltip__link" onClick={this.handleClick}> <a className="tooltip__link" onClick={this.handleClick}>
@ -33,6 +39,6 @@ export let ToolTip = React.createClass({
</span> </span>
); );
} }
}); }
export default ToolTip export default ToolTip

View file

@ -6,34 +6,40 @@ import Link from '../component/link';
const fs = require('fs'); const fs = require('fs');
const {ipcRenderer} = require('electron'); const {ipcRenderer} = require('electron');
const DeveloperPage = React.createClass({ class DeveloperPage extends React.Component {
getInitialState: function() { constructor(props) {
return { super(props);
this.state = {
showDeveloperMenu: lbry.getClientSetting('showDeveloperMenu'), showDeveloperMenu: lbry.getClientSetting('showDeveloperMenu'),
useCustomLighthouseServers: lbry.getClientSetting('useCustomLighthouseServers'), useCustomLighthouseServers: lbry.getClientSetting('useCustomLighthouseServers'),
customLighthouseServers: lbry.getClientSetting('customLighthouseServers').join('\n'), customLighthouseServers: lbry.getClientSetting('customLighthouseServers').join('\n'),
upgradePath: '', upgradePath: '',
}; };
}, }
handleShowDeveloperMenuChange: function(event) {
handleShowDeveloperMenuChange(event) {
lbry.setClientSetting('showDeveloperMenu', event.target.checked); lbry.setClientSetting('showDeveloperMenu', event.target.checked);
lbry.showMenuIfNeeded(); lbry.showMenuIfNeeded();
this.setState({ this.setState({
showDeveloperMenu: event.target.checked, showDeveloperMenu: event.target.checked,
}); });
}, }
handleUseCustomLighthouseServersChange: function(event) {
handleUseCustomLighthouseServersChange(event) {
lbry.setClientSetting('useCustomLighthouseServers', event.target.checked); lbry.setClientSetting('useCustomLighthouseServers', event.target.checked);
this.setState({ this.setState({
useCustomLighthouseServers: event.target.checked, useCustomLighthouseServers: event.target.checked,
}); });
}, }
handleUpgradeFileChange: function(event) {
handleUpgradeFileChange(event) {
this.setState({ this.setState({
upgradePath: event.target.files[0].path, upgradePath: event.target.files[0].path,
}); });
}, }
handleForceUpgradeClick: function() {
handleForceUpgradeClick() {
let upgradeSent = false; let upgradeSent = false;
if (!this.state.upgradePath) { if (!this.state.upgradePath) {
alert('Please select a file to upgrade from'); alert('Please select a file to upgrade from');
@ -51,8 +57,9 @@ const DeveloperPage = React.createClass({
alert('Failed to start upgrade. Is "' + this.state.upgradePath + '" a valid path to the upgrade?'); alert('Failed to start upgrade. Is "' + this.state.upgradePath + '" a valid path to the upgrade?');
} }
} }
}, }
render: function() {
render() {
return ( return (
<main> <main>
<section className="card"> <section className="card">
@ -82,6 +89,6 @@ const DeveloperPage = React.createClass({
</main> </main>
); );
} }
}); }
export default DeveloperPage; export default DeveloperPage;

View file

@ -5,14 +5,17 @@ import Link from 'component/link';
import SubHeader from 'component/subHeader' import SubHeader from 'component/subHeader'
import {version as uiVersion} from 'json!../../../package.json'; import {version as uiVersion} from 'json!../../../package.json';
var HelpPage = React.createClass({ class HelpPage extends React.Component {
getInitialState: function() { constructor(props) {
return { super(props);
this.state = {
versionInfo: null, versionInfo: null,
lbryId: null, lbryId: null,
}; };
}, }
componentWillMount: function() {
componentWillMount() {
lbry.getVersionInfo((info) => { lbry.getVersionInfo((info) => {
this.setState({ this.setState({
versionInfo: info, versionInfo: info,
@ -23,11 +26,13 @@ var HelpPage = React.createClass({
lbryId: info.lbry_id, lbryId: info.lbry_id,
}); });
}); });
}, }
componentDidMount: function() {
componentDidMount() {
document.title = "Help"; document.title = "Help";
}, }
render: function() {
render() {
let ver, osName, platform, newVerLink; let ver, osName, platform, newVerLink;
if (this.state.versionInfo) { if (this.state.versionInfo) {
ver = this.state.versionInfo; ver = this.state.versionInfo;
@ -119,6 +124,6 @@ var HelpPage = React.createClass({
</main> </main>
); );
} }
}); }
export default HelpPage; export default HelpPage;

View file

@ -5,10 +5,41 @@ import Link from 'component/link';
import rewards from 'rewards'; import rewards from 'rewards';
import Modal from 'component/modal'; import Modal from 'component/modal';
var PublishPage = React.createClass({ class PublishPage extends React.Component {
_requiredFields: ['meta_title', 'name', 'bid', 'tos_agree'], constructor(props) {
super(props);
_updateChannelList: function(channel) { this._requiredFields = ['meta_title', 'name', 'bid', 'tos_agree'];
this.state = {
channels: null,
rawName: '',
name: '',
bid: 10,
hasFile: false,
feeAmount: '',
feeCurrency: 'USD',
channel: 'anonymous',
newChannelName: '@',
newChannelBid: 10,
nameResolved: null,
myClaimExists: null,
topClaimValue: 0.0,
myClaimValue: 0.0,
myClaimMetadata: null,
copyrightNotice: '',
otherLicenseDescription: '',
otherLicenseUrl: '',
uploadProgress: 0.0,
uploaded: false,
errorMessage: null,
submitting: false,
creatingChannel: false,
modal: null,
};
}
_updateChannelList(channel) {
// Calls API to update displayed list of channels. If a channel name is provided, will select // Calls API to update displayed list of channels. If a channel name is provided, will select
// that channel at the same time (used immediately after creating a channel) // that channel at the same time (used immediately after creating a channel)
lbry.channel_list_mine().then((channels) => { lbry.channel_list_mine().then((channels) => {
@ -18,8 +49,9 @@ var PublishPage = React.createClass({
... channel ? {channel} : {} ... channel ? {channel} : {}
}); });
}); });
}, }
handleSubmit: function(event) {
handleSubmit(event) {
if (typeof event !== 'undefined') { if (typeof event !== 'undefined') {
event.preventDefault(); event.preventDefault();
} }
@ -112,51 +144,27 @@ var PublishPage = React.createClass({
} else { } else {
doPublish(); doPublish();
} }
}, }
getInitialState: function() {
return { handlePublishStarted() {
channels: null,
rawName: '',
name: '',
bid: 10,
hasFile: false,
feeAmount: '',
feeCurrency: 'USD',
channel: 'anonymous',
newChannelName: '@',
newChannelBid: 10,
nameResolved: null,
myClaimExists: null,
topClaimValue: 0.0,
myClaimValue: 0.0,
myClaimMetadata: null,
copyrightNotice: '',
otherLicenseDescription: '',
otherLicenseUrl: '',
uploadProgress: 0.0,
uploaded: false,
errorMessage: null,
submitting: false,
creatingChannel: false,
modal: null,
};
},
handlePublishStarted: function() {
this.setState({ this.setState({
modal: 'publishStarted', modal: 'publishStarted',
}); });
}, }
handlePublishStartedConfirmed: function() {
handlePublishStartedConfirmed() {
this.props.navigate('/published') this.props.navigate('/published')
}, }
handlePublishError: function(error) {
handlePublishError(error) {
this.setState({ this.setState({
submitting: false, submitting: false,
modal: 'error', modal: 'error',
errorMessage: error.message, errorMessage: error.message,
}); });
}, }
handleNameChange: function(event) {
handleNameChange(event) {
var rawName = event.target.value; var rawName = event.target.value;
if (!rawName) { if (!rawName) {
@ -228,28 +236,33 @@ var PublishPage = React.createClass({
}); });
}); });
}); });
}, }
handleBidChange: function(event) {
handleBidChange(event) {
this.setState({ this.setState({
bid: event.target.value, bid: event.target.value,
}); });
}, }
handleFeeAmountChange: function(event) {
handleFeeAmountChange(event) {
this.setState({ this.setState({
feeAmount: event.target.value, feeAmount: event.target.value,
}); });
}, }
handleFeeCurrencyChange: function(event) {
handleFeeCurrencyChange(event) {
this.setState({ this.setState({
feeCurrency: event.target.value, feeCurrency: event.target.value,
}); });
}, }
handleFeePrefChange: function(feeEnabled) {
handleFeePrefChange(feeEnabled) {
this.setState({ this.setState({
isFee: feeEnabled isFee: feeEnabled
}); });
}, }
handleLicenseChange: function(event) {
handleLicenseChange(event) {
var licenseType = event.target.options[event.target.selectedIndex].getAttribute('data-license-type'); var licenseType = event.target.options[event.target.selectedIndex].getAttribute('data-license-type');
var newState = { var newState = {
copyrightChosen: licenseType == 'copyright', copyrightChosen: licenseType == 'copyright',
@ -261,30 +274,35 @@ var PublishPage = React.createClass({
} }
this.setState(newState); this.setState(newState);
}, }
handleCopyrightNoticeChange: function(event) {
handleCopyrightNoticeChange(event) {
this.setState({ this.setState({
copyrightNotice: event.target.value, copyrightNotice: event.target.value,
}); });
}, }
handleOtherLicenseDescriptionChange: function(event) {
handleOtherLicenseDescriptionChange(event) {
this.setState({ this.setState({
otherLicenseDescription: event.target.value, otherLicenseDescription: event.target.value,
}); });
}, }
handleOtherLicenseUrlChange: function(event) {
handleOtherLicenseUrlChange(event) {
this.setState({ this.setState({
otherLicenseUrl: event.target.value, otherLicenseUrl: event.target.value,
}); });
}, }
handleChannelChange: function (event) {
handleChannelChange(event) {
const channel = event.target.value; const channel = event.target.value;
this.setState({ this.setState({
channel: channel, channel: channel,
}); });
}, }
handleNewChannelNameChange: function (event) {
handleNewChannelNameChange(event) {
const newChannelName = (event.target.value.startsWith('@') ? event.target.value : '@' + event.target.value); const newChannelName = (event.target.value.startsWith('@') ? event.target.value : '@' + event.target.value);
if (newChannelName.length > 1 && !lbry.nameIsValid(newChannelName.substr(1), false)) { if (newChannelName.length > 1 && !lbry.nameIsValid(newChannelName.substr(1), false)) {
@ -297,18 +315,21 @@ var PublishPage = React.createClass({
this.setState({ this.setState({
newChannelName: newChannelName, newChannelName: newChannelName,
}); });
}, }
handleNewChannelBidChange: function (event) {
handleNewChannelBidChange(event) {
this.setState({ this.setState({
newChannelBid: event.target.value, newChannelBid: event.target.value,
}); });
}, }
handleTOSChange: function(event) {
handleTOSChange(event) {
this.setState({ this.setState({
TOSAgreed: event.target.checked, TOSAgreed: event.target.checked,
}); });
}, }
handleCreateChannelClick: function (event) {
handleCreateChannelClick(event) {
if (this.state.newChannelName.length < 5) { if (this.state.newChannelName.length < 5) {
this.refs.newChannelName.showError('LBRY channel names must be at least 4 characters in length.'); this.refs.newChannelName.showError('LBRY channel names must be at least 4 characters in length.');
return; return;
@ -334,8 +355,9 @@ var PublishPage = React.createClass({
creatingChannel: false, creatingChannel: false,
}); });
}); });
}, }
getLicenseUrl: function() {
getLicenseUrl() {
if (!this.refs.meta_license) { if (!this.refs.meta_license) {
return ''; return '';
} else if (this.state.otherLicenseChosen) { } else if (this.state.otherLicenseChosen) {
@ -343,20 +365,21 @@ var PublishPage = React.createClass({
} else { } else {
return this.refs.meta_license.getSelectedElement().getAttribute('data-url') || '' ; return this.refs.meta_license.getSelectedElement().getAttribute('data-url') || '' ;
} }
}, }
componentWillMount: function() {
componentWillMount() {
this._updateChannelList(); this._updateChannelList();
}, }
componentDidUpdate: function() {
}, onFileChange() {
onFileChange: function() {
if (this.refs.file.getValue()) { if (this.refs.file.getValue()) {
this.setState({ hasFile: true }) this.setState({ hasFile: true })
} else { } else {
this.setState({ hasFile: false }) this.setState({ hasFile: false })
} }
}, }
getNameBidHelpText: function() {
getNameBidHelpText() {
if (!this.state.name) { if (!this.state.name) {
return "Select a URL for this publish."; return "Select a URL for this publish.";
} else if (this.state.nameResolved === false) { } else if (this.state.nameResolved === false) {
@ -369,13 +392,15 @@ var PublishPage = React.createClass({
} else { } else {
return ''; return '';
} }
}, }
closeModal: function() {
closeModal() {
this.setState({ this.setState({
modal: null, modal: null,
}); });
}, }
render: function() {
render() {
if (this.state.channels === null) { if (this.state.channels === null) {
return null; return null;
} }
@ -564,6 +589,6 @@ var PublishPage = React.createClass({
</main> </main>
); );
} }
}); }
export default PublishPage; export default PublishPage;

View file

@ -3,8 +3,17 @@ import Link from 'component/link';
import Modal from '../component/modal.js'; import Modal from '../component/modal.js';
import lbry from '../lbry.js'; import lbry from '../lbry.js';
var ReportPage = React.createClass({ class ReportPage extends React.Component {
submitMessage: function() { constructor(props) {
super(props);
this.state = {
submitting: false,
modal: null,
};
}
submitMessage() {
if (this._messageArea.value) { if (this._messageArea.value) {
this.setState({ this.setState({
submitting: true submitting: true
@ -17,19 +26,15 @@ var ReportPage = React.createClass({
}); });
this._messageArea.value = ''; this._messageArea.value = '';
} }
}, }
closeModal: function() {
closeModal() {
this.setState({ this.setState({
modal: null, modal: null,
}) })
},
getInitialState: function() {
return {
submitting: false,
modal: null,
} }
},
render: function() { render() {
return ( return (
<main className="main--single-column"> <main className="main--single-column">
<section className="card"> <section className="card">
@ -53,6 +58,6 @@ var ReportPage = React.createClass({
</main> </main>
); );
} }
}); }
export default ReportPage; export default ReportPage;

View file

@ -4,16 +4,17 @@ import {CreditAmount, Icon} from 'component/common.js';
import SubHeader from 'component/subHeader' import SubHeader from 'component/subHeader'
import {RewardLink} from 'component/reward-link'; import {RewardLink} from 'component/reward-link';
const RewardTile = React.createClass({ export class RewardTile extends React.Component {
propTypes: { static propTypes = {
type: React.PropTypes.string.isRequired, type: React.PropTypes.string.isRequired,
title: React.PropTypes.string.isRequired, title: React.PropTypes.string.isRequired,
description: React.PropTypes.string.isRequired, description: React.PropTypes.string.isRequired,
claimed: React.PropTypes.bool.isRequired, claimed: React.PropTypes.bool.isRequired,
value: React.PropTypes.number.isRequired, value: React.PropTypes.number.isRequired,
onRewardClaim: React.PropTypes.func onRewardClaim: React.PropTypes.func
}, }
render: function() {
render() {
return ( return (
<section className="card"> <section className="card">
<div className="card__inner"> <div className="card__inner">
@ -31,19 +32,23 @@ const RewardTile = React.createClass({
</section> </section>
); );
} }
}); }
export let RewardsPage = React.createClass({ export class RewardsPage extends React.Component {
componentWillMount: function() { constructor(props) {
this.loadRewards() super(props);
},
getInitialState: function() { this.state = {
return {
userRewards: null, userRewards: null,
failed: null failed: null,
}; };
}, }
loadRewards: function() {
componentWillMount() {
this.loadRewards()
}
loadRewards() {
lbryio.call('reward', 'list', {}).then((userRewards) => { lbryio.call('reward', 'list', {}).then((userRewards) => {
this.setState({ this.setState({
userRewards: userRewards, userRewards: userRewards,
@ -51,8 +56,9 @@ export let RewardsPage = React.createClass({
}, () => { }, () => {
this.setState({failed: true }) this.setState({failed: true })
}); });
}, }
render: function() {
render() {
return ( return (
<main className="main--single-column"> <main className="main--single-column">
<SubHeader /> <SubHeader />
@ -66,6 +72,6 @@ export let RewardsPage = React.createClass({
</main> </main>
); );
} }
}); }
export default RewardsPage; export default RewardsPage;

View file

@ -3,46 +3,10 @@ import {FormField, FormRow} from 'component/form.js';
import SubHeader from 'component/subHeader' import SubHeader from 'component/subHeader'
import lbry from 'lbry.js'; import lbry from 'lbry.js';
var SettingsPage = React.createClass({ class SettingsPage extends React.Component {
setDaemonSetting: function(name, value) { constructor(props) {
this.props.setDaemonSetting(name, value) super(props);
},
setClientSetting: function(name, value) {
lbry.setClientSetting(name, value)
this._onSettingSaveSuccess()
},
onRunOnStartChange: function (event) {
this.setDaemonSetting('run_on_startup', event.target.checked);
},
onShareDataChange: function (event) {
this.setDaemonSetting('share_usage_data', event.target.checked);
},
onDownloadDirChange: function(event) {
this.setDaemonSetting('download_directory', event.target.value);
},
onMaxUploadPrefChange: function(isLimited) {
if (!isLimited) {
this.setDaemonSetting('max_upload', 0.0);
}
this.setState({
isMaxUpload: isLimited
});
},
onMaxUploadFieldChange: function(event) {
this.setDaemonSetting('max_upload', Number(event.target.value));
},
onMaxDownloadPrefChange: function(isLimited) {
if (!isLimited) {
this.setDaemonSetting('max_download', 0.0);
}
this.setState({
isMaxDownload: isLimited
});
},
onMaxDownloadFieldChange: function(event) {
this.setDaemonSetting('max_download', Number(event.target.value));
},
getInitialState: function() {
const daemonSettings = this.props.daemonSettings const daemonSettings = this.props.daemonSettings
return { return {
@ -51,14 +15,64 @@ var SettingsPage = React.createClass({
showNsfw: lbry.getClientSetting('showNsfw'), showNsfw: lbry.getClientSetting('showNsfw'),
showUnavailable: lbry.getClientSetting('showUnavailable'), showUnavailable: lbry.getClientSetting('showUnavailable'),
} }
}, }
onShowNsfwChange: function(event) {
lbry.setClientSetting('showNsfw', event.target.checked);
},
onShowUnavailableChange: function(event) {
}, setDaemonSetting(name, value) {
render: function() { this.props.setDaemonSetting(name, value)
}
setClientSetting(name, value) {
lbry.setClientSetting(name, value)
this._onSettingSaveSuccess()
}
onRunOnStartChange(event) {
this.setDaemonSetting('run_on_startup', event.target.checked);
}
onShareDataChange(event) {
this.setDaemonSetting('share_usage_data', event.target.checked);
}
onDownloadDirChange(event) {
this.setDaemonSetting('download_directory', event.target.value);
}
onMaxUploadPrefChange(isLimited) {
if (!isLimited) {
this.setDaemonSetting('max_upload', 0.0);
}
this.setState({
isMaxUpload: isLimited
});
}
onMaxUploadFieldChange(event) {
this.setDaemonSetting('max_upload', Number(event.target.value));
}
onMaxDownloadPrefChange(isLimited) {
if (!isLimited) {
this.setDaemonSetting('max_download', 0.0);
}
this.setState({
isMaxDownload: isLimited
});
}
onMaxDownloadFieldChange(event) {
this.setDaemonSetting('max_download', Number(event.target.value));
}
onShowNsfwChange(event) {
lbry.setClientSetting('showNsfw', event.target.checked);
}
onShowUnavailableChange(event) {
}
render() {
const { const {
daemonSettings daemonSettings
} = this.props } = this.props
@ -185,6 +199,6 @@ var SettingsPage = React.createClass({
</main> </main>
); );
} }
}); }
export default SettingsPage; export default SettingsPage;

View file

@ -1,11 +1,12 @@
import React from 'react'; import React from 'react';
import lbry from '../lbry.js'; import lbry from '../lbry.js';
var StartPage = React.createClass({ class StartPage extends React.Component {
componentWillMount: function() { componentWillMount() {
lbry.stop(); lbry.stop();
}, }
render: function() {
render() {
return ( return (
<main className="main--single-column"> <main className="main--single-column">
<h3>LBRY is Closed</h3> <h3>LBRY is Closed</h3>
@ -13,6 +14,6 @@ var StartPage = React.createClass({
</main> </main>
); );
} }
}); }
export default StartPage; export default StartPage;