diff --git a/_locales/en/messages.json b/_locales/en/messages.json index c3659b390..8492aa2ea 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -22,16 +22,9 @@ } } }, - "all": { - "description": "Default setting in the 'filter by type' dropdown for the tag browser. Doesn't filter anything out. Should read as 'Show all'.", - "message": "all" - }, "banner_check_your_email_title": { "message": "Please check your email shortly for a link to reset your password." }, - "banner_no_such_account_message": { - "message": "Looks like we can't find this email and password combo. Give it another shot." - }, "banner_email_not_in_system_message": { "message": "Sorry, that email isn't in our system." }, @@ -41,10 +34,6 @@ "blacklist_error_whitelist_url": { "message": "This site has been removed from your Trusted Sites list and added to your Restricted Sites list" }, - "blocked": { - "description": "Select this to show only blocked (checked) tags in the tag browser. Should read as 'Show blocked'.", - "message": "blocked" - }, "blocked_redirect_action_always_title": { "description": "Title for the 'Allow always and reload' button on the blocked redirect page.", "message": "Always allow and reload." @@ -375,31 +364,6 @@ } } }, - "copyright": { - "description": "Copyright message, shown in page footers.", - "message": "$C$ $YEAR$ $GHOSTERY$, a part of $COMPANY_ADDRESS$", - "placeholders": { - "c": { - "content": "©" - }, - "company_address": { - "content": "$1", - "example": "GHOSTERY, Inc., Such-and-such Street, Such-and-such Floor, New York, NY, Zip Code" - }, - "ghostery": { - "content": "Ghostery" - }, - "year": { - "content": "2015" - } - } - }, - "email_confirm_field_label": { - "message": "Confirm Email:" - }, - "email_field_label": { - "message": "Email:" - }, "error_email_forgot": { "message": "Hmm, I can’t find that email. Maybe try another?" }, @@ -409,12 +373,6 @@ "forgot_password_message": { "message": "Forgot your password? Hey, it happens to everyone. We'll email you instructions to reset your password." }, - "invalid_email_confirmation": { - "message": "Your emails do not match." - }, - "invalid_email_create": { - "message": "Please enter a valid email." - }, "invalid_email_forgot": { "message": "Sorry, you have to enter a real email address." }, @@ -532,9 +490,6 @@ "description": "as in '5 (trackers) WHITELISTED'", "message": "Whitelisted" }, - "panel_create_account": { - "message": "Create Account" - }, "panel_email_verification_sent": { "message": "$BOLD_HTML_STARTS$ Success! $BOLD_HTML_END$ An account verification email has been sent to $EMAIL$", "placeholders": { @@ -568,9 +523,6 @@ "panel_help_questions_header": { "message": "Questions and Comments" }, - "panel_help_support": { - "message": "Support" - }, "panel_help_setup": { "message": "Set Up Ghostery" }, @@ -623,15 +575,6 @@ "panel_menu_about": { "message": "About" }, - "panel_menu_ghostery_subscriber": { - "message": "Ghostery Plus" - }, - "panel_menu_signin": { - "message": "Sign in" - }, - "panel_menu_signout": { - "message": "Sign out" - }, "global_settings_saved": { "message": "Global Settings Saved" }, @@ -691,9 +634,6 @@ "panel_signin_success_title": { "message": "Congrats! Your Ghostery account is ready to go." }, - "panel_title_create_account": { - "message": "Create Account" - }, "panel_tracker_found_sources_title": { "message": "Detected tracker URLs:" }, @@ -739,15 +679,9 @@ "panel_detail_menu_rewards_title": { "message": "Rewards" }, - "panel_detail_menu_stats_title": { - "message": "Historical stats" - }, "panel_detail_menu_premium_title": { "message": "Premium" }, - "panel_detail_learn_more": { - "message": "Learn More" - }, "panel_detail_history_title": { "message": "History" }, @@ -802,27 +736,15 @@ "notification_library_update_link": { "message": "Check out what's new" }, - "panel_header_sign_in": { - "message": "Sign In" - }, "panel_header_verify_account": { "message": "Verify Account" }, - "panel_header_simple_view": { - "message": "Simple View" - }, - "panel_header_detailed_view": { - "message": "Detailed View" - }, "password_characters_requirements": { "message": "Only these special characters are allowed: !@#$%^&*=+()<>{}[];:,./?" }, "password_field_label": { "message": "Password" }, - "create_password_field_label": { - "message": "Password:" - }, "password_requirements": { "message": "Use between 8 and 50 characters." }, @@ -1126,57 +1048,6 @@ "blocking_category_tracker_found": { "message": "Found" }, - "drawer_title_enable_anti_tracking": { - "message": "Enhanced Anti-Tracking" - }, - "drawer_tooltip_enable_anti_tracking": { - "message": "Anonymize unblocked and unknown trackers for greater browsing protection" - }, - "drawer_label_enable_anti_tracking": { - "message": "Trackers Anonymized" - }, - "drawer_desc_enable_anti_tracking": { - "message": "Private data points have been removed." - }, - "drawer_status_enable_anti_tracking": { - "message": "Anti-Tracking is" - }, - "drawer_title_enable_ad_block": { - "message": "Enhanced Ad Blocking" - }, - "drawer_tooltip_enable_ad_block": { - "message": "Block advertisements on websites you visit" - }, - "drawer_label_enable_ad_block": { - "message": "Ads Blocked" - }, - "drawer_desc_enable_ad_block": { - "message": "Ad spots have been blocked." - }, - "drawer_status_enable_ad_block": { - "message": "Ad Blocking is" - }, - "drawer_title_enable_smart_block": { - "message": "Smart Blocking" - }, - "drawer_tooltip_enable_smart_block": { - "message": "Automatically block and unblock trackers to optimize page performance" - }, - "drawer_label_enable_smart_block": { - "message": "Trackers Adjusted" - }, - "drawer_desc_enable_smart_block": { - "message": "Trackers have been temporarily blocked or unblocked." - }, - "drawer_status_enable_smart_block": { - "message": "Smart Blocking is" - }, - "drawer_on": { - "message": "On" - }, - "drawer_off": { - "message": "Off" - }, "blocking_unblock_all": { "message": "Unblock All" }, @@ -1246,34 +1117,16 @@ "alert_site_restricted_off": { "message": "Site no longer blacklisted." }, - "tooltip_anti_track": { - "message": "Enhanced Anti-Tracking" - }, - "tooltip_anti_track_body": { - "message": "Anonymize personal data for greater protection." - }, - "tooltip_anti_track_body_on": { + "tooltip_anti_track_on": { "message": "Personal data points anonymized." }, "tooltip_body_in_cliqz": { "message": "Feature already active in Cliqz by default." }, - "tooltip_ad_block": { - "message": "Enhanced Ad Blocking" - }, - "tooltip_ad_block_body": { - "message": "Block advertisements." - }, - "tooltip_ad_block_body_on": { + "tooltip_ad_block_on": { "message": "Advertisements have been blocked." }, - "tooltip_smart_block": { - "message": "Smart Blocking" - }, - "tooltip_smart_block_body": { - "message": "Automatically block and unblock trackers to optimize page performance." - }, - "tooltip_smart_block_body_on": { + "tooltip_smart_block_on": { "message": "Tracker blocking adjusted to optimize page performance." }, "tooltip_trust": { @@ -1294,12 +1147,6 @@ "tooltip_resume": { "message": "Resume Ghostery" }, - "tooltip_expert": { - "message": "Detailed View" - }, - "tooltip_simple": { - "message": "Simple View" - }, "license_module": { "message": "Module" }, @@ -1350,30 +1197,15 @@ "hub_side_navigation_home": { "message": "Home" }, - "hub_side_navigation_setup": { - "message": "Customize Setup" - }, "hub_side_navigation_tutorial": { "message": "Take a Tutorial" }, - "hub_side_navigation_supporter": { - "message": "Get Ghostery Plus" - }, "hub_side_navigation_rewards": { "message": "Try Ghostery Rewards" }, "hub_side_navigation_products": { "message": "See More Ghostery Products" }, - "hub_side_navigation_create_account": { - "message": "Create Account" - }, - "hub_side_navigation_log_in": { - "message": "Sign In" - }, - "hub_side_navigation_log_out": { - "message": "Sign Out" - }, "hub_home_page_title": { "message": "Ghostery Hub - Home" }, @@ -1404,24 +1236,15 @@ "hub_home_subheader_optimize": { "message": "Optimize your Ghostery experience" }, - "hub_home_subheader_create_account": { - "message": "Create Account" - }, "hub_home_feature_tutorial_title": { "message": "Take a Tutorial" }, "hub_home_feature_tutorial_text": { "message": "Walk through Ghostery's main features." }, - "hub_home_feature_tutorial_button": { - "message": "Start" - }, "hub_home_feature_tutorial_button_alt": { "message": "Tutorial Complete" }, - "hub_home_feature_setup_title": { - "message": "Customize Setup" - }, "hub_home_feature_setup_text": { "message": "Edit your settings and blocking preferences." }, @@ -1434,12 +1257,6 @@ "hub_home_feature_supporter_text": { "message": "Upgrade to Ghostery Plus and unlock special features." }, - "hub_home_feature_supporter_button": { - "message": "Get Ghostery Plus" - }, - "hub_home_feature_supporter_button_alt": { - "message": "Already Subscribed" - }, "hub_setup_page_title": { "message": "Ghostery Hub - Setup" }, @@ -1475,15 +1292,6 @@ "hub_setup_exit_flow": { "message": "Exit Custom Setup" }, - "hub_setup_nav_previous": { - "message": "Previous" - }, - "hub_setup_nav_next": { - "message": "Next" - }, - "hub_setup_nav_done": { - "message": "Done" - }, "hub_setup_enter_modal_text": { "message": "Entering custom setup will override your previous Ghostery settings. Do you want to continue?" }, @@ -1520,24 +1328,9 @@ "hub_setup_blocking_description_custom": { "message": "Choose which trackers to block" }, - "hub_setup_antisuite_name_antitracking": { - "message": "Enhanced Anti-Tracking" - }, "hub_setup_antisuite_description_antitracking": { "message": "Anonymize unblocked and unknown trackers for greater browsing protection." }, - "hub_setup_adblock_name_adblocking": { - "message": "Enhanced Ad Blocking" - }, - "hub_setup_adblock_description_adblocking": { - "message": "Block advertisements on websites you visit." - }, - "hub_setup_smartblocking_name_smartblocking": { - "message": "Smart Blocking" - }, - "hub_setup_smartblocking_description_smartblocking": { - "message": "Automatically block and unblock trackers to optimize page performance." - }, "hub_setup_feature_already_active": { "message": "This feature is already active in Cliqz by default. $LINK_LM_START$Learn More$LINK_LM_END$", "placeholders": { @@ -1581,18 +1374,9 @@ "hub_setup_feature_tutorial_description": { "message": "Walk through Ghostery's main features." }, - "hub_setup_feature_tutorial_button": { - "message": "Start" - }, - "hub_setup_feature_supporter_title": { - "message": "Get Ghostery Plus" - }, "hub_setup_feature_supporter_description": { "message": "Support Ghostery and unlock special perks." }, - "hub_setup_feature_supporter_button": { - "message": "Support" - }, "hub_setup_feature_products_title": { "message": "See more Ghostery Products" }, @@ -1626,21 +1410,6 @@ "hub_tutorial_exit_flow": { "message": "Exit Tutorial" }, - "hub_tutorial_nav_previous": { - "message": "Previous" - }, - "hub_tutorial_nav_next": { - "message": "Next" - }, - "hub_tutorial_nav_done": { - "message": "Done" - }, - "hub_tutorial_simple_view": { - "message": "Simple View" - }, - "hub_tutorial_detailed_view": { - "message": "Detailed View" - }, "hub_tutorial_detailed_expanded_view": { "message": "Detailed Expanded View" }, @@ -1692,24 +1461,9 @@ "hub_tutorial_antisuite_title": { "message": "Get extra protection and automated control with our enhanced privacy features:" }, - "hub_tutorial_antisuite_antitracking_title": { - "message": "Enhanced Anti-Tracking" - }, "hub_tutorial_antisuite_antitracking_description": { "message": "Remove data points that websites can use to identify you." }, - "hub_tutorial_antisuite_adblocking_title": { - "message": "Enhanced Ad Blocking" - }, - "hub_tutorial_antisuite_adblocking_description": { - "message": "Block advertisements on the pages you visit." - }, - "hub_tutorial_antisuite_smartblocking_title": { - "message": "Smart Blocking" - }, - "hub_tutorial_antisuite_smartblocking_description": { - "message": "Automatically block and unblock trackers to optimize page performance." - }, "hub_products_page_title" : { "message": "Ghostery Hub - Try Other Ghostery Products" }, @@ -1746,9 +1500,6 @@ "hub_rewards_header_description": { "message": "Our new Rewards feature offers a powerful, completely private new way to receive real discounts online. Turn it on and check it out!" }, - "hub_rewards_header_learn_more": { - "message": "Learn More" - }, "hub_rewards_experience_title": { "message": "A Smarter Shopping Experience" }, @@ -1779,12 +1530,6 @@ "hub_supporter_header_description": { "message": "Show your support and unlock special perks!" }, - "hub_supporter_button_text": { - "message": "Get Ghostery Plus" - }, - "hub_supporter_button_text_alt": { - "message": "Already Subscribed" - }, "hub_supporter_price": { "message": "$SUP_START$$$SUP_END$$SPAN_START$2$SPAN_END$ per month", "placeholders": { @@ -1802,15 +1547,9 @@ } } }, - "hub_supporter_perk_themes_title": { - "message": "New Themes" - }, "hub_supporter_perk_themes_description": { "message": "Customize the Ghostery colors - try our Midnight theme!" }, - "hub_supporter_perk_stats_title": { - "message": "Historical Blocking Stats" - }, "hub_supporter_perk_stats_description": { "message": "View your blocking statistics and see how Ghostery is working for you" }, @@ -1823,21 +1562,12 @@ "hub_supporter_manifesto": { "message": "We strive to deliver the best privacy protection services to our users free of cost. While we do not charge for our privacy suite, you may choose to support us through a small monthly subscription. Join us in our mission by upgrading to Ghostery Plus - and unlock cool perks along the way!" }, - "hub_supporter_feature_theme_title": { - "message": "New Themes" - }, "hub_supporter_feature_theme_description": { "message": "Customize the Ghostery colors for a new visual experience! Introduced through popular request. Check out our special Midnight theme, and more to come." }, - "hub_supporter_feature_stats_title": { - "message": "Historical Blocking Stats" - }, "hub_supporter_feature_stats_description": { "message": "View historical blocking results with graphs and statistics to reveal trends and learn how Ghostery has affected your browsing." }, - "hub_supporter_feature_support_title": { - "message": "Priority Support" - }, "hub_supporter_feature_support_description": { "message": "Need assistance? Find a broken page? Have your questions answered and issues resolved fast with our Priority help desk service, accessible only when signed in with a Plus account." }, @@ -1859,15 +1589,6 @@ "hub_login_header_title": { "message": "Sign in to your account." }, - "hub_login_label_email": { - "message": "Email:" - }, - "hub_login_label_password": { - "message": "Password:" - }, - "hub_login_label_email_invalid": { - "message": "Please enter a valid email." - }, "hub_login_label_password_invalid": { "message": "Use between 8 and 50 characters." }, @@ -1877,39 +1598,18 @@ "hub_login_link_create_account": { "message": "Sign up." }, - "hub_login_button_submit": { - "message": "Sign In" - }, "hub_login_toast_success": { "message": "Sign in successful! Your account settings have been imported." }, - "hub_login_toast_error": { - "message": "Looks like we can't find this email and password combo. Give it another shot." - }, "hub_create_account_header_title": { "message": "Would you like to create a Ghostery account to sync settings across browsers and devices?" }, - "hub_create_account_label_email": { - "message": "Email:" - }, - "hub_create_account_label_email_confirm": { - "message": "Confirm Email:" - }, "hub_create_account_label_first_name": { "message": "First Name (Optional):" }, "hub_create_account_label_email_last_name": { "message": "Last Name (Optional):" }, - "hub_create_account_label_password": { - "message": "Password:" - }, - "hub_create_account_label_email_invalid": { - "message": "Please enter a valid email." - }, - "hub_create_account_label_email_confirm_invalid": { - "message": "Your emails do not match." - }, "hub_create_account_label_password_invalid": { "message": "Only these special characters are allowed: !@#$%^&*=+()<>{}[];:,./?" }, @@ -1925,9 +1625,6 @@ "hub_create_account_link_login": { "message": "Sign in here." }, - "hub_create_account_button_submit": { - "message": "Create Account" - }, "hub_create_account_toast_success": { "message": "Account Successfully Created" }, @@ -2059,9 +1756,6 @@ "rewards_code_copied_toast_notification": { "message": "Rewards code copied!" }, - "rewards_learn_more": { - "message": "Learn More" - }, "offers_hub_copy_btn": { "message": "Copy code" }, @@ -2080,30 +1774,15 @@ "subscription_themes": { "message": "Ghostery Themes" }, - "subscription_info_title": { - "message": "Ghostery Plus" - }, "subscription_themes_title": { "message": "Themes" }, - "subscription_priority_support_title": { - "message": "Priority Support" - }, - "subscription_priority_support": { - "message": "Priority Support" - }, - "subscription_history_stats": { - "message": "Historical Stats" - }, "subscribe_pitch": { "message": "While Ghostery is free, you can choose to support us through a small subscription of $2 per month in exchange for cool perks, such as color themes, priority help service, and more. Join our mission and subscribe!" }, "subscribe_pitch_learn_more": { "message": "Learn more" }, - "subscribe_pitch_button_label": { - "message": "Get Ghostery Plus!" - }, "subscribe_pitch_sign_here": { "message": "Already a subscriber? Sign in here" }, @@ -2125,9 +1804,6 @@ "subscription_themes_tooltip": { "message": "Change the color scheme of Ghostery!" }, - "subscription_tracker_stats": { - "message": "Historical Stats" - }, "subscription_charge_date" : { "message": "Next Payment Date" }, @@ -2172,9 +1848,6 @@ "panel_stats_menu_daily": { "message": "Daily" }, - "panel_stats_header_title": { - "message": "Historical Tracker Stats" - }, "panel_stats_header_title_monthly": { "message": "Historical Tracker Stats (Monthly Avg.)" }, @@ -2237,9 +1910,6 @@ "panel_stats_pitch_modal_sign_in": { "message": "Sign in here" }, - "panel_stats_pitch_modal_subscribe": { - "message": "Get Ghostery Plus!" - }, "panel_stats_pitch_modal_tooltip": { "message": "Erase all statistics history up until this point in time." }, @@ -2261,12 +1931,6 @@ "ads": { "message": "ads" }, - "cliqz_feature_status_on": { - "message": "On" - }, - "cliqz_feature_status_off": { - "message": "Off" - }, "create_account_form_legal_consent_checkbox_label": { "message": "I accept the $LINK_TERMS_START$Terms and Conditions$LINK_END$, the $LINK_LICENSE_START$Public License Agreement$LINK_END$, and consent to data practices found in the $LINK_PRIVACY_START$Privacy Policy$LINK_END$.", "placeholders": { @@ -2295,5 +1959,156 @@ }, "unknown_description": { "message": "Unknown trackers scrubbed by Anti-Tracking" + }, + "thanks_for_downloading_ghostery": { + "message": "Thanks for downloading Ghostery!" + }, + "choose_your_privacy_plan": { + "message": "Choose your privacy plan" + }, + "choose_your_ghostery_privacy_plan": { + "message": "Choose your Ghostery privacy plan" + }, + "ghostery_basic": { + "message": "Ghostery Basic" + }, + "ghostery_plus": { + "message": "Ghostery Plus" + }, + "locale_appropriate_currency_icon": { + "message": "$$", + "description": "Use '$$' to mean '$'. '$' has a special meaning in the code and the first '$' tells the browser to ignore the special meaning of the second '$' and print it literally." + }, + "plus_monthly_subscription_price_number": { + "message": "2" + }, + "per_month": { + "message": "per month" + }, + "protection_for_this_browser": { + "message": "Protection for this browser" + }, + "blocks_ads": { + "message": "Blocks Ads" + }, + "blocks_trackers": { + "message": "Blocks Trackers" + }, + "fast_browsing": { + "message": "Fast Browsing" + }, + "select_basic": { + "message": "Select Basic" + }, + "select_plus": { + "message": "Select Plus" + }, + "recommended": { + "message": "Recommended" + }, + "get_ghostery_plus": { + "message": "Get Ghostery Plus" + }, + "get_ghostery_plus_bang": { + "message": "Get Ghostery Plus!" + }, + "already_subscribed": { + "message": "Already Subscribed" + }, + "new_themes": { + "message": "New Themes" + }, + "historical_blocking_stats": { + "message": "Historical Blocking Stats" + }, + "sign_in": { + "message": "Sign In" + }, + "sign_out": { + "message": "Sign Out" + }, + "create_account": { + "message": "Create Account" + }, + "email_colon": { + "message": "Email:" + }, + "confirm_email_colon": { + "message": "Confirm Email:" + }, + "next": { + "message": "Next" + }, + "previous": { + "message": "Previous" + }, + "done": { + "message": "Done" + }, + "simple_view": { + "message": "Simple View" + }, + "detailed_view": { + "message": "Detailed View" + }, + "support": { + "message": "Support" + }, + "start": { + "message": "Start" + }, + "password_colon": { + "message": "Password:" + }, + "please_enter_a_valid_email": { + "message": "Please enter a valid email." + }, + "your_email_do_not_match": { + "message": "Your emails do not match." + }, + "customize_setup": { + "message": "Customize Setup" + }, + "learn_more": { + "message": "Learn More" + }, + "historical_stats": { + "message": "Historical Stats" + }, + "priority_support": { + "message": "Priority Support" + }, + "on": { + "message": "On" + }, + "off": { + "message": "Off" + }, + "enhanced_ad_blocking": { + "message": "Enhanced Ad Blocking" + }, + "smart_blocking": { + "message": "Smart Blocking" + }, + "smart_blocking_DESC": { + "message": "Automatically block and unblock trackers to optimize page performance." + }, + "ad_blocking_DESC": { + "message": "Block advertisements on the pages you visit." + }, + "anti_tracking_DESC": { + "message": "Anonymize personal data for greater protection." + }, + "no_such_email_password_combo": { + "message": "Looks like we can't find this email and password combo. Give it another shot." + }, + "all_basic_features_plus_COLON": { + "message": "All basic features, plus:" + }, + "historical_tracker_stats": { + "message": "Historical Tracker Stats" + }, + "new_color_themes": { + "message": "New Color Themes" } } diff --git a/app/content-scripts/rewards/OfferCard.jsx b/app/content-scripts/rewards/OfferCard.jsx index 9e26138b5..c97e906e9 100644 --- a/app/content-scripts/rewards/OfferCard.jsx +++ b/app/content-scripts/rewards/OfferCard.jsx @@ -74,7 +74,7 @@ class OfferCard extends Component { message: t('rewards_first_prompt_extended'), textLink: { href: 'https://www.ghostery.com/faqs/what-is-ghostery-rewards/', - text: t('rewards_learn_more'), + text: t('learn_more'), callback: () => { this.props.actions.sendSignal('offer_first_learn'); sendMessage('ping', 'rewards_first_learn_more'); diff --git a/app/hub/Views/CreateAccountView/CreateAccountView.jsx b/app/hub/Views/CreateAccountView/CreateAccountView.jsx index 432463ee7..9bd342680 100644 --- a/app/hub/Views/CreateAccountView/CreateAccountView.jsx +++ b/app/hub/Views/CreateAccountView/CreateAccountView.jsx @@ -73,7 +73,7 @@ const CreateAccountView = (props) => {
{ /> {emailError && (
- {t('hub_create_account_label_email_invalid')} + {t('please_enter_a_valid_email')}
)}
{ /> {confirmEmailError && (
- {t('hub_create_account_label_email_confirm_invalid')} + {t('your_emails_do_not_match')}
)}
@@ -147,7 +147,7 @@ const CreateAccountView = (props) => {
{
diff --git a/app/hub/Views/CreateAccountView/__tests__/__snapshots__/CreateAccountView.test.jsx.snap b/app/hub/Views/CreateAccountView/__tests__/__snapshots__/CreateAccountView.test.jsx.snap index 61e4288d1..d1f69a18d 100644 --- a/app/hub/Views/CreateAccountView/__tests__/__snapshots__/CreateAccountView.test.jsx.snap +++ b/app/hub/Views/CreateAccountView/__tests__/__snapshots__/CreateAccountView.test.jsx.snap @@ -40,7 +40,7 @@ exports[`app/hub/Views/CreateAccount component Snapshot tests with react-test-re className="CreateAccountView__inputLabel" htmlFor="create-account-email" > - hub_create_account_label_email + email_colon - hub_create_account_label_email_confirm + confirm_email_colon - hub_create_account_label_password + password_colon - hub_create_account_button_submit + create_account
@@ -288,7 +288,7 @@ exports[`app/hub/Views/CreateAccount component Snapshot tests with react-test-re className="CreateAccountView__inputLabel" htmlFor="create-account-email" > - hub_create_account_label_email + email_colon - hub_create_account_label_email_invalid + please_enter_a_valid_email
- hub_create_account_label_email_confirm + confirm_email_colon - hub_create_account_label_email_confirm_invalid + your_emails_do_not_match
@@ -386,7 +386,7 @@ exports[`app/hub/Views/CreateAccount component Snapshot tests with react-test-re className="CreateAccountView__inputLabel" htmlFor="create-account-password" > - hub_create_account_label_password + password_colon - hub_create_account_button_submit + create_account diff --git a/app/hub/Views/HomeView/HomeView.jsx b/app/hub/Views/HomeView/HomeView.jsx index b22261ce3..e19d54d45 100644 --- a/app/hub/Views/HomeView/HomeView.jsx +++ b/app/hub/Views/HomeView/HomeView.jsx @@ -106,7 +106,7 @@ const HomeView = (props) => { ) : ( - {t('hub_home_subheader_create_account')} + {t('create_account')} )} @@ -120,7 +120,7 @@ const HomeView = (props) => { {t('hub_home_feature_tutorial_text')} - {tutorial_complete ? t('hub_home_feature_tutorial_button_alt') : t('hub_home_feature_tutorial_button')} + {tutorial_complete ? t('hub_home_feature_tutorial_button_alt') : t('start')}
@@ -128,7 +128,7 @@ const HomeView = (props) => {
- {t('hub_home_feature_setup_title')} + {t('customize_setup')}
{t('hub_home_feature_setup_text')} @@ -146,7 +146,7 @@ const HomeView = (props) => {
- {isPlus ? t('hub_home_feature_supporter_button_alt') : t('hub_home_feature_supporter_button')} + {isPlus ? t('Aready_Subscribed') : t('get_ghostery_plus')}
diff --git a/app/hub/Views/HomeView/HomeView.scss b/app/hub/Views/HomeView/HomeView.scss index 00fbf9b47..7a228b9cc 100644 --- a/app/hub/Views/HomeView/HomeView.scss +++ b/app/hub/Views/HomeView/HomeView.scss @@ -154,16 +154,16 @@ // Firefox Font Size Override and Image Size Override @-moz-document url-prefix() { - .HomeView--firefoxFontSize { - font-size: 75%; - } +.HomeView--firefoxFontSize { + font-size: 75%; +} +.HomeView--firefoxImageSize { + height: 113.875px; +} +@media only screen and (max-width: 740px) { .HomeView--firefoxImageSize { - height: 113.875px; - } - @media only screen and (max-width: 740px) { - .HomeView--firefoxImageSize { - min-width: 126px !important; - max-width: 146px !important; - } + min-width: 126px !important; + max-width: 146px !important; } } +} diff --git a/app/hub/Views/HomeView/HomeViewActions.js b/app/hub/Views/HomeView/HomeViewActions.js index 20f3c5057..3de1b1976 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, SET_METRICS } from './HomeViewConstants'; +import { GET_HOME_PROPS, MARK_PLUS_PROMO_MODAL_SHOWN, SET_METRICS } from './HomeViewConstants'; export function getHomeProps() { return function(dispatch) { @@ -39,3 +39,9 @@ export function setMetrics(actionData) { }); }; } + +export function markPlusPromoModalShown() { + return { + type: MARK_PLUS_PROMO_MODAL_SHOWN, + }; +} diff --git a/app/hub/Views/HomeView/HomeViewConstants.js b/app/hub/Views/HomeView/HomeViewConstants.js index 02218a87b..2defff14b 100644 --- a/app/hub/Views/HomeView/HomeViewConstants.js +++ b/app/hub/Views/HomeView/HomeViewConstants.js @@ -13,4 +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 SET_METRICS = 'SET_METRICS'; diff --git a/app/hub/Views/HomeView/HomeViewContainer.jsx b/app/hub/Views/HomeView/HomeViewContainer.jsx index b3660cf85..fd11d3081 100644 --- a/app/hub/Views/HomeView/HomeViewContainer.jsx +++ b/app/hub/Views/HomeView/HomeViewContainer.jsx @@ -15,6 +15,8 @@ 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 { sendMessage } from '../../utils'; /** * @class Implement the Home View for the Ghostery Hub @@ -27,6 +29,7 @@ class HomeViewContainer extends Component { const { justInstalled } = QueryString.parse(window.location.search); this.state = { + getUserResolved: false, justInstalled: justInstalled === 'true', }; @@ -34,25 +37,44 @@ class HomeViewContainer extends Component { window.document.title = title; props.actions.getHomeProps(); - props.actions.getUser(); + + // 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 + props.actions.getUser() + .then(() => { + this.setState({ + getUserResolved: true, + }); + }); } /** - * Function to handle toggling Metrics Opt-In - */ + * @private + * Function to handle toggling Metrics Opt-In + */ _handleToggleMetrics = () => { const enable_metrics = !this.props.home.enable_metrics; this.props.actions.setMetrics({ enable_metrics }); } /** - * React's required render function. Returns JSX - * @return {JSX} JSX for rendering the Home View of the Hub app + * @private + * Function to handle clicks on Select Plus and Select Basic in the Plus Promo Modal */ - render() { + _handlePlusPromoModalClicks = () => { + // GH-1777 + // we want to show the Plus Promo modal once per Hub visit - not every time the user returns to the Home view + this.props.actions.markPlusPromoModalShown(); + + sendMessage('SET_PLUS_PROMO_MODAL_SEEN', {}); + } + + _render() { const { justInstalled } = this.state; const { home, user } = this.props; + const isPlus = user && user.subscriptionsPlus || false; const { + plus_promo_modal_shown, setup_complete, tutorial_complete, enable_metrics, @@ -64,10 +86,29 @@ class HomeViewContainer extends Component { enable_metrics, changeMetrics: this._handleToggleMetrics, email: user ? user.email : '', - isPlus: user && user.subscriptionsPlus || false, + isPlus, }; - return ; + return ( +
+ + +
+ ); + } + + /** + * React's required render function. Returns JSX + * @return {JSX} JSX for rendering the Home View of the Hub app + */ + render() { + const { getUserResolved } = this.state; + + return (getUserResolved ? this._render() : null); } } @@ -75,9 +116,10 @@ class HomeViewContainer extends Component { // Note: isRequired is not needed when a prop has a default value HomeViewContainer.propTypes = { home: PropTypes.shape({ + enable_metrics: PropTypes.bool, + plus_promo_modal_shown: PropTypes.bool, setup_complete: PropTypes.bool, tutorial_complete: PropTypes.bool, - enable_metrics: PropTypes.bool, }), user: PropTypes.shape({ email: PropTypes.string, @@ -85,17 +127,19 @@ HomeViewContainer.propTypes = { }), actions: PropTypes.shape({ getHomeProps: PropTypes.func.isRequired, - setMetrics: PropTypes.func.isRequired, getUser: PropTypes.func.isRequired, + markPlusPromoModalShown: PropTypes.func.isRequired, + setMetrics: PropTypes.func.isRequired, }).isRequired, }; // Default props used on the Home View HomeViewContainer.defaultProps = { home: { + enable_metrics: false, + plus_promo_modal_shown: false, setup_complete: false, tutorial_complete: false, - enable_metrics: false, }, user: { email: '', diff --git a/app/hub/Views/HomeView/HomeViewReducer.js b/app/hub/Views/HomeView/HomeViewReducer.js index e14aaa559..f60c13123 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, SET_METRICS } from './HomeViewConstants'; +import { GET_HOME_PROPS, MARK_PLUS_PROMO_MODAL_SHOWN, SET_METRICS } from './HomeViewConstants'; const initialState = {}; @@ -31,6 +31,13 @@ function HomeViewReducer(state = initialState, action) { }), }); } + case MARK_PLUS_PROMO_MODAL_SHOWN: { + return Object.assign({}, state, { + home: Object.assign({}, state.home, { + plus_promo_modal_shown: true, + }) + }); + } case SET_METRICS: { const { enable_metrics } = action.data; return Object.assign({}, state, { diff --git a/app/hub/Views/HomeView/__tests__/__snapshots__/HomeView.test.jsx.snap b/app/hub/Views/HomeView/__tests__/__snapshots__/HomeView.test.jsx.snap index 1b14914b8..808de5ec5 100644 --- a/app/hub/Views/HomeView/__tests__/__snapshots__/HomeView.test.jsx.snap +++ b/app/hub/Views/HomeView/__tests__/__snapshots__/HomeView.test.jsx.snap @@ -75,7 +75,7 @@ exports[`app/hub/Views/HomeView component Snapshot tests with react-test-rendere href="/create-account" onClick={[Function]} > - hub_home_subheader_create_account + create_account
- hub_home_feature_tutorial_button + start
- hub_home_feature_setup_title + customize_setup
- hub_home_feature_supporter_button + get_ghostery_plus
@@ -295,7 +295,7 @@ exports[`app/hub/Views/HomeView component Snapshot tests with react-test-rendere
- hub_home_feature_setup_title + customize_setup
- hub_home_feature_supporter_button_alt + Aready_Subscribed
diff --git a/app/hub/Views/LogInView/LogInView.jsx b/app/hub/Views/LogInView/LogInView.jsx index 2147985b6..6e76b3462 100644 --- a/app/hub/Views/LogInView/LogInView.jsx +++ b/app/hub/Views/LogInView/LogInView.jsx @@ -56,7 +56,7 @@ const LogInView = (props) => {
{ /> {emailError && (
- {t('hub_login_label_email_invalid')} + {t('please_enter_a_valid_email')}
)} {
diff --git a/app/hub/Views/LogInView/LogInViewContainer.jsx b/app/hub/Views/LogInView/LogInViewContainer.jsx index b5d9c616a..fb9cd1289 100644 --- a/app/hub/Views/LogInView/LogInViewContainer.jsx +++ b/app/hub/Views/LogInView/LogInViewContainer.jsx @@ -109,7 +109,7 @@ class LogInViewContainer extends Component { this.props.history.push('/'); } else { this.props.actions.setToast({ - toastMessage: t('hub_login_toast_error'), + toastMessage: t('no_such_email_password_combo'), toastClass: 'alert' }); } diff --git a/app/hub/Views/LogInView/__tests__/__snapshots__/LogInView.test.jsx.snap b/app/hub/Views/LogInView/__tests__/__snapshots__/LogInView.test.jsx.snap index 82823ec9d..d6b6f0e0f 100644 --- a/app/hub/Views/LogInView/__tests__/__snapshots__/LogInView.test.jsx.snap +++ b/app/hub/Views/LogInView/__tests__/__snapshots__/LogInView.test.jsx.snap @@ -40,7 +40,7 @@ exports[`app/hub/Views/LogIn component Snapshot tests with react-test-renderer l className="LogInView__inputLabel" htmlFor="login-email" > - hub_login_label_email + email_colon - hub_login_label_password + password_colon - hub_login_button_submit + sign_in
@@ -140,7 +140,7 @@ exports[`app/hub/Views/LogIn component Snapshot tests with react-test-renderer l className="LogInView__inputLabel" htmlFor="login-email" > - hub_login_label_email + email_colon - hub_login_label_email_invalid + please_enter_a_valid_email - hub_login_button_submit + sign_in diff --git a/app/hub/Views/PlusView/PlusView.jsx b/app/hub/Views/PlusView/PlusView.jsx index 9f6d0d89c..6457f84fe 100644 --- a/app/hub/Views/PlusView/PlusView.jsx +++ b/app/hub/Views/PlusView/PlusView.jsx @@ -36,11 +36,11 @@ class PlusView extends Component { return isPlus ? (
- {t('hub_supporter_button_text_alt')} + {t('already_subscribed')}
) : ( - {t('hub_supporter_button_text')} + {t('get_ghostery_plus')} ); } @@ -74,7 +74,7 @@ class PlusView extends Component {
- {t('hub_supporter_perk_themes_title')} + {t('new_themes')}
{t('hub_supporter_perk_themes_description')} @@ -83,7 +83,7 @@ class PlusView extends Component {
- {t('hub_supporter_perk_stats_title')} + {t('historical_blocking_stats')}
{t('hub_supporter_perk_stats_description')} @@ -110,7 +110,7 @@ class PlusView extends Component {
- {t('hub_supporter_feature_theme_title')} + {t('new_themes')}
{t('hub_supporter_feature_theme_description')} @@ -121,7 +121,7 @@ class PlusView extends Component { {t('hub_supporter_feature_theme_title')}
@@ -139,12 +139,12 @@ class PlusView extends Component { {t('hub_supporter_feature_stats_title')}
- {t('hub_supporter_feature_stats_title')} + {t('historical_blocking_stats')}
{t('hub_supporter_feature_stats_description')} @@ -155,7 +155,7 @@ class PlusView extends Component { {t('hub_supporter_feature_stats_title')}
@@ -171,7 +171,7 @@ class PlusView extends Component {
- {t('hub_supporter_feature_support_title')} + {t('priority_support')}
{t('hub_supporter_feature_support_description')} @@ -182,7 +182,7 @@ class PlusView extends Component { {t('hub_supporter_feature_support_title')}
diff --git a/app/hub/Views/PlusView/__tests__/__snapshots__/PlusView.test.jsx.snap b/app/hub/Views/PlusView/__tests__/__snapshots__/PlusView.test.jsx.snap index dff7f3f49..c673637ca 100644 --- a/app/hub/Views/PlusView/__tests__/__snapshots__/PlusView.test.jsx.snap +++ b/app/hub/Views/PlusView/__tests__/__snapshots__/PlusView.test.jsx.snap @@ -29,7 +29,7 @@ exports[`app/hub/Views/PlusView component Snapshot tests with react-test-rendere
- hub_supporter_button_text_alt + already_subscribed
- hub_supporter_perk_themes_title + new_themes
- hub_supporter_perk_stats_title + historical_blocking_stats
- hub_supporter_feature_theme_title + new_themes
- hub_supporter_button_text_alt + already_subscribed
hub_supporter_feature_theme_title @@ -157,7 +157,7 @@ exports[`app/hub/Views/PlusView component Snapshot tests with react-test-rendere
- hub_supporter_button_text_alt + already_subscribed
hub_supporter_feature_stats_title @@ -186,7 +186,7 @@ exports[`app/hub/Views/PlusView component Snapshot tests with react-test-rendere
- hub_supporter_feature_stats_title + historical_blocking_stats
- hub_supporter_button_text_alt + already_subscribed
hub_supporter_feature_stats_title @@ -221,7 +221,7 @@ exports[`app/hub/Views/PlusView component Snapshot tests with react-test-rendere
- hub_supporter_button_text_alt + already_subscribed
- hub_supporter_feature_support_title + priority_support
- hub_supporter_button_text_alt + already_subscribed
hub_supporter_feature_support_title @@ -276,7 +276,7 @@ exports[`app/hub/Views/PlusView component Snapshot tests with react-test-rendere
- hub_supporter_button_text_alt + already_subscribed
- hub_supporter_button_text_alt + already_subscribed
- hub_supporter_button_text + get_ghostery_plus
- hub_supporter_perk_themes_title + new_themes
- hub_supporter_perk_stats_title + historical_blocking_stats
- hub_supporter_feature_theme_title + new_themes
- hub_supporter_button_text + get_ghostery_plus
hub_supporter_feature_theme_title @@ -502,7 +502,7 @@ exports[`app/hub/Views/PlusView component Snapshot tests with react-test-rendere rel="noopener noreferrer" target="_blank" > - hub_supporter_button_text + get_ghostery_plus
hub_supporter_feature_stats_title @@ -531,7 +531,7 @@ exports[`app/hub/Views/PlusView component Snapshot tests with react-test-rendere
- hub_supporter_feature_stats_title + historical_blocking_stats
- hub_supporter_button_text + get_ghostery_plus
hub_supporter_feature_stats_title @@ -574,7 +574,7 @@ exports[`app/hub/Views/PlusView component Snapshot tests with react-test-rendere rel="noopener noreferrer" target="_blank" > - hub_supporter_button_text + get_ghostery_plus
- hub_supporter_feature_support_title + priority_support
- hub_supporter_button_text + get_ghostery_plus
hub_supporter_feature_support_title @@ -637,7 +637,7 @@ exports[`app/hub/Views/PlusView component Snapshot tests with react-test-rendere rel="noopener noreferrer" target="_blank" > - hub_supporter_button_text + get_ghostery_plus
- hub_supporter_button_text + get_ghostery_plus diff --git a/app/hub/Views/RewardsView/__tests__/__snapshots__/RewardsView.test.jsx.snap b/app/hub/Views/RewardsView/__tests__/__snapshots__/RewardsView.test.jsx.snap index fa349dd34..f5d3ad6fe 100644 --- a/app/hub/Views/RewardsView/__tests__/__snapshots__/RewardsView.test.jsx.snap +++ b/app/hub/Views/RewardsView/__tests__/__snapshots__/RewardsView.test.jsx.snap @@ -37,7 +37,7 @@ exports[`app/hub/Views/RewardsView component Snapshot tests with react-test-rend rel="noopener noreferrer" target="_blank" > - hub_rewards_header_learn_more + learn_more
diff --git a/app/hub/Views/SetupViews/SetupAntiSuiteView/SetupAntiSuiteViewContainer.jsx b/app/hub/Views/SetupViews/SetupAntiSuiteView/SetupAntiSuiteViewContainer.jsx index 08302f49b..42c9f03fe 100644 --- a/app/hub/Views/SetupViews/SetupAntiSuiteView/SetupAntiSuiteViewContainer.jsx +++ b/app/hub/Views/SetupViews/SetupAntiSuiteView/SetupAntiSuiteViewContainer.jsx @@ -36,8 +36,8 @@ class SetupAntiSuiteViewContainer extends Component { hrefPrev: `/setup/${index - 1}`, hrefNext: `/setup/${index + 1}`, hrefDone: '/', - textPrev: t('hub_setup_nav_previous'), - textNext: t('hub_setup_nav_next'), + textPrev: t('previous'), + textNext: t('next'), textDone: t('hub_setup_exit_flow'), }); @@ -103,7 +103,7 @@ class SetupAntiSuiteViewContainer extends Component { const features = [ { id: 'anti-tracking', - name: t('hub_setup_antisuite_name_antitracking'), + name: t('enhanced_anti_tracking'), enabled: anti_tracking_enabled, locked: IS_CLIQZ, toggle: IS_CLIQZ ? @@ -113,20 +113,20 @@ class SetupAntiSuiteViewContainer extends Component { }, { id: 'ad-block', - name: t('hub_setup_adblock_name_adblocking'), + name: t('enhanced_ad_blocking'), enabled: ad_block_enabled, locked: IS_CLIQZ, toggle: IS_CLIQZ ? () => {} : () => this._handleToggle('ad-block'), - description: IS_CLIQZ ? t('hub_setup_feature_already_active') : t('hub_setup_adblock_description_adblocking'), + description: IS_CLIQZ ? t('hub_setup_feature_already_active') : t('ad_blocking_DESC'), }, { id: 'smart-blocking', - name: t('hub_setup_smartblocking_name_smartblocking'), + name: t('smart_blocking'), enabled: enable_smart_block, toggle: () => this._handleToggle('smart-blocking'), - description: t('hub_setup_smartblocking_description_smartblocking'), + description: t('smart_blocking_DESC'), } ]; diff --git a/app/hub/Views/SetupViews/SetupBlockingDropdown/SetupBlockingDropdown.jsx b/app/hub/Views/SetupViews/SetupBlockingDropdown/SetupBlockingDropdown.jsx index f876ad30b..1944171e1 100644 --- a/app/hub/Views/SetupViews/SetupBlockingDropdown/SetupBlockingDropdown.jsx +++ b/app/hub/Views/SetupViews/SetupBlockingDropdown/SetupBlockingDropdown.jsx @@ -80,7 +80,7 @@ class SetupBlockingDropdown extends Component {
- {t('hub_setup_nav_done')} + {t('done')}
diff --git a/app/hub/Views/SetupViews/SetupBlockingDropdown/__tests__/__snapshots__/SetupBlockingDropdown.test.jsx.snap b/app/hub/Views/SetupViews/SetupBlockingDropdown/__tests__/__snapshots__/SetupBlockingDropdown.test.jsx.snap index 0fe67c4a8..1bbb9a35c 100644 --- a/app/hub/Views/SetupViews/SetupBlockingDropdown/__tests__/__snapshots__/SetupBlockingDropdown.test.jsx.snap +++ b/app/hub/Views/SetupViews/SetupBlockingDropdown/__tests__/__snapshots__/SetupBlockingDropdown.test.jsx.snap @@ -14,7 +14,7 @@ exports[`app/hub/Views/SetupViews/SetupBlockingDropdown component Snapshot tests className="button success" onClick={[Function]} > - hub_setup_nav_done + done
diff --git a/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingViewContainer.jsx b/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingViewContainer.jsx index fdc2e5124..e1b7ac71c 100644 --- a/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingViewContainer.jsx +++ b/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingViewContainer.jsx @@ -40,7 +40,7 @@ class SetupBlockingViewContainer extends Component { hrefNext: `/setup/${index + 1}`, hrefDone: '/', textPrev: false, - textNext: t('hub_setup_nav_next'), + textNext: t('next'), textDone: t('hub_setup_exit_flow'), }); diff --git a/app/hub/Views/SetupViews/SetupDoneView/SetupDoneViewContainer.jsx b/app/hub/Views/SetupViews/SetupDoneView/SetupDoneViewContainer.jsx index 1416b0388..3ee04fcb9 100644 --- a/app/hub/Views/SetupViews/SetupDoneView/SetupDoneViewContainer.jsx +++ b/app/hub/Views/SetupViews/SetupDoneView/SetupDoneViewContainer.jsx @@ -33,8 +33,8 @@ class SetupDoneViewContainer extends Component { hrefPrev: `/setup/${index - 1}`, hrefNext: '/', hrefDone: '/', - textPrev: t('hub_setup_nav_previous'), - textNext: t('hub_setup_nav_done'), + textPrev: t('previous'), + textNext: t('done'), textDone: t('hub_setup_exit_flow'), }); @@ -56,14 +56,14 @@ class SetupDoneViewContainer extends Component { id: 'tutorial', title: t('hub_setup_feature_tutorial_title'), description: t('hub_setup_feature_tutorial_description'), - buttonText: t('hub_setup_feature_tutorial_button'), + buttonText: t('start'), buttonHref: '/tutorial/1', }, { id: 'plus', - title: t('hub_setup_feature_supporter_title'), + title: t('get_ghostery_plus'), description: t('hub_setup_feature_supporter_description'), - buttonText: t('hub_setup_feature_supporter_button'), + buttonText: t('support'), buttonHref: '/plus', }, { diff --git a/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebViewContainer.jsx b/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebViewContainer.jsx index c7dc7ee8f..3e6415082 100644 --- a/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebViewContainer.jsx +++ b/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebViewContainer.jsx @@ -33,8 +33,8 @@ class SetupHumanWebViewContainer extends Component { hrefPrev: `/setup/${index - 1}`, hrefNext: `/setup/${index + 1}`, hrefDone: '/', - textPrev: t('hub_setup_nav_previous'), - textNext: t('hub_setup_nav_next'), + textPrev: t('previous'), + textNext: t('next'), textDone: t('hub_setup_exit_flow'), }); diff --git a/app/hub/Views/SideNavigationView/SideNavigationViewContainer.jsx b/app/hub/Views/SideNavigationView/SideNavigationViewContainer.jsx index f3526640f..7bd78abcf 100644 --- a/app/hub/Views/SideNavigationView/SideNavigationViewContainer.jsx +++ b/app/hub/Views/SideNavigationView/SideNavigationViewContainer.jsx @@ -49,21 +49,21 @@ class SideNavigationViewContainer extends Component { const menuItems = [ { href: '/', icon: 'home', text: t('hub_side_navigation_home') }, - { href: '/setup', icon: 'setup', text: t('hub_side_navigation_setup') }, + { href: '/setup', icon: 'setup', text: t('customize_setup') }, { href: '/tutorial', icon: 'tutorial', text: t('hub_side_navigation_tutorial') }, - { href: '/plus', icon: 'plus', text: t('hub_side_navigation_supporter') }, + { href: '/plus', icon: 'plus', text: t('get_ghostery_plus') }, ...(IS_CLIQZ ? [] : [{ href: '/rewards', icon: 'rewards', text: t('hub_side_navigation_rewards') }]), { href: '/products', icon: 'products', text: t('hub_side_navigation_products') } ]; const bottomItems = user ? [ { id: 'email', href: `https://account.${globals.GHOSTERY_DOMAIN}.com/`, text: user.email }, - { id: 'logout', text: t('hub_side_navigation_log_out'), clickHandler: this._handleLogoutClick }, + { id: 'logout', text: t('sign_out'), clickHandler: this._handleLogoutClick }, ] : [ - { id: 'create-account', href: '/create-account', text: t('hub_side_navigation_create_account') }, + { id: 'create-account', href: '/create-account', text: t('create_account') }, { id: 'log-id', href: '/log-in', - text: t('hub_side_navigation_log_in'), + text: t('sign_in'), icon: 'profile', }, ]; diff --git a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteView.jsx b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteView.jsx index ed5776b48..5b4ec4e55 100644 --- a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteView.jsx +++ b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteView.jsx @@ -22,20 +22,20 @@ const TutorialAntiSuiteView = () => (
- {t('hub_tutorial_simple_view')} + {t('simple_view')}
{t('hub_tutorial_simple_view')}
- {t('hub_tutorial_detailed_view')} + {t('detailed_view')}
{t('hub_tutorial_detailed_view')}
@@ -48,7 +48,7 @@ const TutorialAntiSuiteView = () => (
- {t('hub_tutorial_antisuite_antitracking_title')} + {t('enhanced_anti_tracking')}
{t('hub_tutorial_antisuite_antitracking_description')} @@ -59,10 +59,10 @@ const TutorialAntiSuiteView = () => (
- {t('hub_tutorial_antisuite_adblocking_title')} + {t('enhanced_ad_blocking')}
- {t('hub_tutorial_antisuite_adblocking_description')} + {t('ad_blocking_DESC')}
@@ -70,10 +70,10 @@ const TutorialAntiSuiteView = () => (
- {t('hub_tutorial_antisuite_smartblocking_title')} + {t('smart_blocking')}
- {t('hub_tutorial_antisuite_smartblocking_description')} + {t('smart_blocking_DESC')}
diff --git a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteViewContainer.jsx b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteViewContainer.jsx index bd8a4af68..a08f8708c 100644 --- a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteViewContainer.jsx +++ b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteViewContainer.jsx @@ -33,8 +33,8 @@ class TutorialAntiSuiteViewContainer extends Component { hrefPrev: `/tutorial/${index - 1}`, hrefNext: '/', hrefDone: '/', - textPrev: t('hub_tutorial_nav_previous'), - textNext: t('hub_tutorial_nav_done'), + textPrev: t('previous'), + textNext: t('done'), textDone: t('hub_tutorial_exit_flow'), }); diff --git a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/__test__/__snapshots__/TutorialAntiSuiteView.test.jsx.snap b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/__test__/__snapshots__/TutorialAntiSuiteView.test.jsx.snap index a99bef9d4..83a6fdc3e 100644 --- a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/__test__/__snapshots__/TutorialAntiSuiteView.test.jsx.snap +++ b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/__test__/__snapshots__/TutorialAntiSuiteView.test.jsx.snap @@ -10,20 +10,20 @@ exports[`app/hub/Views/TutorialViews/TutorialAntiSuiteView component Snapshot te
- hub_tutorial_simple_view + simple_view
hub_tutorial_simple_view
- hub_tutorial_detailed_view + detailed_view
hub_tutorial_detailed_view @@ -49,7 +49,7 @@ exports[`app/hub/Views/TutorialViews/TutorialAntiSuiteView component Snapshot te
- hub_tutorial_antisuite_antitracking_title + enhanced_anti_tracking
- hub_tutorial_antisuite_adblocking_title + enhanced_ad_blocking
- hub_tutorial_antisuite_adblocking_description + ad_blocking_DESC
@@ -87,12 +87,12 @@ exports[`app/hub/Views/TutorialViews/TutorialAntiSuiteView component Snapshot te
- hub_tutorial_antisuite_smartblocking_title + smart_blocking
- hub_tutorial_antisuite_smartblocking_description + smart_blocking_DESC
diff --git a/app/hub/Views/TutorialViews/TutorialBlockingView/TutorialBlockingView.jsx b/app/hub/Views/TutorialViews/TutorialBlockingView/TutorialBlockingView.jsx index eb3d9e4a7..ca0199702 100644 --- a/app/hub/Views/TutorialViews/TutorialBlockingView/TutorialBlockingView.jsx +++ b/app/hub/Views/TutorialViews/TutorialBlockingView/TutorialBlockingView.jsx @@ -22,12 +22,12 @@ const TutorialBlockingView = () => (
- {t('hub_tutorial_detailed_view')} + {t('detailed_view')}
{t('hub_tutorial_detailed_view')}
{t('hub_tutorial_detailed_expanded_view')} diff --git a/app/hub/Views/TutorialViews/TutorialBlockingView/TutorialBlockingViewContainer.jsx b/app/hub/Views/TutorialViews/TutorialBlockingView/TutorialBlockingViewContainer.jsx index d85fc5dfd..246ac22d1 100644 --- a/app/hub/Views/TutorialViews/TutorialBlockingView/TutorialBlockingViewContainer.jsx +++ b/app/hub/Views/TutorialViews/TutorialBlockingView/TutorialBlockingViewContainer.jsx @@ -33,8 +33,8 @@ class TutorialBlockingViewContainer extends Component { hrefPrev: `/tutorial/${index - 1}`, hrefNext: `/tutorial/${index + 1}`, hrefDone: '/', - textPrev: t('hub_tutorial_nav_previous'), - textNext: t('hub_tutorial_nav_next'), + textPrev: t('previous'), + textNext: t('next'), textDone: t('hub_tutorial_exit_flow'), }); } diff --git a/app/hub/Views/TutorialViews/TutorialBlockingView/__tests__/__snapshots__/TutorialBlockingView.test.jsx.snap b/app/hub/Views/TutorialViews/TutorialBlockingView/__tests__/__snapshots__/TutorialBlockingView.test.jsx.snap index a86a12011..f314105f1 100644 --- a/app/hub/Views/TutorialViews/TutorialBlockingView/__tests__/__snapshots__/TutorialBlockingView.test.jsx.snap +++ b/app/hub/Views/TutorialViews/TutorialBlockingView/__tests__/__snapshots__/TutorialBlockingView.test.jsx.snap @@ -10,10 +10,10 @@ exports[`app/hub/Views/TutorialViews/TutorialBlockingView component Snapshot tes
- hub_tutorial_detailed_view + detailed_view
hub_tutorial_detailed_view diff --git a/app/hub/Views/TutorialViews/TutorialLayoutView/TutorialLayoutView.jsx b/app/hub/Views/TutorialViews/TutorialLayoutView/TutorialLayoutView.jsx index f869c252e..56a7bac57 100644 --- a/app/hub/Views/TutorialViews/TutorialLayoutView/TutorialLayoutView.jsx +++ b/app/hub/Views/TutorialViews/TutorialLayoutView/TutorialLayoutView.jsx @@ -24,12 +24,12 @@ const TutorialLayoutView = () => ( {t('hub_tutorial_simple_view')} {t('hub_tutorial_detailed_view')}
diff --git a/app/hub/Views/TutorialViews/TutorialLayoutView/TutorialLayoutViewContainer.jsx b/app/hub/Views/TutorialViews/TutorialLayoutView/TutorialLayoutViewContainer.jsx index e8e276dea..407bf8fa9 100644 --- a/app/hub/Views/TutorialViews/TutorialLayoutView/TutorialLayoutViewContainer.jsx +++ b/app/hub/Views/TutorialViews/TutorialLayoutView/TutorialLayoutViewContainer.jsx @@ -33,8 +33,8 @@ class TutorialLayoutViewContainer extends Component { hrefPrev: `/tutorial/${index - 1}`, hrefNext: `/tutorial/${index + 1}`, hrefDone: '/', - textPrev: t('hub_tutorial_nav_previous'), - textNext: t('hub_tutorial_nav_next'), + textPrev: t('previous'), + textNext: t('next'), textDone: t('hub_tutorial_exit_flow'), }); } diff --git a/app/hub/Views/TutorialViews/TutorialLayoutView/__tests__/__snapshots__/TutorialLayoutView.test.jsx.snap b/app/hub/Views/TutorialViews/TutorialLayoutView/__tests__/__snapshots__/TutorialLayoutView.test.jsx.snap index 4bfd63c38..1b7dcb048 100644 --- a/app/hub/Views/TutorialViews/TutorialLayoutView/__tests__/__snapshots__/TutorialLayoutView.test.jsx.snap +++ b/app/hub/Views/TutorialViews/TutorialLayoutView/__tests__/__snapshots__/TutorialLayoutView.test.jsx.snap @@ -8,12 +8,12 @@ exports[`app/hub/Views/TutorialViews/TutorialLayoutView component Snapshot tests className="columns small-10 medium-8 large-6 small-offset-1" > hub_tutorial_simple_view hub_tutorial_detailed_view diff --git a/app/hub/Views/TutorialViews/TutorialTrackerListView/TutorialTrackerListViewContainer.jsx b/app/hub/Views/TutorialViews/TutorialTrackerListView/TutorialTrackerListViewContainer.jsx index f09f35815..b59c40b1d 100644 --- a/app/hub/Views/TutorialViews/TutorialTrackerListView/TutorialTrackerListViewContainer.jsx +++ b/app/hub/Views/TutorialViews/TutorialTrackerListView/TutorialTrackerListViewContainer.jsx @@ -33,8 +33,8 @@ class TutorialTrackerListViewContainer extends Component { hrefPrev: `/tutorial/${index - 1}`, hrefNext: `/tutorial/${index + 1}`, hrefDone: '/', - textPrev: t('hub_tutorial_nav_previous'), - textNext: t('hub_tutorial_nav_next'), + textPrev: t('previous'), + textNext: t('next'), textDone: t('hub_tutorial_exit_flow'), }); } diff --git a/app/hub/Views/TutorialViews/TutorialTrustView/TutorialTrustView.jsx b/app/hub/Views/TutorialViews/TutorialTrustView/TutorialTrustView.jsx index 31c66ff5a..605aaa9cb 100644 --- a/app/hub/Views/TutorialViews/TutorialTrustView/TutorialTrustView.jsx +++ b/app/hub/Views/TutorialViews/TutorialTrustView/TutorialTrustView.jsx @@ -22,20 +22,20 @@ const TutorialTrustView = () => (
- {t('hub_tutorial_simple_view')} + {t('simple_view')}
{t('hub_tutorial_simple_view')}
- {t('hub_tutorial_detailed_view')} + {t('detailed_view')}
{t('hub_tutorial_detailed_view')}
diff --git a/app/hub/Views/TutorialViews/TutorialTrustView/TutorialTrustViewContainer.jsx b/app/hub/Views/TutorialViews/TutorialTrustView/TutorialTrustViewContainer.jsx index 373233096..f48598ad0 100644 --- a/app/hub/Views/TutorialViews/TutorialTrustView/TutorialTrustViewContainer.jsx +++ b/app/hub/Views/TutorialViews/TutorialTrustView/TutorialTrustViewContainer.jsx @@ -33,8 +33,8 @@ class TutorialTrustViewContainer extends Component { hrefPrev: `/tutorial/${index - 1}`, hrefNext: `/tutorial/${index + 1}`, hrefDone: '/', - textPrev: t('hub_tutorial_nav_previous'), - textNext: t('hub_tutorial_nav_next'), + textPrev: t('previous'), + textNext: t('next'), textDone: t('hub_tutorial_exit_flow'), }); } diff --git a/app/hub/Views/TutorialViews/TutorialTrustView/__tests__/__snapshots__/TutorialTrustView.test.jsx.snap b/app/hub/Views/TutorialViews/TutorialTrustView/__tests__/__snapshots__/TutorialTrustView.test.jsx.snap index a472a37fe..27e9a3973 100644 --- a/app/hub/Views/TutorialViews/TutorialTrustView/__tests__/__snapshots__/TutorialTrustView.test.jsx.snap +++ b/app/hub/Views/TutorialViews/TutorialTrustView/__tests__/__snapshots__/TutorialTrustView.test.jsx.snap @@ -10,20 +10,20 @@ exports[`app/hub/Views/TutorialViews/TutorialTrustView component Snapshot tests
- hub_tutorial_simple_view + simple_view
hub_tutorial_simple_view
- hub_tutorial_detailed_view + detailed_view
hub_tutorial_detailed_view diff --git a/app/hub/Views/TutorialViews/TutorialVideoView/TutorialVideoViewContainer.jsx b/app/hub/Views/TutorialViews/TutorialVideoView/TutorialVideoViewContainer.jsx index 65b4a5ee2..a6af3c5ce 100644 --- a/app/hub/Views/TutorialViews/TutorialVideoView/TutorialVideoViewContainer.jsx +++ b/app/hub/Views/TutorialViews/TutorialVideoView/TutorialVideoViewContainer.jsx @@ -34,7 +34,7 @@ class TutorialVideoViewContainer extends Component { hrefNext: `/tutorial/${index + 1}`, hrefDone: '/', textPrev: false, - textNext: t('hub_tutorial_nav_next'), + textNext: t('next'), textDone: t('hub_tutorial_exit_flow'), }); } diff --git a/app/hub/utils/index.js b/app/hub/utils/index.js index 0766b4f07..156704369 100644 --- a/app/hub/utils/index.js +++ b/app/hub/utils/index.js @@ -14,10 +14,14 @@ // Imports utilities from elsewhere in the codebase to reduce duplicate code import { log } from '../../../src/utils/common'; -import { sendMessageInPromise as importedSMIP } from '../../panel/utils/msg'; +import { sendMessage as importedSM, sendMessageInPromise as importedSMIP } from '../../panel/utils/msg'; const sendMessageInPromise = function(name, message) { return importedSMIP(name, message, 'ghostery-hub'); }; -export { log, sendMessageInPromise }; +const sendMessage = function(name, message) { + return importedSM(name, message, 'ghostery-hub'); +}; + +export { log, sendMessage, sendMessageInPromise }; diff --git a/app/images/hub/home/check-icon.svg b/app/images/hub/home/check-icon.svg new file mode 100644 index 000000000..7e2e16aad --- /dev/null +++ b/app/images/hub/home/check-icon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/app/images/hub/home/recommended-banner.svg b/app/images/hub/home/recommended-banner.svg new file mode 100644 index 000000000..4777a7728 --- /dev/null +++ b/app/images/hub/home/recommended-banner.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/panel/components/BuildingBlocks/CliqzFeature.jsx b/app/panel/components/BuildingBlocks/CliqzFeature.jsx index 72cfe1372..b699e387a 100644 --- a/app/panel/components/BuildingBlocks/CliqzFeature.jsx +++ b/app/panel/components/BuildingBlocks/CliqzFeature.jsx @@ -51,19 +51,50 @@ class CliqzFeature extends React.Component { } _getStatus(active) { - return active ? t('cliqz_feature_status_on') : t('cliqz_feature_status_off'); + return active ? t('on') : t('off'); } _getTooltipBodyText(active, isTooltipBody, type) { if (!isTooltipBody) return false; - return active ? - t(`tooltip_${type}_body_on`) : - t(`tooltip_${type}_body`); + if (active) { + switch (type) { + case 'ad_block': + return t('tooltip_ad_block_on'); + case 'anti_track': + return t('tooltip_anti_track_on'); + case 'smart_block': + return t('tooltip_smart_block_on'); + default: + return false; + } + } else { + switch (type) { + case 'ad_block': + return t('ad_blocking_DESC'); + case 'anti_track': + return t('anti_tracking_DESC'); + case 'smart_block': + return t('smart_blocking_DESC'); + default: + return false; + } + } } _getTooltipHeaderText(isTooltipHeader, type) { - return isTooltipHeader ? t(`tooltip_${type}`) : false; + if (!isTooltipHeader) return false; + + switch (type) { + case 'ad_block': + return t('enhanced_ad_blocking'); + case 'anti_track': + return t('enhanced_anti_tracking'); + case 'smart_block': + return t('smart_blocking'); + default: + return false; + } } _getAlertText(active, type) { @@ -103,7 +134,14 @@ class CliqzFeature extends React.Component { const iconClassNames = ClassNames('CliqzFeature__icon', cssTypeName, 'g-tooltip'); const featureType = type === 'anti_track' ? 'anti_tracking' : type; - const featureName = t(`drawer_title_enable_${featureType}`); + let featureName; + if (featureType === 'anti_tracking') { + featureName = t('enhanced_anti_tracking'); + } else if (featureType === 'ad_block') { + featureName = t('enhanced_ad_blocking'); + } else if (featureType === 'smart_block') { + featureName = t('smart_blocking'); + } return (
diff --git a/app/panel/components/CreateAccount.jsx b/app/panel/components/CreateAccount.jsx index db5fe2f4a..8c615c5f5 100644 --- a/app/panel/components/CreateAccount.jsx +++ b/app/panel/components/CreateAccount.jsx @@ -152,21 +152,21 @@ class CreateAccount extends React.Component {

- { t('invalid_email_create') } + { t('please_enter_a_valid_email') }

-

{ t('invalid_email_confirmation') }

+

{ t('your_emails_do_not_match') }

@@ -194,7 +194,7 @@ class CreateAccount extends React.Component {
@@ -240,7 +240,7 @@ class CreateAccount extends React.Component {
diff --git a/app/panel/components/DetailMenu.jsx b/app/panel/components/DetailMenu.jsx index ecec07c98..9443029d5 100644 --- a/app/panel/components/DetailMenu.jsx +++ b/app/panel/components/DetailMenu.jsx @@ -74,7 +74,7 @@ class DetailMenu extends React.Component { - { t('panel_detail_menu_stats_title') } + { t('historical_stats') }
diff --git a/app/panel/components/ForgotPassword.jsx b/app/panel/components/ForgotPassword.jsx index f187ff21d..b1d0f7bbe 100644 --- a/app/panel/components/ForgotPassword.jsx +++ b/app/panel/components/ForgotPassword.jsx @@ -83,7 +83,7 @@ class ForgotPassword extends React.Component {
diff --git a/app/panel/components/Header.jsx b/app/panel/components/Header.jsx index 8768b72c2..a8be9d5ff 100644 --- a/app/panel/components/Header.jsx +++ b/app/panel/components/Header.jsx @@ -101,7 +101,7 @@ class Header extends React.Component { let text = ''; let handleOnClick = null; if (!loggedIn) { - text = t('panel_header_sign_in'); + text = t('sign_in'); handleOnClick = this.handleSignin; } else if (loggedIn && user && !user.emailValidated) { text = t('panel_header_verify_account'); @@ -186,7 +186,7 @@ class Header extends React.Component { const simpleTab = (
- {t('panel_header_simple_view')} + {t('simple_view')}
); @@ -194,7 +194,7 @@ class Header extends React.Component { const detailedTab = (
- {t('panel_header_detailed_view')} + {t('detailed_view')}
); diff --git a/app/panel/components/HeaderMenu.jsx b/app/panel/components/HeaderMenu.jsx index 5b0dcc2d7..bc03910c0 100644 --- a/app/panel/components/HeaderMenu.jsx +++ b/app/panel/components/HeaderMenu.jsx @@ -236,7 +236,7 @@ class HeaderMenu extends React.Component { - { t('panel_menu_ghostery_subscriber') } + { t('ghostery_plus') }
@@ -251,10 +251,10 @@ class HeaderMenu extends React.Component { { email }
- { t('panel_menu_signin') } + { t('sign_in') }
- { t('panel_menu_signout') } + { t('sign_out') }
diff --git a/app/panel/components/Help.jsx b/app/panel/components/Help.jsx index 057a47736..c436a5b06 100644 --- a/app/panel/components/Help.jsx +++ b/app/panel/components/Help.jsx @@ -33,7 +33,7 @@ const Help = () => {

{ t('panel_help_questions_header') }

{t('panel_help_faq')} {t('panel_help_feedback')} - { t('panel_help_support') } + { t('support') }

{ t('panel_help_contact_header') }

diff --git a/app/panel/components/Login.jsx b/app/panel/components/Login.jsx index 4ea3c807d..d92dbe856 100644 --- a/app/panel/components/Login.jsx +++ b/app/panel/components/Login.jsx @@ -99,7 +99,7 @@ class Login extends React.Component {
@@ -121,7 +121,7 @@ class Login extends React.Component {
@@ -136,7 +136,7 @@ class Login extends React.Component { { t('panel_forgot_password') }
- { t('panel_create_account') } + { t('create_account') }
diff --git a/app/panel/components/Panel.jsx b/app/panel/components/Panel.jsx index 684d21b4d..64a34941f 100644 --- a/app/panel/components/Panel.jsx +++ b/app/panel/components/Panel.jsx @@ -12,10 +12,13 @@ */ import React from 'react'; +import ClassNames from 'classnames'; import Header from '../containers/HeaderContainer'; +import { PlusPromoModal } from '../../shared-components'; import { DynamicUIPortContext } from '../contexts/DynamicUIPortContext'; import { sendMessage } from '../utils/msg'; import { setTheme } from '../utils/utils'; +import Modal from '../../shared-components/Modal'; /** * @class Implement base view with functionality common to all views. * @memberof PanelClasses @@ -28,6 +31,10 @@ class Panel extends React.Component { this.closeNotification = this.closeNotification.bind(this); this.clickReloadBanner = this.clickReloadBanner.bind(this); this.filterTrackers = this.filterTrackers.bind(this); + + this.state = { + plusPromoModalShown: false, + }; } /** @@ -193,6 +200,57 @@ class Panel extends React.Component { return false; } + _handlePlusPromoModalClicks = () => { + // TODO send appropriate metrics ping(s) for GH-1775 + sendMessage('promoModals.sawPlusPromo', {}); + this.setState({ + plusPromoModalShown: true + }); + } + + _renderPlusPromoUpgradeModal() { + const contentClassNames = ClassNames( + 'PlusPromoModal__content', + 'flex-container', + 'flex-dir-column', + 'align-middle', + 'panel' + ); + + return ( + +
+
[Upgrade version of the Plus Promo modal]
+
+ Dismiss +
+
+
+ ); + } + + _renderPlusPromoModal = () => { + const { plusPromoModalShown } = this.state; + const { account, haveSeenInitialPlusPromo, isTimeForAPlusPromo } = this.props; + + if (account && account.user && account.user.subscriptionsPlus) return null; // don't show the promo to Plus subscribers! + if (account && account.user && account.user.scopes && account.user.scopes.includes('subscriptions:insights')) return null; // don't show the promo to Insights subscribers, either + + if (plusPromoModalShown || !isTimeForAPlusPromo) return null; + + const version = haveSeenInitialPlusPromo ? PlusPromoModal.UPGRADE : PlusPromoModal.INITIAL; + + if (haveSeenInitialPlusPromo) { return this._renderPlusPromoUpgradeModal(); } + + return ( + + ); + } + /** * React's required render function. Returns JSX * @return {JSX} JSX for rendering the Panel @@ -207,6 +265,7 @@ class Panel extends React.Component { return (
+ {this._renderPlusPromoModal()}
diff --git a/app/panel/components/Rewards.jsx b/app/panel/components/Rewards.jsx index fee5e4fc1..8ba483f27 100644 --- a/app/panel/components/Rewards.jsx +++ b/app/panel/components/Rewards.jsx @@ -224,7 +224,7 @@ class Rewards extends React.Component {
{ t('panel_detail_rewards_cliqz_text') }

- { t('panel_detail_learn_more') } + { t('learn_more') }
); diff --git a/app/panel/components/Stats.jsx b/app/panel/components/Stats.jsx index 117230c8f..b4028171b 100644 --- a/app/panel/components/Stats.jsx +++ b/app/panel/components/Stats.jsx @@ -106,13 +106,13 @@ class Stats extends React.Component { getSummaryTitle = (type) => { switch (type) { case 'cumulative': - return t('panel_stats_header_title'); + return t('historical_tracker_stats'); case 'monthly': return t('panel_stats_header_title_monthly'); case 'daily': return t('panel_stats_header_title_daily'); default: - return t('panel_stats_header_title'); + return t('historical_tracker_stats'); } } diff --git a/app/panel/components/StatsView.jsx b/app/panel/components/StatsView.jsx index 312d8fa20..e850cac14 100644 --- a/app/panel/components/StatsView.jsx +++ b/app/panel/components/StatsView.jsx @@ -196,7 +196,7 @@ const StatsView = (props) => {
-
{t('panel_stats_pitch_modal_subscribe')}
+
{t('Get_Ghostery_Plus_bang')}
{ !loggedIn && (
diff --git a/app/panel/components/Subscribe.jsx b/app/panel/components/Subscribe.jsx index dab8ecd5f..e21fdf240 100644 --- a/app/panel/components/Subscribe.jsx +++ b/app/panel/components/Subscribe.jsx @@ -40,7 +40,7 @@ const Subscribe = (props) => { {t('subscribe_pitch_learn_more')}
- {t('subscribe_pitch_button_label')} + {t('Get_Ghostery_Plus_bang')}
{(loggedIn === 'false') && ( diff --git a/app/panel/components/Subscription/PrioritySupport.jsx b/app/panel/components/Subscription/PrioritySupport.jsx index 57b63ec52..94ddd15aa 100644 --- a/app/panel/components/Subscription/PrioritySupport.jsx +++ b/app/panel/components/Subscription/PrioritySupport.jsx @@ -24,7 +24,7 @@ const PrioritySupport = () => (
-

{ t('subscription_priority_support_title') }

+

{ t('priority_support') }

{ t('subscription_support') }
diff --git a/app/panel/components/Subscription/SubscriptionInfo.jsx b/app/panel/components/Subscription/SubscriptionInfo.jsx index 3090992c8..93c1161a4 100644 --- a/app/panel/components/Subscription/SubscriptionInfo.jsx +++ b/app/panel/components/Subscription/SubscriptionInfo.jsx @@ -45,7 +45,7 @@ const SubscriptionInfo = (props) => {
-

{ t('subscription_info_title') }

+

{ t('ghostery_plus') }

{loading ? (
) : ( @@ -75,8 +75,8 @@ const SubscriptionInfo = (props) => {
  • {t('subscription_midnight_theme')}
  • -
  • {t('subscription_tracker_stats')}
  • -
  • {t('subscription_priority_support')}
  • +
  • {t('historical_stats')}
  • +
  • {t('priority_support')}
diff --git a/app/panel/components/Subscription/SubscriptionMenu.jsx b/app/panel/components/Subscription/SubscriptionMenu.jsx index b718e67be..279ac3322 100644 --- a/app/panel/components/Subscription/SubscriptionMenu.jsx +++ b/app/panel/components/Subscription/SubscriptionMenu.jsx @@ -33,13 +33,13 @@ const SubscriptionMenu = () => (
  • - { t('subscription_priority_support') } + { t('priority_support') }
  • - { t('subscription_history_stats') } + { t('historical_stats') }
  • diff --git a/app/panel/components/Summary.jsx b/app/panel/components/Summary.jsx index 766e84b0c..01cf55b04 100644 --- a/app/panel/components/Summary.jsx +++ b/app/panel/components/Summary.jsx @@ -707,7 +707,7 @@ class Summary extends React.Component { return (
    - +
    ); } diff --git a/app/panel/reducers/panel.js b/app/panel/reducers/panel.js index 194f16c73..b249b6e70 100644 --- a/app/panel/reducers/panel.js +++ b/app/panel/reducers/panel.js @@ -108,7 +108,7 @@ export default (state = initialState, action) => { switch (err.code) { case '10050': case '10110': - errorText = t('banner_no_such_account_message'); + errorText = t('no_such_email_password_combo'); break; default: errorText = t('server_error_message'); @@ -139,7 +139,7 @@ export default (state = initialState, action) => { errorText = t('email_address_in_use'); break; case '10080': - errorText = t('invalid_email_confirmation'); + errorText = t('your_emails_do_not_match'); break; default: errorText = t('server_error_message'); diff --git a/app/scss/hub.scss b/app/scss/hub.scss index 1faa03903..a59365f96 100644 --- a/app/scss/hub.scss +++ b/app/scss/hub.scss @@ -53,6 +53,7 @@ html, body, #root { @import './partials/_hub_mixins'; @import './partials/_hub_svgs'; @import './partials/_shared_components_svgs'; +@import './partials/_fonts'; // Imports from ../hub directory @import '../hub/Views/SideNavigationView/SideNavigationView.scss'; @@ -75,6 +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/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 c37affeec..f7e6e1952 100644 --- a/app/scss/panel.scss +++ b/app/scss/panel.scss @@ -73,3 +73,7 @@ html body { @import './partials/_subscribe'; @import './partials/_stats'; @import './partials/_stats_graph'; + +// Imports from ../shared-components directory +@import '../shared-components/Modal/Modal.scss'; +@import '../shared-components/PlusPromoModal/PlusPromoModal.scss'; diff --git a/app/scss/partials/_fonts.scss b/app/scss/partials/_fonts.scss index 0317018f2..919880895 100644 --- a/app/scss/partials/_fonts.scss +++ b/app/scss/partials/_fonts.scss @@ -8,7 +8,7 @@ * 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 @@ -182,3 +182,8 @@ src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/opensans-semibold-latin.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; } + +@font-face { + font-family: Roboto; + src: local(Roboto), url(../fonts/roboto-all-charsets.woff2) format('woff2'), url(../fonts/roboto-all-charsets.woff) format('woff'); +} diff --git a/app/shared-components/PlusPromoModal/PlusPromoModal.jsx b/app/shared-components/PlusPromoModal/PlusPromoModal.jsx new file mode 100644 index 000000000..4b55a6bba --- /dev/null +++ b/app/shared-components/PlusPromoModal/PlusPromoModal.jsx @@ -0,0 +1,141 @@ +/** + * Plus Promo Modal Component + * renders Plus Promo inside of the shared 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'; + +function _renderInitialVersion(props) { + const { show, location, clickHandler } = props; + + const isInHub = location === 'hub'; + + const locationClassName = { + 'in-hub': isInHub, + 'in-panel': location === 'panel' + }; + const contentClassNames = ClassNames( + 'PlusPromoModal__content', + 'flex-container', + 'flex-dir-column', + 'align-middle', + locationClassName + ); + const optionsContainerClassNames = ClassNames( + 'PlusPromoModal__options-container', + 'full-width', + locationClassName + ); + const chooseYourPlanClassNames = ClassNames( + 'PlusPromoModal__choose-your-plan', + locationClassName + ); + const recommendedBannerClassNames = ClassNames( + 'PlusPromoModal__recommended-banner', + locationClassName + ); + const optionDescriptionBoxClassNames = ClassNames( + 'PlusPromoModal__option-description-box', + locationClassName + ); + + // TODO refactor for clarity & concision alongside implementing _renderUpgradeVersion for GH-1813 + return ( + +
    +
    + {isInHub && ( +
    + {t('thanks_for_downloading_ghostery')} +
    + )} +
    + {isInHub ? t('choose_your_privacy_plan') : t('choose_your_ghostery_privacy_plan')} +
    +
    +
    +
    +
    {t('ghostery_basic')}
    +
    + {t('locale_appropriate_currency_icon')} + 0 + + {t('per_month')} +
    +
    +
    {t('protection_for_this_browser')}
    +
    {t('blocks_ads')}
    +
    {t('blocks_trackers')}
    +
    {t('fast_browsing')}
    +
    +
    +
    + {t('select_basic')} +
    +
    +
    +
    +
    + +
    {t('recommended')}
    +
    +
    {t('ghostery_plus')}
    +
    + {t('locale_appropriate_currency_icon')} + {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_plus')} + +
    +
    +
    + + ); +} + +/** + * A Functional React component for a Plus Promo Modal + * @return {JSX} JSX for rendering a Plus Promo Modal + * @memberof SharedComponents + */ +const PlusPromoModal = props => _renderInitialVersion(props); + +// PropTypes ensure we pass required props of the correct type +PlusPromoModal.propTypes = { + show: PropTypes.bool.isRequired, + location: PropTypes.string.isRequired, + clickHandler: PropTypes.func.isRequired, +}; + +export default PlusPromoModal; diff --git a/app/shared-components/PlusPromoModal/PlusPromoModal.scss b/app/shared-components/PlusPromoModal/PlusPromoModal.scss new file mode 100644 index 000000000..7aea1c077 --- /dev/null +++ b/app/shared-components/PlusPromoModal/PlusPromoModal.scss @@ -0,0 +1,200 @@ +.PlusPromoModal__content { + position: relative; + background-color: #f7f7f7; + border: 1.9px solid #930194; + z-index: 10; + + &.in-hub { + width: 646px; + height: 553px; + } + + &.in-panel { + width: 556px; + height: 471px; + } +} + +.PlusPromoModal__buttons-background { + background-color: #e7ecee; + position: absolute; + bottom: 3px; + width: 99%; + height: 72px; + z-index: -1; +} + +.PlusPromoModal__thanks-for-download { + padding-top: 30px; + font-size: 26px; + font-weight: bold; +} + +.PlusPromoModal__choose-your-plan { + font-size: 18px; + font-weight: bold; + + &.in-hub { padding-top: 10px; } + &.in-panel { padding-top: 17px; } +} + +.PlusPromoModal__options-container { + height: 100%; + margin-top: 44px; + display: flex; + + &.in-hub { justify-content: space-evenly; } + &.in-panel { justify-content: space-around; } +} + +.PlusPromoModal__option-container { + display: flex; + align-items: center; + flex-direction: column; +} + +.PlusPromoModal__option-description-box { + border-style: solid; + border-width: 3px; + background-color: #FFFFFF; + + &.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 { + margin-bottom: 45px; + width: 240px; + height: 298px; + } + + &.in-panel { + margin-bottom: 30px; + width: 221px; + height: 294px; + } +} + +.PlusPromoModal__recommended-banner { + position: absolute; + + &.in-hub { + left: -30px; + top: -30px; + } + + &.in-panel { + left: -10px; + top: -32px; + } +} + +.PlusPromoModal__recommended-banner-text { + position: relative; + left: 18px; + top: -47px; + transform: rotate(-15deg); + color: white; + font-size: 16px; + font-weight: bold; +} + +.PlusPromoModal__option-header { + margin-top: 20px; + font-size: 19px; + font-weight: bold; + letter-spacing: -0.5px; + 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-size: 30px; + font-weight: bold; +} + +.PlusPromoModal__amount { + vertical-align: middle; + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 58px; +} + +.PlusPromoModal__per-month { + vertical-align: sub; + font-size: 18px; + font-weight: bold; +} + +.PlusPromoModal__option-description-item { + padding-bottom: 15px; + font-size: 16px; + text-align: center; + color: #333333; + + &.italic { + font-style: italic; + } +} + +.PlusPromoModal__check-icon { + padding-right: 5px; + margin-top: -18px; +} + +.PlusPromoModal__plus-option-description-item-container { + display: flex; + justify-content: center; +} + +.PlusPromoModal__button { + margin: 0; + font-size: 11px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + display: flex; + align-items: center; + justify-content: center; + box-shadow: none; + + &.basic { + width: 135px; + height: 40px; + border: solid 2px #15b4f2; + background-color: white; + color: #2cbcf4; + } + &.basic:hover { + background-color: #2cbcf4; + color: white; + } + + &.plus { + width: 163px; + height: 38px; + border: none; + background-image: linear-gradient(to bottom, #2fdbfa, #15b4f2); + color: white; + font-weight: 600; + letter-spacing: 0.5px; + } + &.plus:hover { + background-image: linear-gradient(to bottom, #1fcbea, #05a4e2); + } +} diff --git a/app/shared-components/PlusPromoModal/index.js b/app/shared-components/PlusPromoModal/index.js new file mode 100644 index 000000000..da26a8b7e --- /dev/null +++ b/app/shared-components/PlusPromoModal/index.js @@ -0,0 +1,16 @@ +/** + * Point of entry index.js file for 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 PlusPromoModal from './PlusPromoModal'; + +export default PlusPromoModal; diff --git a/app/shared-components/index.js b/app/shared-components/index.js index 7910b2ef5..a7fe2f139 100644 --- a/app/shared-components/index.js +++ b/app/shared-components/index.js @@ -17,6 +17,7 @@ import ExitButton from './ExitButton'; import Modal from './Modal'; +import PlusPromoModal from './PlusPromoModal'; import SteppedNavigation from './SteppedNavigation'; import ToastMessage from './ToastMessage'; import ToggleCheckbox from './ToggleCheckbox'; @@ -25,6 +26,7 @@ import ToggleSwitch from './ToggleSwitch'; export { ExitButton, Modal, + PlusPromoModal, SteppedNavigation, ToastMessage, ToggleCheckbox, diff --git a/src/background.js b/src/background.js index de12238b3..c1f9b4683 100644 --- a/src/background.js +++ b/src/background.js @@ -42,6 +42,7 @@ import metrics from './classes/Metrics'; import rewards from './classes/Rewards'; import account from './classes/Account'; import GhosteryModule from './classes/Module'; +import promoModals from './classes/PromoModals'; // utilities import { allowAllwaysC2P } from './utils/click2play'; @@ -541,6 +542,9 @@ function handleRewards(name, message, callback) { */ function handleGhosteryHub(name, message, callback) { switch (name) { + case 'SET_PLUS_PROMO_MODAL_SEEN': + promoModals.recordPlusPromoSighting(); + break; case 'SEND_PING': { const { type } = message; metrics.ping(type); @@ -1074,6 +1078,10 @@ function onMessageHandler(request, sender, callback) { }); return true; } + if (name === 'promoModals.sawPlusPromo') { + promoModals.recordPlusPromoSighting(); + return true; + } } /** diff --git a/src/classes/ConfData.js b/src/classes/ConfData.js index 121c77ef2..40237eab2 100644 --- a/src/classes/ConfData.js +++ b/src/classes/ConfData.js @@ -123,6 +123,7 @@ class ConfData { _initProperty('notify_library_updates', false); _initProperty('notify_upgrade_updates', true); _initProperty('paid_subscription', false); + _initProperty('plus_promo_modal_last_seen', null); _initProperty('rewards_accepted', false); _initProperty('rewards_opted_in', false); _initProperty('settings_last_imported', 0); diff --git a/src/classes/PanelData.js b/src/classes/PanelData.js index 006738f2e..117c9e7f9 100644 --- a/src/classes/PanelData.js +++ b/src/classes/PanelData.js @@ -27,6 +27,7 @@ import tabInfo from './TabInfo'; import rewards from './Rewards'; import account from './Account'; import dispatcher from './Dispatcher'; +import promoModals from './PromoModals'; import { getCliqzGhosteryBugs, sendCliqzModuleCounts } from '../utils/cliqzModulesData'; import { getActiveTab, flushChromeMemoryCache, processUrl } from '../utils/utils'; import { objectEntries, log } from '../utils/common'; @@ -365,6 +366,8 @@ class PanelData { is_expert, is_android: globals.BROWSER_INFO.os === 'android', language, + isTimeForAPlusPromo: promoModals.isTimeForAPlusPromo(), + haveSeenInitialPlusPromo: promoModals.haveSeenInitialPlusPromo(), reload_banner_status, tab_id, trackers_banner_status, diff --git a/src/classes/PromoModals.js b/src/classes/PromoModals.js new file mode 100644 index 000000000..ddcd04ed2 --- /dev/null +++ b/src/classes/PromoModals.js @@ -0,0 +1,57 @@ +/** + * PromoModals Class + * + * 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 conf from './Conf'; +import globals from './Globals'; + +const DAYS_BETWEEN_PROMOS = { + plus: globals.DEBUG ? 0.00025 : 30, +}; +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 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...) + * @memberOf BackgroundClasses + */ +class PromoModals { + static haveSeenInitialPlusPromo() { + const lastSeenTime = conf[`${PLUS}_${PROMO_MODAL_LAST_SEEN}`]; + return (lastSeenTime !== null); + } + + static isTimeForAPlusPromo() { return this._isTimeForAPromo(PLUS); } + + static recordPlusPromoSighting() { this._recordPromoSighting(PLUS); } + + // TODO integrate the Insights promo modal into the "has it been long enough since last modal?" logic here + static _isTimeForAPromo(type) { + const lastSeenTime = conf[`${type}_${PROMO_MODAL_LAST_SEEN}`]; + + if (lastSeenTime === null) { return true; } + + return ( + (Date.now() - lastSeenTime) > + (MSECS_IN_DAY * DAYS_BETWEEN_PROMOS[type]) + ); + } + + static _recordPromoSighting(type) { + conf[`${type}_${PROMO_MODAL_LAST_SEEN}`] = Date.now(); + } +} + +// the class is simply a namespace for some static methods, +// as we do not need to maintain any state +export default PromoModals; diff --git a/tools/i18n-checker.js b/tools/i18n-checker.js index dbf91e0af..0f5d96f36 100644 --- a/tools/i18n-checker.js +++ b/tools/i18n-checker.js @@ -24,7 +24,7 @@ const oboe = require('oboe'); const LOCALES_FOLDER = './_locales'; const GATHER_FILE_PATHS_EXCEPTIONS = ['.DS_Store']; const LANG_FILES_COUNT = 14; -const DEFAULT_LOCALE_PATH = '../_locales/en/messages.json'; +const DEFAULT_LOCALE_PATH = './_locales/en/messages.json'; const DUPLICATE_TOKENS_FILE = './tools/i18n_results/duplicate_tokens.txt'; const MISSING_TOKENS_FILE = './tools/i18n_results/missing_tokens.txt'; const EXTRA_TOKENS_FILE = './tools/i18n_results/extra_tokens.txt'; @@ -175,7 +175,7 @@ function findMissingKeys(paths) { let hasMissingKeys = false; const missingKeys = {}; paths.forEach((path) => { - const localeJson = jsonfile.readFileSync(`.${path}`); + const localeJson = jsonfile.readFileSync(`${path}`); const locale = path.match(/_locales\/(.*)\/messages.json/)[1]; missingKeys[locale] = []; Object.keys(defaultLocaleJson).forEach((key) => { @@ -210,7 +210,7 @@ function findExtraKeys(paths) { let hasExtraKeys = false; const extraKeys = {}; paths.forEach((path) => { - const localeJson = jsonfile.readFileSync(`.${path}`); + const localeJson = jsonfile.readFileSync(`${path}`); const locale = path.match(/_locales\/(.*)\/messages.json/)[1]; extraKeys[locale] = []; Object.keys(localeJson).forEach((key) => { @@ -243,7 +243,7 @@ function findMalformedKeys(paths) { let hasMalformedKeys = false; const malformedKeys = {}; paths.forEach((path) => { - const localeJson = jsonfile.readFileSync(`.${path}`); + const localeJson = jsonfile.readFileSync(`${path}`); const locale = path.match(/_locales\/(.*)\/messages.json/)[1]; malformedKeys[locale] = []; Object.keys(localeJson).forEach((key) => { @@ -278,7 +278,7 @@ function findMissingPlaceholders(paths) { let hasMissingPlaceholders = false; const missingPlaceholders = {}; paths.forEach((path) => { - const localeJson = jsonfile.readFileSync(`.${path}`); + const localeJson = jsonfile.readFileSync(`${path}`); const locale = path.match(/_locales\/(.*)\/messages.json/)[1]; missingPlaceholders[locale] = []; Object.keys(defaultLocaleJson).forEach((key) => { @@ -322,7 +322,7 @@ function findExtraPlaceholders(paths) { let hasExtraPlaceholders = false; const extraPlaceholders = {}; paths.forEach((path) => { - const localeJson = jsonfile.readFileSync(`.${path}`); + const localeJson = jsonfile.readFileSync(`${path}`); const locale = path.match(/_locales\/(.*)\/messages.json/)[1]; extraPlaceholders[locale] = []; Object.keys(localeJson).forEach((key) => { @@ -364,7 +364,7 @@ function findMalformedPlaceholders(paths) { let hasMalformedPlaceholders = false; const malformedPlaceholders = []; paths.forEach((path) => { - const localeJson = jsonfile.readFileSync(`.${path}`); + const localeJson = jsonfile.readFileSync(`${path}`); const locale = path.match(/_locales\/(.*)\/messages.json/)[1]; malformedPlaceholders[locale] = []; Object.keys(localeJson).forEach((key) => {