lbry-desktop/ui/page/youtubeSync/view.jsx

221 lines
8.1 KiB
JavaScript

// @flow
import { SITE_NAME, DOMAIN } from 'config';
import * as PAGES from 'constants/pages';
import SUPPORTED_LANGUAGES from 'constants/supported_languages';
import React from 'react';
import Page from 'component/page';
import Button from 'component/button';
import Card from 'component/common/card';
import I18nMessage from 'component/i18nMessage';
import { Form, FormField } from 'component/common/form';
import { INVALID_NAME_ERROR } from 'constants/claim';
import { isNameValid } from 'util/lbryURI';
import { Lbryio } from 'lbryinc';
import { useHistory } from 'react-router';
import YoutubeTransferStatus from 'component/youtubeTransferStatus';
import Nag from 'component/common/nag';
import { getDefaultLanguage, sortLanguageMap } from 'util/default-languages';
const STATUS_TOKEN_PARAM = 'status_token';
const ERROR_MESSAGE_PARAM = 'error_message';
const NEW_CHANNEL_PARAM = 'new_channel';
type Props = {
youtubeChannels: ?Array<{ transfer_state: string, sync_status: string }>,
doUserFetch: () => void,
inSignUpFlow?: boolean,
doToggleInterestedInYoutubeSync: () => void,
};
export default function YoutubeSync(props: Props) {
const { youtubeChannels, doUserFetch, inSignUpFlow = false, doToggleInterestedInYoutubeSync } = props;
const {
location: { search, pathname },
push,
replace,
} = useHistory();
const urlParams = new URLSearchParams(search);
const statusToken = urlParams.get(STATUS_TOKEN_PARAM);
const errorMessage = urlParams.get(ERROR_MESSAGE_PARAM);
const newChannelParam = urlParams.get(NEW_CHANNEL_PARAM);
const [channel, setChannel] = React.useState('');
const [language, setLanguage] = React.useState(getDefaultLanguage());
const [nameError, setNameError] = React.useState(undefined);
const [acknowledgedTerms, setAcknowledgedTerms] = React.useState(false);
const [addingNewChannel, setAddingNewChannel] = React.useState(newChannelParam);
const hasYoutubeChannels = youtubeChannels && youtubeChannels.length > 0;
React.useEffect(() => {
const urlParamsInEffect = new URLSearchParams(search);
if (!urlParamsInEffect.get('reset_scroll')) {
urlParamsInEffect.append('reset_scroll', 'youtube');
}
replace(`?${urlParamsInEffect.toString()}`);
}, [pathname, search]);
React.useEffect(() => {
if (statusToken && !hasYoutubeChannels) {
doUserFetch();
}
}, [statusToken, hasYoutubeChannels, doUserFetch]);
React.useEffect(() => {
if (!newChannelParam) {
setAddingNewChannel(false);
}
}, [newChannelParam]);
function handleCreateChannel() {
Lbryio.call('yt', 'new', {
type: 'sync',
immediate_sync: true,
channel_language: language,
desired_lbry_channel_name: `@${channel}`,
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;
});
}
function handleChannelChange(e) {
const { value } = e.target;
setChannel(value);
if (!isNameValid(value)) {
setNameError(INVALID_NAME_ERROR);
} else {
setNameError();
}
}
function handleNewChannel() {
urlParams.append('new_channel', 'true');
push(`${pathname}?${urlParams.toString()}`);
setAddingNewChannel(true);
}
const Wrapper = (props: { children: any }) => {
return inSignUpFlow ? (
<>{props.children}</>
) : (
<Page noSideNavigation authPage>
{props.children}
</Page>
);
};
return (
<Wrapper>
<div className="main__channel-creation">
{hasYoutubeChannels && !addingNewChannel ? (
<YoutubeTransferStatus alwaysShow addNewChannel={handleNewChannel} />
) : (
<Card
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',
})}
actions={
<Form onSubmit={handleCreateChannel}>
<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 %site_name% desired channel name', { site_name: IS_WEB ? SITE_NAME : 'LBRY' })
)}
</label>
<div className="form-field__prefix">@</div>
</fieldset-section>
<FormField
autoFocus
placeholder={__('channel')}
type="text"
name="yt_sync_channel"
className="form-field--short"
value={channel}
onChange={handleChannelChange}
/>
</fieldset-group>
<FormField
name="language_select"
type="select"
label={__('Channel language')}
onChange={(event) => setLanguage(event.target.value)}
value={language}
>
{sortLanguageMap(SUPPORTED_LANGUAGES).map(([langKey, langName]) => (
<option key={langKey} value={langKey}>
{langName}
</option>
))}
</FormField>
<FormField
type="checkbox"
name="yt_sync_terms"
checked={acknowledgedTerms}
onChange={() => setAcknowledgedTerms(!acknowledgedTerms)}
label={
<I18nMessage
tokens={{
terms: (
<Button button="link" label={__('these terms')} href="https://odysee.com/$/youtubetos" />
),
faq: (
<Button
button="link"
label={__('how the program works')}
href="https://odysee.com/@OdyseeHelp:b/youtube-sync:b"
/>
),
site_name: SITE_NAME,
}}
>
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>
}
/>
<div className="section__actions">
<Button
button="primary"
type="submit"
disabled={nameError || !channel || !acknowledgedTerms}
label={__('Claim Now')}
/>
{inSignUpFlow && !errorMessage && (
<Button button="link" label={__('Skip')} onClick={() => doToggleInterestedInYoutubeSync()} />
)}
{errorMessage && <Button button="link" label={__('Skip')} navigate={`/$/${PAGES.REWARDS}`} />}
</div>
<div className="help--card-actions">
<I18nMessage
tokens={{
learn_more: (
<Button
button="link"
label={__('Learn more')}
href="https://odysee.com/@OdyseeHelp:b/youtube-sync:b"
/>
),
}}
>
This will verify you are an active YouTuber with over 300 subscribers and original content. Channel
names cannot be changed once chosen, please be extra careful. %learn_more%.
</I18nMessage>
</div>
</Form>
}
nag={errorMessage && <Nag message={errorMessage} type="error" relative />}
/>
)}
</div>
</Wrapper>
);
}