Fixing address truncation papercuts (#12330)

* fixing address truncation papercuts
feature/default_network_editable
Alex Donesky 3 years ago committed by GitHub
parent 398ea62029
commit aa070edd3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      shared/constants/labels.js
  2. 5
      test/e2e/tests/from-import-ui.spec.js
  3. 4
      test/e2e/tests/incremental-security.spec.js
  4. 2
      ui/components/app/modals/account-modal-container/index.scss
  5. 10
      ui/components/app/permission-page-container/permission-page-container-content/permission-page-container-content.component.js
  6. 2
      ui/components/app/selected-account/selected-account-component.test.js
  7. 7
      ui/components/ui/qr-code/index.scss
  8. 7
      ui/components/ui/qr-code/qr-code.js
  9. 1
      ui/components/ui/sender-to-recipient/index.scss
  10. 14
      ui/components/ui/sender-to-recipient/sender-to-recipient.component.js
  11. 11
      ui/helpers/utils/util.js
  12. 12
      ui/hooks/useTransactionDisplayData.test.js
  13. 7
      ui/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js
  14. 8
      ui/pages/settings/contact-list-tab/index.scss
  15. 8
      ui/selectors/selectors.js

@ -0,0 +1,10 @@
// The character limit on ENS names, nicknames and addresses before we truncate
export const TRUNCATED_NAME_CHAR_LIMIT = 11;
// The number of characters to slice from the beginning of an address for truncated format:
// `${TRUNCATED_ADDRESS_START_CHARS}...${TRUNCATED_ADDRESS_END_CHARS}`
export const TRUNCATED_ADDRESS_START_CHARS = 5;
// The number of characters to slice from the end of an address for truncated format:
// `${TRUNCATED_ADDRESS_START_CHARS}...${TRUNCATED_ADDRESS_END_CHARS}`
export const TRUNCATED_ADDRESS_END_CHARS = 4;

@ -76,8 +76,9 @@ describe('Metamask Import UI', function () {
// shows a QR code for the account
const detailsModal = await driver.findVisibleElement('span .modal');
// shows the correct account address
const [address] = await driver.findElements('.readonly-input__input');
assert.equal(await address.getAttribute('value'), testAddress);
const address = await driver.findElement('.qr-code__address');
assert.equal(await address.getText(), testAddress);
await driver.clickElement('.account-modal__close');
await detailsModal.waitForElementState('hidden');

@ -80,8 +80,8 @@ describe('Incremental Security', function () {
);
// gets the current accounts address
const addressInput = await driver.findElement('.readonly-input__input');
const publicAddress = await addressInput.getAttribute('value');
const address = await driver.findElement('.qr-code__address');
const publicAddress = await address.getText();
// wait for account modal to be visible
const accountModal = await driver.findVisibleElement('span .modal');

@ -31,7 +31,7 @@
@include H1;
background-color: transparent;
color: $dusty-gray;
color: $ui-black;
position: absolute;
cursor: pointer;
top: -10px;

@ -70,12 +70,6 @@ export default class PermissionPageContainerContent extends PureComponent {
);
}
getAccountDescriptor(identity) {
return `${identity.label} (...${identity.address.slice(
identity.address.length - 4,
)})`;
}
renderAccountTooltip(textContent) {
const { selectedIdentities } = this.props;
const { t } = this.context;
@ -90,7 +84,7 @@ export default class PermissionPageContainerContent extends PureComponent {
{selectedIdentities.slice(0, 6).map((identity, index) => {
return (
<div key={`tooltip-identity-${index}`}>
{this.getAccountDescriptor(identity)}
{identity.addressLabel}
</div>
);
})}
@ -126,7 +120,7 @@ export default class PermissionPageContainerContent extends PureComponent {
),
]);
}
return t('connectTo', [this.getAccountDescriptor(selectedIdentities[0])]);
return t('connectTo', [selectedIdentities[0]?.addressLabel]);
}
render() {

@ -15,7 +15,7 @@ describe('SelectedAccount Component', () => {
);
// Checksummed version of address is displayed
expect(wrapper.find('.selected-account__address').text()).toStrictEqual(
'0x1B82...5C9D',
'0x1B8...5C9D',
);
expect(wrapper.find('.selected-account__name').text()).toStrictEqual(
'testName',

@ -24,4 +24,11 @@
color: #f7861c;
margin-bottom: 9px;
}
&__address {
@include H7;
background-color: $ui-1;
padding: 12px;
}
}

@ -3,7 +3,6 @@ import React from 'react';
import qrCode from 'qrcode-generator';
import { connect } from 'react-redux';
import { isHexPrefixed } from 'ethereumjs-util';
import ReadOnlyInput from '../readonly-input/readonly-input';
import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils';
export default connect(mapStateToProps)(QrCodeView);
@ -47,11 +46,7 @@ function QrCodeView(props) {
__html: qrImage.createTableTag(4),
}}
/>
<ReadOnlyInput
wrapperClass="ellip-address-wrapper"
autoFocus
value={toChecksumHexAddress(data)}
/>
<div className="qr-code__address">{toChecksumHexAddress(data)}</div>
</div>
);
}

@ -178,6 +178,7 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-inline-start: 8px;
[dir='rtl'] & {
/*rtl:ignore*/

@ -55,14 +55,12 @@ function SenderAddress({
}
}}
>
{!addressOnly && (
<div className="sender-to-recipient__sender-icon">
<Identicon
address={toChecksumHexAddress(senderAddress)}
diameter={24}
/>
</div>
)}
<Tooltip
position="bottom"
html={tooltipHtml}
@ -73,7 +71,9 @@ function SenderAddress({
<div className="sender-to-recipient__name">
{addressOnly ? (
<span>
{`${t('from')}: ${senderName || checksummedSenderAddress}`}
{`${t('from')}: ${
senderName || shortenAddress(checksummedSenderAddress)
}`}
</span>
) : (
senderName
@ -132,11 +132,9 @@ function RecipientWithAddress({
}
}}
>
{!addressOnly && (
<div className="sender-to-recipient__sender-icon">
<Identicon address={checksummedRecipientAddress} diameter={24} />
</div>
)}
<Tooltip
position="bottom"
html={tooltipHtml}
@ -148,7 +146,9 @@ function RecipientWithAddress({
<div className="sender-to-recipient__name">
<span>{addressOnly ? `${t('to')}: ` : ''}</span>
{addressOnly
? recipientNickname || recipientEns || checksummedRecipientAddress
? recipientNickname ||
recipientEns ||
shortenAddress(checksummedRecipientAddress)
: recipientNickname ||
recipientEns ||
recipientName ||
@ -225,7 +225,7 @@ export default function SenderToRecipient({
/>
) : (
<div className="sender-to-recipient__party sender-to-recipient__party--recipient">
{!addressOnly && <i className="fa fa-file-text-o" />}
<i className="fa fa-file-text-o" />
<div className="sender-to-recipient__name">{t('newContract')}</div>
</div>
)}

@ -13,6 +13,11 @@ import {
ROPSTEN_CHAIN_ID,
} from '../../../shared/constants/network';
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
import {
TRUNCATED_ADDRESS_START_CHARS,
TRUNCATED_NAME_CHAR_LIMIT,
TRUNCATED_ADDRESS_END_CHARS,
} from '../../../shared/constants/labels';
// formatData :: ( date: <Unix Timestamp> ) -> String
export function formatDate(date, format = "M/d/y 'at' T") {
@ -220,11 +225,13 @@ export function exportAsFile(filename, data, type = 'text/csv') {
* than 10 characters.
*/
export function shortenAddress(address = '') {
if (address.length < 11) {
if (address.length < TRUNCATED_NAME_CHAR_LIMIT) {
return address;
}
return `${address.slice(0, 6)}...${address.slice(-4)}`;
return `${address.slice(0, TRUNCATED_ADDRESS_START_CHARS)}...${address.slice(
-TRUNCATED_ADDRESS_END_CHARS,
)}`;
}
export function getAccountByAddress(accounts = [], targetAddress) {

@ -28,7 +28,7 @@ const expectedResults = [
{
title: 'Send',
category: TRANSACTION_GROUP_CATEGORIES.SEND,
subtitle: 'To: 0xffe5...1a97',
subtitle: 'To: 0xffe...1a97',
subtitleContainsOrigin: false,
date: 'May 12, 2020',
primaryCurrency: '-1 ETH',
@ -42,7 +42,7 @@ const expectedResults = [
{
title: 'Send',
category: TRANSACTION_GROUP_CATEGORIES.SEND,
subtitle: 'To: 0x0ccc...8848',
subtitle: 'To: 0x0cc...8848',
subtitleContainsOrigin: false,
date: 'May 12, 2020',
primaryCurrency: '-2 ETH',
@ -55,7 +55,7 @@ const expectedResults = [
{
title: 'Send',
category: TRANSACTION_GROUP_CATEGORIES.SEND,
subtitle: 'To: 0xffe5...1a97',
subtitle: 'To: 0xffe...1a97',
subtitleContainsOrigin: false,
date: 'May 12, 2020',
primaryCurrency: '-2 ETH',
@ -68,7 +68,7 @@ const expectedResults = [
{
title: 'Receive',
category: TRANSACTION_GROUP_CATEGORIES.RECEIVE,
subtitle: 'From: 0x31b9...4523',
subtitle: 'From: 0x31b...4523',
subtitleContainsOrigin: false,
date: 'May 12, 2020',
primaryCurrency: '18.75 ETH',
@ -81,7 +81,7 @@ const expectedResults = [
{
title: 'Receive',
category: TRANSACTION_GROUP_CATEGORIES.RECEIVE,
subtitle: 'From: 0x9eca...a149',
subtitle: 'From: 0x9ec...a149',
subtitleContainsOrigin: false,
date: 'May 8, 2020',
primaryCurrency: '0 ETH',
@ -94,7 +94,7 @@ const expectedResults = [
{
title: 'Receive',
category: TRANSACTION_GROUP_CATEGORIES.RECEIVE,
subtitle: 'From: 0xee01...febb',
subtitle: 'From: 0xee0...febb',
subtitleContainsOrigin: false,
date: 'May 24, 2020',
primaryCurrency: '1 ETH',

@ -105,7 +105,14 @@ export default class EditContact extends PureComponent {
error={this.state.error}
onChange={(e) => this.setState({ newAddress: e.target.value })}
fullWidth
multiline
rows={3}
margin="dense"
classes={{
inputMultiline:
'address-book__view-contact__address__text-area',
inputRoot: 'address-book__view-contact__address',
}}
/>
</div>

@ -112,6 +112,14 @@
line-height: initial !important;
}
&__address {
height: 60px !important;
textarea {
padding-top: 10px !important;
}
}
&__group {
display: flex;
flex-flow: column nowrap;

@ -15,6 +15,8 @@ import {
ALLOWED_SWAPS_CHAIN_IDS,
} from '../../shared/constants/swaps';
import { TRUNCATED_NAME_CHAR_LIMIT } from '../../shared/constants/labels';
import {
shortenAddress,
getAccountByAddress,
@ -321,7 +323,11 @@ export function getAccountsWithLabels(state) {
return getMetaMaskAccountsOrdered(state).map(
({ address, name, balance }) => ({
address,
addressLabel: `${name} (...${address.slice(address.length - 4)})`,
addressLabel: `${
name.length < TRUNCATED_NAME_CHAR_LIMIT
? name
: `${name.slice(0, TRUNCATED_NAME_CHAR_LIMIT - 1)}...`
} (${shortenAddress(address)})`,
label: name,
balance,
}),

Loading…
Cancel
Save