From 985bef652cde83cc232947ae9f17ed406a44ddec Mon Sep 17 00:00:00 2001 From: wlycdgr Date: Tue, 10 Dec 2019 16:17:39 -0500 Subject: [PATCH 01/11] Modifying the Plus promo components to Premium --- app/hub/Views/HomeView/HomeViewActions.js | 6 +- app/hub/Views/HomeView/HomeViewConstants.js | 2 +- app/hub/Views/HomeView/HomeViewContainer.jsx | 68 ++++++++----- app/hub/Views/HomeView/HomeViewReducer.js | 6 +- app/panel/components/Panel.jsx | 49 +++------ .../components/PlusUpgradePromoModal.jsx | 80 --------------- .../PremiumPromoModal.jsx} | 99 ++++++++++--------- .../PremiumPromoModal.scss} | 52 +++++----- .../index.js | 6 +- app/shared-components/index.js | 4 +- src/background.js | 8 +- src/classes/PromoModals.js | 4 +- 12 files changed, 149 insertions(+), 235 deletions(-) rename app/shared-components/{PlusPromoModal/PlusPromoModal.jsx => PremiumPromoModal/PremiumPromoModal.jsx} (52%) rename app/shared-components/{PlusPromoModal/PlusPromoModal.scss => PremiumPromoModal/PremiumPromoModal.scss} (83%) rename app/shared-components/{PlusPromoModal => PremiumPromoModal}/index.js (68%) diff --git a/app/hub/Views/HomeView/HomeViewActions.js b/app/hub/Views/HomeView/HomeViewActions.js index 3de1b1976..026bf2011 100644 --- a/app/hub/Views/HomeView/HomeViewActions.js +++ b/app/hub/Views/HomeView/HomeViewActions.js @@ -12,7 +12,7 @@ */ import { log, sendMessageInPromise } from '../../utils'; -import { GET_HOME_PROPS, MARK_PLUS_PROMO_MODAL_SHOWN, SET_METRICS } from './HomeViewConstants'; +import { GET_HOME_PROPS, MARK_PREMIUM_PROMO_MODAL_SHOWN, SET_METRICS } from './HomeViewConstants'; export function getHomeProps() { return function(dispatch) { @@ -40,8 +40,8 @@ export function setMetrics(actionData) { }; } -export function markPlusPromoModalShown() { +export function markPremiumPromoModalShown() { return { - type: MARK_PLUS_PROMO_MODAL_SHOWN, + type: MARK_PREMIUM_PROMO_MODAL_SHOWN, }; } diff --git a/app/hub/Views/HomeView/HomeViewConstants.js b/app/hub/Views/HomeView/HomeViewConstants.js index 2defff14b..d4040d1eb 100644 --- a/app/hub/Views/HomeView/HomeViewConstants.js +++ b/app/hub/Views/HomeView/HomeViewConstants.js @@ -13,5 +13,5 @@ // Home View export const GET_HOME_PROPS = 'GET_HOME_PROPS'; -export const MARK_PLUS_PROMO_MODAL_SHOWN = 'MARK_PLUS_PROMO_MODAL_SHOWN'; +export const MARK_PREMIUM_PROMO_MODAL_SHOWN = 'MARK_PREMIUM_PROMO_MODAL_SHOWN'; export const SET_METRICS = 'SET_METRICS'; diff --git a/app/hub/Views/HomeView/HomeViewContainer.jsx b/app/hub/Views/HomeView/HomeViewContainer.jsx index b9edcd753..5ed552331 100644 --- a/app/hub/Views/HomeView/HomeViewContainer.jsx +++ b/app/hub/Views/HomeView/HomeViewContainer.jsx @@ -15,7 +15,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import QueryString from 'query-string'; import HomeView from './HomeView'; -import { PlusPromoModal } from '../../../shared-components'; +import { PremiumPromoModal } from '../../../shared-components'; import { sendMessage } from '../../utils'; import globals from '../../../../src/classes/Globals'; @@ -41,8 +41,7 @@ class HomeViewContainer extends Component { props.actions.getHomeProps(); - // Prevent flickering in of user's email if getUser() returns after initial render, - // as well as flickering of plus promo modal if user is already a subscriber + // Prevent flickering in of user's email if getUser() returns after initial render props.actions.getUser() .then(() => { this.setState({ @@ -61,37 +60,54 @@ class HomeViewContainer extends Component { } /** + * Handle clicks on premium promo modal button + * @param type 'basic' (default), 'plus', or 'premium' * @private - * Function to handle clicks on Select Basic in the Plus Promo Modal */ - _handlePromoSelectBasicClick = () => { + _handlePremiumPromoModalClick = (type = 'basic') => { // GH-1777 - // we want to show the Plus Promo modal once per Hub visit - this.props.actions.markPlusPromoModalShown(); - - sendMessage('SET_PLUS_PROMO_MODAL_SEEN', {}); + // we want to show the promo modal exactly once per Hub visit + this.props.actions.markPremiumPromoModalShown(); + + sendMessage('SET_PREMIUM_PROMO_MODAL_SEEN', {}); + + switch (type) { + case 'plus': + window.open(`https://checkout.${DOMAIN}.com/plus?utm_source=gbe&utm_campaign=intro_hub`, '_blank'); + break; + case 'premium': + window.open(`https://reddit.com`, '_blank'); + break; + case 'basic': + default: + break; + } } /** * @private - * Function to handle clicks on 'Select Plus' in the Plus Promo Modal (Choose Your Plan) + * Function to handle clicks on "No thanks, continue with basic" in Premium promo modal */ - _handlePromoSelectPlusClick = () => { - // GH-1777 - // we want to show the Plus Promo modal once per Hub visit - this.props.actions.markPlusPromoModalShown(); + _handleKeepBasicClick = () => { this._handlePremiumPromoModalClick(); } - sendMessage('SET_PLUS_PROMO_MODAL_SEEN', {}); + /** + * @private + * Function to handle clicks on the "Get Plus instead" link in the Premium promo modal + */ + _handleGetPlusClick = () => { this._handlePremiumPromoModalClick('plus'); } - window.open(`https://checkout.${DOMAIN}.com/plus?utm_source=gbe&utm_campaign=intro_hub`, '_blank'); - } + /** + * @private + * Function to handle clicks on the Midnight download button in the Premium promo modal + */ + _handleTryMidnightClick = () => { this._handleTryMidnightClick('midnight'); } _render() { const { justInstalled } = this.state; const { home, user } = this.props; const isPlus = user && user.subscriptionsPlus || false; const { - plus_promo_modal_shown, + premium_promo_modal_shown, setup_complete, tutorial_complete, enable_metrics, @@ -106,15 +122,13 @@ class HomeViewContainer extends Component { isPlus, }; - const showPromoModal = !isPlus && !plus_promo_modal_shown; - return (
-
@@ -137,7 +151,7 @@ class HomeViewContainer extends Component { HomeViewContainer.propTypes = { home: PropTypes.shape({ enable_metrics: PropTypes.bool, - plus_promo_modal_shown: PropTypes.bool, + premium_promo_modal_shown: PropTypes.bool, setup_complete: PropTypes.bool, tutorial_complete: PropTypes.bool, }), @@ -148,7 +162,7 @@ HomeViewContainer.propTypes = { actions: PropTypes.shape({ getHomeProps: PropTypes.func.isRequired, getUser: PropTypes.func.isRequired, - markPlusPromoModalShown: PropTypes.func.isRequired, + markPremiumPromoModalShown: PropTypes.func.isRequired, setMetrics: PropTypes.func.isRequired, }).isRequired, }; @@ -157,7 +171,7 @@ HomeViewContainer.propTypes = { HomeViewContainer.defaultProps = { home: { enable_metrics: false, - plus_promo_modal_shown: false, + premium_promo_modal_shown: false, setup_complete: false, tutorial_complete: false, }, diff --git a/app/hub/Views/HomeView/HomeViewReducer.js b/app/hub/Views/HomeView/HomeViewReducer.js index f60c13123..1582d7e62 100644 --- a/app/hub/Views/HomeView/HomeViewReducer.js +++ b/app/hub/Views/HomeView/HomeViewReducer.js @@ -11,7 +11,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0 */ -import { GET_HOME_PROPS, MARK_PLUS_PROMO_MODAL_SHOWN, SET_METRICS } from './HomeViewConstants'; +import { GET_HOME_PROPS, MARK_PREMIUM_PROMO_MODAL_SHOWN, SET_METRICS } from './HomeViewConstants'; const initialState = {}; @@ -31,10 +31,10 @@ function HomeViewReducer(state = initialState, action) { }), }); } - case MARK_PLUS_PROMO_MODAL_SHOWN: { + case MARK_PREMIUM_PROMO_MODAL_SHOWN: { return Object.assign({}, state, { home: Object.assign({}, state.home, { - plus_promo_modal_shown: true, + premium_promo_modal_shown: true, }) }); } diff --git a/app/panel/components/Panel.jsx b/app/panel/components/Panel.jsx index 575027e6f..dd128c316 100644 --- a/app/panel/components/Panel.jsx +++ b/app/panel/components/Panel.jsx @@ -14,9 +14,8 @@ import React from 'react'; import { NavLink } from 'react-router-dom'; import Header from '../containers/HeaderContainer'; -import { PlusPromoModal } from '../../shared-components'; +import { PremiumPromoModal } from '../../shared-components'; import InsightsPromoModal from './InsightsPromoModal'; -import PlusUpgradePromoModal from './PlusUpgradePromoModal'; import { DynamicUIPortContext } from '../contexts/DynamicUIPortContext'; import { sendMessage } from '../utils/msg'; import { setTheme } from '../utils/utils'; @@ -253,8 +252,7 @@ class Panel extends React.Component { /** * @private - * Handle click action when user selects Subscribe button in - * Plus Upgrade or Insights modal + * Handle click action when user selects Subscribe button in the Insights modal * @param {string} modal Modal type (insights or plus) */ _handlePromoSubscribeClick = (modal) => { @@ -265,9 +263,6 @@ class Panel extends React.Component { if (modal === 'insights') { sendMessage('ping', 'promo_modals_insights_upgrade_cta'); url += 'insights?utm_source=gbe&utm_campaign=in_app_upgrade'; - } else if (modal === 'plus_upgrade') { - sendMessage('ping', 'promo_modals_plus_upgrade_cta'); - url += 'plus?utm_source=gbe&utm_campaign=in_app_upgrade'; } sendMessage('openNewTab', { @@ -281,48 +276,26 @@ class Panel extends React.Component { if (modal === 'insights') { sendMessage('ping', 'promo_modals_decline_insights_upgrade'); - } else if (modal === 'plus_upgrade') { - sendMessage('ping', 'promo_modals_decline_plus_upgrade'); } }; - _plusSubscriber = () => { - const { loggedIn, user } = this.props; - - return loggedIn && (user && user.subscriptionsPlus); - } - _insightsSubscriber = () => { const { loggedIn, user } = this.props; return loggedIn && (user && user.scopes && user.scopes.includes('subscriptions:insights')); } - _renderPlusPromoModal = () => { - if (this._plusSubscriber() || this._insightsSubscriber()) return null; + _renderPremiumPromoModal = () => { + sendMessage('promoModals.sawPremiumPromo', {}); - if (this.props.promoModal === 'plus_upgrade') { - // the upgrade promo does not require the user to make a choice, so we mark it as 'seen' immediately - sendMessage('promoModals.sawPlusPromo', {}); - sendMessage('ping', 'promo_modals_show_upgrade_plus'); - return ( - - ); - } - - // promoModal === 'plus_initial' return ( - ); } @@ -356,8 +329,8 @@ class Panel extends React.Component { return this._renderInsightsPromoModal(); } - if (promoModal === 'plus_initial' || promoModal === 'plus_upgrade') { - return this._renderPlusPromoModal(); + if (promoModal === 'premium') { + return this._renderPremiumPromoModal(); } return null; diff --git a/app/panel/components/PlusUpgradePromoModal.jsx b/app/panel/components/PlusUpgradePromoModal.jsx index e4e5fd456..8b1378917 100644 --- a/app/panel/components/PlusUpgradePromoModal.jsx +++ b/app/panel/components/PlusUpgradePromoModal.jsx @@ -1,81 +1 @@ -/** - * Plus Upgrade Promo Modal Component - * - * Ghostery Browser Extension - * https://www.ghostery.com/ - * - * Copyright 2019 Ghostery, Inc. All rights reserved. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0 - */ -import React from 'react'; -import ClassNames from 'classnames'; -import Modal from '../../shared-components/Modal'; -import ModalExitButton from './BuildingBlocks/ModalExitButton'; - -const PLUS_UPGRADE = 'plus_upgrade'; - -/** - * @class Implements the Upgrade variant of the Plus Promo Modal - * @memberof PanelClasses - */ -class PlusUpgradePromoModal extends React.Component { - handleNoThanksClick = () => { this.props.handleNoThanksClick(PLUS_UPGRADE); } - - handleSubscribeClick = () => { this.props.handleSubscribeClick(PLUS_UPGRADE); } - - handleXClick = () => { this.props.handleXClick(PLUS_UPGRADE); } - - render() { - const { loggedIn } = this.props; - - const contentClassNames = ClassNames( - 'PlusPromoModal__content', - 'flex-container', - 'flex-dir-column', - 'align-middle', - 'panel', - 'upgrade' - ); - - // TODO update ModalExitButton class here - // TODO pass down handler for click on ModalExitButton - return ( - -
- - -
- {t('upgrade_your_ghostery_experience')} -
-
-
-
- - {t('upgrade_to_plus')} - -
-
- { - !loggedIn && - ( -
- {t('already_subscribed_sign_in')} -
- ) - } -
- {t('no_thanks_turn_promos_off')} -
-
-
-
- - ); - } -} - -export default PlusUpgradePromoModal; diff --git a/app/shared-components/PlusPromoModal/PlusPromoModal.jsx b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx similarity index 52% rename from app/shared-components/PlusPromoModal/PlusPromoModal.jsx rename to app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx index a85c5bf0a..b395ba728 100644 --- a/app/shared-components/PlusPromoModal/PlusPromoModal.jsx +++ b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx @@ -1,5 +1,5 @@ /** - * Plus Promo Modal Component + * Premium Promo Modal Component * * Ghostery Browser Extension * https://www.ghostery.com/ @@ -17,17 +17,18 @@ import ClassNames from 'classnames'; import Modal from '../Modal/Modal'; /** - * A functional React component for a Plus Promo Modal that may be displayed in the Hub and/or Panel - * @return {JSX} JSX for rendering a Plus Promo Modal + * A functional React component for a Premium Promo Modal that may be displayed in the Hub and/or Panel + * @return {JSX} JSX for rendering a Premium Promo Modal * @memberof SharedComponents */ -const PlusPromoModal = (props) => { +const PremiumPromoModal = (props) => { const { show, location, - handleSelectBasicClick, - handleSelectPlusClick, - handleSignInClick, + handleTryMidnightClick, + handleGetPlusClick, + handleKeepBasicClick, + handleGoAwayClick, } = props; const isInHub = location === 'hub'; @@ -38,7 +39,7 @@ const PlusPromoModal = (props) => { 'in-panel': location === 'panel' }; const contentClassNames = ClassNames( - 'PlusPromoModal__content', + 'PremiumPromoModal__content', 'flex-container', 'flex-dir-column', 'align-middle', @@ -46,28 +47,28 @@ const PlusPromoModal = (props) => { locationClassName ); const optionsContainerClassNames = ClassNames( - 'PlusPromoModal__options-container', + 'PremiumPromoModal__options-container', 'full-width', locationClassName ); const optionsDecriptionClassNames = ClassNames( - 'PlusPromoModal__option-description-item', + 'PremiumPromoModal__option-description-item', locationClassName ); const chooseYourPlanClassNames = ClassNames( - 'PlusPromoModal__choose-your-plan', + 'PremiumPromoModal__choose-your-plan', locationClassName ); const recommendedBannerClassNames = ClassNames( - 'PlusPromoModal__recommended-banner', + 'PremiumPromoModal__recommended-banner', locationClassName ); const optionDescriptionBoxClassNames = ClassNames( - 'PlusPromoModal__option-description-box', + 'PremiumPromoModal__option-description-box', locationClassName ); const buttonBackgroundClassNames = ClassNames( - 'PlusPromoModal__buttons-background', + 'PremiumPromoModal__buttons-background', 'initial', locationClassName ); @@ -77,7 +78,7 @@ const PlusPromoModal = (props) => {
{isInHub && ( -
+
{t('ghostery_is_ready')}
)} @@ -86,16 +87,16 @@ const PlusPromoModal = (props) => {
-
+
-
{t('ghostery_basic')}
-
- - 0 +
{t('ghostery_basic')}
+
+ + 0 - {t('per_month')} + {t('per_month')}
-
+
{t('faster_cleaner_browsing')}
{t('blocks_ads')}
{t('blocks_trackers')}
@@ -103,36 +104,36 @@ const PlusPromoModal = (props) => {
-
+
-
{t('recommended')}
+
{t('recommended')}
-
{t('ghostery_plus')}
-
- - {t('plus_monthly_subscription_price_number')} +
{t('ghostery_plus')}
+
+ + {t('plus_monthly_subscription_price_number')} - {t('per_month')} + {t('per_month')}
-
+
{t('all_basic_features_plus_COLON')}
-
+
- + {t('historical_tracker_stats')}
-
+
- + {t('priority_support')}
-
+
- + {t('new_color_themes')}
@@ -141,14 +142,14 @@ const PlusPromoModal = (props) => {
-
+
{t('select_basic')}
-
+
{t('select_plus')}
{isInPanel && ( -
+
{t('already_subscribed_sign_in')}
)} @@ -158,17 +159,23 @@ const PlusPromoModal = (props) => { ); }; + // PropTypes ensure we pass required props of the correct type -PlusPromoModal.propTypes = { +PremiumPromoModal.propTypes = { show: PropTypes.bool.isRequired, location: PropTypes.string.isRequired, - handleSelectBasicClick: PropTypes.func.isRequired, - handleSelectPlusClick: PropTypes.func.isRequired, - handleSignInClick: PropTypes.func, + handleTryMidnightClick: PropTypes.func.isRequired, + handleGetPlusClick: PropTypes.func.isRequired, + handleKeepBasicClick: PropTypes.func, + handleGoAwayClick: PropTypes.func, + handleXClick: PropTypes.func, }; -PlusPromoModal.defaultProps = { - handleSignInClick: () => {}, +const noop = () => {}; +PremiumPromoModal.defaultProps = { + handleKeepBasicClick: noop, + handleGoAwayClick: noop, + handleXClick: noop, }; -export default PlusPromoModal; +export default PremiumPromoModal; diff --git a/app/shared-components/PlusPromoModal/PlusPromoModal.scss b/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss similarity index 83% rename from app/shared-components/PlusPromoModal/PlusPromoModal.scss rename to app/shared-components/PremiumPromoModal/PremiumPromoModal.scss index 897a73d0d..deeda291f 100644 --- a/app/shared-components/PlusPromoModal/PlusPromoModal.scss +++ b/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss @@ -1,5 +1,5 @@ /** - * Plus Promo Modal Sass + * Premium Promo Modal Sass * * Ghostery Browser Extension * https://www.ghostery.com/ @@ -11,15 +11,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0 */ -// Plus Promo Modal +// Premium Promo Modal $standard-font-family: Roboto, "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; -.PlusPromoModal__gold-ghostie-badge { +.PremiumPromoModal__gold-ghostie-badge { margin-top: 21px; } -.PlusPromoModal__header { +.PremiumPromoModal__header { font-size: 20px; font-weight: bold; font-family: $standard-font-family; @@ -27,7 +27,7 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti text-align: center; } -.PlusPromoModal__description { +.PremiumPromoModal__description { width: 350px; text-align: center; font-size: 18px; @@ -35,7 +35,7 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti font-family: $standard-font-family } -.PlusPromoModal__content { +.PremiumPromoModal__content { position: relative; background-color: #f7f7f7; border: 1.9px solid #930194; @@ -57,7 +57,7 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti } } -.PlusPromoModal__buttons-background { +.PremiumPromoModal__buttons-background { background-color: #e7ecee; margin-bottom: 3px; width: 99%; @@ -82,14 +82,14 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti } } -.PlusPromoModal__thanks-for-download { +.PremiumPromoModal__thanks-for-download { padding-top: 30px; font-size: 26px; font-weight: bold; text-align: center; } -.PlusPromoModal__choose-your-plan { +.PremiumPromoModal__choose-your-plan { font-size: 18px; font-weight: bold; font-family: $standard-font-family; @@ -102,20 +102,20 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti } } -.PlusPromoModal__options-container { +.PremiumPromoModal__options-container { display: flex; justify-content: space-around; &.in-hub {} &.in-panel {} } -.PlusPromoModal__option-container { +.PremiumPromoModal__option-container { display: flex; align-items: center; flex-direction: column; } -.PlusPromoModal__option-description-box { +.PremiumPromoModal__option-description-box { border-style: solid; border-width: 3px; background-color: #FFFFFF; @@ -144,7 +144,7 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti } } -.PlusPromoModal__recommended-banner { +.PremiumPromoModal__recommended-banner { position: absolute; font-family: $standard-font-family; @@ -159,7 +159,7 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti } } -.PlusPromoModal__recommended-banner-text { +.PremiumPromoModal__recommended-banner-text { position: relative; left: 15px; top: -47px; @@ -169,7 +169,7 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti font-weight: bold; } -.PlusPromoModal__option-header { +.PremiumPromoModal__option-header { margin-top: 20px; font-family: $condensed-font-family; font-size: 19px; @@ -180,7 +180,7 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti &.plus { color: #ebbf73; } } -.PlusPromoModal__price-text { +.PremiumPromoModal__price-text { line-height: 1.3; text-align: center; @@ -188,27 +188,27 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti &.plus { color: #ebbf73; } } -.PlusPromoModal__currency-sign { +.PremiumPromoModal__currency-sign { font-family: $condensed-font-family; font-size: 30px; font-weight: bold; } -.PlusPromoModal__amount { +.PremiumPromoModal__amount { vertical-align: middle; font-family: $standard-font-family; font-size: 58px; font-weight: normal; } -.PlusPromoModal__per-month { +.PremiumPromoModal__per-month { vertical-align: sub; font-family: $condensed-font-family; font-size: 18px; font-weight: bold; } -.PlusPromoModal__option-description-item { +.PremiumPromoModal__option-description-item { padding-bottom: 15px; text-align: center; font-family: $standard-font-family; @@ -224,22 +224,22 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti } } -.PlusPromoModal__check-icon { +.PremiumPromoModal__check-icon { padding-right: 10px; } -.PlusPromoModal__plus-option-description-item-container { +.PremiumPromoModal__plus-option-description-item-container { display: flex; justify-content: center; } -.PlusPromoModal__button-container { +.PremiumPromoModal__button-container { display: flex; margin-bottom: 10px; align-self: center; } -.PlusPromoModal__button { +.PremiumPromoModal__button { cursor: pointer; display: flex; justify-content: center; @@ -299,12 +299,12 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti } } -.PlusPromoModal__text-link-container { +.PremiumPromoModal__text-link-container { display: flex; justify-content: space-evenly; } -.PlusPromoModal__text-link { +.PremiumPromoModal__text-link { margin-left: 10px; margin-right: 10px; font-size: 13px; diff --git a/app/shared-components/PlusPromoModal/index.js b/app/shared-components/PremiumPromoModal/index.js similarity index 68% rename from app/shared-components/PlusPromoModal/index.js rename to app/shared-components/PremiumPromoModal/index.js index da26a8b7e..9d353dc6c 100644 --- a/app/shared-components/PlusPromoModal/index.js +++ b/app/shared-components/PremiumPromoModal/index.js @@ -1,5 +1,5 @@ /** - * Point of entry index.js file for Plus Promo Modal Component + * Point of entry index.js file for Premium Promo Modal Component * * Ghostery Browser Extension * https://www.ghostery.com/ @@ -11,6 +11,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0 */ -import PlusPromoModal from './PlusPromoModal'; +import PremiumPromoModal from './PremiumPromoModal'; -export default PlusPromoModal; +export default PremiumPromoModal; diff --git a/app/shared-components/index.js b/app/shared-components/index.js index a7fe2f139..8cea5f1ae 100644 --- a/app/shared-components/index.js +++ b/app/shared-components/index.js @@ -17,7 +17,7 @@ import ExitButton from './ExitButton'; import Modal from './Modal'; -import PlusPromoModal from './PlusPromoModal'; +import PremiumPromoModal from './PremiumPromoModal'; import SteppedNavigation from './SteppedNavigation'; import ToastMessage from './ToastMessage'; import ToggleCheckbox from './ToggleCheckbox'; @@ -26,7 +26,7 @@ import ToggleSwitch from './ToggleSwitch'; export { ExitButton, Modal, - PlusPromoModal, + PremiumPromoModal, SteppedNavigation, ToastMessage, ToggleCheckbox, diff --git a/src/background.js b/src/background.js index e54fbb533..4c85752b2 100644 --- a/src/background.js +++ b/src/background.js @@ -513,8 +513,8 @@ function handleRewards(name, message, callback) { */ function handleGhosteryHub(name, message, callback) { switch (name) { - case 'SET_PLUS_PROMO_MODAL_SEEN': - promoModals.recordPlusPromoSighting(); + case 'SET_PREMIUM_PROMO_MODAL_SEEN': + promoModals.recordPremiumPromoSighting(); break; case 'SEND_PING': { const { type } = message; @@ -1006,8 +1006,8 @@ function onMessageHandler(request, sender, callback) { }); return true; } - if (name === 'promoModals.sawPlusPromo') { - promoModals.recordPlusPromoSighting(); + if (name === 'promoModals.sawPremiumPromo') { + promoModals.recordPremiumPromoSighting(); return false; } if (name === 'promoModals.sawInsightsPromo') { diff --git a/src/classes/PromoModals.js b/src/classes/PromoModals.js index 2e202d80d..507f6629d 100644 --- a/src/classes/PromoModals.js +++ b/src/classes/PromoModals.js @@ -23,7 +23,7 @@ const WEEKLY_INSIGHTS_TARGET = globals.DEBUG ? 1 : 3; const DAILY_INSIGHTS_TARGET = globals.DEBUG ? 7 : 3; const MSECS_IN_DAY = 86400000; // 1000 msecs-in-sec * 60 secs-in-min * 60 mins-in-hour * 24 hours-in-day -const PLUS = 'plus'; +const PREMIUM = 'premium'; const PLUS_INITIAL = 'plus_initial'; const PLUS_UPGRADE = 'plus_upgrade'; const INSIGHTS = 'insights'; @@ -52,7 +52,7 @@ class PromoModals { return null; } - static recordPlusPromoSighting() { this._recordPromoSighting(PLUS); } + static recordPremiumPromoSighting() { this._recordPromoSighting(PREMIUM); } static recordInsightsPromoSighting() { this._recordPromoSighting(INSIGHTS); } From 3106a301313d8d8a245445a5b63e04290d1fca4f Mon Sep 17 00:00:00 2001 From: wlycdgr Date: Tue, 10 Dec 2019 16:42:23 -0500 Subject: [PATCH 02/11] Continue modifying front end promo code from the old Plus promos to the new Premium promo --- app/panel/components/InsightsPromoModal.jsx | 4 +- app/panel/components/Panel.jsx | 66 ++++++++++++++++----- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/app/panel/components/InsightsPromoModal.jsx b/app/panel/components/InsightsPromoModal.jsx index 7936ad4cc..5b1e54b7e 100644 --- a/app/panel/components/InsightsPromoModal.jsx +++ b/app/panel/components/InsightsPromoModal.jsx @@ -22,7 +22,7 @@ const INSIGHTS = 'insights'; * @memberof PanelClasses */ class InsightsPromoModal extends React.Component { - handleNoThanksClick = () => { this.props.handleNoThanksClick(INSIGHTS); } + handleGoAwayClick = () => { this.props.handleGoAwayClick(INSIGHTS); } handleSubscribeClick = () => { this.props.handleSubscribeClick(INSIGHTS); } @@ -78,7 +78,7 @@ class InsightsPromoModal extends React.Component {
{t('subscribe_pitch_sign_in')} - {t('no_thanks_turn_promos_off')} + {t('no_thanks_turn_promos_off')}
diff --git a/app/panel/components/Panel.jsx b/app/panel/components/Panel.jsx index dd128c316..a53468843 100644 --- a/app/panel/components/Panel.jsx +++ b/app/panel/components/Panel.jsx @@ -199,15 +199,18 @@ class Panel extends React.Component { return false; } - _handlePromoNoThanksClick = (modal) => { + /** + * @param modal 'insights' or 'premium' + * @private + * Handle clicks on the link to turn off promos in the promo modals + */ + _handlePromoGoAwayClick = (modal) => { this.props.actions.togglePromoModal(); sendMessage('promoModals.turnOffPromos', {}); if (modal === 'insights') { sendMessage('ping', 'promo_modals_decline_insights_upgrade'); - } else if (modal === 'plus_upgrade') { - sendMessage('ping', 'promo_modals_decline_plus_upgrade'); } this.props.actions.showNotification({ @@ -217,6 +220,10 @@ class Panel extends React.Component { }); }; + /** + * @private + * Handle clicks on sign in links in promo modals + */ _handlePromoSignInClick = () => { this.props.actions.togglePromoModal(); history.push({ @@ -224,25 +231,29 @@ class Panel extends React.Component { }); }; - _handlePromoSelectBasicClick = () => { + /** + * @private + * Handle clicks on the download button in the Premium promo modals + */ + _handlePromoTryMidnightClick = () => { this.props.actions.togglePromoModal(); - // we do not mark the choice-required initial plus promo as 'seen' until - // the user has clicked Select Basic or Select Plus - sendMessage('promoModals.sawPlusPromo', {}); - }; + // TODO detect OS and begin download of appropriate file + // TODO update with correct URL once it's available + const url = 'https://reddit.com'; + sendMessage('openNewTab', { + url, + become_active: true, + }); + } /** * @private - * Handle clicks on 'Select Plus' from the Plus Promo Modal (Choose Your Plan) + * Handle clicks on the 'Get Plus' option in the Premium modals */ - _handlePromoSelectPlusClick = () => { + _handlePromoGetPlusClick = () => { this.props.actions.togglePromoModal(); - // we do not mark the choice-required initial plus promo as 'seen' until - // the user has clicked Select Basic or Select Plus - sendMessage('promoModals.sawPlusPromo', {}); - const url = `https://checkout.${DOMAIN}.com/plus?utm_source=gbe&utm_campaign=in_app`; sendMessage('openNewTab', { url, @@ -271,6 +282,11 @@ class Panel extends React.Component { }); }; + /** + * @param modal 'insights' or 'premium' + * @private + * Handle clicks on the 'X' close icon in promo modals + */ _handlePromoXClick = (modal) => { this.props.actions.togglePromoModal(); @@ -279,12 +295,22 @@ class Panel extends React.Component { } }; + /** + * @returns {bool} + * @private + * Is the user an Insights subscriber? + */ _insightsSubscriber = () => { const { loggedIn, user } = this.props; return loggedIn && (user && user.scopes && user.scopes.includes('subscriptions:insights')); } + /** + * @returns {JSX} + * @private + * Renders the Premium promo modal + */ _renderPremiumPromoModal = () => { sendMessage('promoModals.sawPremiumPromo', {}); @@ -300,6 +326,11 @@ class Panel extends React.Component { ); } + /** + * @returns {null|JSX} + * @private + * Renders the Insights promo modal if the user is not already an Insights subscriber + */ _renderInsightsPromoModal = () => { if (this._insightsSubscriber()) return null; @@ -309,7 +340,7 @@ class Panel extends React.Component { return ( { const { promoModal, From e6c0166276fc9e733bc4fdc3068fdf9c1962ee3a Mon Sep 17 00:00:00 2001 From: wlycdgr Date: Wed, 11 Dec 2019 11:24:25 -0500 Subject: [PATCH 03/11] Premium modal logic working. Now for the copy and images. --- app/hub/Views/HomeView/HomeViewContainer.jsx | 9 ++--- app/panel/components/Panel.jsx | 3 ++ app/scss/hub.scss | 2 +- app/scss/panel.scss | 2 +- .../PremiumPromoModal/PremiumPromoModal.jsx | 7 ++++ manifest.json | 2 ++ src/classes/ConfData.js | 1 + src/classes/PromoModals.js | 34 +++++-------------- 8 files changed, 29 insertions(+), 31 deletions(-) diff --git a/app/hub/Views/HomeView/HomeViewContainer.jsx b/app/hub/Views/HomeView/HomeViewContainer.jsx index 5ed552331..4c8803a28 100644 --- a/app/hub/Views/HomeView/HomeViewContainer.jsx +++ b/app/hub/Views/HomeView/HomeViewContainer.jsx @@ -76,7 +76,7 @@ class HomeViewContainer extends Component { window.open(`https://checkout.${DOMAIN}.com/plus?utm_source=gbe&utm_campaign=intro_hub`, '_blank'); break; case 'premium': - window.open(`https://reddit.com`, '_blank'); + window.open('https://reddit.com', '_blank'); break; case 'basic': default: @@ -100,7 +100,7 @@ class HomeViewContainer extends Component { * @private * Function to handle clicks on the Midnight download button in the Premium promo modal */ - _handleTryMidnightClick = () => { this._handleTryMidnightClick('midnight'); } + _handleTryMidnightClick = () => { this._handlePremiumPromoModalClick('midnight'); } _render() { const { justInstalled } = this.state; @@ -127,8 +127,9 @@ class HomeViewContainer extends Component {
diff --git a/app/panel/components/Panel.jsx b/app/panel/components/Panel.jsx index a53468843..ad9e0c4b1 100644 --- a/app/panel/components/Panel.jsx +++ b/app/panel/components/Panel.jsx @@ -359,6 +359,9 @@ class Panel extends React.Component { isPromoModalHidden, } = this.props; + console.error(`promoModal: ${promoModal}`); + console.error(`isPromoModalHidden: ${isPromoModalHidden}`); + if (isPromoModalHidden) return null; if (promoModal === 'insights') { diff --git a/app/scss/hub.scss b/app/scss/hub.scss index a59365f96..9cc1a696b 100644 --- a/app/scss/hub.scss +++ b/app/scss/hub.scss @@ -76,7 +76,7 @@ html, body, #root { // Imports from ../shared-components directory @import '../shared-components/ExitButton/ExitButton.scss'; @import '../shared-components/Modal/Modal.scss'; -@import '../shared-components/PlusPromoModal/PlusPromoModal.scss'; +@import '../shared-components/PremiumPromoModal/PremiumPromoModal.scss'; @import '../shared-components/SteppedNavigation/SteppedNavigation.scss'; @import '../shared-components/ToastMessage/ToastMessage.scss'; @import '../shared-components/ToggleCheckbox/ToggleCheckbox.scss'; diff --git a/app/scss/panel.scss b/app/scss/panel.scss index 3f6596ed4..eaef66ef7 100644 --- a/app/scss/panel.scss +++ b/app/scss/panel.scss @@ -79,4 +79,4 @@ html body { // Imports from ../shared-components directory @import '../shared-components/Modal/Modal.scss'; -@import '../shared-components/PlusPromoModal/PlusPromoModal.scss'; +@import '../shared-components/PremiumPromoModal/PremiumPromoModal.scss'; diff --git a/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx index b395ba728..7e0f3a600 100644 --- a/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx +++ b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx @@ -29,6 +29,7 @@ const PremiumPromoModal = (props) => { handleGetPlusClick, handleKeepBasicClick, handleGoAwayClick, + handleXClick, } = props; const isInHub = location === 'hub'; @@ -153,6 +154,12 @@ const PremiumPromoModal = (props) => { {t('already_subscribed_sign_in')}
)} + {isInPanel && ( +
+ )} + {isInPanel && ( +
+ )}
diff --git a/manifest.json b/manifest.json index 3574f74d2..3ea4b2078 100644 --- a/manifest.json +++ b/manifest.json @@ -6,6 +6,8 @@ "strict_min_version": "52.0" } }, + "debug": true, + "log": true, "author": "Ghostery", "name": "__MSG_name__", "short_name": "Ghostery", diff --git a/src/classes/ConfData.js b/src/classes/ConfData.js index 050e302eb..22d73cba5 100644 --- a/src/classes/ConfData.js +++ b/src/classes/ConfData.js @@ -126,6 +126,7 @@ class ConfData { _initProperty('notify_upgrade_updates', true); _initProperty('paid_subscription', false); _initProperty('plus_promo_modal_last_seen', 0); + _initProperty('premium_promo_modal_last_seen', 0); _initProperty('rewards_accepted', false); _initProperty('rewards_opted_in', false); _initProperty('settings_last_imported', 0); diff --git a/src/classes/PromoModals.js b/src/classes/PromoModals.js index 507f6629d..f0079429f 100644 --- a/src/classes/PromoModals.js +++ b/src/classes/PromoModals.js @@ -16,7 +16,7 @@ import globals from './Globals'; import panelData from './PanelData'; const DAYS_BETWEEN_PROMOS = { - plus: globals.DEBUG ? 0.0005 : 30, // 40 seconds on staging + premium: globals.DEBUG ? 0.0005 : 30, // 40 seconds on staging insights: globals.DEBUG ? 0.0005 : 30 // 40 seconds on staging }; const WEEKLY_INSIGHTS_TARGET = globals.DEBUG ? 1 : 3; @@ -24,13 +24,11 @@ const DAILY_INSIGHTS_TARGET = globals.DEBUG ? 7 : 3; const MSECS_IN_DAY = 86400000; // 1000 msecs-in-sec * 60 secs-in-min * 60 mins-in-hour * 24 hours-in-day const PREMIUM = 'premium'; -const PLUS_INITIAL = 'plus_initial'; -const PLUS_UPGRADE = 'plus_upgrade'; const INSIGHTS = 'insights'; const PROMO_MODAL_LAST_SEEN = 'promo_modal_last_seen'; /** - * Static 'namespace' class for handling the business logic for the display of promo modals (Plus, Insights, etc...) + * Static 'namespace' class for handling the business logic for the display of promo modals (Premium, Insights, etc...) * @memberOf BackgroundClasses */ class PromoModals { @@ -41,14 +39,10 @@ class PromoModals { * @return {string} Type of promo to show */ static whichPromoModalShouldWeDisplay() { + // The order is important + // Insights takes priority over Premium if (this._isTimeForAPromo(INSIGHTS)) return INSIGHTS; - - if (this._isTimeForAPromo(PLUS)) { - if (this._haveSeenInitialPlusPromo()) return PLUS_UPGRADE; - - return PLUS_INITIAL; - } - + if (this._isTimeForAPromo(PREMIUM)) return PREMIUM; return null; } @@ -58,11 +52,6 @@ class PromoModals { static turnOffPromos() { panelData.set({ notify_promotions: false }); } - static _haveSeenInitialPlusPromo() { - const lastSeenTime = conf[`${PLUS}_${PROMO_MODAL_LAST_SEEN}`]; - return (lastSeenTime !== 0); - } - /** * Check Conf values to determine if the enough time has * passed for `type` modal to be displayed @@ -72,9 +61,9 @@ class PromoModals { static _isTimeForAPromo(type) { if (conf.notify_promotions === false) { return false; } - const lastSeenPlusPromo = conf[`${PLUS}_${PROMO_MODAL_LAST_SEEN}`]; + const lastSeenPremiumPromo = conf[`${PREMIUM}_${PROMO_MODAL_LAST_SEEN}`]; const lastSeenInsightsPromo = conf[`${INSIGHTS}_${PROMO_MODAL_LAST_SEEN}`]; - const lastSeenPromo = lastSeenPlusPromo > lastSeenInsightsPromo ? lastSeenPlusPromo : lastSeenInsightsPromo; + const lastSeenPromo = Math.max(lastSeenPremiumPromo, lastSeenInsightsPromo); if (type === INSIGHTS && !this._hasEngagedFrequently()) { return false; @@ -107,14 +96,9 @@ class PromoModals { static _hasEngagedFrequently() { const { engaged_daily_count } = conf.metrics || []; - let very_engaged_days = 0; - engaged_daily_count.forEach((count) => { - very_engaged_days = count >= DAILY_INSIGHTS_TARGET ? ++very_engaged_days : very_engaged_days; - }); - - if (very_engaged_days >= WEEKLY_INSIGHTS_TARGET) return true; + const very_engaged_days = engaged_daily_count.reduce((acc, count) => (count >= DAILY_INSIGHTS_TARGET ? acc++ : acc), 0); - return false; + return very_engaged_days >= WEEKLY_INSIGHTS_TARGET; } } From 7cf17c27677db30443c2b492013fd8f3d384a98f Mon Sep 17 00:00:00 2001 From: wlycdgr Date: Wed, 11 Dec 2019 15:54:22 -0500 Subject: [PATCH 04/11] Implementing Premium promo design and copy. WIP. --- app/images/panel/midnight-beta-icon.svg | 6 + app/images/panel/midnight-check-icon.svg | 9 ++ app/images/panel/midnight-logo.svg | 1 + .../PremiumPromoModal/PremiumPromoModal.jsx | 97 +++++---------- .../PremiumPromoModal/PremiumPromoModal.scss | 113 +++++++++++++----- 5 files changed, 130 insertions(+), 96 deletions(-) create mode 100644 app/images/panel/midnight-beta-icon.svg create mode 100644 app/images/panel/midnight-check-icon.svg create mode 100644 app/images/panel/midnight-logo.svg diff --git a/app/images/panel/midnight-beta-icon.svg b/app/images/panel/midnight-beta-icon.svg new file mode 100644 index 000000000..6621b5a68 --- /dev/null +++ b/app/images/panel/midnight-beta-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/images/panel/midnight-check-icon.svg b/app/images/panel/midnight-check-icon.svg new file mode 100644 index 000000000..ba6251149 --- /dev/null +++ b/app/images/panel/midnight-check-icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/app/images/panel/midnight-logo.svg b/app/images/panel/midnight-logo.svg new file mode 100644 index 000000000..28cba2896 --- /dev/null +++ b/app/images/panel/midnight-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx index 7e0f3a600..e509d1442 100644 --- a/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx +++ b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx @@ -35,109 +35,72 @@ const PremiumPromoModal = (props) => { const isInHub = location === 'hub'; const isInPanel = location === 'panel'; - const locationClassName = { - 'in-hub': isInHub, - 'in-panel': location === 'panel' - }; const contentClassNames = ClassNames( 'PremiumPromoModal__content', 'flex-container', 'flex-dir-column', 'align-middle', - 'initial', - locationClassName ); const optionsContainerClassNames = ClassNames( 'PremiumPromoModal__options-container', 'full-width', - locationClassName ); const optionsDecriptionClassNames = ClassNames( 'PremiumPromoModal__option-description-item', - locationClassName ); const chooseYourPlanClassNames = ClassNames( 'PremiumPromoModal__choose-your-plan', - locationClassName ); const recommendedBannerClassNames = ClassNames( 'PremiumPromoModal__recommended-banner', - locationClassName ); const optionDescriptionBoxClassNames = ClassNames( 'PremiumPromoModal__option-description-box', - locationClassName ); const buttonBackgroundClassNames = ClassNames( 'PremiumPromoModal__buttons-background', - 'initial', - locationClassName ); return (
-
- {isInHub && ( -
- {t('ghostery_is_ready')} -
- )} -
- {isInHub ? t('choose_your_privacy_plan') : t('choose_your_ghostery_privacy_plan')} +
+
+
+ Try Ghostery Midnight +
+
7 Day Free Trial ($14/mo)
+
+
+ Get full-coverage protection across all browsers & apps on your device
-
-
-
-
{t('ghostery_basic')}
-
- - 0 - - {t('per_month')} +
+
+
+ +
+ System-wide tracker & ad-blocking
-
-
{t('faster_cleaner_browsing')}
-
{t('blocks_ads')}
-
{t('blocks_trackers')}
-
{t('data_protection')}
+
+
+ +
+ Custom whitelist options
-
-
-
- -
{t('recommended')}
-
-
{t('ghostery_plus')}
-
- - {t('plus_monthly_subscription_price_number')} - - {t('per_month')} +
+
+ +
+ Built-in VPN
-
-
{t('all_basic_features_plus_COLON')}
-
-
- - {t('historical_tracker_stats')} -
-
-
-
- - {t('priority_support')} -
-
-
-
- - {t('new_color_themes')} -
-
+
+
+ +
+ Historical tracking insights
diff --git a/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss b/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss index deeda291f..58cc11278 100644 --- a/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss +++ b/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss @@ -15,16 +15,93 @@ $standard-font-family: Roboto, "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; -.PremiumPromoModal__gold-ghostie-badge { - margin-top: 21px; +.PremiumPromoModal__content { + z-index: 10; + width: 518px; + height: 437px; + border: solid 1.9px #720174; + background-color: #f7f7f7; +} + +.PremiumPromoModal__midnight-logo { + width: 177px; + height: 94px; + margin: 20px 0px 16px; + background-image: url('/app/images/panel/midnight-logo.svg'); } .PremiumPromoModal__header { - font-size: 20px; - font-weight: bold; - font-family: $standard-font-family; - padding: 0 15px; - text-align: center; + display: flex; + width: 100%; + justify-content: space-evenly; +} + +.PremiumPromoModal__header-text { + text-align: center; + font-size: 20px; + font-weight: bold; + font-family: $standard-font-family; +} + +.PremiumPromoModal__header-beta-icon { + float: right; + margin-left: 5px; + width: 20px; + height: 12px; + background-image: url('/app/images/panel/midnight-beta-icon.svg'); +} + +.PremiumPromoModal__sub-header { + margin: 9px 0px 12px; + width: 438px; + text-align: center; + font-size: 18px; + font-weight: 500; + line-height: 1.5; + color: #4A4A4A; +} + +.PremiumPromoModal__features-container { + display: flex; + width: 100%; + margin-bottom: 12px; +} + +.PremiumPromoModal__feature-column { + &:nth-child(odd) { + margin-left: 20px; + width: 55%; + } + &:nth-child(even) { + margin-left: -12px; + margin-right: 25px; + width: 45%; + } +} + +.PremiumPromoModal__feature { + display: flex; + align-items: center; + &:nth-child(1) { + margin-bottom: 20px; + } +} + +.PremiumPromoModal__feature-text { + font-family: $standard-font-family; + font-size: 14px; + color: $medium-gray; + padding-bottom: 5px; + line-height: 16px; +} + +.PremiumPromoModal__checked-circle-icon { + flex: none; + height: 18px; + width: 18px; + margin-right: 8px; + background-image: url('/app/images/panel/midnight-check-icon.svg'); + align-self: flex-start; } .PremiumPromoModal__description { @@ -35,28 +112,6 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti font-family: $standard-font-family } -.PremiumPromoModal__content { - position: relative; - background-color: #f7f7f7; - border: 1.9px solid #930194; - justify-content: space-between; - z-index: 10; - &.initial { - &.in-hub { - width: 646px; - height: 553px; - } - &.in-panel { - width: 556px; - height: 471px; - } - } - &.upgrade { - width: 475px; - min-height: 425px; - } -} - .PremiumPromoModal__buttons-background { background-color: #e7ecee; margin-bottom: 3px; From f52574e73b10ac75c1bc83e121d400675b90e607 Mon Sep 17 00:00:00 2001 From: wlycdgr Date: Wed, 11 Dec 2019 16:22:25 -0500 Subject: [PATCH 05/11] Add X icon to panel version of Premium promo modal --- .../components/PlusUpgradePromoModal.jsx | 80 +++++++++++++++++++ .../PremiumPromoModal/PremiumPromoModal.jsx | 4 + .../PremiumPromoModal/PremiumPromoModal.scss | 1 + 3 files changed, 85 insertions(+) diff --git a/app/panel/components/PlusUpgradePromoModal.jsx b/app/panel/components/PlusUpgradePromoModal.jsx index 8b1378917..e4e5fd456 100644 --- a/app/panel/components/PlusUpgradePromoModal.jsx +++ b/app/panel/components/PlusUpgradePromoModal.jsx @@ -1 +1,81 @@ +/** + * Plus Upgrade Promo Modal Component + * + * Ghostery Browser Extension + * https://www.ghostery.com/ + * + * Copyright 2019 Ghostery, Inc. All rights reserved. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0 + */ +import React from 'react'; +import ClassNames from 'classnames'; +import Modal from '../../shared-components/Modal'; +import ModalExitButton from './BuildingBlocks/ModalExitButton'; + +const PLUS_UPGRADE = 'plus_upgrade'; + +/** + * @class Implements the Upgrade variant of the Plus Promo Modal + * @memberof PanelClasses + */ +class PlusUpgradePromoModal extends React.Component { + handleNoThanksClick = () => { this.props.handleNoThanksClick(PLUS_UPGRADE); } + + handleSubscribeClick = () => { this.props.handleSubscribeClick(PLUS_UPGRADE); } + + handleXClick = () => { this.props.handleXClick(PLUS_UPGRADE); } + + render() { + const { loggedIn } = this.props; + + const contentClassNames = ClassNames( + 'PlusPromoModal__content', + 'flex-container', + 'flex-dir-column', + 'align-middle', + 'panel', + 'upgrade' + ); + + // TODO update ModalExitButton class here + // TODO pass down handler for click on ModalExitButton + return ( + +
+ + +
+ {t('upgrade_your_ghostery_experience')} +
+
+
+
+ + {t('upgrade_to_plus')} + +
+
+ { + !loggedIn && + ( +
+ {t('already_subscribed_sign_in')} +
+ ) + } +
+ {t('no_thanks_turn_promos_off')} +
+
+
+
+ + ); + } +} + +export default PlusUpgradePromoModal; diff --git a/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx index e509d1442..466053446 100644 --- a/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx +++ b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx @@ -15,6 +15,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import ClassNames from 'classnames'; import Modal from '../Modal/Modal'; +import ModalExitButton from '../../panel/components/BuildingBlocks/ModalExitButton'; /** * A functional React component for a Premium Promo Modal that may be displayed in the Hub and/or Panel @@ -64,6 +65,9 @@ const PremiumPromoModal = (props) => { return (
+ {isInPanel && ( + + )}
diff --git a/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss b/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss index 58cc11278..1a9d5fbd5 100644 --- a/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss +++ b/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss @@ -16,6 +16,7 @@ $standard-font-family: Roboto, "Open Sans", "Helvetica Neue", Helvetica, Arial, $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; .PremiumPromoModal__content { + position: relative; z-index: 10; width: 518px; height: 437px; From 0eacbff8ebfab933fd37e7eaca5fd8fd0f527e33 Mon Sep 17 00:00:00 2001 From: wlycdgr Date: Wed, 11 Dec 2019 18:37:50 -0500 Subject: [PATCH 06/11] Premium promo designs complete --- app/hub/Views/HomeView/HomeViewContainer.jsx | 4 +- app/panel/components/Panel.jsx | 4 +- .../PremiumPromoModal/PremiumPromoModal.jsx | 42 +-- .../PremiumPromoModal/PremiumPromoModal.scss | 274 ++---------------- 4 files changed, 56 insertions(+), 268 deletions(-) diff --git a/app/hub/Views/HomeView/HomeViewContainer.jsx b/app/hub/Views/HomeView/HomeViewContainer.jsx index 4c8803a28..45c933b20 100644 --- a/app/hub/Views/HomeView/HomeViewContainer.jsx +++ b/app/hub/Views/HomeView/HomeViewContainer.jsx @@ -76,7 +76,7 @@ class HomeViewContainer extends Component { window.open(`https://checkout.${DOMAIN}.com/plus?utm_source=gbe&utm_campaign=intro_hub`, '_blank'); break; case 'premium': - window.open('https://reddit.com', '_blank'); + window.open('https://ghostery.com/thanks-for-downloading-midnight', '_blank'); break; case 'basic': default: @@ -100,7 +100,7 @@ class HomeViewContainer extends Component { * @private * Function to handle clicks on the Midnight download button in the Premium promo modal */ - _handleTryMidnightClick = () => { this._handlePremiumPromoModalClick('midnight'); } + _handleTryMidnightClick = () => { this._handlePremiumPromoModalClick('premium'); } _render() { const { justInstalled } = this.state; diff --git a/app/panel/components/Panel.jsx b/app/panel/components/Panel.jsx index ad9e0c4b1..97e67e271 100644 --- a/app/panel/components/Panel.jsx +++ b/app/panel/components/Panel.jsx @@ -238,9 +238,7 @@ class Panel extends React.Component { _handlePromoTryMidnightClick = () => { this.props.actions.togglePromoModal(); - // TODO detect OS and begin download of appropriate file - // TODO update with correct URL once it's available - const url = 'https://reddit.com'; + const url = 'https://ghostery.com/thanks-for-downloading-midnight'; sendMessage('openNewTab', { url, become_active: true, diff --git a/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx index 466053446..cd79539e7 100644 --- a/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx +++ b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx @@ -58,9 +58,6 @@ const PremiumPromoModal = (props) => { const optionDescriptionBoxClassNames = ClassNames( 'PremiumPromoModal__option-description-box', ); - const buttonBackgroundClassNames = ClassNames( - 'PremiumPromoModal__buttons-background', - ); return ( @@ -90,7 +87,7 @@ const PremiumPromoModal = (props) => {
- Custom whitelist options + Built-in VPN
@@ -98,7 +95,7 @@ const PremiumPromoModal = (props) => {
- Built-in VPN + Custom whitelist options
@@ -109,24 +106,27 @@ const PremiumPromoModal = (props) => {
-
-
- {t('select_basic')} -
-
- {t('select_plus')} +
+
+
+ Download For Free +
- {isInPanel && ( -
- {t('already_subscribed_sign_in')} +
+
+ Support Ghostery for $2/mo instead
- )} - {isInPanel && ( -
- )} - {isInPanel && ( -
- )} + {isInHub && ( +
+ No thanks, continue with basic +
+ )} + {isInPanel && ( +
+ No thanks, turn promos off +
+ )} +
diff --git a/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss b/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss index 1a9d5fbd5..f8258d80c 100644 --- a/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss +++ b/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss @@ -26,8 +26,8 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti .PremiumPromoModal__midnight-logo { width: 177px; - height: 94px; - margin: 20px 0px 16px; + height: 106px; + margin: 22px 0px 16px; background-image: url('/app/images/panel/midnight-logo.svg'); } @@ -53,11 +53,11 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti } .PremiumPromoModal__sub-header { - margin: 9px 0px 12px; + margin: 9px 0px 22px; width: 438px; text-align: center; font-size: 18px; - font-weight: 500; + font-weight: bold; line-height: 1.5; color: #4A4A4A; } @@ -65,7 +65,7 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti .PremiumPromoModal__features-container { display: flex; width: 100%; - margin-bottom: 12px; + margin-bottom: 28px; } .PremiumPromoModal__feature-column { @@ -105,272 +105,62 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti align-self: flex-start; } -.PremiumPromoModal__description { - width: 350px; - text-align: center; - font-size: 18px; - font-weight: 500; - font-family: $standard-font-family -} - .PremiumPromoModal__buttons-background { background-color: #e7ecee; margin-bottom: 3px; width: 99%; - height: 72px; + height: 107px; z-index: -1; display: flex; - &.initial { - height: 72px; - flex-direction: row; - justify-content: space-around; - align-items: center; - &.in-panel { - height: 80px; - flex-wrap: wrap; - align-content: center; - } - } - &.upgrade { - height: 95px; - flex-direction: column; - justify-content: center; - } -} - -.PremiumPromoModal__thanks-for-download { - padding-top: 30px; - font-size: 26px; - font-weight: bold; - text-align: center; -} - -.PremiumPromoModal__choose-your-plan { - font-size: 18px; - font-weight: bold; - font-family: $standard-font-family; - color: #4a4a4a; - text-align: center; - &.in-hub {margin-top: 10px;} - &.in-panel { - margin-bottom: 10px; - padding-top: 17px; - } -} - -.PremiumPromoModal__options-container { - display: flex; - justify-content: space-around; - &.in-hub {} - &.in-panel {} -} - -.PremiumPromoModal__option-container { - display: flex; - align-items: center; flex-direction: column; -} - -.PremiumPromoModal__option-description-box { - border-style: solid; - border-width: 3px; - background-color: #FFFFFF; - padding: 0 15px; - - &.basic { - border-color: #1dafed; - } - - &.plus { - position: relative; // so that the recommended banner is positioned relative to this element - border-image-source: linear-gradient(39deg, #f2daa2, #eab968); - border-image-slice: 1; - } - - &.in-hub { - width: 240px; - flex: 1; - min-height: 275px; - } - - &.in-panel { - width: 221px; - flex: 1; - min-height: 250px; - } -} - -.PremiumPromoModal__recommended-banner { - position: absolute; - font-family: $standard-font-family; - - &.in-hub { - left: -30px; - top: -30px; - } - - &.in-panel { - left: -30px; - top: -32px; - } -} - -.PremiumPromoModal__recommended-banner-text { - position: relative; - left: 15px; - top: -47px; - transform: rotate(-15deg); - color: white; - font-size: 16px; - font-weight: bold; -} - -.PremiumPromoModal__option-header { - margin-top: 20px; - font-family: $condensed-font-family; - font-size: 19px; - font-weight: bold; - text-align: center; - - &.basic { color: #1dafed; } - &.plus { color: #ebbf73; } -} - -.PremiumPromoModal__price-text { - line-height: 1.3; - text-align: center; - - &.basic { color: #1dafed; } - &.plus { color: #ebbf73; } -} - -.PremiumPromoModal__currency-sign { - font-family: $condensed-font-family; - font-size: 30px; - font-weight: bold; -} - -.PremiumPromoModal__amount { - vertical-align: middle; - font-family: $standard-font-family; - font-size: 58px; - font-weight: normal; -} - -.PremiumPromoModal__per-month { - vertical-align: sub; - font-family: $condensed-font-family; - font-size: 18px; - font-weight: bold; -} - -.PremiumPromoModal__option-description-item { - padding-bottom: 15px; - text-align: center; - font-family: $standard-font-family; - font-size: 16px; - color: #333333; - line-height: 16px; - &.in-panel { - padding-bottom: 10px; - font-size: 15px; - } - &.italic { - font-style: italic; - } -} - -.PremiumPromoModal__check-icon { - padding-right: 10px; -} - -.PremiumPromoModal__plus-option-description-item-container { - display: flex; - justify-content: center; + justify-content: space-evenly } .PremiumPromoModal__button-container { - display: flex; - margin-bottom: 10px; - align-self: center; + display: flex; + justify-content: center; } -.PremiumPromoModal__button { - cursor: pointer; - display: flex; - justify-content: center; - align-items: center; - border-radius: 3px; - font-weight: bold; - font-family: $condensed-font-family; - letter-spacing: 0.5px; - text-transform: uppercase; - cursor: pointer; - transition: background-color 0.25s ease-out, color 0.25s ease-out; - -webkit-appearance: none; +.PremiumPromoModal__download-button { + width: 196px; + height: 36px; + border-radius: 2px; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.24), 0 0 2px 0 rgba(0, 0, 0, 0.12); + background-image: linear-gradient(101deg, #720174 19%, #00aef0 100%); - &.basic { - height: 40px; - font-size: 14px; - border: solid 2px #15b4f2; - background-color: white; - color: #2cbcf4; - box-shadow: none; - } - &.basic:hover { - background-color: #2cbcf4; - color: white; - } + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; - &.plus { - font-size: 14px; - height: 38px; - border: none; - background-image: linear-gradient(to bottom, #2fdbfa, #15b4f2); - color: white; - box-shadow: none; - } - &.plus:hover { - background-image: linear-gradient(to bottom, #1fcbea, #05a4e2); - } + font-family: $condensed-font-family; + font-size: 14px; + font-weight: bold; + letter-spacing: 0.5px; + text-align: center; + color: #ffffff; - &.upgrade { - font-size: 13px; - height: 36px; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.24), 0 0 2px 0 rgba(0, 0, 0, 0.12); - background-color: #1dafed; - color: white; - } - &.upgrade:hover { - background-color: #0698d6; - } + transition: background-color 0.25s ease-out, color 0.25s ease-out; - .side-padded { - padding: 0px 20px 0px; // more localization-proof than hardcoding width - } + &:hover { + background-image: linear-gradient(101deg, #A80AAB 19%, #41BCEA 100%); + } - .button-text { - color: white; - text-decoration: none; - } + text-transform: uppercase; } .PremiumPromoModal__text-link-container { display: flex; - justify-content: space-evenly; + justify-content: space-between; } .PremiumPromoModal__text-link { margin-left: 10px; margin-right: 10px; - font-size: 13px; + font-size: 15px; font-family: $standard-font-family; color: #4a4a4a; text-decoration: underline; text-align: center; cursor: pointer; - &.sign-in { - margin-top: 5px; - width: 100%; - } } From 38e319ce81417d85ae2a0ed8139de9bcb4cc1ded Mon Sep 17 00:00:00 2001 From: wlycdgr Date: Wed, 11 Dec 2019 18:41:50 -0500 Subject: [PATCH 07/11] Remove PlusUpgradePromoModal component --- .../components/PlusUpgradePromoModal.jsx | 81 ------------------- 1 file changed, 81 deletions(-) delete mode 100644 app/panel/components/PlusUpgradePromoModal.jsx diff --git a/app/panel/components/PlusUpgradePromoModal.jsx b/app/panel/components/PlusUpgradePromoModal.jsx deleted file mode 100644 index e4e5fd456..000000000 --- a/app/panel/components/PlusUpgradePromoModal.jsx +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Plus Upgrade Promo Modal Component - * - * Ghostery Browser Extension - * https://www.ghostery.com/ - * - * Copyright 2019 Ghostery, Inc. All rights reserved. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0 - */ - -import React from 'react'; -import ClassNames from 'classnames'; -import Modal from '../../shared-components/Modal'; -import ModalExitButton from './BuildingBlocks/ModalExitButton'; - -const PLUS_UPGRADE = 'plus_upgrade'; - -/** - * @class Implements the Upgrade variant of the Plus Promo Modal - * @memberof PanelClasses - */ -class PlusUpgradePromoModal extends React.Component { - handleNoThanksClick = () => { this.props.handleNoThanksClick(PLUS_UPGRADE); } - - handleSubscribeClick = () => { this.props.handleSubscribeClick(PLUS_UPGRADE); } - - handleXClick = () => { this.props.handleXClick(PLUS_UPGRADE); } - - render() { - const { loggedIn } = this.props; - - const contentClassNames = ClassNames( - 'PlusPromoModal__content', - 'flex-container', - 'flex-dir-column', - 'align-middle', - 'panel', - 'upgrade' - ); - - // TODO update ModalExitButton class here - // TODO pass down handler for click on ModalExitButton - return ( - -
- - -
- {t('upgrade_your_ghostery_experience')} -
-
-
-
- - {t('upgrade_to_plus')} - -
-
- { - !loggedIn && - ( -
- {t('already_subscribed_sign_in')} -
- ) - } -
- {t('no_thanks_turn_promos_off')} -
-
-
-
- - ); - } -} - -export default PlusUpgradePromoModal; From 7483ca221ea45ed0ec5ca8b95c53917b44cb93da Mon Sep 17 00:00:00 2001 From: wlycdgr Date: Wed, 11 Dec 2019 18:59:39 -0500 Subject: [PATCH 08/11] Cleanup PremiumPromoModal component. Add locale strings. --- _locales/en/messages.json | 35 +++++++++++++++++ .../PremiumPromoModal/PremiumPromoModal.jsx | 38 ++++++------------- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index ac933fcdd..8b51e6331 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -2345,5 +2345,40 @@ }, "settings": { "message": "Settings" + }, + "try_ghostery_midnight": { + "message": "Try Ghostery Midnight" + }, + "seven_day_free_trial": { + "message": "7 Day Free Trial ($$14/mo)", + "description": "Do not localize currency. Use the $14 USD amount. The second $ is needed to escape the special meaning of $" + }, + "full_coverage_protection_promise": { + "message": "Get full-coverage protection across all browsers & apps on your device" + }, + "system_wide_tracker_and_ad_blocking": { + "message": "System-wide tracker & ad-blocking" + }, + "built_in_vpn": { + "message": "Built-in VPN" + }, + "custom_whitelist_options": { + "message": "Custom whitelist options" + }, + "historical_tracking_insights": { + "message": "Historical tracking insights" + }, + "download_for_free": { + "message": "Download for free" + }, + "support_ghostery_for_2_instead": { + "message": "Support Ghostery for $$2/mo instead", + "description": "Do not localize currency. Use the $2 USD amount. The second $ is needed to escape the special meaning of $" + }, + "no_thanks_continue_with_basic": { + "message": "No thanks, continue with basic" + }, + "no_thanks_turn_promos_off": { + "message": "No thanks, turn promos off" } } diff --git a/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx index cd79539e7..d7163fb3c 100644 --- a/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx +++ b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx @@ -42,22 +42,6 @@ const PremiumPromoModal = (props) => { 'flex-dir-column', 'align-middle', ); - const optionsContainerClassNames = ClassNames( - 'PremiumPromoModal__options-container', - 'full-width', - ); - const optionsDecriptionClassNames = ClassNames( - 'PremiumPromoModal__option-description-item', - ); - const chooseYourPlanClassNames = ClassNames( - 'PremiumPromoModal__choose-your-plan', - ); - const recommendedBannerClassNames = ClassNames( - 'PremiumPromoModal__recommended-banner', - ); - const optionDescriptionBoxClassNames = ClassNames( - 'PremiumPromoModal__option-description-box', - ); return ( @@ -68,26 +52,26 @@ const PremiumPromoModal = (props) => {
- Try Ghostery Midnight + {t('try_ghostery_midnight')}
-
7 Day Free Trial ($14/mo)
+
{t('seven_day_free_trial')}
- Get full-coverage protection across all browsers & apps on your device + {t('full_coverage_protection_promise')}
- System-wide tracker & ad-blocking + {t('system_wide_tracker_and_ad_blocking')}
- Built-in VPN + {t('built_in_vpn')}
@@ -95,13 +79,13 @@ const PremiumPromoModal = (props) => {
- Custom whitelist options + {t('custom_whitelist_options')}
- Historical tracking insights + {t('historical_tracking_insights')}
@@ -109,21 +93,21 @@ const PremiumPromoModal = (props) => {
- Download For Free + {t('download_for_free')}
- Support Ghostery for $2/mo instead + {t('support_ghostery_for_2_instead')}
{isInHub && (
- No thanks, continue with basic + {t('no_thanks_continue_with_basic')}
)} {isInPanel && (
- No thanks, turn promos off + {t('no_thanks_turn_promos_off')}
)}
From f9cdd94a3cc0d9eb6a191b6b56b0b98d6487cbfa Mon Sep 17 00:00:00 2001 From: wlycdgr Date: Thu, 12 Dec 2019 09:48:58 -0500 Subject: [PATCH 09/11] Remove console logs from Panel --- app/panel/components/Panel.jsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/panel/components/Panel.jsx b/app/panel/components/Panel.jsx index 97e67e271..a104c3e1c 100644 --- a/app/panel/components/Panel.jsx +++ b/app/panel/components/Panel.jsx @@ -357,9 +357,6 @@ class Panel extends React.Component { isPromoModalHidden, } = this.props; - console.error(`promoModal: ${promoModal}`); - console.error(`isPromoModalHidden: ${isPromoModalHidden}`); - if (isPromoModalHidden) return null; if (promoModal === 'insights') { From 5377733042c86d099977df6f18c43e4462c1f20e Mon Sep 17 00:00:00 2001 From: wlycdgr Date: Thu, 12 Dec 2019 10:15:17 -0500 Subject: [PATCH 10/11] Do not show Premium promo to Premium subscribers --- app/hub/Views/HomeView/HomeViewContainer.jsx | 15 ++++++++++++++- app/panel/components/Panel.jsx | 13 +++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/app/hub/Views/HomeView/HomeViewContainer.jsx b/app/hub/Views/HomeView/HomeViewContainer.jsx index 45c933b20..f7ee124e5 100644 --- a/app/hub/Views/HomeView/HomeViewContainer.jsx +++ b/app/hub/Views/HomeView/HomeViewContainer.jsx @@ -102,6 +102,17 @@ class HomeViewContainer extends Component { */ _handleTryMidnightClick = () => { this._handlePremiumPromoModalClick('premium'); } + /** + * @returns {bool} + * @private + * Is the user a Premium subscriber? + */ + _premiumSubscriber = () => { + const { loggedIn, user } = this.props; + + return loggedIn && (user && user.scopes && user.scopes.includes('subscriptions:premium')); + } + _render() { const { justInstalled } = this.state; const { home, user } = this.props; @@ -122,10 +133,12 @@ class HomeViewContainer extends Component { isPlus, }; + const showPromoModal = !premium_promo_modal_shown && !this._premiumSubscriber(); + return (
{ + const { loggedIn, user } = this.props; + + return loggedIn && (user && user.scopes && user.scopes.includes('subscriptions:premium')); + } + /** * @returns {JSX} * @private * Renders the Premium promo modal */ _renderPremiumPromoModal = () => { + if (this._premiumSubscriber()) return null; + sendMessage('promoModals.sawPremiumPromo', {}); return ( From 1fe414b75528889ae348fe57e605296547df3cf4 Mon Sep 17 00:00:00 2001 From: wlycdgr Date: Thu, 12 Dec 2019 10:22:15 -0500 Subject: [PATCH 11/11] Remove debug log from manifest --- manifest.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/manifest.json b/manifest.json index 3ea4b2078..3574f74d2 100644 --- a/manifest.json +++ b/manifest.json @@ -6,8 +6,6 @@ "strict_min_version": "52.0" } }, - "debug": true, - "log": true, "author": "Ghostery", "name": "__MSG_name__", "short_name": "Ghostery",