From 3311e1af1f420b8e9660296c9cc018c3e9a206bd Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 21 Aug 2019 16:54:44 -0400 Subject: [PATCH] header changes with sign in/sign out --- src/platforms/web/stubs.js | 3 + src/ui/component/common/icon-custom.jsx | 7 + src/ui/component/header/index.js | 3 +- src/ui/component/header/view.jsx | 141 ++++++++++++------ src/ui/component/router/view.jsx | 4 +- src/ui/component/sideBar/index.js | 2 + src/ui/component/sideBar/view.jsx | 91 +++++------ .../wunderbar/internal/autocomplete.jsx | 6 +- src/ui/constants/icons.js | 1 + src/ui/index.jsx | 2 +- src/ui/modal/modalAuthFailure/index.js | 14 -- src/ui/modal/modalAuthFailure/view.jsx | 32 ---- src/ui/modal/modalRouter/view.jsx | 3 - src/ui/redux/reducers/app.js | 9 -- src/ui/scss/component/_animation.scss | 11 ++ src/ui/scss/component/_header.scss | 12 +- src/ui/scss/component/_navigation.scss | 8 +- src/ui/scss/component/_wunderbar.scss | 3 +- src/ui/scss/component/menu-button.scss | 19 ++- src/ui/scss/init/_vars.scss | 3 +- 20 files changed, 204 insertions(+), 170 deletions(-) delete mode 100644 src/ui/modal/modalAuthFailure/index.js delete mode 100644 src/ui/modal/modalAuthFailure/view.jsx diff --git a/src/platforms/web/stubs.js b/src/platforms/web/stubs.js index 74e8d3c52..0ef460058 100644 --- a/src/platforms/web/stubs.js +++ b/src/platforms/web/stubs.js @@ -20,4 +20,7 @@ export const remote = { require: callable, }; +export const clipboard = {}; +export const ipcRenderer = {}; + export const isDev = false; diff --git a/src/ui/component/common/icon-custom.jsx b/src/ui/component/common/icon-custom.jsx index d0123f8d3..e98bce146 100644 --- a/src/ui/component/common/icon-custom.jsx +++ b/src/ui/component/common/icon-custom.jsx @@ -295,4 +295,11 @@ export const icons = { ), + [ICONS.SIGN_OUT]: buildIcon( + + + + + + ), }; diff --git a/src/ui/component/header/index.js b/src/ui/component/header/index.js index 12c91ad43..4cb56f16e 100644 --- a/src/ui/component/header/index.js +++ b/src/ui/component/header/index.js @@ -1,10 +1,10 @@ import * as SETTINGS from 'constants/settings'; import { connect } from 'react-redux'; import { selectBalance, SETTINGS as LBRY_REDUX_SETTINGS } from 'lbry-redux'; +import { selectUserEmail } from 'lbryinc'; import { formatCredits } from 'util/format-credits'; import { doSetClientSetting } from 'redux/actions/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings'; - import Header from './view'; const select = state => ({ @@ -14,6 +14,7 @@ const select = state => ({ currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state), automaticDarkModeEnabled: makeSelectClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED)(state), hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state), + email: selectUserEmail(state), }); const perform = dispatch => ({ diff --git a/src/ui/component/header/view.jsx b/src/ui/component/header/view.jsx index 4dbb85374..e494fc0e1 100644 --- a/src/ui/component/header/view.jsx +++ b/src/ui/component/header/view.jsx @@ -1,7 +1,8 @@ // @flow import * as ICONS from 'constants/icons'; import * as SETTINGS from 'constants/settings'; -import * as React from 'react'; +import * as PAGES from 'constants/pages'; +import React, { Fragment } from 'react'; import { withRouter } from 'react-router'; import Button from 'component/button'; import LbcSymbol from 'component/common/lbc-symbol'; @@ -9,6 +10,22 @@ import WunderBar from 'component/wunderbar'; import Icon from 'component/common/icon'; import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button'; +// Move this into jessops password util +import cookie from 'cookie'; +// @if TARGET='app' +import keytar from 'keytar'; +// @endif; +function deleteAuthToken() { + // @if TARGET='app' + keytar.deletePassword('LBRY', 'auth_token').catch(console.error); //eslint-disable-line + // @endif; + // @if TARGET='web' + document.cookie = cookie.serialize('auth_token', '', { + expires: new Date(), + }); + // @endif +} + type Props = { autoUpdateDownloaded: boolean, balance: string, @@ -20,10 +37,20 @@ type Props = { automaticDarkModeEnabled: boolean, setClientSetting: (string, boolean | string) => void, hideBalance: boolean, + email: ?string, }; const Header = (props: Props) => { - const { roundedBalance, history, setClientSetting, currentTheme, automaticDarkModeEnabled, hideBalance } = props; + const { + roundedBalance, + history, + setClientSetting, + currentTheme, + automaticDarkModeEnabled, + hideBalance, + email, + } = props; + const isAuthenticated = Boolean(email); function handleThemeToggle() { if (automaticDarkModeEnabled) { @@ -49,6 +76,12 @@ const Header = (props: Props) => { return __('Account'); } + function signOut() { + // Replace this with actual clearUser function + window.store.dispatch({ type: 'USER_FETCH_FAILURE' }); + deleteAuthToken(); + } + return (
@@ -78,55 +111,67 @@ const Header = (props: Props) => { />
{/* @endif */} + - +
+ {isAuthenticated ? ( + + + + + {getAccountTitle()} + + + history.push(`/$/account`)}> + + {__('Overview')} + + history.push(`/$/rewards`)}> + + {__('Rewards')} + + history.push(`/$/wallet`)}> + + {__('Wallet')} + + history.push(`/$/publish`)}> + + {__('Publish')} + + + + {__('Sign Out')} + + + -
- - - - {getAccountTitle()} - - - history.push(`/$/account`)}> - - {__('Overview')} - - history.push(`/$/rewards`)}> - - {__('Rewards')} - - history.push(`/$/wallet`)}> - - {__('Wallet')} - - history.push(`/$/publish`)}> - - {__('Publish')} - - - - - - - - - - history.push(`/$/settings`)}> - - {__('Settings')} - - history.push(`/$/help`)}> - - {__('Help')} - - - - {currentTheme === 'light' ? 'Dark' : 'Light'} - - - + + + + + + history.push(`/$/settings`)}> + + {__('Settings')} + + history.push(`/$/help`)}> + + {__('Help')} + + + + {currentTheme === 'light' ? 'Dark' : 'Light'} + + + + + ) : ( + +
diff --git a/src/ui/component/router/view.jsx b/src/ui/component/router/view.jsx index 6656a9f23..5d99450de 100644 --- a/src/ui/component/router/view.jsx +++ b/src/ui/component/router/view.jsx @@ -24,6 +24,8 @@ import FollowingPage from 'page/following'; import ListBlocked from 'page/listBlocked'; import FourOhFourPage from 'page/fourOhFour'; +import UserEmail from 'component/userEmail'; + // Tell the browser we are handling scroll restoration if ('scrollRestoration' in history) { history.scrollRestoration = 'manual'; @@ -35,7 +37,7 @@ type Props = { }; function SignInPage() { - return

Sign In

; + return ; } function SignUpPage() { diff --git a/src/ui/component/sideBar/index.js b/src/ui/component/sideBar/index.js index 2e2519897..32bbf837e 100644 --- a/src/ui/component/sideBar/index.js +++ b/src/ui/component/sideBar/index.js @@ -2,6 +2,7 @@ import * as SETTINGS from 'constants/settings'; import { connect } from 'react-redux'; import { selectSubscriptions } from 'redux/selectors/subscriptions'; import { selectFollowedTags } from 'lbry-redux'; +import { selectUserEmail } from 'lbryinc'; import SideBar from './view'; import { makeSelectClientSetting } from 'redux/selectors/settings'; @@ -9,6 +10,7 @@ const select = state => ({ subscriptions: selectSubscriptions(state), followedTags: selectFollowedTags(state), language: makeSelectClientSetting(SETTINGS.LANGUAGE)(state), // trigger redraw on language change + email: selectUserEmail(state), }); const perform = () => ({}); diff --git a/src/ui/component/sideBar/view.jsx b/src/ui/component/sideBar/view.jsx index 552a2a00d..38d6a271b 100644 --- a/src/ui/component/sideBar/view.jsx +++ b/src/ui/component/sideBar/view.jsx @@ -9,10 +9,11 @@ import StickyBox from 'react-sticky-box/dist/esnext'; type Props = { subscriptions: Array, followedTags: Array, + email: ?string, }; function SideBar(props: Props) { - const { subscriptions, followedTags } = props; + const { subscriptions, followedTags, email } = props; function buildLink(path, label, icon, guide) { return { @@ -25,47 +26,53 @@ function SideBar(props: Props) { return ( - + {email ? ( + + ) : ( +
+ )} ); } diff --git a/src/ui/component/wunderbar/internal/autocomplete.jsx b/src/ui/component/wunderbar/internal/autocomplete.jsx index c24c556c5..7c1f0d378 100644 --- a/src/ui/component/wunderbar/internal/autocomplete.jsx +++ b/src/ui/component/wunderbar/internal/autocomplete.jsx @@ -1,3 +1,4 @@ +/* eslint-disable */ /* This is taken from https://github.com/reactjs/react-autocomplete @@ -208,7 +209,7 @@ export default class Autocomplete extends React.Component { this.maybeAutoCompleteText = this.maybeAutoCompleteText.bind(this); } - componentWillMount() { + UNSAFE_componentWillMount() { // this.refs is frozen, so we need to assign a new object to it this.refs = {}; this._ignoreBlur = false; @@ -222,7 +223,7 @@ export default class Autocomplete extends React.Component { this._scrollTimer = null; } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { if (this.state.highlightedIndex !== null) { this.setState(this.ensureHighlightedIndex); } @@ -585,3 +586,4 @@ export default class Autocomplete extends React.Component { ); } } +/* eslint-enable */ diff --git a/src/ui/constants/icons.js b/src/ui/constants/icons.js index b2a88790f..31191ef78 100644 --- a/src/ui/constants/icons.js +++ b/src/ui/constants/icons.js @@ -75,3 +75,4 @@ export const UNBLOCK = 'Circle'; export const VIEW = 'View'; export const EYE = 'Eye'; export const EYE_OFF = 'EyeOff'; +export const SIGN_OUT = 'SignOut'; diff --git a/src/ui/index.jsx b/src/ui/index.jsx index 9a30e57a6..3a96dc8bf 100644 --- a/src/ui/index.jsx +++ b/src/ui/index.jsx @@ -82,7 +82,7 @@ Lbryio.setOverride( authToken = newAuthToken; // @if TARGET='web' - document.cookie = cookie.serialize('auth_token', authToken, { + cookie.serialize('auth_token', authToken, { maxAge: COOKIE_EXPIRE_TIME, }); // @endif diff --git a/src/ui/modal/modalAuthFailure/index.js b/src/ui/modal/modalAuthFailure/index.js deleted file mode 100644 index ed984b8b1..000000000 --- a/src/ui/modal/modalAuthFailure/index.js +++ /dev/null @@ -1,14 +0,0 @@ -import { connect } from 'react-redux'; -import { doHideModal } from 'redux/actions/app'; -import ModalAuthFailure from './view'; - -const select = () => ({}); - -const perform = dispatch => ({ - close: () => dispatch(doHideModal()), -}); - -export default connect( - select, - perform -)(ModalAuthFailure); diff --git a/src/ui/modal/modalAuthFailure/view.jsx b/src/ui/modal/modalAuthFailure/view.jsx deleted file mode 100644 index 90848ce9d..000000000 --- a/src/ui/modal/modalAuthFailure/view.jsx +++ /dev/null @@ -1,32 +0,0 @@ -// @flow -import React from 'react'; -import { Modal } from 'modal/modal'; - -type Props = { - close: () => void, -}; - -class ModalAuthFailure extends React.PureComponent { - render() { - const { close } = this.props; - - return ( - { - window.location.reload(); - }} - onAborted={close} - > -

{__('If reloading does not fix this, or you see this at every start up, please email help@lbry.com.')}

-
- ); - } -} - -export default ModalAuthFailure; diff --git a/src/ui/modal/modalRouter/view.jsx b/src/ui/modal/modalRouter/view.jsx index 25a81cc04..013da8be5 100644 --- a/src/ui/modal/modalRouter/view.jsx +++ b/src/ui/modal/modalRouter/view.jsx @@ -2,7 +2,6 @@ import React from 'react'; import * as MODALS from 'constants/modal_types'; import ModalError from 'modal/modalError'; -import ModalAuthFailure from 'modal/modalAuthFailure'; import ModalDownloading from 'modal/modalDownloading'; import ModalAutoGenerateThumbnail from 'modal/modalAutoGenerateThumbnail'; import ModalAutoUpdateDownloaded from 'modal/modalAutoUpdateDownloaded'; @@ -67,8 +66,6 @@ function ModalRouter(props: Props) { return ; case MODALS.FIRST_REWARD: return ; - case MODALS.AUTHENTICATION_FAILURE: - return ; case MODALS.TRANSACTION_FAILED: return ; case MODALS.REWARD_APPROVAL_REQUIRED: diff --git a/src/ui/redux/reducers/app.js b/src/ui/redux/reducers/app.js index 2517cc442..5746fddd3 100644 --- a/src/ui/redux/reducers/app.js +++ b/src/ui/redux/reducers/app.js @@ -1,7 +1,6 @@ // @flow import * as ACTIONS from 'constants/action_types'; -import * as MODALS from 'constants/modal_types'; import { remote } from 'electron'; // @if TARGET='app' @@ -251,14 +250,6 @@ reducers[ACTIONS.HIDE_MODAL] = state => modalProps: null, }); -// This is fired from the lbryinc module -// Instead of adding callbacks in that module, we can just listen for this event -// There will be no other modals at this time as this is a blocking action -reducers[ACTIONS.AUTHENTICATION_FAILURE] = state => - Object.assign({}, state, { - modal: MODALS.AUTHENTICATION_FAILURE, - }); - reducers[ACTIONS.TOGGLE_SEARCH_EXPANDED] = state => Object.assign({}, state, { searchOptionsExpanded: !state.searchOptionsExpanded, diff --git a/src/ui/scss/component/_animation.scss b/src/ui/scss/component/_animation.scss index fe2878ac5..18e767679 100644 --- a/src/ui/scss/component/_animation.scss +++ b/src/ui/scss/component/_animation.scss @@ -67,3 +67,14 @@ width: 0; } } + +@keyframes menu-animate-in { + 0% { + transform: scaleY(0); + opacity: 0; + } + 100% { + transform: scaleY(1); + opacity: 1; + } +} diff --git a/src/ui/scss/component/_header.scss b/src/ui/scss/component/_header.scss index 5def79c3d..9ae8fff98 100644 --- a/src/ui/scss/component/_header.scss +++ b/src/ui/scss/component/_header.scss @@ -24,14 +24,13 @@ max-width: var(--page-max-width); height: calc(var(--header-height) - 1px); display: flex; - justify-content: space-between; margin: auto; padding: 0 var(--spacing-large); } .header__navigation { + flex: 1; display: flex; - justify-content: space-between; &:last-of-type { width: var(--side-nav-width); @@ -42,6 +41,14 @@ } } +.header__menu { + width: var(--side-nav-width); + margin-left: auto; + display: flex; + justify-content: space-between; + align-items: center; +} + .header__navigation-arrows { display: flex; margin-right: var(--spacing-small); @@ -126,7 +133,6 @@ } .header__navigation-item--lbry { - flex: 1; font-weight: 800; margin-right: var(--spacing-medium); diff --git a/src/ui/scss/component/_navigation.scss b/src/ui/scss/component/_navigation.scss index 92a60e992..af2877767 100644 --- a/src/ui/scss/component/_navigation.scss +++ b/src/ui/scss/component/_navigation.scss @@ -1,13 +1,19 @@ .navigation { width: var(--side-nav-width); font-size: var(--font-body); - // padding-top: 100px; @media (max-width: 600px) { display: none; } } +.navigation--placeholder { + @extend .navigation; + height: 80vh; + background-color: $lbry-blue-1; + border-radius: var(--card-radius); +} + .navigation-links { @extend .ul--no-style; flex-direction: column; diff --git a/src/ui/scss/component/_wunderbar.scss b/src/ui/scss/component/_wunderbar.scss index bbda27414..14c5ab443 100644 --- a/src/ui/scss/component/_wunderbar.scss +++ b/src/ui/scss/component/_wunderbar.scss @@ -1,10 +1,9 @@ .wunderbar { - min-width: 175px; + flex: 1; height: 100%; cursor: text; display: flex; align-items: center; - flex: 1; position: relative; z-index: 1; margin-right: var(--spacing-main-padding); diff --git a/src/ui/scss/component/menu-button.scss b/src/ui/scss/component/menu-button.scss index 6e40544a6..c53ed8bfd 100644 --- a/src/ui/scss/component/menu-button.scss +++ b/src/ui/scss/component/menu-button.scss @@ -17,16 +17,13 @@ white-space: nowrap; outline: none; background-color: $lbry-white; - box-shadow: var(--card-box-shadow) $lbry-gray-2; border: 1px solid $lbry-gray-1; border-top: none; [data-mode='dark'] & { background-color: var(--dm-color-05); color: $lbry-white; - box-shadow: var(--card-box-shadow) $lbry-black; - border: 1px solid $lbry-gray-5; - border-top: none; + border-color: var(--dm-color-03); } } @@ -69,13 +66,14 @@ } } -.menu__title { - &:not(:last-of-type) { - margin-right: var(--spacing-medium); - } +.menu__list--header { + margin-top: -1px; + margin-left: calc(var(--spacing-medium) * -1); + box-shadow: var(--card-box-shadow--attached) $lbry-gray-1; + animation: menu-animate-in var(--animation-duration) var(--animation-style); - span { - margin-left: var(--spacing-small); + [data-mode='dark'] & { + box-shadow: var(--card-box-shadow) $lbry-black; } } @@ -83,6 +81,7 @@ display: flex; align-items: center; padding: var(--spacing-medium); + padding-right: var(--spacing-large); } .menu__title, diff --git a/src/ui/scss/init/_vars.scss b/src/ui/scss/init/_vars.scss index edd45360c..1f2a187b9 100644 --- a/src/ui/scss/init/_vars.scss +++ b/src/ui/scss/init/_vars.scss @@ -74,7 +74,8 @@ $large-breakpoint: 1921px; // Card --card-radius: 5px; --card-max-width: 1000px; - --card-box-shadow: 0px 2px 6px 0; + --card-box-shadow: 0px 2px 6px 0px; + --card-box-shadow--attached: 0px 4px 6px 0px; // Modal --modal-width: 440px;