From fdd9bc9f3799b6404153ed0eb79bf0de212d8ede Mon Sep 17 00:00:00 2001 From: abhishek-01k Date: Fri, 9 Feb 2024 13:52:01 +0530 Subject: [PATCH 1/5] Module height is fixed --- src/App.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 8281a1d3b7..f5997f987a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -370,8 +370,8 @@ const LeftBarContainer = styled.div` top: 0; bottom: 0; width: ${(props) => props.leftBarWidth}px; - // position: fixed; - position: absolute; + position: fixed; + // position: absolute; @media (max-width: 992px) { display: none; From f57813ee4ba91d28e9fe7cba76e7961c1ae5ae26 Mon Sep 17 00:00:00 2001 From: Abhishek <77395788+abhishek-01k@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:27:39 +0530 Subject: [PATCH 2/5] Phase 3 of Guest Mode (#1423) * Phase 3 of Guest Mode * Updated read mode feature * Chat is fixed for Guest Mode and sort imports is fixed * Fixed the infinte render issue * Fixed the Opt-in/opt-out and other flow for guest mode --- src/App.tsx | 148 ++++++++++++----------- src/components/Dropdown.tsx | 3 +- src/components/NavigationButton.js | 2 +- src/components/ProfileModal.tsx | 1 - src/config/NavigationList.js | 4 +- src/connectors/web3Onboard.tsx | 2 +- src/contexts/AppContext.tsx | 74 +++++------- src/contexts/GlobalContext.tsx | 4 +- src/hooks/useAccount.tsx | 11 +- src/modules/chat/ChatModule.tsx | 6 +- src/primaries/Profile.tsx | 133 +++++++++++--------- src/sections/chat/ChatSidebarSection.tsx | 22 +++- src/structure/Header.tsx | 17 +-- src/structure/MasterInterfacePage.tsx | 6 +- src/types/context.ts | 1 + 15 files changed, 233 insertions(+), 201 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 6e6201d39f..1c4c4a089c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -101,6 +101,7 @@ const extendConsole = () => { extendConsole(); // Disable consolve + if (appConfig?.appEnv === "prod") { console.enable("debug", false); console.enable("log", false); @@ -259,78 +260,81 @@ export default function App() { return ( - {(!isActive || !allowedChain) && ( - - - - )} - - - {isActive && !authError && allowedChain && ( - <> - - - - - - - - -
- - - - {!isSnapPage && - - - - } - - - {/* Shared among all pages, load universal things here */} - - - - - - - - - - - )} + {/* {(!isActive || !allowedChain) && ( + + + + )} */} + + <> + + + + + + + + +
+ + + + {!isSnapPage && + + + + } + + + {/* Shared among all pages, load universal things here */} + + + + + + + + + + + + + + + + ); } diff --git a/src/components/Dropdown.tsx b/src/components/Dropdown.tsx index c9716072d4..2b17d78a78 100644 --- a/src/components/Dropdown.tsx +++ b/src/components/Dropdown.tsx @@ -75,11 +75,10 @@ function Dropdown({ dropdownValues, textColor, iconFilter, hoverBGColor }: Dropd spacing="1px" width="max-content" > - {dropdownValue?.title} {mode} + {dropdownValue?.title} {shortenText(dropdownValue?.title,3)} - {mode} {dropdownValue?.invertedIcon && ( diff --git a/src/components/NavigationButton.js b/src/components/NavigationButton.js index 7398df4d76..af2d7a0855 100644 --- a/src/components/NavigationButton.js +++ b/src/components/NavigationButton.js @@ -92,7 +92,7 @@ function NavigationButton({ item, data, sectionID, active, bg = 'none' }) { margin={definedMargin} bg={bg} active={active ? 1 : 0} - onClick={disallowNavigation && handleDisallowedNav} + // onClick={disallowNavigation && handleDisallowedNav} className={data?.name?.toLowerCase()} > {data.iconFactory ? ( diff --git a/src/components/ProfileModal.tsx b/src/components/ProfileModal.tsx index 13c96c2f12..9476b402c7 100644 --- a/src/components/ProfileModal.tsx +++ b/src/components/ProfileModal.tsx @@ -45,7 +45,6 @@ const ProfileModal = ({ showDropdown, setShowDropdown, dropdownValues })=>{ > {shortenText(dropdownValue?.title,3)} - {mode} {dropdownValue?.invertedIcon && (null); const AppContextProvider = ({ children }) => { const { connect, provider, account, wallet, connecting } = useAccount(); const web3onboardToast = useToast(); - const { setReadOnlyWallet, readOnlyWallet, setMode } = useContext(GlobalContext); const [web3NameList, setWeb3NameList] = useState({}); const [snapInstalled, setSnapInstalled] = useState(false); @@ -56,7 +55,7 @@ const AppContextProvider = ({ children }) => { const dispatch = useDispatch(); - const handleConnectWallet = (showToast = false, toastMessage?: string) => { + const handleConnectWallet = async (showToast = false, toastMessage?: string) => { if (showToast) { web3onboardToast.showMessageToast({ toastMessage: toastMessage || "Please connect your wallet to continue", @@ -66,42 +65,33 @@ const AppContextProvider = ({ children }) => { }); } - const onboardModal = document.getElementById("onboard-container"); - onboardModal.style.display = 'block'; - // Open the onboard modal - connect(); - - // Create a resize observer to detect when the onboard modal is rendered - const observer = new ResizeObserver(() => { - const sectionElement = document.querySelector('onboard-v2')?.shadowRoot?.querySelector('.svelte-baitaa'); - const divElement = sectionElement?.querySelector('div'); - if (divElement) { - // Disconnect the observer once the divElement is found - observer.unobserve(onboardModal); - observer.disconnect(); - - // Apply custom styles - divElement.style.position = 'fixed'; - divElement.style.top = '0px'; - divElement.style.right = '0px'; - divElement.style.height = '100vh'; - divElement.style.left = '0px'; - divElement.style.backgroundColor = 'rgba(0, 0, 0, 0.2)'; - divElement.style.backdropFilter = 'blur(5px)'; - } - }); - // Start observing the DOM for changes - observer.observe(onboardModal); + if (wallet?.accounts?.length > 0) { + await initializePushSDK(); + } else { + connect(); + } + } const initialisePushSdkGuestMode = async () => { + console.log("Initialising Push SDK Guest Mode"); + let userInstance; + userInstance = await PushAPI.initialize({ + account: '0x0000000000000000000000000000000000000000', + env: appConfig.appEnv, + }); + dispatch(setUserPushSDKInstance(userInstance)); + } + + const initialisePushSdkReadMode = async () => { + console.log("Initialising Push SDK Read Mode"); let userInstance; userInstance = await PushAPI.initialize({ - account: readOnlyWallet, env: appConfig.appEnv, + account: account, }); dispatch(setUserPushSDKInstance(userInstance)); } @@ -115,7 +105,7 @@ const AppContextProvider = ({ children }) => { hookInfo: progressHook, spinnerType: LOADER_SPINNER_TYPE.PROCESSING, progress: 0, - errorMessage:'' + errorMessage: '' }; if (progressHook) { @@ -184,17 +174,17 @@ const AppContextProvider = ({ children }) => { onboardingProgress.progress = 99; break; case "PUSH-ERROR-00": - onboardingProgress.errorMessage="User Rejected Signature"; + onboardingProgress.errorMessage = "User Rejected Signature"; onboardingProgress.hookInfo.progressTitle = "User Rejected Signature"; onboardingProgress.spinnerType = LOADER_SPINNER_TYPE.ERROR; break; case "PUSH-ERROR-01": - onboardingProgress.errorMessage="Upgrade Failed"; + onboardingProgress.errorMessage = "Upgrade Failed"; onboardingProgress.hookInfo.progressTitle = "Upgrade Failed"; onboardingProgress.spinnerType = LOADER_SPINNER_TYPE.ERROR; break; case "PUSH-ERROR-02": - onboardingProgress.errorMessage="Decrypting Keys Failed"; + onboardingProgress.errorMessage = "Decrypting Keys Failed"; onboardingProgress.hookInfo.progressTitle = "Decrypting Keys Failed"; onboardingProgress.spinnerType = LOADER_SPINNER_TYPE.ERROR; break; @@ -211,18 +201,17 @@ const AppContextProvider = ({ children }) => { progressEnabled: onboardingProgress.progress ? true : false, progress: onboardingProgress.progress, progressNotice: onboardingProgress.hookInfo.progressInfo, - errorMessage:onboardingProgress.errorMessage, + errorMessage: onboardingProgress.errorMessage, }); }; const initializePushSDK = async () => { - console.log("Initialising Push Sdk"); let userInstance; try { const librarySigner = provider?.getSigner(account); - userInstance = await PushAPI.initialize(librarySigner, { - env: appConfig.appEnv, // defaults to staging + userInstance = await PushAPI.initialize(librarySigner!, { + env: appConfig.appEnv, account: account, progressHook: onboardingProgressReformatter, }); @@ -245,10 +234,8 @@ const AppContextProvider = ({ children }) => { }; const getUser = async () => { - console.debug("getUser"); const caip10: string = w2wHelper.walletToCAIP10({ account }); const user = await userPushSDKInstance.info(); - console.log("User push sdk instance", userPushSDKInstance, user); let connectedUser: ConnectedUser; // TODO: Change this to do verification on ceramic to validate if did is valid @@ -291,9 +278,9 @@ const AppContextProvider = ({ children }) => { useEffect(() => { const librarySigner = provider?.getSigner(account); - if (!account || !appConfig?.appEnv) return; + // if (!account || !appConfig?.appEnv) return; if (wallet?.accounts?.length > 0) { - initializePushSDK(); + initialisePushSdkReadMode(); } else { initialisePushSdkGuestMode(); } @@ -355,7 +342,8 @@ const AppContextProvider = ({ children }) => { setConnectedPeerID, displayQR, setDisplayQR, - createUserIfNecessary + createUserIfNecessary, + initialisePushSdkReadMode }}> {children} diff --git a/src/contexts/GlobalContext.tsx b/src/contexts/GlobalContext.tsx index af8e610705..02c8528ffa 100644 --- a/src/contexts/GlobalContext.tsx +++ b/src/contexts/GlobalContext.tsx @@ -17,8 +17,8 @@ export type GlobalContextType = { export const GlobalContext = createContext(null); const GlobalContextProvider = ({ children }) => { - const [readOnlyWallet, setReadOnlyWallet] = useState(); - const [mode, setMode] = useState(); + const [readOnlyWallet, setReadOnlyWallet] = useState('0x0000000000000000000000000000000000000000'); + const [mode, setMode] = useState(ReadOnlyWalletMode.GUEST_MODE); const [sidebarCollapsed, setSidebarCollapsed] = useState(false); return ( diff --git a/src/hooks/useAccount.tsx b/src/hooks/useAccount.tsx index 614199a7e2..d263c6e13d 100644 --- a/src/hooks/useAccount.tsx +++ b/src/hooks/useAccount.tsx @@ -1,6 +1,6 @@ import { useConnectWallet, useSetChain } from '@web3-onboard/react'; import { appConfig } from 'config'; -import { GlobalContext } from 'contexts/GlobalContext'; +import { GlobalContext, ReadOnlyWalletMode } from 'contexts/GlobalContext'; import { ethers } from 'ethers'; import { useContext, useMemo } from 'react'; @@ -32,17 +32,16 @@ export const useAccount = () => { const account = useMemo(() => { if(wallet && wallet.accounts.length > 0) { - setReadOnlyWallet(undefined); - setMode(undefined); return ethers.utils.getAddress(wallet.accounts[0].address); + }else{ + return readOnlyWallet; } - return readOnlyWallet; }, [wallet, readOnlyWallet]); const chainId = useMemo(() => { if(connectedChain) return Number(connectedChain.id); if(readOnlyWallet) return appConfig.coreContractChain; - return undefined; + return appConfig.coreContractChain; }, [connectedChain, readOnlyWallet]); return { @@ -54,7 +53,7 @@ export const useAccount = () => { setWalletModules, setPrimaryWallet, provider, - account : account ? account : readOnlyWallet, + account : account, chainId, isActive, setChain, diff --git a/src/modules/chat/ChatModule.tsx b/src/modules/chat/ChatModule.tsx index 867b9c3c6c..045b89bd85 100644 --- a/src/modules/chat/ChatModule.tsx +++ b/src/modules/chat/ChatModule.tsx @@ -44,6 +44,7 @@ import { checkIfIntent, getUpdatedChatAndIntent, getUpdatedGroupInfo } from 'hel import { ChatUIProvider, darkChatTheme } from '@pushprotocol/uiweb'; import { appConfig } from 'config'; import GLOBALS, { device, globalsMargin } from 'config/Globals'; +import { GlobalContext } from 'contexts/GlobalContext'; export const ToastPosition: ToastOptions = { position: 'top-right', @@ -59,7 +60,7 @@ export const Context = React.createContext(null); // Create Header function Chat({ chatid }) { - const { account, chainId, provider } = useAccount(); + const { account, chainId, provider,wallet } = useAccount(); const { videoCallData } = useContext(VideoCallContext); const { @@ -93,6 +94,7 @@ function Chat({ chatid }) { const [userShouldBeSearched, setUserShouldBeSearched] = useState(false); const [filteredUserData, setFilteredUserData] = useState([]); const [signerData, setSignerData] = useState(); + const { readOnlyWallet } = React.useContext(GlobalContext); const isMobile = useDeviceWidthCheck(600); const queryClient = new QueryClient({}); @@ -393,7 +395,7 @@ function Chat({ chatid }) { theme={theme.scheme === 'dark' && darkChatTheme} // signer={signerData} env={appConfig?.appEnv} - account={account} + account={wallet?.accounts?.length > 0 ? account: readOnlyWallet} pgpPrivateKey={pgpPvtKey} user={userPushSDKInstance} > diff --git a/src/primaries/Profile.tsx b/src/primaries/Profile.tsx index 91394683b8..a33eff33d2 100644 --- a/src/primaries/Profile.tsx +++ b/src/primaries/Profile.tsx @@ -25,13 +25,13 @@ import { SpanV2 } from 'components/reusables/SharedStylingV2.js'; // Create Header const Profile = ({ isDarkMode }) => { - const { web3NameList }: AppContextType = useContext(AppContext); - const { setReadOnlyWallet, readOnlyWallet, mode,setMode }: GlobalContextType = useContext(GlobalContext); + const { web3NameList,initialisePushSdkReadMode,handleConnectWallet }: AppContextType = useContext(AppContext); + const { setReadOnlyWallet, readOnlyWallet, mode, setMode }: GlobalContextType = useContext(GlobalContext); const { authError } = useContext(ErrorContext); const toggleArrowRef = useRef(null); const dropdownRef = useRef(null); const modalRef = React.useRef(null); - const { account, disconnect, wallet } = useAccount(); + const { account, disconnect, wallet, connect } = useAccount(); const { userPushSDKInstance } = useSelector((state: any) => { return state.user; @@ -74,11 +74,9 @@ const Profile = ({ isDarkMode }) => { id: 'disconnect', value: '', function: async () => { - if (readOnlyWallet) { - setReadOnlyWallet(); - } else { - await disconnect(wallet); - } + await disconnect(wallet); + setMode(ReadOnlyWalletMode.GUEST_MODE); + setReadOnlyWallet('0x0000000000000000000000000000000000000000'); }, title: 'Logout', invertedIcon: './logout.svg', @@ -89,61 +87,86 @@ const Profile = ({ isDarkMode }) => { setShowDropdown(false); }); + // to create blockies return ( <> - {account && account !== '' && !authError && ( + + {account && account != '' && !authError ? ( - setShowDropdown(!showDropdown)} - ref={toggleArrowRef} - > - {web3Name === null ? ( - - ) : web3Name ? ( - <>{web3Name} - ) : ( - <>{shortenText(account, 5)} - )} - {mode ? mode : userPushSDKInstance?.readMode && ReadOnlyWalletMode.READ_ONLY_MODE } - - arrow - - - {showDropdown && ( - 0) ? ( + handleConnectWallet()} > - + ) : ( + <> + setShowDropdown(!showDropdown)} + ref={toggleArrowRef} > - - - - - - + {web3Name === null ? ( + + ) : web3Name ? ( + <>{web3Name} + ) : ( + <>{shortenText(account, 5)} + )} + {!(wallet?.accounts?.length > 0) ? ReadOnlyWalletMode.GUEST_MODE : userPushSDKInstance?.readMode && ReadOnlyWalletMode.READ_ONLY_MODE} + + arrow + + + {showDropdown && ( + + + + + + + + + )} + )} + ) : ( + handleConnectWallet()} + > + Connect Wallet + )} ); diff --git a/src/sections/chat/ChatSidebarSection.tsx b/src/sections/chat/ChatSidebarSection.tsx index d7c9f549fb..7d0ba3863d 100644 --- a/src/sections/chat/ChatSidebarSection.tsx +++ b/src/sections/chat/ChatSidebarSection.tsx @@ -29,6 +29,8 @@ import NewTag from 'components/NewTag'; // Internal Configs import GLOBALS from 'config/Globals'; import { appConfig } from '../../config'; +import { useAccount } from 'hooks'; +import { GlobalContext } from 'contexts/GlobalContext'; const createGroupOnMouseEnter = [ @@ -66,10 +68,11 @@ const ChatSidebarSection = ({ showCreateGroupModal, autofilledSearch }) => { const theme = useTheme(); const { setSelectedChatId } = useContext(Context); + const { setMode } = useContext(GlobalContext); const isNewTagVisible = getIsNewTagVisible(new Date('2023-02-22T00:00:00.000'), 90); - const { connectedUser, displayQR, setDisplayQR, initializePushSDK } = useContext(AppContext); + const { connectedUser, displayQR, setDisplayQR, initializePushSDK, handleConnectWallet } = useContext(AppContext); const [searchedUser, setSearchedUser] = useState(''); const { activeTab, setActiveTab } = useContext(Context); @@ -100,8 +103,12 @@ const ChatSidebarSection = ({ showCreateGroupModal, autofilledSearch }) => { } return formattedChatParticipant; } else { - await initializePushSDK(); - return null; + if (userPushSDKInstance.account === '0x0000000000000000000000000000000000000000') { + handleConnectWallet(); + } else if (userPushSDKInstance.signer === undefined || userPushSDKInstance.decryptedPgpPvtKey === undefined) { + await initializePushSDK(); + return null; + } } } @@ -109,7 +116,14 @@ const ChatSidebarSection = ({ showCreateGroupModal, autofilledSearch }) => { if (userPushSDKInstance.decryptedPgpPvtKey) { showCreateGroupModal(); } else { - await initializePushSDK(); + if (userPushSDKInstance.account === '0x0000000000000000000000000000000000000000') { + handleConnectWallet(); + } else { + if (userPushSDKInstance.signer === undefined) { + await initializePushSDK(); + return null; + } + } } } diff --git a/src/structure/Header.tsx b/src/structure/Header.tsx index 4583e6fb7e..77aadd6e40 100644 --- a/src/structure/Header.tsx +++ b/src/structure/Header.tsx @@ -25,6 +25,7 @@ import Profile from 'primaries/Profile'; import { Button, Item, ItemH, Section, Span } from 'primaries/SharedStyling'; import { ReactComponent as EPNSLogoDark } from './assets/epnsDark.svg'; import { ReactComponent as EPNSLogoLight } from './assets/epnsLight.svg'; +import { GlobalContext, ReadOnlyWalletMode } from 'contexts/GlobalContext'; // Internal Configs import ChainIndicator from 'components/ChainIndicator'; @@ -71,7 +72,8 @@ function Header({ isDarkMode, darkModeToggle }) { const navRef = useRef() const { navigationSetup } = useContext(NavigationContext); - const { setSnapInstalled, snapInstalled } = React.useContext(AppContext); + const { setSnapInstalled, snapInstalled } = React.useContext(AppContext); + const { mode } = React.useContext(GlobalContext); const { isActive, switchChain, connect, wallet } = useAccount(); const { authError: error } = useContext(ErrorContext); @@ -205,7 +207,7 @@ function Header({ isDarkMode, darkModeToggle }) { - {headerTag && isActive && !error && !isSnapPage && ( + {headerTag && !error && !isSnapPage && ( )} - }> + }> {!showSnapMobile && !snapInstalled && } - + {isActive && !showLoginControls && !error && ( - {!!error && {getErrorMessage(error)}} + {/* {!!error && {getErrorMessage(error)}} */} {/* {!isActive && !error && Please connect to a Web3 Network} */} - {!!error && Please connect to a Web3 Network} + {/* {!!error && Please connect to a Web3 Network} */} {/* {isActive && !showLoginControls && !error && ( @@ -261,7 +263,8 @@ function Header({ isDarkMode, darkModeToggle }) { )}{' '} */} - + {/* //TODO: The chain Indicator should be removed in guest mode */} + {wallet?.accounts?.length > 0 && } diff --git a/src/structure/MasterInterfacePage.tsx b/src/structure/MasterInterfacePage.tsx index 126f3a7f7d..8e62dbdf32 100644 --- a/src/structure/MasterInterfacePage.tsx +++ b/src/structure/MasterInterfacePage.tsx @@ -4,7 +4,7 @@ import React, { lazy, Suspense } from 'react'; // External Packages import { VscClose } from 'react-icons/vsc'; import { Navigate, Route, Routes, useLocation } from 'react-router-dom'; -import { ToastContainer, toast } from 'react-toastify'; +import { ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.min.css'; import styled from 'styled-components'; import { MdError } from 'react-icons/md'; @@ -104,13 +104,13 @@ function MasterInterfacePage() { } /> } /> - }> + {/* }> */} } /> } /> } /> } /> {/* } /> */} - + {/* */} void; createUserIfNecessary: () => Promise; + initialisePushSdkReadMode:()=>Promise; } From abe0c55a03f11c9d0e876f358a2f6e40db3d2d7a Mon Sep 17 00:00:00 2001 From: Priti Date: Wed, 6 Mar 2024 15:06:30 +0530 Subject: [PATCH 3/5] Resolved chat z-index issues (#1430) --- src/App.tsx | 2 +- src/components/chat/w2wChat/searchBar/SearchBar.tsx | 2 ++ src/sections/chat/ChatSidebarSection.tsx | 6 +++++- src/structure/Navigation.tsx | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 3b99f54c26..0b75a72a91 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -347,7 +347,7 @@ const HeaderContainer = styled.header` width: 100%; position: fixed; top: 0; - z-index: 99999; + z-index: 999; `; const ParentContainer = styled.div` diff --git a/src/components/chat/w2wChat/searchBar/SearchBar.tsx b/src/components/chat/w2wChat/searchBar/SearchBar.tsx index 9adf5ec57a..ce82a177b0 100644 --- a/src/components/chat/w2wChat/searchBar/SearchBar.tsx +++ b/src/components/chat/w2wChat/searchBar/SearchBar.tsx @@ -173,6 +173,7 @@ const SearchBar = ({ autofilled, searchedUser, setSearchedUser }) => { height="48px" top="10px" right="0px" + zIndex="1" > { borderRadius="50%" onClick={() => setActiveTab(3)} > + diff --git a/src/sections/chat/ChatSidebarSection.tsx b/src/sections/chat/ChatSidebarSection.tsx index 7d0ba3863d..ef8095725d 100644 --- a/src/sections/chat/ChatSidebarSection.tsx +++ b/src/sections/chat/ChatSidebarSection.tsx @@ -149,6 +149,7 @@ const ChatSidebarSection = ({ showCreateGroupModal, autofilledSearch }) => { hoverBackground="transparent" color={theme.default.color} flex="1" + zIndex="1" padding="10px 10px 20px 10px" onClick={() => { setActiveTab(0); @@ -168,6 +169,7 @@ const ChatSidebarSection = ({ showCreateGroupModal, autofilledSearch }) => { background="transparent" hoverBackground="transparent" color={theme.default.color} + zIndex="1" flex="1" padding="10px 10px 20px 10px" onClick={() => { @@ -228,6 +230,7 @@ const ChatSidebarSection = ({ showCreateGroupModal, autofilledSearch }) => { autofilled={undefined} searchedUser={searchedUser} setSearchedUser={setSearchedUser} + /> )} {activeTab == 0 && ( @@ -235,6 +238,7 @@ const ChatSidebarSection = ({ showCreateGroupModal, autofilledSearch }) => { // justifyContent="flex-start" flex="none" padding="20px 10px 24px 10px" + zIndex="1" borderRadius={GLOBALS.ADJUSTMENTS.RADIUS.MID} onClick={handleCreateGroup} background="transparent" @@ -351,7 +355,7 @@ const ChatSidebarSection = ({ showCreateGroupModal, autofilledSearch }) => { ) : null} - + {/* Date: Wed, 6 Mar 2024 17:23:45 +0530 Subject: [PATCH 4/5] Resolved Issues in Guest Mode and Read Mode (#1429) * Fixed issues in the Opt In flow * Removed consoles and fixed the send Notification case * Issues Fixed for diff Channel Features like edit channel or add delegate * Removed consoles * Toast has been added for warning when the user rejects * New Opt In flow when the user directly clicks on Opt In * User Opt In Flow with legacy APIs in guest mode and read mode --- package.json | 4 +- src/AppLogin.tsx | 2 +- src/components/ChannelDetails.js | 25 +- src/components/ChannelSettingsDropdown.tsx | 8 +- src/components/Dropdown.tsx | 14 +- src/components/SendNotifications.tsx | 11 +- src/components/ViewChannelItem.js | 1 + .../channel/NotificationSettings.tsx | 49 +- .../dropdowns/ManageNotifSettingDropdown.tsx | 160 ++++-- .../dropdowns/OptinNotifSettingDropdown.tsx | 153 ++++-- .../dropdowns/UpdateNotifSettingDropdown.tsx | 18 +- src/config/Themization.js | 4 + src/contexts/AppContext.tsx | 62 ++- src/contexts/GlobalContext.tsx | 2 +- src/hooks/useToast.tsx | 21 +- .../ChannelOwnerDashboard.tsx | 8 +- src/primaries/Profile.tsx | 14 +- src/sections/chat/ChatSidebarSection.tsx | 5 +- src/segments/Feedbox.tsx | 13 +- src/segments/ViewChannels.tsx | 5 +- src/structure/MasterInterfacePage.tsx | 10 +- src/types/context.ts | 3 +- yarn.lock | 511 +----------------- 23 files changed, 416 insertions(+), 687 deletions(-) diff --git a/package.json b/package.json index dfab0eecc7..75a2f612f0 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,9 @@ "@mui/icons-material": "^5.8.4", "@mui/lab": "^5.0.0-alpha.72", "@mui/material": "^5.5.0", - "@pushprotocol/restapi": "0.0.1-alpha.64", + "@pushprotocol/restapi": "0.0.1-alpha.71", "@pushprotocol/socket": "0.5.3", - "@pushprotocol/uiweb": "0.0.1-alpha.41", + "@pushprotocol/uiweb": "1.3.1-alpha.6", "@reduxjs/toolkit": "^1.7.1", "@testing-library/dom": "^9.0.1", "@testing-library/jest-dom": "^4.2.4", diff --git a/src/AppLogin.tsx b/src/AppLogin.tsx index e32da8f003..610081e1b6 100644 --- a/src/AppLogin.tsx +++ b/src/AppLogin.tsx @@ -121,7 +121,7 @@ const AppLogin = ({ toggleDarkMode }) => { } const initiateGuestModa = () => { - const guestModeAddress = '0x0000000000000000000000000000000000000000'; + const guestModeAddress = '0x0000000000000000000000000000000000000001'; setMode(ReadOnlyWalletMode.GUEST_MODE); setReadOnlyWallet(guestModeAddress); hideOnboardModal(); diff --git a/src/components/ChannelDetails.js b/src/components/ChannelDetails.js index 35c8f25a1b..046219fdc4 100644 --- a/src/components/ChannelDetails.js +++ b/src/components/ChannelDetails.js @@ -49,7 +49,7 @@ export default function ChannelDetails({ isChannelExpired, setIsChannelExpired, const { userPushSDKInstance } = useSelector((state) => { return state.user; }); - const {handleConnectWallet} = useContext(AppContext); + const { handleConnectWallet } = useContext(AppContext); const { CHANNEL_ACTIVE_STATE, CHANNNEL_DEACTIVATED_STATE } = useSelector((state) => state.channels); const { processingState } = useSelector((state) => state.channelCreation); const [verifyingChannel, setVerifyingChannel] = React.useState([]); @@ -77,10 +77,9 @@ export default function ChannelDetails({ isChannelExpired, setIsChannelExpired, const addDelegateToast = useToast(); - const handleDelegateModal = () => { + const handleDelegateModal = async () => { if (!userPushSDKInstance.signer) { - handleConnectWallet(); - return; + await handleConnectWallet(); } showAddDelegateModal(); } @@ -156,17 +155,19 @@ export default function ChannelDetails({ isChannelExpired, setIsChannelExpired, } }, [account]); - const removeDelegate = (walletAddress) => { - return userPushSDKInstance.channel.delegate.remove(convertAddressToAddrCaip(walletAddress, chainId)); + const removeDelegate = async (walletAddress) => { + let userPushInstance = userPushSDKInstance; + if (!userPushInstance.signer) { + userPushInstance = await handleConnectWallet(); + if (!userPushInstance) { + return; + } + } + + return userPushInstance.channel.delegate.remove(convertAddressToAddrCaip(walletAddress, chainId)); }; const navigateToNotifSettings = () => { - - if (!userPushSDKInstance.signer) { - handleConnectWallet(); - return; - } - navigate(APP_PATHS.ChannelSettings); }; diff --git a/src/components/ChannelSettingsDropdown.tsx b/src/components/ChannelSettingsDropdown.tsx index 6e501c4ca1..7649e66aae 100644 --- a/src/components/ChannelSettingsDropdown.tsx +++ b/src/components/ChannelSettingsDropdown.tsx @@ -128,10 +128,10 @@ function ChannelSettings({ DropdownRef, isDropdownOpen, closeDropdown }: Channel const userSignerToast = useToast(); const toggleChannelActivationState = () => { if (isChannelBlocked) return; - if (!userPushSDKInstance.signer) { - handleConnectWallet(); - return; - } + // if (!userPushSDKInstance.signer) { + // handleConnectWallet(); + // return; + // } if (isChannelDeactivated) { showReactivateChannelModal(); } else { diff --git a/src/components/Dropdown.tsx b/src/components/Dropdown.tsx index 2b17d78a78..190a5512c1 100644 --- a/src/components/Dropdown.tsx +++ b/src/components/Dropdown.tsx @@ -5,11 +5,13 @@ import { Link } from 'react-router-dom'; // External Packages import styled, { useTheme } from 'styled-components'; +import { useSelector } from 'react-redux'; // Internal Components import { A, Image, ItemH, Span } from '../primaries/SharedStyling'; -import { GlobalContext } from 'contexts/GlobalContext'; +import { GlobalContext,ReadOnlyWalletMode } from 'contexts/GlobalContext'; import { SpanV2 } from './reusables/SharedStylingV2'; +import { useAccount } from 'hooks'; export type DropdownValueType = { id: number|string, @@ -34,11 +36,16 @@ function Dropdown({ dropdownValues, textColor, iconFilter, hoverBGColor }: Dropd const theme = useTheme(); const {mode} = useContext(GlobalContext); + const { wallet } = useAccount(); const getTextColor = (dropdownValue:DropdownValueType) => { return dropdownValue.textColor ? dropdownValue.textColor:textColor? textColor : theme.snackbarBorderText; } + const { userPushSDKInstance } = useSelector((state: any) => { + return state.user; + }); + const copyToClipboard = (address:string) => { if (navigator && navigator.clipboard) { @@ -80,6 +87,9 @@ function Dropdown({ dropdownValues, textColor, iconFilter, hoverBGColor }: Dropd {shortenText(dropdownValue?.title,3)} + + {!(wallet?.accounts?.length > 0) ? ReadOnlyWalletMode.GUEST_MODE : userPushSDKInstance?.readMode && ReadOnlyWalletMode.READ_ONLY_MODE} + {dropdownValue?.invertedIcon && ( (undefined); const [isLoading, setIsLoading] = React.useState(false); const [isLoadingSettings, setIsLoadingSettings] = React.useState(true); - const {handleConnectWallet} = useContext(AppContext); + const { handleConnectWallet } = useContext(AppContext); const { userPushSDKInstance } = useSelector((state: any) => { return state.user; @@ -133,12 +133,17 @@ function NotificationSettings() { const saveSettings = async () => { try { - if (!userPushSDKInstance.signer) { - handleConnectWallet(); - return; + setIsLoading(true); + + let userPushInstance = userPushSDKInstance; + if (!userPushInstance.signer) { + userPushInstance = await handleConnectWallet(); + if (!userPushInstance) { + setIsLoading(false); + return; + } } - setIsLoading(true); notificationToast.showLoaderToast({ loaderMessage: 'Waiting for Confirmation...' }); const settingData: NotificationSetting[] = settings.map((setting) => { @@ -153,14 +158,14 @@ function NotificationSettings() { console.info( { type: setting.type, - description: setting.description, - default: setting.default, - data: { - lower: setting.lowerLimit, - upper: setting.upperLimit, - ticker: setting.ticker, - enabled: setting.enabled, - }, + description: setting.description, + default: setting.default, + data: { + lower: setting.lowerLimit, + upper: setting.upperLimit, + ticker: setting.ticker, + enabled: setting.enabled, + }, } ) return { @@ -178,14 +183,14 @@ function NotificationSettings() { console.info( { type: setting.type, - description: setting.description, - default: setting.default, - data: { - lower: setting.lowerLimit, - upper: setting.upperLimit, - ticker: setting.ticker, - enabled: setting.enabled, - }, + description: setting.description, + default: setting.default, + data: { + lower: setting.lowerLimit, + upper: setting.upperLimit, + ticker: setting.ticker, + enabled: setting.enabled, + }, } ) return { @@ -202,7 +207,7 @@ function NotificationSettings() { } }); console.info(settingData); - await userPushSDKInstance.channel.setting(settingData); + await userPushInstance.channel.setting(settingData); dispatch(updateChannelSetting({ channelAddress, settings })); setIsLoading(false); diff --git a/src/components/dropdowns/ManageNotifSettingDropdown.tsx b/src/components/dropdowns/ManageNotifSettingDropdown.tsx index dadef23168..abf33cc4ca 100644 --- a/src/components/dropdowns/ManageNotifSettingDropdown.tsx +++ b/src/components/dropdowns/ManageNotifSettingDropdown.tsx @@ -4,6 +4,7 @@ import React, { useContext, useMemo, useState } from "react"; // External Packages import styled, { css, useTheme } from "styled-components"; import { useDispatch, useSelector } from "react-redux"; +import * as PushAPI from "@pushprotocol/restapi"; // Internal Components import { DropdownBtnHandler } from "./DropdownBtnHandler"; @@ -38,7 +39,7 @@ interface ManageNotifSettingDropdownContainerProps { closeDropdown: () => void; } -const ManageNotifSettingDropdownContainer: React.FC = ({ +const ManageNotifSettingDropdownContainer: React.FC = ({ centerOnMobile, optOutHandler, channelSetting, @@ -54,33 +55,33 @@ const ManageNotifSettingDropdownContainer: React.FC {(channelSetting && channelSetting.length != 0) && - - - - - Manage Settings - - - + + + + + Manage Settings + + + -} + } optOutHandler({ setLoading: setTxInProgress })}> {txInProgress && @@ -98,7 +99,7 @@ const ManageNotifSettingDropdownContainer: React.FC = (options) => { - const { + const { children, centerOnMobile, userSetting, @@ -106,15 +107,15 @@ const ManageNotifSettingDropdown: React.FC = (o onSuccessOptout } = options; const [isOpen, setIsOpen] = useState(false); - const { chainId } = useAccount(); + const { chainId, provider, account,wallet } = useAccount(); const { userPushSDKInstance } = useSelector((state: any) => { return state.user; }); const dispatch = useDispatch(); - const {handleConnectWallet} = useContext(AppContext); + const { handleConnectWallet,connectWallet } = useContext(AppContext); const channelSetting = useMemo(() => { - if(channelDetail && channelDetail?.channel_settings) { + if (channelDetail && channelDetail?.channel_settings) { return JSON.parse(channelDetail?.channel_settings); } return null; @@ -132,14 +133,18 @@ const ManageNotifSettingDropdown: React.FC = (o const unsubscribeToast = useToast(); const optOutHandler = async ({ setLoading }: { setLoading?: React.Dispatch> }) => { - const setLoadingFunc = setLoading || (() => {}); - - if (!userPushSDKInstance.signer) { - handleConnectWallet(); - return; - } - + const setLoadingFunc = setLoading || (() => { }); setLoadingFunc(true); + let userPushInstance = userPushSDKInstance; + + //TODO: We can change this back to use Push User + // if (!userPushInstance.signer) { + // userPushInstance = await handleConnectWallet(); + // if (!userPushInstance) { + // setLoadingFunc(false); + // return; + // } + // } try { let channelAddress = channelDetail.channel; @@ -149,9 +154,12 @@ const ManageNotifSettingDropdown: React.FC = (o unsubscribeToast.showLoaderToast({ loaderMessage: 'Waiting for Confirmation...' }); - await userPushSDKInstance.notification.unsubscribe(convertAddressToAddrCaip(channelAddress, chainId), { + const _signer = await provider.getSigner(account); + await PushAPI.channels.unsubscribe({ + signer: _signer, + channelAddress: convertAddressToAddrCaip(channelAddress, chainId), // channel address in CAIP + userAddress: convertAddressToAddrCaip(account, chainId), // user address in CAIP onSuccess: () => { - onSuccessOptout(); dispatch(updateSubscriptionStatus({ channelAddress: channelAddress, status: false })); dispatch(removeUserSetting(channelAddress)); @@ -170,7 +178,7 @@ const ManageNotifSettingDropdown: React.FC = (o closeDropdown(); }, onError: () => { - console.error('opt in error'); + console.error('opt out error'); unsubscribeToast.showMessageToast({ toastTitle: 'Error', toastMessage: `There was an error opting out of channel`, @@ -183,7 +191,45 @@ const ManageNotifSettingDropdown: React.FC = (o ), }); }, + env: appConfig.pushNodesEnv, }); + + + // await userPushInstance.notification.unsubscribe(convertAddressToAddrCaip(channelAddress, chainId), { + // onSuccess: () => { + // onSuccessOptout(); + // dispatch(updateSubscriptionStatus({ channelAddress: channelAddress, status: false })); + // dispatch(removeUserSetting(channelAddress)); + + // unsubscribeToast.showMessageToast({ + // toastTitle: 'Success', + // toastMessage: 'Successfully opted out of channel !', + // toastType: 'SUCCESS', + // getToastIcon: (size) => ( + // + // ), + // }); + + // closeDropdown(); + // }, + // onError: () => { + // console.error('opt in error'); + // unsubscribeToast.showMessageToast({ + // toastTitle: 'Error', + // toastMessage: `There was an error opting out of channel`, + // toastType: 'ERROR', + // getToastIcon: (size) => ( + // + // ), + // }); + // }, + // }); } catch (err) { unsubscribeToast.showMessageToast({ toastTitle: 'Error', @@ -205,24 +251,24 @@ const ManageNotifSettingDropdown: React.FC = (o // render return ( - } - containerPadding="12px 16px" - centerOnMobile={centerOnMobile} - > - {children} - + } + containerPadding="12px 16px" + centerOnMobile={centerOnMobile} + > + {children} + ); } diff --git a/src/components/dropdowns/OptinNotifSettingDropdown.tsx b/src/components/dropdowns/OptinNotifSettingDropdown.tsx index a6c879f8a8..f6f5f33471 100644 --- a/src/components/dropdowns/OptinNotifSettingDropdown.tsx +++ b/src/components/dropdowns/OptinNotifSettingDropdown.tsx @@ -1,5 +1,7 @@ // React + Web3 Essentials import React, { useContext, useMemo, useState } from "react"; +import * as PushAPI from "@pushprotocol/restapi"; +import { ethers } from "ethers"; // External Packages import Switch from 'react-switch'; @@ -71,48 +73,48 @@ const OptinNotifSettingDropdownContainer: React.FC - - {setting.description} - handleSwitchChange(index)} checked={setting.type === 1 ? setting.default : setting.enabled} - checkedIcon={false} - uncheckedIcon={false} - onColor="#D53A94" - offColor="#A0A3B1" - height={16} - width={32} - handleDiameter={12} - /> - - {setting.type === 2 && setting.enabled === true && ( - - - {setting.default} - - handleSliderChange(index, x)} - /> - - )} + + {setting.description} + handleSwitchChange(index)} checked={setting.type === 1 ? setting.default : setting.enabled} + checkedIcon={false} + uncheckedIcon={false} + onColor="#D53A94" + offColor="#A0A3B1" + height={16} + width={32} + handleDiameter={12} + /> + + {setting.type === 2 && setting.enabled === true && ( + + + {setting.default} + + handleSliderChange(index, x)} + /> + + )} {setting.type === 3 && setting.enabled === true && ( - {setting.default.lower} - {setting.default.upper} + {setting.default.lower} - {setting.default.upper} handleSliderChange(index, {lower: startVal, upper: endVal})} + startVal={setting.default.lower} + endVal={setting.default.upper} + max={setting.upperLimit} + min={setting.lowerLimit} + step={setting.ticker || 1} + defaultStartVal={setting.default.lower} + defaultEndVal={setting.default.upper} + onChange={({ startVal, endVal }) => handleSliderChange(index, { lower: startVal, upper: endVal })} /> )} @@ -141,14 +143,14 @@ const OptinNotifSettingDropdownContainer: React.FC = (options) => { const { children, channelDetail, setLoading, onSuccessOptin } = options; - const { chainId } = useAccount(); + const { chainId, provider, account, wallet } = useAccount(); const { userPushSDKInstance } = useSelector((state: any) => { return state.user; }); const [isOpen, setIsOpen] = useState(false); const dispatch = useDispatch(); - const { handleConnectWallet } = useContext(AppContext); + const { handleConnectWallet, connectWallet } = useContext(AppContext); const onCoreNetwork = chainId === appConfig.coreContractChain; @@ -171,14 +173,28 @@ const OptinNotifSettingDropdown: React.FC = (opt const optInHandler = async ({ channelSettings, setLoading }: { channelSettings?: ChannelSetting[], setLoading?: React.Dispatch> }) => { const setLoadingFunc = setLoading || (options && options.setLoading) || (() => { }); - - if (!userPushSDKInstance.signer) { - handleConnectWallet(); - return; - } - setLoadingFunc(true); + let userPushInstance = userPushSDKInstance; + // if (!userPushInstance.signer) { + // userPushInstance = await handleConnectWallet(); + // if (!userPushInstance) { + // setLoadingFunc(false); + // return; + // } + // } + + let walletAddress = account; + let web3Provider = provider; + + if(!(wallet?.accounts?.length > 0)){ + const connectedWallet = await connectWallet(); + walletAddress = connectedWallet.accounts[0].address; + web3Provider = new ethers.providers.Web3Provider(connectedWallet.provider, 'any') + } + + + try { let channelAddress = channelDetail.channel; if (!onCoreNetwork) { @@ -187,11 +203,13 @@ const OptinNotifSettingDropdown: React.FC = (opt subscribeToast.showLoaderToast({ loaderMessage: 'Waiting for Confirmation...' }); - await userPushSDKInstance.notification.subscribe(convertAddressToAddrCaip(channelAddress, chainId), { - settings: notifChannelSettingFormatString({ settings: channelSettings }), - // settings: [], + const _signer = await web3Provider?.getSigner(walletAddress); + + await PushAPI.channels.subscribe({ + signer: _signer, + channelAddress: convertAddressToAddrCaip(channelAddress, chainId), // channel address in CAIP + userAddress: convertAddressToAddrCaip(walletAddress, chainId), // user address in CAIP onSuccess: () => { - onSuccessOptin(); dispatch(updateSubscriptionStatus({ channelAddress, status: true })); dispatch(updateUserSetting({ channelAddress, settings: userSettingsFromDefaultChannelSetting({ channelSetting: channelSettings }) })); @@ -221,8 +239,45 @@ const OptinNotifSettingDropdown: React.FC = (opt ), }); }, + env: appConfig.pushNodesEnv, }); + // await PUSHAPI.channels.subscribe(convertAddressToAddrCaip(channelAddress, chainId), { + // settings: notifChannelSettingFormatString({ settings: channelSettings }), + // // settings: [], + // onSuccess: () => { + // onSuccessOptin(); + // dispatch(updateSubscriptionStatus({ channelAddress, status: true })); + // dispatch(updateUserSetting({ channelAddress, settings: userSettingsFromDefaultChannelSetting({ channelSetting: channelSettings }) })); + + // subscribeToast.showMessageToast({ + // toastTitle: 'Success', + // toastMessage: 'Successfully opted into channel !', + // toastType: 'SUCCESS', + // getToastIcon: (size) => ( + // + // ), + // }); + // }, + // onError: () => { + // console.error('opt in error'); + // subscribeToast.showMessageToast({ + // toastTitle: 'Error', + // toastMessage: `There was an error opting into channel`, + // toastType: 'ERROR', + // getToastIcon: (size) => ( + // + // ), + // }); + // }, + // }); + } catch (err) { subscribeToast.showMessageToast({ diff --git a/src/components/dropdowns/UpdateNotifSettingDropdown.tsx b/src/components/dropdowns/UpdateNotifSettingDropdown.tsx index 055ea4c2fa..a7cc027a01 100644 --- a/src/components/dropdowns/UpdateNotifSettingDropdown.tsx +++ b/src/components/dropdowns/UpdateNotifSettingDropdown.tsx @@ -177,14 +177,18 @@ const UpdateNotifSettingDropdown: React.FC = ({ const saveUserSettingHandler = async ({ userSettings, setLoading }: { userSettings?: UserSetting[], setLoading?: React.Dispatch> }) => { const setLoadingFunc = setLoading || (() => {}); const saveOnSuccessSettingFunc = onSuccessSave || (() => {}); - - if (!userPushSDKInstance.signer) { - handleConnectWallet(); - return; - } - setLoadingFunc(true); + let userPushInstance = userPushSDKInstance; + + if (!userPushInstance.signer) { + userPushInstance = await handleConnectWallet(); + if (!userPushInstance) { + setLoadingFunc(false); + return; + } + } + try { let channelAddress = channelDetail.channel; if (!onCoreNetwork) { @@ -193,7 +197,7 @@ const UpdateNotifSettingDropdown: React.FC = ({ subscribeToast.showLoaderToast({ loaderMessage: 'Waiting for Confirmation...' }); - await userPushSDKInstance.notification.subscribe(convertAddressToAddrCaip(channelAddress, chainId), { + await userPushInstance.notification.subscribe(convertAddressToAddrCaip(channelAddress, chainId), { settings: notifUserSettingFormatString({ settings: userSettings }), // settings: [], onSuccess: () => { diff --git a/src/config/Themization.js b/src/config/Themization.js index d8b37f8308..8d493d4a1e 100644 --- a/src/config/Themization.js +++ b/src/config/Themization.js @@ -177,6 +177,8 @@ const themeLight = { toastSuccessBackground: 'linear-gradient(90.15deg, #30CC8B -125.65%, #30CC8B -125.63%, #F3FFF9 42.81%)', toastErrorBackground: 'linear-gradient(90.15deg, #FF2070 -125.65%, #FF2D79 -125.63%, #FFF9FB 42.81%)', + toastWarningBackground:'linear-gradient(90deg, #FFF2D1 0%, rgba(255, 255, 255, 0.00) 100%)', + // Profile profileBG: 'linear-gradient(107deg, rgba(226,8,128,1) 30%, rgba(103,76,159,1) 70%, rgba(53,197,243,1) 100%)', profileText: '#fff', @@ -471,6 +473,8 @@ const themeDark = { toastShadowColor: '#00000010', toastSuccessBackground: 'linear-gradient(90.15deg, #30CC8B -125.65%, #30CC8B -125.63%, #2F3137 42.81%)', toastErrorBackground: 'linear-gradient(89.96deg, #FF2070 -101.85%, #2F3137 51.33%)', + toastWarningBackground:'linear-gradient(90deg, #66562D 0.03%, #2F3137 74.67%)', + //Profile profileBG: '#2F3137', diff --git a/src/contexts/AppContext.tsx b/src/contexts/AppContext.tsx index b0bfebe771..14ce27f32a 100644 --- a/src/contexts/AppContext.tsx +++ b/src/contexts/AppContext.tsx @@ -2,7 +2,7 @@ import useModalBlur from "hooks/useModalBlur"; import React, { createContext, useContext, useEffect, useState } from "react"; import { ProgressHookType, PushAPI } from '@pushprotocol/restapi'; - +import { ethers } from "ethers"; // Internal Components import { AppContextType, BlockedLoadingI, ConnectedPeerIDType, LocalPeerType, onboardingProgressI, Web3NameListType } from "types/context" @@ -24,6 +24,8 @@ const AppContextProvider = ({ children }) => { const { connect, provider, account, wallet, connecting } = useAccount(); const web3onboardToast = useToast(); + const { readOnlyWallet } = useContext(GlobalContext); + const [web3NameList, setWeb3NameList] = useState({}); const [snapInstalled, setSnapInstalled] = useState(false); @@ -55,7 +57,7 @@ const AppContextProvider = ({ children }) => { const dispatch = useDispatch(); - const handleConnectWallet = async (showToast = false, toastMessage?: string) => { + const connectWallet = async (showToast = false, toastMessage?: string) =>{ if (showToast) { web3onboardToast.showMessageToast({ toastMessage: toastMessage || "Please connect your wallet to continue", @@ -65,11 +67,34 @@ const AppContextProvider = ({ children }) => { }); } + if (!(wallet?.accounts?.length > 0)) { + const walletConnected = await connect(); + return walletConnected[0]; + } + + } + + const handleConnectWallet = async (showToast = false, toastMessage?: string) => { + if (showToast) { + web3onboardToast.showMessageToast({ + toastMessage: toastMessage || "Please connect your wallet to continue", + toastTitle: "Connect Wallet", + toastType: "ERROR", + getToastIcon: (size) => , + }); + } if (wallet?.accounts?.length > 0) { - await initializePushSDK(); + const userPushInstance = await initializePushSDK(); + return userPushInstance; } else { - connect(); + const walletConnected = await connect(); + if (walletConnected) { + const userPushInstance = await initializePushSDK(walletConnected[0]); + return userPushInstance; + } else { + return null; + } } } @@ -77,23 +102,22 @@ const AppContextProvider = ({ children }) => { const initialisePushSdkGuestMode = async () => { - console.log("Initialising Push SDK Guest Mode"); let userInstance; userInstance = await PushAPI.initialize({ - account: '0x0000000000000000000000000000000000000000', + account: readOnlyWallet, env: appConfig.appEnv, }); dispatch(setUserPushSDKInstance(userInstance)); } const initialisePushSdkReadMode = async () => { - console.log("Initialising Push SDK Read Mode"); let userInstance; userInstance = await PushAPI.initialize({ env: appConfig.appEnv, account: account, }); dispatch(setUserPushSDKInstance(userInstance)); + return userInstance; } @@ -174,8 +198,8 @@ const AppContextProvider = ({ children }) => { onboardingProgress.progress = 99; break; case "PUSH-ERROR-00": - onboardingProgress.errorMessage = "User Rejected Signature"; - onboardingProgress.hookInfo.progressTitle = "User Rejected Signature"; + onboardingProgress.errorMessage = "The sign in was rejected by the user. You can still continue in read-only mode."; + onboardingProgress.hookInfo.progressTitle = "Profile Unlock Unsuccessful"; onboardingProgress.spinnerType = LOADER_SPINNER_TYPE.ERROR; break; case "PUSH-ERROR-01": @@ -206,16 +230,23 @@ const AppContextProvider = ({ children }) => { }; - const initializePushSDK = async () => { + const initializePushSDK = async (wallet?: any) => { let userInstance; try { - const librarySigner = provider?.getSigner(account); + + let web3Provider = provider; + let currentAddress = wallet ? wallet.accounts[0].address : account; + + if (wallet) { + web3Provider = new ethers.providers.Web3Provider(wallet.provider, 'any') + } + + const librarySigner = web3Provider?.getSigner(currentAddress); userInstance = await PushAPI.initialize(librarySigner!, { env: appConfig.appEnv, - account: account, + account: currentAddress, progressHook: onboardingProgressReformatter, }); - if (userInstance) { setBlockedLoading({ enabled: false, @@ -227,9 +258,11 @@ const AppContextProvider = ({ children }) => { } dispatch(setUserPushSDKInstance(userInstance)); + return userInstance; } catch (error) { // Handle initialization error console.log("Errror !!!!!", error); + return null; } }; @@ -284,7 +317,7 @@ const AppContextProvider = ({ children }) => { } else { initialisePushSdkGuestMode(); } - }, [account, provider, wallet]); + }, [account]); const createUserIfNecessary = async (): Promise => { try { @@ -327,6 +360,7 @@ const AppContextProvider = ({ children }) => { initializePushSDK, SnapState, handleConnectWallet, + connectWallet, setSnapInstalled, snapInstalled, setBlockedLoading, diff --git a/src/contexts/GlobalContext.tsx b/src/contexts/GlobalContext.tsx index 02c8528ffa..e14ea3bdf4 100644 --- a/src/contexts/GlobalContext.tsx +++ b/src/contexts/GlobalContext.tsx @@ -17,7 +17,7 @@ export type GlobalContextType = { export const GlobalContext = createContext(null); const GlobalContextProvider = ({ children }) => { - const [readOnlyWallet, setReadOnlyWallet] = useState('0x0000000000000000000000000000000000000000'); + const [readOnlyWallet, setReadOnlyWallet] = useState('0x0000000000000000000000000000000000000001'); const [mode, setMode] = useState(ReadOnlyWalletMode.GUEST_MODE); const [sidebarCollapsed, setSidebarCollapsed] = useState(false); diff --git a/src/hooks/useToast.tsx b/src/hooks/useToast.tsx index 07ea5e2aec..2bd94fd15f 100644 --- a/src/hooks/useToast.tsx +++ b/src/hooks/useToast.tsx @@ -56,7 +56,7 @@ export type ShowMessageToastType = ({ }: { toastTitle: string; toastMessage: string; - toastType: 'SUCCESS' | 'ERROR'; + toastType: 'SUCCESS' | 'ERROR' | 'WARNING'; getToastIcon?: (size: number) => JSX.Element; }) => void; @@ -100,7 +100,7 @@ const useToast = ( }; const showMessageToast: ShowMessageToastType = ({ toastTitle, toastMessage, toastType, getToastIcon }) => { - + const toastUI = ( {getToastIcon ? getToastIcon(30) : ''} @@ -123,6 +123,21 @@ const useToast = ( ); + let backgroundColor; + switch (toastType) { + case 'SUCCESS': + backgroundColor = themes.toastSuccessBackground; + break; + case 'ERROR': + backgroundColor = themes.toastErrorBackground; + break; + case 'WARNING': + backgroundColor = themes.toastWarningBackground; // Assuming you have a warning background color defined + break; + default: + backgroundColor = 'defaultBackgroundColor'; // Fallback color + } + const toastRenderParams = { position, hideProgressBar: true, @@ -134,7 +149,7 @@ const useToast = ( closeButton: CloseButton, autoClose: autoClose, style: { - background: toastType === 'SUCCESS' ? themes.toastSuccessBackground : themes.toastErrorBackground, + background: backgroundColor, boxShadow: `10px 10px 10px ${themes.toastShadowColor}`, borderRadius: '20px', margin: isMobile ? '20px' : '0px', diff --git a/src/modules/channelDashboard/ChannelOwnerDashboard.tsx b/src/modules/channelDashboard/ChannelOwnerDashboard.tsx index 76a5d93406..350b41ddf8 100644 --- a/src/modules/channelDashboard/ChannelOwnerDashboard.tsx +++ b/src/modules/channelDashboard/ChannelOwnerDashboard.tsx @@ -149,10 +149,10 @@ const ChannelOwnerDashboard = () => { } const showEditChannel = () => { - if (!userPushSDKInstance.signer) { - handleConnectWallet(); - return; - } + // if (!userPushSDKInstance.signer) { + // handleConnectWallet(); + // return; + // } setEditChannel(true); } diff --git a/src/primaries/Profile.tsx b/src/primaries/Profile.tsx index a33eff33d2..28621ea6ca 100644 --- a/src/primaries/Profile.tsx +++ b/src/primaries/Profile.tsx @@ -25,7 +25,7 @@ import { SpanV2 } from 'components/reusables/SharedStylingV2.js'; // Create Header const Profile = ({ isDarkMode }) => { - const { web3NameList,initialisePushSdkReadMode,handleConnectWallet }: AppContextType = useContext(AppContext); + const { web3NameList,initialisePushSdkReadMode }: AppContextType = useContext(AppContext); const { setReadOnlyWallet, readOnlyWallet, mode, setMode }: GlobalContextType = useContext(GlobalContext); const { authError } = useContext(ErrorContext); const toggleArrowRef = useRef(null); @@ -76,7 +76,7 @@ const Profile = ({ isDarkMode }) => { function: async () => { await disconnect(wallet); setMode(ReadOnlyWalletMode.GUEST_MODE); - setReadOnlyWallet('0x0000000000000000000000000000000000000000'); + setReadOnlyWallet('0x0000000000000000000000000000000000000001'); }, title: 'Logout', invertedIcon: './logout.svg', @@ -87,6 +87,10 @@ const Profile = ({ isDarkMode }) => { setShowDropdown(false); }); + const ConnectWallet = ()=>{ + connect(); + } + // to create blockies return ( @@ -100,7 +104,7 @@ const Profile = ({ isDarkMode }) => { bg="linear-gradient(87.17deg, #B6A0F5 0%, #F46EF7 57.29%, #FF95D5 100%)" color='#FFF' isDarkMode={isDarkMode} - onClick={()=>handleConnectWallet()} + onClick={()=>ConnectWallet()} > Connect Wallet @@ -124,7 +128,7 @@ const Profile = ({ isDarkMode }) => { ) : ( <>{shortenText(account, 5)} )} - {!(wallet?.accounts?.length > 0) ? ReadOnlyWalletMode.GUEST_MODE : userPushSDKInstance?.readMode && ReadOnlyWalletMode.READ_ONLY_MODE} + {/* {!(wallet?.accounts?.length > 0) ? ReadOnlyWalletMode.GUEST_MODE : userPushSDKInstance?.readMode && ReadOnlyWalletMode.READ_ONLY_MODE} */} arrow { bg="linear-gradient(87.17deg, #B6A0F5 0%, #F46EF7 57.29%, #FF95D5 100%)" color='#FFF' isDarkMode={isDarkMode} - onClick={()=>handleConnectWallet()} + onClick={()=>ConnectWallet()} > Connect Wallet diff --git a/src/sections/chat/ChatSidebarSection.tsx b/src/sections/chat/ChatSidebarSection.tsx index 7d0ba3863d..050dcee715 100644 --- a/src/sections/chat/ChatSidebarSection.tsx +++ b/src/sections/chat/ChatSidebarSection.tsx @@ -67,6 +67,7 @@ const ChatSidebarSection = ({ showCreateGroupModal, autofilledSearch }) => { // theme context const theme = useTheme(); + const {readOnlyWallet} = useContext(GlobalContext); const { setSelectedChatId } = useContext(Context); const { setMode } = useContext(GlobalContext); @@ -103,7 +104,7 @@ const ChatSidebarSection = ({ showCreateGroupModal, autofilledSearch }) => { } return formattedChatParticipant; } else { - if (userPushSDKInstance.account === '0x0000000000000000000000000000000000000000') { + if (userPushSDKInstance.account === readOnlyWallet) { handleConnectWallet(); } else if (userPushSDKInstance.signer === undefined || userPushSDKInstance.decryptedPgpPvtKey === undefined) { await initializePushSDK(); @@ -116,7 +117,7 @@ const ChatSidebarSection = ({ showCreateGroupModal, autofilledSearch }) => { if (userPushSDKInstance.decryptedPgpPvtKey) { showCreateGroupModal(); } else { - if (userPushSDKInstance.account === '0x0000000000000000000000000000000000000000') { + if (userPushSDKInstance.account === readOnlyWallet) { handleConnectWallet(); } else { if (userPushSDKInstance.signer === undefined) { diff --git a/src/segments/Feedbox.tsx b/src/segments/Feedbox.tsx index f352e36153..979454aaa2 100644 --- a/src/segments/Feedbox.tsx +++ b/src/segments/Feedbox.tsx @@ -19,6 +19,7 @@ import { Item } from "primaries/SharedStyling"; import { addPaginatedNotifications, incrementPage, + resetNotificationsSlice, setFinishedFetching, updateTopNotifications } from "redux/slices/notificationSlice"; @@ -29,6 +30,7 @@ import { useAccount, useDeviceWidthCheck } from "hooks"; import { ReactComponent as MetamaskLogo } from 'assets/PushSnaps/metamasksnap.svg'; import { ReactComponent as Close } from 'assets/chat/group-chat/close.svg'; import { ReactComponent as OpenLink } from 'assets/PushSnaps/GoToImage.svg' +import { GlobalContext } from "contexts/GlobalContext"; // Internal Configs import { appConfig } from "config"; @@ -45,7 +47,7 @@ const Feedbox = ({ showFilter, setShowFilter, search, setSearch }) => { const dispatch = useDispatch(); const { userPushSDKInstance } = useSelector((state: any) => { return state.user; - }); + }); const modalRef = React.useRef(null); useClickAway(modalRef, () => showFilter && setShowFilter(false)); @@ -71,6 +73,7 @@ const Feedbox = ({ showFilter, setShowFilter, search, setSearch }) => { const [loadFilter, setLoadFilter] = React.useState(false); const [bgUpdateLoading, setBgUpdateLoading] = React.useState(false); const [loading, setLoading] = React.useState(false); + const {readOnlyWallet } = useContext(GlobalContext); const [showSnapInfo, setShowSnapInfo] = React.useState(true); @@ -169,7 +172,7 @@ const Feedbox = ({ showFilter, setShowFilter, search, setSearch }) => { } }; const fetchLatestNotifications = async () => { - if (loading || bgUpdateLoading) return; + // if (loading || bgUpdateLoading) return; setBgUpdateLoading(true); setLoading(true); try { @@ -242,7 +245,7 @@ const Feedbox = ({ showFilter, setShowFilter, search, setSearch }) => { }; React.useEffect(() => { - if (!userPushSDKInstance) return; + if (userPushSDKInstance?.account == readOnlyWallet || !userPushSDKInstance) return; fetchLatestNotifications(); fetchAllNotif(); }, [toggle, userPushSDKInstance]); @@ -366,13 +369,13 @@ const Feedbox = ({ showFilter, setShowFilter, search, setSearch }) => { <> - + Get Notifications directly in MetaMask using Push Snap. Install Push Snap { setShowSnapInfo(false); - }}/> + }} /> diff --git a/src/segments/ViewChannels.tsx b/src/segments/ViewChannels.tsx index 95ad74ff7c..cad1573af9 100644 --- a/src/segments/ViewChannels.tsx +++ b/src/segments/ViewChannels.tsx @@ -65,7 +65,7 @@ function ViewChannels({ loadTeaser, playTeaser }) { useEffect(() => { setLoading(!channels.length); //if there are no channels initially then, set the loader fetchInitialsChannelMeta(); - }, [account, chainId]); + }, [account, chainId,userPushSDKInstance]); useEffect(() => { setChannelsNetworkId(chainId); @@ -191,7 +191,8 @@ function ViewChannels({ loadTeaser, playTeaser }) { return () => { clearTimeout(timeout); }; - }, [search, userPushSDKInstance]); + // userPushSDKInstance should not be used as dependency here. + }, [search]); useEffect(() => { if (!account || !userPushSDKInstance) return; diff --git a/src/structure/MasterInterfacePage.tsx b/src/structure/MasterInterfacePage.tsx index 8e62dbdf32..eee6d356f7 100644 --- a/src/structure/MasterInterfacePage.tsx +++ b/src/structure/MasterInterfacePage.tsx @@ -8,6 +8,8 @@ import { ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.min.css'; import styled from 'styled-components'; import { MdError } from 'react-icons/md'; +import { MdWarning } from "react-icons/md"; + import useToast from 'hooks/useToast'; // Internal Components @@ -231,13 +233,13 @@ function MasterInterfacePage() { {blockedLoading.errorMessage && ( blockedLoadingToast.showMessageToast({ - toastTitle: 'Error', + toastTitle: blockedLoading.title, toastMessage: blockedLoading.errorMessage, - toastType: 'ERROR', + toastType: 'WARNING', getToastIcon: (size) => ( - ), }) diff --git a/src/types/context.ts b/src/types/context.ts index 933238ca01..d4fe95fdc4 100644 --- a/src/types/context.ts +++ b/src/types/context.ts @@ -45,7 +45,8 @@ export interface AppContextType { initializePushSDK: () => Promise; snapInstalled: boolean; setSnapInstalled: (snapInstalled: boolean) => void; - handleConnectWallet: (showToast?: boolean, toastMessage?: string) => void; + handleConnectWallet: (showToast?: boolean, toastMessage?: string) => any; + connectWallet: (showToast?: boolean, toastMessage?: string) => any; setBlockedLoading: (blockedLoading: BlockedLoadingI) => void; blockedLoading: BlockedLoadingI; getUser: () => Promise; diff --git a/yarn.lock b/yarn.lock index e39c26d170..fec4edc6f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -81,17 +81,6 @@ __metadata: languageName: node linkType: hard -"@ambire/signature-validator@npm:^1.3.1": - version: 1.3.1 - resolution: "@ambire/signature-validator@npm:1.3.1" - dependencies: - ethers: ^5.6.5 - tap-spec: ^5.0.0 - tape: ^5.5.3 - checksum: 44c4796f4cbb4624cfd64033523d3491afa899067026e9615322dc6efaca71b16358cbc1661f2fce62d9dedcf424c92d44fe3b2ab8c6f171a59c0c21dc17b2e2 - languageName: node - linkType: hard - "@ampproject/remapping@npm:^2.2.0": version: 2.2.0 resolution: "@ampproject/remapping@npm:2.2.0" @@ -4641,22 +4630,6 @@ __metadata: languageName: node linkType: hard -"@ljharb/resumer@npm:^0.0.1": - version: 0.0.1 - resolution: "@ljharb/resumer@npm:0.0.1" - dependencies: - "@ljharb/through": ^2.3.9 - checksum: 1cff0a485cb857933d2921cb05a349f8fe894fa2bb6b31a347010ecccc4a2b369e43ebe5383a32a60ee6c9572d2c83fcab383eb01727e1507bf29c59f312dae6 - languageName: node - linkType: hard - -"@ljharb/through@npm:^2.3.9": - version: 2.3.9 - resolution: "@ljharb/through@npm:2.3.9" - checksum: a47ffed12ef4b08d07458db8bff5f7a13a7030fddf7dbfa947a765581a634d42ee90f7b8c249315aad122c21ad061e97a74f65aef3c03d2c09291d11312f0bfb - languageName: node - linkType: hard - "@material-ui/core@npm:4.11.0": version: 4.11.0 resolution: "@material-ui/core@npm:4.11.0" @@ -5432,9 +5405,9 @@ __metadata: "@mui/icons-material": ^5.8.4 "@mui/lab": ^5.0.0-alpha.72 "@mui/material": ^5.5.0 - "@pushprotocol/restapi": 0.0.1-alpha.64 + "@pushprotocol/restapi": 0.0.1-alpha.71 "@pushprotocol/socket": 0.5.3 - "@pushprotocol/uiweb": 0.0.1-alpha.41 + "@pushprotocol/uiweb": 1.3.1-alpha.6 "@reduxjs/toolkit": ^1.7.1 "@testing-library/dom": ^6.12.2 "@testing-library/jest-dom": ^4.2.4 @@ -5621,11 +5594,10 @@ __metadata: languageName: node linkType: hard -"@pushprotocol/restapi@npm:0.0.1-alpha.64": - version: 0.0.1-alpha.64 - resolution: "@pushprotocol/restapi@npm:0.0.1-alpha.64" +"@pushprotocol/restapi@npm:0.0.1-alpha.71": + version: 0.0.1-alpha.71 + resolution: "@pushprotocol/restapi@npm:0.0.1-alpha.71" dependencies: - "@ambire/signature-validator": ^1.3.1 "@metamask/eth-sig-util": ^5.0.2 axios: ^0.27.2 buffer: ^6.0.3 @@ -5644,7 +5616,10 @@ __metadata: viem: ^1.20.3 peerDependencies: ethers: ^5.0.0 || ^6.0.0 - checksum: 6c62724de1522572de2dfc62212f7a461f8b92b4c8f32097d8a1cea527bda4e3d00b65ada8b2adb2a466d7615af7eb8092b28defed7dc06293a25ea3b9713503 + peerDependenciesMeta: + ethers: + optional: true + checksum: f54952b8d5eeb6bfad61af52b5d25a5989e9075d3640800cd3042f56c411659ee3add38d673df1497479d3a7fb7500db7789fa9b4e696a0544b556345cd950f7 languageName: node linkType: hard @@ -5672,9 +5647,9 @@ __metadata: languageName: node linkType: hard -"@pushprotocol/uiweb@npm:0.0.1-alpha.41": - version: 0.0.1-alpha.41 - resolution: "@pushprotocol/uiweb@npm:0.0.1-alpha.41" +"@pushprotocol/uiweb@npm:1.3.1-alpha.6": + version: 1.3.1-alpha.6 + resolution: "@pushprotocol/uiweb@npm:1.3.1-alpha.6" dependencies: "@livekit/components-react": ^1.2.2 "@livekit/components-styles": ^1.0.6 @@ -5706,7 +5681,8 @@ __metadata: axios: ^0.27.2 react: ">=16.8.0" styled-components: ^6.0.8 - checksum: bbd07715409e0d22b17f825124202772f65169bbeec4c4b05cc4e5b9020e129957f78b3031549ec5c638046247375fecd8b3653c1dbc039363293763b4d7ba51 + viem: ^1.3.0 + checksum: b931b0e27ef2d209d46d19c651de538a0843f914509a53f7bdbb69e71156406287d2c1561c037f4762523e48bf3d2704e0c2a273b9b0736dcf4ab203f19894d4 languageName: node linkType: hard @@ -10151,13 +10127,6 @@ __metadata: languageName: node linkType: hard -"ansi-regex@npm:^2.0.0": - version: 2.1.1 - resolution: "ansi-regex@npm:2.1.1" - checksum: 190abd03e4ff86794f338a31795d262c1dfe8c91f7e01d04f13f646f1dcb16c5800818f886047876f1272f065570ab86b24b99089f8b68a0e11ff19aed4ca8f1 - languageName: node - linkType: hard - "ansi-regex@npm:^4.0.0, ansi-regex@npm:^4.1.0": version: 4.1.1 resolution: "ansi-regex@npm:4.1.1" @@ -10179,13 +10148,6 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^2.2.1": - version: 2.2.1 - resolution: "ansi-styles@npm:2.2.1" - checksum: ebc0e00381f2a29000d1dac8466a640ce11943cef3bda3cd0020dc042e31e1058ab59bf6169cd794a54c3a7338a61ebc404b7c91e004092dd20e028c432c9c2c - languageName: node - linkType: hard - "ansi-styles@npm:^3.2.0, ansi-styles@npm:^3.2.1": version: 3.2.1 resolution: "ansi-styles@npm:3.2.1" @@ -10387,18 +10349,6 @@ __metadata: languageName: node linkType: hard -"array.prototype.every@npm:^1.1.4": - version: 1.1.5 - resolution: "array.prototype.every@npm:1.1.5" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 - is-string: ^1.0.7 - checksum: 9974435604e135fc8c359a76c89bfe0672c1a80974a76dc61c673e5ea5068f78a31b7a168634ed7691501130ed61d3c788dd1d48ec1265c6cdf3910897b1eba4 - languageName: node - linkType: hard - "array.prototype.flat@npm:^1.2.5, array.prototype.flat@npm:^1.3.1": version: 1.3.1 resolution: "array.prototype.flat@npm:1.3.1" @@ -10449,20 +10399,6 @@ __metadata: languageName: node linkType: hard -"arraybuffer.prototype.slice@npm:^1.0.1": - version: 1.0.1 - resolution: "arraybuffer.prototype.slice@npm:1.0.1" - dependencies: - array-buffer-byte-length: ^1.0.0 - call-bind: ^1.0.2 - define-properties: ^1.2.0 - get-intrinsic: ^1.2.1 - is-array-buffer: ^3.0.2 - is-shared-array-buffer: ^1.0.2 - checksum: e3e9b2a3e988ebfeddce4c7e8f69df730c9e48cb04b0d40ff0874ce3d86b3d1339dd520ffde5e39c02610bc172ecfbd4bc93324b1cabd9554c44a56b131ce0ce - languageName: node - linkType: hard - "asap@npm:~2.0.6": version: 2.0.6 resolution: "asap@npm:2.0.6" @@ -11636,13 +11572,6 @@ __metadata: languageName: node linkType: hard -"buffer-shims@npm:~1.0.0": - version: 1.0.0 - resolution: "buffer-shims@npm:1.0.0" - checksum: 4defd1ffc9b270708ea39c17cac75c91c520c8e2f1d28a4d0ec74dc77445cbf8fc162003f0530fd1f81340347e9a26863d5aa27cd3cc351ec1d0361777d15ace - languageName: node - linkType: hard - "buffer-to-arraybuffer@npm:^0.0.5": version: 0.0.5 resolution: "buffer-to-arraybuffer@npm:0.0.5" @@ -11971,19 +11900,6 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^1.0.0": - version: 1.1.3 - resolution: "chalk@npm:1.1.3" - dependencies: - ansi-styles: ^2.2.1 - escape-string-regexp: ^1.0.2 - has-ansi: ^2.0.0 - strip-ansi: ^3.0.0 - supports-color: ^2.0.0 - checksum: 9d2ea6b98fc2b7878829eec223abcf404622db6c48396a9b9257f6d0ead2acf18231ae368d6a664a83f272b0679158da12e97b5229f794939e555cc574478acd - languageName: node - linkType: hard - "chalk@npm:^2.0.0, chalk@npm:^2.0.1, chalk@npm:^2.4.1": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -13437,32 +13353,6 @@ __metadata: languageName: node linkType: hard -"deep-equal@npm:^2.2.2": - version: 2.2.2 - resolution: "deep-equal@npm:2.2.2" - dependencies: - array-buffer-byte-length: ^1.0.0 - call-bind: ^1.0.2 - es-get-iterator: ^1.1.3 - get-intrinsic: ^1.2.1 - is-arguments: ^1.1.1 - is-array-buffer: ^3.0.2 - is-date-object: ^1.0.5 - is-regex: ^1.1.4 - is-shared-array-buffer: ^1.0.2 - isarray: ^2.0.5 - object-is: ^1.1.5 - object-keys: ^1.1.1 - object.assign: ^4.1.4 - regexp.prototype.flags: ^1.5.0 - side-channel: ^1.0.4 - which-boxed-primitive: ^1.0.2 - which-collection: ^1.0.1 - which-typed-array: ^1.1.9 - checksum: eb61c35157b6ecb96a5359b507b083fbff8ddb4c86a78a781ee38485f77a667465e45d63ee2ebd8a00e86d94c80e499906900cd82c2debb400237e1662cd5397 - languageName: node - linkType: hard - "deep-is@npm:^0.1.3, deep-is@npm:~0.1.3": version: 0.1.4 resolution: "deep-is@npm:0.1.4" @@ -13510,7 +13400,7 @@ __metadata: languageName: node linkType: hard -"define-properties@npm:^1.1.3, define-properties@npm:^1.1.4, define-properties@npm:^1.2.0": +"define-properties@npm:^1.1.3, define-properties@npm:^1.1.4": version: 1.2.0 resolution: "define-properties@npm:1.2.0" dependencies: @@ -13520,13 +13410,6 @@ __metadata: languageName: node linkType: hard -"defined@npm:^1.0.1": - version: 1.0.1 - resolution: "defined@npm:1.0.1" - checksum: b1a852300bdb57f297289b55eafdd0c517afaa3ec8190e78fce91b9d8d0c0369d4505ecbdacfd3d98372e664f4a267d9bd793938d4a8c76209c9d9516fbe2101 - languageName: node - linkType: hard - "delay@npm:^5.0.0": version: 5.0.0 resolution: "delay@npm:5.0.0" @@ -14042,17 +13925,6 @@ __metadata: languageName: node linkType: hard -"dotignore@npm:^0.1.2": - version: 0.1.2 - resolution: "dotignore@npm:0.1.2" - dependencies: - minimatch: ^3.0.4 - bin: - ignored: bin/ignored - checksum: 06bab15e2a2400c6f823a0edbcd73661180f6245a4041a3fe3b9fde4b22ae74b896604df4520a877093f05c656bd080087376c9f605bccdea847664c59910f37 - languageName: node - linkType: hard - "drbg.js@npm:^1.0.1": version: 1.0.1 resolution: "drbg.js@npm:1.0.1" @@ -14074,7 +13946,7 @@ __metadata: languageName: node linkType: hard -"duplexer@npm:^0.1.1, duplexer@npm:^0.1.2": +"duplexer@npm:^0.1.2": version: 0.1.2 resolution: "duplexer@npm:0.1.2" checksum: 62ba61a830c56801db28ff6305c7d289b6dc9f859054e8c982abd8ee0b0a14d2e9a8e7d086ffee12e868d43e2bbe8a964be55ddbd8c8957714c87373c7a4f9b0 @@ -14599,53 +14471,6 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.22.1": - version: 1.22.1 - resolution: "es-abstract@npm:1.22.1" - dependencies: - array-buffer-byte-length: ^1.0.0 - arraybuffer.prototype.slice: ^1.0.1 - available-typed-arrays: ^1.0.5 - call-bind: ^1.0.2 - es-set-tostringtag: ^2.0.1 - es-to-primitive: ^1.2.1 - function.prototype.name: ^1.1.5 - get-intrinsic: ^1.2.1 - get-symbol-description: ^1.0.0 - globalthis: ^1.0.3 - gopd: ^1.0.1 - has: ^1.0.3 - has-property-descriptors: ^1.0.0 - has-proto: ^1.0.1 - has-symbols: ^1.0.3 - internal-slot: ^1.0.5 - is-array-buffer: ^3.0.2 - is-callable: ^1.2.7 - is-negative-zero: ^2.0.2 - is-regex: ^1.1.4 - is-shared-array-buffer: ^1.0.2 - is-string: ^1.0.7 - is-typed-array: ^1.1.10 - is-weakref: ^1.0.2 - object-inspect: ^1.12.3 - object-keys: ^1.1.1 - object.assign: ^4.1.4 - regexp.prototype.flags: ^1.5.0 - safe-array-concat: ^1.0.0 - safe-regex-test: ^1.0.0 - string.prototype.trim: ^1.2.7 - string.prototype.trimend: ^1.0.6 - string.prototype.trimstart: ^1.0.6 - typed-array-buffer: ^1.0.0 - typed-array-byte-length: ^1.0.0 - typed-array-byte-offset: ^1.0.0 - typed-array-length: ^1.0.4 - unbox-primitive: ^1.0.2 - which-typed-array: ^1.1.10 - checksum: 614e2c1c3717cb8d30b6128ef12ea110e06fd7d75ad77091ca1c5dbfb00da130e62e4bbbbbdda190eada098a22b27fe0f99ae5a1171dac2c8663b1e8be8a3a9b - languageName: node - linkType: hard - "es-array-method-boxes-properly@npm:^1.0.0": version: 1.0.0 resolution: "es-array-method-boxes-properly@npm:1.0.0" @@ -14653,7 +14478,7 @@ __metadata: languageName: node linkType: hard -"es-get-iterator@npm:^1.1.2, es-get-iterator@npm:^1.1.3": +"es-get-iterator@npm:^1.1.2": version: 1.1.3 resolution: "es-get-iterator@npm:1.1.3" dependencies: @@ -15724,7 +15549,7 @@ __metadata: languageName: node linkType: hard -"ethers@npm:^5.3.1, ethers@npm:^5.6.5, ethers@npm:^5.6.8, ethers@npm:^5.7.2": +"ethers@npm:^5.3.1, ethers@npm:^5.6.8, ethers@npm:^5.7.2": version: 5.7.2 resolution: "ethers@npm:5.7.2" dependencies: @@ -16126,16 +15951,6 @@ __metadata: languageName: node linkType: hard -"figures@npm:^1.4.0": - version: 1.7.0 - resolution: "figures@npm:1.7.0" - dependencies: - escape-string-regexp: ^1.0.5 - object-assign: ^4.1.0 - checksum: d77206deba991a7977f864b8c8edf9b8b43b441be005482db04b0526e36263adbdb22c1c6d2df15a1ad78d12029bd1aa41ccebcb5d425e1f2cf629c6daaa8e10 - languageName: node - linkType: hard - "file-entry-cache@npm:^6.0.1": version: 6.0.1 resolution: "file-entry-cache@npm:6.0.1" @@ -16572,7 +16387,7 @@ __metadata: languageName: node linkType: hard -"functions-have-names@npm:^1.2.2, functions-have-names@npm:^1.2.3": +"functions-have-names@npm:^1.2.2": version: 1.2.3 resolution: "functions-have-names@npm:1.2.3" checksum: c3f1f5ba20f4e962efb71344ce0a40722163e85bee2101ce25f88214e78182d2d2476aa85ef37950c579eb6cf6ee811c17b3101bb84004bb75655f3e33f3fdb5 @@ -16627,18 +16442,6 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.2.1": - version: 1.2.1 - resolution: "get-intrinsic@npm:1.2.1" - dependencies: - function-bind: ^1.1.1 - has: ^1.0.3 - has-proto: ^1.0.1 - has-symbols: ^1.0.3 - checksum: 5b61d88552c24b0cf6fa2d1b3bc5459d7306f699de060d76442cce49a4721f52b8c560a33ab392cf5575b7810277d54ded9d4d39a1ea61855619ebc005aa7e5f - languageName: node - linkType: hard - "get-iterator@npm:^1.0.2": version: 1.0.2 resolution: "get-iterator@npm:1.0.2" @@ -16801,7 +16604,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^7.0.3, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.2.3": +"glob@npm:^7.0.3, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -17090,15 +16893,6 @@ __metadata: languageName: node linkType: hard -"has-ansi@npm:^2.0.0": - version: 2.0.0 - resolution: "has-ansi@npm:2.0.0" - dependencies: - ansi-regex: ^2.0.0 - checksum: 1b51daa0214440db171ff359d0a2d17bc20061164c57e76234f614c91dbd2a79ddd68dfc8ee73629366f7be45a6df5f2ea9de83f52e1ca24433f2cc78c35d8ec - languageName: node - linkType: hard - "has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": version: 1.0.2 resolution: "has-bigints@npm:1.0.2" @@ -17106,16 +16900,6 @@ __metadata: languageName: node linkType: hard -"has-dynamic-import@npm:^2.0.1": - version: 2.0.1 - resolution: "has-dynamic-import@npm:2.0.1" - dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.1.1 - checksum: 1cb60255cdd354a5f53997dd4c8ae0f821706ced3d1047bb810cb74400f28988b08d4d986318cb6610b79e6b9993a6592e678b6cef3ef0b71ab553eaa99b9c4d - languageName: node - linkType: hard - "has-flag@npm:^3.0.0": version: 3.0.0 resolution: "has-flag@npm:3.0.0" @@ -17771,7 +17555,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1, inherits@npm:~2.0.3, inherits@npm:~2.0.4": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 @@ -18392,13 +18176,6 @@ __metadata: languageName: node linkType: hard -"is-finite@npm:^1.0.1": - version: 1.1.0 - resolution: "is-finite@npm:1.1.0" - checksum: 532b97ed3d03e04c6bd203984d9e4ba3c0c390efee492bad5d1d1cd1802a68ab27adbd3ef6382f6312bed6c8bb1bd3e325ea79a8dc8fe080ed7a06f5f97b93e7 - languageName: node - linkType: hard - "is-fullwidth-code-point@npm:^2.0.0": version: 2.0.0 resolution: "is-fullwidth-code-point@npm:2.0.0" @@ -20940,7 +20717,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.5, lodash@npm:^4.7.0": +"lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.5, lodash@npm:^4.7.0": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 @@ -21455,7 +21232,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": +"minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 @@ -23038,13 +22815,6 @@ __metadata: languageName: node linkType: hard -"parse-ms@npm:^1.0.0": - version: 1.0.1 - resolution: "parse-ms@npm:1.0.1" - checksum: 93fa7921554fe16bc73272a94bf812d1db6a144964fb57692f6de4fccf14bd771a232e8dcdcd4bbaa4aa477796cd3f35374d65596cca12323f2664bc023b4b4c - languageName: node - linkType: hard - "parse5-htmlparser2-tree-adapter@npm:^7.0.0": version: 7.0.0 resolution: "parse5-htmlparser2-tree-adapter@npm:7.0.0" @@ -23420,13 +23190,6 @@ __metadata: languageName: node linkType: hard -"plur@npm:^1.0.0": - version: 1.0.0 - resolution: "plur@npm:1.0.0" - checksum: bd8725178b2db5a708293c072631c84a33299dece6e5041835f874064e51c515d201905408c780e48df54d960d32bc0ac2e9e4cfe6d756ec4fff29ba5adfbf6c - languageName: node - linkType: hard - "pngjs@npm:^3.0.0, pngjs@npm:^3.3.0, pngjs@npm:^3.3.3": version: 3.4.0 resolution: "pngjs@npm:3.4.0" @@ -24415,24 +24178,6 @@ __metadata: languageName: node linkType: hard -"pretty-ms@npm:^2.1.0": - version: 2.1.0 - resolution: "pretty-ms@npm:2.1.0" - dependencies: - is-finite: ^1.0.1 - parse-ms: ^1.0.0 - plur: ^1.0.0 - checksum: a6a3df561f761902080df23407fc549cc3042fd685d8d2906e6cc2bd5024a814fb2bd4bd061e24879a8540c3aa48faba366421d5b49c268fbfb3501493835c2a - languageName: node - linkType: hard - -"process-nextick-args@npm:~1.0.6": - version: 1.0.7 - resolution: "process-nextick-args@npm:1.0.7" - checksum: 41224fbc803ac6c96907461d4dfc20942efa3ca75f2d521bcf7cf0e89f8dec127fb3fb5d76746b8fb468a232ea02d84824fae08e027aec185fd29049c66d49f8 - languageName: node - linkType: hard - "process-nextick-args@npm:~2.0.0": version: 2.0.1 resolution: "process-nextick-args@npm:2.0.1" @@ -24970,13 +24715,6 @@ __metadata: languageName: node linkType: hard -"re-emitter@npm:1.1.3": - version: 1.1.3 - resolution: "re-emitter@npm:1.1.3" - checksum: 3234850c26c4e51622ad7e54172396134cd510c2511da680275ab1e663e5d12c8b81e3e6f4ec025527ed241ad53dae9d1478c0148569840d2fec96a37d155431 - languageName: node - linkType: hard - "react-animation@npm:1.2.2": version: 1.2.2 resolution: "react-animation@npm:1.2.2" @@ -26042,21 +25780,6 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:2.2.9": - version: 2.2.9 - resolution: "readable-stream@npm:2.2.9" - dependencies: - buffer-shims: ~1.0.0 - core-util-is: ~1.0.0 - inherits: ~2.0.1 - isarray: ~1.0.0 - process-nextick-args: ~1.0.6 - string_decoder: ~1.0.0 - util-deprecate: ~1.0.1 - checksum: d186b7051c4a25b769fa158d1025da83dfb0052f8b0889df40e8e942d05b4d0d37470c49cfd73cce886db66d1a8cd5ec5e2ce97857894587d8158da5ed93baa7 - languageName: node - linkType: hard - "readable-stream@npm:> 1.0.0 < 3.0.0, readable-stream@npm:^2.0.1, readable-stream@npm:^2.2.10, readable-stream@npm:^2.2.2, readable-stream@npm:^2.2.8, readable-stream@npm:^2.3.0, readable-stream@npm:^2.3.5, readable-stream@npm:~2.3.6": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" @@ -26242,17 +25965,6 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.5.0": - version: 1.5.0 - resolution: "regexp.prototype.flags@npm:1.5.0" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - functions-have-names: ^1.2.3 - checksum: c541687cdbdfff1b9a07f6e44879f82c66bbf07665f9a7544c5fd16acdb3ec8d1436caab01662d2fbcad403f3499d49ab0b77fbc7ef29ef961d98cc4bc9755b4 - languageName: node - linkType: hard - "regexpp@npm:^3.1.0": version: 3.2.0 resolution: "regexpp@npm:3.2.0" @@ -26321,13 +26033,6 @@ __metadata: languageName: node linkType: hard -"repeat-string@npm:^1.5.2": - version: 1.6.1 - resolution: "repeat-string@npm:1.6.1" - checksum: 1b809fc6db97decdc68f5b12c4d1a671c8e3f65ec4a40c238bc5200e44e85bcc52a54f78268ab9c29fcf5fe4f1343e805420056d1f30fa9a9ee4c2d93e3cc6c0 - languageName: node - linkType: hard - "request@npm:^2.79.0": version: 2.88.2 resolution: "request@npm:2.88.2" @@ -26783,18 +26488,6 @@ __metadata: languageName: node linkType: hard -"safe-array-concat@npm:^1.0.0": - version: 1.0.0 - resolution: "safe-array-concat@npm:1.0.0" - dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.2.0 - has-symbols: ^1.0.3 - isarray: ^2.0.5 - checksum: f43cb98fe3b566327d0c09284de2b15fb85ae964a89495c1b1a5d50c7c8ed484190f4e5e71aacc167e16231940079b326f2c0807aea633d47cc7322f40a6b57f - languageName: node - linkType: hard - "safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": version: 5.1.2 resolution: "safe-buffer@npm:5.1.2" @@ -27683,15 +27376,6 @@ __metadata: languageName: node linkType: hard -"split@npm:1.0.0": - version: 1.0.0 - resolution: "split@npm:1.0.0" - dependencies: - through: 2 - checksum: 84837fa659662fab703efb41f5e3b3c4ae7de605555b6ce53c4fadb2a30b7cc7c8c005f905e6cb16e527ebb4117b6c2da1fe09c1caa150bdaf24df0dff8bf5d3 - languageName: node - linkType: hard - "sprintf-js@npm:1.1.2": version: 1.1.2 resolution: "sprintf-js@npm:1.1.2" @@ -28024,15 +27708,6 @@ __metadata: languageName: node linkType: hard -"string_decoder@npm:~1.0.0": - version: 1.0.3 - resolution: "string_decoder@npm:1.0.3" - dependencies: - safe-buffer: ~5.1.0 - checksum: 57ef02a148fd1ff2f20fe1accd944505ed3703e78bb28d302d940b2ad3dfb469508f79dcd0275ba1960d9675aa206452f76b2416059a6d0b0200bd7e9f552cdb - languageName: node - linkType: hard - "string_decoder@npm:~1.1.1": version: 1.1.1 resolution: "string_decoder@npm:1.1.1" @@ -28053,15 +27728,6 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^3.0.0": - version: 3.0.1 - resolution: "strip-ansi@npm:3.0.1" - dependencies: - ansi-regex: ^2.0.0 - checksum: 9b974de611ce5075c70629c00fa98c46144043db92ae17748fb780f706f7a789e9989fd10597b7c2053ae8d1513fd707816a91f1879b2f71e6ac0b6a863db465 - languageName: node - linkType: hard - "strip-ansi@npm:^5.0.0, strip-ansi@npm:^5.1.0, strip-ansi@npm:^5.2.0": version: 5.2.0 resolution: "strip-ansi@npm:5.2.0" @@ -28308,13 +27974,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^2.0.0": - version: 2.0.0 - resolution: "supports-color@npm:2.0.0" - checksum: 602538c5812b9006404370b5a4b885d3e2a1f6567d314f8b4a41974ffe7d08e525bf92ae0f9c7030e3b4c78e4e34ace55d6a67a74f1571bc205959f5972f88f0 - languageName: node - linkType: hard - "supports-color@npm:^5.3.0, supports-color@npm:^5.5.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -28515,39 +28174,6 @@ __metadata: languageName: node linkType: hard -"tap-out@npm:^2.1.0": - version: 2.1.0 - resolution: "tap-out@npm:2.1.0" - dependencies: - re-emitter: 1.1.3 - readable-stream: 2.2.9 - split: 1.0.0 - trim: 0.0.1 - bin: - tap-out: bin/cmd.js - checksum: b837d8adf646bf06f73a9306a9796a3201c55598c2c70045a2908d044fc2cc9466d52d27a7705c92a2c6ea37d560a84d135f4112bd377346f34d381ed836088b - languageName: node - linkType: hard - -"tap-spec@npm:^5.0.0": - version: 5.0.0 - resolution: "tap-spec@npm:5.0.0" - dependencies: - chalk: ^1.0.0 - duplexer: ^0.1.1 - figures: ^1.4.0 - lodash: ^4.17.10 - pretty-ms: ^2.1.0 - repeat-string: ^1.5.2 - tap-out: ^2.1.0 - through2: ^2.0.0 - bin: - tap-spec: bin/cmd.js - tspec: bin/cmd.js - checksum: 4413acc3ed4b8662b64439ad5be65a4d42edb2f3c5dc273b8ee563f9e7bfdde347e53c92de628a04ab640dda3cd8aea8aeb3ee7aa86bde8118d0584ffd76b788 - languageName: node - linkType: hard - "tapable@npm:^1.0.0": version: 1.1.3 resolution: "tapable@npm:1.1.3" @@ -28562,37 +28188,6 @@ __metadata: languageName: node linkType: hard -"tape@npm:^5.5.3": - version: 5.6.6 - resolution: "tape@npm:5.6.6" - dependencies: - "@ljharb/resumer": ^0.0.1 - "@ljharb/through": ^2.3.9 - array.prototype.every: ^1.1.4 - call-bind: ^1.0.2 - deep-equal: ^2.2.2 - defined: ^1.0.1 - dotignore: ^0.1.2 - for-each: ^0.3.3 - get-package-type: ^0.1.0 - glob: ^7.2.3 - has: ^1.0.3 - has-dynamic-import: ^2.0.1 - inherits: ^2.0.4 - is-regex: ^1.1.4 - minimist: ^1.2.8 - object-inspect: ^1.12.3 - object-is: ^1.1.5 - object-keys: ^1.1.1 - object.assign: ^4.1.4 - resolve: ^2.0.0-next.4 - string.prototype.trim: ^1.2.7 - bin: - tape: bin/tape - checksum: aac4722c7104f8478c8079aa1f441636b720f432074355c2edb1b0c0e2f2822004af2097669186d65ce7c70c57164d85d7da3662338e53515bdb778f5412af30 - languageName: node - linkType: hard - "tar-stream@npm:^1.6.2": version: 1.6.2 resolution: "tar-stream@npm:1.6.2" @@ -28775,7 +28370,7 @@ __metadata: languageName: node linkType: hard -"through2@npm:^2.0.0, through2@npm:^2.0.2, through2@npm:^2.0.3": +"through2@npm:^2.0.2, through2@npm:^2.0.3": version: 2.0.5 resolution: "through2@npm:2.0.5" dependencies: @@ -28785,7 +28380,7 @@ __metadata: languageName: node linkType: hard -"through@npm:2, through@npm:>=2.2.7 <3": +"through@npm:>=2.2.7 <3": version: 2.3.8 resolution: "through@npm:2.3.8" checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd @@ -29016,13 +28611,6 @@ __metadata: languageName: node linkType: hard -"trim@npm:0.0.1": - version: 0.0.1 - resolution: "trim@npm:0.0.1" - checksum: 2b4646dff99a222e8e1526edd4e3a43bbd925af0b8e837c340455d250157e7deefaa4da49bb891ab841e5c27b1afc5e9e32d4b57afb875d2dfcabf4e319b8f7f - languageName: node - linkType: hard - "tryer@npm:^1.0.1": version: 1.0.1 resolution: "tryer@npm:1.0.1" @@ -29233,42 +28821,6 @@ __metadata: languageName: node linkType: hard -"typed-array-buffer@npm:^1.0.0": - version: 1.0.0 - resolution: "typed-array-buffer@npm:1.0.0" - dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.2.1 - is-typed-array: ^1.1.10 - checksum: 3e0281c79b2a40cd97fe715db803884301993f4e8c18e8d79d75fd18f796e8cd203310fec8c7fdb5e6c09bedf0af4f6ab8b75eb3d3a85da69328f28a80456bd3 - languageName: node - linkType: hard - -"typed-array-byte-length@npm:^1.0.0": - version: 1.0.0 - resolution: "typed-array-byte-length@npm:1.0.0" - dependencies: - call-bind: ^1.0.2 - for-each: ^0.3.3 - has-proto: ^1.0.1 - is-typed-array: ^1.1.10 - checksum: b03db16458322b263d87a702ff25388293f1356326c8a678d7515767ef563ef80e1e67ce648b821ec13178dd628eb2afdc19f97001ceae7a31acf674c849af94 - languageName: node - linkType: hard - -"typed-array-byte-offset@npm:^1.0.0": - version: 1.0.0 - resolution: "typed-array-byte-offset@npm:1.0.0" - dependencies: - available-typed-arrays: ^1.0.5 - call-bind: ^1.0.2 - for-each: ^0.3.3 - has-proto: ^1.0.1 - is-typed-array: ^1.1.10 - checksum: 04f6f02d0e9a948a95fbfe0d5a70b002191fae0b8fe0fe3130a9b2336f043daf7a3dda56a31333c35a067a97e13f539949ab261ca0f3692c41603a46a94e960b - languageName: node - linkType: hard - "typed-array-length@npm:^1.0.4": version: 1.0.4 resolution: "typed-array-length@npm:1.0.4" @@ -30603,19 +30155,6 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.10": - version: 1.1.11 - resolution: "which-typed-array@npm:1.1.11" - dependencies: - available-typed-arrays: ^1.0.5 - call-bind: ^1.0.2 - for-each: ^0.3.3 - gopd: ^1.0.1 - has-tostringtag: ^1.0.0 - checksum: 711ffc8ef891ca6597b19539075ec3e08bb9b4c2ca1f78887e3c07a977ab91ac1421940505a197758fb5939aa9524976d0a5bbcac34d07ed6faa75cedbb17206 - languageName: node - linkType: hard - "which-typed-array@npm:^1.1.2, which-typed-array@npm:^1.1.9": version: 1.1.9 resolution: "which-typed-array@npm:1.1.9" From b5f4076d8608d1b233d370d9afd732640c4c1f1d Mon Sep 17 00:00:00 2001 From: Nilesh Gupta Date: Wed, 6 Mar 2024 17:24:24 +0530 Subject: [PATCH 5/5] Added Snap snooze/disable-snooze triggers from dapp (#1438) * fix:css * feat:Snooze refactor * Fix:UI changes * fix:added Enable snooze functionality + displayed time * fix: Navigate to previous modal * fix:snooze duration * fix:Snooze duration * Added fixes for snap triggers * Removed unnecessary states from context --------- Co-authored-by: Ruthu Rao --- src/components/PushSnap/EnableSnoozeModal.tsx | 181 +++++++++ .../PushSnap/PushSnapConfigureModal.tsx | 371 +++++++++--------- src/components/PushSnap/PushSnapSettings.tsx | 345 ++++++++-------- src/config/index.js | 2 + src/helpers/TimerHelper.ts | 19 + src/helpers/index.ts | 28 +- .../receiveNotifs/MetamaskPushSnapModal.tsx | 164 ++++---- src/types/index.ts | 4 + 8 files changed, 689 insertions(+), 425 deletions(-) create mode 100644 src/components/PushSnap/EnableSnoozeModal.tsx create mode 100644 src/types/index.ts diff --git a/src/components/PushSnap/EnableSnoozeModal.tsx b/src/components/PushSnap/EnableSnoozeModal.tsx new file mode 100644 index 0000000000..bbd77af532 --- /dev/null +++ b/src/components/PushSnap/EnableSnoozeModal.tsx @@ -0,0 +1,181 @@ +// React + Web3 Essentials +import React, { useState } from 'react'; + +// External Packages +import styled, { useTheme } from 'styled-components'; + +// Internal Compoonents +import { ItemHV2, ItemVV2, ButtonV2 } from 'components/reusables/SharedStylingV2'; + +// Internal Configs +import { device } from 'config/Globals'; +import { AppContext } from 'contexts/AppContext'; +import { SnoozeDurationType } from 'types'; +import { updateSnoozeDuration } from 'helpers'; +import { defaultSnapOrigin } from 'config'; + +const EnableSnoozeModal = ({ + setSnoozeDuration +}: + {setSnoozeDuration: (snoozeDuration: SnoozeDurationType) => void} +) => { + const { setSnapState } = React.useContext(AppContext); + const theme = useTheme(); + + const [snoozeDurationInput, setSnoozeDurationInput] = useState(1); + + const handleChange = async () => { + const duration = snoozeDurationInput; + + if (duration >= 1 && duration <= 72) { + await window.ethereum?.request({ + method: 'wallet_invokeSnap', + params: { + snapId: defaultSnapOrigin, + request: { + method: 'pushproto_setsnoozeduration', + params: { snoozeDuration: snoozeDurationInput.toString()}, + }, + }, + }) + + setSnapState(3); + } else { + // Display an error message if the input is invalid + console.error('Invalid input. Please enter a number between 1 and 72.'); + } + await updateSnoozeDuration(setSnoozeDuration); + }; + + const handleCancel = async () => { + setSnapState(3); // go back to step one + }; + + return ( + + + Set Snooze Duration + + How long would you like to snooze notifications? You can snooze for 1 to 72 hours. + + { + const duration = parseInt(e.target.value); + if (!isNaN(duration) && duration >= 1 && duration <= 72) { + setSnoozeDurationInput(duration); + } + }} + placeholder="Snooze duration in Hours (e.g. 6)" + /> + + + + + Cancel + + Enable Snooze + + + ); +}; + +export default EnableSnoozeModal; + +const Container = styled(ItemVV2)` + padding: 0px 0px 12px 9px; +`; + +const PrimaryText = styled.p` + margin: 0px; + font-size: 18px; + font-weight: 500; + align-self: baseline; + color: ${(props) => props.theme.modalMessageColor}; +`; + +const SecondaryText = styled.p` + margin: 0px; + font-size: 12px; + font-weight: 400; + line-height: 24px; + text-align: left; + overflow: hidden; + text-overflow: ellipsis; // Show ellipsis (...) when text overflows + + color: ${(props) => props.theme.snapSecondaryText}; +`; + +const SnapButton = styled(ButtonV2)` + align-self: end; + height: 36px; + z-index: 0; + font-family: 'Strawford'; + font-style: normal; + font-weight: 500; + font-size: 14px; + line-height: normal; + border-radius: 8px; +`; + +const FilledButton = styled(SnapButton)` + min-width: 79px; + padding: 14px; + background: #d53a94; + height: 48px; + radius: 12px; + padding: 0px 24px 0px 24px; + color: #fff; + white-space: nowrap; +`; + +const EnptyButton = styled(SnapButton)` + flex-direction: row; + text-align: center; + height: 48px; + padding: 0px 24px 0px 24px; + margin-right: 8px; + border: 1px solid #bac4d6; + color: ${(props) => props.theme.default.color}; + background: ${(props) => props.theme.default.bg}; + gap: 4px; +`; + +const Input = styled.input` + box-sizing: border-box; + display: flex; + flex: 1; + width: 240px; + height: 48px; + padding: 13px 16px 13px 16px; + margin: 10px 3px 0px; + background: ${(props) => props.theme.modalSearchBarBackground}; + + border-radius: 12px; + border: 1px solid #bac4d6; + + color: ${(props) => props.theme.default.secondaryColor || '#000'}; + &:focus { + outline: none; + background-origin: border; + border: 1px solid #bac4d6 !important; + background-clip: padding-box, border-box; + } + &::placeholder { + color: ${(props) => props.theme.default.secondaryColor || '#000'}; + } + @media ${device.mobileL} { + min-width: 300px; + } +`; diff --git a/src/components/PushSnap/PushSnapConfigureModal.tsx b/src/components/PushSnap/PushSnapConfigureModal.tsx index b14fab4240..96352390f1 100644 --- a/src/components/PushSnap/PushSnapConfigureModal.tsx +++ b/src/components/PushSnap/PushSnapConfigureModal.tsx @@ -9,64 +9,73 @@ import styled, { useTheme } from 'styled-components'; // Internal Compoonents import { ReactComponent as MinusCircle } from 'assets/PushSnaps/MinusCircle.svg'; -import InfoImage from "assets/info.svg"; import { Button } from 'components/SharedStyling'; import { ItemHV2, ItemVV2, SpanV2 } from 'components/reusables/SharedStylingV2'; -import Tooltip from 'components/reusables/tooltip/Tooltip'; import { shortenText } from 'helpers/UtilityHelper'; import { useAccount } from 'hooks'; +import { AppContext } from 'contexts/AppContext'; // Internal Configs import { device } from 'config/Globals'; - - -const PushSnapConfigureModal = () => { - const [walletAddresses, setWalletAddresses] = useState([]); +import { SnoozeDurationType } from 'types'; +import { updateSnoozeDuration } from 'helpers'; +import { defaultSnapOrigin } from 'config'; + +const PushSnapConfigureModal = ({ + snoozeDuration, setSnoozeDuration +}: + {snoozeDuration: SnoozeDurationType, setSnoozeDuration: (snoozeDuration: SnoozeDurationType) => void} +) => { const [addresses, setAddresses] = useState([]); const [searchedUser, setSearchedUser] = useState(''); - const [showRemove, setShowRemove] = useState(); - const [toggleStatus, setToggleStatus] = useState(0); - const theme = useTheme(); + const { setSnapState, SnapState } = React.useContext(AppContext); - const defaultSnapOrigin = 'npm:@pushprotocol/snap'; + useEffect(() => { + setChecked(SnapState === 6); + }, [SnapState]); + + const theme = useTheme(); const { chainId, account, provider } = useAccount(); useEffect(() => { - (async function () { - const res = await window.ethereum?.request({ + (async function() { + getWalletAddresses(); + await updateSnoozeDuration(setSnoozeDuration); + })(); + }, []); + + + const disableSnooze = async () => { + await window.ethereum?.request({ method: 'wallet_invokeSnap', params: { snapId: defaultSnapOrigin, request: { - method: 'pushproto_gettogglestatus', - params: { address: searchedUser }, + method: 'pushproto_disablesnooze', }, }, - }); - setToggleStatus(res); - })(); - }, [toggleStatus]); - - useEffect(() => { - getWalletAddresses(); - }, []); + }) + }; async function getSignature(mode: number) { if (mode == 1) { const signer = provider.getSigner(account); - const signature = await signer.signMessage(`Add address ${account} to receive notifications via Push Snap in MetaMask`); + const signature = await signer.signMessage( + `Add address ${account} to receive notifications via Push Snap in MetaMask` + ); return signature; } if (mode == 2) { const signer = provider.getSigner(account); - const signature = await signer.signMessage(`Remove address ${account} to stop receive notifications via Push Snap in MetaMask`); + const signature = await signer.signMessage( + `Remove address ${account} to stop receive notifications via Push Snap in MetaMask` + ); return signature; } } const addWalletAddresses = async () => { - console.debug('searchedUser', searchedUser); const signatureResult = await getSignature(1); if (signatureResult) { if (searchedUser) { @@ -89,25 +98,25 @@ const PushSnapConfigureModal = () => { }; const [checked, setChecked] = useState(false); + + useEffect(() => { + setChecked(snoozeDuration.enabled); + }, [snoozeDuration]); + const handleChange = async (nextChecked) => { setChecked(nextChecked); - await window.ethereum?.request({ - method: 'wallet_invokeSnap', - params: { - snapId: defaultSnapOrigin, - request: { method: 'pushproto_togglepopup' }, - }, - }); - if (toggleStatus < 40) { - setToggleStatus(42); + + // When the switch is turned on + if (nextChecked) { + setSnapState(4); // Enable snooze or show the EnableSnoozeModal } else { - setToggleStatus(0); + await disableSnooze(); } + await updateSnoozeDuration(setSnoozeDuration); }; const removeWalletAddresses = async (walletSelected: string) => { const signatureResult = await getSignature(2); - console.log("Ran",signatureResult) if (signatureResult) { if (walletSelected) { await window.ethereum?.request({ @@ -137,27 +146,27 @@ const PushSnapConfigureModal = () => { }); console.debug('result', result); setAddresses(result); - } + }; const containerRef = React.useRef(null); useClickAway(containerRef, () => { - console.warn('Set show to be null'); setWalletSelected(null); - setShowRemove(null); }); const [walletSelected, setWalletSelected] = useState(); const handleWalletSelect = (address) => { setWalletSelected(address); - } + }; return ( - - + Notification Address Add or remove wallet address to receive notifications @@ -169,133 +178,130 @@ const PushSnapConfigureModal = () => { }} placeholder="0x123 .... 4567" /> - - Add - - - + Add + {addresses?.map((wallet) => ( - - {shortenText(wallet, 8)} - handleWalletSelect(wallet)} color={theme.default.color} /> - - {walletSelected === wallet && - - removeWalletAddresses(walletSelected)}>Remove - - } + + + {shortenText(wallet, 8)} + + handleWalletSelect(wallet)} + color={theme.default.color} + /> + + {walletSelected === wallet && ( + + + removeWalletAddresses(walletSelected)} + > + Remove + + + )} ))} - - - - - Snooze Notification Pop-ups - - - - - - 40} - className="react-switch" - uncheckedIcon={false} - checkedIcon={false} - height={23} - onColor="#D53A94" - width={44} - /> - - {toggleStatus > 40 ? 'On' : 'Off'} - + + {' '} + Snooze Notifications{' '} + + + + {' '} + + + + + + + When snooze is enabled, you won't receive notifications for
a specified period of time. +
-
-
+ + + + {snoozeDuration.enabled == true ? ( + <> + + {' '} + Snooze Duration{' '} + + + + {' '} + {snoozeDuration.hrsLeft} hours + + + ) : ( + '' + )} + + ); }; export default PushSnapConfigureModal; -const InfoToolTip = () => { - - - return ( - - Toggle popups in case of frequent incoming notifications - - } - > - - - - - - ) -} - const Container = styled(ItemVV2)` padding: 0px 0px 12px 9px; `; const ToolTipContainer = styled(ItemVV2)` -box-sizing: border-box; -width: 18.75rem; -// height: 7.5rem; -// max-height: 7.5rem; -background: ${(props) => props.theme.default.bg}; -border-radius: 1rem 1rem 1rem 0.125rem; -justify-content: flex-start; -border: 1px solid rgba(173, 176, 190, 0.2); -align-items: flex-start; -padding: 0.75rem 0.25rem 0.75rem 1rem; -box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.05); - -@media (max-width:400px){ - width:16.75rem; -} - - + box-sizing: border-box; + width: 18.75rem; + // height: 7.5rem; + // max-height: 7.5rem; + background: ${(props) => props.theme.default.bg}; + border-radius: 1rem 1rem 1rem 0.125rem; + justify-content: flex-start; + border: 1px solid rgba(173, 176, 190, 0.2); + align-items: flex-start; + padding: 0.75rem 0.25rem 0.75rem 1rem; + box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.05); + + @media (max-width: 400px) { + width: 16.75rem; + } `; const PrimaryText = styled.p` @@ -303,16 +309,19 @@ const PrimaryText = styled.p` font-size: 18px; font-weight: 500; align-self: baseline; - color:${(props) => props.theme.modalMessageColor}; + color: ${(props) => props.theme.modalMessageColor}; `; const SecondaryText = styled.p` margin: 0px; - font-size: 16px; + font-size: 12px; font-weight: 400; line-height: 24px; text-align: left; - color:${(props) => props.theme.snapSecondaryText}; + overflow: hidden; + text-overflow: ellipsis; // Show ellipsis (...) when text overflows + + color: ${(props) => props.theme.snapSecondaryText}; `; const ToolTipText = styled.p` @@ -323,25 +332,27 @@ const ToolTipText = styled.p` color: #62626a; color: ${(props) => props.theme.modalMessageColor}; text-align: left; -` +`; const SnapButton = styled(Button)` -align-self: end; -height: 36px; -z-index: 0; -font-family: 'Strawford'; -font-style: normal; -font-weight: 500; -font-size: 14px; -line-height: normal; -border-radius: 8px; -` + align-self: end; + height: 36px; + z-index: 0; + font-family: 'Strawford'; + font-style: normal; + font-weight: 500; + font-size: 14px; + line-height: normal; + border-radius: 8px; +`; const FilledButton = styled(SnapButton)` min-width: 79px; padding: 14px; background: #d53a94; - width: fit-content; + width: 79px; + height: 48px; + radius: 12px; color: #fff; `; @@ -349,12 +360,12 @@ const EnptyButton = styled(SnapButton)` flex-direction: row; color: ${(props) => props.theme.default.secondaryColor}; text-align: center; - width:auto; + width: auto; padding: 16px 24px; border: 1px solid #bac4d6; background: ${(props) => props.theme.default.bg}; gap: 4px; -` +`; const ImageInfo = styled.img` margin-right: 5px; @@ -369,10 +380,10 @@ const Input = styled.input` box-sizing: border-box; display: flex; flex: 1; - width: 100%; + width: 240px; height: 48px; - padding: 13px 16px; - margin: 10px 0px 0px; + padding: 13px 16px 13px 16px; + margin: 10px 3px 0px; background: ${(props) => props.theme.modalSearchBarBackground}; border-radius: 12px; @@ -394,15 +405,15 @@ const Input = styled.input` `; const AddressesContainer = styled.div` - display:flex; - flex-direction:column; + display: flex; + flex-direction: column; width: -webkit-fill-available; overflow-y: scroll; gap: 8px; - margin:8px 0 0 0; + margin: 8px 0 0 0; max-height: 250px; flex-wrap: nowrap; - padding:5px 5px 5px 0; + padding: 5px 5px 5px 0; &::-webkit-scrollbar-track { border-radius: 10px; } @@ -422,7 +433,7 @@ const AddressesContainer = styled.div` color-stop(0.86, #cf1c84) ); } -` +`; const AddressesSubContainer = styled(ItemHV2)` max-height: 42px; @@ -430,18 +441,18 @@ const AddressesSubContainer = styled(ItemHV2)` border-radius: 12px; background: ${(props) => props.theme.snapBackground}; justify-content: space-between; -` +`; const MoreOptions = styled(AiOutlineMore)` - width:24px; - height:24px; - cursor:pointer; -` + width: 24px; + height: 24px; + cursor: pointer; +`; const RemoveDiv = styled(ItemHV2)` border-radius: 12px; - border: 1px solid #BAC4D6; - background: #FFF; + border: 1px solid #bac4d6; + background: #fff; cursor: pointer; box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.05); padding: 8px 12px 8px 8px; @@ -450,4 +461,4 @@ const RemoveDiv = styled(ItemHV2)` position: absolute; right: 0; top: 3px; -` +`; diff --git a/src/components/PushSnap/PushSnapSettings.tsx b/src/components/PushSnap/PushSnapSettings.tsx index b93a413b36..47573efeb3 100644 --- a/src/components/PushSnap/PushSnapSettings.tsx +++ b/src/components/PushSnap/PushSnapSettings.tsx @@ -12,192 +12,185 @@ import PushSnapConfigureModal from './PushSnapConfigureModal'; import useModalBlur, { MODAL_POSITION } from 'hooks/useModalBlur'; import AboutSnapModal from 'modules/snap/AboutSnapModal'; - const PushSnapSettings = () => { - const { account, provider } = useAccount(); - - const theme = useTheme(); - const [walletConnected, setWalletConnected] = useState(false); - const [loading, setLoading] = useState(false); - const [addedAddress, setAddedAddress] = useState(false); - - const [snapInstalled, setSnapInstalled] = useState(false); - const defaultSnapOrigin = `npm:@pushprotocol/snap`; - - async function getInstalledSnaps() { - const installedSnaps = await window.ethereum.request({ - method: 'wallet_getSnaps', - }); - console.debug("Snaps installed", installedSnaps); - Object.keys(installedSnaps).forEach((snap) => { - if (snap == 'npm:@pushprotocol/snap') { - setSnapInstalled(true); - } - }); - } - async function getWalletAddresses() { - const result = await window.ethereum?.request({ - method: 'wallet_invokeSnap', - params: { - snapId: defaultSnapOrigin, - request: { method: 'pushproto_getaddresses' }, - }, - }); - - console.debug(account); - console.debug(walletConnected); - if (result.includes(account)) { - setAddedAddress(true); - } else { - setAddedAddress(false); - } + const { account, provider } = useAccount(); + + const theme = useTheme(); + const [walletConnected, setWalletConnected] = useState(false); + const [loading, setLoading] = useState(false); + const [addedAddress, setAddedAddress] = useState(false); + + const [snapInstalled, setSnapInstalled] = useState(false); + const defaultSnapOrigin = `npm:@pushprotocol/snap`; + + async function getInstalledSnaps() { + const installedSnaps = await window.ethereum.request({ + method: 'wallet_getSnaps', + }); + console.debug('Snaps installed', installedSnaps); + Object.keys(installedSnaps).forEach((snap) => { + if (snap == 'npm:@pushprotocol/snap') { + setSnapInstalled(true); + } + }); + } + async function getWalletAddresses() { + const result = await window.ethereum?.request({ + method: 'wallet_invokeSnap', + params: { + snapId: defaultSnapOrigin, + request: { method: 'pushproto_getaddresses' }, + }, + }); + + console.debug(account); + console.debug(walletConnected); + if (result.includes(account)) { + setAddedAddress(true); + } else { + setAddedAddress(false); } + } + useEffect(() => { + getInstalledSnaps(); + getWalletAddresses(); + }, [account, walletConnected]); + + async function connectSnap() { + let snapId = defaultSnapOrigin, + params = {}; + await window.ethereum?.request({ + method: 'wallet_requestSnaps', + params: { + [snapId]: params, + }, + }); + console.info('Snap Installed'); + } - useEffect(() => { - getInstalledSnaps(); - getWalletAddresses(); - }, [account, walletConnected]); - - - async function connectSnap() { - let snapId = defaultSnapOrigin, - params = {}; - await window.ethereum?.request({ - method: 'wallet_requestSnaps', - params: { - [snapId]: params, - }, - }); - console.info('Snap Installed'); - } - - async function connectToMetaMask() { - setLoading(true); - try { - if (!snapInstalled) { - await connectSnap(); - setSnapInstalled(true); - } - setLoading(false); - } catch (error) { - setLoading(false); - console.error('Error', error); - } + async function connectToMetaMask() { + setLoading(true); + try { + if (!snapInstalled) { + await connectSnap(); + setSnapInstalled(true); + } + setLoading(false); + } catch (error) { + setLoading(false); + console.error('Error', error); } + } - console.info("snapInstalled", snapInstalled); - - const InstallSnap = () => { - const { - isModalOpen: isMetamaskPushSnapOpen, - showModal: showPushSnapAbout, - ModalComponent: AboutPushSnapModalComponent, - } = useModalBlur(); - return ( - - - - - - - - - - - - Push Snap - - - powered by MetaMask - - - - - - You’re about to install Push Snap which allows you to receive notifications from Push directly on - MetaMask! - - - - - - {loading ? ( - - ) : ( - connectToMetaMask()}> - {!snapInstalled && 'Connect Snap'} - - )} - - - - - - About this Snap - - - - - - - ) - } + console.info('snapInstalled', snapInstalled); + const InstallSnap = () => { + const { + isModalOpen: isMetamaskPushSnapOpen, + showModal: showPushSnapAbout, + ModalComponent: AboutPushSnapModalComponent, + } = useModalBlur(); return ( - <> - {!snapInstalled ? : ( - <> - - Push Snap Settings - - - + + + + + + + + + + + Push Snap + + + powered by MetaMask + + + + + + You’re about to install Push Snap which allows you to receive notifications from Push directly on + MetaMask! + + + + + + {loading ? ( + + ) : ( + connectToMetaMask()}>{!snapInstalled && 'Connect Snap'} )} + + + + + + About this Snap + + + + + ); + }; + return ( + <> + {!snapInstalled ? ( + + ) : ( + <> + + Snap Settings + + - ); + )} + + ); }; export default PushSnapSettings; @@ -243,4 +236,4 @@ const ConnectButton = styled(SnapButton)` const InfoDiv = styled(ItemHV2)` cursor: pointer; -`; \ No newline at end of file +`; diff --git a/src/config/index.js b/src/config/index.js index aab9cdf67e..c86f14108c 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -30,3 +30,5 @@ const appConfig = { ...dynamicConfig, ...generalConfig }; // export it out export { appConfig, addresses, abis, CHAIN_DETAILS }; + +export const defaultSnapOrigin = 'npm:@pushprotocol/snap'; \ No newline at end of file diff --git a/src/helpers/TimerHelper.ts b/src/helpers/TimerHelper.ts index eabfa323a2..831bc684a1 100644 --- a/src/helpers/TimerHelper.ts +++ b/src/helpers/TimerHelper.ts @@ -43,3 +43,22 @@ export const convertTimestampToDateDayTime = (time: Date):string => { } return `${time.getDate()}/${time.getMonth() + 1}/${time.getFullYear() % 100}`; }; + +export const hoursLeftToTimestamp = (futureTimestamp: number) => { + // Get the current timestamp + const currentTimestamp = Date.now(); + + // Calculate the difference between the future timestamp and the current timestamp + const timeDifference = futureTimestamp - currentTimestamp; + + // If the difference is negative, it means the future timestamp is in the past + if (timeDifference < 0) { + return 0; // Return 0 hours left + } + + // Convert the time difference from milliseconds to hours + const hoursLeft = Math.ceil(timeDifference / (1000 * 60 * 60)); + + // Return the number of hours left + return hoursLeft; +} \ No newline at end of file diff --git a/src/helpers/index.ts b/src/helpers/index.ts index 27d13a7ee8..4607237572 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -1 +1,27 @@ -export * from "./PushTokenContractHelper"; \ No newline at end of file +import { defaultSnapOrigin } from "config"; +import { hoursLeftToTimestamp } from "./TimerHelper"; + +export * from "./PushTokenContractHelper"; + +export const updateSnoozeDuration = async (setSnoozeDuration) => { + const result = await window.ethereum?.request({ + method: 'wallet_invokeSnap', + params: { + snapId: defaultSnapOrigin, + request: { method: 'pushproto_getsnoozeinfo' }, + }, + }); + + if (result?.enabled === true) { + const hrsLeft = hoursLeftToTimestamp(result.duration); + setSnoozeDuration({ + enabled: true, + hrsLeft: hrsLeft + }); + } else { + setSnoozeDuration({ + enabled: false, + hrsLeft: 0 + }); + } + }; \ No newline at end of file diff --git a/src/modules/receiveNotifs/MetamaskPushSnapModal.tsx b/src/modules/receiveNotifs/MetamaskPushSnapModal.tsx index d2f94cc56d..7c575836a6 100644 --- a/src/modules/receiveNotifs/MetamaskPushSnapModal.tsx +++ b/src/modules/receiveNotifs/MetamaskPushSnapModal.tsx @@ -13,88 +13,116 @@ import { Button } from 'components/SharedStyling'; import { ReactComponent as Back } from 'assets/chat/arrowleft.svg'; import { ReactComponent as Close } from 'assets/chat/group-chat/close.svg'; import { ItemHV2, ItemVV2, SpanV2 } from 'components/reusables/SharedStylingV2'; +import ArrowLeft from 'assets/chat/arrowleft.svg'; +import { ImageV2 } from 'components/reusables/SharedStylingV2'; // Internal Configs import { AppContext } from 'contexts/AppContext'; +import EnableSnoozeModal from 'components/PushSnap/EnableSnoozeModal'; +import { SnoozeDurationType } from 'types'; +const MetamaskPushSnapModal = ({ onClose, closeEnabled = true }: { onClose: () => void; closeEnabled?: boolean }) => { + const theme = useTheme(); + const location = useLocation(); -const MetamaskPushSnapModal = ({ - onClose, - closeEnabled = true -}: { - onClose: () => void, - closeEnabled?: boolean -}) => { - const theme = useTheme(); - const location = useLocation(); + const [configure, setConfigure] = useState(false); + const [snoozeDuration, setSnoozeDuration] = useState({ + enabled: false, + hrsLeft: 0 + }); - const [configure, setConfigure] = useState(false); + const { setSnapState, SnapState } = React.useContext(AppContext); - const { setSnapState, SnapState } = React.useContext(AppContext); + const handleCloseModal = () => { + var uri = window.location.toString(); - const handleCloseModal = () => { + if (uri.indexOf('#') > 0) { + var clean_uri = uri.substring(0, uri.indexOf('#')); - var uri = window.location.toString(); - - if (uri.indexOf("#") > 0) { - var clean_uri = uri.substring(0, uri.indexOf("#")); - - window.history.replaceState({}, document.title, clean_uri); - } - - setSnapState(1); - onClose(); + window.history.replaceState({}, document.title, clean_uri); } - const isSnapRoute = location?.pathname === '/snap'; - - return ( - - - - {(SnapState !== 1 && !isSnapRoute) && setSnapState(1)} />} - - {SnapState === 1 && - Receive Notifications - } - {SnapState === 3 && - Settings - } - - {closeEnabled && - - } - - - {SnapState == 1 && } - {SnapState == 2 && } - {SnapState == 3 && } - - - - ); + setSnapState(1); + onClose(); + }; + + const isSnapRoute = location?.pathname === '/snap'; + + return ( + + + + {SnapState === 1 && ( + + Receive Notifications + + )} + {(SnapState == 3 || SnapState == 2) && ( + { + setSnapState(1); + }} + /> + )} + {SnapState === 3 && ( + + Settings + + )} + {SnapState == 4 && ( + { + setSnapState(3); + }} + /> + )} + + {closeEnabled && ( + + )} + + + {SnapState == 1 && ( + + )} + {SnapState == 2 && } + {SnapState == 3 && } + {SnapState == 4 && } + + ); }; export default MetamaskPushSnapModal; const Container = styled(ItemVV2)` - width:420px; - - @media(max-width:476px){ - width:360px; - } + width: 420px; -` \ No newline at end of file + @media (max-width: 476px) { + width: 360px; + } +`; diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000000..a08a4c4d2f --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,4 @@ +export type SnoozeDurationType = { + enabled: boolean; + hrsLeft: number; +};