new first run flow and re-org of wallet area
add changelog add external service option to get credits page remove testing code fix user has existing email and grammar/typos
This commit is contained in:
parent
204fd60f95
commit
8c403f640c
40 changed files with 297 additions and 264 deletions
|
@ -9,9 +9,11 @@ Web UI version numbers should always match the corresponding version of LBRY App
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added
|
### Added
|
||||||
* ShapeShift integration
|
* ShapeShift integration
|
||||||
*
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
* The first run process for new users has changed substantially. New users can now easily receive one credit.
|
||||||
|
* The wallet area has been re-organized. Send and Receive are now on the same page. A new page, "Get Credits", explains how users can add LBRY credits to the app.
|
||||||
|
* The prompt for an insufficient balance is much more user-friendly.
|
||||||
* The credit balance displayed in the main app navigation displays two decimal places instead of one.
|
* The credit balance displayed in the main app navigation displays two decimal places instead of one.
|
||||||
* Moved all redux code into /redux folder
|
* Moved all redux code into /redux folder
|
||||||
* Channel names in pages are highlighted to indicate them being clickable(#814)
|
* Channel names in pages are highlighted to indicate them being clickable(#814)
|
||||||
|
@ -27,7 +29,7 @@ Web UI version numbers should always match the corresponding version of LBRY App
|
||||||
*
|
*
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
*
|
* We previous two separate modals for insufficient credits. These have been combined.
|
||||||
*
|
*
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
|
@ -3,7 +3,7 @@ import Router from "component/router/index";
|
||||||
import Header from "component/header";
|
import Header from "component/header";
|
||||||
import Theme from "component/theme";
|
import Theme from "component/theme";
|
||||||
import ModalRouter from "modal/modalRouter";
|
import ModalRouter from "modal/modalRouter";
|
||||||
import lbry from "lbry";
|
import ReactModal from "react-modal";
|
||||||
import throttle from "util/throttle";
|
import throttle from "util/throttle";
|
||||||
|
|
||||||
class App extends React.PureComponent {
|
class App extends React.PureComponent {
|
||||||
|
@ -28,6 +28,8 @@ class App extends React.PureComponent {
|
||||||
const scrollListener = () => recordScroll(this.mainContent.scrollTop);
|
const scrollListener = () => recordScroll(this.mainContent.scrollTop);
|
||||||
|
|
||||||
this.mainContent.addEventListener("scroll", throttle(scrollListener, 750));
|
this.mainContent.addEventListener("scroll", throttle(scrollListener, 750));
|
||||||
|
|
||||||
|
ReactModal.setAppElement("#window"); //fuck this
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
|
|
@ -69,7 +69,7 @@ export class CreditAmount extends React.PureComponent {
|
||||||
amount: PropTypes.number.isRequired,
|
amount: PropTypes.number.isRequired,
|
||||||
precision: PropTypes.number,
|
precision: PropTypes.number,
|
||||||
isEstimate: PropTypes.bool,
|
isEstimate: PropTypes.bool,
|
||||||
label: PropTypes.bool,
|
label: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
|
||||||
showFree: PropTypes.bool,
|
showFree: PropTypes.bool,
|
||||||
showFullPrice: PropTypes.bool,
|
showFullPrice: PropTypes.bool,
|
||||||
showPlus: PropTypes.bool,
|
showPlus: PropTypes.bool,
|
||||||
|
@ -106,10 +106,12 @@ export class CreditAmount extends React.PureComponent {
|
||||||
amountText = __("free");
|
amountText = __("free");
|
||||||
} else {
|
} else {
|
||||||
if (this.props.label) {
|
if (this.props.label) {
|
||||||
amountText =
|
const label =
|
||||||
formattedAmount +
|
typeof this.props.label === "string"
|
||||||
" " +
|
? this.props.label
|
||||||
(parseFloat(amount) == 1 ? __("credit") : __("credits"));
|
: parseFloat(amount) == 1 ? __("credit") : __("credits");
|
||||||
|
|
||||||
|
amountText = formattedAmount + " " + label;
|
||||||
} else {
|
} else {
|
||||||
amountText = formattedAmount;
|
amountText = formattedAmount;
|
||||||
}
|
}
|
||||||
|
|
|
@ -882,6 +882,7 @@ class PublishForm extends React.PureComponent {
|
||||||
!this.state.submitting ? __("Publish") : __("Publishing...")
|
!this.state.submitting ? __("Publish") : __("Publishing...")
|
||||||
}
|
}
|
||||||
disabled={
|
disabled={
|
||||||
|
this.props.balance <= 0 ||
|
||||||
this.state.submitting ||
|
this.state.submitting ||
|
||||||
(this.state.uri &&
|
(this.state.uri &&
|
||||||
this.props.resolvingUris.indexOf(this.state.uri) !== -1) ||
|
this.props.resolvingUris.indexOf(this.state.uri) !== -1) ||
|
||||||
|
|
|
@ -20,7 +20,11 @@ const RewardSummary = props => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="card__actions">
|
<div className="card__actions">
|
||||||
<Link button="alt" navigate="/rewards" label={__("Learn more")} />
|
<Link
|
||||||
|
button="primary"
|
||||||
|
navigate="/rewards"
|
||||||
|
label={__("Claim Rewards")}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,8 +3,8 @@ import SettingsPage from "page/settings";
|
||||||
import HelpPage from "page/help";
|
import HelpPage from "page/help";
|
||||||
import ReportPage from "page/report.js";
|
import ReportPage from "page/report.js";
|
||||||
import WalletPage from "page/wallet";
|
import WalletPage from "page/wallet";
|
||||||
import ReceiveCreditsPage from "page/receiveCredits";
|
import GetCreditsPage from "../../page/getCredits";
|
||||||
import SendCreditsPage from "page/sendCredits";
|
import SendReceivePage from "page/sendCredits";
|
||||||
import ShowPage from "page/show";
|
import ShowPage from "page/show";
|
||||||
import PublishPage from "page/publish";
|
import PublishPage from "page/publish";
|
||||||
import DiscoverPage from "page/discover";
|
import DiscoverPage from "page/discover";
|
||||||
|
@ -38,11 +38,11 @@ const Router = props => {
|
||||||
invite: <InvitePage params={params} />,
|
invite: <InvitePage params={params} />,
|
||||||
publish: <PublishPage params={params} />,
|
publish: <PublishPage params={params} />,
|
||||||
published: <FileListPublished params={params} />,
|
published: <FileListPublished params={params} />,
|
||||||
receive: <ReceiveCreditsPage params={params} />,
|
getcredits: <GetCreditsPage params={params} />,
|
||||||
report: <ReportPage params={params} />,
|
report: <ReportPage params={params} />,
|
||||||
rewards: <RewardsPage params={params} />,
|
rewards: <RewardsPage params={params} />,
|
||||||
search: <SearchPage params={params} />,
|
search: <SearchPage params={params} />,
|
||||||
send: <SendCreditsPage params={params} />,
|
send: <SendReceivePage params={params} />,
|
||||||
settings: <SettingsPage params={params} />,
|
settings: <SettingsPage params={params} />,
|
||||||
show: <ShowPage {...params} />,
|
show: <ShowPage {...params} />,
|
||||||
wallet: <WalletPage params={params} />,
|
wallet: <WalletPage params={params} />,
|
||||||
|
|
|
@ -6,10 +6,15 @@ import {
|
||||||
selectEmailNewErrorMessage,
|
selectEmailNewErrorMessage,
|
||||||
} from "redux/selectors/user";
|
} from "redux/selectors/user";
|
||||||
import UserEmailNew from "./view";
|
import UserEmailNew from "./view";
|
||||||
|
import rewards from "rewards";
|
||||||
|
import { makeSelectRewardAmountByType } from "redux/selectors/rewards";
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
isPending: selectEmailNewIsPending(state),
|
isPending: selectEmailNewIsPending(state),
|
||||||
errorMessage: selectEmailNewErrorMessage(state),
|
errorMessage: selectEmailNewErrorMessage(state),
|
||||||
|
rewardAmount: makeSelectRewardAmountByType()(state, {
|
||||||
|
reward_type: rewards.TYPE_CONFIRM_EMAIL,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import Link from "component/link";
|
import { CreditAmount } from "component/common";
|
||||||
import { Form, FormRow, Submit } from "component/form.js";
|
import { Form, FormRow, Submit } from "component/form.js";
|
||||||
|
|
||||||
class UserEmailNew extends React.PureComponent {
|
class UserEmailNew extends React.PureComponent {
|
||||||
|
@ -23,20 +23,24 @@ class UserEmailNew extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { errorMessage, isPending } = this.props;
|
const { cancelButton, errorMessage, isPending, rewardAmount } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
Let us know your email and you'll receive{" "}
|
||||||
|
<CreditAmount amount={rewardAmount} label="LBC" />, the blockchain
|
||||||
|
token used by LBRY.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{__(
|
||||||
|
"We'll also let you know about LBRY updates, security issues, and great new content."
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{__("We'll never sell your email, and you can unsubscribe at any time.")}
|
||||||
|
</p>
|
||||||
<Form onSubmit={this.handleSubmit.bind(this)}>
|
<Form onSubmit={this.handleSubmit.bind(this)}>
|
||||||
<p>
|
|
||||||
{__(
|
|
||||||
"This process is required to prevent abuse of the rewards program."
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{__(
|
|
||||||
"We will also contact you about updates and new content, but you can unsubscribe at any time."
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<FormRow
|
<FormRow
|
||||||
type="text"
|
type="text"
|
||||||
label="Email"
|
label="Email"
|
||||||
|
@ -49,9 +53,11 @@ class UserEmailNew extends React.PureComponent {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className="form-row-submit">
|
<div className="form-row-submit">
|
||||||
<Submit label="Next" disabled={isPending} />
|
<Submit label="Submit" disabled={isPending} />
|
||||||
|
{cancelButton}
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,16 @@ import {
|
||||||
selectEmailVerifyErrorMessage,
|
selectEmailVerifyErrorMessage,
|
||||||
} from "redux/selectors/user";
|
} from "redux/selectors/user";
|
||||||
import UserEmailVerify from "./view";
|
import UserEmailVerify from "./view";
|
||||||
|
import rewards from "rewards";
|
||||||
|
import { makeSelectRewardAmountByType } from "redux/selectors/rewards";
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
isPending: selectEmailVerifyIsPending(state),
|
isPending: selectEmailVerifyIsPending(state),
|
||||||
email: selectEmailToVerify(state),
|
email: selectEmailToVerify(state),
|
||||||
errorMessage: selectEmailVerifyErrorMessage(state),
|
errorMessage: selectEmailVerifyErrorMessage(state),
|
||||||
|
rewardAmount: makeSelectRewardAmountByType()(state, {
|
||||||
|
reward_type: rewards.TYPE_CONFIRM_EMAIL,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import Link from "component/link";
|
import Link from "component/link";
|
||||||
|
import { CreditAmount } from "component/common";
|
||||||
import { Form, FormRow, Submit } from "component/form.js";
|
import { Form, FormRow, Submit } from "component/form.js";
|
||||||
|
|
||||||
class UserEmailVerify extends React.PureComponent {
|
class UserEmailVerify extends React.PureComponent {
|
||||||
|
@ -23,10 +24,16 @@ class UserEmailVerify extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { errorMessage, isPending } = this.props;
|
const {
|
||||||
|
cancelButton,
|
||||||
|
errorMessage,
|
||||||
|
email,
|
||||||
|
isPending,
|
||||||
|
rewardAmount,
|
||||||
|
} = this.props;
|
||||||
return (
|
return (
|
||||||
<Form onSubmit={this.handleSubmit.bind(this)}>
|
<Form onSubmit={this.handleSubmit.bind(this)}>
|
||||||
<p>{__("Please enter the verification code emailed to you.")}</p>
|
<p>Please enter the verification code emailed to {email}.</p>
|
||||||
<FormRow
|
<FormRow
|
||||||
type="text"
|
type="text"
|
||||||
label={__("Verification Code")}
|
label={__("Verification Code")}
|
||||||
|
@ -41,12 +48,14 @@ class UserEmailVerify extends React.PureComponent {
|
||||||
<div className="form-field__helper">
|
<div className="form-field__helper">
|
||||||
<p>
|
<p>
|
||||||
{__("Email")}{" "}
|
{__("Email")}{" "}
|
||||||
<Link href="mailto:help@lbry.io" label="help@lbry.io" />{" "}
|
<Link href="mailto:help@lbry.io" label="help@lbry.io" /> or join our{" "}
|
||||||
|
<Link href="https://chat.lbry.io" label="chat" />{" "}
|
||||||
{__("if you encounter any trouble with your code.")}
|
{__("if you encounter any trouble with your code.")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-row-submit form-row-submit--with-footer">
|
<div className="form-row-submit">
|
||||||
<Submit label={__("Verify")} disabled={this.state.submitting} />
|
<Submit label={__("Verify")} disabled={isPending} />
|
||||||
|
{cancelButton}
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
|
|
@ -79,9 +79,16 @@ class UserVerify extends React.PureComponent {
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
<p>
|
<p>
|
||||||
{__(
|
{__(
|
||||||
"If you have a YouTube account with subscribers and views, you can sync your account to be granted instant verification."
|
"If you have a YouTube account with subscribers and views, you can sync your account and content to be granted instant verification."
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
{__("Some account minimums apply.")}{" "}
|
||||||
|
<Link
|
||||||
|
href="https://lbry.io/faq/youtube"
|
||||||
|
label={__("Read more.")}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="card__actions">
|
<div className="card__actions">
|
||||||
<Link
|
<Link
|
||||||
|
|
|
@ -23,11 +23,12 @@ const WalletBalance = props => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="card__actions">
|
<div className="card__actions">
|
||||||
|
<Link button="alt" navigate="/getcredits" label={__("Get Credits")} />
|
||||||
<Link
|
<Link
|
||||||
button="primary"
|
button="alt"
|
||||||
disabled={balance === 0}
|
disabled={balance === 0}
|
||||||
navigate="/backup"
|
navigate="/backup"
|
||||||
label={__("Backup wallet")}
|
label={__("Backup Wallet")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -6,11 +6,10 @@ export const ERROR = "error";
|
||||||
export const INSUFFICIENT_CREDITS = "insufficient_credits";
|
export const INSUFFICIENT_CREDITS = "insufficient_credits";
|
||||||
export const UPGRADE = "upgrade";
|
export const UPGRADE = "upgrade";
|
||||||
export const WELCOME = "welcome";
|
export const WELCOME = "welcome";
|
||||||
|
export const EMAIL_COLLECTION = "email_collection";
|
||||||
export const FIRST_REWARD = "first_reward";
|
export const FIRST_REWARD = "first_reward";
|
||||||
export const AUTHENTICATION_FAILURE = "auth_failure";
|
export const AUTHENTICATION_FAILURE = "auth_failure";
|
||||||
export const TRANSACTION_FAILED = "transaction_failed";
|
export const TRANSACTION_FAILED = "transaction_failed";
|
||||||
export const INSUFFICIENT_BALANCE = "insufficient_balance";
|
|
||||||
export const REWARD_APPROVAL_REQUIRED = "reward_approval_required";
|
export const REWARD_APPROVAL_REQUIRED = "reward_approval_required";
|
||||||
export const AFFIRM_PURCHASE = "affirm_purchase";
|
export const AFFIRM_PURCHASE = "affirm_purchase";
|
||||||
export const CREDIT_INTRO = "credit_intro";
|
|
||||||
export const CONFIRM_CLAIM_REVOKE = "confirmClaimRevoke";
|
export const CONFIRM_CLAIM_REVOKE = "confirmClaimRevoke";
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
/*hardcoded names still exist for these in reducers/settings.js - only discovered when debugging*/
|
/*hardcoded names still exist for these in reducers/settings.js - only discovered when debugging*/
|
||||||
/*Many settings are stored in the localStorage by their name -
|
/*Many settings are stored in the localStorage by their name -
|
||||||
be careful about changing the value of a settings constant, as doing so can invalidate existing settings*/
|
be careful about changing the value of a settings constant, as doing so can invalidate existing settings*/
|
||||||
export const CREDIT_INTRO_ACKNOWLEDGED = "credit_intro_acknowledged";
|
export const CREDIT_REQUIRED_ACKNOWLEDGED = "credit_required_acknowledged";
|
||||||
export const NEW_USER_ACKNOWLEDGED = "welcome_acknowledged";
|
export const NEW_USER_ACKNOWLEDGED = "welcome_acknowledged";
|
||||||
|
export const EMAIL_COLLECTION_ACKNOWLEDGED = "email_collection_acknowledged";
|
||||||
export const LANGUAGE = "language";
|
export const LANGUAGE = "language";
|
||||||
export const SHOW_NSFW = "showNsfw";
|
export const SHOW_NSFW = "showNsfw";
|
||||||
export const SHOW_UNAVAILABLE = "showUnavailable";
|
export const SHOW_UNAVAILABLE = "showUnavailable";
|
||||||
|
|
|
@ -61,7 +61,7 @@ document.addEventListener("click", event => {
|
||||||
if (target.matches("a") || target.matches("button")) {
|
if (target.matches("a") || target.matches("button")) {
|
||||||
// TODO: Look into using accessiblity labels (this would also make the app more accessible)
|
// TODO: Look into using accessiblity labels (this would also make the app more accessible)
|
||||||
let hrefParts = window.location.href.split("#");
|
let hrefParts = window.location.href.split("#");
|
||||||
let element = target.title || target.text.trim();
|
let element = target.title || (target.text && target.text.trim());
|
||||||
if (element) {
|
if (element) {
|
||||||
amplitude.getInstance().logEvent("CLICK", {
|
amplitude.getInstance().logEvent("CLICK", {
|
||||||
target: element,
|
target: element,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doCloseModal } from "redux/actions/app";
|
import { doCloseModal } from "redux/actions/app";
|
||||||
import { doAuthNavigate } 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 } from "redux/selectors/user";
|
||||||
import { selectBalance } from "redux/selectors/wallet";
|
import { selectBalance } from "redux/selectors/wallet";
|
||||||
|
@ -25,17 +25,16 @@ const select = (state, props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const perform = dispatch => () => {
|
const perform = dispatch => () => {
|
||||||
const closeModal = () => {
|
|
||||||
dispatch(doSetClientSetting(settings.CREDIT_INTRO_ACKNOWLEDGED, true));
|
|
||||||
dispatch(doCloseModal());
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
verifyAccount: () => {
|
addBalance: () => {
|
||||||
closeModal();
|
dispatch(doSetClientSetting(settings.CREDIT_REQUIRED_ACKNOWLEDGED, true));
|
||||||
dispatch(doAuthNavigate("/discover"));
|
dispatch(doNavigate("/getcredits"));
|
||||||
|
dispatch(doCloseModal());
|
||||||
|
},
|
||||||
|
closeModal: () => {
|
||||||
|
dispatch(doSetClientSetting(settings.CREDIT_REQUIRED_ACKNOWLEDGED, true));
|
||||||
|
dispatch(doCloseModal());
|
||||||
},
|
},
|
||||||
closeModal: closeModal,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,55 +4,42 @@ import { CreditAmount, CurrencySymbol } from "component/common";
|
||||||
import Link from "component/link/index";
|
import Link from "component/link/index";
|
||||||
|
|
||||||
const ModalCreditIntro = props => {
|
const ModalCreditIntro = props => {
|
||||||
const { closeModal, totalRewardValue, currentBalance, verifyAccount } = props;
|
const { closeModal, totalRewardValue, currentBalance, addBalance } = props;
|
||||||
const totalRewardRounded = Math.round(totalRewardValue / 10) * 10;
|
const totalRewardRounded = Math.round(totalRewardValue / 10) * 10;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal type="custom" isOpen={true} contentLabel="Welcome to LBRY">
|
<Modal type="custom" isOpen={true} contentLabel="Welcome to LBRY">
|
||||||
<section>
|
<section>
|
||||||
<h3 className="modal__header">{__("Blockchain 101")}</h3>
|
<h3 className="modal__header">
|
||||||
|
{__("Computer Wizard Needs Tokens Badly")}
|
||||||
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
LBRY is controlled and powered by a blockchain asset called{" "}
|
Some actions require{" "} LBRY credits
|
||||||
<em>
|
(<em>
|
||||||
<CurrencySymbol />
|
<CurrencySymbol />
|
||||||
</em>. <CurrencySymbol />{" "}
|
</em>), the blockchain token that powers the LBRY network.
|
||||||
{__(
|
</p>
|
||||||
"is used to publish content, to have a say in the network rules, and to access paid content."
|
{currentBalance <= 0 && (
|
||||||
|
<p>
|
||||||
|
You currently have <CreditAmount amount={currentBalance} />, so the
|
||||||
|
actions you can take are limited.
|
||||||
|
</p>
|
||||||
)}
|
)}
|
||||||
</p>
|
|
||||||
{currentBalance <= 0 ? (
|
|
||||||
<div>
|
|
||||||
<p>
|
<p>
|
||||||
You currently have <CreditAmount amount={currentBalance} />, so
|
There are a variety of ways to get credits, including more than{" "}
|
||||||
the actions you can take are limited.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
However, there are a variety of ways to get credits, including
|
|
||||||
more than{" "}
|
|
||||||
{totalRewardValue ? (
|
{totalRewardValue ? (
|
||||||
<CreditAmount amount={totalRewardRounded} />
|
<CreditAmount amount={totalRewardRounded} />
|
||||||
) : (
|
) : (
|
||||||
<span className="credit-amount">{__("?? credits")}</span>
|
<span className="credit-amount">{__("?? credits")}</span>
|
||||||
)}{" "}
|
)}{" "}
|
||||||
{__(
|
{__(" in free rewards for participating in the LBRY beta.")}
|
||||||
" in rewards available for being a proven human during the LBRY beta."
|
|
||||||
)}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
But you probably knew this, since you've already got{" "}
|
|
||||||
<CreditAmount amount={currentBalance} />.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="modal__buttons">
|
<div className="modal__buttons">
|
||||||
<Link
|
<Link
|
||||||
button="primary"
|
button="primary"
|
||||||
onClick={verifyAccount}
|
onClick={addBalance}
|
||||||
label={__("I'm Totally A Human")}
|
label={__("Get Credits")}
|
||||||
/>
|
/>
|
||||||
<Link
|
<Link
|
||||||
button="alt"
|
button="alt"
|
||||||
|
|
21
src/renderer/modal/modalEmailCollection/index.js
Normal file
21
src/renderer/modal/modalEmailCollection/index.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import React from "react";
|
||||||
|
import * as settings from "constants/settings";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { doCloseModal } from "redux/actions/app";
|
||||||
|
import { doSetClientSetting } from "redux/actions/settings";
|
||||||
|
import { selectEmailToVerify, selectUser } from "redux/selectors/user";
|
||||||
|
import ModalEmailCollection from "./view";
|
||||||
|
|
||||||
|
const select = state => ({
|
||||||
|
email: selectEmailToVerify(state),
|
||||||
|
user: selectUser(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
const perform = dispatch => () => ({
|
||||||
|
closeModal: () => {
|
||||||
|
dispatch(doSetClientSetting(settings.EMAIL_COLLECTION_ACKNOWLEDGED, true));
|
||||||
|
dispatch(doCloseModal());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(select, perform)(ModalEmailCollection);
|
45
src/renderer/modal/modalEmailCollection/view.jsx
Normal file
45
src/renderer/modal/modalEmailCollection/view.jsx
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import React from "react";
|
||||||
|
import { Modal } from "modal/modal";
|
||||||
|
import Link from "component/link/index";
|
||||||
|
import UserEmailNew from "component/userEmailNew";
|
||||||
|
import UserEmailVerify from "component/userEmailVerify";
|
||||||
|
|
||||||
|
class ModalEmailCollection extends React.PureComponent {
|
||||||
|
renderInner() {
|
||||||
|
const { closeModal, email, user } = this.props;
|
||||||
|
|
||||||
|
const cancelButton = (
|
||||||
|
<Link button="text" onClick={closeModal} label={__("Not Now")} />
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!user.has_verified_email && !email) {
|
||||||
|
return <UserEmailNew cancelButton={cancelButton} />;
|
||||||
|
} else if (!user.has_verified_email) {
|
||||||
|
return <UserEmailVerify cancelButton={cancelButton} />;
|
||||||
|
} else {
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { user } = this.props;
|
||||||
|
|
||||||
|
//this shouldn't happen
|
||||||
|
if (!user) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal type="custom" isOpen={true} contentLabel="Email">
|
||||||
|
<section>
|
||||||
|
<h3 className="modal__header">
|
||||||
|
Can We <strike>Touch You</strike> Stay In Touch?
|
||||||
|
</h3>
|
||||||
|
{this.renderInner()}
|
||||||
|
</section>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ModalEmailCollection;
|
|
@ -32,12 +32,7 @@ class ModalFirstReward extends React.PureComponent {
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{__(
|
{__(
|
||||||
"No need to understand it all just yet! Try watching or downloading something next."
|
"No need to understand it all just yet! Try watching or publishing something next."
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{__(
|
|
||||||
"Finally, please know that LBRY is an early beta and that it earns the name."
|
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
import { connect } from "react-redux";
|
|
||||||
import { doCloseModal } from "redux/actions/app";
|
|
||||||
import { doNavigate } from "redux/actions/navigation";
|
|
||||||
import ModalInsufficientBalance from "./view";
|
|
||||||
|
|
||||||
const select = state => ({});
|
|
||||||
|
|
||||||
const perform = dispatch => ({
|
|
||||||
addBalance: () => {
|
|
||||||
dispatch(doNavigate("/wallet"));
|
|
||||||
dispatch(doCloseModal());
|
|
||||||
},
|
|
||||||
closeModal: () => dispatch(doCloseModal()),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(select, perform)(ModalInsufficientBalance);
|
|
|
@ -1,26 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
import { Modal } from "modal/modal";
|
|
||||||
|
|
||||||
class ModalInsufficientBalance extends React.PureComponent {
|
|
||||||
render() {
|
|
||||||
const { addBalance, closeModal } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
isOpen={true}
|
|
||||||
type="confirm"
|
|
||||||
contentLabel={__("Not enough credits")}
|
|
||||||
confirmButtonLabel={__("Get Credits")}
|
|
||||||
abortButtonLabel={__("Cancel")}
|
|
||||||
onAborted={closeModal}
|
|
||||||
onConfirmed={addBalance}
|
|
||||||
>
|
|
||||||
{__(
|
|
||||||
"Insufficient balance: after this transaction you would have less than 0 LBCs in your wallet."
|
|
||||||
)}
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ModalInsufficientBalance;
|
|
|
@ -1,17 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
import { connect } from "react-redux";
|
|
||||||
import { doCloseModal } from "redux/actions/app";
|
|
||||||
import { doNavigate } from "redux/actions/navigation";
|
|
||||||
import ModalInsufficientCredits from "./view";
|
|
||||||
|
|
||||||
const select = state => ({});
|
|
||||||
|
|
||||||
const perform = dispatch => ({
|
|
||||||
addFunds: () => {
|
|
||||||
dispatch(doNavigate("/wallet"));
|
|
||||||
dispatch(doCloseModal());
|
|
||||||
},
|
|
||||||
closeModal: () => dispatch(doCloseModal()),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(select, perform)(ModalInsufficientCredits);
|
|
|
@ -1,28 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
import { Modal } from "modal/modal";
|
|
||||||
import { CurrencySymbol } from "component/common";
|
|
||||||
|
|
||||||
class ModalInsufficientCredits extends React.PureComponent {
|
|
||||||
render() {
|
|
||||||
const { addFunds, closeModal } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
isOpen={true}
|
|
||||||
type="confirm"
|
|
||||||
contentLabel={__("Not enough credits")}
|
|
||||||
confirmButtonLabel={__("Get Credits")}
|
|
||||||
abortButtonLabel={__("Not Now")}
|
|
||||||
onAborted={closeModal}
|
|
||||||
onConfirmed={addFunds}
|
|
||||||
>
|
|
||||||
<h3 className="modal__header">{__("More Credits Required")}</h3>
|
|
||||||
<p>
|
|
||||||
You'll need more <CurrencySymbol /> to do this.
|
|
||||||
</p>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ModalInsufficientCredits;
|
|
|
@ -6,8 +6,12 @@ import { selectCurrentModal, selectModalProps } from "redux/selectors/app";
|
||||||
import { selectCurrentPage } from "redux/selectors/navigation";
|
import { selectCurrentPage } from "redux/selectors/navigation";
|
||||||
import { selectCostForCurrentPageUri } from "redux/selectors/cost_info";
|
import { selectCostForCurrentPageUri } from "redux/selectors/cost_info";
|
||||||
import { makeSelectClientSetting } from "redux/selectors/settings";
|
import { makeSelectClientSetting } from "redux/selectors/settings";
|
||||||
import { selectUser } from "redux/selectors/user";
|
import {
|
||||||
|
selectUser,
|
||||||
|
selectUserIsVerificationCandidate,
|
||||||
|
} from "redux/selectors/user";
|
||||||
import { selectBalance } from "redux/selectors/wallet";
|
import { selectBalance } from "redux/selectors/wallet";
|
||||||
|
|
||||||
import ModalRouter from "./view";
|
import ModalRouter from "./view";
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
|
@ -16,12 +20,16 @@ const select = (state, props) => ({
|
||||||
modal: selectCurrentModal(state),
|
modal: selectCurrentModal(state),
|
||||||
modalProps: selectModalProps(state),
|
modalProps: selectModalProps(state),
|
||||||
page: selectCurrentPage(state),
|
page: selectCurrentPage(state),
|
||||||
|
isVerificationCandidate: selectUserIsVerificationCandidate(state),
|
||||||
|
isCreditIntroAcknowledged: makeSelectClientSetting(
|
||||||
|
settings.CREDIT_REQUIRED_ACKNOWLEDGED
|
||||||
|
)(state),
|
||||||
|
isEmailCollectionAcknowledged: makeSelectClientSetting(
|
||||||
|
settings.EMAIL_COLLECTION_ACKNOWLEDGED
|
||||||
|
)(state),
|
||||||
isWelcomeAcknowledged: makeSelectClientSetting(
|
isWelcomeAcknowledged: makeSelectClientSetting(
|
||||||
settings.NEW_USER_ACKNOWLEDGED
|
settings.NEW_USER_ACKNOWLEDGED
|
||||||
)(state),
|
)(state),
|
||||||
isCreditIntroAcknowledged: makeSelectClientSetting(
|
|
||||||
settings.CREDIT_INTRO_ACKNOWLEDGED
|
|
||||||
)(state),
|
|
||||||
user: selectUser(state),
|
user: selectUser(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import React from "react";
|
||||||
import ModalError from "modal/modalError";
|
import ModalError from "modal/modalError";
|
||||||
import ModalAuthFailure from "modal/modalAuthFailure";
|
import ModalAuthFailure from "modal/modalAuthFailure";
|
||||||
import ModalDownloading from "modal/modalDownloading";
|
import ModalDownloading from "modal/modalDownloading";
|
||||||
import ModalInsufficientCredits from "modal/modalInsufficientCredits";
|
|
||||||
import ModalUpgrade from "modal/modalUpgrade";
|
import ModalUpgrade from "modal/modalUpgrade";
|
||||||
import ModalWelcome from "modal/modalWelcome";
|
import ModalWelcome from "modal/modalWelcome";
|
||||||
import ModalFirstReward from "modal/modalFirstReward";
|
import ModalFirstReward from "modal/modalFirstReward";
|
||||||
|
@ -10,10 +9,10 @@ import ModalRewardApprovalRequired from "modal/modalRewardApprovalRequired";
|
||||||
import ModalCreditIntro from "modal/modalCreditIntro";
|
import ModalCreditIntro from "modal/modalCreditIntro";
|
||||||
import ModalRemoveFile from "modal/modalRemoveFile";
|
import ModalRemoveFile from "modal/modalRemoveFile";
|
||||||
import ModalTransactionFailed from "modal/modalTransactionFailed";
|
import ModalTransactionFailed from "modal/modalTransactionFailed";
|
||||||
import ModalInsufficientBalance from "modal/modalInsufficientBalance";
|
|
||||||
import ModalFileTimeout from "modal/modalFileTimeout";
|
import ModalFileTimeout from "modal/modalFileTimeout";
|
||||||
import ModalAffirmPurchase from "modal/modalAffirmPurchase";
|
import ModalAffirmPurchase from "modal/modalAffirmPurchase";
|
||||||
import ModalRevokeClaim from "modal/modalRevokeClaim";
|
import ModalRevokeClaim from "modal/modalRevokeClaim";
|
||||||
|
import ModalEmailCollection from "../modalEmailCollection";
|
||||||
import * as modals from "constants/modal_types";
|
import * as modals from "constants/modal_types";
|
||||||
|
|
||||||
class ModalRouter extends React.PureComponent {
|
class ModalRouter extends React.PureComponent {
|
||||||
|
@ -43,8 +42,8 @@ class ModalRouter extends React.PureComponent {
|
||||||
|
|
||||||
const transitionModal = [
|
const transitionModal = [
|
||||||
this.checkShowWelcome,
|
this.checkShowWelcome,
|
||||||
|
this.checkShowEmail,
|
||||||
this.checkShowCreditIntro,
|
this.checkShowCreditIntro,
|
||||||
this.checkShowInsufficientCredits,
|
|
||||||
].reduce((acc, func) => {
|
].reduce((acc, func) => {
|
||||||
return !acc ? func.bind(this)(props) : acc;
|
return !acc ? func.bind(this)(props) : acc;
|
||||||
}, false);
|
}, false);
|
||||||
|
@ -74,24 +73,30 @@ class ModalRouter extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkShowEmail(props) {
|
||||||
|
const {
|
||||||
|
isEmailCollectionAcknowledged,
|
||||||
|
isVerificationCandidate,
|
||||||
|
user,
|
||||||
|
} = props;
|
||||||
|
if (
|
||||||
|
!isEmailCollectionAcknowledged &&
|
||||||
|
isVerificationCandidate &&
|
||||||
|
user &&
|
||||||
|
!user.has_verified_email
|
||||||
|
) {
|
||||||
|
return modals.EMAIL_COLLECTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
checkShowCreditIntro(props) {
|
checkShowCreditIntro(props) {
|
||||||
const { page, isCreditIntroAcknowledged, user } = props;
|
const { balance, page, isCreditIntroAcknowledged } = props;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
balance <= 0 &&
|
||||||
!isCreditIntroAcknowledged &&
|
!isCreditIntroAcknowledged &&
|
||||||
user &&
|
(["send", "publish"].includes(page) || this.isPaidShowPage(props))
|
||||||
!user.is_reward_approved &&
|
|
||||||
(["rewards", "send", "receive", "publish", "wallet"].includes(page) ||
|
|
||||||
this.isPaidShowPage(props))
|
|
||||||
) {
|
) {
|
||||||
return modals.CREDIT_INTRO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkShowInsufficientCredits(props) {
|
|
||||||
const { balance, page } = props;
|
|
||||||
|
|
||||||
if (balance <= 0 && ["send", "publish"].includes(page)) {
|
|
||||||
return modals.INSUFFICIENT_CREDITS;
|
return modals.INSUFFICIENT_CREDITS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,19 +119,15 @@ class ModalRouter extends React.PureComponent {
|
||||||
case modals.FILE_TIMEOUT:
|
case modals.FILE_TIMEOUT:
|
||||||
return <ModalFileTimeout {...modalProps} />;
|
return <ModalFileTimeout {...modalProps} />;
|
||||||
case modals.INSUFFICIENT_CREDITS:
|
case modals.INSUFFICIENT_CREDITS:
|
||||||
return <ModalInsufficientCredits {...modalProps} />;
|
return <ModalCreditIntro {...modalProps} />;
|
||||||
case modals.WELCOME:
|
case modals.WELCOME:
|
||||||
return <ModalWelcome {...modalProps} />;
|
return <ModalWelcome {...modalProps} />;
|
||||||
case modals.FIRST_REWARD:
|
case modals.FIRST_REWARD:
|
||||||
return <ModalFirstReward {...modalProps} />;
|
return <ModalFirstReward {...modalProps} />;
|
||||||
case modals.AUTHENTICATION_FAILURE:
|
case modals.AUTHENTICATION_FAILURE:
|
||||||
return <ModalAuthFailure {...modalProps} />;
|
return <ModalAuthFailure {...modalProps} />;
|
||||||
case modals.CREDIT_INTRO:
|
|
||||||
return <ModalCreditIntro {...modalProps} />;
|
|
||||||
case modals.TRANSACTION_FAILED:
|
case modals.TRANSACTION_FAILED:
|
||||||
return <ModalTransactionFailed {...modalProps} />;
|
return <ModalTransactionFailed {...modalProps} />;
|
||||||
case modals.INSUFFICIENT_BALANCE:
|
|
||||||
return <ModalInsufficientBalance {...modalProps} />;
|
|
||||||
case modals.REWARD_APPROVAL_REQUIRED:
|
case modals.REWARD_APPROVAL_REQUIRED:
|
||||||
return <ModalRewardApprovalRequired {...modalProps} />;
|
return <ModalRewardApprovalRequired {...modalProps} />;
|
||||||
case modals.CONFIRM_FILE_REMOVE:
|
case modals.CONFIRM_FILE_REMOVE:
|
||||||
|
@ -135,6 +136,8 @@ class ModalRouter extends React.PureComponent {
|
||||||
return <ModalAffirmPurchase {...modalProps} />;
|
return <ModalAffirmPurchase {...modalProps} />;
|
||||||
case modals.CONFIRM_CLAIM_REVOKE:
|
case modals.CONFIRM_CLAIM_REVOKE:
|
||||||
return <ModalRevokeClaim {...modalProps} />;
|
return <ModalRevokeClaim {...modalProps} />;
|
||||||
|
case modals.EMAIL_COLLECTION:
|
||||||
|
return <ModalEmailCollection {...modalProps} />;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
5
src/renderer/page/getCredits/index.js
Normal file
5
src/renderer/page/getCredits/index.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import React from "react";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import GetCreditsPage from "./view";
|
||||||
|
|
||||||
|
export default connect(null, null)(GetCreditsPage);
|
|
@ -1,15 +1,28 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import SubHeader from "component/subHeader";
|
import SubHeader from "component/subHeader";
|
||||||
import Link from "component/link";
|
import Link from "component/link";
|
||||||
import WalletAddress from "component/walletAddress";
|
import RewardSummary from "component/rewardSummary";
|
||||||
import ShapeShift from "component/shapeShift";
|
import ShapeShift from "component/shapeShift";
|
||||||
|
|
||||||
const ReceiveCreditsPage = props => {
|
const GetCreditsPage = props => {
|
||||||
return (
|
return (
|
||||||
<main className="main--single-column">
|
<main className="main--single-column">
|
||||||
<SubHeader />
|
<SubHeader />
|
||||||
<WalletAddress />
|
<RewardSummary />
|
||||||
<ShapeShift />
|
<ShapeShift />
|
||||||
|
<section className="card">
|
||||||
|
<div className="card__title-primary">
|
||||||
|
<h3>{__("From External Wallet")}</h3>
|
||||||
|
</div>
|
||||||
|
<div className="card__actions">
|
||||||
|
<Link
|
||||||
|
button="alt"
|
||||||
|
navigate="/send"
|
||||||
|
icon="icon-send"
|
||||||
|
label={__("Send / Receive")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
<section className="card">
|
<section className="card">
|
||||||
<div className="card__title-primary">
|
<div className="card__title-primary">
|
||||||
<h3>{__("More ways to get LBRY Credits")}</h3>
|
<h3>{__("More ways to get LBRY Credits")}</h3>
|
||||||
|
@ -33,4 +46,4 @@ const ReceiveCreditsPage = props => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ReceiveCreditsPage;
|
export default GetCreditsPage;
|
|
@ -1,5 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
import { connect } from "react-redux";
|
|
||||||
import ReceiveCreditsPage from "./view";
|
|
||||||
|
|
||||||
export default connect(null, null)(ReceiveCreditsPage);
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import SendCreditsPage from "./view";
|
import SendReceivePage from "./view";
|
||||||
|
|
||||||
export default connect(null, null)(SendCreditsPage);
|
export default connect(null, null)(SendReceivePage);
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import SubHeader from "component/subHeader";
|
import SubHeader from "component/subHeader";
|
||||||
import WalletSend from "component/walletSend";
|
import WalletSend from "component/walletSend";
|
||||||
|
import WalletAddress from "component/walletAddress";
|
||||||
|
|
||||||
const SendCreditsPage = props => {
|
const SendReceivePage = props => {
|
||||||
return (
|
return (
|
||||||
<main className="main--single-column">
|
<main className="main--single-column">
|
||||||
<SubHeader />
|
<SubHeader />
|
||||||
<WalletSend />
|
<WalletSend />
|
||||||
|
<WalletAddress />
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SendCreditsPage;
|
export default SendReceivePage;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import lbryio from "lbryio";
|
||||||
import rewards from "rewards";
|
import rewards from "rewards";
|
||||||
import { selectUnclaimedRewardsByType } from "redux/selectors/rewards";
|
import { selectUnclaimedRewardsByType } from "redux/selectors/rewards";
|
||||||
import { selectUserIsRewardApproved } from "redux/selectors/user";
|
import { selectUserIsRewardApproved } from "redux/selectors/user";
|
||||||
|
import { selectClaimedRewardsById } from "../selectors/rewards";
|
||||||
|
|
||||||
export function doRewardList() {
|
export function doRewardList() {
|
||||||
return function(dispatch, getState) {
|
return function(dispatch, getState) {
|
||||||
|
@ -42,7 +43,7 @@ export function doClaimRewardType(rewardType) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!userIsRewardApproved) {
|
if (!userIsRewardApproved && rewardType !== rewards.TYPE_CONFIRM_EMAIL) {
|
||||||
return dispatch({
|
return dispatch({
|
||||||
type: types.OPEN_MODAL,
|
type: types.OPEN_MODAL,
|
||||||
data: { modal: modals.REWARD_APPROVAL_REQUIRED },
|
data: { modal: modals.REWARD_APPROVAL_REQUIRED },
|
||||||
|
@ -61,7 +62,7 @@ export function doClaimRewardType(rewardType) {
|
||||||
reward,
|
reward,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (reward.reward_type == rewards.TYPE_NEW_USER) {
|
if (reward.reward_type == rewards.TYPE_CONFIRM_EMAIL) {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: types.OPEN_MODAL,
|
type: types.OPEN_MODAL,
|
||||||
data: { modal: modals.FIRST_REWARD },
|
data: { modal: modals.FIRST_REWARD },
|
||||||
|
|
|
@ -61,6 +61,22 @@ export function doUserEmailNew(email) {
|
||||||
type: types.USER_EMAIL_NEW_STARTED,
|
type: types.USER_EMAIL_NEW_STARTED,
|
||||||
email: email,
|
email: email,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const success = () => {
|
||||||
|
dispatch({
|
||||||
|
type: types.USER_EMAIL_NEW_SUCCESS,
|
||||||
|
data: { email },
|
||||||
|
});
|
||||||
|
dispatch(doUserFetch());
|
||||||
|
}
|
||||||
|
|
||||||
|
const failure = error => {
|
||||||
|
dispatch({
|
||||||
|
type: types.USER_EMAIL_NEW_FAILURE,
|
||||||
|
data: { error },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
lbryio
|
lbryio
|
||||||
.call(
|
.call(
|
||||||
"user_email",
|
"user_email",
|
||||||
|
@ -75,23 +91,11 @@ export function doUserEmailNew(email) {
|
||||||
"resend_token",
|
"resend_token",
|
||||||
{ email: email, only_if_expired: true },
|
{ email: email, only_if_expired: true },
|
||||||
"post"
|
"post"
|
||||||
);
|
).then(success, failure);
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(success, failure);
|
||||||
dispatch({
|
|
||||||
type: types.USER_EMAIL_NEW_SUCCESS,
|
|
||||||
data: { email },
|
|
||||||
});
|
|
||||||
dispatch(doUserFetch());
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
dispatch({
|
|
||||||
type: types.USER_EMAIL_NEW_FAILURE,
|
|
||||||
data: { error },
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +122,7 @@ export function doUserEmailVerify(verificationToken) {
|
||||||
type: types.USER_EMAIL_VERIFY_SUCCESS,
|
type: types.USER_EMAIL_VERIFY_SUCCESS,
|
||||||
data: { email },
|
data: { email },
|
||||||
});
|
});
|
||||||
|
dispatch(doClaimRewardType(rewards.TYPE_CONFIRM_EMAIL)),
|
||||||
dispatch(doUserFetch());
|
dispatch(doUserFetch());
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Your email is still not verified."); //shouldn't happen
|
throw new Error("Your email is still not verified."); //shouldn't happen
|
||||||
|
|
|
@ -97,7 +97,7 @@ export function doSendDraftTransaction() {
|
||||||
const amount = selectDraftTransactionAmount(state);
|
const amount = selectDraftTransactionAmount(state);
|
||||||
|
|
||||||
if (balance - amount <= 0) {
|
if (balance - amount <= 0) {
|
||||||
return dispatch(doOpenModal(modals.INSUFFICIENT_BALANCE));
|
return dispatch(doOpenModal(modals.INSUFFICIENT_CREDITS));
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -162,7 +162,7 @@ export function doSendSupport(amount, claim_id, uri) {
|
||||||
const balance = selectBalance(state);
|
const balance = selectBalance(state);
|
||||||
|
|
||||||
if (balance - amount <= 0) {
|
if (balance - amount <= 0) {
|
||||||
return dispatch(doOpenModal(modals.INSUFFICIENT_BALANCE));
|
return dispatch(doOpenModal(modals.INSUFFICIENT_CREDITS));
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
|
|
|
@ -24,9 +24,10 @@ const defaultState = {
|
||||||
settings.NEW_USER_ACKNOWLEDGED,
|
settings.NEW_USER_ACKNOWLEDGED,
|
||||||
false
|
false
|
||||||
),
|
),
|
||||||
credit_intro_acknowledged: getLocalStorageSetting(
|
email_collection_acknowledged: getLocalStorageSetting(
|
||||||
settings.CREDIT_INTRO_ACKNOWLEDGED
|
settings.EMAIL_COLLECTION_ACKNOWLEDGED
|
||||||
),
|
),
|
||||||
|
credit_required_acknowledged: false, //this needs to be re-acknowledged every run
|
||||||
language: getLocalStorageSetting(settings.LANGUAGE, "en"),
|
language: getLocalStorageSetting(settings.LANGUAGE, "en"),
|
||||||
theme: getLocalStorageSetting(settings.THEME, "light"),
|
theme: getLocalStorageSetting(settings.THEME, "light"),
|
||||||
themes: getLocalStorageSetting(settings.THEMES, []),
|
themes: getLocalStorageSetting(settings.THEMES, []),
|
||||||
|
|
|
@ -37,17 +37,17 @@ export const selectHeaderLinks = createSelector(selectCurrentPage, page => {
|
||||||
case "wallet":
|
case "wallet":
|
||||||
case "history":
|
case "history":
|
||||||
case "send":
|
case "send":
|
||||||
case "receive":
|
case "getcredits":
|
||||||
case "invite":
|
case "invite":
|
||||||
case "rewards":
|
case "rewards":
|
||||||
case "backup":
|
case "backup":
|
||||||
return {
|
return {
|
||||||
wallet: __("Overview"),
|
wallet: __("Overview"),
|
||||||
history: __("History"),
|
getcredits: __("Get Credits"),
|
||||||
send: __("Send Credits"),
|
send: __("Send / Receive"),
|
||||||
receive: __("Get Credits"),
|
|
||||||
rewards: __("Rewards"),
|
rewards: __("Rewards"),
|
||||||
invite: __("Invites"),
|
invite: __("Invites"),
|
||||||
|
history: __("History"),
|
||||||
};
|
};
|
||||||
case "downloaded":
|
case "downloaded":
|
||||||
case "published":
|
case "published":
|
||||||
|
@ -78,8 +78,8 @@ export const selectPageTitle = createSelector(
|
||||||
case "wallet":
|
case "wallet":
|
||||||
return __("Wallet");
|
return __("Wallet");
|
||||||
case "send":
|
case "send":
|
||||||
return __("Send LBRY Credits");
|
return __("Send or Receive LBRY Credits");
|
||||||
case "receive":
|
case "getcredits":
|
||||||
return __("Get LBRY Credits");
|
return __("Get LBRY Credits");
|
||||||
case "backup":
|
case "backup":
|
||||||
return __("Backup Your Wallet");
|
return __("Backup Your Wallet");
|
||||||
|
|
|
@ -63,9 +63,8 @@ export const selectWunderBarIcon = createSelector(
|
||||||
return "icon-rocket";
|
return "icon-rocket";
|
||||||
case "invite":
|
case "invite":
|
||||||
return "icon-envelope-open";
|
return "icon-envelope-open";
|
||||||
case "address":
|
case "getcredits":
|
||||||
case "receive":
|
return "icon-shopping-cart";
|
||||||
return "icon-credit-card";
|
|
||||||
case "wallet":
|
case "wallet":
|
||||||
case "backup":
|
case "backup":
|
||||||
return "icon-bank";
|
return "icon-bank";
|
||||||
|
|
|
@ -14,16 +14,17 @@ export const selectUserIsPending = createSelector(
|
||||||
|
|
||||||
export const selectUser = createSelector(_selectState, state => state.user);
|
export const selectUser = createSelector(_selectState, state => state.user);
|
||||||
|
|
||||||
export const selectEmailToVerify = createSelector(
|
|
||||||
_selectState,
|
|
||||||
state => state.emailToVerify
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectUserEmail = createSelector(
|
export const selectUserEmail = createSelector(
|
||||||
selectUser,
|
selectUser,
|
||||||
user => (user ? user.primary_email : null)
|
user => (user ? user.primary_email : null)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const selectEmailToVerify = createSelector(
|
||||||
|
_selectState,
|
||||||
|
selectUserEmail,
|
||||||
|
(state, userEmail) => state.emailToVerify || userEmail
|
||||||
|
);
|
||||||
|
|
||||||
export const selectUserIsRewardApproved = createSelector(
|
export const selectUserIsRewardApproved = createSelector(
|
||||||
selectUser,
|
selectUser,
|
||||||
user => user && user.is_reward_approved
|
user => user && user.is_reward_approved
|
||||||
|
|
|
@ -33,10 +33,7 @@ function rewardMessage(type, amount) {
|
||||||
"You earned %s LBC for watching a featured download.",
|
"You earned %s LBC for watching a featured download.",
|
||||||
amount
|
amount
|
||||||
),
|
),
|
||||||
referral: __(
|
referral: __("You earned %s LBC for referring someone.", amount),
|
||||||
"You earned %s LBC for referring someone.",
|
|
||||||
amount
|
|
||||||
),
|
|
||||||
}[type];
|
}[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +41,7 @@ const rewards = {};
|
||||||
|
|
||||||
rewards.TYPE_NEW_DEVELOPER = "new_developer";
|
rewards.TYPE_NEW_DEVELOPER = "new_developer";
|
||||||
rewards.TYPE_NEW_USER = "new_user";
|
rewards.TYPE_NEW_USER = "new_user";
|
||||||
rewards.TYPE_CONFIRM_EMAIL = "confirm_email";
|
rewards.TYPE_CONFIRM_EMAIL = "verified_email";
|
||||||
rewards.TYPE_FIRST_CHANNEL = "new_channel";
|
rewards.TYPE_FIRST_CHANNEL = "new_channel";
|
||||||
rewards.TYPE_FIRST_STREAM = "first_stream";
|
rewards.TYPE_FIRST_STREAM = "first_stream";
|
||||||
rewards.TYPE_MANY_DOWNLOADS = "many_downloads";
|
rewards.TYPE_MANY_DOWNLOADS = "many_downloads";
|
||||||
|
|
|
@ -128,7 +128,7 @@ $text-color: #000;
|
||||||
--card-small-width: $spacing-vertical * 10;
|
--card-small-width: $spacing-vertical * 10;
|
||||||
|
|
||||||
/* Modal */
|
/* Modal */
|
||||||
--modal-width: 420px;
|
--modal-width: 440px;
|
||||||
--modal-bg: var(--color-bg);
|
--modal-bg: var(--color-bg);
|
||||||
--modal-overlay-bg: rgba(#F5F5F5, 0.75); // --color-canvas: #F5F5F5
|
--modal-overlay-bg: rgba(#F5F5F5, 0.75); // --color-canvas: #F5F5F5
|
||||||
--modal-border: 1px solid rgb(204, 204, 204);
|
--modal-border: 1px solid rgb(204, 204, 204);
|
||||||
|
|
Loading…
Add table
Reference in a new issue