Automatically claim initial rewards (new_user & email_verified) when … #6807
6 changed files with 110 additions and 42 deletions
|
@ -17,6 +17,8 @@ import {
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { doOpenModal } from 'redux/actions/app';
|
import { doOpenModal } from 'redux/actions/app';
|
||||||
import { doUpdateBlockListForPublishedChannel } from 'redux/actions/comments';
|
import { doUpdateBlockListForPublishedChannel } from 'redux/actions/comments';
|
||||||
|
import { doClaimInitialRewards } from 'redux/actions/rewards';
|
||||||
|
import { selectIsClaimingInitialRewards, selectHasClaimedInitialRewards } from 'redux/selectors/rewards';
|
||||||
import ChannelForm from './view';
|
import ChannelForm from './view';
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
|
@ -36,6 +38,8 @@ const select = (state, props) => ({
|
||||||
createError: selectCreateChannelError(state),
|
createError: selectCreateChannelError(state),
|
||||||
creatingChannel: selectCreatingChannel(state),
|
creatingChannel: selectCreatingChannel(state),
|
||||||
balance: selectBalance(state),
|
balance: selectBalance(state),
|
||||||
|
isClaimingInitialRewards: selectIsClaimingInitialRewards(state),
|
||||||
|
hasClaimedInitialRewards: selectHasClaimedInitialRewards(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
|
@ -50,6 +54,7 @@ const perform = (dispatch) => ({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
clearChannelErrors: () => dispatch(doClearChannelErrors()),
|
clearChannelErrors: () => dispatch(doClearChannelErrors()),
|
||||||
|
claimInitialRewards: () => dispatch(doClaimInitialRewards()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(ChannelForm);
|
export default connect(select, perform)(ChannelForm);
|
||||||
|
|
|
@ -48,6 +48,7 @@ type Props = {
|
||||||
createError: string,
|
createError: string,
|
||||||
creatingChannel: boolean,
|
creatingChannel: boolean,
|
||||||
clearChannelErrors: () => void,
|
clearChannelErrors: () => void,
|
||||||
|
claimInitialRewards: () => void,
|
||||||
onDone: () => void,
|
onDone: () => void,
|
||||||
openModal: (
|
openModal: (
|
||||||
id: string,
|
id: string,
|
||||||
|
@ -55,6 +56,8 @@ type Props = {
|
||||||
) => void,
|
) => void,
|
||||||
uri: string,
|
uri: string,
|
||||||
disabled: boolean,
|
disabled: boolean,
|
||||||
|
isClaimingInitialRewards: boolean,
|
||||||
|
hasClaimedInitialRewards: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
function ChannelForm(props: Props) {
|
function ChannelForm(props: Props) {
|
||||||
|
@ -79,8 +82,11 @@ function ChannelForm(props: Props) {
|
||||||
creatingChannel,
|
creatingChannel,
|
||||||
createError,
|
createError,
|
||||||
clearChannelErrors,
|
clearChannelErrors,
|
||||||
|
claimInitialRewards,
|
||||||
openModal,
|
openModal,
|
||||||
disabled,
|
disabled,
|
||||||
|
isClaimingInitialRewards,
|
||||||
|
hasClaimedInitialRewards,
|
||||||
} = props;
|
} = props;
|
||||||
const [nameError, setNameError] = React.useState(undefined);
|
const [nameError, setNameError] = React.useState(undefined);
|
||||||
const [bidError, setBidError] = React.useState('');
|
const [bidError, setBidError] = React.useState('');
|
||||||
|
@ -94,6 +100,22 @@ function ChannelForm(props: Props) {
|
||||||
const languageParam = params.languages;
|
const languageParam = params.languages;
|
||||||
const primaryLanguage = Array.isArray(languageParam) && languageParam.length && languageParam[0];
|
const primaryLanguage = Array.isArray(languageParam) && languageParam.length && languageParam[0];
|
||||||
const secondaryLanguage = Array.isArray(languageParam) && languageParam.length >= 2 && languageParam[1];
|
const secondaryLanguage = Array.isArray(languageParam) && languageParam.length >= 2 && languageParam[1];
|
||||||
|
const submitLabel = React.useMemo(() => {
|
||||||
|
if (isClaimingInitialRewards) {
|
||||||
|
return __('Claiming credits...');
|
||||||
|
}
|
||||||
|
return creatingChannel || updatingChannel ? __('Submitting') : __('Submit');
|
||||||
|
}, [isClaimingInitialRewards, creatingChannel, updatingChannel]);
|
||||||
|
const submitDisabled = React.useMemo(() => {
|
||||||
|
return (
|
||||||
|
isClaimingInitialRewards ||
|
||||||
|
creatingChannel ||
|
||||||
|
updatingChannel ||
|
||||||
|
nameError ||
|
||||||
|
bidError ||
|
||||||
|
(isNewChannel && !params.name)
|
||||||
|
);
|
||||||
|
}, [isClaimingInitialRewards, creatingChannel, updatingChannel, nameError, bidError, isNewChannel, params]);
|
||||||
|
|
||||||
function getChannelParams() {
|
function getChannelParams() {
|
||||||
// fill this in with sdk data
|
// fill this in with sdk data
|
||||||
|
@ -219,6 +241,12 @@ function ChannelForm(props: Props) {
|
||||||
clearChannelErrors();
|
clearChannelErrors();
|
||||||
}, [clearChannelErrors]);
|
}, [clearChannelErrors]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!hasClaimedInitialRewards) {
|
||||||
|
claimInitialRewards();
|
||||||
|
}
|
||||||
|
}, [hasClaimedInitialRewards, claimInitialRewards]);
|
||||||
|
|
||||||
// TODO clear and bail after submit
|
// TODO clear and bail after submit
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -453,14 +481,7 @@ function ChannelForm(props: Props) {
|
||||||
actions={
|
actions={
|
||||||
<>
|
<>
|
||||||
<div className="section__actions">
|
<div className="section__actions">
|
||||||
<Button
|
<Button button="primary" disabled={submitDisabled} label={submitLabel} onClick={handleSubmit} />
|
||||||
button="primary"
|
|
||||||
disabled={
|
|
||||||
creatingChannel || updatingChannel || nameError || bidError || (isNewChannel && !params.name)
|
|
||||||
}
|
|
||||||
label={creatingChannel || updatingChannel ? __('Submitting') : __('Submit')}
|
|
||||||
onClick={handleSubmit}
|
|
||||||
/>
|
|
||||||
<Button button="link" label={__('Cancel')} onClick={onDone} />
|
<Button button="link" label={__('Cancel')} onClick={onDone} />
|
||||||
</div>
|
</div>
|
||||||
{errorMsg ? (
|
{errorMsg ? (
|
||||||
|
|
|
@ -18,7 +18,12 @@ import {
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import * as RENDER_MODES from 'constants/file_render_modes';
|
import * as RENDER_MODES from 'constants/file_render_modes';
|
||||||
import { doPublishDesktop } from 'redux/actions/publish';
|
import { doPublishDesktop } from 'redux/actions/publish';
|
||||||
import { selectUnclaimedRewardValue } from 'redux/selectors/rewards';
|
import { doClaimInitialRewards } from 'redux/actions/rewards';
|
||||||
|
import {
|
||||||
|
selectUnclaimedRewardValue,
|
||||||
|
selectIsClaimingInitialRewards,
|
||||||
|
selectHasClaimedInitialRewards,
|
||||||
|
} from 'redux/selectors/rewards';
|
||||||
import {
|
import {
|
||||||
selectModal,
|
selectModal,
|
||||||
selectActiveChannelClaim,
|
selectActiveChannelClaim,
|
||||||
|
@ -27,8 +32,8 @@ import {
|
||||||
} from 'redux/selectors/app';
|
} from 'redux/selectors/app';
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import { makeSelectFileRenderModeForUri } from 'redux/selectors/content';
|
import { makeSelectFileRenderModeForUri } from 'redux/selectors/content';
|
||||||
import PublishPage from './view';
|
|
||||||
import { selectUser } from 'redux/selectors/user';
|
import { selectUser } from 'redux/selectors/user';
|
||||||
|
import PublishPage from './view';
|
||||||
|
|
||||||
const select = (state) => {
|
const select = (state) => {
|
||||||
const myClaimForUri = selectMyClaimForUri(state);
|
const myClaimForUri = selectMyClaimForUri(state);
|
||||||
|
@ -59,6 +64,8 @@ const select = (state) => {
|
||||||
myChannels: selectMyChannelClaims(state),
|
myChannels: selectMyChannelClaims(state),
|
||||||
incognito: selectIncognito(state),
|
incognito: selectIncognito(state),
|
||||||
activeChannelStakedLevel: selectActiveChannelStakedLevel(state),
|
activeChannelStakedLevel: selectActiveChannelStakedLevel(state),
|
||||||
|
isClaimingInitialRewards: selectIsClaimingInitialRewards(state),
|
||||||
|
hasClaimedInitialRewards: selectHasClaimedInitialRewards(state),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,6 +77,7 @@ const perform = (dispatch) => ({
|
||||||
prepareEdit: (claim, uri) => dispatch(doPrepareEdit(claim, uri)),
|
prepareEdit: (claim, uri) => dispatch(doPrepareEdit(claim, uri)),
|
||||||
resetThumbnailStatus: () => dispatch(doResetThumbnailStatus()),
|
resetThumbnailStatus: () => dispatch(doResetThumbnailStatus()),
|
||||||
checkAvailability: (name) => dispatch(doCheckPublishNameAvailability(name)),
|
checkAvailability: (name) => dispatch(doCheckPublishNameAvailability(name)),
|
||||||
|
claimInitialRewards: () => dispatch(doClaimInitialRewards()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(PublishPage);
|
export default connect(select, perform)(PublishPage);
|
||||||
|
|
|
@ -90,6 +90,9 @@ type Props = {
|
||||||
isPostClaim: boolean,
|
isPostClaim: boolean,
|
||||||
permanentUrl: ?string,
|
permanentUrl: ?string,
|
||||||
remoteUrl: ?string,
|
remoteUrl: ?string,
|
||||||
|
isClaimingInitialRewards: boolean,
|
||||||
|
claimInitialRewards: () => void,
|
||||||
|
hasClaimedInitialRewards: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
function PublishForm(props: Props) {
|
function PublishForm(props: Props) {
|
||||||
|
@ -128,6 +131,9 @@ function PublishForm(props: Props) {
|
||||||
isPostClaim,
|
isPostClaim,
|
||||||
permanentUrl,
|
permanentUrl,
|
||||||
remoteUrl,
|
remoteUrl,
|
||||||
|
isClaimingInitialRewards,
|
||||||
|
claimInitialRewards,
|
||||||
|
hasClaimedInitialRewards,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const { replace, location } = useHistory();
|
const { replace, location } = useHistory();
|
||||||
|
@ -263,6 +269,12 @@ function PublishForm(props: Props) {
|
||||||
}
|
}
|
||||||
}, [activeChannelClaimStr, setSignedMessage]);
|
}, [activeChannelClaimStr, setSignedMessage]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!hasClaimedInitialRewards) {
|
||||||
|
claimInitialRewards();
|
||||||
|
}
|
||||||
|
}, [hasClaimedInitialRewards, claimInitialRewards]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!modal) {
|
if (!modal) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -298,7 +310,10 @@ function PublishForm(props: Props) {
|
||||||
|
|
||||||
const isLivestreamMode = mode === PUBLISH_MODES.LIVESTREAM;
|
const isLivestreamMode = mode === PUBLISH_MODES.LIVESTREAM;
|
||||||
let submitLabel;
|
let submitLabel;
|
||||||
if (publishing) {
|
|
||||||
|
if (isClaimingInitialRewards) {
|
||||||
|
submitLabel = __('Claiming credits...');
|
||||||
|
} else if (publishing) {
|
||||||
if (isStillEditing) {
|
if (isStillEditing) {
|
||||||
submitLabel = __('Saving...');
|
submitLabel = __('Saving...');
|
||||||
} else if (isLivestreamMode) {
|
} else if (isLivestreamMode) {
|
||||||
|
@ -623,6 +638,7 @@ function PublishForm(props: Props) {
|
||||||
onClick={handlePublish}
|
onClick={handlePublish}
|
||||||
label={submitLabel}
|
label={submitLabel}
|
||||||
disabled={
|
disabled={
|
||||||
|
isClaimingInitialRewards ||
|
||||||
formDisabled ||
|
formDisabled ||
|
||||||
!formValid ||
|
!formValid ||
|
||||||
uploadThumbnailStatus === THUMBNAIL_STATUSES.IN_PROGRESS ||
|
uploadThumbnailStatus === THUMBNAIL_STATUSES.IN_PROGRESS ||
|
||||||
|
|
|
@ -6,13 +6,13 @@ import { doFetchInviteStatus } from 'redux/actions/user';
|
||||||
import rewards from 'rewards';
|
import rewards from 'rewards';
|
||||||
|
|
||||||
export function doRewardList() {
|
export function doRewardList() {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.FETCH_REWARDS_STARTED,
|
type: ACTIONS.FETCH_REWARDS_STARTED,
|
||||||
});
|
});
|
||||||
|
|
||||||
Lbryio.call('reward', 'list', { multiple_rewards_per_type: true })
|
Lbryio.call('reward', 'list', { multiple_rewards_per_type: true })
|
||||||
.then(userRewards => {
|
.then((userRewards) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.FETCH_REWARDS_COMPLETED,
|
type: ACTIONS.FETCH_REWARDS_COMPLETED,
|
||||||
data: { userRewards },
|
data: { userRewards },
|
||||||
|
@ -35,7 +35,7 @@ export function doClaimRewardType(rewardType, options = {}) {
|
||||||
const reward =
|
const reward =
|
||||||
rewardType === rewards.TYPE_REWARD_CODE || rewardType === rewards.TYPE_NEW_ANDROID
|
rewardType === rewards.TYPE_REWARD_CODE || rewardType === rewards.TYPE_NEW_ANDROID
|
||||||
? { reward_type: rewards.TYPE_REWARD_CODE }
|
? { reward_type: rewards.TYPE_REWARD_CODE }
|
||||||
: unclaimedRewards.find(ur => ur.reward_type === rewardType);
|
: unclaimedRewards.find((ur) => ur.reward_type === rewardType);
|
||||||
|
|
||||||
// Try to claim the email reward right away, even if we haven't called reward_list yet
|
// Try to claim the email reward right away, even if we haven't called reward_list yet
|
||||||
if (
|
if (
|
||||||
|
@ -74,7 +74,7 @@ export function doClaimRewardType(rewardType, options = {}) {
|
||||||
data: { reward },
|
data: { reward },
|
||||||
});
|
});
|
||||||
|
|
||||||
const success = successReward => {
|
const success = (successReward) => {
|
||||||
// Temporary timeout to ensure the sdk has the correct balance after claiming a reward
|
// Temporary timeout to ensure the sdk has the correct balance after claiming a reward
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
dispatch(doUpdateBalance()).then(() => {
|
dispatch(doUpdateBalance()).then(() => {
|
||||||
|
@ -99,7 +99,7 @@ export function doClaimRewardType(rewardType, options = {}) {
|
||||||
}, 2000);
|
}, 2000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const failure = error => {
|
const failure = (error) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.CLAIM_REWARD_FAILURE,
|
type: ACTIONS.CLAIM_REWARD_FAILURE,
|
||||||
data: {
|
data: {
|
||||||
|
@ -121,6 +121,13 @@ export function doClaimRewardType(rewardType, options = {}) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function doClaimInitialRewards() {
|
||||||
|
return (dispatch) => {
|
||||||
|
dispatch(doClaimRewardType(rewards.TYPE_NEW_USER));
|
||||||
|
dispatch(doClaimRewardType(rewards.TYPE_CONFIRM_EMAIL));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function doClaimEligiblePurchaseRewards() {
|
export function doClaimEligiblePurchaseRewards() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
@ -131,10 +138,10 @@ export function doClaimEligiblePurchaseRewards() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unclaimedRewards.find(ur => ur.reward_type === rewards.TYPE_FIRST_STREAM)) {
|
if (unclaimedRewards.find((ur) => ur.reward_type === rewards.TYPE_FIRST_STREAM)) {
|
||||||
dispatch(doClaimRewardType(rewards.TYPE_FIRST_STREAM));
|
dispatch(doClaimRewardType(rewards.TYPE_FIRST_STREAM));
|
||||||
} else {
|
} else {
|
||||||
[rewards.TYPE_MANY_DOWNLOADS, rewards.TYPE_DAILY_VIEW].forEach(type => {
|
[rewards.TYPE_MANY_DOWNLOADS, rewards.TYPE_DAILY_VIEW].forEach((type) => {
|
||||||
dispatch(doClaimRewardType(type, { failSilently: true }));
|
dispatch(doClaimRewardType(type, { failSilently: true }));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -142,7 +149,7 @@ export function doClaimEligiblePurchaseRewards() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doClaimRewardClearError(reward) {
|
export function doClaimRewardClearError(reward) {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.CLAIM_REWARD_CLEAR_ERROR,
|
type: ACTIONS.CLAIM_REWARD_CLEAR_ERROR,
|
||||||
data: { reward },
|
data: { reward },
|
||||||
|
@ -151,8 +158,8 @@ export function doClaimRewardClearError(reward) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doFetchRewardedContent() {
|
export function doFetchRewardedContent() {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
const success = nameToClaimId => {
|
const success = (nameToClaimId) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.FETCH_REWARD_CONTENT_COMPLETED,
|
type: ACTIONS.FETCH_REWARD_CONTENT_COMPLETED,
|
||||||
data: {
|
data: {
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import REWARDS from 'rewards';
|
import REWARDS from 'rewards';
|
||||||
|
|
||||||
const selectState = state => state.rewards || {};
|
const selectState = (state) => state.rewards || {};
|
||||||
|
|
||||||
export const selectUnclaimedRewardsByType = createSelector(selectState, state => state.unclaimedRewardsByType);
|
export const selectUnclaimedRewardsByType = createSelector(selectState, (state) => state.unclaimedRewardsByType);
|
||||||
|
|
||||||
export const selectClaimedRewardsById = createSelector(selectState, state => state.claimedRewardsById);
|
export const selectClaimedRewardsById = createSelector(selectState, (state) => state.claimedRewardsById);
|
||||||
|
|
||||||
export const selectClaimedRewards = createSelector(selectClaimedRewardsById, byId => Object.values(byId) || []);
|
export const selectClaimedRewards = createSelector(selectClaimedRewardsById, (byId) => Object.values(byId) || []);
|
||||||
|
|
||||||
export const selectClaimedRewardsByTransactionId = createSelector(selectClaimedRewards, rewards =>
|
export const selectClaimedRewardsByTransactionId = createSelector(selectClaimedRewards, (rewards) =>
|
||||||
rewards.reduce((mapParam, reward) => {
|
rewards.reduce((mapParam, reward) => {
|
||||||
const map = mapParam;
|
const map = mapParam;
|
||||||
map[reward.transaction_id] = reward;
|
map[reward.transaction_id] = reward;
|
||||||
|
@ -17,47 +17,58 @@ export const selectClaimedRewardsByTransactionId = createSelector(selectClaimedR
|
||||||
}, {})
|
}, {})
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectUnclaimedRewards = createSelector(selectState, state => state.unclaimedRewards);
|
export const selectUnclaimedRewards = createSelector(selectState, (state) => state.unclaimedRewards);
|
||||||
|
|
||||||
export const selectFetchingRewards = createSelector(selectState, state => !!state.fetching);
|
export const selectFetchingRewards = createSelector(selectState, (state) => !!state.fetching);
|
||||||
|
|
||||||
export const selectUnclaimedRewardValue = createSelector(selectUnclaimedRewards, rewards =>
|
export const selectUnclaimedRewardValue = createSelector(selectUnclaimedRewards, (rewards) =>
|
||||||
rewards.reduce((sum, reward) => sum + reward.reward_amount, 0)
|
rewards.reduce((sum, reward) => sum + reward.reward_amount, 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectClaimsPendingByType = createSelector(selectState, state => state.claimPendingByType);
|
export const selectClaimsPendingByType = createSelector(selectState, (state) => state.claimPendingByType);
|
||||||
|
|
||||||
const selectIsClaimRewardPending = (state, props) => selectClaimsPendingByType(state, props)[props.reward_type];
|
const selectIsClaimRewardPending = (state, props) => selectClaimsPendingByType(state, props)[props.reward_type];
|
||||||
|
|
||||||
export const makeSelectIsRewardClaimPending = () =>
|
export const makeSelectIsRewardClaimPending = () =>
|
||||||
createSelector(selectIsClaimRewardPending, isClaiming => isClaiming);
|
createSelector(selectIsClaimRewardPending, (isClaiming) => isClaiming);
|
||||||
|
|
||||||
export const selectClaimErrorsByType = createSelector(selectState, state => state.claimErrorsByType);
|
export const selectClaimErrorsByType = createSelector(selectState, (state) => state.claimErrorsByType);
|
||||||
|
|
||||||
const selectClaimRewardError = (state, props) => selectClaimErrorsByType(state, props)[props.reward_type];
|
const selectClaimRewardError = (state, props) => selectClaimErrorsByType(state, props)[props.reward_type];
|
||||||
|
|
||||||
export const makeSelectClaimRewardError = () => createSelector(selectClaimRewardError, errorMessage => errorMessage);
|
export const makeSelectClaimRewardError = () => createSelector(selectClaimRewardError, (errorMessage) => errorMessage);
|
||||||
|
|
||||||
const selectRewardByType = (state, rewardType) =>
|
const selectRewardByType = (state, rewardType) =>
|
||||||
selectUnclaimedRewards(state).find(reward => reward.reward_type === rewardType);
|
selectUnclaimedRewards(state).find((reward) => reward.reward_type === rewardType);
|
||||||
|
|
||||||
export const makeSelectRewardByType = () => createSelector(selectRewardByType, reward => reward);
|
export const makeSelectRewardByType = () => createSelector(selectRewardByType, (reward) => reward);
|
||||||
|
|
||||||
const selectRewardByClaimCode = (state, claimCode) =>
|
const selectRewardByClaimCode = (state, claimCode) =>
|
||||||
selectUnclaimedRewards(state).find(reward => reward.claim_code === claimCode);
|
selectUnclaimedRewards(state).find((reward) => reward.claim_code === claimCode);
|
||||||
|
|
||||||
export const makeSelectRewardByClaimCode = () => createSelector(selectRewardByClaimCode, reward => reward);
|
export const makeSelectRewardByClaimCode = () => createSelector(selectRewardByClaimCode, (reward) => reward);
|
||||||
|
|
||||||
export const makeSelectRewardAmountByType = () =>
|
export const makeSelectRewardAmountByType = () =>
|
||||||
createSelector(selectRewardByType, reward => (reward ? reward.reward_amount : 0));
|
createSelector(selectRewardByType, (reward) => (reward ? reward.reward_amount : 0));
|
||||||
|
|
||||||
export const selectRewardContentClaimIds = createSelector(selectState, state => state.rewardedContentClaimIds);
|
export const selectRewardContentClaimIds = createSelector(selectState, (state) => state.rewardedContentClaimIds);
|
||||||
|
|
||||||
export const selectReferralReward = createSelector(
|
export const selectReferralReward = createSelector(
|
||||||
selectUnclaimedRewards,
|
selectUnclaimedRewards,
|
||||||
unclaimedRewards => unclaimedRewards.filter(reward => reward.reward_type === REWARDS.TYPE_REFERRAL)[0]
|
(unclaimedRewards) => unclaimedRewards.filter((reward) => reward.reward_type === REWARDS.TYPE_REFERRAL)[0]
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectHasUnclaimedRefereeReward = createSelector(selectUnclaimedRewards, unclaimedRewards =>
|
export const selectHasUnclaimedRefereeReward = createSelector(selectUnclaimedRewards, (unclaimedRewards) =>
|
||||||
unclaimedRewards.some(reward => reward.reward_type === REWARDS.TYPE_REFEREE)
|
unclaimedRewards.some((reward) => reward.reward_type === REWARDS.TYPE_REFEREE)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const selectIsClaimingInitialRewards = createSelector(selectClaimsPendingByType, (claimsPendingByType) => {
|
||||||
|
return !!(claimsPendingByType[REWARDS.TYPE_NEW_USER] || claimsPendingByType[REWARDS.TYPE_CONFIRM_EMAIL]);
|
||||||
|
});
|
||||||
|
|
||||||
|
export const selectHasClaimedInitialRewards = createSelector(selectClaimedRewardsById, (claimedRewardsById) => {
|
||||||
|
const claims = Object.values(claimedRewardsById);
|
||||||
|
const newUserClaimed = !!claims.find((claim) => claim && claim.reward_type === REWARDS.TYPE_NEW_USER);
|
||||||
|
const confirmEmailClaimed = !!claims.find((claim) => claim && claim.reward_type === REWARDS.TYPE_CONFIRM_EMAIL);
|
||||||
|
return newUserClaimed && confirmEmailClaimed;
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue