diff --git a/packages/react-chat-example/src/index.tsx b/packages/react-chat-example/src/index.tsx index 0b279e19..ec517b04 100644 --- a/packages/react-chat-example/src/index.tsx +++ b/packages/react-chat-example/src/index.tsx @@ -123,7 +123,6 @@ const Bubble = styled.div` const Drag = styled.div` position: absolute; - overflow: hidden; `; ReactDOM.render( diff --git a/packages/react-chat/src/components/Form/ContactMenu.tsx b/packages/react-chat/src/components/Form/ContactMenu.tsx index 51381445..8d36f5c2 100644 --- a/packages/react-chat/src/components/Form/ContactMenu.tsx +++ b/packages/react-chat/src/components/Form/ContactMenu.tsx @@ -32,8 +32,7 @@ export function ContactMenu({ id, setShowMenu }: ContactMenuProps) { ); const { setModal } = useModal(ProfileModalName); - const { contact, setBlocked, setIsUntrustworthy, setIsUserFriend } = - useManageContact(id); + const { contact, setBlocked, setIsUntrustworthy } = useManageContact(id); if (!contact) return null; return ( @@ -54,14 +53,18 @@ export function ContactMenu({ id, setShowMenu }: ContactMenuProps) { { - setModal({ id, renamingState: false }); + setModal({ id, renamingState: false, requestState: false }); }} > View Profile {!contact.isFriend && ( - setIsUserFriend(true)}> + { + setModal({ id, requestState: true }); + }} + > Send Contact Request diff --git a/packages/react-chat/src/components/Icons/UserIcon.tsx b/packages/react-chat/src/components/Icons/UserIcon.tsx index cab5304f..a919e284 100644 --- a/packages/react-chat/src/components/Icons/UserIcon.tsx +++ b/packages/react-chat/src/components/Icons/UserIcon.tsx @@ -3,15 +3,17 @@ import styled from "styled-components"; interface UserIconProps { memberView?: boolean; + modalView?: boolean; } -export const UserIcon = ({ memberView }: UserIconProps) => { +export const UserIcon = ({ memberView, modalView }: UserIconProps) => { return ( { }; const Icon = styled.svg` - width: ${({ memberView }) => (memberView ? "20px" : "34px")}; - height: ${({ memberView }) => (memberView ? "20px" : "34px")}; + width: ${({ memberView, modalView }) => + memberView ? "20px" : modalView ? "80px" : "34px"}; + height: ${({ memberView, modalView }) => + memberView ? "20px" : modalView ? "80px" : "34px"}; & > path, & > ellipse { diff --git a/packages/react-chat/src/components/Modals/EditModal.tsx b/packages/react-chat/src/components/Modals/EditModal.tsx index 3c412f93..f05d5a39 100644 --- a/packages/react-chat/src/components/Modals/EditModal.tsx +++ b/packages/react-chat/src/components/Modals/EditModal.tsx @@ -9,7 +9,13 @@ import { AddIcon } from "../Icons/AddIcon"; import { textMediumStyles } from "../Text"; import { Modal } from "./Modal"; -import { ButtonSection, Heading, Section } from "./ModalStyle"; +import { + ButtonSection, + Heading, + Hint, + inputStyles, + Section, +} from "./ModalStyle"; export const EditModalName = "editModal"; @@ -96,26 +102,10 @@ const Label = styled.p` ${textMediumStyles} `; -const Hint = styled.p` - color: ${({ theme }) => theme.secondary}; - font-size: 12px; - line-height: 16px; -`; - const NameInput = styled.input` padding: 14px 70px 14px 8px; - background: ${({ theme }) => theme.inputColor}; - border-radius: 8px; - border: 1px solid ${({ theme }) => theme.inputColor}; - color: ${({ theme }) => theme.primary}; - outline: none; - ${textMediumStyles} - - &:focus { - outline: none; - caret-color: ${({ theme }) => theme.notificationColor}; - } + ${inputStyles} `; const LogoSection = styled.div` diff --git a/packages/react-chat/src/components/Modals/ModalStyle.ts b/packages/react-chat/src/components/Modals/ModalStyle.ts index f8f4a7d5..8e22667a 100644 --- a/packages/react-chat/src/components/Modals/ModalStyle.ts +++ b/packages/react-chat/src/components/Modals/ModalStyle.ts @@ -1,4 +1,4 @@ -import styled from "styled-components"; +import styled, { css } from "styled-components"; import { textMediumStyles } from "../Text"; @@ -29,3 +29,24 @@ export const ButtonSection = styled(Section)` align-items: center; position: relative; `; + +export const Hint = styled.p` + color: ${({ theme }) => theme.secondary}; + font-size: 12px; + line-height: 16px; +`; + +export const inputStyles = css` + background: ${({ theme }) => theme.inputColor}; + border-radius: 8px; + border: 1px solid ${({ theme }) => theme.inputColor}; + 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/Modals/ProfileModal.tsx b/packages/react-chat/src/components/Modals/ProfileModal.tsx index c4a8c37f..d68544d6 100644 --- a/packages/react-chat/src/components/Modals/ProfileModal.tsx +++ b/packages/react-chat/src/components/Modals/ProfileModal.tsx @@ -13,10 +13,16 @@ import { EditSvg } from "../Icons/EditIcon"; import { LeftIconSvg } from "../Icons/LeftIcon"; import { UntrustworthIcon } from "../Icons/UntrustworthIcon"; import { UserIcon } from "../Icons/UserIcon"; -import { textMediumStyles } from "../Text"; +import { textMediumStyles, textSmallStyles } from "../Text"; import { Modal } from "./Modal"; -import { ButtonSection, Heading, Section } from "./ModalStyle"; +import { + ButtonSection, + Heading, + Hint, + inputStyles, + Section, +} from "./ModalStyle"; export const ProfileModalName = "profileModal" as const; @@ -24,11 +30,12 @@ export type ProfileModalProps = { id: string; image?: string; renamingState?: boolean; + requestState?: boolean; }; export const ProfileModal = () => { const { props } = useModal(ProfileModalName); - const { id, image, renamingState } = useMemo( + const { id, image, renamingState, requestState } = useMemo( () => (props ? props : { id: "" }), [props] ); @@ -44,6 +51,12 @@ export const ProfileModal = () => { setRenaming(renamingState ?? false); }, [renamingState]); + const [request, setRequest] = useState(""); + const [requestCreation, setRequestCreation] = useState(requestState ?? false); + useEffect(() => { + setRequestCreation(requestState ?? false); + }, [requestState]); + const { contact, setBlocked, @@ -55,29 +68,35 @@ export const ProfileModal = () => { if (!contact) return null; return ( - +
{id.slice(0, 10)}’s Profile
- + {image ? ( ) : ( - + )} - {contact.customName ?? id.slice(0, 10)} + + {contact.customName ?? id.slice(0, 10)} + {contact.isUntrustworthy && } {!renaming && ( )} @@ -105,16 +124,40 @@ export const ProfileModal = () => { ) : ( <> - - Chatkey: {id.slice(0, 30)} + + {requestCreation ? ( + + {id.slice(0, 10)}...{id.slice(-3)} + + ) : ( + <> + + Chatkey: {id.slice(0, 30)} + - copy(id)}> - - + copy(id)}> + + + + )} - 🎩🍞πŸ₯‘πŸ¦πŸŒˆπŸ“‘πŸ’…πŸ»β™£οΈπŸ””β›ΈπŸ‘΅πŸ…±{" "} + + 🎩🍞πŸ₯‘πŸ¦πŸŒˆπŸ“‘πŸ’…πŸ»β™£οΈπŸ””β›ΈπŸ‘΅πŸ…± + {" "} )} + {requestCreation && ( + + {request.length}/280 + setRequest(e.currentTarget.value)} + required + /> + + )} {renaming ? ( @@ -132,6 +175,22 @@ export const ProfileModal = () => { Apply nickname + ) : requestCreation ? ( + <> + setRequestCreation(false)}> + + + { + setIsUserFriend(true), + setRequestCreation(false), + setRequest(""); + }} + > + Send Contact Request + + ) : ( <> {!contact.isFriend && !isUser && ( @@ -161,7 +220,7 @@ export const ProfileModal = () => { : "Mark as Untrustworthy"} {!contact.isFriend && ( - setIsUserFriend(true)}> + setRequestCreation(true)}> Send Contact Request )} @@ -184,6 +243,10 @@ const NameSection = styled.div` justify-content: center; align-items: center; margin-bottom: 16px; + + &.small { + margin-bottom: 0; + } `; const ProfileIcon = styled.div` @@ -199,6 +262,11 @@ const ProfileIcon = styled.div` flex-shrink: 0; position: relative; cursor: pointer; + + &.small { + width: 64px; + height: 64px; + } `; const UserNameWrapper = styled.div` @@ -219,6 +287,12 @@ const UserName = styled.p` line-height: 30px; letter-spacing: -0.2px; margin-right: 8px; + + &.small { + font-size: 17px; + line-height: 24px; + margin-right: 0; + } `; const UserTrueName = styled.p` @@ -234,6 +308,10 @@ const UserAddressWrapper = styled.div` justify-content: center; align-items: center; margin-bottom: 24px; + + &.small { + margin-bottom: 8px; + } `; const UserAddress = styled.p` @@ -243,6 +321,12 @@ const UserAddress = styled.p` color: ${({ theme }) => theme.secondary}; ${textMediumStyles} + + &.small { + margin-right: 0; + + ${textSmallStyles} + } `; const EmojiKey = styled.div` display: flex; @@ -253,6 +337,10 @@ const EmojiKey = styled.div` font-size: 15px; line-height: 14px; letter-spacing: 0.2px; + + &.small { + ${textSmallStyles} + } `; const ProfileBtn = styled.button` @@ -331,16 +419,25 @@ const NameInputWrapper = styled.div` 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}; - } + ${inputStyles} +`; + +const RequestSection = styled.div` + width: 100%; + display: flex; + flex-direction: column; + align-items: flex-end; + margin: 16px 0; +`; + +const RequestInput = styled.textarea` + width: 100%; + height: 152px; + padding: 10px 16px; + resize: none; + margin-top: 16px; + font-family: "Inter"; + + ${inputStyles} `;