diff --git a/src/appState.ts b/src/appState.ts index eb7aa37d4..0dec0b1df 100644 --- a/src/appState.ts +++ b/src/appState.ts @@ -73,7 +73,7 @@ export const getDefaultAppState = (): Omit< zenModeEnabled: false, zoom: { value: 1 as NormalizedZoomValue, translation: { x: 0, y: 0 } }, viewModeEnabled: false, - networkSpeed: "…", + networkSpeed: 0, }; }; diff --git a/src/components/App.tsx b/src/components/App.tsx index abf63974d..4215370a2 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -1032,7 +1032,7 @@ class App extends React.Component { return; } const speed = await getNetworkSpeed(); - const networkSpeed = speed === "-1" ? "Error!" : speed; + const networkSpeed = speed; this.setState({ networkSpeed }); if (this.netStatsIntervalId) { clearTimeout(this.netStatsIntervalId); diff --git a/src/components/Stats.tsx b/src/components/Stats.tsx index 261213d8b..8515fe583 100644 --- a/src/components/Stats.tsx +++ b/src/components/Stats.tsx @@ -11,7 +11,7 @@ import { t } from "../i18n"; import useIsMobile from "../is-mobile"; import { getTargetElements } from "../scene"; import { AppState } from "../types"; -import { debounce, getVersion, nFormatter } from "../utils"; +import { debounce, formatSpeed, getVersion, nFormatter } from "../utils"; import { close } from "./icons"; import { Island } from "./Island"; import "./Stats.scss"; @@ -182,7 +182,13 @@ export const Stats = (props: { {t("stats.speed")} - {props.appState.networkSpeed} + + {props.appState.networkSpeed === 0 + ? "…" + : props.appState.networkSpeed > 0 + ? formatSpeed(props.appState.networkSpeed) + : t("stats.error")} + ) : null} diff --git a/src/locales/en.json b/src/locales/en.json index 04058d7a9..e7a688b73 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -231,6 +231,7 @@ "collaborators": "Collaborators", "element": "Element", "elements": "Elements", + "error": "Error", "height": "Height", "scene": "Scene", "selected": "Selected", diff --git a/src/networkStats.ts b/src/networkStats.ts index 309571c28..4a289194a 100644 --- a/src/networkStats.ts +++ b/src/networkStats.ts @@ -1,38 +1,36 @@ const IMAGE_URL = `${process.env.REACT_APP_SOCKET_SERVER_URL}/test256.png`; const IMAGE_SIZE_BYTES = 141978; -const calculateSpeed = (startTime: number, endTime: number) => { +const getSpeed = ( + imageSize: number, + startTime: number, + endTime: number, +): number => { const duration = (endTime - startTime) / 1000; - const imageSizeInBits = IMAGE_SIZE_BYTES * 8; - let speed = imageSizeInBits / duration; - // source: en.wikipedia.org/wiki/Data-rate_units#Conversion_table - const suffix = ["B/s", "kB/s", "MB/s", "GB/s"]; - let index = 0; - while (speed > 1000) { - index++; - speed = speed / 1000; + if (duration > 0) { + return imageSize / duration; } - return `${speed.toFixed(index > 1 ? 1 : 0)} ${suffix[index]}`; + return 0; }; -const processImage = (): Promise => { +const processImage = (): Promise => { return new Promise((resolve) => { const image = new Image(); let endTime: number; image.onload = () => { endTime = new Date().getTime(); - const speed = calculateSpeed(startTime, endTime); + const speed = getSpeed(IMAGE_SIZE_BYTES, startTime, endTime); resolve(speed); }; image.onerror = () => { - resolve("-1"); + resolve(-1); }; const startTime = new Date().getTime(); image.src = `${IMAGE_URL}?t=${startTime}`; }); }; -export const getNetworkSpeed = async (): Promise => { +export const getNetworkSpeed = async (): Promise => { return await processImage(); }; diff --git a/src/types.ts b/src/types.ts index 69d5217b8..50b83a314 100644 --- a/src/types.ts +++ b/src/types.ts @@ -88,7 +88,7 @@ export type AppState = { appearance: "light" | "dark"; gridSize: number | null; viewModeEnabled: boolean; - networkSpeed: string; + networkSpeed: number; /** top-most selected groups (i.e. does not include nested groups) */ selectedGroupIds: { [groupId: string]: boolean }; diff --git a/src/utils.ts b/src/utils.ts index 2532aefcc..65473c5ef 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -363,6 +363,17 @@ export const nFormatter = (num: number, digits: number): string => { ); }; +export const formatSpeed = (speed: number): string => { + // source: en.wikipedia.org/wiki/Data-rate_units#Conversion_table + const suffix = ["B/s", "kB/s", "MB/s", "GB/s"]; + let index = 0; + while (speed > 1000) { + index++; + speed = speed / 1000; + } + return `${speed.toFixed(index > 1 ? 1 : 0)} ${suffix[index]}`; +}; + export const getVersion = () => { return ( document.querySelector('meta[name="version"]')?.content ||