aboutsummaryrefslogtreecommitdiffstats
path: root/excalidraw-app/CustomStats.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'excalidraw-app/CustomStats.tsx')
-rw-r--r--excalidraw-app/CustomStats.tsx85
1 files changed, 85 insertions, 0 deletions
diff --git a/excalidraw-app/CustomStats.tsx b/excalidraw-app/CustomStats.tsx
new file mode 100644
index 0000000..96ca55d
--- /dev/null
+++ b/excalidraw-app/CustomStats.tsx
@@ -0,0 +1,85 @@
+import { useEffect, useState } from "react";
+import { debounce, getVersion, nFormatter } from "@excalidraw/excalidraw/utils";
+import {
+ getElementsStorageSize,
+ getTotalStorageSize,
+} from "./data/localStorage";
+import { DEFAULT_VERSION } from "@excalidraw/excalidraw/constants";
+import { t } from "@excalidraw/excalidraw/i18n";
+import { copyTextToSystemClipboard } from "@excalidraw/excalidraw/clipboard";
+import type { NonDeletedExcalidrawElement } from "@excalidraw/excalidraw/element/types";
+import type { UIAppState } from "@excalidraw/excalidraw/types";
+import { Stats } from "@excalidraw/excalidraw";
+
+type StorageSizes = { scene: number; total: number };
+
+const STORAGE_SIZE_TIMEOUT = 500;
+
+const getStorageSizes = debounce((cb: (sizes: StorageSizes) => void) => {
+ cb({
+ scene: getElementsStorageSize(),
+ total: getTotalStorageSize(),
+ });
+}, STORAGE_SIZE_TIMEOUT);
+
+type Props = {
+ setToast: (message: string) => void;
+ elements: readonly NonDeletedExcalidrawElement[];
+ appState: UIAppState;
+};
+const CustomStats = (props: Props) => {
+ const [storageSizes, setStorageSizes] = useState<StorageSizes>({
+ scene: 0,
+ total: 0,
+ });
+
+ useEffect(() => {
+ getStorageSizes((sizes) => {
+ setStorageSizes(sizes);
+ });
+ }, [props.elements, props.appState]);
+ useEffect(() => () => getStorageSizes.cancel(), []);
+
+ const version = getVersion();
+ let hash;
+ let timestamp;
+
+ if (version !== DEFAULT_VERSION) {
+ timestamp = version.slice(0, 16).replace("T", " ");
+ hash = version.slice(21);
+ } else {
+ timestamp = t("stats.versionNotAvailable");
+ }
+
+ return (
+ <Stats.StatsRows order={-1}>
+ <Stats.StatsRow heading>{t("stats.version")}</Stats.StatsRow>
+ <Stats.StatsRow
+ style={{ textAlign: "center", cursor: "pointer" }}
+ onClick={async () => {
+ try {
+ await copyTextToSystemClipboard(getVersion());
+ props.setToast(t("toast.copyToClipboard"));
+ } catch {}
+ }}
+ title={t("stats.versionCopy")}
+ >
+ {timestamp}
+ <br />
+ {hash}
+ </Stats.StatsRow>
+
+ <Stats.StatsRow heading>{t("stats.storage")}</Stats.StatsRow>
+ <Stats.StatsRow columns={2}>
+ <div>{t("stats.scene")}</div>
+ <div>{nFormatter(storageSizes.scene, 1)}</div>
+ </Stats.StatsRow>
+ <Stats.StatsRow columns={2}>
+ <div>{t("stats.total")}</div>
+ <div>{nFormatter(storageSizes.total, 1)}</div>
+ </Stats.StatsRow>
+ </Stats.StatsRows>
+ );
+};
+
+export default CustomStats;