Page MenuHomePhabricator

D9426.id31804.diff
No OneTemporary

D9426.id31804.diff

diff --git a/native/profile/delete-account.react.js b/native/profile/delete-account.react.js
--- a/native/profile/delete-account.react.js
+++ b/native/profile/delete-account.react.js
@@ -10,10 +10,6 @@
} from 'lib/actions/user-actions.js';
import { preRequestUserStateSelector } from 'lib/selectors/account-selectors.js';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
-import type { LogOutResult } from 'lib/types/account-types.js';
-import type { LoadingStatus } from 'lib/types/loading-types.js';
-import type { PreRequestUserState } from 'lib/types/session-types.js';
-import type { DispatchActionPromise } from 'lib/utils/action-utils.js';
import {
useServerCall,
useDispatchActionPromise,
@@ -25,88 +21,69 @@
import { useStyles } from '../themes/colors.js';
import Alert from '../utils/alert.js';
-type Props = {
- // Redux state
- +loadingStatus: LoadingStatus,
- +preRequestUserState: PreRequestUserState,
- +styles: typeof unboundStyles,
- // Redux dispatch functions
- +dispatchActionPromise: DispatchActionPromise,
- // async functions that hit server APIs
- +deleteAccount: (
- preRequestUserState: PreRequestUserState,
- ) => Promise<LogOutResult>,
-};
-class DeleteAccount extends React.PureComponent<Props> {
- render() {
+const loadingStatusSelector = createLoadingStatusSelector(
+ deleteAccountActionTypes,
+);
+
+const DeleteAccount: React.ComponentType<{ ... }> = React.memo<{ ... }>(
+ function DeleteAccount() {
+ const loadingStatus = useSelector(loadingStatusSelector);
+ const preRequestUserState = useSelector(preRequestUserStateSelector);
+ const styles = useStyles(unboundStyles);
+
+ const dispatchActionPromise = useDispatchActionPromise();
+ const callDeleteAccount = useServerCall(deleteAccount);
+
const buttonContent =
- this.props.loadingStatus === 'loading' ? (
+ loadingStatus === 'loading' ? (
<ActivityIndicator size="small" color="white" />
) : (
- <Text style={this.props.styles.saveText}>Delete account</Text>
+ <Text style={styles.saveText}>Delete account</Text>
);
+ const noWayToReverseThisStyles = React.useMemo(
+ () => [styles.warningText, styles.lastWarningText],
+ [styles.warningText, styles.lastWarningText],
+ );
+
+ const deleteAction = React.useCallback(async () => {
+ try {
+ await deleteNativeCredentialsFor();
+ return await callDeleteAccount(preRequestUserState);
+ } catch (e) {
+ Alert.alert('Unknown error', 'Uhh... try again?', [{ text: 'OK' }], {
+ cancelable: false,
+ });
+ throw e;
+ }
+ }, [callDeleteAccount, preRequestUserState]);
+
+ const onDelete = React.useCallback(() => {
+ dispatchActionPromise(deleteAccountActionTypes, deleteAction());
+ }, [dispatchActionPromise, deleteAction]);
+
return (
<ScrollView
- contentContainerStyle={this.props.styles.scrollViewContentContainer}
- style={this.props.styles.scrollView}
+ contentContainerStyle={styles.scrollViewContentContainer}
+ style={styles.scrollView}
>
<View>
- <Text style={this.props.styles.warningText}>
+ <Text style={styles.warningText}>
Your account will be permanently deleted.
</Text>
</View>
<View>
- <Text
- style={[
- this.props.styles.warningText,
- this.props.styles.lastWarningText,
- ]}
- >
+ <Text style={noWayToReverseThisStyles}>
There is no way to reverse this.
</Text>
</View>
- <Button
- onPress={this.submitDeletion}
- style={this.props.styles.deleteButton}
- >
+ <Button onPress={onDelete} style={styles.deleteButton}>
{buttonContent}
</Button>
</ScrollView>
);
- }
-
- submitDeletion = () => {
- this.props.dispatchActionPromise(
- deleteAccountActionTypes,
- this.deleteAccount(),
- );
- };
-
- async deleteAccount() {
- try {
- await deleteNativeCredentialsFor();
- const result = await this.props.deleteAccount(
- this.props.preRequestUserState,
- );
- return result;
- } catch (e) {
- if (e.message === 'invalid_credentials') {
- Alert.alert(
- 'Incorrect password',
- 'The password you entered is incorrect',
- [{ text: 'OK' }],
- { cancelable: false },
- );
- } else {
- Alert.alert('Unknown error', 'Uhh... try again?', [{ text: 'OK' }], {
- cancelable: false,
- });
- }
- throw e;
- }
- }
-}
+ },
+);
const unboundStyles = {
deleteButton: {
@@ -139,29 +116,4 @@
},
};
-const loadingStatusSelector = createLoadingStatusSelector(
- deleteAccountActionTypes,
-);
-
-const ConnectedDeleteAccount: React.ComponentType<{ ... }> = React.memo<{
- ...
-}>(function ConnectedDeleteAccount() {
- const loadingStatus = useSelector(loadingStatusSelector);
- const preRequestUserState = useSelector(preRequestUserStateSelector);
- const styles = useStyles(unboundStyles);
-
- const dispatchActionPromise = useDispatchActionPromise();
- const callDeleteAccount = useServerCall(deleteAccount);
-
- return (
- <DeleteAccount
- loadingStatus={loadingStatus}
- preRequestUserState={preRequestUserState}
- styles={styles}
- dispatchActionPromise={dispatchActionPromise}
- deleteAccount={callDeleteAccount}
- />
- );
-});
-
-export default ConnectedDeleteAccount;
+export default DeleteAccount;
diff --git a/web/settings/account-delete-modal.react.js b/web/settings/account-delete-modal.react.js
--- a/web/settings/account-delete-modal.react.js
+++ b/web/settings/account-delete-modal.react.js
@@ -10,9 +10,6 @@
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
import { preRequestUserStateSelector } from 'lib/selectors/account-selectors.js';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
-import type { LogOutResult } from 'lib/types/account-types.js';
-import type { PreRequestUserState } from 'lib/types/session-types.js';
-import type { DispatchActionPromise } from 'lib/utils/action-utils.js';
import {
useDispatchActionPromise,
useServerCall,
@@ -23,35 +20,50 @@
import Modal from '../modals/modal.react.js';
import { useSelector } from '../redux/redux-utils.js';
-type Props = {
- +preRequestUserState: PreRequestUserState,
- +inputDisabled: boolean,
- +dispatchActionPromise: DispatchActionPromise,
- +deleteAccount: (
- preRequestUserState: PreRequestUserState,
- ) => Promise<LogOutResult>,
- +popModal: () => void,
-};
-type State = {
- +errorMessage: string,
-};
+const deleteAccountLoadingStatusSelector = createLoadingStatusSelector(
+ deleteAccountActionTypes,
+);
-class AccountDeleteModal extends React.PureComponent<Props, State> {
- state = {
- errorMessage: '',
- };
+const AccountDeleteModal: React.ComponentType<{}> = React.memo<{}>(
+ function AccountDeleteModal(): React.Node {
+ const preRequestUserState = useSelector(preRequestUserStateSelector);
+ const inputDisabled = useSelector(
+ state => deleteAccountLoadingStatusSelector(state) === 'loading',
+ );
+ const callDeleteAccount = useServerCall(deleteAccount);
+ const dispatchActionPromise = useDispatchActionPromise();
+
+ const { popModal } = useModalContext();
+
+ const [errorMessage, setErrorMessage] = React.useState('');
- render() {
let errorMsg;
- if (this.state.errorMessage) {
- errorMsg = (
- <div className={css.form_error}>{this.state.errorMessage}</div>
- );
+ if (errorMessage) {
+ errorMsg = <div className={css.form_error}>{errorMessage}</div>;
}
- const { inputDisabled } = this.props;
+ const deleteAction = React.useCallback(async () => {
+ try {
+ setErrorMessage('');
+ const response = await callDeleteAccount(preRequestUserState);
+ popModal();
+ return response;
+ } catch (e) {
+ setErrorMessage('unknown error');
+ throw e;
+ }
+ }, [callDeleteAccount, preRequestUserState, popModal]);
+
+ const onDelete = React.useCallback(
+ (event: SyntheticEvent<HTMLButtonElement>) => {
+ event.preventDefault();
+ dispatchActionPromise(deleteAccountActionTypes, deleteAction());
+ },
+ [dispatchActionPromise, deleteAction],
+ );
+
return (
- <Modal name="Delete Account" onClose={this.props.popModal} size="large">
+ <Modal name="Delete Account" onClose={popModal} size="large">
<div className={css.modal_body}>
<form method="POST">
<SWMansionIcon icon="warning-circle" size={22} />
@@ -64,7 +76,7 @@
variant="filled"
buttonColor={buttonThemes.danger}
type="submit"
- onClick={this.onDelete}
+ onClick={onDelete}
disabled={inputDisabled}
>
Delete Account
@@ -75,55 +87,7 @@
</div>
</Modal>
);
- }
-
- onDelete = (event: SyntheticEvent<HTMLButtonElement>) => {
- event.preventDefault();
- this.props.dispatchActionPromise(
- deleteAccountActionTypes,
- this.deleteAction(),
- );
- };
-
- async deleteAction() {
- try {
- const response = await this.props.deleteAccount(
- this.props.preRequestUserState,
- );
- this.props.popModal();
- return response;
- } catch (e) {
- this.setState({ errorMessage: 'unknown error' });
- throw e;
- }
- }
-}
-
-const deleteAccountLoadingStatusSelector = createLoadingStatusSelector(
- deleteAccountActionTypes,
-);
-
-const ConnectedAccountDeleteModal: React.ComponentType<{}> = React.memo<{}>(
- function ConnectedAccountDeleteModal(): React.Node {
- const preRequestUserState = useSelector(preRequestUserStateSelector);
- const inputDisabled = useSelector(
- state => deleteAccountLoadingStatusSelector(state) === 'loading',
- );
- const callDeleteAccount = useServerCall(deleteAccount);
- const dispatchActionPromise = useDispatchActionPromise();
-
- const modalContext = useModalContext();
-
- return (
- <AccountDeleteModal
- preRequestUserState={preRequestUserState}
- inputDisabled={inputDisabled}
- deleteAccount={callDeleteAccount}
- dispatchActionPromise={dispatchActionPromise}
- popModal={modalContext.popModal}
- />
- );
},
);
-export default ConnectedAccountDeleteModal;
+export default AccountDeleteModal;

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 29, 2:59 PM (20 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2597336
Default Alt Text
D9426.id31804.diff (10 KB)

Event Timeline