From a15a570054f2251a7b4e258613f4f6408d556b75 Mon Sep 17 00:00:00 2001 From: Monalisha Mishra Date: Tue, 19 Sep 2023 19:58:37 +0530 Subject: [PATCH] fix: refactoring code of messageInput chatlist chatbubble --- .../src/app/ChatUITest/ChatViewComponent.tsx | 2 +- .../chat/ChatViewBubble/ChatViewBubble.tsx | 366 +++++------ .../ChatViewComponent/ChatViewComponent.tsx | 4 +- .../chat/ChatViewList/ChatViewList.tsx | 1 - .../chat/ConnectButton/ConnectButton.tsx | 45 +- .../components/chat/ConnectButton/index.tsx | 47 +- .../chat/MessageInput/MessageInput.tsx | 619 +++++++++--------- .../chat/MessageInput/VerificationFailed.tsx | 107 --- .../chat/ProfileHeader/AddWalletContent.tsx | 354 ---------- .../src/lib/components/chat/exportedTypes.ts | 4 +- .../chat/reusables/ChatSearchInput.tsx | 2 +- packages/uiweb/src/lib/config/constants.ts | 4 +- packages/uiweb/src/lib/hooks/index.ts | 4 +- .../src/lib/hooks/useCreateChatProfile.ts | 33 + .../uiweb/src/lib/hooks/useDecryptPGPKey.ts | 39 ++ 15 files changed, 625 insertions(+), 1006 deletions(-) delete mode 100644 packages/uiweb/src/lib/components/chat/MessageInput/VerificationFailed.tsx delete mode 100644 packages/uiweb/src/lib/components/chat/ProfileHeader/AddWalletContent.tsx create mode 100644 packages/uiweb/src/lib/hooks/useCreateChatProfile.ts create mode 100644 packages/uiweb/src/lib/hooks/useDecryptPGPKey.ts 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 5b26347a3..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='b8e068e02fe12d7136bc2f24408835573f30c6fbf0b65ea26ab4c7055a2c85f1' 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..cbfd7ee7e 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 && } -
+ {children} +
+ ); +}; + +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 +215,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 +264,21 @@ const ImageCard = ({ isGroup: boolean; }) => { return ( -
- {isGroup && } -
- {isGroup && } -
- -
+ +
+
-
+ ); }; @@ -281,32 +292,21 @@ const GIFCard = ({ isGroup: boolean; }) => { return ( -
- {isGroup && } -
- {isGroup && } -
- -
+ +
+
-
+ ); }; @@ -322,31 +322,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 +357,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) { diff --git a/packages/uiweb/src/lib/components/chat/ConnectButton/ConnectButton.tsx b/packages/uiweb/src/lib/components/chat/ConnectButton/ConnectButton.tsx index 3ec0c663f..c83175e42 100644 --- a/packages/uiweb/src/lib/components/chat/ConnectButton/ConnectButton.tsx +++ b/packages/uiweb/src/lib/components/chat/ConnectButton/ConnectButton.tsx @@ -1,13 +1,17 @@ -import styled from 'styled-components'; -import { IChatTheme } from '../theme'; -import { useAccount, useChatData } from '../../../hooks'; -import * as PushAPI from '@pushprotocol/restapi'; import { useContext, useEffect, useState } from 'react'; + +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 @@ -30,15 +34,17 @@ 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) - console.log(newAdd) setSigner(signer) setAccount(newAdd); })() @@ -48,12 +54,10 @@ export const ConnectButtonSub = () => { setPgpPrivateKey(null) } } -console.log(wallet) useEffect(() => { - newFunc() + setUserData() }, [wallet]) -console.log(account) useEffect(() => { (async () => { if (account && signer) { @@ -63,25 +67,22 @@ console.log(account) }, [account, signer]); - //move user creation to a hook 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) { @@ -103,8 +104,7 @@ 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; @@ -123,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 c0130adb9..e626a4465 100644 --- a/packages/uiweb/src/lib/components/chat/ConnectButton/index.tsx +++ b/packages/uiweb/src/lib/components/chat/ConnectButton/index.tsx @@ -1,30 +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) -//move to config -const chains = [ +const CHAINS = [ { id: '0x1', token: 'ETH', @@ -62,23 +55,23 @@ const chains = [ rpcUrl: 'https://rpc.ankr.com/arbitrum' } ] -const wallets = [injectedModule(), walletConnect] -//move to config -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 d5a219a3e..a9fd41ade 100644 --- a/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx +++ b/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx @@ -25,7 +25,6 @@ import { getDefaultFeedObject, getNewChatUser, setAccessControl, - walletToPCAIP10, } from '../../../helpers'; import useFetchChat from '../../../hooks/chat/useFetchChat'; import useGetChatProfile from '../../../hooks/useGetChatProfile'; @@ -33,7 +32,6 @@ import useGetGroup from '../../../hooks/chat/useGetGroup'; import useApproveChatRequest from '../../../hooks/chat/useApproveChatRequest'; import useToast from '../helpers/NewToast'; - import { useChatData, useClickAway, @@ -53,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); @@ -81,7 +270,6 @@ export const MessageInput: React.FC = ({ const isMobile = useDeviceWidthCheck(425); const { sendMessage, loading } = usePushSendMessage(); const { - verificationSuccessfull, verifyAccessControl, setVerificationSuccessfull, verified, @@ -202,11 +390,10 @@ export const MessageInput: React.FC = ({ useEffect(() => { if (!account && !env && !chatId) return; - if (account && env && chatId && chatFeed && chatFeed?.groupInformation) - { - setIsMember(checkIfMember(chatFeed,account)); + 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 => { @@ -340,12 +527,12 @@ export const MessageInput: React.FC = ({ } }; - //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 98f5c3dcc..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 '../helpers/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/ProfileHeader/AddWalletContent.tsx b/packages/uiweb/src/lib/components/chat/ProfileHeader/AddWalletContent.tsx deleted file mode 100644 index f370e5278..000000000 --- a/packages/uiweb/src/lib/components/chat/ProfileHeader/AddWalletContent.tsx +++ /dev/null @@ -1,354 +0,0 @@ -import { useContext, useEffect, useState } from "react"; -import styled from "styled-components"; -import { ThemeContext } from "../theme/ThemeProvider"; -import { useChatData } from "../../../hooks"; -import { displayDefaultUser, getAddress, walletToPCAIP10 } from "../../../helpers"; -import { IToast, ModalButtonProps, User } from "../exportedTypes"; -import * as PushAPI from '@pushprotocol/restapi'; -import { ethers } from "ethers"; -import { addWalletValidation } from "../helpers/helper"; -// import ArrowLeftIcon from '../../../icons/ArrowLeft.svg'; -import CloseIcon from '../../../icons/close.svg'; -import { Spinner } from "../../supportChat/spinner/Spinner"; -import { MoreLightIcon } from '../../../icons/MoreLight'; -import { MoreDarkIcon } from '../../../icons/MoreDark'; -import { SearchIcon } from '../../../icons/SearchIcon'; -import { Section, Span, Image } from "../../reusables/sharedStyling"; -import { AddUserDarkIcon } from '../../../icons/Adddark'; -import { device } from "../../../config"; -import { MemberListContainer } from "./MemberListContainer"; -import useMediaQuery from "../../../hooks/useMediaQuery"; - -export const AddWalletContent = ({ onSubmit, handlePrevious, onClose, memberList, handleMemberList, title, groupMembers, isLoading, setToastInfo }: { onSubmit: () => void, onClose: () => void, handlePrevious: () => void, memberList: any, handleMemberList: any, title: string, groupMembers: any, isLoading?: boolean, setToastInfo: React.Dispatch> }) => { - const theme = useContext(ThemeContext); - - const [searchedUser, setSearchedUser] = useState(''); - const [filteredUserData, setFilteredUserData] = useState(null); - const [isInValidAddress, setIsInvalidAddress] = useState(false); - const [isLoadingSearch, setIsLoadingSearch] = useState(false); - const { account, env } = useChatData(); - const isMobile = useMediaQuery(device.mobileL); - - - - useEffect(() => { - if (isInValidAddress) { - setToastInfo({ - message: 'Invalid Address', - status: 'error' - }) - } - }, [isInValidAddress]); - - const onChangeSearchBox = (e: any) => { - setSearchedUser(e.target.value); - }; - - const handleUserSearch = async (userSearchData: string): Promise => { - try { - const caip10 = walletToPCAIP10(userSearchData); - let filteredData: User; - - if (userSearchData.length) { - filteredData = await PushAPI.user.get({ - account: caip10, - env: env - }); - - if (filteredData !== null) { - setFilteredUserData(filteredData); - } - // User is not in the protocol. Create new user - else { - if (ethers.utils.isAddress(userSearchData)) { - const displayUser = displayDefaultUser({ caip10 }); - setFilteredUserData(displayUser); - } else { - setIsInvalidAddress(true); - setFilteredUserData(null); - } - } - } else { - setFilteredUserData(null); - } - setIsLoadingSearch(false); - } - catch (error) { - setToastInfo({ - message: 'Unsuccessful search, Try again', - status: 'error' - }) - } - }; - - const handleSearch = async (e: any): Promise => { - setIsLoadingSearch(true); - setIsInvalidAddress(false); - e.preventDefault(); - if (!ethers.utils.isAddress(searchedUser)) { - let address: string; - try { - address = await getAddress(searchedUser, env) as string; - // if (!address) { - // address = await library.resolveName(searchedUser); - // } - // this ensures address are checksummed - address = ethers.utils.getAddress(address?.toLowerCase()); - if (address) { - handleUserSearch(address); - } else { - setIsInvalidAddress(true); - setFilteredUserData(null); - } - } catch (err) { - setIsInvalidAddress(true); - setFilteredUserData(null); - } finally { - setIsLoadingSearch(false); - } - } else { - handleUserSearch(searchedUser); - } - }; - - const clearInput = () => { - setSearchedUser(''); - setFilteredUserData(null); - setIsLoadingSearch(false); - }; - - const addMemberToList = (member: User) => { - let errorMessage = ''; - - errorMessage = addWalletValidation(member, memberList, groupMembers, account); - - if (errorMessage) { - setToastInfo({ - message: `Error`, - status: 'error' - }) - } else { - handleMemberList((prev: any) => [...prev, { ...member, isAdmin: false }]); - } - - setFilteredUserData(''); - clearInput(); - }; - - const removeMemberFromList = (member: User) => { - const filteredMembers = memberList?.filter((user: any) => user.wallets !== member.wallets); - handleMemberList(filteredMembers); - }; - - return ( -
-
- - {/* handlePrevious()} cursor='pointer' /> */} - - Add Wallets - - onClose()} cursor='pointer' /> -
- -
- Add Wallets - - - {groupMembers - ? `0${memberList?.length + groupMembers?.length} / 09 Members` - : `0${memberList?.length} / 09 Members`} - -
- -
- - -
- {searchedUser.length > 0 && ( - clearInput()} cursor='pointer' /> - )} - {searchedUser.length == 0 && !filteredUserData && -
- -
- } -
-
-
- - {filteredUserData ? ( - - } - darkIcon={} - /> - - ) : isLoadingSearch ? ( -
- -
- ) : null} - - - {memberList?.map((member: any, index: any) => ( - } - darkIcon={} - /> - ))} - - -
- onSubmit()} - isLoading={isLoading} - // loaderTitle={groupMembers ? 'Adding Members' : 'Creating group'} - memberListCount={memberList?.length > 0} - theme={theme} - > - {groupMembers ? 'Add To Group' : 'Create Group'} - {isLoading && } - -
- -
- ) -} - -const SearchBarContent = styled.form` - position: relative; - display: flex; - flex: 1; -`; - -const Input = styled.input` - box-sizing: border-box; - display: flex; - flex: 1; -// min-width: 445px; - height: 48px; - padding: 0px 50px 0px 16px; - margin: 10px 0px 0px; - border-radius: 99px; - border: 1px solid; - border-color: ${(props) => props.theme.modalSearchBarBorderColor}; - background: ${(props) => props.theme.modalSearchBarBackground}; - color: ${(props) => props.color || '#000'}; - &:focus { - outline: none; - background-image: linear-gradient( - ${(props) => props.theme.snapFocusBg}, - ${(props) => props.theme.snapFocusBg} - ), - linear-gradient( - to right, - rgba(182, 160, 245, 1), - rgba(244, 110, 246, 1), - rgba(255, 222, 211, 1), - rgba(255, 207, 197, 1) - ); - background-origin: border; - border: 1px solid transparent !important; - background-clip: padding-box, border-box; - } - &::placeholder { - color: #657795; - } - @media ${device.mobileL} { - min-width: 100%; - } -`; - -const MemberList = styled.div` - // justify-content: flex-start; - // padding: 0px 2px; - // margin: 0 0 34px 0; - flex: 1; - // background: red; - width: 100%; -`; - -const MultipleMemberList = styled.div` - overflow-y: auto; - height: fit-content; - max-height: 216px; - padding: 0px 2px; - overflow-x: hidden; - width: 100%; - - &::-webkit-scrollbar-track { - background-color: ${(props) => props.theme.scrollBg}; - } - - &::-webkit-scrollbar { - background-color: ${(props) => props.theme.scrollBg}; - width: 6px; - } - - @media (max-width: 768px) { - padding: 0px 0px 0px 0px; - max-height: 35vh; - - &::-webkit-scrollbar-track { - background-color: none; - border-radius: 9px; - } - - &::-webkit-scrollbar { - background-color: none; - width: 4px; - } - } - - &::-webkit-scrollbar-thumb { - border-radius: 10px; - background-image: -webkit-gradient( - linear, - left top, - left bottom, - color-stop(0.44, #cf1c84), - color-stop(0.72, #cf1c84), - color-stop(0.86, #cf1c84) - ); - } -`; - -const ModalConfirmButton = styled.button` - margin: 60px 0 0 0; - background: ${(props) => props.memberListCount ? '#CF1C84' : props.theme.groupButtonBackgroundColor}; - color: ${(props) => props.memberListCount ? '#fff' : props.theme.groupButtonTextColor}; - border: ${(props) => props.memberListCount ? 'none' : props.theme.modalConfirmButtonBorder}; - min-width: 50%; - box-sizing: border-box; - cursor: pointer; - border-radius: 15px; - padding: 16px; - font-size: 1.125rem; - font-weight: 500; - display: flex; - align-items: center; - justify-content: ${(props) => props.isLoading ? 'space-between' : 'center'}; - box-shadow: none; -`; \ No newline at end of file diff --git a/packages/uiweb/src/lib/components/chat/exportedTypes.ts b/packages/uiweb/src/lib/components/chat/exportedTypes.ts index b42fc9590..aa15dfda0 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 { @@ -66,7 +66,7 @@ export interface MessageInputProps { File?: boolean; Image?: boolean; isConnected?: boolean; - onClick?: () => void; + onGetTokenClick?: () => void; } export type UpdateGroupType = { diff --git a/packages/uiweb/src/lib/components/chat/reusables/ChatSearchInput.tsx b/packages/uiweb/src/lib/components/chat/reusables/ChatSearchInput.tsx index 1590bfaab..57d237a82 100644 --- a/packages/uiweb/src/lib/components/chat/reusables/ChatSearchInput.tsx +++ b/packages/uiweb/src/lib/components/chat/reusables/ChatSearchInput.tsx @@ -51,7 +51,7 @@ export const ChatSearchInput: React.FC = ({ clearInput(); } }; -console.log(theme.border?.searchInput) + return ( { + 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;