Setup react-query

pull/4/head
J M Rossy 2 years ago
parent edf5652bea
commit e95f5cf6c5
  1. 2
      .prettierrc
  2. 1
      package.json
  3. 41
      src/components/search/SearchError.tsx
  4. 2
      src/consts/appConfig.ts
  5. 2
      src/consts/networksConfig.ts
  6. 30
      src/features/debugger/TxDebugger.tsx
  7. 3
      src/features/search/MessageSearch.tsx
  8. 15
      src/pages/_app.tsx
  9. 27
      yarn.lock

@ -3,7 +3,7 @@
"printWidth": 100,
"singleQuote": true,
"trailingComma": "all",
"importOrder": ["^@abacus-network/(.*)$", "^../(.*)$", "^./(.*)$"],
"importOrder": ["^@hyperlane-xyz/(.*)$", "^../(.*)$", "^./(.*)$"],
"importOrderSeparation": true,
"importOrderSortSpecifiers": true
}

@ -7,6 +7,7 @@
"@hyperlane-xyz/sdk": "^0.5.0-beta0",
"@metamask/jazzicon": "https://github.com/jmrossy/jazzicon#7a8df28974b4e81129bfbe3cab76308b889032a6",
"@rainbow-me/rainbowkit": "^0.4.5",
"@tanstack/react-query": "^4.6.0",
"buffer": "^6.0.3",
"ethers": "^5.6.8",
"formik": "^2.2.9",

@ -1,5 +1,6 @@
import Image from 'next/future/image';
import BugIcon from '../../images/icons/bug.svg';
import ErrorIcon from '../../images/icons/error-circle.svg';
import SearchOffIcon from '../../images/icons/search-off.svg';
import ShrugIcon from '../../images/icons/shrug.svg';
@ -31,25 +32,55 @@ export function SearchError({
);
}
export function SearchInvalidError({ show }: { show: boolean }) {
export function NoSearchError({ show }: { show: boolean }) {
return (
<SearchError
show={show}
imgSrc={BugIcon}
text="Enter a transaction hash that involved at least one Hyperlane message to begin."
imgWidth={50}
/>
);
}
export function SearchInvalidError({
show,
allowAddress,
}: {
show: boolean;
allowAddress: boolean;
}) {
return (
<SearchError
show={show}
imgSrc={SearchOffIcon}
text="Sorry, that search input is not valid. Please try an account
addresses or a transaction hash like 0x123..."
text={`Sorry, that search input is not valid. Please try ${
allowAddress ? 'an account addresses or ' : ''
}a transaction hash like 0xABC123...`}
imgWidth={70}
/>
);
}
export function SearchEmptyError({ show, hasInput }: { show: boolean; hasInput: boolean }) {
export function SearchEmptyError({
show,
hasInput,
allowAddress,
}: {
show: boolean;
hasInput: boolean;
allowAddress: boolean;
}) {
return (
<SearchError
show={show}
imgSrc={ShrugIcon}
text={`Sorry, no results found. Please try ${
hasInput ? 'a different address or hash' : 'again later'
hasInput
? allowAddress
? 'a different address or transaction hash'
: 'a different transaction hash'
: 'again later'
}.`}
imgWidth={110}
/>

@ -9,7 +9,7 @@ export const configs: Record<Environment, Config> = {
debug: isDevMode,
version,
url: 'https://explorer.hyperlane.xyz',
apiUrl: 'https://abacus-explorer-api.hasura.app/v1/graphql',
apiUrl: 'https://abacus-explorer-api.hasura.app/v1/graphql', // TODO change
},
testnet2: {
environment: Environment.Testnet2,

@ -1,6 +1,6 @@
import { Chain, allChains as allChainsWagmi, chain } from 'wagmi';
import { chainConnectionConfigs } from '@abacus-network/sdk';
import { chainConnectionConfigs } from '@hyperlane-xyz/sdk';
export const testConfigs = {
goerli: chainConnectionConfigs.goerli,

@ -1,8 +1,10 @@
import { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { useCallback, useState } from 'react';
import { Fade } from '../../components/animation/Fade';
import { SearchBar } from '../../components/search/SearchBar';
import {
NoSearchError,
SearchEmptyError,
SearchInvalidError,
SearchUnknownError,
@ -13,6 +15,8 @@ import useDebounce from '../../utils/debounce';
import { sanitizeString } from '../../utils/string';
import { isValidSearchQuery } from '../search/utils';
import { debugMessageForHash } from './debugMessage';
export function TxDebugger() {
const environment = useStore((s) => s.environment);
@ -21,11 +25,15 @@ export function TxDebugger() {
const debouncedSearchInput = useDebounce(searchInput, 750);
const hasInput = !!debouncedSearchInput;
const sanitizedInput = sanitizeString(debouncedSearchInput);
const isValidInput = hasInput ? isValidSearchQuery(sanitizedInput, false) : true;
const isValidInput = isValidSearchQuery(sanitizedInput, false);
const fetching = false;
const hasError = false;
const txResult = {};
// Debugger query
const query = useCallback(() => {
if (!isValidInput || !sanitizedInput) return null;
else return debugMessageForHash(sanitizedInput, environment);
}, [isValidInput, sanitizedInput, environment]);
const { isLoading: fetching, error, data } = useQuery(['debugMessage'], query);
const hasError = !!error;
return (
<>
@ -36,19 +44,19 @@ export function TxDebugger() {
placeholder="Search transaction hash to debug message"
/>
<div className="w-full h-[38.05rem] mt-5 bg-white shadow-md border border-blue-50 rounded overflow-auto relative">
{/* Content header and filter bar */}
<div className="px-2 py-3 sm:px-4 md:px-5 md:py-3 flex items-center justify-between border-b border-gray-100">
<h2 className="text-gray-600">{`Transaction Debugger (${envDisplayValue[environment]})`}</h2>
</div>
{/* Message list */}
<Fade show={!hasError && isValidInput && !!txResult}>{JSON.stringify(txResult)}</Fade>
<SearchInvalidError show={!isValidInput} />
<SearchUnknownError show={isValidInput && hasError} />
<Fade show={isValidInput && !hasError && !!data}>{JSON.stringify(data)}</Fade>
<SearchEmptyError
show={isValidInput && !hasError && !fetching && !txResult}
show={isValidInput && !hasError && !fetching && !data}
hasInput={hasInput}
allowAddress={false}
/>
<NoSearchError show={!hasInput && !hasError} />
<SearchInvalidError show={hasInput && !hasError && !isValidInput} allowAddress={false} />
<SearchUnknownError show={hasInput && hasError} />
</div>
</>
);

@ -125,11 +125,12 @@ export function MessageSearch() {
))}
</Fade>
<SearchInvalidError show={!isValidInput} />
<SearchInvalidError show={!isValidInput} allowAddress={true} />
<SearchUnknownError show={isValidInput && hasError} />
<SearchEmptyError
show={isValidInput && !hasError && !fetching && messageList.length === 0}
hasInput={hasInput}
allowAddress={true}
/>
</div>
</>

@ -5,6 +5,7 @@ import {
wallet,
} from '@rainbow-me/rainbowkit';
import '@rainbow-me/rainbowkit/styles.css';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import type { AppProps } from 'next/app';
import { ToastContainer, Zoom, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
@ -52,6 +53,8 @@ const urqlClients: Record<Environment, Client> = {
}),
};
const reactQueryClient = new QueryClient();
export default function App({ Component, router, pageProps }: AppProps) {
const environment = useStore((s) => s.environment);
@ -74,11 +77,13 @@ export default function App({ Component, router, pageProps }: AppProps) {
fontStack: 'system',
})}
>
<UrqlProvider value={urqlClients[environment]}>
<AppLayout pathName={pathName}>
<Component {...pageProps} />
</AppLayout>
</UrqlProvider>
<QueryClientProvider client={reactQueryClient}>
<UrqlProvider value={urqlClients[environment]}>
<AppLayout pathName={pathName}>
<Component {...pageProps} />
</AppLayout>
</UrqlProvider>
</QueryClientProvider>
</RainbowKitProvider>
<ToastContainer transition={Zoom} position={toast.POSITION.BOTTOM_RIGHT} limit={2} />
</WagmiConfig>

@ -885,6 +885,7 @@ __metadata:
"@hyperlane-xyz/sdk": ^0.5.0-beta0
"@metamask/jazzicon": "https://github.com/jmrossy/jazzicon#7a8df28974b4e81129bfbe3cab76308b889032a6"
"@rainbow-me/rainbowkit": ^0.4.5
"@tanstack/react-query": ^4.6.0
"@trivago/prettier-plugin-sort-imports": ^3.2.0
"@types/node": 18.0.4
"@types/react": 18.0.15
@ -1257,6 +1258,32 @@ __metadata:
languageName: node
linkType: hard
"@tanstack/query-core@npm:4.6.0":
version: 4.6.0
resolution: "@tanstack/query-core@npm:4.6.0"
checksum: 945a3b1ddc89ddf484f828cee0be5db0939f51865b2518f8c4ef351c6a3fc992f8c9fbbd32a5bf16b97d0250e95f43c1e571d5a1dfefd99ab835ffe0f934b159
languageName: node
linkType: hard
"@tanstack/react-query@npm:^4.6.0":
version: 4.6.0
resolution: "@tanstack/react-query@npm:4.6.0"
dependencies:
"@tanstack/query-core": 4.6.0
use-sync-external-store: ^1.2.0
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
react-native: "*"
peerDependenciesMeta:
react-dom:
optional: true
react-native:
optional: true
checksum: 39b9f5a71b1c699927db515419889b04e60410472481c5b08645eda8310c73c0c8acfcdffd9d63a5730eefff5e74a4a84939082fbe467d3af0571d837978fbb5
languageName: node
linkType: hard
"@tootallnate/once@npm:2":
version: 2.0.0
resolution: "@tootallnate/once@npm:2.0.0"

Loading…
Cancel
Save