Refactor header Component, split into smaller components and remove what is unused
This commit is contained in:
parent
a196f7a3b0
commit
254fff208d
13 changed files with 370 additions and 588 deletions
22
ui/component/common/header-menu-link.jsx
Normal file
22
ui/component/common/header-menu-link.jsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { MenuLink } from '@reach/menu-button';
|
||||
import Icon from 'component/common/icon';
|
||||
|
||||
type Props = {
|
||||
icon: string,
|
||||
name: string,
|
||||
page: string,
|
||||
};
|
||||
|
||||
export default function HeaderMenuLink(props: Props) {
|
||||
const { icon, name, page } = props;
|
||||
|
||||
return (
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${page}`}>
|
||||
<Icon aria-hidden icon={icon} />
|
||||
{name}
|
||||
</MenuLink>
|
||||
);
|
||||
}
|
|
@ -1,40 +1,33 @@
|
|||
import * as SETTINGS from 'constants/settings';
|
||||
import { connect } from 'react-redux';
|
||||
import { selectTotalBalance, selectBalance } from 'redux/selectors/wallet';
|
||||
import { formatCredits } from 'util/format-credits';
|
||||
import { selectGetSyncErrorMessage } from 'redux/selectors/sync';
|
||||
import { selectUserVerifiedEmail, selectUserEmail, selectEmailToVerify, selectUser } from 'redux/selectors/user';
|
||||
import { doClearEmailEntry, doClearPasswordEntry } from 'redux/actions/user';
|
||||
import { doSetClientSetting } from 'redux/actions/settings';
|
||||
import { doSignOut, doOpenModal } from 'redux/actions/app';
|
||||
import { selectClientSetting, selectLanguage } from 'redux/selectors/settings';
|
||||
import { selectHasNavigated, selectActiveChannelClaim, selectActiveChannelStakedLevel } from 'redux/selectors/app';
|
||||
import { formatCredits } from 'util/format-credits';
|
||||
import { selectClientSetting } from 'redux/selectors/settings';
|
||||
import { selectGetSyncErrorMessage } from 'redux/selectors/sync';
|
||||
import { selectHasNavigated } from 'redux/selectors/app';
|
||||
import { selectTotalBalance, selectBalance } from 'redux/selectors/wallet';
|
||||
import { selectUserVerifiedEmail, selectEmailToVerify, selectUser } from 'redux/selectors/user';
|
||||
import * as MODALS from 'constants/modal_types';
|
||||
import * as SETTINGS from 'constants/settings';
|
||||
import Header from './view';
|
||||
|
||||
const select = (state) => ({
|
||||
language: selectLanguage(state),
|
||||
balance: selectBalance(state),
|
||||
roundedSpendableBalance: formatCredits(selectBalance(state), 2, true),
|
||||
roundedBalance: formatCredits(selectTotalBalance(state), 2, true),
|
||||
currentTheme: selectClientSetting(state, SETTINGS.THEME),
|
||||
automaticDarkModeEnabled: selectClientSetting(state, SETTINGS.AUTOMATIC_DARK_MODE_ENABLED),
|
||||
hideBalance: selectClientSetting(state, SETTINGS.HIDE_BALANCE),
|
||||
authenticated: selectUserVerifiedEmail(state),
|
||||
email: selectUserEmail(state),
|
||||
syncError: selectGetSyncErrorMessage(state),
|
||||
balance: selectBalance(state),
|
||||
emailToVerify: selectEmailToVerify(state),
|
||||
hasNavigated: selectHasNavigated(state),
|
||||
hideBalance: selectClientSetting(state, SETTINGS.HIDE_BALANCE),
|
||||
roundedBalance: formatCredits(selectTotalBalance(state), 2, true),
|
||||
roundedSpendableBalance: formatCredits(selectBalance(state), 2, true),
|
||||
syncError: selectGetSyncErrorMessage(state),
|
||||
user: selectUser(state),
|
||||
activeChannelClaim: selectActiveChannelClaim(state),
|
||||
activeChannelStakedLevel: selectActiveChannelStakedLevel(state),
|
||||
});
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
setClientSetting: (key, value, push) => dispatch(doSetClientSetting(key, value, push)),
|
||||
signOut: () => dispatch(doSignOut()),
|
||||
doOpenModal: (modal, props) => dispatch(doOpenModal(modal, props)),
|
||||
clearEmailEntry: () => dispatch(doClearEmailEntry()),
|
||||
clearPasswordEntry: () => dispatch(doClearPasswordEntry()),
|
||||
signOut: () => dispatch(doSignOut()),
|
||||
openChangelog: (modalProps) => dispatch(doOpenModal(MODALS.CONFIRM, modalProps)),
|
||||
});
|
||||
|
||||
export default connect(select, perform)(Header);
|
||||
|
|
|
@ -1,50 +1,19 @@
|
|||
// @flow
|
||||
import { ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM, ENABLE_UI_NOTIFICATIONS } from 'config';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import * as MODALS from 'constants/modal_types';
|
||||
import * as SETTINGS from 'constants/settings';
|
||||
import * as PAGES from 'constants/pages';
|
||||
import React from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
import classnames from 'classnames';
|
||||
import Button from 'component/button';
|
||||
import WunderBar from 'component/wunderbar';
|
||||
import Icon from 'component/common/icon';
|
||||
import { Menu, MenuList, MenuButton, MenuItem, MenuLink } from '@reach/menu-button';
|
||||
import NavigationButton from 'component/navigationButton';
|
||||
import { useIsMobile } from 'effects/use-screensize';
|
||||
import NotificationBubble from 'component/notificationBubble';
|
||||
import NotificationHeaderButton from 'component/notificationHeaderButton';
|
||||
import ChannelThumbnail from 'component/channelThumbnail';
|
||||
import SkipNavigationButton from 'component/skipNavigationButton';
|
||||
import { withRouter } from 'react-router';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import * as PAGES from 'constants/pages';
|
||||
import Button from 'component/button';
|
||||
import classnames from 'classnames';
|
||||
import HeaderMenuButtons from 'component/headerMenuButtons';
|
||||
import HeaderProfileMenuButton from 'component/headerProfileMenuButton';
|
||||
import Logo from 'component/logo';
|
||||
// @if TARGET='app'
|
||||
import { remote } from 'electron';
|
||||
import { IS_MAC } from 'component/app/view';
|
||||
// @endif
|
||||
import NotificationBubble from 'component/notificationBubble';
|
||||
import React from 'react';
|
||||
import SkipNavigationButton from 'component/skipNavigationButton';
|
||||
import WunderBar from 'component/wunderbar';
|
||||
|
||||
type Props = {
|
||||
user: ?User,
|
||||
balance: string,
|
||||
balance: number,
|
||||
roundedBalance: string,
|
||||
roundedSpendableBalance: string,
|
||||
history: {
|
||||
entities: {}[],
|
||||
goBack: () => void,
|
||||
goForward: () => void,
|
||||
index: number,
|
||||
length: number,
|
||||
location: { pathname: string },
|
||||
push: (string) => void,
|
||||
replace: (string) => void,
|
||||
},
|
||||
currentTheme: string,
|
||||
automaticDarkModeEnabled: boolean,
|
||||
setClientSetting: (string, boolean | string, ?boolean) => void,
|
||||
hideBalance: boolean,
|
||||
email: ?string,
|
||||
authenticated: boolean,
|
||||
authHeader: boolean,
|
||||
backout: {
|
||||
|
@ -53,220 +22,171 @@ type Props = {
|
|||
title: string,
|
||||
simpleTitle: string, // Just use the same value as `title` if `title` is already short (~< 10 chars), unless you have a better idea for title overlfow on mobile
|
||||
},
|
||||
syncError: ?string,
|
||||
balance: number,
|
||||
emailToVerify?: string,
|
||||
signOut: () => void,
|
||||
doOpenModal: (string, ?{}) => void,
|
||||
hasNavigated: boolean,
|
||||
hideBalance: boolean,
|
||||
hideCancel: boolean,
|
||||
history: {
|
||||
goBack: () => void,
|
||||
location: { pathname: string },
|
||||
push: (string) => void,
|
||||
replace: (string) => void,
|
||||
},
|
||||
isAbsoluteSideNavHidden: boolean,
|
||||
roundedBalance: string,
|
||||
roundedSpendableBalance: string,
|
||||
sidebarOpen: boolean,
|
||||
syncError: ?string,
|
||||
user: ?User,
|
||||
clearEmailEntry: () => void,
|
||||
clearPasswordEntry: () => void,
|
||||
hasNavigated: boolean,
|
||||
sidebarOpen: boolean,
|
||||
openChangelog: ({}) => void,
|
||||
setSidebarOpen: (boolean) => void,
|
||||
isAbsoluteSideNavHidden: boolean,
|
||||
hideCancel: boolean,
|
||||
activeChannelClaim: ?ChannelClaim,
|
||||
activeChannelStakedLevel: number,
|
||||
signOut: () => void,
|
||||
};
|
||||
|
||||
const Header = (props: Props) => {
|
||||
const {
|
||||
balance,
|
||||
roundedBalance,
|
||||
roundedSpendableBalance,
|
||||
history,
|
||||
setClientSetting,
|
||||
currentTheme,
|
||||
automaticDarkModeEnabled,
|
||||
hideBalance,
|
||||
email,
|
||||
authenticated,
|
||||
authHeader,
|
||||
signOut,
|
||||
backout,
|
||||
balance,
|
||||
emailToVerify,
|
||||
hideBalance,
|
||||
hideCancel,
|
||||
history,
|
||||
isAbsoluteSideNavHidden,
|
||||
roundedBalance,
|
||||
roundedSpendableBalance,
|
||||
sidebarOpen,
|
||||
syncError,
|
||||
doOpenModal,
|
||||
user,
|
||||
clearEmailEntry,
|
||||
clearPasswordEntry,
|
||||
emailToVerify,
|
||||
backout,
|
||||
sidebarOpen,
|
||||
openChangelog,
|
||||
setSidebarOpen,
|
||||
isAbsoluteSideNavHidden,
|
||||
hideCancel,
|
||||
user,
|
||||
activeChannelClaim,
|
||||
activeChannelStakedLevel,
|
||||
signOut,
|
||||
} = props;
|
||||
|
||||
const {
|
||||
location: { pathname },
|
||||
goBack,
|
||||
push,
|
||||
} = history;
|
||||
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
// on the verify page don't let anyone escape other than by closing the tab to keep session data consistent
|
||||
const isVerifyPage = history.location.pathname.includes(PAGES.AUTH_VERIFY);
|
||||
const isSignUpPage = history.location.pathname.includes(PAGES.AUTH);
|
||||
const isSignInPage = history.location.pathname.includes(PAGES.AUTH_SIGNIN);
|
||||
const isPwdResetPage = history.location.pathname.includes(PAGES.AUTH_PASSWORD_RESET);
|
||||
const hasBackout = Boolean(backout);
|
||||
const isVerifyPage = pathname.includes(PAGES.AUTH_VERIFY);
|
||||
const isSignUpPage = pathname.includes(PAGES.AUTH);
|
||||
const isSignInPage = pathname.includes(PAGES.AUTH_SIGNIN);
|
||||
const isPwdResetPage = pathname.includes(PAGES.AUTH_PASSWORD_RESET);
|
||||
|
||||
// For pages that allow for "backing out", shows a backout option instead of the Home logo
|
||||
const canBackout = Boolean(backout);
|
||||
const { backLabel, backNavDefault, title: backTitle, simpleTitle: simpleBackTitle } = backout || {};
|
||||
const notificationsEnabled = ENABLE_UI_NOTIFICATIONS || (user && user.experimental_ui);
|
||||
const livestreamEnabled = Boolean(
|
||||
ENABLE_NO_SOURCE_CLAIMS &&
|
||||
user &&
|
||||
!user.odysee_live_disabled &&
|
||||
(activeChannelStakedLevel >= CHANNEL_STAKED_LEVEL_LIVESTREAM || user.odysee_live_enabled)
|
||||
);
|
||||
const activeChannelUrl = activeChannelClaim && activeChannelClaim.permanent_url;
|
||||
|
||||
// Sign out if they click the "x" when they are on the password prompt
|
||||
const authHeaderAction = syncError ? { onClick: signOut } : { navigate: '/' };
|
||||
const homeButtonNavigationProps = isVerifyPage ? {} : authHeader ? authHeaderAction : { navigate: '/' };
|
||||
const closeButtonNavigationProps = {
|
||||
onClick: () => {
|
||||
clearEmailEntry();
|
||||
clearPasswordEntry();
|
||||
const authHeaderAction = syncError && { onClick: signOut };
|
||||
const homeButtonNavigationProps = (isVerifyPage && {}) || (authHeader && authHeaderAction) || { navigate: '/' };
|
||||
const sidebarLabel = sidebarOpen
|
||||
? __('Close sidebar - hide channels you are following.')
|
||||
: __('Expand sidebar - view channels you are following.');
|
||||
|
||||
if (syncError) {
|
||||
signOut();
|
||||
}
|
||||
const onBackout = React.useCallback(
|
||||
(e: any) => {
|
||||
const { hasNavigated } = props;
|
||||
const { replace } = history;
|
||||
|
||||
if (isSignInPage && !emailToVerify) {
|
||||
history.goBack();
|
||||
} else if (isSignUpPage) {
|
||||
history.goBack();
|
||||
} else if (isPwdResetPage) {
|
||||
history.goBack();
|
||||
} else {
|
||||
history.push('/');
|
||||
window.removeEventListener('popstate', onBackout);
|
||||
|
||||
if (e.type !== 'popstate') {
|
||||
// if not initiated by pop (back button)
|
||||
if (hasNavigated && !backNavDefault) {
|
||||
goBack();
|
||||
} else {
|
||||
replace(backNavDefault || `/`);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function onBackout(e) {
|
||||
const { history, hasNavigated } = props;
|
||||
const { goBack, replace } = history;
|
||||
|
||||
window.removeEventListener('popstate', onBackout);
|
||||
|
||||
if (e.type !== 'popstate') {
|
||||
// if not initiated by pop (back button)
|
||||
if (hasNavigated && !backNavDefault) {
|
||||
goBack();
|
||||
} else {
|
||||
replace(backNavDefault || `/`);
|
||||
}
|
||||
}
|
||||
}
|
||||
[backNavDefault, goBack, history, props]
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (hasBackout) {
|
||||
if (canBackout) {
|
||||
window.addEventListener('popstate', onBackout);
|
||||
return () => window.removeEventListener('popstate', onBackout);
|
||||
}
|
||||
}, [hasBackout]);
|
||||
}, [canBackout, onBackout]);
|
||||
|
||||
function handleThemeToggle() {
|
||||
if (automaticDarkModeEnabled) {
|
||||
setClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, false);
|
||||
}
|
||||
const userButtons = (className: string) => (
|
||||
<div className={classnames('header__menu', { 'header__menu--with-balance': authenticated })}>
|
||||
{authenticated ? (
|
||||
<>
|
||||
<Button
|
||||
title={
|
||||
balance > 0
|
||||
? __('Immediately spendable: %spendable_balance%', { spendable_balance: roundedSpendableBalance })
|
||||
: __('Your Wallet')
|
||||
}
|
||||
navigate={`/$/${PAGES.WALLET}`}
|
||||
className={classnames(className, 'header__navigation-item--balance')}
|
||||
label={hideBalance || Number(roundedBalance) === 0 ? __('Your Wallet') : roundedBalance}
|
||||
icon={ICONS.LBC}
|
||||
/>
|
||||
|
||||
if (currentTheme === 'dark') {
|
||||
setClientSetting(SETTINGS.THEME, 'light', true);
|
||||
} else {
|
||||
setClientSetting(SETTINGS.THEME, 'dark', true);
|
||||
}
|
||||
}
|
||||
|
||||
const loginButtons = (
|
||||
<div className="header__auth-buttons">
|
||||
<Button
|
||||
navigate={`/$/${PAGES.AUTH_SIGNIN}`}
|
||||
button="link"
|
||||
label={__('Log In')}
|
||||
className="mobile-hidden"
|
||||
disabled={user === null}
|
||||
/>
|
||||
<Button navigate={`/$/${PAGES.AUTH}`} button="primary" label={__('Sign Up')} disabled={user === null} />
|
||||
<HeaderProfileMenuButton />
|
||||
</>
|
||||
) : (
|
||||
<div className="header__auth-buttons">
|
||||
<Button
|
||||
navigate={`/$/${PAGES.AUTH_SIGNIN}`}
|
||||
button="link"
|
||||
label={__('Log In')}
|
||||
className="mobile-hidden"
|
||||
disabled={user === null}
|
||||
/>
|
||||
<Button navigate={`/$/${PAGES.AUTH}`} button="primary" label={__('Sign Up')} disabled={user === null} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
type BalanceButtonProps = { className: string };
|
||||
const BalanceButton = (balanceButtonProps: BalanceButtonProps) => (
|
||||
<Button
|
||||
title={
|
||||
balance > 0
|
||||
? __('Immediately spendable: %spendable_balance%', { spendable_balance: roundedSpendableBalance })
|
||||
: __('Your Wallet')
|
||||
}
|
||||
navigate={`/$/${PAGES.WALLET}`}
|
||||
className={classnames(balanceButtonProps.className, 'header__navigation-item--balance')}
|
||||
label={hideBalance || Number(roundedBalance) === 0 ? __('Your Wallet') : roundedBalance}
|
||||
icon={ICONS.LBC}
|
||||
// @if TARGET='app'
|
||||
onDoubleClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
// @endif
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<header
|
||||
className={classnames('header', {
|
||||
'header--minimal': authHeader,
|
||||
// @if TARGET='app'
|
||||
'header--mac': IS_MAC,
|
||||
// @endif
|
||||
})}
|
||||
// @if TARGET='app'
|
||||
onDoubleClick={(e) => {
|
||||
remote.getCurrentWindow().maximize();
|
||||
}}
|
||||
// @endif
|
||||
>
|
||||
<header className={classnames('header', { 'header--minimal': authHeader })}>
|
||||
<div className="header__contents">
|
||||
{!authHeader && backout ? (
|
||||
{!authHeader && canBackout ? (
|
||||
<div className="card__actions--between">
|
||||
<Button
|
||||
onClick={onBackout}
|
||||
button="link"
|
||||
label={(backLabel && backLabel) || __('Cancel')}
|
||||
icon={ICONS.ARROW_LEFT}
|
||||
/>
|
||||
{backTitle && <h1 className="header__auth-title">{isMobile ? simpleBackTitle || backTitle : backTitle}</h1>}
|
||||
{authenticated || !IS_WEB ? (
|
||||
<BalanceButton className="header__navigation-item menu__title" />
|
||||
) : (
|
||||
loginButtons
|
||||
)}
|
||||
<Button onClick={onBackout} button="link" label={backLabel || __('Cancel')} icon={ICONS.ARROW_LEFT} />
|
||||
|
||||
{backTitle && <h1 className="header__auth-title">{(isMobile && simpleBackTitle) || backTitle}</h1>}
|
||||
|
||||
{userButtons('header__navigation-item menu__title')}
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="header__navigation">
|
||||
<SkipNavigationButton />
|
||||
|
||||
{!authHeader && (
|
||||
<span style={{ position: 'relative' }}>
|
||||
<Button
|
||||
aria-label={
|
||||
sidebarOpen
|
||||
? __('Close sidebar - hide channels you are following.')
|
||||
: __('Expand sidebar - view channels you are following.')
|
||||
}
|
||||
aria-label={sidebarLabel}
|
||||
className="header__navigation-item menu__title header__navigation-item--icon"
|
||||
icon={ICONS.MENU}
|
||||
aria-expanded={sidebarOpen}
|
||||
onClick={() => setSidebarOpen(!sidebarOpen)}
|
||||
>
|
||||
{isAbsoluteSideNavHidden && isMobile && notificationsEnabled && <NotificationBubble />}
|
||||
{isAbsoluteSideNavHidden && isMobile && <NotificationBubble />}
|
||||
</Button>
|
||||
</span>
|
||||
)}
|
||||
|
||||
<Button
|
||||
aria-label={__('Home')}
|
||||
className="header__navigation-item header__navigation-item--lbry"
|
||||
onClick={() => {
|
||||
if (history.location.pathname === '/') window.location.reload();
|
||||
}}
|
||||
// @if TARGET='app'
|
||||
onDoubleClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
// @endif
|
||||
onClick={() => pathname === '/' && window.location.reload()}
|
||||
{...homeButtonNavigationProps}
|
||||
>
|
||||
<Logo />
|
||||
|
@ -275,146 +195,60 @@ const Header = (props: Props) => {
|
|||
{/* @if process.env.DEV_CHANGELOG */}
|
||||
{history.location.pathname === '/' && (
|
||||
<Button
|
||||
title={'Changelog'}
|
||||
title="Changelog"
|
||||
className="badge--alert"
|
||||
label={'Changelog'}
|
||||
label="Changelog"
|
||||
icon={ICONS.FEEDBACK}
|
||||
onClick={() => {
|
||||
doOpenModal(MODALS.CONFIRM, {
|
||||
onClick={() =>
|
||||
openChangelog({
|
||||
title: __('Changelog'),
|
||||
subtitle: __('Warning: this is a test instance.'),
|
||||
body: <p style={{ whiteSpace: 'pre-wrap' }}>{process.env.DEV_CHANGELOG}</p>,
|
||||
onConfirm: (closeModal) => closeModal(),
|
||||
hideCancel: true,
|
||||
});
|
||||
}}
|
||||
})
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{/* @endif */}
|
||||
|
||||
{!authHeader && (
|
||||
<div className="header__center">
|
||||
{/* @if TARGET='app' */}
|
||||
{!authHeader && (
|
||||
<div className="header__buttons">
|
||||
<NavigationButton isBackward history={history} />
|
||||
<NavigationButton isBackward={false} history={history} />
|
||||
</div>
|
||||
)}
|
||||
{/* @endif */}
|
||||
|
||||
{!authHeader && <WunderBar />}
|
||||
|
||||
<HeaderMenuButtons
|
||||
authenticated={authenticated}
|
||||
notificationsEnabled={notificationsEnabled}
|
||||
history={history}
|
||||
handleThemeToggle={handleThemeToggle}
|
||||
currentTheme={currentTheme}
|
||||
livestreamEnabled={livestreamEnabled}
|
||||
/>
|
||||
<WunderBar />
|
||||
<HeaderMenuButtons />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{!authHeader && !backout ? (
|
||||
<div className={classnames('header__menu', { 'header__menu--with-balance': !IS_WEB || authenticated })}>
|
||||
{(!IS_WEB || authenticated) && (
|
||||
<BalanceButton className="header__navigation-item menu__title mobile-hidden" />
|
||||
)}
|
||||
{!authHeader && !canBackout
|
||||
? userButtons('header__navigation-item menu__title mobile-hidden')
|
||||
: !isVerifyPage &&
|
||||
!hideCancel && (
|
||||
<div className="header__menu">
|
||||
{/* Add an empty span here so we can use the same style as above */}
|
||||
{/* This pushes the close button to the right side */}
|
||||
<span />
|
||||
|
||||
{IS_WEB && !authenticated && loginButtons}
|
||||
<Button
|
||||
title={__('Go Back')}
|
||||
button="alt"
|
||||
// className="button--header-close"
|
||||
icon={ICONS.REMOVE}
|
||||
onClick={() => {
|
||||
clearEmailEntry();
|
||||
clearPasswordEntry();
|
||||
|
||||
{(authenticated || !IS_WEB) && (
|
||||
<Menu>
|
||||
<MenuButton
|
||||
aria-label={__('Your account')}
|
||||
title={__('Your account')}
|
||||
className={classnames('header__navigation-item', {
|
||||
'menu__title header__navigation-item--icon': !activeChannelUrl,
|
||||
'header__navigation-item--profile-pic': activeChannelUrl,
|
||||
})}
|
||||
// @if TARGET='app'
|
||||
onDoubleClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (syncError) signOut();
|
||||
|
||||
if ((isSignInPage && !emailToVerify) || isSignUpPage || isPwdResetPage) {
|
||||
goBack();
|
||||
} else {
|
||||
push('/');
|
||||
}
|
||||
}}
|
||||
// @endif
|
||||
>
|
||||
{activeChannelUrl ? (
|
||||
<ChannelThumbnail uri={activeChannelUrl} small noLazyLoad />
|
||||
) : (
|
||||
<Icon size={18} icon={ICONS.ACCOUNT} aria-hidden />
|
||||
)}
|
||||
</MenuButton>
|
||||
<MenuList className="menu__list--header">
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${PAGES.UPLOADS}`}>
|
||||
<Icon aria-hidden icon={ICONS.PUBLISH} />
|
||||
{__('Uploads')}
|
||||
</MenuLink>
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${PAGES.CHANNELS}`}>
|
||||
<Icon aria-hidden icon={ICONS.CHANNEL} />
|
||||
{__('Channels')}
|
||||
</MenuLink>
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${PAGES.CREATOR_DASHBOARD}`}>
|
||||
<Icon aria-hidden icon={ICONS.ANALYTICS} />
|
||||
{__('Creator Analytics')}
|
||||
</MenuLink>
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${PAGES.REWARDS}`}>
|
||||
<Icon aria-hidden icon={ICONS.REWARDS} />
|
||||
{__('Rewards')}
|
||||
</MenuLink>
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${PAGES.INVITE}`}>
|
||||
<Icon aria-hidden icon={ICONS.INVITE} />
|
||||
{__('Invites')}
|
||||
</MenuLink>
|
||||
|
||||
{authenticated ? (
|
||||
<MenuItem onSelect={IS_WEB ? signOut : () => doOpenModal(MODALS.SIGN_OUT)}>
|
||||
<div className="menu__link">
|
||||
<Icon aria-hidden icon={ICONS.SIGN_OUT} />
|
||||
{__('Sign Out')}
|
||||
</div>
|
||||
<span className="menu__link-help">{email}</span>
|
||||
</MenuItem>
|
||||
) : !IS_WEB ? (
|
||||
<>
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${PAGES.AUTH}`}>
|
||||
<Icon aria-hidden icon={ICONS.SIGN_UP} />
|
||||
{__('Sign Up')}
|
||||
</MenuLink>
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${PAGES.AUTH_SIGNIN}`}>
|
||||
<Icon aria-hidden icon={ICONS.SIGN_IN} />
|
||||
{__('Sign In')}
|
||||
</MenuLink>
|
||||
</>
|
||||
) : null}
|
||||
</MenuList>
|
||||
</Menu>
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
!isVerifyPage &&
|
||||
!hideCancel && (
|
||||
<div className="header__menu">
|
||||
{/* Add an empty span here so we can use the same style as above */}
|
||||
{/* This pushes the close button to the right side */}
|
||||
<span />
|
||||
|
||||
<Button
|
||||
title={__('Go Back')}
|
||||
button="alt"
|
||||
// className="button--header-close"
|
||||
icon={ICONS.REMOVE}
|
||||
{...closeButtonNavigationProps}
|
||||
// @if TARGET='app'
|
||||
onDoubleClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
// @endif
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
@ -422,92 +256,4 @@ const Header = (props: Props) => {
|
|||
);
|
||||
};
|
||||
|
||||
type HeaderMenuButtonProps = {
|
||||
authenticated: boolean,
|
||||
notificationsEnabled: boolean,
|
||||
history: { push: (string) => void },
|
||||
handleThemeToggle: (string) => void,
|
||||
currentTheme: string,
|
||||
livestreamEnabled: boolean,
|
||||
};
|
||||
|
||||
function HeaderMenuButtons(props: HeaderMenuButtonProps) {
|
||||
const { authenticated, notificationsEnabled, handleThemeToggle, currentTheme, livestreamEnabled } = props;
|
||||
|
||||
return (
|
||||
<div className="header__buttons">
|
||||
{(authenticated || !IS_WEB) && (
|
||||
<Menu>
|
||||
<MenuButton
|
||||
aria-label={__('Publish a file, or create a channel')}
|
||||
title={__('Publish a file, or create a channel')}
|
||||
className="header__navigation-item menu__title header__navigation-item--icon mobile-hidden"
|
||||
// @if TARGET='app'
|
||||
onDoubleClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
// @endif
|
||||
>
|
||||
<Icon size={18} icon={ICONS.PUBLISH} aria-hidden />
|
||||
</MenuButton>
|
||||
|
||||
<MenuList className="menu__list--header">
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${PAGES.UPLOAD}`}>
|
||||
<Icon aria-hidden icon={ICONS.PUBLISH} />
|
||||
{__('Upload')}
|
||||
</MenuLink>
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${PAGES.CHANNEL_NEW}`}>
|
||||
<Icon aria-hidden icon={ICONS.CHANNEL} />
|
||||
{__('New Channel')}
|
||||
</MenuLink>
|
||||
{/* @if TARGET='web' */}
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${PAGES.YOUTUBE_SYNC}`}>
|
||||
<Icon aria-hidden icon={ICONS.YOUTUBE} />
|
||||
{__('Sync YouTube Channel')}
|
||||
</MenuLink>
|
||||
{/* @endif */}
|
||||
{livestreamEnabled && (
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${PAGES.LIVESTREAM}`}>
|
||||
<Icon aria-hidden icon={ICONS.VIDEO} />
|
||||
{__('Go Live')}
|
||||
</MenuLink>
|
||||
)}
|
||||
</MenuList>
|
||||
</Menu>
|
||||
)}
|
||||
|
||||
{notificationsEnabled && <NotificationHeaderButton />}
|
||||
|
||||
<Menu>
|
||||
<MenuButton
|
||||
aria-label={__('Settings')}
|
||||
title={__('Settings')}
|
||||
className="header__navigation-item menu__title header__navigation-item--icon mobile-hidden"
|
||||
// @if TARGET='app'
|
||||
onDoubleClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
// @endif
|
||||
>
|
||||
<Icon size={18} icon={ICONS.SETTINGS} aria-hidden />
|
||||
</MenuButton>
|
||||
<MenuList className="menu__list--header">
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${PAGES.SETTINGS}`}>
|
||||
<Icon aria-hidden tooltip icon={ICONS.SETTINGS} />
|
||||
{__('Settings')}
|
||||
</MenuLink>
|
||||
<MenuLink className="menu__link" as={Link} to={`/$/${PAGES.HELP}`}>
|
||||
<Icon aria-hidden icon={ICONS.HELP} />
|
||||
{__('Help')}
|
||||
</MenuLink>
|
||||
<MenuItem className="menu__link" onSelect={handleThemeToggle}>
|
||||
<Icon icon={currentTheme === 'light' ? ICONS.DARK : ICONS.LIGHT} />
|
||||
{currentTheme === 'light' ? __('Dark') : __('Light')}
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default withRouter(Header);
|
||||
|
|
24
ui/component/headerMenuButtons/index.js
Normal file
24
ui/component/headerMenuButtons/index.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { doSetClientSetting } from 'redux/actions/settings';
|
||||
import { selectActiveChannelStakedLevel } from 'redux/selectors/app';
|
||||
import { selectClientSetting } from 'redux/selectors/settings';
|
||||
import * as SETTINGS from 'constants/settings';
|
||||
import HeaderMenuButtons from './view';
|
||||
import { selectUserVerifiedEmail, selectUser } from 'redux/selectors/user';
|
||||
|
||||
const select = (state) => ({
|
||||
activeChannelStakedLevel: selectActiveChannelStakedLevel(state),
|
||||
authenticated: selectUserVerifiedEmail(state),
|
||||
automaticDarkModeEnabled: selectClientSetting(state, SETTINGS.AUTOMATIC_DARK_MODE_ENABLED),
|
||||
currentTheme: selectClientSetting(state, SETTINGS.THEME),
|
||||
user: selectUser(state),
|
||||
});
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
handleThemeToggle: (automaticDarkModeEnabled, currentTheme) => {
|
||||
if (automaticDarkModeEnabled) dispatch(doSetClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, false));
|
||||
dispatch(doSetClientSetting(SETTINGS.THEME, currentTheme === 'dark' ? 'light' : 'dark', true));
|
||||
},
|
||||
});
|
||||
|
||||
export default connect(select, perform)(HeaderMenuButtons);
|
82
ui/component/headerMenuButtons/view.jsx
Normal file
82
ui/component/headerMenuButtons/view.jsx
Normal file
|
@ -0,0 +1,82 @@
|
|||
// @flow
|
||||
import { ENABLE_UI_NOTIFICATIONS, ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM } from 'config';
|
||||
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import * as PAGES from 'constants/pages';
|
||||
import HeaderMenuLink from 'component/common/header-menu-link';
|
||||
import Icon from 'component/common/icon';
|
||||
import NotificationHeaderButton from 'component/notificationHeaderButton';
|
||||
import React from 'react';
|
||||
|
||||
type HeaderMenuButtonProps = {
|
||||
activeChannelStakedLevel: number,
|
||||
authenticated: boolean,
|
||||
automaticDarkModeEnabled: boolean,
|
||||
currentTheme: string,
|
||||
user: ?User,
|
||||
handleThemeToggle: (boolean, string) => void,
|
||||
};
|
||||
|
||||
export default function HeaderMenuButtons(props: HeaderMenuButtonProps) {
|
||||
const {
|
||||
authenticated,
|
||||
automaticDarkModeEnabled,
|
||||
currentTheme,
|
||||
activeChannelStakedLevel,
|
||||
user,
|
||||
handleThemeToggle,
|
||||
} = props;
|
||||
|
||||
const notificationsEnabled = ENABLE_UI_NOTIFICATIONS || (user && user.experimental_ui);
|
||||
const livestreamEnabled = Boolean(
|
||||
ENABLE_NO_SOURCE_CLAIMS &&
|
||||
user &&
|
||||
!user.odysee_live_disabled &&
|
||||
(activeChannelStakedLevel >= CHANNEL_STAKED_LEVEL_LIVESTREAM || user.odysee_live_enabled)
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="header__buttons">
|
||||
{authenticated && (
|
||||
<Menu>
|
||||
<MenuButton
|
||||
aria-label={__('Publish a file, or create a channel')}
|
||||
title={__('Publish a file, or create a channel')}
|
||||
className="header__navigation-item menu__title header__navigation-item--icon mobile-hidden"
|
||||
>
|
||||
<Icon size={18} icon={ICONS.PUBLISH} aria-hidden />
|
||||
</MenuButton>
|
||||
|
||||
<MenuList className="menu__list--header">
|
||||
<HeaderMenuLink page={PAGES.UPLOAD} icon={ICONS.PUBLISH} name={__('Upload')} />
|
||||
<HeaderMenuLink page={PAGES.CHANNEL_NEW} icon={ICONS.CHANNEL} name={__('New Channel')} />
|
||||
<HeaderMenuLink page={PAGES.YOUTUBE_SYNC} icon={ICONS.YOUTUBE} name={__('Sync YouTube Channel')} />
|
||||
{livestreamEnabled && <HeaderMenuLink page={PAGES.LIVESTREAM} icon={ICONS.VIDEO} name={__('Go Live')} />}
|
||||
</MenuList>
|
||||
</Menu>
|
||||
)}
|
||||
|
||||
{notificationsEnabled && <NotificationHeaderButton />}
|
||||
|
||||
<Menu>
|
||||
<MenuButton
|
||||
aria-label={__('Settings')}
|
||||
title={__('Settings')}
|
||||
className="header__navigation-item menu__title header__navigation-item--icon mobile-hidden"
|
||||
>
|
||||
<Icon size={18} icon={ICONS.SETTINGS} aria-hidden />
|
||||
</MenuButton>
|
||||
|
||||
<MenuList className="menu__list--header">
|
||||
<HeaderMenuLink page={PAGES.SETTINGS} icon={ICONS.SETTINGS} name={__('Settings')} />
|
||||
<HeaderMenuLink page={PAGES.HELP} icon={ICONS.HELP} name={__('Help')} />
|
||||
|
||||
<MenuItem className="menu__link" onSelect={() => handleThemeToggle(automaticDarkModeEnabled, currentTheme)}>
|
||||
<Icon icon={currentTheme === 'light' ? ICONS.DARK : ICONS.LIGHT} />
|
||||
{currentTheme === 'light' ? __('Dark') : __('Light')}
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
}
|
16
ui/component/headerProfileMenuButton/index.js
Normal file
16
ui/component/headerProfileMenuButton/index.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { doSignOut } from 'redux/actions/app';
|
||||
import { selectActiveChannelClaim } from 'redux/selectors/app';
|
||||
import { selectUserEmail } from 'redux/selectors/user';
|
||||
import HeaderProfileMenuButton from './view';
|
||||
|
||||
const select = (state) => ({
|
||||
activeChannelClaim: selectActiveChannelClaim(state),
|
||||
email: selectUserEmail(state),
|
||||
});
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
signOut: () => dispatch(doSignOut()),
|
||||
});
|
||||
|
||||
export default connect(select, perform)(HeaderProfileMenuButton);
|
58
ui/component/headerProfileMenuButton/view.jsx
Normal file
58
ui/component/headerProfileMenuButton/view.jsx
Normal file
|
@ -0,0 +1,58 @@
|
|||
// @flow
|
||||
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import * as PAGES from 'constants/pages';
|
||||
import ChannelThumbnail from 'component/channelThumbnail';
|
||||
import classnames from 'classnames';
|
||||
import HeaderMenuLink from 'component/common/header-menu-link';
|
||||
import Icon from 'component/common/icon';
|
||||
import React from 'react';
|
||||
|
||||
type HeaderMenuButtonProps = {
|
||||
activeChannelClaim: ?ChannelClaim,
|
||||
email: ?string,
|
||||
signOut: () => void,
|
||||
};
|
||||
|
||||
export default function HeaderProfileMenuButton(props: HeaderMenuButtonProps) {
|
||||
const { activeChannelClaim, email, signOut } = props;
|
||||
|
||||
const activeChannelUrl = activeChannelClaim && activeChannelClaim.permanent_url;
|
||||
|
||||
return (
|
||||
<div className="header__buttons">
|
||||
<Menu>
|
||||
<MenuButton
|
||||
aria-label={__('Your account')}
|
||||
title={__('Your account')}
|
||||
className={classnames('header__navigation-item', {
|
||||
'menu__title header__navigation-item--icon': !activeChannelUrl,
|
||||
'header__navigation-item--profile-pic': activeChannelUrl,
|
||||
})}
|
||||
>
|
||||
{activeChannelUrl ? (
|
||||
<ChannelThumbnail uri={activeChannelUrl} small noLazyLoad />
|
||||
) : (
|
||||
<Icon size={18} icon={ICONS.ACCOUNT} aria-hidden />
|
||||
)}
|
||||
</MenuButton>
|
||||
|
||||
<MenuList className="menu__list--header">
|
||||
<HeaderMenuLink page={PAGES.UPLOADS} icon={ICONS.PUBLISH} name={__('Uploads')} />
|
||||
<HeaderMenuLink page={PAGES.CHANNELS} icon={ICONS.CHANNEL} name={__('Channels')} />
|
||||
<HeaderMenuLink page={PAGES.CREATOR_DASHBOARD} icon={ICONS.ANALYTICS} name={__('Creator Analytics')} />
|
||||
<HeaderMenuLink page={PAGES.REWARDS} icon={ICONS.REWARDS} name={__('Rewards')} />
|
||||
<HeaderMenuLink page={PAGES.INVITE} icon={ICONS.INVITE} name={__('Invites')} />
|
||||
|
||||
<MenuItem onSelect={signOut}>
|
||||
<div className="menu__link">
|
||||
<Icon aria-hidden icon={ICONS.SIGN_OUT} />
|
||||
{__('Sign Out')}
|
||||
</div>
|
||||
<span className="menu__link-help">{email}</span>
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
import NavigationButton from './view';
|
||||
|
||||
export default NavigationButton;
|
|
@ -1,97 +0,0 @@
|
|||
// @flow
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import Button from 'component/button';
|
||||
|
||||
// the maximum length of history to show per button
|
||||
const MAX_HISTORY_SIZE = 12;
|
||||
|
||||
type Props = {
|
||||
isBackward: boolean,
|
||||
history: {
|
||||
entries: Array<{ key: string, title: string, pathname: string }>,
|
||||
go: number => void,
|
||||
goBack: () => void,
|
||||
goForward: () => void,
|
||||
index: number,
|
||||
length: number,
|
||||
location: { pathname: string },
|
||||
push: string => void,
|
||||
},
|
||||
};
|
||||
|
||||
// determines which slice of entries should make up the back or forward button drop-downs (isBackward vs !isBackward respectively)
|
||||
const sliceEntries = (currentIndex, entries, historyLength, isBackward, maxSize) => {
|
||||
let l = isBackward ? 0 : currentIndex + 1;
|
||||
let r = isBackward ? currentIndex : historyLength;
|
||||
const exceedsMax = maxSize < r - l;
|
||||
if (!exceedsMax) {
|
||||
return entries.slice(l, r);
|
||||
} else if (isBackward) {
|
||||
l = r - maxSize;
|
||||
} else {
|
||||
r = l + maxSize;
|
||||
}
|
||||
return entries.slice(l, r);
|
||||
};
|
||||
|
||||
const NavigationButton = (props: Props) => {
|
||||
const { isBackward, history } = props;
|
||||
const { entries, go } = history;
|
||||
const currentIndex = history.index;
|
||||
const historyLength = history.length;
|
||||
const [showHistory, setShowHistory] = useState(false);
|
||||
|
||||
// creates an <li> intended for the button's <ul>
|
||||
const makeItem = useCallback(
|
||||
(entry: { pathname: string, title: string, key: string }, index: number) => {
|
||||
// difference between the current index and the index of the entry
|
||||
const backwardDif = index - (currentIndex < MAX_HISTORY_SIZE ? currentIndex : MAX_HISTORY_SIZE);
|
||||
const forwardDif = index + 1;
|
||||
return (
|
||||
<li
|
||||
className="header__navigation-button"
|
||||
role="link"
|
||||
key={entry.key}
|
||||
onMouseDown={() => {
|
||||
setShowHistory(false);
|
||||
go(isBackward ? backwardDif : forwardDif);
|
||||
}}
|
||||
>
|
||||
<span>{entry.title}</span>
|
||||
<span className="header__navigation-button-help">{entry.pathname === '/' ? __('Home') : entry.pathname}</span>
|
||||
</li>
|
||||
);
|
||||
},
|
||||
[currentIndex, isBackward, go]
|
||||
);
|
||||
const slicedEntries = sliceEntries(currentIndex, entries, historyLength, isBackward, MAX_HISTORY_SIZE);
|
||||
return (
|
||||
<div
|
||||
// @if TARGET='app'
|
||||
onDoubleClick={e => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
// @endif
|
||||
>
|
||||
<Button
|
||||
className={`header__navigation-item header__navigation-item--${isBackward ? 'back' : 'forward'}`}
|
||||
description={isBackward ? __('Navigate back') : __('Navigate forward')}
|
||||
onBlur={() => setShowHistory(false)}
|
||||
onClick={() => (isBackward ? history.goBack() : history.goForward())}
|
||||
onContextMenu={e => {
|
||||
setShowHistory(!showHistory);
|
||||
// the following three lines prevent the regular context menu (right click menu) from appearing
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
}}
|
||||
icon={isBackward ? ICONS.ARROW_LEFT : ICONS.ARROW_RIGHT}
|
||||
iconSize={18}
|
||||
disabled={slicedEntries.length === 0}
|
||||
/>
|
||||
{showHistory && <ul className={'header__navigation-dropdown'}>{slicedEntries.map(makeItem)}</ul>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default NavigationButton;
|
|
@ -35,7 +35,6 @@ export const WALLET_PASSWORD_UNSAVE = 'wallet_password_unsave';
|
|||
export const CREATE_CHANNEL = 'create_channel';
|
||||
export const YOUTUBE_WELCOME = 'youtube_welcome';
|
||||
export const SET_REFERRER = 'set_referrer';
|
||||
export const SIGN_OUT = 'sign_out';
|
||||
export const LIQUIDATE_SUPPORTS = 'liquidate_supports';
|
||||
export const MASS_TIP_UNLOCK = 'mass_tip_unlock';
|
||||
export const CONFIRM_AGE = 'confirm_age';
|
||||
|
|
|
@ -73,7 +73,6 @@ const ModalRevokeClaim = lazyImport(() => import('modal/modalRevokeClaim' /* web
|
|||
const ModalRewardCode = lazyImport(() => import('modal/modalRewardCode' /* webpackChunkName: "modalRewardCode" */));
|
||||
const ModalSendTip = lazyImport(() => import('modal/modalSendTip' /* webpackChunkName: "modalSendTip" */));
|
||||
const ModalSetReferrer = lazyImport(() => import('modal/modalSetReferrer' /* webpackChunkName: "modalSetReferrer" */));
|
||||
const ModalSignOut = lazyImport(() => import('modal/modalSignOut' /* webpackChunkName: "modalSignOut" */));
|
||||
const ModalSocialShare = lazyImport(() => import('modal/modalSocialShare' /* webpackChunkName: "modalSocialShare" */));
|
||||
const ModalSupportsLiquidate = lazyImport(() =>
|
||||
import('modal/modalSupportsLiquidate' /* webpackChunkName: "modalSupportsLiquidate" */)
|
||||
|
@ -157,8 +156,6 @@ function getModal(id) {
|
|||
return ModalYoutubeWelcome;
|
||||
case MODALS.SET_REFERRER:
|
||||
return ModalSetReferrer;
|
||||
case MODALS.SIGN_OUT:
|
||||
return ModalSignOut;
|
||||
case MODALS.CONFIRM_AGE:
|
||||
return ModalConfirmAge;
|
||||
case MODALS.FILE_SELECTION:
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { doSignOut, doHideModal } from 'redux/actions/app';
|
||||
import ModalSignOut from './view';
|
||||
|
||||
export default connect(null, {
|
||||
doSignOut,
|
||||
doHideModal,
|
||||
})(ModalSignOut);
|
|
@ -1,47 +0,0 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { Modal } from 'modal/modal';
|
||||
import Card from 'component/common/card';
|
||||
import Button from 'component/button';
|
||||
import I18nMessage from 'component/i18nMessage';
|
||||
|
||||
type Props = {
|
||||
doHideModal: () => void,
|
||||
doSignOut: () => void,
|
||||
};
|
||||
|
||||
function ModalRepost(props: Props) {
|
||||
const { doHideModal, doSignOut } = props;
|
||||
|
||||
return (
|
||||
<Modal isOpen type="card">
|
||||
<Card
|
||||
title={__('Sign out')}
|
||||
subtitle={
|
||||
<I18nMessage
|
||||
tokens={{
|
||||
rename_wallet_instructions: (
|
||||
<Button
|
||||
button="link"
|
||||
label={__('rename your existing wallet')}
|
||||
href="https://lbry.com/faq/lbry-directories"
|
||||
/>
|
||||
),
|
||||
}}
|
||||
>
|
||||
Your wallet data will remain intact. If you sign in with a different account, the wallets will be merged. To
|
||||
prevent this, you need to %rename_wallet_instructions% in the lbry/wallets directory.
|
||||
</I18nMessage>
|
||||
}
|
||||
actions={
|
||||
<div className="section__actions">
|
||||
<Button button="primary" label={__('Sign Out')} onClick={doSignOut} />
|
||||
<Button button="link" label={__('Cancel')} onClick={doHideModal} />
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default ModalRepost;
|
Loading…
Reference in a new issue