first run improvements + kill first follow modal

This commit is contained in:
Sean Yesmunt 2020-08-27 13:56:18 -04:00
parent 61b6c19320
commit 7e8b2bb184
7 changed files with 100 additions and 21 deletions

View file

@ -17,6 +17,7 @@ import Nag from 'component/common/nag';
import REWARDS from 'rewards';
import usePersistedState from 'effects/use-persisted-state';
import FileDrop from 'component/fileDrop';
import NagContinueFirstRun from 'component/nagContinueFirstRun';
// @if TARGET='app'
import useZoom from 'effects/use-zoom';
// @endif
@ -330,6 +331,7 @@ function App(props: Props) {
{/* @if TARGET='web' */}
<YoutubeWelcome />
{!shouldHideNag && <OpenInAppLink uri={uri} />}
{!shouldHideNag && <NagContinueFirstRun />}
{(lbryTvApiStatus === STATUS_DEGRADED || lbryTvApiStatus === STATUS_FAILING) && !shouldHideNag && (
<NagDegradedPerformance onClose={() => setLbryTvApiStatus(STATUS_OK)} />
)}

View file

@ -0,0 +1,17 @@
import { connect } from 'react-redux';
import { SETTINGS } from 'lbry-redux';
import { makeSelectClientSetting } from 'redux/selectors/settings';
import { doSetClientSetting, doSyncClientSettings } from 'redux/actions/settings';
import UserSignIn from './view';
const select = state => ({
followingAcknowledged: makeSelectClientSetting(SETTINGS.FOLLOWING_ACKNOWLEDGED)(state),
firstRunStarted: makeSelectClientSetting(SETTINGS.FIRST_RUN_STARTED)(state),
});
const perform = dispatch => ({
syncSettings: () => dispatch(doSyncClientSettings()),
setClientSetting: (setting, value) => dispatch(doSetClientSetting(setting, value)),
});
export default connect(select, perform)(UserSignIn);

View file

@ -0,0 +1,45 @@
// @flow
import * as PAGES from 'constants/pages';
import React from 'react';
import Nag from 'component/common/nag';
import { SETTINGS } from 'lbry-redux';
import { useHistory } from 'react-router';
type Props = {
followingAcknowledged: boolean,
firstRunStarted: boolean,
setClientSetting: (string, boolean) => void,
syncSetttings: () => void,
};
export default function NagContinueFirstRun(props: Props) {
const { firstRunStarted, followingAcknowledged, setClientSetting, syncSetttings } = props;
const {
location: { pathname },
push,
} = useHistory();
const isOnFirstRun = pathname.includes(PAGES.AUTH);
function onClose() {
setClientSetting(SETTINGS.FOLLOWING_ACKNOWLEDGED, true);
syncSetttings();
}
function handleContinue() {
push(`/$/${PAGES.AUTH}`);
}
if (isOnFirstRun || !firstRunStarted || followingAcknowledged) {
return null;
}
return (
<Nag
type="helpful"
message={__('Do you want to continue the setup process?')}
actionText={__('Continue')}
onClick={handleContinue}
onClose={onClose}
/>
);
}

View file

@ -1,13 +1,11 @@
import { connect } from 'react-redux';
import { doChannelSubscribe, doChannelUnsubscribe } from 'redux/actions/subscriptions';
import { doOpenModal } from 'redux/actions/app';
import { selectSubscriptions, makeSelectIsSubscribed, selectFirstRunCompleted } from 'redux/selectors/subscriptions';
import { makeSelectIsSubscribed, selectFirstRunCompleted } from 'redux/selectors/subscriptions';
import { makeSelectPermanentUrlForUri } from 'lbry-redux';
import { doToast } from 'redux/actions/notifications';
import SubscribeButton from './view';
const select = (state, props) => ({
subscriptions: selectSubscriptions(state),
isSubscribed: makeSelectIsSubscribed(props.uri, true)(state),
firstRunCompleted: selectFirstRunCompleted(state),
permanentUrl: makeSelectPermanentUrlForUri(props.uri)(state),
@ -16,6 +14,5 @@ const select = (state, props) => ({
export default connect(select, {
doChannelSubscribe,
doChannelUnsubscribe,
doOpenModal,
doToast,
})(SubscribeButton);

View file

@ -1,5 +1,4 @@
// @flow
import * as MODALS from 'constants/modal_types';
import * as ICONS from 'constants/icons';
import React, { useRef } from 'react';
import { parseURI } from 'lbry-redux';
@ -15,10 +14,8 @@ type SubscriptionArgs = {
type Props = {
permanentUrl: ?string,
isSubscribed: boolean,
subscriptions: Array<string>,
doChannelSubscribe: ({ channelName: string, uri: string }) => void,
doChannelUnsubscribe: SubscriptionArgs => void,
doOpenModal: (id: string) => void,
showSnackBarOnSubscribe: boolean,
doToast: ({ message: string }) => void,
shrinkOnMobile: boolean,
@ -29,8 +26,6 @@ export default function SubscribeButton(props: Props) {
permanentUrl,
doChannelSubscribe,
doChannelUnsubscribe,
doOpenModal,
subscriptions,
isSubscribed,
showSnackBarOnSubscribe,
doToast,
@ -65,10 +60,6 @@ export default function SubscribeButton(props: Props) {
onClick={e => {
e.stopPropagation();
if (!subscriptions.length) {
doOpenModal(MODALS.FIRST_SUBSCRIPTION);
}
subscriptionHandler({
channelName: claimName,
uri: permanentUrl,

View file

@ -46,12 +46,18 @@ const select = state => ({
const perform = dispatch => ({
fetchUser: () => dispatch(doUserFetch()),
claimReward: () =>
claimConfirmEmailReward: () =>
dispatch(
doClaimRewardType(REWARD_TYPES.TYPE_CONFIRM_EMAIL, {
notifyError: false,
})
),
claimNewUserReward: () =>
dispatch(
doClaimRewardType(REWARD_TYPES.NEW_USER, {
notifyError: false,
})
),
syncSettings: () => dispatch(doSyncClientSettings()),
setClientSetting: (setting, value) => dispatch(doSetClientSetting(setting, value)),
});

View file

@ -25,7 +25,8 @@ type Props = {
balance: ?number,
fetchingChannels: boolean,
claimingReward: boolean,
claimReward: () => void,
claimConfirmEmailReward: () => void,
claimNewUserReward: () => void,
fetchUser: () => void,
claimedRewards: Array<Reward>,
history: { replace: string => void },
@ -42,14 +43,15 @@ type Props = {
rewardsAcknowledged: boolean,
};
function UserSignIn(props: Props) {
function UserSignUp(props: Props) {
const {
emailToVerify,
user,
claimingReward,
claimedRewards,
channels,
claimReward,
claimConfirmEmailReward,
claimNewUserReward,
balance,
history,
location,
@ -83,7 +85,6 @@ function UserSignIn(props: Props) {
const isYoutubeTransferComplete =
hasYoutubeChannels &&
youtubeChannels.every(channel => channel.transfer_state === YOUTUBE_STATUSES.COMPLETED_TRANSFER);
// Complexity warning
// We can't just check if we are currently fetching something
// We may want to keep a component rendered while something is being fetched, instead of replacing it with the large spinner
@ -122,15 +123,29 @@ function UserSignIn(props: Props) {
fetchUser();
}, [fetchUser]);
React.useEffect(() => {
if (hasVerifiedEmail) {
setSettingAndSync(SETTINGS.FIRST_RUN_STARTED, true);
}
}, [hasVerifiedEmail]);
React.useEffect(() => {
// Don't claim the reward if sync is enabled until after a sync has been completed successfully
// If we do it before, we could end up trying to sync a wallet with a non-zero balance which will fail to sync
const delayForSync = syncEnabled && !hasSynced;
if (hasVerifiedEmail && !hasClaimedEmailAward && !hasFetchedReward && !delayForSync) {
claimReward();
claimConfirmEmailReward();
}
}, [hasVerifiedEmail, claimReward, hasClaimedEmailAward, hasFetchedReward, syncEnabled, hasSynced, balance]);
}, [
hasVerifiedEmail,
claimConfirmEmailReward,
hasClaimedEmailAward,
hasFetchedReward,
syncEnabled,
hasSynced,
balance,
]);
// Loop through this list from the end, until it finds a matching component
// If it never finds one, assume the user has completed every step and redirect them
@ -228,6 +243,12 @@ function UserSignIn(props: Props) {
const [componentToRender, isScrollable] = getSignInStep();
React.useEffect(() => {
if (!componentToRender) {
claimNewUserReward();
}
}, [componentToRender, claimNewUserReward]);
if (!componentToRender) {
history.replace(redirect || '/');
}
@ -237,4 +258,4 @@ function UserSignIn(props: Props) {
);
}
export default withRouter(UserSignIn);
export default withRouter(UserSignUp);