Commit 20f8c0e8 authored by Max Alekseenko's avatar Max Alekseenko

add warning state for wallet button

parent 24cfa420
...@@ -6,6 +6,7 @@ import { render } from '@testing-library/react'; ...@@ -6,6 +6,7 @@ import { render } from '@testing-library/react';
import React from 'react'; import React from 'react';
import { AppContextProvider } from 'lib/contexts/app'; import { AppContextProvider } from 'lib/contexts/app';
import { MarketplaceContextProvider } from 'lib/contexts/marketplace';
import { ScrollDirectionProvider } from 'lib/contexts/scrollDirection'; import { ScrollDirectionProvider } from 'lib/contexts/scrollDirection';
import { SocketProvider } from 'lib/socket/context'; import { SocketProvider } from 'lib/socket/context';
import theme from 'theme'; import theme from 'theme';
...@@ -41,7 +42,9 @@ const TestApp = ({ children }: {children: React.ReactNode}) => { ...@@ -41,7 +42,9 @@ const TestApp = ({ children }: {children: React.ReactNode}) => {
<ScrollDirectionProvider> <ScrollDirectionProvider>
<GrowthBookProvider> <GrowthBookProvider>
<SocketProvider> <SocketProvider>
{ children } <MarketplaceContextProvider>
{ children }
</MarketplaceContextProvider>
</SocketProvider> </SocketProvider>
</GrowthBookProvider> </GrowthBookProvider>
</ScrollDirectionProvider> </ScrollDirectionProvider>
......
import { useRouter } from 'next/router';
import React, { createContext, useContext } from 'react';
type Props = {
children: React.ReactNode;
}
type TMarketplaceContext = {
isAutoConnectDisabled: boolean;
setIsAutoConnectDisabled: (isAutoConnectDisabled: boolean) => void;
}
const MarketplaceContext = createContext<TMarketplaceContext>({
isAutoConnectDisabled: false,
setIsAutoConnectDisabled: () => {},
});
export function MarketplaceContextProvider({ children }: Props) {
const router = useRouter();
const [ isAutoConnectDisabled, setIsAutoConnectDisabled ] = React.useState(false);
React.useEffect(() => {
setIsAutoConnectDisabled(false);
}, [ router.pathname ]);
return (
<MarketplaceContext.Provider value={{ isAutoConnectDisabled, setIsAutoConnectDisabled }}>
{ children }
</MarketplaceContext.Provider>
);
}
export function useMarketplaceContext() {
return useContext(MarketplaceContext);
}
...@@ -12,6 +12,7 @@ import config from 'configs/app'; ...@@ -12,6 +12,7 @@ import config from 'configs/app';
import useQueryClientConfig from 'lib/api/useQueryClientConfig'; import useQueryClientConfig from 'lib/api/useQueryClientConfig';
import { AppContextProvider } from 'lib/contexts/app'; import { AppContextProvider } from 'lib/contexts/app';
import { ChakraProvider } from 'lib/contexts/chakra'; import { ChakraProvider } from 'lib/contexts/chakra';
import { MarketplaceContextProvider } from 'lib/contexts/marketplace';
import { ScrollDirectionProvider } from 'lib/contexts/scrollDirection'; import { ScrollDirectionProvider } from 'lib/contexts/scrollDirection';
import { growthBook } from 'lib/growthbook/init'; import { growthBook } from 'lib/growthbook/init';
import useLoadFeatures from 'lib/growthbook/useLoadFeatures'; import useLoadFeatures from 'lib/growthbook/useLoadFeatures';
...@@ -67,7 +68,9 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) { ...@@ -67,7 +68,9 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
<GrowthBookProvider growthbook={ growthBook }> <GrowthBookProvider growthbook={ growthBook }>
<ScrollDirectionProvider> <ScrollDirectionProvider>
<SocketProvider url={ `${ config.api.socket }${ config.api.basePath }/socket/v2` }> <SocketProvider url={ `${ config.api.socket }${ config.api.basePath }/socket/v2` }>
{ getLayout(<Component { ...pageProps }/>) } <MarketplaceContextProvider>
{ getLayout(<Component { ...pageProps }/>) }
</MarketplaceContextProvider>
</SocketProvider> </SocketProvider>
</ScrollDirectionProvider> </ScrollDirectionProvider>
</GrowthBookProvider> </GrowthBookProvider>
......
...@@ -11,6 +11,7 @@ import { route } from 'nextjs-routes'; ...@@ -11,6 +11,7 @@ import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import type { ResourceError } from 'lib/api/resources'; import type { ResourceError } from 'lib/api/resources';
import useApiFetch from 'lib/api/useApiFetch'; import useApiFetch from 'lib/api/useApiFetch';
import { useMarketplaceContext } from 'lib/contexts/marketplace';
import throwOnResourceLoadError from 'lib/errors/throwOnResourceLoadError'; import throwOnResourceLoadError from 'lib/errors/throwOnResourceLoadError';
import useFetch from 'lib/hooks/useFetch'; import useFetch from 'lib/hooks/useFetch';
import * as metadata from 'lib/metadata'; import * as metadata from 'lib/metadata';
...@@ -129,6 +130,7 @@ const MarketplaceApp = () => { ...@@ -129,6 +130,7 @@ const MarketplaceApp = () => {
enabled: feature.isEnabled, enabled: feature.isEnabled,
}); });
const { data, isPending } = query; const { data, isPending } = query;
const { setIsAutoConnectDisabled } = useMarketplaceContext();
useEffect(() => { useEffect(() => {
if (data) { if (data) {
...@@ -136,8 +138,9 @@ const MarketplaceApp = () => { ...@@ -136,8 +138,9 @@ const MarketplaceApp = () => {
{ pathname: '/apps/[id]', query: { id: data.id } }, { pathname: '/apps/[id]', query: { id: data.id } },
{ app_name: data.title }, { app_name: data.title },
); );
setIsAutoConnectDisabled(!data.internalWallet);
} }
}, [ data ]); }, [ data, setIsAutoConnectDisabled ]);
throwOnResourceLoadError(query); throwOnResourceLoadError(query);
......
...@@ -2,8 +2,9 @@ import { useColorModeValue } from '@chakra-ui/react'; ...@@ -2,8 +2,9 @@ import { useColorModeValue } from '@chakra-ui/react';
export default function useMenuColors() { export default function useMenuColors() {
const themedBackground = useColorModeValue('blackAlpha.50', 'whiteAlpha.50'); const themedBackground = useColorModeValue('blackAlpha.50', 'whiteAlpha.50');
const themedBackgroundOrange = useColorModeValue('orange.100', 'orange.900');
const themedBorderColor = useColorModeValue('gray.300', 'gray.700'); const themedBorderColor = useColorModeValue('gray.300', 'gray.700');
const themedColor = useColorModeValue('blackAlpha.800', 'gray.400'); const themedColor = useColorModeValue('blackAlpha.800', 'gray.400');
return { themedBackground, themedBorderColor, themedColor }; return { themedBackground, themedBackgroundOrange, themedBorderColor, themedColor };
} }
import { Box, Flex, chakra } from '@chakra-ui/react';
import React from 'react';
import useIsMobile from 'lib/hooks/useIsMobile';
import AddressIdenticon from 'ui/shared/entities/address/AddressIdenticon';
import IconSvg from 'ui/shared/IconSvg';
import useMenuButtonColors from '../useMenuButtonColors';
type Props = {
address: string;
isAutoConnectDisabled?: boolean;
className?: string;
};
const WalletIdenticon = ({ address, isAutoConnectDisabled, className }: Props) => {
const { themedBackgroundOrange } = useMenuButtonColors();
const isMobile = useIsMobile();
return (
<Box className={ className } position="relative">
<AddressIdenticon size={ 20 } hash={ address }/>
{ isAutoConnectDisabled && (
<Flex
alignItems="center"
justifyContent="center"
boxSize="14px"
position="absolute"
bottom={ isMobile ? '-3px' : '-1px' }
right={ isMobile ? '-4px' : '-5px' }
backgroundColor="rgba(16, 17, 18, 0.80)"
borderRadius="full"
border="1px solid"
borderColor={ themedBackgroundOrange }
>
<IconSvg
name="integration/partial"
color="white"
boxSize="8px"
/>
</Flex>
) }
</Box>
);
};
export default chakra(WalletIdenticon);
import { Box, Button, Text } from '@chakra-ui/react'; import { Box, Button, Text, Flex } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import * as mixpanel from 'lib/mixpanel/index'; import * as mixpanel from 'lib/mixpanel/index';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps'; import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import IconSvg from 'ui/shared/IconSvg';
import useMenuButtonColors from '../useMenuButtonColors';
type Props = { type Props = {
address?: string; address?: string;
disconnect?: () => void; disconnect?: () => void;
isAutoConnectDisabled?: boolean;
}; };
const WalletMenuContent = ({ address, disconnect }: Props) => { const WalletMenuContent = ({ address, disconnect, isAutoConnectDisabled }: Props) => {
const { themedBackgroundOrange } = useMenuButtonColors();
const onAddressClick = React.useCallback(() => { const onAddressClick = React.useCallback(() => {
mixpanel.logEvent(mixpanel.EventTypes.WALLET_ACTION, { Action: 'Address click' }); mixpanel.logEvent(mixpanel.EventTypes.WALLET_ACTION, { Action: 'Address click' });
}, []); }, []);
return ( return (
<Box> <Box>
{ isAutoConnectDisabled && (
<Flex
borderRadius="base"
p={ 3 }
mb={ 3 }
alignItems="center"
backgroundColor={ themedBackgroundOrange }
>
<IconSvg
name="integration/partial"
color="current"
boxSize={ 5 }
flexShrink={ 0 }
mr={ 2 }
/>
<Text fontSize="xs" lineHeight="16px">
Connect your wallet in the app below
</Text>
</Flex>
) }
<Text <Text
fontSize="sm" fontSize="sm"
fontWeight={ 600 } fontWeight={ 600 }
......
import type { ButtonProps } from '@chakra-ui/react'; import type { ButtonProps } from '@chakra-ui/react';
import { Popover, PopoverContent, PopoverBody, PopoverTrigger, Button, Box, useBoolean, chakra } from '@chakra-ui/react'; import { Popover, PopoverContent, PopoverBody, PopoverTrigger, Button, Box, useBoolean, chakra, useColorModeValue } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { useMarketplaceContext } from 'lib/contexts/marketplace';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import * as mixpanel from 'lib/mixpanel/index'; import * as mixpanel from 'lib/mixpanel/index';
import AddressIdenticon from 'ui/shared/entities/address/AddressIdenticon';
import HashStringShorten from 'ui/shared/HashStringShorten'; import HashStringShorten from 'ui/shared/HashStringShorten';
import useWallet from 'ui/snippets/walletMenu/useWallet'; import useWallet from 'ui/snippets/walletMenu/useWallet';
import WalletMenuContent from 'ui/snippets/walletMenu/WalletMenuContent'; import WalletMenuContent from 'ui/snippets/walletMenu/WalletMenuContent';
import useMenuButtonColors from '../useMenuButtonColors'; import useMenuButtonColors from '../useMenuButtonColors';
import WalletIdenticon from './WalletIdenticon';
import WalletTooltip from './WalletTooltip'; import WalletTooltip from './WalletTooltip';
type Props = { type Props = {
...@@ -20,9 +21,10 @@ type Props = { ...@@ -20,9 +21,10 @@ type Props = {
const WalletMenuDesktop = ({ isHomePage, className, size = 'md' }: Props) => { const WalletMenuDesktop = ({ isHomePage, className, size = 'md' }: Props) => {
const { isWalletConnected, address, connect, disconnect, isModalOpening, isModalOpen } = useWallet({ source: 'Header' }); const { isWalletConnected, address, connect, disconnect, isModalOpening, isModalOpen } = useWallet({ source: 'Header' });
const { themedBackground, themedBorderColor, themedColor } = useMenuButtonColors(); const { themedBackground, themedBackgroundOrange, themedBorderColor, themedColor } = useMenuButtonColors();
const [ isPopoverOpen, setIsPopoverOpen ] = useBoolean(false); const [ isPopoverOpen, setIsPopoverOpen ] = useBoolean(false);
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const { isAutoConnectDisabled } = useMarketplaceContext();
const variant = React.useMemo(() => { const variant = React.useMemo(() => {
if (isWalletConnected) { if (isWalletConnected) {
...@@ -31,13 +33,16 @@ const WalletMenuDesktop = ({ isHomePage, className, size = 'md' }: Props) => { ...@@ -31,13 +33,16 @@ const WalletMenuDesktop = ({ isHomePage, className, size = 'md' }: Props) => {
return isHomePage ? 'solid' : 'outline'; return isHomePage ? 'solid' : 'outline';
}, [ isWalletConnected, isHomePage ]); }, [ isWalletConnected, isHomePage ]);
const themedColorForOrangeBg = useColorModeValue('blackAlpha.800', 'whiteAlpha.800');
let buttonStyles: Partial<ButtonProps> = {}; let buttonStyles: Partial<ButtonProps> = {};
if (isWalletConnected) { if (isWalletConnected) {
const backgroundColor = isAutoConnectDisabled ? themedBackgroundOrange : themedBackground;
const color = isAutoConnectDisabled ? themedColorForOrangeBg : themedColor;
buttonStyles = { buttonStyles = {
bg: isHomePage ? 'blue.50' : themedBackground, bg: isHomePage ? 'blue.50' : backgroundColor,
color: isHomePage ? 'blackAlpha.800' : themedColor, color: isHomePage ? 'blackAlpha.800' : color,
_hover: { _hover: {
color: isHomePage ? 'blackAlpha.800' : themedColor, color: isHomePage ? 'blackAlpha.800' : color,
}, },
}; };
} else if (isHomePage) { } else if (isHomePage) {
...@@ -82,9 +87,7 @@ const WalletMenuDesktop = ({ isHomePage, className, size = 'md' }: Props) => { ...@@ -82,9 +87,7 @@ const WalletMenuDesktop = ({ isHomePage, className, size = 'md' }: Props) => {
> >
{ isWalletConnected ? ( { isWalletConnected ? (
<> <>
<Box mr={ 2 }> <WalletIdenticon address={ address } isAutoConnectDisabled={ isAutoConnectDisabled } mr={ 2 }/>
<AddressIdenticon size={ 20 } hash={ address }/>
</Box>
<HashStringShorten hash={ address } isTooltipDisabled/> <HashStringShorten hash={ address } isTooltipDisabled/>
</> </>
) : 'Connect wallet' } ) : 'Connect wallet' }
...@@ -95,7 +98,7 @@ const WalletMenuDesktop = ({ isHomePage, className, size = 'md' }: Props) => { ...@@ -95,7 +98,7 @@ const WalletMenuDesktop = ({ isHomePage, className, size = 'md' }: Props) => {
{ isWalletConnected && ( { isWalletConnected && (
<PopoverContent w="235px"> <PopoverContent w="235px">
<PopoverBody padding="24px 16px 16px 16px"> <PopoverBody padding="24px 16px 16px 16px">
<WalletMenuContent address={ address } disconnect={ disconnect }/> <WalletMenuContent address={ address } disconnect={ disconnect } isAutoConnectDisabled={ isAutoConnectDisabled }/>
</PopoverBody> </PopoverBody>
</PopoverContent> </PopoverContent>
) } ) }
......
import { Drawer, DrawerOverlay, DrawerContent, DrawerBody, useDisclosure, IconButton } from '@chakra-ui/react'; import { Drawer, DrawerOverlay, DrawerContent, DrawerBody, useDisclosure, IconButton } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { useMarketplaceContext } from 'lib/contexts/marketplace';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import * as mixpanel from 'lib/mixpanel/index'; import * as mixpanel from 'lib/mixpanel/index';
import AddressIdenticon from 'ui/shared/entities/address/AddressIdenticon';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import useWallet from 'ui/snippets/walletMenu/useWallet'; import useWallet from 'ui/snippets/walletMenu/useWallet';
import WalletMenuContent from 'ui/snippets/walletMenu/WalletMenuContent'; import WalletMenuContent from 'ui/snippets/walletMenu/WalletMenuContent';
import useMenuButtonColors from '../useMenuButtonColors'; import useMenuButtonColors from '../useMenuButtonColors';
import WalletIdenticon from './WalletIdenticon';
import WalletTooltip from './WalletTooltip'; import WalletTooltip from './WalletTooltip';
const WalletMenuMobile = () => { const WalletMenuMobile = () => {
const { isOpen, onOpen, onClose } = useDisclosure(); const { isOpen, onOpen, onClose } = useDisclosure();
const { isWalletConnected, address, connect, disconnect, isModalOpening, isModalOpen } = useWallet({ source: 'Header' }); const { isWalletConnected, address, connect, disconnect, isModalOpening, isModalOpen } = useWallet({ source: 'Header' });
const { themedBackground, themedBorderColor, themedColor } = useMenuButtonColors(); const { themedBackground, themedBackgroundOrange, themedBorderColor, themedColor } = useMenuButtonColors();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const { isAutoConnectDisabled } = useMarketplaceContext();
const openPopover = React.useCallback(() => { const openPopover = React.useCallback(() => {
mixpanel.logEvent(mixpanel.EventTypes.WALLET_ACTION, { Action: 'Open' }); mixpanel.logEvent(mixpanel.EventTypes.WALLET_ACTION, { Action: 'Open' });
onOpen(); onOpen();
}, [ onOpen ]); }, [ onOpen ]);
const themedBg = isAutoConnectDisabled ? themedBackgroundOrange : themedBackground;
return ( return (
<> <>
<WalletTooltip isDisabled={ isWalletConnected || isMobile === undefined || !isMobile } isMobile> <WalletTooltip isDisabled={ isWalletConnected || isMobile === undefined || !isMobile } isMobile>
<IconButton <IconButton
aria-label="wallet menu" aria-label="wallet menu"
icon={ isWalletConnected ? icon={ isWalletConnected ?
<AddressIdenticon size={ 20 } hash={ address }/> : <WalletIdenticon address={ address } isAutoConnectDisabled={ isAutoConnectDisabled }/> :
<IconSvg name="wallet" boxSize={ 6 }/> <IconSvg name="wallet" boxSize={ 6 }/>
} }
variant={ isWalletConnected ? 'subtle' : 'outline' } variant={ isWalletConnected ? 'subtle' : 'outline' }
colorScheme="gray" colorScheme="gray"
boxSize="40px" boxSize="40px"
flexShrink={ 0 } flexShrink={ 0 }
bg={ isWalletConnected ? themedBackground : undefined } bg={ isWalletConnected ? themedBg : undefined }
color={ themedColor } color={ themedColor }
borderColor={ !isWalletConnected ? themedBorderColor : undefined } borderColor={ !isWalletConnected ? themedBorderColor : undefined }
onClick={ isWalletConnected ? openPopover : connect } onClick={ isWalletConnected ? openPopover : connect }
...@@ -52,7 +56,7 @@ const WalletMenuMobile = () => { ...@@ -52,7 +56,7 @@ const WalletMenuMobile = () => {
<DrawerOverlay/> <DrawerOverlay/>
<DrawerContent maxWidth="260px"> <DrawerContent maxWidth="260px">
<DrawerBody p={ 6 }> <DrawerBody p={ 6 }>
<WalletMenuContent address={ address } disconnect={ disconnect }/> <WalletMenuContent address={ address } disconnect={ disconnect } isAutoConnectDisabled={ isAutoConnectDisabled }/>
</DrawerBody> </DrawerBody>
</DrawerContent> </DrawerContent>
</Drawer> </Drawer>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment