From 3aa01ad2724a6a90df9ddd55e86922f268829ae9 Mon Sep 17 00:00:00 2001 From: Lipis Date: Tue, 5 Jan 2021 20:06:14 +0200 Subject: [PATCH] chore: Remove tracking (#2722) * chore: Remove tracking * process * rename * remove * prod * Update public/index.html Co-authored-by: David Luzar * Update public/index.html * eol * more * stats Co-authored-by: David Luzar --- .env.production | 2 +- Dockerfile | 1 - analytics.md | 64 ---------- package.json | 4 +- public/index.html | 6 +- src/actions/actionAddToLibrary.ts | 2 - src/actions/actionAlign.tsx | 19 +-- src/actions/actionCanvas.tsx | 17 --- src/actions/actionDistribute.tsx | 17 ++- src/actions/actionExport.tsx | 11 +- src/actions/actionMenu.tsx | 2 - src/actions/actionNavigate.tsx | 8 +- src/actions/actionProperties.tsx | 116 +++++++----------- src/analytics.ts | 20 +-- src/charts.ts | 4 +- src/components/Actions.tsx | 23 ++-- src/components/App.tsx | 18 +-- .../BackgroundPickerAndDarkModeToggle.tsx | 3 - src/components/CollabButton.tsx | 6 +- src/components/ExportDialog.tsx | 2 - src/components/GitHubCorner.tsx | 6 +- src/components/LayerUI.tsx | 82 +++++-------- src/components/MobileMenu.tsx | 2 - src/components/ShortcutsDialog.tsx | 10 -- src/data/blob.ts | 2 - src/data/index.ts | 7 +- src/data/json.ts | 14 +-- src/excalidraw-app/collab/CollabWrapper.tsx | 48 ++++---- src/excalidraw-app/collab/RoomDialog.tsx | 10 +- src/excalidraw-app/data/index.ts | 13 +- src/excalidraw-app/index.tsx | 68 ++++------ src/i18n.ts | 3 - src/zindex.ts | 7 +- 33 files changed, 182 insertions(+), 435 deletions(-) delete mode 100644 analytics.md diff --git a/.env.production b/.env.production index 0a6355ed..01fb7767 100644 --- a/.env.production +++ b/.env.production @@ -1 +1 @@ -REACT_APP_INCLUDE_GTAG=true +REACT_APP_GOOGLE_ANALYTICS_ID=UA-387204-13 diff --git a/Dockerfile b/Dockerfile index eb9da172..27f3a708 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,6 @@ WORKDIR /opt/node_app COPY package.json package-lock.json ./ RUN npm i --no-optional -ARG REACT_APP_INCLUDE_GTAG=false ARG NODE_ENV=production COPY . . diff --git a/analytics.md b/analytics.md deleted file mode 100644 index 30e2ccac..00000000 --- a/analytics.md +++ /dev/null @@ -1,64 +0,0 @@ -| Excalidraw | Category | Name | Label | Value | -| ----------------------- | -------- | ---------------------------------- | ------------------------------- | --------- | -| Shape / Selection | shape | selection, rectangle, diamond, etc | `toolbar` or `shortcut` | -| Text on double click | shape | text | `double-click` | -| Lock selection | shape | lock | `on` or `off` | -| Clear canvas | action | clear canvas | -| Zoom in | action | zoom | in | `zoom` | -| Zoom out | action | zoom | out | `zoom` | -| Zoom fit | action | zoom | fit | `zoom` | -| Zoom reset | action | zoom | reset | `zoom` | -| Scroll back to content | action | scroll to content | -| Load file | io | load | `MIME type` | -| Import from URL | io | import | -| Save | io | save | -| Save as | io | save as | -| Export to backend | io | export | backend | -| Export as SVG | io | export | `svg` or `clipboard-svg` | -| Export to PNG | io | export | `png` or `clipboard-png` | -| Canvas color | change | canvas color | `color` | -| Background color | change | background color | `color` | -| Stroke color | change | stroke color | `color` | -| Stroke width | change | stroke | width | `width` | -| Stroke style | change | style | `solid` or `dashed` or `dotted` | -| Stroke sloppiness | change | stroke | sloppiness | `value` | -| Fill | change | fill | `value` | -| Edge | change | edge | `value` | -| Opacity | change | opacity | value | `opacity` | -| Project name | change | title | -| Theme | change | theme | `light` or `dark` | -| Change language | change | language | `language` | -| Send to back | layer | move | `back` | -| Send backward | layer | move | `down` | -| Bring to front | layer | move | `front` | -| Bring forward | layer | move | `up` | -| Align left | align | align | `left` | -| Align right | align | align | `right` | -| Align top | align | align | `top` | -| Align bottom | align | align | `bottom` | -| Center horizontally | align | horizontally | `center` | -| Center vertically | align | vertically | `center` | -| Distribute horizontally | align | distribute | `horizontally` | -| Distribute vertically | align | distribute | `vertically` | -| Start session | share | session start | -| Join session | share | session join | -| Start end | share | session end | -| 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 | -| Excalidraw guides | exit | guides | -| File issues | exit | issues | -| First load | load | first load | -| Load from stroage | load | storage | size | `bytes` | diff --git a/package.json b/package.json index 3bf149b7..9876a5d1 100644 --- a/package.json +++ b/package.json @@ -81,8 +81,8 @@ "private": true, "scripts": { "build-node": "node ./scripts/build-node.js", - "build:app:docker": "REACT_APP_INCLUDE_GTAG=false REACT_APP_DISABLE_SENTRY=true react-scripts build", - "build:app": "REACT_APP_INCLUDE_GTAG=true REACT_APP_GIT_SHA=$NOW_GITHUB_COMMIT_SHA react-scripts build", + "build:app:docker": "REACT_APP_DISABLE_SENTRY=true react-scripts build", + "build:app": "REACT_APP_GIT_SHA=$NOW_GITHUB_COMMIT_SHA react-scripts build", "build:version": "node ./scripts/build-version.js", "build": "npm run build:app && npm run build:version", "eject": "react-scripts eject", diff --git a/public/index.html b/public/index.html index 138dc4e0..24b76e86 100644 --- a/public/index.html +++ b/public/index.html @@ -86,10 +86,10 @@ - <% if (process.env.REACT_APP_INCLUDE_GTAG === 'true') { %> + <% if (process.env.REACT_APP_GOOGLE_ANALYTICS_ID) { %> <% } %> diff --git a/src/actions/actionAddToLibrary.ts b/src/actions/actionAddToLibrary.ts index 53727a81..a0abbf5c 100644 --- a/src/actions/actionAddToLibrary.ts +++ b/src/actions/actionAddToLibrary.ts @@ -3,7 +3,6 @@ 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", @@ -16,7 +15,6 @@ 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/actions/actionAlign.tsx b/src/actions/actionAlign.tsx index 77c1e880..5397df9b 100644 --- a/src/actions/actionAlign.tsx +++ b/src/actions/actionAlign.tsx @@ -1,7 +1,5 @@ import React from "react"; -import { KEYS } from "../keys"; -import { t } from "../i18n"; -import { register } from "./register"; +import { alignElements, Alignment } from "../align"; import { AlignBottomIcon, AlignLeftIcon, @@ -10,14 +8,15 @@ import { CenterHorizontallyIcon, CenterVerticallyIcon, } from "../components/icons"; -import { getSelectedElements, isSomeElementSelected } from "../scene"; -import { getElementMap, getNonDeletedElements } from "../element"; import { ToolButton } from "../components/ToolButton"; +import { getElementMap, getNonDeletedElements } from "../element"; import { ExcalidrawElement } from "../element/types"; +import { t } from "../i18n"; +import { KEYS } from "../keys"; +import { getSelectedElements, isSomeElementSelected } from "../scene"; import { AppState } from "../types"; -import { alignElements, Alignment } from "../align"; import { getShortcutKey } from "../utils"; -import { trackEvent, EVENT_ALIGN } from "../analytics"; +import { register } from "./register"; const enableActionGroup = ( elements: readonly ExcalidrawElement[], @@ -44,7 +43,6 @@ const alignSelectedElements = ( export const actionAlignTop = register({ name: "alignTop", perform: (elements, appState) => { - trackEvent(EVENT_ALIGN, "align", "top"); return { appState, elements: alignSelectedElements(elements, appState, { @@ -74,7 +72,6 @@ export const actionAlignTop = register({ export const actionAlignBottom = register({ name: "alignBottom", perform: (elements, appState) => { - trackEvent(EVENT_ALIGN, "align", "bottom"); return { appState, elements: alignSelectedElements(elements, appState, { @@ -104,7 +101,6 @@ export const actionAlignBottom = register({ export const actionAlignLeft = register({ name: "alignLeft", perform: (elements, appState) => { - trackEvent(EVENT_ALIGN, "align", "left"); return { appState, elements: alignSelectedElements(elements, appState, { @@ -134,7 +130,6 @@ export const actionAlignLeft = register({ export const actionAlignRight = register({ name: "alignRight", perform: (elements, appState) => { - trackEvent(EVENT_ALIGN, "align", "right"); return { appState, elements: alignSelectedElements(elements, appState, { @@ -164,7 +159,6 @@ export const actionAlignRight = register({ export const actionAlignVerticallyCentered = register({ name: "alignVerticallyCentered", perform: (elements, appState) => { - trackEvent(EVENT_ALIGN, "vertically", "center"); return { appState, elements: alignSelectedElements(elements, appState, { @@ -190,7 +184,6 @@ export const actionAlignVerticallyCentered = register({ export const actionAlignHorizontallyCentered = register({ name: "alignHorizontallyCentered", perform: (elements, appState) => { - trackEvent(EVENT_ALIGN, "horizontally", "center"); return { appState, elements: alignSelectedElements(elements, appState, { diff --git a/src/actions/actionCanvas.tsx b/src/actions/actionCanvas.tsx index aff1a7f6..d29b7c71 100644 --- a/src/actions/actionCanvas.tsx +++ b/src/actions/actionCanvas.tsx @@ -1,7 +1,5 @@ import React from "react"; -import { EVENT_ACTION, EVENT_CHANGE, trackEvent } from "../analytics"; import { getDefaultAppState } from "../appState"; -import colors from "../colors"; import { ColorPicker } from "../components/ColorPicker"; import { resetZoom, trash, zoomIn, zoomOut } from "../components/icons"; import { ToolButton } from "../components/ToolButton"; @@ -21,15 +19,6 @@ import { register } from "./register"; export const actionChangeViewBackgroundColor = register({ name: "changeViewBackgroundColor", perform: (_, appState, value) => { - if (value !== appState.viewBackgroundColor) { - trackEvent( - EVENT_CHANGE, - "canvas color", - colors.canvasBackground.includes(value) - ? `${value} (picker ${colors.canvasBackground.indexOf(value)})` - : value, - ); - } return { appState: { ...appState, viewBackgroundColor: value }, commitToHistory: true, @@ -52,7 +41,6 @@ export const actionChangeViewBackgroundColor = register({ export const actionClearCanvas = register({ name: "clearCanvas", perform: (elements, appState: AppState) => { - trackEvent(EVENT_ACTION, "clear canvas"); return { elements: elements.map((element) => newElementWith(element, { isDeleted: true }), @@ -98,7 +86,6 @@ export const actionZoomIn = register({ { left: appState.offsetLeft, top: appState.offsetTop }, { x: appState.width / 2, y: appState.height / 2 }, ); - trackEvent(EVENT_ACTION, "zoom", "in", zoom.value * 100); return { appState: { ...appState, @@ -133,7 +120,6 @@ export const actionZoomOut = register({ { x: appState.width / 2, y: appState.height / 2 }, ); - trackEvent(EVENT_ACTION, "zoom", "out", zoom.value * 100); return { appState: { ...appState, @@ -161,7 +147,6 @@ export const actionZoomOut = register({ export const actionResetZoom = register({ name: "resetZoom", perform: (_elements, appState) => { - trackEvent(EVENT_ACTION, "zoom", "reset", 100); return { appState: { ...appState, @@ -234,12 +219,10 @@ const zoomToFitElements = ( left: appState.offsetLeft, top: appState.offsetTop, }); - const action = zoomToSelection ? "selection" : "fit"; const [x1, y1, x2, y2] = commonBounds; const centerX = (x1 + x2) / 2; const centerY = (y1 + y2) / 2; - trackEvent(EVENT_ACTION, "zoom", action, newZoom.value * 100); return { appState: { ...appState, diff --git a/src/actions/actionDistribute.tsx b/src/actions/actionDistribute.tsx index 15669dde..fdd8267c 100644 --- a/src/actions/actionDistribute.tsx +++ b/src/actions/actionDistribute.tsx @@ -1,19 +1,18 @@ import React from "react"; -import { CODES } from "../keys"; -import { t } from "../i18n"; -import { register } from "./register"; import { DistributeHorizontallyIcon, DistributeVerticallyIcon, } from "../components/icons"; -import { getSelectedElements, isSomeElementSelected } from "../scene"; -import { getElementMap, getNonDeletedElements } from "../element"; import { ToolButton } from "../components/ToolButton"; -import { ExcalidrawElement } from "../element/types"; -import { AppState } from "../types"; import { distributeElements, Distribution } from "../disitrubte"; +import { getElementMap, getNonDeletedElements } from "../element"; +import { ExcalidrawElement } from "../element/types"; +import { t } from "../i18n"; +import { CODES } from "../keys"; +import { getSelectedElements, isSomeElementSelected } from "../scene"; +import { AppState } from "../types"; import { getShortcutKey } from "../utils"; -import { EVENT_ALIGN, trackEvent } from "../analytics"; +import { register } from "./register"; const enableActionGroup = ( elements: readonly ExcalidrawElement[], @@ -40,7 +39,6 @@ const distributeSelectedElements = ( export const distributeHorizontally = register({ name: "distributeHorizontally", perform: (elements, appState) => { - trackEvent(EVENT_ALIGN, "distribute", "horizontally"); return { appState, elements: distributeSelectedElements(elements, appState, { @@ -69,7 +67,6 @@ export const distributeHorizontally = register({ export const distributeVertically = register({ name: "distributeVertically", perform: (elements, appState) => { - trackEvent(EVENT_ALIGN, "distribute", "vertically"); return { appState, elements: distributeSelectedElements(elements, appState, { diff --git a/src/actions/actionExport.tsx b/src/actions/actionExport.tsx index 2748ad3a..ac60fdd3 100644 --- a/src/actions/actionExport.tsx +++ b/src/actions/actionExport.tsx @@ -1,22 +1,21 @@ import React from "react"; -import { EVENT_CHANGE, EVENT_IO, trackEvent } from "../analytics"; -import { load, save, saveAs } from "../components/icons"; +import { trackEvent } from "../analytics"; +import { load, questionCircle, save, saveAs } from "../components/icons"; import { ProjectName } from "../components/ProjectName"; import { ToolButton } from "../components/ToolButton"; +import "../components/ToolIcon.scss"; import { Tooltip } from "../components/Tooltip"; -import { questionCircle } from "../components/icons"; import { loadFromJSON, saveAsJSON } from "../data"; import { t } from "../i18n"; import useIsMobile from "../is-mobile"; import { KEYS } from "../keys"; import { muteFSAbortError } from "../utils"; import { register } from "./register"; -import "../components/ToolIcon.scss"; export const actionChangeProjectName = register({ name: "changeProjectName", perform: (_elements, appState, value) => { - trackEvent(EVENT_CHANGE, "title"); + trackEvent("change", "title"); return { appState: { ...appState, name: value }, commitToHistory: false }; }, PanelComponent: ({ appState, updateData }) => ( @@ -100,7 +99,6 @@ export const actionSaveScene = register({ perform: async (elements, appState, value) => { try { const { fileHandle } = await saveAsJSON(elements, appState); - trackEvent(EVENT_IO, "save"); return { commitToHistory: false, appState: { ...appState, fileHandle } }; } catch (error) { if (error?.name !== "AbortError") { @@ -131,7 +129,6 @@ export const actionSaveAsScene = register({ ...appState, fileHandle: null, }); - trackEvent(EVENT_IO, "save as"); return { commitToHistory: false, appState: { ...appState, fileHandle } }; } catch (error) { if (error?.name !== "AbortError") { diff --git a/src/actions/actionMenu.tsx b/src/actions/actionMenu.tsx index 7abe74c4..6ae29e51 100644 --- a/src/actions/actionMenu.tsx +++ b/src/actions/actionMenu.tsx @@ -7,7 +7,6 @@ import { register } from "./register"; import { allowFullScreen, exitFullScreen, isFullScreen } from "../utils"; import { CODES, KEYS } from "../keys"; import { HelpIcon } from "../components/HelpIcon"; -import { EVENT_DIALOG, trackEvent } from "../analytics"; export const actionToggleCanvasMenu = register({ name: "toggleCanvasMenu", @@ -72,7 +71,6 @@ export const actionFullScreen = register({ export const actionShortcuts = register({ name: "toggleShortcuts", perform: (_elements, appState) => { - trackEvent(EVENT_DIALOG, "shortcuts"); return { appState: { ...appState, diff --git a/src/actions/actionNavigate.tsx b/src/actions/actionNavigate.tsx index 02d981f7..ea9012f9 100644 --- a/src/actions/actionNavigate.tsx +++ b/src/actions/actionNavigate.tsx @@ -1,16 +1,14 @@ import React from "react"; -import { Avatar } from "../components/Avatar"; -import { register } from "./register"; import { getClientColors, getClientInitials } from "../clients"; -import { Collaborator } from "../types"; +import { Avatar } from "../components/Avatar"; import { centerScrollOn } from "../scene/scroll"; -import { EVENT_SHARE, trackEvent } from "../analytics"; +import { Collaborator } from "../types"; +import { register } from "./register"; export const actionGoToCollaborator = register({ name: "goToCollaborator", perform: (_elements, appState, value) => { const point = value as Collaborator["pointer"]; - trackEvent(EVENT_SHARE, "go to collaborator"); if (!point) { return { appState, commitToHistory: false }; } diff --git a/src/actions/actionProperties.tsx b/src/actions/actionProperties.tsx index a818cf24..b6e39fa3 100644 --- a/src/actions/actionProperties.tsx +++ b/src/actions/actionProperties.tsx @@ -1,56 +1,53 @@ import React from "react"; -import { getLanguage } from "../i18n"; -import { - ExcalidrawElement, - ExcalidrawTextElement, - TextAlign, - FontFamily, - ExcalidrawLinearElement, - Arrowhead, -} from "../element/types"; -import { - getCommonAttributeOfSelectedElements, - isSomeElementSelected, - getTargetElements, - canChangeSharpness, - canHaveArrowheads, -} from "../scene"; -import { ButtonSelect } from "../components/ButtonSelect"; +import { AppState } from "../../src/types"; import { ButtonIconSelect } from "../components/ButtonIconSelect"; +import { ButtonSelect } from "../components/ButtonSelect"; +import { ColorPicker } from "../components/ColorPicker"; import { IconPicker } from "../components/IconPicker"; import { - isTextElement, - redrawTextBoundingBox, - getNonDeletedElements, -} from "../element"; -import { isLinearElement, isLinearElementType } from "../element/typeChecks"; -import { ColorPicker } from "../components/ColorPicker"; -import { AppState } from "../../src/types"; -import { t } from "../i18n"; -import { register } from "./register"; -import { newElementWith } from "../element/mutateElement"; -import { DEFAULT_FONT_SIZE, DEFAULT_FONT_FAMILY } from "../constants"; -import { randomInteger } from "../random"; -import { - FillHachureIcon, - FillCrossHatchIcon, - FillSolidIcon, - StrokeWidthIcon, - StrokeStyleSolidIcon, - StrokeStyleDashedIcon, - StrokeStyleDottedIcon, - EdgeSharpIcon, - EdgeRoundIcon, - SloppinessArchitectIcon, - SloppinessArtistIcon, - SloppinessCartoonistIcon, ArrowheadArrowIcon, ArrowheadBarIcon, ArrowheadDotIcon, ArrowheadNoneIcon, + EdgeRoundIcon, + EdgeSharpIcon, + FillCrossHatchIcon, + FillHachureIcon, + FillSolidIcon, + SloppinessArchitectIcon, + SloppinessArtistIcon, + SloppinessCartoonistIcon, + StrokeStyleDashedIcon, + StrokeStyleDottedIcon, + StrokeStyleSolidIcon, + StrokeWidthIcon, } from "../components/icons"; -import { EVENT_CHANGE, trackEvent } from "../analytics"; -import colors from "../colors"; +import { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE } from "../constants"; +import { + getNonDeletedElements, + isTextElement, + redrawTextBoundingBox, +} from "../element"; +import { newElementWith } from "../element/mutateElement"; +import { isLinearElement, isLinearElementType } from "../element/typeChecks"; +import { + Arrowhead, + ExcalidrawElement, + ExcalidrawLinearElement, + ExcalidrawTextElement, + FontFamily, + TextAlign, +} from "../element/types"; +import { getLanguage, t } from "../i18n"; +import { randomInteger } from "../random"; +import { + canChangeSharpness, + canHaveArrowheads, + getCommonAttributeOfSelectedElements, + getTargetElements, + isSomeElementSelected, +} from "../scene"; +import { register } from "./register"; const changeProperty = ( elements: readonly ExcalidrawElement[], @@ -92,15 +89,6 @@ const getFormValue = function ( export const actionChangeStrokeColor = register({ name: "changeStrokeColor", perform: (elements, appState, value) => { - if (value !== appState.currentItemStrokeColor) { - trackEvent( - EVENT_CHANGE, - "stroke color", - colors.elementStroke.includes(value) - ? `${value} (picker ${colors.elementStroke.indexOf(value)})` - : value, - ); - } return { elements: changeProperty(elements, appState, (el) => newElementWith(el, { @@ -132,16 +120,6 @@ export const actionChangeStrokeColor = register({ export const actionChangeBackgroundColor = register({ name: "changeBackgroundColor", perform: (elements, appState, value) => { - if (value !== appState.currentItemBackgroundColor) { - trackEvent( - EVENT_CHANGE, - "background color", - colors.elementBackground.includes(value) - ? `${value} (picker ${colors.elementBackground.indexOf(value)})` - : value, - ); - } - return { elements: changeProperty(elements, appState, (el) => newElementWith(el, { @@ -173,7 +151,6 @@ export const actionChangeBackgroundColor = register({ export const actionChangeFillStyle = register({ name: "changeFillStyle", perform: (elements, appState, value) => { - trackEvent(EVENT_CHANGE, "fill", value); return { elements: changeProperty(elements, appState, (el) => newElementWith(el, { @@ -223,7 +200,6 @@ export const actionChangeFillStyle = register({ export const actionChangeStrokeWidth = register({ name: "changeStrokeWidth", perform: (elements, appState, value) => { - trackEvent(EVENT_CHANGE, "stroke", "width", value); return { elements: changeProperty(elements, appState, (el) => newElementWith(el, { @@ -286,7 +262,6 @@ export const actionChangeStrokeWidth = register({ export const actionChangeSloppiness = register({ name: "changeSloppiness", perform: (elements, appState, value) => { - trackEvent(EVENT_CHANGE, "stroke", "sloppiness", value); return { elements: changeProperty(elements, appState, (el) => newElementWith(el, { @@ -335,7 +310,6 @@ export const actionChangeSloppiness = register({ export const actionChangeStrokeStyle = register({ name: "changeStrokeStyle", perform: (elements, appState, value) => { - trackEvent(EVENT_CHANGE, "style", value); return { elements: changeProperty(elements, appState, (el) => newElementWith(el, { @@ -383,7 +357,6 @@ export const actionChangeStrokeStyle = register({ export const actionChangeOpacity = register({ name: "changeOpacity", perform: (elements, appState, value) => { - trackEvent(EVENT_CHANGE, "opacity", "value", value); return { elements: changeProperty(elements, appState, (el) => newElementWith(el, { @@ -580,7 +553,6 @@ export const actionChangeSharpness = register({ const shouldUpdateForLinearElements = targetElements.length ? targetElements.every(isLinearElement) : isLinearElementType(appState.elementType); - trackEvent(EVENT_CHANGE, "edge", value); return { elements: changeProperty(elements, appState, (el) => newElementWith(el, { @@ -642,12 +614,6 @@ export const actionChangeArrowhead = register({ return { elements: changeProperty(elements, appState, (el) => { if (isLinearElement(el)) { - trackEvent( - EVENT_CHANGE, - `arrowhead ${value.position}`, - value.type || "none", - ); - const { position, type } = value; if (position === "start") { diff --git a/src/analytics.ts b/src/analytics.ts index 25586273..30a3887e 100644 --- a/src/analytics.ts +++ b/src/analytics.ts @@ -1,18 +1,7 @@ -export const EVENT_ACTION = "action"; -export const EVENT_ALIGN = "align"; -export const EVENT_CHANGE = "change"; -export const EVENT_DIALOG = "dialog"; -export const EVENT_EXIT = "exit"; -export const EVENT_IO = "io"; -export const EVENT_LAYER = "layer"; -export const EVENT_LIBRARY = "library"; -export const EVENT_LOAD = "load"; -export const EVENT_SHAPE = "shape"; -export const EVENT_SHARE = "share"; -export const EVENT_MAGIC = "magic"; - export const trackEvent = - typeof window !== "undefined" && window.gtag + process.env.REACT_APP_GOOGLE_ANALYTICS_ID && + typeof window !== "undefined" && + window.gtag ? (category: string, name: string, label?: string, value?: number) => { window.gtag("event", name, { event_category: category, @@ -23,5 +12,6 @@ export const trackEvent = : typeof process !== "undefined" && process?.env?.JEST_WORKER_ID ? (category: string, name: string, label?: string, value?: number) => {} : (category: string, name: string, label?: string, value?: number) => { - console.info("Track Event", category, name, label, value); + // Uncomment the next line to track locally + // console.info("Track Event", category, name, label, value); }; diff --git a/src/charts.ts b/src/charts.ts index 48e21d46..3b2bbb38 100644 --- a/src/charts.ts +++ b/src/charts.ts @@ -1,4 +1,4 @@ -import { EVENT_MAGIC, trackEvent } from "./analytics"; +import { trackEvent } from "./analytics"; import colors from "./colors"; import { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, ENV } from "./constants"; import { newElement, newLinearElement, newTextElement } from "./element"; @@ -473,7 +473,7 @@ export const renderSpreadsheet = ( x: number, y: number, ): ChartElements => { - trackEvent(EVENT_MAGIC, "chart", chartType, spreadsheet.values.length); + trackEvent("magic", "chart", chartType, spreadsheet.values.length); if (chartType === "line") { return chartTypeLine(spreadsheet, x, y); } diff --git a/src/components/Actions.tsx b/src/components/Actions.tsx index ad1a0a45..177fd61c 100644 --- a/src/components/Actions.tsx +++ b/src/components/Actions.tsx @@ -1,23 +1,22 @@ import React from "react"; -import { AppState, Zoom } from "../types"; -import { ExcalidrawElement } from "../element/types"; import { ActionManager } from "../actions/manager"; +import { getNonDeletedElements } from "../element"; +import { ExcalidrawElement } from "../element/types"; +import { t } from "../i18n"; +import useIsMobile from "../is-mobile"; import { - hasBackground, - hasStroke, canChangeSharpness, - hasText, canHaveArrowheads, getTargetElements, + hasBackground, + hasStroke, + hasText, } from "../scene"; -import { t } from "../i18n"; import { SHAPES } from "../shapes"; -import { ToolButton } from "./ToolButton"; +import { AppState, Zoom } from "../types"; import { capitalizeString, isTransparent, setCursorForShape } from "../utils"; import Stack from "./Stack"; -import useIsMobile from "../is-mobile"; -import { getNonDeletedElements } from "../element"; -import { trackEvent, EVENT_SHAPE, EVENT_DIALOG } from "../analytics"; +import { ToolButton } from "./ToolButton"; export const SelectedShapeActions = ({ appState, @@ -181,7 +180,6 @@ export const ShapesSwitcher = ({ aria-keyshortcuts={shortcut} data-testid={value} onChange={() => { - trackEvent(EVENT_SHAPE, value, "toolbar"); setAppState({ elementType: value, multiElement: null, @@ -203,9 +201,6 @@ 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 b6132d24..a53fe52d 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -8,12 +8,7 @@ import { createRedoAction, createUndoAction } from "../actions/actionHistory"; import { ActionManager } from "../actions/manager"; import { actions } from "../actions/register"; import { ActionResult } from "../actions/types"; -import { - EVENT_DIALOG, - EVENT_LIBRARY, - EVENT_SHAPE, - trackEvent, -} from "../analytics"; +import { trackEvent } from "../analytics"; import { getDefaultAppState } from "../appState"; import { copyToClipboard, @@ -111,7 +106,7 @@ import { selectGroupsForSelectedElements, } from "../groups"; import { createHistory, SceneHistory } from "../history"; -import { t, getLanguage, setLanguage, languages, defaultLang } from "../i18n"; +import { defaultLang, getLanguage, languages, setLanguage, t } from "../i18n"; import { CODES, getResizeCenterPointKey, @@ -504,7 +499,6 @@ class App extends React.Component { ) ) { await Library.importLibrary(blob); - trackEvent(EVENT_LIBRARY, "import"); this.setState({ isLibraryOpen: true, }); @@ -1134,7 +1128,6 @@ class App extends React.Component { toggleLock = () => { this.setState((prevState) => { - trackEvent(EVENT_SHAPE, "lock", !prevState.elementLocked ? "on" : "off"); return { elementLocked: !prevState.elementLocked, elementType: prevState.elementLocked @@ -1158,7 +1151,7 @@ class App extends React.Component { toggleStats = () => { if (!this.state.showStats) { - trackEvent(EVENT_DIALOG, "stats"); + trackEvent("dialog", "stats"); } this.setState({ showStats: !this.state.showStats, @@ -1270,9 +1263,6 @@ class App extends React.Component { } if (event.code === CODES.NINE) { - if (!this.state.isLibraryOpen) { - trackEvent(EVENT_DIALOG, "library"); - } this.setState({ isLibraryOpen: !this.state.isLibraryOpen }); } @@ -1357,7 +1347,6 @@ class App extends React.Component { ) { const shape = findShapeByKey(event.key); if (shape) { - trackEvent(EVENT_SHAPE, shape, "shortcut"); this.selectShapeTool(shape); } else if (event.key === KEYS.Q) { this.toggleLock(); @@ -1741,7 +1730,6 @@ class App extends React.Component { resetCursor(); if (!event[KEYS.CTRL_OR_CMD]) { - trackEvent(EVENT_SHAPE, "text", "double-click"); this.startTextEditing({ sceneX, sceneY, diff --git a/src/components/BackgroundPickerAndDarkModeToggle.tsx b/src/components/BackgroundPickerAndDarkModeToggle.tsx index e87ff08a..f2eba131 100644 --- a/src/components/BackgroundPickerAndDarkModeToggle.tsx +++ b/src/components/BackgroundPickerAndDarkModeToggle.tsx @@ -1,6 +1,5 @@ import React from "react"; import { ActionManager } from "../actions/manager"; -import { EVENT_CHANGE, trackEvent } from "../analytics"; import { AppState } from "../types"; import { DarkModeToggle } from "./DarkModeToggle"; @@ -19,8 +18,6 @@ export const BackgroundPickerAndDarkModeToggle = ({ { - // TODO: track the theme on the first load too - trackEvent(EVENT_CHANGE, "theme", appearance); setAppState({ appearance }); }} /> diff --git a/src/components/CollabButton.tsx b/src/components/CollabButton.tsx index 297b5639..a046041d 100644 --- a/src/components/CollabButton.tsx +++ b/src/components/CollabButton.tsx @@ -6,7 +6,6 @@ import useIsMobile from "../is-mobile"; import { users } from "./icons"; import "./CollabButton.scss"; -import { EVENT_DIALOG, trackEvent } from "../analytics"; const CollabButton = ({ isCollaborating, @@ -23,10 +22,7 @@ const CollabButton = ({ className={clsx("CollabButton", { "is-collaborating": isCollaborating, })} - onClick={() => { - trackEvent(EVENT_DIALOG, "collaboration"); - onClick(); - }} + onClick={onClick} icon={users} type="button" title={t("buttons.roomDialog")} diff --git a/src/components/ExportDialog.tsx b/src/components/ExportDialog.tsx index 4abae755..2df04aa7 100644 --- a/src/components/ExportDialog.tsx +++ b/src/components/ExportDialog.tsx @@ -1,7 +1,6 @@ import React, { useEffect, useRef, useState } from "react"; import { render, unmountComponentAtNode } from "react-dom"; import { ActionsManagerInterface } from "../actions/types"; -import { EVENT_DIALOG, trackEvent } from "../analytics"; import { probablySupportsClipboardBlob } from "../clipboard"; import { canvasToBlob } from "../data/blob"; import { NonDeletedExcalidrawElement } from "../element/types"; @@ -251,7 +250,6 @@ export const ExportDialog = ({ <> { - trackEvent(EVENT_DIALOG, "export"); setModalIsShown(true); }} icon={exportFile} diff --git a/src/components/GitHubCorner.tsx b/src/components/GitHubCorner.tsx index a61a0b73..e7c2206f 100644 --- a/src/components/GitHubCorner.tsx +++ b/src/components/GitHubCorner.tsx @@ -1,6 +1,5 @@ -import React from "react"; import oc from "open-color"; -import { EVENT_EXIT, trackEvent } from "../analytics"; +import React from "react"; // https://github.com/tholman/github-corners export const GitHubCorner = React.memo( @@ -17,9 +16,6 @@ export const GitHubCorner = React.memo( target="_blank" rel="noopener noreferrer" aria-label="GitHub repository" - onClick={() => { - trackEvent(EVENT_EXIT, "github"); - }} > - { - trackEvent(EVENT_EXIT, "libraries"); - }} - > + {t("labels.libraries")} , @@ -267,7 +251,6 @@ const LibraryMenu = ({ const items = await Library.loadLibrary(); const nextItems = items.filter((_, index) => index !== indexToRemove); Library.saveLibrary(nextItems); - trackEvent(EVENT_LIBRARY, "remove"); setLibraryItems(nextItems); }, []); @@ -276,7 +259,6 @@ const LibraryMenu = ({ const items = await Library.loadLibrary(); const nextItems = [...items, elements]; onAddToLibrary(); - trackEvent(EVENT_LIBRARY, "add"); Library.saveLibrary(nextItems); setLibraryItems(nextItems); }, @@ -328,9 +310,6 @@ const LayerUI = ({ href="https://blog.excalidraw.com/end-to-end-encryption/" target="_blank" rel="noopener noreferrer" - onClick={() => { - trackEvent(EVENT_EXIT, "e2ee shield"); - }} > {shield} @@ -567,7 +546,6 @@ const LayerUI = ({