feat: show network stats for collaboration

This commit is contained in:
Aakansha Doshi 2021-02-06 19:50:35 +05:30
parent 1e17c1967b
commit 8157c84d11
6 changed files with 83 additions and 1 deletions

View File

@ -73,6 +73,7 @@ export const getDefaultAppState = (): Omit<
zenModeEnabled: false,
zoom: { value: 1 as NormalizedZoomValue, translation: { x: 0, y: 0 } },
viewModeEnabled: false,
networkSpeed: "calculating...",
};
};
@ -153,6 +154,7 @@ const APP_STATE_STORAGE_CONF = (<
zenModeEnabled: { browser: true, export: false },
zoom: { browser: true, export: false },
viewModeEnabled: { browser: false, export: false },
networkSpeed: { browser: false, export: false },
});
const _clearAppStateForStorage = <ExportType extends "export" | "browser">(

View File

@ -1,3 +1,4 @@
// @ts-nocheck
import { Point, simplify } from "points-on-curve";
import React from "react";
import { RoughCanvas } from "roughjs/bin/canvas";
@ -182,6 +183,7 @@ import LayerUI from "./LayerUI";
import { Stats } from "./Stats";
import { Toast } from "./Toast";
import { actionToggleViewMode } from "../actions/actionToggleViewMode";
import { getNetworkSpeed } from "../networkStats";
const { history } = createHistory();
@ -461,6 +463,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
setAppState={this.setAppState}
elements={this.scene.getElements()}
onClose={this.toggleStats}
isCollaborating={this.props.isCollaborating}
/>
)}
{this.state.toastMessage !== null && (
@ -845,6 +848,21 @@ class App extends React.Component<ExcalidrawProps, AppState> {
this.addEventListeners();
}
if (
prevState.showStats !== this.state.showStats ||
prevProps.isCollaborating !== this.props.isCollaborating
) {
if (this.state.showStats && this.props.isCollaborating) {
this.calculateNetStats();
navigator.connection.addEventListener("change", this.calculateNetStats);
} else {
navigator.connection.removeEventListener(
"change",
this.calculateNetStats,
);
}
}
document
.querySelector(".excalidraw")
?.classList.toggle("Appearance_dark", this.state.appearance === "dark");
@ -970,6 +988,11 @@ class App extends React.Component<ExcalidrawProps, AppState> {
}
}
private calculateNetStats = async () => {
const speed = await getNetworkSpeed();
const networkSpeed = speed === -1 ? "Error!" : speed;
this.setState({ networkSpeed });
};
// Copy/paste
private onCut = withBatchedUpdates((event: ClipboardEvent) => {

View File

@ -30,6 +30,7 @@ export const Stats = (props: {
setAppState: React.Component<any, AppState>["setState"];
elements: readonly NonDeletedExcalidrawElement[];
onClose: () => void;
isCollaborating: boolean;
}) => {
const isMobile = useIsMobile();
const [storageSizes, setStorageSizes] = useState<StorageSizes>({
@ -192,6 +193,21 @@ export const Stats = (props: {
{hash}
</td>
</tr>
{props.isCollaborating ? (
<>
<tr>
<th colSpan={2}>{t("stats.collaboration")}</th>
</tr>
<tr>
<td>{t("stats.collaborators")}</td>
<td>{props.appState.collaborators.size}</td>
</tr>
<tr>
<td>{t("stats.networkSpeed")}</td>
<td>{props.appState.networkSpeed}</td>
</tr>
</>
) : null}
</tbody>
</table>
</Island>

View File

@ -238,7 +238,10 @@
"version": "Version",
"versionCopy": "Click to copy",
"versionNotAvailable": "Version not available",
"width": "Width"
"width": "Width",
"collaboration": "Collaboration",
"networkSpeed": "Network Speed",
"collaborators": "Collaborators"
},
"toast": {
"copyStyles": "Copied styles.",

37
src/networkStats.ts Normal file
View File

@ -0,0 +1,37 @@
const IMAGE_URL =
"https://user-images.githubusercontent.com/11256141/107117897-76fa3880-68a3-11eb-9ec6-c214c7af373b.png";
const IMAGE_SIZE = 4525154; // in bytes
const calculateSpeed = (startTime: number, endTime: number) => {
const duration = (endTime - startTime) / 1000;
const imageSizeInBits = IMAGE_SIZE * 8;
let speed = imageSizeInBits / duration;
const suffix = ["bps", "kbps", "mbps", "gbps"];
let index = 0;
while (speed > 1024) {
index++;
speed = speed / 1024;
}
return `${speed.toFixed(2)} ${suffix[index]}`;
};
const processImage = () => {
return new Promise((resolve, reject) => {
const image = new Image();
let endTime: number;
image.onload = () => {
endTime = new Date().getTime();
const speed = calculateSpeed(startTime, endTime);
resolve(speed);
};
image.onerror = () => {
resolve(-1);
};
const startTime = new Date().getTime();
image.src = `${IMAGE_URL}?t=${startTime}`; // start time acts as a cache buster so everytime new url is requested
});
};
export const getNetworkSpeed = async () => {
return await processImage();
};

View File

@ -88,6 +88,7 @@ export type AppState = {
appearance: "light" | "dark";
gridSize: number | null;
viewModeEnabled: boolean;
networkSpeed?: string;
/** top-most selected groups (i.e. does not include nested groups) */
selectedGroupIds: { [groupId: string]: boolean };