Skip to content

Commit

Permalink
Add Connection Health to VPNCard (#58)
Browse files Browse the repository at this point in the history
Depends on:
mozilla-mobile/mozilla-vpn-client#9854

Add's a stability attribute for the `<vpn-card>` element. Swapping out
the time string for that status.


https://github.com/user-attachments/assets/61ebe3b5-86d7-4a3b-baca-7420737ec568
  • Loading branch information
strseb committed Sep 24, 2024
1 parent 200f896 commit c0799cf
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 22 deletions.
5 changes: 5 additions & 0 deletions src/assets/img/error.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/assets/img/globe-shield-off.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 7 additions & 2 deletions src/assets/img/globe-shield-on.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 26 additions & 1 deletion src/background/vpncontroller/states.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export class VPNState {
subscribed = true;
// True if it is authenticated
authenticated = false;
// Can be "Stable", "Unstable", "NoSignal"
connectionStability = "Stable";
/**
* A socks:// url to connect to
* to bypass the vpn.
Expand All @@ -52,6 +54,10 @@ export class VPNState {
* Timestamp since the VPN connection was established
*/
connectedSince = 0;

static NoSignal = "NoSignal";
static Unstable = "Unstable";
static Stable = "Stable";
}

/**
Expand Down Expand Up @@ -121,10 +127,28 @@ export class StateVPNEnabled extends StateVPNDisabled {
* @param {ServerCity | undefined} exitServerCity
* @param {ServerCountry | undefined } exitServerCountry
*/
constructor(exitServerCity, exitServerCountry, aloophole, connectedSince) {
constructor(
exitServerCity,
exitServerCountry,
aloophole,
connectedSince,
connectionHealth = "Stable"
) {
super(exitServerCity, exitServerCountry);
this.exitServerCity = exitServerCity;
this.exitServerCountry = exitServerCountry;
this.loophole = aloophole;
this.connectedSince = connectedSince;
if (
![VPNState.NoSignal, VPNState.Stable, VPNState.Unstable].includes(
connectionHealth
)
) {
throw new Error(
`${connectionHealth} is not a Valid Value for ConnectionHealth`
);
}
this.connectionHealth = connectionHealth;
}
state = "Enabled";
subscribed = true;
Expand Down Expand Up @@ -171,6 +195,7 @@ export class vpnStatusResponse {
connectedSince: "0",
app: "MozillaVPN::CustomState",
vpn: "Controller::StateOn",
connectionHealth: "Stable",
localProxy: {
available: false,
url: "https://localhost:8080",
Expand Down
3 changes: 2 additions & 1 deletion src/background/vpncontroller/vpncontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,8 @@ export function fromVPNStatusResponse(
exitServerCity,
exitServerCountry,
status.localProxy?.url,
connectedSince
connectedSince,
status.connectionHealth
);
}
if (
Expand Down
101 changes: 84 additions & 17 deletions src/components/vpncard.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
import { tr } from "../shared/i18n.js";
import { resetSizing } from "./styles.js";

import { VPNState } from "../background/vpncontroller/states.js";

/**
* @typedef {import("../background/vpncontroller/states.js").VPNState} VPNState
*/
Expand All @@ -22,6 +24,7 @@ export class VPNCard extends LitElement {
connectedSince: { type: Date },
cityName: { type: String },
countryFlag: { type: String },
stability: { type: String },
};

constructor() {
Expand All @@ -30,6 +33,7 @@ export class VPNCard extends LitElement {
this.cityName = "";
this.countryFlag = "";
this.connectedSince = 0;
this.stability = VPNState.Stable;
}
#intervalHandle = null;

Expand All @@ -54,11 +58,13 @@ export class VPNCard extends LitElement {
const boxClasses = {
box: true,
on: this.enabled,
unstable: this.enabled && this.stability === VPNState.Unstable,
noSignal: this.enabled && this.stability === VPNState.NoSignal,
stable:
this.enabled &&
this.stability != VPNState.Unstable &&
this.stability != VPNState.NoSignal,
};
const shieldURL = this.enabled
? "../../assets/img/globe-shield-on.svg"
: "../../assets/img/globe-shield-off.svg";

function formatSingle(value) {
if (value === 0) return "00";
return (value < 10 ? "0" : "") + value;
Expand All @@ -81,22 +87,19 @@ export class VPNCard extends LitElement {
const time = Date.now() - this.connectedSince;
//console.log(`Elapsed Time: ${time}`)

const timeString = this.enabled
? html`<p class="timer">${formatTime(time)}</p>`
: html``;

const subLine = this.enabled
? null
: html`<p class="subline">${tr("turnOnForPrivateConnection")}</p>`;
const timeString =
this.enabled && this.stability === VPNState.Stable
? html`<p class="timer">${formatTime(time)}</p>`
: html``;
const vpnHeader = this.enabled ? tr("vpnIsOn") : tr("vpnIsOff");

return html`
<div class="${classMap(boxClasses)}">
<main>
<img src=${shieldURL} />
${VPNCard.shield(this.enabled)}
<div class="infobox">
<h1>${vpnHeader}</h1>
${subLine} ${timeString}
${VPNCard.subline(this.enabled, this.stability)} ${timeString}
</div>
<button class="pill" @click=${this.#toggle}></button>
</main>
Expand All @@ -119,6 +122,41 @@ export class VPNCard extends LitElement {
`;
}

static subline(enabled, stability) {
if (!enabled) {
return html`<p class="subline">${tr("turnOnForPrivateConnection")}</p>`;
}
const errorSvg = html`
<svg>
<use xlink:href="../../assets/img/error.svg#error"></use>
</svg>
`;

switch (stability) {
case VPNState.NoSignal:
return html`<p class="subline">${errorSvg} No Signal</p>`;
case VPNState.Unstable:
return html`<p class="subline">${errorSvg} Unstable</p>`;
default:
null;
}
}

static shield(enabled) {
if (!enabled) {
return html`
<svg>
<use xlink:href="../../assets/img/globe-shield-off.svg#globe"></use>
</svg>
`;
}
return html`
<svg>
<use xlink:href="../../assets/img/globe-shield-on.svg#globe"></use>
</svg>
`;
}

static styles = css`
${resetSizing}
Expand Down Expand Up @@ -147,6 +185,9 @@ export class VPNCard extends LitElement {
width: 100%;
justify-content: baseline;
}
footer img {
margin-right: 8px;
}
main {
justify-content: space-between;
padding: var(--default-padding);
Expand All @@ -173,12 +214,21 @@ export class VPNCard extends LitElement {
.box.on * {
color: var(--main-card-text-color);
}
.box.unstable {
--shield-color: var(--color-warning);
--error-fill: var(--color-warning);
}
.box.noSignal {
--shield-color: var(--color-fatal-error);
--error-fill: var(--color-fatal-error);
}
.box.stable {
--shield-color: var(--color-enabled);
}
.infobox {
flex: 4;
}
img {
margin-right: var(--default-padding);
}
h1 {
font-size: 18px;
line-height: 20px;
Expand All @@ -188,15 +238,32 @@ export class VPNCard extends LitElement {
font-size: 14px;
line-height: 21px;
font-weight: 400;
color: var(--main-card-text-color);
opacity: 0.7;
}
.timer,
.subline {
margin-block-start: calc(var(--default-padding) / 2);
}
.subline svg {
width: 14px;
height: 14px;
margin: 0px;
transform: scale(1.1);
}
.unstable .subline {
color: var(--color-warning);
}
.noSignal .subline {
color: var(--color-fatal-error);
}
svg {
height: 48px;
width: 48px;
transition: all 3s;
margin-right: var(--default-padding);
}
.pill {
width: 45px;
height: 24px;
Expand Down
1 change: 1 addition & 0 deletions src/ui/browserAction/popupPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export class BrowserActionPopup extends LitElement {
.cityName=${this.vpnState?.exitServerCity?.name}
.countryFlag=${this.vpnState?.exitServerCountry?.code}
.connectedSince=${this.vpnState?.connectedSince}
.stability=${this.vpnState?.connectionStability}
></vpn-card>
${this.locationSettings()}
</main>
Expand Down
2 changes: 2 additions & 0 deletions src/ui/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
--font-family-semi-bold: "Inter Semi Bold";
--font-family-bold: "Inter Bold";
--color-enabled: #3fe1b0;
--color-warning: #ffa436;
--color-fatal-error: #ff6a75;
--main-card-background: #321c64;
--main-card-text-color: white;
--main-card--pill-background: lch(
Expand Down

0 comments on commit c0799cf

Please sign in to comment.