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:
parent
ea4c7d9d15
commit
ef3ea8c319
7 changed files with 29 additions and 78 deletions
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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({
|
||||
|
|
Loading…
Add table
Reference in a new issue