aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app
diff options
context:
space:
mode:
authorDan J Miller <danjm.com@gmail.com>2019-08-03 04:31:26 +0800
committerGitHub <noreply@github.com>2019-08-03 04:31:26 +0800
commit9d5be5d29fcdab1273e30810f87de4624b8622a1 (patch)
tree60d59d7c4d72c2af25c711c7c805142e94d28989 /ui/app
parentdadda918b4f2b82c6da82c6d0605d9134868202f (diff)
downloadtangerine-wallet-browser-9d5be5d29fcdab1273e30810f87de4624b8622a1.tar.gz
tangerine-wallet-browser-9d5be5d29fcdab1273e30810f87de4624b8622a1.tar.zst
tangerine-wallet-browser-9d5be5d29fcdab1273e30810f87de4624b8622a1.zip
New notification fixes (#6955)
* Replace use of backup-notification with use of home notification * Pin notifications relative to window * Remove unneeded isRequired condition on some home.component properties * Refactor rendering of home notifications * UX for multiple notifications * Adds dismissal to provider request notification. * Fix test failures The e2e tests have been updated to reference `home-notification` classnames instead of the removed `background-notification`. The active tab proptypes and default values were updated as well.
Diffstat (limited to 'ui/app')
-rw-r--r--ui/app/components/app/backup-notification/backup-notification.component.js50
-rw-r--r--ui/app/components/app/backup-notification/backup-notification.container.js16
-rw-r--r--ui/app/components/app/backup-notification/index.js1
-rw-r--r--ui/app/components/app/backup-notification/index.scss75
-rw-r--r--ui/app/components/app/home-notification/home-notification.component.js6
-rw-r--r--ui/app/components/app/home-notification/index.scss16
-rw-r--r--ui/app/components/app/index.scss2
-rw-r--r--ui/app/components/app/multiple-notifications/index.js1
-rw-r--r--ui/app/components/app/multiple-notifications/index.scss80
-rw-r--r--ui/app/components/app/multiple-notifications/multiple-notifications.component.js39
-rw-r--r--ui/app/css/itcss/generic/index.scss11
-rw-r--r--ui/app/pages/home/home.component.js67
-rw-r--r--ui/app/pages/home/home.container.js9
13 files changed, 200 insertions, 173 deletions
diff --git a/ui/app/components/app/backup-notification/backup-notification.component.js b/ui/app/components/app/backup-notification/backup-notification.component.js
deleted file mode 100644
index dba79186c..000000000
--- a/ui/app/components/app/backup-notification/backup-notification.component.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import React, { PureComponent } from 'react'
-import PropTypes from 'prop-types'
-import Button from '../../ui/button'
-import {
- INITIALIZE_SEED_PHRASE_ROUTE,
-} from '../../../helpers/constants/routes'
-
-export default class BackupNotification extends PureComponent {
- static propTypes = {
- history: PropTypes.object,
- showSeedPhraseBackupAfterOnboarding: PropTypes.func,
- }
-
- static contextTypes = {
- t: PropTypes.func,
- metricsEvent: PropTypes.func,
- }
-
- handleSubmit = () => {
- const { history, showSeedPhraseBackupAfterOnboarding } = this.props
- showSeedPhraseBackupAfterOnboarding()
- history.push(INITIALIZE_SEED_PHRASE_ROUTE)
- }
-
- render () {
- const { t } = this.context
-
- return (
- <div className="backup-notification">
- <div className="backup-notification__header">
- <img
- className="backup-notification__icon"
- src="images/meta-shield.svg"
- />
- <div className="backup-notification__text">Backup your Secret Recovery code to keep your wallet and funds secure.</div>
- <i className="fa fa-info-circle"></i>
- </div>
- <div className="backup-notification__buttons">
- <Button
- type="primary"
- className="backup-notification__submit-button"
- onClick={this.handleSubmit}
- >
- { t('backupNow') }
- </Button>
- </div>
- </div>
- )
- }
-}
diff --git a/ui/app/components/app/backup-notification/backup-notification.container.js b/ui/app/components/app/backup-notification/backup-notification.container.js
deleted file mode 100644
index 6996770bc..000000000
--- a/ui/app/components/app/backup-notification/backup-notification.container.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import { connect } from 'react-redux'
-import { withRouter } from 'react-router-dom'
-import { compose } from 'recompose'
-import BackupNotification from './backup-notification.component'
-import { showSeedPhraseBackupAfterOnboarding } from '../../../store/actions'
-
-const mapDispatchToProps = dispatch => {
- return {
- showSeedPhraseBackupAfterOnboarding: () => dispatch(showSeedPhraseBackupAfterOnboarding()),
- }
-}
-
-export default compose(
- withRouter,
- connect(null, mapDispatchToProps)
-)(BackupNotification)
diff --git a/ui/app/components/app/backup-notification/index.js b/ui/app/components/app/backup-notification/index.js
deleted file mode 100644
index a1cbfe75a..000000000
--- a/ui/app/components/app/backup-notification/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './backup-notification.container'
diff --git a/ui/app/components/app/backup-notification/index.scss b/ui/app/components/app/backup-notification/index.scss
deleted file mode 100644
index 2d76c6ce4..000000000
--- a/ui/app/components/app/backup-notification/index.scss
+++ /dev/null
@@ -1,75 +0,0 @@
-.backup-notification {
- background: rgba(36, 41, 46, 0.9);
- box-shadow: 0px 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;
-
- position: absolute;
- right: 0;
- bottom: 0;
-
- &__header {
- display: flex;
- }
-
- &__text {
- font-family: Roboto;
- font-style: normal;
- font-weight: normal;
- font-size: 12px;
- color: #FFFFFF;
- 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: rgba(36, 41, 46, 0.9);
- height: 34px;
- width: 155px;
- padding: 0;
-
- &:hover {
- border-color: #6A737D;
- background-color: #6A737D;
- }
- }
-
- &__submit-button {
- border: 2px solid #6A737D;
- box-sizing: border-box;
- border-radius: 6px;
- color: $white;
- background-color: rgba(36, 41, 46, 0.9);
- height: 34px;
- width: 155px;
- padding: 0;
-
- &:hover {
- background-color: #3b4046;
- }
-
- &:active {
- background-color:#141618;
- }
- }
-
- &__buttons {
- display: flex;
- width: 130px;
- align-self: flex-end;
- }
-} \ No newline at end of file
diff --git a/ui/app/components/app/home-notification/home-notification.component.js b/ui/app/components/app/home-notification/home-notification.component.js
index cc46eb53a..cc86ef6d8 100644
--- a/ui/app/components/app/home-notification/home-notification.component.js
+++ b/ui/app/components/app/home-notification/home-notification.component.js
@@ -1,4 +1,5 @@
import React, { PureComponent } from 'react'
+import classnames from 'classnames'
import {Tooltip as ReactTippy} from 'react-tippy'
import PropTypes from 'prop-types'
import Button from '../../ui/button'
@@ -22,6 +23,7 @@ export default class HomeNotification extends PureComponent {
onIgnore: PropTypes.func,
descriptionText: PropTypes.string.isRequired,
infoText: PropTypes.string,
+ classNames: PropTypes.array,
}
handleAccept = () => {
@@ -33,10 +35,10 @@ export default class HomeNotification extends PureComponent {
}
render () {
- const { descriptionText, acceptText, onAccept, ignoreText, onIgnore, infoText } = this.props
+ const { descriptionText, acceptText, onAccept, ignoreText, onIgnore, infoText, classNames = [] } = this.props
return (
- <div className="home-notification">
+ <div className={classnames('home-notification', ...classNames)}>
<div className="home-notification__header">
<div className="home-notification__header-container">
<img
diff --git a/ui/app/components/app/home-notification/index.scss b/ui/app/components/app/home-notification/index.scss
index 9cc868d46..c855a0814 100644
--- a/ui/app/components/app/home-notification/index.scss
+++ b/ui/app/components/app/home-notification/index.scss
@@ -10,7 +10,10 @@
border-radius: 8px;
height: 116px;
padding: 16px;
- margin: 8px;
+
+ @media screen and (min-width: 576px) {
+ min-width: 472px;
+ }
display: flex;
flex-flow: column;
@@ -50,6 +53,10 @@
width: 155px;
padding: 0;
+ @media screen and (max-width: 575px) {
+ width: 135px;
+ }
+
&:hover {
border-color: #6A737D;
background-color: #6A737D;
@@ -69,6 +76,11 @@
height: 34px;
width: 155px;
padding: 0;
+ margin-left: 4px;
+
+ @media screen and (max-width: 575px) {
+ width: 135px;
+ }
&:hover {
border-color: #6A737D;
@@ -83,7 +95,7 @@
&__buttons {
display: flex;
width: 100%;
- justify-content: space-between;
+ justify-content: flex-start;
flex-direction: row-reverse;
}
}
diff --git a/ui/app/components/app/index.scss b/ui/app/components/app/index.scss
index 09a97ac28..1ccb6a94a 100644
--- a/ui/app/components/app/index.scss
+++ b/ui/app/components/app/index.scss
@@ -84,4 +84,4 @@
@import 'home-notification/index';
-@import 'backup-notification/index';
+@import 'multiple-notifications/index';
diff --git a/ui/app/components/app/multiple-notifications/index.js b/ui/app/components/app/multiple-notifications/index.js
new file mode 100644
index 000000000..a27a65187
--- /dev/null
+++ b/ui/app/components/app/multiple-notifications/index.js
@@ -0,0 +1 @@
+export { default } from './multiple-notifications.component'
diff --git a/ui/app/components/app/multiple-notifications/index.scss b/ui/app/components/app/multiple-notifications/index.scss
new file mode 100644
index 000000000..e3ee39a74
--- /dev/null
+++ b/ui/app/components/app/multiple-notifications/index.scss
@@ -0,0 +1,80 @@
+.home-notification-wrapper--show-all,
+.home-notification-wrapper--show-first {
+ display: flex;
+ flex-direction: column;
+ width: 472px;
+ height: 116px;
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ margin: 8px;
+
+ @media screen and (max-width: 576px) {
+ width: 340px;
+ }
+
+ .home-notification-wrapper__i-container {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ visibility: none;
+
+ .fa-sm {
+ display: initial;
+ position: absolute;
+ bottom: 14px;
+ left: 16px;
+ color: white;
+ cursor: pointer;
+ visibility: visible;
+
+ &:hover {
+ color: #b0d7f2;
+ font-size: 1.1rem;
+ }
+ }
+ }
+}
+
+.home-notification-wrapper--show-all {
+ height: 356px;;
+ justify-content: flex-end;
+ margin-bottom: 0;
+
+ .home-notification-wrapper__i-container {
+ height: 0;
+ }
+
+ > div {
+ position: relative;
+ margin-top: 8px;
+ }
+
+ .fa-sm {
+ margin-bottom: 8px;
+ }
+
+}
+
+.home-notification-wrapper--show-first {
+ > div {
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ visibility: hidden;
+ }
+
+ > div:first-of-type {
+ visibility: visible;
+
+ }
+
+ .fa-sm {
+ position: relative;
+ display: initial;
+ }
+}
+
+.flipped {
+ transform: rotate(180deg);
+}
diff --git a/ui/app/components/app/multiple-notifications/multiple-notifications.component.js b/ui/app/components/app/multiple-notifications/multiple-notifications.component.js
new file mode 100644
index 000000000..95dbb5c9a
--- /dev/null
+++ b/ui/app/components/app/multiple-notifications/multiple-notifications.component.js
@@ -0,0 +1,39 @@
+import React, { PureComponent } from 'react'
+import classnames from 'classnames'
+import PropTypes from 'prop-types'
+
+export default class MultipleNotifications extends PureComponent {
+ static propTypes = {
+ notifications: PropTypes.array,
+ classNames: PropTypes.array,
+ }
+
+ state = {
+ showAll: false,
+ }
+
+ render () {
+ const { showAll } = this.state
+ const { notifications, classNames = [] } = this.props
+
+ return (<div
+ className={classnames(...classNames, {
+ 'home-notification-wrapper--show-all': showAll,
+ 'home-notification-wrapper--show-first': !showAll,
+ })}
+ >
+ {notifications
+ .filter(notificationConfig => notificationConfig.shouldBeRendered)
+ .map(notificationConfig => notificationConfig.component)
+ }
+ <div
+ className="home-notification-wrapper__i-container"
+ onClick={() => this.setState({ showAll: !showAll })}
+ >
+ {notifications.length > 1 ? <i className={classnames('fa fa-sm fa-sort-amount-asc', {
+ 'flipped': !showAll,
+ })} /> : null}
+ </div>
+ </div>)
+ }
+}
diff --git a/ui/app/css/itcss/generic/index.scss b/ui/app/css/itcss/generic/index.scss
index 771008205..aaf6c7c0e 100644
--- a/ui/app/css/itcss/generic/index.scss
+++ b/ui/app/css/itcss/generic/index.scss
@@ -130,3 +130,14 @@ input.form-control {
overflow: hidden;
text-overflow: ellipsis;
}
+
+.pinned-to-bottom {
+ position: absolute;
+ bottom: 0px;
+}
+
+.pinned-to-bottom-right {
+ position: absolute;
+ bottom: 0px;
+ right: 0;
+}
diff --git a/ui/app/pages/home/home.component.js b/ui/app/pages/home/home.component.js
index e59106537..dca4c8540 100644
--- a/ui/app/pages/home/home.component.js
+++ b/ui/app/pages/home/home.component.js
@@ -3,15 +3,16 @@ import PropTypes from 'prop-types'
import Media from 'react-media'
import { Redirect } from 'react-router-dom'
import HomeNotification from '../../components/app/home-notification'
+import MultipleNotifications from '../../components/app/multiple-notifications'
import WalletView from '../../components/app/wallet-view'
import TransactionView from '../../components/app/transaction-view'
import ProviderApproval from '../provider-approval'
-import BackupNotification from '../../components/app/backup-notification'
import {
RESTORE_VAULT_ROUTE,
CONFIRM_TRANSACTION_ROUTE,
CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE,
+ INITIALIZE_SEED_PHRASE_ROUTE,
} from '../../helpers/constants/routes'
export default class Home extends PureComponent {
@@ -20,15 +21,17 @@ export default class Home extends PureComponent {
}
static defaultProps = {
- activeTab: null,
+ activeTab: {},
unsetMigratedPrivacyMode: null,
forceApproveProviderRequestByOrigin: null,
}
static propTypes = {
activeTab: PropTypes.shape({
- title: PropTypes.string.isRequired,
- url: PropTypes.string.isRequired,
+ origin: PropTypes.string,
+ protocol: PropTypes.string,
+ title: PropTypes.string,
+ url: PropTypes.string,
}),
history: PropTypes.object,
forgottenPassword: PropTypes.bool,
@@ -40,6 +43,8 @@ export default class Home extends PureComponent {
viewingUnconnectedDapp: PropTypes.bool.isRequired,
forceApproveProviderRequestByOrigin: PropTypes.func,
shouldShowSeedPhraseReminder: PropTypes.bool,
+ showSeedPhraseBackupAfterOnboarding: PropTypes.bool,
+ rejectProviderRequestByOrigin: PropTypes.func,
}
componentWillMount () {
@@ -77,6 +82,8 @@ export default class Home extends PureComponent {
viewingUnconnectedDapp,
forceApproveProviderRequestByOrigin,
shouldShowSeedPhraseReminder,
+ showSeedPhraseBackupAfterOnboarding,
+ rejectProviderRequestByOrigin,
} = this.props
if (forgottenPassword) {
@@ -98,39 +105,49 @@ export default class Home extends PureComponent {
{ !history.location.pathname.match(/^\/confirm-transaction/)
? (
<TransactionView>
- {
- showPrivacyModeNotification
- ? (
- <HomeNotification
+ <MultipleNotifications
+ className
+ notifications={[
+ {
+ shouldBeRendered: showPrivacyModeNotification,
+ component: <HomeNotification
descriptionText={t('privacyModeDefault')}
acceptText={t('learnMore')}
onAccept={() => {
window.open('https://medium.com/metamask/42549d4870fa', '_blank', 'noopener')
unsetMigratedPrivacyMode()
}}
- />
- )
- : null
- }
- {
- viewingUnconnectedDapp
- ? (
- <HomeNotification
+ key="home-privacyModeDefault"
+ />,
+ },
+ {
+ shouldBeRendered: viewingUnconnectedDapp,
+ component: <HomeNotification
descriptionText={t('shareAddressToConnect', [activeTab.origin])}
acceptText={t('shareAddress')}
onAccept={() => {
forceApproveProviderRequestByOrigin(activeTab.origin)
}}
+ ignoreText={t('dismiss')}
+ onIgnore={() => rejectProviderRequestByOrigin(activeTab.origin)}
infoText={t('shareAddressInfo', [activeTab.origin])}
- />
- )
- : null
- }
- {
- shouldShowSeedPhraseReminder
- ? (<BackupNotification />)
- : null
- }
+ key="home-shareAddressToConnect"
+ />,
+ },
+ {
+ shouldBeRendered: shouldShowSeedPhraseReminder,
+ component: <HomeNotification
+ descriptionText={t('backupApprovalNotice')}
+ acceptText={t('backupNow')}
+ onAccept={() => {
+ showSeedPhraseBackupAfterOnboarding()
+ history.push(INITIALIZE_SEED_PHRASE_ROUTE)
+ }}
+ infoText={t('backupApprovalInfo')}
+ key="home-backupApprovalNotice"
+ />,
+ },
+ ]}/>
</TransactionView>
)
: null }
diff --git a/ui/app/pages/home/home.container.js b/ui/app/pages/home/home.container.js
index 064c914cd..434d4b7e3 100644
--- a/ui/app/pages/home/home.container.js
+++ b/ui/app/pages/home/home.container.js
@@ -7,6 +7,8 @@ import { getCurrentEthBalance } from '../../selectors/selectors'
import {
forceApproveProviderRequestByOrigin,
unsetMigratedPrivacyMode,
+ showSeedPhraseBackupAfterOnboarding,
+ rejectProviderRequestByOrigin,
} from '../../store/actions'
import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import { ENVIRONMENT_TYPE_POPUP } from '../../../../app/scripts/lib/enums'
@@ -17,6 +19,7 @@ const mapStateToProps = state => {
const { activeTab, metamask, appState } = state
const {
approvedOrigins,
+ dismissedOrigins,
lostAccounts,
suggestedTokens,
providerRequests,
@@ -34,7 +37,8 @@ const mapStateToProps = state => {
activeTab &&
activeTabDappProtocols.includes(activeTab.protocol) &&
privacyMode &&
- !approvedOrigins[activeTab.origin]
+ !approvedOrigins[activeTab.origin] &&
+ !dismissedOrigins[activeTab.origin]
)
const isPopup = getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP
@@ -48,12 +52,15 @@ const mapStateToProps = state => {
activeTab,
viewingUnconnectedDapp: isUnconnected && isPopup,
shouldShowSeedPhraseReminder: !seedPhraseBackedUp && (parseInt(accountBalance, 16) > 0 || tokens.length > 0),
+ isPopup,
}
}
const mapDispatchToProps = (dispatch) => ({
unsetMigratedPrivacyMode: () => dispatch(unsetMigratedPrivacyMode()),
forceApproveProviderRequestByOrigin: (origin) => dispatch(forceApproveProviderRequestByOrigin(origin)),
+ rejectProviderRequestByOrigin: origin => dispatch(rejectProviderRequestByOrigin(origin)),
+ showSeedPhraseBackupAfterOnboarding: () => dispatch(showSeedPhraseBackupAfterOnboarding()),
})
export default compose(