Page MenuHomePhabricator

D7546.id25426.diff
No OneTemporary

D7546.id25426.diff

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
@@ -23,6 +23,7 @@
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import type {
ImageAvatarDBContent,
+ ENSAvatarDBContent,
UpdateUserAvatarRemoveRequest,
} from 'lib/types/avatar-types.js';
import type { LoadingStatus } from 'lib/types/loading-types.js';
@@ -37,6 +38,7 @@
useServerCall,
} from 'lib/utils/action-utils.js';
+import CommIcon from '../components/comm-icon.react.js';
import SWMansionIcon from '../components/swmansion-icon.react.js';
import { getCompatibleMediaURI } from '../media/identifier-utils.js';
import type { MediaResult } from '../media/media-utils.js';
@@ -352,8 +354,33 @@
return removeThreadAvatar;
}
+function useENSUserAvatar(): [() => Promise<void>, boolean] {
+ const dispatchActionPromise = useDispatchActionPromise();
+ const updateUserAvatarCall = useServerCall(updateUserAvatar);
+
+ const updateUserAvatarLoadingStatus: LoadingStatus = useSelector(
+ updateUserAvatarLoadingStatusSelector,
+ );
+
+ const saveENSUserAvatar = React.useCallback(async () => {
+ const ensAvatarRequest: ENSAvatarDBContent = {
+ type: 'ens',
+ };
+
+ dispatchActionPromise(
+ updateUserAvatarActionTypes,
+ updateUserAvatarCall(ensAvatarRequest),
+ );
+ }, [dispatchActionPromise, updateUserAvatarCall]);
+
+ return React.useMemo(
+ () => [saveENSUserAvatar, updateUserAvatarLoadingStatus === 'loading'],
+ [saveENSUserAvatar, updateUserAvatarLoadingStatus],
+ );
+}
+
type ShowAvatarActionSheetOptions = {
- +id: 'emoji' | 'image' | 'cancel' | 'remove',
+ +id: 'emoji' | 'image' | 'ens' | 'cancel' | 'remove',
+onPress?: () => mixed,
};
function useShowAvatarActionSheet(
@@ -371,6 +398,8 @@
return 'Use Emoji';
} else if (option.id === 'image') {
return 'Select image';
+ } else if (option.id === 'ens') {
+ return 'Use ENS Avatar';
} else if (option.id === 'remove') {
return 'Remove avatar';
} else {
@@ -403,6 +432,14 @@
style={styles.bottomSheetIcon}
/>
);
+ } else if (option.id === 'ens') {
+ return (
+ <CommIcon
+ name="ethereum-outline"
+ size={18}
+ style={styles.bottomSheetIcon}
+ />
+ );
} else if (option.id === 'remove') {
return (
<SWMansionIcon
@@ -463,4 +500,5 @@
useSelectFromGalleryAndUpdateThreadAvatar,
useRemoveUserAvatar,
useRemoveThreadAvatar,
+ useENSUserAvatar,
};
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
@@ -3,13 +3,18 @@
import * as React from 'react';
import { ActivityIndicator, TouchableOpacity, View } from 'react-native';
+import { useENSAvatar } from 'lib/hooks/ens-cache.js';
+import { getETHAddressForUserInfo } from 'lib/shared/account-utils.js';
+
import {
+ useENSUserAvatar,
useRemoveUserAvatar,
useSelectFromGalleryAndUpdateUserAvatar,
useShowAvatarActionSheet,
} from './avatar-hooks.js';
import EditAvatarBadge from './edit-avatar-badge.react.js';
import UserAvatar from './user-avatar.react.js';
+import { useSelector } from '../redux/redux-utils.js';
import { useStyles } from '../themes/colors.js';
type Props = {
@@ -21,26 +26,44 @@
const styles = useStyles(unboundStyles);
const { userID, onPressEmojiAvatarFlow, disabled } = props;
+ const currentUserInfo = useSelector(state => state.currentUserInfo);
+ const ethAddress = React.useMemo(
+ () => getETHAddressForUserInfo(currentUserInfo),
+ [currentUserInfo],
+ );
+ const ensAvatarURI = useENSAvatar(ethAddress);
+
const [selectFromGalleryAndUpdateUserAvatar, isGalleryAvatarUpdateLoading] =
useSelectFromGalleryAndUpdateUserAvatar();
+ const [saveENSUserAvatar, isENSAvatarUpdateLoading] = useENSUserAvatar();
const [removeUserAvatar, isRemoveAvatarUpdateLoading] = useRemoveUserAvatar();
const isAvatarUpdateInProgress =
- isGalleryAvatarUpdateLoading || isRemoveAvatarUpdateLoading;
+ isGalleryAvatarUpdateLoading ||
+ isRemoveAvatarUpdateLoading ||
+ isENSAvatarUpdateLoading;
- const actionSheetConfig = React.useMemo(
- () => [
+ const actionSheetConfig = React.useMemo(() => {
+ const configOptions = [
{ id: 'emoji', onPress: onPressEmojiAvatarFlow },
{ id: 'image', onPress: selectFromGalleryAndUpdateUserAvatar },
- { id: 'remove', onPress: removeUserAvatar },
- ],
- [
- onPressEmojiAvatarFlow,
- removeUserAvatar,
- selectFromGalleryAndUpdateUserAvatar,
- ],
- );
+ ];
+
+ if (ensAvatarURI) {
+ configOptions.push({ id: 'ens', onPress: saveENSUserAvatar });
+ }
+
+ configOptions.push({ id: 'remove', onPress: removeUserAvatar });
+
+ return configOptions;
+ }, [
+ ensAvatarURI,
+ onPressEmojiAvatarFlow,
+ removeUserAvatar,
+ saveENSUserAvatar,
+ selectFromGalleryAndUpdateUserAvatar,
+ ]);
const showAvatarActionSheet = useShowAvatarActionSheet(actionSheetConfig);

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 18, 1:33 AM (22 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2532574
Default Alt Text
D7546.id25426.diff (5 KB)

Event Timeline