From ae2ac4f2c6d7a0e18cad9c12d5768e81ed48ed32 Mon Sep 17 00:00:00 2001 From: William O'Beirne Date: Fri, 11 May 2018 11:15:32 -0400 Subject: [PATCH] Production Release Changes (#1673) * Remove beta agreement, move modals to Root, and initial work on welcome modal. * Local storage detection for welcome modal * Remove announcement from header. Allow tooltips to point in non-top directions. * Show modal fade at bottom on non-footer modals * Update README * Update all links back to old mycrypto to classic.mycrypto, add footer link too. * Localize welcome modal * Remove release candidate version text, change to legacy.mycrypto instead of classic.mycrypto. * update banner; add hackerone link --- README.md | 6 +- common/Root.tsx | 10 ++- common/components/BetaAgreement/index.scss | 66 ----------------- common/components/BetaAgreement/index.tsx | 73 ------------------- common/components/Footer/index.tsx | 3 - .../Header/components/OnlineStatus.scss | 1 - .../Header/components/OnlineStatus.tsx | 4 +- common/components/WelcomeModal.scss | 26 +++++++ common/components/WelcomeModal.tsx | 62 ++++++++++++++++ common/components/index.ts | 1 - common/components/ui/Modal/ModalBody.tsx | 6 +- common/components/ui/Modal/index.scss | 4 + common/components/ui/Modal/index.tsx | 4 +- common/components/ui/TitleBar.scss | 27 ------- common/components/ui/TitleBar.tsx | 11 --- common/components/ui/Tooltip.scss | 59 +++++++++++++-- common/components/ui/Tooltip.tsx | 6 +- common/components/ui/index.ts | 1 - common/config/data.tsx | 11 +-- common/config/links.ts | 4 + common/containers/OnboardModal/index.tsx | 17 ++--- common/containers/TabSection/WebTemplate.tsx | 3 +- common/sass/mixins.scss | 14 +++- common/sass/variables.scss | 1 + common/sass/variables/tooltips.scss | 4 + common/translations/lang/en.json | 13 +++- common/utils/formatters.ts | 2 +- common/utils/localStorage.ts | 17 +++++ 28 files changed, 233 insertions(+), 223 deletions(-) delete mode 100644 common/components/BetaAgreement/index.scss delete mode 100644 common/components/BetaAgreement/index.tsx create mode 100644 common/components/WelcomeModal.scss create mode 100644 common/components/WelcomeModal.tsx delete mode 100644 common/components/ui/TitleBar.scss delete mode 100644 common/components/ui/TitleBar.tsx create mode 100644 common/sass/variables/tooltips.scss diff --git a/README.md b/README.md index 87d45df8..ae08c10f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ -# MyCrypto Beta RC (VISIT [MyCryptoHQ/mycrypto.com](https://github.com/MyCryptoHQ/mycrypto.com) for the current site)
Just looking to download? Grab our [latest release](https://github.com/MyCryptoHQ/MyCrypto/releases) +# MyCrypto Web & Desktop Apps [![Greenkeeper badge](https://badges.greenkeeper.io/MyCryptoHq/MyCrypto.svg)](https://greenkeeper.io/) [![Coverage Status](https://coveralls.io/repos/github/MyCryptoHQ/MyCrypto/badge.svg?branch=develop)](https://coveralls.io/github/MyCryptoHQ/MyCrypto?branch=develop) +* **Just looking to download?** Grab our [latest release](https://github.com/MyCryptoHQ/MyCrypto/releases). +* **Looking for the old site?** Check out [https://legacy.mycrypto.com](https://legacy.mycrypto.com) or the source at [MyCryptoHQ/mycrypto.com](https://github.com/MyCryptoHQ/mycrypto.com) + ## Running the App This codebase targets Node 8.9.4 (LTS). After `npm install`ing all dependencies (You may be required to install additional system dependencies, due to some node modules relying on them) you can run various commands depending on what you want to do: @@ -132,3 +135,4 @@ npm run test:int Cross browser testing and debugging provided by the very lovely team at BrowserStack. + diff --git a/common/Root.tsx b/common/Root.tsx index 0fe992d7..38d166c6 100644 --- a/common/Root.tsx +++ b/common/Root.tsx @@ -15,8 +15,9 @@ import ErrorScreen from 'components/ErrorScreen'; import PageNotFound from 'components/PageNotFound'; import LogOutPrompt from 'components/LogOutPrompt'; import QrSignerModal from 'containers/QrSignerModal'; +import OnboardModal from 'containers/OnboardModal'; +import WelcomeModal from 'components/WelcomeModal'; import NewAppReleaseModal from 'components/NewAppReleaseModal'; -import { TitleBar } from 'components/ui'; import { Store } from 'redux'; import { pollOfflineStatus, TPollOfflineStatus } from 'actions/config'; import { AppState } from 'reducers'; @@ -104,12 +105,17 @@ class RootClass extends Component { - {process.env.BUILD_ELECTRON && } {routes} {process.env.BUILD_ELECTRON && } + {!process.env.DOWNLOADABLE_BUILD && ( + + + + + )} diff --git a/common/components/BetaAgreement/index.scss b/common/components/BetaAgreement/index.scss deleted file mode 100644 index 6bad52ae..00000000 --- a/common/components/BetaAgreement/index.scss +++ /dev/null @@ -1,66 +0,0 @@ -@import 'common/sass/variables'; -@import 'common/sass/mixins'; - -.BetaAgreement { - @include cover-message; - background: $brand-info; - - &-content { - h2 { - text-align: center; - } - - &-buttons { - padding-top: 20px; - - &-btn { - display: block; - width: 100%; - max-width: 280px; - margin: 0 auto; - border: none; - padding: 0; - transition: $transition; - - &.is-continue { - height: 60px; - line-height: 60px; - font-size: 22px; - background: rgba(#fff, 0.96); - color: $gray-dark; - border-radius: 4px; - margin-bottom: 20px; - - &:hover { - background: #fff; - color: $gray-darker; - } - } - - &.is-reject { - background: none; - color: #fff; - opacity: 0.7; - - &:hover { - opacity: 1; - } - } - } - } - } - - // Fade out - &.is-fading { - pointer-events: none; - opacity: 0; - background: #fff; - transition: all 500ms ease 400ms; - - .BetaAgreement-content { - opacity: 0; - transform: translateY(15px); - transition: all 500ms ease; - } - } -} diff --git a/common/components/BetaAgreement/index.tsx b/common/components/BetaAgreement/index.tsx deleted file mode 100644 index b8472e74..00000000 --- a/common/components/BetaAgreement/index.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from 'react'; -import { NewTabLink } from 'components/ui'; -import { discordURL } from 'config'; -import './index.scss'; - -const LS_KEY = 'acknowledged-beta'; - -interface State { - isFading: boolean; - hasAcknowledged: boolean; -} -export default class BetaAgreement extends React.PureComponent<{}, State> { - public state = { - hasAcknowledged: !!localStorage.getItem(LS_KEY), - isFading: false - }; - - public render() { - if (this.state.hasAcknowledged) { - return null; - } - - const isFading = this.state.isFading ? 'is-fading' : ''; - - return ( -
-
-

Welcome to the New MyCrypto Beta Release Candidate!

-

- You are about to use the new MyCrypto Beta Release Candidate. Although this is a release - candidate for production, we encourage caution while using this unreleased version of - MyCrypto. -

-

We hope to move this version of MyCrypto into production in the near future!

-

- Feedback and bug reports are greatly appreciated. You can file issues on our{' '} - - GitHub repository - {' '} - or join our Discord server to discuss the - beta. -

-

Are you sure you would like to continue?

- -
- - -
-
-
- ); - } - - private doContinue = () => { - localStorage.setItem(LS_KEY, 'true'); - this.setState({ isFading: true }); - - setTimeout(() => { - this.setState({ hasAcknowledged: true }); - }, 1000); - }; - - private reject = () => { - window.location.assign('https://mycrypto.com'); - }; -} diff --git a/common/components/Footer/index.tsx b/common/components/Footer/index.tsx index 3af4fe66..027b405e 100644 --- a/common/components/Footer/index.tsx +++ b/common/components/Footer/index.tsx @@ -12,7 +12,6 @@ import React from 'react'; import PreFooter from './PreFooter'; import DisclaimerModal from 'components/DisclaimerModal'; import { NewTabLink } from 'components/ui'; -import OnboardModal from 'containers/OnboardModal'; import './index.scss'; import { translateRaw } from 'translations'; @@ -133,8 +132,6 @@ export default class Footer extends React.PureComponent { - - ); diff --git a/common/components/Header/components/OnlineStatus.scss b/common/components/Header/components/OnlineStatus.scss index 7a3acbc0..c92840f1 100644 --- a/common/components/Header/components/OnlineStatus.scss +++ b/common/components/Header/components/OnlineStatus.scss @@ -12,7 +12,6 @@ .OnlineStatus { position: relative; - top: -2px; width: 12px; height: 12px; text-align: center; diff --git a/common/components/Header/components/OnlineStatus.tsx b/common/components/Header/components/OnlineStatus.tsx index d36e3090..b7dba55d 100644 --- a/common/components/Header/components/OnlineStatus.tsx +++ b/common/components/Header/components/OnlineStatus.tsx @@ -7,8 +7,8 @@ interface Props { } const OnlineStatus: React.SFC = ({ isOffline }) => ( -
- {isOffline ? 'Offline' : 'Online'} +
+ {isOffline ? 'Offline' : 'Online'}
); diff --git a/common/components/WelcomeModal.scss b/common/components/WelcomeModal.scss new file mode 100644 index 00000000..1128dd1c --- /dev/null +++ b/common/components/WelcomeModal.scss @@ -0,0 +1,26 @@ +@import 'common/sass/variables'; + +.WelcomeModal { + font-size: $font-size-bump-more; + + &-logo { + display: block; + max-width: 380px; + margin: $space auto $space * 2; + } + + &-beta { + margin-top: -$space-md; + font-size: $font-size-base; + text-align: center; + } + + &-continue { + display: block; + margin: $space * 2 auto 0; + } + + p, ul { + margin-bottom: $space; + } +} diff --git a/common/components/WelcomeModal.tsx b/common/components/WelcomeModal.tsx new file mode 100644 index 00000000..5d62ba76 --- /dev/null +++ b/common/components/WelcomeModal.tsx @@ -0,0 +1,62 @@ +import React from 'react'; +import translate from 'translations'; +import { Modal, NewTabLink } from 'components/ui'; +import { isLegacyUser, isBetaUser } from 'utils/localStorage'; +import Logo from 'assets/images/logo-mycrypto-transparent.svg'; +import './WelcomeModal.scss'; + +const LS_KEY = 'acknowledged-welcome'; + +interface State { + isOpen: boolean; +} + +export default class WelcomeModal extends React.Component<{}, State> { + public state: State = { + isOpen: false + }; + + public componentDidMount() { + if (isLegacyUser() && !localStorage.getItem(LS_KEY)) { + this.setState({ isOpen: true }); + } + } + + public render() { + return ( + +
+ + {isBetaUser() && ( +

+ πŸ’– {translate('WELCOME_MODAL_BETA')} πŸš€ +

+ )} +

{translate('WELCOME_MODAL_INTRO')}

+
    +
  • {translate('WELCOME_MODAL_FEATURE_1')}
  • +
  • {translate('WELCOME_MODAL_FEATURE_2')}
  • +
  • {translate('WELCOME_MODAL_FEATURE_3')}
  • +
  • {translate('WELCOME_MODAL_FEATURE_4')}
  • +
  • + + {translate('WELCOME_MODAL_FEATURE_5')} + +
  • +
  • {translate('WELCOME_MODAL_FEATURE_MORE')}
  • +
+

{translate('WELCOME_MODAL_LINKS')}

+ + +
+
+ ); + } + + private close = () => { + this.setState({ isOpen: false }); + localStorage.setItem(LS_KEY, 'true'); + }; +} diff --git a/common/components/index.ts b/common/components/index.ts index 4543dfbc..d49f23c4 100644 --- a/common/components/index.ts +++ b/common/components/index.ts @@ -14,7 +14,6 @@ export { default as Header } from './Header'; export { default as Footer } from './Footer'; export { default as BalanceSidebar } from './BalanceSidebar'; export { default as PaperWallet } from './PaperWallet'; -export { default as BetaAgreement } from './BetaAgreement'; export { default as TXMetaDataPanel } from './TXMetaDataPanel'; export { default as WalletDecrypt } from './WalletDecrypt'; export { default as TogglablePassword } from './TogglablePassword'; diff --git a/common/components/ui/Modal/ModalBody.tsx b/common/components/ui/Modal/ModalBody.tsx index 1f4d2fb8..459d39e8 100644 --- a/common/components/ui/Modal/ModalBody.tsx +++ b/common/components/ui/Modal/ModalBody.tsx @@ -3,8 +3,8 @@ import closeIcon from 'assets/images/close.svg'; import { IButton } from 'components/ui/Modal'; interface Props { - title?: string; - children: any; + title?: React.ReactNode; + children: React.ReactNode; modalStyle?: CSSProperties; hasButtons?: number; buttons?: IButton[]; @@ -67,7 +67,7 @@ export default class ModalBody extends React.Component {
(this.modalContent = div as HTMLElement)}> {children} -
+
{hasButtons &&
{this.renderButtons()}
}
diff --git a/common/components/ui/Modal/index.scss b/common/components/ui/Modal/index.scss index 15319619..b7ebbed3 100644 --- a/common/components/ui/Modal/index.scss +++ b/common/components/ui/Modal/index.scss @@ -53,6 +53,10 @@ $m-anim-speed: 400ms; bottom: 4.5rem; left: 50%; transform: translateX(-50%); + + &.has-no-footer { + bottom: 0; + } } &-header { diff --git a/common/components/ui/Modal/index.tsx b/common/components/ui/Modal/index.tsx index 7f2aba92..4ad01c2e 100644 --- a/common/components/ui/Modal/index.tsx +++ b/common/components/ui/Modal/index.tsx @@ -12,9 +12,9 @@ export interface IButton { } interface Props { isOpen?: boolean; - title?: string; + title?: React.ReactNode; disableButtons?: boolean; - children: any; + children: React.ReactNode; buttons?: IButton[]; maxWidth?: number; handleClose(): void; diff --git a/common/components/ui/TitleBar.scss b/common/components/ui/TitleBar.scss deleted file mode 100644 index d6450593..00000000 --- a/common/components/ui/TitleBar.scss +++ /dev/null @@ -1,27 +0,0 @@ -@import 'common/sass/variables'; - -$height: 22px; - -// TODO - Implement styles for custom title bar on all platforms -.TitleBar, -.TitleBarPlaceholder { - display: none; -} - -.TitleBar { - position: fixed; - top: 0; - left: 0; - right: 0; - height: $height; - line-height: $height; - -webkit-user-select: none; - -webkit-app-region: drag; - background: $body-bg; - z-index: $zindex-top; - box-shadow: 0 1px 1px rgba(#000, 0.08); -} - -.TitleBarPlaceholder { - height: $height; -} diff --git a/common/components/ui/TitleBar.tsx b/common/components/ui/TitleBar.tsx deleted file mode 100644 index fe7fdcdd..00000000 --- a/common/components/ui/TitleBar.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; -import './TitleBar.scss'; - -const TitleBar: React.SFC<{}> = () => ( - -
-
- -); - -export default TitleBar; diff --git a/common/components/ui/Tooltip.scss b/common/components/ui/Tooltip.scss index e6033a23..49cdde1d 100644 --- a/common/components/ui/Tooltip.scss +++ b/common/components/ui/Tooltip.scss @@ -1,9 +1,9 @@ @import 'common/sass/variables'; @import 'common/sass/mixins'; -$tooltip-bg: rgba(#222, 0.95); - .Tooltip { + display: flex; + justify-content: center; position: absolute; top: 0; left: 50%; @@ -14,7 +14,7 @@ $tooltip-bg: rgba(#222, 0.95); pointer-events: none; opacity: 0; visibility: hidden; - transform: translate(-50%, -100%) translateY(-5px); + transform: translate(-50%, -100%) translateY(-$tooltip-start-distance); transition-property: opacity, transform, visibility; transition-duration: 100ms, 100ms, 0ms; transition-delay: 0ms, 0ms, 100ms; @@ -32,7 +32,7 @@ $tooltip-bg: rgba(#222, 0.95); bottom: 0; left: 50%; transform: translate(-50%, 100%); - @include triangle(10px, $tooltip-bg, down); + @include triangle($tooltip-arrow-size * 2, $tooltip-bg, down); } } @@ -46,7 +46,7 @@ $tooltip-bg: rgba(#222, 0.95); border-radius: 2px; &:after { - @include triangle(8px, $tooltip-bg, down); + border-width: $tooltip-arrow-size - 1; } } } @@ -60,8 +60,55 @@ $tooltip-bg: rgba(#222, 0.95); border-radius: 4px; &:after { - @include triangle(12px, $tooltip-bg, down); + border-width: $tooltip-arrow-size + 1; } } } + + // Direction, top is default + &.is-direction-left { + left: 0; + top: 50%; + justify-content: flex-end; + transform: translate(-100%, -50%) translateX(-$tooltip-start-distance); + + > span:after { + bottom: 50%; + right: 0; + left: auto; + transform: translate(100%, 50%); + border-top-color: transparent; + border-left-color: $tooltip-bg; + } + } + + &.is-direction-right { + left: auto; + right: 0; + top: 50%; + justify-content: flex-start; + transform: translate(100%, -50%) translateX($tooltip-start-distance); + + > span:after { + bottom: 50%; + left: 0; + transform: translate(-100%, 50%); + border-top-color: transparent; + border-right-color: $tooltip-bg; + } + } + + &.is-direction-bottom { + top: auto; + bottom: 0; + transform: translate(-50%, 100%) translateY($tooltip-start-distance); + + > span:after { + bottom: auto; + top: 0; + transform: translate(-50%, -100%); + border-top-color: transparent; + border-bottom-color: $tooltip-bg; + } + } } diff --git a/common/components/ui/Tooltip.tsx b/common/components/ui/Tooltip.tsx index 6698f741..00ed8afe 100644 --- a/common/components/ui/Tooltip.tsx +++ b/common/components/ui/Tooltip.tsx @@ -5,13 +5,15 @@ import './Tooltip.scss'; interface Props { children: React.ReactElement | string; size?: 'sm' | 'md' | 'lg'; + direction?: 'top' | 'bottom' | 'left' | 'right'; } -const Tooltip: React.SFC = ({ size, children }) => ( +const Tooltip: React.SFC = ({ size, direction, children }) => (
{children} diff --git a/common/components/ui/index.ts b/common/components/ui/index.ts index 3ab350a2..1f649559 100644 --- a/common/components/ui/index.ts +++ b/common/components/ui/index.ts @@ -11,7 +11,6 @@ export { default as UnitDisplay } from './UnitDisplay'; export { default as Spinner } from './Spinner'; export { default as SwapDropdown } from './SwapDropdown'; export { default as Tooltip } from './Tooltip'; -export { default as TitleBar } from './TitleBar'; export { default as HelpLink } from './HelpLink'; export { default as Input } from './Input'; export { default as TextArea } from './TextArea'; diff --git a/common/config/data.tsx b/common/config/data.tsx index 7637c0d9..90d6266f 100644 --- a/common/config/data.tsx +++ b/common/config/data.tsx @@ -1,16 +1,15 @@ import React from 'react'; // For ANNOUNCEMENT_MESSAGE jsx -import NewTabLink from 'components/ui/NewTabLink'; import { getValues } from '../utils/helpers'; import packageJson from '../../package.json'; import { GasPriceSetting } from 'types/network'; import { makeExplorer } from 'utils/helpers'; +import NewTabLink from 'components/ui/NewTabLink'; export const languages = require('./languages.json'); export const discordURL = 'https://discord.gg/VSaTXEA'; // Displays in the footer -export const VERSION_RAW = packageJson.version; -export const VERSION = `${VERSION_RAW} (Release Candidate 2)`; +export const VERSION = packageJson.version; export const N_FACTOR = 8192; // Bricks the app once this date has been exceeded. Remember to update these 2 @@ -26,10 +25,8 @@ export const VERSION_RC = `${packageJson.version}-RC.0`; export const ANNOUNCEMENT_TYPE = ''; export const ANNOUNCEMENT_MESSAGE = ( - This is a Beta Release Candidate of the new MyCrypto. Please submit any bug reports to our{' '} - GitHub and use{' '} - HackerOne for critical - vulnerabilities. Join the discussion on Discord. + Welcome to the new MyCrypto. We hope you like it! If it's urgent and you need the old site, you + can still use MyCrypto Legacy ); diff --git a/common/config/links.ts b/common/config/links.ts index ad9841a9..3e5c979c 100644 --- a/common/config/links.ts +++ b/common/config/links.ts @@ -47,6 +47,10 @@ export const socialMediaLinks: Link[] = [ ]; export const productLinks: Link[] = [ + { + link: 'https://legacy.mycrypto.com/', + text: translateRaw('OLD_MYCRYPTO') + }, { link: 'https://chrome.google.com/webstore/detail/etheraddresslookup/pdknmigbbbhmllnmgdfalmedcmcefdfn', diff --git a/common/containers/OnboardModal/index.tsx b/common/containers/OnboardModal/index.tsx index 77f4c444..94fcdc50 100644 --- a/common/containers/OnboardModal/index.tsx +++ b/common/containers/OnboardModal/index.tsx @@ -28,9 +28,7 @@ import { SecureSlideThree, FinalSlide } from './components'; - -const ONBOARD_LOCAL_STORAGE_KEY = 'onboardStatus'; -const NUMBER_OF_SLIDES = 10; +import { ONBOARD_LOCAL_STORAGE_KEY, NUMBER_OF_ONBOARD_SLIDES } from 'utils/localStorage'; interface State { isOpen: boolean; @@ -58,7 +56,6 @@ class OnboardModal extends React.Component { public componentDidMount() { const { sessionStarted } = this.props; - const currentSlide = Number(localStorage.getItem(ONBOARD_LOCAL_STORAGE_KEY)) || 0; if (!sessionStarted) { @@ -68,7 +65,7 @@ class OnboardModal extends React.Component { isOpen: true }); } - if (currentSlide > 0 && currentSlide < NUMBER_OF_SLIDES) { + if (currentSlide > 0 && currentSlide < NUMBER_OF_ONBOARD_SLIDES) { this.props.resumeSlide(currentSlide); this.setState({ isOpen: true @@ -90,7 +87,7 @@ class OnboardModal extends React.Component { const firstButtons: IButton[] = [ { - disabled: slideNumber === NUMBER_OF_SLIDES, + disabled: slideNumber === NUMBER_OF_ONBOARD_SLIDES, text: translate('ACTION_6'), type: 'primary', onClick: this.handleNextSlide @@ -115,8 +112,8 @@ class OnboardModal extends React.Component { } ]; - const buttons = slideNumber === NUMBER_OF_SLIDES ? lastButtons : firstButtons; - const steps = new Array(NUMBER_OF_SLIDES).fill({}); + const buttons = slideNumber === NUMBER_OF_ONBOARD_SLIDES ? lastButtons : firstButtons; + const steps = new Array(NUMBER_OF_ONBOARD_SLIDES).fill({}); return (
@@ -158,8 +155,8 @@ class OnboardModal extends React.Component { ]; - if (slides.length !== NUMBER_OF_SLIDES) { - console.log('Slides length do not match const NUMBER_OF_SLIDES'); + if (slides.length !== NUMBER_OF_ONBOARD_SLIDES) { + console.log('Slides length do not match const NUMBER_OF_ONBOARD_SLIDES'); } const currentSlideIndex = this.props.slideNumber - 1; diff --git a/common/containers/TabSection/WebTemplate.tsx b/common/containers/TabSection/WebTemplate.tsx index 7fbb848f..abb6dad3 100644 --- a/common/containers/TabSection/WebTemplate.tsx +++ b/common/containers/TabSection/WebTemplate.tsx @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; -import { BetaAgreement, Footer, Header } from 'components'; +import { Footer, Header } from 'components'; import { AppState } from 'reducers'; import Notifications from './Notifications'; import OfflineTab from './OfflineTab'; @@ -38,7 +38,6 @@ class WebTemplate extends Component {
-
); } diff --git a/common/sass/mixins.scss b/common/sass/mixins.scss index a995fd16..1e1e770a 100644 --- a/common/sass/mixins.scss +++ b/common/sass/mixins.scss @@ -87,8 +87,20 @@ &:hover .Tooltip { opacity: 1; visibility: visible; - transform: translate(-50%, -100%) translateY(-8px); + transform: translate(-50%, -100%) translateY(-$tooltip-hover-distance); transition-delay: 400ms, 400ms, 300ms; + + &.is-direction-left { + transform: translate(-100%, -50%) translateX(-$tooltip-hover-distance); + } + + &.is-direction-right { + transform: translate(100%, -50%) translateX($tooltip-hover-distance); + } + + &.is-direction-bottom { + transform: translate(-50%, 100%) translateY($tooltip-hover-distance); + } } } diff --git a/common/sass/variables.scss b/common/sass/variables.scss index eb7736a6..c7aa17b7 100644 --- a/common/sass/variables.scss +++ b/common/sass/variables.scss @@ -7,6 +7,7 @@ @import './variables/transitions'; @import './variables/links'; @import './variables/tables'; +@import './variables/tooltips'; @import './variables/buttons'; @import './variables/forms'; @import './variables/zindex'; diff --git a/common/sass/variables/tooltips.scss b/common/sass/variables/tooltips.scss new file mode 100644 index 00000000..21d60481 --- /dev/null +++ b/common/sass/variables/tooltips.scss @@ -0,0 +1,4 @@ +$tooltip-start-distance: 5px; +$tooltip-hover-distance: 9px; +$tooltip-arrow-size: 5px; +$tooltip-bg: rgba(#222, 0.95); diff --git a/common/translations/lang/en.json b/common/translations/lang/en.json index 2f8bda0f..4ba745e7 100644 --- a/common/translations/lang/en.json +++ b/common/translations/lang/en.json @@ -390,6 +390,7 @@ "ETHERSCAMDB": "EtherScamDB", "ETHER_SECURITY_LOOKUP": "EtherSecurityLookup", "ETHER_ADDRESS_LOOKUP": "EtherAddressLookup", + "OLD_MYCRYPTO": "MyCrypto (Legacy Site)", "LEDGER_REFERRAL_1": "Buy a Ledger Wallet", "LEDGER_REFERRAL_2": "Don’t have a Ledger? Order one now!", "LEDGER_TIP": "**Tip:** Make sure you're logged into the $network app on your hardware wallet, and have enabled browser support in the settings", @@ -561,6 +562,16 @@ "APP_UPDATE_TITLE": "New App Version Available", "APP_UPDATE_BODY": "An updated version of the MyCrypto app has just been released! You can upgrade to the new version by downloading it from our GitHub release page.", "APP_UPDATE_CONFIRM": "Get the New Version", - "APP_UPDATE_CANCEL": "Maybe Later" + "APP_UPDATE_CANCEL": "Maybe Later", + "WELCOME_MODAL_BETA": "Thank you for testing the beta! People like you made this launch possible", + "WELCOME_MODAL_INTRO": "Welcome to the all new MyCrypto! We've made some cool new changes to the site that we're excited to show you. Beyond the new and improved look and feel of the site, we've also added a ton of new features:", + "WELCOME_MODAL_FEATURE_1": "Token balance scanner", + "WELCOME_MODAL_FEATURE_2": "Combined Send, Info, and Send Offline tabs", + "WELCOME_MODAL_FEATURE_3": "Parity Signer app integration", + "WELCOME_MODAL_FEATURE_4": "Recent transactions history", + "WELCOME_MODAL_FEATURE_5": "A downloadable desktop app", + "WELCOME_MODAL_FEATURE_MORE": "...and much, much more!", + "WELCOME_MODAL_LINKS": "Help out with any issues you find by [reporting bugs on GitHub](https://github.com/MyCryptoHQ/MyCrypto/issues) or [HackerOne](https://hackerone.com/mycrypto). Need something from the old site, or just miss that clunky feel? We've kept it up as [MyCrypto Legacy](https://legacy.mycrypto.com).", + "WELCOME_MODAL_CONTINUE": "Show me the new site!" } } diff --git a/common/utils/formatters.ts b/common/utils/formatters.ts index f994e948..7df7f3cf 100644 --- a/common/utils/formatters.ts +++ b/common/utils/formatters.ts @@ -113,7 +113,7 @@ export function bytesToHuman(bytes: number) { } export function ensV3Url(name: string) { - return `https://mycrypto.com/?ensname=${name}#ens`; + return `https://legacy.mycrypto.com/?ensname=${name}#ens`; } export function hexToNumber(hex: string) { diff --git a/common/utils/localStorage.ts b/common/utils/localStorage.ts index 5cb8ea24..7b0a0ffb 100644 --- a/common/utils/localStorage.ts +++ b/common/utils/localStorage.ts @@ -4,6 +4,8 @@ import { IWallet, WalletConfig } from 'libs/wallet'; import { AppState } from 'reducers'; export const REDUX_STATE = 'REDUX_STATE'; +export const ONBOARD_LOCAL_STORAGE_KEY = 'onboardStatus'; +export const NUMBER_OF_ONBOARD_SLIDES = 10; export function loadState(): T | undefined { try { @@ -61,3 +63,18 @@ function getWalletConfigKey(wallet: IWallet): string { const address = wallet.getAddressString(); return sha256(`${address}-mycrypto`).toString('hex'); } + +export function isLegacyUser() { + // All devs are legacy users! + const oldLSValue = localStorage.getItem('gasPrice') || process.env.NODE_ENV !== 'production'; + const onboardProgress = localStorage.getItem(ONBOARD_LOCAL_STORAGE_KEY); + + if (oldLSValue && onboardProgress && parseInt(onboardProgress, 10) >= NUMBER_OF_ONBOARD_SLIDES) { + return true; + } + return false; +} + +export function isBetaUser() { + return !!localStorage.getItem('acknowledged-beta'); +}