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
Next

Modifying the Plus promo components to Premium

  • Loading branch information
wlycdgr committed Dec 10, 2019
commit 985bef652cde83cc232947ae9f17ed406a44ddec
@@ -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,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 (
<div className="full-height">
<PlusPromoModal
show={showPromoModal}
<PremiumPromoModal
show={!premium_promo_modal_shown}
location="hub"
handleSelectBasicClick={this._handlePromoSelectBasicClick}
handleSelectPlusClick={this._handlePromoSelectPlusClick}
handleKeepBasicClick: {this._handleKeepBasicClick}
handleGetPlusClick: {this._handleGetPlusClick}
/>
<HomeView {...childProps} />
</div>
@@ -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,
},
@@ -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,
})
});
}
@@ -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 (
<PlusUpgradePromoModal
handleNoThanksClick={this._handlePromoNoThanksClick}
handleSignInClick={this._handlePromoSignInClick}
handleSubscribeClick={this._handlePromoSubscribeClick}
handleXClick={this._handlePromoXClick}
/>
);
}

// promoModal === 'plus_initial'
return (
<PlusPromoModal
<PremiumPromoModal
show
location="panel"
handleSelectBasicClick={this._handlePromoSelectBasicClick}
handleSelectPlusClick={this._handlePromoSelectPlusClick}
handleSignInClick={this._handlePromoSignInClick}
handleGoAwayClick={this._handlePromoGoAwayClick}
handleGetPlusClick={this._handlePromoGetPlusClick}
handleTryMidnightClick={this._handlePromoTryMidnightClick}
handleXClick={this._handlePromoXClick}
/>
);
}
@@ -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;
@@ -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 (
<Modal show>
<div className={contentClassNames}>
<ModalExitButton className="InsightsModal__exitButton" toggleModal={this.handleXClick} />
<img className="PlusPromoModal__gold-ghostie-badge" src="/app/images/hub/home/gold-ghostie-badge.svg" />
<div className="PlusPromoModal__header">
{t('upgrade_your_ghostery_experience')}
</div>
<div className="PlusPromoModal__description cta" dangerouslySetInnerHTML={{ __html: t('upgrade_cta_TEXT') }} />
<div className="PlusPromoModal__buttons-background upgrade">
<div className="PlusPromoModal__button-container">
<span onClick={this.handleSubscribeClick} className="PlusPromoModal__button upgrade">
<span className="side-padded button-text">{t('upgrade_to_plus')}</span>
</span>
</div>
<div className="PlusPromoModal__text-link-container">
{
!loggedIn &&
(
<div onClick={this.props.handleSignInClick} className="PlusPromoModal__text-link">
{t('already_subscribed_sign_in')}
</div>
)
}
<div onClick={this.handleNoThanksClick} className="PlusPromoModal__text-link">
{t('no_thanks_turn_promos_off')}
</div>
</div>
</div>
</div>
</Modal>
);
}
}

export default PlusUpgradePromoModal;
ProTip! Use n and p to navigate between commits in a pull request.