Login flow (#163)
* Add button styles * Fix UserCreation styles * Extract addWrapper * Fix UserCreationModal styles * Add next step modal * Change UserLogo styles * Add colorWheel to You user * Add qrcode.react package * Fix profile icon * Add icons * Add Status modal for mobile * Extract input styles * Add Status modal for desktop * Change paste function * Extract login instructions
This commit is contained in:
parent
7c3bb65e09
commit
094976642a
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -26,6 +26,7 @@
|
|||
"@types/emoji-mart": "^3.0.6",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"@types/node": "^16.9.6",
|
||||
"@types/qrcode.react": "^1.0.2",
|
||||
"@types/react": "^17.0.16",
|
||||
"@types/styled-components": "^5.1.12",
|
||||
"@typescript-eslint/eslint-plugin": "^4.29.0",
|
||||
|
@ -39,6 +40,7 @@
|
|||
"npm-run-all": "^4.1.5",
|
||||
"npm-watch": "^0.11.0",
|
||||
"prettier": "^2.3.2",
|
||||
"qrcode.react": "^1.0.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-node": "^10.1.0",
|
||||
"typescript": "^4.3.5"
|
||||
|
|
|
@ -9,7 +9,7 @@ import { Activity } from "../models/Activity";
|
|||
import { equalDate } from "../utils/equalDate";
|
||||
|
||||
import { DownloadButton } from "./Buttons/DownloadButton";
|
||||
import { buttonStyles } from "./Buttons/buttonStyle";
|
||||
import { buttonTransparentStyles } from "./Buttons/buttonStyle";
|
||||
import { Mention } from "./Chat/ChatMessageContent";
|
||||
import { Logo } from "./CommunityIdentity";
|
||||
import { ContactMenu } from "./Form/ContactMenu";
|
||||
|
@ -365,23 +365,11 @@ const InviteDiv = styled.div`
|
|||
`;
|
||||
|
||||
const FilterBtn = styled.button`
|
||||
${buttonStyles}
|
||||
${textSmallStyles}
|
||||
|
||||
padding: 10px 12px;
|
||||
background: ${({ theme }) => theme.bodyBackgroundColor};
|
||||
${buttonTransparentStyles}
|
||||
|
||||
& + & {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: ${({ theme }) => theme.buttonBgHover};
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: ${({ theme }) => theme.buttonBg};
|
||||
}
|
||||
`;
|
||||
|
||||
const BtnWrapper = styled.div`
|
||||
|
|
|
@ -66,10 +66,6 @@ const Link = styled.a`
|
|||
|
||||
${buttonStyles}
|
||||
|
||||
&:hover {
|
||||
background: ${({ theme }) => theme.buttonBgHover};
|
||||
}
|
||||
|
||||
&.activity {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import { css } from "styled-components";
|
||||
|
||||
export const buttonStyles = css`
|
||||
font-family: "Inter";
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
text-align: center;
|
||||
border-radius: 8px;
|
||||
color: ${({ theme }) => theme.tertiary};
|
||||
background: ${({ theme }) => theme.buttonBg};
|
||||
|
||||
&:hover {
|
||||
background: ${({ theme }) => theme.buttonBgHover};
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: ${({ theme }) => theme.buttonBg};
|
||||
}
|
||||
`;
|
||||
|
||||
export const buttonTransparentStyles = css`
|
||||
font-family: "Inter";
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
color: ${({ theme }) => theme.tertiary};
|
||||
background: inherit;
|
||||
padding: 10px 12px;
|
||||
border-radius: 8px;
|
||||
|
||||
&:hover {
|
||||
background: ${({ theme }) => theme.buttonBgHover};
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: ${({ theme }) => theme.buttonBg};
|
||||
}
|
||||
`;
|
|
@ -1,12 +0,0 @@
|
|||
import { css } from "styled-components";
|
||||
|
||||
export const buttonStyles = css`
|
||||
border-radius: 8px;
|
||||
font-family: "Inter";
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
text-align: center;
|
||||
color: ${({ theme }) => theme.tertiary};
|
||||
background: ${({ theme }) => theme.buttonBg};
|
||||
`;
|
|
@ -13,6 +13,7 @@ import { Members } from "./Members/Members";
|
|||
import { CommunityModal } from "./Modals/CommunityModal";
|
||||
import { EditModal } from "./Modals/EditModal";
|
||||
import { ProfileModal } from "./Modals/ProfileModal";
|
||||
import { StatusModal } from "./Modals/StatusModal";
|
||||
import { UserCreationModal } from "./Modals/UserCreationModal";
|
||||
import { ToastMessageList } from "./ToastMessages/ToastMessageList";
|
||||
import { UserCreation } from "./UserCreation/UserCreation";
|
||||
|
@ -24,6 +25,7 @@ function Modals() {
|
|||
<UserCreationModal />
|
||||
<EditModal />
|
||||
<ProfileModal />
|
||||
<StatusModal />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { copy } from "../../utils/copy";
|
||||
import { reduceString } from "../../utils/reduceString";
|
||||
import { textMediumStyles, textSmallStyles } from "../Text";
|
||||
|
||||
import { ButtonWrapper, InputBtn, Label, Text, Wrapper } from "./inputStyles";
|
||||
|
||||
interface CopyInputProps {
|
||||
label: string;
|
||||
|
@ -15,57 +15,9 @@ export const CopyInput = ({ label, value }: CopyInputProps) => (
|
|||
<Label>{label}</Label>
|
||||
<Wrapper>
|
||||
<Text>{reduceString(value, 15, 15)}</Text>
|
||||
<CopyButtonWrapper>
|
||||
<CopyButton onClick={() => copy(value)}>Copy</CopyButton>
|
||||
</CopyButtonWrapper>
|
||||
<ButtonWrapper>
|
||||
<InputBtn onClick={() => copy(value)}>Copy</InputBtn>
|
||||
</ButtonWrapper>
|
||||
</Wrapper>
|
||||
</div>
|
||||
);
|
||||
|
||||
const Label = styled.p`
|
||||
margin-bottom: 7px;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: ${({ theme }) => theme.primary};
|
||||
|
||||
${textSmallStyles}
|
||||
`;
|
||||
|
||||
const Wrapper = styled.div`
|
||||
position: relative;
|
||||
padding: 14px 70px 14px 8px;
|
||||
background: ${({ theme }) => theme.inputColor};
|
||||
border-radius: 8px;
|
||||
`;
|
||||
|
||||
const Text = styled.p`
|
||||
color: ${({ theme }) => theme.primary};
|
||||
|
||||
${textMediumStyles}
|
||||
`;
|
||||
|
||||
const CopyButtonWrapper = styled.div`
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: 70px;
|
||||
transform: translateY(-50%);
|
||||
background: ${({ theme }) => theme.inputColor};
|
||||
border-radius: 8px;
|
||||
`;
|
||||
|
||||
const CopyButton = styled.button`
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
letter-spacing: 0.1px;
|
||||
color: ${({ theme }) => theme.tertiary};
|
||||
background: ${({ theme }) => theme.buttonBg};
|
||||
border: 1px solid ${({ theme }) => theme.tertiary};
|
||||
border-radius: 6px;
|
||||
`;
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { MobileIcon } from "../Icons/MobileIcon";
|
||||
import { ProfileSvg } from "../Icons/ProfileIcon";
|
||||
import { ScanIcon } from "../Icons/ScanIcon";
|
||||
import { textMediumStyles } from "../Text";
|
||||
|
||||
interface LoginInstructionsProps {
|
||||
mobileFlow: boolean;
|
||||
}
|
||||
|
||||
export function LoginInstructions({ mobileFlow }: LoginInstructionsProps) {
|
||||
return (
|
||||
<Instructions>
|
||||
<InstructionStep>
|
||||
Open Status App on your {mobileFlow ? "mobile" : "desktop"}
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
Navigate yourself to{" "}
|
||||
<InstructionIcon>
|
||||
{" "}
|
||||
<ProfileSvg width={13} height={13} /> <span>Profile</span>
|
||||
</InstructionIcon>{" "}
|
||||
tab
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
Select{" "}
|
||||
<InstructionIcon>
|
||||
<MobileIcon />
|
||||
</InstructionIcon>{" "}
|
||||
<span>Sync Settings</span>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
Tap{" "}
|
||||
<InstructionIcon>
|
||||
{" "}
|
||||
<ScanIcon />{" "}
|
||||
</InstructionIcon>{" "}
|
||||
<span>{mobileFlow ? "Scan" : "Display"} sync code</span>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
{mobileFlow
|
||||
? "Scan the sync code from this screen"
|
||||
: "Paste the sync code above"}{" "}
|
||||
↑
|
||||
</InstructionStep>
|
||||
</Instructions>
|
||||
);
|
||||
}
|
||||
|
||||
const Instructions = styled.ol`
|
||||
color: ${({ theme }) => theme.secondary};
|
||||
margin: auto 0;
|
||||
list-style-type: decimal;
|
||||
counter-reset: ollist;
|
||||
|
||||
${textMediumStyles}
|
||||
`;
|
||||
|
||||
const InstructionStep = styled.li`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& + & {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
& > span {
|
||||
color: ${({ theme }) => theme.tertiary};
|
||||
}
|
||||
|
||||
&::before {
|
||||
counter-increment: ollist;
|
||||
content: counter(ollist) ".";
|
||||
margin-right: 4px;
|
||||
}
|
||||
`;
|
||||
|
||||
const InstructionIcon = styled.div`
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
background: ${({ theme }) => theme.buttonBg};
|
||||
color: ${({ theme }) => theme.tertiary};
|
||||
font-size: 8px;
|
||||
line-height: 10px;
|
||||
margin: 0 6px;
|
||||
`;
|
|
@ -0,0 +1,43 @@
|
|||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { paste } from "../../utils/paste";
|
||||
|
||||
import {
|
||||
ButtonWrapper,
|
||||
InputBtn,
|
||||
inputStyles,
|
||||
Label,
|
||||
Wrapper,
|
||||
} from "./inputStyles";
|
||||
|
||||
interface PasteInputProps {
|
||||
label: string;
|
||||
}
|
||||
|
||||
export const PasteInput = ({ label }: PasteInputProps) => (
|
||||
<PasteWrapper>
|
||||
<Label>{label}</Label>
|
||||
<Wrapper>
|
||||
<Input id="pasteInput" type="text" placeholder="eg. 0x2Ef19" />
|
||||
<ButtonWrapper>
|
||||
<InputBtn onClick={() => paste("pasteInput")}>Paste</InputBtn>
|
||||
</ButtonWrapper>
|
||||
</Wrapper>
|
||||
</PasteWrapper>
|
||||
);
|
||||
|
||||
const PasteWrapper = styled.div`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const Input = styled.input`
|
||||
${inputStyles}
|
||||
width: 100%;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
border: none;
|
||||
`;
|
|
@ -0,0 +1,73 @@
|
|||
import styled, { css } from "styled-components";
|
||||
|
||||
import { textMediumStyles, textSmallStyles } from "../Text";
|
||||
|
||||
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};
|
||||
}
|
||||
`;
|
||||
|
||||
export const Label = styled.p`
|
||||
margin-bottom: 7px;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: ${({ theme }) => theme.primary};
|
||||
|
||||
${textSmallStyles}
|
||||
`;
|
||||
|
||||
export const Wrapper = styled.div`
|
||||
position: relative;
|
||||
padding: 14px 70px 14px 8px;
|
||||
background: ${({ theme }) => theme.inputColor};
|
||||
border-radius: 8px;
|
||||
`;
|
||||
|
||||
export const Text = styled.p`
|
||||
color: ${({ theme }) => theme.primary};
|
||||
|
||||
${textMediumStyles}
|
||||
`;
|
||||
|
||||
export const ButtonWrapper = styled.div`
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: 70px;
|
||||
transform: translateY(-50%);
|
||||
background: ${({ theme }) => theme.inputColor};
|
||||
border-radius: 8px;
|
||||
`;
|
||||
|
||||
export const InputBtn = styled.button`
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
letter-spacing: 0.1px;
|
||||
color: ${({ theme }) => theme.tertiary};
|
||||
background: ${({ theme }) => theme.buttonBg};
|
||||
border: 1px solid ${({ theme }) => theme.tertiary};
|
||||
border-radius: 6px;
|
||||
`;
|
||||
|
||||
export const NameInput = styled.input`
|
||||
width: 328px;
|
||||
padding: 11px 16px;
|
||||
|
||||
${inputStyles}
|
||||
`;
|
|
@ -0,0 +1,30 @@
|
|||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
interface ChainIconProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const ChainIcon = ({ className }: ChainIconProps) => {
|
||||
return (
|
||||
<Icon
|
||||
width="27"
|
||||
height="27"
|
||||
viewBox="0 0 27 27"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={className}
|
||||
>
|
||||
<path d="M20.4919 24.7159C20.8389 24.3784 21.0941 23.9583 21.2306 23.4878C21.4369 22.7771 21.3498 22.0383 20.9854 21.4075L19.409 18.6769C19.0542 18.0624 18.4794 17.6245 17.7859 17.4387C17.7672 17.4337 17.7484 17.4289 17.7296 17.4242C17.2537 17.3072 16.7622 17.318 16.2963 17.4498L16.0648 17.0489C16.4119 16.7113 16.6672 16.2913 16.8038 15.8207C17.01 15.11 16.9229 14.371 16.5583 13.7399L14.9818 11.0093C14.6175 10.3783 14.0207 9.93364 13.3026 9.75668C12.8268 9.63968 12.3354 9.6507 11.8696 9.78247L11.6383 9.38174C11.9854 9.04419 12.2406 8.62397 12.3771 8.15336C12.5833 7.44267 12.4961 6.70371 12.1317 6.07268L10.5555 3.34242C9.92796 2.25533 8.63218 1.78173 7.44346 2.11579L6.77962 0.966562L5.55141 1.67598L6.21505 2.82497C5.33134 3.6873 5.09343 5.04607 5.72069 6.13334L7.29678 8.86349C7.65152 9.47804 8.22631 9.91611 8.91998 10.1019C8.93866 10.1069 8.95759 10.1118 8.97645 10.1164C9.4525 10.2334 9.94405 10.2225 10.41 10.0907L10.6413 10.4915C10.2942 10.829 10.0389 11.2492 9.90228 11.7198C9.69599 12.4305 9.78306 13.1695 10.1474 13.8005L11.7239 16.5311C12.0787 17.1456 12.6535 17.5836 13.3469 17.7693C13.3656 17.7743 13.3844 17.7792 13.4032 17.7838C13.8793 17.9009 14.3708 17.8899 14.8366 17.7581L15.068 18.1587C14.7209 18.4963 14.4657 18.9166 14.3292 19.3873C14.1231 20.0981 14.2102 20.837 14.5746 21.4677L16.1507 24.1983C16.5166 24.8315 17.1093 25.2567 17.7754 25.4351C18.2525 25.5629 18.7673 25.5642 19.2634 25.4247L19.9272 26.5746L21.1557 25.8658L20.4919 24.7159ZM10.881 8.06957L10.283 7.03348L9.05454 7.74257L9.65273 8.77879C9.53961 8.77949 9.42646 8.76647 9.31528 8.73914C8.97586 8.6576 8.69461 8.44787 8.52523 8.15445L6.94922 5.42435C6.71569 5.01958 6.74147 4.53136 6.97287 4.1369L7.17981 4.49521L8.40806 3.7858L8.20171 3.42851C8.32536 3.42779 8.44744 3.44307 8.56435 3.4744C8.87937 3.5588 9.15698 3.75669 9.32721 4.05159L10.9034 6.782C11.0729 7.07532 11.1125 7.422 11.015 7.75814C10.9831 7.86787 10.938 7.97221 10.881 8.06957ZM15.3074 15.7371L14.709 14.7008L13.4807 15.4101L14.079 16.4463C13.9662 16.447 13.8531 16.4339 13.7421 16.4066C13.4017 16.3224 13.1216 16.1153 12.9523 15.8221L11.3758 13.0914C11.2065 12.7982 11.1669 12.4515 11.2645 12.1153C11.2964 12.0055 11.3416 11.901 11.3987 11.8036L11.9967 12.8396L13.2252 12.1305L12.627 11.0943C12.7398 11.0936 12.8529 11.1067 12.9638 11.134C12.9729 11.1362 12.982 11.1385 12.991 11.1409C13.3186 11.2287 13.5886 11.4329 13.7534 11.7184L15.3299 14.449L15.33 14.4491C15.4995 14.7425 15.5391 15.0891 15.4415 15.4253C15.4098 15.5352 15.3645 15.6396 15.3074 15.7371ZM19.7344 23.4038L19.5279 23.0461L18.2996 23.7553L18.5057 24.1125C18.0485 24.1155 17.6129 23.8936 17.3791 23.4891L15.8029 20.7587C15.6336 20.4655 15.594 20.1188 15.6915 19.7825C15.7234 19.6727 15.7685 19.5682 15.8256 19.4708L16.424 20.5071L17.6523 19.7978L17.054 18.7618C17.1668 18.7611 17.2796 18.7742 17.3907 18.8015C17.3997 18.8037 17.4087 18.806 17.4177 18.8084C17.7455 18.8963 18.0157 19.1006 18.1805 19.3861L19.757 22.1167L19.7571 22.1169C19.9264 22.4099 19.966 22.7564 19.8684 23.0924C19.8366 23.2021 19.7914 23.3064 19.7344 23.4038Z" />
|
||||
</Icon>
|
||||
);
|
||||
};
|
||||
|
||||
const Icon = styled.svg`
|
||||
fill: ${({ theme }) => theme.secondary};
|
||||
transform: rotate(15deg);
|
||||
|
||||
&.transformed {
|
||||
transform: matrix(-0.97, 0.26, 0.26, 0.97, 0, 0);
|
||||
}
|
||||
`;
|
|
@ -0,0 +1,25 @@
|
|||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
export const MobileIcon = () => {
|
||||
return (
|
||||
<Icon
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M12 18.5C12.8284 18.5 13.5 17.8284 13.5 17C13.5 16.1716 12.8284 15.5 12 15.5C11.1716 15.5 10.5 16.1716 10.5 17C10.5 17.8284 11.1716 18.5 12 18.5Z" />
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M5 6C5 3.79086 6.79086 2 9 2H15C17.2091 2 19 3.79086 19 6V18C19 20.2091 17.2091 22 15 22H9C6.79086 22 5 20.2091 5 18V6ZM6.5 6C6.5 4.61929 7.61929 3.5 9 3.5H15C16.3807 3.5 17.5 4.61929 17.5 6V18C17.5 19.3807 16.3807 20.5 15 20.5H9C7.61929 20.5 6.5 19.3807 6.5 18V6Z"
|
||||
/>
|
||||
</Icon>
|
||||
);
|
||||
};
|
||||
|
||||
const Icon = styled.svg`
|
||||
fill: ${({ theme }) => theme.tertiary};
|
||||
`;
|
|
@ -9,7 +9,7 @@ type ProfileSvgProps = {
|
|||
|
||||
export function ProfileSvg({ width, height, className }: ProfileSvgProps) {
|
||||
return (
|
||||
<svg
|
||||
<Icon
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 16 16"
|
||||
|
@ -28,7 +28,7 @@ export function ProfileSvg({ width, height, className }: ProfileSvgProps) {
|
|||
clipRule="evenodd"
|
||||
d="M8.00065 14.6673C11.6825 14.6673 14.6673 11.6825 14.6673 8.00065C14.6673 4.31875 11.6825 1.33398 8.00065 1.33398C4.31875 1.33398 1.33398 4.31875 1.33398 8.00065C1.33398 11.6825 4.31875 14.6673 8.00065 14.6673ZM8.00065 13.6673C11.1303 13.6673 13.6673 11.1303 13.6673 8.00065C13.6673 4.87104 11.1303 2.33398 8.00065 2.33398C4.87104 2.33398 2.33398 4.87104 2.33398 8.00065C2.33398 11.1303 4.87104 13.6673 8.00065 13.6673Z"
|
||||
/>
|
||||
</svg>
|
||||
</Icon>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -36,12 +36,10 @@ export const ProfileIcon = () => {
|
|||
return <Icon width={16} height={16} />;
|
||||
};
|
||||
|
||||
const Icon = styled(ProfileSvg)`
|
||||
& > path {
|
||||
fill: ${({ theme }) => theme.tertiary};
|
||||
}
|
||||
const Icon = styled.svg`
|
||||
fill: ${({ theme }) => theme.tertiary};
|
||||
|
||||
&:hover > path {
|
||||
&:hover {
|
||||
fill: ${({ theme }) => theme.bodyBackgroundColor};
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
export const ScanIcon = () => {
|
||||
return (
|
||||
<Icon
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M0.754395 11.9998C0.754395 11.5855 1.09018 11.2498 1.50439 11.2498H22.4953C22.9095 11.2498 23.2453 11.5855 23.2453 11.9998C23.2453 12.414 22.9095 12.7498 22.4953 12.7498H1.50439C1.09018 12.7498 0.754395 12.414 0.754395 11.9998Z" />
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M1.99985 6.75293C1.99985 4.12958 4.12649 2.00293 6.74985 2.00293H8.74985C9.16406 2.00293 9.49985 2.33872 9.49985 2.75293C9.49985 3.16714 9.16406 3.50293 8.74985 3.50293H6.74985C4.95492 3.50293 3.49985 4.958 3.49985 6.75293V8.54012C3.49985 8.95434 3.16406 9.29012 2.74985 9.29012C2.33563 9.29012 1.99985 8.95434 1.99985 8.54012V6.75293Z"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M1.99985 17.2498C1.99985 19.8731 4.12649 21.9998 6.74985 21.9998H8.74985C9.16406 21.9998 9.49985 21.664 9.49985 21.2498C9.49985 20.8355 9.16406 20.4998 8.74985 20.4998H6.74985C4.95492 20.4998 3.49985 19.0447 3.49985 17.2498V15.4626C3.49985 15.0483 3.16406 14.7126 2.74985 14.7126C2.33563 14.7126 1.99985 15.0483 1.99985 15.4626V17.2498Z"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M21.9998 6.75293C21.9998 4.12958 19.8732 2.00293 17.2498 2.00293H15.2498C14.8356 2.00293 14.4998 2.33872 14.4998 2.75293C14.4998 3.16714 14.8356 3.50293 15.2498 3.50293H17.2498C19.0448 3.50293 20.4998 4.958 20.4998 6.75293V8.54012C20.4998 8.95434 20.8356 9.29012 21.2498 9.29012C21.6641 9.29012 21.9998 8.95434 21.9998 8.54012V6.75293Z"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M21.9998 17.2498C21.9998 19.8731 19.8732 21.9998 17.2498 21.9998H15.2498C14.8356 21.9998 14.4998 21.664 14.4998 21.2498C14.4998 20.8355 14.8356 20.4998 15.2498 20.4998H17.2498C19.0448 20.4998 20.4998 19.0447 20.4998 17.2498V15.4626C20.4998 15.0483 20.8356 14.7126 21.2498 14.7126C21.6641 14.7126 21.9998 15.0483 21.9998 15.4626V17.2498Z"
|
||||
/>
|
||||
</Icon>
|
||||
);
|
||||
};
|
||||
|
||||
const Icon = styled.svg`
|
||||
fill: ${({ theme }) => theme.tertiary};
|
||||
`;
|
|
@ -12,6 +12,7 @@ import { UserLogo } from "./UserLogo";
|
|||
interface MemberProps {
|
||||
contact: Contact;
|
||||
isOnline?: boolean;
|
||||
isYou?: boolean;
|
||||
switchShowMembers?: () => void;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
@ -19,6 +20,7 @@ interface MemberProps {
|
|||
export function Member({
|
||||
contact,
|
||||
isOnline,
|
||||
isYou,
|
||||
switchShowMembers,
|
||||
onClick,
|
||||
}: MemberProps) {
|
||||
|
@ -38,12 +40,17 @@ export function Member({
|
|||
};
|
||||
|
||||
return (
|
||||
<MemberData onClick={onClick ? onClick : onMemberClick}>
|
||||
<MemberData
|
||||
onClick={onClick ? onClick : onMemberClick}
|
||||
className={`${isYou && "you"}`}
|
||||
>
|
||||
<MemberIcon
|
||||
style={{
|
||||
backgroundImage: "unset",
|
||||
}}
|
||||
className={isOnline ? "online" : "offline"}
|
||||
className={
|
||||
!isYou && isOnline ? "online" : !isYou && !isOnline ? "offline" : ""
|
||||
}
|
||||
onClick={() => setShowMenu((e) => !e)}
|
||||
>
|
||||
{showMenu && <ContactMenu id={contact.id} setShowMenu={setShowMenu} />}
|
||||
|
@ -74,7 +81,7 @@ export const MemberData = styled.div`
|
|||
cursor: pointer;
|
||||
|
||||
&.you {
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { useMemo } from "react";
|
||||
import { utils } from "status-communities/dist/cjs";
|
||||
import { bufToHex } from "status-communities/dist/cjs/utils";
|
||||
import styled from "styled-components";
|
||||
|
||||
|
@ -10,9 +11,8 @@ import {
|
|||
import { useMessengerContext } from "../../contexts/messengerProvider";
|
||||
import { TopBtn } from "../Chat/ChatTopbar";
|
||||
import { LogoutIcon } from "../Icons/LogoutIcon";
|
||||
import { UserIcon } from "../Icons/UserIcon";
|
||||
|
||||
import { Member, MemberData, MemberIcon } from "./Member";
|
||||
import { Member } from "./Member";
|
||||
|
||||
interface MembersListProps {
|
||||
switchShowMembers?: () => void;
|
||||
|
@ -21,8 +21,10 @@ interface MembersListProps {
|
|||
export function MembersList({ switchShowMembers }: MembersListProps) {
|
||||
const { contacts } = useMessengerContext();
|
||||
const identity = useIdentity();
|
||||
const nickname = useNickname();
|
||||
|
||||
const logout = useSetIdentity();
|
||||
const nickname = useNickname();
|
||||
|
||||
const userContacts = useMemo(() => {
|
||||
if (identity) {
|
||||
return Object.values(contacts).filter(
|
||||
|
@ -32,6 +34,7 @@ export function MembersList({ switchShowMembers }: MembersListProps) {
|
|||
return Object.values(contacts);
|
||||
}
|
||||
}, [contacts, identity]);
|
||||
|
||||
const onlineContacts = useMemo(
|
||||
() => userContacts.filter((e) => e.online),
|
||||
[userContacts]
|
||||
|
@ -46,17 +49,20 @@ export function MembersList({ switchShowMembers }: MembersListProps) {
|
|||
{identity && (
|
||||
<MemberCategory>
|
||||
<MemberCategoryName>You</MemberCategoryName>
|
||||
<MemberData className="you">
|
||||
<Row>
|
||||
<MemberIcon>
|
||||
<UserIcon memberView={true} />
|
||||
</MemberIcon>
|
||||
<MemberName>{nickname}</MemberName>
|
||||
</Row>
|
||||
<Row>
|
||||
<Member
|
||||
contact={{
|
||||
id: utils.bufToHex(identity.publicKey),
|
||||
customName: nickname,
|
||||
trueName: utils.bufToHex(identity.publicKey),
|
||||
}}
|
||||
switchShowMembers={switchShowMembers}
|
||||
isYou={true}
|
||||
/>
|
||||
<TopBtn onClick={() => logout(undefined)}>
|
||||
<LogoutIcon />
|
||||
</TopBtn>
|
||||
</MemberData>
|
||||
</Row>
|
||||
</MemberCategory>
|
||||
)}
|
||||
{onlineContacts.length > 0 && (
|
||||
|
@ -113,21 +119,8 @@ const MemberCategoryName = styled.h3`
|
|||
margin-bottom: 8px;
|
||||
`;
|
||||
|
||||
const MemberName = styled.p`
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
color: ${({ theme }) => theme.primary};
|
||||
opacity: 0.7;
|
||||
margin-left: 8px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
const Row = styled.div`
|
||||
display: flex;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
`;
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Contact } from "../../models/Contact";
|
|||
type UserLogoProps = {
|
||||
radius: number;
|
||||
colorWheel: [string, number][];
|
||||
contact: Contact;
|
||||
contact?: Contact;
|
||||
showOnlineStatus?: boolean;
|
||||
icon?: string;
|
||||
};
|
||||
|
@ -29,17 +29,17 @@ export function UserLogo({
|
|||
}, [colorWheel]);
|
||||
|
||||
const letters = useMemo(() => {
|
||||
if (contact?.customName) {
|
||||
if (contact && contact?.customName) {
|
||||
return contact.customName.slice(0, 2);
|
||||
}
|
||||
if (contact.trueName) {
|
||||
if (contact && contact.trueName) {
|
||||
return contact.trueName.slice(0, 2);
|
||||
}
|
||||
}, [contact]);
|
||||
|
||||
const logoClassnName = useMemo(() => {
|
||||
if (showOnlineStatus) {
|
||||
if (contact.online) {
|
||||
if (contact && contact.online) {
|
||||
return "online";
|
||||
}
|
||||
return "offline";
|
||||
|
@ -49,7 +49,11 @@ export function UserLogo({
|
|||
|
||||
return (
|
||||
<Wrapper radius={radius} conicGradient={conicGradient}>
|
||||
<Logo icon={icon} radius={radius} className={logoClassnName}>
|
||||
<Logo
|
||||
icon={icon}
|
||||
radius={radius}
|
||||
className={contact ? logoClassnName : "empty"}
|
||||
>
|
||||
{!icon && <TextWrapper radius={radius}>{letters}</TextWrapper>}
|
||||
</Logo>
|
||||
</Wrapper>
|
||||
|
@ -57,8 +61,6 @@ export function UserLogo({
|
|||
}
|
||||
|
||||
const TextWrapper = styled.div<{ radius: number }>`
|
||||
font-family: Inter;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
font-size: calc(${({ radius }) => radius}px / 2.5);
|
||||
line-height: calc(${({ radius }) => radius}px / 2.1);
|
||||
|
@ -66,12 +68,13 @@ const TextWrapper = styled.div<{ radius: number }>`
|
|||
align-items: center;
|
||||
text-align: center;
|
||||
letter-spacing: -0.4px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
color: ${({ theme }) => theme.iconTextColor};
|
||||
`;
|
||||
|
||||
const Logo = styled.div<{ radius: number; icon?: string }>`
|
||||
width: calc(${({ radius }) => radius}px - 6px);
|
||||
height: calc(${({ radius }) => radius}px - 6px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
|
@ -83,9 +86,6 @@ const Logo = styled.div<{ radius: number; icon?: string }>`
|
|||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-image: ${({ icon }) => icon && `url(${icon}`};
|
||||
color: ${({ theme }) => theme.iconTextColor};
|
||||
margin: auto;
|
||||
display: flex;
|
||||
|
||||
&.offline {
|
||||
&::after {
|
||||
|
@ -110,18 +110,23 @@ const Logo = styled.div<{ radius: number; icon?: string }>`
|
|||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
background-color: #4ebc60;
|
||||
background-color: ${({ theme }) => theme.greenColor};
|
||||
border: 2px solid ${({ theme }) => theme.bodyBackgroundColor};
|
||||
}
|
||||
}
|
||||
|
||||
&.empty {
|
||||
background-color: ${({ theme }) => theme.bodyBackgroundColor};
|
||||
background-image: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const Wrapper = styled.div<{ radius: number; conicGradient: string }>`
|
||||
export const Wrapper = styled.div<{ radius: number; conicGradient: string }>`
|
||||
width: ${({ radius }) => radius}px;
|
||||
height: ${({ radius }) => radius}px;
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
background: ${({ conicGradient }) => conicGradient};
|
||||
`;
|
||||
|
|
|
@ -5,15 +5,16 @@ import { useMessengerContext } from "../../contexts/messengerProvider";
|
|||
import { useModal } from "../../contexts/modalProvider";
|
||||
import { buttonStyles } from "../Buttons/buttonStyle";
|
||||
import { ChannelLogo } from "../Channels/Channel";
|
||||
import { inputStyles } from "../Form/inputStyles";
|
||||
import { AddIcon } from "../Icons/AddIcon";
|
||||
import { textMediumStyles } from "../Text";
|
||||
|
||||
import { Modal } from "./Modal";
|
||||
import {
|
||||
AddWrapper,
|
||||
ButtonSection,
|
||||
Heading,
|
||||
Hint,
|
||||
inputStyles,
|
||||
Section,
|
||||
} from "./ModalStyle";
|
||||
|
||||
|
@ -125,17 +126,9 @@ const GroupLogo = styled(ChannelLogo)`
|
|||
margin-right: 0;
|
||||
`;
|
||||
|
||||
const AddPictureInputWrapper = styled.div`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
const AddPictureInputWrapper = styled(AddWrapper)`
|
||||
top: 0;
|
||||
right: 8px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: ${({ theme }) => theme.tertiary};
|
||||
border-radius: 50%;
|
||||
`;
|
||||
|
||||
const AddPictureInput = styled.input`
|
||||
|
@ -153,8 +146,4 @@ const SaveBtn = styled.button`
|
|||
padding: 11px 24px;
|
||||
|
||||
${buttonStyles}
|
||||
|
||||
&:hover {
|
||||
background: ${({ theme }) => theme.buttonBgHover};
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -64,8 +64,4 @@ const ButtonYes = styled.button`
|
|||
padding: 11px 24px;
|
||||
|
||||
${buttonStyles}
|
||||
|
||||
&:hover {
|
||||
background: ${({ theme }) => theme.buttonBgHover};
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import styled, { css } from "styled-components";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { buttonStyles } from "../Buttons/buttonStyle";
|
||||
import { textMediumStyles } from "../Text";
|
||||
|
@ -29,10 +29,6 @@ export const Btn = styled.button`
|
|||
margin-left: 8px;
|
||||
${buttonStyles}
|
||||
|
||||
&:hover {
|
||||
background: ${({ theme }) => theme.buttonBgHover};
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background: ${({ theme }) => theme.border};
|
||||
color: ${({ theme }) => theme.secondary};
|
||||
|
@ -67,17 +63,13 @@ export const Hint = styled.p`
|
|||
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};
|
||||
}
|
||||
export const AddWrapper = styled.div`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: ${({ theme }) => theme.tertiary};
|
||||
border-radius: 50%;
|
||||
`;
|
||||
|
|
|
@ -7,9 +7,9 @@ import { useIdentity } from "../../contexts/identityProvider";
|
|||
import { useModal } from "../../contexts/modalProvider";
|
||||
import { useToasts } from "../../contexts/toastProvider";
|
||||
import { useManageContact } from "../../hooks/useManageContact";
|
||||
import { NameInput } from "../../styles/Inputs";
|
||||
import { copy } from "../../utils";
|
||||
import { buttonStyles } from "../Buttons/buttonStyle";
|
||||
import { inputStyles, NameInput } from "../Form/inputStyles";
|
||||
import { ClearSvg } from "../Icons/ClearIcon";
|
||||
import { CopySvg } from "../Icons/CopyIcon";
|
||||
import { EditSvg } from "../Icons/EditIcon";
|
||||
|
@ -25,7 +25,6 @@ import {
|
|||
ButtonSection,
|
||||
Heading,
|
||||
Hint,
|
||||
inputStyles,
|
||||
Section,
|
||||
} from "./ModalStyle";
|
||||
|
||||
|
@ -349,7 +348,7 @@ const UserAddressWrapper = styled.div`
|
|||
}
|
||||
`;
|
||||
|
||||
const UserAddress = styled.p`
|
||||
export const UserAddress = styled.p`
|
||||
display: flex;
|
||||
letter-spacing: 1px;
|
||||
margin-right: 8px;
|
||||
|
@ -363,11 +362,8 @@ const UserAddress = styled.p`
|
|||
${textSmallStyles}
|
||||
}
|
||||
`;
|
||||
const EmojiKey = styled.div`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
export const EmojiKey = styled.div`
|
||||
width: 116px;
|
||||
gap: 8px;
|
||||
font-size: 15px;
|
||||
line-height: 14px;
|
||||
|
@ -383,7 +379,6 @@ const ProfileBtn = styled.button`
|
|||
${buttonStyles}
|
||||
background: ${({ theme }) => theme.bodyBackgroundColor};
|
||||
border: 1px solid ${({ theme }) => theme.border};
|
||||
border-radius: 8px;
|
||||
margin-left: 8px;
|
||||
|
||||
&.red {
|
||||
|
@ -393,10 +388,6 @@ const ProfileBtn = styled.button`
|
|||
&.red:hover {
|
||||
background: ${({ theme }) => theme.buttonNoBgHover};
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: ${({ theme }) => theme.buttonBgHover};
|
||||
}
|
||||
`;
|
||||
|
||||
const CopyButton = styled.button`
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
import QRCode from "qrcode.react";
|
||||
import React, { useState } from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { buttonStyles } from "../Buttons/buttonStyle";
|
||||
import { LoginInstructions } from "../Form/LoginInstructions";
|
||||
import { PasteInput } from "../Form/PasteInput";
|
||||
|
||||
import { Modal } from "./Modal";
|
||||
import { Heading, Section } from "./ModalStyle";
|
||||
|
||||
export const StatusModalName = "StatusModal";
|
||||
|
||||
export enum StatusModalState {
|
||||
Mobile,
|
||||
Desktop,
|
||||
}
|
||||
|
||||
export function StatusModal() {
|
||||
const [modalState, setModalState] = useState<StatusModalState>(
|
||||
StatusModalState.Mobile
|
||||
);
|
||||
|
||||
const mobileFlow = modalState === StatusModalState.Mobile;
|
||||
const desktopFlow = modalState === StatusModalState.Desktop;
|
||||
|
||||
const switchModalState = (state: StatusModalState) => {
|
||||
setModalState((prev) => (prev === state ? StatusModalState.Mobile : state));
|
||||
};
|
||||
return (
|
||||
<Modal name={StatusModalName}>
|
||||
<Section>
|
||||
<Heading>Sync with Status profile</Heading>
|
||||
</Section>
|
||||
<MiddleSection>
|
||||
<Switch>
|
||||
<SwitchBtn
|
||||
className={`${modalState === StatusModalState.Mobile && "active"}`}
|
||||
onClick={() => switchModalState(StatusModalState.Mobile)}
|
||||
>
|
||||
From mobile
|
||||
</SwitchBtn>
|
||||
<SwitchBtnMobile
|
||||
className={`${modalState === StatusModalState.Desktop && "active"}`}
|
||||
onClick={() => switchModalState(StatusModalState.Desktop)}
|
||||
>
|
||||
From desktop
|
||||
</SwitchBtnMobile>
|
||||
</Switch>
|
||||
|
||||
{mobileFlow && <QRCode value="https://status.im/get/" size={158} />}
|
||||
|
||||
{desktopFlow && <PasteInput label="Paste sync code" />}
|
||||
|
||||
<LoginInstructions mobileFlow={mobileFlow} />
|
||||
</MiddleSection>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
const MiddleSection = styled(Section)`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
height: 514px;
|
||||
`;
|
||||
|
||||
const Switch = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 32px;
|
||||
`;
|
||||
|
||||
const SwitchBtn = styled.button`
|
||||
${buttonStyles}
|
||||
width: 159px;
|
||||
padding: 7px 0;
|
||||
text-align: center;
|
||||
color: ${({ theme }) => theme.tertiary};
|
||||
background: ${({ theme }) => theme.buttonBg};
|
||||
position: relative;
|
||||
|
||||
&.active {
|
||||
background: ${({ theme }) => theme.tertiary};
|
||||
color: ${({ theme }) => theme.bodyBackgroundColor};
|
||||
z-index: 10000;
|
||||
}
|
||||
`;
|
||||
|
||||
const SwitchBtnMobile = styled(SwitchBtn)`
|
||||
margin-left: -8px;
|
||||
`;
|
|
@ -3,17 +3,21 @@ import { Identity } from "status-communities/dist/cjs";
|
|||
import styled from "styled-components";
|
||||
|
||||
import {
|
||||
useIdentity,
|
||||
useSetIdentity,
|
||||
useSetNikcname,
|
||||
} from "../../contexts/identityProvider";
|
||||
import { useModal } from "../../contexts/modalProvider";
|
||||
import { Contact } from "../../models/Contact";
|
||||
import { NameInput } from "../../styles/Inputs";
|
||||
import { NameInput } from "../Form/inputStyles";
|
||||
import { AddIcon } from "../Icons/AddIcon";
|
||||
import { ChainIcon } from "../Icons/ChainIcon";
|
||||
import { LeftIconSvg } from "../Icons/LeftIcon";
|
||||
import { UserLogo } from "../Members/UserLogo";
|
||||
|
||||
import { Modal } from "./Modal";
|
||||
import {
|
||||
AddWrapper,
|
||||
BackBtn,
|
||||
Btn,
|
||||
ButtonSection,
|
||||
|
@ -22,44 +26,90 @@ import {
|
|||
Section,
|
||||
Text,
|
||||
} from "./ModalStyle";
|
||||
import { EmojiKey, UserAddress } from "./ProfileModal";
|
||||
|
||||
export const UserCreationModalName = "UserCreationModal";
|
||||
|
||||
export function UserCreationModal() {
|
||||
const identity = useIdentity();
|
||||
const setIdentity = useSetIdentity();
|
||||
const setNickname = useSetNikcname();
|
||||
|
||||
const [customNameInput, setCustomNameInput] = useState("");
|
||||
const [nextStep, setNextStep] = useState(false);
|
||||
const { setModal } = useModal(UserCreationModalName);
|
||||
return (
|
||||
<Modal name={UserCreationModalName}>
|
||||
<Section>
|
||||
<Heading>Create a Status Profile</Heading>
|
||||
</Section>
|
||||
<MiddleSection>
|
||||
<Content>
|
||||
<MiddleSection className={`${!nextStep && "initial"}`}>
|
||||
{nextStep ? (
|
||||
<Title>Your emojihash and identicon ring</Title>
|
||||
) : (
|
||||
<Title>Your profile</Title>
|
||||
)}
|
||||
{nextStep ? (
|
||||
<StyledHint>
|
||||
Longer and unusual names are better as they are less likely to be
|
||||
used by someone else.
|
||||
{" "}
|
||||
This set of emojis and coloured ring around your avatar are unique
|
||||
and represent your chat key, so your friends can easily distinguish
|
||||
you from potential impersonators.
|
||||
</StyledHint>
|
||||
<LogoWrapper>
|
||||
<UserLogo
|
||||
contact={{ trueName: customNameInput } as Contact}
|
||||
radius={80}
|
||||
colorWheel={[
|
||||
["red", 150],
|
||||
["blue", 250],
|
||||
["green", 360],
|
||||
]}
|
||||
/>
|
||||
</LogoWrapper>
|
||||
) : (
|
||||
<StyledHint>
|
||||
Longer and unusual names are better as they are <br /> less likely
|
||||
to be used by someone else.
|
||||
</StyledHint>
|
||||
)}
|
||||
|
||||
<LogoWrapper>
|
||||
<UserLogo
|
||||
contact={{ trueName: customNameInput } as Contact}
|
||||
radius={80}
|
||||
colorWheel={[
|
||||
["red", 150],
|
||||
["blue", 250],
|
||||
["green", 360],
|
||||
]}
|
||||
/>
|
||||
{!nextStep && (
|
||||
<AddIconWrapper>
|
||||
<AddIcon />
|
||||
</AddIconWrapper>
|
||||
)}
|
||||
</LogoWrapper>
|
||||
{!nextStep && (
|
||||
<NameInput
|
||||
placeholder="Display name"
|
||||
value={customNameInput}
|
||||
onChange={(e) => setCustomNameInput(e.currentTarget.value)}
|
||||
/>
|
||||
</Content>
|
||||
)}
|
||||
{nextStep && identity && (
|
||||
<>
|
||||
<UserAddress>
|
||||
{" "}
|
||||
Chatkey: {identity.privateKey.slice(0, 10)}...
|
||||
{identity.privateKey.slice(-3)}{" "}
|
||||
</UserAddress>
|
||||
<ChainIcons>
|
||||
<ChainIcon className="transformed" />
|
||||
<ChainIcon />
|
||||
</ChainIcons>
|
||||
<UserAttributes>
|
||||
<EmojiKey>🎩🍞🥑🦍🌈📡💅🏻♣️🔔⛸👵🅱</EmojiKey>
|
||||
<UserLogo
|
||||
radius={40}
|
||||
colorWheel={[
|
||||
["red", 150],
|
||||
["blue", 250],
|
||||
["green", 360],
|
||||
]}
|
||||
/>
|
||||
</UserAttributes>
|
||||
</>
|
||||
)}
|
||||
</MiddleSection>
|
||||
<ButtonSection>
|
||||
<BackBtn onClick={() => setModal(false)}>
|
||||
|
@ -67,10 +117,13 @@ export function UserCreationModal() {
|
|||
</BackBtn>
|
||||
<Btn
|
||||
onClick={() => {
|
||||
setIdentity(Identity.generate());
|
||||
setNickname(customNameInput);
|
||||
setModal(false);
|
||||
nextStep
|
||||
? setModal(false)
|
||||
: (setIdentity(Identity.generate()),
|
||||
setNickname(customNameInput),
|
||||
setNextStep(true));
|
||||
}}
|
||||
disabled={!customNameInput}
|
||||
>
|
||||
Next
|
||||
</Btn>
|
||||
|
@ -80,39 +133,55 @@ export function UserCreationModal() {
|
|||
}
|
||||
|
||||
const MiddleSection = styled(Section)`
|
||||
margin-bottom: 102px;
|
||||
height: 420px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
&.initial {
|
||||
padding: 32px;
|
||||
}
|
||||
`;
|
||||
|
||||
const Title = styled(Text)`
|
||||
font-weight: bold;
|
||||
font-size: 22px;
|
||||
line-height: 30px;
|
||||
letter-spacing: -0.2px;
|
||||
margin-bottom: 16px;
|
||||
`;
|
||||
|
||||
const StyledHint = styled(Hint)`
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
margin-bottom: 32px;
|
||||
text-align: center;
|
||||
`;
|
||||
|
||||
const LogoWrapper = styled.div`
|
||||
position: relative;
|
||||
display: flex;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 38px;
|
||||
margin-bottom: 32px;
|
||||
`;
|
||||
|
||||
const StyledHint = styled(Hint)`
|
||||
font-family: Inter;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
text-align: center;
|
||||
const AddIconWrapper = styled(AddWrapper)`
|
||||
top: 0;
|
||||
right: -50%;
|
||||
transform: translateX(-50%);
|
||||
`;
|
||||
|
||||
const Title = styled(Text)`
|
||||
font-family: Inter;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
font-size: 22px;
|
||||
line-height: 30px;
|
||||
|
||||
text-align: center;
|
||||
letter-spacing: -0.2px;
|
||||
margin-bottom: 16px;
|
||||
const ChainIcons = styled.div`
|
||||
width: 104px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 16px 0;
|
||||
`;
|
||||
|
||||
const Content = styled.div`
|
||||
margin-top: 16px;
|
||||
margin-left: 65px;
|
||||
margin-right: 65px;
|
||||
const UserAttributes = styled.div`
|
||||
width: 200px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 32px;
|
||||
`;
|
||||
|
|
|
@ -2,65 +2,56 @@ import React from "react";
|
|||
import styled from "styled-components";
|
||||
|
||||
import { useModal } from "../../contexts/modalProvider";
|
||||
import { buttonStyles, buttonTransparentStyles } from "../Buttons/buttonStyle";
|
||||
import { ColorChatIcon } from "../Icons/ColorChatIcon";
|
||||
import { StatusModalName } from "../Modals/StatusModal";
|
||||
import { UserCreationModalName } from "../Modals/UserCreationModal";
|
||||
import { textSmallStyles } from "../Text";
|
||||
|
||||
export function UserCreation() {
|
||||
const { setModal } = useModal(UserCreationModalName);
|
||||
const { setModal: setStatusModal } = useModal(StatusModalName);
|
||||
|
||||
return (
|
||||
<Background>
|
||||
<Wrapper>
|
||||
<IconWrapper>
|
||||
<ColorChatIcon />
|
||||
</IconWrapper>
|
||||
<TitleWrapper>Want in on the discussion ?</TitleWrapper>
|
||||
<ThrowAwayButton onClick={() => setModal(true)}>
|
||||
Use a throwaway account
|
||||
</ThrowAwayButton>
|
||||
</Wrapper>
|
||||
</Background>
|
||||
<Wrapper>
|
||||
<ColorChatIcon />
|
||||
<TitleWrapper>Want to jump into the discussion?</TitleWrapper>
|
||||
<LoginBtn onClick={() => setStatusModal(true)}>
|
||||
Sync with Status profile
|
||||
</LoginBtn>
|
||||
<LoginBtn>Connect Ethereum Wallet</LoginBtn>
|
||||
<ThrowAwayButton onClick={() => setModal(true)}>
|
||||
Use a throwaway account
|
||||
</ThrowAwayButton>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const ThrowAwayButton = styled.button`
|
||||
font-family: Inter;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
color: #4360df;
|
||||
`;
|
||||
|
||||
const IconWrapper = styled.div`
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
background-color: ${({ theme }) => theme.sectionBackgroundColor};
|
||||
`;
|
||||
|
||||
const TitleWrapper = styled.div`
|
||||
font-family: Inter;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
font-size: 17px;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
margin-top: 25px;
|
||||
margin-bottom: 24px;
|
||||
margin: 24px 0;
|
||||
color: ${({ theme }) => theme.primary};
|
||||
`;
|
||||
|
||||
const Wrapper = styled.div`
|
||||
margin: auto;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
const LoginBtn = styled.button`
|
||||
${buttonStyles}
|
||||
${textSmallStyles}
|
||||
padding: 10px 12px;
|
||||
margin-bottom: 16px;
|
||||
`;
|
||||
|
||||
const Background = styled.div`
|
||||
background: #f6f8fa;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
const ThrowAwayButton = styled.button`
|
||||
${buttonTransparentStyles}
|
||||
`;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
export type Contact = {
|
||||
id: string;
|
||||
online: boolean;
|
||||
online?: boolean;
|
||||
trueName: string;
|
||||
customName?: string;
|
||||
isUntrustworthy: boolean;
|
||||
blocked: boolean;
|
||||
isUntrustworthy?: boolean;
|
||||
blocked?: boolean;
|
||||
isFriend?: boolean;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
import styled from "styled-components";
|
||||
|
||||
import { inputStyles } from "../components/Modals/ModalStyle";
|
||||
|
||||
export const NameInput = styled.input`
|
||||
width: 328px;
|
||||
padding: 11px 16px;
|
||||
|
||||
${inputStyles}
|
||||
`;
|
|
@ -0,0 +1,9 @@
|
|||
export const paste = (elementId: string) => {
|
||||
navigator.clipboard
|
||||
.readText()
|
||||
.then(
|
||||
(clipText) =>
|
||||
((<HTMLInputElement>document.getElementById(elementId)).value =
|
||||
clipText)
|
||||
);
|
||||
};
|
31
yarn.lock
31
yarn.lock
|
@ -279,6 +279,7 @@ __metadata:
|
|||
"@types/emoji-mart": ^3.0.6
|
||||
"@types/mocha": ^9.0.0
|
||||
"@types/node": ^16.9.6
|
||||
"@types/qrcode.react": ^1.0.2
|
||||
"@types/react": ^17.0.16
|
||||
"@types/styled-components": ^5.1.12
|
||||
"@typescript-eslint/eslint-plugin": ^4.29.0
|
||||
|
@ -295,6 +296,7 @@ __metadata:
|
|||
npm-run-all: ^4.1.5
|
||||
npm-watch: ^0.11.0
|
||||
prettier: ^2.3.2
|
||||
qrcode.react: ^1.0.1
|
||||
react: ^17.0.2
|
||||
react-dom: ^17.0.2
|
||||
react-is: ^17.0.2
|
||||
|
@ -983,6 +985,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/qrcode.react@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "@types/qrcode.react@npm:1.0.2"
|
||||
dependencies:
|
||||
"@types/react": "*"
|
||||
checksum: be256f0192366b4c0822da43c732bf3e29beb954c89d739aa770f09e5160842a3ca4d6814cb57bbcbbf8997cf7af0b998de318dab957f0820f267bb746c9a329
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/react-dom@npm:>=16.9.0, @types/react-dom@npm:^17.0.9":
|
||||
version: 17.0.9
|
||||
resolution: "@types/react-dom@npm:17.0.9"
|
||||
|
@ -9261,6 +9272,26 @@ fsevents@~2.3.2:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"qr.js@npm:0.0.0":
|
||||
version: 0.0.0
|
||||
resolution: "qr.js@npm:0.0.0"
|
||||
checksum: 5ac6c393967bdeaa660e7fd3a501a25eb538c1f6008a4d30ab2b97bbe520e5c236530090773f1578aa0a523cdaa6923c866615e21143f9e7cd22abd41c789b69
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"qrcode.react@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "qrcode.react@npm:1.0.1"
|
||||
dependencies:
|
||||
loose-envify: ^1.4.0
|
||||
prop-types: ^15.6.0
|
||||
qr.js: 0.0.0
|
||||
peerDependencies:
|
||||
react: ^15.5.3 || ^16.0.0 || ^17.0.0
|
||||
checksum: 154a9557d103fa776cd99bc0d2600b862be74872ff965052533bc38ea0606c4d0965b4dd6df93e53f1db86699517a25db2718bbbc08c5d535a90c0d335552e9a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"qs@npm:6.7.0":
|
||||
version: 6.7.0
|
||||
resolution: "qs@npm:6.7.0"
|
||||
|
|
Loading…
Reference in New Issue