mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 01:47:00 +01:00
Fixing address truncation papercuts (#12330)
* fixing address truncation papercuts
This commit is contained in:
parent
398ea62029
commit
aa070edd3f
10
shared/constants/labels.js
Normal file
10
shared/constants/labels.js
Normal file
@ -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>
|
||||
)}
|
||||
<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>
|
||||
)}
|
||||
<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…
Reference in New Issue
Block a user