[Account] grab SyncToggle and AccountPassword

Also made visual changes for the new Settings Page.

## SyncToggle:
It will no longer be under a dedicated Card, so the "Sync" title is not there to give context for the case of "no verified email".

Changed it such that the checkbox is always visible (it's label is self-explanatory) but disable when email is not set. The "Add Email" button will then appear below, so everything now makes sense in context.
This commit is contained in:
infinite-persistence 2021-08-05 15:00:21 +08:00
parent 3b080012ac
commit 04b510d88b
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0
6 changed files with 144 additions and 108 deletions

View file

@ -0,0 +1,15 @@
import { connect } from 'react-redux';
import { doWalletStatus, selectWalletIsEncrypted } from 'lbry-redux';
import { selectUserVerifiedEmail } from 'redux/selectors/user';
import SettingAccount from './view';
const select = (state) => ({
isAuthenticated: selectUserVerifiedEmail(state),
walletEncrypted: selectWalletIsEncrypted(state),
});
const perform = (dispatch) => ({
doWalletStatus: () => dispatch(doWalletStatus()),
});
export default connect(select, perform)(SettingAccount);

View file

@ -0,0 +1,55 @@
// @flow
import React from 'react';
import Card from 'component/common/card';
import SettingAccountPassword from 'component/settingAccountPassword';
import SyncToggle from 'component/syncToggle';
import { getPasswordFromCookie } from 'util/saved-passwords';
type Props = {
// --- select ---
isAuthenticated: boolean,
walletEncrypted: boolean,
// --- perform ---
doWalletStatus: () => void,
};
export default function SettingAccount(props: Props) {
const { isAuthenticated, walletEncrypted, doWalletStatus } = props;
const [storedPassword, setStoredPassword] = React.useState(false);
// Determine if password is stored.
React.useEffect(() => {
if (isAuthenticated || !IS_WEB) {
doWalletStatus();
getPasswordFromCookie().then((p) => {
if (typeof p === 'string') {
setStoredPassword(true);
}
});
}
// enterSettings(); @KP need to do this at each component, or just at Settings Page?
}, []); // eslint-disable-line react-hooks/exhaustive-deps
return (
<Card
title={__('Account')}
subtitle=""
isBodyList
body={
<>
{isAuthenticated && (
<div className="card__main-actions">
<SettingAccountPassword />
</div>
)}
{/* @if TARGET='app' */}
<div className="card__main-actions">
<SyncToggle disabled={walletEncrypted && !storedPassword && storedPassword !== ''} />
</div>
{/* @endif */}
</>
}
/>
);
}

View file

@ -3,7 +3,6 @@ import React, { useState } from 'react';
import { FormField, Form } from 'component/common/form'; import { FormField, Form } from 'component/common/form';
import Button from 'component/button'; import Button from 'component/button';
import ErrorText from 'component/common/error-text'; import ErrorText from 'component/common/error-text';
import Card from 'component/common/card';
import * as PAGES from 'constants/pages'; import * as PAGES from 'constants/pages';
type Props = { type Props = {
@ -38,12 +37,7 @@ export default function SettingAccountPassword(props: Props) {
} }
}, [passwordSetSuccess, setOldPassword, setNewPassword, doClearPasswordEntry, doToast]); }, [passwordSetSuccess, setOldPassword, setNewPassword, doClearPasswordEntry, doToast]);
return ( return isAddingPassword ? (
<Card
title={__('Account password')}
subtitle={hasPassword ? '' : __('You do not currently have a password set.')}
actions={
isAddingPassword ? (
<div> <div>
<Form onSubmit={handleSubmit} className="section"> <Form onSubmit={handleSubmit} className="section">
{hasPassword && ( {hasPassword && (
@ -52,7 +46,7 @@ export default function SettingAccountPassword(props: Props) {
name="setting_set_old_password" name="setting_set_old_password"
label={__('Old Password')} label={__('Old Password')}
value={oldPassword} value={oldPassword}
onChange={e => setOldPassword(e.target.value)} onChange={(e) => setOldPassword(e.target.value)}
/> />
)} )}
<FormField <FormField
@ -60,7 +54,7 @@ export default function SettingAccountPassword(props: Props) {
name="setting_set_new_password" name="setting_set_new_password"
label={__('New Password')} label={__('New Password')}
value={newPassword} value={newPassword}
onChange={e => setNewPassword(e.target.value)} onChange={(e) => setNewPassword(e.target.value)}
/> />
<div className="section__actions"> <div className="section__actions">
@ -79,13 +73,16 @@ export default function SettingAccountPassword(props: Props) {
)} )}
</div> </div>
) : ( ) : (
<div className="section__actions--between">
<div>
<p>{__('Password')}</p>
{!hasPassword && <p className="help">{__('You do not currently have a password set.')}</p>}
</div>
<Button <Button
button="primary" button="primary"
label={hasPassword ? __('Update Your Password') : __('Add A Password')} label={hasPassword ? __('Update Your Password') : __('Add A Password')}
onClick={() => setIsAddingPassword(true)} onClick={() => setIsAddingPassword(true)}
/> />
) </div>
}
/>
); );
} }

View file

@ -6,10 +6,10 @@ import { withRouter } from 'react-router';
import { FormField } from 'component/common/form'; import { FormField } from 'component/common/form';
type Props = { type Props = {
setSyncEnabled: boolean => void, setSyncEnabled: (boolean) => void,
syncEnabled: boolean, syncEnabled: boolean,
verifiedEmail: ?string, verifiedEmail: ?string,
history: { push: string => void }, history: { push: (string) => void },
location: UrlLocation, location: UrlLocation,
getSyncError: ?string, getSyncError: ?string,
disabled: boolean, disabled: boolean,
@ -21,20 +21,24 @@ function SyncToggle(props: Props) {
return ( return (
<div> <div>
{!verifiedEmail ? (
<div>
<Button requiresAuth button="primary" label={__('Add Email')} />
<p className="help">{__('An email address is required to sync your account.')}</p>
</div>
) : (
<FormField <FormField
type="checkbox" type="checkbox"
name="sync_toggle" name="sync_toggle"
label={__('Sync your balance and preferences across devices.')} label={__('Sync your balance and preferences across devices.')}
checked={syncEnabled} checked={syncEnabled && verifiedEmail}
onChange={() => openModal(MODALS.SYNC_ENABLE, { mode: syncEnabled ? 'disable' : 'enable' })} onChange={() => openModal(MODALS.SYNC_ENABLE, { mode: syncEnabled ? 'disable' : 'enable' })}
disabled={disabled} disabled={disabled || !verifiedEmail}
helper={
disabled
? __("To enable Sync, close LBRY completely and check 'Remember Password' during wallet unlock.")
: null
}
/> />
{!verifiedEmail && (
<div>
<p className="help">{__('An email address is required to sync your account.')}</p>
<Button requiresAuth button="primary" label={__('Add Email')} />
</div>
)} )}
</div> </div>
); );

View file

@ -1,5 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doClearCache, doNotifyForgetPassword, doToggle3PAnalytics, doOpenModal } from 'redux/actions/app'; import { doClearCache, doToggle3PAnalytics, doOpenModal } from 'redux/actions/app';
import { selectAllowAnalytics } from 'redux/selectors/app'; import { selectAllowAnalytics } from 'redux/selectors/app';
import { import {
doSetDaemonSetting, doSetDaemonSetting,
@ -16,7 +16,7 @@ import {
selectLanguage, selectLanguage,
selectShowMatureContent, selectShowMatureContent,
} from 'redux/selectors/settings'; } from 'redux/selectors/settings';
import { doWalletStatus, selectMyChannelUrls, selectWalletIsEncrypted, SETTINGS } from 'lbry-redux'; import { selectMyChannelUrls, SETTINGS } from 'lbry-redux';
import SettingsPage from './view'; import SettingsPage from './view';
import { selectUserVerifiedEmail, selectUser } from 'redux/selectors/user'; import { selectUserVerifiedEmail, selectUser } from 'redux/selectors/user';
@ -30,7 +30,6 @@ const select = (state) => ({
automaticDarkModeEnabled: makeSelectClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED)(state), automaticDarkModeEnabled: makeSelectClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED)(state),
clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state), clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state),
autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY)(state), autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY)(state),
walletEncrypted: selectWalletIsEncrypted(state),
autoDownload: makeSelectClientSetting(SETTINGS.AUTO_DOWNLOAD)(state), autoDownload: makeSelectClientSetting(SETTINGS.AUTO_DOWNLOAD)(state),
hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state), hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state),
floatingPlayer: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state), floatingPlayer: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state),
@ -47,8 +46,6 @@ const perform = (dispatch) => ({
toggle3PAnalytics: (allow) => dispatch(doToggle3PAnalytics(allow)), toggle3PAnalytics: (allow) => dispatch(doToggle3PAnalytics(allow)),
clearCache: () => dispatch(doClearCache()), clearCache: () => dispatch(doClearCache()),
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
updateWalletStatus: () => dispatch(doWalletStatus()),
confirmForgetPassword: (modalProps) => dispatch(doNotifyForgetPassword(modalProps)),
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })), clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
setDarkTime: (time, options) => dispatch(doSetDarkTime(time, options)), setDarkTime: (time, options) => dispatch(doSetDarkTime(time, options)),
openModal: (id, params) => dispatch(doOpenModal(id, params)), openModal: (id, params) => dispatch(doOpenModal(id, params)),

View file

@ -7,14 +7,12 @@ import { SETTINGS } from 'lbry-redux';
import { FormField } from 'component/common/form'; import { FormField } from 'component/common/form';
import Button from 'component/button'; import Button from 'component/button';
import Page from 'component/page'; import Page from 'component/page';
import SettingAccount from 'component/settingAccount';
import SettingLanguage from 'component/settingLanguage'; import SettingLanguage from 'component/settingLanguage';
import FileSelector from 'component/common/file-selector'; import FileSelector from 'component/common/file-selector';
import SyncToggle from 'component/syncToggle';
import HomepageSelector from 'component/homepageSelector'; import HomepageSelector from 'component/homepageSelector';
import Card from 'component/common/card'; import Card from 'component/common/card';
import SettingAccountPassword from 'component/settingAccountPassword';
import classnames from 'classnames'; import classnames from 'classnames';
import { getPasswordFromCookie } from 'util/saved-passwords';
import { SIMPLE_SITE } from 'config'; import { SIMPLE_SITE } from 'config';
// $FlowFixMe // $FlowFixMe
import homepages from 'homepages'; import homepages from 'homepages';
@ -61,9 +59,6 @@ type Props = {
automaticDarkModeEnabled: boolean, automaticDarkModeEnabled: boolean,
clock24h: boolean, clock24h: boolean,
autoplay: boolean, autoplay: boolean,
updateWalletStatus: () => void,
walletEncrypted: boolean,
confirmForgetPassword: ({}) => void,
floatingPlayer: boolean, floatingPlayer: boolean,
hideReposts: ?boolean, hideReposts: ?boolean,
clearPlayingUri: () => void, clearPlayingUri: () => void,
@ -79,7 +74,6 @@ type Props = {
type State = { type State = {
clearingCache: boolean, clearingCache: boolean,
storedPassword: boolean,
}; };
class SettingsPage extends React.PureComponent<Props, State> { class SettingsPage extends React.PureComponent<Props, State> {
@ -88,26 +82,15 @@ class SettingsPage extends React.PureComponent<Props, State> {
this.state = { this.state = {
clearingCache: false, clearingCache: false,
storedPassword: false,
}; };
(this: any).onThemeChange = this.onThemeChange.bind(this); (this: any).onThemeChange = this.onThemeChange.bind(this);
(this: any).onAutomaticDarkModeChange = this.onAutomaticDarkModeChange.bind(this); (this: any).onAutomaticDarkModeChange = this.onAutomaticDarkModeChange.bind(this);
(this: any).onChangeTime = this.onChangeTime.bind(this); (this: any).onChangeTime = this.onChangeTime.bind(this);
(this: any).onConfirmForgetPassword = this.onConfirmForgetPassword.bind(this);
} }
componentDidMount() { componentDidMount() {
const { isAuthenticated, enterSettings } = this.props; const { enterSettings } = this.props;
if (isAuthenticated || !IS_WEB) {
this.props.updateWalletStatus();
getPasswordFromCookie().then((p) => {
if (typeof p === 'string') {
this.setState({ storedPassword: true });
}
});
}
enterSettings(); enterSettings();
} }
@ -134,15 +117,6 @@ class SettingsPage extends React.PureComponent<Props, State> {
this.props.setClientSetting(SETTINGS.CLOCK_24H, value); this.props.setClientSetting(SETTINGS.CLOCK_24H, value);
} }
onConfirmForgetPassword() {
const { confirmForgetPassword } = this.props;
confirmForgetPassword({
callback: () => {
this.setState({ storedPassword: false });
},
});
}
onChangeTime(event: SyntheticInputEvent<*>, options: OptionTimes) { onChangeTime(event: SyntheticInputEvent<*>, options: OptionTimes) {
const { value } = event.target; const { value } = event.target;
@ -180,7 +154,6 @@ class SettingsPage extends React.PureComponent<Props, State> {
automaticDarkModeEnabled, automaticDarkModeEnabled,
clock24h, clock24h,
autoplay, autoplay,
walletEncrypted,
// autoDownload, // autoDownload,
setDaemonSetting, setDaemonSetting,
setClientSetting, setClientSetting,
@ -194,12 +167,17 @@ class SettingsPage extends React.PureComponent<Props, State> {
myChannelUrls, myChannelUrls,
user, user,
} = this.props; } = this.props;
const { storedPassword } = this.state;
const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0; const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0;
const startHours = ['18', '19', '20', '21']; const startHours = ['18', '19', '20', '21'];
const endHours = ['5', '6', '7', '8']; const endHours = ['5', '6', '7', '8'];
return ( const newStyle = true;
return newStyle ? (
<Page noFooter noSideNavigation backout={{ title: __('Settings'), backLabel: __('Done') }} className="card-stack">
<SettingAccount />
</Page>
) : (
<Page <Page
noFooter noFooter
noSideNavigation noSideNavigation
@ -235,7 +213,6 @@ class SettingsPage extends React.PureComponent<Props, State> {
</section> </section>
) : ( ) : (
<div className={classnames('card-stack', { 'card--disabled': IS_WEB && !isAuthenticated })}> <div className={classnames('card-stack', { 'card--disabled': IS_WEB && !isAuthenticated })}>
{isAuthenticated && <SettingAccountPassword />}
{/* @if TARGET='app' */} {/* @if TARGET='app' */}
<Card <Card
title={__('Download directory')} title={__('Download directory')}
@ -252,15 +229,6 @@ class SettingsPage extends React.PureComponent<Props, State> {
</React.Fragment> </React.Fragment>
} }
/> />
<Card
title={__('Sync')}
subtitle={
walletEncrypted && !storedPassword && storedPassword !== ''
? __("To enable Sync, close LBRY completely and check 'Remember Password' during wallet unlock.")
: null
}
actions={<SyncToggle disabled={walletEncrypted && !storedPassword && storedPassword !== ''} />}
/>
{/* @endif */} {/* @endif */}
<Card <Card