From 3e35d449783dc6017d563fb81d5fc15eaf037e0c Mon Sep 17 00:00:00 2001 From: Alex Liebowitz Date: Wed, 17 May 2017 04:10:25 -0400 Subject: [PATCH 1/2] Basics of conversion to ES6 classes --- ui/js/component/auth.js | 167 ++++++++++++++++------------- ui/js/component/common.js | 145 ++++++++++++++----------- ui/js/component/form.js | 112 +++++++++++-------- ui/js/component/load_screen.js | 31 +++--- ui/js/component/menu.js | 59 +++++----- ui/js/component/modal-page.js | 8 +- ui/js/component/modal.js | 68 ++++++------ ui/js/component/notice.js | 22 ++-- ui/js/component/reward-link.js | 48 +++++---- ui/js/component/snack-bar.js | 38 ++++--- ui/js/component/splash.js | 37 ++++--- ui/js/component/tooltip.js | 30 +++--- ui/js/page/developer.js | 35 +++--- ui/js/page/help/view.jsx | 25 +++-- ui/js/page/publish/view.jsx | 189 +++++++++++++++++++-------------- ui/js/page/report.js | 31 +++--- ui/js/page/rewards.js | 40 ++++--- ui/js/page/settings/view.jsx | 110 ++++++++++--------- ui/js/page/start.js | 11 +- 19 files changed, 684 insertions(+), 522 deletions(-) diff --git a/ui/js/component/auth.js b/ui/js/component/auth.js index 261b065b1..df18b0817 100644 --- a/ui/js/component/auth.js +++ b/ui/js/component/auth.js @@ -9,23 +9,28 @@ import {CreditAmount, Address} from "../component/common.js"; import {getLocal, getSession, setSession, setLocal} from '../utils.js'; -const SubmitEmailStage = React.createClass({ - getInitialState: function() { - return { +class SubmitEmailStage extends React.Component { + constructor(props) { + super(props); + + this.state = { rewardType: null, email: '', submitting: false }; - }, - handleEmailChanged: function(event) { + } + + handleEmailChanged(event) { this.setState({ email: event.target.value, }); - }, - onEmailSaved: function(email) { + } + + onEmailSaved(email) { this.props.setStage("confirm", { email: email }) - }, - handleSubmit: function(event) { + } + + handleSubmit(event) { event.preventDefault(); this.setState({ @@ -42,8 +47,9 @@ const SubmitEmailStage = React.createClass({ } this.setState({ submitting: false }); }); - }, - render: function() { + } + + render() { return (
@@ -57,23 +63,27 @@ const SubmitEmailStage = React.createClass({
); } -}); +} -const ConfirmEmailStage = React.createClass({ - getInitialState: function() { - return { +class ConfirmEmailStage extends React.Component { + constructor(props) { + super(props); + + this.state = { rewardType: null, code: '', submitting: false, errorMessage: null, }; - }, - handleCodeChanged: function(event) { + } + + handleCodeChanged(event) { this.setState({ code: event.target.value, }); - }, - handleSubmit: function(event) { + } + + handleSubmit(event) { event.preventDefault(); this.setState({ submitting: true, @@ -93,8 +103,9 @@ const ConfirmEmailStage = React.createClass({ onSubmitError(new Error("Your email is still not verified.")) //shouldn't happen? } }, onSubmitError); - }, - render: function() { + } + + render() { return (
@@ -111,25 +122,26 @@ const ConfirmEmailStage = React.createClass({
); } -}); +} -const WelcomeStage = React.createClass({ - propTypes: { - endAuth: React.PropTypes.func, - }, - getInitialState: function() { - return { +class WelcomeStage extends React.Component { + constructor(props) { + super(props); + + this.state = { hasReward: false, rewardAmount: null, - } - }, - onRewardClaim: function(reward) { + }; + } + + onRewardClaim(reward) { this.setState({ hasReward: true, rewardAmount: reward.amount }) - }, - render: function() { + } + + render() { return ( !this.state.hasReward ? @@ -156,11 +168,13 @@ const WelcomeStage = React.createClass({ ); } -}); +} +WelcomeStage.propTypes = { + endAuth: React.PropTypes.func, +}; - -const ErrorStage = React.createClass({ - render: function() { +class ErrorStage extends React.Component { + render() { return (

An error was encountered that we cannot continue from.

@@ -170,29 +184,32 @@ const ErrorStage = React.createClass({
); } -}); +} -const PendingStage = React.createClass({ - render: function() { +class PendingStage extends React.Component { + render() { return (

Preparing for first access

); } -}); +} -const CodeRequiredStage = React.createClass({ - _balanceSubscribeId: null, - getInitialState: function() { - return { +class CodeRequiredStage extends React.Component { + constructor(props) { + super(props); + + this._balanceSubscribeId = nullp + + this.state = { balance: 0, address: getLocal('wallet_address') - } - }, + }; + } - componentWillMount: function() { + componentWillMount() { this._balanceSubscribeId = lbry.balanceSubscribe((balance) => { this.setState({ balance: balance @@ -205,13 +222,15 @@ const CodeRequiredStage = React.createClass({ this.setState({ address: address }); }); } - }, - componentWillUnmount: function() { + } + + componentWillUnmount() { if (this._balanceSubscribeId) { lbry.balanceUnsubscribe(this._balanceSubscribeId) } - }, - render: function() { + } + + render() { const disabled = this.state.balance < 1; return (
@@ -234,31 +253,36 @@ const CodeRequiredStage = React.createClass({
); } -}); +} -export const AuthOverlay = React.createClass({ - _stages: { - pending: PendingStage, - error: ErrorStage, - nocode: CodeRequiredStage, - email: SubmitEmailStage, - confirm: ConfirmEmailStage, - welcome: WelcomeStage - }, - getInitialState: function() { - return { +export class AuthOverlay extends React.Component { + constructor(props) { + super(props); + + this._stages = { + pending: PendingStage, + error: ErrorStage, + nocode: CodeRequiredStage, + email: SubmitEmailStage, + confirm: ConfirmEmailStage, + welcome: WelcomeStage + } + + this.state = { stage: "pending", stageProps: {} }; - }, - setStage: function(stage, stageProps = {}) { + } + + setStage(stage, stageProps = {}) { this.setState({ stage: stage, stageProps: stageProps }) - }, - componentWillMount: function() { + } + + componentWillMount() { lbryio.authenticate().then((user) => { if (!user.HasVerifiedEmail) { if (getLocal('auth_bypassed')) { @@ -284,8 +308,9 @@ export const AuthOverlay = React.createClass({ } })); }) - }, - render: function() { + } + + render() { if (!this.state.stage) { return null; } @@ -299,4 +324,4 @@ export const AuthOverlay = React.createClass({ ); } -}); \ No newline at end of file +} \ No newline at end of file diff --git a/ui/js/component/common.js b/ui/js/component/common.js index aac91004a..d2e05d6f6 100644 --- a/ui/js/component/common.js +++ b/ui/js/component/common.js @@ -2,65 +2,69 @@ import React from 'react'; import lbry from '../lbry.js'; //component/icon.js -export let Icon = React.createClass({ - propTypes: { +export class Icon extends React.Component { + static propTypes = { icon: React.PropTypes.string.isRequired, className: React.PropTypes.string, fixed: React.PropTypes.bool, - }, - render: function() { + } + + static defaultProps = { + lines: null + } + + render() { const {fixed, className, ...other} = this.props; const spanClassName = ('icon ' + ('fixed' in this.props ? 'icon-fixed-width ' : '') + this.props.icon + ' ' + (this.props.className || '')); return } -}); +} -export let TruncatedText = React.createClass({ - propTypes: { - lines: React.PropTypes.number - }, - getDefaultProps: function() { - return { - lines: null, - } - }, - render: function() { +export class TruncatedText extends React.Component { + static propTypes = { + lines: React.PropTypes.number, + } + + render() { return {this.props.children}; } -}); +} -export let BusyMessage = React.createClass({ - propTypes: { - message: React.PropTypes.string - }, - render: function() { +export class BusyMessage extends React.Component { + static propTypes = { + message: React.PropTypes.string, + } + + render() { return {this.props.message} } -}); +} -export let CurrencySymbol = React.createClass({ - render: function() { return LBC; } -}); +export class CurrencySymbol extends React.Component { + render() { + return LBC; + } +} -export let CreditAmount = React.createClass({ - propTypes: { +export class CreditAmount extends React.Component { + static propTypes = { amount: React.PropTypes.number.isRequired, precision: React.PropTypes.number, isEstimate: React.PropTypes.bool, label: React.PropTypes.bool, showFree: React.PropTypes.bool, look: React.PropTypes.oneOf(['indicator', 'plain']), - }, - getDefaultProps: function() { - return { - precision: 1, - label: true, - showFree: false, - look: 'indicator', - } - }, - render: function() { + } + + static defaultProps = { + precision: 1, + label: true, + showFree: false, + look: 'indicator', + } + + render() { const formattedAmount = lbry.formatCredits(this.props.amount, this.props.precision); let amountText; if (this.props.showFree && parseFloat(formattedAmount) == 0) { @@ -80,45 +84,56 @@ export let CreditAmount = React.createClass({ ); } -}); +} -var addressStyle = { +let addressStyle = { fontFamily: '"Consolas", "Lucida Console", "Adobe Source Code Pro", monospace', }; -export let Address = React.createClass({ - _inputElem: null, - propTypes: { +export class Address extends React.Component { + static propTypes = { address: React.PropTypes.string, - }, - render: function() { + } + + constructor(props) { + super(props); + + this._inputElem = null; + } + + render() { return ( { this._inputElem = input; }} onFocus={() => { this._inputElem.select(); }} style={addressStyle} readOnly="readonly" value={this.props.address}> ); } -}); +} -export let Thumbnail = React.createClass({ - _defaultImageUri: lbry.imagePath('default-thumb.svg'), - _maxLoadTime: 10000, - _isMounted: false, - - propTypes: { +export class Thumbnail extends React.Component { + static propTypes = { src: React.PropTypes.string, - }, - handleError: function() { + } + + handleError() { if (this.state.imageUrl != this._defaultImageUri) { this.setState({ 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, }; - }, - componentDidMount: function() { + } + + componentDidMount() { this._isMounted = true; setTimeout(() => { if (this._isMounted && !this.refs.img.complete) { @@ -127,14 +142,16 @@ export let Thumbnail = React.createClass({ }); } }, this._maxLoadTime); - }, - componentWillUnmount: function() { + } + + componentWillUnmount() { this._isMounted = false; - }, - render: function() { + } + + render() { const className = this.props.className ? this.props.className : '', otherProps = Object.assign({}, this.props) delete otherProps.className; return - }, -}); + } +} diff --git a/ui/js/component/form.js b/ui/js/component/form.js index f75310c92..64946c31f 100644 --- a/ui/js/component/form.js +++ b/ui/js/component/form.js @@ -8,24 +8,28 @@ function formFieldId() { return "form-field-" + (++formFieldCounter); } -export let FormField = React.createClass({ - _fieldRequiredText: 'This field is required', - _type: null, - _element: null, - - propTypes: { +export class FormField extends React.Component { + static propTypes = { type: React.PropTypes.string.isRequired, prefix: React.PropTypes.string, postfix: React.PropTypes.string, 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, errorMessage: null, - } - }, - componentWillMount: function() { + }; + } + + componentWillMount() { if (['text', 'number', 'radio', 'checkbox', 'file'].includes(this.props.type)) { this._element = 'input'; this._type = this.props.type; @@ -36,17 +40,20 @@ export let FormField = React.createClass({ // Non field, e.g.