diff --git a/web/avatars/edit-user-avatar-menu.react.js b/web/avatars/edit-user-avatar-menu.react.js
index 8f17f0081..0591be2e7 100644
--- a/web/avatars/edit-user-avatar-menu.react.js
+++ b/web/avatars/edit-user-avatar-menu.react.js
@@ -1,156 +1,156 @@
// @flow
import invariant from 'invariant';
import * as React from 'react';
import { EditUserAvatarContext } from 'lib/components/edit-user-avatar-provider.react.js';
import { useModalContext } from 'lib/components/modal-provider.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
import { useENSAvatar } from 'lib/hooks/ens-cache.js';
import { getETHAddressForUserInfo } from 'lib/shared/account-utils.js';
import { useUploadAvatarMedia } from './avatar-hooks.react.js';
import css from './edit-avatar-menu.css';
-import EmojiAvatarSelectionModal from './emoji-avatar-selection-modal.react.js';
+import UserEmojiAvatarSelectionModal from './user-emoji-avatar-selection-modal.react.js';
import CommIcon from '../CommIcon.react.js';
import MenuItem from '../components/menu-item.react.js';
import Menu from '../components/menu.react.js';
import { allowedMimeTypeString } from '../media/file-utils.js';
import { useSelector } from '../redux/redux-utils.js';
const editIcon = (
);
function EditUserAvatarMenu(): React.Node {
const currentUserInfo = useSelector(state => state.currentUserInfo);
const ethAddress: ?string = React.useMemo(
() => getETHAddressForUserInfo(currentUserInfo),
[currentUserInfo],
);
const ensAvatarURI: ?string = useENSAvatar(ethAddress);
const editUserAvatarContext = React.useContext(EditUserAvatarContext);
invariant(editUserAvatarContext, 'editUserAvatarContext should be set');
const { baseSetUserAvatar } = editUserAvatarContext;
const removeUserAvatar = React.useCallback(
() => baseSetUserAvatar({ type: 'remove' }),
[baseSetUserAvatar],
);
const { pushModal } = useModalContext();
const openEmojiSelectionModal = React.useCallback(
- () => pushModal(),
+ () => pushModal(),
[pushModal],
);
const emojiMenuItem = React.useMemo(
() => (
),
[openEmojiSelectionModal],
);
const imageInputRef = React.useRef();
const onImageMenuItemClicked = React.useCallback(
() => imageInputRef.current?.click(),
[],
);
const uploadAvatarMedia = useUploadAvatarMedia();
const onImageSelected = React.useCallback(
async event => {
const uploadResult = await uploadAvatarMedia(event.target.files[0]);
baseSetUserAvatar({ type: 'image', uploadID: uploadResult.id });
},
[baseSetUserAvatar, uploadAvatarMedia],
);
const imageMenuItem = React.useMemo(
() => (
),
[onImageMenuItemClicked],
);
const setENSUserAvatar = React.useCallback(
() => baseSetUserAvatar({ type: 'ens' }),
[baseSetUserAvatar],
);
const ethereumIcon = React.useMemo(
() => ,
[],
);
const ensMenuItem = React.useMemo(
() => (
),
[ethereumIcon, setENSUserAvatar],
);
const removeMenuItem = React.useMemo(
() => (
),
[removeUserAvatar],
);
const menuItems = React.useMemo(() => {
const items = [emojiMenuItem, imageMenuItem];
if (ensAvatarURI) {
items.push(ensMenuItem);
}
if (currentUserInfo?.avatar) {
items.push(removeMenuItem);
}
return items;
}, [
currentUserInfo?.avatar,
emojiMenuItem,
ensAvatarURI,
ensMenuItem,
imageMenuItem,
removeMenuItem,
]);
return (
);
}
export default EditUserAvatarMenu;
diff --git a/web/avatars/emoji-avatar-selection-modal.react.js b/web/avatars/emoji-avatar-selection-modal.react.js
index 2696d4ad8..8de4338e8 100644
--- a/web/avatars/emoji-avatar-selection-modal.react.js
+++ b/web/avatars/emoji-avatar-selection-modal.react.js
@@ -1,169 +1,155 @@
// @flow
import data from '@emoji-mart/data';
import Picker from '@emoji-mart/react';
-import invariant from 'invariant';
import * as React from 'react';
-import { EditUserAvatarContext } from 'lib/components/edit-user-avatar-provider.react.js';
import { useModalContext } from 'lib/components/modal-provider.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import {
- defaultAnonymousUserEmojiAvatar,
- getAvatarForUser,
- getDefaultAvatar,
-} from 'lib/shared/avatar-utils.js';
import type {
ClientAvatar,
ClientEmojiAvatar,
} from 'lib/types/avatar-types.js';
import Avatar from './avatar.react.js';
import css from './emoji-avatar-selection-modal.css';
import Button, { buttonThemes } from '../components/button.react.js';
import Tabs from '../components/tabs.react.js';
import LoadingIndicator from '../loading-indicator.react.js';
import Modal from '../modals/modal.react.js';
import ColorSelector from '../modals/threads/color-selector.react.js';
-import { useSelector } from '../redux/redux-utils.js';
type TabType = 'emoji' | 'color';
-function EmojiAvatarSelectionModal(): React.Node {
+type Props = {
+ +currentAvatar: ClientAvatar,
+ +defaultAvatar: ClientEmojiAvatar,
+ +setEmojiAvatar: (pendingEmojiAvatar: ClientEmojiAvatar) => Promise,
+ +avatarSaveInProgress: boolean,
+};
+function EmojiAvatarSelectionModal(props: Props): React.Node {
const { popModal } = useModalContext();
- const editUserAvatarContext = React.useContext(EditUserAvatarContext);
- invariant(editUserAvatarContext, 'editUserAvatarContext should be set');
-
- const { baseSetUserAvatar, userAvatarSaveInProgress } = editUserAvatarContext;
+ const { currentAvatar, defaultAvatar, setEmojiAvatar, avatarSaveInProgress } =
+ props;
const [updateAvatarStatus, setUpdateAvatarStatus] =
React.useState('success' | 'failure')>();
- const currentUserInfo = useSelector(state => state.currentUserInfo);
- const currentUserAvatar: ClientAvatar = getAvatarForUser(currentUserInfo);
- const defaultUserAvatar: ClientEmojiAvatar = currentUserInfo?.username
- ? getDefaultAvatar(currentUserInfo.username)
- : defaultAnonymousUserEmojiAvatar;
-
const [pendingAvatarEmoji, setPendingAvatarEmoji] = React.useState(
- currentUserAvatar.type === 'emoji'
- ? currentUserAvatar.emoji
- : defaultUserAvatar.emoji,
+ currentAvatar.type === 'emoji' ? currentAvatar.emoji : defaultAvatar.emoji,
);
const [pendingAvatarColor, setPendingAvatarColor] = React.useState(
- currentUserAvatar.type === 'emoji'
- ? currentUserAvatar.color
- : defaultUserAvatar.color,
+ currentAvatar.type === 'emoji' ? currentAvatar.color : defaultAvatar.color,
);
const pendingEmojiAvatar: ClientEmojiAvatar = React.useMemo(
() => ({
type: 'emoji',
emoji: pendingAvatarEmoji,
color: pendingAvatarColor,
}),
[pendingAvatarColor, pendingAvatarEmoji],
);
const onEmojiSelect = React.useCallback(selection => {
setUpdateAvatarStatus();
setPendingAvatarEmoji(selection.native);
}, []);
const onColorSelection = React.useCallback((hex: string) => {
setUpdateAvatarStatus();
setPendingAvatarColor(hex);
}, []);
const onSaveAvatar = React.useCallback(async () => {
try {
- await baseSetUserAvatar(pendingEmojiAvatar);
+ await setEmojiAvatar(pendingEmojiAvatar);
setUpdateAvatarStatus('success');
} catch {
setUpdateAvatarStatus('failure');
}
- }, [pendingEmojiAvatar, baseSetUserAvatar]);
+ }, [setEmojiAvatar, pendingEmojiAvatar]);
let saveButtonContent;
let buttonColor;
- if (userAvatarSaveInProgress) {
+ if (avatarSaveInProgress) {
buttonColor = buttonThemes.standard;
saveButtonContent = ;
} else if (updateAvatarStatus === 'success') {
buttonColor = buttonThemes.success;
saveButtonContent = (
<>
{'Avatar update succeeded.'}
>
);
} else if (updateAvatarStatus === 'failure') {
buttonColor = buttonThemes.danger;
saveButtonContent = (
<>
{'Avatar update failed. Please try again.'}
>
);
} else {
buttonColor = buttonThemes.standard;
saveButtonContent = 'Save Avatar';
}
const [currentTabType, setCurrentTabType] = React.useState('emoji');
return (
);
}
export default EmojiAvatarSelectionModal;
diff --git a/web/avatars/user-emoji-avatar-selection-modal.react.js b/web/avatars/user-emoji-avatar-selection-modal.react.js
new file mode 100644
index 000000000..6fb209b4a
--- /dev/null
+++ b/web/avatars/user-emoji-avatar-selection-modal.react.js
@@ -0,0 +1,43 @@
+// @flow
+
+import invariant from 'invariant';
+import * as React from 'react';
+
+import { EditUserAvatarContext } from 'lib/components/edit-user-avatar-provider.react.js';
+import {
+ defaultAnonymousUserEmojiAvatar,
+ getAvatarForUser,
+ getDefaultAvatar,
+} from 'lib/shared/avatar-utils.js';
+import type {
+ ClientAvatar,
+ ClientEmojiAvatar,
+} from 'lib/types/avatar-types.js';
+
+import EmojiAvatarSelectionModal from './emoji-avatar-selection-modal.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+
+function UserEmojiAvatarSelectionModal(): React.Node {
+ const editUserAvatarContext = React.useContext(EditUserAvatarContext);
+ invariant(editUserAvatarContext, 'editUserAvatarContext should be set');
+
+ const { baseSetUserAvatar, userAvatarSaveInProgress } = editUserAvatarContext;
+
+ const currentUserInfo = useSelector(state => state.currentUserInfo);
+ const currentUserAvatar: ClientAvatar = getAvatarForUser(currentUserInfo);
+
+ const defaultUserAvatar: ClientEmojiAvatar = currentUserInfo?.username
+ ? getDefaultAvatar(currentUserInfo.username)
+ : defaultAnonymousUserEmojiAvatar;
+
+ return (
+
+ );
+}
+
+export default UserEmojiAvatarSelectionModal;