Commit cc89fcfb authored by tom's avatar tom

bug fixes

parent f363957a
...@@ -11,4 +11,4 @@ ...@@ -11,4 +11,4 @@
| NEXT_PUBLIC_NETWORK_GOVERNANCE_TOKEN_SYMBOL | `string` | Network governance token symbol | - | - | `GNO` | v1.12.0 | v1.29.0 | Replaced by NEXT_PUBLIC_NETWORK_SECONDARY_COIN_SYMBOL | | NEXT_PUBLIC_NETWORK_GOVERNANCE_TOKEN_SYMBOL | `string` | Network governance token symbol | - | - | `GNO` | v1.12.0 | v1.29.0 | Replaced by NEXT_PUBLIC_NETWORK_SECONDARY_COIN_SYMBOL |
| NEXT_PUBLIC_SWAP_BUTTON_URL | `string` | Application ID in the marketplace or website URL | - | - | `uniswap` | v1.24.0 | v1.31.0 | Replaced by NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS | | NEXT_PUBLIC_SWAP_BUTTON_URL | `string` | Application ID in the marketplace or website URL | - | - | `uniswap` | v1.24.0 | v1.31.0 | Replaced by NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS |
| NEXT_PUBLIC_HOMEPAGE_SHOW_AVG_BLOCK_TIME | `boolean` | Set to false if average block time is useless for the network | - | `true` | `false` | v1.0.x+ | v1.35.0 | Replaced by NEXT_PUBLIC_HOMEPAGE_STATS | | NEXT_PUBLIC_HOMEPAGE_SHOW_AVG_BLOCK_TIME | `boolean` | Set to false if average block time is useless for the network | - | `true` | `false` | v1.0.x+ | v1.35.0 | Replaced by NEXT_PUBLIC_HOMEPAGE_STATS |
| NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY | `string` | Google reCAPTCHA v2 site key | - | - | `<your-secret>` | v1.35.0 | Replaced by NEXT_PUBLIC_RE_CAPTCHA_V3_APP_SITE_KEY | | NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY | `string` | Google reCAPTCHA v2 site key | - | - | `<your-secret>` | v1.36.0 | Replaced by NEXT_PUBLIC_RE_CAPTCHA_V3_APP_SITE_KEY |
...@@ -341,9 +341,10 @@ Settings for meta tags, OG tags and SEO ...@@ -341,9 +341,10 @@ Settings for meta tags, OG tags and SEO
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version | | Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
| --- | --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED | `boolean` | Set to true if network has account feature | Required | - | `true` | v1.0.x+ | | NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED | `boolean` | Set to true if network has account feature | Required | - | `true` | v1.0.x+ |
| NEXT_PUBLIC_AUTH0_CLIENT_ID | `string` | **DEPRECATED** Client id for [Auth0](https://auth0.com/) provider | Required | - | `<your-secret>` | v1.0.x+ | | NEXT_PUBLIC_RE_CAPTCHA_V3_APP_SITE_KEY | `boolean` | See [below](ENVS.md#google-recaptcha) | Required | - | `<your-secret>` | v1.36.0+ |
| NEXT_PUBLIC_AUTH_URL | `string` | **DEPRECATED** Account auth base url; it is used for building login URL (`${ NEXT_PUBLIC_AUTH_URL }/auth/auth0`) and logout return URL (`${ NEXT_PUBLIC_AUTH_URL }/auth/logout`); if not provided the base app URL will be used instead | Required | - | `https://blockscout.com` | v1.0.x+ | | NEXT_PUBLIC_AUTH0_CLIENT_ID | `string` | **DEPRECATED** Client id for [Auth0](https://auth0.com/) provider | - | - | `<your-secret>` | v1.0.x+ |
| NEXT_PUBLIC_LOGOUT_URL | `string` | **DEPRECATED** Account logout url. Required if account is supported for the app instance. | Required | - | `https://blockscoutcom.us.auth0.com/v2/logout` | v1.0.x+ | | NEXT_PUBLIC_AUTH_URL | `string` | **DEPRECATED** Account auth base url; it is used for building login URL (`${ NEXT_PUBLIC_AUTH_URL }/auth/auth0`) and logout return URL (`${ NEXT_PUBLIC_AUTH_URL }/auth/logout`); if not provided the base app URL will be used instead | - | - | `https://blockscout.com` | v1.0.x+ |
| NEXT_PUBLIC_LOGOUT_URL | `string` | **DEPRECATED** Account logout url. Required if account is supported for the app instance. | - | - | `https://blockscoutcom.us.auth0.com/v2/logout` | v1.0.x+ |
&nbsp; &nbsp;
...@@ -440,7 +441,7 @@ This feature is **enabled by default** with the `coinzilla` ads provider. To swi ...@@ -440,7 +441,7 @@ This feature is **enabled by default** with the `coinzilla` ads provider. To swi
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version | | Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
| --- | --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_RE_CAPTCHA_V3_APP_SITE_KEY | `string` | See [below](ENVS.md#google-recaptcha) | true | - | `<your-secret>` | v1.35.0+ | | NEXT_PUBLIC_RE_CAPTCHA_V3_APP_SITE_KEY | `string` | See [below](ENVS.md#google-recaptcha) | true | - | `<your-secret>` | v1.36.0+ |
&nbsp; &nbsp;
...@@ -798,4 +799,4 @@ For obtaining the variables values please refer to [reCAPTCHA documentation](htt ...@@ -798,4 +799,4 @@ For obtaining the variables values please refer to [reCAPTCHA documentation](htt
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version | | Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
| --- | --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_RE_CAPTCHA_V3_APP_SITE_KEY | `string` | Google reCAPTCHA v3 site key | - | - | `<your-secret>` | v1.35.0+ | | NEXT_PUBLIC_RE_CAPTCHA_V3_APP_SITE_KEY | `string` | Google reCAPTCHA v3 site key | - | - | `<your-secret>` | v1.36.0+ |
...@@ -68,6 +68,8 @@ const MyProfileEmail = ({ profileQuery }: Props) => { ...@@ -68,6 +68,8 @@ const MyProfileEmail = ({ profileQuery }: Props) => {
} }
}, [ apiFetch, authModal, toast ]); }, [ apiFetch, authModal, toast ]);
const hasDirtyFields = Object.keys(formApi.formState.dirtyFields).length > 0;
return ( return (
<section> <section>
<Heading as="h2" size="sm" mb={ 3 }>Notifications</Heading> <Heading as="h2" size="sm" mb={ 3 }>Notifications</Heading>
...@@ -88,7 +90,7 @@ const MyProfileEmail = ({ profileQuery }: Props) => { ...@@ -88,7 +90,7 @@ const MyProfileEmail = ({ profileQuery }: Props) => {
size="sm" size="sm"
variant="outline" variant="outline"
type="submit" type="submit"
isDisabled={ formApi.formState.isSubmitting || !formApi.formState.isDirty } isDisabled={ formApi.formState.isSubmitting || !hasDirtyFields }
isLoading={ formApi.formState.isSubmitting } isLoading={ formApi.formState.isSubmitting }
loadingText="Save changes" loadingText="Save changes"
> >
......
...@@ -35,7 +35,7 @@ const MyProfileFieldsEmail = ({ isReadOnly }: Props) => { ...@@ -35,7 +35,7 @@ const MyProfileFieldsEmail = ({ isReadOnly }: Props) => {
bgColor="dialog_bg" bgColor="dialog_bg"
/> />
<InputPlaceholder text="Email" error={ fieldState.error }/> <InputPlaceholder text="Email" error={ fieldState.error }/>
{ !formState.isDirty && ( { !formState.dirtyFields.email && (
<InputRightElement h="100%"> <InputRightElement h="100%">
<IconSvg name="certified" boxSize={ 5 } color="green.500"/> <IconSvg name="certified" boxSize={ 5 } color="green.500"/>
</InputRightElement> </InputRightElement>
......
...@@ -4,6 +4,8 @@ import React from 'react'; ...@@ -4,6 +4,8 @@ import React from 'react';
import type { Screen } from '../types'; import type { Screen } from '../types';
import type { UserInfo } from 'types/api/account'; import type { UserInfo } from 'types/api/account';
import config from 'configs/app';
interface Props { interface Props {
email: string; email: string;
onConnectWallet: (screen: Screen) => void; onConnectWallet: (screen: Screen) => void;
...@@ -32,7 +34,7 @@ const AuthModalScreenSuccessEmail = ({ email, onConnectWallet, isAuth, profile } ...@@ -32,7 +34,7 @@ const AuthModalScreenSuccessEmail = ({ email, onConnectWallet, isAuth, profile }
<chakra.span fontWeight="700">{ email }</chakra.span>{ ' ' } <chakra.span fontWeight="700">{ email }</chakra.span>{ ' ' }
email has been successfully used to log in to your Blockscout account. email has been successfully used to log in to your Blockscout account.
</Text> </Text>
{ !profile?.address_hash && ( { !profile?.address_hash && config.features.blockchainInteraction.isEnabled && (
<> <>
<Text mt={ 6 }>Add your web3 wallet to safely interact with smart contracts and dapps inside Blockscout.</Text> <Text mt={ 6 }>Add your web3 wallet to safely interact with smart contracts and dapps inside Blockscout.</Text>
<Button mt={ 6 } onClick={ handleConnectWalletClick }>Connect wallet</Button> <Button mt={ 6 } onClick={ handleConnectWalletClick }>Connect wallet</Button>
......
...@@ -10,12 +10,12 @@ import config from 'configs/app'; ...@@ -10,12 +10,12 @@ import config from 'configs/app';
import { useMarketplaceContext } from 'lib/contexts/marketplace'; import { useMarketplaceContext } from 'lib/contexts/marketplace';
import shortenString from 'lib/shortenString'; import shortenString from 'lib/shortenString';
import Hint from 'ui/shared/Hint'; import Hint from 'ui/shared/Hint';
import TruncatedValue from 'ui/shared/TruncatedValue';
import useLogout from 'ui/snippets/auth/useLogout'; import useLogout from 'ui/snippets/auth/useLogout';
import UserWalletAutoConnectAlert from '../UserWalletAutoConnectAlert'; import UserWalletAutoConnectAlert from '../UserWalletAutoConnectAlert';
import UserProfileContentNavLink from './UserProfileContentNavLink'; import UserProfileContentNavLink from './UserProfileContentNavLink';
import UserProfileContentWallet from './UserProfileContentWallet'; import UserProfileContentWallet from './UserProfileContentWallet';
import { getUserHandle } from './utils';
const navLinks: Array<NavLink> = [ const navLinks: Array<NavLink> = [
{ {
...@@ -80,6 +80,7 @@ const UserProfileContent = ({ data, onClose, onLogin, onAddEmail, onAddAddress } ...@@ -80,6 +80,7 @@ const UserProfileContent = ({ data, onClose, onLogin, onAddEmail, onAddAddress }
/> />
<Box fontSize="xs" lineHeight={ 4 } fontWeight="500" borderColor="divider" borderWidth="1px" borderRadius="base"> <Box fontSize="xs" lineHeight={ 4 } fontWeight="500" borderColor="divider" borderWidth="1px" borderRadius="base">
{ config.features.blockchainInteraction.isEnabled && (
<Flex p={ 2 } borderColor="divider" borderBottomWidth="1px"> <Flex p={ 2 } borderColor="divider" borderBottomWidth="1px">
<Box>Address</Box> <Box>Address</Box>
<Hint label="Address" boxSize={ 4 } ml={ 1 } mr="auto"/> <Hint label="Address" boxSize={ 4 } ml={ 1 } mr="auto"/>
...@@ -88,10 +89,11 @@ const UserProfileContent = ({ data, onClose, onLogin, onAddEmail, onAddAddress } ...@@ -88,10 +89,11 @@ const UserProfileContent = ({ data, onClose, onLogin, onAddEmail, onAddAddress }
<Link onClick={ onAddAddress } color="text_secondary" _hover={{ color: 'link_hovered', textDecoration: 'none' }}>Add wallet</Link> <Link onClick={ onAddAddress } color="text_secondary" _hover={{ color: 'link_hovered', textDecoration: 'none' }}>Add wallet</Link>
} }
</Flex> </Flex>
<Flex p={ 2 }> ) }
<Flex p={ 2 } columnGap={ 4 }>
<Box mr="auto">Email</Box> <Box mr="auto">Email</Box>
{ data?.email ? { data?.email ?
<Box>{ getUserHandle(data.email) }</Box> : <TruncatedValue value={ data.email + data.email }/> :
<Link onClick={ onAddEmail } color="text_secondary" _hover={{ color: 'link_hovered', textDecoration: 'none' }}>Add email</Link> <Link onClick={ onAddEmail } color="text_secondary" _hover={{ color: 'link_hovered', textDecoration: 'none' }}>Add email</Link>
} }
</Flex> </Flex>
......
...@@ -10,7 +10,6 @@ import useAccount from 'lib/web3/useAccount'; ...@@ -10,7 +10,6 @@ import useAccount from 'lib/web3/useAccount';
import Popover from 'ui/shared/chakra/Popover'; import Popover from 'ui/shared/chakra/Popover';
import AuthModal from 'ui/snippets/auth/AuthModal'; import AuthModal from 'ui/snippets/auth/AuthModal';
import useProfileQuery from 'ui/snippets/auth/useProfileQuery'; import useProfileQuery from 'ui/snippets/auth/useProfileQuery';
import useSignInWithWallet from 'ui/snippets/auth/useSignInWithWallet';
import UserProfileButton from './UserProfileButton'; import UserProfileButton from './UserProfileButton';
import UserProfileContent from './UserProfileContent'; import UserProfileContent from './UserProfileContent';
...@@ -20,17 +19,18 @@ interface Props { ...@@ -20,17 +19,18 @@ interface Props {
buttonVariant?: ButtonProps['variant']; buttonVariant?: ButtonProps['variant'];
} }
const initialScreen = {
type: config.features.blockchainInteraction.isEnabled ? 'select_method' as const : 'email' as const,
};
const UserProfileDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) => { const UserProfileDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) => {
const [ authInitialScreen, setAuthInitialScreen ] = React.useState<Screen>({ const [ authInitialScreen, setAuthInitialScreen ] = React.useState<Screen>(initialScreen);
type: config.features.blockchainInteraction.isEnabled ? 'select_method' : 'email',
});
const router = useRouter(); const router = useRouter();
const authModal = useDisclosure(); const authModal = useDisclosure();
const profileMenu = useDisclosure(); const profileMenu = useDisclosure();
const profileQuery = useProfileQuery(); const profileQuery = useProfileQuery();
const signInWithWallet = useSignInWithWallet({});
const { address: web3Address } = useAccount(); const { address: web3Address } = useAccount();
const handleProfileButtonClick = React.useCallback(() => { const handleProfileButtonClick = React.useCallback(() => {
...@@ -40,14 +40,12 @@ const UserProfileDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) => ...@@ -40,14 +40,12 @@ const UserProfileDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) =>
return; return;
} }
// TODO @tom2drum use auth modal instead if (router.pathname === '/apps/[id]' && config.features.blockchainInteraction.isEnabled) {
if (router.pathname === '/apps/[id]') { setAuthInitialScreen({ type: 'connect_wallet' });
signInWithWallet.start();
return;
} }
authModal.onOpen(); authModal.onOpen();
}, [ profileQuery.data, router.pathname, authModal, profileMenu, signInWithWallet, web3Address ]); }, [ profileQuery.data, router.pathname, authModal, profileMenu, web3Address ]);
const handleAddEmailClick = React.useCallback(() => { const handleAddEmailClick = React.useCallback(() => {
setAuthInitialScreen({ type: 'email', isAuth: true }); setAuthInitialScreen({ type: 'email', isAuth: true });
...@@ -59,6 +57,11 @@ const UserProfileDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) => ...@@ -59,6 +57,11 @@ const UserProfileDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) =>
authModal.onOpen(); authModal.onOpen();
}, [ authModal ]); }, [ authModal ]);
const handleAuthModalClose = React.useCallback(() => {
setAuthInitialScreen(initialScreen);
authModal.onClose();
}, [ authModal ]);
return ( return (
<> <>
<Popover openDelay={ 300 } placement="bottom-end" isLazy isOpen={ profileMenu.isOpen } onClose={ profileMenu.onClose }> <Popover openDelay={ 300 } placement="bottom-end" isLazy isOpen={ profileMenu.isOpen } onClose={ profileMenu.onClose }>
...@@ -68,7 +71,6 @@ const UserProfileDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) => ...@@ -68,7 +71,6 @@ const UserProfileDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) =>
size={ buttonSize } size={ buttonSize }
variant={ buttonVariant } variant={ buttonVariant }
onClick={ handleProfileButtonClick } onClick={ handleProfileButtonClick }
isPending={ signInWithWallet.isPending }
/> />
</PopoverTrigger> </PopoverTrigger>
{ (profileQuery.data || web3Address) && ( { (profileQuery.data || web3Address) && (
...@@ -87,7 +89,7 @@ const UserProfileDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) => ...@@ -87,7 +89,7 @@ const UserProfileDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) =>
</Popover> </Popover>
{ authModal.isOpen && ( { authModal.isOpen && (
<AuthModal <AuthModal
onClose={ authModal.onClose } onClose={ handleAuthModalClose }
initialScreen={ authInitialScreen } initialScreen={ authInitialScreen }
/> />
) } ) }
......
...@@ -9,22 +9,22 @@ import * as mixpanel from 'lib/mixpanel'; ...@@ -9,22 +9,22 @@ import * as mixpanel from 'lib/mixpanel';
import useAccount from 'lib/web3/useAccount'; import useAccount from 'lib/web3/useAccount';
import AuthModal from 'ui/snippets/auth/AuthModal'; import AuthModal from 'ui/snippets/auth/AuthModal';
import useProfileQuery from 'ui/snippets/auth/useProfileQuery'; import useProfileQuery from 'ui/snippets/auth/useProfileQuery';
import useSignInWithWallet from 'ui/snippets/auth/useSignInWithWallet';
import UserProfileButton from './UserProfileButton'; import UserProfileButton from './UserProfileButton';
import UserProfileContent from './UserProfileContent'; import UserProfileContent from './UserProfileContent';
const initialScreen = {
type: config.features.blockchainInteraction.isEnabled ? 'select_method' as const : 'email' as const,
};
const UserProfileMobile = () => { const UserProfileMobile = () => {
const [ authInitialScreen, setAuthInitialScreen ] = React.useState<Screen>({ const [ authInitialScreen, setAuthInitialScreen ] = React.useState<Screen>(initialScreen);
type: config.features.blockchainInteraction.isEnabled ? 'select_method' : 'email',
});
const router = useRouter(); const router = useRouter();
const authModal = useDisclosure(); const authModal = useDisclosure();
const profileMenu = useDisclosure(); const profileMenu = useDisclosure();
const profileQuery = useProfileQuery(); const profileQuery = useProfileQuery();
const signInWithWallet = useSignInWithWallet({});
const { address: web3Address } = useAccount(); const { address: web3Address } = useAccount();
const handleProfileButtonClick = React.useCallback(() => { const handleProfileButtonClick = React.useCallback(() => {
...@@ -34,14 +34,12 @@ const UserProfileMobile = () => { ...@@ -34,14 +34,12 @@ const UserProfileMobile = () => {
return; return;
} }
// TODO @tom2drum use auth modal instead if (router.pathname === '/apps/[id]' && config.features.blockchainInteraction.isEnabled) {
if (router.pathname === '/apps/[id]') { setAuthInitialScreen({ type: 'connect_wallet' });
signInWithWallet.start();
return;
} }
authModal.onOpen(); authModal.onOpen();
}, [ profileQuery.data, web3Address, router.pathname, authModal, profileMenu, signInWithWallet ]); }, [ profileQuery.data, web3Address, router.pathname, authModal, profileMenu ]);
const handleAddEmailClick = React.useCallback(() => { const handleAddEmailClick = React.useCallback(() => {
setAuthInitialScreen({ type: 'email', isAuth: true }); setAuthInitialScreen({ type: 'email', isAuth: true });
...@@ -53,6 +51,11 @@ const UserProfileMobile = () => { ...@@ -53,6 +51,11 @@ const UserProfileMobile = () => {
authModal.onOpen(); authModal.onOpen();
}, [ authModal ]); }, [ authModal ]);
const handleAuthModalClose = React.useCallback(() => {
setAuthInitialScreen(initialScreen);
authModal.onClose();
}, [ authModal ]);
return ( return (
<> <>
<UserProfileButton <UserProfileButton
...@@ -83,7 +86,7 @@ const UserProfileMobile = () => { ...@@ -83,7 +86,7 @@ const UserProfileMobile = () => {
) } ) }
{ authModal.isOpen && ( { authModal.isOpen && (
<AuthModal <AuthModal
onClose={ authModal.onClose } onClose={ handleAuthModalClose }
initialScreen={ authInitialScreen } initialScreen={ authInitialScreen }
/> />
) } ) }
......
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