Skip to content

Commit

Permalink
Merge pull request #126 from multiversx/scroll-to-section
Browse files Browse the repository at this point in the history
Scroll to Section
  • Loading branch information
radumojic authored Sep 11, 2024
2 parents a1328e1 + ba77edf commit a482fd7
Show file tree
Hide file tree
Showing 14 changed files with 438 additions and 245 deletions.
73 changes: 38 additions & 35 deletions src/components/DataDecode/DataDecode.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import BigNumber from 'bignumber.js';
import { Anchor, Dropdown } from 'react-bootstrap';
Expand All @@ -8,7 +8,7 @@ import { addressIsBech32, bech32, isUtf8 } from 'helpers';
import { faExclamationTriangle } from 'icons/regular';
import { TransactionTokensType } from 'types';

export enum DecodeMethodType {
export enum DecodeMethodEnum {
raw = 'raw',
text = 'text',
decimal = 'decimal',
Expand All @@ -17,18 +17,18 @@ export enum DecodeMethodType {

export const decode = (
part: string,
decodeMethod: DecodeMethodType | string,
decodeMethod: DecodeMethodEnum,
transactionTokens?: TransactionTokensType
) => {
switch (decodeMethod) {
case DecodeMethodType.text:
case DecodeMethodEnum.text:
try {
return Buffer.from(String(part), 'hex').toString('utf8');
} catch {}
return part;
case DecodeMethodType.decimal:
case DecodeMethodEnum.decimal:
return part !== '' ? new BigNumber(part, 16).toString(10) : '';
case DecodeMethodType.smart:
case DecodeMethodEnum.smart:
try {
const bech32Encoded = bech32.encode(part);
if (addressIsBech32(bech32Encoded)) {
Expand All @@ -54,7 +54,7 @@ export const decode = (
}
} catch {}
return part;
case DecodeMethodType.raw:
case DecodeMethodEnum.raw:
default:
return part;
}
Expand Down Expand Up @@ -88,7 +88,7 @@ export const decodeForDisplay = ({
identifier
}: {
input: string;
decodeMethod: DecodeMethodType;
decodeMethod: DecodeMethodEnum;
identifier?: string;
}) => {
const display: {
Expand Down Expand Up @@ -145,7 +145,7 @@ export const decodeForDisplay = ({
const parts = input.split('\n');
const initialDecodedParts = parts.map((part) => {
const base64Buffer = Buffer.from(String(part), 'base64');
if (decodeMethod === DecodeMethodType.raw) {
if (decodeMethod === DecodeMethodEnum.raw) {
return part;
} else {
return decode(base64Buffer.toString('hex'), decodeMethod);
Expand Down Expand Up @@ -198,24 +198,33 @@ export const DataDecode = ({
}: {
value: string;
className?: string;
initialDecodeMethod?: DecodeMethodType | string;
setDecodeMethod?: React.Dispatch<React.SetStateAction<string>>;
initialDecodeMethod?: DecodeMethodEnum;
setDecodeMethod?: Dispatch<SetStateAction<DecodeMethodEnum>>;
identifier?: string;
}) => {
const [activeKey, setActiveKey] = useState(
const defaultDecodeMethod =
initialDecodeMethod &&
Object.values<string>(DecodeMethodType).includes(initialDecodeMethod)
Object.values<string>(DecodeMethodEnum).includes(initialDecodeMethod)
? initialDecodeMethod
: DecodeMethodType.raw
);
: DecodeMethodEnum.raw;

const [activeKey, setActiveKey] = useState(defaultDecodeMethod);
const [displayValue, setDisplayValue] = useState('');
const [validationWarnings, setValidationWarnings] = useState<any>([]);
const [hasOverflow, setHasOverflow] = useState<boolean>(false);

const handleSelect = (eventKey: any) => {
if (!eventKey) {
return DecodeMethodEnum.raw;
}

setActiveKey(eventKey);
};

useEffect(() => {
const { displayValue, validationWarnings } = decodeForDisplay({
input: value,
decodeMethod: activeKey as DecodeMethodType,
decodeMethod: activeKey as DecodeMethodEnum,
identifier
});
setDisplayValue(displayValue);
Expand All @@ -242,9 +251,7 @@ export const DataDecode = ({
<CopyButton text={displayValue} className='copy-button' />
<Dropdown
className='position-absolute'
onSelect={(eventKey: any) => {
return eventKey ? setActiveKey(eventKey) : DecodeMethodType.raw;
}}
onSelect={handleSelect}
onToggle={(e) => {
setHasOverflow(e);
}}
Expand All @@ -264,39 +271,35 @@ export const DataDecode = ({
>
<Dropdown.Item
as={Anchor} // This is needed due to issues between threejs, react-bootstrap and typescript, what a time to be alive: https://github.com/react-bootstrap/react-bootstrap/issues/6283
eventKey={DecodeMethodType.raw}
className={`${
activeKey === DecodeMethodType.raw ? 'active' : ''
}`}
eventKey={DecodeMethodEnum.raw}
className={activeKey === DecodeMethodEnum.raw ? 'active' : ''}
>
Raw
</Dropdown.Item>
<Dropdown.Item
as={Anchor}
eventKey={DecodeMethodType.text}
className={`${
activeKey === DecodeMethodType.text ? 'active' : ''
}`}
eventKey={DecodeMethodEnum.text}
className={activeKey === DecodeMethodEnum.text ? 'active' : ''}
>
Text
</Dropdown.Item>
{value.length < MAX_DECODE_TX_DATA_LENGTH && (
<>
<Dropdown.Item
as={Anchor}
eventKey={DecodeMethodType.decimal}
className={`${
activeKey === DecodeMethodType.decimal ? 'active' : ''
}`}
eventKey={DecodeMethodEnum.decimal}
className={
activeKey === DecodeMethodEnum.decimal ? 'active' : ''
}
>
Decimal
</Dropdown.Item>
<Dropdown.Item
as={Anchor}
eventKey={DecodeMethodType.smart}
className={`${
activeKey === DecodeMethodType.smart ? 'active' : ''
}`}
eventKey={DecodeMethodEnum.smart}
className={
activeKey === DecodeMethodEnum.smart ? 'active' : ''
}
>
Smart
</Dropdown.Item>
Expand Down
30 changes: 19 additions & 11 deletions src/components/DetailItem/DetailItem.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export interface DetailItemType {
import classNames from 'classnames';
import { WithClassnameType } from 'types';

export interface DetailItemUIType extends WithClassnameType {
children?: React.ReactNode;
title?: string | React.ReactNode;
className?: string;
colWidth?: string;
noBorder?: boolean;
verticalCenter?: boolean;
Expand All @@ -14,23 +16,29 @@ export const DetailItem = ({
colWidth = '2',
noBorder = false,
verticalCenter = false
}: DetailItemType) => {
}: DetailItemUIType) => {
if (!title && !children) {
return null;
}

return (
<div
className={`row detail-item ${className} ${
noBorder ? 'pt-3 pb-1' : 'border-bottom py-3'
}`}
className={classNames(
'row detail-item',
{
'pt-3 pb-1': noBorder
},
{ 'border-bottom py-3': !noBorder },
className
)}
>
<div
className={`col-lg-${colWidth} ${
verticalCenter
? 'd-flex align-items-center justify-content-lg-end'
: ''
} text-lg-end text-neutral-400`}
className={classNames(
`col-lg-${colWidth} text-lg-end text-neutral-400`,
{
'd-flex align-items-center justify-content-lg-end': verticalCenter
}
)}
>
{title}
</div>
Expand Down
1 change: 1 addition & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ export * from './useNetworkRouter';
export * from './useNotifications';
export * from './useScamFlag';
export * from './useScollInView';
export * from './useScrollToTransactionSection';
export * from './useSearch';
export * from './useTempStorageNotification';
1 change: 1 addition & 0 deletions src/hooks/urlFilters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from './useGetPage';
export * from './useGetSearch';
export * from './useGetSort';
export * from './useGetTransactionFilters';
export * from './useGetTransactionUrlHashParams';
export * from './useGetTransactionInPoolFilters';
65 changes: 65 additions & 0 deletions src/hooks/urlFilters/useGetTransactionUrlHashParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { useLocation } from 'react-router-dom';

import { DecodeMethodEnum } from 'components/DataDecode';

export const useGetTransactionUrlHashParams = () => {
const { hash } = useLocation();

// hash order: hashId/hashIndex/hashDecodeMethod/secondHashDecodeMethod/thirdHashDecodeMethod

const hashArray = hash.replace('#', '').split('/');
const [firstParam, secondParam, thirdParam, fourthParam, fifthParam] =
hashArray;

if (
hashArray.length === 1 &&
Object.values<string>(DecodeMethodEnum).includes(firstParam)
) {
return {
hashId: '',
hashIndex: 0,
hashDecodeMethod: firstParam as DecodeMethodEnum,
secondHashDecodeMethod: DecodeMethodEnum.raw,
thirdHashDecodeMethod: DecodeMethodEnum.raw
};
}

if (
hashArray.length === 2 &&
Object.values<string>(DecodeMethodEnum).includes(secondParam)
) {
return {
hashId: firstParam,
hashIndex: 0,
hashDecodeMethod: secondParam as DecodeMethodEnum,
secondHashDecodeMethod: DecodeMethodEnum.raw,
thirdHashDecodeMethod: DecodeMethodEnum.raw
};
}

const hashDecodeMethod = Object.values<string>(DecodeMethodEnum).includes(
thirdParam
)
? (thirdParam as DecodeMethodEnum)
: DecodeMethodEnum.raw;

const secondHashDecodeMethod = Object.values<string>(
DecodeMethodEnum
).includes(fourthParam)
? (fourthParam as DecodeMethodEnum)
: DecodeMethodEnum.raw;

const thirdHashDecodeMethod = Object.values<string>(
DecodeMethodEnum
).includes(fifthParam)
? (fifthParam as DecodeMethodEnum)
: DecodeMethodEnum.raw;

return {
hashId: firstParam,
hashIndex: secondParam,
hashDecodeMethod,
secondHashDecodeMethod,
thirdHashDecodeMethod
};
};
21 changes: 21 additions & 0 deletions src/hooks/useScrollToTransactionSection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { RefObject, useEffect } from 'react';

import { useGetTransactionUrlHashParams } from 'hooks';

export const useScrollToTransactionSection = (
ref?: RefObject<HTMLDivElement>
) => {
const { hashId } = useGetTransactionUrlHashParams();

useEffect(() => {
setTimeout(() => {
if (hashId && ref?.current && ref.current !== null) {
ref.current.scrollIntoView({
behavior: 'smooth',
block: 'start',
inline: 'start'
});
}
}, 200);
}, [hashId]);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Dispatch, SetStateAction } from 'react';

import { DataDecode, DecodeMethodEnum } from 'components';

interface EventExtraDataUIType {
data: string[];
identifier?: string;
initialDecodeMethod?: DecodeMethodEnum;
setDecodeMethod?: Dispatch<SetStateAction<DecodeMethodEnum>>;
}

export const EventExtraData = ({
data,
identifier,
initialDecodeMethod,
setDecodeMethod
}: EventExtraDataUIType) => {
const mergedData = data.join('\n');

return (
<DataDecode
value={mergedData}
identifier={identifier}
initialDecodeMethod={initialDecodeMethod}
setDecodeMethod={setDecodeMethod}
/>
);
};
Loading

0 comments on commit a482fd7

Please sign in to comment.