diff --git a/web/components/single-line.css b/web/components/single-line.css
new file mode 100644
index 000000000..137ff62ed
--- /dev/null
+++ b/web/components/single-line.css
@@ -0,0 +1,5 @@
+.singleLine {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
diff --git a/web/components/single-line.react.js b/web/components/single-line.react.js
new file mode 100644
index 000000000..ec577a45d
--- /dev/null
+++ b/web/components/single-line.react.js
@@ -0,0 +1,25 @@
+// @flow
+
+import classNames from 'classnames';
+import * as React from 'react';
+
+import { firstLine } from 'lib/utils/string-utils.js';
+
+import css from './single-line.css';
+
+type Props = {
+ +children: string,
+ +className?: string,
+};
+
+function SingleLine(props: Props): React.Node {
+ const { children, className } = props;
+
+ const text = firstLine(children);
+
+ const singleLineClassName = classNames([css.singleLine, className]);
+
+ return
{text}
;
+}
+
+export default SingleLine;
diff --git a/web/modals/user-profile/user-profile.css b/web/modals/user-profile/user-profile.css
index 073227f6f..0a64ae971 100644
--- a/web/modals/user-profile/user-profile.css
+++ b/web/modals/user-profile/user-profile.css
@@ -1,57 +1,58 @@
.container {
padding: 0 32px 32px;
width: 552px;
max-width: 80vw;
}
.userInfoContainer {
display: flex;
align-items: center;
margin-bottom: 24px;
}
.userAvatarContainer:hover {
cursor: pointer;
}
.usernameContainer {
- padding-left: 16px;
+ margin-left: 16px;
+ overflow: hidden;
}
.usernameText {
font-size: var(--xxl-font-24);
color: var(--fg);
font-weight: 500;
}
.copyUsernameContainer {
display: flex;
align-items: center;
color: var(--purple-link);
margin-top: 8px;
}
.copyUsernameContainer:hover {
cursor: pointer;
}
.copyUsernameText {
font-size: var(--xs-font-12);
margin-left: 4px;
}
.multiButtonRowContainer {
display: flex;
column-gap: 8px;
}
.actionButton {
column-gap: 8px;
flex: 1;
width: 100%;
}
.incomingFriendRequestText {
color: var(--fg);
margin: 24px 0 8px 0;
}
diff --git a/web/modals/user-profile/user-profile.react.js b/web/modals/user-profile/user-profile.react.js
index d16300110..64f3d5433 100644
--- a/web/modals/user-profile/user-profile.react.js
+++ b/web/modals/user-profile/user-profile.react.js
@@ -1,99 +1,100 @@
// @flow
import * as React from 'react';
import { useModalContext } from 'lib/components/modal-provider.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
import { relationshipBlockedInEitherDirection } from 'lib/shared/relationship-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 UserProfileAvatarModal from './user-profile-avatar-modal.react.js';
import css from './user-profile.css';
import UserAvatar from '../../avatars/user-avatar.react.js';
+import SingleLine from '../../components/single-line.react.js';
type Props = {
+userInfo: ?UserInfo,
+userProfileThreadInfo: ?UserProfileThreadInfo,
};
function UserProfile(props: Props): React.Node {
const { userInfo, userProfileThreadInfo } = props;
const { pushModal } = useModalContext();
const usernameText = stringForUserExplicit(userInfo);
const [usernameCopied, setUsernameCopied] = React.useState(false);
const onClickUserAvatar = React.useCallback(() => {
pushModal();
}, [pushModal, userInfo?.id]);
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}
+
{usernameText}
{!usernameCopied ? 'Copy username' : 'Username copied!'}
{actionButtons}
),
[
actionButtons,
onClickCopyUsername,
onClickUserAvatar,
userInfo?.id,
usernameCopied,
usernameText,
],
);
return userProfile;
}
export default UserProfile;