diff --git a/CHANGELOG.md b/CHANGELOG.md
index 95582ba5d..d7ed025b1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+### GHOSTERY 8.4.6 (UNRELEASED)
+
++ Modularize Rewards code (#462)
+
### GHOSTERY 8.4.5 (November 20, 2019)
+ Remove unused telemetry from promo modals (#474)
diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 9f34a79b1..8b51e6331 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -782,7 +782,7 @@
"message": "We seem to be having a technical issue. Try again later."
},
"email_address_in_use": {
- "message": "That email address is already in use. Please choose another. "
+ "message": "That email address is already in use. Please choose another. "
},
"short_description": {
"description": "A short description of this extension (Ghostery).",
@@ -1659,7 +1659,7 @@
"message": "Account Successfully Created"
},
"hub_create_account_toast_error": {
- "message": "That email address is already in use. Please choose another."
+ "message": "That email address is already in use. Please choose another."
},
"enable_when_paused": {
"message": "To use this function, Resume Ghostery."
@@ -1993,6 +1993,168 @@
"enhanced_anti_tracking": {
"message": "Enhanced Anti-Tracking"
},
+ "panel_rewards_view__reward": {
+ "message": "Reward"
+ },
+ "panel_rewards_view__rewards": {
+ "message": "Rewards"
+ },
+ "OFFERS_BEGIN": {
+ "message": ""
+ },
+ "myoffrz_affiliate_link": {
+ "message": "affiliate link"
+ },
+ "myoffrz_copy_and_go": {
+ "message": "copy & go"
+ },
+ "myoffrz_feedback_option1": {
+ "message": "I already used the offer"
+ },
+ "myoffrz_feedback_option2": {
+ "message": "It's not a good deal"
+ },
+ "myoffrz_feedback_option3": {
+ "message": "It's not relevant to me"
+ },
+ "myoffrz_feedback_option4": {
+ "message": "Other reasons"
+ },
+ "myoffrz_feedback_title": {
+ "message": "Feedback"
+ },
+ "myoffrz_get_code": {
+ "message": "Get code"
+ },
+ "myoffrz_offer_removed": {
+ "message": "This offer was removed."
+ },
+ "myoffrz_optional": {
+ "message": "Optional"
+ },
+ "myoffrz_powered_by_offrz": {
+ "message": "POWERED BY MyOffrz"
+ },
+ "myoffrz_show_code": {
+ "message": "Show code"
+ },
+ "myoffrz_show_more": {
+ "message": "Show more"
+ },
+ "myoffrz_skip": {
+ "message": "Skip"
+ },
+ "myoffrz_welcome_link": {
+ "message": "How It Works"
+ },
+ "myoffrz_welcome_text": {
+ "message": "As you browse the Internet, we are searching for attractive offers based on your interests."
+ },
+ "myoffrz_welcome_title": {
+ "message": "Hello!"
+ },
+ "myoffrz_why_offers_text": {
+ "message": "No personal data leaves your device. Your browser automatically identifies what you might be interested in based on your previous use. "
+ },
+ "myoffrz_why_see_these_offers": {
+ "message": "Why do I see these offers?"
+ },
+ "myoffrz_why_see_this": {
+ "message": "Why do I see this?"
+ },
+ "myoffrz_badge_text_new": {
+ "message": "NEW"
+ },
+ "myoffrz_conditions": {
+ "message": "Conditions"
+ },
+ "myoffrz_turnoff_rewards": {
+ "message": "Turn off Ghostery Rewards"
+ },
+ "OFFERS_ALREADY_TRANSLATED": {
+ "message": ""
+ },
+ "myoffrz_help": {
+ "message": "Help"
+ },
+ "myoffrz_learn_more": {
+ "message": "Learn more"
+ },
+ "myoffrz_send": {
+ "message": "Send"
+ },
+ "myoffrz_settings": {
+ "message": "Settings"
+ },
+ "myoffrz_tooltip_new_offer": {
+ "message": "New Reward discovered!"
+ },
+ "myoffrz_turnoff_notification": {
+ "message": "Ghostery Rewards is now off. You can always turn it on in your Settings or the Rewards dashboard."
+ },
+ "myoffrz_optin_description": {
+ "message": "Would you like to receive offers and discounts from trusted Ghostery partners?"
+ },
+ "myoffrz_optin_title": {
+ "message": "New Reward discovered!"
+ },
+ "myoffrz_no": {
+ "message": "no"
+ },
+ "myoffrz_yes": {
+ "message": "yes"
+ },
+ "myoffrz_rewards_new": {
+ "message": "New Reward discovered!"
+ },
+ "myoffrz_apply_code": {
+ "message": "Apply code"
+ },
+ "myoffrz_cancel": {
+ "message": "Cancel"
+ },
+ "myoffrz_copied": {
+ "message": "Copied"
+ },
+ "myoffrz_copy_code": {
+ "message": "Copy code"
+ },
+ "myoffrz_expires_in_day": {
+ "message": "Available for 1 day"
+ },
+ "myoffrz_expires_in_days": {
+ "message": "Available for $COUNT$ days",
+ "placeholders": {
+ "count": {
+ "content": "$1"
+ }
+ }
+ },
+ "myoffrz_expires_in_hour": {
+ "message": "Available for 1 hour"
+ },
+ "myoffrz_expires_in_hours": {
+ "message": "Available for $COUNT$ hours",
+ "placeholders": {
+ "count": {
+ "content": "$1"
+ }
+ }
+ },
+ "myoffrz_expires_in_minute": {
+ "message": "Available for 1 minute"
+ },
+ "myoffrz_expires_in_minutes": {
+ "message": "Available for $COUNT$ minutes",
+ "placeholders": {
+ "count": {
+ "content": "$1"
+ }
+ }
+ },
+ "OFFERS_ENDS": {
+ "message": ""
+ },
"unknown": {
"message": "Unknown"
},
@@ -2183,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/content-scripts/rewards/HotDog.jsx b/app/content-scripts/rewards/HotDog.jsx
deleted file mode 100644
index 365462653..000000000
--- a/app/content-scripts/rewards/HotDog.jsx
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * HotDog 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, { Component } from 'react';
-import { withRouter } from 'react-router-dom';
-
-/**
- * @class Create the Rewards "HotDog", aka UI element
- * @memberOf RewardsContentScript
- */
-class HotDog extends Component {
- constructor(props) {
- super(props);
- this.state = {
- closed: false
- };
- this.shownSignal = false;
- this.iframeEl = window.parent.document.getElementById('ghostery-iframe-container');
-
- if (this.iframeEl) {
- this.iframeEl.classList = '';
- this.iframeEl.classList.add('hot-dog');
- }
-
- this.ghostyStar = `url(${chrome.extension.getURL('app/images/rewards/ghosty-star.svg')})`;
- this.closeIcon = `url(${chrome.extension.getURL('app/images/rewards/light-x.svg')})`;
- this.close = this.close.bind(this);
- this.navigate = this.navigate.bind(this);
- }
-
- UNSAFE_componentWillReceiveProps(nextProps) {
- if (nextProps.reward && nextProps.reward !== null && !this.shownSignal) {
- this.props.actions.sendSignal('offer_notification_hotdog');
- this.shownSignal = true;
- }
- }
-
- navigate() {
- this.props.actions.sendSignal('offer_click_hotdog');
- if (this.iframeEl) {
- this.iframeEl.classList.add('offer-card');
- }
- this.props.history.push('/offercard');
- }
-
- close() {
- this.props.actions.sendSignal('offer_closed_hotdog');
- if (this.iframeEl) {
- this.iframeEl.classList = '';
- }
- this.setState({
- closed: true
- });
- }
-
- render() {
- return (
-
{ this.closeNotification(); }}
- style={{ backgroundImage: this.closeIcon }}
- />
- );
- }
-
- render() {
- return (
-
- {!this.state.closed && (
-
-
-
-
- {this.props.data.type === 'first-prompt' && this.renderOptoutImage()}
- {this.props.data.type !== 'first-prompt' && this.renderClose()}
-
- {this.props.data.type === 'first-prompt' && this.renderLabels()}
- {this.props.data.type === 'first-prompt' && this.renderHeadline()}
- {this.props.data.message}
- {' '}
- {this.props.data.type === 'first-prompt' && this.renderOptoutLink()}
-
- {this.props.data.buttons && (
-
- { this.closeNotification(true); }}>
- {t('rewards_yes')}
-
- { this.closeNotification(false); }}>
- {t('rewards_no')}
-
-
- )}
- {this.props.data.textLink && this.props.data.type !== 'first-prompt'
- && (
-
{
- if (this.props.data.textLink.callback) {
- this.props.data.textLink.callback();
- }
- }}
- >
- {this.props.data.textLink.text}
-
- )
- }
-
-
-
- )}
-
- );
- }
-}
-
-export default Notification;
diff --git a/app/content-scripts/rewards/OfferCard.jsx b/app/content-scripts/rewards/OfferCard.jsx
deleted file mode 100644
index c97e906e9..000000000
--- a/app/content-scripts/rewards/OfferCard.jsx
+++ /dev/null
@@ -1,361 +0,0 @@
-/**
- * Offer Card 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, { Component } from 'react';
-import msgModule from '../utils/msg';
-import { computeTimeDelta } from '../../panel/utils/utils';
-import Notification from './Notification';
-import Settings from './Settings';
-import ClickOutside from '../../panel/components/BuildingBlocks/ClickOutside';
-import Tooltip from '../../panel/components/Tooltip';
-
-const msg = msgModule('rewards');
-const { sendMessage } = msg;
-
-/**
- * @class Generate Rewards offer card
- * @memberOf RewardsContentScript
- */
-class OfferCard extends Component {
- constructor(props) {
- super(props);
- const {
- attrs: { isCodeHidden } = {},
- offer_data: offerData = {},
- } = props.reward || {};
- const { ui_info: { template_data: templateData = {} } = {} } = offerData;
- this.state = {
- code: isCodeHidden ? '*****' : templateData.code,
- closed: false,
- copyText: t('rewards_copy_code'),
- showPrompt: this.props.conf.rewardsPromptAccepted ? false : 1,
- showSettings: false,
- rewardUI: templateData,
- shouldShowCross: this.props.conf.rewardsPromptAccepted,
- };
-
- this.iframeEl = window.parent.document.getElementById('ghostery-iframe-container');
- if (this.iframeEl) {
- this.iframeContentDocument = this.iframeEl.contentDocument;
- this.iframeEl.classList = '';
- this.iframeEl.classList.add('offer-card');
- }
- this.rewardPictureEl = null;
-
- this.betaLogo = `url(${chrome.extension.getURL('app/images/rewards/ghostery-rewards-beta.png')})`;
- this.closeIcon = `url(${chrome.extension.getURL('app/images/drawer/x.svg')})`;
- this.ghostyGrey = `url(${chrome.extension.getURL('app/images/rewards/ghosty-grey.svg')})`;
- this.kebabIcon = `url(${chrome.extension.getURL('app/images/rewards/settings-kebab.svg')})`;
- this.poweredByMyoffrz = `url(${chrome.extension.getURL('app/images/rewards/powered-by-myoffrz.svg')})`;
-
- this.closeOfferCard = this.closeOfferCard.bind(this);
- this.copyCode = this.copyCode.bind(this);
- this.disableRewards = this.disableRewards.bind(this);
- this.disableRewardsNotification = this.disableRewardsNotification.bind(this);
- this.toggleSettings = this.toggleSettings.bind(this);
- this.handleImageLoaded = this.handleImageLoaded.bind(this);
- this.handlePrompt = this.handlePrompt.bind(this);
- this.redeem = this.redeem.bind(this);
-
- this.notifications = [
- {
- type: 'first-prompt',
- buttons: true,
- message: t('rewards_first_prompt_extended'),
- textLink: {
- href: 'https://www.ghostery.com/faqs/what-is-ghostery-rewards/',
- text: t('learn_more'),
- callback: () => {
- this.props.actions.sendSignal('offer_first_learn');
- sendMessage('ping', 'rewards_first_learn_more');
- },
- },
- closeCallback: (option) => { this.handlePrompt(1, option); },
- },
- {
- type: 'second-prompt',
- buttons: true,
- message: t('rewards_second_prompt'),
- textLink: {},
- closeCallback: (option) => { this.handlePrompt(2, option); },
- },
- {
- type: 'disabled-message',
- buttons: false,
- message: t('rewards_disable_notification'),
- textLink: {
- text: t('rewards_disable_confirm'),
- callback: this.closeOfferCard,
- },
- closeCallback: this.closeOfferCard,
- },
- ];
-
- const { reward } = props;
- this.props.actions.messageBackground('rewardSeen', {
- offerId: reward.offer_id
- });
- this.props.actions.sendSignal('offer_shown');
- this.props.actions.sendSignal('offer_dsp_session');
- }
-
- componentDidMount() {
- this.props.actions.addRewardSeenListener();
- if (this.state.rewardUI.picture_url) {
- const bgImg = new Image();
- bgImg.onload = () => {
- this.rewardPictureEl.style.backgroundImage = `url(${bgImg.src})`;
- };
- bgImg.src = this.state.rewardUI.picture_url;
- }
- }
-
- copyCode() {
- this.props.actions.sendSignal('code_copied');
-
- // 'copied' feedback for user
- this.setState({
- copyText: `${t('rewards_code_copied')}!`,
- code: this.state.rewardUI.code,
- }, () => {
- this.offerCardRef.querySelector('.reward-code-input').select();
- document.execCommand('copy');
- });
-
- // prevent multiple clicks
- clearTimeout(this.timeout);
- this.timeout = setTimeout(() => {
- this.setState({
- copyText: t('rewards_copy_code')
- });
- }, 3000);
- }
-
- toggleSettings() {
- if (!this.state.showSettings) {
- this.props.actions.sendSignal('offer_settings');
- }
- this.setState({
- showSettings: !this.state.showSettings
- });
- }
-
- disableRewards() {
- const signal = {
- actionId: 'rewards_off',
- origin: 'rewards-hotdog-card',
- type: 'action-signal',
- };
- sendMessage('setPanelData', { enable_offers: false, signal });
- // TODO catch
- sendMessage('ping', 'rewards_off');
- }
-
- disableRewardsNotification() {
- this.disableRewards();
- this.setState({
- showPrompt: 3
- });
- }
-
- handlePrompt(promptNumber, option) {
- const reject = () => {
- this.props.actions.sendSignal('offer_first_optout');
- sendMessage('ping', 'rewards_first_reject_optout');
- this.disableRewards();
- this.closeOfferCard();
- };
- if (promptNumber === 1) {
- if (!option) {
- reject();
- return;
- }
- this.props.actions.messageBackground('rewardsPromptOptedIn');
- this.props.actions.sendSignal('offer_first_optin');
- sendMessage('ping', 'rewards_first_accept');
- } else if (promptNumber === 2) {
- if (option) {
- reject();
- return;
- }
- this.props.actions.sendSignal('offer_first_optlater');
- sendMessage('ping', 'rewards_first_reject_optin');
- this.closeOfferCard();
- }
- this.props.actions.messageBackground('rewardsPromptAccepted');
- this.setState({
- showPrompt: false,
- shouldShowCross: true,
- });
- }
-
- closeOfferCard() {
- this.props.actions.removeFocusListener();
- if (this.iframeEl) {
- this.iframeEl.classList = '';
- }
- this.setState({
- closed: true
- });
- }
-
- redeem() {
- this.setState({ code: this.state.rewardUI.code });
- this.props.actions.sendSignal('offer_ca_action');
- }
-
- handleImageLoaded(e) {
- e.target.classList.remove('hide');
- }
-
- renderNotification(type) {
- const notificationProps = this.notifications[type];
- return (
-
- );
- }
-
- renderExpiresText() {
- const { expirationMs } = this.props.reward.offer_data;
- const expireDays = Math.round((new Date()).setDate(new Date().getDate() + expirationMs / 1000 / 60 / 60 / 24));
- const delta = computeTimeDelta(new Date(expireDays), new Date());
- const { count, type } = delta;
- if (count === 1) {
- return t(`rewards_expires_in_${type.slice(0, -1)}`);
- }
- return t(`rewards_expires_in_${type}`, [count]);
- }
-
- renderCross() {
- return (
-
{ this.props.actions.sendSignal('offer_closed_card'); this.closeOfferCard(); }}
- style={{ backgroundImage: this.closeIcon }}
- />
- );
- }
-
- render() {
- return (
- // @TODO condition for hide class
-
{ this.offerCardRef = ref; }} className="ghostery-rewards-component">
- { this.state.closed !== true && (
-
-
-
-
- {this.state.shouldShowCross && this.renderCross()}
-
-
-
-
-
-
-
-
{ this.kebabRef = node; }}
- />
- { this.state.showSettings && (
-
-
- { this.props.actions.sendSignal('about_ghostery_rewards', false); }} disable={this.disableRewardsNotification} />
-
-
- )}
-
- { this.state.rewardUI.picture_url && (
-
-
-
{ this.rewardPictureEl = node; }} />
-
-
- )}
-
- {/*
*/}
-
- { this.state.rewardUI.benefit }
-
-
- { this.state.rewardUI.headline }
-
-
- { this.state.rewardUI.desc }
-
-
-
- { this.state.rewardUI.code && (
-
- )}
-
-
- { this.renderExpiresText() }
-
- {this.state.rewardUI.conditions && (
-
- { t('rewards_terms_conditions') }
-
-
- )}
-
-
- {this.state.rewardUI.call_to_action.text}
-
-
-
-
- { this.state.showPrompt === 1 &&
- this.renderNotification(0)
- }
- { this.state.showPrompt === 2 &&
- this.renderNotification(1)
- }
- { this.state.showPrompt === 3 &&
- this.renderNotification(2)
- }
-
- )}
-
- );
- }
-}
-
-export default OfferCard;
diff --git a/app/content-scripts/rewards/Settings.jsx b/app/content-scripts/rewards/Settings.jsx
deleted file mode 100644
index 65c9524a6..000000000
--- a/app/content-scripts/rewards/Settings.jsx
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * Settings 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, { Component } from 'react';
-
-/**
- * @class Handles settings for Rewards
- * @memberOf RewardsContentScript
- */
-class Settings extends Component {
- constructor(props) {
- super(props);
- this.closeIcon = `url(${chrome.extension.getURL('app/images/rewards/white-x.svg')})`;
- this.state = {
- closed: false
- };
-
- this.close = this.close.bind(this);
- }
-
- close() {
- this.setState({
- closed: true
- });
- if (typeof this.props.closeCallback === 'function') {
- this.props.closeCallback();
- }
- }
-
- render() {
- return (
-
- {!this.state.closed && (
-
-
-
-
{t('rewards_about')}
-
{ this.close(); this.props.disable(); }}>
- {t('rewards_disable')}
-
-
- {/*
{t('rewards_settings')}
-
{t('rewards_delete')}
*/}
-
-
- )}
-
- );
- }
-}
-
-export default Settings;
diff --git a/app/content-scripts/rewards/index.jsx b/app/content-scripts/rewards/index.jsx
deleted file mode 100644
index 0befce2bb..000000000
--- a/app/content-scripts/rewards/index.jsx
+++ /dev/null
@@ -1,249 +0,0 @@
-/**
- * Ghostery Rewards
- *
- * 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
- */
-
-/**
- * @namespace RewardsContentScript
- */
-
-/* eslint no-use-before-define: 0 */
-import React from 'react';
-import ReactDOM from 'react-dom';
-import { Router, Route } from 'react-router-dom';
-import retargetEvents from 'react-shadow-dom-retarget-events';
-import HotDog from './HotDog';
-import OfferCard from './OfferCard';
-import msgModule from '../utils/msg';
-import history from '../../panel/utils/history';
-import globals from '../../../src/classes/Globals';
-
-const msg = msgModule('rewards');
-const { sendMessage } = msg;
-const { onMessage } = globals;
-const channelsSupported = (typeof chrome.runtime.connect === 'function');
-
-/**
- * @class Injects Ghostery Rewards components
- * @memberOf RewardsContentScript
- */
-class RewardsApp {
- constructor() {
- this.reward = null;
- this.conf = null;
- this.rewardsContainer = document.createElement('div');
- this.rewardsApp = document.createElement('div');
- this.rewardsIframe = null;
- this.iframeStyle = null;
- this.port = null;
- this.mainView = null;
- this.rewardsApp.id = 'ghostery-rewards-app';
- this.rewardsApp.className = 'show';
-
- this.handleMessages = this.handleMessages.bind(this);
- this.sendSignal = this.sendSignal.bind(this);
- this.messageBackground = this.messageBackground.bind(this);
- this.removeFocusListener = this.removeFocusListener.bind(this);
- this.focusListener = this.focusListener.bind(this);
- this.addRewardSeenListener = this.addRewardSeenListener.bind(this);
-
- this.actions = {
- sendSignal: this.sendSignal,
- messageBackground: this.messageBackground,
- removeFocusListener: this.removeFocusListener,
- addRewardSeenListener: this.addRewardSeenListener
- };
- }
-
- init() {
- if (document.readyState === 'complete') {
- this.start();
- } else {
- document.onreadystatechange = () => {
- if (document.readyState === 'complete') {
- this.start();
- }
- };
- }
- }
-
- start() {
- if (document.head.createShadowRoot || document.head.attachShadow) {
- this.renderShadow();
- } else {
- // use iframe to encapsulate CSS - fallback for everything else besides chrome
- this.renderIframe();
- }
- }
-
- renderReact() {
- const MainView = this.mainView;
- ReactDOM.render(
, this.rewardsApp);
- }
-
- renderShadow() {
- // Use shadowDOM to encapsulate CSS
- document.body.appendChild(this.rewardsContainer);
- const shadowRoot = this.rewardsContainer.attachShadow({ mode: 'open' }); // Get the shadow root
- shadowRoot.appendChild(this.rewardsApp); // Append React root to shadow root
- retargetEvents(shadowRoot); // Reattach React click events
-
- this.mainView = props => (
-
-
-
- }
- />
-
- }
- />
-
- }
- />
-
- );
- this.initListener();
- }
-
- renderIframe() {
- this.rewardsIframe = document.createElement('iframe');
- this.rewardsIframe.id = 'ghostery-iframe-container';
- this.rewardsIframe.onload = () => {
- this.iframeStyle = document.createElement('link');
- this.iframeStyle.rel = 'stylesheet';
- this.iframeStyle.type = 'text/css';
- this.iframeStyle.href = chrome.extension.getURL('dist/css/rewards_styles.css');
-
- this.rewardsIframe.contentWindow.document.head.appendChild(this.iframeStyle);
- this.rewardsContainer = this.rewardsIframe.contentWindow.document.body;
-
- this.rewardsApp.classList.add('iframe-child');
- this.rewardsContainer.appendChild(this.rewardsApp);
- this.mainView = props => (
-
-
-
- }
- />
-
- }
- />
-
- }
- />
-
-
- );
- this.initListener();
- };
- document.body.appendChild(this.rewardsIframe);
- }
-
- initListener() {
- if (channelsSupported) {
- this.port = chrome.runtime.connect({ name: 'rewardsPort' });
- if (this.port) {
- this.port.onMessage.addListener(this.handleMessages);
- this.port.postMessage({ name: 'rewardsLoaded' });
- }
- } else {
- // TODO listen for this in background.js
- sendMessage('rewardsLoaded');
- onMessage.addListener(this.handleMessages);
- }
- }
-
- handleMessages(request) {
- if (request.name === 'showOffer' || request.name === 'showHotDog') {
- this.reward = request.reward;
- this.conf = request.conf;
- }
-
- if (request.name === 'showOffer') {
- history.push('/offercard');
- }
-
- // in FF 61 react sees some elements in iframes as non interactive
- // react overwrites the event handlers for these elements with `function noop() {}`
- // https://github.com/facebook/react/blob/16.4.2-dev/packages/react-dom/src/client/ReactDOMFiberComponent.js#L235
- // using setTimeout to render react is a temporary workaround
- setTimeout(() => {
- this.renderReact();
- });
- }
-
- focusListener() {
- this.sendSignal('offer_shown');
- }
-
- addRewardSeenListener() {
- window.addEventListener('focus', this.focusListener);
- }
-
- removeFocusListener() {
- window.removeEventListener('focus', this.focusListener);
- }
-
- messageBackground(name, message, signal = false) {
- if (
- signal &&
- this.port &&
- (message.actionId !== 'rewards_off') &&
- (message.actionId !== 'rewards_on')
- ) {
- this.port.postMessage({
- name,
- message
- });
- } else {
- sendMessage(name, message);
- }
- }
-
- sendSignal(actionId, offerSignal = true) {
- // Cliqz metrics
- const offerId = offerSignal ? this.reward.offer_id : null;
- const message = {
- offerId,
- actionId,
- origin: 'rewards-hotdog-card',
- type: !offerSignal ? 'action-signal' : 'offer-action-signal',
- };
- this.messageBackground('rewardSignal', message, true);
- }
-}
-
-const rewardsApp = new RewardsApp();
-rewardsApp.init();
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..45c933b20 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://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'); }
- 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._handlePremiumPromoModalClick('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 +122,14 @@ class HomeViewContainer extends Component {
isPlus,
};
- const showPromoModal = !isPlus && !plus_promo_modal_shown;
-
return (
@@ -137,7 +152,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 +163,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 +172,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/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/images/rewards/best-offer.svg b/app/images/rewards/best-offer.svg
deleted file mode 100644
index 13a0f4d8d..000000000
--- a/app/images/rewards/best-offer.svg
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
- best-offer-icon13x12
- Created with Sketch.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/images/rewards/exclusive.svg b/app/images/rewards/exclusive.svg
deleted file mode 100644
index 61bb751d5..000000000
--- a/app/images/rewards/exclusive.svg
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
- exclusive-icon13x12
- Created with Sketch.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/images/rewards/ghostery-rewards-beta.png b/app/images/rewards/ghostery-rewards-beta.png
deleted file mode 100644
index 929d71fc8..000000000
Binary files a/app/images/rewards/ghostery-rewards-beta.png and /dev/null differ
diff --git a/app/images/rewards/ghostery_O.png b/app/images/rewards/ghostery_O.png
deleted file mode 100644
index 40bb85692..000000000
Binary files a/app/images/rewards/ghostery_O.png and /dev/null differ
diff --git a/app/images/rewards/light-x.svg b/app/images/rewards/light-x.svg
deleted file mode 100644
index c7006483f..000000000
--- a/app/images/rewards/light-x.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/app/images/rewards/powered-by-myoffrz.svg b/app/images/rewards/powered-by-myoffrz.svg
deleted file mode 100644
index 26f202dd8..000000000
--- a/app/images/rewards/powered-by-myoffrz.svg
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- powered_by
- Created with Sketch.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/images/rewards/settings-kebab.svg b/app/images/rewards/settings-kebab.svg
deleted file mode 100644
index bc9b11daa..000000000
--- a/app/images/rewards/settings-kebab.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/app/images/rewards/white-x.svg b/app/images/rewards/white-x.svg
deleted file mode 100644
index 9dd5cd1a4..000000000
--- a/app/images/rewards/white-x.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/app/panel/actions/RewardsActions.js b/app/panel/actions/RewardsActions.js
index 1c75bac48..a8d61933d 100644
--- a/app/panel/actions/RewardsActions.js
+++ b/app/panel/actions/RewardsActions.js
@@ -14,8 +14,6 @@
import {
UPDATE_REWARDS_DATA,
TOGGLE_OFFERS_ENABLED,
- REMOVE_OFFER,
- SET_OFFER_READ,
SEND_SIGNAL
} from '../constants/constants';
@@ -43,29 +41,6 @@ export function toggleOffersEnabled(enabled) {
};
}
-/**
- * Removes a reward from the rewards list
- * @param {String} id The ID of the reward we want to remove.
- * @return {Object}
- */
-export function removeOffer(id) {
- return {
- type: REMOVE_OFFER,
- data: { id }
- };
-}
-
-/**
- * Sets the unread status of an offer to false
- * @param {String} id the ID of the reward we want to update.
- * @return {Object}
- */
-export function setOfferRead(id) {
- return {
- type: SET_OFFER_READ,
- data: { id }
- };
-}
// TODO the reducer calls getRewardMessage
// determine whether it would be better to simply call getRewardMessage directly where sendSignal is called
diff --git a/app/panel/actions/__tests__/RewardsActions.js b/app/panel/actions/__tests__/RewardsActions.js
index b182350a3..eccf4fff9 100644
--- a/app/panel/actions/__tests__/RewardsActions.js
+++ b/app/panel/actions/__tests__/RewardsActions.js
@@ -18,8 +18,6 @@ import * as rewardsActions from '../RewardsActions';
import {
UPDATE_REWARDS_DATA,
TOGGLE_OFFERS_ENABLED,
- REMOVE_OFFER,
- SET_OFFER_READ,
SEND_SIGNAL
} from '../../constants/constants';
@@ -63,30 +61,6 @@ describe('app/panel/actions/RewardsActions.js', () => {
expect(actions).toEqual([expectedPayload]);
});
- test('removeOffer action should return correctly', () => {
- const initialState = {};
- const store = mockStore(initialState);
-
- const id = 'test_reward_id';
- const expectedPayload = { data: { id }, type: REMOVE_OFFER };
- store.dispatch(rewardsActions.removeOffer(id));
-
- const actions = store.getActions();
- expect(actions).toEqual([expectedPayload]);
- });
-
- test('setOfferRead action should return correctly', () => {
- const initialState = {};
- const store = mockStore(initialState);
-
- const id = 'test_reward_id';
- const expectedPayload = { data: { id }, type: SET_OFFER_READ };
- store.dispatch(rewardsActions.setOfferRead(id));
-
- const actions = store.getActions();
- expect(actions).toEqual([expectedPayload]);
- });
-
test('sendSignal offer-action-signal should return correctly', () => {
const initialState = {};
const store = mockStore(initialState);
diff --git a/app/panel/components/BuildingBlocks/RewardDetail.jsx b/app/panel/components/BuildingBlocks/RewardDetail.jsx
deleted file mode 100644
index ec9e9b3a6..000000000
--- a/app/panel/components/BuildingBlocks/RewardDetail.jsx
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * Reward Detail 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 { computeTimeDelta } from '../../utils/utils';
-import { sendMessage } from '../../utils/msg';
-import Tooltip from '../Tooltip';
-
-/**
- * @class Implements the details for a single reward for for the Rewards Panel
- * @memberof PanelBuildingBlocks
- */
-class RewardDetail extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- copyText: t('rewards_copy_code'),
- code: props.isCodeHidden ? '*****' : props.code,
- };
-
- // Event Bindings
- this.handleCopyClick = this.handleCopyClick.bind(this);
- this.handleRedeemClick = this.handleRedeemClick.bind(this);
- }
-
- /**
- * Lifecycle event
- */
- UNSAFE_componentWillMount() {
- this.props.actions.setOfferRead(this.props.id);
- }
-
- /**
- * Handles clicking the copy button
- */
- handleCopyClick() {
- // Show a toast notification
- this.props.actions.showNotification({
- text: t('rewards_code_copied_toast_notification'),
- classes: 'purple',
- });
-
- // Update and reset Copy Code text
- this.setState({
- code: this.props.code,
- copyText: t('rewards_code_copied'),
- }, () => {
- // Copy the reward code
- this.copyNode.querySelector('input').select();
- document.execCommand('copy');
- });
- setTimeout(() => {
- this.setState({ copyText: t('rewards_copy_code') });
- }, 3000);
-
- // Send a signal to the offers black box
- this.props.actions.sendSignal('code_copied', this.props.id);
- }
-
- /**
- * Handles clicking the redeem button
- * @param {Object} event the event object
- */
- handleRedeemClick(event) {
- event.preventDefault();
- this.props.actions.sendSignal('offer_ca_action', this.props.id);
- sendMessage('openNewTab', {
- url: this.props.redeemUrl,
- become_active: true,
- });
- window.close();
- }
-
- /**
- * Helper render function for the expires text.
- * @return {JSX} JSX for the Rewards Detail
- */
- renderExpiresText() {
- const { expires } = this.props;
- const delta = computeTimeDelta(new Date(expires), new Date());
- const { count, type } = delta;
- if (count === 1) {
- return t(`rewards_expires_in_${type.slice(0, -1)}`);
- }
- return t(`rewards_expires_in_${type}`, [count]);
- }
-
- /**
- * React's required render function. Returns JSX
- * @return {JSX} JSX for rendering the details for a Reward
- */
- render() {
- const {
- code,
- text,
- description,
- benefit,
- conditions,
- pictureUrl,
- redeemText
- } = this.props;
-
- return (
-
-
- {benefit && (
-
- { benefit }
-
- )}
- {text && (
-
- { text }
-
- )}
- {description && (
-
- { description }
-
- )}
- {code && (
-
- { this.copyNode = node; }}>
- {this.state.code}
-
-
-
- {this.state.copyText}
-
-
- )}
-
-
- { this.renderExpiresText() }
-
- {conditions && (
-
-
- { t('rewards_terms_conditions') }
-
-
-
- )}
-
-
- { redeemText }
-
-
- );
- }
-}
-
-export default RewardDetail;
diff --git a/app/panel/components/BuildingBlocks/RewardListItem.jsx b/app/panel/components/BuildingBlocks/RewardListItem.jsx
deleted file mode 100644
index 398100889..000000000
--- a/app/panel/components/BuildingBlocks/RewardListItem.jsx
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * Reward List Item 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 { Link } from 'react-router-dom';
-import ClassNames from 'classnames';
-import { computeTimeDelta } from '../../utils/utils';
-
-/**
- * @class Implements a single reward in a list for the Rewards Panel
- * @memberof PanelBuildingBlocks
- */
-class RewardListItem extends React.Component {
- constructor(props) {
- super(props);
- this.state = {};
-
- // Event Bindings
- this.handleClick = this.handleClick.bind(this);
- this.clickCloseButton = this.clickCloseButton.bind(this);
-
- // Send Signal
- this.props.actions.sendSignal('offer_shown', this.props.id);
- }
-
- /**
- * Handle the click event: everything normal unless it is disabled
- * @param {Object} event the click event
- */
- handleClick(event) {
- const { disabled, unread, id } = this.props;
- if (disabled) {
- event.preventDefault();
- } else {
- if (unread) {
- this.props.actions.sendSignal('offer_click_specific_new', id);
- }
- this.props.actions.sendSignal('offer_click_specific', id);
- this.props.actions.sendSignal('offer_dsp_session', id);
- }
- }
-
- /**
- * Handle clicking on the close button
- * @param {Object} event the click event
- */
- clickCloseButton(event) {
- // Prevent the event from propagating and linking to the Reward Detail
- event.preventDefault();
- event.stopPropagation();
-
- const { id } = this.props;
- this.props.actions.removeOffer(id);
- this.props.actions.sendSignal('remove_offer_link', id);
- }
-
- /**
- * Helper render function for the expires text.
- * @return {JSX} JSX for the Rewards Items List
- */
- renderExpiresText() {
- const { expires } = this.props;
- const delta = computeTimeDelta(new Date(expires), new Date());
- const { count, type } = delta;
- if (count === 1) {
- return t(`rewards_expires_in_${type.slice(0, -1)}`);
- }
- return t(`rewards_expires_in_${type}`, [count]);
- }
-
- /**
- * React's required render function. Returns JSX
- * @return {JSX} JSX for rendering a Reward within the Rewards List
- */
- render() {
- const {
- id,
- isLong,
- text,
- benefit,
- unread,
- disabled,
- logoUrl,
- } = this.props;
- const itemClassName = ClassNames('RewardListItem', 'row', {
- 'RewardListItem--greyscale': disabled,
- 'RewardListItem--unread': unread,
- 'RewardListItem--elongated': isLong,
- 'not-clickable': disabled,
- clickable: !disabled,
- });
-
- return (
-
-
-
-
-
-
-
{ benefit }
-
{ text }
-
{ this.renderExpiresText() }
-
-
-
-
- );
- }
-}
-
-export default RewardListItem;
diff --git a/app/panel/components/BuildingBlocks/index.js b/app/panel/components/BuildingBlocks/index.js
index 3cb86a8ca..edc925cbc 100644
--- a/app/panel/components/BuildingBlocks/index.js
+++ b/app/panel/components/BuildingBlocks/index.js
@@ -21,8 +21,6 @@ import GhosteryFeature from './GhosteryFeature';
import NotScanned from './NotScanned';
import PauseButton from './PauseButton';
import ToggleSlider from './ToggleSlider';
-import RewardDetail from './RewardDetail';
-import RewardListItem from './RewardListItem';
import ModalExitButton from './ModalExitButton';
export {
@@ -33,7 +31,5 @@ export {
NotScanned,
PauseButton,
ToggleSlider,
- RewardDetail,
- RewardListItem,
ModalExitButton
};
diff --git a/app/panel/components/Detail.jsx b/app/panel/components/Detail.jsx
index 662cead77..dfb9bf494 100644
--- a/app/panel/components/Detail.jsx
+++ b/app/panel/components/Detail.jsx
@@ -63,20 +63,23 @@ class Detail extends React.Component {
const condensedToggleClassNames = ClassNames('condensed-toggle', {
condensed: this.props.is_expanded,
});
- const { enable_offers, unread_offer_ids } = this.props;
const activeTab = this.props.history.location.pathname.includes('rewards') ? 'rewards' : 'blocking';
+ const contentDetailsClassNames = ClassNames({
+ expanded: this.props.is_expanded,
+ rewardsView: activeTab === 'rewards',
+ });
return (
-
+
0}
+ hasReward={false}
subscriptionsPlus={this.props.user && this.props.user.subscriptionsPlus}
activeTab={activeTab}
/>
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 45f5de0e4..97e67e271 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';
@@ -150,10 +149,6 @@ class Panel extends React.Component {
reload: true
});
}
-
- if (panel.enable_offers && panel.unread_offer_ids.length > 0) {
- sendMessage('ping', 'engaged_offer');
- }
}
/**
@@ -204,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({
@@ -222,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({
@@ -229,25 +231,27 @@ 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', {});
- };
+ const url = 'https://ghostery.com/thanks-for-downloading-midnight';
+ 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,
@@ -257,8 +261,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) => {
@@ -269,9 +272,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', {
@@ -280,57 +280,55 @@ 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();
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);
- }
-
+ /**
+ * @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'));
}
- _renderPlusPromoModal = () => {
- if (this._plusSubscriber() || this._insightsSubscriber()) return null;
-
- 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 (
-
- );
- }
+ /**
+ * @returns {JSX}
+ * @private
+ * Renders the Premium promo modal
+ */
+ _renderPremiumPromoModal = () => {
+ sendMessage('promoModals.sawPremiumPromo', {});
- // promoModal === 'plus_initial'
return (
-
);
}
+ /**
+ * @returns {null|JSX}
+ * @private
+ * Renders the Insights promo modal if the user is not already an Insights subscriber
+ */
_renderInsightsPromoModal = () => {
if (this._insightsSubscriber()) return null;
@@ -340,7 +338,7 @@ class Panel extends React.Component {
return (
{
const {
promoModal,
isPromoModalHidden,
} = this.props;
+ console.error(`promoModal: ${promoModal}`);
+ console.error(`isPromoModalHidden: ${isPromoModalHidden}`);
+
if (isPromoModalHidden) return null;
if (promoModal === 'insights') {
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
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;
diff --git a/app/panel/components/Rewards.jsx b/app/panel/components/Rewards.jsx
index 8ba483f27..3a36932bf 100644
--- a/app/panel/components/Rewards.jsx
+++ b/app/panel/components/Rewards.jsx
@@ -13,11 +13,12 @@
import React from 'react';
import ClassNames from 'classnames';
-import { Link, Route } from 'react-router-dom';
-import { ToggleSlider, RewardListItem, RewardDetail } from './BuildingBlocks';
+import { Route } from 'react-router-dom';
+import { ToggleSlider } from './BuildingBlocks';
import { DynamicUIPortContext } from '../contexts/DynamicUIPortContext';
import { sendMessage } from '../utils/msg';
import globals from '../../../src/classes/Globals';
+import { log } from '../../../src/utils/common';
const IS_CLIQZ = (globals.BROWSER_INFO.name === 'cliqz');
@@ -33,7 +34,10 @@ class Rewards extends React.Component {
constructor(props) {
super(props);
this.state = {
- rewardsArray: null,
+ iframeWidth: 0,
+ iframeHeight: 0,
+ shouldHideRewards: false,
+ rewardsCount: 0,
};
// event bindings
@@ -41,10 +45,13 @@ class Rewards extends React.Component {
// helper render functions
this.renderRewardListComponent = this.renderRewardListComponent.bind(this);
- this.renderRewardDetailComponent = this.renderRewardDetailComponent.bind(this);
- this.handleBackClick = this.handleBackClick.bind(this);
this.handleFaqClick = this.handleFaqClick.bind(this);
this.handlePortMessage = this.handlePortMessage.bind(this);
+
+
+ // myoffrz
+ this.iframe = React.createRef();
+ this.handleMyoffrzMessage = this.handleMyoffrzMessage.bind(this);
}
/**
@@ -53,66 +60,79 @@ class Rewards extends React.Component {
componentDidMount() {
this._dynamicUIPort = this.context;
this._dynamicUIPort.onMessage.addListener(this.handlePortMessage);
- this._dynamicUIPort.postMessage({ name: 'RewardsComponentDidMount' });
+ window.addEventListener('message', this.handleMyoffrzMessage);
+ this._dynamicUIPort.postMessage({ name: 'RewardsComponentDidMount' });
this.props.actions.sendSignal('hub_open');
}
- /**
- * Lifecycle event
- */
- UNSAFE_componentWillReceiveProps(nextProps) {
- let rewardsArray = null;
- if (nextProps.rewards) {
- rewardsArray = Object.keys(nextProps.rewards).map((key) => {
- const reward = nextProps.rewards[key].offer_data;
- const { isCodeHidden } = nextProps.rewards[key].attrs || {};
- const createdTS = nextProps.rewards[key].createdTs;
- return {
- id: reward.offer_id,
- unread: nextProps.unread_offer_ids.indexOf(reward.offer_id) !== -1,
- code: reward.ui_info.template_data.code,
- isCodeHidden,
- text: reward.ui_info.template_data.title,
- description: reward.ui_info.template_data.desc,
- benefit: reward.ui_info.template_data.benefit,
- conditions: reward.ui_info.template_data.conditions,
- logo_url: reward.ui_info.template_data.logo_url,
- picture_url: reward.ui_info.template_data.picture_url,
- redeem_url: reward.ui_info.template_data.call_to_action.url,
- redeem_text: reward.ui_info.template_data.call_to_action.text,
- expires: new Date(createdTS + reward.expirationMs),
- };
- }).filter(reward => reward.expires > Date.now());
- }
- this.setState({ rewardsArray });
- }
-
/**
* Lifecycle event
*/
componentWillUnmount() {
/* @TODO send message to background to remove port onDisconnect event */
this.props.actions.sendSignal('hub_closed');
-
this._dynamicUIPort.postMessage({ name: 'RewardsComponentWillUnmount' });
this._dynamicUIPort.onMessage.removeListener(this.handlePortMessage);
+ window.removeEventListener('message', this.handleMyoffrzMessage);
}
/**
- * Handles message from the dynamic UI port to background
- */
+ * Handles message from the dynamic UI port to background
+ */
handlePortMessage(msg) {
if (msg.to !== 'rewards' || !msg.body) { return; }
+ // msg.body can contain enable_offers prop
this.props.actions.updateRewardsData(msg.body);
}
- /**
- * Handles clicking the back button
- */
- handleBackClick(offerId) {
- this.props.actions.sendSignal('offer_return_hub', offerId);
+ iframeResize(data = {}) {
+ const { width = 0, height = 0 } = data;
+ this.setState({ iframeWidth: width, iframeHeight: height });
+ }
+
+ sendToIframe(message) {
+ this.iframe.current.contentWindow.postMessage(JSON.stringify({
+ target: 'cliqz-offers-cc',
+ origin: 'window',
+ message,
+ }), '*');
+ }
+
+ myoffrzSendRuntimeMessage({ message, target }) {
+ chrome.runtime.sendMessage({ message, target }, (result = {}) => {
+ if (chrome.runtime.lastError) {
+ log('myoffrzSendRuntimeMessage, runtime.lastError', chrome.runtime.lastError);
+ return;
+ }
+ if (result.action !== 'pushData' || !this.iframe.current) { return; }
+ const { data: { vouchers = [] } = {} } = result;
+ const rewardsCount = vouchers.length;
+ this.setState({ shouldHideRewards: rewardsCount === 0, rewardsCount });
+ this.iframe.current.frameBorder = 0;
+ this.sendToIframe(result);
+ });
+ }
+
+ handleMyoffrzMessage(msg = {}) {
+ let target;
+ let message;
+ try {
+ const parsedData = JSON.parse(msg.data || '{}');
+ target = parsedData.target;
+ message = parsedData.message || {};
+ } catch (e) {
+ // just silent return
+ return;
+ }
+
+ if (target !== 'cliqz-offers-cc') { return; }
+ if (message.action === 'resize') {
+ this.iframeResize(message.data);
+ } else {
+ this.myoffrzSendRuntimeMessage({ message, target });
+ }
}
/**
@@ -150,33 +170,15 @@ class Rewards extends React.Component {
* Helper render function for the Rewards Header
* @return {JSX} JSX for the Rewards Header
*/
- renderRewardsHeader = (routeProps) => {
- let reward;
- const { id } = routeProps.match.params;
- if (id && this.state.rewardsArray) {
- reward = this.state.rewardsArray.find(el => el.id === id);
- }
- const { enable_offers, location } = this.props;
- const showBack = location.pathname.indexOf('/detail/rewards/detail') !== -1;
- const showToggle = location.pathname === '/detail/rewards/list';
- const headerClassNames = ClassNames('RewardsPanel__header', 'flex-container', 'align-middle', {
- 'align-justify': !showBack,
- });
- const headerTitleClassNames = ClassNames('RewardsPanel__title', {
- 'RewardsPanel--left-padding': showBack,
- });
+ renderRewardsHeader = () => {
+ const { enable_offers } = this.props;
+ const headerClassNames = ClassNames('RewardsPanel__header', 'flex-container', 'align-middle', 'align-justify');
+ const headerTitleClassNames = ClassNames('RewardsPanel__title');
return (
- {showBack && (
-
{ this.handleBackClick(id); }}>
-
-
-
-
- )}
{ t('ghostery_rewards') }
- {showToggle && !IS_CLIQZ && (
+ {!IS_CLIQZ && (
{enable_offers ? t('rewards_on') : t('rewards_off')}
@@ -188,9 +190,6 @@ class Rewards extends React.Component {
/>
)}
- {!showToggle && reward &&
-
- }
);
}
@@ -209,92 +208,76 @@ class Rewards extends React.Component {
);
}
+ renderCLIQZtext() {
+ return (
+
+ { this.renderRewardSvg() }
+
{ t('panel_detail_rewards_cliqz_text') }
+
+
+ { t('panel_detail_learn_more') }
+
+
+ );
+ }
+
+ renderRewardsTurnoffText() {
+ return (
+
+ { this.renderRewardSvg() }
+
{ t('panel_detail_rewards_off') }
+
+ );
+ }
+
+ renderRewardsNoneFoundText() {
+ return (
+
+ { this.renderRewardSvg() }
+
{ t('panel_detail_rewards_none_found') }
+
+ );
+ }
+
/**
* Helper render function for the list of Rewards Items
* @return {JSX} JSX for the Rewards Items List
*/
renderRewardListComponent() {
- const { actions, enable_offers, is_expanded } = this.props;
- const { rewardsArray } = this.state;
+ if (IS_CLIQZ) { return this.renderCLIQZtext(); }
+ const { enable_offers, is_expanded } = this.props;
+ if (!enable_offers) { return this.renderRewardsTurnoffText(); }
- if (IS_CLIQZ) {
- return (
-
- { this.renderRewardSvg() }
-
{ t('panel_detail_rewards_cliqz_text') }
-
-
- { t('learn_more') }
-
-
- );
- }
- if (enable_offers && !rewardsArray) {
- return (
-
- { this.renderRewardSvg() }
-
{ t('panel_detail_rewards_loading') }
-
- );
- }
- if (enable_offers && rewardsArray.length === 0) {
- return (
-
- { this.renderRewardSvg() }
-
{ t('panel_detail_rewards_none_found') }
-
- );
- }
- if (!enable_offers && (!rewardsArray || rewardsArray.length === 0)) {
- return (
-
- { this.renderRewardSvg() }
-
{ t('panel_detail_rewards_off') }
-
- );
- }
-
- const rewardsList = rewardsArray.map((reward, index) => (
-
- ));
- return { rewardsList }
;
- }
+ const {
+ shouldHideRewards,
+ iframeWidth,
+ iframeHeight,
+ rewardsCount,
+ } = this.state;
+ if (shouldHideRewards) { return this.renderRewardsNoneFoundText(); }
- /**
- * Helper render function for an individual Reward Item
- * @return {JSX} JSX for the Rewards Detail Item
- */
- renderRewardDetailComponent(routeProps) {
- const { id } = routeProps.match.params;
- const reward = this.state.rewardsArray.find(el => el.id === id);
+ const src = chrome.runtime.getURL('cliqz/offers-cc/index.html?cross-origin');
+ const text = t(`panel_rewards_view__reward${rewardsCount === 1 ? '' : 's'}`);
return (
-
+ <>
+ {is_expanded && (
+
+
{rewardsCount}
+
{text}
+
+ )}
+
+ >
);
}
@@ -305,9 +288,8 @@ class Rewards extends React.Component {
render() {
return (
-
+
-
);
}
diff --git a/app/panel/components/Summary.jsx b/app/panel/components/Summary.jsx
index 81fec0993..6b4f09186 100644
--- a/app/panel/components/Summary.jsx
+++ b/app/panel/components/Summary.jsx
@@ -718,10 +718,6 @@ class Summary extends React.Component {
* @return {JSX} JSX for rendering the rewards navicon
*/
_renderRewardsNavicon() {
- const { unread_offer_ids } = this.props;
-
- const unreadOffersAvailable = (unread_offer_ids && unread_offer_ids.length > 0) || false;
-
const rewardsNaviconClassNames = ClassNames(
'Summary__rewardsNavicon',
'Summary__rewardsNavicon--absolutely-positioned',
@@ -734,7 +730,6 @@ class Summary extends React.Component {
return (
- {unreadOffersAvailable && }
);
diff --git a/app/panel/components/__tests__/RewardDetail.jsx b/app/panel/components/__tests__/RewardDetail.jsx
deleted file mode 100644
index b35ebf7e3..000000000
--- a/app/panel/components/__tests__/RewardDetail.jsx
+++ /dev/null
@@ -1,179 +0,0 @@
-/**
- * Reward Detail Test 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 renderer from 'react-test-renderer';
-import { shallow } from 'enzyme';
-import RewardDetail from '../BuildingBlocks/RewardDetail';
-
-// Fake the translation function to only return the translation key
-global.t = function(str) {
- return str;
-};
-
-// Fake the Tooltip implementation
-jest.mock('../Tooltip');
-
-describe('app/panel/components/BuildingBlocks/RewardDetail.jsx', () => {
- describe('Snapshot tests with react-test-renderer', () => {
- test('reward detail is rendered with all values present', () => {
- const initialState = {
- actions: {
- updateRewardsData: () => {},
- toggleOffersEnabled: () => {},
- removeOffer: () => {},
- setOfferRead: () => {},
- sendSignal: () => {}
- },
- code: 'test_code',
- conditions: 'test reward conditions',
- description: 'test reward description',
- expires: 1527880170315,
- id: 'test_reward_id',
- logoUrl: 'https://www.ghostery.com/wp-content/themes/ghostery/images/ghostery_logo.svg',
- pictureUrl: 'https://www.ghostery.com/wp-content/uploads/2017/12/simple-detailed-1024x833.png',
- redeemUrl: 'https://www.offer-redeem-test.com',
- redeemText: 'redeem now',
- text: 'test reward title'
- };
- const component = renderer.create( ).toJSON();
- expect(component).toMatchSnapshot();
- });
-
- test('reward detail is rendered with missing text', () => {
- const initialState = {
- actions: {
- updateRewardsData: () => {},
- toggleOffersEnabled: () => {},
- removeOffer: () => {},
- setOfferRead: () => {},
- sendSignal: () => {}
- },
- code: 'test_code',
- conditions: 'test reward conditions',
- description: 'test reward description',
- expires: 1527880170315,
- id: 'test_reward_id',
- logoUrl: 'https://www.ghostery.com/wp-content/themes/ghostery/images/ghostery_logo.svg',
- pictureUrl: 'https://www.ghostery.com/wp-content/uploads/2017/12/simple-detailed-1024x833.png',
- redeemUrl: 'https://www.offer-redeem-test.com',
- redeemText: 'redeem now',
- text: ''
- };
- const component = renderer.create( ).toJSON();
- expect(component).toMatchSnapshot();
- });
-
- test('reward detail is rendered with missing description', () => {
- const initialState = {
- actions: {
- updateRewardsData: () => {},
- toggleOffersEnabled: () => {},
- removeOffer: () => {},
- setOfferRead: () => {},
- sendSignal: () => {}
- },
- code: 'test_code',
- conditions: 'test reward conditions',
- description: '',
- expires: 1527880170315,
- id: 'test_reward_id',
- logoUrl: 'https://www.ghostery.com/wp-content/themes/ghostery/images/ghostery_logo.svg',
- pictureUrl: 'https://www.ghostery.com/wp-content/uploads/2017/12/simple-detailed-1024x833.png',
- redeemUrl: 'https://www.offer-redeem-test.com',
- redeemText: 'redeem now',
- text: 'test reward title'
- };
- const component = renderer.create( ).toJSON();
- expect(component).toMatchSnapshot();
- });
-
- test('reward detail is rendered with missing code', () => {
- const initialState = {
- actions: {
- updateRewardsData: () => {},
- toggleOffersEnabled: () => {},
- removeOffer: () => {},
- setOfferRead: () => {},
- sendSignal: () => {}
- },
- code: '',
- conditions: 'test reward conditions',
- description: 'test reward description',
- expires: 1527880170315,
- id: 'test_reward_id',
- logoUrl: 'https://www.ghostery.com/wp-content/themes/ghostery/images/ghostery_logo.svg',
- pictureUrl: 'https://www.ghostery.com/wp-content/uploads/2017/12/simple-detailed-1024x833.png',
- redeemUrl: 'https://www.offer-redeem-test.com',
- redeemText: 'redeem now',
- text: 'test reward title'
- };
- const component = renderer.create( ).toJSON();
- expect(component).toMatchSnapshot();
- });
-
- test('reward detail is rendered with missing conditions', () => {
- const initialState = {
- actions: {
- updateRewardsData: () => {},
- toggleOffersEnabled: () => {},
- removeOffer: () => {},
- setOfferRead: () => {},
- sendSignal: () => {}
- },
- code: 'test_code',
- conditions: '',
- description: 'test reward description',
- expires: 1527880170315,
- id: 'test_reward_id',
- logoUrl: 'https://www.ghostery.com/wp-content/themes/ghostery/images/ghostery_logo.svg',
- pictureUrl: 'https://www.ghostery.com/wp-content/uploads/2017/12/simple-detailed-1024x833.png',
- redeemUrl: 'https://www.offer-redeem-test.com',
- redeemText: 'redeem now',
- text: 'test reward title'
- };
- const component = renderer.create( ).toJSON();
- expect(component).toMatchSnapshot();
- });
- });
-
- describe('Shallow snapshot tests rendered with Enzyme', () => {
- test('reward detail is rendered correctly the code is copied', () => {
- const initialState = {
- actions: {
- updateRewardsData: () => {},
- toggleOffersEnabled: () => {},
- removeOffer: () => {},
- setOfferRead: () => {},
- sendSignal: () => {}
- },
- code: 'test_code',
- conditions: 'test reward conditions',
- description: 'test reward description',
- expires: 1527880170315,
- id: 'test_reward_id',
- logoUrl: 'https://www.ghostery.com/wp-content/themes/ghostery/images/ghostery_logo.svg',
- pictureUrl: 'https://www.ghostery.com/wp-content/uploads/2017/12/simple-detailed-1024x833.png',
- redeemUrl: 'https://www.offer-redeem-test.com',
- redeemText: 'redeem now',
- text: 'test reward title'
- };
- const component = shallow( );
- expect(component.text()).toEqual(expect.stringContaining('rewards_copy_code'));
- expect(component.text()).not.toEqual(expect.stringContaining('rewards_code_copied'));
- component.setState({ copyText: t('rewards_code_copied') });
- expect(component.text()).not.toEqual(expect.stringContaining('rewards_copy_code'));
- expect(component.text()).toEqual(expect.stringContaining('rewards_code_copied'));
- });
- });
-});
diff --git a/app/panel/components/__tests__/RewardListItem.jsx b/app/panel/components/__tests__/RewardListItem.jsx
deleted file mode 100644
index 888d3c127..000000000
--- a/app/panel/components/__tests__/RewardListItem.jsx
+++ /dev/null
@@ -1,156 +0,0 @@
-/**
- * Reward List Item Test 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 renderer from 'react-test-renderer';
-import { MemoryRouter } from 'react-router';
-import RewardListItem from '../BuildingBlocks/RewardListItem';
-
-// Fake the translation function to only return the translation key
-global.t = function(str) {
- return str;
-};
-
-describe('app/panel/components/BuildingBlocks/RewardListItem.jsx', () => {
- describe('Snapshot tests with react-test-renderer', () => {
- test('reward list item is rendered correctly', () => {
- const initialState = {
- actions: {
- updateRewardsData: () => {},
- toggleOffersEnabled: () => {},
- removeOffer: () => {},
- setOfferRead: () => {},
- sendSignal: () => {}
- },
- disabled: false,
- expires: 1527885633645,
- id: 'test_reward_id',
- index: 0,
- isLong: false,
- logoUrl: 'https://www.ghostery.com/wp-content/themes/ghostery/images/ghostery_logo.svg',
- text: 'test reward title',
- unread: false
- };
- const component = renderer.create(
-
-
-
- ).toJSON();
- expect(component).toMatchSnapshot();
- });
-
- test('reward list item is rendered correctly when disabled', () => {
- const initialState = {
- actions: {
- updateRewardsData: () => {},
- toggleOffersEnabled: () => {},
- removeOffer: () => {},
- setOfferRead: () => {},
- sendSignal: () => {}
- },
- disabled: true,
- expires: 1527885633645,
- id: 'test_reward_id',
- index: 0,
- isLong: false,
- logoUrl: 'https://www.ghostery.com/wp-content/themes/ghostery/images/ghostery_logo.svg',
- text: 'test reward title',
- unread: false
- };
- const component = renderer.create(
-
-
-
- ).toJSON();
- expect(component).toMatchSnapshot();
- });
-
- test('reward list item is rendered correctly when unread', () => {
- const initialState = {
- actions: {
- updateRewardsData: () => {},
- toggleOffersEnabled: () => {},
- removeOffer: () => {},
- setOfferRead: () => {},
- sendSignal: () => {}
- },
- disabled: false,
- expires: 1527885633645,
- id: 'test_reward_id',
- index: 0,
- isLong: false,
- logoUrl: 'https://www.ghostery.com/wp-content/themes/ghostery/images/ghostery_logo.svg',
- text: 'test reward title',
- unread: true
- };
- const component = renderer.create(
-
-
-
- ).toJSON();
- expect(component).toMatchSnapshot();
- });
-
- test('reward list item is rendered correctly when elongated', () => {
- const initialState = {
- actions: {
- updateRewardsData: () => {},
- toggleOffersEnabled: () => {},
- removeOffer: () => {},
- setOfferRead: () => {},
- sendSignal: () => {}
- },
- disabled: false,
- expires: 1527885633645,
- id: 'test_reward_id',
- index: 0,
- isLong: true,
- logoUrl: 'https://www.ghostery.com/wp-content/themes/ghostery/images/ghostery_logo.svg',
- text: 'test reward title',
- unread: false
- };
- const component = renderer.create(
-
-
-
- ).toJSON();
- expect(component).toMatchSnapshot();
- });
-
- test('reward list item is rendered correctly when disabled, unread, and elongated', () => {
- const initialState = {
- actions: {
- updateRewardsData: () => {},
- toggleOffersEnabled: () => {},
- removeOffer: () => {},
- setOfferRead: () => {},
- sendSignal: () => {}
- },
- disabled: true,
- expires: 1527885633645,
- id: 'test_reward_id',
- index: 0,
- isLong: true,
- logoUrl: 'https://www.ghostery.com/wp-content/themes/ghostery/images/ghostery_logo.svg',
- text: 'test reward title',
- unread: true
- };
- const component = renderer.create(
-
-
-
- ).toJSON();
- expect(component).toMatchSnapshot();
- });
- });
-});
diff --git a/app/panel/components/__tests__/__snapshots__/RewardDetail.jsx.snap b/app/panel/components/__tests__/__snapshots__/RewardDetail.jsx.snap
deleted file mode 100644
index 6ca12f909..000000000
--- a/app/panel/components/__tests__/__snapshots__/RewardDetail.jsx.snap
+++ /dev/null
@@ -1,339 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`app/panel/components/BuildingBlocks/RewardDetail.jsx Snapshot tests with react-test-renderer reward detail is rendered with all values present 1`] = `
-
-
-
- test reward title
-
-
- test reward description
-
-
-
-
- test_code
-
-
-
-
- rewards_copy_code
-
-
-
-
- rewards_expires_in_days
-
-
-
- rewards_terms_conditions
-
-
-
-
- redeem now
-
-
-`;
-
-exports[`app/panel/components/BuildingBlocks/RewardDetail.jsx Snapshot tests with react-test-renderer reward detail is rendered with missing code 1`] = `
-
-
-
- test reward title
-
-
- test reward description
-
-
-
-
- rewards_expires_in_days
-
-
-
- rewards_terms_conditions
-
-
-
-
- redeem now
-
-
-`;
-
-exports[`app/panel/components/BuildingBlocks/RewardDetail.jsx Snapshot tests with react-test-renderer reward detail is rendered with missing conditions 1`] = `
-
-
-
- test reward title
-
-
- test reward description
-
-
-
-
- test_code
-
-
-
-
- rewards_copy_code
-
-
-
-
- rewards_expires_in_days
-
-
-
-
- redeem now
-
-
-`;
-
-exports[`app/panel/components/BuildingBlocks/RewardDetail.jsx Snapshot tests with react-test-renderer reward detail is rendered with missing description 1`] = `
-
-
-
- test reward title
-
-
-
-
-
- test_code
-
-
-
-
- rewards_copy_code
-
-
-
-
- rewards_expires_in_days
-
-
-
- rewards_terms_conditions
-
-
-
-
- redeem now
-
-
-`;
-
-exports[`app/panel/components/BuildingBlocks/RewardDetail.jsx Snapshot tests with react-test-renderer reward detail is rendered with missing text 1`] = `
-
-
-
-
- test reward description
-
-
-
-
- test_code
-
-
-
-
- rewards_copy_code
-
-
-
-
- rewards_expires_in_days
-
-
-
- rewards_terms_conditions
-
-
-
-
- redeem now
-
-
-`;
diff --git a/app/panel/components/__tests__/__snapshots__/RewardListItem.jsx.snap b/app/panel/components/__tests__/__snapshots__/RewardListItem.jsx.snap
deleted file mode 100644
index ce577bf0d..000000000
--- a/app/panel/components/__tests__/__snapshots__/RewardListItem.jsx.snap
+++ /dev/null
@@ -1,346 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`app/panel/components/BuildingBlocks/RewardListItem.jsx Snapshot tests with react-test-renderer reward list item is rendered correctly 1`] = `
-
-
-
-
-
-
-
-
- test reward title
-
-
- rewards_expires_in_days
-
-
-
-
-
-`;
-
-exports[`app/panel/components/BuildingBlocks/RewardListItem.jsx Snapshot tests with react-test-renderer reward list item is rendered correctly when disabled 1`] = `
-
-
-
-
-
-
-
-
- test reward title
-
-
- rewards_expires_in_days
-
-
-
-
-
-`;
-
-exports[`app/panel/components/BuildingBlocks/RewardListItem.jsx Snapshot tests with react-test-renderer reward list item is rendered correctly when disabled, unread, and elongated 1`] = `
-
-
-
-
-
-
-
-
- test reward title
-
-
- rewards_expires_in_days
-
-
-
-
-
-`;
-
-exports[`app/panel/components/BuildingBlocks/RewardListItem.jsx Snapshot tests with react-test-renderer reward list item is rendered correctly when elongated 1`] = `
-
-
-
-
-
-
-
-
- test reward title
-
-
- rewards_expires_in_days
-
-
-
-
-
-`;
-
-exports[`app/panel/components/BuildingBlocks/RewardListItem.jsx Snapshot tests with react-test-renderer reward list item is rendered correctly when unread 1`] = `
-
-
-
-
-
-
-
-
- test reward title
-
-
- rewards_expires_in_days
-
-
-
-
-
-`;
diff --git a/app/panel/components/__tests__/__snapshots__/Rewards.jsx.snap b/app/panel/components/__tests__/__snapshots__/Rewards.jsx.snap
index 626e36bba..16ccba52c 100644
--- a/app/panel/components/__tests__/__snapshots__/Rewards.jsx.snap
+++ b/app/panel/components/__tests__/__snapshots__/Rewards.jsx.snap
@@ -107,27 +107,11 @@ exports[`app/panel/components/Rewards.jsx Snapshot tests with react-test-rendere
-
-
-
-
-
-
-
- panel_detail_rewards_loading
-
-
+
`;
diff --git a/app/panel/constants/constants.js b/app/panel/constants/constants.js
index 8f7f8ede5..7c321d3b2 100644
--- a/app/panel/constants/constants.js
+++ b/app/panel/constants/constants.js
@@ -33,8 +33,6 @@ export const TOGGLE_EXPANDED = 'TOGGLE_EXPANDED';
// rewards
export const UPDATE_REWARDS_DATA = 'UPDATE_REWARDS_DATA';
export const TOGGLE_OFFERS_ENABLED = 'TOGGLE_OFFERS_ENABLED';
-export const REMOVE_OFFER = 'REMOVE_OFFER';
-export const SET_OFFER_READ = 'SET_OFFER_READ';
export const SEND_SIGNAL = 'SEND_SIGNAL';
// blocking
diff --git a/app/panel/containers/DetailContainer.js b/app/panel/containers/DetailContainer.js
index 7c5ca97ae..b2e734998 100644
--- a/app/panel/containers/DetailContainer.js
+++ b/app/panel/containers/DetailContainer.js
@@ -27,7 +27,6 @@ import * as actions from '../actions/DetailActions';
const mapStateToProps = state => Object.assign({}, state.detail, state.account, {
is_expanded: state.panel.is_expanded,
enable_offers: state.panel.enable_offers,
- unread_offer_ids: state.panel.unread_offer_ids,
});
/**
* Bind Detailed view action creators using Redux's bindActionCreators
diff --git a/app/panel/reducers/__tests__/rewards.js b/app/panel/reducers/__tests__/rewards.js
index 633295a9a..6b6c57ea4 100644
--- a/app/panel/reducers/__tests__/rewards.js
+++ b/app/panel/reducers/__tests__/rewards.js
@@ -16,16 +16,12 @@ import rewardsReducer from '../rewards';
import {
UPDATE_REWARDS_DATA,
TOGGLE_OFFERS_ENABLED,
- REMOVE_OFFER,
- SET_OFFER_READ,
SEND_SIGNAL
} from '../../constants/constants';
// Copied from app/panel/reducers/rewards.js
const initialState = Immutable({
- rewards: null,
enable_offers: false,
- unread_offer_ids: [],
});
describe('app/panel/reducers/rewards.js', () => {
@@ -52,74 +48,6 @@ describe('app/panel/reducers/rewards.js', () => {
expect(rewardsReducer(initialState, action)).toEqual(updatedState);
});
- test('reducer correctly handles REMOVE_OFFER', () => {
- const data = { id: 'test_reward_id' };
- const action = { data, type: REMOVE_OFFER };
-
- const initState = Immutable({
- rewards: {
- test_reward_id: { reward: 'test' },
- test_reward_id_alt: { reward: 'test_alt' },
- },
- enable_offers: true,
- unread_offer_ids: ['test_reward_id', 'test_reward_id_alt'],
- });
-
- expect(rewardsReducer(initState, action)).toEqual({
- rewards: {
- test_reward_id_alt: { reward: 'test_alt' },
- },
- enable_offers: true,
- unread_offer_ids: ['test_reward_id_alt'],
- });
- });
-
- test('reducer correctly handles SET_OFFER_READ', () => {
- const data = { id: 'test_reward_id' };
- const action = { data, type: SET_OFFER_READ };
-
- const initState = Immutable({
- rewards: {
- test_reward_id: { reward: 'test' },
- test_reward_id_alt: { reward: 'test_alt' },
- },
- enable_offers: true,
- unread_offer_ids: ['test_reward_id', 'test_reward_id_alt'],
- });
-
- expect(rewardsReducer(initState, action)).toEqual({
- rewards: {
- test_reward_id: { reward: 'test' },
- test_reward_id_alt: { reward: 'test_alt' },
- },
- enable_offers: true,
- unread_offer_ids: ['test_reward_id_alt'],
- });
- });
-
- test('reducer correctly handles SET_OFFER_READ when offer is not new', () => {
- const data = { id: 'test_reward_id' };
- const action = { data, type: SET_OFFER_READ };
-
- const initState = Immutable({
- rewards: {
- test_reward_id: { reward: 'test' },
- test_reward_id_alt: { reward: 'test_alt' },
- },
- enable_offers: true,
- unread_offer_ids: ['test_reward_id_alt'],
- });
-
- expect(rewardsReducer(initState, action)).toEqual({
- rewards: {
- test_reward_id: { reward: 'test' },
- test_reward_id_alt: { reward: 'test_alt' },
- },
- enable_offers: true,
- unread_offer_ids: ['test_reward_id_alt'],
- });
- });
-
test('reducer correctly handles SEND_SIGNAL', () => {
const data = {
actionId: 'action_id',
diff --git a/app/panel/reducers/panel.js b/app/panel/reducers/panel.js
index 196417655..756db8c47 100644
--- a/app/panel/reducers/panel.js
+++ b/app/panel/reducers/panel.js
@@ -22,8 +22,6 @@ import {
UPDATE_NOTIFICATION_STATUS,
TOGGLE_CHECKBOX,
TOGGLE_OFFERS_ENABLED,
- REMOVE_OFFER,
- SET_OFFER_READ,
TOGGLE_EXPANDED,
SET_THEME,
CLEAR_THEME,
@@ -252,16 +250,6 @@ export default (state = initialState, action) => {
const enable_offers = action.data.enabled;
return Object.assign({}, state, { enable_offers });
}
- case REMOVE_OFFER:
- case SET_OFFER_READ: {
- const unread_offer_ids = state.unread_offer_ids.slice();
- const idx = unread_offer_ids.indexOf(action.data.id);
- if (idx !== -1) {
- unread_offer_ids.splice(idx, 1);
- return Object.assign({}, state, { unread_offer_ids });
- }
- return state;
- }
case TOGGLE_PROMO_MODAL: {
return {
...state,
diff --git a/app/panel/reducers/rewards.js b/app/panel/reducers/rewards.js
index 7f7d83e8f..52a6f2b6c 100644
--- a/app/panel/reducers/rewards.js
+++ b/app/panel/reducers/rewards.js
@@ -14,16 +14,12 @@
import {
UPDATE_REWARDS_DATA,
TOGGLE_OFFERS_ENABLED,
- REMOVE_OFFER,
- SET_OFFER_READ,
SEND_SIGNAL
} from '../constants/constants';
import { sendRewardMessage } from '../utils/msg';
const initialState = {
- rewards: null,
enable_offers: false,
- unread_offer_ids: [],
};
/**
@@ -44,33 +40,6 @@ export default (state = initialState, action) => {
return Object.assign({}, state, { enable_offers });
}
- case REMOVE_OFFER: {
- // Remove offer from unread array
- const unread_offer_ids = [...state.unread_offer_ids];
- const idx = unread_offer_ids.indexOf(action.data.id);
- if (idx !== -1) {
- unread_offer_ids.splice(idx, 1);
- }
-
- // Remove offer from offers list
- const rewards = Object.assign({}, state.rewards);
- delete rewards[action.data.id];
-
- sendRewardMessage('deleteReward', { offerId: action.data.id });
- return Object.assign({}, state, { unread_offer_ids, rewards });
- }
-
- case SET_OFFER_READ: {
- const unread_offer_ids = [...state.unread_offer_ids];
- const idx = unread_offer_ids.indexOf(action.data.id);
- if (idx !== -1) {
- unread_offer_ids.splice(idx, 1);
- sendRewardMessage('rewardSeen', { offerId: action.data.id });
- return Object.assign({}, state, { unread_offer_ids });
- }
- return state;
- }
-
case SEND_SIGNAL: {
sendRewardMessage('rewardSignal', action.data);
return state;
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/scss/partials/_detail.scss b/app/scss/partials/_detail.scss
index 8ee7a06f3..c07b45528 100644
--- a/app/scss/partials/_detail.scss
+++ b/app/scss/partials/_detail.scss
@@ -65,6 +65,10 @@
}
}
+#content-detail.rewardsView {
+ background-color: #f7f8fb;
+}
+
#content-detail {
@include expanding-panel(66px);
}
diff --git a/app/scss/partials/_rewards.scss b/app/scss/partials/_rewards.scss
index dd42e5d89..4332e8875 100644
--- a/app/scss/partials/_rewards.scss
+++ b/app/scss/partials/_rewards.scss
@@ -13,7 +13,6 @@
// Rewards Panel Component Classes
.RewardsPanel {
- background-color: #ffffff;
}
.RewardsPanel__header {
padding: 10px 13px;
@@ -37,14 +36,11 @@
text-transform: uppercase;
padding-right: 7px;
}
-.RewardsPanel__scroll_content {
- height: 377px;
- overflow-y: scroll;
-}
.RewardsPanel__info {
margin: 0 40px;
text-align: center;
font-size: 14px;
+ background-color: #f7f8fb;
}
.RewardsPanel__reward_icon {
margin: 70px 0 20px;
@@ -53,213 +49,22 @@
.RewardsPanel__learn_more {
margin-top: 10px;
}
-
-// Reward List Item Component Classes
-.RewardListItem {
- height: 85px;
- border: 1px solid #cecece;
- border-left-width: 0;
- border-radius: 0;
- padding: 10px 0 10px 10px;
-
- .flex-grow {
- flex: 1;
- }
-}
-.RewardListItem.RewardListItem--unread + .RewardListItem.RewardListItem--unread,
-.RewardListItem:not(.RewardListItem--unread) + .RewardListItem:not(.RewardListItem--unread) {
- height: 85px;
- border-top: 0;
+.RewardsPanel__rewards_count_wrapper {
+ float: left;
+ margin: 120px 0 0 45px;
}
-.RewardListItem__image_container {
- width: 100px;
- min-width: 100px;
+.RewardsPanel__rewards_count {
+ color: purple;
+ font-size: 48px;
text-align: center;
- padding-right: 8px;
- border-right: 1px solid #cecece;
- margin-right: 18px;
-}
-.RewardListItem__image {
- max-height: 52px;
- width: auto;
-}
-.RewardListItem--greyscale .RewardListItem__image {
- -webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
- filter: grayscale(100%);
-}
-.RewardListItem__benefit {
- color: #4a4a4a;
- font-size: 11px;
- font-weight: 600;
- max-width: 188px;
- line-height: 20px;
- max-height: 40px;
- text-overflow: ellipsis;
- word-wrap: break-word;
-}
-.RewardListItem__title {
- color: #4a4a4a;
- font-size: 11px;
- max-width: 188px;
- max-height: 40px;
- text-overflow: ellipsis;
- word-wrap: break-word;
- margin-bottom: 7px;
-}
-.RewardListItem--greyscale .RewardListItem__text {
- color: #9b9b9b;
-}
-.RewardListItem__expires {
- color: #9b9b9b;
- font-size: 11px;
- max-width: 188px;
-}
-.RewardListItem--elongated .RewardListItem__text,
-.RewardListItem--elongated .RewardListItem__expires {
- max-width: 354px;
-}
-
-.RewardListItem--greyscale .RewardListItem__close_button,
-.RewardListItem--greyscale .RewardListItem__details_link {
- display: none;
-}
-.RewardListItem__close_button {
- line-height: 0;
- padding: 5px 10px;
- margin-top: -5px;
-}
-.RewardListItem__details_link {
- line-height: 0;
- padding: 5px 10px;
- margin-bottom: -5px;
-}
-.RewardListItem__close_button svg,
-.RewardListItem__details_link svg {
- @include transition(fill 0.2s);
-}
-.RewardListItem__close_button svg { fill: #9b9b9b; }
-.RewardListItem__close_button:hover svg { fill: #4a4a4a; }
-
-.RewardListItem__details_link svg { fill: rgba(#4a4a4a, 0); }
-.RewardListItem:hover .RewardListItem__details_link svg { fill: rgba(#4a4a4a, 1); }
-.RewardListItem__close_button:hover + .RewardListItem__details_link svg { fill: rgba(#4a4a4a, 0); }
-
-.RewardListItem--unread {
- border-color: #5b0059;
- border-left-width: 7px;
-}
-.RewardListItem--unread .RewardListItem__image_container {
- border-color: #5b0059;
- margin-left: -7px;
-}
-.RewardListItem--greyscale.RewardListItem--unread,
-.RewardListItem--greyscale.RewardListItem--unread .RewardListItem__image_container {
- border-color: #cecece;
-}
-
-// Reward Detail Component Classes
-.RewardDetail {
- height: 377px;
-}
-.RewardDetail__image_container {
- height: 167px;
- width: 100%;
-}
-.RewardDetail__picture {
- height: 100%;
- width: 100%;
- background-color: #efefef;
- background-repeat: no-repeat;
- background-size: cover;
- background-position: center;
-}
-.RewardDetail__logo {
- position: absolute;
- right: 10px;
- height: 35px;
- width: auto;
-}
-.RewardDetail__benefit {
- margin: 0 27px;
- font-size: 16px;
- font-weight: bold;
- line-height: 24px;
- max-height: 48px;
- color: #4a4a4a;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-.RewardDetail__title {
- margin: 0 17px;
- font-size: 12px;
- font-weight: bold;
- line-height: 1.27;
- max-height: 48px;
- color: #4a4a4a;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-.RewardDetail__description {
- margin: 0 17px 5px 17px;
- font-size: 12px;
- line-height: 1.27;
- max-height: 36px;
- color: #4a4a4a;
}
-.RewardDetail__code_container {
- margin: 0 17px;
- padding: 10px;
- background-color: #efefef;
- border: 1px solid #cccccc;
- border-radius: 3px;
-}
-.RewardDetail__code {
- font-size: 13px;
- color: #494949;
- font-weight: 600;
-}
-.RewardDetail__code input {
- height: 10px;
- width: 10px;
- padding: 0;
- margin: 0;
- display: inline-block;
- opacity: 0;
- cursor: default;
-}
-.RewardDetail__copy {
- font-size: 10px;
- color: #5b005c;
- font-weight: 600;
+.RewardsPanel__rewards_count_title {
+ font-size: 18px;
+ letter-spacing: 1px;
text-transform: uppercase;
}
-.RewardDetail__details_container {
- margin: 0 17px;
-}
-.RewardDetail__expires {
- font-size: 12px;
- font-weight: 600;
- color: #4a4a4a;
- white-space: nowrap;
- text-overflow: ellipsis;
- overflow: hidden;
-}
-.RewardDetail__terms {
- font-size: 11px;
- color: #9b9b9b;
- white-space: nowrap;
- text-overflow: ellipsis;
- overflow: hidden;
-}
-.RewardDetail__redeem_button {
- background-color: #5b0059;
- color: #ffffff;
- font-size: 14px;
- font-weight: 600;
- text-align: center;
- padding: 10px;
- text-transform: uppercase;
- white-space: nowrap;
- text-overflow: ellipsis;
- overflow: hidden;
+.RewardsPanel__myoffrz_iframe {
+ float: right;
+ border: 1px solid silver;
+ border-radius: 7px;
}
diff --git a/app/scss/rewards.scss b/app/scss/rewards.scss
deleted file mode 100644
index 3980001b5..000000000
--- a/app/scss/rewards.scss
+++ /dev/null
@@ -1,614 +0,0 @@
-/**
- * Rewards Content Script Sass
- *
- * 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 Global Partials
-@import "settings"; //includes _colors.scss
-@import './partials/_tooltip';
-
-#ghostery-rewards-app, #ghostery-iframe-container {
- z-index: 2147483647 !important;
- font-family: $body-font-family!important;
- position: fixed;
- top: 30px;
- right: 30px;
-}
-
-#ghostery-iframe-container {
- border: none;
- &.hot-dog {
- height: 59px;
- width: 266px;
- }
-
- &.offer-card {
- width: 268px;
- height: 531px;
- }
-}
-
-.ghostery-rewards-component {
- opacity: 1 !important;
- * {
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- }
-
- .hide {
- visibility: hidden;
- }
-
- a {
- text-decoration: none;
- }
-
- .flex-grow {
- flex: 1;
- }
-
- .hot-dog-container {
- border-radius: 25px;
- background-color: $dark-purple;
- position: relative;
- display: flex;
- height: 50px;
- width: 265px;
- opacity: 1;
- white-space: nowrap;
- background-repeat: no-repeat;
- background-position: left 22px center;
- border-bottom: 0px;
- cursor: pointer;
- }
-
- .ghostery-reward-text {
- line-height: 1.3;
- color: $white;
- font-size: 12px;
- margin-top: 16px;
- margin-left: auto;
- margin-right: auto;
- transition: visibility 1s;
- }
-
- .hot-dog-close {
- width: 21px;
- height: 21px;
- border: 1px solid $dark-purple;
- background-color: $white;
- position: absolute;
- border-radius: 50%;
- right: 6px;
- top: -9px;
- background-repeat: no-repeat;
- background-position: center center;
- background-size: 9px;
- cursor: pointer;
- }
-
- &.ghostery-right {
- right: 30px;
- }
-
- &:hover, &.show {
- .ghostery-reward-close {
- transition: visibility 1000ms;
- visibility: visible;
- }
- .ghostery-reward-text {
- transition: visibility 0s;
- visibility: visible;
- }
- }
-
- .ghostery-reward-card {
- color: $tundora;
- background-color: #f2f2f2;
- width: 265px;
- border: 1px solid #9b9b9b;
- border-radius: 4px;
- text-align: left;
-
- .reward-card-header {
- display: flex;
- height: 36px;
- width: 100%;
-
- .reward-card-close {
- cursor: pointer;
- align-self: center;
- margin-right: 8px;
- margin-left: auto;
- height: 10px;
- width: 10px;
- background-repeat: no-repeat;
- }
-
- .rewards-logo-beta {
- flex: 1;
- height: 13px;
- margin-left: 8px;
- align-self: center;
- background-repeat: no-repeat;
- background-size: auto 13px;
- }
- }
-
- .reward-content-img {
- height: 120px;
- width: 247px;
- display: flex;
- align-items: center;
-
- .img {
- height: 100%;
- width: 100%;
- background-repeat: no-repeat;
- background-size: cover;
- background-position: center;
- }
- }
-
- .reward-content {
- display: flex;
- flex-wrap: wrap;
- flex-direction: column;
- background-color: $white;
- align-items: center;
- margin-left: auto;
- margin-right: auto;
- width: 247px;
- border: 1px solid $dark-purple;
- border-radius: 4px;
-
- .reward-content-header {
- display: flex;
- flex-direction: row;
- height: 48px;
- width: 100%;
- justify-content: flex-end;
- align-items: center;
-
- .reward-company-logo {
- height: 38px;
- display: flex;
- align-items: center;
-
- img {
- height: 100%;
- object-fit: contain;
- }
- }
-
- .reward-settings-kebab {
- cursor: pointer;
- width: 20px;
- height: 37px;
- background-repeat: no-repeat;
- background-position: 6px;
- }
-
- }
-
- .reward-content-detail {
- display: flex;
- flex-direction: column;
- width: 220px;
- margin-bottom: 9px;
- color: $tundora;
-
- .reward-benefit {
- margin-top: 10px;
- margin-bottom: 12px;
- font-size: 25px;
- line-height: 26px;
- white-space: nowrap;
- // text-overflow: ellipsis;
- overflow: hidden;
- width: 100%;
- min-height: 26px;
- -ms-hyphens: auto;
- -moz-hyphens: auto;
- -webkit-hyphens: auto;
- hyphens: auto;
- word-break: break-word;
- word-wrap: break-word;
- }
-
- .reward-headline {
- font-size: 13px;
- font-weight: 500;
- line-height: 13px;
- line-height: 15px;
- -ms-hyphens: auto;
- -moz-hyphens: auto;
- -webkit-hyphens: auto;
- hyphens: auto;
- word-break: break-word;
- word-wrap: break-word;
- }
-
- .reward-description {
- margin-top: 14px;
- font-size: 13px;
- line-height: 15px;
- -ms-hyphens: auto;
- -moz-hyphens: auto;
- -webkit-hyphens: auto;
- hyphens: auto;
- word-break: break-word;
- word-wrap: break-word;
- }
-
- }
-
- .reward-code {
- display: flex;
- width: 225px;
- height: 32px;
- border: 1px solid #dadada;
- border-radius: 5px;
- background-color: #f2f2f2;
-
- div {
- flex: 1;
- user-select: text;
- margin-left: 8px;
- align-self: center;
- font-size: 13px;
- font-weight: 500;
- border: 0px;
- background-color: transparent;
- white-space: nowrap;
- text-overflow: ellipsis;
- max-width: 50%;
- overflow: hidden;
- .reward-code-input {
- opacity: 0;
- position: absolute;
- z-index: -1;
- }
- }
-
- a {
- text-align: right;
- align-self: center;
- margin-right: 8px;
- margin-left: auto;
- color: $dark-purple;
- font-size: 10px;
- font-weight: $global-weight-bold;
- cursor: pointer;
- text-transform: uppercase;
- }
-
- }
-
- .reward-content-footer {
- display: flex;
- width: 225px;
- height: 46px;
- font-size: 11px;
- span {
- margin-top: 15px;
- flex: 1;
- }
- .reward-terms {
- margin-top: 15px;
- color: $tundora;
- }
- }
-
- .reward-redeem {
- color: $white;
- background-color: $dark-purple;
- width: 100%;
- height: 41px;
- text-align: center;
- line-height: 41px;
- font-size: 14px;
- border: 0px;
- cursor: pointer;
- }
- }
-
- .reward-footer {
- display: flex;
- height: 32px;
-
- .reward-feedback {
- flex: 2;
- align-self: center;
- margin-left: 8px;
-
- .rewards-smiley {
-
- }
-
- .rewards-dd-arrow {
-
- }
-
- a {
- cursor: pointer;
- font-size: 12px;
- color: #6A7E90;
- }
- }
-
- .reward-powered-by-myoffrz {
- width: 98px;
- cursor: pointer;
- }
-
- .reward-ghosty {
- flex: 1;
- background-repeat: no-repeat;
- background-position: center right;
- height: 100%;
- align-self: flex-end;
- margin-right: 8px;
- }
- }
- }
-
- .rewards-popup-container {
- width: 100%;
- height: 100%;
- position: absolute;
- text-align: center;
- color: $white;
- }
-
- .rewards-settings-container {
- .rewards-settings {
- color: $tundora;
- position: absolute;
- margin-top: -10px;
- background-color: $white;
- border: 1px solid #9b9b9b;
- border-radius: 4px;
- box-shadow: 0px 4px 10px grey;
- display: flex;
- flex-direction: column;
- text-align: left;
- line-height: 2;
- padding: 5px;
- margin-left: -148px;
-
- a {
- color: $tundora;
- }
-
- .about, .settings, .delete, .disable {
- font-size: 12px;
- flex: 1;
- display: flex;
- align-items: center;
- padding: 0px 10px;
- font-weight: 500;
- cursor: pointer;
- user-select: none;
- &:hover {
- background: $porcelain;
- }
- }
-
- .about {
- align-items: flex-end;
- }
-
- .delete {
- align-items: flex-start;
- }
- }
- }
-
- .rewards-notification-container {
- position: absolute;
- top: 0;
- right: 0;
- width: 100%;
- height: 100%;
- max-height: 600px;
- max-width: 300px;
- animation: fadein 0.5s;
- -webkit-animation: fadein 0.5s;
-
- @keyframes fadein {
- from { opacity: 0; }
- to { opacity: 1; }
- }
- @-webkit-keyframes fadein {
- from { opacity: 0; }
- to { opacity: 1; }
- }
-
-
- .rewards-notification-optout-image-wrapper {
- height: 80%;
- img {
- width: 100%;
- }
- }
-
- .rewards-notification {
- margin-top: 17px;
- margin-left: auto;
- margin-right: auto;
- height: 161px;
- width: 208px;
- background-color: $dark-purple;
- border: 2px solid transparent;
- border-radius: 4px;
- display: flex;
- flex-direction: column;
- font-size: 13px;
- line-height: 2;
-
- &.first-prompt {
- margin-top: 37px;
- height: calc(100% - 74px);
- width: 244px;
- background-color: $white;
- border: 2px solid $dark-purple;
- color: black;
- }
-
- .notification-text {
- margin: 0px 22px 0px 22px;
- }
-
- .notification-text.first-prompt {
- margin: unset;
- padding-left: 16px;
- text-align: left;
- line-height: 20px;
- height: 100%;
- overflow: hidden;
-
- .first-prompt-labels {
- font-size: 9px;
- img {
- margin-bottom: -2px;
- }
- }
-
- .first-prompt-label {
- text-transform: uppercase;
- color: silver;
- padding-left: 3px;
- padding-right: 6px;
- }
-
- .first-prompt-headline {
- color: $dark-purple;
- font-size: 14px;
- font-weight: 700;
- padding-top: 11px;
- padding-bottom: 5px;
- }
-
- a {
- color: black;
- }
- }
-
- a {
- text-decoration: underline;
- cursor: pointer;
- }
-
- .close {
- cursor: pointer;
- background-repeat: no-repeat;
- height: 10px;
- width: 10px;
- align-self: flex-end;
- margin: 10px 10px 0px 0px;
- }
-
- .notification-buttons {
- display: flex;
- justify-content: center;
- flex-direction: row;
- .btn {
- width: 60px;
- height: 30px;
- border-radius: 3px;
- text-transform: uppercase;
- }
- &.first-prompt {
- .btn {
- width: 104px;
- }
- button {
- &:nth-child(1) {
- background-color: $dark-purple;
- color: $white;
- &:hover {
- background-color: $dark-purple;
- color: $white;
- }
- }
- &:nth-child(2) {
- border: 1px solid $dark-purple;
- background-color: transparent;
- color: $dark-purple;
- &:hover {
- border: 1px solid $dark-purple;
- background-color: transparent;
- color: $dark-purple;
- }
- }
- }
- }
- button {
- cursor: pointer;
- font-weight: bold;
- transition: background-color 0.25s ease-out, color 0.25s ease-out;
- margin-top: 10px;
- margin-bottom: 10px;
- &:nth-child(1) {
- margin-right:5px;
- color:$dark-purple;
- border: 2px solid $dark-purple;
- }
- &:nth-child(2) {
- margin-left:5px;
- border: 2px solid transparent;
- &:hover {
- border: 2px solid $dark-purple;
- }
- }
- &:hover{
- background-color: $dark-purple;
- color: $white;
- }
- }
- }
- }
- .rewards-notification.second-prompt{
- .notification-buttons {
- button{
- &:nth-child(1) {
- background-color: $dark-purple;
- color: $white;
- }
- &:hover {
- background-color: #D8D8D8;
- border-color: #D8D8D8;
- color: $black;
- }
- }
- }
- }
- }
-
- .rewards-notification-overlay {
- height: 100%;
- width: 100%;
- background-color: #eee;
- position: absolute;
- opacity: .6;
- }
-
- .btn {
-
- }
-
-}
-
-#ghostery-rewards-app.iframe-child {
- top: 9px;
- right: 1px;
-}
diff --git a/app/shared-components/PlusPromoModal/PlusPromoModal.jsx b/app/shared-components/PlusPromoModal/PlusPromoModal.jsx
deleted file mode 100644
index a85c5bf0a..000000000
--- a/app/shared-components/PlusPromoModal/PlusPromoModal.jsx
+++ /dev/null
@@ -1,174 +0,0 @@
-/**
- * Plus 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 PropTypes from 'prop-types';
-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
- * @memberof SharedComponents
- */
-const PlusPromoModal = (props) => {
- const {
- show,
- location,
- handleSelectBasicClick,
- handleSelectPlusClick,
- handleSignInClick,
- } = props;
-
- const isInHub = location === 'hub';
- const isInPanel = location === 'panel';
-
- const locationClassName = {
- 'in-hub': isInHub,
- 'in-panel': location === 'panel'
- };
- const contentClassNames = ClassNames(
- 'PlusPromoModal__content',
- 'flex-container',
- 'flex-dir-column',
- 'align-middle',
- 'initial',
- locationClassName
- );
- const optionsContainerClassNames = ClassNames(
- 'PlusPromoModal__options-container',
- 'full-width',
- locationClassName
- );
- const optionsDecriptionClassNames = ClassNames(
- 'PlusPromoModal__option-description-item',
- locationClassName
- );
- const chooseYourPlanClassNames = ClassNames(
- 'PlusPromoModal__choose-your-plan',
- locationClassName
- );
- const recommendedBannerClassNames = ClassNames(
- 'PlusPromoModal__recommended-banner',
- locationClassName
- );
- const optionDescriptionBoxClassNames = ClassNames(
- 'PlusPromoModal__option-description-box',
- locationClassName
- );
- const buttonBackgroundClassNames = ClassNames(
- 'PlusPromoModal__buttons-background',
- 'initial',
- locationClassName
- );
-
- return (
-
-
-
- {isInHub && (
-
- {t('ghostery_is_ready')}
-
- )}
-
- {isInHub ? t('choose_your_privacy_plan') : t('choose_your_ghostery_privacy_plan')}
-
-
-
-
-
-
{t('ghostery_basic')}
-
-
- 0
-
- {t('per_month')}
-
-
-
{t('faster_cleaner_browsing')}
-
{t('blocks_ads')}
-
{t('blocks_trackers')}
-
{t('data_protection')}
-
-
-
-
-
-
-
-
{t('recommended')}
-
-
{t('ghostery_plus')}
-
-
- {t('plus_monthly_subscription_price_number')}
-
- {t('per_month')}
-
-
-
{t('all_basic_features_plus_COLON')}
-
-
-
- {t('historical_tracker_stats')}
-
-
-
-
-
- {t('priority_support')}
-
-
-
-
-
- {t('new_color_themes')}
-
-
-
-
-
-
-
-
- {t('select_basic')}
-
-
- {t('select_plus')}
-
- {isInPanel && (
-
- {t('already_subscribed_sign_in')}
-
- )}
-
-
-
- );
-};
-
-// PropTypes ensure we pass required props of the correct type
-PlusPromoModal.propTypes = {
- show: PropTypes.bool.isRequired,
- location: PropTypes.string.isRequired,
- handleSelectBasicClick: PropTypes.func.isRequired,
- handleSelectPlusClick: PropTypes.func.isRequired,
- handleSignInClick: PropTypes.func,
-};
-
-PlusPromoModal.defaultProps = {
- handleSignInClick: () => {},
-};
-
-export default PlusPromoModal;
diff --git a/app/shared-components/PlusPromoModal/PlusPromoModal.scss b/app/shared-components/PlusPromoModal/PlusPromoModal.scss
deleted file mode 100644
index 897a73d0d..000000000
--- a/app/shared-components/PlusPromoModal/PlusPromoModal.scss
+++ /dev/null
@@ -1,320 +0,0 @@
-/**
- * Plus Promo Modal Sass
- *
- * 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
- */
-
-// Plus 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 {
- margin-top: 21px;
-}
-
-.PlusPromoModal__header {
- font-size: 20px;
- font-weight: bold;
- font-family: $standard-font-family;
- padding: 0 15px;
- text-align: center;
-}
-
-.PlusPromoModal__description {
- width: 350px;
- text-align: center;
- font-size: 18px;
- font-weight: 500;
- font-family: $standard-font-family
-}
-
-.PlusPromoModal__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;
- }
-}
-
-.PlusPromoModal__buttons-background {
- background-color: #e7ecee;
- margin-bottom: 3px;
- width: 99%;
- height: 72px;
- 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;
- }
-}
-
-.PlusPromoModal__thanks-for-download {
- padding-top: 30px;
- font-size: 26px;
- font-weight: bold;
- text-align: center;
-}
-
-.PlusPromoModal__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;
- }
-}
-
-.PlusPromoModal__options-container {
- display: flex;
- justify-content: space-around;
- &.in-hub {}
- &.in-panel {}
-}
-
-.PlusPromoModal__option-container {
- display: flex;
- align-items: center;
- flex-direction: column;
-}
-
-.PlusPromoModal__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;
- }
-}
-
-.PlusPromoModal__recommended-banner {
- position: absolute;
- font-family: $standard-font-family;
-
- &.in-hub {
- left: -30px;
- top: -30px;
- }
-
- &.in-panel {
- left: -30px;
- top: -32px;
- }
-}
-
-.PlusPromoModal__recommended-banner-text {
- position: relative;
- left: 15px;
- top: -47px;
- transform: rotate(-15deg);
- color: white;
- font-size: 16px;
- font-weight: bold;
-}
-
-.PlusPromoModal__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; }
-}
-
-.PlusPromoModal__price-text {
- line-height: 1.3;
- text-align: center;
-
- &.basic { color: #1dafed; }
- &.plus { color: #ebbf73; }
-}
-
-.PlusPromoModal__currency-sign {
- font-family: $condensed-font-family;
- font-size: 30px;
- font-weight: bold;
-}
-
-.PlusPromoModal__amount {
- vertical-align: middle;
- font-family: $standard-font-family;
- font-size: 58px;
- font-weight: normal;
-}
-
-.PlusPromoModal__per-month {
- vertical-align: sub;
- font-family: $condensed-font-family;
- font-size: 18px;
- font-weight: bold;
-}
-
-.PlusPromoModal__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;
- }
-}
-
-.PlusPromoModal__check-icon {
- padding-right: 10px;
-}
-
-.PlusPromoModal__plus-option-description-item-container {
- display: flex;
- justify-content: center;
-}
-
-.PlusPromoModal__button-container {
- display: flex;
- margin-bottom: 10px;
- align-self: center;
-}
-
-.PlusPromoModal__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;
-
- &.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;
- }
-
- &.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);
- }
-
- &.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;
- }
-
- .side-padded {
- padding: 0px 20px 0px; // more localization-proof than hardcoding width
- }
-
- .button-text {
- color: white;
- text-decoration: none;
- }
-}
-
-.PlusPromoModal__text-link-container {
- display: flex;
- justify-content: space-evenly;
-}
-
-.PlusPromoModal__text-link {
- margin-left: 10px;
- margin-right: 10px;
- font-size: 13px;
- font-family: $standard-font-family;
- color: #4a4a4a;
- text-decoration: underline;
- text-align: center;
- cursor: pointer;
- &.sign-in {
- margin-top: 5px;
- width: 100%;
- }
-}
diff --git a/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx
new file mode 100644
index 000000000..d7163fb3c
--- /dev/null
+++ b/app/shared-components/PremiumPromoModal/PremiumPromoModal.jsx
@@ -0,0 +1,139 @@
+/**
+ * Premium 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 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
+ * @return {JSX} JSX for rendering a Premium Promo Modal
+ * @memberof SharedComponents
+ */
+const PremiumPromoModal = (props) => {
+ const {
+ show,
+ location,
+ handleTryMidnightClick,
+ handleGetPlusClick,
+ handleKeepBasicClick,
+ handleGoAwayClick,
+ handleXClick,
+ } = props;
+
+ const isInHub = location === 'hub';
+ const isInPanel = location === 'panel';
+
+ const contentClassNames = ClassNames(
+ 'PremiumPromoModal__content',
+ 'flex-container',
+ 'flex-dir-column',
+ 'align-middle',
+ );
+
+ return (
+
+
+ {isInPanel && (
+
+ )}
+
+
+
+
{t('try_ghostery_midnight')}
+
+
+
{t('seven_day_free_trial')}
+
+
+ {t('full_coverage_protection_promise')}
+
+
+
+
+
+
+ {t('system_wide_tracker_and_ad_blocking')}
+
+
+
+
+
+ {t('built_in_vpn')}
+
+
+
+
+
+
+
+ {t('custom_whitelist_options')}
+
+
+
+
+
+ {t('historical_tracking_insights')}
+
+
+
+
+
+
+
+ {t('download_for_free')}
+
+
+
+
+ {t('support_ghostery_for_2_instead')}
+
+ {isInHub && (
+
+ {t('no_thanks_continue_with_basic')}
+
+ )}
+ {isInPanel && (
+
+ {t('no_thanks_turn_promos_off')}
+
+ )}
+
+
+
+
+ );
+};
+
+
+// PropTypes ensure we pass required props of the correct type
+PremiumPromoModal.propTypes = {
+ show: PropTypes.bool.isRequired,
+ location: PropTypes.string.isRequired,
+ handleTryMidnightClick: PropTypes.func.isRequired,
+ handleGetPlusClick: PropTypes.func.isRequired,
+ handleKeepBasicClick: PropTypes.func,
+ handleGoAwayClick: PropTypes.func,
+ handleXClick: PropTypes.func,
+};
+
+const noop = () => {};
+PremiumPromoModal.defaultProps = {
+ handleKeepBasicClick: noop,
+ handleGoAwayClick: noop,
+ handleXClick: noop,
+};
+
+export default PremiumPromoModal;
diff --git a/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss b/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss
new file mode 100644
index 000000000..f8258d80c
--- /dev/null
+++ b/app/shared-components/PremiumPromoModal/PremiumPromoModal.scss
@@ -0,0 +1,166 @@
+/**
+ * Premium Promo Modal Sass
+ *
+ * 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
+ */
+
+// 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;
+
+.PremiumPromoModal__content {
+ position: relative;
+ z-index: 10;
+ width: 518px;
+ height: 437px;
+ border: solid 1.9px #720174;
+ background-color: #f7f7f7;
+}
+
+.PremiumPromoModal__midnight-logo {
+ width: 177px;
+ height: 106px;
+ margin: 22px 0px 16px;
+ background-image: url('/app/images/panel/midnight-logo.svg');
+}
+
+.PremiumPromoModal__header {
+ 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 22px;
+ width: 438px;
+ text-align: center;
+ font-size: 18px;
+ font-weight: bold;
+ line-height: 1.5;
+ color: #4A4A4A;
+}
+
+.PremiumPromoModal__features-container {
+ display: flex;
+ width: 100%;
+ margin-bottom: 28px;
+}
+
+.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__buttons-background {
+ background-color: #e7ecee;
+ margin-bottom: 3px;
+ width: 99%;
+ height: 107px;
+ z-index: -1;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-evenly
+}
+
+.PremiumPromoModal__button-container {
+ display: flex;
+ justify-content: center;
+}
+
+.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%);
+
+ cursor: pointer;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ font-family: $condensed-font-family;
+ font-size: 14px;
+ font-weight: bold;
+ letter-spacing: 0.5px;
+ text-align: center;
+ color: #ffffff;
+
+ transition: background-color 0.25s ease-out, color 0.25s ease-out;
+
+ &:hover {
+ background-image: linear-gradient(101deg, #A80AAB 19%, #41BCEA 100%);
+ }
+
+ text-transform: uppercase;
+}
+
+.PremiumPromoModal__text-link-container {
+ display: flex;
+ justify-content: space-between;
+}
+
+.PremiumPromoModal__text-link {
+ margin-left: 10px;
+ margin-right: 10px;
+ font-size: 15px;
+ font-family: $standard-font-family;
+ color: #4a4a4a;
+ text-decoration: underline;
+ text-align: center;
+ cursor: pointer;
+}
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/manifest.json b/manifest.json
index 7de9f2855..3ea4b2078 100644
--- a/manifest.json
+++ b/manifest.json
@@ -6,11 +6,13 @@
"strict_min_version": "52.0"
}
},
+ "debug": true,
+ "log": true,
"author": "Ghostery",
"name": "__MSG_name__",
"short_name": "Ghostery",
- "version": "8.4.5",
- "version_name": "8.4.5",
+ "version": "8.4.6",
+ "version_name": "8.4.6",
"default_locale": "en",
"description": "__MSG_short_description__",
"icons": {
@@ -98,6 +100,9 @@
"minimum_opera_version": "45",
"web_accessible_resources": [
"app/images/*",
- "dist/css/rewards_styles.css"
+ "dist/css/rewards_styles.css",
+ "cliqz/offers-cc/index.html",
+ "cliqz/offers-reminder/index.html",
+ "cliqz/popup-notification/images/*"
]
-}
\ No newline at end of file
+}
diff --git a/package.json b/package.json
index d1ff63e79..16c9ac1c9 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
"@cliqz/adblocker-circumvention": "^1.3.1",
"@cliqz/url-parser": "^1.0.4",
"base64-js": "^1.3.1",
- "browser-core": "https://github.com/cliqz-oss/browser-core/releases/download/v7.40.1/browser-core-7.40.1.tgz",
+ "browser-core": "https://github.com/cliqz-oss/browser-core/releases/download/v7.40.2/browser-core-7.40.2.tgz",
"classnames": "^2.2.5",
"d3": "^5.12.0",
"foundation-sites": "^6.4.4-rc1",
@@ -59,7 +59,6 @@
"react-markdown": "^4.2.2",
"react-redux": "^7.1.1",
"react-router-dom": "^5.1.2",
- "react-shadow-dom-retarget-events": "^1.0.10",
"react-svg": "^10.0.22",
"redux": "^4.0.4",
"redux-object": "^0.5.10",
diff --git a/src/background.js b/src/background.js
index 771dd5b98..4c85752b2 100644
--- a/src/background.js
+++ b/src/background.js
@@ -20,7 +20,7 @@
*/
import { debounce, every, size } from 'underscore';
import moment from 'moment/min/moment-with-locales.min';
-import cliqz, { prefs } from './classes/Cliqz';
+import cliqz from './classes/Cliqz';
// object class
import Events from './classes/EventHandlers';
// static classes
@@ -69,7 +69,6 @@ const {
const IS_EDGE = (BROWSER_INFO.name === 'edge');
const IS_FIREFOX = (BROWSER_INFO.name === 'firefox');
const VERSION_CHECK_URL = `https://${CDN_SUB_DOMAIN}.ghostery.com/update/version`;
-const OFFERS_HANDLER_ID = 'ghostery';
const REAL_ESTATE_ID = 'ghostery';
const onBeforeRequest = events.onBeforeRequest.bind(events);
const onHeadersReceived = events.onHeadersReceived.bind(events);
@@ -81,14 +80,11 @@ const moduleMock = {
};
const humanweb = cliqz.modules['human-web'];
const { adblocker, antitracking, hpnv2 } = cliqz.modules;
-const messageCenter = cliqz.modules['message-center'] || moduleMock;
const offers = cliqz.modules['offers-v2'] || moduleMock;
const insights = cliqz.modules.insights || moduleMock;
// add ghostery module to expose ghostery state to cliqz
cliqz.modules.ghostery = new GhosteryModule();
-let OFFERS_ENABLE_SIGNAL;
-
/**
* Enable or disable specified module.
* @memberOf Background
@@ -106,24 +102,6 @@ function setCliqzModuleEnabled(module, enabled) {
return Promise.resolve();
}
-/**
- * Register/unregister real estate with Offers core module.
- * @memberOf Background
- * @param {Object} offersModule offers module
- * @param {Boolean} register true - register, false - unregister
- */
-function registerWithOffers(offersModule, register) {
- if (!offersModule.isEnabled) {
- return Promise.resolve();
- }
-
- log('REGISTER WITH OFFERS CALLED', register);
- return offersModule.action(register ? 'registerRealEstate' : 'unregisterRealEstate', { realEstateID: REAL_ESTATE_ID })
- .catch(() => {
- log(`FAILED TO ${register ? 'REGISTER' : 'UNREGISTER'} REAL ESTATE WITH OFFERS CORE`);
- });
-}
-
/**
* Check and fetch a new tracker library every hour as needed
* @memberOf Background
@@ -267,6 +245,24 @@ function getSiteData() {
}));
}
+/**
+ * Register/unregister real estate with Offers core module.
+ * @memberOf Background
+ * @param {Object} offersModule offers module
+ * @param {Boolean} register true - register, false - unregister
+ */
+function registerWithOffers(offersModule, register) {
+ if (!offersModule.isEnabled) {
+ return Promise.resolve();
+ }
+
+ log('REGISTER WITH OFFERS CALLED', register);
+ return offersModule.action(register ? 'registerRealEstate' : 'unregisterRealEstate', { realEstateID: REAL_ESTATE_ID })
+ .catch(() => {
+ log(`FAILED TO ${register ? 'REGISTER' : 'UNREGISTER'} REAL ESTATE WITH OFFERS CORE`);
+ });
+}
+
/**
* @todo consider never return anything explicitly from message handlers
* as we never make callback calls asynchronously.
@@ -372,15 +368,9 @@ function handleGhosteryDotCom(name, message, tab_id) {
*/
function handleNotifications(name, message, tab_id, callback) {
if (name === 'dismissCMPMessage') {
- if (utils.isCliqzOffer(message.cmp_data)) {
- reportCliqzOffer(message);
- } else if (cmp.CMP_DATA && cmp.CMP_DATA.length) {
+ if (cmp.CMP_DATA && cmp.CMP_DATA.length) {
cmp.CMP_DATA.splice(0, 1);
}
- } else if (name === 'cmpMessageShown') {
- if (utils.isCliqzOffer(message.cmp_data)) {
- reportCliqzOffer(message);
- }
} else if (name === 'openTab') {
utils.openNewTab(message);
if (callback) {
@@ -498,34 +488,15 @@ function handleBlockedRedirect(name, message, tab_id, callback) {
*/
function handleRewards(name, message, callback) {
switch (name) {
- case 'rewardSignal':
+ case 'rewardSignal': // e.g. hub_open | hub_closed
rewards.sendSignal(message);
break;
- case 'rewardSeen':
- rewards.markRewardRead(message.offerId);
- button.update();
- break;
- case 'deleteReward':
- rewards.markRewardRead(message.offerId);
- rewards.deleteReward(message.offerId);
- button.update();
- break;
- case 'rewardsPromptAccepted':
- conf.rewards_accepted = true;
- break;
- case 'rewardsPromptOptedIn':
- conf.rewards_opted_in = true;
- break;
case 'ping':
metrics.ping(message);
break;
case 'setPanelData':
if (message.hasOwnProperty('enable_offers')) {
- if (!offers.isEnabled && message.enable_offers === true) {
- OFFERS_ENABLE_SIGNAL = message.signal;
- } else if (message.enable_offers === false) {
- rewards.sendSignal(message.signal);
- }
+ rewards.sendSignal(message.signal);
panelData.set({ enable_offers: message.enable_offers });
}
return callback();
@@ -542,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;
@@ -622,20 +593,12 @@ function handleGhosteryHub(name, message, callback) {
break;
}
case 'SET_GHOSTERY_REWARDS': {
- const { enable_ghostery_rewards } = message;
- if (!offers.isEnabled && enable_ghostery_rewards === true) {
- OFFERS_ENABLE_SIGNAL = {
- actionId: 'rewards_on',
- origin: 'ghostery-setup-flow',
- type: 'action-signal',
- };
- } else if (enable_ghostery_rewards === false) {
- rewards.sendSignal({
- actionId: 'rewards_off',
- origin: 'ghostery-setup-flow',
- type: 'action-signal',
- });
- }
+ const { enable_ghostery_rewards = true } = message;
+ rewards.sendSignal({
+ actionId: `rewards_${enable_ghostery_rewards ? 'on' : 'off'}`,
+ origin: 'ghostery-setup-flow',
+ type: 'action-signal',
+ });
panelData.set({ enable_offers: enable_ghostery_rewards });
callback({ enable_ghostery_rewards });
break;
@@ -681,41 +644,6 @@ function handlePurplebox(name, message) {
return false;
}
-/**
- * Reformats messages coming from context script and sends them to Cliqz.
- * @memberOf Background
- *
- * @param {Object} message message data
- */
-function reportCliqzOffer(message) {
- const { offer_id } = message.cmp_data.data.offer_info;
- const msgToOffersCore = {
- // OFFERS_HANDLER_ID is scoped to background.js
- // If we ever need it elswhere - we can make it the property of
- // globals (src/classes/Globals)
- origin: OFFERS_HANDLER_ID,
- type: 'offer-action-signal',
- data: {
- action_id: '',
- offer_id
- }
- };
- // check the type of the message
- if (message.reason === 'offerShown') {
- msgToOffersCore.data.action_id = 'offer_shown';
- } else if (message.reason === 'closeButton') {
- msgToOffersCore.data.action_id = 'offer_closed';
- } else if (message.reason === 'link') {
- msgToOffersCore.data.action_id = 'offer_ca_action';
- } else {
- // TODO: @serge how do we log here an error?
- log('[offers_log]: unknown message reason: ', message.reason);
- return;
- }
- const cliqzCore = cliqz.modules.core;
- cliqzCore.action('publishEvent', 'offers-recv-ch', msgToOffersCore);
-}
-
/**
* Aggregated handler for
runtime.onMessage
*
@@ -1078,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') {
@@ -1123,20 +1051,14 @@ function initializeDispatcher() {
});
dispatcher.on('conf.save.enable_offers', (enableOffersIn) => {
button.update();
- let firstStep = Promise.resolve();
+ const firstStep = Promise.resolve();
let enableOffers = enableOffersIn;
if (IS_CLIQZ) {
enableOffers = false;
- } else if (!enableOffers) {
- const actions = cliqz &&
- cliqz.modules['offers-v2'] &&
- cliqz.modules['offers-v2'].background &&
- cliqz.modules['offers-v2'].background.actions;
- if (actions) {
- firstStep = actions.flushSignals();
- }
- OFFERS_ENABLE_SIGNAL = undefined;
+ } else if (!enableOffers && cliqz.modules['offers-v2'].isEnabled) {
+ cliqz.modules['offers-v2'].action('flushSignals');
}
+
const toggleModule = () => setCliqzModuleEnabled(offers, enableOffers);
const toggleConnection = () => registerWithOffers(offers, enableOffers);
if (enableOffers) {
@@ -1222,7 +1144,7 @@ function setupABTest() {
});
}
if (abtest.hasTest('antitracking_whitelist2')) {
- prefs.set('attrackBloomFilter', false);
+ cliqz.prefs.set('attrackBloomFilter', false);
}
// overlay search AB test
// if (abtest.hasTest('overlay_search')) {
@@ -1329,20 +1251,6 @@ adblocker.on('enabled', () => {
*/
offers.on('enabled', () => {
offers.isReady().then(() => {
- log('IN OFFERS ON ENABLED', offers, messageCenter);
- if (OFFERS_ENABLE_SIGNAL) {
- rewards.sendSignal(OFFERS_ENABLE_SIGNAL);
-
- const actions = cliqz &&
- cliqz.modules['offers-v2'] &&
- cliqz.modules['offers-v2'].background &&
- cliqz.modules['offers-v2'].background.actions;
- if (actions) {
- actions.flushSignals();
- }
-
- OFFERS_ENABLE_SIGNAL = undefined;
- }
if (DEBUG) {
offers.action('setConfiguration', {
config_location: 'de',
@@ -1353,86 +1261,7 @@ offers.on('enabled', () => {
offersTelemetryFreq: '10'
});
}
- registerWithOffers(offers, true)
- .then(() => {
- setCliqzModuleEnabled(messageCenter, true);
- });
- });
-});
-
-/**
- * Set listener for 'enabled' event for Offers module.
- * It registers message handler for messages with the offers.
- * This handler adds incoming message data to the array of
- * notification messages (CMP_DATA) to be eventually displayed.
- * @memberOf Background
- */
-messageCenter.on('enabled', () => {
- messageCenter.isReady().then(() => {
- log('IN MESSAGE CENTER ON ENABLED', offers, messageCenter);
- // const messageCenter = cliqz.modules['message-center'];
- return messageCenter.action('registerMessageHandler', OFFERS_HANDLER_ID, (msg) => {
- // offers enabled at the moment when message received
- messageCenter.action('hideMessage', OFFERS_HANDLER_ID, msg);
- msg.Dismiss = 1; // to be immediately dismissed once shown
- /**
- * We changed the message structure here so we need to map
- * to the new way on ghostery 8 after nav-ext 1.18
- *
- * {
- * id: offerInfoCpy.display_id,
- * Message: offerInfoCpy.ui_info.template_data.title,
- * Link: offerInfoCpy.ui_info.template_data.call_to_action.url,
- * LinkText: offerInfoCpy.ui_info.template_data.call_to_action.text,
- * type: 'offers',
- * origin: 'cliqz',
- * data: {
- * offer_info: {
- * offer_id: data.offer_data.offer_id,
- * offer_urls: urlsToShow
- * }
- * }
- * }
- */
- // first check that the message is from core and is the one we expect
- if (msg.origin === 'offers-core' &&
- msg.type === 'push-offer' &&
- msg.data.offer_data
- ) {
- log('RECEIVED OFFER', msg);
-
- const unreadIdx = rewards.unreadOfferIds.indexOf(msg.data.offer_id);
- if (unreadIdx !== -1) {
- rewards.unreadOfferIds.splice(unreadIdx, 1);
- }
- rewards.storedOffers[msg.data.offer_id] = msg.data;
- rewards.unreadOfferIds.push(msg.data.offer_id);
- button.update();
-
- // Don't show the Rewards hotdog if Ghostery is currently paused
- if (msg.data.offer_data.ui_info.notif_type !== 'star' && !globals.SESSION.paused_blocking) {
- // We use getTabByUrl() instead of getActiveTab()
- // because user may open the offer-triggering url in a new tab
- // through the context menu, which may not switch to the new tab
- // If the url provided by Cliqz turns out to be invalid, we fall back to getActiveTabs
- if (msg.data.display_rule && msg.data.display_rule.url) {
- utils.getTabByUrl(
- msg.data.display_rule.url,
- (tab) => {
- const tabId = tab ? tab.id : 0;
- rewards.showHotDogOrOffer(tabId, msg.data);
- },
- () => {
- utils.getActiveTab((tab) => {
- const tabId = tab ? tab.id : 0;
- rewards.showHotDogOrOffer(tabId, msg.data);
- });
- }
- );
- }
- }
- }
- });
+ registerWithOffers(offers, true);
});
});
@@ -1785,6 +1614,19 @@ function initializeGhosteryModules() {
conf.enable_human_web = !humanweb.isDisabled && !(IS_FIREFOX && globals.JUST_INSTALLED);
conf.enable_offers = !offers.isDisabled && !(IS_FIREFOX && globals.JUST_INSTALLED);
}
+
+ const myoffrzShouldMigrate = conf.rewards_opted_in !== undefined && cliqz.prefs.get('myoffrz.opted_in', undefined) === undefined;
+ if (myoffrzShouldMigrate) {
+ cliqz.prefs.set('myoffrz.opted_in', conf.rewards_opted_in);
+ conf.rewards_opted_in = undefined;
+ }
+ cliqz.events.subscribe('myoffrz:turnoff', () => {
+ panelData.set({ enable_offers: false });
+ rewards.sendSignal({
+ actionId: 'rewards_off',
+ type: 'action-signal',
+ });
+ });
}
});
}).catch((e) => {
diff --git a/src/classes/BrowserButton.js b/src/classes/BrowserButton.js
index 34731cc31..453eb668e 100644
--- a/src/classes/BrowserButton.js
+++ b/src/classes/BrowserButton.js
@@ -15,7 +15,6 @@
import conf from './Conf';
import foundBugs from './FoundBugs';
-import rewards from './Rewards';
import Policy from './Policy';
import { getCliqzData } from '../utils/cliqzModulesData';
import { getTab } from '../utils/utils';
@@ -78,8 +77,7 @@ class BrowserButton {
if (globals.BROWSER_INFO.os === 'android') { return; }
if (tabId <= 0) { return; }
- const iconAlt = (!active) ? '_off' :
- (conf.enable_offers && rewards.unreadOfferIds.length > 0) ? '_star' : '';
+ const iconAlt = (!active) ? '_off' : '';
chrome.browserAction.setIcon({
path: {
@@ -105,9 +103,7 @@ class BrowserButton {
// Only show the badge if the conf setting allows it
if (conf.show_badge) {
- // Don't show badgeText when there is a new reward and Ghostery is active
- // Otherwise set the tracker count to the badgeText
- const text = (conf.enable_offers && rewards.unreadOfferIds.length && active) ? '' : trackerCount;
+ const text = trackerCount;
chrome.browserAction.setBadgeText({ text, tabId });
// Set badge background color
diff --git a/src/classes/Cliqz.js b/src/classes/Cliqz.js
index 04beda655..0d6e05a34 100644
--- a/src/classes/Cliqz.js
+++ b/src/classes/Cliqz.js
@@ -16,4 +16,3 @@ import CLIQZ from 'browser-core';
import globals from './Globals';
export default new (CLIQZ.App)({ debug: globals.DEBUG });
-export const { prefs } = CLIQZ;
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/Metrics.js b/src/classes/Metrics.js
index 7632cefc5..e7a532298 100644
--- a/src/classes/Metrics.js
+++ b/src/classes/Metrics.js
@@ -15,7 +15,6 @@ import globals from './Globals';
import conf from './Conf';
import { log, prefsSet, prefsGet } from '../utils/common';
import { getActiveTab, processUrlQuery } from '../utils/utils';
-import rewards from './Rewards';
// CONSTANTS
const FREQUENCIES = { // in milliseconds
@@ -26,7 +25,6 @@ const FREQUENCIES = { // in milliseconds
};
const CRITICAL_METRICS = ['install', 'install_complete', 'upgrade', 'active', 'engaged', 'uninstall'];
const CAMPAIGN_METRICS = ['install', 'active', 'uninstall'];
-const FIRST_REWARD_METRICS = ['rewards_first_accept', 'rewards_first_reject', 'rewards_first_reject_optin', 'rewards_first_reject_optout', 'rewards_first_learn_more'];
const { METRICS_SUB_DOMAIN, EXTENSION_VERSION, BROWSER_INFO } = globals;
const IS_EDGE = (BROWSER_INFO.name === 'edge');
const MAX_DELAYED_PINGS = 100;
@@ -229,7 +227,6 @@ class Metrics {
case 'create_account_extension':
case 'create_account_setup':
case 'list_dash':
- case 'rewards_learn':
case 'pause_snooze':
case 'smartblock_off':
case 'smartblock_on':
@@ -242,21 +239,10 @@ class Metrics {
this._sendReq(type, ['all', 'daily', 'monthly']);
break;
- // Rewards Pings
- case 'engaged_offer':
- this._sendReq('engaged_offer', ['daily', 'weekly', 'monthly']);
- break;
case 'rewards_off':
case 'rewards_on':
this._sendReq(type, ['all', 'daily']);
break;
- case 'rewards_first_learn_more':
- case 'rewards_first_accept':
- case 'rewards_first_reject':
- case 'rewards_first_reject_optin':
- case 'rewards_first_reject_optout':
- this._sendReq(type, ['all']);
- break;
// Ghostery 8.3+
case 'sign_in_success':
@@ -385,8 +371,6 @@ class Metrics {
`&sb=${encodeURIComponent(conf.setup_block.toString())}` +
// Recency, days since last active daily ping
`&rc=${encodeURIComponent(this._getRecencyActive(type, frequency).toString())}` +
- // Current number of rewards received
- `&rr=${encodeURIComponent(this._getRewardsCount().toString())}` +
// New parameters to Ghostery 8.3
// Subscription Type
@@ -409,11 +393,6 @@ class Metrics {
`&us=${encodeURIComponent(this.utm_source)}` +
// Marketing campaign (Former utm_campaign)
`&uc=${encodeURIComponent(this.utm_campaign)}`;
- } else if (FIRST_REWARD_METRICS.includes(type)) {
- // metrics specific to the first reward instance
- metrics_url +=
- // Reward ID
- `&rid=${encodeURIComponent(this._getRewardId().toString())}`;
} else if (type === 'broken_page' && this._brokenPageWatcher.on) {
metrics_url +=
// What triggered the broken page ping?
@@ -548,39 +527,6 @@ class Metrics {
return subscriptions.productName.toUpperCase().replace(' ', '_');
}
- /**
- * Get the number of Rewards shown to the user.
- *
- * @private
- *
- * @return {string} number of rewards, grouped into ranges.
- */
- _getRewardsCount() {
- const numShown = rewards.totalOffersSeen;
- if (numShown >= 6) {
- return '6+';
- }
- if (numShown >= 2) {
- return '2-5';
- }
- if (numShown === 1) {
- return '1';
- }
- return '0';
- }
-
- /**
- * Get the current Reward Id.
- *
- * @private
- *
- * @return {string} the current Reward Id
- */
- _getRewardId() {
- const currentOffer = rewards.currentOffer || { offer_id: 'no_id' };
- return currentOffer.offer_id;
- }
-
/**
* Get the Int associated with the Current Theme.
* @private
diff --git a/src/classes/PanelData.js b/src/classes/PanelData.js
index 4cc1772dc..96b07c2a7 100644
--- a/src/classes/PanelData.js
+++ b/src/classes/PanelData.js
@@ -16,7 +16,6 @@
import { isEqual, throttle } from 'underscore';
import button from './BrowserButton';
-import cliqz from './Cliqz';
import conf from './Conf';
import foundBugs from './FoundBugs';
import bugDb from './BugDb';
@@ -32,12 +31,6 @@ import { getCliqzGhosteryBugs, sendCliqzModuleCounts } from '../utils/cliqzModul
import { getActiveTab, flushChromeMemoryCache, processUrl } from '../utils/utils';
import { objectEntries, log } from '../utils/common';
-const cliqzModuleMock = {
- isEnabled: false,
- on: () => {},
-};
-const offers = cliqz.modules['offers-v2'] || cliqzModuleMock;
-
const SYNC_SET = new Set(globals.SYNC_ARRAY);
const { IS_CLIQZ } = globals;
const policy = new Policy();
@@ -94,10 +87,6 @@ class PanelData {
account.getUserSettings()
.then(userSettings => this._postUserSettings(userSettings))
.catch(() => log('Failed getting remote user settings from PanelData#initPort. User not logged in.'));
-
- if (this._needToFilterOffersByRemote()) {
- rewards.filterOffersByRemote().catch(err => log('Failed to filter offers by remote:', err));
- }
});
}
@@ -130,16 +119,7 @@ class PanelData {
case 'RewardsComponentDidMount':
this._mountedComponents.rewards = true;
this._panelPort.onDisconnect.addListener(rewards.panelHubClosedListener);
- if (this._needToFilterOffersByRemote()) {
- rewards.filterOffersByRemote()
- .then(() => this._postRewardsData())
- .catch((err) => {
- log('Failed to filter offers by remote:', err);
- this._postRewardsData();
- });
- } else {
- this._postRewardsData();
- }
+ this._postRewardsData();
break;
case 'RewardsComponentWillUnmount':
this._mountedComponents.rewards = false;
@@ -370,7 +350,6 @@ class PanelData {
reload_banner_status,
tab_id,
trackers_banner_status,
- unread_offer_ids: rewards.unreadOfferIds,
}, this._getDynamicPanelData(tab_id));
}
@@ -391,12 +370,8 @@ class PanelData {
* @return {Object} Rewards view data
*/
_getRewardsData() {
- const { storedOffers, unreadOfferIds } = rewards;
-
return {
enable_offers: conf.enable_offers,
- rewards: storedOffers,
- unread_offer_ids: unreadOfferIds,
};
}
@@ -537,16 +512,6 @@ class PanelData {
};
}
- /**
- * Checks to see whether we need to retrieve a filtered set of rewards from Cliqz
- * @returns {boolean} true if we do need to retrieve filtered rewards
- */
- _needToFilterOffersByRemote() {
- const { enable_offers, is_expert } = conf;
-
- return (offers.isEnabled && enable_offers && is_expert);
- }
-
/**
* Retrieves antitracking and adblock counts and sends it to the panel
*/
diff --git a/src/classes/PromoModals.js b/src/classes/PromoModals.js
index 2e202d80d..f0079429f 100644
--- a/src/classes/PromoModals.js
+++ b/src/classes/PromoModals.js
@@ -16,21 +16,19 @@ 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;
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 PLUS_INITIAL = 'plus_initial';
-const PLUS_UPGRADE = 'plus_upgrade';
+const PREMIUM = 'premium';
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,28 +39,19 @@ 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;
}
- static recordPlusPromoSighting() { this._recordPromoSighting(PLUS); }
+ static recordPremiumPromoSighting() { this._recordPromoSighting(PREMIUM); }
static recordInsightsPromoSighting() { this._recordPromoSighting(INSIGHTS); }
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;
}
}
diff --git a/src/classes/Rewards.js b/src/classes/Rewards.js
index 74ded9fd6..2a84f0902 100644
--- a/src/classes/Rewards.js
+++ b/src/classes/Rewards.js
@@ -11,15 +11,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint consistent-return: 0 */
-
-import { clone } from 'underscore';
-import button from './BrowserButton';
import cliqz from './Cliqz';
-import conf from './Conf';
-import tabInfo from './TabInfo';
-import { log, prefsGet, prefsSet } from '../utils/common';
-import { injectScript } from '../utils/utils';
+import { log } from '../utils/common';
/**
* Class for handling Ghostery Rewards Box overlay.
@@ -27,27 +20,9 @@ import { injectScript } from '../utils/utils';
*/
class Rewards {
constructor() {
- this.getStoredOffers();
- this.currentOffer = null;
- this.ports = new Map();
- this.channelsSupported = (typeof chrome.runtime.onConnect === 'object');
this.panelHubClosedListener = this.panelHubClosedListener.bind(this);
}
- deleteReward(offerId) {
- delete this.storedOffers[offerId];
- // @TODO send signal?
- this.updateStoredOffers();
- }
-
- markRewardRead(offerId) {
- const rewardIdx = this.unreadOfferIds.indexOf(offerId);
- if (rewardIdx !== -1) {
- this.unreadOfferIds.splice(rewardIdx, 1);
- this.updateStoredOffers();
- }
- }
-
sendSignal(message) {
const {
offerId, actionId, origin, type
@@ -66,102 +41,6 @@ class Rewards {
cliqz.modules['offers-v2'].background.actions.processRealEstateMessage(signal);
}
- async filterOffersByRemote() {
- await cliqz.modules['offers-v2'].isReady();
- const args = { filters: { by_rs_dest: 'ghostery' } };
- const offers = cliqz.modules['offers-v2'].background.actions.getStoredOffers(args);
- const newStoredOffers = {};
- (offers || []).forEach(({ offer_id: offerId, attrs = {}, offer_info: offerInfo }) => {
- const offer = (this.storedOffers || {})[offerId];
- if (offer) {
- const newOffer = clone(offer);
- newOffer.attrs = attrs;
- newOffer.offer_data = offerInfo;
- newStoredOffers[offerId] = newOffer;
- }
- });
- this.storedOffers = newStoredOffers;
- this.unreadOfferIds = this.unreadOfferIds.filter(id => newStoredOffers[id]);
- }
-
- async getStoredOffers() {
- const {
- storedOffers,
- unreadOfferIds,
- totalOffersSeen,
- } = await prefsGet('storedOffers', 'unreadOfferIds', 'totalOffersSeen');
- this.storedOffers = storedOffers || {};
- this.unreadOfferIds = unreadOfferIds || [];
- this.totalOffersSeen = totalOffersSeen || 0;
- }
-
- updateStoredOffers() {
- prefsSet({ storedOffers: this.storedOffers });
- prefsSet({ unreadOfferIds: this.unreadOfferIds }).then(() => { button.update(); });
- }
-
- showHotDogOrOffer(tab_id, offer) {
- this.updateStoredOffers();
- this.totalOffersSeen++;
- prefsSet({ totalOffersSeen: this.totalOffersSeen });
- this.currentOffer = offer;
- const tab = tabInfo.getTabInfo(tab_id);
-
- // If the tab is prefetched, we can't add Rewards hotdog to it
- if (!conf.enable_offers || !tab || tab.rewards) {
- return Promise.resolve(false);
- }
-
- // Inject script cannot handle errors properly, but we call createBox after verifying that the tab is OK
- // So update hotdog status for this tab
- // tabInfo.setTabInfo(tab_id, 'rewards', true);
- if (this.channelsSupported) {
- if (this.ports.has(tab_id)) {
- this.ports.get(tab_id).disconnect();
- this.ports.delete(tab_id);
- }
- if (!this.connectListenerAdded) {
- this.connectListenerAdded = true;
- chrome.runtime.onConnect.addListener((port) => {
- if (port && port.name === 'rewardsPort' && port.sender && port.sender.tab && port.sender.tab.id) {
- const tabId = port.sender.tab.id;
- if (!this.ports.has(tabId)) {
- this.ports.set(tabId, port);
- this.ports.get(tabId).onMessage.addListener((message) => {
- const responseMessage = conf.rewards_opted_in ? 'showOffer' : 'showHotDog';
- switch (message.name) {
- case 'rewardsLoaded':
- this.ports.get(tabId).postMessage({
- name: responseMessage,
- reward: this.currentOffer,
- conf: {
- rewardsPromptAccepted: conf.rewards_accepted
- }
- });
- break;
- case 'rewardSignal':
- this.sendSignal(message.message);
- break;
- case 'rewardSeen':
- this.markRewardRead(message.offerId);
- button.update();
- break;
- default:
- break;
- }
- });
- }
- }
- });
- }
- }
-
- return injectScript(tab_id, 'dist/rewards.js', 'dist/css/rewards_styles.css', 'document_start').catch((err) => {
- log('rewards injectScript error', err);
- return false;
- });
- }
-
panelHubClosedListener() {
this.sendSignal({
offerId: null,
diff --git a/webpack.config.js b/webpack.config.js
index 542ce971f..d17bdc26a 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -57,7 +57,6 @@ module.exports = {
panel_android_react: [`${PANEL_ANDROID_DIR}/index.jsx`],
panel_react: [`${PANEL_DIR}/index.jsx`],
purplebox: [`${CONTENT_SCRIPTS_DIR}/purplebox.js`],
- rewards: [`${CONTENT_SCRIPTS_DIR}/rewards`],
shared_comp_react: [`${SHARED_COMP_DIR}/index.js`],
// Sass
foundation: [`${SASS_DIR}/vendor/foundation.scss`],
@@ -68,7 +67,6 @@ module.exports = {
panel: [`${SASS_DIR}/panel.scss`],
panel_android: [`${SASS_DIR}/panel_android.scss`],
purplebox_styles: [`${SASS_DIR}/purplebox.scss`],
- rewards_styles: [`${SASS_DIR}/rewards.scss`],
},
output: {
filename: '[name].js',
@@ -96,7 +94,6 @@ module.exports = {
`${RM} ./dist/panel.js`,
`${RM} ./dist/panel_android.js`,
`${RM} ./dist/purplebox_styles.js`,
- `${RM} ./dist/rewards_styles.js`,
]
}),
// Create global `t` function for i18n
diff --git a/yarn.lock b/yarn.lock
index 4af63b5da..1d61e25b4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1353,9 +1353,9 @@ brorand@^1.0.1:
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
-"browser-core@https://github.com/cliqz-oss/browser-core/releases/download/v7.40.1/browser-core-7.40.1.tgz":
- version "7.40.1"
- resolved "https://github.com/cliqz-oss/browser-core/releases/download/v7.40.1/browser-core-7.40.1.tgz#ce3cabff15be5dc26ba539184e8f0f0f28ad2244"
+"browser-core@https://github.com/cliqz-oss/browser-core/releases/download/v7.40.2/browser-core-7.40.2.tgz":
+ version "7.40.2"
+ resolved "https://github.com/cliqz-oss/browser-core/releases/download/v7.40.2/browser-core-7.40.2.tgz#b10ea47c7136685cedf8235677cb8c3df19cc76f"
dependencies:
"@cliqz-oss/dexie" "^2.0.4"
"@cliqz/adblocker-webextension" "^1.3.0"
@@ -6630,11 +6630,6 @@ react-router@5.1.2, react-router@^5.1.2:
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
-react-shadow-dom-retarget-events@^1.0.10:
- version "1.0.10"
- resolved "https://registry.yarnpkg.com/react-shadow-dom-retarget-events/-/react-shadow-dom-retarget-events-1.0.10.tgz#78c3c039bf2ea4e788d91d390662c9ccaf8d92ad"
- integrity sha512-OOt7ugDgSuXiy+PmMOMHqvm4ko6X+cJsre/N124dCJhLBXqv1xVLjwuhpeY7/nv7p/YxytvyfwYG+M19NMnSjQ==
-
react-svg@^10.0.22:
version "10.0.22"
resolved "https://registry.yarnpkg.com/react-svg/-/react-svg-10.0.22.tgz#be8b32a3276e187997cc6eb5b8f88929c5ef16c9"