Page MenuHomePhabricator

D10756.diff
No OneTemporary

D10756.diff

diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js
--- a/lib/actions/user-actions.js
+++ b/lib/actions/user-actions.js
@@ -25,6 +25,7 @@
KeyserverAuthRequest,
ClientLogInResponse,
KeyserverLogOutResult,
+ LogOutResult,
} from '../types/account-types.js';
import type {
UpdateUserAvatarRequest,
@@ -66,6 +67,7 @@
import { getConfig } from '../utils/config.js';
import { useKeyserverCall } from '../utils/keyserver-call.js';
import { useSelector } from '../utils/redux-utils.js';
+import { usingCommServicesAccessToken } from '../utils/services-utils.js';
import sleep from '../utils/sleep.js';
import { ashoatKeyserverID } from '../utils/validation-utils.js';
@@ -188,21 +190,38 @@
);
}
-const deleteIdentityAccountActionTypes = Object.freeze({
- started: 'DELETE_IDENTITY_ACCOUNT_STARTED',
- success: 'DELETE_IDENTITY_ACCOUNT_SUCCESS',
- failed: 'DELETE_IDENTITY_ACCOUNT_FAILED',
+const deleteAccountActionTypes = Object.freeze({
+ started: 'DELETE_ACCOUNT_STARTED',
+ success: 'DELETE_ACCOUNT_SUCCESS',
+ failed: 'DELETE_ACCOUNT_FAILED',
});
-function useDeleteIdentityAccount(): () => Promise<void> {
+function useDeleteAccount(): () => Promise<LogOutResult> {
const client = React.useContext(IdentityClientContext);
const identityClient = client?.identityClient;
- return React.useCallback(() => {
- if (!identityClient) {
- throw new Error('Identity service client is not initialized');
- }
- return identityClient.deleteUser();
- }, [identityClient]);
+
+ const preRequestUserState = useSelector(preRequestUserStateSelector);
+ const callKeyserverDeleteAccount = useKeyserverCall(deleteKeyserverAccount);
+
+ return React.useCallback(async () => {
+ const identityPromise = (async () => {
+ if (!usingCommServicesAccessToken) {
+ return undefined;
+ }
+ if (!identityClient) {
+ throw new Error('Identity service client is not initialized');
+ }
+ return await identityClient.deleteUser();
+ })();
+ const [keyserverResult] = await Promise.all([
+ callKeyserverDeleteAccount({
+ preRequestUserState,
+ }),
+ identityPromise,
+ ]);
+ const { keyserverIDs: _, ...result } = keyserverResult;
+ return result;
+ }, [callKeyserverDeleteAccount, identityClient, preRequestUserState]);
}
const keyserverRegisterActionTypes = Object.freeze({
@@ -743,8 +762,8 @@
updateUserAvatar,
resetUserStateActionType,
setAccessTokenActionType,
- deleteIdentityAccountActionTypes,
- useDeleteIdentityAccount,
+ deleteAccountActionTypes,
+ useDeleteAccount,
keyserverAuthActionTypes,
useKeyserverAuth,
identityRegisterActionTypes,
diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js
--- a/lib/types/redux-types.js
+++ b/lib/types/redux-types.js
@@ -234,18 +234,18 @@
+loadingInfo: LoadingInfo,
}
| {
- +type: 'DELETE_IDENTITY_ACCOUNT_STARTED',
+ +type: 'DELETE_ACCOUNT_STARTED',
+payload?: void,
+loadingInfo: LoadingInfo,
}
| {
- +type: 'DELETE_IDENTITY_ACCOUNT_FAILED',
+ +type: 'DELETE_ACCOUNT_FAILED',
+error: true,
+payload: Error,
+loadingInfo: LoadingInfo,
}
| {
- +type: 'DELETE_IDENTITY_ACCOUNT_SUCCESS',
+ +type: 'DELETE_ACCOUNT_SUCCESS',
+payload: LogOutResult,
+loadingInfo: LoadingInfo,
}
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
@@ -5,17 +5,11 @@
import { ScrollView } from 'react-native-gesture-handler';
import {
- deleteIdentityAccountActionTypes,
- deleteKeyserverAccountActionTypes,
- useDeleteIdentityAccount,
- useDeleteKeyserverAccount,
+ deleteAccountActionTypes,
+ useDeleteAccount,
} from 'lib/actions/user-actions.js';
-import {
- createLoadingStatusSelector,
- combineLoadingStatuses,
-} from 'lib/selectors/loading-selectors.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js';
-import { usingCommServicesAccessToken } from 'lib/utils/services-utils.js';
import type { ProfileNavigationProp } from './profile.react.js';
import { deleteNativeCredentialsFor } from '../account/native-credentials.js';
@@ -25,11 +19,8 @@
import { useStyles } from '../themes/colors.js';
import Alert from '../utils/alert.js';
-const keyserverLoadingStatusSelector = createLoadingStatusSelector(
- deleteKeyserverAccountActionTypes,
-);
-const identityLoadingStatusSelector = createLoadingStatusSelector(
- deleteIdentityAccountActionTypes,
+const deleteAccountLoadingStatusSelector = createLoadingStatusSelector(
+ deleteAccountActionTypes,
);
type Props = {
@@ -38,20 +29,16 @@
};
const DeleteAccount: React.ComponentType<Props> = React.memo<Props>(
function DeleteAccount() {
- const keyserverLoadingStatus = useSelector(keyserverLoadingStatusSelector);
- const identityLoadingStatus = useSelector(identityLoadingStatusSelector);
- const combinedLoadingStatuses = combineLoadingStatuses(
- keyserverLoadingStatus,
- identityLoadingStatus,
+ const deleteAccountLoadingStatus = useSelector(
+ deleteAccountLoadingStatusSelector,
);
const styles = useStyles(unboundStyles);
const dispatchActionPromise = useDispatchActionPromise();
- const callDeleteKeyserverAccount = useDeleteKeyserverAccount();
- const callDeleteIdentityAccount = useDeleteIdentityAccount();
+ const callDeleteAccount = useDeleteAccount();
- const isButtonDisabled = combinedLoadingStatuses === 'loading';
+ const isButtonDisabled = deleteAccountLoadingStatus === 'loading';
const buttonContent = isButtonDisabled ? (
<ActivityIndicator size="small" color="white" />
@@ -64,26 +51,10 @@
[styles.warningText, styles.lastWarningText],
);
- const deleteKeyserverAction = React.useCallback(async () => {
+ const deleteAccountAction = React.useCallback(async () => {
try {
await deleteNativeCredentialsFor();
- return await callDeleteKeyserverAccount();
- } catch (e) {
- Alert.alert(
- 'Unknown error deleting keyserver account',
- 'Uhh... try again?',
- [{ text: 'OK' }],
- {
- cancelable: false,
- },
- );
- throw e;
- }
- }, [callDeleteKeyserverAccount]);
-
- const deleteIdentityAction = React.useCallback(async () => {
- try {
- return await callDeleteIdentityAccount();
+ return await callDeleteAccount();
} catch (e) {
Alert.alert(
'Unknown error deleting account',
@@ -95,20 +66,14 @@
);
throw e;
}
- }, [callDeleteIdentityAccount]);
+ }, [callDeleteAccount]);
const onDelete = React.useCallback(() => {
void dispatchActionPromise(
- deleteKeyserverAccountActionTypes,
- deleteKeyserverAction(),
+ deleteAccountActionTypes,
+ deleteAccountAction(),
);
- if (usingCommServicesAccessToken) {
- void dispatchActionPromise(
- deleteIdentityAccountActionTypes,
- deleteIdentityAction(),
- );
- }
- }, [dispatchActionPromise, deleteKeyserverAction, deleteIdentityAction]);
+ }, [dispatchActionPromise, deleteAccountAction]);
return (
<ScrollView
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
@@ -3,113 +3,64 @@
import * as React from 'react';
import {
- useDeleteKeyserverAccount,
- deleteKeyserverAccountActionTypes,
- useDeleteIdentityAccount,
- deleteIdentityAccountActionTypes,
+ useDeleteAccount,
+ deleteAccountActionTypes,
} from 'lib/actions/user-actions.js';
import { useModalContext } from 'lib/components/modal-provider.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js';
-import { usingCommServicesAccessToken } from 'lib/utils/services-utils.js';
import css from './account-delete-modal.css';
import Button, { buttonThemes } from '../components/button.react.js';
import Modal from '../modals/modal.react.js';
import { useSelector } from '../redux/redux-utils.js';
-const deleteKeyserverAccountLoadingStatusSelector = createLoadingStatusSelector(
- deleteKeyserverAccountActionTypes,
-);
-const deleteIdentityAccountLoadingStatusSelector = createLoadingStatusSelector(
- deleteIdentityAccountActionTypes,
+const deleteAccountLoadingStatusSelector = createLoadingStatusSelector(
+ deleteAccountActionTypes,
);
const AccountDeleteModal: React.ComponentType<{}> = React.memo<{}>(
function AccountDeleteModal(): React.Node {
- const isDeleteKeyserverAccountLoading = useSelector(
- state => deleteKeyserverAccountLoadingStatusSelector(state) === 'loading',
- );
- const isDeleteIdentityAccountLoading = useSelector(
- state => deleteIdentityAccountLoadingStatusSelector(state) === 'loading',
+ const inputDisabled = useSelector(
+ state => deleteAccountLoadingStatusSelector(state) === 'loading',
);
- const inputDisabled =
- isDeleteKeyserverAccountLoading || isDeleteIdentityAccountLoading;
-
- const callDeleteIdentityAccount = useDeleteIdentityAccount();
- const callDeleteKeyserverAccount = useDeleteKeyserverAccount();
+ const callDeleteAccount = useDeleteAccount();
const dispatchActionPromise = useDispatchActionPromise();
-
const { popModal } = useModalContext();
- const [keyserverErrorMessage, setKeyserverErrorMessage] =
- React.useState('');
- const [identityErrorMessage, setIdentityErrorMessage] = React.useState('');
-
- const keyserverError = keyserverErrorMessage ? (
- <p>{keyserverErrorMessage}</p>
- ) : null;
- const identityError = identityErrorMessage ? (
- <p>{identityErrorMessage}</p>
- ) : null;
- let combinedErrorMessages;
- if (keyserverError || identityError) {
- combinedErrorMessages = (
+ const [errorMessage, setErrorMessage] = React.useState('');
+ let error;
+ if (errorMessage) {
+ error = (
<div className={css.form_error}>
- {keyserverError}
- {identityError}
+ <p>{errorMessage}</p>
</div>
);
}
- const deleteKeyserverAction = React.useCallback(async () => {
+ const deleteAccountAction = React.useCallback(async () => {
try {
- setKeyserverErrorMessage('');
- const response = await callDeleteKeyserverAccount();
- // This check ensures that we don't call `popModal()` twice
- if (!usingCommServicesAccessToken) {
- popModal();
- }
- return response;
- } catch (e) {
- setKeyserverErrorMessage(
- 'unknown error deleting account from keyserver',
- );
- throw e;
- }
- }, [callDeleteKeyserverAccount, popModal]);
-
- const deleteIdentityAction = React.useCallback(async () => {
- try {
- setIdentityErrorMessage('');
- const response = await callDeleteIdentityAccount();
+ setErrorMessage('');
+ const response = await callDeleteAccount();
popModal();
return response;
} catch (e) {
- setIdentityErrorMessage(
- 'unknown error deleting account from identity service',
- );
+ setErrorMessage('unknown error deleting account');
throw e;
}
- }, [callDeleteIdentityAccount, popModal]);
+ }, [callDeleteAccount, popModal]);
const onDelete = React.useCallback(
(event: SyntheticEvent<HTMLButtonElement>) => {
event.preventDefault();
void dispatchActionPromise(
- deleteKeyserverAccountActionTypes,
- deleteKeyserverAction(),
+ deleteAccountActionTypes,
+ deleteAccountAction(),
);
- if (usingCommServicesAccessToken) {
- void dispatchActionPromise(
- deleteIdentityAccountActionTypes,
- deleteIdentityAction(),
- );
- }
},
- [dispatchActionPromise, deleteKeyserverAction, deleteIdentityAction],
+ [dispatchActionPromise, deleteAccountAction],
);
return (
@@ -131,7 +82,7 @@
>
Delete Account
</Button>
- {combinedErrorMessages}
+ {error}
</div>
</form>
</div>

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 6, 1:04 PM (20 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2430986
Default Alt Text
D10756.diff (12 KB)

Event Timeline