Changeset View
Changeset View
Standalone View
Standalone View
web/cashtab/src/components/Home/Tx.js
import React, { useState } from 'react'; | import React, { useState } from 'react'; | ||||
import { Link } from 'react-router-dom'; | import { Link } from 'react-router-dom'; | ||||
import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||
import styled from 'styled-components'; | import styled from 'styled-components'; | ||||
import { | import { | ||||
SendIcon, | SendIcon, | ||||
ReceiveIcon, | ReceiveIcon, | ||||
GenesisIcon, | GenesisIcon, | ||||
UnparsedIcon, | UnparsedIcon, | ||||
ThemedContactsOutlined, | ThemedContactsOutlined, | ||||
} from 'components/Common/CustomIcons'; | } from 'components/Common/CustomIcons'; | ||||
import { currency } from 'components/Common/Ticker'; | import { currency } from 'components/Common/Ticker'; | ||||
import { fromLegacyDecimals } from 'utils/cashMethods'; | |||||
import { formatBalance, formatDate } from 'utils/formatting'; | import { formatBalance, formatDate } from 'utils/formatting'; | ||||
import TokenIcon from 'components/Tokens/TokenIcon'; | import TokenIcon from 'components/Tokens/TokenIcon'; | ||||
import { Collapse } from 'antd'; | import { Collapse } from 'antd'; | ||||
import CopyToClipboard from 'components/Common/CopyToClipboard'; | import CopyToClipboard from 'components/Common/CopyToClipboard'; | ||||
import { | import { | ||||
ThemedCopySolid, | ThemedCopySolid, | ||||
ThemedLinkSolid, | ThemedLinkSolid, | ||||
ThemedPdfSolid, | ThemedPdfSolid, | ||||
▲ Show 20 Lines • Show All 377 Lines • ▼ Show 20 Lines | const Tx = ({ | ||||
addressesInContactList, | addressesInContactList, | ||||
contactList, | contactList, | ||||
cashtabSettings, | cashtabSettings, | ||||
}) => { | }) => { | ||||
const [displayedMessage, setDisplayedMessage] = useState(false); | const [displayedMessage, setDisplayedMessage] = useState(false); | ||||
const handleShowMessage = () => { | const handleShowMessage = () => { | ||||
setDisplayedMessage(!displayedMessage); | setDisplayedMessage(!displayedMessage); | ||||
}; | }; | ||||
const txDate = | const txDate = formatDate(data.timeFirstSeen, navigator.language); | ||||
typeof data.blocktime === 'undefined' | |||||
? formatDate() | // A wallet migrating from bch-api tx history to chronik will get caught here for one update cycle | ||||
: formatDate(data.blocktime, navigator.language); | |||||
// if data only includes height and txid, then the tx could not be parsed by cashtab | |||||
// render as such but keep link to block explorer | |||||
let unparsedTx = false; | let unparsedTx = false; | ||||
if (!Object.keys(data).includes('outgoingTx')) { | if (!Object.keys(data).includes('parsed')) { | ||||
unparsedTx = true; | unparsedTx = true; | ||||
} | } | ||||
return ( | return ( | ||||
<> | <> | ||||
{unparsedTx ? ( | {unparsedTx ? ( | ||||
<TxWrapper> | <TxWrapper> | ||||
<UnparsedTx> | <UnparsedTx> | ||||
<UnparsedIcon /> | <UnparsedIcon /> | ||||
Show All 9 Lines | return ( | ||||
) : ( | ) : ( | ||||
<AntdContextCollapseWrapper> | <AntdContextCollapseWrapper> | ||||
<Collapse bordered={false}> | <Collapse bordered={false}> | ||||
<Panel | <Panel | ||||
showArrow={false} | showArrow={false} | ||||
header={ | header={ | ||||
<> | <> | ||||
<TxWrapper> | <TxWrapper> | ||||
{data.outgoingTx ? ( | {data.parsed.legacy.outgoingTx ? ( | ||||
<> | <> | ||||
{data.tokenTx && | {data.parsed.legacy.tokenTx && | ||||
data.tokenInfo | data.slpTxData.slpMeta | ||||
.transactionType === | .txType === 'GENESIS' ? ( | ||||
'GENESIS' ? ( | |||||
<GenesisTx> | <GenesisTx> | ||||
<GenesisIcon /> | <GenesisIcon /> | ||||
</GenesisTx> | </GenesisTx> | ||||
) : ( | ) : ( | ||||
<SentTx> | <SentTx> | ||||
<SendIcon /> | <SendIcon /> | ||||
</SentTx> | </SentTx> | ||||
)} | )} | ||||
</> | </> | ||||
) : ( | ) : ( | ||||
<ReceivedTx> | <ReceivedTx> | ||||
<ReceiveIcon /> | <ReceiveIcon /> | ||||
</ReceivedTx> | </ReceivedTx> | ||||
)} | )} | ||||
<LeftTextCtn> | <LeftTextCtn> | ||||
{data.outgoingTx ? ( | {data.parsed.legacy.outgoingTx ? ( | ||||
<> | <> | ||||
{data.tokenTx && | {data.parsed.legacy | ||||
data.tokenInfo | .tokenTx && | ||||
.transactionType === | data.slpTxData.slpMeta | ||||
.txType === | |||||
'GENESIS' ? ( | 'GENESIS' ? ( | ||||
<GenesisHeader> | <GenesisHeader> | ||||
Genesis | Genesis | ||||
</GenesisHeader> | </GenesisHeader> | ||||
) : ( | ) : ( | ||||
<h3>Sent</h3> | <h3>Sent</h3> | ||||
)} | )} | ||||
</> | </> | ||||
) : ( | ) : ( | ||||
<ReceivedFromCtn> | <ReceivedFromCtn> | ||||
<ReceivedHeader> | <ReceivedHeader> | ||||
Received | Received | ||||
</ReceivedHeader> | </ReceivedHeader> | ||||
{addressesInContactList.includes( | {addressesInContactList.includes( | ||||
data.replyAddress, | data.parsed.legacy | ||||
.replyAddress, | |||||
) && ( | ) && ( | ||||
<> | <> | ||||
<h4>from</h4> | <h4>from</h4> | ||||
{contactList.map( | {contactList.map( | ||||
( | ( | ||||
contact, | contact, | ||||
index, | index, | ||||
) => { | ) => { | ||||
let result; | let result; | ||||
const contactAddress = | const contactAddress = | ||||
contact.address; | contact.address; | ||||
const dataAddress = | const dataAddress = | ||||
data.replyAddress; | data | ||||
.parsed | |||||
.legacy | |||||
.replyAddress; | |||||
if ( | if ( | ||||
contactAddress === | contactAddress === | ||||
dataAddress | dataAddress | ||||
) { | ) { | ||||
result = | result = | ||||
contact.name; | contact.name; | ||||
} else { | } else { | ||||
result = | result = | ||||
Show All 11 Lines | return ( | ||||
}, | }, | ||||
)} | )} | ||||
</> | </> | ||||
)} | )} | ||||
</ReceivedFromCtn> | </ReceivedFromCtn> | ||||
)} | )} | ||||
<h4>{txDate}</h4> | <h4>{txDate}</h4> | ||||
</LeftTextCtn> | </LeftTextCtn> | ||||
{data.tokenTx ? ( | {data.parsed.legacy.tokenTx ? ( | ||||
<TokenInfo | <TokenInfo | ||||
outgoing={data.outgoingTx} | outgoing={ | ||||
data.parsed.legacy | |||||
.outgoingTx | |||||
} | |||||
> | > | ||||
{data.tokenTx && | {data.parsed.legacy.tokenTx && | ||||
data.tokenInfo ? ( | data.parsed.genesisInfo ? ( | ||||
<> | <> | ||||
<TxTokenIcon> | <TxTokenIcon> | ||||
<TokenIcon | <TokenIcon | ||||
size={32} | size={32} | ||||
tokenId={ | tokenId={ | ||||
data | data.parsed | ||||
.tokenInfo | .genesisInfo | ||||
.tokenId | .tokenId | ||||
} | } | ||||
/> | /> | ||||
</TxTokenIcon> | </TxTokenIcon> | ||||
{data.outgoingTx ? ( | {data.parsed.legacy | ||||
.outgoingTx ? ( | |||||
<RightTextCtn> | <RightTextCtn> | ||||
{data.tokenInfo | {data.slpTxData | ||||
.transactionType === | .slpMeta | ||||
.txType === | |||||
'GENESIS' ? ( | 'GENESIS' ? ( | ||||
<> | <> | ||||
<TokenTxAmtGenesis> | <TokenTxAmtGenesis> | ||||
+{' '} | +{' '} | ||||
{data.tokenInfo.qtyReceived.toString()} | {data.parsed.etokenAmount.toString()} | ||||
| | ||||
{ | { | ||||
data | data | ||||
.tokenInfo | .parsed | ||||
.genesisInfo | |||||
.tokenTicker | .tokenTicker | ||||
} | } | ||||
</TokenTxAmtGenesis> | </TokenTxAmtGenesis> | ||||
<TokenName> | <TokenName> | ||||
{ | { | ||||
data | data | ||||
.tokenInfo | .parsed | ||||
.genesisInfo | |||||
.tokenName | .tokenName | ||||
} | } | ||||
</TokenName> | </TokenName> | ||||
</> | </> | ||||
) : ( | ) : ( | ||||
<> | <> | ||||
<TokenTxAmt> | <TokenTxAmt> | ||||
-{' '} | -{' '} | ||||
{data.tokenInfo.qtySent.toString()} | {data.parsed.etokenAmount.toString()} | ||||
| | ||||
{ | { | ||||
data | data | ||||
.tokenInfo | .parsed | ||||
.genesisInfo | |||||
.tokenTicker | .tokenTicker | ||||
} | } | ||||
</TokenTxAmt> | </TokenTxAmt> | ||||
<TokenName> | <TokenName> | ||||
{ | { | ||||
data | data | ||||
.tokenInfo | .parsed | ||||
.genesisInfo | |||||
.tokenName | .tokenName | ||||
} | } | ||||
</TokenName> | </TokenName> | ||||
</> | </> | ||||
)} | )} | ||||
</RightTextCtn> | </RightTextCtn> | ||||
) : ( | ) : ( | ||||
<RightTextCtn> | <RightTextCtn> | ||||
<TokenTxAmtReceived> | <TokenTxAmtReceived> | ||||
+{' '} | +{' '} | ||||
{data.tokenInfo.qtyReceived.toString()} | {data.parsed.etokenAmount.toString()} | ||||
| | ||||
{ | { | ||||
data | data | ||||
.tokenInfo | .parsed | ||||
.genesisInfo | |||||
.tokenTicker | .tokenTicker | ||||
} | } | ||||
</TokenTxAmtReceived> | </TokenTxAmtReceived> | ||||
<TokenName> | <TokenName> | ||||
{ | { | ||||
data | data | ||||
.tokenInfo | .parsed | ||||
.genesisInfo | |||||
.tokenName | .tokenName | ||||
} | } | ||||
</TokenName> | </TokenName> | ||||
</RightTextCtn> | </RightTextCtn> | ||||
)} | )} | ||||
</> | </> | ||||
) : ( | ) : ( | ||||
<span>Token Tx</span> | <span>Token Tx</span> | ||||
)} | )} | ||||
</TokenInfo> | </TokenInfo> | ||||
) : ( | ) : ( | ||||
<> | <> | ||||
<TxInfo | <TxInfo | ||||
outgoing={data.outgoingTx} | outgoing={ | ||||
data.parsed.legacy | |||||
.outgoingTx | |||||
} | |||||
> | > | ||||
{data.outgoingTx ? ( | {data.parsed.legacy | ||||
.outgoingTx ? ( | |||||
<> | <> | ||||
<h3> | <h3> | ||||
- | - | ||||
{formatBalance( | {formatBalance( | ||||
fromLegacyDecimals( | data.parsed | ||||
data.amountSent, | .legacy | ||||
), | .amountSent, | ||||
)}{' '} | )}{' '} | ||||
{ | { | ||||
currency.ticker | currency.ticker | ||||
} | } | ||||
</h3> | </h3> | ||||
{fiatPrice !== | {fiatPrice !== | ||||
null && | null && | ||||
!isNaN( | !isNaN( | ||||
data.amountSent, | data.parsed | ||||
.legacy | |||||
.amountSent, | |||||
) && ( | ) && ( | ||||
<h4> | <h4> | ||||
- | - | ||||
{ | { | ||||
currency | currency | ||||
.fiatCurrencies[ | .fiatCurrencies[ | ||||
fiatCurrency | fiatCurrency | ||||
] | ] | ||||
.symbol | .symbol | ||||
} | } | ||||
{( | {( | ||||
fromLegacyDecimals( | data | ||||
data.amountSent, | .parsed | ||||
) * | .legacy | ||||
.amountSent * | |||||
fiatPrice | fiatPrice | ||||
).toFixed( | ).toFixed( | ||||
2, | 2, | ||||
)}{' '} | )}{' '} | ||||
{ | { | ||||
currency | currency | ||||
.fiatCurrencies | .fiatCurrencies | ||||
.fiatCurrency | .fiatCurrency | ||||
} | } | ||||
</h4> | </h4> | ||||
)} | )} | ||||
</> | </> | ||||
) : ( | ) : ( | ||||
<> | <> | ||||
<TokenTxAmtReceived> | <TokenTxAmtReceived> | ||||
+ | + | ||||
{formatBalance( | {formatBalance( | ||||
fromLegacyDecimals( | data.parsed | ||||
data.amountReceived, | .legacy | ||||
), | .amountReceived, | ||||
)}{' '} | )}{' '} | ||||
{ | { | ||||
currency.ticker | currency.ticker | ||||
} | } | ||||
</TokenTxAmtReceived> | </TokenTxAmtReceived> | ||||
{fiatPrice !== | {fiatPrice !== | ||||
null && | null && | ||||
!isNaN( | !isNaN( | ||||
data.amountReceived, | data.parsed | ||||
.legacy | |||||
.amountReceived, | |||||
) && ( | ) && ( | ||||
<h4> | <h4> | ||||
+ | + | ||||
{ | { | ||||
currency | currency | ||||
.fiatCurrencies[ | .fiatCurrencies[ | ||||
fiatCurrency | fiatCurrency | ||||
] | ] | ||||
.symbol | .symbol | ||||
} | } | ||||
{( | {( | ||||
fromLegacyDecimals( | data | ||||
data.amountReceived, | .parsed | ||||
) * | .legacy | ||||
.amountReceived * | |||||
fiatPrice | fiatPrice | ||||
).toFixed( | ).toFixed( | ||||
2, | 2, | ||||
)}{' '} | )}{' '} | ||||
{ | { | ||||
currency | currency | ||||
.fiatCurrencies | .fiatCurrencies | ||||
.fiatCurrency | .fiatCurrency | ||||
} | } | ||||
</h4> | </h4> | ||||
)} | )} | ||||
</> | </> | ||||
)} | )} | ||||
</TxInfo> | </TxInfo> | ||||
</> | </> | ||||
)} | )} | ||||
{data.opReturnMessage && ( | {data.parsed.legacy.opReturnMessage && ( | ||||
<> | <> | ||||
<OpReturnType | <OpReturnType | ||||
received={!data.outgoingTx} | received={ | ||||
!data.parsed.legacy | |||||
.outgoingTx | |||||
} | |||||
aria-expanded={ | aria-expanded={ | ||||
cashtabSettings.hideMessagesFromUnknownSenders | cashtabSettings.hideMessagesFromUnknownSenders | ||||
? displayedMessage | ? displayedMessage | ||||
: false | : false | ||||
} | } | ||||
> | > | ||||
{!data.outgoingTx && | {!data.parsed.legacy | ||||
.outgoingTx && | |||||
!addressesInContactList.includes( | !addressesInContactList.includes( | ||||
data.replyAddress, | data.parsed.legacy | ||||
.replyAddress, | |||||
) && ( | ) && ( | ||||
<NotInContactsAlert> | <NotInContactsAlert> | ||||
Warning: This | Warning: This | ||||
sender is not in | sender is not in | ||||
your contact | your contact | ||||
list. Beware of | list. Beware of | ||||
scams. | scams. | ||||
</NotInContactsAlert> | </NotInContactsAlert> | ||||
)} | )} | ||||
{data.isCashtabMessage ? ( | {data.parsed.legacy | ||||
.isCashtabMessage ? ( | |||||
<h4> | <h4> | ||||
Cashtab Message{' '} | Cashtab Message{' '} | ||||
</h4> | </h4> | ||||
) : ( | ) : ( | ||||
<h4> | <h4> | ||||
External Message | External Message | ||||
</h4> | </h4> | ||||
)} | )} | ||||
{data.isEncryptedMessage ? ( | {data.parsed.legacy | ||||
.isEncryptedMessage ? ( | |||||
<EncryptionMessageLabel> | <EncryptionMessageLabel> | ||||
- Encrypted | - Encrypted | ||||
</EncryptionMessageLabel> | </EncryptionMessageLabel> | ||||
) : ( | ) : ( | ||||
'' | '' | ||||
)} | )} | ||||
<br /> | <br /> | ||||
{cashtabSettings.hideMessagesFromUnknownSenders ? ( | {cashtabSettings.hideMessagesFromUnknownSenders ? ( | ||||
<> | <> | ||||
{/*unencrypted OP_RETURN Message*/} | {/*unencrypted OP_RETURN Message*/} | ||||
{data.opReturnMessage && | {data.parsed.legacy | ||||
!data.isEncryptedMessage && ( | .opReturnMessage && | ||||
!data.parsed | |||||
.legacy | |||||
.isEncryptedMessage && ( | |||||
<> | <> | ||||
{!displayedMessage && | {!displayedMessage && | ||||
!data.outgoingTx && | !data | ||||
.parsed | |||||
.legacy | |||||
.outgoingTx && | |||||
!addressesInContactList.includes( | !addressesInContactList.includes( | ||||
data.replyAddress, | data | ||||
.parsed | |||||
.legacy | |||||
.replyAddress, | |||||
) ? ( | ) ? ( | ||||
<ShowHideMessageButton | <ShowHideMessageButton | ||||
onClick={e => { | onClick={e => { | ||||
e.stopPropagation(); | e.stopPropagation(); | ||||
handleShowMessage(); | handleShowMessage(); | ||||
}} | }} | ||||
> | > | ||||
Show | Show | ||||
</ShowHideMessageButton> | </ShowHideMessageButton> | ||||
) : ( | ) : ( | ||||
<> | <> | ||||
<p> | <p> | ||||
{' '} | {' '} | ||||
{ | { | ||||
data.opReturnMessage | data | ||||
.parsed | |||||
.legacy | |||||
.opReturnMessage | |||||
} | } | ||||
</p> | </p> | ||||
{!addressesInContactList.includes( | {!addressesInContactList.includes( | ||||
data.replyAddress, | data | ||||
.parsed | |||||
.legacy | |||||
.replyAddress, | |||||
) && | ) && | ||||
!data.outgoingTx && ( | !data | ||||
.parsed | |||||
.legacy | |||||
.outgoingTx && ( | |||||
<ShowHideMessageButton | <ShowHideMessageButton | ||||
onClick={e => { | onClick={e => { | ||||
e.stopPropagation(); | e.stopPropagation(); | ||||
handleShowMessage(); | handleShowMessage(); | ||||
}} | }} | ||||
> | > | ||||
Hide | Hide | ||||
</ShowHideMessageButton> | </ShowHideMessageButton> | ||||
)} | )} | ||||
</> | </> | ||||
)} | )} | ||||
</> | </> | ||||
)} | )} | ||||
{data.opReturnMessage && | {data.parsed.legacy | ||||
data.isEncryptedMessage && ( | .opReturnMessage && | ||||
data.parsed | |||||
.legacy | |||||
.isEncryptedMessage && ( | |||||
<> | <> | ||||
{!displayedMessage && | {!displayedMessage && | ||||
!data.outgoingTx && | !data | ||||
.parsed | |||||
.legacy | |||||
.outgoingTx && | |||||
!addressesInContactList.includes( | !addressesInContactList.includes( | ||||
data.replyAddress, | data | ||||
.parsed | |||||
.legacy | |||||
.replyAddress, | |||||
) ? ( | ) ? ( | ||||
<ShowHideMessageButton | <ShowHideMessageButton | ||||
onClick={e => { | onClick={e => { | ||||
e.stopPropagation(); | e.stopPropagation(); | ||||
handleShowMessage(); | handleShowMessage(); | ||||
}} | }} | ||||
> | > | ||||
Show | Show | ||||
</ShowHideMessageButton> | </ShowHideMessageButton> | ||||
) : ( | ) : ( | ||||
<> | <> | ||||
<DecryptedMessage | <DecryptedMessage | ||||
authorized={ | authorized={ | ||||
data.decryptionSuccess | data | ||||
.parsed | |||||
.legacy | |||||
.decryptionSuccess | |||||
} | } | ||||
> | > | ||||
{ | { | ||||
data.opReturnMessage | data | ||||
.parsed | |||||
.legacy | |||||
.opReturnMessage | |||||
} | } | ||||
</DecryptedMessage> | </DecryptedMessage> | ||||
{!addressesInContactList.includes( | {!addressesInContactList.includes( | ||||
data.replyAddress, | data | ||||
.parsed | |||||
.legacy | |||||
.replyAddress, | |||||
) && | ) && | ||||
// do not render 'Hide' button if msg cannot be decrypted | // do not render 'Hide' button if msg cannot be decrypted | ||||
data.decryptionSuccess && ( | data | ||||
.parsed | |||||
.legacy | |||||
.decryptionSuccess && ( | |||||
<ShowHideMessageButton | <ShowHideMessageButton | ||||
onClick={e => { | onClick={e => { | ||||
e.stopPropagation(); | e.stopPropagation(); | ||||
handleShowMessage(); | handleShowMessage(); | ||||
}} | }} | ||||
> | > | ||||
Hide | Hide | ||||
</ShowHideMessageButton> | </ShowHideMessageButton> | ||||
)} | )} | ||||
</> | </> | ||||
)} | )} | ||||
</> | </> | ||||
)} | )} | ||||
</> | </> | ||||
) : ( | ) : ( | ||||
<> | <> | ||||
{/*unencrypted OP_RETURN Message*/} | {/*unencrypted OP_RETURN Message*/} | ||||
{data.opReturnMessage && | {data.parsed.legacy | ||||
!data.isEncryptedMessage ? ( | .opReturnMessage && | ||||
!data.parsed.legacy | |||||
.isEncryptedMessage ? ( | |||||
<p> | <p> | ||||
{ | { | ||||
data.opReturnMessage | data | ||||
.parsed | |||||
.legacy | |||||
.opReturnMessage | |||||
} | } | ||||
</p> | </p> | ||||
) : ( | ) : ( | ||||
'' | '' | ||||
)} | )} | ||||
{/*encrypted and wallet is authorized to view OP_RETURN Message*/} | {/*encrypted and wallet is authorized to view OP_RETURN Message*/} | ||||
{data.opReturnMessage && | {data.parsed.legacy | ||||
data.isEncryptedMessage && | .opReturnMessage && | ||||
data.decryptionSuccess ? ( | data.parsed.legacy | ||||
.isEncryptedMessage && | |||||
data.parsed.legacy | |||||
.decryptionSuccess ? ( | |||||
<p> | <p> | ||||
{ | { | ||||
data.opReturnMessage | data | ||||
.parsed | |||||
.legacy | |||||
.opReturnMessage | |||||
} | } | ||||
</p> | </p> | ||||
) : ( | ) : ( | ||||
'' | '' | ||||
)} | )} | ||||
{/*encrypted but wallet is not authorized to view OP_RETURN Message*/} | {/*encrypted but wallet is not authorized to view OP_RETURN Message*/} | ||||
{data.opReturnMessage && | {data.parsed.legacy | ||||
data.isEncryptedMessage && | .opReturnMessage && | ||||
!data.decryptionSuccess ? ( | data.parsed.legacy | ||||
.isEncryptedMessage && | |||||
!data.parsed.legacy | |||||
.decryptionSuccess ? ( | |||||
<UnauthorizedDecryptionMessage> | <UnauthorizedDecryptionMessage> | ||||
{ | { | ||||
data.opReturnMessage | data | ||||
.parsed | |||||
.legacy | |||||
.opReturnMessage | |||||
} | } | ||||
</UnauthorizedDecryptionMessage> | </UnauthorizedDecryptionMessage> | ||||
) : ( | ) : ( | ||||
'' | '' | ||||
)} | )} | ||||
</> | </> | ||||
)} | )} | ||||
{(!data.outgoingTx && | {(!data.parsed.legacy | ||||
data.replyAddress && | .outgoingTx && | ||||
data.parsed.legacy | |||||
.replyAddress && | |||||
addressesInContactList.includes( | addressesInContactList.includes( | ||||
data.replyAddress, | data.parsed.legacy | ||||
.replyAddress, | |||||
)) || | )) || | ||||
(!cashtabSettings.hideMessagesFromUnknownSenders && | (!cashtabSettings.hideMessagesFromUnknownSenders && | ||||
!data.outgoingTx && | !data.parsed.legacy | ||||
data.replyAddress && | .outgoingTx && | ||||
data.parsed.legacy | |||||
.replyAddress && | |||||
displayedMessage) ? ( | displayedMessage) ? ( | ||||
<Link | <Link | ||||
to={{ | to={{ | ||||
pathname: `/send`, | pathname: `/send`, | ||||
state: { | state: { | ||||
replyAddress: | replyAddress: | ||||
data.replyAddress, | data | ||||
.parsed | |||||
.legacy | |||||
.replyAddress, | |||||
}, | }, | ||||
}} | }} | ||||
> | > | ||||
Reply | Reply | ||||
</Link> | </Link> | ||||
) : ( | ) : ( | ||||
'' | '' | ||||
)} | )} | ||||
Show All 15 Lines | return ( | ||||
<DropdownButton> | <DropdownButton> | ||||
<DropdownIconWrapper> | <DropdownIconWrapper> | ||||
<TextLayer>Txid</TextLayer> | <TextLayer>Txid</TextLayer> | ||||
<ThemedCopySolid /> | <ThemedCopySolid /> | ||||
</DropdownIconWrapper> | </DropdownIconWrapper> | ||||
</DropdownButton> | </DropdownButton> | ||||
</CopyToClipboard> | </CopyToClipboard> | ||||
{data.opReturnMessage && ( | {data.parsed.legacy.opReturnMessage && ( | ||||
<CopyToClipboard | <CopyToClipboard | ||||
data={data.opReturnMessage} | data={ | ||||
data.parsed.legacy.opReturnMessage | |||||
} | |||||
optionalOnCopyNotification={{ | optionalOnCopyNotification={{ | ||||
title: 'Cashtab message copied to clipboard', | title: 'Cashtab message copied to clipboard', | ||||
msg: `${data.opReturnMessage}`, | msg: `${data.parsed.legacy.opReturnMessage}`, | ||||
}} | }} | ||||
> | > | ||||
<DropdownButton> | <DropdownButton> | ||||
<DropdownIconWrapper> | <DropdownIconWrapper> | ||||
<TextLayer>Msg</TextLayer> | <TextLayer>Msg</TextLayer> | ||||
<ThemedCopySolid /> | <ThemedCopySolid /> | ||||
</DropdownIconWrapper> | </DropdownIconWrapper> | ||||
</DropdownButton> | </DropdownButton> | ||||
Show All 22 Lines | return ( | ||||
> | > | ||||
<DropdownButton> | <DropdownButton> | ||||
<DropdownIconWrapper> | <DropdownIconWrapper> | ||||
<TextLayer>Receipt</TextLayer> | <TextLayer>Receipt</TextLayer> | ||||
<ThemedPdfSolid /> | <ThemedPdfSolid /> | ||||
</DropdownIconWrapper> | </DropdownIconWrapper> | ||||
</DropdownButton> | </DropdownButton> | ||||
</TxLink> | </TxLink> | ||||
{!data.outgoingTx && | {!data.parsed.legacy.outgoingTx && | ||||
data.replyAddress && | data.parsed.legacy.replyAddress && | ||||
!addressesInContactList.includes( | !addressesInContactList.includes( | ||||
data.replyAddress, | data.parsed.legacy.replyAddress, | ||||
) && ( | ) && ( | ||||
<AddToContacts> | <AddToContacts> | ||||
<DropdownButton> | <DropdownButton> | ||||
<Link | <Link | ||||
to={{ | to={{ | ||||
pathname: `/configure`, | pathname: `/configure`, | ||||
state: { | state: { | ||||
contactToAdd: | contactToAdd: | ||||
data.replyAddress, | data.parsed | ||||
.legacy | |||||
.replyAddress, | |||||
}, | }, | ||||
}} | }} | ||||
> | > | ||||
<DropdownIconWrapper> | <DropdownIconWrapper> | ||||
<TextLayer> | <TextLayer> | ||||
Add to contacts | Add to contacts | ||||
</TextLayer> | </TextLayer> | ||||
<ThemedContactsOutlined /> | <ThemedContactsOutlined /> | ||||
Show All 37 Lines |