import { Checkbox } from '@gear-js/ui'; import { Codec } from '@polkadot/types/types'; import { HexString } from '@polkadot/util/types'; import { isHex } from '@polkadot/util'; import { useEffect, useState } from 'react'; import { useProgram } from '@/features/program'; import { useMetadata } from '@/features/metadata'; import { PreformattedBlock } from '@/shared/ui/preformattedBlock'; import { isNullOrUndefined } from '@/shared/helpers'; import { FormattedUserMessageSentData, FormattedSendMessageData, FormattedSendReplyData, FormattedUploadProgramData, FormattedCreateProgramData, } from '../../types'; import { Method } from '../../consts'; import styles from './decoded-preformatted-block.module.scss'; type ProgramIdProps = { programId: HexString | undefined }; type UserMessageSentProps = { data: FormattedUserMessageSentData; method: Method.UserMessageSent }; type SendMessageProps = { data: FormattedSendMessageData; method: Method.SendMessage }; type SendReplyProps = { data: FormattedSendReplyData; method: Method.SendReply }; type UploadProgramProps = { data: FormattedUploadProgramData; method: Method.UploadProgram }; type CreateProgramProps = { data: FormattedCreateProgramData; method: Method.CreateProgram }; type Props = ProgramIdProps & (UserMessageSentProps | SendMessageProps | SendReplyProps | UploadProgramProps | CreateProgramProps); const DecodedPreformattedBlock = ({ programId, data, method }: Props) => { const getPayload = () => { switch (method) { case Method.UserMessageSent: return data.message.payload; case Method.SendMessage: case Method.SendReply: return data.payload; case Method.UploadProgram: case Method.CreateProgram: return data.initPayload; default: } }; const payload = getPayload(); const isFormattedPayloadHex = isHex(payload); const [decodedPayload, setDecodedPayload] = useState(); const [isDecodedPayload, setIsDecodedPayload] = useState(false); const [error, setError] = useState(''); const isError = !!error; const { data: program } = useProgram(isFormattedPayloadHex ? programId : undefined); const { metadata } = useMetadata(program?.metahash); const getTypes = () => { if (!metadata) return []; switch (method) { case Method.UserMessageSent: return [metadata.types.handle.output, metadata.types.init.output, metadata.types.others.output]; case Method.SendMessage: return [metadata.types.handle.input, metadata.types.others.input]; case Method.SendReply: return [metadata.types.reply]; case Method.UploadProgram: case Method.CreateProgram: return [metadata.types.init.input]; default: return []; } }; const decodeType = (type: number | null, isLastFallback: boolean) => { if (!metadata) return; try { if (isNullOrUndefined(type)) throw new Error(); setDecodedPayload(metadata.createType(type, payload)); return true; } catch { if (isLastFallback) setError("Can't decode payload"); return false; } }; useEffect(() => { if (!metadata) return; const types = getTypes(); const lastTypeIndex = types.length - 1; types.some((type, index) => decodeType(type, index === lastTypeIndex)); // eslint-disable-next-line react-hooks/exhaustive-deps }, [metadata]); const handleCheckboxChange = () => setIsDecodedPayload((prevValue) => !prevValue); const getDecodedPayloadData = () => { const formattedDecodedPayload = decodedPayload?.toHuman() || ''; switch (method) { case Method.UserMessageSent: return { ...data, message: { ...data.message, payload: formattedDecodedPayload } }; case Method.SendMessage: case Method.SendReply: return { ...data, payload: formattedDecodedPayload }; case Method.UploadProgram: case Method.CreateProgram: return { ...data, initPayload: formattedDecodedPayload }; default: } }; return ( <> {isFormattedPayloadHex && (
{isError &&

{error}

}
)} ); }; export { DecodedPreformattedBlock };