aboutsummaryrefslogtreecommitdiffstats
path: root/excalidraw-app/CustomStats.tsx
blob: 96ca55d67fdc45ac8736e64c22fa61e7df54b7c9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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;