diff --git a/native/components/user-profile-relationship-button.react.js b/native/components/user-profile-relationship-button.react.js new file mode 100644 index 000000000..86a2e1af0 --- /dev/null +++ b/native/components/user-profile-relationship-button.react.js @@ -0,0 +1,122 @@ +// @flow + +import * as React from 'react'; +import { View, Text } from 'react-native'; + +import { useRelationshipPrompt } from 'lib/hooks/relationship-prompt.js'; +import { userRelationshipStatus } from 'lib/types/relationship-types.js'; +import type { ThreadInfo } from 'lib/types/thread-types.js'; +import type { UserInfo } from 'lib/types/user-types'; + +import RelationshipButton from './relationship-button.react.js'; +import { useStyles } from '../themes/colors.js'; +import Alert from '../utils/alert.js'; + +const onErrorCallback = () => { + Alert.alert('Unknown error', 'Uhh... try again?', [{ text: 'OK' }]); +}; + +type Props = { + +threadInfo: ThreadInfo, + +pendingPersonalThreadUserInfo?: UserInfo, +}; + +function UserProfileRelationshipButton(props: Props): React.Node { + const { threadInfo, pendingPersonalThreadUserInfo } = props; + + const { + otherUserInfo, + callbacks: { friendUser, unfriendUser }, + } = useRelationshipPrompt( + threadInfo, + onErrorCallback, + pendingPersonalThreadUserInfo, + ); + + const styles = useStyles(unboundStyles); + + const userProfileRelationshipButton = React.useMemo(() => { + if ( + !otherUserInfo || + !otherUserInfo.username || + otherUserInfo.relationshipStatus === userRelationshipStatus.FRIEND + ) { + return null; + } + + if ( + otherUserInfo.relationshipStatus === + userRelationshipStatus.REQUEST_RECEIVED + ) { + return ( + + + Incoming friend request + + + + + + + + + + + ); + } + + if ( + otherUserInfo.relationshipStatus === userRelationshipStatus.REQUEST_SENT + ) { + return ( + + + + ); + } + + return ( + + + + ); + }, [ + friendUser, + otherUserInfo, + styles.acceptFriendRequestButtonContainer, + styles.incomingFriendRequestButtonsContainer, + styles.incomingFriendRequestContainer, + styles.incomingFriendRequestLabel, + styles.rejectFriendRequestButtonContainer, + styles.singleButtonContainer, + unfriendUser, + ]); + + return userProfileRelationshipButton; +} + +const unboundStyles = { + singleButtonContainer: { + marginTop: 16, + }, + incomingFriendRequestContainer: { + marginTop: 24, + }, + incomingFriendRequestLabel: { + color: 'modalForegroundLabel', + }, + incomingFriendRequestButtonsContainer: { + flexDirection: 'row', + marginTop: 8, + }, + acceptFriendRequestButtonContainer: { + flex: 1, + marginRight: 4, + }, + rejectFriendRequestButtonContainer: { + flex: 1, + marginLeft: 4, + }, +}; + +export default UserProfileRelationshipButton; diff --git a/native/components/user-profile.react.js b/native/components/user-profile.react.js index 1cf8fa47a..3e9da772d 100644 --- a/native/components/user-profile.react.js +++ b/native/components/user-profile.react.js @@ -1,157 +1,176 @@ // @flow import Clipboard from '@react-native-clipboard/clipboard'; import * as React from 'react'; import { View, Text, TouchableOpacity } from 'react-native'; 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 { UserInfo } from 'lib/types/user-types'; import sleep from 'lib/utils/sleep.js'; import SWMansionIcon from './swmansion-icon.react.js'; import UserProfileMessageButton from './user-profile-message-button.react.js'; +import UserProfileRelationshipButton from './user-profile-relationship-button.react.js'; import UserAvatar from '../avatars/user-avatar.react.js'; import SingleLine from '../components/single-line.react.js'; import { useStyles } from '../themes/colors.js'; type Props = { +userInfo: ?UserInfo, }; function UserProfile(props: Props): React.Node { const { userInfo } = props; const userProfileThreadInfo = useUserProfileThreadInfo(userInfo); const usernameText = stringForUserExplicit(userInfo); const [usernameCopied, setUsernameCopied] = React.useState(false); const styles = useStyles(unboundStyles); const onPressCopyUsername = React.useCallback(async () => { Clipboard.setString(usernameText); setUsernameCopied(true); await sleep(3000); setUsernameCopied(false); }, [usernameText]); const copyUsernameButton = React.useMemo(() => { if (usernameCopied) { return ( Username copied! ); } return ( Copy username ); }, [ onPressCopyUsername, styles.copyUsernameContainer, styles.copyUsernameIcon, styles.copyUsernameText, usernameCopied, ]); const messageButton = React.useMemo(() => { if ( !userProfileThreadInfo || relationshipBlockedInEitherDirection(userInfo?.relationshipStatus) ) { return null; } const { threadInfo, pendingPersonalThreadUserInfo } = userProfileThreadInfo; return ( ); }, [userInfo?.relationshipStatus, userProfileThreadInfo]); + const relationshipButton = React.useMemo(() => { + if ( + !userProfileThreadInfo || + relationshipBlockedInEitherDirection(userInfo?.relationshipStatus) + ) { + return null; + } + + const { threadInfo, pendingPersonalThreadUserInfo } = userProfileThreadInfo; + return ( + + ); + }, [userInfo?.relationshipStatus, userProfileThreadInfo]); + return ( {usernameText} {copyUsernameButton} {messageButton} + {relationshipButton} ); } const unboundStyles = { container: { paddingHorizontal: 16, }, moreIcon: { color: 'modalButtonLabel', alignSelf: 'flex-end', }, userInfoContainer: { flexDirection: 'row', }, usernameContainer: { flex: 1, justifyContent: 'center', alignItems: 'flex-start', paddingLeft: 16, }, usernameText: { color: 'modalForegroundLabel', fontSize: 18, fontWeight: '500', }, copyUsernameContainer: { flexDirection: 'row', justifyContent: 'center', paddingTop: 8, }, copyUsernameIcon: { color: 'purpleLink', marginRight: 4, }, copyUsernameText: { color: 'purpleLink', fontSize: 12, }, messageButtonContainer: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', backgroundColor: 'purpleButton', paddingVertical: 8, marginTop: 16, borderRadius: 8, }, messageButtonIcon: { color: 'floatingButtonLabel', paddingRight: 8, }, messageButtonText: { color: 'floatingButtonLabel', }, }; export default UserProfile;