diff --git a/src/_locales/en_US/messages.json b/src/_locales/en_US/messages.json index 6dc747576f..459fc6a001 100644 --- a/src/_locales/en_US/messages.json +++ b/src/_locales/en_US/messages.json @@ -359,6 +359,26 @@ "message": "Privacy Policy", "description": "Shown at the bottom of the intro page." }, + "intro_pin_nudge": { + "message": "First, $START_SPAN_TAG$pin Privacy Badger to your toolbar$END_SPAN_TAG$ for easy access to the \"$DISABLE_FOR_SITE$\" button.", + "description": "Part of a Chrome-only overlay on the intro page", + "placeholders": { + "start_span_tag": { + "content": "" + }, + "disable_for_site": { + "content": "$1", + "example": "Disable for this site" + }, + "end_span_tag": { + "content": "" + } + } + }, + "intro_pin_instructions": { + "message": "To pin Privacy Badger's icon, click on the puzzle piece icon in your browser toolbar. Then, click on the pin icon next to Privacy Badger.", + "description": "Alt text for pinning instructions image. Shown on the Chrome-only overlay of the intro page." + }, "share_button_title_facebook": { "message": "Share on Facebook", "description": "Text shown when you hover over the social sharing buttons on the intro page." diff --git a/src/icons/close.svg b/src/icons/close.svg new file mode 100644 index 0000000000..770c9fdd3e --- /dev/null +++ b/src/icons/close.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/lib/i18n.js b/src/lib/i18n.js index e0eef24aff..6d4be15082 100644 --- a/src/lib/i18n.js +++ b/src/lib/i18n.js @@ -78,6 +78,17 @@ function setTextDirection() { ['.btn-silo', '.btn-silo div', '#allowlist-form > div > div > div', '#widget-site-exceptions-select-div', '#widget-site-exceptions-remove-button'].forEach((selector) => { toggle_css_value(selector, "float", "left", "right"); }); + } else if (document.location.pathname == "/skin/firstRun.html") { + $('#pin-nudge').css({ + right: 'unset', + left: '15px' + }); + $('#pin-image').css("transform", "scaleX(-1)"); + $('#dismiss-nudge').css({ + float: 'left', + right: 'unset', + left: '-5px' + }); } } diff --git a/src/skin/css/firstRun.css b/src/skin/css/firstRun.css index c63b40adb8..5dcad229e2 100644 --- a/src/skin/css/firstRun.css +++ b/src/skin/css/firstRun.css @@ -410,7 +410,7 @@ header img { @media print, screen and (min-width: 40em) { header img { margin:1rem 0 0; - width:15rem; + width:12rem; } } header .title-bar h1 { @@ -498,8 +498,8 @@ header .title-bar h1 { display:block; margin:2.5rem auto 2rem; padding-bottom:3rem; - width:94px; z-index:3; + width: 146px; } .share-links>a { position:relative; @@ -648,6 +648,7 @@ header .title-bar h1 { visibility:visible; } } + /* fonts */ @font-face { font-family:'ChunkFive'; @@ -789,6 +790,72 @@ body { background-image:linear-gradient(#DFDFE6, #DFDFE6 30%, #fff 30%); padding:4rem 0; } + +#overlay { + width: 100%; + height: 100%; + z-index: 999; + background-color: #1f171769; + position: fixed; + top: 0; + left: 0; +} + +@keyframes bounce { + 0%, 20%, 50%, 80%, 100% {transform: translateY(0);} + 40% {transform: translateY(-20px);} + 60% {transform: translateY(-5px);} +} + +#dismiss-nudge { + float: right; + padding-bottom: 5px; + margin: 5px; + position: relative; + top: -5px; + right: -5px; +} + +#dismiss-nudge img { + height: 20px; +} + +#dismiss-nudge:hover img, #dismiss-nudge:focus img { + /* Calculated with https://codepen.io/sosuke/pen/Pjoqqp to match #F06A0A */ + filter: invert(63%) sepia(46%) saturate(6632%) hue-rotate(356deg) brightness(95%) contrast(98%); +} + +#pin-nudge-text { + line-height: 1.5; + width: 275px; + font-size: 17px; +} + +#pin-nudge-cta { + font-family:"OpenSans-Bold",sans-serif; +} + +#pin-image { + width: 275px; + border-radius: 8px; +} + +#pin-nudge { + background-color: #DFDFE6; + position: fixed; + top: 15px; + right: 15px; + padding: 25px; + z-index: 1000; + border-radius: 8px; + box-shadow: rgba(0, 0, 0, 0.25) 0px 0px 20px, rgba(0, 0, 0, 0.35) 0px 25px 30px; + animation: bounce 2s ease 1; + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; +} + #pb-privacy-policy, #pb-privacy-policy a { color:#707070; font-family:"OpenSans-Light",sans-serif; @@ -841,4 +908,17 @@ body { border-left: 0.4275rem solid #555; color: #fff; } + + #pin-nudge { + background-color: #555; + } + + #dismiss-nudge img { + filter: invert(0.85); + } + + #dismiss-nudge:hover img, #dismiss-nudge:focus img { + /* Calculated with https://codepen.io/sosuke/pen/Pjoqqp to match #F06A0A */ + filter: invert(63%) sepia(46%) saturate(6632%) hue-rotate(356deg) brightness(95%) contrast(98%);; + } } diff --git a/src/skin/firstRun.html b/src/skin/firstRun.html index ff62aae634..1a9bc37f93 100644 --- a/src/skin/firstRun.html +++ b/src/skin/firstRun.html @@ -28,6 +28,18 @@

+ + + +
diff --git a/src/skin/images/mastodon.svg b/src/skin/images/mastodon.svg index 25d284c215..78e1a900c2 100644 --- a/src/skin/images/mastodon.svg +++ b/src/skin/images/mastodon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/skin/images/pinning-instructions.png b/src/skin/images/pinning-instructions.png new file mode 100644 index 0000000000..3855d9203d Binary files /dev/null and b/src/skin/images/pinning-instructions.png differ diff --git a/src/skin/js/firstRun.js b/src/skin/js/firstRun.js index ef508e38b6..7a36fe5a16 100644 --- a/src/skin/js/firstRun.js +++ b/src/skin/js/firstRun.js @@ -15,4 +15,64 @@ $(function () { }); } }); + + function hideNudgeOverlay() { + $("body").css('overflow', 'auto'); + $("#pin-nudge").fadeOut(); + $("#overlay").fadeOut(); + document.removeEventListener("click", clickHandler); + document.removeEventListener("keydown", keydownHandler); + } + + function clickHandler(e) { + // Hide the pin nudge when a user clicks outside the popup + if (!document.getElementById('pin-nudge').contains(e.target)) { + hideNudgeOverlay(); + } + } + + function keydownHandler(e) { + // Hide the pin nudge when a user presses 'Esc' + if (e.keyCode === 27) { + hideNudgeOverlay(); + } else if (e.keyCode === 9) { + // Trap focus within the popup + $("#dismiss-nudge").trigger("focus"); + e.preventDefault(); + } + } + + // Don't show the pin nudge in Firefox because extensions are pinned automatically + // chrome.action is only available in MV3 and chrome.browserAction is only available in <= MV2 + // chrome.browserAction.getUserSettings doesn't exist in MV2 but does in Firefox + let is_chromium_mv3 = !!chrome.action; + let is_chromium_mv2 = chrome.browserAction && !chrome.browserAction.getUserSettings; + if (is_chromium_mv2 || is_chromium_mv3) { + $("#pin-nudge-text").html(chrome.i18n.getMessage("intro_pin_nudge", [chrome.i18n.getMessage("popup_disable_for_site")])); + $("#pin-nudge").show(); + $("#overlay").show(); + $("body").css('overflow', 'hidden'); + document.addEventListener("click", clickHandler); + document.addEventListener("keydown", keydownHandler); + } + + $("#dismiss-nudge").on("click", function (e) { + e.preventDefault(); + hideNudgeOverlay(); + }); + + let interval_id; + // Auto-dismiss the nudge once user pins Privacy Badger + async function checkIsPinned() { + let userSettings = await chrome.action.getUserSettings(); + if (userSettings.isOnToolbar) { + hideNudgeOverlay(); + clearInterval(interval_id); + } + } + + // For Chromium, we can only check if PB is pinned in MV3 + if (is_chromium_mv3) { + interval_id = setInterval(() => checkIsPinned(), 1000); + } }); diff --git a/src/skin/popup.html b/src/skin/popup.html index 60cc3c6175..0aa0f950c5 100644 --- a/src/skin/popup.html +++ b/src/skin/popup.html @@ -39,10 +39,9 @@