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;