diff --git a/native/chat/settings/thread-settings-avatar.react.js b/native/chat/settings/thread-settings-avatar.react.js
--- a/native/chat/settings/thread-settings-avatar.react.js
+++ b/native/chat/settings/thread-settings-avatar.react.js
@@ -37,6 +37,7 @@
diff --git a/native/components/edit-avatar.react.js b/native/components/edit-avatar.react.js
--- a/native/components/edit-avatar.react.js
+++ b/native/components/edit-avatar.react.js
@@ -2,26 +2,63 @@
import { useActionSheet } from '@expo/react-native-action-sheet';
import * as React from 'react';
-import { View, TouchableOpacity, Platform } from 'react-native';
+import {
+ View,
+ TouchableOpacity,
+ ActivityIndicator,
+ Platform,
+} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
+import { updateUserAvatarActionTypes } from 'lib/actions/user-actions.js';
+import { useENSAvatar } from 'lib/hooks/ens-cache.js';
+import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { getEthAddressForUserInfo } from 'lib/utils/ens-helpers.js';
+
import CommIcon from '../components/comm-icon.react.js';
import SWMansionIcon from '../components/swmansion-icon.react.js';
+import { useSelector } from '../redux/redux-utils.js';
import { useColors, useStyles } from '../themes/colors.js';
+import { useSaveUserAvatar } from '../utils/avatar-utils.js';
+
+const userAvatarLoadingStatusSelector = createLoadingStatusSelector(
+ updateUserAvatarActionTypes,
+);
type Props = {
+children: React.Node,
+ +childAvatarType: 'user' | 'thread',
+onPressEmojiAvatarFlow: () => mixed,
+disabled?: boolean,
};
function EditAvatar(props: Props): React.Node {
- const { onPressEmojiAvatarFlow, children, disabled } = props;
+ const { children, childAvatarType, onPressEmojiAvatarFlow, disabled } = props;
const { showActionSheetWithOptions } = useActionSheet();
const colors = useColors();
const styles = useStyles(unboundStyles);
+ const currentUserInfo = useSelector(state => state.currentUserInfo);
+
+ const ethAddress = React.useMemo(
+ () => getEthAddressForUserInfo(currentUserInfo),
+ [currentUserInfo],
+ );
+ const ensAvatarURI = useENSAvatar(ethAddress);
+
+ const saveUserAvatar = useSaveUserAvatar();
+ const saveUserAvatarCallLoading = useSelector(
+ state => userAvatarLoadingStatusSelector(state) === 'loading',
+ );
+
+ const onPressUseENSAvatar = React.useCallback(() => {
+ const newAvatarRequest = {
+ type: 'ens',
+ };
+ saveUserAvatar(newAvatarRequest);
+ }, [saveUserAvatar]);
+
const editAvatarOptions = React.useMemo(() => {
const options = [
{
@@ -38,6 +75,21 @@
},
];
+ if (ensAvatarURI && childAvatarType === 'user') {
+ options.push({
+ id: 'ens',
+ text: 'Use ENS Avatar',
+ onPress: onPressUseENSAvatar,
+ icon: (
+
+ ),
+ });
+ }
+
if (Platform.OS === 'ios') {
options.push({
id: 'cancel',
@@ -46,7 +98,13 @@
});
}
return options;
- }, [onPressEmojiAvatarFlow, styles.bottomSheetIcon]);
+ }, [
+ childAvatarType,
+ ensAvatarURI,
+ onPressEmojiAvatarFlow,
+ onPressUseENSAvatar,
+ styles.bottomSheetIcon,
+ ]);
const insets = useSafeAreaInsets();
@@ -89,7 +147,7 @@
}, [editAvatarOptions, insets.bottom, showActionSheetWithOptions]);
const editBadge = React.useMemo(() => {
- if (disabled) {
+ if (disabled || saveUserAvatarCallLoading) {
return null;
}
@@ -106,13 +164,30 @@
}, [
colors.floatingButtonLabel,
disabled,
+ saveUserAvatarCallLoading,
styles.editAvatarIcon,
styles.editAvatarIconContainer,
]);
+ const loadingContainer = React.useMemo(() => {
+ if (!saveUserAvatarCallLoading) {
+ return null;
+ }
+
+ return (
+
+
+
+ );
+ }, [saveUserAvatarCallLoading, styles.loadingContainer]);
+
return (
-
+
{children}
+ {loadingContainer}
{editBadge}
);
@@ -137,6 +212,15 @@
bottomSheetIcon: {
color: '#000000',
},
+ loadingContainer: {
+ position: 'absolute',
+ backgroundColor: '#000000',
+ width: 112,
+ height: 112,
+ borderRadius: 56,
+ opacity: 0.6,
+ justifyContent: 'center',
+ },
};
export default EditAvatar;
diff --git a/native/profile/profile-screen.react.js b/native/profile/profile-screen.react.js
--- a/native/profile/profile-screen.react.js
+++ b/native/profile/profile-screen.react.js
@@ -131,7 +131,10 @@
-
+