Refactor unclaimed rewards as array to keep order from api.lbry.io. Display reward notification message through snackbar with fallback for rewards without a message.

This commit is contained in:
Travis Eden 2018-05-17 16:31:49 -04:00
parent ea4c7d9d15
commit ef3ea8c319
7 changed files with 29 additions and 78 deletions

View file

@ -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;

View file

@ -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),
};
};

View file

@ -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),
};
};

View file

@ -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 => {

View file

@ -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;
let { 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 = unclaimedRewards.slice(0, index).concat(unclaimedRewards.slice(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 = Object.assign({}, state, {
unclaimedRewardsByType,
const newState = {
...state,
unclaimedRewards,
claimedRewardsById,
});
};
return setClaimRewardState(newState, newReward, false, '');
return setClaimRewardState(newState, reward, false, '');
};
reducers[ACTIONS.CLAIM_REWARD_FAILURE] = (state, action) => {

View file

@ -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);

View file

@ -1,46 +1,8 @@
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';
rewards.TYPE_NEW_USER = 'new_user';
rewards.TYPE_CONFIRM_EMAIL = 'verified_email';
rewards.TYPE_FIRST_CHANNEL = 'new_channel';
rewards.TYPE_FIRST_STREAM = 'first_stream';
rewards.TYPE_MANY_DOWNLOADS = 'many_downloads';
rewards.TYPE_FIRST_PUBLISH = 'first_publish';
rewards.TYPE_FEATURED_DOWNLOAD = 'featured_download';
rewards.TYPE_REFERRAL = 'referral';
rewards.YOUTUBE_CREATOR = 'youtube_creator';
rewards.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) {
if (!Lbryio.enabled) {
@ -48,7 +10,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({