Commit c7315ba0 authored by tom's avatar tom

tx socket

parent 49734a3e
...@@ -8,7 +8,7 @@ type Params = SocketSubscriber & { ...@@ -8,7 +8,7 @@ type Params = SocketSubscriber & {
isDisabled: boolean; isDisabled: boolean;
} }
export default function useSocketRoom({ isDisabled, channelId, eventId, onMessage, onClose, onError }: Params) { export default function useSocketRoom({ isDisabled, channelId, eventId, onMessage, onClose, onError, hash }: Params) {
React.useEffect(() => { React.useEffect(() => {
if (isDisabled) { if (isDisabled) {
return; return;
...@@ -20,6 +20,7 @@ export default function useSocketRoom({ isDisabled, channelId, eventId, onMessag ...@@ -20,6 +20,7 @@ export default function useSocketRoom({ isDisabled, channelId, eventId, onMessag
onMessage, onMessage,
onClose, onClose,
onError, onError,
hash,
} as SocketSubscriber; } as SocketSubscriber;
const socket = (new Socket).init(); const socket = (new Socket).init();
...@@ -29,5 +30,5 @@ export default function useSocketRoom({ isDisabled, channelId, eventId, onMessag ...@@ -29,5 +30,5 @@ export default function useSocketRoom({ isDisabled, channelId, eventId, onMessag
socket.leaveRoom(room); socket.leaveRoom(room);
socket.close(); socket.close();
}; };
}, [ channelId, eventId, isDisabled, onClose, onError, onMessage ]); }, [ channelId, eventId, hash, isDisabled, onClose, onError, onMessage ]);
} }
...@@ -77,7 +77,9 @@ class Socket { ...@@ -77,7 +77,9 @@ class Socket {
this.socket?.removeEventListener('error', this.handleError); this.socket?.removeEventListener('error', this.handleError);
this.socket?.removeEventListener('close', this.handleClose); this.socket?.removeEventListener('close', this.handleClose);
Object.values(this.channels).forEach((channel) => channel.forEach((subscriber) => subscriber.onClose?.())); if (this.socket?.readyState === OPEN_STATE) {
Object.values(this.channels).forEach((channel) => channel.forEach((subscriber) => subscriber.onClose?.()));
}
} }
afterClose() { afterClose() {
...@@ -139,7 +141,7 @@ class Socket { ...@@ -139,7 +141,7 @@ class Socket {
return pattern; return pattern;
} }
return pattern.replace('[hash]', hash); return pattern.replace('[hash]', hash.toLowerCase());
} }
} }
......
...@@ -4,7 +4,8 @@ export type SocketData = [ null, null, string, string, unknown ]; ...@@ -4,7 +4,8 @@ export type SocketData = [ null, null, string, string, unknown ];
export type SocketSubscriber = SocketSubscribers.BlocksNewBlock | export type SocketSubscriber = SocketSubscribers.BlocksNewBlock |
SocketSubscribers.BlockNewBlock | SocketSubscribers.BlockNewBlock |
SocketSubscribers.BlockNewBlock; SocketSubscribers.BlockNewBlock |
SocketSubscribers.TxStatusUpdate;
interface SocketSubscriberGeneric<Channel extends string, Event extends string, Payload> { interface SocketSubscriberGeneric<Channel extends string, Event extends string, Payload> {
channelId: Channel; channelId: Channel;
...@@ -20,4 +21,5 @@ export namespace SocketSubscribers { ...@@ -20,4 +21,5 @@ export namespace SocketSubscribers {
export type BlocksNewBlock = SocketSubscriberGeneric<'blocks:new_block', 'new_block', NewBlockSocketResponse>; export type BlocksNewBlock = SocketSubscriberGeneric<'blocks:new_block', 'new_block', NewBlockSocketResponse>;
export type BlocksIndexStatus = SocketSubscriberGeneric<'blocks:indexing', 'index_status', {finished: boolean; ratio: string}>; export type BlocksIndexStatus = SocketSubscriberGeneric<'blocks:indexing', 'index_status', {finished: boolean; ratio: string}>;
export type BlockNewBlock = SocketSubscriberGeneric<'blocks:[hash]', 'new_block', NewBlockSocketResponse>; export type BlockNewBlock = SocketSubscriberGeneric<'blocks:[hash]', 'new_block', NewBlockSocketResponse>;
export type TxStatusUpdate = SocketSubscriberGeneric<'transactions:[hash]', 'collated', NewBlockSocketResponse>;
} }
import { Grid, GridItem, Text, Box, Icon, Link, Spinner, Tag, Flex, Tooltip, chakra } from '@chakra-ui/react'; import { Grid, GridItem, Text, Box, Icon, Link, Spinner, Tag, Flex, Tooltip, Alert, chakra } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery, useQueryClient } from '@tanstack/react-query';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import { scroller, Element } from 'react-scroll'; import { scroller, Element } from 'react-scroll';
import type { SocketSubscribers } from 'lib/socket/types';
import type { Transaction } from 'types/api/transaction'; import type { Transaction } from 'types/api/transaction';
import { QueryKeys } from 'types/client/queries'; import { QueryKeys } from 'types/client/queries';
...@@ -16,6 +17,7 @@ import successIcon from 'icons/status/success.svg'; ...@@ -16,6 +17,7 @@ import successIcon from 'icons/status/success.svg';
import { WEI, WEI_IN_GWEI } from 'lib/consts'; import { WEI, WEI_IN_GWEI } from 'lib/consts';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import useFetch from 'lib/hooks/useFetch'; import useFetch from 'lib/hooks/useFetch';
import useSocketRoom from 'lib/hooks/useSocketRoom';
import getConfirmationDuration from 'lib/tx/getConfirmationDuration'; import getConfirmationDuration from 'lib/tx/getConfirmationDuration';
import Address from 'ui/shared/address/Address'; import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressIcon from 'ui/shared/address/AddressIcon';
...@@ -46,6 +48,8 @@ const TOKEN_TRANSFERS = [ ...@@ -46,6 +48,8 @@ const TOKEN_TRANSFERS = [
const TxDetails = () => { const TxDetails = () => {
const router = useRouter(); const router = useRouter();
const fetch = useFetch(); const fetch = useFetch();
const queryClient = useQueryClient();
const [ socketAlert, setSocketAlert ] = React.useState('');
const { data, isLoading, isError } = useQuery<unknown, unknown, Transaction>( const { data, isLoading, isError } = useQuery<unknown, unknown, Transaction>(
[ QueryKeys.tx, router.query.id ], [ QueryKeys.tx, router.query.id ],
...@@ -55,6 +59,28 @@ const TxDetails = () => { ...@@ -55,6 +59,28 @@ const TxDetails = () => {
}, },
); );
const handleStatusUpdateMessage: SocketSubscribers.BlocksNewBlock['onMessage'] = React.useCallback(() => {
queryClient.invalidateQueries({ queryKey: [ QueryKeys.tx, router.query.id ] });
}, [ queryClient, router.query.id ]);
const handleSocketClose = React.useCallback(() => {
setSocketAlert('Connection is lost. Please click here to update transaction info.');
}, []);
const handleSocketError = React.useCallback(() => {
setSocketAlert('An error has occurred while fetching new blocks. Please click here to update transaction info.');
}, []);
useSocketRoom({
channelId: 'transactions:[hash]',
eventId: 'collated',
hash: data?.hash,
onMessage: handleStatusUpdateMessage,
onClose: handleSocketClose,
onError: handleSocketError,
isDisabled: isLoading || isError,
});
const [ isExpanded, setIsExpanded ] = React.useState(false); const [ isExpanded, setIsExpanded ] = React.useState(false);
const handleCutClick = React.useCallback(() => { const handleCutClick = React.useCallback(() => {
...@@ -87,6 +113,11 @@ const TxDetails = () => { ...@@ -87,6 +113,11 @@ const TxDetails = () => {
return ( return (
<Grid columnGap={ 8 } rowGap={{ base: 3, lg: 3 }} templateColumns={{ base: 'minmax(0, 1fr)', lg: 'auto minmax(0, 1fr)' }}> <Grid columnGap={ 8 } rowGap={{ base: 3, lg: 3 }} templateColumns={{ base: 'minmax(0, 1fr)', lg: 'auto minmax(0, 1fr)' }}>
{ socketAlert && (
<GridItem colSpan={{ base: undefined, lg: 2 }} mb={ 2 }>
<Alert status="warning" as="a" href={ window.document.location.href }>{ socketAlert }</Alert>
</GridItem>
) }
<DetailsInfoItem <DetailsInfoItem
title="Transaction hash" title="Transaction hash"
hint="Unique character string (TxID) assigned to every verified transaction." hint="Unique character string (TxID) assigned to every verified transaction."
......
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