good chunk of progress towards auth and rewards refactor / degating
This commit is contained in:
parent
eb170b9720
commit
a17d19038e
18 changed files with 344 additions and 196 deletions
|
@ -26,20 +26,36 @@ export function doClaimReward(reward) {
|
|||
type: types.CLAIM_REWARD_STARTED,
|
||||
data: { reward }
|
||||
})
|
||||
try {
|
||||
const success = (a) => {
|
||||
console.log(a)
|
||||
dispatch({
|
||||
type: types.CLAIM_REWARD_COMPLETED,
|
||||
data: {
|
||||
a
|
||||
}
|
||||
})
|
||||
}
|
||||
const failure = (a) => console.error(a)
|
||||
rewards.claimReward(reward.reward_type).then(success, failure)
|
||||
} catch(err) {
|
||||
console.error(err)
|
||||
|
||||
const success = (a) => {
|
||||
console.log(a)
|
||||
dispatch({
|
||||
type: types.CLAIM_REWARD_SUCCESS,
|
||||
data: {
|
||||
a
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const failure = (error) => {
|
||||
dispatch({
|
||||
type: types.CLAIM_REWARD_FAILURE,
|
||||
data: {
|
||||
reward,
|
||||
error
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
rewards.claimReward(reward.reward_type).then(success, failure)
|
||||
}
|
||||
}
|
||||
|
||||
export function doClaimRewardClearError(reward) {
|
||||
return function(dispatch, getState) {
|
||||
dispatch({
|
||||
type: types.CLAIM_REWARD_CLEAR_ERROR,
|
||||
data: { reward }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
import * as types from 'constants/action_types'
|
||||
import lbryio from 'lbryio'
|
||||
import {
|
||||
setLocal
|
||||
} from 'utils'
|
||||
import {
|
||||
doFetchRewards
|
||||
} from 'actions/rewards'
|
||||
|
||||
export function doAuthenticate() {
|
||||
return function(dispatch, getState) {
|
||||
|
@ -18,4 +24,39 @@ export function doAuthenticate() {
|
|||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function doUserEmailNew(email) {
|
||||
return function(dispatch, getState) {
|
||||
dispatch({
|
||||
type: types.USER_EMAIL_NEW_STARTED,
|
||||
})
|
||||
lbryio.call('user_email', 'new', { email }, 'post').then(() => {
|
||||
dispatch({
|
||||
type: types.USER_EMAIL_NEW_SUCCESS,
|
||||
data: { email }
|
||||
})
|
||||
}, (error) => {
|
||||
if (error.xhr && (error.xhr.status == 409 || error.message == "This email is already in use")) {
|
||||
dispatch({
|
||||
type: types.USER_EMAIL_NEW_EXISTS,
|
||||
data: { email }
|
||||
})
|
||||
} else {
|
||||
dispatch({
|
||||
type: types.USER_EMAIL_NEW_FAILURE,
|
||||
data: { error: error.message }
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function doUserEmailDecline() {
|
||||
return function(dispatch, getState) {
|
||||
setLocal('user_email_declined', true)
|
||||
dispatch({
|
||||
type: types.USER_EMAIL_DECLINE,
|
||||
})
|
||||
}
|
||||
}
|
|
@ -3,19 +3,23 @@ import {
|
|||
connect
|
||||
} from 'react-redux'
|
||||
import {
|
||||
doStartUpgrade,
|
||||
doCancelUpgrade,
|
||||
} from 'actions/app'
|
||||
doUserEmailDecline
|
||||
} from 'actions/user'
|
||||
import {
|
||||
selectAuthenticationIsPending,
|
||||
selectEmailNewDeclined,
|
||||
selectUser,
|
||||
} from 'selectors/user'
|
||||
import AuthOverlay from './view'
|
||||
|
||||
const select = (state) => ({
|
||||
isPending: selectAuthenticationIsPending(state)
|
||||
isPending: selectAuthenticationIsPending(state),
|
||||
isEmailDeclined: selectEmailNewDeclined(state),
|
||||
user: selectUser(state),
|
||||
})
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
userEmailDecline: () => dispatch(doUserEmailDecline())
|
||||
})
|
||||
|
||||
export default connect(select, perform)(AuthOverlay)
|
||||
|
|
|
@ -5,73 +5,34 @@ import Modal from "component/modal.js";
|
|||
import ModalPage from "component/modal-page.js";
|
||||
import Link from "component/link"
|
||||
import {BusyMessage} from "component/common"
|
||||
import {RewardLink} from 'component/reward-link';
|
||||
import {RewardLink} from 'component/rewardLink';
|
||||
import UserEmailNew from 'component/userEmailNew';
|
||||
import {FormRow} from "component/form.js";
|
||||
import {CreditAmount, Address} from "component/common.js";
|
||||
import {getLocal, setLocal} from 'utils.js';
|
||||
import rewards from 'rewards'
|
||||
|
||||
|
||||
class SubmitEmailStage extends React.Component {
|
||||
class EmailStage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
rewardType: null,
|
||||
email: '',
|
||||
showNoEmailConfirm: false,
|
||||
submitting: false
|
||||
};
|
||||
}
|
||||
|
||||
handleEmailChanged(event) {
|
||||
this.setState({
|
||||
email: event.target.value,
|
||||
});
|
||||
}
|
||||
|
||||
onEmailSaved(email) {
|
||||
this.props.setStage("confirm", { email: email })
|
||||
}
|
||||
|
||||
onEmailSkipClick() {
|
||||
this.setState({ showNoEmailConfirm: true })
|
||||
}
|
||||
|
||||
onEmailSkipConfirm() {
|
||||
setLocal('auth_bypassed', true);
|
||||
this.props.setStage(null)
|
||||
}
|
||||
|
||||
handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
||||
this.setState({
|
||||
submitting: true,
|
||||
});
|
||||
lbryio.call('user_email', 'new', {email: this.state.email}, 'post').then(() => {
|
||||
this.onEmailSaved(this.state.email);
|
||||
}, (error) => {
|
||||
if (error.xhr && (error.xhr.status == 409 || error.message == "This email is already in use")) {
|
||||
this.onEmailSaved(this.state.email);
|
||||
return;
|
||||
} else if (this._emailRow) {
|
||||
this._emailRow.showError(error.message)
|
||||
}
|
||||
this.setState({ submitting: false });
|
||||
});
|
||||
this.props.userEmailDecline()
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<section>
|
||||
<form onSubmit={(event) => { this.handleSubmit(event) }}>
|
||||
<FormRow ref={(ref) => { this._emailRow = ref }} type="text" label="Email" placeholder="scrwvwls@lbry.io"
|
||||
name="email" value={this.state.email}
|
||||
onChange={(event) => { this.handleEmailChanged(event) }} />
|
||||
<div className="form-row-submit form-row-submit--with-footer">
|
||||
<Link button="primary" label="Next" disabled={this.state.submitting} onClick={(event) => { this.handleSubmit(event) }} />
|
||||
</div>
|
||||
<UserEmailNew />
|
||||
<div className="form-row-submit">
|
||||
{ this.state.showNoEmailConfirm ?
|
||||
<div>
|
||||
<p className="help form-input-width">If you continue without an email, you will be ineligible to earn free LBC rewards, as well as unable to receive security related communications.</p>
|
||||
|
@ -80,7 +41,7 @@ class SubmitEmailStage extends React.Component {
|
|||
:
|
||||
<Link className="button-text-help" onClick={ () => { this.onEmailSkipClick() }} label="Do I have to?" />
|
||||
}
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
@ -91,7 +52,6 @@ class ConfirmEmailStage extends React.Component {
|
|||
super(props);
|
||||
|
||||
this.state = {
|
||||
rewardType: null,
|
||||
code: '',
|
||||
submitting: false,
|
||||
errorMessage: null,
|
||||
|
@ -275,10 +235,8 @@ export class AuthOverlay extends React.Component {
|
|||
super(props);
|
||||
|
||||
this._stages = {
|
||||
pending: PendingStage,
|
||||
error: ErrorStage,
|
||||
nocode: CodeRequiredStage,
|
||||
email: SubmitEmailStage,
|
||||
confirm: ConfirmEmailStage,
|
||||
welcome: WelcomeStage
|
||||
}
|
||||
|
@ -320,21 +278,35 @@ export class AuthOverlay extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
let StageContent
|
||||
let stageContent
|
||||
|
||||
const {
|
||||
isPending,
|
||||
isEmailDeclined,
|
||||
user,
|
||||
userEmailDecline
|
||||
} = this.props
|
||||
|
||||
if (isPending) {
|
||||
StageContent = PendingStage;
|
||||
} else {
|
||||
console.log('auth overlay render')
|
||||
console.log(user)
|
||||
|
||||
if (isEmailDeclined) {
|
||||
return null
|
||||
StageContent = this._stages[this.state.stage];
|
||||
} else if (isPending) {
|
||||
stageContent = <PendingStage />;
|
||||
} else if (!user.has_email) {
|
||||
stageContent = <EmailStage userEmailDecline={userEmailDecline} />;
|
||||
}
|
||||
else {
|
||||
return null
|
||||
//StageContent = this._stages[this.state.stage];
|
||||
}
|
||||
|
||||
if (!StageContent) {
|
||||
return <span className="empty">Unknown authentication step.</span>
|
||||
}
|
||||
return <ModalPage className="modal-page--full" isOpen={true} contentLabel="Authentication">
|
||||
<h1>LBRY Early Access</h1>
|
||||
{stageContent}
|
||||
</ModalPage>;
|
||||
|
||||
//setStage={(stage, stageProps) => { this.setStage(stage, stageProps) }} {...this.state.stageProps}
|
||||
return (
|
||||
true || this.state.stage != "welcome" ?
|
||||
|
|
|
@ -179,8 +179,8 @@ export class FormRow extends React.Component {
|
|||
this._fieldRequiredText = __("This field is required");
|
||||
|
||||
this.state = {
|
||||
isError: false,
|
||||
errorMessage: null,
|
||||
isError: !!props.errorMessage,
|
||||
errorMessage: typeof props.errorMessage === "string" ? props.errorMessage : '',
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -225,6 +225,7 @@ export class FormRow extends React.Component {
|
|||
delete fieldProps.label;
|
||||
}
|
||||
delete fieldProps.helper;
|
||||
delete fieldProps.errorMessage;
|
||||
|
||||
return (
|
||||
<div className="form-row">
|
||||
|
|
|
@ -4,17 +4,24 @@ import {
|
|||
} from 'react-redux'
|
||||
import {
|
||||
makeSelectHasClaimedReward,
|
||||
makeSelectClaimRewardError,
|
||||
makeSelectIsRewardClaimPending
|
||||
} from 'selectors/rewards'
|
||||
import {
|
||||
doClaimReward,
|
||||
doClaimRewardClearError
|
||||
} from 'actions/rewards'
|
||||
import RewardLink from './view'
|
||||
|
||||
const makeSelect = () => {
|
||||
const selectHasClaimedReward = makeSelectHasClaimedReward()
|
||||
const selectIsPending = makeSelectIsRewardClaimPending()
|
||||
const selectError = makeSelectClaimRewardError()
|
||||
|
||||
const select = (state, props) => ({
|
||||
claimed: selectHasClaimedReward(state, props)
|
||||
isClaimed: selectHasClaimedReward(state, props),
|
||||
errorMessage: selectError(state, props),
|
||||
isPending: selectIsPending(state, props)
|
||||
})
|
||||
|
||||
return select
|
||||
|
@ -22,6 +29,7 @@ const makeSelect = () => {
|
|||
|
||||
const perform = (dispatch) => ({
|
||||
claimReward: (reward) => dispatch(doClaimReward(reward)),
|
||||
clearError: (reward) => dispatch(doClaimRewardClearError(reward))
|
||||
})
|
||||
|
||||
export default connect(makeSelect, perform)(RewardLink)
|
||||
|
|
|
@ -1,116 +1,27 @@
|
|||
import React from 'react';
|
||||
import lbry from 'lbry'
|
||||
import {Icon} from 'component/common';
|
||||
import Modal from 'component/modal';
|
||||
import rewards from 'rewards';
|
||||
import Link from 'component/link'
|
||||
|
||||
// class RewardLink extends React.Component {
|
||||
// static propTypes = {
|
||||
// type: React.PropTypes.string.isRequired,
|
||||
// claimed: React.PropTypes.bool,
|
||||
// onRewardClaim: React.PropTypes.func,
|
||||
// onRewardFailure: React.PropTypes.func
|
||||
// }
|
||||
|
||||
// constructor(props) {
|
||||
// super(props);
|
||||
|
||||
// this.state = {
|
||||
// claimable: true,
|
||||
// pending: false,
|
||||
// errorMessage: null
|
||||
// };
|
||||
// }
|
||||
|
||||
// refreshClaimable() {
|
||||
// switch(this.props.type) {
|
||||
// case 'new_user':
|
||||
// this.setState({ claimable: true });
|
||||
// return;
|
||||
|
||||
// case 'first_publish':
|
||||
// lbry.claim_list_mine().then((list) => {
|
||||
// this.setState({
|
||||
// claimable: list.length > 0
|
||||
// })
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
// componentWillMount() {
|
||||
// this.refreshClaimable();
|
||||
// }
|
||||
|
||||
// claimReward() {
|
||||
// this.setState({
|
||||
// pending: true
|
||||
// })
|
||||
|
||||
// rewards.claimReward(this.props.type).then((reward) => {
|
||||
// this.setState({
|
||||
// pending: false,
|
||||
// errorMessage: null
|
||||
// })
|
||||
// if (this.props.onRewardClaim) {
|
||||
// this.props.onRewardClaim(reward);
|
||||
// }
|
||||
// }).catch((error) => {
|
||||
// this.setState({
|
||||
// errorMessage: error.message,
|
||||
// pending: false
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
|
||||
// clearError() {
|
||||
// if (this.props.onRewardFailure) {
|
||||
// this.props.onRewardFailure()
|
||||
// }
|
||||
// this.setState({
|
||||
// errorMessage: null
|
||||
// })
|
||||
// }
|
||||
|
||||
// render() {
|
||||
// return (
|
||||
// <div className="reward-link">
|
||||
// {this.props.claimed
|
||||
// ? <span><Icon icon="icon-check" /> Reward claimed.</span>
|
||||
// : <Link button={this.props.button ? this.props.button : 'alt'} disabled={this.state.pending || !this.state.claimable }
|
||||
// label={ this.state.pending ? "Claiming..." : "Claim Reward"} onClick={() => { this.claimReward() }} />}
|
||||
// {this.state.errorMessage ?
|
||||
// <Modal isOpen={true} contentLabel="Reward Claim Error" className="error-modal" onConfirmed={() => { this.clearError() }}>
|
||||
// {this.state.errorMessage}
|
||||
// </Modal>
|
||||
// : ''}
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
const RewardLink = (props) => {
|
||||
const {
|
||||
reward,
|
||||
claimed,
|
||||
button,
|
||||
pending,
|
||||
claimable = true,
|
||||
claimReward,
|
||||
errorMessage,
|
||||
clearError,
|
||||
errorMessage,
|
||||
isClaimed,
|
||||
isPending
|
||||
} = props
|
||||
|
||||
console.log(props)
|
||||
return (
|
||||
<div className="reward-link">
|
||||
{claimed
|
||||
{isClaimed
|
||||
? <span><Icon icon="icon-check" /> Reward claimed.</span>
|
||||
: <Link button={button ? button : 'alt'} disabled={pending || !claimable }
|
||||
label={ pending ? "Claiming..." : "Claim Reward"} onClick={() => { claimReward(reward) }} />}
|
||||
: <Link button={button ? button : 'alt'} disabled={isPending}
|
||||
label={ isPending ? "Claiming..." : "Claim Reward"} onClick={() => { claimReward(reward) }} />}
|
||||
{errorMessage ?
|
||||
<Modal isOpen={true} contentLabel="Reward Claim Error" className="error-modal" onConfirmed={() => { clearError() }}>
|
||||
<Modal isOpen={true} contentLabel="Reward Claim Error" className="error-modal" onConfirmed={() => { clearError(reward) }}>
|
||||
{errorMessage}
|
||||
</Modal>
|
||||
: ''}
|
||||
|
|
23
ui/js/component/userEmailNew/index.jsx
Normal file
23
ui/js/component/userEmailNew/index.jsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
connect
|
||||
} from 'react-redux'
|
||||
import {
|
||||
doUserEmailNew
|
||||
} from 'actions/user'
|
||||
import {
|
||||
selectEmailNewIsPending,
|
||||
selectEmailNewErrorMessage,
|
||||
} from 'selectors/user'
|
||||
import UserEmailNew from './view'
|
||||
|
||||
const select = (state) => ({
|
||||
isPending: selectEmailNewIsPending(state),
|
||||
errorMessage: selectEmailNewErrorMessage(state),
|
||||
})
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
addUserEmail: (email) => dispatch(doUserEmailNew(email))
|
||||
})
|
||||
|
||||
export default connect(select, perform)(UserEmailNew)
|
43
ui/js/component/userEmailNew/view.jsx
Normal file
43
ui/js/component/userEmailNew/view.jsx
Normal file
|
@ -0,0 +1,43 @@
|
|||
import React from 'react';
|
||||
import Link from 'component/link';
|
||||
import {FormRow} from 'component/form.js';
|
||||
|
||||
class UserEmailNew extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
email: ''
|
||||
};
|
||||
}
|
||||
|
||||
handleEmailChanged(event) {
|
||||
this.setState({
|
||||
email: event.target.value,
|
||||
});
|
||||
}
|
||||
|
||||
handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
this.props.addUserEmail(this.state.email)
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
errorMessage,
|
||||
isPending
|
||||
} = this.props
|
||||
|
||||
return <form onSubmit={(event) => { this.handleSubmit(event) }}>
|
||||
<FormRow type="text" label="Email" placeholder="scrwvwls@lbry.io"
|
||||
name="email" value={this.state.email}
|
||||
errorMessage={errorMessage}
|
||||
onChange={(event) => { this.handleEmailChanged(event) }} />
|
||||
<div className="form-row-submit">
|
||||
<Link button="primary" label="Next" disabled={isPending} onClick={(event) => { this.handleSubmit(event) }} />
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
|
||||
export default UserEmailNew
|
|
@ -74,10 +74,16 @@ export const DAEMON_SETTINGS_RECEIVED = "DAEMON_SETTINGS_RECEIVED";
|
|||
export const AUTHENTICATION_STARTED = 'AUTHENTICATION_STARTED'
|
||||
export const AUTHENTICATION_SUCCESS = 'AUTHENTICATION_SUCCESS'
|
||||
export const AUTHENTICATION_FAILURE = 'AUTHENTICATION_FAILURE'
|
||||
export const USER_EMAIL_DECLINE = 'USER_EMAIL_DECLINE'
|
||||
export const USER_EMAIL_NEW_STARTED = 'USER_EMAIL_NEW_STARTED'
|
||||
export const USER_EMAIL_NEW_SUCCESS = 'USER_EMAIL_NEW_SUCCESS'
|
||||
export const USER_EMAIL_NEW_EXISTS = 'USER_EMAIL_NEW_EXISTS'
|
||||
export const USER_EMAIL_NEW_FAILURE = 'USER_EMAIL_NEW_FAILURE'
|
||||
|
||||
// Rewards
|
||||
export const FETCH_REWARDS_STARTED = 'FETCH_REWARDS_STARTED'
|
||||
export const FETCH_REWARDS_COMPLETED = 'FETCH_REWARDS_COMPLETED'
|
||||
export const CLAIM_REWARD_STARTED = 'CLAIM_REWARD_STARTED'
|
||||
export const CLAIM_REWARD_COMPLETED = 'CLAIM_REWARD_COMPLETED'
|
||||
|
||||
export const CLAIM_REWARD_SUCCESS = 'CLAIM_REWARD_SUCCESS'
|
||||
export const CLAIM_REWARD_FAILURE = 'CLAIM_REWARD_FAILURE'
|
||||
export const CLAIM_REWARD_CLEAR_ERROR = 'CLAIM_REWARD_CLEAR_ERROR'
|
||||
|
|
|
@ -144,7 +144,7 @@ lbryio.authenticate = function() {
|
|||
lbryio._authenticationPromise = new Promise((resolve, reject) => {
|
||||
lbry.status().then((response) => {
|
||||
|
||||
let installation_id = response.installation_id.substring(0, response.installation_id.length - 6) + "C";
|
||||
let installation_id = response.installation_id.substring(0, response.installation_id.length - 2) + "D";
|
||||
|
||||
function setCurrentUser() {
|
||||
lbryio.call('user', 'me').then((data) => {
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
} from 'react-redux'
|
||||
import {
|
||||
selectFetchingRewards,
|
||||
selectIsRewardEligible,
|
||||
selectRewards,
|
||||
} from 'selectors/rewards'
|
||||
import RewardsPage from './view'
|
||||
|
|
|
@ -16,7 +16,7 @@ const RewardTile = (props) => {
|
|||
<div className="card__inner">
|
||||
<div className="card__title-primary">
|
||||
<CreditAmount amount={reward.reward_amount} />
|
||||
<h3>{reward.title}</h3>
|
||||
<h3>{reward.reward_title}</h3>
|
||||
</div>
|
||||
<div className="card__actions">
|
||||
{claimed
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import * as types from "constants/action_types";
|
||||
|
||||
const reducers = {};
|
||||
const defaultState = {};
|
||||
const reducers = {}
|
||||
const defaultState = {
|
||||
fetching: false,
|
||||
claimPendingByType: {},
|
||||
claimErrorsByType: {}
|
||||
};
|
||||
|
||||
reducers[types.FETCH_REWARDS_STARTED] = function(state, action) {
|
||||
const newRewards = Object.assign({}, state.rewards, {
|
||||
|
@ -26,28 +30,49 @@ reducers[types.FETCH_REWARDS_COMPLETED] = function(state, action) {
|
|||
return Object.assign({}, state, newRewards)
|
||||
}
|
||||
|
||||
function setClaimRewardState(state, reward, isClaiming, errorMessage="") {
|
||||
const newClaimPendingByType = Object.assign({}, state.claimPendingByType)
|
||||
const newClaimErrorsByType = Object.assign({}, state.claimErrorsByType)
|
||||
newClaimPendingByType[reward.reward_type] = isClaiming
|
||||
newClaimErrorsByType[reward.reward_type] = errorMessage
|
||||
|
||||
return Object.assign({}, state, {
|
||||
claimPendingByType: newClaimPendingByType,
|
||||
claimErrorsByType: newClaimErrorsByType,
|
||||
})
|
||||
}
|
||||
|
||||
reducers[types.CLAIM_REWARD_STARTED] = function(state, action) {
|
||||
const {
|
||||
reward,
|
||||
} = action.data
|
||||
|
||||
const newRewards = Object.assign({}, state, {
|
||||
claiming: true,
|
||||
})
|
||||
|
||||
return Object.assign({}, state, newRewards)
|
||||
return setClaimRewardState(state, reward, true, "")
|
||||
}
|
||||
|
||||
reducers[types.CLAIM_REWARD_COMPLETED] = function(state, action) {
|
||||
reducers[types.CLAIM_REWARD_SUCCESS] = function(state, action) {
|
||||
const {
|
||||
reward,
|
||||
} = action.data
|
||||
|
||||
const newRewards = Object.assign({}, state, {
|
||||
claiming: false,
|
||||
})
|
||||
return setClaimRewardState(state, reward, false, "")
|
||||
}
|
||||
|
||||
return Object.assign({}, state, newRewards)
|
||||
reducers[types.CLAIM_REWARD_FAILURE] = function(state, action) {
|
||||
const {
|
||||
reward,
|
||||
error
|
||||
} = action.data
|
||||
|
||||
return setClaimRewardState(state, reward, false, error.message)
|
||||
}
|
||||
|
||||
reducers[types.CLAIM_REWARD_CLEAR_ERROR] = function(state, action) {
|
||||
const {
|
||||
reward
|
||||
} = action.data
|
||||
|
||||
return setClaimRewardState(state, reward, state.claimPendingByType[reward.reward_type], "")
|
||||
}
|
||||
|
||||
export default function reducer(state = defaultState, action) {
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
import * as types from 'constants/action_types'
|
||||
import {
|
||||
getLocal
|
||||
} from 'utils'
|
||||
|
||||
const reducers = {}
|
||||
|
||||
const defaultState = {
|
||||
authenticationIsPending: false,
|
||||
emailNewIsPending: false,
|
||||
emailNewErrorMessage: '',
|
||||
emailNewDeclined: getLocal('user_email_declined', false),
|
||||
user: undefined
|
||||
}
|
||||
|
||||
|
@ -27,6 +33,40 @@ reducers[types.AUTHENTICATION_FAILURE] = function(state, action) {
|
|||
})
|
||||
}
|
||||
|
||||
reducers[types.USER_EMAIL_DECLINE] = function(state, action) {
|
||||
return Object.assign({}, state, {
|
||||
emailNewDeclined: true
|
||||
})
|
||||
}
|
||||
|
||||
reducers[types.USER_EMAIL_NEW_STARTED] = function(state, action) {
|
||||
return Object.assign({}, state, {
|
||||
emailNewIsPending: true,
|
||||
emailNewErrorMessage: ''
|
||||
})
|
||||
}
|
||||
|
||||
reducers[types.USER_EMAIL_NEW_SUCCESS] = function(state, action) {
|
||||
return Object.assign({}, state, {
|
||||
emailNewIsPending: false,
|
||||
})
|
||||
}
|
||||
|
||||
reducers[types.USER_EMAIL_NEW_EXISTS] = function(state, action) {
|
||||
return Object.assign({}, state, {
|
||||
emailNewIsPending: false,
|
||||
})
|
||||
}
|
||||
|
||||
reducers[types.USER_EMAIL_NEW_FAILURE] = function(state, action) {
|
||||
return Object.assign({}, state, {
|
||||
emailNewIsPending: false,
|
||||
emailNewErrorMessage: action.data.error
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
export default function reducer(state = defaultState, action) {
|
||||
const handler = reducers[action.type];
|
||||
if (handler) return handler(state, action);
|
||||
|
|
|
@ -93,7 +93,7 @@ rewards.TYPE_FEATURED_DOWNLOAD = 'featured_download';
|
|||
|
||||
rewards.claimReward = function(type) {
|
||||
function requestReward(resolve, reject, params) {
|
||||
if (!lbryio.enabled) {
|
||||
if (!lbryio.enabled || !lbryio.getAccessToken()) {
|
||||
reject(new Error(__('Rewards are not enabled.')));
|
||||
return;
|
||||
}
|
||||
|
@ -193,7 +193,10 @@ rewards.claimReward = function(type) {
|
|||
});
|
||||
};
|
||||
|
||||
rewards.claimEligiblePurchaseRewards = function() {
|
||||
rewards.claimEligiblePurchaseRewards = () => {
|
||||
if (!lbryio.enabled || !lbryio.getAccessToken()) {
|
||||
return;
|
||||
}
|
||||
let types = {};
|
||||
types[rewards.TYPE_FIRST_STREAM] = false;
|
||||
types[rewards.TYPE_FEATURED_DOWNLOAD] = false;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { createSelector } from "reselect";
|
||||
import { selectUser } from "selectors/user";
|
||||
|
||||
const _selectState = state => state.rewards || {};
|
||||
|
||||
|
@ -12,6 +13,11 @@ export const selectRewards = createSelector(
|
|||
(byType) => Object.values(byType) || []
|
||||
)
|
||||
|
||||
export const selectIsRewardEligible = createSelector(
|
||||
selectUser,
|
||||
(user) => user.can_claim_rewards
|
||||
)
|
||||
|
||||
export const selectClaimedRewards = createSelector(
|
||||
selectRewards,
|
||||
(rewards) => rewards.filter(reward => reward.transaction_id !== "")
|
||||
|
@ -20,7 +26,7 @@ export const selectClaimedRewards = createSelector(
|
|||
export const selectClaimedRewardsByType = createSelector(
|
||||
selectClaimedRewards,
|
||||
(claimedRewards) => {
|
||||
const byType = []
|
||||
const byType = {}
|
||||
claimedRewards.forEach(reward => byType[reward.reward_type] = reward)
|
||||
return byType
|
||||
}
|
||||
|
@ -42,6 +48,39 @@ export const makeSelectHasClaimedReward = () => {
|
|||
)
|
||||
}
|
||||
|
||||
export const selectClaimsPendingByType = createSelector(
|
||||
_selectState,
|
||||
(state) => state.claimPendingByType
|
||||
)
|
||||
|
||||
const selectIsClaimRewardPending = (state, props) => {
|
||||
return selectClaimsPendingByType(state, props)[props.reward.reward_type]
|
||||
}
|
||||
|
||||
export const makeSelectIsRewardClaimPending = () => {
|
||||
return createSelector(
|
||||
selectIsClaimRewardPending,
|
||||
(isClaiming) => isClaiming
|
||||
)
|
||||
}
|
||||
|
||||
export const selectClaimErrorsByType = createSelector(
|
||||
_selectState,
|
||||
(state) => state.claimErrorsByType
|
||||
)
|
||||
|
||||
const selectClaimRewardError = (state, props) => {
|
||||
console.log(selectClaimErrorsByType(state, props));
|
||||
return selectClaimErrorsByType(state, props)[props.reward.reward_type]
|
||||
}
|
||||
|
||||
export const makeSelectClaimRewardError = () => {
|
||||
return createSelector(
|
||||
selectClaimRewardError,
|
||||
(errorMessage) => errorMessage
|
||||
)
|
||||
}
|
||||
|
||||
const selectRewardByType = (state, props) => {
|
||||
return selectRewardsByType(state)[props.reward_type]
|
||||
}
|
||||
|
|
|
@ -7,7 +7,22 @@ export const selectAuthenticationIsPending = createSelector(
|
|||
(state) => state.authenticationIsPending
|
||||
)
|
||||
|
||||
export const selectAuthenticationIsFailed = createSelector(
|
||||
export const selectUser = createSelector(
|
||||
_selectState,
|
||||
(state) => state.user === null
|
||||
(state) => state.user
|
||||
)
|
||||
|
||||
export const selectEmailNewIsPending = createSelector(
|
||||
_selectState,
|
||||
(state) => state.emailNewIsPending
|
||||
)
|
||||
|
||||
export const selectEmailNewErrorMessage = createSelector(
|
||||
_selectState,
|
||||
(state) => state.emailNewErrorMessage
|
||||
)
|
||||
|
||||
export const selectEmailNewDeclined = createSelector(
|
||||
_selectState,
|
||||
(state) => state.emailNewDeclined
|
||||
)
|
Loading…
Reference in a new issue