diff --git a/.husky/pre-commit b/.husky/pre-commit index 2665d0376..86348e63c 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -4,4 +4,4 @@ echo "\nRunning GIT hooks..." yarn cleanbuild yarn nx affected --target=lint -yarn nx affected --target=test \ No newline at end of file +# yarn nx affected --target=test \ No newline at end of file diff --git a/packages/examples/sdk-frontend-react/src/app/ChatUITest/ChatViewComponent.tsx b/packages/examples/sdk-frontend-react/src/app/ChatUITest/ChatViewComponent.tsx index 95e6b3384..d8a4862f3 100644 --- a/packages/examples/sdk-frontend-react/src/app/ChatUITest/ChatViewComponent.tsx +++ b/packages/examples/sdk-frontend-react/src/app/ChatUITest/ChatViewComponent.tsx @@ -14,7 +14,7 @@ const ChatViewComponentTest = () => {

Chat UI Test page

- console.log("BOIIII RETURNNNSSSSS")} chatId='0960dcbd95ad905a3eec0b66d24efbfd950d6afd8b8d8113c53c2a0444c45304' limit={10} isConnected={true} /> + console.log("BOIIII RETURNNNSSSSS")} chatId='b8e068e02fe12d7136bc2f24408835573f30c6fbf0b65ea26ab4c7055a2c85f1' limit={10} isConnected={true} />
); diff --git a/packages/uiweb/src/lib/components/chat/ChatViewBubble/ChatViewBubble.tsx b/packages/uiweb/src/lib/components/chat/ChatViewBubble/ChatViewBubble.tsx index f527c883b..1b388c4ed 100644 --- a/packages/uiweb/src/lib/components/chat/ChatViewBubble/ChatViewBubble.tsx +++ b/packages/uiweb/src/lib/components/chat/ChatViewBubble/ChatViewBubble.tsx @@ -1,8 +1,23 @@ -import { useContext, useEffect, useState } from 'react'; -import { Section, Span, Image } from '../../reusables'; +import { + ReactElement, + ReactNode, + useContext, + useEffect, + useState, +} from 'react'; + import moment from 'moment'; import styled from 'styled-components'; +import { TwitterTweetEmbed } from 'react-twitter-embed'; + +import { Section, Span, Image } from '../../reusables'; +import { checkTwitterUrl } from '../helpers/twitter'; +import { ChatDataContext } from '../../../context'; +import { useChatData } from '../../../hooks'; +import { ThemeContext } from '../theme/ThemeProvider'; + import { FileMessageContent } from '../../../types'; +import { IMessagePayload, TwitterFeedReturnType } from '../exportedTypes'; import { FILE_ICON } from '../../../config'; import { formatFileSize, @@ -10,12 +25,6 @@ import { pCAIP10ToWallet, shortenText, } from '../../../helpers'; -import { checkTwitterUrl } from '../helpers/twitter'; -import { IMessagePayload, TwitterFeedReturnType } from '../exportedTypes'; -import { TwitterTweetEmbed } from 'react-twitter-embed'; -import { ChatDataContext } from '../../../context'; -import { useChatData } from '../../../hooks'; -import { ThemeContext } from '../theme/ThemeProvider'; const SenderMessageAddress = ({ chat }: { chat: IMessagePayload }) => { const { account } = useContext(ChatDataContext); @@ -73,19 +82,18 @@ const SenderMessageProfilePicture = ({ chat }: { chat: IMessagePayload }) => { ); }; - -//can create a wrapper for till the senderMessageAddress and use it for all cards(types of messages) -const MessageCard = ({ +const MessageWrapper = ({ chat, - position, + children, isGroup, + maxWidth, }: { chat: IMessagePayload; - position: number; + children: ReactNode; isGroup: boolean; + maxWidth?: string; }) => { const theme = useContext(ThemeContext); - const time = moment(chat.timestamp).format('hh:mm a'); return (
{isGroup && }
{isGroup && } -
+ +
+ ); +}; + +const MessageCard = ({ + chat, + position, + isGroup, +}: { + chat: IMessagePayload; + position: number; + isGroup: boolean; +}) => { + const theme = useContext(ThemeContext); + const time = moment(chat.timestamp).format('hh:mm a'); + return ( + +
+ {' '} +
+ {chat.messageContent.split('\n').map((str) => ( + + {str} + + ))} +
+ - {' '} -
- {chat.messageContent.split('\n').map((str) => ( - - {str} - - ))} -
- - {time} - -
+ {time} +
-
+ ); }; @@ -189,51 +216,42 @@ const FileCard = ({ const size = fileContent.size; return ( -
- {isGroup && } -
- {isGroup && } -
- extension icon -
- - {shortenText(name, 11)} - - - {formatFileSize(size)} - -
- - + +
+ extension icon +
+ + {shortenText(name, 11)} + + + {formatFileSize(size)} +
+ +
-
+ ); }; @@ -247,27 +265,21 @@ const ImageCard = ({ isGroup: boolean; }) => { return ( -
- {isGroup && } -
- {isGroup && } -
- -
+ +
+
-
+ ); }; @@ -281,32 +293,21 @@ const GIFCard = ({ isGroup: boolean; }) => { return ( -
- {isGroup && } -
- {isGroup && } -
- -
+ +
+
-
+ ); }; @@ -322,31 +323,21 @@ const TwitterCard = ({ position: number; }) => { return ( -
- {isGroup && } -
- {isGroup && } -
- -
+ +
+
-
+ ); }; export const ChatViewBubble = ({ chat }: { chat: IMessagePayload }) => { - const { account} = - useChatData(); + const { account } = useChatData(); const position = pCAIP10ToWallet(chat.fromDID).toLowerCase() !== account?.toLowerCase() ? 0 @@ -367,8 +358,6 @@ export const ChatViewBubble = ({ chat }: { chat: IMessagePayload }) => { } }, [chat.toDID, isGroup]); - - if (messageType === 'TwitterFeedLink') { chat.messageType = 'TwitterFeedLink'; } diff --git a/packages/uiweb/src/lib/components/chat/ChatViewComponent/ChatViewComponent.tsx b/packages/uiweb/src/lib/components/chat/ChatViewComponent/ChatViewComponent.tsx index 73db94254..a4a2fca4b 100644 --- a/packages/uiweb/src/lib/components/chat/ChatViewComponent/ChatViewComponent.tsx +++ b/packages/uiweb/src/lib/components/chat/ChatViewComponent/ChatViewComponent.tsx @@ -34,7 +34,7 @@ export const ChatViewComponent: React.FC = ( file = true, gif = true, isConnected = true, - onClick, + onGetTokenClick, } = options || {}; const { env, signer, account, pgpPrivateKey } = useChatData(); @@ -86,7 +86,7 @@ export const ChatViewComponent: React.FC = ( {(messageInput && (!!signer || (!!account && !!pgpPrivateKey) || isConnected )) && (
= ( setChatStatusText(''); }, [chatId, account, env]); - //need to do something about fetching connectedUser in every component useEffect(() => { (async () => { if (!connectedProfile && account) { @@ -129,6 +128,7 @@ export const ChatViewList: React.FC = ( setLoading(false); })(); }, [chatId, pgpPrivateKey, account, env]); + //moniters socket changes useEffect(() => { if (checkIfSameChat(messagesSinceLastConnection, account!, chatId)) { @@ -166,7 +166,6 @@ export const ChatViewList: React.FC = ( } } }, [groupInformationSinceLastConnection]); - useEffect(() => { if (conversationHash) { diff --git a/packages/uiweb/src/lib/components/chat/ConnectButton/ConnectButton.tsx b/packages/uiweb/src/lib/components/chat/ConnectButton/ConnectButton.tsx index a67c40b4d..c83175e42 100644 --- a/packages/uiweb/src/lib/components/chat/ConnectButton/ConnectButton.tsx +++ b/packages/uiweb/src/lib/components/chat/ConnectButton/ConnectButton.tsx @@ -1,15 +1,17 @@ -import styled from 'styled-components'; -import { IChatTheme } from '../theme'; -import { useChatData } from '../../../hooks'; -import * as PushAPI from '@pushprotocol/restapi'; import { useContext, useEffect, useState } from 'react'; -import { init, useConnectWallet } from "@web3-onboard/react"; -import injectedModule from "@web3-onboard/injected-wallets"; + +import styled from 'styled-components'; import { Signer, ethers } from 'ethers'; +import { useAccount, useChatData } from '../../../hooks'; import { ThemeContext } from '../theme/ThemeProvider'; -import { device } from '../../../config'; +import useGetChatProfile from '../../../hooks/useGetChatProfile'; +import useCreateChatProfile from '../../../hooks/useCreateChatProfile'; +import useDecryptPGPKey from '../../../hooks/useDecryptPGPKey'; + import { getAddressFromSigner } from '../../../helpers'; +import { IChatTheme } from '../theme'; +import { device } from '../../../config'; /** * @interface IThemeProps @@ -20,7 +22,7 @@ interface IThemeProps { } export const ConnectButtonSub = () => { - const [{ wallet, connecting }, connect, disconnect] = useConnectWallet(); + const {wallet, connecting , connect, disconnect} = useAccount(); const { signer, @@ -32,11 +34,14 @@ export const ConnectButtonSub = () => { setSigner, } = useChatData(); const theme = useContext(ThemeContext); + const {fetchChatProfile} = useGetChatProfile(); + const {creteChatProfile} = useCreateChatProfile(); + const {decryptPGPKey} = useDecryptPGPKey(); + - const newFunc = () => { + const setUserData = () => { if (wallet) { (async () => { - const ethersProvider = new ethers.providers.Web3Provider(wallet.provider, 'any') const signer = ethersProvider.getSigner() const newAdd = await getAddressFromSigner(signer) @@ -49,12 +54,10 @@ export const ConnectButtonSub = () => { setPgpPrivateKey(null) } } - useEffect(() => { - newFunc() + setUserData() }, [wallet]) - useEffect(() => { (async () => { if (account && signer) { @@ -63,24 +66,23 @@ export const ConnectButtonSub = () => { })(); }, [account, signer]); + const handleUserCreation = async () => { if (!account && !env) return; try { - let user = await PushAPI.user.get({ account: account!, env: env }); + let user = await fetchChatProfile({ profileId: account! ,env}); if (!user) { if (!signer) return; - user = await PushAPI.user.create({ - signer: signer, - env: env, - }); + user = await creteChatProfile({ signer: signer ,env}); } if (user?.encryptedPrivateKey && !pgpPrivateKey) { - const decryptPgpKey = await PushAPI.chat.decryptPGPKey({ - encryptedPGPPrivateKey: user.encryptedPrivateKey, + const decryptPgpKey = await decryptPGPKey({ + encryptedPrivateKey: user.encryptedPrivateKey, account: account!, signer: signer, env: env, }); + if(decryptPgpKey) setPgpPrivateKey(decryptPgpKey); } } catch (e: any) { @@ -102,10 +104,10 @@ const ConnectButtonDiv = styled.div` button{ background: ${(props) => `${props.theme.backgroundColor.buttonBackground}!important`}; - // color: ${(props) => `${props.theme.backgroundColor.buttonText}!important`}; - color: #fff; + color: ${(props) => `${props.theme.textColor.buttonText}!important`}; text-align:center; font-size: 1em; + cursor:pointer; border-radius: 10px; padding: 10px 20px; outline: none; @@ -121,4 +123,7 @@ const ConnectButtonDiv = styled.div` @media ${device.mobileL} { font-size: 12px; } + body.modal-open { + overflow-y: hidden; + } `; diff --git a/packages/uiweb/src/lib/components/chat/ConnectButton/index.tsx b/packages/uiweb/src/lib/components/chat/ConnectButton/index.tsx index 3465bf8ba..e626a4465 100644 --- a/packages/uiweb/src/lib/components/chat/ConnectButton/index.tsx +++ b/packages/uiweb/src/lib/components/chat/ConnectButton/index.tsx @@ -1,29 +1,23 @@ import { IChatTheme } from '../theme'; import { ConnectButtonSub } from './ConnectButton'; -import { InfuraAPIKey } from '../../../config'; +import { BLOCKNATIVE_PROJECT_ID, InfuraAPIKey } from '../../../config'; import { Web3OnboardProvider } from '@web3-onboard/react'; import injectedModule from '@web3-onboard/injected-wallets'; import walletConnectModule from '@web3-onboard/walletconnect' import init from '@web3-onboard/core'; -import { ethers } from 'ethers'; +const APP_META_DATA = { + name: 'Push Protocol', + icon: 'https://files.slack.com/files-pri/T011WQBLH39-F05QWQA0MSR/pushlogoblocknative.png', + description: 'Example showcasing how to connect a wallet.', -/** - * @interface IThemeProps - * this interface is used for defining the props for styled components - */ -interface IThemeProps { - theme?: IChatTheme; -} - -const wcv2InitOptions = { - projectId: '64a44a0fb537407bfe97d24330e4109c', - requiredChains: [1, 56] + recommendedInjectedWallets: [ + { name: 'MetaMask', url: 'https://metamask.io' }, + ] } -const walletConnect = walletConnectModule(wcv2InitOptions) -const chains = [ +const CHAINS = [ { id: '0x1', token: 'ETH', @@ -61,22 +55,23 @@ const chains = [ rpcUrl: 'https://rpc.ankr.com/arbitrum' } ] -const wallets = [injectedModule(), walletConnect] -const appMetadata = { - name: 'Push Protocol', - icon: 'https://files.slack.com/files-pri/T011WQBLH39-F05QWQA0MSR/pushlogoblocknative.png', - description: 'Example showcasing how to connect a wallet.', - recommendedInjectedWallets: [ - { name: 'MetaMask', url: 'https://metamask.io' }, - ] +const wcv2InitOptions = { + projectId: BLOCKNATIVE_PROJECT_ID, + requiredChains: [1, 56] } +const walletConnect = walletConnectModule(wcv2InitOptions) + +const wallets = [injectedModule(), walletConnect] + + + const web3OnBoard = init({ wallets, - chains, - appMetadata, + chains:CHAINS, + appMetadata:APP_META_DATA, accountCenter: { desktop: { enabled: false diff --git a/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx b/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx index 5b06abac0..9a016c54a 100644 --- a/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx +++ b/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx @@ -1,19 +1,14 @@ -import { - useChatData, - useClickAway, - useDeviceWidthCheck, - usePushChatSocket, -} from '../../../hooks'; -import type { FileMessageContent } from '../../../types'; import { ChangeEvent, useContext, useEffect, useRef, useState } from 'react'; -import { GIFType, IChatTheme, MessageInputProps } from '../exportedTypes'; + import styled from 'styled-components'; -import { PUBLIC_GOOGLE_TOKEN, device } from '../../../config'; +import { MdCheckCircle, MdError } from 'react-icons/md'; +import EmojiPicker, { EmojiClickData } from 'emoji-picker-react'; +import GifPicker from 'gif-picker-react'; +import { IFeeds } from '@pushprotocol/restapi'; + import { Section, Div, Span } from '../../reusables'; import { EmojiIcon } from '../../../icons/Emoji'; -import EmojiPicker, { EmojiClickData } from 'emoji-picker-react'; import { GifIcon } from '../../../icons/Gif'; -import GifPicker from 'gif-picker-react'; import { AttachmentIcon } from '../../../icons/Attachment'; import usePushSendMessage from '../../../hooks/chat/usePushSendMessage'; import { SendCompIcon } from '../../../icons/SendCompIcon'; @@ -25,21 +20,28 @@ import TokenGatedIcon from '../../../icons/Token-Gated.svg'; import { Modal } from '../reusables/Modal'; import { Image } from '../../reusables'; import { ConnectButtonComp } from '../ConnectButton'; -import useGetGroupByID from '../../../hooks/chat/useGetGroupByID'; import { checkIfIntent, getDefaultFeedObject, getNewChatUser, setAccessControl, - walletToPCAIP10, } from '../../../helpers'; import useFetchChat from '../../../hooks/chat/useFetchChat'; import useGetChatProfile from '../../../hooks/useGetChatProfile'; -import { IFeeds } from '@pushprotocol/restapi'; import useGetGroup from '../../../hooks/chat/useGetGroup'; import useApproveChatRequest from '../../../hooks/chat/useApproveChatRequest'; +import { + useChatData, + useClickAway, + useDeviceWidthCheck, + usePushChatSocket, +} from '../../../hooks'; + +import type { FileMessageContent } from '../../../types'; +import { GIFType, IChatTheme, MessageInputProps } from '../exportedTypes'; +import { PUBLIC_GOOGLE_TOKEN, device } from '../../../config'; +import { checkIfAccessVerifiedGroup, checkIfMember } from '../helpers'; import useToast from '../reusables/NewToast'; -import { MdCheckCircle, MdError } from 'react-icons/md'; /** * @interface IThemeProps @@ -49,13 +51,204 @@ interface IThemeProps { theme?: IChatTheme; } +export interface JoinVerificationGroupSectionProps { + isRules: boolean; + isMember: boolean; + onGetTokenClick?: () => void; + handleJoinGroup: () => void; + checkVerification: () => void; +} + +const JoinVerificationGroupSection: React.FC< + JoinVerificationGroupSectionProps +> = ({ isRules, isMember, onGetTokenClick, handleJoinGroup, checkVerification }) => { + const theme = useContext(ThemeContext); + const { loading: approveLoading } = useApproveChatRequest(); + const { + verificationSuccessfull, + setVerificationSuccessfull, + verified, + loading: accessLoading, + } = useVerifyAccessControl(); + const { pgpPrivateKey } = useChatData(); + + const isJoinGroup = () =>{ + return pgpPrivateKey && !isMember; + } + + const isNotVerified = () =>{ + return pgpPrivateKey && !verified && isMember && isRules; + } + return ( + <> + {isJoinGroup() || + isNotVerified() && ( +
+ + {isJoinGroup() && + 'Click on the button to join the group'} + {isNotVerified() && ( + <> + Sending messages requires{' '} + + 1 PUSH Token + {' '} + for participation.{' '} + + Learn More + + + )} + + + + isJoinGroup() + ? handleJoinGroup() + : checkVerification() + } + > + { isJoinGroup() && approveLoading ? ( + + ) : ( + ' Join Group ' + )} + {isNotVerified() && + (accessLoading ? ( + + ) : ( + 'Verify Access' + ))} + + +
+ )} + {pgpPrivateKey && !verificationSuccessfull && ( + +
+ + Verification Failed + + + Please ensure the following conditions are met to participate and + send messages. + +
+ token-gated +
+ {' '} + + Token Gated + + + You need to have{' '} + + 1 PUSH Token + {' '} + in your wallet to be able to send messages. + +
+
+
+ { + if (onGetTokenClick) { + onGetTokenClick(); + } + setVerificationSuccessfull(true); + }} + > + + Get Free Tokens + + + + { + setVerificationSuccessfull(true); + }} + > + Close + +
+
+
+ )} + + ); +}; +const ConnectButtonSection: React.FC = () => { + const { signer } = useChatData(); + return ( +
+ {!signer && ( + + You need to connect your wallet to get started + + )} + +
+ ); +}; + export const MessageInput: React.FC = ({ chatId, Emoji = true, GIF = true, File = true, isConnected, - onClick, + onGetTokenClick, }) => { const [typedMessage, setTypedMessage] = useState(''); const [showEmojis, setShowEmojis] = useState(false); @@ -77,7 +270,6 @@ export const MessageInput: React.FC = ({ const isMobile = useDeviceWidthCheck(425); const { sendMessage, loading } = usePushSendMessage(); const { - verificationSuccessfull, verifyAccessControl, setVerificationSuccessfull, verified, @@ -198,8 +390,10 @@ export const MessageInput: React.FC = ({ useEffect(() => { if (!account && !env && !chatId) return; - if (account && env && chatId && chatFeed && chatFeed?.groupInformation) - checkIfrules(); + if (account && env && chatId && chatFeed && chatFeed?.groupInformation) { + setIsMember(checkIfMember(chatFeed, account)); + setIsRules(checkIfAccessVerifiedGroup(chatFeed)); + } }, [chatId, chatFeed, account, env]); const addEmoji = (emojiData: EmojiClickData, event: MouseEvent): void => { @@ -334,34 +528,12 @@ export const MessageInput: React.FC = ({ } }; - //shift to helpers - const checkIfrules = async () => { - const members = chatFeed?.groupInformation?.members || []; - const pendingMembers = chatFeed?.groupInformation?.pendingMembers || []; - const allMembers = [...members, ...pendingMembers]; - allMembers.forEach((acc) => { - if ( - acc.wallet.toLowerCase() === walletToPCAIP10(account!).toLowerCase() - ) { - setIsMember(true); - } - }); - - if ( - chatFeed?.groupInformation?.rules && - (chatFeed?.groupInformation?.rules?.entry || - chatFeed?.groupInformation?.rules?.chat) - ) { - setIsRules(true); - } - }; - - //break into different components(connect button, join group and verification, typebar input) return !Object.keys(chatFeed || {}).length ? ( <> {!pgpPrivateKey && (isConnected || !!signer) && ( = ({ alignItems="center" justifyContent="space-between" > -
- {!signer && ( - - You need to connect your wallet to get started - - )} - -
+
)} ) : !checkIfIntent({ chat: chatFeed, account: account! }) && Object.keys(chatFeed || {}).length ? ( - - - {Object.keys(chatFeed || {}).length && chatFeed?.groupInformation ? ( + + {Object.keys(chatFeed || {}).length && chatFeed?.groupInformation ? ( + + ) : null} + {pgpPrivateKey && + (((isRules ? verified : true) && isMember) || + (chatFeed && !chatFeed?.groupInformation)) && ( <> - {pgpPrivateKey && !isMember && ( -
- + {Emoji && ( +
setShowEmojis(!showEmojis)} > - Click on the button to join the group - - - handleJoinGroup()}> - {approveLoading ? ( - - ) : ( - ' Join Group ' - )} - - -
- )} - {pgpPrivateKey && !verified && isMember && isRules && ( -
- + + )} + {showEmojis && ( +
- Sending messages requires{' '} - - 1 PUSH Token - {' '} - for participation.{' '} - - Learn More - - - - checkVerification()}> - {accessLoading ? ( - - ) : ( - 'Verify Access' - )} - - -
- )} - {pgpPrivateKey && !verificationSuccessfull && ( - + +
+ )} + { + if (event.key === 'Enter' && !event.shiftKey) { + event.preventDefault(); + sendTextMsg(); + } + }} + placeholder="Type your message..." + onChange={(e) => onChangeTypedMessage(e.target.value)} + value={typedMessage} + ref={textAreaRef} + rows={1} + /> +
+ + {GIF && (
setGifOpen(!gifOpen)} > - - Verification Failed - - - Please ensure the following conditions are met to - participate and send messages. - -
- token-gated -
- {' '} - {/* Added marginLeft */} - - Token Gated - - - You need to have{' '} - - 1 PUSH Token - {' '} - in your wallet to be able to send messages. - -
-
-
- { - if (onClick) { - onClick(); - } - setVerificationSuccessfull(true); - }} - > - - Get Free Tokens - - - - { - setVerificationSuccessfull(true); - }} - > - Close - -
+
- - )} - - ) : null} - {pgpPrivateKey && - (((isRules ? verified : true) && isMember) || - (chatFeed && !chatFeed?.groupInformation)) && ( - <> -
- {Emoji && ( -
setShowEmojis(!showEmojis)} - > - -
- )} - {showEmojis && ( -
- + +
+ )} +
+ {!fileUploading && File && ( + <> +
+ +
+ uploadFile(e)} /> -
+ )} - { - if (event.key === 'Enter' && !event.shiftKey) { - event.preventDefault(); - sendTextMsg(); - } - }} - placeholder="Type your message..." - onChange={(e) => onChangeTypedMessage(e.target.value)} - value={typedMessage} - ref={textAreaRef} - rows={1} - />
- - {GIF && ( -
setGifOpen(!gifOpen)} - > - -
- )} - {gifOpen && ( -
- -
- )} -
- {!fileUploading && File && ( - <> -
- -
- uploadFile(e)} - /> - - )} + {!(loading || fileUploading) && ( +
sendTextMsg()} + > +
- {!(loading || fileUploading) && ( -
sendTextMsg()} - > - -
- )} + )} - {(loading || fileUploading) && ( -
- -
- )} - - - )} - - + {(loading || fileUploading) && ( +
+ +
+ )} + + + )} + ) : ( <> ); }; -const Container = styled.div` - width: 100%; - overflow: hidden; - border: ${(props) => props.theme.border?.messageInput}; - border-radius: ${(props) => props.theme.borderRadius?.messageInput}; -`; -const TypebarSection = styled(Section)` +const TypebarSection = styled(Section)<{ border?: string }>` gap: 10px; + border: ${(props) => props.border || 'none'}; @media ${device.mobileL} { gap: 0px; } diff --git a/packages/uiweb/src/lib/components/chat/MessageInput/VerificationFailed.tsx b/packages/uiweb/src/lib/components/chat/MessageInput/VerificationFailed.tsx deleted file mode 100644 index 4bc874936..000000000 --- a/packages/uiweb/src/lib/components/chat/MessageInput/VerificationFailed.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import React, { useContext } from 'react' -import { Modal } from '../reusables/Modal' -import { Image, Section, Span } from '../../reusables' -import { ThemeContext } from '../theme/ThemeProvider'; -import TokenGatedIcon from "../../../icons/Token-Gated.svg" -import OpenLink from "../../../icons/OpenLink"; -import styled from 'styled-components'; -import useVerifyAccessControl from '../../../hooks/chat/useVerifyAccessControl'; - - -const VerificationFailed = () => { - const theme = useContext(ThemeContext); - const { setVerificationSuccessfull, verificationSuccessfull } = useVerifyAccessControl(); - return ( - -
- Verification Failed - Please ensure the following conditions are met to participate and send messages. -
- token-gated -
{/* Added marginLeft */} - Token Gated - You need to have 1 PUSH Token in your wallet to be able to send messages. -
-
-
- - - Get Tokens - - - - { - setVerificationSuccessfull(false) - console.log(verificationSuccessfull) - }}> - - Close - - -
-
-
- ) -} - -export default VerificationFailed - - -const ConnectWrapper = styled.div` - display: flex; - align-items: center; - flex-direction: column; - `; - -const ConnectWrapperClose = styled.div` - display: flex; - align-items: center; - flex-direction: column; -`; - - -const StyledButton = styled.button` - border: 0px; - outline: 0px; - padding: 22px 9px; - font-weight: 500; - border-radius: 12px; - font-size: 17px; - cursor: pointer; - width: 147px; - height: 44px; - text-align: start; - align-items: center; - display: flex; - justify-content: center; - `; - -const StyledButtonClose = styled.button` - border: 0px; - outline: 0px; - padding: 24px 9px; - font-weight: 500; - border-radius: 12px; - font-size: 17px; - cursor: pointer; - width: 147px; - height: 44px; - text-align: start; - align-items: center; - display: flex; - justify-content: center; -`; - - -const Connect = styled(StyledButton)` - color: #D53A94; - border: 2px solid #D53A94; - background: none; - gap: 8px; - `; - -const ConnectClose = styled(StyledButtonClose)` - color: rgb(255, 255, 255); - background: #D53A94; - gap: 8px; - `; diff --git a/packages/uiweb/src/lib/components/chat/exportedTypes.ts b/packages/uiweb/src/lib/components/chat/exportedTypes.ts index f4ac46dfa..e362528f7 100644 --- a/packages/uiweb/src/lib/components/chat/exportedTypes.ts +++ b/packages/uiweb/src/lib/components/chat/exportedTypes.ts @@ -19,7 +19,7 @@ export interface IChatViewComponentProps { gif?: boolean; file?: boolean; isConnected?: boolean; - onClick?: () => void; + onGetTokenClick?: () => void; } export interface IChatProfile { @@ -57,7 +57,7 @@ export interface MessageInputProps { File?: boolean; Image?: boolean; isConnected?: boolean; - onClick?: () => void; + onGetTokenClick?: () => void; } diff --git a/packages/uiweb/src/lib/components/chat/helpers/helper.ts b/packages/uiweb/src/lib/components/chat/helpers/helper.ts index 531e29cea..77899a9b0 100644 --- a/packages/uiweb/src/lib/components/chat/helpers/helper.ts +++ b/packages/uiweb/src/lib/components/chat/helpers/helper.ts @@ -2,6 +2,7 @@ import { IMessagePayload, User } from "../exportedTypes"; import { ethers } from "ethers"; import { IGroup } from "../../../types"; import { walletToPCAIP10 } from "../../../helpers"; +import { IFeeds } from "@pushprotocol/restapi"; export const profilePicture = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvklEQVR4AcXBsW2FMBiF0Y8r3GQb6jeBxRauYRpo4yGQkMd4A7kg7Z/GUfSKe8703fKDkTATZsJsrr0RlZSJ9r4RLayMvLmJjnQS1d6IhJkwE2bT13U/DBzp5BN73xgRZsJMmM1HOolqb/yWiWpvjJSUiRZWopIykTATZsJs5g+1N6KSMiO1N/5DmAkzYTa9Lh6MhJkwE2ZzSZlo7xvRwson3txERzqJhJkwE2bT6+JhoKTMJ2pvjAgzYSbMfgDlXixqjH6gRgAAAABJRU5ErkJggg==`; @@ -78,4 +79,31 @@ export function isValidETHAddress(address: string) { return ethers.utils.isAddress(address); } - \ No newline at end of file + export const checkIfMember = (chatFeed:IFeeds,account:string) => { + const members = chatFeed?.groupInformation?.members || []; + const pendingMembers = chatFeed?.groupInformation?.pendingMembers || []; + const allMembers = [...members, ...pendingMembers]; + let isMember = false; + allMembers.forEach((acc) => { + if ( + acc.wallet.toLowerCase() === walletToPCAIP10(account!).toLowerCase() + ) { + isMember = true; + } + }); + + + return isMember; + }; + + export const checkIfAccessVerifiedGroup = (chatFeed:IFeeds) => { + let isRules = false; + if ( + chatFeed?.groupInformation?.rules && + (chatFeed?.groupInformation?.rules?.entry || + chatFeed?.groupInformation?.rules?.chat) + ) { + isRules = true; + } + return isRules; + }; diff --git a/packages/uiweb/src/lib/components/chat/reusables/ChatSearchInput.tsx b/packages/uiweb/src/lib/components/chat/reusables/ChatSearchInput.tsx index 12d41764e..17d0b6355 100644 --- a/packages/uiweb/src/lib/components/chat/reusables/ChatSearchInput.tsx +++ b/packages/uiweb/src/lib/components/chat/reusables/ChatSearchInput.tsx @@ -60,6 +60,7 @@ export const ChatSearchInput: React.FC = ({ clearInput(); } }; + return ( { + const [{ wallet, connecting }, connect, disconnect, updateBalances, setWalletModules, setPrimaryWallet] = + useConnectWallet(); + + const [{ chains, connectedChain, settingChain }, setChain] = useSetChain(); + + const isActive = () => { + return wallet && wallet.accounts.length > 0 ? true : false; + }; + + const switchChain = async (desiredChain: number) => { + setChain({ chainId: ethers.utils.hexValue(desiredChain) }); + }; + + return { + wallet, + connecting, + connect, + disconnect, + updateBalances, + setWalletModules, + setPrimaryWallet, + provider: wallet ? new ethers.providers.Web3Provider(wallet.provider, 'any') : undefined, + account: wallet && wallet.accounts.length > 0 ? ethers.utils.getAddress(wallet.accounts[0].address) : undefined, + chainId: connectedChain ? Number(connectedChain.id) : undefined, + isActive, + setChain, + switchChain, + settingChain, + chains, + }; +}; \ No newline at end of file diff --git a/packages/uiweb/src/lib/hooks/index.ts b/packages/uiweb/src/lib/hooks/index.ts index 7b432b467..0da0a8f8c 100644 --- a/packages/uiweb/src/lib/hooks/index.ts +++ b/packages/uiweb/src/lib/hooks/index.ts @@ -8,4 +8,6 @@ export * from './chatAndNotification'; export * from './useDivOffsetWidth'; export * from './useDeviceWidthCheck'; export * from './useGetChatProfile'; -export * from './useMediaQuery'; \ No newline at end of file +export * from './useMediaQuery'; +export * from './useCreateChatProfile'; +export * from './useDecryptPGPKey'; \ No newline at end of file diff --git a/packages/uiweb/src/lib/hooks/useCreateChatProfile.ts b/packages/uiweb/src/lib/hooks/useCreateChatProfile.ts new file mode 100644 index 000000000..fea956c0e --- /dev/null +++ b/packages/uiweb/src/lib/hooks/useCreateChatProfile.ts @@ -0,0 +1,33 @@ +import * as PushAPI from '@pushprotocol/restapi'; +import { useCallback, useContext } from 'react'; +import { SignerType } from '@pushprotocol/restapi'; + +export interface CreateChatProfileParams { + signer: SignerType | undefined; + env:PushAPI.Env +} + +const useCreateChatProfile = () => { + const creteChatProfile = useCallback( + async ({ + signer, + env + }: CreateChatProfileParams): Promise => { + try { + const profile = await PushAPI.user.create({ + env: env, + signer: signer, + }); + return profile; + } catch (error) { + console.log(error); + return; + } + }, + [] + ); + + return { creteChatProfile }; +}; + +export default useCreateChatProfile; diff --git a/packages/uiweb/src/lib/hooks/useDecryptPGPKey.ts b/packages/uiweb/src/lib/hooks/useDecryptPGPKey.ts new file mode 100644 index 000000000..b5fe1ff37 --- /dev/null +++ b/packages/uiweb/src/lib/hooks/useDecryptPGPKey.ts @@ -0,0 +1,39 @@ +import * as PushAPI from '@pushprotocol/restapi'; +import { useCallback, useContext } from 'react'; +import { SignerType } from '@pushprotocol/restapi'; + +export interface DecryptPGPKeyParams { + account: string; + signer: SignerType | undefined; + encryptedPrivateKey: string; + env:PushAPI.Env +} + +const useDecryptPGPKey = () => { + const decryptPGPKey = useCallback( + async ({ + account, + encryptedPrivateKey, + signer, + env + }: DecryptPGPKeyParams): Promise => { + try { + const decryptPgpKey = await PushAPI.chat.decryptPGPKey({ + encryptedPGPPrivateKey: encryptedPrivateKey, + account: account!, + signer: signer, + env: env, + }); + return decryptPgpKey; + } catch (error) { + console.log(error); + return; + } + }, + [] + ); + + return { decryptPGPKey }; +}; + +export default useDecryptPGPKey;