1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Connect screen multi accounts tooltip (#8181)

* Implement tooltip and styled sentence parts on header text of second screen of multi-account-select flow

* Clean up code related to the multi-accounts tooltip implementation
This commit is contained in:
Dan J Miller 2020-04-02 12:47:10 -02:30 committed by GitHub
parent 522fb98560
commit af24309dc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 119 additions and 16 deletions

View File

@ -54,9 +54,21 @@
"message": "Connect to $1",
"description": "$1 is the name/origin of a site/dapp that the user can connect to metamask"
},
"connectToAll": {
"message": "Connect to all your $1",
"description": "$1 will be replaced by the translation of connectToAllAccounts"
},
"connectToAllAccounts": {
"message": "accounts",
"description": "will replace $1 in connectToAll, completing the sentence 'connect to all of your accounts', will be text that shows list of accounts on hover"
},
"connectToMultiple": {
"message": "Connect to $1 accounts",
"description": "$1 is the number of accounts to connect to"
"message": "Connect to $1",
"description": "$1 will be replaced by the translation of connectToMultipleNumberOfAccounts"
},
"connectToMultipleNumberOfAccounts": {
"message": "$1 accounts",
"description": "$1 is the number of accounts to which the site/dapp is asking to connect; this will substitute $1 in connectToMultiple"
},
"contractInteraction": {
"message": "Contract Interaction"
@ -1025,6 +1037,10 @@
"personalAddressDetected": {
"message": "Personal address detected. Input the token contract address."
},
"plusXMore": {
"message": "+ $1 more",
"description": "$1 is a number of additional but unshown items in a list- this message will be shown in place of those items"
},
"prev": {
"message": "Prev"
},

View File

@ -3,7 +3,7 @@
border: none;
box-shadow: none;
margin-top: 45px;
width: 466px;
width: 488px;
min-height: 468px;
&__header {
@ -106,6 +106,15 @@
padding: 0;
}
}
&__tooltip-body {
display: 'flex';
flex-direction: 'column';
}
&__bold-title-elements {
font-weight: bold;
}
}
.permission-result {

View File

@ -3,6 +3,7 @@ import React, { PureComponent } from 'react'
import Identicon from '../../../ui/identicon'
import IconWithFallBack from '../../../ui/icon-with-fallback'
import PermissionsConnectHeader from '../../permissions-connect-header'
import Tooltip from '../../../ui/tooltip-v2'
import classnames from 'classnames'
export default class PermissionPageContainerContent extends PureComponent {
@ -13,6 +14,7 @@ export default class PermissionPageContainerContent extends PureComponent {
permissionsDescriptions: PropTypes.object.isRequired,
onPermissionToggle: PropTypes.func.isRequired,
selectedIdentities: PropTypes.array,
allIdentitiesSelected: PropTypes.bool,
redirect: PropTypes.bool,
permissionRejected: PropTypes.bool,
}
@ -21,6 +23,7 @@ export default class PermissionPageContainerContent extends PureComponent {
redirect: null,
permissionRejected: null,
selectedIdentities: [],
allIdentitiesSelected: false,
}
static contextTypes = {
@ -99,26 +102,92 @@ export default class PermissionPageContainerContent extends PureComponent {
)
}
render () {
const { domainMetadata, redirect, permissionRejected, selectedIdentities } = this.props
getAccountDescriptor (identity) {
return `${identity.label} (...${identity.address.slice(identity.address.length - 4)})`
}
renderAccountTooltip (textContent) {
const { selectedIdentities } = this.props
const { t } = this.context
return (
<Tooltip
key="all-account-connect-tooltip"
position="bottom"
wrapperClassName="permission-approval-container__bold-title-elements"
html={(
<div style={{ display: 'flex', flexDirection: 'column' }}>
{ selectedIdentities.slice(0, 6).map((identity, index) => {
return (
<div key={ `tooltip-identity-${index}` }>
{ this.getAccountDescriptor(identity) }
</div>
)
}) }
{ selectedIdentities.length > 6
? t('plusXMore', [ selectedIdentities.length - 6 ])
: null
}
</div>
)}
>
{ textContent }
</Tooltip>
)
}
getTitle () {
const { domainMetadata, redirect, permissionRejected, selectedIdentities, allIdentitiesSelected } = this.props
const { t } = this.context
let titleArgs
if (redirect && permissionRejected) {
titleArgs = [ 'cancelledConnectionWithMetaMask' ]
return t('cancelledConnectionWithMetaMask')
} else if (redirect) {
titleArgs = [ 'connectingWithMetaMask' ]
return t('connectingWithMetaMask')
} else if (domainMetadata.extensionId) {
titleArgs = [ 'externalExtension', [domainMetadata.extensionId] ]
return t('externalExtension', [domainMetadata.extensionId])
} else if (allIdentitiesSelected) {
return t(
'connectToAll',
[
(
<span
key="multi-account-connect-all-accounts"
className="permission-approval-container__bold-title-elements"
>
{ this.renderAccountTooltip(t('connectToAllAccounts')) }
</span>
),
]
)
} else if (selectedIdentities.length > 1) {
titleArgs = ['connectToMultiple', [ selectedIdentities.length ] ]
return t(
'connectToMultiple',
[
this.renderAccountTooltip(t('connectToMultipleNumberOfAccounts', [ selectedIdentities.length ])),
]
)
} else {
titleArgs = [
return t(
'connectTo', [
`${selectedIdentities[0].label} (...${selectedIdentities[0].address.slice(selectedIdentities[0].address.length - 4)})`,
],
]
(
<span
key="connect-to-one-account"
className="permission-approval-container__bold-title-elements"
>
{ this.getAccountDescriptor(selectedIdentities[0]) }
</span>
),
]
)
}
}
render () {
const { domainMetadata, redirect } = this.props
const { t } = this.context
const title = this.getTitle()
return (
<div
@ -132,7 +201,7 @@ export default class PermissionPageContainerContent extends PureComponent {
<PermissionsConnectHeader
icon={domainMetadata.icon}
iconName={domainMetadata.origin}
headerTitle={t(...titleArgs)}
headerTitle={title}
headerText={ domainMetadata.extensionId
? t('thisWillAllowExternalExtension', [domainMetadata.extensionId])
: t('thisWillAllow', [domainMetadata.origin])

View File

@ -10,6 +10,7 @@ export default class PermissionPageContainer extends Component {
approvePermissionsRequest: PropTypes.func.isRequired,
rejectPermissionsRequest: PropTypes.func.isRequired,
selectedIdentities: PropTypes.array,
allIdentitiesSelected: PropTypes.bool,
permissionsDescriptions: PropTypes.object.isRequired,
request: PropTypes.object,
redirect: PropTypes.bool,
@ -24,6 +25,7 @@ export default class PermissionPageContainer extends Component {
request: {},
requestMetadata: {},
selectedIdentities: [],
allIdentitiesSelected: false,
}
static contextTypes = {
@ -117,6 +119,7 @@ export default class PermissionPageContainer extends Component {
selectedIdentities,
redirect,
permissionRejected,
allIdentitiesSelected,
} = this.props
return (
@ -130,6 +133,7 @@ export default class PermissionPageContainer extends Component {
selectedIdentities={selectedIdentities}
redirect={redirect}
permissionRejected={permissionRejected}
allIdentitiesSelected={allIdentitiesSelected}
/>
{ !redirect
? (

View File

@ -3,15 +3,20 @@ import PermissionPageContainer from './permission-page-container.component'
import {
getPermissionsDescriptions,
getTargetDomainMetadata,
getMetaMaskIdentities,
} from '../../../selectors/selectors'
const mapStateToProps = (state, ownProps) => {
const { request, cachedOrigin } = ownProps
const { request, cachedOrigin, selectedIdentities } = ownProps
const targetDomainMetadata = getTargetDomainMetadata(state, request, cachedOrigin)
const allIdentities = getMetaMaskIdentities(state)
const allIdentitiesSelected = Object.keys(selectedIdentities).length === Object.keys(allIdentities).length
return {
permissionsDescriptions: getPermissionsDescriptions(state),
targetDomainMetadata,
allIdentitiesSelected,
}
}