From c7522dc0a59cc9331659aab0e503960851485dd0 Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Fri, 25 Aug 2017 23:21:26 -0400 Subject: [PATCH] better? merging is hard releasable? --- ui/js/actions/app.js | 4 + ui/js/actions/rewards.js | 14 +- ui/js/actions/user.js | 1 - ui/js/component/cardVerify/view.jsx | 2 +- ui/js/component/fileActions/view.jsx | 26 ++-- ui/js/component/inviteList/view.jsx | 13 +- ui/js/component/inviteNew/index.js | 18 ++- ui/js/component/inviteNew/view.jsx | 13 +- ui/js/component/inviteSummary/index.js | 14 -- ui/js/component/inviteSummary/view.jsx | 35 ----- ui/js/component/link/view.jsx | 8 +- ui/js/component/rewardLink/view.jsx | 2 +- ui/js/component/rewardSummary/view.jsx | 9 +- ui/js/component/rewardTile/view.jsx | 19 ++- ui/js/component/router/view.jsx | 2 +- .../component/transactionListRecent/view.jsx | 2 +- ui/js/component/userEmailNew/view.jsx | 10 ++ ui/js/component/userVerify/view.jsx | 146 ++++++++++++++---- ui/js/component/walletAddress/view.jsx | 2 +- ui/js/component/walletBalance/view.jsx | 14 +- ui/js/component/walletSend/view.jsx | 18 +-- ui/js/constants/modal_types.js | 1 + ui/js/modal/modalCreditIntro/view.jsx | 53 +++---- ui/js/modal/modalInsufficientCredits/index.js | 2 +- ui/js/modal/modalInsufficientCredits/view.jsx | 4 +- .../modalRewardApprovalRequired/index.js | 14 ++ .../modalRewardApprovalRequired/view.jsx | 33 ++++ ui/js/modal/modalRouter/index.js | 2 + ui/js/modal/modalRouter/view.jsx | 73 ++++++--- ui/js/page/auth/view.jsx | 66 ++++---- ui/js/page/help/index.js | 4 +- ui/js/page/help/view.jsx | 24 ++- ui/js/page/publish/index.js | 2 + ui/js/page/receiveCredits/view.jsx | 21 ++- ui/js/page/rewards/view.jsx | 22 ++- ui/js/page/sendCredits/view.jsx | 1 - ui/js/page/wallet/view.jsx | 10 +- ui/js/rewards.js | 11 ++ ui/js/selectors/app.js | 10 +- ui/js/selectors/rewards.js | 16 +- ui/js/selectors/search.js | 2 + ui/scss/_global.scss | 4 +- ui/scss/_gui.scss | 9 -- ui/scss/component/_button.scss | 2 +- ui/scss/component/_card.scss | 32 ++-- ui/scss/component/_table.scss | 5 + 46 files changed, 519 insertions(+), 276 deletions(-) delete mode 100644 ui/js/component/inviteSummary/index.js delete mode 100644 ui/js/component/inviteSummary/view.jsx create mode 100644 ui/js/modal/modalRewardApprovalRequired/index.js create mode 100644 ui/js/modal/modalRewardApprovalRequired/view.jsx diff --git a/ui/js/actions/app.js b/ui/js/actions/app.js index 34cceed37..ec2af78f0 100644 --- a/ui/js/actions/app.js +++ b/ui/js/actions/app.js @@ -26,6 +26,10 @@ const { lbrySettings: config } = require("../../../app/package.json"); export function doNavigate(path, params = {}, options = {}) { return function(dispatch, getState) { + if (!path) { + return; + } + let url = path; if (params) url = `${url}?${toQueryString(params)}`; diff --git a/ui/js/actions/rewards.js b/ui/js/actions/rewards.js index 227ab7a4a..b55d44c8d 100644 --- a/ui/js/actions/rewards.js +++ b/ui/js/actions/rewards.js @@ -3,6 +3,7 @@ import * as modals from "constants/modal_types"; import lbryio from "lbryio"; import rewards from "rewards"; import { selectUnclaimedRewardsByType } from "selectors/rewards"; +import { selectUserIsRewardApproved } from "selectors/user"; export function doRewardList() { return function(dispatch, getState) { @@ -31,14 +32,23 @@ export function doRewardList() { export function doClaimRewardType(rewardType) { return function(dispatch, getState) { - const rewardsByType = selectUnclaimedRewardsByType(getState()), - reward = rewardsByType[rewardType]; + const state = getState(), + rewardsByType = selectUnclaimedRewardsByType(state), + reward = rewardsByType[rewardType], + userIsRewardApproved = selectUserIsRewardApproved(state); if (reward.transaction_id) { //already claimed, do nothing return; } + if (!userIsRewardApproved) { + return dispatch({ + type: types.OPEN_MODAL, + data: { modal: modals.REWARD_APPROVAL_REQUIRED }, + }); + } + dispatch({ type: types.CLAIM_REWARD_STARTED, data: { reward }, diff --git a/ui/js/actions/user.js b/ui/js/actions/user.js index 2267621d1..360707a43 100644 --- a/ui/js/actions/user.js +++ b/ui/js/actions/user.js @@ -1,7 +1,6 @@ import * as types from "constants/action_types"; import * as modals from "constants/modal_types"; import lbryio from "lbryio"; -import { doOpenModal } from "actions/app"; import { doOpenModal, doShowSnackBar } from "actions/app"; import { doRewardList, doClaimRewardType } from "actions/rewards"; import { selectEmailToVerify, selectUser } from "selectors/user"; diff --git a/ui/js/component/cardVerify/view.jsx b/ui/js/component/cardVerify/view.jsx index 0432a69e1..4494cbf6c 100644 --- a/ui/js/component/cardVerify/view.jsx +++ b/ui/js/component/cardVerify/view.jsx @@ -165,7 +165,7 @@ class CardVerify extends React.Component { render() { return ( {content} {showMenu - ? - openInFolder(fileInfo)} - label={openInFolderMessage} - /> - openModal(modals.CONFIRM_FILE_REMOVE)} - label={__("Remove...")} - /> - + ?
+ + openInFolder(fileInfo)} + label={openInFolderMessage} + /> + openModal(modals.CONFIRM_FILE_REMOVE)} + label={__("Remove...")} + /> + +
: ""} {invitee.invite_reward_claimed ? - : } + : invitee.invite_accepted + ? + : + {__("unclaimable")} + } ); diff --git a/ui/js/component/inviteNew/index.js b/ui/js/component/inviteNew/index.js index b210aaf36..b31213b3f 100644 --- a/ui/js/component/inviteNew/index.js +++ b/ui/js/component/inviteNew/index.js @@ -6,13 +6,21 @@ import { selectUserInviteNewIsPending, selectUserInviteNewErrorMessage, } from "selectors/user"; +import rewards from "rewards"; +import { makeSelectRewardAmountByType } from "selectors/rewards"; + import { doUserInviteNew } from "actions/user"; -const select = state => ({ - errorMessage: selectUserInviteNewErrorMessage(state), - invitesRemaining: selectUserInvitesRemaining(state), - isPending: selectUserInviteNewIsPending(state), -}); +const select = state => { + const selectReward = makeSelectRewardAmountByType(); + + return { + errorMessage: selectUserInviteNewErrorMessage(state), + invitesRemaining: selectUserInvitesRemaining(state), + isPending: selectUserInviteNewIsPending(state), + rewardAmount: selectReward(state, { reward_type: rewards.TYPE_REFERRAL }), + }; +}; const perform = dispatch => ({ inviteNew: email => dispatch(doUserInviteNew(email)), diff --git a/ui/js/component/inviteNew/view.jsx b/ui/js/component/inviteNew/view.jsx index 6dc2d0f01..3f37e9c1b 100644 --- a/ui/js/component/inviteNew/view.jsx +++ b/ui/js/component/inviteNew/view.jsx @@ -1,5 +1,5 @@ import React from "react"; -import { BusyMessage } from "component/common"; +import { BusyMessage, CreditAmount } from "component/common"; import Link from "component/link"; import { FormRow } from "component/form.js"; @@ -62,15 +62,15 @@ class InviteNew extends React.PureComponent { inviteNew, inviteStatusIsPending, isPending, + rewardAmount, } = this.props; return (
+

- {__( - "Invite a Friend (or Enemy) (or Someone You Are Somewhat Ambivalent About)" - )} + {__("Invite a Friend")}

{/* @@ -81,6 +81,11 @@ class InviteNew extends React.PureComponent {

{__("You have no invites.")}

} */}
+

+ {__( + "Or an enemy. Or your cousin Jerry, who you're kind of unsure about." + )} +

({ - invitesRemaining: selectUserInvitesRemaining(state), - isPending: selectUserInviteNewIsPending(state), -}); - -export default connect(select)(InviteSummary); diff --git a/ui/js/component/inviteSummary/view.jsx b/ui/js/component/inviteSummary/view.jsx deleted file mode 100644 index 99ae46682..000000000 --- a/ui/js/component/inviteSummary/view.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import React from "react"; -import Link from "component/link"; -import { CreditAmount, BusyMessage } from "component/common"; - -const InviteSummary = props => { - const { isPending, invitesRemaining } = props; - - return ( -
-
-

{__("Invites")}

-
-
- {isPending && } - {!isPending && -

- {__n( - "You have %d invite remaining.", - "You have %d invites remaining.", - invitesRemaining - )} -

} -
-
- 0 ? "primary" : "text"} - navigate="/invite" - label={__("Go To Invites")} - /> -
-
- ); -}; - -export default InviteSummary; diff --git a/ui/js/component/link/view.jsx b/ui/js/component/link/view.jsx index 1980258af..6760c6cd3 100644 --- a/ui/js/component/link/view.jsx +++ b/ui/js/component/link/view.jsx @@ -22,11 +22,11 @@ const Link = props => { (button ? " button-block button-" + button + " button-set-item" : "") + (disabled ? " disabled" : ""); - const onClick = props.onClick - ? props.onClick - : () => { + const onClick = !props.onClick && navigate + ? () => { doNavigate(navigate); - }; + } + : props.onClick; let content; if (children) { diff --git a/ui/js/component/rewardLink/view.jsx b/ui/js/component/rewardLink/view.jsx index 4f019fcf2..9eeee17e2 100644 --- a/ui/js/component/rewardLink/view.jsx +++ b/ui/js/component/rewardLink/view.jsx @@ -16,7 +16,7 @@ const RewardLink = props => { return (
{ unclaimed rewards.

}
-
- 0 ? "primary" : "text"} - navigate="/rewards" - label={__("Go To Rewards")} - /> +
+ +
); diff --git a/ui/js/component/rewardTile/view.jsx b/ui/js/component/rewardTile/view.jsx index 4545d0d46..027fc484f 100644 --- a/ui/js/component/rewardTile/view.jsx +++ b/ui/js/component/rewardTile/view.jsx @@ -1,6 +1,8 @@ import React from "react"; import { CreditAmount, Icon } from "component/common"; import RewardLink from "component/rewardLink"; +import Link from "component/link"; +import rewards from "rewards"; const RewardTile = props => { const { reward } = props; @@ -14,12 +16,19 @@ const RewardTile = props => {

{reward.reward_title}

-
- {claimed - ? {__("Reward claimed.")} - : } -
{reward.reward_description}
+
+ {reward.reward_type == rewards.TYPE_REFERRAL && + } + {reward.reward_type !== rewards.TYPE_REFERRAL && + (claimed + ? {__("Reward claimed.")} + : )} +
); diff --git a/ui/js/component/router/view.jsx b/ui/js/component/router/view.jsx index 7023344e4..db114b861 100644 --- a/ui/js/component/router/view.jsx +++ b/ui/js/component/router/view.jsx @@ -30,7 +30,6 @@ const Router = props => { const { currentPage, params } = props; return route(currentPage, { - address: , auth: , backup: , channel: , @@ -42,6 +41,7 @@ const Router = props => { invite: , publish: , published: , + receive: , report: , rewards: , search: , diff --git a/ui/js/component/transactionListRecent/view.jsx b/ui/js/component/transactionListRecent/view.jsx index 8b8010770..82c09995d 100644 --- a/ui/js/component/transactionListRecent/view.jsx +++ b/ui/js/component/transactionListRecent/view.jsx @@ -26,7 +26,7 @@ class TransactionListRecent extends React.PureComponent { />} {hasTransactions && -
+
+

+ {__( + "This process is required to prevent abuse of the rewards program." + )} +

+

+ {__( + "We will also contact you about updates and new content, but you can unsubscribe at any time." + )} +

-

- {__( - "To ensure you are a real person, we require a valid credit or debit card." - ) + - " " + - __("There is no charge at all, now or in the future.") + - " "} - -

- {errorMessage &&

{errorMessage}

} -

- -

-

- {__( - "You can continue without this step, but you will not be eligible to earn rewards." - )} -

- navigate("/discover")} - button="alt" - label={__("Skip Rewards")} - /> +
+
+

{__("Final Human Proof")}

+
+
+

+ Finally, please complete one and only one of the + options below. +

+
+
+
+
+

{__("1) Proof via Credit")}

+
+
+

+ {__( + "If you have a valid credit or debit card, you can instantly prove your humanity." + ) + + " " + + __( + "There is no charge at all for this, now or in the future." + ) + + " "} + +

+ {errorMessage && +

{errorMessage}

} +

+ +

+
+
+
+
+

{__("2) Proof via YouTube")}

+
+
+

+ {__( + "If you have a YouTube account with published videos that you want to make available on LBRY, syncing your account will grant instant authorization." + )} +

+
+
+ +
+
+
+ This will not automatically refresh after approval. Once you have + synced your account, just navigate away or click + {" "} . +
+
+
+
+
+

{__("3) Proof via Chat")}

+
+
+

+ {__( + "A moderator capable of approving you is typically available in the #verification channel of our chat room." + )} +

+

+ {__( + "This process will likely involve providing proof of a stable and established online identity of some kind." + )} +

+
+
+ +
+
+
+
+
{__("Or, Skip It Entirely")}
+
+
+ +

+ {__( + "You can continue without this step, but you will not be eligible to earn rewards." + )} +

+ +
+
+ navigate("/discover")} + button="alt" + label={__("Skip Rewards")} + /> +
+
); } diff --git a/ui/js/component/walletAddress/view.jsx b/ui/js/component/walletAddress/view.jsx index 8a9fb3ab6..7b9d78f14 100644 --- a/ui/js/component/walletAddress/view.jsx +++ b/ui/js/component/walletAddress/view.jsx @@ -18,7 +18,7 @@ class WalletAddress extends React.PureComponent {

{__( - 'Other LBRY users may send credits to you by entering this address on the "Send" page.' + "Use this address to receive credits send by another user (or yourself)." )}

diff --git a/ui/js/component/walletBalance/view.jsx b/ui/js/component/walletBalance/view.jsx index 217cd59d9..5e0eca86f 100644 --- a/ui/js/component/walletBalance/view.jsx +++ b/ui/js/component/walletBalance/view.jsx @@ -21,13 +21,19 @@ const WalletBalance = props => { {(balance || balance === 0) && }
-
- - +
+ +
diff --git a/ui/js/component/walletSend/view.jsx b/ui/js/component/walletSend/view.jsx index 444acca4a..680106584 100644 --- a/ui/js/component/walletSend/view.jsx +++ b/ui/js/component/walletSend/view.jsx @@ -42,15 +42,15 @@ const WalletSend = props => { onChange={setAddress} value={address} /> -
-
- 0.0) || !address} - /> - +
+ 0.0) || !address} + /> + +
{modal == "insufficientBalance" && diff --git a/ui/js/constants/modal_types.js b/ui/js/constants/modal_types.js index d6686f15f..c9d319290 100644 --- a/ui/js/constants/modal_types.js +++ b/ui/js/constants/modal_types.js @@ -7,4 +7,5 @@ export const UPGRADE = "upgrade"; export const WELCOME = "welcome"; export const FIRST_REWARD = "first_reward"; export const AUTHENTICATION_FAILURE = "auth_failure"; +export const REWARD_APPROVAL_REQUIRED = "REWARD_APPROVAL_REQUIRED"; export const CREDIT_INTRO = "credit_intro"; diff --git a/ui/js/modal/modalCreditIntro/view.jsx b/ui/js/modal/modalCreditIntro/view.jsx index cdf4253dd..5f56c11b4 100644 --- a/ui/js/modal/modalCreditIntro/view.jsx +++ b/ui/js/modal/modalCreditIntro/view.jsx @@ -2,7 +2,7 @@ import React from "react"; import { Modal } from "modal/modal"; import { CreditAmount, CurrencySymbol } from "component/common"; import Link from "component/link/index"; -import { formatCredits } from "utils"; +import { formatCredits } from "util/formatCredits"; const ModalCreditIntro = props => { const { closeModal, currentBalance, totalRewardValue, verifyAccount } = props; @@ -12,50 +12,51 @@ const ModalCreditIntro = props => { return (
-

{__("Quick Credit Intro")}

+

{__("Blockchain 101")}

- The LBRY network is controlled and powered by credits called{" "} - , a blockchain asset. {" "} + LBRY is controlled and powered by a blockchain asset called {" "} + .{" "} {" "} {__( "is used to publish content, to have a say in the network rules, and to access paid content." )}

-

- {__("New verified users can receive more than ")} {" "} - {totalRewardValue - ? - : {__("credits")}} - {" "} {__(" in rewards for usage and influence of the network.")} -

{currentBalance <= 0 - ?

- + ?

+

+ You currently have , so + the actions you can take are limited. +

+

+ However, there are a variety of ways to get credits, including + more than {" "} + {totalRewardValue + ? + : {__("?? credits")}} + {" "}{" "} {__( - "Without any credits, you will not be able to take this action." + " in rewards available for being a proven human during the LBRY beta." )} - -

- :

- {__( - "But you probably knew all this, since you've already got %s of them!", - formatCredits(currentBalance, 2) - )} -

} +

+
+ :
+

+ But you probably knew this, since you've already got{" "} + . +

+
}
diff --git a/ui/js/modal/modalInsufficientCredits/index.js b/ui/js/modal/modalInsufficientCredits/index.js index 0ece4f1fe..eefaa7c68 100644 --- a/ui/js/modal/modalInsufficientCredits/index.js +++ b/ui/js/modal/modalInsufficientCredits/index.js @@ -7,7 +7,7 @@ const select = state => ({}); const perform = dispatch => ({ addFunds: () => { - dispatch(doNavigate("/rewards")); + dispatch(doNavigate("/wallet")); dispatch(doCloseModal()); }, closeModal: () => dispatch(doCloseModal()), diff --git a/ui/js/modal/modalInsufficientCredits/view.jsx b/ui/js/modal/modalInsufficientCredits/view.jsx index 2e4bd089f..397fc0301 100644 --- a/ui/js/modal/modalInsufficientCredits/view.jsx +++ b/ui/js/modal/modalInsufficientCredits/view.jsx @@ -1,5 +1,6 @@ import React from "react"; import { Modal } from "modal/modal"; +import { CurrencySymbol } from "component/common"; class ModalInsufficientCredits extends React.PureComponent { render() { @@ -15,7 +16,8 @@ class ModalInsufficientCredits extends React.PureComponent { onAborted={closeModal} onConfirmed={addFunds} > -

{__("More LBRY credits are required to take this action.")}

+

{__("More Credits Required")}

+

You'll need more to do this.

); } diff --git a/ui/js/modal/modalRewardApprovalRequired/index.js b/ui/js/modal/modalRewardApprovalRequired/index.js new file mode 100644 index 000000000..c42c54a83 --- /dev/null +++ b/ui/js/modal/modalRewardApprovalRequired/index.js @@ -0,0 +1,14 @@ +import React from "react"; +import { connect } from "react-redux"; +import { doCloseModal, doAuthNavigate } from "actions/app"; +import ModalRewardApprovalRequired from "./view"; + +const perform = dispatch => ({ + doAuth: () => { + dispatch(doCloseModal()); + dispatch(doAuthNavigate()); + }, + closeModal: () => dispatch(doCloseModal()), +}); + +export default connect(null, perform)(ModalRewardApprovalRequired); diff --git a/ui/js/modal/modalRewardApprovalRequired/view.jsx b/ui/js/modal/modalRewardApprovalRequired/view.jsx new file mode 100644 index 000000000..bb98d2bf7 --- /dev/null +++ b/ui/js/modal/modalRewardApprovalRequired/view.jsx @@ -0,0 +1,33 @@ +import React from "react"; +import { Modal } from "modal/modal"; + +class ModalRewardApprovalRequired extends React.PureComponent { + render() { + const { closeModal, doAuth } = this.props; + + return ( + +
+

+ {__("This is awkward. Are you real?")} +

+

+ {__( + "Before we can give you any credits, we need to perform a brief check to make sure you're a new and unique person." + )} +

+
+
+ ); + } +} + +export default ModalRewardApprovalRequired; diff --git a/ui/js/modal/modalRouter/index.js b/ui/js/modal/modalRouter/index.js index 1c3a0d573..9bf9601c5 100644 --- a/ui/js/modal/modalRouter/index.js +++ b/ui/js/modal/modalRouter/index.js @@ -6,9 +6,11 @@ import { makeSelectClientSetting } from "selectors/settings"; import { selectUser } from "selectors/user"; import { selectCostForCurrentPageUri } from "selectors/cost_info"; import * as settings from "constants/settings"; +import { selectBalance } from "selectors/wallet"; import ModalRouter from "./view"; const select = (state, props) => ({ + balance: selectBalance(state), showPageCost: selectCostForCurrentPageUri(state), modal: selectCurrentModal(state), page: selectCurrentPage(state), diff --git a/ui/js/modal/modalRouter/view.jsx b/ui/js/modal/modalRouter/view.jsx index 2af2a21ed..a21851c3b 100644 --- a/ui/js/modal/modalRouter/view.jsx +++ b/ui/js/modal/modalRouter/view.jsx @@ -6,10 +6,20 @@ import ModalInsufficientCredits from "modal/modalInsufficientCredits"; import ModalUpgrade from "modal/modalUpgrade"; import ModalWelcome from "modal/modalWelcome"; import ModalFirstReward from "modal/modalFirstReward"; +import ModalRewardApprovalRequired from "modal/modalRewardApprovalRequired"; import * as modals from "constants/modal_types"; import ModalCreditIntro from "modal/modalCreditIntro"; class ModalRouter extends React.PureComponent { + constructor(props) { + super(props); + + this.state = { + lastTransitionModal: null, + lastTransitionPage: null, + }; + } + componentWillMount() { this.showTransitionModals(this.props); } @@ -19,55 +29,72 @@ class ModalRouter extends React.PureComponent { } showTransitionModals(props) { - const { modal } = props; + const { modal, openModal, page } = props; if (modal) { return; } - [ - this.checkShowWelcome.bind(this), - this.checkShowCreditIntro.bind(this), - ].find(func => func(props)); + const transitionModal = [ + this.checkShowWelcome, + this.checkShowCreditIntro, + this.checkShowInsufficientCredits, + ].reduce((acc, func) => { + return !acc ? func.bind(this)(props) : acc; + }, false); + + if ( + transitionModal && + (transitionModal != this.state.lastTransitionModal || + page != this.state.lastTransitionPage) + ) { + openModal(transitionModal); + this.setState({ + lastTransitionModal: transitionModal, + lastTransitionPage: page, + }); + } } checkShowWelcome(props) { - const { isWelcomeAcknowledged, openModal, user } = props; + const { isWelcomeAcknowledged, user } = props; if ( !isWelcomeAcknowledged && user && !user.is_reward_approved && !user.is_identity_verified ) { - openModal(modals.WELCOME); - return true; + return modals.WELCOME; } } checkShowCreditIntro(props) { - const { - page, - isCreditIntroAcknowledged, - openModal, - user, - showPageCost, - } = props; + const { page, isCreditIntroAcknowledged, user } = props; if ( !isCreditIntroAcknowledged && user && !user.is_reward_approved && - !user.is_identity_verified && - ["rewards", "send", "address", "show", "publish", "wallet"].includes( - page - ) && - (page != "show" || showPageCost > 0) + (["rewards", "send", "receive", "publish", "wallet"].includes(page) || + this.isPaidShowPage(props)) ) { - openModal(modals.CREDIT_INTRO); - return true; + return modals.CREDIT_INTRO; } } + checkShowInsufficientCredits(props) { + const { balance, page } = props; + + if (balance <= 0 && ["send", "publish"].includes(page)) { + return modals.INSUFFICIENT_CREDITS; + } + } + + isPaidShowPage(props) { + const { page, showPageCost } = props; + return page === "show" && showPageCost > 0; + } + render() { const { modal } = this.props; @@ -88,6 +115,8 @@ class ModalRouter extends React.PureComponent { return ; case modals.CREDIT_INTRO: return ; + case modals.REWARD_APPROVAL_REQUIRED: + return ; default: return null; } diff --git a/ui/js/page/auth/view.jsx b/ui/js/page/auth/view.jsx index 55bef96a8..b9ac51bbd 100644 --- a/ui/js/page/auth/view.jsx +++ b/ui/js/page/auth/view.jsx @@ -30,11 +30,11 @@ export class AuthPage extends React.PureComponent { const { email, isPending, isVerificationCandidate, user } = this.props; if (isPending || (user && !user.has_verified_email && !email)) { - return __("Welcome to LBRY"); + return __("Human Proofing"); } else if (user && !user.has_verified_email) { return __("Confirm Email"); } else if (user && !user.is_identity_verified && !user.is_reward_approved) { - return __("Confirm Identity"); + return __("Final Verification"); } else { return __("Welcome to LBRY"); } @@ -44,51 +44,45 @@ export class AuthPage extends React.PureComponent { const { email, isPending, isVerificationCandidate, user } = this.props; if (isPending) { - return ; + return [, true]; } else if (user && !user.has_verified_email && !email) { - return ; + return [, true]; } else if (user && !user.has_verified_email) { - return ; + return [, true]; } else if (user && !user.is_identity_verified) { - return ; + return [, false]; } else { - return {__("No further steps.")}; + return [{__("No further steps.")}, true]; } } render() { const { email, user, isPending, navigate } = this.props; + const [innerContent, useTemplate] = this.renderMain(); - return ( -
-
-
-

{this.getTitle()}

-
-
- {!isPending && - !email && - user && - !user.has_verified_email && -

- {__("Create a verified identity and receive LBC rewards.")} -

} - {this.renderMain()} -
-
-
- {__( - "This information is disclosed only to LBRY, Inc. and not to the LBRY network. It is only required to earn LBRY rewards." - ) + " "} - navigate("/discover")} - label={__("Return home")} - />. + return useTemplate + ?
+
+
+

{this.getTitle()}

-
-
-
- ); +
+ {innerContent} +
+
+
+ {__( + "This information is disclosed only to LBRY, Inc. and not to the LBRY network. It is only required to earn LBRY rewards." + ) + " "} + navigate("/discover")} + label={__("Return home")} + />. +
+
+
+ + : innerContent; } } diff --git a/ui/js/page/help/index.js b/ui/js/page/help/index.js index c4ea548b2..93492d915 100644 --- a/ui/js/page/help/index.js +++ b/ui/js/page/help/index.js @@ -1,5 +1,5 @@ import React from "react"; -import { doNavigate } from "actions/app"; +import { doAuthNavigate } from "actions/app"; import { connect } from "react-redux"; import { doFetchAccessToken } from "actions/user"; import { selectAccessToken, selectUser } from "selectors/user"; @@ -11,7 +11,7 @@ const select = state => ({ }); const perform = dispatch => ({ - navigate: (path, params) => dispatch(doNavigate(path, params)), + doAuth: () => dispatch(doAuthNavigate("/help")), fetchAccessToken: () => dispatch(doFetchAccessToken()), }); diff --git a/ui/js/page/help/view.jsx b/ui/js/page/help/view.jsx index f56d058e8..cb1627635 100644 --- a/ui/js/page/help/view.jsx +++ b/ui/js/page/help/view.jsx @@ -3,7 +3,7 @@ import React from "react"; import lbry from "lbry.js"; import Link from "component/link"; import SubHeader from "component/subHeader"; -import { BusyMessage } from "component/common"; +import { BusyMessage, Icon } from "component/common"; class HelpPage extends React.PureComponent { constructor(props) { @@ -50,7 +50,7 @@ class HelpPage extends React.PureComponent { render() { let ver, osName, platform, newVerLink; - const { navigate, user } = this.props; + const { doAuth, user } = this.props; if (this.state.versionInfo) { ver = this.state.versionInfo; @@ -119,7 +119,7 @@ class HelpPage extends React.PureComponent {

{__("Did you find something wrong?")}

navigate("report")} + navigate="/report" label={__("Submit a Bug Report")} icon="icon-bug" button="alt" @@ -143,7 +143,7 @@ class HelpPage extends React.PureComponent {

:

{__("Your copy of LBRY is up to date.")}

} {this.state.uiVersion && ver - ? + ?
@@ -162,7 +162,21 @@ class HelpPage extends React.PureComponent { + + + + diff --git a/ui/js/page/publish/index.js b/ui/js/page/publish/index.js index f296f1687..1816bf2d5 100644 --- a/ui/js/page/publish/index.js +++ b/ui/js/page/publish/index.js @@ -16,10 +16,12 @@ import { doCreateChannel, doPublish, } from "actions/content"; +import { selectBalance } from "selectors/wallet"; import rewards from "rewards"; import PublishPage from "./view"; const select = state => ({ + balance: selectBalance(state), myClaims: selectMyClaims(state), fetchingChannels: selectFetchingMyChannels(state), channels: selectMyChannelClaims(state), diff --git a/ui/js/page/receiveCredits/view.jsx b/ui/js/page/receiveCredits/view.jsx index b00f8dc34..120071748 100644 --- a/ui/js/page/receiveCredits/view.jsx +++ b/ui/js/page/receiveCredits/view.jsx @@ -1,6 +1,6 @@ import React from "react"; import SubHeader from "component/subHeader"; -import WalletBalance from "component/walletBalance"; +import Link from "component/link"; import WalletAddress from "component/walletAddress"; const ReceiveCreditsPage = props => { @@ -8,6 +8,25 @@ const ReceiveCreditsPage = props => {
+
+
+

{__("Where To Find Credits")}

+
+
+

+ { + "LBRY credits can be purchased on exchanges, earned for contributions, for mining, and more." + } +

+
+
+ +
+
); }; diff --git a/ui/js/page/rewards/view.jsx b/ui/js/page/rewards/view.jsx index e579a63c7..51d75e406 100644 --- a/ui/js/page/rewards/view.jsx +++ b/ui/js/page/rewards/view.jsx @@ -33,13 +33,20 @@ class RewardsPage extends React.PureComponent { ) { return (
+
+

{__("Humans Only")}

+

- {__("Only verified accounts are eligible to earn rewards.")} + {__("Rewards are for human beings only.")} + {" "} + {__( + "You'll have to prove you're one of us before you can claim any rewards." + )}

- +
); @@ -89,12 +96,11 @@ class RewardsPage extends React.PureComponent { ); } else if (user === null) { - return (

{__( - "This application is unable to earn rewards due to an authentication failure." + "This application is unable to earn rewards due to an authentication failure." )}

@@ -106,8 +112,12 @@ class RewardsPage extends React.PureComponent { ); } else { - return rewards.map(reward => - + return ( +
+ {rewards.map(reward => + + )} +
); } } diff --git a/ui/js/page/sendCredits/view.jsx b/ui/js/page/sendCredits/view.jsx index b0603b9c7..96937bcc6 100644 --- a/ui/js/page/sendCredits/view.jsx +++ b/ui/js/page/sendCredits/view.jsx @@ -1,6 +1,5 @@ import React from "react"; import SubHeader from "component/subHeader"; -import WalletBalance from "component/walletBalance"; import WalletSend from "component/walletSend"; const SendCreditsPage = props => { diff --git a/ui/js/page/wallet/view.jsx b/ui/js/page/wallet/view.jsx index 302a2271e..b8bee1c94 100644 --- a/ui/js/page/wallet/view.jsx +++ b/ui/js/page/wallet/view.jsx @@ -2,16 +2,16 @@ import React from "react"; import SubHeader from "component/subHeader"; import WalletBalance from "component/walletBalance"; import RewardSummary from "component/rewardSummary"; -import InviteSummary from "component/inviteSummary"; import TransactionListRecent from "component/transactionListRecent"; const WalletPage = props => { return ( -
+
- - - +
+ + +
); diff --git a/ui/js/rewards.js b/ui/js/rewards.js index 8430c7f31..0a3475246 100644 --- a/ui/js/rewards.js +++ b/ui/js/rewards.js @@ -96,6 +96,17 @@ rewards.TYPE_MANY_DOWNLOADS = "many_downloads"; rewards.TYPE_FIRST_PUBLISH = "first_publish"; rewards.TYPE_FEATURED_DOWNLOAD = "featured_download"; rewards.TYPE_REFERRAL = "referral"; +rewards.SORT_ORDER = [ + rewards.TYPE_NEW_USER, + rewards.TYPE_CONFIRM_EMAIL, + rewards.TYPE_FIRST_STREAM, + rewards.TYPE_FIRST_CHANNEL, + rewards.TYPE_FIRST_PUBLISH, + rewards.TYPE_FEATURED_DOWNLOAD, + rewards.TYPE_MANY_DOWNLOADS, + rewards.TYPE_REFERRAL, + rewards.TYPE_NEW_DEVELOPER, +]; rewards.claimReward = function(type) { function requestReward(resolve, reject, params) { diff --git a/ui/js/selectors/app.js b/ui/js/selectors/app.js index b902b629f..eb950f3b1 100644 --- a/ui/js/selectors/app.js +++ b/ui/js/selectors/app.js @@ -39,7 +39,7 @@ export const selectPageTitle = createSelector( return __("Wallet"); case "send": return __("Send Credits"); - case "address": + case "receive": return __("Wallet Address"); case "backup": return __("Backup Your Wallet"); @@ -143,17 +143,17 @@ export const selectHeaderLinks = createSelector(selectCurrentPage, page => { case "wallet": case "history": case "send": - case "address": + case "receive": case "invite": case "rewards": case "backup": return { wallet: __("Overview"), - rewards: __("Rewards"), - invite: __("Invites"), history: __("History"), send: __("Send"), - address: __("Address"), + receive: __("Receive"), + rewards: __("Rewards"), + invite: __("Invites"), }; case "downloaded": case "published": diff --git a/ui/js/selectors/rewards.js b/ui/js/selectors/rewards.js index 88d4de730..c2a646563 100644 --- a/ui/js/selectors/rewards.js +++ b/ui/js/selectors/rewards.js @@ -1,5 +1,6 @@ import { createSelector } from "reselect"; import { selectUser } from "selectors/user"; +import rewards from "rewards"; const _selectState = state => state.rewards || {}; @@ -20,7 +21,13 @@ export const selectClaimedRewards = createSelector( export const selectUnclaimedRewards = createSelector( selectUnclaimedRewardsByType, - byType => Object.values(byType) || [] + byType => + Object.values(byType).sort(function(a, b) { + return rewards.SORT_ORDER.indexOf(a.reward_type) < + rewards.SORT_ORDER.indexOf(b.reward_type) + ? -1 + : 1; + }) || [] ); export const selectIsRewardEligible = createSelector( @@ -83,3 +90,10 @@ const selectRewardByType = (state, props) => { export const makeSelectRewardByType = () => { return createSelector(selectRewardByType, reward => reward); }; + +export const makeSelectRewardAmountByType = () => { + return createSelector( + selectRewardByType, + reward => (reward ? reward.reward_amount : 0) + ); +}; diff --git a/ui/js/selectors/search.js b/ui/js/selectors/search.js index 2a77ebe9a..2ef8a1410 100644 --- a/ui/js/selectors/search.js +++ b/ui/js/selectors/search.js @@ -38,6 +38,8 @@ export const selectWunderBarAddress = createSelector( export const selectWunderBarIcon = createSelector(selectCurrentPage, page => { switch (page) { + case "auth": + return "icon-user"; case "search": return "icon-search"; case "settings": diff --git a/ui/scss/_global.scss b/ui/scss/_global.scss index b554b77a1..9a838b2d7 100644 --- a/ui/scss/_global.scss +++ b/ui/scss/_global.scss @@ -2,8 +2,8 @@ $spacing-vertical: 24px; -$padding-button: 12px; -$padding-text-link: 4px; +$padding-button: $spacing-vertical * 2/3; +$padding-text-link: 0px; $color-primary: #155B4A; $color-primary-light: saturate(lighten($color-primary, 50%), 20%); diff --git a/ui/scss/_gui.scss b/ui/scss/_gui.scss index b8d9ec040..338ccac3c 100644 --- a/ui/scss/_gui.scss +++ b/ui/scss/_gui.scss @@ -134,15 +134,6 @@ p } } -/*should this be here or work this way? had to hack additional rule below*/ -.icon:only-child { - position: relative; - top: 0.16em; -} -.icon-featured > .icon { - top: 0; -} - .help { font-size: .85em; color: $color-help; diff --git a/ui/scss/component/_button.scss b/ui/scss/component/_button.scss index 5c6fed22f..cd00b8fe4 100644 --- a/ui/scss/component/_button.scss +++ b/ui/scss/component/_button.scss @@ -8,7 +8,7 @@ $button-focus-shift: 12%; + .button-set-item { - margin-left: $padding-button; + margin-left: $spacing-vertical; } } diff --git a/ui/scss/component/_card.scss b/ui/scss/component/_card.scss index 712eb9ea7..c5e17b66b 100644 --- a/ui/scss/component/_card.scss +++ b/ui/scss/component/_card.scss @@ -23,10 +23,11 @@ $width-card-small: $spacing-vertical * 10; } .card__title-primary, .card__title-identity, -.card__actions, .card__content, -.card__subtext { - padding: 0 $padding-card-horizontal; +.card__subtext, +.card__actions { + padding-left: $padding-card-horizontal; + padding-right: $padding-card-horizontal; } .card--small { .card__title-primary, @@ -39,6 +40,7 @@ $width-card-small: $spacing-vertical * 10; } .card__title-primary { margin-top: $spacing-vertical * 2/3; + margin-bottom: $spacing-vertical * 2/3; } .card__title-identity { margin-top: $spacing-vertical * 1/3; @@ -46,13 +48,6 @@ $width-card-small: $spacing-vertical * 10; } .card__actions { margin-top: $spacing-vertical * 2/3; -} -.card__actions--bottom { - margin-top: $spacing-vertical * 1/3; - margin-bottom: $spacing-vertical * 1/3; -} -.card__actions--form-submit { - margin-top: $spacing-vertical; margin-bottom: $spacing-vertical * 2/3; } .card__content { @@ -259,4 +254,21 @@ $padding-right-card-hover-hack: 30px; .card__icon-featured-content { color: orangered; +} + + +/* +if we keep doing things like this, we should add a real grid system, but I'm going to be a selective dick about it - Jeremy + */ +.card-grid { + $margin-card-grid: $spacing-vertical * 2/3; + display:flex; + flex-wrap: wrap; + > .card { + width: $width-page-constrained / 2 - $margin-card-grid / 2; + flex-grow:1; + } + > .card:nth-of-type(2n - 1) { + margin-right: $margin-card-grid; + } } \ No newline at end of file diff --git a/ui/scss/component/_table.scss b/ui/scss/component/_table.scss index 7f5600aa1..38893eae5 100644 --- a/ui/scss/component/_table.scss +++ b/ui/scss/component/_table.scss @@ -52,6 +52,11 @@ table.table-standard { } } } +.table-standard--definition-list { + th { + text-align: right; + } +} table.table-stretch { width: 100%;
{__("App")} {user && user.primary_email ? user.primary_email - : {__("none")}} + : + {__("none")} + ( doAuth()} + label={__("set email")} + />) + } +
{__("Reward Eligible")} + {user && user.is_reward_approved + ? + : }