Add token requirements (#165)
This commit is contained in:
parent
a90696a8f4
commit
626f70c576
|
@ -46,13 +46,14 @@ export function Chat() {
|
||||||
{!narrow && (
|
{!narrow && (
|
||||||
<ChannelsWrapper>
|
<ChannelsWrapper>
|
||||||
<StyledCommunity />
|
<StyledCommunity />
|
||||||
{identity ? <Channels /> : <UserCreation />}
|
{identity ? <Channels /> : <UserCreation permission={true} />}
|
||||||
</ChannelsWrapper>
|
</ChannelsWrapper>
|
||||||
)}
|
)}
|
||||||
{state === ChatState.ChatBody && (
|
{state === ChatState.ChatBody && (
|
||||||
<ChatBody
|
<ChatBody
|
||||||
onClick={() => setShowMembers(!showMembers)}
|
onClick={() => setShowMembers(!showMembers)}
|
||||||
showMembers={showMembers}
|
showMembers={showMembers}
|
||||||
|
permission={true}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showMembers && !narrow && state === ChatState.ChatBody && <Members />}
|
{showMembers && !narrow && state === ChatState.ChatBody && <Members />}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import styled from "styled-components";
|
||||||
import { useMessengerContext } from "../../contexts/messengerProvider";
|
import { useMessengerContext } from "../../contexts/messengerProvider";
|
||||||
import { useNarrow } from "../../contexts/narrowProvider";
|
import { useNarrow } from "../../contexts/narrowProvider";
|
||||||
import { Reply } from "../../hooks/useReply";
|
import { Reply } from "../../hooks/useReply";
|
||||||
|
import { TokenRequirement } from "../Form/TokenRequirement";
|
||||||
import { MessagesList } from "../Messages/MessagesList";
|
import { MessagesList } from "../Messages/MessagesList";
|
||||||
import { NarrowChannels } from "../NarrowMode/NarrowChannels";
|
import { NarrowChannels } from "../NarrowMode/NarrowChannels";
|
||||||
import { NarrowMembers } from "../NarrowMode/NarrowMembers";
|
import { NarrowMembers } from "../NarrowMode/NarrowMembers";
|
||||||
|
@ -22,9 +23,10 @@ export enum ChatBodyState {
|
||||||
interface ChatBodyProps {
|
interface ChatBodyProps {
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
showMembers: boolean;
|
showMembers: boolean;
|
||||||
|
permission: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ChatBody({ onClick, showMembers }: ChatBodyProps) {
|
export function ChatBody({ onClick, showMembers, permission }: ChatBodyProps) {
|
||||||
const { messenger, activeChannel, communityData } = useMessengerContext();
|
const { messenger, activeChannel, communityData } = useMessengerContext();
|
||||||
const narrow = useNarrow();
|
const narrow = useNarrow();
|
||||||
|
|
||||||
|
@ -50,67 +52,98 @@ export function ChatBody({ onClick, showMembers }: ChatBodyProps) {
|
||||||
const [reply, setReply] = useState<Reply | undefined>(undefined);
|
const [reply, setReply] = useState<Reply | undefined>(undefined);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChatBodyWrapper className={className}>
|
<Wrapper>
|
||||||
{editGroup && communityData ? (
|
<ChatBodyWrapper className={className}>
|
||||||
<ChatCreation
|
{editGroup && communityData ? (
|
||||||
setEditGroup={setEditGroup}
|
<ChatCreation
|
||||||
activeChannel={activeChannel}
|
setEditGroup={setEditGroup}
|
||||||
/>
|
activeChannel={activeChannel}
|
||||||
) : (
|
/>
|
||||||
<ChatTopbar
|
) : (
|
||||||
className={className}
|
<ChatTopbar
|
||||||
onClick={onClick}
|
className={className}
|
||||||
setEditGroup={setEditGroup}
|
onClick={onClick}
|
||||||
showMembers={showMembers}
|
setEditGroup={setEditGroup}
|
||||||
showState={showState}
|
showMembers={showMembers}
|
||||||
switchShowState={switchShowState}
|
showState={showState}
|
||||||
/>
|
switchShowState={switchShowState}
|
||||||
)}
|
/>
|
||||||
{messenger ? (
|
)}
|
||||||
<>
|
{messenger ? (
|
||||||
{showState === ChatBodyState.Chat && (
|
<>
|
||||||
<>
|
{showState === ChatBodyState.Chat && (
|
||||||
{messenger && communityData ? (
|
<>
|
||||||
<MessagesList setReply={setReply} />
|
{messenger && communityData ? (
|
||||||
) : (
|
<MessagesList setReply={setReply} />
|
||||||
<LoadingSkeleton />
|
) : (
|
||||||
)}
|
<LoadingSkeleton />
|
||||||
<ChatInput reply={reply} setReply={setReply} />
|
)}
|
||||||
</>
|
<ChatInput reply={reply} setReply={setReply} />
|
||||||
)}
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
{showState === ChatBodyState.Channels && (
|
{showState === ChatBodyState.Channels && (
|
||||||
<NarrowChannels
|
<NarrowChannels
|
||||||
setShowChannels={() => switchShowState(ChatBodyState.Channels)}
|
setShowChannels={() => switchShowState(ChatBodyState.Channels)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showState === ChatBodyState.Members && (
|
{showState === ChatBodyState.Members && (
|
||||||
<NarrowMembers
|
<NarrowMembers
|
||||||
switchShowMembersList={() =>
|
switchShowMembersList={() =>
|
||||||
switchShowState(ChatBodyState.Members)
|
switchShowState(ChatBodyState.Members)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<LoadingSkeleton />
|
<LoadingSkeleton />
|
||||||
<ChatInput reply={reply} setReply={setReply} />
|
<ChatInput reply={reply} setReply={setReply} />
|
||||||
</>
|
</>
|
||||||
|
)}
|
||||||
|
</ChatBodyWrapper>
|
||||||
|
{!permission && (
|
||||||
|
<BluredWrapper>
|
||||||
|
<TokenRequirement />
|
||||||
|
</BluredWrapper>
|
||||||
)}
|
)}
|
||||||
</ChatBodyWrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChatBodyWrapper = styled.div`
|
const Wrapper = styled.div`
|
||||||
width: 61%;
|
width: 61%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: ${({ theme }) => theme.bodyBackgroundColor};
|
background: ${({ theme }) => theme.bodyBackgroundColor};
|
||||||
|
position: relative;
|
||||||
|
|
||||||
&.narrow {
|
&.narrow {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const ChatBodyWrapper = styled.div`
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
background: ${({ theme }) => theme.bodyBackgroundColor};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const BluredWrapper = styled.div`
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: center;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
background: ${({ theme }) => theme.bodyBackgroundGradient};
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
|
z-index: 2;
|
||||||
|
`;
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
import React from "react";
|
||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
import { useMessengerContext } from "../../contexts/messengerProvider";
|
||||||
|
import { textMediumStyles } from "../Text";
|
||||||
|
|
||||||
|
const communityRequirements = {
|
||||||
|
requirements: [
|
||||||
|
{
|
||||||
|
name: "STN",
|
||||||
|
amount: 10,
|
||||||
|
logo: "https://status.im/img/logo.svg",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
alternativeRequirements: [
|
||||||
|
{
|
||||||
|
name: "ETH",
|
||||||
|
amount: 1,
|
||||||
|
logo: "https://ethereum.org/static/a110735dade3f354a46fc2446cd52476/db4de/eth-home-icon.webp",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MKR",
|
||||||
|
amount: 10,
|
||||||
|
logo: "https://cryptologos.cc/logos/maker-mkr-logo.svg?v=017",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export function TokenRequirement() {
|
||||||
|
const { communityData } = useMessengerContext();
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<Text>
|
||||||
|
To join <span>{communityData?.name}</span> community chat you need to
|
||||||
|
hold:
|
||||||
|
</Text>
|
||||||
|
<Row>
|
||||||
|
{communityRequirements.requirements.map((req) => (
|
||||||
|
<Requirement key={req.name + req.amount}>
|
||||||
|
<Logo
|
||||||
|
style={{
|
||||||
|
backgroundImage: `url(${req.logo}`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Amount>
|
||||||
|
{req.amount} {req.name}{" "}
|
||||||
|
</Amount>
|
||||||
|
</Requirement>
|
||||||
|
))}
|
||||||
|
</Row>
|
||||||
|
{communityRequirements.alternativeRequirements && <Text>or</Text>}
|
||||||
|
<Row>
|
||||||
|
{communityRequirements.alternativeRequirements.map((req) => (
|
||||||
|
<Requirement key={req.name + req.amount}>
|
||||||
|
<Logo
|
||||||
|
style={{
|
||||||
|
backgroundImage: `url(${req.logo}`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Amount>
|
||||||
|
{req.amount} {req.name}{" "}
|
||||||
|
</Amount>
|
||||||
|
</Requirement>
|
||||||
|
))}
|
||||||
|
</Row>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
height: 50%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Text = styled.p`
|
||||||
|
color: ${({ theme }) => theme.primary};
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
& > span {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
${textMediumStyles}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Requirement = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 2px 12px 2px 2px;
|
||||||
|
background: ${({ theme }) => theme.buttonBg};
|
||||||
|
color: ${({ theme }) => theme.tertiary};
|
||||||
|
|
||||||
|
&.denial {
|
||||||
|
background: ${({ theme }) => theme.buttonNoBgHover};
|
||||||
|
color: ${({ theme }) => theme.redColor};
|
||||||
|
}
|
||||||
|
|
||||||
|
& + & {
|
||||||
|
margin-left: 18px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Amount = styled.p`
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-left: 6px;
|
||||||
|
|
||||||
|
${textMediumStyles}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Row = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Logo = styled.div`
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
`;
|
|
@ -0,0 +1,38 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export const EthereumLogo = () => (
|
||||||
|
<svg
|
||||||
|
width="28"
|
||||||
|
height="28"
|
||||||
|
viewBox="0 0 128 128"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M64 128C99.3462 128 128 99.3462 128 64C128 28.6538 99.3462 0 64 0C28.6538 0 0 28.6538 0 64C0 99.3462 28.6538 128 64 128Z"
|
||||||
|
fill="#627EEA"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M65.9922 16V51.48L95.9802 64.88L65.9922 16Z"
|
||||||
|
fill="white"
|
||||||
|
fillOpacity="0.602"
|
||||||
|
/>
|
||||||
|
<path d="M65.992 16L36 64.88L65.992 51.48V16Z" fill="white" />
|
||||||
|
<path
|
||||||
|
d="M65.9922 87.872V111.98L96.0002 70.464L65.9922 87.872Z"
|
||||||
|
fill="white"
|
||||||
|
fillOpacity="0.602"
|
||||||
|
/>
|
||||||
|
<path d="M65.992 111.98V87.868L36 70.464L65.992 111.98Z" fill="white" />
|
||||||
|
<path
|
||||||
|
d="M65.9922 82.292L95.9802 64.88L65.9922 51.488V82.292Z"
|
||||||
|
fill="white"
|
||||||
|
fillOpacity="0.2"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M36 64.88L65.992 82.292V51.488L36 64.88Z"
|
||||||
|
fill="white"
|
||||||
|
fillOpacity="0.602"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
|
@ -0,0 +1,33 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export const MarkerdaoLogo = () => (
|
||||||
|
<svg
|
||||||
|
width="28"
|
||||||
|
height="28"
|
||||||
|
viewBox="0 0 128 128"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M64 128C99.3462 128 128 99.3462 128 64C128 28.6538 99.3462 0 64 0C28.6538 0 0 28.6538 0 64C0 99.3462 28.6538 128 64 128Z"
|
||||||
|
fill="url(#paint0_linear_1538_226102)"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M32.4995 83.2V53.0773L55.3433 70.2699V83.2H61.1737V69.056C61.1715 67.9913 60.6693 66.9873 59.819 66.3467L32.1155 45.4891C31.5272 45.052 30.8133 44.816 30.0803 44.816C28.2139 44.816 26.6757 46.3469 26.667 48.2133V83.2H32.4995ZM95.6761 83.2V53.0773L72.8323 70.2699V83.2H67.0019V69.056C67.0041 67.9913 67.5062 66.9873 68.3566 66.3467L96.0601 45.4976C96.6484 45.0605 97.3622 44.8243 98.0953 44.8243C99.9585 44.8243 101.495 46.3501 101.509 48.2133V83.2H95.6761Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient
|
||||||
|
id="paint0_linear_1538_226102"
|
||||||
|
x1="64"
|
||||||
|
y1="0"
|
||||||
|
x2="64"
|
||||||
|
y2="128"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
>
|
||||||
|
<stop stop-color="#4FA89B" />
|
||||||
|
<stop offset="1" stop-color="#6ACEBB" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
);
|
|
@ -0,0 +1,24 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export const StatusIcon = () => (
|
||||||
|
<svg
|
||||||
|
width="29"
|
||||||
|
height="28"
|
||||||
|
viewBox="0 0 29 28"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M14.5 0.000366217C6.76794 0.000139753 0.5 6.26798 0.5 14.0001C0.5 21.7323 6.76794 28.0001 14.5 28.0001C22.2321 28.0001 28.5 21.7321 28.5 14.0001C28.5 6.26821 22.2321 0.000366217 14.5 0.000366217Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M16.8615 13.8707C15.1835 13.9674 14.1319 13.5765 12.4537 13.6734C12.0375 13.6968 11.6242 13.7571 11.2186 13.8537C11.4663 10.7502 13.6627 8.03539 16.6495 7.86283C18.4823 7.75707 20.3143 8.88871 20.4136 10.7258C20.5114 12.5314 19.1347 13.7393 16.8617 13.8705L16.8615 13.8707ZM12.3555 20.2187C10.5996 20.3179 8.8449 19.2585 8.74961 17.5394C8.6559 15.8495 9.97506 14.719 12.1525 14.5963C13.7598 14.5057 14.7674 14.8717 16.3746 14.7808C16.7732 14.759 17.1691 14.7026 17.5579 14.6121C17.321 17.5165 15.2169 20.0575 12.3555 20.2187ZM14.5 0.000226461C6.76794 -2.92639e-09 0.5 6.26784 0.5 14C0.5 21.7322 6.76794 28 14.5 28C22.2321 28 28.5 21.7319 28.5 14C28.5 6.26807 22.2321 0 14.5 0"
|
||||||
|
fill="#4360DF"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
|
@ -9,7 +9,11 @@ import { UserCreationModalName } from "../Modals/UserCreationModal";
|
||||||
import { WalletModalName } from "../Modals/WalletModal";
|
import { WalletModalName } from "../Modals/WalletModal";
|
||||||
import { textSmallStyles } from "../Text";
|
import { textSmallStyles } from "../Text";
|
||||||
|
|
||||||
export function UserCreation() {
|
interface UserCreationProps {
|
||||||
|
permission: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function UserCreation({ permission }: UserCreationProps) {
|
||||||
const { setModal } = useModal(UserCreationModalName);
|
const { setModal } = useModal(UserCreationModalName);
|
||||||
const { setModal: setStatusModal } = useModal(StatusModalName);
|
const { setModal: setStatusModal } = useModal(StatusModalName);
|
||||||
const { setModal: setWalletModal } = useModal(WalletModalName);
|
const { setModal: setWalletModal } = useModal(WalletModalName);
|
||||||
|
@ -24,9 +28,11 @@ export function UserCreation() {
|
||||||
<LoginBtn onClick={() => setWalletModal(true)}>
|
<LoginBtn onClick={() => setWalletModal(true)}>
|
||||||
Connect Ethereum Wallet
|
Connect Ethereum Wallet
|
||||||
</LoginBtn>
|
</LoginBtn>
|
||||||
<ThrowAwayButton onClick={() => setModal(true)}>
|
{permission && (
|
||||||
Use a throwaway account
|
<ThrowAwayButton onClick={() => setModal(true)}>
|
||||||
</ThrowAwayButton>
|
Use a throwaway account
|
||||||
|
</ThrowAwayButton>
|
||||||
|
)}
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ export type Theme = {
|
||||||
tertiary: string;
|
tertiary: string;
|
||||||
bodyBackgroundColor: string;
|
bodyBackgroundColor: string;
|
||||||
sectionBackgroundColor: string;
|
sectionBackgroundColor: string;
|
||||||
|
bodyBackgroundGradient: string;
|
||||||
guestNameColor: string;
|
guestNameColor: string;
|
||||||
iconColor: string;
|
iconColor: string;
|
||||||
iconUserColor: string;
|
iconUserColor: string;
|
||||||
|
@ -34,6 +35,8 @@ export const lightTheme: Theme = {
|
||||||
tertiary: "#4360DF",
|
tertiary: "#4360DF",
|
||||||
bodyBackgroundColor: "#fff",
|
bodyBackgroundColor: "#fff",
|
||||||
sectionBackgroundColor: "#F6F8FA",
|
sectionBackgroundColor: "#F6F8FA",
|
||||||
|
bodyBackgroundGradient:
|
||||||
|
"linear-gradient(0deg, #FFFFFF 50%, rgba(255, 255, 255, 0) 102.57%)",
|
||||||
guestNameColor: "#887AF9",
|
guestNameColor: "#887AF9",
|
||||||
iconColor: "#D37EF4",
|
iconColor: "#D37EF4",
|
||||||
iconUserColor: "#717199",
|
iconUserColor: "#717199",
|
||||||
|
@ -65,6 +68,8 @@ export const darkTheme: Theme = {
|
||||||
tertiary: "#88B0FF",
|
tertiary: "#88B0FF",
|
||||||
bodyBackgroundColor: "#000",
|
bodyBackgroundColor: "#000",
|
||||||
sectionBackgroundColor: "#252525",
|
sectionBackgroundColor: "#252525",
|
||||||
|
bodyBackgroundGradient:
|
||||||
|
"linear-gradient(0deg, #000 50%, rgba(255, 255, 255, 0) 102.57%)",
|
||||||
guestNameColor: "#887AF9",
|
guestNameColor: "#887AF9",
|
||||||
iconColor: "#D37EF4",
|
iconColor: "#D37EF4",
|
||||||
iconUserColor: "#717199",
|
iconUserColor: "#717199",
|
||||||
|
|
Loading…
Reference in New Issue