Commit e817d438 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Merge pull request #1649 from blockscout/hotfix/incorrect-initial-dapp-sorting

Fix initial dapp sorting
parents c8f60016 8df5ab3f
......@@ -338,14 +338,15 @@
"options": [
"main",
"main.L2",
"poa_core",
"eth",
"eth_goerli",
"sepolia",
"eth",
"rootstock",
"polygon",
"zkevm",
"gnosis",
"rootstock",
"stability",
"poa_core",
"localhost",
],
"default": "main"
......
# Set of ENVs for Ethereum network explorer
# https://eth.blockscout.com/
# app configuration
NEXT_PUBLIC_APP_PROTOCOL=http
NEXT_PUBLIC_APP_HOST=localhost
NEXT_PUBLIC_APP_PORT=3000
# blockchain parameters
NEXT_PUBLIC_NETWORK_NAME=Stability Testnet
NEXT_PUBLIC_NETWORK_SHORT_NAME=Stability
NEXT_PUBLIC_NETWORK_ID=20180427
NEXT_PUBLIC_NETWORK_CURRENCY_NAME=FREE
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=FREE
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18
NEXT_PUBLIC_NETWORK_VERIFICATION_TYPE=validation
NEXT_PUBLIC_NETWORK_RPC_URL=https://free.testnet.stabilityprotocol.com
NEXT_PUBLIC_IS_TESTNET=true
# api configuration
NEXT_PUBLIC_API_HOST=stability-testnet.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
# ui config
## homepage
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND="rgb(255, 145, 0)"
NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND="rgba(46, 51, 81, 1)"
NEXT_PUBLIC_HOMEPAGE_PLATE_TEXT_COLOR="rgba(122, 235, 246, 1)"
## sidebar
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/rsk-testnet.json
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/stability.svg
NEXT_PUBLIC_NETWORK_LOGO_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/stability-dark.svg
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/stability-short.svg
NEXT_PUBLIC_NETWORK_ICON_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/stability-short-dark.svg
## footer
## views
NEXT_PUBLIC_VIEWS_ADDRESS_HIDDEN_VIEWS="['top_accounts']"
NEXT_PUBLIC_VIEWS_TX_HIDDEN_FIELDS="['value','fee_currency','gas_price','gas_fees','burnt_fees']"
NEXT_PUBLIC_VIEWS_TX_ADDITIONAL_FIELDS="['fee_per_gas']"
NEXT_PUBLIC_VIEWS_BLOCK_HIDDEN_FIELDS="['burnt_fees','total_reward']"
## misc
# app features
NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_HAS_BEACON_CHAIN=false
NEXT_PUBLIC_STATS_API_HOST=https://stats-stability-testnet.k8s.blockscout.com
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_CONTRACT_CODE_IDES="[{'title':'Remix IDE','url':'https://remix.blockscout.com/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]"
NEXT_PUBLIC_MARKETPLACE_ENABLED=true
NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-categories/default.json
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/shrqUAcjgGJ4jU88C
NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com/
NEXT_PUBLIC_GAS_TRACKER_ENABLED=false
NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE='stability'
#meta
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/stability.png
......@@ -657,7 +657,7 @@ export const RESOURCES = {
validators: {
path: '/api/v2/validators/:chainType',
pathParams: [ 'chainType' as const ],
filterFields: [ 'address_hash' as const, 'state' as const ],
filterFields: [ 'address_hash' as const, 'state_filter' as const ],
},
validators_counters: {
path: '/api/v2/validators/:chainType/counters',
......
......@@ -17,7 +17,8 @@ export enum EventTypes {
PAGE_WIDGET = 'Page widget',
TX_INTERPRETATION_INTERACTION = 'Transaction interpratetion interaction',
EXPERIMENT_STARTED = 'Experiment started',
FILTERS = 'Filters'
FILTERS = 'Filters',
BUTTON_CLICK = 'Button click',
}
/* eslint-disable @typescript-eslint/indent */
......@@ -107,5 +108,9 @@ Type extends EventTypes.FILTERS ? {
'Source': 'Marketplace';
'Filter name': string;
} :
Type extends EventTypes.BUTTON_CLICK ? {
'Content': 'Swap button';
'Source': string;
} :
undefined;
/* eslint-enable @typescript-eslint/indent */
......@@ -27,7 +27,6 @@ const ICONS: Record<keyof GasPrices, IconName> = {
};
const GasTrackerPriceSnippet = ({ data, type, isLoading }: Props) => {
const bgColors = {
fast: 'transparent',
average: useColorModeValue('gray.50', 'whiteAlpha.200'),
......@@ -43,19 +42,19 @@ const GasTrackerPriceSnippet = ({ data, type, isLoading }: Props) => {
w={{ lg: 'calc(100% / 3)' }}
bgColor={ bgColors[type] }
>
<Skeleton textStyle="h3" display="inline-block" isLoaded={ !isLoading }>{ TITLES[type] }</Skeleton>
<Skeleton textStyle="h3" isLoaded={ !isLoading } w="fit-content">{ TITLES[type] }</Skeleton>
<Flex columnGap={ 3 } alignItems="center" mt={ 3 }>
<IconSvg name={ ICONS[type] } boxSize={{ base: '30px', xl: 10 }} isLoading={ isLoading } flexShrink={ 0 }/>
<Skeleton isLoaded={ !isLoading }>
<GasPrice data={ data } fontSize={{ base: '36px', xl: '48px' }} lineHeight="48px" fontWeight={ 600 } letterSpacing="-1px" fontFamily="heading"/>
</Skeleton>
</Flex>
<Skeleton isLoaded={ !isLoading } fontSize="sm" color="text_secondary" mt={ 3 } display="inline-block">
<Skeleton isLoaded={ !isLoading } fontSize="sm" color="text_secondary" mt={ 3 } w="fit-content">
{ data.price && data.fiat_price && <GasPrice data={ data } prefix={ `${ asymp } ` } unitMode="secondary"/> }
<span> per transaction</span>
{ data.time && <span> / { (data.time / SECOND).toLocaleString(undefined, { maximumFractionDigits: 1 }) }s</span> }
</Skeleton>
<Skeleton isLoaded={ !isLoading } fontSize="sm" color="text_secondary" mt={ 2 } display="inline-block" whiteSpace="pre">
<Skeleton isLoaded={ !isLoading } fontSize="sm" color="text_secondary" mt={ 2 } w="fit-content" whiteSpace="pre">
{ data.base_fee && <span>Base { data.base_fee.toLocaleString(undefined, { maximumFractionDigits: 0 }) }</span> }
{ data.base_fee && data.priority_fee && <span> / </span> }
{ data.priority_fee && <span>Priority { data.priority_fee.toLocaleString(undefined, { maximumFractionDigits: 0 }) }</span> }
......
......@@ -30,6 +30,7 @@ export default function useMarketplace() {
const [ selectedCategoryId, setSelectedCategoryId ] = React.useState<string>(MarketplaceCategory.ALL);
const [ filterQuery, setFilterQuery ] = React.useState(defaultFilterQuery);
const [ favoriteApps, setFavoriteApps ] = React.useState<Array<string>>([]);
const [ isFavoriteAppsLoaded, setIsFavoriteAppsLoaded ] = React.useState<boolean>(false);
const [ isAppInfoModalOpen, setIsAppInfoModalOpen ] = React.useState<boolean>(false);
const [ isDisclaimerModalOpen, setIsDisclaimerModalOpen ] = React.useState<boolean>(false);
......@@ -71,11 +72,16 @@ export default function useMarketplace() {
setSelectedCategoryId(newCategory);
}, []);
const { isPlaceholderData, isError, error, data, displayedApps } = useMarketplaceApps(debouncedFilterQuery, selectedCategoryId, favoriteApps);
const { isPlaceholderData: isCategoriesPlaceholderData, data: categories } = useMarketplaceCategories(data, isPlaceholderData);
const {
isPlaceholderData, isError, error, data, displayedApps,
} = useMarketplaceApps(debouncedFilterQuery, selectedCategoryId, favoriteApps, isFavoriteAppsLoaded);
const {
isPlaceholderData: isCategoriesPlaceholderData, data: categories,
} = useMarketplaceCategories(data, isPlaceholderData);
React.useEffect(() => {
setFavoriteApps(getFavoriteApps());
setIsFavoriteAppsLoaded(true);
}, [ ]);
React.useEffect(() => {
......
......@@ -47,7 +47,12 @@ function sortApps(apps: Array<MarketplaceAppOverview>, favoriteApps: Array<strin
});
}
export default function useMarketplaceApps(filter: string, selectedCategoryId: string = MarketplaceCategory.ALL, favoriteApps: Array<string> = []) {
export default function useMarketplaceApps(
filter: string,
selectedCategoryId: string = MarketplaceCategory.ALL,
favoriteApps: Array<string> = [],
isFavoriteAppsLoaded: boolean = false, // eslint-disable-line @typescript-eslint/no-inferrable-types
) {
const fetch = useFetch();
const apiFetch = useApiFetch();
......@@ -55,7 +60,7 @@ export default function useMarketplaceApps(filter: string, selectedCategoryId: s
const lastFavoriteAppsRef = React.useRef(favoriteApps);
React.useEffect(() => {
lastFavoriteAppsRef.current = favoriteApps;
}, [ selectedCategoryId ]); // eslint-disable-line react-hooks/exhaustive-deps
}, [ selectedCategoryId, isFavoriteAppsLoaded ]); // eslint-disable-line react-hooks/exhaustive-deps
const { isPlaceholderData, isError, error, data } = useQuery<unknown, ResourceError<unknown>, Array<MarketplaceAppOverview>>({
queryKey: [ 'marketplace-dapps' ],
......
import { Button, Box } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
import { route } from 'nextjs-routes';
import config from 'configs/app';
import getPageType from 'lib/mixpanel/getPageType';
import * as mixpanel from 'lib/mixpanel/index';
import IconSvg from 'ui/shared/IconSvg';
const feature = config.features.swapButton;
const SwapButton = () => {
const router = useRouter();
const source = getPageType(router.pathname);
const handleClick = React.useCallback(() => {
mixpanel.logEvent(mixpanel.EventTypes.BUTTON_CLICK, { Content: 'Swap button', Source: source });
}, [ source ]);
if (!feature.isEnabled) {
return null;
}
......@@ -27,6 +37,7 @@ const SwapButton = () => {
borderRadius="sm"
height={ 5 }
px={ 1.5 }
onClick={ handleClick }
>
<IconSvg name="swap" boxSize={ 3 } mr={{ base: 0, sm: 1 }}/>
<Box display={{ base: 'none', sm: 'inline' }}>
......
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