Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-1895 and GH-1896: Midnight promos #485

Merged
merged 12 commits into from Dec 12, 2019
@@ -2348,5 +2348,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"
}
}
@@ -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,
};
}
@@ -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';
@@ -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,65 @@ 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://ghostery.com/thanks-for-downloading-midnight', '_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'); }

/**
* @private
* Function to handle clicks on the Midnight download button in the Premium promo modal
*/
_handleTryMidnightClick = () => { this._handlePremiumPromoModalClick('premium'); }

/**
* @returns {bool}
* @private
* Is the user a Premium subscriber?
*/
_premiumSubscriber = () => {
const { loggedIn, user } = this.props;

window.open(`https://checkout.${DOMAIN}.com/plus?utm_source=gbe&utm_campaign=intro_hub`, '_blank');
return loggedIn && (user && user.scopes && user.scopes.includes('subscriptions:premium'));
}

_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 +133,16 @@ class HomeViewContainer extends Component {
isPlus,
};

const showPromoModal = !isPlus && !plus_promo_modal_shown;
const showPromoModal = !premium_promo_modal_shown && !this._premiumSubscriber();

return (
<div className="full-height">
<PlusPromoModal
<PremiumPromoModal
show={showPromoModal}
location="hub"
handleSelectBasicClick={this._handlePromoSelectBasicClick}
handleSelectPlusClick={this._handlePromoSelectPlusClick}
handleKeepBasicClick={this._handleKeepBasicClick}
handleGetPlusClick={this._handleGetPlusClick}
handleTryMidnightClick={this._handleTryMidnightClick}
/>
<HomeView {...childProps} />
</div>
@@ -137,7 +165,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 +176,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 +185,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,
},
@@ -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,
})
});
}
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="12" viewBox="0 0 20 12">
<g fill="none" fill-rule="evenodd">
<path fill="#4A4A4A" fill-rule="nonzero" d="M3.459 3.1v1.942h.457c.22 0 .391-.056.515-.168.124-.112.186-.315.186-.609v-.41c0-.266-.048-.458-.143-.577-.096-.12-.247-.179-.452-.179h-.563zm0 2.993V8.35h.67c.198 0 .348-.053.45-.158.104-.105.155-.294.155-.567v-.64c0-.344-.059-.578-.175-.704-.117-.126-.31-.19-.58-.19h-.52zm.595-4.044c.609 0 1.05.14 1.323.42.272.28.409.704.409 1.271v.263c0 .378-.06.69-.18.934-.121.246-.313.428-.575.547.32.119.544.313.675.583.131.27.197.6.197.992v.599c0 .567-.15 1-.447 1.297-.297.298-.74.446-1.328.446H2.29V2.05h1.764zm3.719 3.098h1.604v1.05H7.773v2.154H9.79v1.05H6.604V2.05H9.79v1.05H7.773v2.048zm2.422-3.098h3.613v1.05h-1.222v6.302h-1.169V3.1h-1.222V2.05zm4.856 5.02h1.126l-.563-3.718-.563 3.719zm2.667 2.332h-1.18l-.201-1.334h-1.435L14.7 9.401h-1.073l1.19-7.352h1.71l1.19 7.352z"/>
<rect width="18.923" height="10.486" x=".482" y=".482" stroke="#4A4A4A" stroke-width=".964" rx=".771"/>
</g>
</svg>
@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
<defs>
<linearGradient id="a" x1="19.758%" y1="8.241%" y2="92.098%">
<stop offset="0%" stop-color="#720174"/>
<stop offset="100%" stop-color="#00AEF0"/>
</linearGradient>
</defs>
<path fill="url(#a)" fill-rule="evenodd" d="M297 257a9 9 0 1 1 0 18 9 9 0 0 1 0-18zm3.345 5.529l-4.188 4.665-2.665-2.09-.925 1.2 3.77 2.956 5.125-5.714-1.117-1.017z" transform="translate(-288 -257)"/>
</svg>
@@ -0,0 +1 @@
<svg height="94" viewBox="0 0 177 94" width="177" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#720174"/><stop offset="1" stop-color="#00aef0"/></linearGradient><linearGradient id="b" x1="19.758%" xlink:href="#a" y1="8.457%" y2="91.88%"/><linearGradient id="c" x1="19.758%" xlink:href="#a" y1="38.205%" y2="61.891%"/><linearGradient id="d" x1="19.758%" xlink:href="#a" y1="29.122%" y2="71.048%"/><linearGradient id="e" x1="21.008%" x2="97.932%" xlink:href="#a" y1="8.241%" y2="92.098%"/><linearGradient id="f" x1="26.239%" x2="89.284%" xlink:href="#a" y1="8.241%" y2="92.098%"/><g fill="none" fill-rule="evenodd"><path d="m137.254 85.351-.647.646.647.647a.5.5 0 1 1 -.708.706l-.647-.646-.647.646a.5.5 0 1 1 -.707-.706l.647-.647-.647-.646a.5.5 0 0 1 .707-.707l.647.647.647-.647a.5.5 0 0 1 .708.707z" fill="url(#b)"/><g fill-rule="nonzero"><path d="m158.953 46.619a.501.501 0 1 0 0-1.003 5.019 5.019 0 0 1 -5.013-5.013.501.501 0 0 0 -1.002 0 5.019 5.019 0 0 1 -4.977 5.013h-.036a.501.501 0 1 0 0 1.003 5.019 5.019 0 0 1 5.013 5.012.501.501 0 0 0 1.002 0 5.019 5.019 0 0 1 4.977-5.012zm-5.411 2.711a6.053 6.053 0 0 0 -3.11-3.11c1.39-.61 2.5-1.72 3.11-3.11.61 1.39 1.72 2.5 3.11 3.11-1.39.61-2.5 1.72-3.11 3.11zm-134.736 34.322a8.66 8.66 0 0 1 -8.651-8.65.501.501 0 0 0 -1.003 0 8.66 8.66 0 0 1 -8.65 8.65.501.501 0 1 0 0 1.002 8.66 8.66 0 0 1 8.65 8.65.501.501 0 0 0 1.003 0 8.66 8.66 0 0 1 8.65-8.65.501.501 0 1 0 0-1.002zm-9.218 6.515a9.698 9.698 0 0 0 -6.079-6.08 9.698 9.698 0 0 0 6.08-6.078 9.698 9.698 0 0 0 6.079 6.079 9.698 9.698 0 0 0 -6.08 6.079zm109.262-71.167v2.005h2.006a.501.501 0 1 1 0 1.003h-2.006v2.005a.501.501 0 0 1 -1.002 0v-2.005h-2.005a.501.501 0 1 1 0-1.003h2.005v-2.005a.501.501 0 0 1 1.002 0zm-74.543.694 1.15-1.15-1.15-1.15a.501.501 0 0 1 .709-.708l1.15 1.15 1.149-1.15a.501.501 0 0 1 .709.709l-1.15 1.15 1.15 1.149a.501.501 0 1 1 -.71.708l-1.149-1.149-1.15 1.15a.501.501 0 1 1 -.708-.71zm-41.4 43.317-.649.648.649.648a.501.501 0 1 1 -.71.709l-.647-.648-.649.648a.501.501 0 1 1 -.708-.709l.648-.648-.648-.648a.501.501 0 0 1 .708-.709l.649.648.648-.648a.501.501 0 0 1 .709.709zm173.449 16.04-.648.649.648.648a.501.501 0 1 1 -.709.709l-.648-.648-.648.648a.501.501 0 1 1 -.709-.709l.648-.648-.648-.648a.501.501 0 0 1 .709-.71l.648.65.648-.65a.501.501 0 0 1 .709.71zm-133.053 9.309-.648-.648-.648.648a.501.501 0 1 1 -.709-.71l.648-.647-.648-.648a.501.501 0 0 1 .709-.71l.648.649.648-.648a.501.501 0 0 1 .71.709l-.649.648.648.648a.501.501 0 1 1 -.709.709zm-34.74-52.77v4.01h4.011a.501.501 0 1 1 0 1.002h-4.01v4.01a.501.501 0 0 1 -1.003 0v-4.01h-4.01a.501.501 0 1 1 0-1.002h4.01v-4.01a.501.501 0 0 1 1.003 0zm133.347-32.582a.501.501 0 0 1 -.501.5h-2.005v2.006a.501.501 0 0 1 -1.003 0v-2.005h-2.005a.501.501 0 1 1 0-1.003h2.005v-2.005a.501.501 0 0 1 1.003 0v2.005h2.005a.501.501 0 0 1 .501.502z" fill="url(#c)"/><path d="m106.777 18.884h-21.034c-.204-1.486-.618-2.95-1.525-4.232-1.665-2.36-4.367-3.31-6.752-4.148-1.435-.504-2.79-.981-3.704-1.666-.893-.67-1.739-1.841-2.636-3.08-1.515-2.097-3.231-4.472-5.959-5.385-2.626-.878-5.319-.026-7.693.727-1.486.47-2.889.915-4.085.915-1.194 0-2.598-.444-4.084-.915-2.375-.753-5.07-1.605-7.693-.728-2.729.914-4.448 3.29-5.963 5.387-.894 1.238-1.74 2.408-2.632 3.078-.914.685-2.269 1.162-3.704 1.666-2.384.837-5.088 1.788-6.752 4.146-.907 1.283-1.32 2.748-1.525 4.233h-21.036l6.872 18.868-6.872 18.865h21.035c.203 1.486.618 2.949 1.523 4.233 1.666 2.359 4.369 3.309 6.752 4.147 1.436.505 2.792.98 3.705 1.666.891.67 1.737 1.84 2.633 3.079 1.515 2.096 3.234 4.473 5.963 5.387 2.62.877 5.316.024 7.693-.727 1.486-.47 2.888-.915 4.084-.915s2.599.444 4.085.915c1.659.526 3.472 1.1 5.308 1.1.794 0 1.592-.108 2.384-.373 2.728-.913 4.445-3.288 5.96-5.385.896-1.239 1.742-2.41 2.636-3.08.914-.685 2.269-1.162 3.704-1.666 2.385-.838 5.088-1.788 6.752-4.148.907-1.284 1.32-2.747 1.523-4.232h21.037l-6.872-18.866zm-99.904 32.823 5.085-13.957-5.085-13.957h13.919c-.036 1.087-.118 2.094-.375 2.911-.33 1.049-1.136 2.22-1.987 3.46-1.476 2.145-3.15 4.58-3.15 7.586 0 3.008 1.674 5.44 3.15 7.586.851 1.24 1.657 2.411 1.987 3.46.257.817.34 1.824.375 2.911h-13.92zm77.592-9.21c-1.021 1.487-2.079 3.023-2.633 4.783-.577 1.834-.607 3.766-.637 5.637-.032 2.038-.063 3.963-.825 5.044-.779 1.104-2.557 1.729-4.439 2.39-1.708.601-3.474 1.221-4.97 2.344-1.477 1.108-2.582 2.638-3.651 4.115-1.197 1.655-2.327 3.218-3.615 3.65-1.195.398-2.96-.16-4.823-.75-1.757-.557-3.574-1.132-5.484-1.132-1.909 0-3.726.575-5.482 1.131-1.869.591-3.632 1.151-4.826.75-1.286-.43-2.418-1.995-3.617-3.651-1.067-1.478-2.172-3.006-3.648-4.113-1.496-1.123-3.262-1.743-4.97-2.343-1.882-.662-3.66-1.287-4.44-2.39-.763-1.083-.793-3.009-.825-5.046-.028-1.87-.06-3.802-.636-5.635-.554-1.76-1.61-3.296-2.632-4.781-1.168-1.7-2.271-3.304-2.271-4.749 0-1.443 1.103-3.05 2.27-4.748 1.022-1.485 2.08-3.022 2.633-4.782.577-1.832.606-3.764.637-5.633.031-2.04.063-3.964.826-5.047.778-1.103 2.557-1.728 4.44-2.39 1.707-.6 3.472-1.221 4.968-2.344 1.476-1.107 2.58-2.636 3.648-4.112 1.199-1.657 2.33-3.221 3.617-3.652.28-.094.594-.134.931-.134 1.099 0 2.466.433 3.895.885 1.757.557 3.573 1.132 5.483 1.132s3.727-.575 5.484-1.132c1.869-.59 3.63-1.148 4.824-.75 1.286.431 2.417 1.996 3.614 3.65 1.069 1.478 2.174 3.007 3.652 4.114 1.496 1.122 3.261 1.743 4.97 2.344 1.881.662 3.66 1.287 4.438 2.39.765 1.083.795 3.007.826 5.045.028 1.869.059 3.802.637 5.634.554 1.761 1.61 3.298 2.632 4.784 1.168 1.698 2.271 3.303 2.271 4.746-.001 1.442-1.105 3.047-2.272 4.746zm15.439 9.21h-13.92c.038-1.087.118-2.094.376-2.911.33-1.049 1.135-2.22 1.988-3.46 1.475-2.146 3.148-4.58 3.148-7.586 0-3.007-1.673-5.439-3.148-7.584-.853-1.24-1.658-2.411-1.988-3.462-.258-.817-.34-1.824-.375-2.911h13.918l-5.084 13.957z" fill="url(#d)" transform="translate(35 9)"/><path d="m53.389 12.117c-13.84 0-25.098 11.498-25.098 25.634 0 14.134 11.259 25.632 25.098 25.632 13.838 0 25.096-11.498 25.096-25.632s-11.258-25.634-25.096-25.634zm0 47.075c-11.576 0-20.993-9.618-20.993-21.441s9.417-21.442 20.993-21.442c11.574 0 20.991 9.619 20.991 21.442s-9.416 21.441-20.99 21.441z" fill="url(#e)" transform="translate(35 9)"/><path d="m19.69 15.115v-6.343c0-4.845-4-8.772-8.93-8.772-4.935 0-8.933 3.927-8.933 8.772v6.434c-.038.83-.239 2.731-1.22 4.957-1.318 2.99-.227 2.633.75 2.387.977-.245 3.16-1.205 3.84-.022.682 1.183 1.25 2.21 2.841 1.54 1.59-.67 2.34-.892 2.567-.892h.31c.226 0 .976.223 2.567.892 1.59.67 2.159-.357 2.84-1.54.682-1.183 2.863-.223 3.84.022.977.246 2.068.603.75-2.387-1.02-2.316-1.196-4.278-1.223-5.048z" fill="url(#f)" transform="translate(77 34)"/><path d="m87.763 44.989c-1.41-.002-2.553-1.193-2.554-2.662a.151.151 0 0 0 -.148-.154.151.151 0 0 0 -.148.154c-.002 1.47-1.145 2.66-2.555 2.662a.151.151 0 0 0 -.148.154c0 .085.066.154.148.154 1.41.002 2.553 1.193 2.555 2.662 0 .085.066.154.148.154.081 0 .148-.069.148-.154.001-1.47 1.144-2.66 2.554-2.662.082 0 .148-.069.148-.154a.151.151 0 0 0 -.148-.154zm5.325-1.919c-.94 0-1.702-.797-1.703-1.779a.101.101 0 0 0 -.099-.103.101.101 0 0 0 -.098.103c-.001.982-.763 1.778-1.703 1.78a.101.101 0 0 0 -.099.103c0 .057.044.103.099.103.94 0 1.702.797 1.703 1.78 0 .056.044.102.098.102a.101.101 0 0 0 .1-.103c0-.982.762-1.778 1.702-1.78a.101.101 0 0 0 .099-.102.101.101 0 0 0 -.099-.103zm-4.058-3.438c-.575 0-1.041-.48-1.042-1.073a.061.061 0 0 0 -.06-.062.061.061 0 0 0 -.06.062c-.001.592-.468 1.073-1.043 1.073a.061.061 0 0 0 -.06.063c0 .034.027.062.06.062.575 0 1.042.48 1.042 1.073 0 .035.027.063.06.063.034 0 .061-.028.061-.063 0-.592.467-1.073 1.043-1.073.033 0 .06-.028.06-.062a.061.061 0 0 0 -.06-.063z" fill="#fff"/></g></g></svg>
@@ -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 {
</div>
<div className="InsightsModal__other-options-container flex-container align-justify">
<span onClick={this.props.handleSignInClick} className="InsightsModal__link">{t('subscribe_pitch_sign_in')}</span>
<span onClick={this.handleNoThanksClick} className="InsightsModal__link">{t('no_thanks_turn_promos_off')}</span>
<span onClick={this.handleGoAwayClick} className="InsightsModal__link">{t('no_thanks_turn_promos_off')}</span>
</div>
</div>
</div>
ProTip! Use n and p to navigate between commits in a pull request.