diff --git a/entrypoints/background.ts b/entrypoints/background.ts
index 266321f..be8a02d 100644
--- a/entrypoints/background.ts
+++ b/entrypoints/background.ts
@@ -1,4 +1,4 @@
-import { trackError } from "@/features/analytics";
+import { track, trackError } from "@/features/analytics";
import { collectionCount, getCollections, saveCollections } from "@/features/collectionStorage";
import { migrateStorage } from "@/features/migration";
import { showWelcomeDialog } from "@/features/v3welcome/utils/showWelcomeDialog";
@@ -31,7 +31,7 @@ export default defineBackground(() =>
browser.runtime.onInstalled.addListener(async ({ reason, previousVersion }) =>
{
logger("onInstalled", reason, previousVersion);
- analytics.track("extension_installed", { reason, previousVersion: previousVersion ?? "none" });
+ track("extension_installed", { reason, previousVersion: previousVersion ?? "none" });
const previousMajor: number = previousVersion ? parseInt(previousVersion.split(".")[0]) : 0;
diff --git a/entrypoints/sidepanel/components/EditDialog.tsx b/entrypoints/sidepanel/components/EditDialog.tsx
index ba28478..a863891 100644
--- a/entrypoints/sidepanel/components/EditDialog.tsx
+++ b/entrypoints/sidepanel/components/EditDialog.tsx
@@ -1,4 +1,5 @@
import { getCollectionTitle } from "@/entrypoints/sidepanel/utils/getCollectionTitle";
+import { track } from "@/features/analytics";
import { useGroupColors } from "@/hooks/useGroupColors";
import { CollectionItem, GroupItem } from "@/models/CollectionModels";
import * as fui from "@fluentui/react-components";
@@ -27,9 +28,9 @@ export default function EditDialog(props: GroupEditDialogProps): ReactElement
const handleSave = () =>
{
if (props.type === "collection" ? props.collection !== null : props.group !== null)
- analytics.track("item_edited", { type: props.type });
+ track("item_edited", { type: props.type });
else
- analytics.track("item_created", { type: props.type });
+ track("item_created", { type: props.type });
if (props.type === "collection")
props.onSave({
diff --git a/entrypoints/sidepanel/layouts/collections/CollectionListView.tsx b/entrypoints/sidepanel/layouts/collections/CollectionListView.tsx
index 4471c4c..4b91f47 100644
--- a/entrypoints/sidepanel/layouts/collections/CollectionListView.tsx
+++ b/entrypoints/sidepanel/layouts/collections/CollectionListView.tsx
@@ -5,6 +5,7 @@ import CloudIssueMessages from "@/entrypoints/sidepanel/layouts/collections/mess
import CtaMessage from "@/entrypoints/sidepanel/layouts/collections/messages/CtaMessage";
import filterCollections, { CollectionFilterType } from "@/entrypoints/sidepanel/utils/filterCollections";
import sortCollections from "@/entrypoints/sidepanel/utils/sortCollections";
+import { track } from "@/features/analytics";
import useSettings from "@/hooks/useSettings";
import { CollectionItem } from "@/models/CollectionModels";
import { DndContext, DragEndEvent, DragOverlay, DragStartEvent, MouseSensor, TouchSensor, useSensor, useSensors } from "@dnd-kit/core";
@@ -65,7 +66,7 @@ export default function CollectionListView(): ReactElement
if (sortMode !== "custom")
setSortMode("custom");
- analytics.track("used_drag_and_drop");
+ track("used_drag_and_drop");
}
};
diff --git a/entrypoints/sidepanel/layouts/collections/messages/CtaMessage.tsx b/entrypoints/sidepanel/layouts/collections/messages/CtaMessage.tsx
index 0afb3fd..73afa51 100644
--- a/entrypoints/sidepanel/layouts/collections/messages/CtaMessage.tsx
+++ b/entrypoints/sidepanel/layouts/collections/messages/CtaMessage.tsx
@@ -1,5 +1,6 @@
import { BuyMeACoffee20Regular } from "@/assets/BuyMeACoffee20";
import { buyMeACoffeeLink, storeLink } from "@/data/links";
+import { track } from "@/features/analytics";
import { useBmcStyles } from "@/hooks/useBmcStyles";
import extLink from "@/utils/extLink";
import { Button, Link, MessageBar, MessageBarActions, MessageBarBody, MessageBarProps, MessageBarTitle } from "@fluentui/react-components";
@@ -29,9 +30,9 @@ export default function CtaMessage(props: MessageBarProps): ReactElement
setCounter(counter);
if (counter === -1)
- analytics.track("bmc_clicked");
+ track("bmc_clicked");
else
- analytics.track("cta_dismissed");
+ track("cta_dismissed");
};
if (counter < 50)
@@ -41,7 +42,7 @@ export default function CtaMessage(props: MessageBarProps): ReactElement
} { ...props }>
{ i18n.t("cta_message.title") }
- { i18n.t("cta_message.message") } analytics.track("feedback_clicked") }>{ i18n.t("cta_message.feedback") }
+ { i18n.t("cta_message.message") } track("feedback_clicked") }>{ i18n.t("cta_message.feedback") }
- } { ...extLink(buyMeACoffeeLink) } onClick={ () => analytics.track("feedback_clicked") }>
+ } { ...extLink(buyMeACoffeeLink) } onClick={ () => track("feedback_clicked") }>
{ i18n.t("common.cta.sponsor") }
- } { ...extLink(storeLink) } onClick={ () => analytics.track("bmc_clicked") }>
+ } { ...extLink(storeLink) } onClick={ () => track("bmc_clicked") }>
{ i18n.t("common.cta.feedback") }
} { ...extLink(githubLinks.release) } >
diff --git a/features/analytics/index.ts b/features/analytics/index.ts
index 9bb71e6..301debd 100644
--- a/features/analytics/index.ts
+++ b/features/analytics/index.ts
@@ -1,2 +1,3 @@
export { default as userPropertiesStorage } from "./utils/userPropertiesStorage";
export { default as trackError } from "./utils/trackError";
+export { default as track } from "./utils/track";
diff --git a/features/analytics/utils/track.ts b/features/analytics/utils/track.ts
new file mode 100644
index 0000000..2162843
--- /dev/null
+++ b/features/analytics/utils/track.ts
@@ -0,0 +1,11 @@
+export default function track(eventName: string, eventProperties?: Record): void
+{
+ try
+ {
+ analytics.track(eventName, eventProperties);
+ }
+ catch (ex)
+ {
+ console.error("Failed to send analytics event", ex);
+ }
+}
diff --git a/features/analytics/utils/trackError.ts b/features/analytics/utils/trackError.ts
index 840a291..004378c 100644
--- a/features/analytics/utils/trackError.ts
+++ b/features/analytics/utils/trackError.ts
@@ -1,8 +1,15 @@
export default function trackError(name: string, error: Error): void
{
- analytics.track(name, {
- name: error.name,
- message: error.message,
- stack: error.stack ?? "no_stack"
- });
+ try
+ {
+ analytics.track(name, {
+ name: error.name,
+ message: error.message,
+ stack: error.stack ?? "no_stack"
+ });
+ }
+ catch (ex)
+ {
+ console.error("Failed to send error report", ex);
+ }
}
diff --git a/features/v3welcome/components/WelcomeDialog.tsx b/features/v3welcome/components/WelcomeDialog.tsx
index 3085564..963d1fa 100644
--- a/features/v3welcome/components/WelcomeDialog.tsx
+++ b/features/v3welcome/components/WelcomeDialog.tsx
@@ -1,5 +1,6 @@
import { useTheme } from "@/contexts/ThemeProvider";
import { v3blogPost } from "@/data/links";
+import { track } from "@/features/analytics";
import extLink from "@/utils/extLink";
import * as fui from "@fluentui/react-components";
@@ -41,7 +42,7 @@ export default function WelcomeDialog(): React.ReactElement
analytics.track("visit_blog_button_click") }
+ onClick={ () => track("visit_blog_button_click") }
>
{ i18n.t("features.v3welcome.actions.visit_blog") }
diff --git a/utils/saveTabsToCollection.ts b/utils/saveTabsToCollection.ts
index e155cdd..c92877b 100644
--- a/utils/saveTabsToCollection.ts
+++ b/utils/saveTabsToCollection.ts
@@ -1,7 +1,8 @@
+import { track } from "@/features/analytics";
import { CollectionItem, GroupItem } from "@/models/CollectionModels";
import { Tabs } from "wxt/browser";
-import { settings } from "./settings";
import sendNotification from "./sendNotification";
+import { settings } from "./settings";
export default async function saveTabsToCollection(closeTabs: boolean): Promise
{
@@ -24,7 +25,7 @@ export default async function saveTabsToCollection(closeTabs: boolean): Promise<
if (closeTabs)
await browser.tabs.remove(tabsToClose.map(i => i.id!));
- analytics.track(closeTabs ? "set_aside" : "save");
+ track(closeTabs ? "set_aside" : "save");
return collection;
}