diff --git a/native/avatars/avatar-hooks.js b/native/avatars/avatar-hooks.js
--- a/native/avatars/avatar-hooks.js
+++ b/native/avatars/avatar-hooks.js
@@ -329,37 +329,6 @@
);
}
-function useRemoveUserAvatar(): [() => void, boolean] {
- const dispatchActionPromise = useDispatchActionPromise();
- const updateUserAvatarCall = useServerCall(updateUserAvatar);
- const updateUserAvatarLoadingStatus: LoadingStatus = useSelector(
- updateUserAvatarLoadingStatusSelector,
- );
-
- const removeUserAvatar = React.useCallback(() => {
- const removeAvatarRequest: UpdateUserAvatarRemoveRequest = {
- type: 'remove',
- };
-
- dispatchActionPromise(
- updateUserAvatarActionTypes,
- (async () => {
- try {
- return await updateUserAvatarCall(removeAvatarRequest);
- } catch (e) {
- Alert.alert('Avatar update failed', 'Unable to update avatar.');
- throw e;
- }
- })(),
- );
- }, [dispatchActionPromise, updateUserAvatarCall]);
-
- return React.useMemo(
- () => [removeUserAvatar, updateUserAvatarLoadingStatus === 'loading'],
- [removeUserAvatar, updateUserAvatarLoadingStatus],
- );
-}
-
function useRemoveThreadAvatar(threadID: string): [() => void, boolean] {
const dispatchActionPromise = useDispatchActionPromise();
const changeThreadSettingsCall = useServerCall(changeThreadSettings);
@@ -550,7 +519,6 @@
useShowAvatarActionSheet,
useSelectFromGalleryAndUpdateUserAvatar,
useSelectFromGalleryAndUpdateThreadAvatar,
- useRemoveUserAvatar,
useRemoveThreadAvatar,
useENSUserAvatar,
};
diff --git a/native/avatars/edit-user-avatar-provider.react.js b/native/avatars/edit-user-avatar-provider.react.js
new file mode 100644
--- /dev/null
+++ b/native/avatars/edit-user-avatar-provider.react.js
@@ -0,0 +1,80 @@
+// @flow
+
+import * as React from 'react';
+import { Alert } from 'react-native';
+
+import {
+ updateUserAvatar,
+ updateUserAvatarActionTypes,
+} from 'lib/actions/user-actions.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import type { UpdateUserAvatarRemoveRequest } from 'lib/types/avatar-types.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import {
+ useDispatchActionPromise,
+ useServerCall,
+} from 'lib/utils/action-utils.js';
+
+import { useSelector } from '../redux/redux-utils.js';
+
+export type EditUserAvatarContextType = {
+ +userAvatarSaveInProgress: boolean,
+ +removeUserAvatar: () => void,
+};
+
+const EditUserAvatarContext: React.Context =
+ React.createContext();
+
+const updateUserAvatarLoadingStatusSelector = createLoadingStatusSelector(
+ updateUserAvatarActionTypes,
+);
+
+type Props = {
+ +children: React.Node,
+};
+function EditUserAvatarProvider(props: Props): React.Node {
+ const { children } = props;
+
+ const dispatchActionPromise = useDispatchActionPromise();
+ const updateUserAvatarCall = useServerCall(updateUserAvatar);
+
+ const updateUserAvatarLoadingStatus: LoadingStatus = useSelector(
+ updateUserAvatarLoadingStatusSelector,
+ );
+
+ const userAvatarSaveInProgress = updateUserAvatarLoadingStatus === 'loading';
+
+ const removeUserAvatar = React.useCallback(() => {
+ const removeAvatarRequest: UpdateUserAvatarRemoveRequest = {
+ type: 'remove',
+ };
+
+ dispatchActionPromise(
+ updateUserAvatarActionTypes,
+ (async () => {
+ try {
+ return await updateUserAvatarCall(removeAvatarRequest);
+ } catch (e) {
+ Alert.alert('Avatar update failed', 'Unable to update avatar.');
+ throw e;
+ }
+ })(),
+ );
+ }, [dispatchActionPromise, updateUserAvatarCall]);
+
+ const context = React.useMemo(
+ () => ({
+ userAvatarSaveInProgress,
+ removeUserAvatar,
+ }),
+ [removeUserAvatar, userAvatarSaveInProgress],
+ );
+
+ return (
+
+ {children}
+
+ );
+}
+
+export { EditUserAvatarContext, EditUserAvatarProvider };
diff --git a/native/avatars/edit-user-avatar.react.js b/native/avatars/edit-user-avatar.react.js
--- a/native/avatars/edit-user-avatar.react.js
+++ b/native/avatars/edit-user-avatar.react.js
@@ -1,5 +1,6 @@
// @flow
+import invariant from 'invariant';
import * as React from 'react';
import { ActivityIndicator, TouchableOpacity, View } from 'react-native';
@@ -8,11 +9,11 @@
import {
useENSUserAvatar,
- useRemoveUserAvatar,
useSelectFromGalleryAndUpdateUserAvatar,
useShowAvatarActionSheet,
} from './avatar-hooks.js';
import EditAvatarBadge from './edit-avatar-badge.react.js';
+import { EditUserAvatarContext } from './edit-user-avatar-provider.react.js';
import UserAvatar from './user-avatar.react.js';
import { useSelector } from '../redux/redux-utils.js';
import { useStyles } from '../themes/colors.js';
@@ -26,6 +27,10 @@
const styles = useStyles(unboundStyles);
const { userID, onPressEmojiAvatarFlow, disabled } = props;
+ const editUserAvatarContext = React.useContext(EditUserAvatarContext);
+ invariant(editUserAvatarContext, 'editUserAvatarContext should be set');
+ const { userAvatarSaveInProgress, removeUserAvatar } = editUserAvatarContext;
+
const currentUserInfo = useSelector(state => state.currentUserInfo);
const ethAddress = React.useMemo(
() => getETHAddressForUserInfo(currentUserInfo),
@@ -37,12 +42,11 @@
useSelectFromGalleryAndUpdateUserAvatar();
const [saveENSUserAvatar, isENSAvatarUpdateLoading] = useENSUserAvatar();
- const [removeUserAvatar, isRemoveAvatarUpdateLoading] = useRemoveUserAvatar();
const isAvatarUpdateInProgress =
isGalleryAvatarUpdateLoading ||
- isRemoveAvatarUpdateLoading ||
- isENSAvatarUpdateLoading;
+ isENSAvatarUpdateLoading ||
+ userAvatarSaveInProgress;
const actionSheetConfig = React.useMemo(() => {
const configOptions = [
diff --git a/native/root.react.js b/native/root.react.js
--- a/native/root.react.js
+++ b/native/root.react.js
@@ -22,6 +22,7 @@
import { MediaCacheProvider } from 'lib/components/media-cache-provider.react.js';
import { actionLogger } from 'lib/utils/action-logger.js';
+import { EditUserAvatarProvider } from './avatars/edit-user-avatar-provider.react.js';
import ChatContextProvider from './chat/chat-context-provider.react.js';
import { FeatureFlagsProvider } from './components/feature-flags-provider.react.js';
import PersistedStateGate from './components/persisted-state-gate.js';
@@ -256,23 +257,25 @@
-
-
-
-
-
- {gated}
-
-
-
-
- {navigation}
-
-
+
+
+
+
+
+
+ {gated}
+
+
+
+
+ {navigation}
+
+
+