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-1969 Plus In App Promo & GH-1970 Telemetry #509

Merged
merged 18 commits into from Apr 20, 2020
Merged
Changes from 1 commit
Commits
File filter
Filter file types
Jump to
Jump to file
Failed to load files.

Always

Just for now

Add click events to promo modal

  • Loading branch information
benstrumeyer committed Mar 9, 2020
commit 95280ff9dc9e5c0255eaeb0226e5d97fa384e815
@@ -28,7 +28,7 @@ const ModalExitButton = (props) => {
} = props;

const borderClassNames = ClassNames('ModalExitButton__exit flex-container align-middle', {
'spring-green': border === 'spring-green'
green: border === 'green'
});

return (
@@ -29,8 +29,9 @@ class InsightsPromoModal extends React.Component {
handleXClick = () => { this.props.handleXClick(INSIGHTS); }

render() {
const { show } = this.props;
return (
<Modal show>
<Modal show={show}>
<div className="InsightsModal__content flex-container flex-dir-column align-middle">
<ModalExitButton className="InsightsModal__exitButton" toggleModal={this.handleXClick} />
<div className="InsightsModal__image" />
@@ -16,7 +16,7 @@ import { NavLink } from 'react-router-dom';
import Header from '../containers/HeaderContainer';
import { PremiumPromoModal } from '../../shared-components';
import InsightsPromoModal from './InsightsPromoModal';
import PlusPromoModal from './PlusPromoModal';
import PlusPromoModal from '../containers/PlusPromoModalContainer';
import { DynamicUIPortContext } from '../contexts/DynamicUIPortContext';
import { sendMessage } from '../utils/msg';
import { setTheme } from '../utils/utils';
@@ -246,6 +246,21 @@ class Panel extends React.Component {
});
}

/**
* @private
* Handle clicks on the download button in the Premium promo modals
*/
_handlePromoTryPlusClick = () => {
this.props.actions.togglePromoModal();

// Add utm params
const url = `https://checkout.${DOMAIN}.com/plus?utm_source=gbe&utm_campaign=in_app_spring2020`;
sendMessage('openNewTab', {
url,
become_active: true,
});
}

/**
* @private
* Handle clicks on the 'Get Plus' option in the Premium modals
@@ -287,6 +302,7 @@ class Panel extends React.Component {
* Handle clicks on the 'X' close icon in promo modals
*/
_handlePromoXClick = (modal) => {
console.log('handling x click');
this.props.actions.togglePromoModal();

if (modal === 'insights') {
@@ -370,6 +386,7 @@ class Panel extends React.Component {
handleSignInClick={this._handlePromoSignInClick}
handleSubscribeClick={this._handlePromoSubscribeClick}
handleXClick={this._handlePromoXClick}
show
/>
);
}
@@ -380,51 +397,46 @@ class Panel extends React.Component {
* Renders the Insights promo modal if the user is not already an Insights subscriber
This conversation was marked as resolved by Eden12345

This comment has been minimized.

@Eden12345

Eden12345 Mar 23, 2020
Contributor

Looks like this comment needs to be updated

This comment has been minimized.

@benstrumeyer

benstrumeyer Mar 31, 2020
Author Contributor

Updated comment!

*/
_renderPlusPromoModal = () => {
// if (this._plusSubscriber()) return null;
if (this._plusSubscriber()) {
console.log('test');
}

// sendMessage('promoModals.sawPlusPromo', {});
if (this._plusSubscriber() || this._premiumSubscriber()) { return null; }

// sendMessage('ping', 'promo_modals_show_plus');
sendMessage('promoModals.sawPlusPromo', {});
sendMessage('ping', 'promo_modals_show_plus');

return (
<PlusPromoModal
handleGoAwayClick={this._handlePromoGoAwayClick}
handleSignInClick={this._handlePromoSignInClick}
handleSubscribeClick={this._handlePromoSubscribeClick}
This conversation was marked as resolved by Eden12345

This comment has been minimized.

@Eden12345

Eden12345 Mar 23, 2020
Contributor

Won't this._handlePromoSubscribeClick open the checkout for Premium rather than Plus, since it's just the checkout URL (which automatically redirects to Premium from what I can see)?

This comment has been minimized.

@benstrumeyer

benstrumeyer Apr 7, 2020
Author Contributor

fixed!

handleTryPlusClick={this._handlePromoTryPlusClick}
handleXClick={this._handlePromoXClick}
show
/>
);
}

_renderPromoModal = () => this._renderPlusPromoModal();

/**
* @returns {null|JSX}
* @private
* Renders either the Insights or the Premium promo modal
*/
// _renderPromoModal = () => {
// const {
// promoModal,
// isPromoModalHidden,
// } = this.props;
_renderPromoModal = () => {
const {
promoModal,
isPromoModalHidden,
} = this.props;

// if (isPromoModalHidden) return null;
if (isPromoModalHidden) return null;

// if (promoModal === 'insights') {
// return this._renderInsightsPromoModal();
// }
if (promoModal === 'insights') {
return this._renderInsightsPromoModal();
}

// if (promoModal === 'premium') {
// return this._renderPremiumPromoModal();
// }
if (promoModal === 'plus') {
return this._renderPlusPromoModal();
}

// return null;
// }
return null;
}

/**
* React's required render function. Returns JSX
@@ -1,5 +1,5 @@
/**
* PlusPromo Modal Component
* PlusPromoModal Component
*
* Ghostery Browser Extension
* https://www.ghostery.com/
@@ -25,13 +25,11 @@ import ModalExitButton from './BuildingBlocks/ModalExitButton';
const PlusPromoModal = (props) => {
This conversation was marked as resolved by Eden12345

This comment has been minimized.

@Eden12345

Eden12345 Mar 23, 2020
Contributor

Is there a way we could combine PlusPromoModal, InsightsPromoModal, and PremiumPromoModal, or at least wrap them all in the same outer component that takes care of the functions that are essential to each (eg. handleGoAwayClick, handleSignInClick, handleXClick)?

const {
show,
location,
isPlus,
handleTryMidnightClick,
handleGetPlusClick,
handleKeepBasicClick,
handleTryPlusClick,
handleSignInClick,
handleGoAwayClick,
handleXClick,
loggedIn
} = props;

const contentClassNames = ClassNames(
@@ -44,7 +42,7 @@ const PlusPromoModal = (props) => {
return (
<Modal show={show}>
<div className={contentClassNames}>
<ModalExitButton className="PlusPromoModal__exitButton" toggleModal={handleXClick} border="spring-green" />
<ModalExitButton className="PlusPromoModal__exitButton" toggleModal={handleXClick} border="green" />
<div className="PlusPromoModal__plus-logo" />
<div className="PlusPromoModal__main-content-container">
<div className="PlusPromoModal__header">
@@ -58,13 +56,15 @@ const PlusPromoModal = (props) => {
</div>
<div className="PlusPromoModal__call-to-action-container">
<div className="PlusPromoModal__button-container flex-container align-center">
<button type="button" className="PlusPromoModal__download-button" onClick={handleTryMidnightClick}>
<button type="button" className="PlusPromoModal__download-button" onClick={handleTryPlusClick}>
<span>UPGRADE TO PLUS</span>
</button>
</div>
<div className="flex-container align-justify">
<span className="PlusPromoModal__link">Already a plus subscriber?</span>
<span className="PlusPromoModal__link">{t('no_thanks_turn_promos_off')}</span>
<div>
{!loggedIn &&
<span className="PlusPromoModal__link sign-in" onClick={handleSignInClick}>Already a plus subscriber?</span>
}
<span className="PlusPromoModal__link turn-promos-off" onClick={handleGoAwayClick}>{t('no_thanks_turn_promos_off')}</span>
</div>
</div>
</div>
@@ -74,21 +74,13 @@ const PlusPromoModal = (props) => {


// PropTypes ensure we pass required props of the correct type
// PlusPromoModal.propTypes = {
// show: PropTypes.bool.isRequired,
// isPlus: PropTypes.bool.isRequired,
// handleTryMidnightClick: PropTypes.func.isRequired,
// handleGetPlusClick: PropTypes.func.isRequired,
// handleKeepBasicClick: PropTypes.func,
// handleGoAwayClick: PropTypes.func,
// handleXClick: PropTypes.func,
// };

// const noop = () => {};
// PlusPromoModal.defaultProps = {
// handleKeepBasicClick: noop,
// handleGoAwayClick: noop,
// handleXClick: noop,
// };
PlusPromoModal.propTypes = {
show: PropTypes.bool.isRequired,
handleTryPlusClick: PropTypes.func.isRequired,
handleSignInClick: PropTypes.func.isRequired,
handleGoAwayClick: PropTypes.func.isRequired,
handleXClick: PropTypes.func.isRequired,
loggedIn: PropTypes.bool.isRequired,
};

export default PlusPromoModal;
@@ -0,0 +1,28 @@
/**
* PlusPromoModal Container
*
* 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 { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import PlusPromoModal from '../components/PlusPromoModal';
/**
* Map redux store state properties to Panel view component own properties.
* @memberOf PanelContainers
* @param {Object} state entire Redux store's state
* @param {Object} ownProps props passed to the connected component
* @return {function} this function returns plain object, which will be merged into Panel view component props
* @todo We are not using ownProps, so we better not specify it explicitly,
* in this case it won't be passed by React (see https://github.com/reactjs/react-redux/blob/master/docs/api.md).
*/
const mapStateToProps = state => Object.assign({}, state.account, {});

export default withRouter(connect(mapStateToProps)(PlusPromoModal));
@@ -24,7 +24,7 @@
&.grey {
border: solid 0.8px #325e97;
}
&.spring-green {
&.green {
border: solid 2px $spring-green;
}
}
@@ -171,5 +171,15 @@ $condensed-font-family: Roboto Condensed, "Open Sans", "Helvetica Neue", Helveti
color: #4a4a4a;
text-decoration: underline;
text-align: center;
cursor: pointer;
cursor: pointer;

&.sign-in {
float: left;
left: 10px;
}

&.turn-promos-off {
float: right;
right: 10px;
}
}
@@ -990,6 +990,7 @@ function onMessageHandler(request, sender, callback) {
return false;
}
if (name === 'promoModals.turnOffPromos') {
console.log('turning off promos');
promoModals.turnOffPromos();
return false;
}
@@ -510,10 +510,16 @@ class Metrics {
*/
_getThemeValue() {
const { current_theme } = conf;
if (current_theme === 'midnight-theme') {
return 1;
switch (current_theme) {
case 'midnight-theme':
This conversation was marked as resolved by wlycdgr

This comment has been minimized.

@wlycdgr

wlycdgr Apr 13, 2020
Member

Nothing to change here & now, but just a note that we should remember to update this bit to dark-blue-theme in the final theme framework PR

This comment has been minimized.

@benstrumeyer

benstrumeyer Apr 16, 2020
Author Contributor

I spoke with Frank a while ago and I think we're only visually updating the theme to dark-blue-theme and not the theme variables themselves so we can prevent breakage for users on older versions of the extension that request a midnight-theme from the account project which would no longer exist. We do however have a ticket in the backlog to do this properly

return 1;
case 'leaf-theme':
return 2;
case 'palm-theme':
return 3;
default:
return 0;
}
return 0;
}

/**
@@ -99,8 +99,10 @@ class PromoModals {
*/
static _hasEngagedFrequently() {
const { engaged_daily_count } = conf.metrics || [];
console.log(engaged_daily_count);

const very_engaged_days = engaged_daily_count.reduce((acc, count) => (count >= DAILY_INSIGHTS_TARGET ? ++acc : acc), 0);
console.log('very engaged days: ', very_engaged_days);

return very_engaged_days >= WEEKLY_INSIGHTS_TARGET;
}
ProTip! Use n and p to navigate between commits in a pull request.