diff --git a/analytics.md b/analytics.md index 3d8fb52d..7ba56a97 100644 --- a/analytics.md +++ b/analytics.md @@ -46,9 +46,15 @@ | Copy room link | share | copy link | | Go to collaborator | share | go to collaborator | | Change name | share | name | +| Add to library | library | add | +| Remove from library | library | remove | +| Load library | library | load | +| Save library | library | save | +| Import library | library | import | | Shortcuts dialog | dialog | shortcuts | | Collaboration dialog | dialog | collaboration | | Export dialog | dialog | export | +| Library dialog | dialog | library | | E2EE shield | exit | e2ee shield | | GitHub corner | exit | github | | Excalidraw blog | exit | blog | diff --git a/src/actions/actionAddToLibrary.ts b/src/actions/actionAddToLibrary.ts index 71527a0b..53727a81 100644 --- a/src/actions/actionAddToLibrary.ts +++ b/src/actions/actionAddToLibrary.ts @@ -3,6 +3,7 @@ import { getSelectedElements } from "../scene"; import { getNonDeletedElements } from "../element"; import { deepCopyElement } from "../element/newElement"; import { Library } from "../data/library"; +import { EVENT_LIBRARY, trackEvent } from "../analytics"; export const actionAddToLibrary = register({ name: "addToLibrary", @@ -15,7 +16,7 @@ export const actionAddToLibrary = register({ Library.loadLibrary().then((items) => { Library.saveLibrary([...items, selectedElements.map(deepCopyElement)]); }); - + trackEvent(EVENT_LIBRARY, "add"); return false; }, contextMenuOrder: 6, diff --git a/src/analytics.ts b/src/analytics.ts index 1730fdec..84d9529e 100644 --- a/src/analytics.ts +++ b/src/analytics.ts @@ -7,6 +7,7 @@ export const EVENT_ALIGN = "align"; export const EVENT_SHARE = "share"; export const EVENT_IO = "io"; export const EVENT_DIALOG = "dialog"; +export const EVENT_LIBRARY = "library"; export const trackEvent = window.gtag ? (category: string, name: string, label?: string, value?: number) => { diff --git a/src/components/Actions.tsx b/src/components/Actions.tsx index 36fa19ef..1377cf67 100644 --- a/src/components/Actions.tsx +++ b/src/components/Actions.tsx @@ -16,7 +16,7 @@ import { capitalizeString, isTransparent, setCursorForShape } from "../utils"; import Stack from "./Stack"; import useIsMobile from "../is-mobile"; import { getNonDeletedElements } from "../element"; -import { trackEvent, EVENT_SHAPE } from "../analytics"; +import { trackEvent, EVENT_SHAPE, EVENT_DIALOG } from "../analytics"; export const SelectedShapeActions = ({ appState, @@ -196,6 +196,9 @@ export const ShapesSwitcher = ({ title={`${capitalizeString(t("toolBar.library"))} — 9`} aria-label={capitalizeString(t("toolBar.library"))} onClick={() => { + if (!isLibraryOpen) { + trackEvent(EVENT_DIALOG, "library"); + } setAppState({ isLibraryOpen: !isLibraryOpen }); }} /> diff --git a/src/components/App.tsx b/src/components/App.tsx index 69fb29d3..c40b7e66 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -181,7 +181,13 @@ import { isSavedToFirebase, } from "../data/firebase"; import { getNewZoom } from "../scene/zoom"; -import { EVENT_SHAPE, EVENT_SHARE, trackEvent } from "../analytics"; +import { + EVENT_DIALOG, + EVENT_LIBRARY, + EVENT_SHAPE, + EVENT_SHARE, + trackEvent, +} from "../analytics"; /** * @param func handler taking at most single parameter (event). @@ -548,6 +554,7 @@ class App extends React.Component { ) ) { await Library.importLibrary(blob); + trackEvent(EVENT_LIBRARY, "import"); this.setState({ isLibraryOpen: true, }); @@ -1577,6 +1584,9 @@ class App extends React.Component { } if (event.code === CODES.NINE) { + if (!this.state.isLibraryOpen) { + trackEvent(EVENT_DIALOG, "library"); + } this.setState({ isLibraryOpen: !this.state.isLibraryOpen }); } diff --git a/src/components/LayerUI.tsx b/src/components/LayerUI.tsx index 6c909340..8cd86698 100644 --- a/src/components/LayerUI.tsx +++ b/src/components/LayerUI.tsx @@ -45,7 +45,12 @@ import { muteFSAbortError } from "../utils"; import { BackgroundPickerAndDarkModeToggle } from "./BackgroundPickerAndDarkModeToggle"; import clsx from "clsx"; import { Library } from "../data/library"; -import { EVENT_ACTION, EVENT_EXIT, trackEvent } from "../analytics"; +import { + EVENT_ACTION, + EVENT_EXIT, + EVENT_LIBRARY, + trackEvent, +} from "../analytics"; interface LayerUIProps { actionManager: ActionManager; @@ -252,6 +257,7 @@ const LibraryMenu = ({ const items = await Library.loadLibrary(); const nextItems = items.filter((_, index) => index !== indexToRemove); Library.saveLibrary(nextItems); + trackEvent(EVENT_LIBRARY, "remove"); setLibraryItems(nextItems); }, []); @@ -260,6 +266,7 @@ const LibraryMenu = ({ const items = await Library.loadLibrary(); const nextItems = [...items, elements]; onAddToLibrary(); + trackEvent(EVENT_LIBRARY, "add"); Library.saveLibrary(nextItems); setLibraryItems(nextItems); }, diff --git a/src/data/json.ts b/src/data/json.ts index 2eb4f950..67e969be 100644 --- a/src/data/json.ts +++ b/src/data/json.ts @@ -7,6 +7,7 @@ import { loadFromBlob } from "./blob"; import { Library } from "./library"; import { MIME_TYPES } from "../constants"; import { clearElementsForExport } from "../element"; +import { EVENT_LIBRARY, trackEvent } from "../analytics"; export const serializeAsJSON = ( elements: readonly ExcalidrawElement[], @@ -83,6 +84,7 @@ export const saveLibraryAsJSON = async () => { description: "Excalidraw library file", extensions: [".excalidrawlib"], }); + trackEvent(EVENT_LIBRARY, "save"); }; export const importLibraryFromJSON = async () => { @@ -91,5 +93,6 @@ export const importLibraryFromJSON = async () => { extensions: [".json", ".excalidrawlib"], mimeTypes: ["application/json"], }); + trackEvent(EVENT_LIBRARY, "load"); Library.importLibrary(blob); };