commit 1f15a177ae062fa0a6b821ffe3ae99b1c8449f9e
parent d0eb41a0b8c2a29660ad088df3c5c86b81698e73
Author: Rebecca King <rking@mozilla.com>
Date: Fri, 19 Dec 2025 13:49:44 +0000
Bug 2006808 - Remove connection timer from IP Protection panel - r=ip-protection-reviewers,fchasen
Differential Revision: https://phabricator.services.mozilla.com/D277058
Diffstat:
8 files changed, 5 insertions(+), 145 deletions(-)
diff --git a/browser/components/ipprotection/IPProtectionPanel.sys.mjs b/browser/components/ipprotection/IPProtectionPanel.sys.mjs
@@ -64,8 +64,6 @@ export class IPProtectionPanel {
/**
* @typedef {object} State
* @property {boolean} isProtectionEnabled
- * True if IP Protection via the proxy is enabled
- * @property {Date} protectionEnabledSince
* The timestamp in milliseconds since IP Protection was enabled
* @property {boolean} isSignedOut
* True if not signed in to account
@@ -115,12 +113,10 @@ export class IPProtectionPanel {
constructor(window) {
this.handleEvent = this.#handleEvent.bind(this);
- let { activatedAt: protectionEnabledSince } = lazy.IPPProxyManager;
-
this.state = {
isSignedOut: !lazy.IPPSignInWatcher.isSignedIn,
- isProtectionEnabled: !!protectionEnabledSince,
- protectionEnabledSince,
+ isProtectionEnabled:
+ lazy.IPPProxyManager.state === lazy.IPPProxyStates.ACTIVE,
location: {
name: "United States",
code: "us",
@@ -434,15 +430,14 @@ export class IPProtectionPanel {
event.type == "IPProtectionService:StateChanged" ||
event.type === "IPPEnrollAndEntitleManager:StateChanged"
) {
- let { activatedAt: protectionEnabledSince } = lazy.IPPProxyManager;
let hasError =
lazy.IPPProxyManager.state === lazy.IPPProxyStates.ERROR &&
lazy.IPPProxyManager.errors.includes(ERRORS.GENERIC);
this.setState({
isSignedOut: !lazy.IPPSignInWatcher.isSignedIn,
- isProtectionEnabled: !!protectionEnabledSince,
- protectionEnabledSince,
+ isProtectionEnabled:
+ lazy.IPPProxyManager.state === lazy.IPPProxyStates.ACTIVE,
hasUpgraded: lazy.IPPEnrollAndEntitleManager.hasUpgraded,
error: hasError ? ERRORS.GENERIC : "",
});
diff --git a/browser/components/ipprotection/content/ipprotection-content.mjs b/browser/components/ipprotection/content/ipprotection-content.mjs
@@ -93,15 +93,6 @@ export default class IPProtectionContentElement extends MozLitElement {
);
}
- get canShowConnectionTime() {
- return (
- this.state &&
- this.state.isProtectionEnabled &&
- this.state.protectionEnabledSince &&
- !this.state.isSignedOut
- );
- }
-
get canEnableConnection() {
return this.state && this.state.isProtectionEnabled && !this.state.error;
}
@@ -248,8 +239,6 @@ export default class IPProtectionContentElement extends MozLitElement {
return html`
<ipprotection-status-card
.protectionEnabled=${this.canEnableConnection}
- .canShowTime=${this.canShowConnectionTime}
- .enabledSince=${this.state.protectionEnabledSince}
.location=${this.state.location}
.siteData=${ifDefined(this.state.siteData)}
></ipprotection-status-card>
diff --git a/browser/components/ipprotection/content/ipprotection-status-card.mjs b/browser/components/ipprotection/content/ipprotection-status-card.mjs
@@ -8,10 +8,6 @@ import {
classMap,
styleMap,
} from "chrome://global/content/vendor/lit.all.mjs";
-import {
- connectionTimer,
- defaultTimeValue,
-} from "chrome://browser/content/ipprotection/ipprotection-timer.mjs";
// eslint-disable-next-line import/no-unassigned-import
import "chrome://global/content/elements/moz-toggle.mjs";
@@ -192,11 +188,6 @@ export default class IPProtectionStatusCard extends MozLitElement {
}
cardDescriptionTemplate() {
- // The template consists of location name and connection time.
- let time = this.canShowTime
- ? connectionTimer(this.enabledSince)
- : defaultTimeValue;
-
// To work around mox-box-item description elements being hard to reach because of the shadowDOM,
// let's use a lit stylemap to apply style changes directly.
let labelStyles = styleMap({
@@ -219,11 +210,6 @@ export default class IPProtectionStatusCard extends MozLitElement {
style=${imgStyles}
/>
</div>
- <span
- id="time"
- data-l10n-id="ipprotection-connection-time"
- data-l10n-args=${time}
- ></span>
</div>
`
: null;
diff --git a/browser/components/ipprotection/content/ipprotection-timer.mjs b/browser/components/ipprotection/content/ipprotection-timer.mjs
@@ -1,80 +0,0 @@
-/* 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 https://mozilla.org/MPL/2.0/. */
-
-import {
- asyncReplace,
- until,
- AsyncDirective,
- directive,
-} from "chrome://global/content/vendor/lit.all.mjs";
-
-const TIMER_INTERVAL_MS = 1000;
-
-// Returns a promise until asnyncReplace has yielded at least once.
-const hasYielded = async asyncReplaceDirective => {
- await asyncReplaceDirective.values[0].next();
- return asyncReplaceDirective;
-};
-
-/**
- * A directive that produces a live updating l10n args object with the duration
- * since the given timestamp in milliseconds.
- */
-class TimerDirective extends AsyncDirective {
- render(timeConnectedSince) {
- return until(
- hasYielded(asyncReplace(this.currentTime(timeConnectedSince))),
- this.getFormattedTime(timeConnectedSince)
- );
- }
- /**
- * Returns a generator that yields a l10n args object with the current connection time
- * every second.
- *
- * @param {number} timeConnectedSince
- * The time in milliseconds
- * @returns {AsyncGenerator<string>}
- * @yields {string}
- */
- async *currentTime(timeConnectedSince) {
- while (true) {
- if (!this.isConnected) {
- return;
- }
- yield this.getFormattedTime(timeConnectedSince);
- await new Promise(resolve => setTimeout(resolve, TIMER_INTERVAL_MS));
- }
- }
-
- /**
- * Returns the formatted connection duration time string as HH:MM:SS (hours, minutes, seconds).
- *
- * @param {number} startMS
- * The timestamp in milliseconds since a connection to the proxy was made.
- * @returns {string}
- * The formatted time in HH:MM:SS as l10n args object.
- */
- getFormattedTime(startMS) {
- let duration = window.Temporal.Duration.from({
- milliseconds: Math.ceil(ChromeUtils.now() - startMS),
- }).round({ smallestUnit: "seconds", largestUnit: "hours" });
-
- let formatter = new Intl.DurationFormat("en-US", {
- style: "digital",
- hoursDisplay: "always",
- hours: "2-digit",
- });
- const time = formatter.format(duration);
- return JSON.stringify({ time });
- }
-}
-
-export const defaultTimeValue = `{"time":""}`;
-/**
- * A directive that produces a live updating l10n args object with the duration
- * since the given timestamp in milliseconds.
- * Usage:
- * <my-element data-l10n-args=${connectionTimer(startTimestamp)}></my-element>
- */
-export const connectionTimer = directive(TimerDirective);
diff --git a/browser/components/ipprotection/jar.mn b/browser/components/ipprotection/jar.mn
@@ -14,4 +14,3 @@ browser.jar:
content/browser/ipprotection/ipprotection-site-settings-control.mjs (content/ipprotection-site-settings-control.mjs)
content/browser/ipprotection/ipprotection-status-card.css (content/ipprotection-status-card.css)
content/browser/ipprotection/ipprotection-status-card.mjs (content/ipprotection-status-card.mjs)
- content/browser/ipprotection/ipprotection-timer.mjs (content/ipprotection-timer.mjs)
diff --git a/browser/components/ipprotection/tests/browser/browser_ipprotection_status_card.js b/browser/components/ipprotection/tests/browser/browser_ipprotection_status_card.js
@@ -21,8 +21,6 @@ ChromeUtils.defineESModuleGetters(lazy, {
add_task(async function test_status_card_in_panel() {
const l10nIdOn = "ipprotection-connection-status-on";
const l10nIdOff = "ipprotection-connection-status-off";
- const fiveDaysInMS = 5 * 24 * 60 * 60 * 1000;
- const enabledSince = Date.now() - fiveDaysInMS;
const mockLocation = {
name: "United States",
code: "us",
@@ -30,7 +28,6 @@ add_task(async function test_status_card_in_panel() {
let content = await openPanel({
isSignedOut: false,
- protectionEnabledSince: enabledSince,
location: mockLocation,
});
@@ -60,20 +57,9 @@ add_task(async function test_status_card_in_panel() {
);
Assert.ok(locationNameFilter.length, "Found location in status card");
- // We can't check the time value directly, so instead see if the lit timerDirective is loaded in the component.
- // Assert that there's no timerDirective, so that we know the timer is not running.
- let timerDirectiveFilter = descriptionMetadata.values.filter(
- value => value._$litDirective$?.name == "TimerDirective"
- );
- Assert.ok(
- !timerDirectiveFilter.length,
- "Timer should not be loaded in description meta data"
- );
-
// Set state as if protection is enabled
await setPanelState({
isSignedOut: false,
- protectionEnabledSince: enabledSince,
location: mockLocation,
isProtectionEnabled: true,
});
@@ -88,16 +74,6 @@ add_task(async function test_status_card_in_panel() {
"Status card connection toggle data-l10n-id should be correct when protection is enabled"
);
- // Now check the timerDirective again and see if it's loaded. If found, then the timer is running.
- descriptionMetadata = statusCard?.statusGroupEl.description;
- timerDirectiveFilter = descriptionMetadata.values.filter(
- value => value._$litDirective$?.name == "TimerDirective"
- );
- Assert.ok(
- timerDirectiveFilter.length,
- "Timer should be loaded now in description meta data"
- );
-
await closePanel();
});
diff --git a/browser/components/ipprotection/tests/xpcshell/test_IPProtectionPanel.js b/browser/components/ipprotection/tests/xpcshell/test_IPProtectionPanel.js
@@ -18,7 +18,6 @@ class FakeIPProtectionPanelElement {
this.state = {
isSignedOut: true,
isProtectionEnabled: false,
- protectionEnabledSince: null,
};
this.isConnected = false;
}
diff --git a/browser/locales-preview/ipProtection.ftl b/browser/locales-preview/ipProtection.ftl
@@ -53,11 +53,7 @@ ipprotection-connection-status-on =
ipprotection-connection-status-off =
.label = VPN is off
-# The panel status card has a header, as well as VPN server location name and connection time displayed under it when the VPN is on.
-# Variables:
-# $time (String) - The amount of time connected to the proxy as HH:MM:SS (hours, minutes, seconds).
-ipprotection-connection-time = { $time }
-
+# The panel status card has a header, as well as VPN server location name displayed under it when the VPN is on.
# Location refers to the VPN server geographical position.
ipprotection-location-title =
.title = Location selected based on fastest server