Skip to content

Commit

Permalink
some real data
Browse files Browse the repository at this point in the history
  • Loading branch information
shakyShane committed Feb 17, 2025
1 parent e172a2d commit ed12a5b
Show file tree
Hide file tree
Showing 6 changed files with 329 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@
.inlineSwitch {
display: flex;
align-items: center;
/*gap: 8px;*/
color: var(--ntp-text-muted);
&[data-state="connected"] svg {
color: #21C000;
Expand Down
100 changes: 100 additions & 0 deletions special-pages/pages/new-tab/app/vpn/Icons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { h } from 'preact';

export function Arrow() {
return (
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M3.99995 7.625C4.34513 7.625 4.62495 7.34518 4.62495 7V2.50888L6.05806 3.94199C6.30214 4.18607 6.69786 4.18607 6.94194 3.94199C7.18602 3.69791 7.18602 3.30218 6.94194 3.05811L4.44189 0.558058C4.32468 0.440847 4.16571 0.374999 3.99995 0.375C3.83419 0.375001 3.67522 0.44085 3.55801 0.558063L1.05805 3.05806C0.813979 3.30214 0.813982 3.69787 1.05806 3.94195C1.30214 4.18602 1.69787 4.18602 1.94195 3.94194L3.37495 2.5089L3.37495 7C3.37495 7.34518 3.65477 7.625 3.99995 7.625Z"
fill="currentColor"
/>
</svg>
);
}

export function ConnectionLongest() {
return (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M8.62503 3.625C8.62503 3.27982 8.34521 3 8.00003 3C7.65485 3 7.37503 3.27982 7.37503 3.625V8C7.37503 8.34518 7.65485 8.625 8.00003 8.625H11.375C11.7202 8.625 12 8.34518 12 8C12 7.65482 11.7202 7.375 11.375 7.375H8.62503V3.625Z"
fill="black"
fill-opacity="0.84"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M8.00003 -0.0107422C3.5758 -0.0107422 -0.0107422 3.5758 -0.0107422 8.00003C-0.0107422 12.4243 3.5758 16.0108 8.00003 16.0108C12.4243 16.0108 16.0108 12.4243 16.0108 8.00003C16.0108 3.5758 12.4243 -0.0107422 8.00003 -0.0107422ZM1.26081 8.00003C1.26081 4.27806 4.27806 1.26081 8.00003 1.26081C11.722 1.26081 14.7393 4.27806 14.7393 8.00003C14.7393 11.722 11.722 14.7393 8.00003 14.7393C4.27806 14.7393 1.26081 11.722 1.26081 8.00003Z"
fill="black"
fill-opacity="0.84"
/>
</svg>
);
}

export function ConnectionTime() {
return (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_63_3083)">
<path
d="M8.5204 0.0169997C8.47374 0.00588457 8.42506 0 8.375 0C8.02983 0 7.75 0.279822 7.75 0.625V3.375C7.75 3.72018 8.02983 4 8.375 4C8.72018 4 9 3.72018 9 3.375V1.32454C10.116 1.49171 11.1757 1.93662 12.0797 2.62244C13.1407 3.42737 13.9399 4.52819 14.3767 5.78633C14.8134 7.04447 14.8683 8.4037 14.5343 9.69293C14.2003 10.9822 13.4923 12.1438 12.4996 13.0316C11.5069 13.9194 10.2737 14.4936 8.95531 14.6821C7.63692 14.8706 6.29223 14.6649 5.0905 14.0908C3.88877 13.5168 2.88372 12.6 2.20184 11.456C1.51996 10.312 1.19174 8.9919 1.25848 7.66178C1.27578 7.31703 1.01034 7.02354 0.665592 7.00624C0.320847 6.98894 0.0273539 7.25439 0.0100552 7.59913C-0.0690483 9.17558 0.319957 10.7402 1.12811 12.096C1.93626 13.4519 3.12744 14.5384 4.5517 15.2187C5.97597 15.8991 7.56968 16.1429 9.13222 15.9195C10.6948 15.6961 12.1563 15.0155 13.3329 13.9633C14.5094 12.9111 15.3485 11.5344 15.7443 10.0064C16.1402 8.47844 16.0752 6.8675 15.5575 5.37638C15.0399 3.88525 14.0927 2.58058 12.8352 1.62659C11.5856 0.678607 10.0851 0.118996 8.5204 0.0169997Z"
fill="currentColor"
fill-opacity="0.84"
/>
<path
d="M4.58737 0.764456C4.89956 0.61721 5.27202 0.750928 5.41926 1.06312C5.56651 1.37532 5.43279 1.74777 5.12059 1.89502C4.94137 1.97955 4.76651 2.07166 4.59642 2.17097C4.29834 2.34502 3.9156 2.24447 3.74155 1.94638C3.5675 1.6483 3.66805 1.26556 3.96614 1.09151C4.16774 0.973801 4.37498 0.864631 4.58737 0.764456Z"
fill="currentColor"
fill-opacity="0.84"
/>
<path
d="M1.3687 3.52504C1.56178 3.23892 1.95025 3.16349 2.23638 3.35657C2.5225 3.54965 2.59793 3.93813 2.40485 4.22425C2.29467 4.38752 2.19137 4.55601 2.09536 4.72935C1.9281 5.0313 1.54774 5.14049 1.24579 4.97324C0.943836 4.80598 0.834645 4.42561 1.0019 4.12366C1.11569 3.91824 1.23812 3.71855 1.3687 3.52504Z"
fill="currentColor"
fill-opacity="0.84"
/>
<path
d="M3 7.625C3 7.27982 3.27983 7 3.625 7H8.375C8.72018 7 9 7.27982 9 7.625C9 7.97018 8.72018 8.25 8.375 8.25H3.625C3.27983 8.25 3 7.97018 3 7.625Z"
fill="currentColor"
fill-opacity="0.84"
/>
</g>
</svg>
);
}

export function Ip() {
return (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M2 4.125C2 2.39911 3.39911 1 5.125 1H10.875C12.6009 1 14 2.39911 14 4.125V6.875C14 8.60089 12.6009 10 10.875 10H9V12.011C9.51638 12.248 9.875 12.7696 9.875 13.375C9.875 14.2034 9.20343 14.875 8.375 14.875C7.76964 14.875 7.24803 14.5164 7.01102 14L1.625 14C1.27982 14 1 13.7202 1 13.375C1 13.0299 1.27982 12.75 1.625 12.75L7.011 12.75C7.16067 12.4239 7.42387 12.1607 7.75 12.011V10H5.125C3.39911 10 2 8.60089 2 6.875V4.125ZM5.125 2.25C4.08947 2.25 3.25 3.08947 3.25 4.125V6.875C3.25 7.91053 4.08947 8.75 5.125 8.75H10.875C11.9105 8.75 12.75 7.91053 12.75 6.875V4.125C12.75 3.08947 11.9105 2.25 10.875 2.25H5.125Z"
fill="currentColor"
fill-opacity="0.84"
/>
<path
d="M11.625 14H14.375C14.7202 14 15 13.7202 15 13.375C15 13.0298 14.7202 12.75 14.375 12.75H11.625C11.2798 12.75 11 13.0298 11 13.375C11 13.7202 11.2798 14 11.625 14Z"
fill="currentColor"
fill-opacity="0.84"
/>
</svg>
);
}

export function Volume() {
return (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M9.45142 12.7847C10.2383 12.546 10.9541 12.117 11.5355 11.5355L8 8V3C7.17775 3 6.36818 3.20279 5.64302 3.59039C4.91785 3.978 4.29947 4.53847 3.84265 5.22215C3.38583 5.90583 3.10467 6.69162 3.02408 7.50991C2.94348 8.32821 3.06594 9.15375 3.3806 9.91342C3.69527 10.6731 4.19242 11.3434 4.82803 11.8651C5.46365 12.3867 6.21809 12.7435 7.02455 12.9039C7.83101 13.0643 8.66458 13.0234 9.45142 12.7847Z"
fill="black"
fill-opacity="0.84"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0ZM1.25 8C1.25 4.27208 4.27208 1.25 8 1.25C11.7279 1.25 14.75 4.27208 14.75 8C14.75 11.7279 11.7279 14.75 8 14.75C4.27208 14.75 1.25 11.7279 1.25 8Z"
fill="black"
fill-opacity="0.84"
/>
</svg>
);
}
40 changes: 40 additions & 0 deletions special-pages/pages/new-tab/app/vpn/VPNInterface.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,44 @@
[data-theme=dark] & {
border-color: var(--color-white-at-9);
}
}
.body {
margin-top: 32px;
}
.item {
display: flex;
align-items: center;
gap: 12px;
}
.icon {

}
.itemBody {
/*outline: 1px solid black;*/
}
.label {}
.value {
font-size: var(--small-label-font-size);
font-weight: var(--small-label-font-weight);
line-height: var(--small-label-line-height);
display: flex;
align-items: center;

svg {
margin-right: 1px;
}
svg:nth-child(2) {
margin-left: 8px;
transform: rotate(180deg);
}
span + span {
margin-left: 3px;
}
}
.list {
display: grid;
grid-template-columns: 1fr 1fr;
grid-row-gap: 16px;
grid-column-gap: 16px;
padding-right: 40px;
}
147 changes: 145 additions & 2 deletions special-pages/pages/new-tab/app/vpn/Vpn.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { h } from 'preact';
import { Fragment, h } from 'preact';
import styles from './VPNInterface.module.css';
import { useTypedTranslationWith } from '../types.js';
import { useVisibility } from '../widget-list/widget-config.provider.js';
import { useCustomizer } from '../customizer/components/CustomizerMenu.js';
import { VpnContext, VpnProvider } from './VpnProvider.js';
import { useContext, useId } from 'preact/hooks';
import { useContext, useId, useEffect, useState } from 'preact/hooks';
import { VpnHeading } from '../privacy-stats/components/VpnHeading.js';
import { Arrow, ConnectionLongest, ConnectionTime, Ip, Volume } from './Icons.js';

/**
* @import enStrings from "./strings.json"
Expand Down Expand Up @@ -35,6 +36,128 @@ export function Vpn({ data, expansion, toggle }) {
id: TOGGLE_ID,
}}
/>
{expansion === 'expanded' && <VpnBody data={data} />}
</div>
);
}

/**
* @param {object} props
* @param {VPNWidgetData} props.data
*/
function VpnBody({ data }) {
const { t } = useTypedTranslationWith(/** @type {Strings} */ ({}));

Check failure on line 49 in special-pages/pages/new-tab/app/vpn/Vpn.js

View workflow job for this annotation

GitHub Actions / unit (ubuntu-latest)

't' is assigned a value but never used

return (
<div class={styles.body}>
<ul class={styles.list}>
{data.state !== 'disconnected' && (
<li>
<ConnectionTimeItem timestamp={data.value?.session.connectedSince} />
</li>
)}
<li>
<LongestConnection timespan={data.value?.history.longestConnection} />
</li>
{data.state !== 'disconnected' && (
<Fragment>
<li>
<IpItem ip={data.value?.session.currentIp} />
</li>
<li>
<DataVolume dataVolume={data.value?.session.dataVolume} />
</li>
</Fragment>
)}
</ul>
</div>
);
}

/**
* @param {object} props
* @param {string|undefined} props.ip
*/
function IpItem({ ip }) {
const { t } = useTypedTranslationWith(/** @type {Strings} */ ({}));
return (
<Item icon={<Ip />}>
<span class={styles.label}>{t('vpn_ipLabel')}</span>
{ip && <span className={styles.value}>{ip}</span>}
</Item>
);
}

/**
* @param {object} props
* @param {import('../../types/new-tab').Timespan|undefined} props.timespan
*/
function LongestConnection({ timespan }) {
const { t } = useTypedTranslationWith(/** @type {Strings} */ ({}));
const display = timespan ? [timespan.weeks, timespan.days, timespan.hours, timespan.minutes] : undefined;
return (
<Item icon={<ConnectionLongest />}>
<span class={styles.label}>{t('vpn_longestConnectionLabel')}</span>
{timespan && display && (
<span class={styles.value}>
{display.map((item, index) => {
const lookup = ['w', 'd', 'h', 'm'];
return item !== undefined ? <span>{item + lookup[index]}</span> : null;
})}
</span>
)}
</Item>
);
}

/**
* @param {object} props
* @param {number|undefined} props.timestamp
*/
function ConnectionTimeItem({ timestamp }) {
const { t } = useTypedTranslationWith(/** @type {Strings} */ ({}));
const [connectedDisplay, setConnectedDisplay] = useState(() => (timestamp ? formatDuration(timestamp) : null));
useEffect(() => {
const interval = setInterval(() => {
setConnectedDisplay(formatDuration(timestamp));
}, 1000);

return () => clearInterval(interval);
}, [timestamp]);
return (
<Item icon={<ConnectionTime />}>
<span class={styles.label}>{t('vpn_connectionTimeLabel')}</span>
{timestamp !== undefined && connectedDisplay !== null && <span class={styles.value}>{formatDuration(timestamp)}</span>}
</Item>
);
}

/**
* @param {object} props
* @param {import('../../types/new-tab').DataVolumeMetrics|undefined} props.dataVolume
*/
function DataVolume({ dataVolume }) {
const { t } = useTypedTranslationWith(/** @type {Strings} */ ({}));
return (
<Item icon={<Volume />}>
<span class={styles.label}>{t('vpn_dataVolumeLabel')}</span>
{dataVolume && (
<span class={styles.value}>
<Arrow />
{dataVolume.upload} {dataVolume.unit}
<Arrow />
{dataVolume.download} {dataVolume.unit}
</span>
)}
</Item>
);
}

function Item({ children, icon }) {
return (
<div class={styles.item}>
<div class={styles.icon}>{icon}</div>
<div class={styles.itemBody}>{children}</div>
</div>
);
}
Expand Down Expand Up @@ -87,3 +210,23 @@ export function VpnConsumer() {
}
return null;
}

function formatDuration(from) {
if (!Number.isFinite(from) || from < 0) {
throw new Error('Invalid timestamp');
}

const now = Date.now();
const duration = Math.max(0, Math.floor((now - from) / 1000));

const days = Math.floor(duration / 86400);
const hours = Math.floor((duration % 86400) / 3600);
const minutes = Math.floor((duration % 3600) / 60);

const parts = [];
if (days > 0) parts.push(`${days}d`);
if (hours > 0) parts.push(`${hours}h`);
if (minutes > 0) parts.push(`${minutes}m`);

return parts.join(' ') || '0m';
}
24 changes: 24 additions & 0 deletions special-pages/pages/new-tab/app/vpn/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,29 @@
"vpn_tryButton": {
"title": "Try for Free",
"note": ""
},
"vpn_connectionTimeLabel": {
"title": "Connection Time",
"note": ""
},
"vpn_longestConnectionLabel": {
"title": "Longest Connection",
"note": ""
},
"vpn_longestConnectionLabel": {
"title": "Longest Connection",
"note": ""
},
"vpn_ipLabel": {
"title": "IP Address",
"note": ""
},
"vpn_dataVolumeLabel": {
"title": "Data Volume",
"note": ""
},
"vpn_usageLabel": {
"title": "Usage",
"note": ""
}
}
20 changes: 20 additions & 0 deletions special-pages/pages/new-tab/public/locales/en/new-tab.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,26 @@
"title": "Try for Free",
"note": ""
},
"vpn_connectionTimeLabel": {
"title": "Connection Time",
"note": ""
},
"vpn_longestConnectionLabel": {
"title": "Longest Connection",
"note": ""
},
"vpn_ipLabel": {
"title": "IP Address",
"note": ""
},
"vpn_dataVolumeLabel": {
"title": "Data Volume",
"note": ""
},
"vpn_usageLabel": {
"title": "Usage",
"note": ""
},
"updateNotification_updated_version": {
"title": "Browser Updated to version {version}.",
"note": "Text to indicate which new version was updated. `{version}` will be formatted like `1.22.0`"
Expand Down

0 comments on commit ed12a5b

Please sign in to comment.