first run improvements + kill first follow modal
This commit is contained in:
parent
61b6c19320
commit
7e8b2bb184
7 changed files with 100 additions and 21 deletions
|
@ -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)} />
|
||||
)}
|
||||
|
|
17
ui/component/nagContinueFirstRun/index.js
Normal file
17
ui/component/nagContinueFirstRun/index.js
Normal 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);
|
45
ui/component/nagContinueFirstRun/view.jsx
Normal file
45
ui/component/nagContinueFirstRun/view.jsx
Normal 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}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)),
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue