Commit c7315ba0 authored by tom's avatar tom

tx socket

parent 49734a3e
......@@ -8,7 +8,7 @@ type Params = SocketSubscriber & {
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(() => {
if (isDisabled) {
return;
......@@ -20,6 +20,7 @@ export default function useSocketRoom({ isDisabled, channelId, eventId, onMessag
onMessage,
onClose,
onError,
hash,
} as SocketSubscriber;
const socket = (new Socket).init();
......@@ -29,5 +30,5 @@ export default function useSocketRoom({ isDisabled, channelId, eventId, onMessag
socket.leaveRoom(room);
socket.close();
};
}, [ channelId, eventId, isDisabled, onClose, onError, onMessage ]);
}, [ channelId, eventId, hash, isDisabled, onClose, onError, onMessage ]);
}
......@@ -77,7 +77,9 @@ class Socket {
this.socket?.removeEventListener('error', this.handleError);
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() {
......@@ -139,7 +141,7 @@ class Socket {
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 ];
export type SocketSubscriber = SocketSubscribers.BlocksNewBlock |
SocketSubscribers.BlockNewBlock |
SocketSubscribers.BlockNewBlock;
SocketSubscribers.BlockNewBlock |
SocketSubscribers.TxStatusUpdate;
interface SocketSubscriberGeneric<Channel extends string, Event extends string, Payload> {
channelId: Channel;
......@@ -20,4 +21,5 @@ export namespace SocketSubscribers {
export type BlocksNewBlock = SocketSubscriberGeneric<'blocks:new_block', 'new_block', NewBlockSocketResponse>;
export type BlocksIndexStatus = SocketSubscriberGeneric<'blocks:indexing', 'index_status', {finished: boolean; ratio: string}>;
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 { useQuery } from '@tanstack/react-query';
import { Grid, GridItem, Text, Box, Icon, Link, Spinner, Tag, Flex, Tooltip, Alert, chakra } from '@chakra-ui/react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import BigNumber from 'bignumber.js';
import { useRouter } from 'next/router';
import React from 'react';
import { scroller, Element } from 'react-scroll';
import type { SocketSubscribers } from 'lib/socket/types';
import type { Transaction } from 'types/api/transaction';
import { QueryKeys } from 'types/client/queries';
......@@ -16,6 +17,7 @@ import successIcon from 'icons/status/success.svg';
import { WEI, WEI_IN_GWEI } from 'lib/consts';
import dayjs from 'lib/date/dayjs';
import useFetch from 'lib/hooks/useFetch';
import useSocketRoom from 'lib/hooks/useSocketRoom';
import getConfirmationDuration from 'lib/tx/getConfirmationDuration';
import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
......@@ -46,6 +48,8 @@ const TOKEN_TRANSFERS = [
const TxDetails = () => {
const router = useRouter();
const fetch = useFetch();
const queryClient = useQueryClient();
const [ socketAlert, setSocketAlert ] = React.useState('');
const { data, isLoading, isError } = useQuery<unknown, unknown, Transaction>(
[ QueryKeys.tx, router.query.id ],
......@@ -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 handleCutClick = React.useCallback(() => {
......@@ -87,6 +113,11 @@ const TxDetails = () => {
return (
<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
title="Transaction hash"
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