diff options
author | Dan J Miller <danjm.com@gmail.com> | 2019-03-05 23:45:01 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-05 23:45:01 +0800 |
commit | c7573663557b0db778a2907eaf2fd1918ced4914 (patch) | |
tree | 3fed2dbe12a845704bff3268e9ee610d55bcc8c2 /ui/app/components/pages/first-time-flow/metametrics-opt-in | |
parent | 1765864e40f548b805cdbdbe59ada3e0c445a52d (diff) | |
download | tangerine-wallet-browser-c7573663557b0db778a2907eaf2fd1918ced4914.tar.gz tangerine-wallet-browser-c7573663557b0db778a2907eaf2fd1918ced4914.tar.zst tangerine-wallet-browser-c7573663557b0db778a2907eaf2fd1918ced4914.zip |
Metametrics (#6171)
* Add metametrics provider and util.
* Add backend api and state for participating in metametrics.
* Add frontend action for participating in metametrics.
* Add metametrics opt-in screen.
* Add metametrics events to first time flow.
* Add metametrics events for route changes
* Add metametrics events for send and confirm screens
* Add metametrics events to dropdowns, transactions, log in and out, settings, sig requests and main screen
* Ensures each log in is measured as a new visit by metametrics.
* Ensure metametrics is called with an empty string for dimensions params if specified
* Adds opt in metametrics modal after unlock for existing users
* Adds settings page toggle for opting in and out of MetaMetrics
* Switch metametrics dimensions to page level scope
* Lint, test and translation fixes for metametrics.
* Update design for metametrics opt-in screen
* Complete responsive styling of metametrics-opt-in modal
* Use new chart image on metrics opt in screens
* Incorporate the metametrics opt-in screen into the new onboarding flow
* Update e2e tests to accomodate metametrics changes
* Mock out metametrics network requests in integration tests
* Fix tx-list integration test to support metametrics provider.
* Send number of tokens and accounts data with every metametrics event.
* Update metametrics event descriptor schema and add new events.
* Fix import tos bug and send gas button bug due to metametrics changes.
* Various small fixes on the metametrics branch.
* Add origin custom variable type to metametrics.util
* Fix names of onboarding complete actions (metametrics).
* Fix names of Metrics Options actions (metametrics).
* Clean up code related to metametrics.
* Fix bad merge conflict resolution and improve promise handling in sendMetaMetrics event and confrim tx base
* Don't send a second metrics event if user has gone back during first time flow.
* Collect metametrics on going back from onboarding create/import.
* Add missing custom variable constants for metametrics
* Fix metametrics provider
* Make height of opt-in modal responsive.
* Adjust text content for opt-in modal.
* Update metametrics event names and clean up code in opt-in-modal
* Put phishing warning step next to last in onboarding flow
* Link terms of service on create and import screens of first time flow
* Add subtext to options on the onboarding select action screen.
* Fix styling of bullet points on end of onboarding screen.
* Combine phishing warning and congratulations screens.
* Fix placement of users if unlocking after an incomplete onboarding import flow.
* Fix capitalization in opt-in screen
* Fix last onboarding screen translations
* Add link to 'Learn More' on the last screen of onboarding
* Code clean up: metametrics branch
* Update e2e tests for phishing warning step removal
* e2e tests passing on metametrics branch
* Different tracking urls for metametrics on development and prod
Diffstat (limited to 'ui/app/components/pages/first-time-flow/metametrics-opt-in')
4 files changed, 333 insertions, 0 deletions
diff --git a/ui/app/components/pages/first-time-flow/metametrics-opt-in/index.js b/ui/app/components/pages/first-time-flow/metametrics-opt-in/index.js new file mode 100644 index 000000000..4bc2fc3a7 --- /dev/null +++ b/ui/app/components/pages/first-time-flow/metametrics-opt-in/index.js @@ -0,0 +1 @@ +export { default } from './metametrics-opt-in.container' diff --git a/ui/app/components/pages/first-time-flow/metametrics-opt-in/index.scss b/ui/app/components/pages/first-time-flow/metametrics-opt-in/index.scss new file mode 100644 index 000000000..6c2e37785 --- /dev/null +++ b/ui/app/components/pages/first-time-flow/metametrics-opt-in/index.scss @@ -0,0 +1,136 @@ +.metametrics-opt-in { + position: relative; + width: 100%; + + a { + color: #2f9ae0bf; + } + + &__main { + display: flex; + flex-direction: column; + margin-left: 26.26%; + margin-right: 28%; + color: black; + + @media screen and (max-width: 575px) { + justify-content: center; + margin-left: 2%; + margin-right: 0%; + } + + .app-header__logo-container { + margin-top: 3%; + } + } + + &__title { + position: relative; + margin-top: 20px; + + font-family: Roboto; + font-style: normal; + font-weight: normal; + line-height: normal; + font-size: 42px; + } + + &__body-graphic { + margin-top: 25px; + + .fa-bar-chart { + color: #C4C4C4; + } + } + + &__description { + font-family: Roboto; + font-style: normal; + font-weight: normal; + line-height: 21px; + font-size: 16px; + margin-top: 12px; + } + + &__committments { + display: flex; + flex-direction: column; + } + + &__content { + overflow-y: scroll; + flex: 1; + } + + &__row { + display: flex; + margin-top: 8px; + + .fa-check { + margin-right: 12px; + color: #1ACC56; + } + + .fa-times { + margin-right: 12px; + color: #D0021B; + } + } + + &__bold { + font-weight: bold; + } + + &__break-row { + margin-top: 30px; + } + + &__body { + position: relative; + display: flex; + max-width: 730px; + flex-direction: column; + } + + &__body-text { + max-width: 548px; + margin-left: 16px; + margin-right: 16px; + } + + &__bottom-text { + margin-top: 10px; + color: #9a9a9a; + } + + &__content { + overflow-y: auto; + } + + &__footer { + margin-top: 26px; + + @media screen and (max-width: 575px) { + margin-top: 10px; + justify-content: center; + margin-left: 2%; + max-height: 520px; + } + + .page-container__footer { + border-top: none; + max-width: 535px; + margin-bottom: 15px; + + button { + height: 44px; + min-height: 44px; + margin-right: 16px; + } + + header { + padding: 0px; + } + } + } +}
\ No newline at end of file diff --git a/ui/app/components/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js b/ui/app/components/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js new file mode 100644 index 000000000..834516f5f --- /dev/null +++ b/ui/app/components/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js @@ -0,0 +1,169 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import PageContainerFooter from '../../../page-container/page-container-footer' + +export default class MetaMetricsOptIn extends Component { + static propTypes = { + history: PropTypes.object, + setParticipateInMetaMetrics: PropTypes.func, + nextRoute: PropTypes.string, + firstTimeSelectionMetaMetricsName: PropTypes.string, + participateInMetaMetrics: PropTypes.bool, + } + + static contextTypes = { + metricsEvent: PropTypes.func, + } + + render () { + const { metricsEvent } = this.context + const { + nextRoute, + history, + setParticipateInMetaMetrics, + firstTimeSelectionMetaMetricsName, + participateInMetaMetrics, + } = this.props + + return ( + <div className="metametrics-opt-in"> + <div className="metametrics-opt-in__main"> + <div className="app-header__logo-container"> + <img + className="app-header__metafox-logo app-header__metafox-logo--horizontal" + src="/images/logo/metamask-logo-horizontal.svg" + height={30} + /> + <img + className="app-header__metafox-logo app-header__metafox-logo--icon" + src="/images/logo/metamask-fox.svg" + height={42} + width={42} + /> + </div> + <div className="metametrics-opt-in__body-graphic"> + <img src="images/metrics-chart.svg" /> + </div> + <div className="metametrics-opt-in__title">Help Us Improve MetaMask</div> + <div className="metametrics-opt-in__body"> + <div className="metametrics-opt-in__description"> + MetaMask would like to gather usage data to better understand how our users interact with the extension. This data + will be used to continually improve the usability and user experience of our product and the Etheruem ecosystem. + </div> + <div className="metametrics-opt-in__description"> + MetaMask will.. + </div> + + <div className="metametrics-opt-in__committments"> + <div className="metametrics-opt-in__row"> + <i className="fa fa-check" /> + <div className="metametrics-opt-in__row-description"> + Always allow you to opt-out via Settings + </div> + </div> + <div className="metametrics-opt-in__row"> + <i className="fa fa-check" /> + <div className="metametrics-opt-in__row-description"> + Send anonymized click & pageview events + </div> + </div> + <div className="metametrics-opt-in__row"> + <i className="fa fa-check" /> + <div className="metametrics-opt-in__row-description"> + Maintain a public aggregate dashboard to educate the community + </div> + </div> + <div className="metametrics-opt-in__row metametrics-opt-in__break-row"> + <i className="fa fa-times" /> + <div className="metametrics-opt-in__row-description"> + <span className="metametrics-opt-in__bold">Never</span> collect keys, addresses, transactions, balances, hashes, or any personal information + </div> + </div> + <div className="metametrics-opt-in__row"> + <i className="fa fa-times" /> + <div className="metametrics-opt-in__row-description"> + <span className="metametrics-opt-in__bold">Never</span> collect your full IP address + </div> + </div> + <div className="metametrics-opt-in__row"> + <i className="fa fa-times" /> + <div className="metametrics-opt-in__row-description"> + <span className="metametrics-opt-in__bold">Never</span> sell data for profit. Ever! + </div> + </div> + </div> + </div> + <div className="metametrics-opt-in__footer"> + <PageContainerFooter + onCancel={() => { + setParticipateInMetaMetrics(false) + .then(() => { + if (participateInMetaMetrics === null) { + return metricsEvent({ + eventOpts: { + category: 'Onboarding', + action: 'Metrics Option', + name: 'Metrics Opt Out', + }, + isOptIn: true, + }, { + excludeMetaMetricsId: true, + }) + .then(() => { + history.push(nextRoute) + }) + } + }) + }} + cancelText={'No Thanks'} + hideCancel={false} + onSubmit={() => { + setParticipateInMetaMetrics(true) + .then(([participateStatus, metaMetricsId]) => { + const promise = participateInMetaMetrics === null + ? metricsEvent({ + eventOpts: { + category: 'Onboarding', + action: 'Metrics Option', + name: 'Metrics Opt In', + }, + isOptIn: true, + }) + : Promise.resolve() + + promise + .then(() => { + return metricsEvent({ + eventOpts: { + category: 'Onboarding', + action: 'Import or Create', + name: firstTimeSelectionMetaMetricsName, + }, + isOptIn: true, + metaMetricsId, + }) + }) + .then(() => { + history.push(nextRoute) + }) + }) + }} + submitText={'I agree'} + submitButtonType={'confirm'} + disabled={false} + /> + <div className="metametrics-opt-in__bottom-text"> + This data is aggregated and is therefore anonymous for the purposes of General Data Protection Regulation (EU) 2016/679. For more information in relation to our privacy practices, please see our <a + href="https://metamask.io/privacy.html" + target="_blank" + rel="noopener noreferrer" + > + Privacy Policy here + </a>. + </div> + </div> + </div> + </div> + ) + } +} diff --git a/ui/app/components/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.container.js b/ui/app/components/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.container.js new file mode 100644 index 000000000..b13af8bf6 --- /dev/null +++ b/ui/app/components/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.container.js @@ -0,0 +1,27 @@ +import { connect } from 'react-redux' +import MetaMetricsOptIn from './metametrics-opt-in.component' +import { setParticipateInMetaMetrics } from '../../../../actions' +import { getFirstTimeFlowTypeRoute } from '../first-time-flow.selectors' + +const firstTimeFlowTypeNameMap = { + create: 'Selected Create New Wallet', + 'import': 'Selected Import Wallet', +} + +const mapStateToProps = (state) => { + const { firstTimeFlowType, participateInMetaMetrics } = state.metamask + + return { + nextRoute: getFirstTimeFlowTypeRoute(state), + firstTimeSelectionMetaMetricsName: firstTimeFlowTypeNameMap[firstTimeFlowType], + participateInMetaMetrics, + } +} + +const mapDispatchToProps = dispatch => { + return { + setParticipateInMetaMetrics: (val) => dispatch(setParticipateInMetaMetrics(val)), + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(MetaMetricsOptIn) |