diff --git a/.eslintrc.json b/.eslintrc.json index 80013b8..a6129f0 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -25,6 +25,7 @@ "import/no-commonjs": "warn", "import/no-amd": "warn", "import/prefer-default-export": "ignore", - "func-names": ["warn", "as-needed"] + "func-names": ["warn", "as-needed"], + "no-plusplus": 0 } } diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ac09074..9345bad 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -86,7 +86,9 @@ const SET_SYNC_COMPLETED = 'SET_SYNC_COMPLETED'; const SET_DEFAULT_ACCOUNT = 'SET_DEFAULT_ACCOUNT'; const SYNC_APPLY_STARTED = 'SYNC_APPLY_STARTED'; const SYNC_APPLY_COMPLETED = 'SYNC_APPLY_COMPLETED'; -const SYNC_APPLY_FAILED = 'SYNC_APPLY_FAILED'; +const SYNC_APPLY_FAILED = 'SYNC_APPLY_FAILED'; // User + +const USER_SETTINGS_POPULATE = 'USER_SETTINGS_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ GENERATE_AUTH_TOKEN_FAILURE: GENERATE_AUTH_TOKEN_FAILURE, @@ -159,7 +161,8 @@ var action_types = /*#__PURE__*/Object.freeze({ SET_DEFAULT_ACCOUNT: SET_DEFAULT_ACCOUNT, SYNC_APPLY_STARTED: SYNC_APPLY_STARTED, SYNC_APPLY_COMPLETED: SYNC_APPLY_COMPLETED, - SYNC_APPLY_FAILED: SYNC_APPLY_FAILED + SYNC_APPLY_FAILED: SYNC_APPLY_FAILED, + USER_SETTINGS_POPULATE: USER_SETTINGS_POPULATE }); const Lbryio = { @@ -213,6 +216,13 @@ Lbryio.call = (resource, action, params = {}, method = 'get') => { auth_token: token, ...params }; + Object.keys(fullParams).forEach(key => { + const value = fullParams[key]; + + if (typeof value === 'object') { + fullParams[key] = JSON.stringify(value); + } + }); const qs = querystring.stringify(fullParams); let url = `${Lbryio.CONNECTION_STRING}${resource}/${action}?${qs}`; let options = { @@ -371,7 +381,7 @@ Lbryio.setOverride = (methodName, newMethod) => { const rewards = {}; rewards.TYPE_NEW_DEVELOPER = 'new_developer'; rewards.TYPE_NEW_USER = 'new_user'; -rewards.TYPE_CONFIRM_EMAIL = 'verified_email'; +rewards.TYPE_CONFIRM_EMAIL = 'email_provided'; rewards.TYPE_FIRST_CHANNEL = 'new_channel'; rewards.TYPE_FIRST_STREAM = 'first_stream'; rewards.TYPE_MANY_DOWNLOADS = 'many_downloads'; @@ -709,6 +719,7 @@ const selectPhoneVerifyIsPending = reselect.createSelector(selectState$1, state const selectPhoneVerifyErrorMessage = reselect.createSelector(selectState$1, state => state.phoneVerifyErrorMessage); const selectIdentityVerifyIsPending = reselect.createSelector(selectState$1, state => state.identityVerifyIsPending); const selectIdentityVerifyErrorMessage = reselect.createSelector(selectState$1, state => state.identityVerifyErrorMessage); +const selectUserVerifiedEmail = reselect.createSelector(selectUser, user => user && user.has_verified_email); const selectUserIsVerificationCandidate = reselect.createSelector(selectUser, user => user && (!user.has_verified_email || !user.is_identity_verified)); const selectAccessToken = reselect.createSelector(selectState$1, state => state.accessToken); const selectUserInviteStatusIsPending = reselect.createSelector(selectState$1, state => state.inviteStatusIsPending); @@ -1121,16 +1132,16 @@ function doClaimRewardType(rewardType, options = {}) { const unclaimedRewards = selectUnclaimedRewards(state); const reward = rewardType === 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 - if (rewardType !== rewards.TYPE_REWARD_CODE) { + if (rewardType !== rewards.TYPE_REWARD_CODE || rewardType !== rewards.TYPE_CONFIRM_EMAIL) { if (!reward || reward.transaction_id) { // already claimed or doesn't exist, do nothing return; } } - if (!userIsRewardApproved && rewardType !== rewards.TYPE_CONFIRM_EMAIL) { + if (!userIsRewardApproved && rewardType !== rewards.TYPE_CONFIRM_EMAIL && rewardType !== rewards.TYPE_REWARD_CODE) { if (!options || !options.failSilently && rewards.callbacks.rewardApprovalRequested) { rewards.callbacks.rewardApprovalRequested(); } @@ -1163,6 +1174,10 @@ function doClaimRewardType(rewardType, options = {}) { } dispatch(doRewardList()); + + if (options.callback) { + options.callback(); + } }; const failure = error => { @@ -1180,6 +1195,10 @@ function doClaimRewardType(rewardType, options = {}) { isError: true })); } + + if (options.callback) { + options.callback(error); + } }; rewards.claimReward(rewardType, params).then(success, failure); @@ -2409,7 +2428,8 @@ reducers$2[lbryRedux.ACTIONS.USER_FETCH_STARTED] = state => Object.assign({}, st reducers$2[lbryRedux.ACTIONS.USER_FETCH_SUCCESS] = (state, action) => Object.assign({}, state, { userIsPending: false, - user: action.data.user + user: action.data.user, + emailToVerify: action.data.user.has_verified_email ? null : state.emailToVerify }); reducers$2[lbryRedux.ACTIONS.USER_FETCH_FAILURE] = state => Object.assign({}, state, { @@ -2971,6 +2991,7 @@ exports.selectUserIsPending = selectUserIsPending; exports.selectUserIsRewardApproved = selectUserIsRewardApproved; exports.selectUserIsVerificationCandidate = selectUserIsVerificationCandidate; exports.selectUserPhone = selectUserPhone; +exports.selectUserVerifiedEmail = selectUserVerifiedEmail; exports.selectViewMode = selectViewMode; exports.setSubscriptionLatest = setSubscriptionLatest; exports.statsReducer = statsReducer; diff --git a/src/index.js b/src/index.js index 81f1156..23aaa28 100644 --- a/src/index.js +++ b/src/index.js @@ -147,6 +147,7 @@ export { selectUserInviteNewIsPending, selectUserInviteNewErrorMessage, selectUserInviteReferralLink, + selectUserVerifiedEmail, } from 'redux/selectors/user'; export { makeSelectFetchingCostInfoForUri, diff --git a/src/lbryio.js b/src/lbryio.js index a0edaef..c6c75b4 100644 --- a/src/lbryio.js +++ b/src/lbryio.js @@ -48,6 +48,13 @@ Lbryio.call = (resource, action, params = {}, method = 'get') => { return Lbryio.getAuthToken().then(token => { const fullParams = { auth_token: token, ...params }; + Object.keys(fullParams).forEach(key => { + const value = fullParams[key]; + if (typeof value === 'object') { + fullParams[key] = JSON.stringify(value); + } + }); + const qs = querystring.stringify(fullParams); let url = `${Lbryio.CONNECTION_STRING}${resource}/${action}?${qs}`; diff --git a/src/redux/actions/rewards.js b/src/redux/actions/rewards.js index 86ddff1..0b5e445 100644 --- a/src/redux/actions/rewards.js +++ b/src/redux/actions/rewards.js @@ -37,14 +37,19 @@ export function doClaimRewardType(rewardType, options = {}) { ? { reward_type: rewards.TYPE_REWARD_CODE } : unclaimedRewards.find(ur => ur.reward_type === rewardType); - if (rewardType !== rewards.TYPE_REWARD_CODE) { + // Try to claim the email reward right away, even if we haven't called reward_list yet + if (rewardType !== rewards.TYPE_REWARD_CODE || rewardType !== rewards.TYPE_CONFIRM_EMAIL) { if (!reward || reward.transaction_id) { // already claimed or doesn't exist, do nothing return; } } - if (!userIsRewardApproved && rewardType !== rewards.TYPE_CONFIRM_EMAIL) { + if ( + !userIsRewardApproved && + rewardType !== rewards.TYPE_CONFIRM_EMAIL && + rewardType !== rewards.TYPE_REWARD_CODE + ) { if (!options || (!options.failSilently && rewards.callbacks.rewardApprovalRequested)) { rewards.callbacks.rewardApprovalRequested(); } @@ -78,6 +83,10 @@ export function doClaimRewardType(rewardType, options = {}) { } dispatch(doRewardList()); + + if (options.callback) { + options.callback(); + } }; const failure = error => { @@ -92,6 +101,10 @@ export function doClaimRewardType(rewardType, options = {}) { if (options.notifyError) { dispatch(doToast({ message: error.message, isError: true })); } + + if (options.callback) { + options.callback(error); + } }; rewards.claimReward(rewardType, params).then(success, failure); diff --git a/src/redux/reducers/user.js b/src/redux/reducers/user.js index 18affc3..cb0c7b9 100644 --- a/src/redux/reducers/user.js +++ b/src/redux/reducers/user.js @@ -46,6 +46,7 @@ reducers[ACTIONS.USER_FETCH_SUCCESS] = (state, action) => Object.assign({}, state, { userIsPending: false, user: action.data.user, + emailToVerify: action.data.user.has_verified_email ? null : state.emailToVerify, }); reducers[ACTIONS.USER_FETCH_FAILURE] = state => diff --git a/src/redux/selectors/user.js b/src/redux/selectors/user.js index 46c8541..56f16e0 100644 --- a/src/redux/selectors/user.js +++ b/src/redux/selectors/user.js @@ -93,6 +93,11 @@ export const selectIdentityVerifyErrorMessage = createSelector( state => state.identityVerifyErrorMessage ); +export const selectUserVerifiedEmail = createSelector( + selectUser, + user => user && user.has_verified_email +); + export const selectUserIsVerificationCandidate = createSelector( selectUser, user => user && (!user.has_verified_email || !user.is_identity_verified) diff --git a/src/rewards.js b/src/rewards.js index 80b1337..77444c4 100644 --- a/src/rewards.js +++ b/src/rewards.js @@ -5,7 +5,7 @@ const rewards = {}; rewards.TYPE_NEW_DEVELOPER = 'new_developer'; rewards.TYPE_NEW_USER = 'new_user'; -rewards.TYPE_CONFIRM_EMAIL = 'verified_email'; +rewards.TYPE_CONFIRM_EMAIL = 'email_provided'; rewards.TYPE_FIRST_CHANNEL = 'new_channel'; rewards.TYPE_FIRST_STREAM = 'first_stream'; rewards.TYPE_MANY_DOWNLOADS = 'many_downloads';