diff --git a/CHANGELOG.md b/CHANGELOG.md index ff500fb76..f2e2737bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). * Add flair to snackbar ([#1313](https://github.com/lbryio/lbry-app/pull/1313)) * Made font in price badge larger ([#1420](https://github.com/lbryio/lbry-app/pull/1420)) * Store subscriptions in internal database ([#1424](https://github.com/lbryio/lbry-app/pull/1424)) + * Move rewards logic to interal api ([#1509](https://github.com/lbryio/lbry-app/pull/1509)) ### Fixed * Fix content-type not shown correctly in file description ([#863](https://github.com/lbryio/lbry-app/pull/863)) diff --git a/src/renderer/component/inviteNew/index.js b/src/renderer/component/inviteNew/index.js index b0e00c8db..bfb65ab39 100644 --- a/src/renderer/component/inviteNew/index.js +++ b/src/renderer/component/inviteNew/index.js @@ -1,26 +1,17 @@ -import React from 'react'; import { connect } from 'react-redux'; -import InviteNew from './view'; import { selectUserInvitesRemaining, selectUserInviteNewIsPending, selectUserInviteNewErrorMessage, } from 'redux/selectors/user'; -import rewards from 'rewards'; -import { makeSelectRewardAmountByType } from 'redux/selectors/rewards'; - import { doUserInviteNew } from 'redux/actions/user'; +import InviteNew from './view'; -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 select = state => ({ + errorMessage: selectUserInviteNewErrorMessage(state), + invitesRemaining: selectUserInvitesRemaining(state), + isPending: selectUserInviteNewIsPending(state), +}); const perform = dispatch => ({ inviteNew: email => dispatch(doUserInviteNew(email)), diff --git a/src/renderer/component/inviteNew/view.jsx b/src/renderer/component/inviteNew/view.jsx index e3cafa568..8b9a54b6b 100644 --- a/src/renderer/component/inviteNew/view.jsx +++ b/src/renderer/component/inviteNew/view.jsx @@ -29,8 +29,7 @@ class FormInviteNew extends React.PureComponent { } render() { - const { errorMessage, isPending, rewardAmount } = this.props; - const label = `${__('Get')} ${rewardAmount} LBC`; + const { errorMessage, isPending } = this.props; return (
); diff --git a/src/renderer/component/rewardLink/index.js b/src/renderer/component/rewardLink/index.js index 9ecfe0dba..f7e3561ef 100644 --- a/src/renderer/component/rewardLink/index.js +++ b/src/renderer/component/rewardLink/index.js @@ -16,7 +16,7 @@ const makeSelect = () => { const select = (state, props) => ({ errorMessage: selectError(state, props), isPending: selectIsPending(state, props), - reward: selectReward(state, props), + reward: selectReward(state, props.reward_type), }); return select; diff --git a/src/renderer/component/userVerify/index.js b/src/renderer/component/userVerify/index.js index a6ca5a554..b139c96c1 100644 --- a/src/renderer/component/userVerify/index.js +++ b/src/renderer/component/userVerify/index.js @@ -1,4 +1,5 @@ import { connect } from 'react-redux'; +import { doNotify, MODALS } from 'lbry-redux'; import { doNavigate } from 'redux/actions/navigation'; import { doUserIdentityVerify } from 'redux/actions/user'; import rewards from 'rewards'; @@ -8,15 +9,14 @@ import { selectIdentityVerifyErrorMessage, } from 'redux/selectors/user'; import UserVerify from './view'; -import { doNotify, MODALS } from 'lbry-redux'; -const select = (state, props) => { +const select = state => { const selectReward = makeSelectRewardByType(); return { isPending: selectIdentityVerifyIsPending(state), errorMessage: selectIdentityVerifyErrorMessage(state), - reward: selectReward(state, { reward_type: rewards.TYPE_NEW_USER }), + reward: selectReward(state, rewards.TYPE_NEW_USER), }; }; diff --git a/src/renderer/modal/modalFirstReward/index.js b/src/renderer/modal/modalFirstReward/index.js index f3f2576e9..c38b9d7e0 100644 --- a/src/renderer/modal/modalFirstReward/index.js +++ b/src/renderer/modal/modalFirstReward/index.js @@ -8,7 +8,7 @@ const select = state => { const selectReward = makeSelectRewardByType(); return { - reward: selectReward(state, { reward_type: rewards.TYPE_NEW_USER }), + reward: selectReward(state, rewards.TYPE_NEW_USER), }; }; diff --git a/src/renderer/modal/modalFirstReward/view.jsx b/src/renderer/modal/modalFirstReward/view.jsx index 5d86e3636..510716386 100644 --- a/src/renderer/modal/modalFirstReward/view.jsx +++ b/src/renderer/modal/modalFirstReward/view.jsx @@ -6,7 +6,7 @@ import CreditAmount from 'component/common/credit-amount'; class ModalFirstReward extends React.PureComponent { render() { - const { closeModal, reward } = this.props; + const { closeModal } = this.props; return (
- {__('You just earned your first reward of')}{' '}
-
{__('You just earned your first reward!')}
{__( "This reward will show in your Wallet in the top right momentarily (if it hasn't already)." diff --git a/src/renderer/redux/actions/rewards.js b/src/renderer/redux/actions/rewards.js index dd4446f3f..581772a3d 100644 --- a/src/renderer/redux/actions/rewards.js +++ b/src/renderer/redux/actions/rewards.js @@ -1,7 +1,7 @@ import * as ACTIONS from 'constants/action_types'; import Lbryio from 'lbryio'; import { doNotify, MODALS } from 'lbry-redux'; -import { selectUnclaimedRewardsByType } from 'redux/selectors/rewards'; +import { selectUnclaimedRewards } from 'redux/selectors/rewards'; import { selectUserIsRewardApproved } from 'redux/selectors/user'; import rewards from 'rewards'; @@ -30,8 +30,8 @@ export function doRewardList() { export function doClaimRewardType(rewardType) { return (dispatch, getState) => { const state = getState(); - const rewardsByType = selectUnclaimedRewardsByType(state); - const reward = rewardsByType[rewardType]; + const unclaimedRewards = selectUnclaimedRewards(state); + const reward = unclaimedRewards.find(ur => ur.reward_type === rewardType); const userIsRewardApproved = selectUserIsRewardApproved(state); if (!reward || reward.transaction_id) { @@ -84,14 +84,14 @@ export function doClaimRewardType(rewardType) { export function doClaimEligiblePurchaseRewards() { return (dispatch, getState) => { const state = getState(); - const rewardsByType = selectUnclaimedRewardsByType(state); + const unclaimedRewards = selectUnclaimedRewards(state); const userIsRewardApproved = selectUserIsRewardApproved(state); if (!userIsRewardApproved || !Lbryio.enabled) { return; } - if (rewardsByType[rewards.TYPE_FIRST_STREAM]) { + 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 => { diff --git a/src/renderer/redux/reducers/rewards.js b/src/renderer/redux/reducers/rewards.js index f2f42c004..67f861e6c 100644 --- a/src/renderer/redux/reducers/rewards.js +++ b/src/renderer/redux/reducers/rewards.js @@ -4,7 +4,7 @@ const reducers = {}; const defaultState = { fetching: false, claimedRewardsById: {}, // id => reward - unclaimedRewardsByType: {}, + unclaimedRewards: [], claimPendingByType: {}, claimErrorsByType: {}, }; @@ -17,19 +17,19 @@ reducers[ACTIONS.FETCH_REWARDS_STARTED] = state => reducers[ACTIONS.FETCH_REWARDS_COMPLETED] = (state, action) => { const { userRewards } = action.data; - const unclaimedRewards = {}; + const unclaimedRewards = []; const claimedRewards = {}; userRewards.forEach(reward => { if (reward.transaction_id) { claimedRewards[reward.id] = reward; } else { - unclaimedRewards[reward.reward_type] = reward; + unclaimedRewards.push(reward); } }); return Object.assign({}, state, { claimedRewardsById: claimedRewards, - unclaimedRewardsByType: unclaimedRewards, + unclaimedRewards, fetching: false, }); }; @@ -62,24 +62,21 @@ reducers[ACTIONS.CLAIM_REWARD_STARTED] = (state, action) => { reducers[ACTIONS.CLAIM_REWARD_SUCCESS] = (state, action) => { const { reward } = action.data; + const { unclaimedRewards } = state; - const unclaimedRewardsByType = Object.assign({}, state.unclaimedRewardsByType); - const existingReward = unclaimedRewardsByType[reward.reward_type]; + const index = unclaimedRewards.findIndex(ur => ur.reward_type === reward.reward_type); + unclaimedRewards.splice(index, 1); - const newReward = Object.assign({}, reward, { - reward_title: existingReward.reward_title, - reward_description: existingReward.reward_description, - }); + const { claimedRewardsById } = state; + claimedRewardsById[reward.id] = reward; - const claimedRewardsById = Object.assign({}, state.claimedRewardsById); - claimedRewardsById[reward.id] = newReward; + const newState = { + ...state, + unclaimedRewards: [...unclaimedRewards], + claimedRewardsById: { ...claimedRewardsById }, + }; - const newState = Object.assign({}, state, { - unclaimedRewardsByType, - claimedRewardsById, - }); - - return setClaimRewardState(newState, newReward, false, ''); + return setClaimRewardState(newState, reward, false, ''); }; reducers[ACTIONS.CLAIM_REWARD_FAILURE] = (state, action) => { diff --git a/src/renderer/redux/selectors/rewards.js b/src/renderer/redux/selectors/rewards.js index cb0c83f52..c7fd3ef3d 100644 --- a/src/renderer/redux/selectors/rewards.js +++ b/src/renderer/redux/selectors/rewards.js @@ -1,5 +1,4 @@ import { createSelector } from 'reselect'; -import REWARDS from 'rewards'; const selectState = state => state.rewards || {}; @@ -26,16 +25,7 @@ export const selectClaimedRewardsByTransactionId = createSelector(selectClaimedR }, {}) ); -export const selectUnclaimedRewards = createSelector( - selectUnclaimedRewardsByType, - byType => - Object.values(byType).sort( - (a, b) => - REWARDS.SORT_ORDER.indexOf(a.reward_type) < REWARDS.SORT_ORDER.indexOf(b.reward_type) - ? -1 - : 1 - ) || [] -); +export const selectUnclaimedRewards = createSelector(selectState, state => state.unclaimedRewards); export const selectFetchingRewards = createSelector(selectState, state => !!state.fetching); @@ -65,7 +55,8 @@ const selectClaimRewardError = (state, props) => export const makeSelectClaimRewardError = () => createSelector(selectClaimRewardError, errorMessage => errorMessage); -const selectRewardByType = (state, props) => selectUnclaimedRewardsByType(state)[props.reward_type]; +const selectRewardByType = (state, rewardType) => + selectUnclaimedRewards(state).find(reward => reward.reward_type === rewardType); export const makeSelectRewardByType = () => createSelector(selectRewardByType, reward => reward); diff --git a/src/renderer/rewards.js b/src/renderer/rewards.js index 9905866d3..9da3727a9 100644 --- a/src/renderer/rewards.js +++ b/src/renderer/rewards.js @@ -1,21 +1,6 @@ import { Lbry, doNotify } from 'lbry-redux'; import Lbryio from 'lbryio'; -function rewardMessage(type, amount) { - return { - new_developer: __('You earned %s for registering as a new developer.', amount), - new_user: __('You earned %s LBC new user reward.', amount), - verified_email: __('You earned %s LBC for verifying your email address.', amount), - new_channel: __('You earned %s LBC for creating a publisher identity.', amount), - first_stream: __('You earned %s LBC for streaming your first video.', amount), - many_downloads: __('You earned %s LBC for downloading a bunch of things.', amount), - first_publish: __('You earned %s LBC for making your first publication.', amount), - featured_download: __('You earned %s LBC for watching a featured download.', amount), - referral: __('You earned %s LBC for referring someone.', amount), - youtube_creator: __('You earned %s LBC for syncing your YouTube channel.', amount), - }[type]; -} - const rewards = {}; rewards.TYPE_NEW_DEVELOPER = 'new_developer'; @@ -28,18 +13,6 @@ rewards.TYPE_FIRST_PUBLISH = 'first_publish'; rewards.TYPE_FEATURED_DOWNLOAD = 'featured_download'; rewards.TYPE_REFERRAL = 'referral'; rewards.YOUTUBE_CREATOR = 'youtube_creator'; -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.YOUTUBE_CREATOR, -]; rewards.claimReward = type => { function requestReward(resolve, reject, params) { @@ -48,7 +21,8 @@ rewards.claimReward = type => { return; } Lbryio.call('reward', 'new', params, 'post').then(reward => { - const message = rewardMessage(type, reward.reward_amount); + const message = + reward.reward_notification || `You have claimed a ${reward.reward_amount} LBC reward.`; // Display global notice const action = doNotify({