1
0
mirror of https://github.com/XFox111/TabsAsideExtension.git synced 2026-04-22 07:58:01 +03:00

feat: ga4 analytics #117

This commit is contained in:
2025-05-05 19:25:25 +03:00
parent b6be86aac9
commit 5d4a59153a
25 changed files with 135 additions and 11 deletions
+2
View File
@@ -0,0 +1,2 @@
export { default as userPropertiesStorage } from "./utils/userPropertiesStorage";
export { default as trackError } from "./utils/trackError";
+8
View File
@@ -0,0 +1,8 @@
export default function trackError(name: string, error: Error): void
{
analytics.track(name, {
name: error.name,
message: error.message,
stack: error.stack ?? "no_stack"
});
}
@@ -0,0 +1,35 @@
import { cloudDisabled, collectionCount } from "@/features/collectionStorage";
import { settings } from "@/utils/settings";
import { WxtStorageItem } from "wxt/storage";
// @ts-expect-error we don't need to implement a full storage item
const userPropertiesStorage: WxtStorageItem<Record<string, string>, any> =
{
getValue: async (): Promise<UserProperties> =>
{
console.log("userPropertiesStorage.getValue");
const properties: UserProperties =
{
cloud_used: await cloudDisabled.getValue() ? "-1" : (await browser.storage.sync.getBytesInUse() / 102400).toString(),
collection_count: (await collectionCount.getValue()).toString()
};
for (const key of Object.keys(settings))
{
const value = await settings[key as keyof typeof settings].getValue();
properties[`option_${key}`] = value.valueOf().toString();
}
return properties;
},
setValue: async () => { }
};
export default userPropertiesStorage;
export type UserProperties =
{
collection_count: string;
cloud_used: string;
[key: `option_${string}`]: string;
};
@@ -1,3 +1,4 @@
import { trackError } from "@/features/analytics";
import { CollectionItem } from "@/models/CollectionModels";
import getLogger from "@/utils/getLogger";
import { collectionStorage } from "./collectionStorage";
@@ -32,6 +33,7 @@ export default async function getCollections(): Promise<[CollectionItem[], Cloud
{
logger("Failed to get cloud storage");
console.error(ex);
trackError("cloud_get_error", ex as Error);
return [await getCollectionsFromLocal(), "parse_error"];
}
}
@@ -1,3 +1,4 @@
import { trackError } from "@/features/analytics";
import { CollectionItem } from "@/models/CollectionModels";
import getLogger from "@/utils/getLogger";
import { collectionStorage } from "./collectionStorage";
@@ -37,5 +38,6 @@ async function replaceLocalWithCloud(): Promise<void>
{
logger("Failed to get cloud storage");
console.error(ex);
trackError("conflict_resolve_with_cloud_error", ex as Error);
}
}
@@ -1,3 +1,4 @@
import { trackError } from "@/features/analytics";
import { CollectionItem, GraphicsStorage } from "@/models/CollectionModels";
import getLogger from "@/utils/getLogger";
import sendNotification from "@/utils/sendNotification";
@@ -26,6 +27,7 @@ export default async function saveCollections(
{
logger("Failed to save cloud storage");
console.error(ex);
trackError("cloud_save_error", ex as Error);
if ((ex as Error).message.includes("MAX_WRITE_OPERATIONS_PER_MINUTE"))
await sendNotification({
@@ -39,7 +39,10 @@ export default function WelcomeDialog(): React.ReactElement
<fui.DialogActions>
<fui.DialogTrigger disableButtonEnhancement>
<fui.Button appearance="primary" as="a" { ...extLink(v3blogPost) }>
<fui.Button
appearance="primary" as="a" { ...extLink(v3blogPost) }
onClick={ () => analytics.track("visit_blog_button_click") }
>
{ i18n.t("features.v3welcome.actions.visit_blog") }
</fui.Button>
</fui.DialogTrigger>