aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/app/components/app/home-notification/home-notification.component.js110
-rw-r--r--ui/app/components/app/home-notification/index.js1
-rw-r--r--ui/app/components/app/home-notification/index.scss106
-rw-r--r--ui/app/components/app/index.scss2
-rw-r--r--ui/app/components/app/transaction-list/transaction-list.component.js3
-rw-r--r--ui/app/components/app/transaction-view/transaction-view.component.js12
-rw-r--r--ui/app/pages/home/home.component.js60
-rw-r--r--ui/app/pages/home/home.container.js26
-rw-r--r--ui/app/store/actions.js14
-rw-r--r--ui/index.js1
10 files changed, 331 insertions, 4 deletions
diff --git a/ui/app/components/app/home-notification/home-notification.component.js b/ui/app/components/app/home-notification/home-notification.component.js
new file mode 100644
index 000000000..cc46eb53a
--- /dev/null
+++ b/ui/app/components/app/home-notification/home-notification.component.js
@@ -0,0 +1,110 @@
+import React, { PureComponent } from 'react'
+import {Tooltip as ReactTippy} from 'react-tippy'
+import PropTypes from 'prop-types'
+import Button from '../../ui/button'
+
+export default class HomeNotification extends PureComponent {
+ static contextTypes = {
+ metricsEvent: PropTypes.func,
+ }
+
+ static defaultProps = {
+ onAccept: null,
+ ignoreText: null,
+ onIgnore: null,
+ infoText: null,
+ }
+
+ static propTypes = {
+ acceptText: PropTypes.string.isRequired,
+ onAccept: PropTypes.func,
+ ignoreText: PropTypes.string,
+ onIgnore: PropTypes.func,
+ descriptionText: PropTypes.string.isRequired,
+ infoText: PropTypes.string,
+ }
+
+ handleAccept = () => {
+ this.props.onAccept()
+ }
+
+ handleIgnore = () => {
+ this.props.onIgnore()
+ }
+
+ render () {
+ const { descriptionText, acceptText, onAccept, ignoreText, onIgnore, infoText } = this.props
+
+ return (
+ <div className="home-notification">
+ <div className="home-notification__header">
+ <div className="home-notification__header-container">
+ <img
+ className="home-notification__icon"
+ alt=""
+ src="images/icons/connect.svg"
+ />
+ <div className="home-notification__text">
+ { descriptionText }
+ </div>
+ </div>
+ {
+ infoText ? (
+ <ReactTippy
+ style={{
+ display: 'flex',
+ }}
+ html={(
+ <p className="home-notification-tooltip__content">
+ {infoText}
+ </p>
+ )}
+ offset={-36}
+ distance={36}
+ animation="none"
+ position="top"
+ arrow
+ theme="info"
+ >
+ <img
+ alt=""
+ src="images/icons/info.svg"
+ />
+ </ReactTippy>
+ ) : (
+ null
+ )
+ }
+ </div>
+ <div className="home-notification__buttons">
+ {
+ (onAccept && acceptText) ? (
+ <Button
+ type="primary"
+ className="home-notification__accept-button"
+ onClick={this.handleAccept}
+ >
+ { acceptText }
+ </Button>
+ ) : (
+ null
+ )
+ }
+ {
+ (onIgnore && ignoreText) ? (
+ <Button
+ type="secondary"
+ className="home-notification__ignore-button"
+ onClick={this.handleIgnore}
+ >
+ { ignoreText }
+ </Button>
+ ) : (
+ null
+ )
+ }
+ </div>
+ </div>
+ )
+ }
+}
diff --git a/ui/app/components/app/home-notification/index.js b/ui/app/components/app/home-notification/index.js
new file mode 100644
index 000000000..918a35be2
--- /dev/null
+++ b/ui/app/components/app/home-notification/index.js
@@ -0,0 +1 @@
+export { default } from './home-notification.component'
diff --git a/ui/app/components/app/home-notification/index.scss b/ui/app/components/app/home-notification/index.scss
new file mode 100644
index 000000000..9cc868d46
--- /dev/null
+++ b/ui/app/components/app/home-notification/index.scss
@@ -0,0 +1,106 @@
+.tippy-tooltip.info-theme {
+ background: rgba(36, 41, 46, 0.9);
+ color: $white;
+ border-radius: 8px;
+}
+
+.home-notification {
+ background: rgba(36, 41, 46, 0.9);
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12);
+ border-radius: 8px;
+ height: 116px;
+ padding: 16px;
+ margin: 8px;
+
+ display: flex;
+ flex-flow: column;
+ justify-content: space-between;
+
+ &__header-container {
+ display: flex;
+ }
+
+ &__header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ &__text {
+ font-family: Roboto, 'sans-serif';
+ font-style: normal;
+ font-weight: normal;
+ font-size: 12px;
+ color: $white;
+ margin-left: 10px;
+ margin-right: 8px;
+ }
+
+ .fa-info-circle {
+ color: #6A737D;
+ }
+
+ &__ignore-button {
+ border: 2px solid #6A737D;
+ box-sizing: border-box;
+ border-radius: 6px;
+ color: $white;
+ background-color: inherit;
+ height: 34px;
+ width: 155px;
+ padding: 0;
+
+ &:hover {
+ border-color: #6A737D;
+ background-color: #6A737D;
+ }
+
+ &:active {
+ background-color: #141618;
+ }
+ }
+
+ &__accept-button {
+ border: 2px solid #6A737D;
+ box-sizing: border-box;
+ border-radius: 6px;
+ color: $white;
+ background-color: inherit;
+ height: 34px;
+ width: 155px;
+ padding: 0;
+
+ &:hover {
+ border-color: #6A737D;
+ background-color: #6A737D;
+ }
+
+ &:active {
+ background-color: #141618;
+ }
+ }
+
+ &__buttons {
+ display: flex;
+ width: 100%;
+ justify-content: space-between;
+ flex-direction: row-reverse;
+ }
+}
+
+.home-notification-tooltip {
+ &__tooltip-container {
+ display: flex;
+ }
+
+ &__content {
+ font-family: Roboto, 'sans-serif';
+ font-style: normal;
+ font-weight: normal;
+ font-size: 12px;
+ color: $white;
+ text-align: left;
+ display: inline-block;
+ width: 200px;
+ }
+}
diff --git a/ui/app/components/app/index.scss b/ui/app/components/app/index.scss
index 1236f0c38..9b7da8c2e 100644
--- a/ui/app/components/app/index.scss
+++ b/ui/app/components/app/index.scss
@@ -79,3 +79,5 @@
@import 'gas-customization/gas-price-button-group/index';
@import '../ui/toggle-button/index';
+
+@import 'home-notification/index';
diff --git a/ui/app/components/app/transaction-list/transaction-list.component.js b/ui/app/components/app/transaction-list/transaction-list.component.js
index 3c096e3fd..157e7200b 100644
--- a/ui/app/components/app/transaction-list/transaction-list.component.js
+++ b/ui/app/components/app/transaction-list/transaction-list.component.js
@@ -10,11 +10,13 @@ export default class TransactionList extends PureComponent {
}
static defaultProps = {
+ children: null,
pendingTransactions: [],
completedTransactions: [],
}
static propTypes = {
+ children: PropTypes.node,
pendingTransactions: PropTypes.array,
completedTransactions: PropTypes.array,
selectedToken: PropTypes.object,
@@ -120,6 +122,7 @@ export default class TransactionList extends PureComponent {
return (
<div className="transaction-list">
{ this.renderTransactions() }
+ { this.props.children }
</div>
)
}
diff --git a/ui/app/components/app/transaction-view/transaction-view.component.js b/ui/app/components/app/transaction-view/transaction-view.component.js
index 7014ca173..fb2c2145c 100644
--- a/ui/app/components/app/transaction-view/transaction-view.component.js
+++ b/ui/app/components/app/transaction-view/transaction-view.component.js
@@ -10,6 +10,14 @@ export default class TransactionView extends PureComponent {
t: PropTypes.func,
}
+ static propTypes = {
+ children: PropTypes.node,
+ }
+
+ static defaultProps = {
+ children: null,
+ }
+
render () {
return (
<div className="transaction-view">
@@ -20,7 +28,9 @@ export default class TransactionView extends PureComponent {
<div className="transaction-view__balance-wrapper">
<TransactionViewBalance />
</div>
- <TransactionList />
+ <TransactionList>
+ { this.props.children }
+ </TransactionList>
</div>
)
}
diff --git a/ui/app/pages/home/home.component.js b/ui/app/pages/home/home.component.js
index a3b486c57..1fd12a359 100644
--- a/ui/app/pages/home/home.component.js
+++ b/ui/app/pages/home/home.component.js
@@ -2,6 +2,7 @@ import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import Media from 'react-media'
import { Redirect } from 'react-router-dom'
+import HomeNotification from '../../components/app/home-notification'
import WalletView from '../../components/app/wallet-view'
import TransactionView from '../../components/app/transaction-view'
import ProviderApproval from '../provider-approval'
@@ -13,12 +14,30 @@ import {
} from '../../helpers/constants/routes'
export default class Home extends PureComponent {
+ static contextTypes = {
+ t: PropTypes.func,
+ }
+
+ static defaultProps = {
+ activeTab: null,
+ unsetMigratedPrivacyMode: null,
+ forceApproveProviderRequestByOrigin: null,
+ }
+
static propTypes = {
+ activeTab: PropTypes.shape({
+ title: PropTypes.string.isRequired,
+ url: PropTypes.string.isRequired,
+ }),
history: PropTypes.object,
forgottenPassword: PropTypes.bool,
suggestedTokens: PropTypes.object,
unconfirmedTransactionsCount: PropTypes.number,
providerRequests: PropTypes.array,
+ showPrivacyModeNotification: PropTypes.bool.isRequired,
+ unsetMigratedPrivacyMode: PropTypes.func,
+ viewingUnconnectedDapp: PropTypes.bool.isRequired,
+ forceApproveProviderRequestByOrigin: PropTypes.func,
}
componentWillMount () {
@@ -45,10 +64,16 @@ export default class Home extends PureComponent {
}
render () {
+ const { t } = this.context
const {
+ activeTab,
forgottenPassword,
providerRequests,
history,
+ showPrivacyModeNotification,
+ unsetMigratedPrivacyMode,
+ viewingUnconnectedDapp,
+ forceApproveProviderRequestByOrigin,
} = this.props
if (forgottenPassword) {
@@ -68,7 +93,40 @@ export default class Home extends PureComponent {
query="(min-width: 576px)"
render={() => <WalletView />}
/>
- { !history.location.pathname.match(/^\/confirm-transaction/) ? <TransactionView /> : null }
+ { !history.location.pathname.match(/^\/confirm-transaction/)
+ ? (
+ <TransactionView>
+ {
+ showPrivacyModeNotification
+ ? (
+ <HomeNotification
+ descriptionText={t('privacyModeDefault')}
+ acceptText={t('learnMore')}
+ onAccept={() => {
+ window.open('https://medium.com/metamask/42549d4870fa', '_blank', 'noopener')
+ unsetMigratedPrivacyMode()
+ }}
+ />
+ )
+ : null
+ }
+ {
+ viewingUnconnectedDapp
+ ? (
+ <HomeNotification
+ descriptionText={t('shareAddressToConnect', [activeTab.origin])}
+ acceptText={t('shareAddress')}
+ onAccept={() => {
+ forceApproveProviderRequestByOrigin(activeTab.origin)
+ }}
+ infoText={t('shareAddressInfo', [activeTab.origin])}
+ />
+ )
+ : null
+ }
+ </TransactionView>
+ )
+ : null }
</div>
</div>
)
diff --git a/ui/app/pages/home/home.container.js b/ui/app/pages/home/home.container.js
index a4690a17a..81a3946c5 100644
--- a/ui/app/pages/home/home.container.js
+++ b/ui/app/pages/home/home.container.js
@@ -3,26 +3,48 @@ import { compose } from 'recompose'
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import { unconfirmedTransactionsCountSelector } from '../../selectors/confirm-transaction'
+import {
+ forceApproveProviderRequestByOrigin,
+ unsetMigratedPrivacyMode,
+} from '../../store/actions'
+import { getEnvironmentType } from '../../../../app/scripts/lib/util'
+import { ENVIRONMENT_TYPE_POPUP } from '../../../../app/scripts/lib/enums'
const mapStateToProps = state => {
- const { metamask, appState } = state
+ const { activeTab, metamask, appState } = state
const {
+ approvedOrigins,
lostAccounts,
suggestedTokens,
providerRequests,
+ migratedPrivacyMode,
+ featureFlags: {
+ privacyMode,
+ } = {},
} = metamask
const { forgottenPassword } = appState
+ const isUnconnected = Boolean(activeTab && privacyMode && !approvedOrigins[activeTab.origin])
+ const isPopup = getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP
+
return {
lostAccounts,
forgottenPassword,
suggestedTokens,
unconfirmedTransactionsCount: unconfirmedTransactionsCountSelector(state),
providerRequests,
+ showPrivacyModeNotification: migratedPrivacyMode,
+ activeTab,
+ viewingUnconnectedDapp: isUnconnected && isPopup,
}
}
+const mapDispatchToProps = (dispatch) => ({
+ unsetMigratedPrivacyMode: () => dispatch(unsetMigratedPrivacyMode()),
+ forceApproveProviderRequestByOrigin: (origin) => dispatch(forceApproveProviderRequestByOrigin(origin)),
+})
+
export default compose(
withRouter,
- connect(mapStateToProps)
+ connect(mapStateToProps, mapDispatchToProps)
)(Home)
diff --git a/ui/app/store/actions.js b/ui/app/store/actions.js
index 2667dd803..726deb59d 100644
--- a/ui/app/store/actions.js
+++ b/ui/app/store/actions.js
@@ -324,6 +324,7 @@ var actions = {
setUseNativeCurrencyAsPrimaryCurrencyPreference,
setShowFiatConversionOnTestnetsPreference,
setAutoLogoutTimeLimit,
+ unsetMigratedPrivacyMode,
// Onboarding
setCompletedOnboarding,
@@ -348,6 +349,7 @@ var actions = {
approveProviderRequestByOrigin,
rejectProviderRequestByOrigin,
+ forceApproveProviderRequestByOrigin,
clearApprovedOrigins,
setFirstTimeFlowType,
@@ -2637,6 +2639,12 @@ function approveProviderRequestByOrigin (origin) {
}
}
+function forceApproveProviderRequestByOrigin (origin) {
+ return () => {
+ background.forceApproveProviderRequestByOrigin(origin)
+ }
+}
+
function rejectProviderRequestByOrigin (origin) {
return () => {
background.rejectProviderRequestByOrigin(origin)
@@ -2758,3 +2766,9 @@ function getTokenParams (tokenAddress) {
})
}
}
+
+function unsetMigratedPrivacyMode () {
+ return () => {
+ background.unsetMigratedPrivacyMode()
+ }
+}
diff --git a/ui/index.js b/ui/index.js
index 7eb305653..db9292761 100644
--- a/ui/index.js
+++ b/ui/index.js
@@ -34,6 +34,7 @@ async function startApp (metamaskState, backgroundConnection, opts) {
const enLocaleMessages = await fetchLocale('en')
const store = configureStore({
+ activeTab: opts.activeTab,
// metamaskState represents the cross-tab state
metamask: metamaskState,