diff --git a/web/cashtab/src/assets/copy.svg b/web/cashtab/src/assets/copy.svg
new file mode 100644
index 000000000..37b371f6a
--- /dev/null
+++ b/web/cashtab/src/assets/copy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/web/cashtab/src/assets/external-link-square-alt.svg b/web/cashtab/src/assets/external-link-square-alt.svg
new file mode 100644
index 000000000..e2b6e07ee
--- /dev/null
+++ b/web/cashtab/src/assets/external-link-square-alt.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/web/cashtab/src/components/Common/CustomIcons.js b/web/cashtab/src/components/Common/CustomIcons.js
index c487f449f..185623392 100644
--- a/web/cashtab/src/components/Common/CustomIcons.js
+++ b/web/cashtab/src/components/Common/CustomIcons.js
@@ -1,89 +1,105 @@
import * as React from 'react';
import styled from 'styled-components';
import {
CopyOutlined,
DollarOutlined,
LoadingOutlined,
WalletOutlined,
QrcodeOutlined,
SettingOutlined,
LockOutlined,
} from '@ant-design/icons';
import { Image } from 'antd';
import { currency } from '@components/Common/Ticker';
import { ReactComponent as Send } from '@assets/send.svg';
import { ReactComponent as Receive } from '@assets/receive.svg';
import { ReactComponent as Genesis } from '@assets/flask.svg';
import { ReactComponent as Unparsed } from '@assets/alert-circle.svg';
import { ReactComponent as Home } from '@assets/home.svg';
import { ReactComponent as Settings } from '@assets/cog.svg';
+import { ReactComponent as CopySolid } from '@assets/copy.svg';
+import { ReactComponent as LinkSolid } from '@assets/external-link-square-alt.svg';
export const CashLoadingIcon = ;
export const CashReceivedNotificationIcon = () => (
);
export const TokenReceivedNotificationIcon = () => (
);
export const MessageSignedNotificationIcon = () => (
);
export const ThemedCopyOutlined = styled(CopyOutlined)`
color: ${props => props.theme.icons.outlined} !important;
`;
export const ThemedDollarOutlined = styled(DollarOutlined)`
color: ${props => props.theme.icons.outlined} !important;
`;
export const ThemedWalletOutlined = styled(WalletOutlined)`
color: ${props => props.theme.icons.outlined} !important;
`;
export const ThemedQrcodeOutlined = styled(QrcodeOutlined)`
color: ${props => props.theme.walletBackground} !important;
`;
export const ThemedSettingOutlined = styled(SettingOutlined)`
color: ${props => props.theme.icons.outlined} !important;
`;
export const ThemedLockOutlined = styled(LockOutlined)`
color: ${props => props.theme.icons.outlined} !important;
`;
+export const ThemedCopySolid = styled(CopySolid)`
+ fill: ${props => props.theme.contrast};
+ padding: 0rem 0rem 0.27rem 0rem;
+ height: 1.3em;
+ width: 1.3em;
+`;
+
+export const ThemedLinkSolid = styled(LinkSolid)`
+ fill: ${props => props.theme.contrast};
+ padding: 0.15rem 0rem 0.18rem 0rem;
+ height: 1.3em;
+ width: 1.3em;
+`;
+
export const LoadingBlock = styled.div`
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
flex-direction: column;
svg {
width: 50px;
height: 50px;
fill: ${props => props.theme.eCashBlue};
}
`;
export const CashLoader = () => (
);
export const ReceiveIcon = () => ;
export const GenesisIcon = () => ;
export const UnparsedIcon = () => ;
export const HomeIcon = () => ;
export const SettingsIcon = () => ;
export const SendIcon = styled(Send)`
transform: rotate(-35deg);
`;
diff --git a/web/cashtab/src/components/Common/Notifications.js b/web/cashtab/src/components/Common/Notifications.js
index 4b0e7943d..81332534e 100644
--- a/web/cashtab/src/components/Common/Notifications.js
+++ b/web/cashtab/src/components/Common/Notifications.js
@@ -1,182 +1,192 @@
import * as React from 'react';
import { notification } from 'antd';
import {
CashReceivedNotificationIcon,
TokenReceivedNotificationIcon,
} from '@components/Common/CustomIcons';
import Paragraph from 'antd/lib/typography/Paragraph';
import { currency } from '@components/Common/Ticker';
import { MessageSignedNotificationIcon } from '@components/Common/CustomIcons';
import { isMobile } from 'react-device-detect';
const getDeviceNotificationStyle = () => {
if (isMobile) {
const notificationStyle = {
width: '100%',
marginTop: '10%',
};
return notificationStyle;
}
if (!isMobile) {
const notificationStyle = {
width: '100%',
};
return notificationStyle;
}
};
// Success Notifications:
const sendXecNotification = link => {
const notificationStyle = getDeviceNotificationStyle();
notification.success({
message: 'Success',
description: (
Transaction successful. Click to view in block explorer.
),
duration: currency.notificationDurationShort,
icon: ,
style: notificationStyle,
});
};
const createTokenNotification = link => {
const notificationStyle = getDeviceNotificationStyle();
notification.success({
message: 'Success',
description: (
Token created! Click to view in block explorer.
),
icon: ,
style: notificationStyle,
});
};
const tokenIconSubmitSuccess = () => {
const notificationStyle = getDeviceNotificationStyle();
notification.success({
message: 'Success',
description: (
Your eToken icon was successfully submitted.
),
icon: ,
style: notificationStyle,
});
};
const sendTokenNotification = link => {
const notificationStyle = getDeviceNotificationStyle();
notification.success({
message: 'Success',
description: (
Transaction successful. Click to view in block explorer.
),
duration: currency.notificationDurationShort,
icon: ,
style: notificationStyle,
});
};
const xecReceivedNotification = (
balances,
previousBalances,
cashtabSettings,
fiatPrice,
) => {
const notificationStyle = getDeviceNotificationStyle();
notification.success({
message: 'Transaction received',
description: (
+{' '}
{parseFloat(
Number(
balances.totalBalance - previousBalances.totalBalance,
).toFixed(currency.cashDecimals),
).toLocaleString()}{' '}
{currency.ticker}{' '}
{cashtabSettings &&
cashtabSettings.fiatCurrency &&
`(${
currency.fiatCurrencies[cashtabSettings.fiatCurrency]
.symbol
}${(
Number(
balances.totalBalance -
previousBalances.totalBalance,
) * fiatPrice
).toFixed(
currency.cashDecimals,
)} ${cashtabSettings.fiatCurrency.toUpperCase()})`}
),
duration: currency.notificationDurationShort,
icon: ,
style: notificationStyle,
});
};
const eTokenReceivedNotification = (
currency,
receivedSlpTicker,
receivedSlpQty,
receivedSlpName,
) => {
const notificationStyle = getDeviceNotificationStyle();
notification.success({
message: `${currency.tokenTicker} transaction received: ${receivedSlpTicker}`,
description: (
You received {receivedSlpQty.toString()} {receivedSlpName}
),
duration: currency.notificationDurationShort,
icon: ,
style: notificationStyle,
});
};
// Error Notification:
const errorNotification = (error, message, stringDescribingCallEvent) => {
const notificationStyle = getDeviceNotificationStyle();
console.log(error, message, stringDescribingCallEvent);
notification.error({
message: 'Error',
description: message,
duration: currency.notificationDurationLong,
style: notificationStyle,
});
};
const messageSignedNotification = msgSignature => {
const notificationStyle = getDeviceNotificationStyle();
notification.success({
message: 'Message Signature Generated',
description: {msgSignature} ,
icon: ,
style: notificationStyle,
});
};
+const generalNotification = (data, msgStr) => {
+ const notificationStyle = getDeviceNotificationStyle();
+ notification.success({
+ message: msgStr,
+ description: data,
+ style: notificationStyle,
+ });
+};
+
export {
sendXecNotification,
createTokenNotification,
tokenIconSubmitSuccess,
sendTokenNotification,
xecReceivedNotification,
eTokenReceivedNotification,
errorNotification,
messageSignedNotification,
+ generalNotification,
};
diff --git a/web/cashtab/src/components/Common/StyledCollapse.js b/web/cashtab/src/components/Common/StyledCollapse.js
index 782c03f8b..e98eb1be6 100644
--- a/web/cashtab/src/components/Common/StyledCollapse.js
+++ b/web/cashtab/src/components/Common/StyledCollapse.js
@@ -1,92 +1,114 @@
import styled from 'styled-components';
import { Collapse } from 'antd';
export const StyledCollapse = styled(Collapse)`
background: ${props => props.theme.collapses.background} !important;
border: 1px solid ${props => props.theme.collapses.border} !important;
.ant-collapse-content {
border-top: none;
background-color: ${props =>
props.theme.collapses.expandedBackground} !important;
}
.ant-collapse-item {
border-bottom: none !important;
}
*:not(button) {
color: ${props => props.theme.collapses.color} !important;
}
`;
export const TokenCollapse = styled(Collapse)`
${({ disabled = false, ...props }) =>
disabled === true
? `
background: ${props.theme.buttons.secondary.background} !important;
.ant-collapse-header {
font-size: 18px;
font-weight: bold;
color: ${props.theme.buttons.secondary.color} !important;
svg {
color: ${props.theme.buttons.secondary.color} !important;
}
}
.ant-collapse-arrow {
font-size: 18px;
}
`
: `
background: ${props.theme.eCashBlue} !important;
.ant-collapse-header {
font-size: 18px;
font-weight: bold;
color: ${props.theme.contrast} !important;
svg {
color: ${props.theme.contrast} !important;
}
}
.ant-collapse-arrow {
font-size: 18px;
}
`}
`;
export const AdvancedCollapse = styled(Collapse)`
.ant-collapse-content {
background-color: ${props =>
props.theme.advancedCollapse.expandedBackground} !important;
}
${({ disabled = false, ...props }) =>
disabled === true
? `
background: ${props.theme.buttons.secondary.background} !important;
.ant-collapse-header {
font-size: 18px;
font-weight: normal;
color: ${props.theme.buttons.secondary.color} !important;
svg {
color: ${props.theme.buttons.secondary.color} !important;
}
}
.ant-collapse-arrow {
font-size: 18px;
}
`
: `
background: ${props.theme.advancedCollapse.background} !important;
.ant-collapse-header {
font-size: 18px;
font-weight: bold;
color: ${props.theme.advancedCollapse.color} !important;
svg {
color: ${props.theme.advancedCollapse.icon} !important;
}
}
.ant-collapse-arrow {
font-size: 18px;
}
`}
`;
+
+export const AntdContextCollapseWrapper = styled.div`
+ .ant-collapse {
+ border: none !important;
+ background-color: transparent !important;
+ }
+ .ant-collapse-item {
+ border: none !important;
+ }
+ .ant-collapse-header {
+ padding: 0 !important;
+ color: ${props => props.theme.forms.text} !important;
+ }
+ border-radius: 16px;
+ .ant-collapse-content-box {
+ padding-right: 0 !important;
+ }
+
+ @media screen and (max-width: 500px) {
+ grid-template-columns: 24px 30% 50%;
+ }
+`;
diff --git a/web/cashtab/src/components/Configure/__tests__/__snapshots__/Configure.test.js.snap b/web/cashtab/src/components/Configure/__tests__/__snapshots__/Configure.test.js.snap
index f27cbd546..65dd7225c 100644
--- a/web/cashtab/src/components/Configure/__tests__/__snapshots__/Configure.test.js.snap
+++ b/web/cashtab/src/components/Configure/__tests__/__snapshots__/Configure.test.js.snap
@@ -1,805 +1,805 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP @generated
exports[`Configure with a wallet 1`] = `
Backup your wallet
Your seed phrase is the only way to restore your wallet. Write it down. Keep it safe.
Click to reveal seed phrase
Manage Wallets
New Wallet
Import Wallet
Fiat Currency
General Settings
[
Documentation
|
Privacy Policy
]
`;
exports[`Configure without a wallet 1`] = `
Backup your wallet
Your seed phrase is the only way to restore your wallet. Write it down. Keep it safe.
Manage Wallets
New Wallet
Import Wallet
Fiat Currency
General Settings
[
Documentation
|
Privacy Policy
]
`;
diff --git a/web/cashtab/src/components/Home/Tx.js b/web/cashtab/src/components/Home/Tx.js
index 94f8de7d9..83617fe68 100644
--- a/web/cashtab/src/components/Home/Tx.js
+++ b/web/cashtab/src/components/Home/Tx.js
@@ -1,544 +1,707 @@
import React from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
-import styled from 'styled-components';
+import styled, { css } from 'styled-components';
import {
SendIcon,
ReceiveIcon,
GenesisIcon,
UnparsedIcon,
} from '@components/Common/CustomIcons';
import { currency } from '@components/Common/Ticker';
import { fromLegacyDecimals } from '@utils/cashMethods';
import { formatBalance, formatDate } from '@utils/formatting';
import TokenIcon from '@components/Tokens/TokenIcon';
-
+import { Collapse } from 'antd';
+import { AntdContextCollapseWrapper } from '@components/Common/StyledCollapse';
+import { generalNotification } from '@components/Common/Notifications';
+import { CopyToClipboard } from 'react-copy-to-clipboard';
+import {
+ ThemedCopySolid,
+ ThemedLinkSolid,
+} from '@components/Common/CustomIcons';
const TxIcon = styled.div`
svg {
width: 20px;
height: 20px;
}
height: 40px;
width: 40px;
border: 1px solid #fff;
display: flex;
align-items: center;
justify-content: center;
border-radius: 100px;
`;
const SentTx = styled(TxIcon)`
svg {
margin-right: -3px;
}
fill: ${props => props.theme.contrast};
`;
const ReceivedTx = styled(TxIcon)`
svg {
fill: ${props => props.theme.eCashBlue};
}
border-color: ${props => props.theme.eCashBlue};
`;
const GenesisTx = styled(TxIcon)`
border-color: ${props => props.theme.genesisGreen};
svg {
fill: ${props => props.theme.genesisGreen};
}
`;
const UnparsedTx = styled(TxIcon)`
color: ${props => props.theme.eCashBlue} !important;
`;
const DateType = styled.div`
text-align: left;
padding: 12px;
@media screen and (max-width: 500px) {
font-size: 0.8rem;
}
`;
const LeftTextCtn = styled.div`
text-align: left;
display: flex;
align-items: left;
flex-direction: column;
margin-left: 10px;
h3 {
color: ${props => props.theme.contrast};
font-size: 14px;
font-weight: 700;
margin: 0;
}
.genesis {
color: ${props => props.theme.genesisGreen};
}
.received {
color: ${props => props.theme.eCashBlue};
}
h4 {
font-size: 12px;
color: ${props => props.theme.lightWhite};
margin: 0;
}
`;
const RightTextCtn = styled.div`
text-align: right;
display: flex;
align-items: left;
flex-direction: column;
margin-left: 10px;
h3 {
color: ${props => props.theme.contrast};
font-size: 14px;
font-weight: 700;
margin: 0;
}
.genesis {
color: ${props => props.theme.genesisGreen};
}
.received {
color: ${props => props.theme.eCashBlue};
}
h4 {
font-size: 12px;
color: ${props => props.theme.lightWhite};
margin: 0;
}
`;
const OpReturnType = styled.div`
text-align: right;
width: 100%;
padding: 10px;
border-radius: 5px;
background: ${props => props.theme.sentMessage};
margin-top: 15px;
h4 {
color: ${props => props.theme.lightWhite};
margin: 0;
font-size: 12px;
display: inline-block;
}
p {
color: ${props => props.theme.contrast};
margin: 0;
font-size: 14px;
margin-bottom: 10px;
overflow-wrap: break-word;
}
a {
color: ${props => props.theme.contrast};
margin: 0;
font-size: 10px;
border: 1px solid ${props => props.theme.contrast};
border-radius: 5px;
padding: 2px 10px;
opacity: 0.6;
}
a:hover {
opacity: 1;
border-color: ${props => props.theme.eCashBlue};
color: ${props => props.theme.contrast};
background: ${props => props.theme.eCashBlue};
}
${({ received, ...props }) =>
received &&
`
text-align: left;
background: ${props.theme.receivedMessage};
`}
`;
const SentLabel = styled.span`
font-weight: bold;
color: ${props => props.theme.secondary} !important;
`;
const ReceivedLabel = styled.span`
font-weight: bold;
color: ${props => props.theme.eCashBlue} !important;
`;
const GenesisLabel = styled.span`
font-weight: bold;
color: ${props => props.theme.genesisGreen} !important;
`;
const CashtabMessageLabel = styled.span`
text-align: left;
font-weight: bold;
color: ${props => props.theme.eCashBlue} !important;
white-space: nowrap;
`;
const EncryptionMessageLabel = styled.span`
font-weight: bold;
font-size: 12px;
color: ${props => props.theme.encryptionRed};
white-space: nowrap;
`;
const UnauthorizedDecryptionMessage = styled.span`
text-align: left;
color: ${props => props.theme.encryptionRed};
white-space: nowrap;
font-style: italic;
`;
const MessageLabel = styled.span`
text-align: left;
font-weight: bold;
color: ${props => props.theme.secondary} !important;
white-space: nowrap;
`;
const ReplyMessageLabel = styled.span`
color: ${props => props.theme.eCashBlue} !important;
`;
const TxInfo = styled.div`
text-align: right;
display: flex;
align-items: left;
flex-direction: column;
margin-left: 10px;
flex-grow: 2;
h3 {
color: ${props => props.theme.contrast};
font-size: 14px;
font-weight: 700;
margin: 0;
}
.genesis {
color: ${props => props.theme.genesisGreen};
}
.received {
color: ${props => props.theme.eCashBlue};
}
h4 {
font-size: 12px;
color: ${props => props.theme.lightWhite};
margin: 0;
}
@media screen and (max-width: 500px) {
font-size: 0.8rem;
}
`;
const TokenInfo = styled.div`
display: flex;
flex-grow: 1;
justify-content: flex-end;
color: ${props =>
props.outgoing ? props.theme.secondary : props.theme.eCashBlue};
@media screen and (max-width: 500px) {
font-size: 0.8rem;
grid-template-columns: 16px auto;
}
`;
const TxTokenIcon = styled.div`
img {
height: 24px;
width: 24px;
}
@media screen and (max-width: 500px) {
img {
height: 16px;
width: 16px;
}
}
grid-column-start: 1;
grid-column-end: span 1;
grid-row-start: 1;
grid-row-end: span 2;
align-self: center;
`;
const TokenTxAmt = styled.h3`
text-align: right;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
`;
const TokenName = styled.h4`
text-align: right;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
`;
const TxWrapper = styled.div`
display: flex;
align-items: center;
border-top: 1px solid rgba(255, 255, 255, 0.12);
color: ${props => props.theme.contrast};
padding: 10px 0;
flex-wrap: wrap;
`;
+const Panel = Collapse.Panel;
+
+const DropdownIconWrapper = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 4px;
+`;
+
+const TextLayer = styled.div`
+ font-size: 12px;
+ color: ${props => props.theme.contrast};
+`;
+
+const DropdownButton = styled.button`
+ display: flex;
+ justify-content: flex-end;
+ background-color: ${props => props.theme.walletBackground};
+ border: none;
+ cursor: pointer;
+ padding: 0;
+ &:hover {
+ div {
+ color: ${props => props.theme.eCashBlue}!important;
+ }
+ svg {
+ fill: ${props => props.theme.eCashBlue}!important;
+ }
+ }
+`;
+const PanelCtn = styled.div`
+ display: flex;
+ justify-content: flex-end;
+ right: 0;
+ gap: 8px;
+`;
+
+export const TxLink = styled.a`
+ color: ${props => props.theme.primary};
+`;
+
const Tx = ({ data, fiatPrice, fiatCurrency }) => {
const txDate =
typeof data.blocktime === 'undefined'
? formatDate()
: 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;
if (!Object.keys(data).includes('outgoingTx')) {
unparsedTx = true;
}
return (
<>
{unparsedTx ? (
Unparsed
{txDate}
Open in Explorer
) : (
-
- {data.outgoingTx ? (
- <>
- {data.tokenTx &&
- data.tokenInfo.transactionType === 'GENESIS' ? (
-
-
-
- ) : (
-
-
-
- )}
- >
- ) : (
-
-
-
- )}
-
-
- {data.outgoingTx ? (
- <>
- {data.tokenTx &&
- data.tokenInfo.transactionType === 'GENESIS' ? (
- Genesis
- ) : (
- Sent
- )}
- >
- ) : (
- Received
- )}
- {txDate}
-
- {data.tokenTx ? (
-
- {data.tokenTx && data.tokenInfo ? (
+
+
+
-
-
-
- {data.outgoingTx ? (
-
- {data.tokenInfo.transactionType ===
- 'GENESIS' ? (
+
+ {data.outgoingTx ? (
+ <>
+ {data.tokenTx &&
+ data.tokenInfo
+ .transactionType ===
+ 'GENESIS' ? (
+
+
+
+ ) : (
+
+
+
+ )}
+ >
+ ) : (
+
+
+
+ )}
+
+
+ {data.outgoingTx ? (
<>
-
- +{' '}
- {data.tokenInfo.qtyReceived.toString()}
-
- {
- data.tokenInfo
- .tokenTicker
- }
-
-
- {
- data.tokenInfo
- .tokenName
- }
-
+ {data.tokenTx &&
+ data.tokenInfo
+ .transactionType ===
+ 'GENESIS' ? (
+
+ Genesis
+
+ ) : (
+
+ Sent
+
+ )}
>
) : (
- <>
-
- -{' '}
- {data.tokenInfo.qtySent.toString()}
-
- {
- data.tokenInfo
- .tokenTicker
- }
-
-
- {
- data.tokenInfo
- .tokenName
- }
-
- >
+
+ Received
+
)}
-
- ) : (
-
-
- +{' '}
- {data.tokenInfo.qtyReceived.toString()}
-
- {data.tokenInfo.tokenTicker}
-
-
- {data.tokenInfo.tokenName}
-
-
- )}
+ {txDate}
+
+ {data.tokenTx ? (
+
+ {data.tokenTx &&
+ data.tokenInfo ? (
+ <>
+
+
+
+ {data.outgoingTx ? (
+
+ {data.tokenInfo
+ .transactionType ===
+ 'GENESIS' ? (
+ <>
+
+ +{' '}
+ {data.tokenInfo.qtyReceived.toString()}
+
+ {
+ data
+ .tokenInfo
+ .tokenTicker
+ }
+
+
+ {
+ data
+ .tokenInfo
+ .tokenName
+ }
+
+ >
+ ) : (
+ <>
+
+ -{' '}
+ {data.tokenInfo.qtySent.toString()}
+
+ {
+ data
+ .tokenInfo
+ .tokenTicker
+ }
+
+
+ {
+ data
+ .tokenInfo
+ .tokenName
+ }
+
+ >
+ )}
+
+ ) : (
+
+
+ +{' '}
+ {data.tokenInfo.qtyReceived.toString()}
+
+ {
+ data
+ .tokenInfo
+ .tokenTicker
+ }
+
+
+ {
+ data
+ .tokenInfo
+ .tokenName
+ }
+
+
+ )}
+ >
+ ) : (
+ Token Tx
+ )}
+
+ ) : (
+ <>
+
+ {data.outgoingTx ? (
+ <>
+
+ -
+ {formatBalance(
+ fromLegacyDecimals(
+ data.amountSent,
+ ),
+ )}{' '}
+ {
+ currency.ticker
+ }
+
+ {fiatPrice !==
+ null &&
+ !isNaN(
+ data.amountSent,
+ ) && (
+
+ -
+ {
+ currency
+ .fiatCurrencies[
+ fiatCurrency
+ ]
+ .symbol
+ }
+ {(
+ fromLegacyDecimals(
+ data.amountSent,
+ ) *
+ fiatPrice
+ ).toFixed(
+ 2,
+ )}{' '}
+ {
+ currency
+ .fiatCurrencies
+ .fiatCurrency
+ }
+
+ )}
+ >
+ ) : (
+ <>
+
+ +
+ {formatBalance(
+ fromLegacyDecimals(
+ data.amountReceived,
+ ),
+ )}{' '}
+ {
+ currency.ticker
+ }
+
+ {fiatPrice !==
+ null &&
+ !isNaN(
+ data.amountReceived,
+ ) && (
+
+ +
+ {
+ currency
+ .fiatCurrencies[
+ fiatCurrency
+ ]
+ .symbol
+ }
+ {(
+ fromLegacyDecimals(
+ data.amountReceived,
+ ) *
+ fiatPrice
+ ).toFixed(
+ 2,
+ )}{' '}
+ {
+ currency
+ .fiatCurrencies
+ .fiatCurrency
+ }
+
+ )}
+ >
+ )}
+
+ >
+ )}
+ {data.opReturnMessage && (
+ <>
+
+ {data.isCashtabMessage ? (
+ Cashtab Message
+ ) : (
+
+ External Message
+
+ )}
+ {data.isEncryptedMessage ? (
+
+ - Encrypted
+
+ ) : (
+ ''
+ )}
+
+ {/*unencrypted OP_RETURN Message*/}
+ {data.opReturnMessage &&
+ !data.isEncryptedMessage ? (
+
+ {
+ data.opReturnMessage
+ }
+
+ ) : (
+ ''
+ )}
+ {/*encrypted and wallet is authorized to view OP_RETURN Message*/}
+ {data.opReturnMessage &&
+ data.isEncryptedMessage &&
+ data.decryptionSuccess ? (
+
+ {
+ data.opReturnMessage
+ }
+
+ ) : (
+ ''
+ )}
+ {/*encrypted but wallet is not authorized to view OP_RETURN Message*/}
+ {data.opReturnMessage &&
+ data.isEncryptedMessage &&
+ !data.decryptionSuccess ? (
+
+ {
+ data.opReturnMessage
+ }
+
+ ) : (
+ ''
+ )}
+ {!data.outgoingTx &&
+ data.replyAddress ? (
+
+ Reply To Message
+
+ ) : (
+ ''
+ )}
+
+ >
+ )}
+
>
- ) : (
- Token Tx
- )}
-
- ) : (
- <>
-
- {data.outgoingTx ? (
- <>
-
- -
- {formatBalance(
- fromLegacyDecimals(
- data.amountSent,
- ),
- )}{' '}
- {currency.ticker}
-
- {fiatPrice !== null &&
- !isNaN(data.amountSent) && (
-
- -
- {
- currency.fiatCurrencies[
- fiatCurrency
- ].symbol
- }
- {(
- fromLegacyDecimals(
- data.amountSent,
- ) * fiatPrice
- ).toFixed(2)}{' '}
- {
- currency.fiatCurrencies
- .fiatCurrency
- }
-
- )}
- >
- ) : (
- <>
-
- +
- {formatBalance(
- fromLegacyDecimals(
- data.amountReceived,
- ),
- )}{' '}
- {currency.ticker}
-
- {fiatPrice !== null &&
- !isNaN(data.amountReceived) && (
-
- +
- {
- currency.fiatCurrencies[
- fiatCurrency
- ].symbol
- }
- {(
- fromLegacyDecimals(
- data.amountReceived,
- ) * fiatPrice
- ).toFixed(2)}{' '}
- {
- currency.fiatCurrencies
- .fiatCurrency
- }
-
- )}
- >
- )}
-
- >
- )}
- {data.opReturnMessage && (
- <>
-
- {data.isCashtabMessage ? (
- Cashtab Message
- ) : (
- External Message
- )}
- {data.isEncryptedMessage ? (
-
- - Encrypted
-
- ) : (
- ''
- )}
-
- {/*unencrypted OP_RETURN Message*/}
- {data.opReturnMessage &&
- !data.isEncryptedMessage ? (
- {data.opReturnMessage}
- ) : (
- ''
- )}
- {/*encrypted and wallet is authorized to view OP_RETURN Message*/}
- {data.opReturnMessage &&
- data.isEncryptedMessage &&
- data.decryptionSuccess ? (
- {data.opReturnMessage}
- ) : (
- ''
- )}
- {/*encrypted but wallet is not authorized to view OP_RETURN Message*/}
- {data.opReturnMessage &&
- data.isEncryptedMessage &&
- !data.decryptionSuccess ? (
-
- {data.opReturnMessage}
-
- ) : (
- ''
- )}
- {!data.outgoingTx && data.replyAddress ? (
-
+
+
+ {
+ generalNotification(
+ data.txid,
+ 'Tx ID copied to clipboard',
+ );
}}
>
- Reply To Message
-
- ) : (
- ''
- )}
-
- >
- )}
-
+
+ Copy Tx ID
+
+
+
+
+
+
+
+
+
+ View on be.cash
+
+
+
+
+
+
+
+
+
+
)}
>
);
};
Tx.propTypes = {
data: PropTypes.object,
fiatPrice: PropTypes.number,
fiatCurrency: PropTypes.string,
};
export default Tx;
diff --git a/web/cashtab/src/components/Home/TxHistory.js b/web/cashtab/src/components/Home/TxHistory.js
index c79a317ee..21364d613 100644
--- a/web/cashtab/src/components/Home/TxHistory.js
+++ b/web/cashtab/src/components/Home/TxHistory.js
@@ -1,37 +1,27 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import Tx from './Tx';
-export const TxLink = styled.a`
- color: ${props => props.theme.forms.text};
-`;
-
const TxHistory = ({ txs, fiatPrice, fiatCurrency }) => {
return (
{txs.map(tx => (
-
-
-
+ data={tx}
+ fiatPrice={fiatPrice}
+ fiatCurrency={fiatCurrency}
+ />
))}
);
};
TxHistory.propTypes = {
txs: PropTypes.array,
fiatPrice: PropTypes.number,
fiatCurrency: PropTypes.string,
};
export default TxHistory;
diff --git a/web/cashtab/src/components/Home/__tests__/__snapshots__/Home.test.js.snap b/web/cashtab/src/components/Home/__tests__/__snapshots__/Home.test.js.snap
index 1a1e37413..f930fc356 100644
--- a/web/cashtab/src/components/Home/__tests__/__snapshots__/Home.test.js.snap
+++ b/web/cashtab/src/components/Home/__tests__/__snapshots__/Home.test.js.snap
@@ -1,481 +1,481 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP @generated
exports[`Wallet with BCH balances 1`] = `
Array [
MigrationTestAlpha
0
XEC
$
NaN
USD
,
Transactions
eTokens
🎉
Congratulations on your new wallet!
🎉
Start using the wallet immediately to receive
XEC
payments, or load it up with
XEC
to send to others
Create eToken
Tokens sent to your
eToken
address will appear here
,
]
`;
exports[`Wallet with BCH balances and tokens 1`] = `
Array [
MigrationTestAlpha
0
XEC
$
NaN
USD
,
Transactions
eTokens
🎉
Congratulations on your new wallet!
🎉
Start using the wallet immediately to receive
XEC
payments, or load it up with
XEC
to send to others
Create eToken
Tokens sent to your
eToken
address will appear here
,
]
`;
exports[`Wallet with BCH balances and tokens and state field 1`] = `
Array [
MigrationTestAlpha
0.06
XEC
$
NaN
USD
,
Transactions
eTokens
🎉
Congratulations on your new wallet!
🎉
Start using the wallet immediately to receive
XEC
payments, or load it up with
XEC
to send to others
,
]
`;
exports[`Wallet without BCH balance 1`] = `
Array [
MigrationTestAlpha
0
XEC
$
NaN
USD
,
Transactions
eTokens
🎉
Congratulations on your new wallet!
🎉
Start using the wallet immediately to receive
XEC
payments, or load it up with
XEC
to send to others
Create eToken
Tokens sent to your
eToken
address will appear here
,
]
`;
exports[`Without wallet defined 1`] = `
`;
diff --git a/web/cashtab/src/components/Receive/__tests__/__snapshots__/Receive.test.js.snap b/web/cashtab/src/components/Receive/__tests__/__snapshots__/Receive.test.js.snap
index 94ce4a59c..9bb24f511 100644
--- a/web/cashtab/src/components/Receive/__tests__/__snapshots__/Receive.test.js.snap
+++ b/web/cashtab/src/components/Receive/__tests__/__snapshots__/Receive.test.js.snap
@@ -1,534 +1,534 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP @generated
exports[`Wallet with BCH balances 1`] = `
`;
exports[`Wallet with BCH balances and tokens 1`] = `
`;
exports[`Wallet with BCH balances and tokens and state field 1`] = `
`;
exports[`Wallet without BCH balance 1`] = `
`;
exports[`Without wallet defined 1`] = `
`;
diff --git a/web/cashtab/src/components/Send/__tests__/__snapshots__/Send.test.js.snap b/web/cashtab/src/components/Send/__tests__/__snapshots__/Send.test.js.snap
index 26ccd26f6..e7faa995c 100644
--- a/web/cashtab/src/components/Send/__tests__/__snapshots__/Send.test.js.snap
+++ b/web/cashtab/src/components/Send/__tests__/__snapshots__/Send.test.js.snap
@@ -1,2354 +1,2354 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP @generated
exports[`Wallet with BCH balances 1`] = `
Array [
MigrationTestAlpha
You currently have 0
XEC
Deposit some funds to use this feature
,
,
]
`;
exports[`Wallet with BCH balances and tokens 1`] = `
Array [
MigrationTestAlpha
You currently have 0
XEC
Deposit some funds to use this feature
,
,
]
`;
exports[`Wallet with BCH balances and tokens and state field 1`] = `
Array [
MigrationTestAlpha
0.06
XEC
$
NaN
USD
,
,
]
`;
exports[`Wallet without BCH balance 1`] = `
Array [
MigrationTestAlpha
You currently have 0
XEC
Deposit some funds to use this feature
,
,
]
`;
exports[`Without wallet defined 1`] = `
Array [
You currently have 0
XEC
Deposit some funds to use this feature
,
,
]
`;
diff --git a/web/cashtab/src/components/Send/__tests__/__snapshots__/SendToken.test.js.snap b/web/cashtab/src/components/Send/__tests__/__snapshots__/SendToken.test.js.snap
index ce4787c5a..b149f9337 100644
--- a/web/cashtab/src/components/Send/__tests__/__snapshots__/SendToken.test.js.snap
+++ b/web/cashtab/src/components/Send/__tests__/__snapshots__/SendToken.test.js.snap
@@ -1,244 +1,244 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP @generated
exports[`Wallet with BCH balances and tokens 1`] = `null`;
exports[`Wallet with BCH balances and tokens and state field 1`] = `
`;
exports[`Without wallet defined 1`] = `null`;
diff --git a/web/cashtab/src/components/Tokens/__tests__/__snapshots__/CreateTokenForm.test.js.snap b/web/cashtab/src/components/Tokens/__tests__/__snapshots__/CreateTokenForm.test.js.snap
index e23c98557..1bfa85cc4 100644
--- a/web/cashtab/src/components/Tokens/__tests__/__snapshots__/CreateTokenForm.test.js.snap
+++ b/web/cashtab/src/components/Tokens/__tests__/__snapshots__/CreateTokenForm.test.js.snap
@@ -1,375 +1,375 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP @generated
exports[`Wallet with BCH balances and tokens and state field 1`] = `
Create a Token
Create eToken
`;
diff --git a/web/cashtab/src/components/Tokens/__tests__/__snapshots__/Tokens.test.js.snap b/web/cashtab/src/components/Tokens/__tests__/__snapshots__/Tokens.test.js.snap
index 452501797..ae66b3a85 100644
--- a/web/cashtab/src/components/Tokens/__tests__/__snapshots__/Tokens.test.js.snap
+++ b/web/cashtab/src/components/Tokens/__tests__/__snapshots__/Tokens.test.js.snap
@@ -1,620 +1,620 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP @generated
exports[`Wallet with BCH balances 1`] = `
Array [
MigrationTestAlpha
0
XEC
$
NaN
USD
,
Create a Token
You need at least
5.5
XEC
(
$
NaN
USD
) to create a token
,
]
`;
exports[`Wallet with BCH balances and tokens 1`] = `
Array [
MigrationTestAlpha
0
XEC
$
NaN
USD
,
Create a Token
You need at least
5.5
XEC
(
$
NaN
USD
) to create a token
,
]
`;
exports[`Wallet with BCH balances and tokens and state field 1`] = `
Array [
MigrationTestAlpha
0.06
XEC
$
NaN
USD
,
Create a Token
Create eToken
,
]
`;
exports[`Wallet without BCH balance 1`] = `
Array [
MigrationTestAlpha
0
XEC
$
NaN
USD
,
Create a Token
You need at least
5.5
XEC
(
$
NaN
USD
) to create a token
,
]
`;
exports[`Without wallet defined 1`] = `
Array [
,
Create a Token
You need at least
5.5
XEC
(
$
NaN
USD
) to create a token
,
]
`;