add yotube sync to initial sign up flow
This commit is contained in:
parent
baafd60f4f
commit
f547053ebc
11 changed files with 125 additions and 56 deletions
|
@ -23,6 +23,8 @@ type Props = {
|
|||
setShareDiagnosticData: boolean => void,
|
||||
doSignUp: (string, ?string) => Promise<any>,
|
||||
clearEmailEntry: () => void,
|
||||
interestedInYoutubSync: boolean,
|
||||
doToggleInterestedInYoutubeSync: () => void,
|
||||
};
|
||||
|
||||
function UserEmailNew(props: Props) {
|
||||
|
@ -35,6 +37,8 @@ function UserEmailNew(props: Props) {
|
|||
setShareDiagnosticData,
|
||||
clearEmailEntry,
|
||||
emailExists,
|
||||
interestedInYoutubSync,
|
||||
doToggleInterestedInYoutubeSync,
|
||||
} = props;
|
||||
const { share_usage_data: shareUsageData } = daemonSettings;
|
||||
const { push, location } = useHistory();
|
||||
|
@ -113,6 +117,14 @@ function UserEmailNew(props: Props) {
|
|||
onChange={e => setPassword(e.target.value)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="checkbox"
|
||||
name="youtube_sync_checkbox"
|
||||
label={__('Sync my YouTube channel')}
|
||||
checked={interestedInYoutubSync}
|
||||
onChange={() => doToggleInterestedInYoutubeSync()}
|
||||
/>
|
||||
|
||||
{!IS_WEB && (
|
||||
<FormField
|
||||
type="checkbox"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// @flow
|
||||
import * as PAGES from 'constants/pages';
|
||||
import React, { useState } from 'react';
|
||||
import { isNameValid } from 'lbry-redux';
|
||||
import Button from 'component/button';
|
||||
|
@ -15,10 +14,18 @@ type Props = {
|
|||
createChannelError: string,
|
||||
claimingReward: boolean,
|
||||
user: User,
|
||||
doToggleInterestedInYoutubeSync: () => void,
|
||||
};
|
||||
|
||||
function UserFirstChannel(props: Props) {
|
||||
const { createChannel, creatingChannel, claimingReward, user, createChannelError } = props;
|
||||
const {
|
||||
createChannel,
|
||||
creatingChannel,
|
||||
claimingReward,
|
||||
user,
|
||||
createChannelError,
|
||||
doToggleInterestedInYoutubeSync,
|
||||
} = props;
|
||||
const { primary_email: primaryEmail } = user;
|
||||
const initialChannel = primaryEmail ? primaryEmail.split('@')[0] : '';
|
||||
const [channel, setChannel] = useState(initialChannel);
|
||||
|
@ -87,7 +94,7 @@ function UserFirstChannel(props: Props) {
|
|||
<Button
|
||||
button="link"
|
||||
label={__('Sync it and skip this step')}
|
||||
navigate={`/$/${PAGES.YOUTUBE_SYNC}`}
|
||||
onClick={() => doToggleInterestedInYoutubeSync()}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
|
|
|
@ -20,6 +20,8 @@ import {
|
|||
SETTINGS,
|
||||
} from 'lbry-redux';
|
||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||
import { selectInterestedInYoutubeSync } from 'redux/selectors/app';
|
||||
import { doToggleInterestedInYoutubeSync } from 'redux/actions/app';
|
||||
import UserSignIn from './view';
|
||||
|
||||
const select = state => ({
|
||||
|
@ -42,6 +44,7 @@ const select = state => ({
|
|||
syncingWallet: selectGetSyncIsPending(state),
|
||||
hasSynced: Boolean(selectSyncHash(state)),
|
||||
creatingChannel: selectCreatingChannel(state),
|
||||
interestedInYoutubeSync: selectInterestedInYoutubeSync(state),
|
||||
});
|
||||
|
||||
const perform = dispatch => ({
|
||||
|
@ -60,6 +63,7 @@ const perform = dispatch => ({
|
|||
),
|
||||
syncSettings: () => dispatch(doSyncClientSettings()),
|
||||
setClientSetting: (setting, value) => dispatch(doSetClientSetting(setting, value)),
|
||||
doToggleInterestedInYoutubeSync: () => dispatch(doToggleInterestedInYoutubeSync()),
|
||||
});
|
||||
|
||||
export default connect(select, perform)(UserSignIn);
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
import * as PAGES from 'constants/pages';
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { withRouter } from 'react-router';
|
||||
import { useHistory } from 'react-router';
|
||||
import UserEmailNew from 'component/userEmailNew';
|
||||
import UserEmailVerify from 'component/userEmailVerify';
|
||||
import UserFirstChannel from 'component/userFirstChannel';
|
||||
import UserChannelFollowIntro from 'component/userChannelFollowIntro';
|
||||
import UserTagFollowIntro from 'component/userTagFollowIntro';
|
||||
import YoutubeSync from 'page/youtubeSync';
|
||||
import { DEFAULT_BID_FOR_FIRST_CHANNEL } from 'component/userFirstChannel/view';
|
||||
import { YOUTUBE_STATUSES } from 'lbryinc';
|
||||
import { SETTINGS } from 'lbry-redux';
|
||||
|
@ -18,6 +19,10 @@ import YoutubeTransferStatus from 'component/youtubeTransferStatus';
|
|||
import useFetched from 'effects/use-fetched';
|
||||
import Confetti from 'react-confetti';
|
||||
|
||||
const REDIRECT_PARAM = 'redirect';
|
||||
const REDIRECT_IMMEDIATELY_PARAM = 'immediate';
|
||||
const STEP_PARAM = 'step';
|
||||
|
||||
type Props = {
|
||||
user: ?User,
|
||||
emailToVerify: ?string,
|
||||
|
@ -29,8 +34,6 @@ type Props = {
|
|||
claimNewUserReward: () => void,
|
||||
fetchUser: () => void,
|
||||
claimedRewards: Array<Reward>,
|
||||
history: { replace: string => void },
|
||||
location: { search: string },
|
||||
youtubeChannels: Array<any>,
|
||||
syncEnabled: boolean,
|
||||
hasSynced: boolean,
|
||||
|
@ -41,6 +44,8 @@ type Props = {
|
|||
followingAcknowledged: boolean,
|
||||
tagsAcknowledged: boolean,
|
||||
rewardsAcknowledged: boolean,
|
||||
interestedInYoutubeSync: boolean,
|
||||
doToggleInterestedInYoutubeSync: () => void,
|
||||
};
|
||||
|
||||
function UserSignUp(props: Props) {
|
||||
|
@ -53,8 +58,6 @@ function UserSignUp(props: Props) {
|
|||
claimConfirmEmailReward,
|
||||
claimNewUserReward,
|
||||
balance,
|
||||
history,
|
||||
location,
|
||||
fetchUser,
|
||||
youtubeChannels,
|
||||
syncEnabled,
|
||||
|
@ -67,12 +70,17 @@ function UserSignUp(props: Props) {
|
|||
rewardsAcknowledged,
|
||||
syncSettings,
|
||||
setClientSetting,
|
||||
interestedInYoutubeSync,
|
||||
doToggleInterestedInYoutubeSync,
|
||||
} = props;
|
||||
const { search } = location;
|
||||
const {
|
||||
location: { search, pathname },
|
||||
replace,
|
||||
} = useHistory();
|
||||
const urlParams = new URLSearchParams(search);
|
||||
const redirect = urlParams.get('redirect');
|
||||
const step = urlParams.get('step');
|
||||
const shouldRedirectImmediately = urlParams.get('immediate');
|
||||
const redirect = urlParams.get(REDIRECT_PARAM);
|
||||
const step = urlParams.get(STEP_PARAM);
|
||||
const shouldRedirectImmediately = urlParams.get(REDIRECT_IMMEDIATELY_PARAM);
|
||||
const [initialSignInStep, setInitialSignInStep] = React.useState();
|
||||
const hasVerifiedEmail = user && user.has_verified_email;
|
||||
const rewardsApproved = user && user.is_reward_approved;
|
||||
|
@ -97,11 +105,12 @@ function UserSignUp(props: Props) {
|
|||
const showSyncPassword = syncEnabled && getSyncError;
|
||||
const showChannelCreation =
|
||||
hasVerifiedEmail &&
|
||||
balance !== undefined &&
|
||||
balance !== null &&
|
||||
balance > DEFAULT_BID_FOR_FIRST_CHANNEL &&
|
||||
channelCount === 0 &&
|
||||
!hasYoutubeChannels;
|
||||
((balance !== undefined &&
|
||||
balance !== null &&
|
||||
balance > DEFAULT_BID_FOR_FIRST_CHANNEL &&
|
||||
channelCount === 0 &&
|
||||
!hasYoutubeChannels) ||
|
||||
interestedInYoutubeSync);
|
||||
const showYoutubeTransfer = hasVerifiedEmail && hasYoutubeChannels && !isYoutubeTransferComplete;
|
||||
const showFollowIntro = step === 'channels' || (hasVerifiedEmail && !followingAcknowledged);
|
||||
const showTagsIntro = step === 'tags' || (hasVerifiedEmail && !tagsAcknowledged);
|
||||
|
@ -150,7 +159,12 @@ function UserSignUp(props: Props) {
|
|||
// 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
|
||||
const SIGN_IN_FLOW = [
|
||||
showEmail && <UserEmailNew />,
|
||||
showEmail && (
|
||||
<UserEmailNew
|
||||
interestedInYoutubSync={interestedInYoutubeSync}
|
||||
doToggleInterestedInYoutubeSync={doToggleInterestedInYoutubeSync}
|
||||
/>
|
||||
),
|
||||
showEmailVerification && <UserEmailVerify />,
|
||||
showUserVerification && (
|
||||
<UserVerify
|
||||
|
@ -159,47 +173,48 @@ function UserSignUp(props: Props) {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
showChannelCreation && <UserFirstChannel />,
|
||||
showChannelCreation &&
|
||||
(interestedInYoutubeSync ? (
|
||||
<YoutubeSync inSignUpFlow />
|
||||
) : (
|
||||
<UserFirstChannel doToggleInterestedInYoutubeSync={doToggleInterestedInYoutubeSync} />
|
||||
)),
|
||||
showFollowIntro && (
|
||||
<UserChannelFollowIntro
|
||||
onContinue={() => {
|
||||
let url = `/$/${PAGES.AUTH}?reset_scroll=1`;
|
||||
if (redirect) {
|
||||
url += `&redirect=${redirect}`;
|
||||
}
|
||||
if (shouldRedirectImmediately) {
|
||||
url += `&immediate=true`;
|
||||
if (urlParams.get('reset_scroll')) {
|
||||
urlParams.delete('reset_scroll');
|
||||
urlParams.append('reset_scroll', '2');
|
||||
}
|
||||
|
||||
history.replace(url);
|
||||
urlParams.delete(STEP_PARAM);
|
||||
|
||||
setSettingAndSync(SETTINGS.FOLLOWING_ACKNOWLEDGED, true);
|
||||
replace(`${pathname}?${urlParams.toString()}`);
|
||||
}}
|
||||
onBack={() => {
|
||||
let url = `/$/${PAGES.AUTH}?reset_scroll=1&step=tags`;
|
||||
if (redirect) {
|
||||
url += `&redirect=${redirect}`;
|
||||
}
|
||||
if (shouldRedirectImmediately) {
|
||||
url += `&immediate=true`;
|
||||
if (urlParams.get('reset_scroll')) {
|
||||
urlParams.delete('reset_scroll');
|
||||
urlParams.append('reset_scroll', '3');
|
||||
}
|
||||
|
||||
history.replace(url);
|
||||
setSettingAndSync(SETTINGS.FOLLOWING_ACKNOWLEDGED, false);
|
||||
replace(`${pathname}?${urlParams.toString()}`);
|
||||
}}
|
||||
/>
|
||||
),
|
||||
showTagsIntro && (
|
||||
<UserTagFollowIntro
|
||||
onContinue={() => {
|
||||
let url = `/$/${PAGES.AUTH}?reset_scroll=1&step=channels`;
|
||||
let url = `/$/${PAGES.AUTH}?reset_scroll=1&${STEP_PARAM}=channels`;
|
||||
if (redirect) {
|
||||
url += `&redirect=${redirect}`;
|
||||
url += `&${REDIRECT_PARAM}=${redirect}`;
|
||||
}
|
||||
if (shouldRedirectImmediately) {
|
||||
url += `&immediate=true`;
|
||||
url += `&${REDIRECT_IMMEDIATELY_PARAM}=true`;
|
||||
}
|
||||
|
||||
history.replace(url);
|
||||
replace(url);
|
||||
setSettingAndSync(SETTINGS.TAGS_ACKNOWLEDGED, true);
|
||||
}}
|
||||
/>
|
||||
|
@ -228,7 +243,7 @@ function UserSignUp(props: Props) {
|
|||
if (!initialSignInStep) {
|
||||
setInitialSignInStep(i);
|
||||
} else if (i !== initialSignInStep && i !== SIGN_IN_FLOW.length - 1) {
|
||||
history.replace(redirect);
|
||||
replace(redirect);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,7 +265,7 @@ function UserSignUp(props: Props) {
|
|||
}, [componentToRender, claimNewUserReward]);
|
||||
|
||||
if (!componentToRender) {
|
||||
history.replace(redirect || '/');
|
||||
replace(redirect || '/');
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -258,4 +273,4 @@ function UserSignUp(props: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
export default withRouter(UserSignUp);
|
||||
export default UserSignUp;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// @flow
|
||||
import { SITE_NAME } from 'config';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import * as React from 'react';
|
||||
import classnames from 'classnames';
|
||||
|
@ -168,20 +169,15 @@ export default function YoutubeTransferStatus(props: Props) {
|
|||
onClick={claimChannels}
|
||||
label={youtubeChannels.length > 1 ? __('Claim Channels') : __('Claim Channel')}
|
||||
/>
|
||||
{addNewChannel ? (
|
||||
<Button button="link" label={__('Add Another Channel')} onClick={addNewChannel} />
|
||||
) : (
|
||||
<Button button="link" label={__('Learn More')} href="https://lbry.com/faq/youtube#transfer" />
|
||||
)}
|
||||
<Button button="link" label={__('Explore %SITE_NAME%', { SITE_NAME })} navigate="/" />
|
||||
</div>
|
||||
|
||||
<p className="help">
|
||||
{youtubeChannels.length > 1
|
||||
? __('You will be able to claim your channels once they finish syncing.')
|
||||
: __('You will be able to claim your channel once it has finished syncing.')}{' '}
|
||||
{addNewChannel && (
|
||||
<Button button="link" label={__('Learn More')} href="https://lbry.com/faq/youtube#transfer" />
|
||||
)}
|
||||
<Button button="link" label={__('Learn More')} href="https://lbry.com/faq/youtube#transfer" />{' '}
|
||||
{addNewChannel && <Button button="link" label={__('Add Another Channel')} onClick={addNewChannel} />}
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ export const SET_WELCOME_VERSION = 'SET_WELCOME_VERSION';
|
|||
export const SET_ALLOW_ANALYTICS = 'SET_ALLOW_ANALYTICS';
|
||||
export const SET_HAS_NAVIGATED = 'SET_HAS_NAVIGATED';
|
||||
export const SET_SYNC_LOCK = 'SET_SYNC_LOCK';
|
||||
export const TOGGLE_YOUTUBE_SYNC_INTEREST = 'TOGGLE_YOUTUBE_SYNC_INTEREST';
|
||||
|
||||
// Navigation
|
||||
export const CHANGE_AFTER_AUTH_PATH = 'CHANGE_AFTER_AUTH_PATH';
|
||||
|
|
|
@ -21,10 +21,11 @@ const NEW_CHANNEL_PARAM = 'new_channel';
|
|||
type Props = {
|
||||
youtubeChannels: ?Array<{ transfer_state: string, sync_status: string }>,
|
||||
doUserFetch: () => void,
|
||||
inSignUpFlow?: boolean,
|
||||
};
|
||||
|
||||
export default function YoutubeSync(props: Props) {
|
||||
const { youtubeChannels, doUserFetch } = props;
|
||||
const { youtubeChannels, doUserFetch, inSignUpFlow = false } = props;
|
||||
const {
|
||||
location: { search, pathname },
|
||||
push,
|
||||
|
@ -56,7 +57,7 @@ export default function YoutubeSync(props: Props) {
|
|||
type: 'sync',
|
||||
immediate_sync: true,
|
||||
desired_lbry_channel_name: `@${channel}`,
|
||||
return_url: `https://${DOMAIN}/$/${PAGES.YOUTUBE_SYNC}`,
|
||||
return_url: `https://${DOMAIN}/$/${inSignUpFlow ? PAGES.AUTH : PAGES.YOUTUBE_SYNC}`,
|
||||
}).then(ytAuthUrl => {
|
||||
// react-router isn't needed since it's a different domain
|
||||
window.location.href = ytAuthUrl;
|
||||
|
@ -79,14 +80,24 @@ export default function YoutubeSync(props: Props) {
|
|||
setAddingNewChannel(true);
|
||||
}
|
||||
|
||||
const Wrapper = (props: { children: any }) => {
|
||||
return inSignUpFlow ? (
|
||||
<>{props.children}</>
|
||||
) : (
|
||||
<Page noSideNavigation authPage>
|
||||
{props.children}
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Page noSideNavigation authPage>
|
||||
<Wrapper>
|
||||
<div className="main__channel-creation">
|
||||
{hasYoutubeChannels && !addingNewChannel ? (
|
||||
<YoutubeTransferStatus alwaysShow addNewChannel={handleNewChannel} />
|
||||
) : (
|
||||
<Card
|
||||
title={__('Connect with your fans while earning rewards')}
|
||||
title={__('Sync your YouTube channel to %site_name%', { site_name: IS_WEB ? SITE_NAME : 'LBRY' })}
|
||||
subtitle={__('Get your YouTube videos in front of the %site_name% audience.', {
|
||||
site_name: IS_WEB ? SITE_NAME : 'LBRY',
|
||||
})}
|
||||
|
@ -95,7 +106,11 @@ export default function YoutubeSync(props: Props) {
|
|||
<fieldset-group class="fieldset-group--smushed fieldset-group--disabled-prefix">
|
||||
<fieldset-section>
|
||||
<label htmlFor="auth_first_channel">
|
||||
{nameError ? <span className="error__text">{nameError}</span> : __('Your Channel')}
|
||||
{nameError ? (
|
||||
<span className="error__text">{nameError}</span>
|
||||
) : (
|
||||
__('Your %site_name% channel name', { site_name: IS_WEB ? SITE_NAME : 'LBRY' })
|
||||
)}
|
||||
</label>
|
||||
<div className="form-field__prefix">@</div>
|
||||
</fieldset-section>
|
||||
|
@ -128,10 +143,11 @@ export default function YoutubeSync(props: Props) {
|
|||
href="https://lbry.com/faq/youtube"
|
||||
/>
|
||||
),
|
||||
site_name: SITE_NAME,
|
||||
}}
|
||||
>
|
||||
I want to sync my content to the LBRY network and agree to %terms%. I have also read and
|
||||
understand %faq%.
|
||||
I want to sync my content to %site_name% and the LBRY network and agree to %terms%. I have also
|
||||
read and understand %faq%.
|
||||
</I18nMessage>
|
||||
}
|
||||
/>
|
||||
|
@ -163,6 +179,6 @@ export default function YoutubeSync(props: Props) {
|
|||
/>
|
||||
)}
|
||||
</div>
|
||||
</Page>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -667,3 +667,9 @@ export function doHandleSyncComplete(error, hasNewData) {
|
|||
export function doSyncWithPreferences() {
|
||||
return dispatch => dispatch(doSyncSubscribe());
|
||||
}
|
||||
|
||||
export function doToggleInterestedInYoutubeSync() {
|
||||
return {
|
||||
type: ACTIONS.TOGGLE_YOUTUBE_SYNC_INTEREST,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ export type AppState = {
|
|||
allowAnalytics: boolean,
|
||||
hasNavigated: boolean,
|
||||
syncLocked: boolean,
|
||||
interestedInYoutubeSync: boolean,
|
||||
};
|
||||
|
||||
const defaultState: AppState = {
|
||||
|
@ -78,6 +79,7 @@ const defaultState: AppState = {
|
|||
allowAnalytics: false,
|
||||
hasNavigated: false,
|
||||
syncLocked: false,
|
||||
interestedInYoutubeSync: false,
|
||||
};
|
||||
|
||||
// @@router comes from react-router
|
||||
|
@ -289,6 +291,13 @@ reducers[ACTIONS.TOGGLE_SEARCH_EXPANDED] = state =>
|
|||
searchOptionsExpanded: !state.searchOptionsExpanded,
|
||||
});
|
||||
|
||||
reducers[ACTIONS.TOGGLE_YOUTUBE_SYNC_INTEREST] = (state, action) => {
|
||||
return {
|
||||
...state,
|
||||
interestedInYoutubeSync: !state.interestedInYoutubeSync,
|
||||
};
|
||||
};
|
||||
|
||||
reducers[LBRY_REDUX_ACTIONS.USER_STATE_POPULATE] = (state, action) => {
|
||||
const { welcomeVersion, allowAnalytics } = action.data;
|
||||
return {
|
||||
|
|
|
@ -82,3 +82,5 @@ export const selectScrollStartingPosition = createSelector(selectState, state =>
|
|||
export const selectIsPasswordSaved = createSelector(selectState, state => state.isPasswordSaved);
|
||||
|
||||
export const selectSyncIsLocked = createSelector(selectState, state => state.syncLocked);
|
||||
|
||||
export const selectInterestedInYoutubeSync = createSelector(selectState, state => state.interestedInYoutubeSync);
|
||||
|
|
|
@ -56,6 +56,7 @@ const appFilter = createFilter('app', [
|
|||
'muted',
|
||||
'allowAnalytics',
|
||||
'welcomeVersion',
|
||||
'interestedInYoutubeSync',
|
||||
]);
|
||||
// We only need to persist the receiveAddress for the wallet
|
||||
const walletFilter = createFilter('wallet', ['receiveAddress']);
|
||||
|
|
Loading…
Add table
Reference in a new issue