Sending request form (#141)
This commit is contained in:
parent
faef8d0a02
commit
49417a5c25
|
@ -123,7 +123,6 @@ const Bubble = styled.div`
|
|||
|
||||
const Drag = styled.div`
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
ReactDOM.render(
|
||||
|
|
|
@ -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) {
|
|||
<MenuSection>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
setModal({ id, renamingState: false });
|
||||
setModal({ id, renamingState: false, requestState: false });
|
||||
}}
|
||||
>
|
||||
<ProfileSvg width={16} height={16} />
|
||||
<MenuText>View Profile</MenuText>
|
||||
</MenuItem>
|
||||
{!contact.isFriend && (
|
||||
<MenuItem onClick={() => setIsUserFriend(true)}>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
setModal({ id, requestState: true });
|
||||
}}
|
||||
>
|
||||
<AddContactSvg width={16} height={16} />
|
||||
<MenuText>Send Contact Request</MenuText>
|
||||
</MenuItem>
|
||||
|
|
|
@ -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 (
|
||||
<Icon
|
||||
viewBox="0 0 34 34"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
memberView={memberView}
|
||||
modalView={modalView}
|
||||
>
|
||||
<ellipse cx="17" cy="10.3883" rx="6.94445" ry="6.94445" />
|
||||
<path
|
||||
|
@ -24,8 +26,10 @@ export const UserIcon = ({ memberView }: UserIconProps) => {
|
|||
};
|
||||
|
||||
const Icon = styled.svg<UserIconProps>`
|
||||
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 {
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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};
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -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 (
|
||||
<Modal name={ProfileModalName} className="profile">
|
||||
<Modal
|
||||
name={ProfileModalName}
|
||||
className={`${!requestCreation && "profile"}`}
|
||||
>
|
||||
<Section>
|
||||
<Heading>{id.slice(0, 10)}’s Profile</Heading>
|
||||
</Section>
|
||||
|
||||
<ProfileSection>
|
||||
<NameSection>
|
||||
<NameSection className={`${requestCreation && "small"}`}>
|
||||
{image ? (
|
||||
<ProfileIcon
|
||||
style={{
|
||||
backgroundImage: `url(${image}`,
|
||||
}}
|
||||
className={`${requestCreation && "small"}`}
|
||||
/>
|
||||
) : (
|
||||
<UserIcon />
|
||||
<UserIcon modalView={!requestCreation} />
|
||||
)}
|
||||
<UserNameWrapper>
|
||||
<UserName>{contact.customName ?? id.slice(0, 10)}</UserName>
|
||||
<UserName className={`${requestCreation && "small"}`}>
|
||||
{contact.customName ?? id.slice(0, 10)}
|
||||
</UserName>
|
||||
{contact.isUntrustworthy && <UntrustworthIcon />}
|
||||
{!renaming && (
|
||||
<button onClick={() => setRenaming(true)}>
|
||||
{" "}
|
||||
<EditSvg width={24} height={24} />
|
||||
{!requestCreation && <EditSvg width={24} height={24} />}
|
||||
</button>
|
||||
)}
|
||||
</UserNameWrapper>
|
||||
|
@ -105,16 +124,40 @@ export const ProfileModal = () => {
|
|||
</NameInputWrapper>
|
||||
) : (
|
||||
<>
|
||||
<UserAddressWrapper>
|
||||
<UserAddress>Chatkey: {id.slice(0, 30)}</UserAddress>
|
||||
<UserAddressWrapper className={`${requestCreation && "small"}`}>
|
||||
{requestCreation ? (
|
||||
<UserAddress>
|
||||
{id.slice(0, 10)}...{id.slice(-3)}
|
||||
</UserAddress>
|
||||
) : (
|
||||
<>
|
||||
<UserAddress className={`${requestCreation && "small"}`}>
|
||||
Chatkey: {id.slice(0, 30)}
|
||||
</UserAddress>
|
||||
|
||||
<CopyButton onClick={() => copy(id)}>
|
||||
<CopySvg width={24} height={24} />
|
||||
</CopyButton>
|
||||
<CopyButton onClick={() => copy(id)}>
|
||||
<CopySvg width={24} height={24} />
|
||||
</CopyButton>
|
||||
</>
|
||||
)}
|
||||
</UserAddressWrapper>
|
||||
<EmojiKey>🎩🍞🥑🦍🌈📡💅🏻♣️🔔⛸👵🅱</EmojiKey>{" "}
|
||||
<EmojiKey className={`${requestCreation && "small"}`}>
|
||||
🎩🍞🥑🦍🌈📡💅🏻♣️🔔⛸👵🅱
|
||||
</EmojiKey>{" "}
|
||||
</>
|
||||
)}
|
||||
{requestCreation && (
|
||||
<RequestSection>
|
||||
<Hint>{request.length}/280</Hint>
|
||||
<RequestInput
|
||||
value={request}
|
||||
placeholder="Say who you are / why you want to became a contact..."
|
||||
maxLength={280}
|
||||
onInput={(e) => setRequest(e.currentTarget.value)}
|
||||
required
|
||||
/>
|
||||
</RequestSection>
|
||||
)}
|
||||
</ProfileSection>
|
||||
<ButtonSection>
|
||||
{renaming ? (
|
||||
|
@ -132,6 +175,22 @@ export const ProfileModal = () => {
|
|||
Apply nickname
|
||||
</Btn>
|
||||
</>
|
||||
) : requestCreation ? (
|
||||
<>
|
||||
<BackBtn onClick={() => setRequestCreation(false)}>
|
||||
<LeftIconSvg width={28} height={28} />
|
||||
</BackBtn>
|
||||
<Btn
|
||||
disabled={!request}
|
||||
onClick={() => {
|
||||
setIsUserFriend(true),
|
||||
setRequestCreation(false),
|
||||
setRequest("");
|
||||
}}
|
||||
>
|
||||
Send Contact Request
|
||||
</Btn>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{!contact.isFriend && !isUser && (
|
||||
|
@ -161,7 +220,7 @@ export const ProfileModal = () => {
|
|||
: "Mark as Untrustworthy"}
|
||||
</ProfileBtn>
|
||||
{!contact.isFriend && (
|
||||
<Btn onClick={() => setIsUserFriend(true)}>
|
||||
<Btn onClick={() => setRequestCreation(true)}>
|
||||
Send Contact Request
|
||||
</Btn>
|
||||
)}
|
||||
|
@ -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}
|
||||
`;
|
||||
|
|
Loading…
Reference in New Issue