add nudges to sign up
This commit is contained in:
parent
35ab5b1578
commit
f63de7f930
12 changed files with 192 additions and 39 deletions
|
@ -1476,5 +1476,6 @@
|
|||
"Currently winning": "Currently winning",
|
||||
"URL can not include a space": "URL can not include a space",
|
||||
"Creator analytics are down for maintenance. Please check back later.": "Creator analytics are down for maintenance. Please check back later.",
|
||||
"Sign up to earn %lbc% for you and your favorite creators.": "Sign up to earn %lbc% for you and your favorite creators.",
|
||||
"--end--": "--end--"
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { doOpenModal } from 'redux/actions/app';
|
||||
import ClaimSupportButton from './view';
|
||||
import { selectUser } from 'redux/selectors/user';
|
||||
import { makeSelectTagInClaimOrChannelForUri } from 'lbry-redux';
|
||||
import ClaimSupportButton from './view';
|
||||
|
||||
const DISABLE_SUPPORT_TAG = 'disable-support';
|
||||
const select = (state, props) => ({
|
||||
disableSupport: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_SUPPORT_TAG)(state),
|
||||
user: selectUser(state),
|
||||
});
|
||||
|
||||
export default connect(select, {
|
||||
|
|
|
@ -4,29 +4,60 @@ import * as ICONS from 'constants/icons';
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import Button from 'component/button';
|
||||
import usePersistedState from 'effects/use-persisted-state';
|
||||
|
||||
type Props = {
|
||||
uri: string,
|
||||
doOpenModal: (string, {}) => void,
|
||||
fileAction?: boolean,
|
||||
disableSupport: boolean,
|
||||
user: ?User,
|
||||
};
|
||||
|
||||
export default function ClaimSupportButton(props: Props) {
|
||||
const { doOpenModal, uri, fileAction, disableSupport } = props;
|
||||
const { doOpenModal, uri, fileAction, disableSupport, user } = props;
|
||||
const [showNudge, setShowNudge] = React.useState(false);
|
||||
const [nudgeAcknowledged, setNudgeAcknowledged] = usePersistedState('nudge:support-acknowledge', false);
|
||||
const emailVerified = user && user.has_verified_email;
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!emailVerified && !nudgeAcknowledged && fileAction) {
|
||||
setShowNudge(true);
|
||||
}
|
||||
}, [emailVerified, nudgeAcknowledged, fileAction]);
|
||||
|
||||
if (disableSupport) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
button={fileAction ? undefined : 'alt'}
|
||||
className={classnames({ 'button--file-action': fileAction })}
|
||||
icon={ICONS.LBC}
|
||||
iconSize={fileAction ? 22 : undefined}
|
||||
label={__('Support --[button to support a claim]--')}
|
||||
requiresAuth={IS_WEB}
|
||||
title={__('Support this claim')}
|
||||
onClick={() => doOpenModal(MODALS.SEND_TIP, { uri, isSupport: true })}
|
||||
/>
|
||||
<>
|
||||
<Button
|
||||
button={fileAction ? undefined : 'alt'}
|
||||
className={classnames({ 'button--file-action': fileAction, 'button--highlighted': showNudge })}
|
||||
icon={ICONS.LBC}
|
||||
iconSize={fileAction ? 22 : undefined}
|
||||
label={__('Support --[button to support a claim]--')}
|
||||
requiresAuth={IS_WEB}
|
||||
title={__('Support this claim')}
|
||||
onClick={() => doOpenModal(MODALS.SEND_TIP, { uri, isSupport: true })}
|
||||
/>
|
||||
{showNudge && (
|
||||
<div className="nudge">
|
||||
<div className="nudge__wrapper">
|
||||
<span className="nudge__text">{__('Create an account to support this creator!')}</span>
|
||||
<Button
|
||||
className="nudge__close"
|
||||
button="close"
|
||||
icon={ICONS.REMOVE}
|
||||
onClick={() => {
|
||||
setNudgeAcknowledged(true);
|
||||
setShowNudge(false);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -174,6 +174,13 @@ const Header = (props: Props) => {
|
|||
return hideBalance || Number(roundedBalance) === 0 ? __('Your Wallet') : roundedBalance;
|
||||
}
|
||||
|
||||
const loginButtons = (
|
||||
<div className="header__auth-buttons">
|
||||
<Button navigate={`/$/${PAGES.AUTH_SIGNIN}`} button="link" label={__('Log In')} className="mobile-hidden" />
|
||||
<Button navigate={`/$/${PAGES.AUTH}`} button="primary" label={__('Sign Up')} />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<header
|
||||
className={classnames('header', {
|
||||
|
@ -198,18 +205,22 @@ const Header = (props: Props) => {
|
|||
icon={ICONS.ARROW_LEFT}
|
||||
/>
|
||||
{backTitle && <h1 className="header__auth-title">{isMobile ? simpleBackTitle || backTitle : backTitle}</h1>}
|
||||
<Button
|
||||
aria-label={__('Your wallet')}
|
||||
navigate={`/$/${PAGES.WALLET}`}
|
||||
className="header__navigation-item menu__title header__navigation-item--balance"
|
||||
label={getWalletTitle()}
|
||||
icon={ICONS.LBC}
|
||||
// @if TARGET='app'
|
||||
onDoubleClick={e => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
// @endif
|
||||
/>
|
||||
{authenticated ? (
|
||||
<Button
|
||||
aria-label={__('Your wallet')}
|
||||
navigate={`/$/${PAGES.WALLET}`}
|
||||
className="header__navigation-item menu__title header__navigation-item--balance"
|
||||
label={getWalletTitle()}
|
||||
icon={ICONS.LBC}
|
||||
// @if TARGET='app'
|
||||
onDoubleClick={e => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
// @endif
|
||||
/>
|
||||
) : (
|
||||
loginButtons
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
|
@ -409,17 +420,7 @@ const Header = (props: Props) => {
|
|||
/>
|
||||
)}
|
||||
|
||||
{IS_WEB && !authenticated && (
|
||||
<div className="header__auth-buttons">
|
||||
<Button
|
||||
navigate={`/$/${PAGES.AUTH_SIGNIN}`}
|
||||
button="link"
|
||||
label={__('Log In')}
|
||||
className="mobile-hidden"
|
||||
/>
|
||||
<Button navigate={`/$/${PAGES.AUTH}`} button="primary" label={__('Sign Up')} />
|
||||
</div>
|
||||
)}
|
||||
{IS_WEB && !authenticated && loginButtons}
|
||||
</div>
|
||||
) : (
|
||||
!isVerifyPage &&
|
||||
|
|
|
@ -5,7 +5,9 @@ import * as ICONS from 'constants/icons';
|
|||
import React from 'react';
|
||||
import Button from 'component/button';
|
||||
import classnames from 'classnames';
|
||||
import Icon from 'component/common/icon';
|
||||
import NotificationBubble from 'component/notificationBubble';
|
||||
import I18nMessage from 'component/i18nMessage';
|
||||
import { PINNED_LABEL_1, PINNED_URI_1, PINNED_URI_2, PINNED_LABEL_2 } from 'config';
|
||||
// @if TARGET='app'
|
||||
import { IS_MAC } from 'component/app/view';
|
||||
|
@ -260,6 +262,17 @@ function SideNavigation(props: Props) {
|
|||
return () => window.removeEventListener('keydown', handleKeydown);
|
||||
}, [sidebarOpen, setSidebarOpen, isAbsolute]);
|
||||
|
||||
const unAuthNudge = (
|
||||
<div className="navigation__auth-nudge">
|
||||
<span>
|
||||
<I18nMessage tokens={{ lbc: <Icon icon={ICONS.LBC} /> }}>
|
||||
Sign up to earn %lbc% for you and your favorite creators.
|
||||
</I18nMessage>
|
||||
</span>
|
||||
<Button button="secondary" label={__('Sign Up')} navigate={`/$/${PAGES.AUTH}`} />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames('navigation__wrapper', {
|
||||
|
@ -321,6 +334,20 @@ function SideNavigation(props: Props) {
|
|||
))}
|
||||
</ul>
|
||||
)}
|
||||
|
||||
{!isAuthenticated &&
|
||||
(sidebarOpen ? (
|
||||
unAuthNudge
|
||||
) : (
|
||||
<div className="navigation-links--micro">
|
||||
<Button
|
||||
label={__('Sign In')}
|
||||
icon={ICONS.SIGN_IN}
|
||||
className={classnames('navigation-link')}
|
||||
activeClass="navigation-link--active"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</nav>
|
||||
)}
|
||||
|
@ -396,6 +423,7 @@ function SideNavigation(props: Props) {
|
|||
))}
|
||||
</ul>
|
||||
)}
|
||||
{!isAuthenticated && unAuthNudge}
|
||||
</div>
|
||||
</nav>
|
||||
<div
|
||||
|
|
|
@ -12,8 +12,10 @@ import FileSelector from 'component/common/file-selector';
|
|||
import SyncToggle from 'component/syncToggle';
|
||||
import Card from 'component/common/card';
|
||||
import SettingAccountPassword from 'component/settingAccountPassword';
|
||||
import classnames from 'classnames';
|
||||
import { getPasswordFromCookie } from 'util/saved-passwords';
|
||||
import { Lbryio } from 'lbryinc';
|
||||
import Yrbl from 'component/yrbl';
|
||||
|
||||
type Price = {
|
||||
currency: string,
|
||||
|
@ -190,12 +192,27 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
}}
|
||||
className="card-stack"
|
||||
>
|
||||
{!isAuthenticated && IS_WEB && (
|
||||
<div className="main--empty">
|
||||
<Yrbl
|
||||
type="happy"
|
||||
title={__('Sign up for full control')}
|
||||
subtitle={__('Unlock new buttons that change things.')}
|
||||
actions={
|
||||
<div className="section__actions">
|
||||
<Button button="primary" icon={ICONS.SIGN_UP} label={__('Sign Up')} navigate={`/$/${PAGES.AUTH}`} />
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!IS_WEB && noDaemonSettings ? (
|
||||
<section className="card card--section">
|
||||
<div className="card__title card__title--deprecated">{__('Failed to load settings.')}</div>
|
||||
</section>
|
||||
) : (
|
||||
<div>
|
||||
<div className={classnames({ 'card--disabled': IS_WEB && !isAuthenticated })}>
|
||||
<Card title={__('Language')} actions={<SettingLanguage />} />
|
||||
{isAuthenticated && <SettingAccountPassword />}
|
||||
{/* @if TARGET='app' */}
|
||||
|
|
|
@ -46,7 +46,7 @@ import {
|
|||
selectAllowAnalytics,
|
||||
} from 'redux/selectors/app';
|
||||
import { selectDaemonSettings, makeSelectClientSetting } from 'redux/selectors/settings';
|
||||
import { selectUser } from 'redux/selectors/user';
|
||||
import { selectUser, selectUserVerifiedEmail } from 'redux/selectors/user';
|
||||
// import { selectDaemonSettings } from 'redux/selectors/settings';
|
||||
import { doSyncSubscribe, doSetPrefsReady } from 'redux/actions/sync';
|
||||
import { doAuthenticate } from 'redux/actions/user';
|
||||
|
@ -335,13 +335,20 @@ export function doAlertError(errorList) {
|
|||
}
|
||||
|
||||
export function doAlertWaitingForSync() {
|
||||
return dispatch =>
|
||||
return (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const authenticated = selectUserVerifiedEmail(state);
|
||||
|
||||
dispatch(
|
||||
doToast({
|
||||
message: __('Please wait a bit, we are still getting your account ready.'),
|
||||
message:
|
||||
!authenticated && IS_WEB
|
||||
? __('Sign in or create an account to change this setting.')
|
||||
: __('Please wait a bit, we are still getting your account ready.'),
|
||||
isError: false,
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export function doDaemonReady() {
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
@import 'component/nag';
|
||||
@import 'component/navigation';
|
||||
@import 'component/notification';
|
||||
@import 'component/nudge';
|
||||
@import 'component/pagination';
|
||||
@import 'component/purchase';
|
||||
@import 'component/placeholder';
|
||||
|
|
|
@ -203,6 +203,10 @@
|
|||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.button--highlighted {
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.button__content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
@ -236,3 +236,24 @@
|
|||
top: calc(var(--header-height) + var(--mac-titlebar-height));
|
||||
}
|
||||
}
|
||||
|
||||
.navigation__auth-nudge {
|
||||
@extend .card;
|
||||
margin: var(--spacing-s);
|
||||
margin-top: var(--spacing-l);
|
||||
padding: var(--spacing-xs);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.button {
|
||||
margin-top: var(--spacing-s);
|
||||
}
|
||||
|
||||
.button__content {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-bottom: -2px;
|
||||
}
|
||||
}
|
||||
|
|
39
ui/scss/component/_nudge.scss
Normal file
39
ui/scss/component/_nudge.scss
Normal file
|
@ -0,0 +1,39 @@
|
|||
.nudge {
|
||||
z-index: 3;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: calc(var(--height-button) + var(--spacing-s));
|
||||
white-space: normal;
|
||||
overflow: visible;
|
||||
padding: var(--spacing-m);
|
||||
border-radius: var(--border-radius);
|
||||
box-shadow: var(--card-box-shadow);
|
||||
background-color: var(--color-secondary);
|
||||
color: var(--color-white);
|
||||
|
||||
.button--close {
|
||||
.icon {
|
||||
stroke: var(--color-white);
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
top: -0.5rem;
|
||||
left: 3rem;
|
||||
transform: rotate(45deg);
|
||||
background-color: var(--color-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
.nudge__wrapper {
|
||||
width: 10rem;
|
||||
margin-right: var(--spacing-m);
|
||||
|
||||
@media (min-width: $breakpoint-small) {
|
||||
width: 12.5rem;
|
||||
}
|
||||
}
|
|
@ -104,6 +104,7 @@
|
|||
}
|
||||
|
||||
.section__actions {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: var(--spacing-l);
|
||||
|
|
Loading…
Add table
Reference in a new issue