change: less intrusive first run experience
This commit is contained in:
parent
1f74ff3c63
commit
defc08eccb
24 changed files with 449 additions and 191 deletions
|
@ -67,6 +67,7 @@
|
||||||
"react-feather": "^1.0.8",
|
"react-feather": "^1.0.8",
|
||||||
"react-modal": "^3.1.7",
|
"react-modal": "^3.1.7",
|
||||||
"react-paginate": "^5.2.1",
|
"react-paginate": "^5.2.1",
|
||||||
|
"react-pose": "^4.0.5",
|
||||||
"react-redux": "^5.0.3",
|
"react-redux": "^5.0.3",
|
||||||
"react-simplemde-editor": "^3.6.16",
|
"react-simplemde-editor": "^3.6.16",
|
||||||
"react-toggle": "^4.0.2",
|
"react-toggle": "^4.0.2",
|
||||||
|
|
29
src/renderer/component/emailCollection/index.js
Normal file
29
src/renderer/component/emailCollection/index.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import * as SETTINGS from 'constants/settings';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { doSetClientSetting } from 'redux/actions/settings';
|
||||||
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
|
import { selectEmailToVerify, selectUser } from 'lbryinc';
|
||||||
|
import FirstRunEmailCollection from './view';
|
||||||
|
|
||||||
|
const select = state => ({
|
||||||
|
emailCollectionAcknowledged: makeSelectClientSetting(SETTINGS.EMAIL_COLLECTION_ACKNOWLEDGED)(
|
||||||
|
state
|
||||||
|
),
|
||||||
|
email: selectEmailToVerify(state),
|
||||||
|
user: selectUser(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
const perform = dispatch => () => ({
|
||||||
|
completeFirstRun: () => {
|
||||||
|
dispatch(doSetClientSetting(SETTINGS.EMAIL_COLLECTION_ACKNOWLEDGED, true));
|
||||||
|
dispatch(doSetClientSetting(SETTINGS.FIRST_RUN_COMPLETED, true));
|
||||||
|
},
|
||||||
|
acknowledgeEmail: () => {
|
||||||
|
dispatch(doSetClientSetting(SETTINGS.EMAIL_COLLECTION_ACKNOWLEDGED, true));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(FirstRunEmailCollection);
|
46
src/renderer/component/emailCollection/view.jsx
Normal file
46
src/renderer/component/emailCollection/view.jsx
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// @flow
|
||||||
|
import React from 'react';
|
||||||
|
import Button from 'component/button';
|
||||||
|
import UserEmailNew from 'component/userEmailNew';
|
||||||
|
import UserEmailVerify from 'component/userEmailVerify';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
email: string,
|
||||||
|
emailCollectionAcknowledged: boolean,
|
||||||
|
user: ?{ has_verified_email: boolean },
|
||||||
|
completeFirstRun: () => void,
|
||||||
|
acknowledgeEmail: () => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
class FirstRunEmailCollection extends React.PureComponent<Props> {
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
completeFirstRun,
|
||||||
|
email,
|
||||||
|
user,
|
||||||
|
emailCollectionAcknowledged,
|
||||||
|
acknowledgeEmail,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
// this shouldn't happen
|
||||||
|
if (!user) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cancelButton = <Button button="link" onClick={completeFirstRun} label={__('Not Now')} />;
|
||||||
|
if (user && !user.has_verified_email && !email) {
|
||||||
|
return <UserEmailNew cancelButton={cancelButton} />;
|
||||||
|
} else if (user && !user.has_verified_email) {
|
||||||
|
return <UserEmailVerify cancelButton={cancelButton} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to acknowledge here so users don't see an empty email screen in the first run banner
|
||||||
|
if (!emailCollectionAcknowledged) {
|
||||||
|
acknowledgeEmail();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FirstRunEmailCollection;
|
29
src/renderer/component/firstRun/index.js
Normal file
29
src/renderer/component/firstRun/index.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import * as SETTINGS from 'constants/settings';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { selectUser } from 'lbryinc';
|
||||||
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
|
import { doSetClientSetting } from 'redux/actions/settings';
|
||||||
|
import FirstRun from './view';
|
||||||
|
|
||||||
|
const select = state => ({
|
||||||
|
emailCollectionAcknowledged: makeSelectClientSetting(SETTINGS.EMAIL_COLLECTION_ACKNOWLEDGED)(
|
||||||
|
state
|
||||||
|
),
|
||||||
|
welcomeAcknowledged: makeSelectClientSetting(SETTINGS.NEW_USER_ACKNOWLEDGED)(state),
|
||||||
|
firstRunComplete: makeSelectClientSetting(SETTINGS.FIRST_RUN_COMPLETED)(state),
|
||||||
|
user: selectUser(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
const perform = dispatch => ({
|
||||||
|
acknowledgeWelcome: () => {
|
||||||
|
dispatch(doSetClientSetting(SETTINGS.NEW_USER_ACKNOWLEDGED, true));
|
||||||
|
},
|
||||||
|
completeFirstRun: () => {
|
||||||
|
dispatch(doSetClientSetting(SETTINGS.FIRST_RUN_COMPLETED, true));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(FirstRun);
|
115
src/renderer/component/firstRun/view.jsx
Normal file
115
src/renderer/component/firstRun/view.jsx
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
// @flow
|
||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import posed from 'react-pose';
|
||||||
|
import Button from 'component/button';
|
||||||
|
import EmailCollection from 'component/emailCollection';
|
||||||
|
import Native from 'native';
|
||||||
|
|
||||||
|
//
|
||||||
|
// Animation for items inside banner
|
||||||
|
// The height for items must be static (in banner.scss) so that we can reliably animate into the banner and be vertically centered
|
||||||
|
//
|
||||||
|
const spring = {
|
||||||
|
type: 'spring',
|
||||||
|
stiffness: 100,
|
||||||
|
damping: 10,
|
||||||
|
mass: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Welcome = posed.div({
|
||||||
|
hide: { opacity: 0, y: '310px', ...spring },
|
||||||
|
show: { opacity: 1, ...spring },
|
||||||
|
});
|
||||||
|
|
||||||
|
const Email = posed.div({
|
||||||
|
hide: { opacity: 0, y: '0', ...spring },
|
||||||
|
show: { opacity: 1, y: '-310px', ...spring, delay: 175 },
|
||||||
|
});
|
||||||
|
|
||||||
|
const Help = posed.div({
|
||||||
|
hide: { opacity: 0, y: '0', ...spring },
|
||||||
|
show: { opacity: 1, y: '-620px', ...spring, delay: 175 },
|
||||||
|
});
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
welcomeAcknowledged: boolean,
|
||||||
|
emailCollectionAcknowledged: boolean,
|
||||||
|
firstRunComplete: boolean,
|
||||||
|
acknowledgeWelcome: () => void,
|
||||||
|
completeFirstRun: () => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class FirstRun extends PureComponent<Props> {
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
welcomeAcknowledged,
|
||||||
|
emailCollectionAcknowledged,
|
||||||
|
firstRunComplete,
|
||||||
|
acknowledgeWelcome,
|
||||||
|
completeFirstRun,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
if (firstRunComplete) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const showWelcome = !welcomeAcknowledged;
|
||||||
|
const showEmail = !emailCollectionAcknowledged && welcomeAcknowledged;
|
||||||
|
const showHelp = !showWelcome && !showEmail;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="banner banner--first-run">
|
||||||
|
<img
|
||||||
|
alt="Friendly gerbil"
|
||||||
|
className="yrbl--first-run banner__item"
|
||||||
|
src={Native.imagePath('gerbil-happy.png')}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="banner__item">
|
||||||
|
<div className="banner__item--static-for-animation">
|
||||||
|
<Welcome className="banner__content" pose={showWelcome ? 'show' : 'hide'}>
|
||||||
|
<div>
|
||||||
|
<header className="card__header">
|
||||||
|
<h1 className="card__title">{__('Hi There')}</h1>
|
||||||
|
</header>
|
||||||
|
<div className="card__content">
|
||||||
|
<p>
|
||||||
|
{__('Using LBRY is like dating a centaur. Totally normal up top, and')}{' '}
|
||||||
|
<em>{__('way different')}</em> {__('underneath.')}
|
||||||
|
</p>
|
||||||
|
<p>{__('Up top, LBRY is similar to popular media sites.')}</p>
|
||||||
|
<p>
|
||||||
|
{__(
|
||||||
|
'Below, LBRY is controlled by users -- you -- via blockchain and decentralization.'
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<div className="card__actions">
|
||||||
|
<Button button="primary" onClick={acknowledgeWelcome} label={__("I'm In")} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Welcome>
|
||||||
|
</div>
|
||||||
|
<div className="banner__item--static-for-animation">
|
||||||
|
<Email pose={showEmail ? 'show' : 'hide'}>
|
||||||
|
<EmailCollection />
|
||||||
|
</Email>
|
||||||
|
</div>
|
||||||
|
<div className="banner__item--static-for-animation">
|
||||||
|
<Help pose={showHelp ? 'show' : 'hide'}>
|
||||||
|
<header className="card__header">
|
||||||
|
<h1 className="card__title">{__('You Are Awesome!')}</h1>
|
||||||
|
</header>
|
||||||
|
<div className="card__content">
|
||||||
|
<p>{__("Check out some of the neat files below me. I'll see you around!")}</p>
|
||||||
|
<div className="card__actions">
|
||||||
|
<Button button="primary" onClick={completeFirstRun} label={__('See You Later')} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,7 +61,7 @@ class SocialShare extends React.PureComponent<Props> {
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
<label className="card__subtitle">{__('Web link')}</label>
|
<label className="card__subtitle">{__('Web link')}</label>
|
||||||
<CopyableText copyable={speechURL} />
|
<CopyableText copyable={speechURL} />
|
||||||
<div className="card__actions card__actions--center card__actions--top-space">
|
<div className="card__actions card__actions--center">
|
||||||
<ToolTip onComponent body={__('Facebook')}>
|
<ToolTip onComponent body={__('Facebook')}>
|
||||||
<Button
|
<Button
|
||||||
iconColor="blue"
|
iconColor="blue"
|
||||||
|
@ -95,7 +95,7 @@ class SocialShare extends React.PureComponent<Props> {
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
<label className="card__subtitle">{__('LBRY App link')}</label>
|
<label className="card__subtitle">{__('LBRY App link')}</label>
|
||||||
<CopyableText copyable={lbryURL} noSnackbar />
|
<CopyableText copyable={lbryURL} noSnackbar />
|
||||||
<div className="card__actions card__actions--center card__actions--top-space">
|
<div className="card__actions card__actions--center">
|
||||||
<ToolTip onComponent body={__('Facebook')}>
|
<ToolTip onComponent body={__('Facebook')}>
|
||||||
<Button
|
<Button
|
||||||
iconColor="blue"
|
iconColor="blue"
|
||||||
|
|
|
@ -42,16 +42,14 @@ class UserEmailNew extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<p>
|
<header className="card__header">
|
||||||
|
<h2 className="card__title">{__("Don't Miss Out")}</h2>
|
||||||
|
<p className="card__subtitle">
|
||||||
{__("We'll let you know about LBRY updates, security issues, and great new content.")}
|
{__("We'll let you know about LBRY updates, security issues, and great new content.")}
|
||||||
</p>
|
</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
<p>
|
<Form className="card__content" onSubmit={this.handleSubmit}>
|
||||||
{__(
|
|
||||||
'In addition, your email address will never be sold and you can unsubscribe at any time.'
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<Form onSubmit={this.handleSubmit}>
|
|
||||||
<FormRow>
|
<FormRow>
|
||||||
<FormField
|
<FormField
|
||||||
stretch
|
stretch
|
||||||
|
@ -66,10 +64,13 @@ class UserEmailNew extends React.PureComponent<Props, State> {
|
||||||
</FormRow>
|
</FormRow>
|
||||||
|
|
||||||
<div className="card__actions">
|
<div className="card__actions">
|
||||||
<Submit label="Submit" disabled={isPending} />
|
<Submit label="Submit" disabled={isPending || !this.state.email} />
|
||||||
{cancelButton}
|
{cancelButton}
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
|
<p className="help">
|
||||||
|
{__('Your email address will never be sold and you can unsubscribe at any time.')}
|
||||||
|
</p>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,12 @@ class UserEmailVerify extends React.PureComponent<Props> {
|
||||||
const { cancelButton, email } = this.props;
|
const { cancelButton, email } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<React.Fragment>
|
||||||
|
<header className="card__header">
|
||||||
|
<h2 className="card__title">{__('Waiting For Verification')}</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div className="card__content">
|
||||||
<p>
|
<p>
|
||||||
{__('An email was sent to')} {email}.{' '}
|
{__('An email was sent to')} {email}.{' '}
|
||||||
{__('Follow the link and you will be good to go. This will update automatically.')}
|
{__('Follow the link and you will be good to go. This will update automatically.')}
|
||||||
|
@ -66,11 +71,12 @@ class UserEmailVerify extends React.PureComponent<Props> {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="help">
|
<p className="help">
|
||||||
{__('Email')} <Button button="link" href="mailto:help@lbry.io" label="help@lbry.io" /> or
|
{__('Email')} <Button button="link" href="mailto:help@lbry.io" label="help@lbry.io" />{' '}
|
||||||
join our <Button button="link" href="https://chat.lbry.io" label="chat" />{' '}
|
or join our <Button button="link" href="https://chat.lbry.io" label="chat" />{' '}
|
||||||
{__('if you encounter any trouble verifying.')}
|
{__('if you encounter any trouble verifying.')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
export const CREDIT_REQUIRED_ACKNOWLEDGED = 'credit_required_acknowledged';
|
export const CREDIT_REQUIRED_ACKNOWLEDGED = 'credit_required_acknowledged';
|
||||||
export const NEW_USER_ACKNOWLEDGED = 'welcome_acknowledged';
|
export const NEW_USER_ACKNOWLEDGED = 'welcome_acknowledged';
|
||||||
export const EMAIL_COLLECTION_ACKNOWLEDGED = 'email_collection_acknowledged';
|
export const EMAIL_COLLECTION_ACKNOWLEDGED = 'email_collection_acknowledged';
|
||||||
|
export const FIRST_RUN_COMPLETED = 'first_run_completed';
|
||||||
export const LANGUAGE = 'language';
|
export const LANGUAGE = 'language';
|
||||||
export const SHOW_NSFW = 'showNsfw';
|
export const SHOW_NSFW = 'showNsfw';
|
||||||
export const SHOW_UNAVAILABLE = 'showUnavailable';
|
export const SHOW_UNAVAILABLE = 'showUnavailable';
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
import * as settings from 'constants/settings';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { doHideModal } from 'redux/actions/app';
|
|
||||||
import { doSetClientSetting } from 'redux/actions/settings';
|
|
||||||
import { selectEmailToVerify, selectUser } from 'lbryinc';
|
|
||||||
import ModalEmailCollection from './view';
|
|
||||||
|
|
||||||
const select = state => ({
|
|
||||||
email: selectEmailToVerify(state),
|
|
||||||
user: selectUser(state),
|
|
||||||
});
|
|
||||||
|
|
||||||
const perform = dispatch => () => ({
|
|
||||||
closeModal: () => {
|
|
||||||
dispatch(doSetClientSetting(settings.EMAIL_COLLECTION_ACKNOWLEDGED, true));
|
|
||||||
dispatch(doHideModal());
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(
|
|
||||||
select,
|
|
||||||
perform
|
|
||||||
)(ModalEmailCollection);
|
|
|
@ -1,54 +0,0 @@
|
||||||
// @flow
|
|
||||||
import React from 'react';
|
|
||||||
import { Modal } from 'modal/modal';
|
|
||||||
import Button from 'component/button';
|
|
||||||
import UserEmailNew from 'component/userEmailNew';
|
|
||||||
import UserEmailVerify from 'component/userEmailVerify';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
closeModal: () => void,
|
|
||||||
email: string,
|
|
||||||
user: ?{ has_verified_email: boolean },
|
|
||||||
};
|
|
||||||
|
|
||||||
class ModalEmailCollection extends React.PureComponent<Props> {
|
|
||||||
getTitle() {
|
|
||||||
// const { user } = this.props;
|
|
||||||
//
|
|
||||||
// if (user && user.email && !user.has_verified_email) {
|
|
||||||
// return __('Awaiting Confirmation');
|
|
||||||
// }
|
|
||||||
|
|
||||||
return __('Can We Stay In Touch?');
|
|
||||||
}
|
|
||||||
|
|
||||||
renderInner() {
|
|
||||||
const { closeModal, email, user } = this.props;
|
|
||||||
|
|
||||||
const cancelButton = <Button button="link" onClick={closeModal} label={__('Not Now')} />;
|
|
||||||
if (user && !user.has_verified_email && !email) {
|
|
||||||
return <UserEmailNew cancelButton={cancelButton} />;
|
|
||||||
} else if (user && !user.has_verified_email) {
|
|
||||||
return <UserEmailVerify onModal cancelButton={cancelButton} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return closeModal();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { user } = this.props;
|
|
||||||
|
|
||||||
// this shouldn't happen
|
|
||||||
if (!user) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal type="custom" isOpen contentLabel="Email" title={this.getTitle()}>
|
|
||||||
<section className="card__content">{this.renderInner()}</section>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ModalEmailCollection;
|
|
|
@ -16,7 +16,6 @@ import ModalTransactionFailed from 'modal/modalTransactionFailed';
|
||||||
import ModalFileTimeout from 'modal/modalFileTimeout';
|
import ModalFileTimeout from 'modal/modalFileTimeout';
|
||||||
import ModalAffirmPurchase from 'modal/modalAffirmPurchase';
|
import ModalAffirmPurchase from 'modal/modalAffirmPurchase';
|
||||||
import ModalRevokeClaim from 'modal/modalRevokeClaim';
|
import ModalRevokeClaim from 'modal/modalRevokeClaim';
|
||||||
import ModalEmailCollection from 'modal/modalEmailCollection';
|
|
||||||
import ModalPhoneCollection from 'modal/modalPhoneCollection';
|
import ModalPhoneCollection from 'modal/modalPhoneCollection';
|
||||||
import ModalFirstSubscription from 'modal/modalFirstSubscription';
|
import ModalFirstSubscription from 'modal/modalFirstSubscription';
|
||||||
import ModalConfirmTransaction from 'modal/modalConfirmTransaction';
|
import ModalConfirmTransaction from 'modal/modalConfirmTransaction';
|
||||||
|
@ -78,11 +77,10 @@ class ModalRouter extends React.PureComponent<Props, State> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const transitionModal = [
|
const transitionModal = [this.checkShowCreditIntro].reduce(
|
||||||
this.checkShowWelcome,
|
(acc, func) => (!acc ? func.bind(this)(props) : acc),
|
||||||
this.checkShowEmail,
|
false
|
||||||
this.checkShowCreditIntro,
|
);
|
||||||
].reduce((acc, func) => (!acc ? func.bind(this)(props) : acc), false);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
transitionModal &&
|
transitionModal &&
|
||||||
|
@ -96,30 +94,6 @@ class ModalRouter extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkShowWelcome(props: Props) {
|
|
||||||
const { isWelcomeAcknowledged, user } = props;
|
|
||||||
|
|
||||||
if (!isWelcomeAcknowledged && user && !user.is_reward_approved && !user.is_identity_verified) {
|
|
||||||
return MODALS.WELCOME;
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkShowEmail(props: Props) {
|
|
||||||
const { isEmailCollectionAcknowledged, isVerificationCandidate, user } = props;
|
|
||||||
if (
|
|
||||||
!isEmailCollectionAcknowledged &&
|
|
||||||
isVerificationCandidate &&
|
|
||||||
user &&
|
|
||||||
!user.has_verified_email
|
|
||||||
) {
|
|
||||||
return MODALS.EMAIL_COLLECTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkShowCreditIntro(props: Props) {
|
checkShowCreditIntro(props: Props) {
|
||||||
const { balance, page, isCreditIntroAcknowledged } = props;
|
const { balance, page, isCreditIntroAcknowledged } = props;
|
||||||
|
|
||||||
|
@ -185,8 +159,6 @@ class ModalRouter extends React.PureComponent<Props, State> {
|
||||||
return <ModalRevokeClaim {...modalProps} />;
|
return <ModalRevokeClaim {...modalProps} />;
|
||||||
case MODALS.PHONE_COLLECTION:
|
case MODALS.PHONE_COLLECTION:
|
||||||
return <ModalPhoneCollection {...modalProps} />;
|
return <ModalPhoneCollection {...modalProps} />;
|
||||||
case MODALS.EMAIL_COLLECTION:
|
|
||||||
return <ModalEmailCollection {...modalProps} />;
|
|
||||||
case MODALS.FIRST_SUBSCRIPTION:
|
case MODALS.FIRST_SUBSCRIPTION:
|
||||||
return <ModalFirstSubscription {...modalProps} />;
|
return <ModalFirstSubscription {...modalProps} />;
|
||||||
case MODALS.SEND_TIP:
|
case MODALS.SEND_TIP:
|
||||||
|
|
|
@ -30,19 +30,6 @@ class AuthPage extends React.PureComponent<Props> {
|
||||||
this.navigateIfAuthenticated(nextProps);
|
this.navigateIfAuthenticated(nextProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTitle() {
|
|
||||||
const { email, isPending, user } = this.props;
|
|
||||||
|
|
||||||
if (isPending || (user && !user.has_verified_email && !email)) {
|
|
||||||
return __('Human Proofing');
|
|
||||||
} else if (user && !user.has_verified_email) {
|
|
||||||
return __('Awaiting Confirmation');
|
|
||||||
} else if (user && !user.is_identity_verified && !user.is_reward_approved) {
|
|
||||||
return __('Final Verification');
|
|
||||||
}
|
|
||||||
return __('Welcome to LBRY');
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateIfAuthenticated = (props: Props) => {
|
navigateIfAuthenticated = (props: Props) => {
|
||||||
const { isPending, user, pathAfterAuth, navigate } = props;
|
const { isPending, user, pathAfterAuth, navigate } = props;
|
||||||
if (
|
if (
|
||||||
|
@ -78,11 +65,6 @@ class AuthPage extends React.PureComponent<Props> {
|
||||||
<Page>
|
<Page>
|
||||||
{useTemplate ? (
|
{useTemplate ? (
|
||||||
<section className="card card--section">
|
<section className="card card--section">
|
||||||
<header className="card__header card__header--flat">
|
|
||||||
<h2 className="card__title">{this.getTitle()}</h2>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div className="card__content">
|
|
||||||
{innerContent}
|
{innerContent}
|
||||||
|
|
||||||
<p className="help">
|
<p className="help">
|
||||||
|
@ -95,7 +77,6 @@ class AuthPage extends React.PureComponent<Props> {
|
||||||
label={__('Return home.')}
|
label={__('Return home.')}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
) : (
|
) : (
|
||||||
innerContent
|
innerContent
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import CategoryList from 'component/categoryList';
|
import CategoryList from 'component/categoryList';
|
||||||
|
import FirstRun from 'component/firstRun';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
fetchFeaturedUris: () => void,
|
fetchFeaturedUris: () => void,
|
||||||
fetchRewardedContent: () => void,
|
fetchRewardedContent: () => void,
|
||||||
|
fetchRewards: () => void,
|
||||||
fetchingFeaturedUris: boolean,
|
fetchingFeaturedUris: boolean,
|
||||||
featuredUris: {},
|
featuredUris: {},
|
||||||
};
|
};
|
||||||
|
@ -59,6 +61,7 @@ class DiscoverPage extends React.PureComponent<Props> {
|
||||||
const failedToLoad = !fetchingFeaturedUris && !hasContent;
|
const failedToLoad = !fetchingFeaturedUris && !hasContent;
|
||||||
return (
|
return (
|
||||||
<Page noPadding isLoading={!hasContent && fetchingFeaturedUris}>
|
<Page noPadding isLoading={!hasContent && fetchingFeaturedUris}>
|
||||||
|
<FirstRun />
|
||||||
{hasContent &&
|
{hasContent &&
|
||||||
Object.keys(featuredUris).map(
|
Object.keys(featuredUris).map(
|
||||||
category =>
|
category =>
|
||||||
|
|
|
@ -10,24 +10,34 @@ function getLocalStorageSetting(setting, fallback) {
|
||||||
const reducers = {};
|
const reducers = {};
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
clientSettings: {
|
clientSettings: {
|
||||||
instantPurchaseEnabled: getLocalStorageSetting(SETTINGS.INSTANT_PURCHASE_ENABLED, false),
|
[SETTINGS.INSTANT_PURCHASE_ENABLED]: getLocalStorageSetting(
|
||||||
instantPurchaseMax: getLocalStorageSetting(SETTINGS.INSTANT_PURCHASE_MAX, {
|
SETTINGS.INSTANT_PURCHASE_ENABLED,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
[SETTINGS.INSTANT_PURCHASE_MAX]: getLocalStorageSetting(SETTINGS.INSTANT_PURCHASE_MAX, {
|
||||||
currency: 'LBC',
|
currency: 'LBC',
|
||||||
amount: 0.1,
|
amount: 0.1,
|
||||||
}),
|
}),
|
||||||
showNsfw: getLocalStorageSetting(SETTINGS.SHOW_NSFW, false),
|
[SETTINGS.SHOW_NSFW]: getLocalStorageSetting(SETTINGS.SHOW_NSFW, false),
|
||||||
showUnavailable: getLocalStorageSetting(SETTINGS.SHOW_UNAVAILABLE, true),
|
[SETTINGS.SHOW_UNAVAILABLE]: getLocalStorageSetting(SETTINGS.SHOW_UNAVAILABLE, true),
|
||||||
welcome_acknowledged: getLocalStorageSetting(SETTINGS.NEW_USER_ACKNOWLEDGED, false),
|
[SETTINGS.NEW_USER_ACKNOWLEDGED]: getLocalStorageSetting(SETTINGS.NEW_USER_ACKNOWLEDGED, false),
|
||||||
email_collection_acknowledged: getLocalStorageSetting(SETTINGS.EMAIL_COLLECTION_ACKNOWLEDGED),
|
[SETTINGS.EMAIL_COLLECTION_ACKNOWLEDGED]: getLocalStorageSetting(
|
||||||
credit_required_acknowledged: false, // this needs to be re-acknowledged every run
|
SETTINGS.EMAIL_COLLECTION_ACKNOWLEDGED,
|
||||||
language: getLocalStorageSetting(SETTINGS.LANGUAGE, 'en'),
|
false
|
||||||
theme: getLocalStorageSetting(SETTINGS.THEME, 'light'),
|
),
|
||||||
themes: getLocalStorageSetting(SETTINGS.THEMES, []),
|
[SETTINGS.FIRST_RUN_COMPLETED]: getLocalStorageSetting(SETTINGS.FIRST_RUN_COMPLETED, false),
|
||||||
automaticDarkModeEnabled: getLocalStorageSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, false),
|
[SETTINGS.CREDIT_REQUIRED_ACKNOWLEDGED]: false, // this needs to be re-acknowledged every run
|
||||||
autoplay: getLocalStorageSetting(SETTINGS.AUTOPLAY, false),
|
[SETTINGS.LANGUAGE]: getLocalStorageSetting(SETTINGS.LANGUAGE, 'en'),
|
||||||
resultCount: Number(getLocalStorageSetting(SETTINGS.RESULT_COUNT, 50)),
|
[SETTINGS.THEME]: getLocalStorageSetting(SETTINGS.THEME, 'dark'),
|
||||||
autoDownload: getLocalStorageSetting(SETTINGS.AUTO_DOWNLOAD, true),
|
[SETTINGS.THEMES]: getLocalStorageSetting(SETTINGS.THEMES, []),
|
||||||
osNotificationsEnabled: Boolean(
|
[SETTINGS.AUTOMATIC_DARK_MODE_ENABLED]: getLocalStorageSetting(
|
||||||
|
SETTINGS.AUTOMATIC_DARK_MODE_ENABLED,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
[SETTINGS.AUTOPLAY]: getLocalStorageSetting(SETTINGS.AUTOPLAY, false),
|
||||||
|
[SETTINGS.RESULT_COUNT]: Number(getLocalStorageSetting(SETTINGS.RESULT_COUNT, 50)),
|
||||||
|
[SETTINGS.AUTO_DOWNLOAD]: getLocalStorageSetting(SETTINGS.AUTO_DOWNLOAD, true),
|
||||||
|
[SETTINGS.OS_NOTIFICATIONS_ENABLED]: Boolean(
|
||||||
getLocalStorageSetting(SETTINGS.OS_NOTIFICATIONS_ENABLED, true)
|
getLocalStorageSetting(SETTINGS.OS_NOTIFICATIONS_ENABLED, true)
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
@import 'init/gui';
|
@import 'init/gui';
|
||||||
@import 'component/animation';
|
@import 'component/animation';
|
||||||
@import 'component/badge';
|
@import 'component/badge';
|
||||||
|
@import 'component/banner';
|
||||||
@import 'component/button';
|
@import 'component/button';
|
||||||
@import 'component/card';
|
@import 'component/card';
|
||||||
@import 'component/channel';
|
@import 'component/channel';
|
||||||
|
@ -45,3 +46,4 @@
|
||||||
@import 'component/toggle';
|
@import 'component/toggle';
|
||||||
@import 'component/tooltip';
|
@import 'component/tooltip';
|
||||||
@import 'component/wunderbar';
|
@import 'component/wunderbar';
|
||||||
|
@import 'component/yrbl';
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
.badge--cost:not(.badge--large) {
|
.badge--cost:not(.badge--large) {
|
||||||
background-color: $lbry-yellow-2;
|
background-color: $lbry-yellow-2;
|
||||||
|
color: $lbry-black;
|
||||||
|
|
||||||
html[data-theme='dark'] & {
|
html[data-theme='dark'] & {
|
||||||
background-color: $lbry-yellow-3;
|
background-color: $lbry-yellow-3;
|
||||||
|
|
30
src/renderer/scss/component/_banner.scss
Normal file
30
src/renderer/scss/component/_banner.scss
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
.banner {
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: $lbry-black;
|
||||||
|
color: $lbry-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner--first-run {
|
||||||
|
height: 310px;
|
||||||
|
|
||||||
|
// Adjust this class inside other `.banner--xxx` styles for control over animation
|
||||||
|
.banner__item--static-for-animation {
|
||||||
|
height: 310px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner__item {
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-left: var(--spacing-vertical-large);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner__content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
|
@ -81,7 +81,7 @@
|
||||||
// C O N T E N T
|
// C O N T E N T
|
||||||
|
|
||||||
.card__content {
|
.card__content {
|
||||||
font-size: 1.15rem;
|
font-size: 1.25rem;
|
||||||
|
|
||||||
p:not(:last-child) {
|
p:not(:last-child) {
|
||||||
margin-bottom: var(--spacing-vertical-medium);
|
margin-bottom: var(--spacing-vertical-medium);
|
||||||
|
@ -174,9 +174,13 @@
|
||||||
// S U B T I T L E
|
// S U B T I T L E
|
||||||
|
|
||||||
.card__subtitle {
|
.card__subtitle {
|
||||||
font-size: 1.25rem;
|
font-size: 1.15rem;
|
||||||
margin-bottom: var(--spacing-vertical-small);
|
margin-bottom: var(--spacing-vertical-small);
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: var(--spacing-vertical-small);
|
||||||
|
}
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
bottom: -0.12rem;
|
bottom: -0.12rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -613,10 +613,10 @@
|
||||||
|
|
||||||
.media-group__header-navigation {
|
.media-group__header-navigation {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-right: var(--spacing-vertical-medium);
|
padding-right: var(--spacing-vertical-large);
|
||||||
|
|
||||||
button:not(:last-of-type) {
|
button:not(:last-of-type) {
|
||||||
margin-right: var(--spacing-vertical-tiny);
|
margin-right: var(--spacing-vertical-medium);
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
|
|
10
src/renderer/scss/component/_yrbl.scss
Normal file
10
src/renderer/scss/component/_yrbl.scss
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
.yrbl {
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yrbl--first-run {
|
||||||
|
align-self: center;
|
||||||
|
height: 200px;
|
||||||
|
width: auto;
|
||||||
|
margin: 0 var(--spacing-vertical-large);
|
||||||
|
}
|
|
@ -150,7 +150,6 @@ input {
|
||||||
.card {
|
.card {
|
||||||
.help {
|
.help {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
margin-top: var(--spacing-vertical-large);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +159,7 @@ input {
|
||||||
color: $lbry-gray-5;
|
color: $lbry-gray-5;
|
||||||
display: block;
|
display: block;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
margin-top: var(--spacing-vertical-large);
|
||||||
margin-bottom: var(--spacing-vertical-large);
|
margin-bottom: var(--spacing-vertical-large);
|
||||||
|
|
||||||
html[data-theme='dark'] & {
|
html[data-theme='dark'] & {
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 265 KiB |
96
yarn.lock
96
yarn.lock
|
@ -101,6 +101,16 @@
|
||||||
lodash "^4.2.0"
|
lodash "^4.2.0"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
|
"@emotion/is-prop-valid@^0.7.3":
|
||||||
|
version "0.7.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.7.3.tgz#a6bf4fa5387cbba59d44e698a4680f481a8da6cc"
|
||||||
|
dependencies:
|
||||||
|
"@emotion/memoize" "0.7.1"
|
||||||
|
|
||||||
|
"@emotion/memoize@0.7.1":
|
||||||
|
version "0.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.1.tgz#e93c13942592cf5ef01aa8297444dc192beee52f"
|
||||||
|
|
||||||
"@lbry/color@^1.0.2":
|
"@lbry/color@^1.0.2":
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@lbry/color/-/color-1.0.3.tgz#ec22b2c48b0e358759528fb3bbe7ba468d4e41ca"
|
resolved "https://registry.yarnpkg.com/@lbry/color/-/color-1.0.3.tgz#ec22b2c48b0e358759528fb3bbe7ba468d4e41ca"
|
||||||
|
@ -128,12 +138,33 @@
|
||||||
node-fetch "^2.1.1"
|
node-fetch "^2.1.1"
|
||||||
url-template "^2.0.8"
|
url-template "^2.0.8"
|
||||||
|
|
||||||
|
"@popmotion/easing@^1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@popmotion/easing/-/easing-1.0.1.tgz#48336aea29542113df10aeb81b4fd10f0b95f937"
|
||||||
|
|
||||||
|
"@popmotion/popcorn@^0.3.0":
|
||||||
|
version "0.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@popmotion/popcorn/-/popcorn-0.3.1.tgz#f0f33fbf7ff66f2cd0bf28be24bee0b1d46b65e8"
|
||||||
|
dependencies:
|
||||||
|
"@popmotion/easing" "^1.0.1"
|
||||||
|
framesync "^4.0.1"
|
||||||
|
hey-listen "^1.0.5"
|
||||||
|
style-value-types "^3.0.7"
|
||||||
|
|
||||||
"@samverschueren/stream-to-observable@^0.3.0":
|
"@samverschueren/stream-to-observable@^0.3.0":
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f"
|
resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f"
|
||||||
dependencies:
|
dependencies:
|
||||||
any-observable "^0.3.0"
|
any-observable "^0.3.0"
|
||||||
|
|
||||||
|
"@types/invariant@^2.2.29":
|
||||||
|
version "2.2.29"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.29.tgz#aa845204cd0a289f65d47e0de63a6a815e30cc66"
|
||||||
|
|
||||||
|
"@types/node@^10.0.5":
|
||||||
|
version "10.12.18"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67"
|
||||||
|
|
||||||
"@types/node@^8.0.24":
|
"@types/node@^8.0.24":
|
||||||
version "8.10.21"
|
version "8.10.21"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.21.tgz#12b3f2359b27aa05a45d886c8ba1eb8d1a77e285"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.21.tgz#12b3f2359b27aa05a45d886c8ba1eb8d1a77e285"
|
||||||
|
@ -4222,6 +4253,12 @@ fragment-cache@^0.2.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
map-cache "^0.2.2"
|
map-cache "^0.2.2"
|
||||||
|
|
||||||
|
framesync@^4.0.0, framesync@^4.0.1:
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/framesync/-/framesync-4.0.1.tgz#ed7791baf0d266f58ab02000456f82cb384815bf"
|
||||||
|
dependencies:
|
||||||
|
hey-listen "^1.0.5"
|
||||||
|
|
||||||
fresh@0.5.2:
|
fresh@0.5.2:
|
||||||
version "0.5.2"
|
version "0.5.2"
|
||||||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
||||||
|
@ -4667,6 +4704,10 @@ he@1.1.x:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
|
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
|
||||||
|
|
||||||
|
hey-listen@^1.0.4, hey-listen@^1.0.5:
|
||||||
|
version "1.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.5.tgz#6d0a3a2f60177f65bc4404d571a00025bf5dc20e"
|
||||||
|
|
||||||
highlight.js@^9.3.0:
|
highlight.js@^9.3.0:
|
||||||
version "9.12.0"
|
version "9.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e"
|
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e"
|
||||||
|
@ -7322,6 +7363,29 @@ pluralize@^7.0.0:
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
|
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
|
||||||
|
|
||||||
|
popmotion-pose@^3.4.0:
|
||||||
|
version "3.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/popmotion-pose/-/popmotion-pose-3.4.1.tgz#e13e52ba9fe02051926ca6313a7615876f459990"
|
||||||
|
dependencies:
|
||||||
|
"@popmotion/easing" "^1.0.1"
|
||||||
|
hey-listen "^1.0.5"
|
||||||
|
popmotion "^8.5.0"
|
||||||
|
pose-core "^2.0.0"
|
||||||
|
style-value-types "^3.0.6"
|
||||||
|
tslib "^1.9.1"
|
||||||
|
|
||||||
|
popmotion@^8.5.0:
|
||||||
|
version "8.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-8.6.0.tgz#14edf50376fc2d656b59e0d46390896577818abb"
|
||||||
|
dependencies:
|
||||||
|
"@popmotion/easing" "^1.0.1"
|
||||||
|
"@popmotion/popcorn" "^0.3.0"
|
||||||
|
framesync "^4.0.0"
|
||||||
|
hey-listen "^1.0.5"
|
||||||
|
style-value-types "^3.0.6"
|
||||||
|
stylefire "^2.3.4"
|
||||||
|
tslib "^1.9.1"
|
||||||
|
|
||||||
portfinder@^1.0.9:
|
portfinder@^1.0.9:
|
||||||
version "1.0.13"
|
version "1.0.13"
|
||||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9"
|
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9"
|
||||||
|
@ -7330,6 +7394,15 @@ portfinder@^1.0.9:
|
||||||
debug "^2.2.0"
|
debug "^2.2.0"
|
||||||
mkdirp "0.5.x"
|
mkdirp "0.5.x"
|
||||||
|
|
||||||
|
pose-core@^2.0.0:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/pose-core/-/pose-core-2.0.2.tgz#6a0bd1e7218e4bf30be9c26a30be8eeb5b8695df"
|
||||||
|
dependencies:
|
||||||
|
"@types/invariant" "^2.2.29"
|
||||||
|
"@types/node" "^10.0.5"
|
||||||
|
hey-listen "^1.0.5"
|
||||||
|
tslib "^1.9.1"
|
||||||
|
|
||||||
posix-character-classes@^0.1.0:
|
posix-character-classes@^0.1.0:
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
||||||
|
@ -7907,6 +7980,15 @@ react-paginate@^5.2.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
prop-types "^15.6.1"
|
prop-types "^15.6.1"
|
||||||
|
|
||||||
|
react-pose@^4.0.5:
|
||||||
|
version "4.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-pose/-/react-pose-4.0.5.tgz#056309b62e32ce0190f90ef35d7ade1b4c463d85"
|
||||||
|
dependencies:
|
||||||
|
"@emotion/is-prop-valid" "^0.7.3"
|
||||||
|
hey-listen "^1.0.5"
|
||||||
|
popmotion-pose "^3.4.0"
|
||||||
|
tslib "^1.9.1"
|
||||||
|
|
||||||
react-redux@^5.0.3:
|
react-redux@^5.0.3:
|
||||||
version "5.0.7"
|
version "5.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8"
|
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8"
|
||||||
|
@ -9260,6 +9342,18 @@ style-loader@^0.20.2:
|
||||||
loader-utils "^1.1.0"
|
loader-utils "^1.1.0"
|
||||||
schema-utils "^0.4.5"
|
schema-utils "^0.4.5"
|
||||||
|
|
||||||
|
style-value-types@^3.0.6, style-value-types@^3.0.7:
|
||||||
|
version "3.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-3.0.7.tgz#6e7a22cc8b1a4465193268ed66ad5f2a82579054"
|
||||||
|
|
||||||
|
stylefire@^2.3.4:
|
||||||
|
version "2.3.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/stylefire/-/stylefire-2.3.7.tgz#285b86a48f6c25bbdcccb5dafa26b9f578235bb5"
|
||||||
|
dependencies:
|
||||||
|
framesync "^4.0.0"
|
||||||
|
hey-listen "^1.0.4"
|
||||||
|
style-value-types "^3.0.6"
|
||||||
|
|
||||||
sumchecker@^1.2.0:
|
sumchecker@^1.2.0:
|
||||||
version "1.3.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-1.3.1.tgz#79bb3b4456dd04f18ebdbc0d703a1d1daec5105d"
|
resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-1.3.1.tgz#79bb3b4456dd04f18ebdbc0d703a1d1daec5105d"
|
||||||
|
@ -9592,7 +9686,7 @@ truncate-utf8-bytes@^1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
utf8-byte-length "^1.0.1"
|
utf8-byte-length "^1.0.1"
|
||||||
|
|
||||||
tslib@^1.9.0:
|
tslib@^1.9.0, tslib@^1.9.1:
|
||||||
version "1.9.3"
|
version "1.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue