Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3159602
D9426.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
10 KB
Referenced Files
None
Subscribers
None
D9426.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 6, 11:31 PM (21 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2433591
Default Alt Text
D9426.diff (10 KB)
Attached To
Mode
D9426: [native][web] Convert account deletion components to hooks
Attached
Detach File
Event Timeline
Log In to Comment