From c14d10fc3f59f0da9bd1065fd12d762a676a49f9 Mon Sep 17 00:00:00 2001 From: aleksandr panin <38907423+aleksandr-cliqz@users.noreply.github.com> Date: Fri, 22 Nov 2019 17:09:07 +0100 Subject: [PATCH 01/10] M20-52: Full takeover of Ghostery rewards (#462) * M20-52: first proto for myoffrz rewards * M20-52: linter * M20-52: typos in package.json and yarn.lock * M20-52: typos part 2 in yarn and package.json * M20-52: adding test locales for en * M20-52: turnoff rewards from reward-box * M20-52: adding web_accessible_resources for offers-reminder * M20-52: myoffrz actions was renamed * M20-52: turnoff ghostery rewards (just adding flag) * M20-52: move inline styles to css file * M20-52: fix typos * M20-52: [locales] remove duplicates * M20-52: rename locales * M20-52: locales adding support for goo chrome * M20-52: known rewards keys for poland * M20-52: rearrange locale keys * M20-52: fix typos * M20-52: clean code: src and content-scripts * M20-52: fix typos * M20-52: clean up for app/panel/rewards * M20-52: clean up for css and images * M20-52: fix for eslint * M20-52: fix tests * M20-52: fixing TODOs * M20-52: clean up for unread offers * M20-52: fix typos * M20-52: adding missing signals * M20-52: adding border to iframe * M20-52: reset rewards_opted_in after migration * M20-52: revert pl translations * M20-52: fix duplicate translations * M20-52: remove unused eact-shadow-dom-retarget-events * M20-52: remove unused code * M20-52: fix typos yarn,lock * M20-52: listen to myOffrzTurnoff in different place * M20-52: adding events for myoffrz:turnoff * test * fix test * M20-52: new cliqz version 7.40.2 * M20-52: update yarn.lock --- _locales/en/messages.json | 167 +++++ app/content-scripts/rewards/HotDog.jsx | 84 --- app/content-scripts/rewards/Notification.jsx | 145 ----- app/content-scripts/rewards/OfferCard.jsx | 361 ---------- app/content-scripts/rewards/Settings.jsx | 62 -- app/content-scripts/rewards/index.jsx | 249 ------- app/images/rewards/best-offer.svg | 20 - app/images/rewards/exclusive.svg | 31 - app/images/rewards/ghostery-rewards-beta.png | Bin 50589 -> 0 bytes app/images/rewards/ghostery_O.png | Bin 54004 -> 0 bytes app/images/rewards/light-x.svg | 3 - app/images/rewards/powered-by-myoffrz.svg | 21 - app/images/rewards/settings-kebab.svg | 5 - app/images/rewards/white-x.svg | 3 - app/panel/actions/RewardsActions.js | 25 - app/panel/actions/__tests__/RewardsActions.js | 26 - .../BuildingBlocks/RewardDetail.jsx | 165 ----- .../BuildingBlocks/RewardListItem.jsx | 132 ---- app/panel/components/BuildingBlocks/index.js | 4 - app/panel/components/Detail.jsx | 9 +- app/panel/components/Panel.jsx | 4 - app/panel/components/Rewards.jsx | 282 ++++---- app/panel/components/Summary.jsx | 5 - .../components/__tests__/RewardDetail.jsx | 179 ----- .../components/__tests__/RewardListItem.jsx | 156 ----- .../__snapshots__/RewardDetail.jsx.snap | 339 ---------- .../__snapshots__/RewardListItem.jsx.snap | 346 ---------- .../__tests__/__snapshots__/Rewards.jsx.snap | 28 +- app/panel/constants/constants.js | 2 - app/panel/containers/DetailContainer.js | 1 - app/panel/reducers/__tests__/rewards.js | 72 -- app/panel/reducers/panel.js | 12 - app/panel/reducers/rewards.js | 31 - app/scss/partials/_detail.scss | 4 + app/scss/partials/_rewards.scss | 227 +------ app/scss/rewards.scss | 614 ------------------ manifest.json | 5 +- package.json | 3 +- src/background.js | 252 ++----- src/classes/BrowserButton.js | 8 +- src/classes/Cliqz.js | 1 - src/classes/Metrics.js | 54 -- src/classes/PanelData.js | 37 +- src/classes/Rewards.js | 123 +--- webpack.config.js | 3 - yarn.lock | 11 +- 46 files changed, 390 insertions(+), 3921 deletions(-) delete mode 100644 app/content-scripts/rewards/HotDog.jsx delete mode 100644 app/content-scripts/rewards/Notification.jsx delete mode 100644 app/content-scripts/rewards/OfferCard.jsx delete mode 100644 app/content-scripts/rewards/Settings.jsx delete mode 100644 app/content-scripts/rewards/index.jsx delete mode 100644 app/images/rewards/best-offer.svg delete mode 100644 app/images/rewards/exclusive.svg delete mode 100644 app/images/rewards/ghostery-rewards-beta.png delete mode 100644 app/images/rewards/ghostery_O.png delete mode 100644 app/images/rewards/light-x.svg delete mode 100644 app/images/rewards/powered-by-myoffrz.svg delete mode 100644 app/images/rewards/settings-kebab.svg delete mode 100644 app/images/rewards/white-x.svg delete mode 100644 app/panel/components/BuildingBlocks/RewardDetail.jsx delete mode 100644 app/panel/components/BuildingBlocks/RewardListItem.jsx delete mode 100644 app/panel/components/__tests__/RewardDetail.jsx delete mode 100644 app/panel/components/__tests__/RewardListItem.jsx delete mode 100644 app/panel/components/__tests__/__snapshots__/RewardDetail.jsx.snap delete mode 100644 app/panel/components/__tests__/__snapshots__/RewardListItem.jsx.snap delete mode 100644 app/scss/rewards.scss diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 9f34a79b1..363f5ddf8 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1993,6 +1993,173 @@ "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" }, 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.state.closed !== true && ( -
-
-
- {t('rewards_new_text')} -
-
-
-
- )} -
- ); - } -} - -export default withRouter(HotDog); diff --git a/app/content-scripts/rewards/Notification.jsx b/app/content-scripts/rewards/Notification.jsx deleted file mode 100644 index 9aaed0ffe..000000000 --- a/app/content-scripts/rewards/Notification.jsx +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Notification 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 notifications for Rewards - * @memberOf RewardsContentScript - */ -class Notification extends Component { - constructor(props) { - super(props); - this.closeIcon = `url(${chrome.extension.getURL('app/images/rewards/white-x.svg')})`; - this.state = { - closed: false - }; - - this.closeNotification = this.closeNotification.bind(this); - } - - closeNotification(confirm) { - if (typeof this.props.data.closeCallback === 'function') { - this.props.data.closeCallback(confirm); - } - this.setState({ - closed: true - }); - } - - renderOptoutImage() { - return ( -
- -
- ); - } - - renderOptoutLink() { - return ( - this.props.data.textLink.callback()} - > - {this.props.data.textLink.text} - - ); - } - - renderHeadline() { - return ( -
- {t('rewards_first_prompt_headline')} -
- ); - } - - renderLabels() { - return ( -
- - {t('rewards_exclusive')} - - {t('rewards_best_offer')} -
- ); - } - - renderClose() { - 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.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.state.code} - -
- {this.state.copyText} -
- )} -
- - { this.renderExpiresText() } - - {this.state.rewardUI.conditions && ( -
- { t('rewards_terms_conditions') } - -
- )} -
- - {this.state.rewardUI.call_to_action.text} - -
-
-
-
- {this.props.conf.rewardsPromptAccepted && - {t('rewards_disable')} - } -
-
- -
- -
-
- { 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/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 929d71fc894f2e41dca589373dd0b0730c689d19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50589 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 Im`ULO1?A_2PXGV_ 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/Panel.jsx b/app/panel/components/Panel.jsx index 45f5de0e4..575027e6f 100644 --- a/app/panel/components/Panel.jsx +++ b/app/panel/components/Panel.jsx @@ -150,10 +150,6 @@ class Panel extends React.Component { reload: true }); } - - if (panel.enable_offers && panel.unread_offer_ids.length > 0) { - sendMessage('ping', 'engaged_offer'); - } } /** 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}
+
+ )} +