commit
b054bc096e
45 changed files with 200 additions and 1347 deletions
|
@ -17,10 +17,10 @@ module.name_mapper='^types\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/types\1'
|
||||||
module.name_mapper='^component\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/component\1'
|
module.name_mapper='^component\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/component\1'
|
||||||
module.name_mapper='^page\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/page\1'
|
module.name_mapper='^page\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/page\1'
|
||||||
module.name_mapper='^lbry\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/lbry\1'
|
module.name_mapper='^lbry\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/lbry\1'
|
||||||
module.name_mapper='^rewards\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/rewards\1'
|
|
||||||
module.name_mapper='^modal\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/modal\1'
|
module.name_mapper='^modal\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/modal\1'
|
||||||
module.name_mapper='^app\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/app\1'
|
module.name_mapper='^app\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/app\1'
|
||||||
module.name_mapper='^native\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/native\1'
|
module.name_mapper='^native\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/native\1'
|
||||||
module.name_mapper='^analytics\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/analytics\1'
|
module.name_mapper='^analytics\(.*\)$' -> '<PROJECT_ROOT>/src/renderer/analytics\1'
|
||||||
|
|
||||||
|
|
||||||
[strict]
|
[strict]
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
"hast-util-sanitize": "^1.1.2",
|
"hast-util-sanitize": "^1.1.2",
|
||||||
"keytar": "^4.2.1",
|
"keytar": "^4.2.1",
|
||||||
"lbry-redux": "lbryio/lbry-redux#d1cee82af119c0c5f98ec27f94b2e7f61e34b54c",
|
"lbry-redux": "lbryio/lbry-redux#d1cee82af119c0c5f98ec27f94b2e7f61e34b54c",
|
||||||
|
"lbryinc": "lbryio/lbryinc#c09aa2645ecccb33c83e9a9545ff119232910f6f",
|
||||||
"localforage": "^1.7.1",
|
"localforage": "^1.7.1",
|
||||||
"mammoth": "^1.4.6",
|
"mammoth": "^1.4.6",
|
||||||
"mime": "^2.3.1",
|
"mime": "^2.3.1",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
import mixpanel from 'mixpanel-browser';
|
import mixpanel from 'mixpanel-browser';
|
||||||
import Lbryio from 'lbryio';
|
import { Lbryio } from 'lbryinc';
|
||||||
import isDev from 'electron-is-dev';
|
import isDev from 'electron-is-dev';
|
||||||
|
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
|
|
|
@ -38,4 +38,7 @@ global.__ = i18n.__;
|
||||||
global.__n = i18n.__n;
|
global.__n = i18n.__n;
|
||||||
global.app = app;
|
global.app = app;
|
||||||
|
|
||||||
|
// Lbryinc needs access to the redux store for dispatching auth-releated actions
|
||||||
|
global.store = app.store;
|
||||||
|
|
||||||
export default app;
|
export default app;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectPageTitle, selectHistoryIndex, selectActiveHistoryEntry } from 'lbry-redux';
|
import { selectPageTitle, selectHistoryIndex, selectActiveHistoryEntry } from 'lbry-redux';
|
||||||
import { doRecordScroll } from 'redux/actions/navigation';
|
import { doRecordScroll } from 'redux/actions/navigation';
|
||||||
import { selectUser } from 'redux/selectors/user';
|
import { selectUser } from 'lbryinc';
|
||||||
import { doAlertError } from 'redux/actions/app';
|
import { doAlertError } from 'redux/actions/app';
|
||||||
import App from './view';
|
import App from './view';
|
||||||
|
|
||||||
|
@ -17,4 +17,7 @@ const perform = dispatch => ({
|
||||||
recordScroll: scrollPosition => dispatch(doRecordScroll(scrollPosition)),
|
recordScroll: scrollPosition => dispatch(doRecordScroll(scrollPosition)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(App);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(App);
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectUserEmail } from 'redux/selectors/user';
|
import { selectUserEmail } from 'lbryinc';
|
||||||
import CardVerify from './view';
|
import CardVerify from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
email: selectUserEmail(state),
|
email: selectUserEmail(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({});
|
const perform = () => ({});
|
||||||
|
|
||||||
export default connect(select, perform)(CardVerify);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(CardVerify);
|
||||||
|
|
|
@ -3,6 +3,7 @@ import * as settings from 'constants/settings';
|
||||||
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, savePosition } from 'redux/actions/content';
|
import { doPlayUri, doSetPlayingUri, savePosition } from 'redux/actions/content';
|
||||||
|
import { doClaimEligiblePurchaseRewards } from 'lbryinc';
|
||||||
import {
|
import {
|
||||||
makeSelectMetadataForUri,
|
makeSelectMetadataForUri,
|
||||||
makeSelectContentTypeForUri,
|
makeSelectContentTypeForUri,
|
||||||
|
@ -13,7 +14,6 @@ import {
|
||||||
makeSelectDownloadingForUri,
|
makeSelectDownloadingForUri,
|
||||||
selectSearchBarFocused,
|
selectSearchBarFocused,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { doClaimEligiblePurchaseRewards } from 'redux/actions/rewards';
|
|
||||||
import { makeSelectClientSetting, selectShowNsfw } from 'redux/selectors/settings';
|
import { makeSelectClientSetting, selectShowNsfw } from 'redux/selectors/settings';
|
||||||
import { selectPlayingUri, makeSelectContentPositionForUri } from 'redux/selectors/content';
|
import { selectPlayingUri, makeSelectContentPositionForUri } from 'redux/selectors/content';
|
||||||
import { selectFileInfoErrors } from 'redux/selectors/file_info';
|
import { selectFileInfoErrors } from 'redux/selectors/file_info';
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectUserInvitees, selectUserInviteStatusIsPending } from 'redux/selectors/user';
|
import { selectUserInvitees, selectUserInviteStatusIsPending } from 'lbryinc';
|
||||||
import InviteList from './view';
|
import InviteList from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
@ -8,6 +7,9 @@ const select = state => ({
|
||||||
isPending: selectUserInviteStatusIsPending(state),
|
isPending: selectUserInviteStatusIsPending(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({});
|
const perform = () => ({});
|
||||||
|
|
||||||
export default connect(select, perform)(InviteList);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(InviteList);
|
||||||
|
|
|
@ -1,10 +1,20 @@
|
||||||
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import RewardLink from 'component/rewardLink';
|
import RewardLink from 'component/rewardLink';
|
||||||
import rewards from 'rewards.js';
|
import { rewards } from 'lbryinc';
|
||||||
import * as icons from 'constants/icons';
|
import * as icons from 'constants/icons';
|
||||||
|
|
||||||
class InviteList extends React.PureComponent {
|
type Props = {
|
||||||
|
invitees: ?Array<{
|
||||||
|
email: string,
|
||||||
|
invite_accepted: boolean,
|
||||||
|
invite_reward_claimed: boolean,
|
||||||
|
invite_reward_claimable: boolean,
|
||||||
|
}>,
|
||||||
|
};
|
||||||
|
|
||||||
|
class InviteList extends React.PureComponent<Props> {
|
||||||
render() {
|
render() {
|
||||||
const { invitees } = this.props;
|
const { invitees } = this.props;
|
||||||
|
|
||||||
|
@ -31,8 +41,8 @@ class InviteList extends React.PureComponent {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{invitees.map((invitee, index) => (
|
{invitees.map(invitee => (
|
||||||
<tr key={index}>
|
<tr key={invitee.email}>
|
||||||
<td>{invitee.email}</td>
|
<td>{invitee.email}</td>
|
||||||
<td className="text-center">
|
<td className="text-center">
|
||||||
{invitee.invite_accepted ? (
|
{invitee.invite_accepted ? (
|
||||||
|
|
|
@ -3,8 +3,8 @@ import {
|
||||||
selectUserInvitesRemaining,
|
selectUserInvitesRemaining,
|
||||||
selectUserInviteNewIsPending,
|
selectUserInviteNewIsPending,
|
||||||
selectUserInviteNewErrorMessage,
|
selectUserInviteNewErrorMessage,
|
||||||
} from 'redux/selectors/user';
|
doUserInviteNew,
|
||||||
import { doUserInviteNew } from 'redux/actions/user';
|
} from 'lbryinc';
|
||||||
import InviteNew from './view';
|
import InviteNew from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
@ -17,4 +17,7 @@ const perform = dispatch => ({
|
||||||
inviteNew: email => dispatch(doUserInviteNew(email)),
|
inviteNew: email => dispatch(doUserInviteNew(email)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(InviteNew);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(InviteNew);
|
||||||
|
|
|
@ -3,9 +3,10 @@ import {
|
||||||
makeSelectClaimRewardError,
|
makeSelectClaimRewardError,
|
||||||
makeSelectRewardByType,
|
makeSelectRewardByType,
|
||||||
makeSelectIsRewardClaimPending,
|
makeSelectIsRewardClaimPending,
|
||||||
} from 'redux/selectors/rewards';
|
doClaimRewardType,
|
||||||
|
doClaimRewardClearError,
|
||||||
|
} from 'lbryinc';
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import { doClaimRewardType, doClaimRewardClearError } from 'redux/actions/rewards';
|
|
||||||
import RewardLink from './view';
|
import RewardLink from './view';
|
||||||
|
|
||||||
const makeSelect = () => {
|
const makeSelect = () => {
|
||||||
|
@ -28,4 +29,7 @@ const perform = dispatch => ({
|
||||||
navigate: path => dispatch(doNavigate(path)),
|
navigate: path => dispatch(doNavigate(path)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(makeSelect, perform)(RewardLink);
|
export default connect(
|
||||||
|
makeSelect,
|
||||||
|
perform
|
||||||
|
)(RewardLink);
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectClaimedRewards } from 'redux/selectors/rewards';
|
import { selectClaimedRewards } from 'lbryinc';
|
||||||
import RewardListClaimed from './view';
|
import RewardListClaimed from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
rewards: selectClaimedRewards(state),
|
rewards: selectClaimedRewards(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, null)(RewardListClaimed);
|
export default connect(
|
||||||
|
select,
|
||||||
|
null
|
||||||
|
)(RewardListClaimed);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectUnclaimedRewardValue, selectFetchingRewards } from 'redux/selectors/rewards';
|
import { selectUnclaimedRewardValue, selectFetchingRewards, doRewardList } from 'lbryinc';
|
||||||
import { doRewardList } from 'redux/actions/rewards';
|
|
||||||
import { doFetchRewardedContent } from 'redux/actions/content';
|
import { doFetchRewardedContent } from 'redux/actions/content';
|
||||||
import RewardSummary from './view';
|
import RewardSummary from './view';
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import React from 'react';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import RewardLink from 'component/rewardLink';
|
import RewardLink from 'component/rewardLink';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import rewards from 'rewards';
|
import { rewards } from 'lbryinc';
|
||||||
import * as icons from 'constants/icons';
|
import * as icons from 'constants/icons';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectClaimedRewardsByTransactionId } from 'redux/selectors/rewards';
|
import { selectClaimedRewardsByTransactionId } from 'lbryinc';
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import { doNotify } from 'lbry-redux';
|
import { selectAllMyClaimsByOutpoint, doNotify } from 'lbry-redux';
|
||||||
import { selectAllMyClaimsByOutpoint } from 'lbry-redux';
|
|
||||||
import TransactionList from './view';
|
import TransactionList from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
@ -15,4 +14,7 @@ const perform = dispatch => ({
|
||||||
openModal: (modal, props) => dispatch(doNotify(modal, props)),
|
openModal: (modal, props) => dispatch(doNotify(modal, props)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(TransactionList);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(TransactionList);
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doUserEmailNew, doUserInviteNew } from 'redux/actions/user';
|
import { selectEmailNewIsPending, selectEmailNewErrorMessage, doUserEmailNew } from 'lbryinc';
|
||||||
import { selectEmailNewIsPending, selectEmailNewErrorMessage } from 'redux/selectors/user';
|
|
||||||
import UserEmailNew from './view';
|
import UserEmailNew from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
@ -13,4 +11,7 @@ const perform = dispatch => ({
|
||||||
addUserEmail: email => dispatch(doUserEmailNew(email)),
|
addUserEmail: email => dispatch(doUserEmailNew(email)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(UserEmailNew);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(UserEmailNew);
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import {
|
|
||||||
doUserEmailVerify,
|
|
||||||
doUserEmailVerifyFailure,
|
|
||||||
doUserResendVerificationEmail,
|
|
||||||
} from 'redux/actions/user';
|
|
||||||
import {
|
import {
|
||||||
selectEmailVerifyIsPending,
|
selectEmailVerifyIsPending,
|
||||||
selectEmailToVerify,
|
selectEmailToVerify,
|
||||||
selectEmailVerifyErrorMessage,
|
selectEmailVerifyErrorMessage,
|
||||||
} from 'redux/selectors/user';
|
doUserEmailVerify,
|
||||||
|
doUserEmailVerifyFailure,
|
||||||
|
doUserResendVerificationEmail,
|
||||||
|
} from 'lbryinc';
|
||||||
import UserEmailVerify from './view';
|
import UserEmailVerify from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
@ -23,4 +21,7 @@ const perform = dispatch => ({
|
||||||
resendVerificationEmail: email => dispatch(doUserResendVerificationEmail(email)),
|
resendVerificationEmail: email => dispatch(doUserResendVerificationEmail(email)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(UserEmailVerify);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(UserEmailVerify);
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doUserPhoneNew } from 'redux/actions/user';
|
import { selectPhoneNewErrorMessage, doUserPhoneNew } from 'lbryinc';
|
||||||
import { selectPhoneNewErrorMessage } from 'redux/selectors/user';
|
|
||||||
import UserPhoneNew from './view';
|
import UserPhoneNew from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
@ -9,7 +7,10 @@ const select = state => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
addUserPhone: (phone, country_code) => dispatch(doUserPhoneNew(phone, country_code)),
|
addUserPhone: (phone, countryCode) => dispatch(doUserPhoneNew(phone, countryCode)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(UserPhoneNew);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(UserPhoneNew);
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doUserPhoneVerify, doUserPhoneReset } from 'redux/actions/user';
|
|
||||||
import {
|
import {
|
||||||
|
doUserPhoneVerify,
|
||||||
|
doUserPhoneReset,
|
||||||
selectPhoneToVerify,
|
selectPhoneToVerify,
|
||||||
selectPhoneVerifyErrorMessage,
|
selectPhoneVerifyErrorMessage,
|
||||||
selectUserCountryCode,
|
selectUserCountryCode,
|
||||||
} from 'redux/selectors/user';
|
} from 'lbryinc';
|
||||||
import UserPhoneVerify from './view';
|
import UserPhoneVerify from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
@ -19,4 +19,7 @@ const perform = dispatch => ({
|
||||||
verifyUserPhone: code => dispatch(doUserPhoneVerify(code)),
|
verifyUserPhone: code => dispatch(doUserPhoneVerify(code)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(UserPhoneVerify);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(UserPhoneVerify);
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doNotify, MODALS } from 'lbry-redux';
|
import { doNotify, MODALS } from 'lbry-redux';
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import { doUserIdentityVerify } from 'redux/actions/user';
|
|
||||||
import rewards from 'rewards';
|
|
||||||
import { makeSelectRewardByType } from 'redux/selectors/rewards';
|
|
||||||
import {
|
import {
|
||||||
|
doUserIdentityVerify,
|
||||||
|
rewards,
|
||||||
|
makeSelectRewardByType,
|
||||||
selectIdentityVerifyIsPending,
|
selectIdentityVerifyIsPending,
|
||||||
selectIdentityVerifyErrorMessage,
|
selectIdentityVerifyErrorMessage,
|
||||||
} from 'redux/selectors/user';
|
} from 'lbryinc';
|
||||||
import UserVerify from './view';
|
import UserVerify from './view';
|
||||||
|
|
||||||
const select = state => {
|
const select = state => {
|
||||||
|
@ -26,4 +26,7 @@ const perform = dispatch => ({
|
||||||
verifyPhone: () => dispatch(doNotify({ id: MODALS.PHONE_COLLECTION })),
|
verifyPhone: () => dispatch(doNotify({ id: MODALS.PHONE_COLLECTION })),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(UserVerify);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(UserVerify);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import CardVerify from 'component/cardVerify';
|
import CardVerify from 'component/cardVerify';
|
||||||
import lbryio from 'lbryio';
|
import Lbryio from 'lbryinc';
|
||||||
import * as icons from 'constants/icons';
|
import * as icons from 'constants/icons';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -51,7 +51,7 @@ class UserVerify extends React.PureComponent<Props> {
|
||||||
label={__('Perform Card Verification')}
|
label={__('Perform Card Verification')}
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
token={this.onToken}
|
token={this.onToken}
|
||||||
stripeKey={lbryio.getStripeToken()}
|
stripeKey={Lbryio.getStripeToken()}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
|
|
|
@ -11,9 +11,10 @@ import { doConditionalAuthNavigate, doDaemonReady, doAutoUpdate } from 'redux/ac
|
||||||
import { doNotify, doBlackListedOutpointsSubscribe, isURIValid } from 'lbry-redux';
|
import { doNotify, doBlackListedOutpointsSubscribe, isURIValid } from 'lbry-redux';
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import { doDownloadLanguages, doUpdateIsNightAsync } from 'redux/actions/settings';
|
import { doDownloadLanguages, doUpdateIsNightAsync } from 'redux/actions/settings';
|
||||||
import { doUserEmailVerify, doAuthenticate } from 'redux/actions/user';
|
import { doUserEmailVerify, doAuthenticate, Lbryio } from 'lbryinc';
|
||||||
import 'scss/all.scss';
|
import 'scss/all.scss';
|
||||||
import store from 'store';
|
import store from 'store';
|
||||||
|
import pjson from 'package.json';
|
||||||
import app from './app';
|
import app from './app';
|
||||||
import analytics from './analytics';
|
import analytics from './analytics';
|
||||||
import doLogWarningConsoleMessage from './logWarningConsoleMessage';
|
import doLogWarningConsoleMessage from './logWarningConsoleMessage';
|
||||||
|
@ -23,6 +24,40 @@ const APPPAGEURL = 'lbry://?';
|
||||||
|
|
||||||
autoUpdater.logger = remote.require('electron-log');
|
autoUpdater.logger = remote.require('electron-log');
|
||||||
|
|
||||||
|
// We need to override Lbryio for getting/setting the authToken
|
||||||
|
// We interect with ipcRenderer to get the auth key from a users keyring
|
||||||
|
Lbryio.setOverride('setAuthToken', status => {
|
||||||
|
Lbryio.call(
|
||||||
|
'user',
|
||||||
|
'new',
|
||||||
|
{
|
||||||
|
auth_token: '',
|
||||||
|
language: 'en',
|
||||||
|
app_id: status.installation_id,
|
||||||
|
},
|
||||||
|
'post'
|
||||||
|
).then(response => {
|
||||||
|
if (!response.auth_token) {
|
||||||
|
throw new Error(__('auth_token is missing from response'));
|
||||||
|
}
|
||||||
|
|
||||||
|
ipcRenderer.send('set-auth-token', response.auth_token);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Lbryio.setOverride(
|
||||||
|
'getAuthToken',
|
||||||
|
() =>
|
||||||
|
new Promise(resolve => {
|
||||||
|
ipcRenderer.once('auth-token-response', (event, token) => {
|
||||||
|
Lbryio.authToken = token;
|
||||||
|
resolve(token);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcRenderer.send('get-auth-token');
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
ipcRenderer.on('open-uri-requested', (event, uri, newSession) => {
|
ipcRenderer.on('open-uri-requested', (event, uri, newSession) => {
|
||||||
if (uri && uri.startsWith('lbry://')) {
|
if (uri && uri.startsWith('lbry://')) {
|
||||||
if (uri.startsWith('lbry://?verify=')) {
|
if (uri.startsWith('lbry://?verify=')) {
|
||||||
|
@ -156,7 +191,7 @@ const init = () => {
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<SplashScreen
|
<SplashScreen
|
||||||
authenticate={() => app.store.dispatch(doAuthenticate())}
|
authenticate={() => app.store.dispatch(doAuthenticate(pjson.version))}
|
||||||
onReadyToLaunch={onDaemonReady}
|
onReadyToLaunch={onDaemonReady}
|
||||||
/>
|
/>
|
||||||
</Provider>,
|
</Provider>,
|
||||||
|
|
|
@ -1,155 +0,0 @@
|
||||||
import { ipcRenderer } from 'electron';
|
|
||||||
import { Lbry } from 'lbry-redux';
|
|
||||||
import querystring from 'querystring';
|
|
||||||
|
|
||||||
const Lbryio = {
|
|
||||||
enabled: true,
|
|
||||||
authenticationPromise: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
const CONNECTION_STRING = process.env.LBRY_APP_API_URL
|
|
||||||
? process.env.LBRY_APP_API_URL.replace(/\/*$/, '/') // exactly one slash at the end
|
|
||||||
: 'https://api.lbry.io/';
|
|
||||||
|
|
||||||
Lbryio.call = (resource, action, params = {}, method = 'get') => {
|
|
||||||
if (!Lbryio.enabled) {
|
|
||||||
console.log(__('Internal API disabled'));
|
|
||||||
return Promise.reject(new Error(__('LBRY internal API is disabled')));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(method === 'get' || method === 'post')) {
|
|
||||||
return Promise.reject(new Error(__('Invalid method')));
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkAndParse(response) {
|
|
||||||
if (response.status >= 200 && response.status < 300) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
return response.json().then(json => {
|
|
||||||
let error;
|
|
||||||
if (json.error) {
|
|
||||||
error = new Error(json.error);
|
|
||||||
} else {
|
|
||||||
error = new Error('Unknown API error signature');
|
|
||||||
}
|
|
||||||
error.response = response; // This is primarily a hack used in actions/user.js
|
|
||||||
return Promise.reject(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeRequest(url, options) {
|
|
||||||
return fetch(url, options).then(checkAndParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Lbryio.getAuthToken().then(token => {
|
|
||||||
const fullParams = { auth_token: token, ...params };
|
|
||||||
const qs = querystring.stringify(fullParams);
|
|
||||||
let url = `${CONNECTION_STRING}${resource}/${action}?${qs}`;
|
|
||||||
|
|
||||||
let options = {
|
|
||||||
method: 'GET',
|
|
||||||
};
|
|
||||||
|
|
||||||
if (method === 'post') {
|
|
||||||
options = {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
body: qs,
|
|
||||||
};
|
|
||||||
url = `${CONNECTION_STRING}${resource}/${action}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return makeRequest(url, options).then(response => response.data);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Lbryio.authToken = null;
|
|
||||||
|
|
||||||
Lbryio.getAuthToken = () =>
|
|
||||||
new Promise(resolve => {
|
|
||||||
if (Lbryio.authToken) {
|
|
||||||
resolve(Lbryio.authToken);
|
|
||||||
} else {
|
|
||||||
ipcRenderer.once('auth-token-response', (event, token) => {
|
|
||||||
Lbryio.authToken = token;
|
|
||||||
return resolve(token);
|
|
||||||
});
|
|
||||||
ipcRenderer.send('get-auth-token');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Lbryio.setAuthToken = token => {
|
|
||||||
Lbryio.authToken = token ? token.toString().trim() : null;
|
|
||||||
ipcRenderer.send('set-auth-token', token);
|
|
||||||
};
|
|
||||||
|
|
||||||
Lbryio.getCurrentUser = () => Lbryio.call('user', 'me');
|
|
||||||
|
|
||||||
Lbryio.authenticate = () => {
|
|
||||||
if (!Lbryio.enabled) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
resolve({
|
|
||||||
id: 1,
|
|
||||||
language: 'en',
|
|
||||||
primary_email: 'disabled@lbry.io',
|
|
||||||
has_verified_email: true,
|
|
||||||
is_identity_verified: true,
|
|
||||||
is_reward_approved: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Lbryio.authenticationPromise === null) {
|
|
||||||
Lbryio.authenticationPromise = new Promise((resolve, reject) => {
|
|
||||||
Lbryio.getAuthToken()
|
|
||||||
.then(token => {
|
|
||||||
if (!token || token.length > 60) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that token works
|
|
||||||
return Lbryio.getCurrentUser()
|
|
||||||
.then(() => true)
|
|
||||||
.catch(() => false);
|
|
||||||
})
|
|
||||||
.then(isTokenValid => {
|
|
||||||
if (isTokenValid) {
|
|
||||||
return reject;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Lbry.status()
|
|
||||||
.then(status =>
|
|
||||||
Lbryio.call(
|
|
||||||
'user',
|
|
||||||
'new',
|
|
||||||
{
|
|
||||||
auth_token: '',
|
|
||||||
language: 'en',
|
|
||||||
app_id: status.installation_id,
|
|
||||||
},
|
|
||||||
'post'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.then(response => {
|
|
||||||
if (!response.auth_token) {
|
|
||||||
throw new Error(__('auth_token is missing from response'));
|
|
||||||
}
|
|
||||||
return Lbryio.setAuthToken(response.auth_token);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(Lbryio.getCurrentUser)
|
|
||||||
.then(resolve, reject);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Lbryio.authenticationPromise;
|
|
||||||
};
|
|
||||||
|
|
||||||
Lbryio.getStripeToken = () =>
|
|
||||||
CONNECTION_STRING.startsWith('http://localhost:')
|
|
||||||
? 'pk_test_NoL1JWL7i1ipfhVId5KfDZgo'
|
|
||||||
: 'pk_live_e8M4dRNnCCbmpZzduEUZBgJO';
|
|
||||||
|
|
||||||
export default Lbryio;
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import { doSetClientSetting } from 'redux/actions/settings';
|
import { doSetClientSetting } from 'redux/actions/settings';
|
||||||
import { selectUserIsRewardApproved } from 'redux/selectors/user';
|
import { selectUserIsRewardApproved, selectUnclaimedRewardValue } from 'lbryinc';
|
||||||
import { selectBalance, doHideNotification } from 'lbry-redux';
|
import { selectBalance, doHideNotification } from 'lbry-redux';
|
||||||
import { selectUnclaimedRewardValue } from 'redux/selectors/rewards';
|
|
||||||
import * as settings from 'constants/settings';
|
import * as settings from 'constants/settings';
|
||||||
import ModalCreditIntro from './view';
|
import ModalCreditIntro from './view';
|
||||||
|
|
||||||
|
@ -25,4 +24,7 @@ const perform = dispatch => () => ({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(ModalCreditIntro);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(ModalCreditIntro);
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as settings from 'constants/settings';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doHideNotification } from 'lbry-redux';
|
import { doHideNotification } from 'lbry-redux';
|
||||||
import { doSetClientSetting } from 'redux/actions/settings';
|
import { doSetClientSetting } from 'redux/actions/settings';
|
||||||
import { selectEmailToVerify, selectUser } from 'redux/selectors/user';
|
import { selectEmailToVerify, selectUser } from 'lbryinc';
|
||||||
import ModalEmailCollection from './view';
|
import ModalEmailCollection from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
@ -17,4 +17,7 @@ const perform = dispatch => () => ({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(ModalEmailCollection);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(ModalEmailCollection);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import rewards from 'rewards';
|
import { rewards, makeSelectRewardByType } from 'lbryinc';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doHideNotification } from 'lbry-redux';
|
import { doHideNotification } from 'lbry-redux';
|
||||||
import { makeSelectRewardByType } from 'redux/selectors/rewards';
|
|
||||||
import ModalFirstReward from './view';
|
import ModalFirstReward from './view';
|
||||||
|
|
||||||
const select = state => {
|
const select = state => {
|
||||||
|
@ -16,4 +15,7 @@ const perform = dispatch => ({
|
||||||
closeModal: () => dispatch(doHideNotification()),
|
closeModal: () => dispatch(doHideNotification()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(ModalFirstReward);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(ModalFirstReward);
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
import React from 'react';
|
|
||||||
import * as settings from 'constants/settings';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doHideNotification } from 'lbry-redux';
|
import { doHideNotification } from 'lbry-redux';
|
||||||
import { doSetClientSetting } from 'redux/actions/settings';
|
import { selectPhoneToVerify, selectUser } from 'lbryinc';
|
||||||
import { selectPhoneToVerify, selectUser } from 'redux/selectors/user';
|
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import ModalPhoneCollection from './view';
|
import ModalPhoneCollection from './view';
|
||||||
|
|
||||||
|
@ -19,4 +16,7 @@ const perform = dispatch => () => ({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(ModalPhoneCollection);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(ModalPhoneCollection);
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
selectNotificationProps,
|
selectNotificationProps,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import { selectUser, selectUserIsVerificationCandidate } from 'redux/selectors/user';
|
import { selectUser, selectUserIsVerificationCandidate } from 'lbryinc';
|
||||||
|
|
||||||
import ModalRouter from './view';
|
import ModalRouter from './view';
|
||||||
|
|
||||||
|
@ -32,4 +32,7 @@ const perform = dispatch => ({
|
||||||
openModal: notification => dispatch(doNotify(notification)),
|
openModal: notification => dispatch(doNotify(notification)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(ModalRouter);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(ModalRouter);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
selectUser,
|
selectUser,
|
||||||
selectUserIsPending,
|
selectUserIsPending,
|
||||||
selectIdentityVerifyIsPending,
|
selectIdentityVerifyIsPending,
|
||||||
} from 'redux/selectors/user';
|
} from 'lbryinc';
|
||||||
import AuthPage from './view';
|
import AuthPage from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
@ -26,4 +26,7 @@ const perform = dispatch => ({
|
||||||
navigate: path => dispatch(doNavigate(path)),
|
navigate: path => dispatch(doNavigate(path)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(AuthPage);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(AuthPage);
|
||||||
|
|
|
@ -21,7 +21,7 @@ type Props = {
|
||||||
navigate: (string, ?{}) => void,
|
navigate: (string, ?{}) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class AuthPage extends React.PureComponent<Props> {
|
class AuthPage extends React.PureComponent<Props> {
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
this.navigateIfAuthenticated(this.props);
|
this.navigateIfAuthenticated(this.props);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doAuthNavigate } from 'redux/actions/navigation';
|
import { doAuthNavigate } from 'redux/actions/navigation';
|
||||||
import { doFetchAccessToken } from 'redux/actions/user';
|
import { doFetchAccessToken, selectAccessToken, selectUser } from 'lbryinc';
|
||||||
import { selectDaemonSettings } from 'redux/selectors/settings';
|
import { selectDaemonSettings } from 'redux/selectors/settings';
|
||||||
import { selectAccessToken, selectUser } from 'redux/selectors/user';
|
|
||||||
import HelpPage from './view';
|
import HelpPage from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import InvitePage from './view';
|
|
||||||
import { doFetchInviteStatus } from 'redux/actions/user';
|
|
||||||
import {
|
import {
|
||||||
|
doFetchInviteStatus,
|
||||||
selectUserInviteStatusFailed,
|
selectUserInviteStatusFailed,
|
||||||
selectUserInviteStatusIsPending,
|
selectUserInviteStatusIsPending,
|
||||||
} from 'redux/selectors/user';
|
} from 'lbryinc';
|
||||||
|
import InvitePage from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
isFailed: selectUserInviteStatusFailed(state),
|
isFailed: selectUserInviteStatusFailed(state),
|
||||||
|
@ -16,4 +15,7 @@ const perform = dispatch => ({
|
||||||
fetchInviteStatus: () => dispatch(doFetchInviteStatus()),
|
fetchInviteStatus: () => dispatch(doFetchInviteStatus()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(InvitePage);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(InvitePage);
|
||||||
|
|
|
@ -3,10 +3,10 @@ import {
|
||||||
selectFetchingRewards,
|
selectFetchingRewards,
|
||||||
selectUnclaimedRewards,
|
selectUnclaimedRewards,
|
||||||
selectClaimedRewards,
|
selectClaimedRewards,
|
||||||
} from 'redux/selectors/rewards';
|
selectUser,
|
||||||
import { selectUser } from 'redux/selectors/user';
|
doRewardList,
|
||||||
|
} from 'lbryinc';
|
||||||
import { doAuthNavigate, doNavigate } from 'redux/actions/navigation';
|
import { doAuthNavigate, doNavigate } from 'redux/actions/navigation';
|
||||||
import { doRewardList } from 'redux/actions/rewards';
|
|
||||||
import { selectDaemonSettings } from 'redux/selectors/settings';
|
import { selectDaemonSettings } from 'redux/selectors/settings';
|
||||||
import RewardsPage from './view';
|
import RewardsPage from './view';
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ import Native from 'native';
|
||||||
import { doFetchRewardedContent } from 'redux/actions/content';
|
import { doFetchRewardedContent } from 'redux/actions/content';
|
||||||
import { doFetchDaemonSettings } from 'redux/actions/settings';
|
import { doFetchDaemonSettings } from 'redux/actions/settings';
|
||||||
import { doAuthNavigate } from 'redux/actions/navigation';
|
import { doAuthNavigate } from 'redux/actions/navigation';
|
||||||
import { doAuthenticate } from 'redux/actions/user';
|
|
||||||
import { doCheckSubscriptionsInit } from 'redux/actions/subscriptions';
|
import { doCheckSubscriptionsInit } from 'redux/actions/subscriptions';
|
||||||
import {
|
import {
|
||||||
selectIsUpgradeSkipped,
|
selectIsUpgradeSkipped,
|
||||||
|
@ -28,7 +27,8 @@ import {
|
||||||
selectRemoteVersion,
|
selectRemoteVersion,
|
||||||
selectUpgradeTimer,
|
selectUpgradeTimer,
|
||||||
} from 'redux/selectors/app';
|
} from 'redux/selectors/app';
|
||||||
import { lbrySettings as config } from 'package.json';
|
import { doAuthenticate } from 'lbryinc';
|
||||||
|
import { lbrySettings as config, version as appVersion } from 'package.json';
|
||||||
|
|
||||||
const { autoUpdater } = remote.require('electron-updater');
|
const { autoUpdater } = remote.require('electron-updater');
|
||||||
const { download } = remote.require('electron-dl');
|
const { download } = remote.require('electron-dl');
|
||||||
|
@ -333,7 +333,7 @@ export function doDaemonReady() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
|
||||||
dispatch(doAuthenticate());
|
dispatch(doAuthenticate(appVersion));
|
||||||
dispatch({ type: ACTIONS.DAEMON_READY });
|
dispatch({ type: ACTIONS.DAEMON_READY });
|
||||||
dispatch(doFetchDaemonSettings());
|
dispatch(doFetchDaemonSettings());
|
||||||
dispatch(doBalanceSubscribe());
|
dispatch(doBalanceSubscribe());
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as NOTIFICATION_TYPES from 'constants/notification_types';
|
import * as NOTIFICATION_TYPES from 'constants/notification_types';
|
||||||
import { ipcRenderer } from 'electron';
|
import { ipcRenderer } from 'electron';
|
||||||
import Lbryio from 'lbryio';
|
|
||||||
import { doAlertError } from 'redux/actions/app';
|
import { doAlertError } from 'redux/actions/app';
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import {
|
import {
|
||||||
|
@ -32,6 +31,7 @@ import { makeSelectClientSetting, selectosNotificationsEnabled } from 'redux/sel
|
||||||
import setBadge from 'util/setBadge';
|
import setBadge from 'util/setBadge';
|
||||||
import setProgressBar from 'util/setProgressBar';
|
import setProgressBar from 'util/setProgressBar';
|
||||||
import analytics from 'analytics';
|
import analytics from 'analytics';
|
||||||
|
import { Lbryio } from 'lbryinc';
|
||||||
|
|
||||||
const DOWNLOAD_POLL_INTERVAL = 250;
|
const DOWNLOAD_POLL_INTERVAL = 250;
|
||||||
|
|
||||||
|
|
|
@ -1,117 +0,0 @@
|
||||||
import * as ACTIONS from 'constants/action_types';
|
|
||||||
import Lbryio from 'lbryio';
|
|
||||||
import { doNotify, MODALS } from 'lbry-redux';
|
|
||||||
import { selectUnclaimedRewards } from 'redux/selectors/rewards';
|
|
||||||
import { selectUserIsRewardApproved } from 'redux/selectors/user';
|
|
||||||
import rewards from 'rewards';
|
|
||||||
|
|
||||||
export function doRewardList() {
|
|
||||||
return dispatch => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.FETCH_REWARDS_STARTED,
|
|
||||||
});
|
|
||||||
|
|
||||||
Lbryio.call('reward', 'list', { multiple_rewards_per_type: true })
|
|
||||||
.then(userRewards => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.FETCH_REWARDS_COMPLETED,
|
|
||||||
data: { userRewards },
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.FETCH_REWARDS_COMPLETED,
|
|
||||||
data: { userRewards: [] },
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doClaimRewardType(rewardType, options) {
|
|
||||||
return (dispatch, getState) => {
|
|
||||||
const state = getState();
|
|
||||||
const unclaimedRewards = selectUnclaimedRewards(state);
|
|
||||||
const reward = unclaimedRewards.find(ur => ur.reward_type === rewardType);
|
|
||||||
const userIsRewardApproved = selectUserIsRewardApproved(state);
|
|
||||||
|
|
||||||
if (!reward || reward.transaction_id) {
|
|
||||||
// already claimed or doesn't exist, do nothing
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!userIsRewardApproved && rewardType !== rewards.TYPE_CONFIRM_EMAIL) {
|
|
||||||
if (!options || !options.failSilently) {
|
|
||||||
const action = doNotify({
|
|
||||||
id: MODALS.REWARD_APPROVAL_REQUIRED,
|
|
||||||
isError: false,
|
|
||||||
});
|
|
||||||
dispatch(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.CLAIM_REWARD_STARTED,
|
|
||||||
data: { reward },
|
|
||||||
});
|
|
||||||
|
|
||||||
const success = successReward => {
|
|
||||||
dispatch(doRewardList());
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.CLAIM_REWARD_SUCCESS,
|
|
||||||
data: {
|
|
||||||
reward: successReward,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (successReward.reward_type === rewards.TYPE_NEW_USER) {
|
|
||||||
const action = doNotify({
|
|
||||||
id: MODALS.FIRST_REWARD,
|
|
||||||
isError: false,
|
|
||||||
});
|
|
||||||
dispatch(action);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const failure = error => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.CLAIM_REWARD_FAILURE,
|
|
||||||
data: {
|
|
||||||
reward,
|
|
||||||
error: !options || !options.failSilently ? error : undefined,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
rewards.claimReward(rewardType).then(success, failure);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doClaimEligiblePurchaseRewards() {
|
|
||||||
return (dispatch, getState) => {
|
|
||||||
const state = getState();
|
|
||||||
const unclaimedRewards = selectUnclaimedRewards(state);
|
|
||||||
const userIsRewardApproved = selectUserIsRewardApproved(state);
|
|
||||||
|
|
||||||
if (!userIsRewardApproved || !Lbryio.enabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unclaimedRewards.find(ur => ur.reward_type === rewards.TYPE_FIRST_STREAM)) {
|
|
||||||
dispatch(doClaimRewardType(rewards.TYPE_FIRST_STREAM));
|
|
||||||
} else {
|
|
||||||
[rewards.TYPE_MANY_DOWNLOADS, rewards.TYPE_FEATURED_DOWNLOAD].forEach(type => {
|
|
||||||
dispatch(doClaimRewardType(type, { failSilently: true }));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doClaimRewardClearError(reward) {
|
|
||||||
return dispatch => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.CLAIM_REWARD_CLEAR_ERROR,
|
|
||||||
data: { reward },
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -2,16 +2,14 @@
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
import * as NOTIFICATION_TYPES from 'constants/notification_types';
|
import * as NOTIFICATION_TYPES from 'constants/notification_types';
|
||||||
import * as SETTINGS from 'constants/settings';
|
import * as SETTINGS from 'constants/settings';
|
||||||
import rewards from 'rewards';
|
import { Lbryio, rewards, doClaimRewardType } from 'lbryinc';
|
||||||
import type { Dispatch, SubscriptionNotifications } from 'redux/reducers/subscriptions';
|
import type { Dispatch, SubscriptionNotifications } from 'redux/reducers/subscriptions';
|
||||||
import type { Subscription } from 'types/subscription';
|
import type { Subscription } from 'types/subscription';
|
||||||
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import { Lbry, buildURI, parseURI, selectCurrentPage } from 'lbry-redux';
|
import { Lbry, buildURI, parseURI, selectCurrentPage } from 'lbry-redux';
|
||||||
import { doPurchaseUri, doFetchClaimsByChannel } from 'redux/actions/content';
|
import { doPurchaseUri, doFetchClaimsByChannel } from 'redux/actions/content';
|
||||||
import { doClaimRewardType } from 'redux/actions/rewards';
|
|
||||||
import Promise from 'bluebird';
|
import Promise from 'bluebird';
|
||||||
import Lbryio from 'lbryio';
|
|
||||||
|
|
||||||
const CHECK_SUBSCRIPTIONS_INTERVAL = 15 * 60 * 1000;
|
const CHECK_SUBSCRIPTIONS_INTERVAL = 15 * 60 * 1000;
|
||||||
const SUBSCRIPTION_DOWNLOAD_LIMIT = 1;
|
const SUBSCRIPTION_DOWNLOAD_LIMIT = 1;
|
||||||
|
@ -246,7 +244,7 @@ export const doChannelSubscribe = (subscription: Subscription) => (
|
||||||
claim_id: claimId,
|
claim_id: claimId,
|
||||||
});
|
});
|
||||||
|
|
||||||
dispatch(doClaimRewardType(rewards.SUBSCRIPTION, { failSilently: true }));
|
dispatch(doClaimRewardType(rewards.TYPE_SUBSCRIPTION, { failSilently: true }));
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(doCheckSubscription(subscription.uri, true));
|
dispatch(doCheckSubscription(subscription.uri, true));
|
||||||
|
|
|
@ -1,360 +0,0 @@
|
||||||
import * as ACTIONS from 'constants/action_types';
|
|
||||||
import Lbryio from 'lbryio';
|
|
||||||
import { Lbry, doNotify, MODALS, doHideNotification } from 'lbry-redux';
|
|
||||||
import { doClaimRewardType, doRewardList } from 'redux/actions/rewards';
|
|
||||||
import {
|
|
||||||
selectEmailToVerify,
|
|
||||||
selectPhoneToVerify,
|
|
||||||
selectUserCountryCode,
|
|
||||||
} from 'redux/selectors/user';
|
|
||||||
import rewards from 'rewards';
|
|
||||||
import analytics from 'analytics';
|
|
||||||
import pjson from 'package.json';
|
|
||||||
|
|
||||||
export function doFetchInviteStatus() {
|
|
||||||
return dispatch => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_INVITE_STATUS_FETCH_STARTED,
|
|
||||||
});
|
|
||||||
|
|
||||||
Lbryio.call('user', 'invite_status')
|
|
||||||
.then(status => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_INVITE_STATUS_FETCH_SUCCESS,
|
|
||||||
data: {
|
|
||||||
invitesRemaining: status.invites_remaining ? status.invites_remaining : 0,
|
|
||||||
invitees: status.invitees,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_INVITE_STATUS_FETCH_FAILURE,
|
|
||||||
data: { error },
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doInstallNew() {
|
|
||||||
const payload = { app_version: pjson.version };
|
|
||||||
Lbry.status().then(status => {
|
|
||||||
payload.app_id = status.installation_id;
|
|
||||||
if (status.dht) payload.node_id = status.dht.node_id;
|
|
||||||
Lbry.version().then(version => {
|
|
||||||
payload.daemon_version = version.lbrynet_version;
|
|
||||||
payload.operating_system = version.os_system;
|
|
||||||
payload.platform = version.platform;
|
|
||||||
Lbryio.call('install', 'new', payload);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doAuthenticate() {
|
|
||||||
return dispatch => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.AUTHENTICATION_STARTED,
|
|
||||||
});
|
|
||||||
Lbryio.authenticate()
|
|
||||||
.then(user => {
|
|
||||||
analytics.setUser(user);
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.AUTHENTICATION_SUCCESS,
|
|
||||||
data: { user },
|
|
||||||
});
|
|
||||||
dispatch(doRewardList());
|
|
||||||
dispatch(doFetchInviteStatus());
|
|
||||||
doInstallNew();
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
dispatch(doNotify({ id: MODALS.AUTHENTICATION_FAILURE }));
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.AUTHENTICATION_FAILURE,
|
|
||||||
data: { error },
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doUserFetch() {
|
|
||||||
return dispatch => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_FETCH_STARTED,
|
|
||||||
});
|
|
||||||
Lbryio.getCurrentUser()
|
|
||||||
.then(user => {
|
|
||||||
analytics.setUser(user);
|
|
||||||
dispatch(doRewardList());
|
|
||||||
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_FETCH_SUCCESS,
|
|
||||||
data: { user },
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_FETCH_FAILURE,
|
|
||||||
data: { error },
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doUserPhoneReset() {
|
|
||||||
return {
|
|
||||||
type: ACTIONS.USER_PHONE_RESET,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doUserPhoneNew(phone, countryCode) {
|
|
||||||
return dispatch => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_PHONE_NEW_STARTED,
|
|
||||||
data: { phone, country_code: countryCode },
|
|
||||||
});
|
|
||||||
|
|
||||||
const success = () => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_PHONE_NEW_SUCCESS,
|
|
||||||
data: { phone },
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const failure = error => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_PHONE_NEW_FAILURE,
|
|
||||||
data: { error },
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Lbryio.call(
|
|
||||||
'user',
|
|
||||||
'phone_number_new',
|
|
||||||
{ phone_number: phone, country_code: countryCode },
|
|
||||||
'post'
|
|
||||||
).then(success, failure);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doUserPhoneVerifyFailure(error) {
|
|
||||||
return {
|
|
||||||
type: ACTIONS.USER_PHONE_VERIFY_FAILURE,
|
|
||||||
data: { error },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doUserPhoneVerify(verificationCode) {
|
|
||||||
return (dispatch, getState) => {
|
|
||||||
const phoneNumber = selectPhoneToVerify(getState());
|
|
||||||
const countryCode = selectUserCountryCode(getState());
|
|
||||||
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_PHONE_VERIFY_STARTED,
|
|
||||||
code: verificationCode,
|
|
||||||
});
|
|
||||||
|
|
||||||
Lbryio.call(
|
|
||||||
'user',
|
|
||||||
'phone_number_confirm',
|
|
||||||
{
|
|
||||||
verification_code: verificationCode,
|
|
||||||
phone_number: phoneNumber,
|
|
||||||
country_code: countryCode,
|
|
||||||
},
|
|
||||||
'post'
|
|
||||||
)
|
|
||||||
.then(user => {
|
|
||||||
if (user.is_identity_verified) {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_PHONE_VERIFY_SUCCESS,
|
|
||||||
data: { user },
|
|
||||||
});
|
|
||||||
dispatch(doHideNotification());
|
|
||||||
dispatch(doClaimRewardType(rewards.TYPE_NEW_USER));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => dispatch(doUserPhoneVerifyFailure(error)));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doUserEmailNew(email) {
|
|
||||||
return dispatch => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_EMAIL_NEW_STARTED,
|
|
||||||
email,
|
|
||||||
});
|
|
||||||
|
|
||||||
const success = () => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_EMAIL_NEW_SUCCESS,
|
|
||||||
data: { email },
|
|
||||||
});
|
|
||||||
dispatch(doUserFetch());
|
|
||||||
};
|
|
||||||
|
|
||||||
const failure = error => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_EMAIL_NEW_FAILURE,
|
|
||||||
data: { error },
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Lbryio.call('user_email', 'new', { email, send_verification_email: true }, 'post')
|
|
||||||
.catch(error => {
|
|
||||||
if (error.response && error.response.status === 409) {
|
|
||||||
return Lbryio.call(
|
|
||||||
'user_email',
|
|
||||||
'resend_token',
|
|
||||||
{ email, only_if_expired: true },
|
|
||||||
'post'
|
|
||||||
).then(success, failure);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
})
|
|
||||||
.then(success, failure);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doUserResendVerificationEmail(email) {
|
|
||||||
return dispatch => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_EMAIL_VERIFY_RETRY,
|
|
||||||
email,
|
|
||||||
});
|
|
||||||
|
|
||||||
const success = () => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_EMAIL_NEW_SUCCESS,
|
|
||||||
data: { email },
|
|
||||||
});
|
|
||||||
dispatch(doUserFetch());
|
|
||||||
};
|
|
||||||
|
|
||||||
const failure = error => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_EMAIL_NEW_FAILURE,
|
|
||||||
data: { error },
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Lbryio.call('user_email', 'resend_token', { email }, 'post')
|
|
||||||
.catch(error => {
|
|
||||||
if (error.response && error.response.status === 409) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(success, failure);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doUserEmailVerifyFailure(error) {
|
|
||||||
return {
|
|
||||||
type: ACTIONS.USER_EMAIL_VERIFY_FAILURE,
|
|
||||||
data: { error },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doUserEmailVerify(verificationToken, recaptcha) {
|
|
||||||
return (dispatch, getState) => {
|
|
||||||
const email = selectEmailToVerify(getState());
|
|
||||||
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_EMAIL_VERIFY_STARTED,
|
|
||||||
code: verificationToken,
|
|
||||||
recaptcha,
|
|
||||||
});
|
|
||||||
|
|
||||||
Lbryio.call(
|
|
||||||
'user_email',
|
|
||||||
'confirm',
|
|
||||||
{
|
|
||||||
verification_token: verificationToken,
|
|
||||||
email,
|
|
||||||
recaptcha,
|
|
||||||
},
|
|
||||||
'post'
|
|
||||||
)
|
|
||||||
.then(userEmail => {
|
|
||||||
if (userEmail.is_verified) {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_EMAIL_VERIFY_SUCCESS,
|
|
||||||
data: { email },
|
|
||||||
});
|
|
||||||
dispatch(doUserFetch());
|
|
||||||
} else {
|
|
||||||
throw new Error('Your email is still not verified.'); // shouldn't happen
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => dispatch(doUserEmailVerifyFailure(error)));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doUserIdentityVerify(stripeToken) {
|
|
||||||
return dispatch => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_IDENTITY_VERIFY_STARTED,
|
|
||||||
token: stripeToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
Lbryio.call('user', 'verify_identity', { stripe_token: stripeToken }, 'post')
|
|
||||||
.then(user => {
|
|
||||||
if (user.is_identity_verified) {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_IDENTITY_VERIFY_SUCCESS,
|
|
||||||
data: { user },
|
|
||||||
});
|
|
||||||
dispatch(doClaimRewardType(rewards.TYPE_NEW_USER));
|
|
||||||
} else {
|
|
||||||
throw new Error('Your identity is still not verified. This should not happen.'); // shouldn't happen
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_IDENTITY_VERIFY_FAILURE,
|
|
||||||
data: { error: error.toString() },
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doFetchAccessToken() {
|
|
||||||
return dispatch => {
|
|
||||||
const success = token =>
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.FETCH_ACCESS_TOKEN_SUCCESS,
|
|
||||||
data: { token },
|
|
||||||
});
|
|
||||||
Lbryio.getAuthToken().then(success);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doUserInviteNew(email) {
|
|
||||||
return dispatch => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_INVITE_NEW_STARTED,
|
|
||||||
});
|
|
||||||
|
|
||||||
Lbryio.call('user', 'invite', { email }, 'post')
|
|
||||||
.then(() => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_INVITE_NEW_SUCCESS,
|
|
||||||
data: { email },
|
|
||||||
});
|
|
||||||
|
|
||||||
dispatch(
|
|
||||||
doNotify({
|
|
||||||
displayType: ['snackbar'],
|
|
||||||
message: __('Invite sent to %s', email),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
dispatch(doFetchInviteStatus());
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.USER_INVITE_NEW_FAILURE,
|
|
||||||
data: { error },
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,98 +0,0 @@
|
||||||
import * as ACTIONS from 'constants/action_types';
|
|
||||||
|
|
||||||
const reducers = {};
|
|
||||||
const defaultState = {
|
|
||||||
fetching: false,
|
|
||||||
claimedRewardsById: {}, // id => reward
|
|
||||||
unclaimedRewards: [],
|
|
||||||
claimPendingByType: {},
|
|
||||||
claimErrorsByType: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
reducers[ACTIONS.FETCH_REWARDS_STARTED] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
fetching: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.FETCH_REWARDS_COMPLETED] = (state, action) => {
|
|
||||||
const { userRewards } = action.data;
|
|
||||||
|
|
||||||
const unclaimedRewards = [];
|
|
||||||
const claimedRewards = {};
|
|
||||||
userRewards.forEach(reward => {
|
|
||||||
if (reward.transaction_id) {
|
|
||||||
claimedRewards[reward.id] = reward;
|
|
||||||
} else {
|
|
||||||
unclaimedRewards.push(reward);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
claimedRewardsById: claimedRewards,
|
|
||||||
unclaimedRewards,
|
|
||||||
fetching: false,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function setClaimRewardState(state, reward, isClaiming, errorMessage = '') {
|
|
||||||
const newClaimPendingByType = Object.assign({}, state.claimPendingByType);
|
|
||||||
const newClaimErrorsByType = Object.assign({}, state.claimErrorsByType);
|
|
||||||
if (isClaiming) {
|
|
||||||
newClaimPendingByType[reward.reward_type] = isClaiming;
|
|
||||||
} else {
|
|
||||||
delete newClaimPendingByType[reward.reward_type];
|
|
||||||
}
|
|
||||||
if (errorMessage) {
|
|
||||||
newClaimErrorsByType[reward.reward_type] = errorMessage;
|
|
||||||
} else {
|
|
||||||
delete newClaimErrorsByType[reward.reward_type];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
claimPendingByType: newClaimPendingByType,
|
|
||||||
claimErrorsByType: newClaimErrorsByType,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
reducers[ACTIONS.CLAIM_REWARD_STARTED] = (state, action) => {
|
|
||||||
const { reward } = action.data;
|
|
||||||
|
|
||||||
return setClaimRewardState(state, reward, true, '');
|
|
||||||
};
|
|
||||||
|
|
||||||
reducers[ACTIONS.CLAIM_REWARD_SUCCESS] = (state, action) => {
|
|
||||||
const { reward } = action.data;
|
|
||||||
const { unclaimedRewards } = state;
|
|
||||||
|
|
||||||
const index = unclaimedRewards.findIndex(ur => ur.reward_type === reward.reward_type);
|
|
||||||
unclaimedRewards.splice(index, 1);
|
|
||||||
|
|
||||||
const { claimedRewardsById } = state;
|
|
||||||
claimedRewardsById[reward.id] = reward;
|
|
||||||
|
|
||||||
const newState = {
|
|
||||||
...state,
|
|
||||||
unclaimedRewards: [...unclaimedRewards],
|
|
||||||
claimedRewardsById: { ...claimedRewardsById },
|
|
||||||
};
|
|
||||||
|
|
||||||
return setClaimRewardState(newState, reward, false, '');
|
|
||||||
};
|
|
||||||
|
|
||||||
reducers[ACTIONS.CLAIM_REWARD_FAILURE] = (state, action) => {
|
|
||||||
const { reward, error } = action.data;
|
|
||||||
|
|
||||||
return setClaimRewardState(state, reward, false, error ? error.message : '');
|
|
||||||
};
|
|
||||||
|
|
||||||
reducers[ACTIONS.CLAIM_REWARD_CLEAR_ERROR] = (state, action) => {
|
|
||||||
const { reward } = action.data;
|
|
||||||
|
|
||||||
return setClaimRewardState(state, reward, state.claimPendingByType[reward.reward_type], '');
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function reducer(state = defaultState, action) {
|
|
||||||
const handler = reducers[action.type];
|
|
||||||
if (handler) return handler(state, action);
|
|
||||||
return state;
|
|
||||||
}
|
|
|
@ -1,222 +0,0 @@
|
||||||
import * as ACTIONS from 'constants/action_types';
|
|
||||||
|
|
||||||
const reducers = {};
|
|
||||||
|
|
||||||
const defaultState = {
|
|
||||||
authenticationIsPending: false,
|
|
||||||
userIsPending: false,
|
|
||||||
emailNewIsPending: false,
|
|
||||||
emailNewErrorMessage: '',
|
|
||||||
emailToVerify: '',
|
|
||||||
inviteNewErrorMessage: '',
|
|
||||||
inviteNewIsPending: false,
|
|
||||||
inviteStatusIsPending: false,
|
|
||||||
invitesRemaining: undefined,
|
|
||||||
invitees: undefined,
|
|
||||||
user: undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
reducers[ACTIONS.AUTHENTICATION_STARTED] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
authenticationIsPending: true,
|
|
||||||
userIsPending: true,
|
|
||||||
user: defaultState.user,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.AUTHENTICATION_SUCCESS] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
authenticationIsPending: false,
|
|
||||||
userIsPending: false,
|
|
||||||
user: action.data.user,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.AUTHENTICATION_FAILURE] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
authenticationIsPending: false,
|
|
||||||
userIsPending: false,
|
|
||||||
user: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_FETCH_STARTED] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
userIsPending: true,
|
|
||||||
user: defaultState.user,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_FETCH_SUCCESS] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
userIsPending: false,
|
|
||||||
user: action.data.user,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_FETCH_FAILURE] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
userIsPending: true,
|
|
||||||
user: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_PHONE_NEW_STARTED] = (state, action) => {
|
|
||||||
const user = Object.assign({}, state.user);
|
|
||||||
user.country_code = action.data.country_code;
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
phoneNewIsPending: true,
|
|
||||||
phoneNewErrorMessage: '',
|
|
||||||
user,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_PHONE_NEW_SUCCESS] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
phoneToVerify: action.data.phone,
|
|
||||||
phoneNewIsPending: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_PHONE_RESET] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
phoneToVerify: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_PHONE_NEW_FAILURE] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
phoneNewIsPending: false,
|
|
||||||
phoneNewErrorMessage: action.data.error,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_PHONE_VERIFY_STARTED] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
phoneVerifyIsPending: true,
|
|
||||||
phoneVerifyErrorMessage: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_PHONE_VERIFY_SUCCESS] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
phoneToVerify: '',
|
|
||||||
phoneVerifyIsPending: false,
|
|
||||||
user: action.data.user,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_PHONE_VERIFY_FAILURE] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
phoneVerifyIsPending: false,
|
|
||||||
phoneVerifyErrorMessage: action.data.error,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_EMAIL_NEW_STARTED] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
emailNewIsPending: true,
|
|
||||||
emailNewErrorMessage: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_EMAIL_NEW_SUCCESS] = (state, action) => {
|
|
||||||
const user = Object.assign({}, state.user);
|
|
||||||
user.primary_email = action.data.email;
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
emailToVerify: action.data.email,
|
|
||||||
emailNewIsPending: false,
|
|
||||||
user,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_EMAIL_NEW_EXISTS] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
emailToVerify: action.data.email,
|
|
||||||
emailNewIsPending: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_EMAIL_NEW_FAILURE] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
emailNewIsPending: false,
|
|
||||||
emailNewErrorMessage: action.data.error,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_EMAIL_VERIFY_STARTED] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
emailVerifyIsPending: true,
|
|
||||||
emailVerifyErrorMessage: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_EMAIL_VERIFY_SUCCESS] = (state, action) => {
|
|
||||||
const user = Object.assign({}, state.user);
|
|
||||||
user.primary_email = action.data.email;
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
emailToVerify: '',
|
|
||||||
emailVerifyIsPending: false,
|
|
||||||
user,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_EMAIL_VERIFY_FAILURE] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
emailVerifyIsPending: false,
|
|
||||||
emailVerifyErrorMessage: action.data.error,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_IDENTITY_VERIFY_STARTED] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
identityVerifyIsPending: true,
|
|
||||||
identityVerifyErrorMessage: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_IDENTITY_VERIFY_SUCCESS] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
identityVerifyIsPending: false,
|
|
||||||
identityVerifyErrorMessage: '',
|
|
||||||
user: action.data.user,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_IDENTITY_VERIFY_FAILURE] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
identityVerifyIsPending: false,
|
|
||||||
identityVerifyErrorMessage: action.data.error,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.FETCH_ACCESS_TOKEN_SUCCESS] = (state, action) => {
|
|
||||||
const { token } = action.data;
|
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
accessToken: token,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_INVITE_STATUS_FETCH_STARTED] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
inviteStatusIsPending: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_INVITE_STATUS_FETCH_SUCCESS] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
inviteStatusIsPending: false,
|
|
||||||
invitesRemaining: action.data.invitesRemaining,
|
|
||||||
invitees: action.data.invitees,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_INVITE_NEW_STARTED] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
inviteNewIsPending: true,
|
|
||||||
inviteNewErrorMessage: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_INVITE_NEW_SUCCESS] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
inviteNewIsPending: false,
|
|
||||||
inviteNewErrorMessage: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_INVITE_NEW_FAILURE] = (state, action) =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
inviteNewIsPending: false,
|
|
||||||
inviteNewErrorMessage: action.data.error.message,
|
|
||||||
});
|
|
||||||
|
|
||||||
reducers[ACTIONS.USER_INVITE_STATUS_FETCH_FAILURE] = state =>
|
|
||||||
Object.assign({}, state, {
|
|
||||||
inviteStatusIsPending: false,
|
|
||||||
invitesRemaining: null,
|
|
||||||
invitees: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default function reducer(state = defaultState, action) {
|
|
||||||
const handler = reducers[action.type];
|
|
||||||
if (handler) return handler(state, action);
|
|
||||||
return state;
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
import { createSelector } from 'reselect';
|
|
||||||
|
|
||||||
const selectState = state => state.rewards || {};
|
|
||||||
|
|
||||||
export const selectUnclaimedRewardsByType = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.unclaimedRewardsByType
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectClaimedRewardsById = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.claimedRewardsById
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectClaimedRewards = createSelector(
|
|
||||||
selectClaimedRewardsById,
|
|
||||||
byId => Object.values(byId) || []
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectClaimedRewardsByTransactionId = createSelector(selectClaimedRewards, rewards =>
|
|
||||||
rewards.reduce((mapParam, reward) => {
|
|
||||||
const map = mapParam;
|
|
||||||
map[reward.transaction_id] = reward;
|
|
||||||
return map;
|
|
||||||
}, {})
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectUnclaimedRewards = createSelector(selectState, state => state.unclaimedRewards);
|
|
||||||
|
|
||||||
export const selectFetchingRewards = createSelector(selectState, state => !!state.fetching);
|
|
||||||
|
|
||||||
export const selectUnclaimedRewardValue = createSelector(selectUnclaimedRewards, rewards =>
|
|
||||||
rewards.reduce((sum, reward) => sum + reward.reward_amount, 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectClaimsPendingByType = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.claimPendingByType
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectIsClaimRewardPending = (state, props) =>
|
|
||||||
selectClaimsPendingByType(state, props)[props.reward_type];
|
|
||||||
|
|
||||||
export const makeSelectIsRewardClaimPending = () =>
|
|
||||||
createSelector(selectIsClaimRewardPending, isClaiming => isClaiming);
|
|
||||||
|
|
||||||
export const selectClaimErrorsByType = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.claimErrorsByType
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectClaimRewardError = (state, props) =>
|
|
||||||
selectClaimErrorsByType(state, props)[props.reward_type];
|
|
||||||
|
|
||||||
export const makeSelectClaimRewardError = () =>
|
|
||||||
createSelector(selectClaimRewardError, errorMessage => errorMessage);
|
|
||||||
|
|
||||||
const selectRewardByType = (state, rewardType) =>
|
|
||||||
selectUnclaimedRewards(state).find(reward => reward.reward_type === rewardType);
|
|
||||||
|
|
||||||
export const makeSelectRewardByType = () => createSelector(selectRewardByType, reward => reward);
|
|
||||||
|
|
||||||
export const makeSelectRewardAmountByType = () =>
|
|
||||||
createSelector(selectRewardByType, reward => (reward ? reward.reward_amount : 0));
|
|
|
@ -1,118 +0,0 @@
|
||||||
import { createSelector } from 'reselect';
|
|
||||||
|
|
||||||
export const selectState = state => state.user || {};
|
|
||||||
|
|
||||||
export const selectAuthenticationIsPending = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.authenticationIsPending
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectUserIsPending = createSelector(selectState, state => state.userIsPending);
|
|
||||||
|
|
||||||
export const selectUser = createSelector(selectState, state => state.user);
|
|
||||||
|
|
||||||
export const selectUserEmail = createSelector(
|
|
||||||
selectUser,
|
|
||||||
user => (user ? user.primary_email : null)
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectUserPhone = createSelector(
|
|
||||||
selectUser,
|
|
||||||
user => (user ? user.phone_number : null)
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectUserCountryCode = createSelector(
|
|
||||||
selectUser,
|
|
||||||
user => (user ? user.country_code : null)
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectEmailToVerify = createSelector(
|
|
||||||
selectState,
|
|
||||||
selectUserEmail,
|
|
||||||
(state, userEmail) => state.emailToVerify || userEmail
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectPhoneToVerify = createSelector(
|
|
||||||
selectState,
|
|
||||||
selectUserPhone,
|
|
||||||
(state, userPhone) => state.phoneToVerify || userPhone
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectUserIsRewardApproved = createSelector(
|
|
||||||
selectUser,
|
|
||||||
user => user && user.is_reward_approved
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectEmailNewIsPending = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.emailNewIsPending
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectEmailNewErrorMessage = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.emailNewErrorMessage
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectPhoneNewErrorMessage = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.phoneNewErrorMessage
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectEmailVerifyIsPending = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.emailVerifyIsPending
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectEmailVerifyErrorMessage = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.emailVerifyErrorMessage
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectPhoneVerifyErrorMessage = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.phoneVerifyErrorMessage
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectIdentityVerifyIsPending = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.identityVerifyIsPending
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectIdentityVerifyErrorMessage = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.identityVerifyErrorMessage
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectUserIsVerificationCandidate = createSelector(
|
|
||||||
selectUser,
|
|
||||||
user => user && (!user.has_verified_email || !user.is_identity_verified)
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectAccessToken = createSelector(selectState, state => state.accessToken);
|
|
||||||
|
|
||||||
export const selectUserInviteStatusIsPending = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.inviteStatusIsPending
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectUserInvitesRemaining = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.invitesRemaining
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectUserInvitees = createSelector(selectState, state => state.invitees);
|
|
||||||
|
|
||||||
export const selectUserInviteStatusFailed = createSelector(
|
|
||||||
selectUserInvitesRemaining,
|
|
||||||
() => selectUserInvitesRemaining === null
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectUserInviteNewIsPending = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.inviteNewIsPending
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectUserInviteNewErrorMessage = createSelector(
|
|
||||||
selectState,
|
|
||||||
state => state.inviteNewErrorMessage
|
|
||||||
);
|
|
|
@ -1,113 +0,0 @@
|
||||||
import { Lbry, doNotify } from 'lbry-redux';
|
|
||||||
import Lbryio from 'lbryio';
|
|
||||||
|
|
||||||
const rewards = {};
|
|
||||||
|
|
||||||
rewards.TYPE_NEW_DEVELOPER = 'new_developer';
|
|
||||||
rewards.TYPE_NEW_USER = 'new_user';
|
|
||||||
rewards.TYPE_CONFIRM_EMAIL = 'verified_email';
|
|
||||||
rewards.TYPE_FIRST_CHANNEL = 'new_channel';
|
|
||||||
rewards.TYPE_FIRST_STREAM = 'first_stream';
|
|
||||||
rewards.TYPE_MANY_DOWNLOADS = 'many_downloads';
|
|
||||||
rewards.TYPE_FIRST_PUBLISH = 'first_publish';
|
|
||||||
rewards.TYPE_FEATURED_DOWNLOAD = 'featured_download';
|
|
||||||
rewards.TYPE_REFERRAL = 'referral';
|
|
||||||
rewards.YOUTUBE_CREATOR = 'youtube_creator';
|
|
||||||
rewards.SUBSCRIPTION = 'subscription';
|
|
||||||
|
|
||||||
rewards.claimReward = type => {
|
|
||||||
function requestReward(resolve, reject, params) {
|
|
||||||
if (!Lbryio.enabled) {
|
|
||||||
reject(new Error(__('Rewards are not enabled.')));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Lbryio.call('reward', 'new', params, 'post').then(reward => {
|
|
||||||
const message =
|
|
||||||
reward.reward_notification || `You have claimed a ${reward.reward_amount} LBC reward.`;
|
|
||||||
|
|
||||||
// Display global notice
|
|
||||||
const action = doNotify({
|
|
||||||
message,
|
|
||||||
linkText: __('Show All'),
|
|
||||||
linkTarget: '/rewards',
|
|
||||||
isError: false,
|
|
||||||
displayType: ['snackbar'],
|
|
||||||
});
|
|
||||||
window.app.store.dispatch(action);
|
|
||||||
|
|
||||||
// Add more events here to display other places
|
|
||||||
|
|
||||||
resolve(reward);
|
|
||||||
}, reject);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
Lbry.wallet_unused_address().then(address => {
|
|
||||||
const params = {
|
|
||||||
reward_type: type,
|
|
||||||
wallet_address: address,
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case rewards.TYPE_FIRST_CHANNEL:
|
|
||||||
Lbry.claim_list_mine()
|
|
||||||
.then(claims => {
|
|
||||||
const claim = claims
|
|
||||||
.reverse()
|
|
||||||
.find(
|
|
||||||
foundClaim =>
|
|
||||||
foundClaim.name.length &&
|
|
||||||
foundClaim.name[0] === '@' &&
|
|
||||||
foundClaim.txid.length &&
|
|
||||||
foundClaim.category === 'claim'
|
|
||||||
);
|
|
||||||
if (claim) {
|
|
||||||
params.transaction_id = claim.txid;
|
|
||||||
requestReward(resolve, reject, params);
|
|
||||||
} else {
|
|
||||||
reject(new Error(__('Please create a channel identity first.')));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(reject);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case rewards.TYPE_FIRST_PUBLISH:
|
|
||||||
Lbry.claim_list_mine()
|
|
||||||
.then(claims => {
|
|
||||||
const claim = claims
|
|
||||||
.reverse()
|
|
||||||
.find(
|
|
||||||
foundClaim =>
|
|
||||||
foundClaim.name.length &&
|
|
||||||
foundClaim.name[0] !== '@' &&
|
|
||||||
foundClaim.txid.length &&
|
|
||||||
foundClaim.category === 'claim'
|
|
||||||
);
|
|
||||||
if (claim) {
|
|
||||||
params.transaction_id = claim.txid;
|
|
||||||
requestReward(resolve, reject, params);
|
|
||||||
} else {
|
|
||||||
reject(
|
|
||||||
claims.length
|
|
||||||
? new Error(
|
|
||||||
__(
|
|
||||||
'Please publish something and wait for confirmation by the network to claim this reward.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
: new Error(__('Please publish something to claim this reward.'))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(reject);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case rewards.TYPE_FIRST_STREAM:
|
|
||||||
case rewards.TYPE_NEW_USER:
|
|
||||||
default:
|
|
||||||
requestReward(resolve, reject, params);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export default rewards;
|
|
|
@ -12,9 +12,8 @@ import {
|
||||||
blacklistReducer,
|
blacklistReducer,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import navigationReducer from 'redux/reducers/navigation';
|
import navigationReducer from 'redux/reducers/navigation';
|
||||||
import rewardsReducer from 'redux/reducers/rewards';
|
|
||||||
import settingsReducer from 'redux/reducers/settings';
|
import settingsReducer from 'redux/reducers/settings';
|
||||||
import userReducer from 'redux/reducers/user';
|
import { userReducer, rewardsReducer } from 'lbryinc';
|
||||||
import shapeShiftReducer from 'redux/reducers/shape_shift';
|
import shapeShiftReducer from 'redux/reducers/shape_shift';
|
||||||
import subscriptionsReducer from 'redux/reducers/subscriptions';
|
import subscriptionsReducer from 'redux/reducers/subscriptions';
|
||||||
import publishReducer from 'redux/reducers/publish';
|
import publishReducer from 'redux/reducers/publish';
|
||||||
|
|
14
yarn.lock
14
yarn.lock
|
@ -5655,6 +5655,13 @@ lazy-val@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.3.tgz#bb97b200ef00801d94c317e29dc6ed39e31c5edc"
|
resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.3.tgz#bb97b200ef00801d94c317e29dc6ed39e31c5edc"
|
||||||
|
|
||||||
|
lbry-redux@lbryio/lbry-redux:
|
||||||
|
version "0.0.1"
|
||||||
|
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/a8e81949837171e94e649fce6f7c7a8b7faadd51"
|
||||||
|
dependencies:
|
||||||
|
proxy-polyfill "0.1.6"
|
||||||
|
reselect "^3.0.0"
|
||||||
|
|
||||||
lbry-redux@lbryio/lbry-redux#d1cee82af119c0c5f98ec27f94b2e7f61e34b54c:
|
lbry-redux@lbryio/lbry-redux#d1cee82af119c0c5f98ec27f94b2e7f61e34b54c:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/d1cee82af119c0c5f98ec27f94b2e7f61e34b54c"
|
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/d1cee82af119c0c5f98ec27f94b2e7f61e34b54c"
|
||||||
|
@ -5662,6 +5669,13 @@ lbry-redux@lbryio/lbry-redux#d1cee82af119c0c5f98ec27f94b2e7f61e34b54c:
|
||||||
proxy-polyfill "0.1.6"
|
proxy-polyfill "0.1.6"
|
||||||
reselect "^3.0.0"
|
reselect "^3.0.0"
|
||||||
|
|
||||||
|
lbryinc@lbryio/lbryinc#c09aa2645ecccb33c83e9a9545ff119232910f6f:
|
||||||
|
version "0.0.1"
|
||||||
|
resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/c09aa2645ecccb33c83e9a9545ff119232910f6f"
|
||||||
|
dependencies:
|
||||||
|
lbry-redux lbryio/lbry-redux
|
||||||
|
reselect "^3.0.0"
|
||||||
|
|
||||||
lcid@^1.0.0:
|
lcid@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
|
resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
|
||||||
|
|
Loading…
Reference in a new issue