diff --git a/src/components/common/PeerColorWrapper.tsx b/src/components/common/PeerColorWrapper.tsx
new file mode 100644
index 000000000..8f0b3e83e
--- /dev/null
+++ b/src/components/common/PeerColorWrapper.tsx
@@ -0,0 +1,35 @@
+import React, { memo } from '../../lib/teact/teact';
+
+import type { ApiPeer } from '../../api/types';
+
+import buildClassName from '../../util/buildClassName';
+import { getPeerColorClass } from './helpers/peerColor';
+
+import EmojiIconBackground from './embedded/EmojiIconBackground';
+
+type OwnProps = {
+ peer?: ApiPeer;
+ noUserColors?: boolean;
+ shoudReset?: boolean;
+ className?: string;
+ emojiIconClassName?: string;
+ children: React.ReactNode;
+};
+
+function PeerColorWrapper({
+ peer, noUserColors, shoudReset, className, emojiIconClassName, children,
+}: OwnProps) {
+ return (
+
+ {peer?.color?.backgroundEmojiId && (
+
+ )}
+ {children}
+
+ );
+}
+
+export default memo(PeerColorWrapper);
diff --git a/src/components/middle/message/Contact.module.scss b/src/components/middle/message/Contact.module.scss
new file mode 100644
index 000000000..e3c67136a
--- /dev/null
+++ b/src/components/middle/message/Contact.module.scss
@@ -0,0 +1,83 @@
+.root {
+ position: relative;
+ margin: 0.25rem 0.25rem 0.875rem 0.25rem;
+ border-radius: 0.25rem;
+ overflow: hidden;
+ background-color: var(--accent-background-color);
+ color: var(--accent-color);
+
+ &::before {
+ content: "";
+ display: block;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ inset-inline-start: 0;
+ width: 0.1875rem;
+ background: var(--bar-gradient, var(--accent-color));
+ }
+}
+
+.info-container {
+ display: flex;
+ padding: 0.5rem 1.5rem 0.5rem 0.75rem;
+ cursor: var(--custom-cursor, pointer);
+}
+
+.info {
+ display: flex;
+ flex-direction: column;
+ align-self: center;
+ margin-left: 0.5rem;
+}
+
+.name {
+ font-size: 1rem;
+ margin-bottom: 0.25rem;
+ font-weight: 500;
+ max-width: 12.5rem;
+}
+
+.phone {
+ color: var(--color-text);
+}
+
+.name,
+.phone {
+ line-height: 1rem;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.divider {
+ height: 0.0625rem;
+ margin: 0 0.5rem;
+ background: var(--accent-color);
+ filter: opacity(0.4)
+}
+
+.buttons {
+ display: flex;
+
+ .button {
+ width: auto;
+ flex: 1;
+ height: 2.25rem;
+ border-radius: 0;
+ font-weight: 500;
+ background-color: transparent;
+ color: var(--accent-color);
+ --ripple-color: var(--accent-background-active-color);
+
+ &:not(.disabled):not(:disabled):hover {
+ color: var(--accent-color);
+ background-color: transparent;
+ }
+ }
+}
+
+.emoji-icon-background {
+ margin-bottom: 2.25rem;
+}
+
\ No newline at end of file
diff --git a/src/components/middle/message/Contact.scss b/src/components/middle/message/Contact.scss
deleted file mode 100644
index a57e0f815..000000000
--- a/src/components/middle/message/Contact.scss
+++ /dev/null
@@ -1,38 +0,0 @@
-.Contact {
- display: flex;
- align-items: center;
- padding: 0.25rem;
-
- &.interactive {
- cursor: var(--custom-cursor, pointer);
- }
-
- .Avatar {
- margin-right: 0.8125rem;
- }
-
- .contact-info {
- padding: 0.5rem;
- padding-left: 0;
- white-space: nowrap;
- overflow: hidden;
-
- .contact-name {
- font-size: 1rem;
- margin-bottom: 0.25rem;
- font-weight: 500;
- }
-
- .contact-phone {
- color: var(--secondary-color);
- }
-
- .contact-name,
- .contact-phone {
- line-height: 1rem;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- }
- }
-}
diff --git a/src/components/middle/message/Contact.tsx b/src/components/middle/message/Contact.tsx
index 6bff7fd96..cdd617af4 100644
--- a/src/components/middle/message/Contact.tsx
+++ b/src/components/middle/message/Contact.tsx
@@ -4,15 +4,19 @@ import { getActions, withGlobal } from '../../../global';
import type { ApiContact, ApiCountryCode, ApiUser } from '../../../api/types';
+import { getCanAddContact, getUserFullName } from '../../../global/helpers';
import { selectUser } from '../../../global/selectors';
-import buildClassName from '../../../util/buildClassName';
+import { copyTextToClipboard } from '../../../util/clipboard';
import { formatPhoneNumberWithCode } from '../../../util/phoneNumber';
+import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import Avatar from '../../common/Avatar';
+import PeerColorWrapper from '../../common/PeerColorWrapper';
+import Button from '../../ui/Button';
-import './Contact.scss';
+import styles from './Contact.module.scss';
type OwnProps = {
contact: ApiContact;
@@ -28,38 +32,81 @@ const UNREGISTERED_CONTACT_ID = '0';
const Contact: FC = ({
contact, user, phoneCodeList,
}) => {
- const { openChat } = getActions();
+ const lang = useLang();
+ const {
+ openChat, openAddContactDialog, showNotification, openChatWithInfo,
+ } = getActions();
const {
- firstName,
- lastName,
phoneNumber,
userId,
} = contact;
const isRegistered = userId !== UNREGISTERED_CONTACT_ID;
+ const canAddContact = isRegistered && user && getCanAddContact(user);
- const handleClick = useLastCallback(() => {
+ const handleOpenChat = useLastCallback(() => {
openChat({ id: userId });
});
+ const handleAddContact = useLastCallback(() => {
+ openAddContactDialog({ userId: user?.id });
+ });
+
+ const handleClick = useLastCallback(() => {
+ if (user) {
+ openChatWithInfo({ id: userId });
+ } else {
+ copyTextToClipboard(phoneNumber);
+ showNotification({ message: lang('PhoneCopied') });
+ }
+ });
+
return (
-
-
-
-
{firstName} {lastName}
-
{formatPhoneNumberWithCode(phoneCodeList, phoneNumber)}
+
+
+
+
+
+ {user ? getUserFullName(user) : getContactName(contact)}
+
+
{formatPhoneNumberWithCode(phoneCodeList, phoneNumber)}
+
-
+ {isRegistered && (
+ <>
+
+
+
+ {canAddContact && (
+
+ )}
+
+ >
+ )}
+
);
};
+function getContactName(contact: ApiContact) {
+ if (contact.firstName && contact.lastName) {
+ return `${contact.firstName} ${contact.lastName}`;
+ }
+
+ if (contact.firstName) {
+ return contact.firstName;
+ }
+
+ if (contact.lastName) {
+ return contact.lastName;
+ }
+
+ return '';
+}
+
export default withGlobal
(
(global, { contact }): StateProps => {
const { countryList: { phoneCodes: phoneCodeList } } = global;