Skip to content

Commit

Permalink
Merge pull request #2054 from blockscout/release/v1_32_0-fixes
Browse files Browse the repository at this point in the history
Fixes for release v.1.32.0
  • Loading branch information
tom2drum authored Jul 3, 2024
2 parents 110076d + b8fedb9 commit ca3d530
Show file tree
Hide file tree
Showing 16 changed files with 123 additions and 59 deletions.
1 change: 1 addition & 0 deletions lib/hooks/useToast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const defaultOptions: UseToastOptions & { toastComponent?: React.FC<ToastProps>
containerStyle: {
margin: 8,
},
variant: 'subtle',
};

export default function useToastModified() {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"chakra-react-select": "^4.4.3",
"crypto-js": "^4.2.0",
"d3": "^7.6.1",
"dappscout-iframe": "0.2.1",
"dappscout-iframe": "0.2.2",
"dayjs": "^1.11.5",
"dom-to-image": "^2.6.0",
"focus-visible": "^5.2.0",
Expand Down
52 changes: 52 additions & 0 deletions playwright/fixtures/mockRpcResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import type { TestFixture, Page } from '@playwright/test';
import _isEqual from 'lodash/isEqual';
import type { PublicRpcSchema } from 'viem';

import { getEnvValue } from 'configs/app/utils';

type Params = PublicRpcSchema[number];

export type MockRpcResponseFixture = (params: Params) => Promise<void>;

// WIP
const fixture: TestFixture<MockRpcResponseFixture, { page: Page }> = async({ page }, use) => {
await use(async({ Method, ReturnType }) => {
const rpcUrl = getEnvValue('NEXT_PUBLIC_NETWORK_RPC_URL');

if (!rpcUrl) {
return;
}

await page.route(rpcUrl, (route) => {
const method = route.request().method();

if (method !== 'POST') {
route.continue();
return;
}

const json = route.request().postDataJSON();
const id = json?.id;

const payload = {
id,
jsonrpc: '2.0',
method: Method,
// TODO: add params to match actual payload
};

if (_isEqual(json, payload) && id !== undefined) {
return route.fulfill({
status: 200,
body: JSON.stringify({
id,
jsonrpc: '2.0',
result: ReturnType,
}),
});
}
});
});
};

export default fixture;
3 changes: 3 additions & 0 deletions playwright/lib.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as mockConfigResponse from './fixtures/mockConfigResponse';
import * as mockContractReadResponse from './fixtures/mockContractReadResponse';
import * as mockEnvs from './fixtures/mockEnvs';
import * as mockFeatures from './fixtures/mockFeatures';
import * as mockRpcResponse from './fixtures/mockRpcResponse';
import * as mockTextAd from './fixtures/mockTextAd';
import * as render from './fixtures/render';
import * as socketServer from './fixtures/socketServer';
Expand All @@ -20,6 +21,7 @@ interface Fixtures {
mockContractReadResponse: mockContractReadResponse.MockContractReadResponseFixture;
mockEnvs: mockEnvs.MockEnvsFixture;
mockFeatures: mockFeatures.MockFeaturesFixture;
mockRpcResponse: mockRpcResponse.MockRpcResponseFixture;
createSocket: socketServer.CreateSocketFixture;
injectMetaMaskProvider: injectMetaMaskProvider.InjectMetaMaskProvider;
mockTextAd: mockTextAd.MockTextAdFixture;
Expand All @@ -33,6 +35,7 @@ const test = base.extend<Fixtures>({
mockContractReadResponse: mockContractReadResponse.default,
mockEnvs: mockEnvs.default,
mockFeatures: mockFeatures.default,
mockRpcResponse: mockRpcResponse.default,
// FIXME: for some reason Playwright does not intercept requests to text ad provider when running multiple tests in parallel
// even if we have a global request interceptor (maybe it is related to service worker issue, maybe not)
// so we have to inject mockTextAd fixture in each test and mock the response where it is needed
Expand Down
46 changes: 23 additions & 23 deletions ui/blocks/BlocksTableItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,33 +86,33 @@ const BlocksTableItem = ({ data, isLoading, enableTimeIncrement }: Props) => {
</Skeleton>
) : data.tx_count }
</Td>
<Td fontSize="sm">
<Skeleton isLoaded={ !isLoading } display="inline-block">{ BigNumber(data.gas_used || 0).toFormat() }</Skeleton>
<Flex mt={ 2 }>
<Tooltip label={ isLoading ? undefined : 'Gas Used %' }>
<Box>
<Utilization
colorScheme="gray"
value={ BigNumber(data.gas_used || 0).dividedBy(BigNumber(data.gas_limit)).toNumber() }
isLoading={ isLoading }
/>
</Box>
</Tooltip>
{ data.gas_target_percentage && (
<>
<TextSeparator color={ separatorColor } mx={ 1 }/>
<GasUsedToTargetRatio value={ data.gas_target_percentage } isLoading={ isLoading }/>
</>
) }
</Flex>
</Td>
{ !isRollup && !config.UI.views.block.hiddenFields?.total_reward && (
<Td fontSize="sm">
<Skeleton isLoaded={ !isLoading } display="inline-block">{ BigNumber(data.gas_used || 0).toFormat() }</Skeleton>
<Flex mt={ 2 }>
<Tooltip label={ isLoading ? undefined : 'Gas Used %' }>
<Box>
<Utilization
colorScheme="gray"
value={ BigNumber(data.gas_used || 0).dividedBy(BigNumber(data.gas_limit)).toNumber() }
isLoading={ isLoading }
/>
</Box>
</Tooltip>
{ data.gas_target_percentage && (
<>
<TextSeparator color={ separatorColor } mx={ 1 }/>
<GasUsedToTargetRatio value={ data.gas_target_percentage } isLoading={ isLoading }/>
</>
) }
</Flex>
<Skeleton isLoaded={ !isLoading } display="inline-block">
{ totalReward.toFixed(8) }
</Skeleton>
</Td>
) }
<Td fontSize="sm">
<Skeleton isLoaded={ !isLoading } display="inline-block">
{ totalReward.toFixed(8) }
</Skeleton>
</Td>
{ !isRollup && !config.UI.views.block.hiddenFields?.burnt_fees && (
<Td fontSize="sm">
<Flex alignItems="center" columnGap={ 2 }>
Expand Down
2 changes: 1 addition & 1 deletion ui/marketplace/MarketplaceAppCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ const MarketplaceAppCard = ({
showContractList={ showContractList }
isLoading={ isLoading }
source="Discovery view"
popoverPlacement={ isMobile ? 'bottom-end' : 'bottom-start' }
popoverPlacement={ isMobile ? 'bottom-end' : 'left' }
position="absolute"
right={{ base: 3, md: 5 }}
top={{ base: '10px', md: 5 }}
Expand Down
2 changes: 1 addition & 1 deletion ui/nameDomains/NameDomainsActionBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const NameDomainsActionBar = ({
minW={{ base: 'auto', lg: '250px' }}
size="xs"
onChange={ onSearchChange }
placeholder="Search by name"
placeholder="Search by name or address"
initialValue={ searchTerm }
isLoading={ isInitialLoading }
/>
Expand Down
22 changes: 9 additions & 13 deletions ui/pages/GasTracker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,12 @@ const GasTracker = () => {
</Flex>
);

const content = (() => {
const snippets = (() => {
if (!isPlaceholderData && data?.gas_prices?.slow === null && data?.gas_prices.average === null && data.gas_prices.fast === null) {
return <Alert status="warning">No data available yet</Alert>;
return <Alert status="warning">No recent data available</Alert>;
}

return (
<>
{ data?.gas_prices && <GasTrackerPrices prices={ data.gas_prices } isLoading={ isLoading }/> }
{ config.features.stats.isEnabled && (
<Box mt={ 12 }>
<GasTrackerChart/>
</Box>
) }
</>
);
return data?.gas_prices ? <GasTrackerPrices prices={ data.gas_prices } isLoading={ isLoading }/> : null;
})();

return (
Expand All @@ -88,7 +79,12 @@ const GasTracker = () => {
secondRow={ titleSecondRow }
withTextAd
/>
{ content }
{ snippets }
{ config.features.stats.isEnabled && (
<Box mt={ 12 }>
<GasTrackerChart/>
</Box>
) }
</>
);
};
Expand Down
4 changes: 2 additions & 2 deletions ui/pages/MarketplaceApp.pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ const testFn: Parameters<typeof test>[1] = async({ render, mockConfigResponse, m
await expect(component).toHaveScreenshot();
};

test('base view +@dark-mode', testFn);
test.fixme('base view +@dark-mode', testFn);

test.describe('mobile', () => {
test.use({ viewport: devices['iPhone 13 Pro'].viewport });
test('base view', testFn);
test.fixme('base view', testFn);
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions ui/shared/Toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function getBgColor(status?: AlertStatus) {
}
}

const Toast = ({ onClose, title, description, id, isClosable, status }: ToastProps) => {
const Toast = ({ onClose, title, description, id, isClosable, status, icon }: ToastProps) => {

const ids = id ?
{
Expand Down Expand Up @@ -48,7 +48,7 @@ const Toast = ({ onClose, title, description, id, isClosable, status }: ToastPro
maxWidth="400px"
>
<chakra.div flex="1" maxWidth="100%">
{ title && <AlertTitle id={ ids?.title }>{ title }</AlertTitle> }
{ title && <AlertTitle id={ ids?.title } display="flex" alignItems="center">{ icon }{ title }</AlertTitle> }
{ description && (
<AlertDescription id={ ids?.description } display="block">
{ description }
Expand Down
36 changes: 24 additions & 12 deletions ui/tokenInstance/TokenInstanceMetadataFetcher.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { chakra, Alert, Modal, ModalBody, ModalCloseButton, ModalContent, ModalHeader, ModalOverlay } from '@chakra-ui/react';
import type { ToastId } from '@chakra-ui/react';
import { chakra, Alert, Modal, ModalBody, ModalCloseButton, ModalContent, ModalHeader, ModalOverlay, Spinner } from '@chakra-ui/react';
import { useQueryClient } from '@tanstack/react-query';
import React from 'react';
import ReCaptcha from 'react-google-recaptcha';
Expand All @@ -9,7 +10,7 @@ import type { TokenInstance } from 'types/api/token';
import config from 'configs/app';
import useApiFetch from 'lib/api/useApiFetch';
import { getResourceKey } from 'lib/api/useApiQuery';
import { MINUTE } from 'lib/consts';
import { MINUTE, SECOND } from 'lib/consts';
import useToast from 'lib/hooks/useToast';
import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage';
Expand All @@ -23,6 +24,7 @@ interface Props {

const TokenInstanceMetadataFetcher = ({ hash, id }: Props) => {
const timeoutId = React.useRef<number>();
const toastId = React.useRef<ToastId>();

const { status, setStatus } = useMetadataUpdateContext() || {};
const apiFetch = useApiFetch();
Expand All @@ -31,12 +33,12 @@ const TokenInstanceMetadataFetcher = ({ hash, id }: Props) => {

const handleRefreshError = React.useCallback(() => {
setStatus?.('ERROR');
toast.closeAll();
toast({
toastId.current && toast.update(toastId.current, {
title: 'Error',
description: 'The refreshing process has failed. Please try again.',
status: 'warning',
variant: 'subtle',
duration: 5 * SECOND,
isClosable: true,
});
}, [ setStatus, toast ]);

Expand All @@ -49,21 +51,22 @@ const TokenInstanceMetadataFetcher = ({ hash, id }: Props) => {
},
})
.then(() => {
toast({
setStatus?.('WAITING_FOR_RESPONSE');
toastId.current = toast({
title: 'Please wait',
description: 'Refetching metadata request sent',
icon: <Spinner size="sm" mr={ 2 }/>,
status: 'warning',
variant: 'subtle',
duration: null,
isClosable: false,
});
setStatus?.('WAITING_FOR_RESPONSE');
timeoutId.current = window.setTimeout(handleRefreshError, 2 * MINUTE);
})
.catch(() => {
toast({
title: 'Error',
description: 'Unable to initialize metadata update',
status: 'warning',
variant: 'subtle',
});
setStatus?.('ERROR');
});
Expand Down Expand Up @@ -112,12 +115,12 @@ const TokenInstanceMetadataFetcher = ({ hash, id }: Props) => {
};
});

toast.closeAll();
toast({
toastId.current && toast.update(toastId.current, {
title: 'Success!',
description: 'Metadata has been refreshed',
status: 'success',
variant: 'subtle',
duration: 5 * SECOND,
isClosable: true,
});

setStatus?.('SUCCESS');
Expand All @@ -138,6 +141,15 @@ const TokenInstanceMetadataFetcher = ({ hash, id }: Props) => {
handler: handleSocketMessage,
});

React.useEffect(() => {
return () => {
timeoutId.current && window.clearTimeout(timeoutId.current);
toastId.current && toast.close(toastId.current);
};
// run only on mount/unmount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<Modal isOpen={ status === 'MODAL_OPENED' } onClose={ handleModalClose } size={{ base: 'full', lg: 'sm' }}>
<ModalOverlay/>
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8605,10 +8605,10 @@ damerau-levenshtein@^1.0.8:
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==

[email protected].1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/dappscout-iframe/-/dappscout-iframe-0.2.1.tgz#b4718515ee4f00022af3912fac6ca1a321c156f9"
integrity sha512-EsiAAEk2I6hN+/E8o45WUn4BFd7aN8UvBwsIcOH79WOly0GOOHkPEO/puPkBCV0EcdxBsZIfssx3X0fSWVz5Bw==
[email protected].2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/dappscout-iframe/-/dappscout-iframe-0.2.2.tgz#de3df6abccad68a27c9304300b92d86ec0ab1c59"
integrity sha512-ASOimgBRG61pSYQLdYGWePdiO3IsfTEgWZ6CHpZ4XQjJRmj1+WiWF56vFTeLIo5aucp+2+6oRCJ8KgKHGVDj0A==
dependencies:
react "^18.2.0"
react-dom "^18.2.0"
Expand Down

0 comments on commit ca3d530

Please sign in to comment.