diff --git a/web/modals/user-profile/user-profile-modal.react.js b/web/modals/user-profile/user-profile-modal.react.js index 57945b62a..768f3e30c 100644 --- a/web/modals/user-profile/user-profile-modal.react.js +++ b/web/modals/user-profile/user-profile-modal.react.js @@ -1,37 +1,56 @@ // @flow import * as React from 'react'; import { useModalContext } from 'lib/components/modal-provider.react.js'; +import { useUserProfileThreadInfo } from 'lib/shared/thread-utils.js'; import type { UserInfo } from 'lib/types/user-types.js'; +import UserProfileMenu from './user-profile-menu.react.js'; import UserProfile from './user-profile.react.js'; import { useSelector } from '../../redux/redux-utils.js'; import Modal from '../modal.react.js'; type Props = { +userID: string, }; function UserProfileModal(props: Props): React.Node { const { userID } = props; const { popModal } = useModalContext(); const userInfo: ?UserInfo = useSelector( state => state.userStore.userInfos[userID], ); + const userProfileThreadInfo = useUserProfileThreadInfo(userInfo); + + const menuButton = React.useMemo(() => { + if (!userProfileThreadInfo) { + // The case for anonymous users + return null; + } + return ; + }, [userProfileThreadInfo]); + const userProfileModal = React.useMemo( () => ( - - + + ), - [popModal, userInfo], + [menuButton, popModal, userInfo, userProfileThreadInfo], ); return userProfileModal; } export default UserProfileModal; diff --git a/web/modals/user-profile/user-profile.react.js b/web/modals/user-profile/user-profile.react.js index f77645a21..9b2d26564 100644 --- a/web/modals/user-profile/user-profile.react.js +++ b/web/modals/user-profile/user-profile.react.js @@ -1,89 +1,88 @@ // @flow import * as React from 'react'; import SWMansionIcon from 'lib/components/SWMansionIcon.react.js'; import { relationshipBlockedInEitherDirection } from 'lib/shared/relationship-utils.js'; -import { useUserProfileThreadInfo } from 'lib/shared/thread-utils.js'; import { stringForUserExplicit } from 'lib/shared/user-utils.js'; +import type { UserProfileThreadInfo } from 'lib/types/thread-types'; import type { UserInfo } from 'lib/types/user-types'; import sleep from 'lib/utils/sleep.js'; import UserProfileActionButtons from './user-profile-action-buttons.react.js'; import css from './user-profile.css'; import UserAvatar from '../../avatars/user-avatar.react.js'; type Props = { +userInfo: ?UserInfo, + +userProfileThreadInfo: ?UserProfileThreadInfo, }; function UserProfile(props: Props): React.Node { - const { userInfo } = props; - - const userProfileThreadInfo = useUserProfileThreadInfo(userInfo); + const { userInfo, userProfileThreadInfo } = props; const usernameText = stringForUserExplicit(userInfo); const [usernameCopied, setUsernameCopied] = React.useState(false); const onClickCopyUsername = React.useCallback(async () => { if (usernameCopied) { return; } await navigator.clipboard.writeText(usernameText); setUsernameCopied(true); await sleep(3000); setUsernameCopied(false); }, [usernameCopied, usernameText]); const actionButtons = React.useMemo(() => { if ( !userProfileThreadInfo || relationshipBlockedInEitherDirection(userInfo?.relationshipStatus) ) { return null; } return ( ); }, [userInfo?.relationshipStatus, userProfileThreadInfo]); const userProfile = React.useMemo( () => (
{usernameText}

{!usernameCopied ? 'Copy username' : 'Username copied!'}

{actionButtons}
), [ actionButtons, onClickCopyUsername, userInfo?.id, usernameCopied, usernameText, ], ); return userProfile; } export default UserProfile;