diff --git a/packages/react-chat/src/components/Chat/ChatMessages.tsx b/packages/react-chat/src/components/Chat/ChatMessages.tsx index c04c9322..44a319a1 100644 --- a/packages/react-chat/src/components/Chat/ChatMessages.tsx +++ b/packages/react-chat/src/components/Chat/ChatMessages.tsx @@ -28,6 +28,9 @@ type ChatUiMessageProps = { setImage: (img: string) => void; setLink: (link: string) => void; setUser: (user: string) => void; + customName?: string; + trueName?: string; + setRenaming: (val: boolean) => void; }; function ChatUiMessage({ @@ -37,6 +40,9 @@ function ChatUiMessage({ setImage, setLink, setUser, + customName, + trueName, + setRenaming, }: ChatUiMessageProps) { const [showMenu, setShowMenu] = useState(false); const [isUntrustworthy, setIsUntrustworthy] = useState(false); @@ -63,6 +69,9 @@ function ChatUiMessage({ setShowMenu={setShowMenu} isUntrustworthy={isUntrustworthy} setIsUntrustworthy={setIsUntrustworthy} + customName={customName} + trueName={trueName} + setRenaming={setRenaming} /> )} @@ -71,7 +80,15 @@ function ChatUiMessage({ - {message.sender.slice(0, 10)} + + {" "} + {customName ? customName : message.sender.slice(0, 10)} + + {customName && ( + + {message.sender.slice(0, 5)}...{message.sender.slice(-3)} + + )} {isUntrustworthy && } {message.date.toLocaleString()} @@ -119,11 +136,23 @@ export function ChatMessages() { ); useEffect(() => (!showLinkModal ? setLink("") : undefined), [showLinkModal]); + const [renaming, setRenaming] = useState(false); + const [customName, setCustomName] = useState(""); + const [trueName, setTrueName] = useState(""); + return ( - + {loadingMessages && ( @@ -139,6 +168,9 @@ export function ChatMessages() { setLink={setLink} setImage={setImage} setUser={setUser} + customName={customName} + trueName={trueName} + setRenaming={setRenaming} /> ))} @@ -226,6 +258,27 @@ const UserName = styled.p` ${textMediumStyles} `; +export const UserAddress = styled.p` + font-size: 10px; + line-height: 14px; + letter-spacing: 0.2px; + color: ${({ theme }) => theme.secondary}; + position: relative; + padding-right: 8px; + + &:after { + content: ""; + position: absolute; + right: 0; + top: 50%; + transform: translateY(-50%); + width: 4px; + height: 4px; + border-radius: 50%; + background: ${({ theme }) => theme.secondary}; + } +`; + const TimeWrapper = styled.div` font-size: 10px; line-height: 14px; diff --git a/packages/react-chat/src/components/Form/ContactMenu.tsx b/packages/react-chat/src/components/Form/ContactMenu.tsx index 7378b871..a9c73a87 100644 --- a/packages/react-chat/src/components/Form/ContactMenu.tsx +++ b/packages/react-chat/src/components/Form/ContactMenu.tsx @@ -5,7 +5,7 @@ import { useBlockedUsers } from "../../contexts/blockedUsersProvider"; import { useFriends } from "../../contexts/friendsProvider"; import { useModal } from "../../contexts/modalProvider"; import { ChatMessage } from "../../models/ChatMessage"; -import { Icon } from "../Chat/ChatMessages"; +import { Icon, UserAddress } from "../Chat/ChatMessages"; import { AddContactSvg } from "../Icons/AddContactIcon"; import { BlockSvg } from "../Icons/BlockIcon"; import { ChatSvg } from "../Icons/ChatIcon"; @@ -24,6 +24,9 @@ type ContactMenuProps = { setShowMenu: (val: boolean) => void; isUntrustworthy: boolean; setIsUntrustworthy: (val: boolean) => void; + customName?: string; + trueName?: string; + setRenaming: (val: boolean) => void; }; export function ContactMenu({ @@ -31,6 +34,9 @@ export function ContactMenu({ setShowMenu, isUntrustworthy, setIsUntrustworthy, + customName, + trueName, + setRenaming, }: ContactMenuProps) { const id = message.sender; const { blockedUsers, setBlockedUsers } = useBlockedUsers(); @@ -59,9 +65,12 @@ export function ContactMenu({ )} - {message.sender.slice(0, 10)} + + {customName ? customName : message.sender.slice(0, 10)} + {isUntrustworthy && } + {trueName && ({trueName})} {message.sender.slice(0, 10)}...{message.sender.slice(-3)} @@ -83,7 +92,12 @@ export function ContactMenu({ Send Message )} - + { + setModal(true); + setRenaming(true); + }} + > Rename @@ -151,10 +165,10 @@ const UserName = styled.p` ${textMediumStyles} `; -const UserAddress = styled.p` - font-size: 10px; - line-height: 14px; - letter-spacing: 0.2px; - margin-bottom: 8px; - color: ${({ theme }) => theme.secondary}; +const UserTrueName = styled.p` + color: ${({ theme }) => theme.primary}; + font-size: 12px; + line-height: 16px; + letter-spacing: 0.1px; + margin-top: 4px; `; diff --git a/packages/react-chat/src/components/Icons/ClearIcon.tsx b/packages/react-chat/src/components/Icons/ClearIcon.tsx index 3d537d12..27d6e293 100644 --- a/packages/react-chat/src/components/Icons/ClearIcon.tsx +++ b/packages/react-chat/src/components/Icons/ClearIcon.tsx @@ -13,7 +13,6 @@ export function ClearSvg({ height, width, className }: ClearSvgProps) { width={width} height={height} viewBox="0 0 16 16" - fill="none" xmlns="http://www.w3.org/2000/svg" className={className} > @@ -36,6 +35,14 @@ const Icon = styled(ClearSvg)` fill: ${({ theme }) => theme.tertiary}; } + &.profile { + fill: ${({ theme }) => theme.secondary}; + } + + &.profile > path { + fill: ${({ theme }) => theme.bodyBackgroundColor}; + } + &:hover > path { fill: ${({ theme }) => theme.bodyBackgroundColor}; } diff --git a/packages/react-chat/src/components/Modals/ModalStyle.ts b/packages/react-chat/src/components/Modals/ModalStyle.ts index cadc3dad..f8f4a7d5 100644 --- a/packages/react-chat/src/components/Modals/ModalStyle.ts +++ b/packages/react-chat/src/components/Modals/ModalStyle.ts @@ -26,4 +26,6 @@ export const Text = styled.p` export const ButtonSection = styled(Section)` display: flex; justify-content: flex-end; + align-items: center; + position: relative; `; diff --git a/packages/react-chat/src/components/Modals/ProfileModal.tsx b/packages/react-chat/src/components/Modals/ProfileModal.tsx index 962cb593..8cdfe431 100644 --- a/packages/react-chat/src/components/Modals/ProfileModal.tsx +++ b/packages/react-chat/src/components/Modals/ProfileModal.tsx @@ -5,8 +5,10 @@ import { useBlockedUsers } from "../../contexts/blockedUsersProvider"; import { useFriends } from "../../contexts/friendsProvider"; import { copy } from "../../utils"; import { buttonStyles } from "../Buttons/buttonStyle"; +import { ClearSvg } from "../Icons/ClearIcon"; import { CopySvg } from "../Icons/CopyIcon"; import { EditSvg } from "../Icons/EditIcon"; +import { LeftIconSvg } from "../Icons/LeftIcon"; import { UntrustworthIcon } from "../Icons/UntrustworthIcon"; import { UserIcon } from "../Icons/UserIcon"; import { textMediumStyles } from "../Text"; @@ -19,9 +21,24 @@ export const ProfileModalName = "profileModal"; interface ProfileModalProps { user: string; image?: string; + renaming: boolean; + customName?: string; + trueName?: string; + setRenaming: (val: boolean) => void; + setTrueName: (val: string) => void; + setCustomName: (val: string) => void; } -export const ProfileModal = ({ user, image }: ProfileModalProps) => { +export const ProfileModal = ({ + user, + image, + renaming, + customName, + trueName, + setRenaming, + setTrueName, + setCustomName, +}: ProfileModalProps) => { const [isUntrustworthy, setIsUntrustworthy] = useState(false); const { blockedUsers, setBlockedUsers } = useBlockedUsers(); @@ -41,7 +58,7 @@ export const ProfileModal = ({ user, image }: ProfileModalProps) => { {user.slice(0, 10)}’s Profile -
+ {image ? ( { )} - {user.slice(0, 10)} + {customName ? customName : user.slice(0, 10)} {isUntrustworthy && } - + {!renaming && ( + + )} + {trueName && {trueName}} + {trueName && } + {renaming ? ( + + setCustomName(e.currentTarget.value)} + /> + {customName && ( + { + setCustomName(""); + setTrueName(""); + }} + > + + + )} + + ) : ( + <> + + Chatkey: {user.slice(0, 30)} - - Chatkey: {user.slice(0, 30)} - - copy(user)}> - - - - - 🎩🍞πŸ₯‘πŸ¦πŸŒˆπŸ“‘πŸ’…πŸ»β™£οΈπŸ””β›ΈπŸ‘΅πŸ…± -
+ copy(user)}> + + + + 🎩🍞πŸ₯‘πŸ¦πŸŒˆπŸ“‘πŸ’…πŸ»β™£οΈπŸ””β›ΈπŸ‘΅πŸ…±{" "} + + )} + - {!userIsFriend && ( - { - userInBlocked - ? setBlockedUsers((prev) => prev.filter((e) => e != user)) - : setBlockedUsers((prev) => [...prev, user]); - }} - > - {userInBlocked ? "Unblock" : "Block"} - - )} - {userIsFriend && ( - setFriends((prev) => prev.filter((e) => e != user))} - > - Remove Contact - - )} - setIsUntrustworthy(!isUntrustworthy)} - > - {isUntrustworthy - ? "Remove Untrustworthy Mark" - : "Mark as Untrustworthy"} - - {!userIsFriend && ( - setFriends((prev) => [...prev, user])}> - Send Contact Request - + {renaming ? ( + <> + setRenaming(false)}> + + + { + setTrueName(user.slice(0, 10)); + setRenaming(false); + }} + > + Apply nickname + + + ) : ( + <> + {!userIsFriend && ( + { + userInBlocked + ? setBlockedUsers((prev) => prev.filter((e) => e != user)) + : setBlockedUsers((prev) => [...prev, user]); + }} + > + {userInBlocked ? "Unblock" : "Block"} + + )} + {userIsFriend && ( + + setFriends((prev) => prev.filter((e) => e != user)) + } + > + Remove Contact + + )} + setIsUntrustworthy(!isUntrustworthy)} + > + {isUntrustworthy + ? "Remove Untrustworthy Mark" + : "Mark as Untrustworthy"} + + {!userIsFriend && ( + setFriends((prev) => [...prev, user])}> + Send Contact Request + + )} + )} ); }; +const ProfileSection = styled(Section)` + display: flex; + flex-direction: column; + align-items: center; +`; + const NameSection = styled.div` display: flex; flex-direction: column; + justify-content: center; align-items: center; margin-bottom: 16px; `; @@ -150,6 +222,14 @@ const UserName = styled.p` margin-right: 8px; `; +const UserTrueName = styled.p` + color: ${({ theme }) => theme.primary}; + font-size: 12px; + line-height: 16px; + letter-spacing: 0.1px; + margin-top: 8px; +`; + const UserAddressWrapper = styled.div` display: flex; justify-content: center; @@ -211,4 +291,57 @@ const Btn = styled.button` &:hover { background: ${({ theme }) => theme.buttonBgHover}; } + + &:disabled { + background: ${({ theme }) => theme.border}; + color: ${({ theme }) => theme.secondary}; + } +`; + +const BackBtn = styled(Btn)` + position: absolute; + left: 16px; + top: 16px; + width: 44px; + height: 44px; + border-radius: 50%; + padding: 8px; + margin-left: 0; + + & > svg { + fill: ${({ theme }) => theme.tertiary}; + } +`; + +const ClearBtn = styled.button` + position: absolute; + right: 16px; + top: 50%; + transform: translateY(-50%); + border-radius: 50%; + + & > svg { + fill: ${({ theme }) => theme.secondary}; + } +`; + +const NameInputWrapper = styled.div` + position: relative; +`; + +const NameInput = styled.input` + width: 328px; + padding: 11px 16px; + background: ${({ theme }) => theme.inputColor}; + border-radius: 8px; + border: 1px solid ${({ theme }) => theme.border}; + color: ${({ theme }) => theme.primary}; + outline: none; + + ${textMediumStyles} + + &:focus { + outline: 1px solid ${({ theme }) => theme.tertiary}; + caret-color: ${({ theme }) => theme.notificationColor}; + } `; diff --git a/packages/react-chat/src/components/ReactChat.tsx b/packages/react-chat/src/components/ReactChat.tsx index 76e39f69..6af8359d 100644 --- a/packages/react-chat/src/components/ReactChat.tsx +++ b/packages/react-chat/src/components/ReactChat.tsx @@ -4,6 +4,7 @@ import styled from "styled-components"; import { BlockedUsersProvider } from "../contexts/blockedUsersProvider"; import { FetchMetadataProvider } from "../contexts/fetchMetadataProvider"; +import { FriendsProvider } from "../contexts/friendsProvider"; import { ModalProvider } from "../contexts/modalProvider"; import { NarrowProvider } from "../contexts/narrowProvider"; import { Metadata } from "../models/Metadata"; @@ -29,13 +30,15 @@ export function ReactChat({ - - - - -