From 396411f8b3d7449973f9464c6f49e27229b390d7 Mon Sep 17 00:00:00 2001 From: Lesley Norton Date: Sun, 5 Dec 2021 16:48:42 -0600 Subject: [PATCH] Update panel - Badge the Options icon when proxy and/or nativeMessaging permissions are disabled. Remove on click, don't show again. - Use localized strings - Refactors + cleanup --- src/css/popup.css | 66 ++++++++++----------- src/js/mozillaVpn.js | 2 +- src/js/popup.js | 137 +++++++++++++++++++++++-------------------- src/popup.html | 28 ++++----- 4 files changed, 120 insertions(+), 113 deletions(-) diff --git a/src/css/popup.css b/src/css/popup.css index 7c40de1..f063fdd 100644 --- a/src/css/popup.css +++ b/src/css/popup.css @@ -445,6 +445,7 @@ input:checked + .slider::before { /* Primary CTA Buttons */ .primary-cta { + block-size: 32px; background-color: var(--primaryCtaDefault); border: transparent; border-radius: 4px; @@ -481,10 +482,6 @@ input:checked + .slider::before { transition: opacity 0.1s ease-in-out, max-height 0.3s ease-in-out; } -#moz-vpn-tout.disappear { - animation: hideTout 0.2s ease-in forwards; -} - @keyframes appear { 0% { opacity: 0; @@ -497,22 +494,6 @@ input:checked + .slider::before { } } -@keyframes hideTout { - 0% { - transform: translateY(0%); - opacity: 1; - } - - 50% { - opacity: 1; - } - - 100% { - transform: translateY(20%); - opacity: 0; - } -} - /* Mozilla VPN Controller UI in Container Management Panel */ .moz-vpn-content, @@ -522,9 +503,6 @@ input:checked + .slider::before { flex-direction: column; padding-block: 16px; transition: max-height 0.3s ease-in-out, padding-block-end 0.2s ease-in-out; - - /* max-block-size: 56px; */ - min-block-size: 56px; box-shadow: 0 0 0 1px var(--hr-grey); } @@ -610,7 +588,8 @@ input.proxies { .moz-vpn-cta { block-size: 32px; - margin-block: 16px; + margin-block-start: 16px; + margin-block-end: 4px; margin-inline: var(--marginInline); text-align: center; } @@ -685,6 +664,7 @@ input.proxies { max-block-size: 0; opacity: 0; visibility: hidden; + display: none; background-color: var(--bgColor); transition: max-height 0.2s ease-in-out, opacity 0.2s ease-in-out, visibility 0.2s ease-in-out; } @@ -713,6 +693,7 @@ input.proxies { } .expanded .collapsible-content { + display: flex; max-block-size: 500px; opacity: 1; visibility: visible; @@ -1518,9 +1499,7 @@ manage things like container crud */ /* Panel footer */ .panel-footer { align-items: center; - background: #efefef; block-size: var(--footerHeight); - border-block-end: 1px solid #d8d8d8; color: #000; display: flex; font-size: 13px; @@ -1994,6 +1973,24 @@ input { text-decoration: none; } +.info-icon-alert::after { + block-size: 12px; + inline-size: 12px; + background-color: var(--alertColor); + content: "1"; + border-radius: 50%; + position: absolute; + inset-block: -5px; + inset-inline-end: -6px; + box-shadow: 0 0 1px #00000075; + font-size: 8px; + color: white; + display: flex; + align-items: center; + justify-content: center; + font-weight: bolder; +} + .delete-warning { padding-block-end: 8px; padding-block-start: 8px; @@ -2035,7 +2032,9 @@ tr:hover > td > .trash-button { #advanced-proxy-settings-panel, .advanced-proxy-panel-content { - block-size: 100%; + position: absolute; + inset-block: 0; + inset-inline: 0; } .permissions-overlay { @@ -2053,17 +2052,12 @@ tr:hover > td > .trash-button { } #enable-proxy-permissions { - block-size: var(--rowHeight); text-align: center; font-family: var(--fontMetropolis); font-size: 14px; margin-block-start: 1rem; } -.permissions-overlay-copy { - text-align: center; -} - @media (prefers-color-scheme: dark) { :root { --iconCloseX: url("/img/close-light.svg"); @@ -2094,6 +2088,10 @@ tr:hover > td > .trash-button { --text-grey: #fefffe; } + .permissions-overlay { + background-color: #494755; + } + .tooltip { background-color: var(--controllerActive); } @@ -2185,10 +2183,6 @@ tr:hover > td > .trash-button { background-color: #676767; } - .panel-footer { - border-block-end: solid 1px #4a4a4a; - } - input[type="text"]:focus { box-shadow: 0 0 0 3px var(--blue50); border-color: var(--blue30); diff --git a/src/js/mozillaVpn.js b/src/js/mozillaVpn.js index d7f03b0..9fc337a 100644 --- a/src/js/mozillaVpn.js +++ b/src/js/mozillaVpn.js @@ -156,7 +156,7 @@ const MozillaVPN = { }; }, - async requiredPermissionsEnabled() { + async bothPermissionsEnabled() { const proxyPermissionEnabled = await browser.permissions.contains({ permissions: ["proxy"] }); const nativeMessagingPermissionEnabled = await browser.permissions.contains({ permissions: ["nativeMessaging"] }); return (proxyPermissionEnabled && nativeMessagingPermissionEnabled); diff --git a/src/js/popup.js b/src/js/popup.js index e28dc52..51d34b0 100644 --- a/src/js/popup.js +++ b/src/js/popup.js @@ -662,24 +662,7 @@ Logic.registerPanel(P_CONTAINERS_LIST, { // This method is called when the object is registered. async initialize() { - const mozillaVpnToutName = "moz-tout-main-panel"; - await browser.runtime.sendMessage({ method: "MozillaVPN_queryStatus" }); - Utils.addEnterHandler(document.querySelector("#moz-vpn-learn-more"), () => { - MozillaVPN.handleMozillaCtaClick("mac-main-panel-btn"); - window.close(); - }); - Utils.addEnterHandler(document.querySelector(".dismiss-moz-vpn-tout"), async() => { - const { mozillaVpnHiddenToutsList } = await browser.storage.local.get("mozillaVpnHiddenToutsList"); - if (typeof(mozillaVpnHiddenToutsList) === "undefined") { - await browser.storage.local.set({ "mozillaVpnHiddenToutsList": [] }); - } - document.querySelector("#moz-vpn-tout").classList.add("disappear"); - mozillaVpnHiddenToutsList.push({ - name: mozillaVpnToutName - }); - await browser.storage.local.set({ mozillaVpnHiddenToutsList }); - }); Utils.addEnterHandler(document.querySelector("#manage-containers-link"), (e) => { if (!e.target.classList.contains("disable-edit-containers")) { Logic.showPanel(MANAGE_CONTAINERS_PICKER); @@ -694,9 +677,6 @@ Logic.registerPanel(P_CONTAINERS_LIST, { Utils.addEnterHandler(document.querySelector("#always-open-in"), () => { Logic.showPanel(ALWAYS_OPEN_IN_PICKER); }); - Utils.addEnterHandler(document.querySelector("#info-icon"), () => { - browser.runtime.openOptionsPage(); - }); Utils.addEnterHandler(document.querySelector("#sort-containers-link"), async () => { try { await browser.runtime.sendMessage({ @@ -708,16 +688,58 @@ Logic.registerPanel(P_CONTAINERS_LIST, { } }); + const mozillaVpnToutName = "moz-tout-main-panel"; + const mozillaVpnPermissionsWarningDotName = "moz-permissions-warning-dot"; + + let { mozillaVpnHiddenToutsList } = await browser.storage.local.get("mozillaVpnHiddenToutsList"); + if (typeof(mozillaVpnHiddenToutsList) === "undefined") { + await browser.storage.local.set({ "mozillaVpnHiddenToutsList": [] }); + mozillaVpnHiddenToutsList = []; + } + + // Decide whether to show Mozilla VPN tout const mozVpnTout = document.getElementById("moz-vpn-tout"); const mozillaVpnInstalled = await browser.runtime.sendMessage({ method: "MozillaVPN_getInstallationStatus" }); - if (mozillaVpnInstalled) { - return mozVpnTout.remove(); + const mozillaVpnToutShouldBeHidden = mozillaVpnHiddenToutsList.find(tout => tout.name === mozillaVpnToutName); + if (mozillaVpnInstalled || mozillaVpnToutShouldBeHidden) { + mozVpnTout.remove(); } - const { mozillaVpnHiddenToutsList } = await browser.storage.local.get("mozillaVpnHiddenToutsList"); - const mozillaVpnToutShouldBeHidden = mozillaVpnHiddenToutsList && mozillaVpnHiddenToutsList.find(tout => tout.name === mozillaVpnToutName); - if (mozillaVpnToutShouldBeHidden) { - return mozVpnTout.remove(); + + // Add handlers if tout is visible + const mozVpnDismissTout = document.querySelector(".dismiss-moz-vpn-tout"); + if (mozVpnDismissTout) { + Utils.addEnterHandler((mozVpnDismissTout), async() => { + mozVpnTout.remove(); + mozillaVpnHiddenToutsList.push({ + name: mozillaVpnToutName + }); + await browser.storage.local.set({ mozillaVpnHiddenToutsList }); + }); + + Utils.addEnterHandler(document.querySelector("#moz-vpn-learn-more"), () => { + MozillaVPN.handleMozillaCtaClick("mac-main-panel-btn"); + window.close(); + }); } + + // Badge Options icon if both nativeMessaging and/or proxy permissions are disabled + const bothMozillaVpnPermissionsEnabled = await MozillaVPN.bothPermissionsEnabled(); + const warningDotShouldBeHidden = mozillaVpnHiddenToutsList.find(tout => tout.name === mozillaVpnPermissionsWarningDotName); + const optionsIcon = document.getElementById("info-icon"); + if (optionsIcon && !bothMozillaVpnPermissionsEnabled && !warningDotShouldBeHidden) { + optionsIcon.classList.add("info-icon-alert"); + } + + Utils.addEnterHandler((document.querySelector("#info-icon")), async() => { + browser.runtime.openOptionsPage(); + if (!mozillaVpnHiddenToutsList.find(tout => tout.name === mozillaVpnPermissionsWarningDotName)) { + optionsIcon.classList.remove("info-icon-alert"); + mozillaVpnHiddenToutsList.push({ + name: mozillaVpnPermissionsWarningDotName + }); + } + await browser.storage.local.set({ mozillaVpnHiddenToutsList }); + }); }, unregister() { @@ -799,7 +821,6 @@ Logic.registerPanel(P_CONTAINERS_LIST, { Utils.addEnterHandler(showPanelButton, () => { Logic.showPanel(P_CONTAINER_INFO, identity); }); - } const list = document.querySelector("#identities-list"); @@ -1438,23 +1459,23 @@ Logic.registerPanel(P_CONTAINER_EDIT, { async connectedCallback() { const { mozillaVpnHiddenToutsList } = await browser.storage.local.get("mozillaVpnHiddenToutsList"); const mozillaVpnCollapseEditContainerTout = mozillaVpnHiddenToutsList && mozillaVpnHiddenToutsList.find(tout => tout.name === this.toutName); - this.requiredPermissionsEnabled = await MozillaVPN.requiredPermissionsEnabled(); + const mozillaVpnInstalled = await browser.runtime.sendMessage({ method: "MozillaVPN_getInstallationStatus" }); this.hideShowButton.addEventListener("click", this); - if (mozillaVpnCollapseEditContainerTout) { + if (mozillaVpnCollapseEditContainerTout && !mozillaVpnInstalled) { this.collapseUi(); } // Add listeners if (!this.classList.contains("has-attached-listeners")) { + const bothMozillaVpnPermissionsEnabled = await MozillaVPN.bothPermissionsEnabled(); this.primaryCta.addEventListener("click", async() => { - if (!this.requiredPermissionsEnabled) { - await browser.permissions.request({ permissions: ["proxy", "nativeMessaging"] }); - } else { - MozillaVPN.handleMozillaCtaClick("mac-edit-container-panel-btn"); + if (!bothMozillaVpnPermissionsEnabled && mozillaVpnInstalled) { + return await browser.permissions.request({ permissions: ["proxy", "nativeMessaging"] }); } + MozillaVPN.handleMozillaCtaClick("mac-edit-container-panel-btn"); }); this.switch.addEventListener("click", async() => { @@ -1507,7 +1528,6 @@ Logic.registerPanel(P_CONTAINER_EDIT, { await proxifiedContainers.set(id.cookieStoreId, proxy); this.switch.checked = true; this.updateProxyDependentUi(proxy); - } else { this.switch.checked = false; return; @@ -1523,23 +1543,19 @@ Logic.registerPanel(P_CONTAINER_EDIT, { const mozillaVpnInstalled = await browser.runtime.sendMessage({ method: "MozillaVPN_getInstallationStatus" }); const mozillaVpnConnected = await browser.runtime.sendMessage({ method: "MozillaVPN_getConnectionStatus" }); - if (!mozillaVpnInstalled) { - this.hideEls(this.switch, this.switchLabel, this.currentServerButton); + this.subtitle.textContent = browser.i18n.getMessage("protectThisContainer"); - if (!this.requiredPermissionsEnabled) { - this.subtitle.textContent = "This feature requires Native Messaging and Proxy permissions"; - this.subtitle.style.flex = "1 1 100%"; - this.subtitle.style.textAlign = "center"; - this.primaryCta.style.marginBlockStart = "8px"; - this.primaryCta.textContent = "Enable now"; // TODO - return this.expandUi(); - } else { - this.subtitle.textContent = browser.i18n.getMessage("protectThisContainer"); - } - } else { + const bothMozillaVpnPermissionsEnabled = await MozillaVPN.bothPermissionsEnabled(); - // Mozilla VPN installed... + if (mozillaVpnInstalled && !bothMozillaVpnPermissionsEnabled) { + this.subtitle.style.flex = "1 1 100%"; + this.subtitle.textContent = browser.i18n.getMessage("additionalPermissionNeeded"); + this.hideEls(this.hideShowButton, this.switch, this.switchLabel); + this.primaryCta.textContent = "Enable"; + return; + } + if (mozillaVpnInstalled) { // Hide cta and hide/show button this.hideEls(this.primaryCta, this.hideShowButton); @@ -1547,7 +1563,11 @@ Logic.registerPanel(P_CONTAINER_EDIT, { this.subtitle.textContent = mozillaVpnConnected ? browser.i18n.getMessage("useCustomLocation") : browser.i18n.getMessage("mozillaVpnMustBeOn"); } - if (!mozillaVpnConnected) { + if (mozillaVpnConnected) { + [this.switchLabel, this.switch].forEach(el => { + el.style.display = "inline-block"; + }); + } else { this.hideEls(this.switch, this.switchLabel, this.currentServerButton); this.switch.checked = false; } @@ -1601,10 +1621,8 @@ Logic.registerPanel(P_CONTAINER_EDIT, { } async updateProxyDependentUi(proxyInfo) { - const containerHasProxy = typeof(proxyInfo) !== "undefined"; - const mozillaVpnProxyLocationAvailable = (proxy) => { - return typeof(proxy.countryCode) !== "undefined" && typeof(proxyInfo.cityName) !== "undefined"; + return typeof(proxy) !== "undefined" && typeof(proxy.countryCode) !== "undefined" && typeof(proxy.cityName) !== "undefined"; }; const mozillaVpnProxyIsEnabled = (proxy) => { @@ -1617,7 +1635,7 @@ Logic.registerPanel(P_CONTAINER_EDIT, { const mozillaVpnConnected = await browser.runtime.sendMessage({ method: "MozillaVPN_getConnectionStatus" }); if ( - !containerHasProxy || + !proxyInfo || !mozillaVpnProxyLocationAvailable(proxyInfo) || !mozillaVpnConnected ) { @@ -1632,7 +1650,7 @@ Logic.registerPanel(P_CONTAINER_EDIT, { } // Populate inputs and server button with current or previously stored mozilla vpn proxy - if(containerHasProxy && mozillaVpnProxyLocationAvailable(proxyInfo)) { + if(proxyInfo && mozillaVpnProxyLocationAvailable(proxyInfo)) { this.currentCountryFlag.style.backgroundImage = `url("./img/flags/${proxyInfo.countryCode.toUpperCase()}.png")`; this.currentCountryFlag.style.backgroundImage = proxyInfo.countryCode + ".png"; this.currentCityName.textContent = proxyInfo.cityName; @@ -1643,12 +1661,10 @@ Logic.registerPanel(P_CONTAINER_EDIT, { expandUi() { this.classList.add("expanded"); - this.style.maxHeight = 500 + "px"; } collapseUi() { this.classList.remove("expanded"); - this.style.maxHeight = 56 + "px"; } hideEls(...els) { @@ -1847,17 +1863,14 @@ Logic.registerPanel(P_CONTAINER_EDIT, { return; } - mozillaVpnUi.updateProxyDependentUi({}); const proxyPermissionEnabled = await browser.permissions.contains({ permissions: ["proxy"] }); if (proxyPermissionEnabled) { const proxyData = await proxifiedContainers.retrieve(identity.cookieStoreId); - if (proxyData) { - if (proxyData.proxy && proxyData.proxy.mozProxyEnabled && !mozillaVpnConnected) { - return; - } - mozillaVpnUi.updateProxyDependentUi(proxyData.proxy); + if (proxyData && proxyData.proxy.mozProxyEnabled && !mozillaVpnConnected) { return; } + const proxy = proxyData ? proxyData.proxy : {}; + mozillaVpnUi.updateProxyDependentUi(proxy); } }, }); diff --git a/src/popup.html b/src/popup.html index 2e55e57..586d0e5 100644 --- a/src/popup.html +++ b/src/popup.html @@ -98,7 +98,7 @@
-
- - -
-
-
- -
- -
+
+ +
- +
+
+ +
+ +
+
+ @@ -324,7 +324,7 @@ - +