From be151fd6f7e7860cc60bee67bab815c155e86fcd Mon Sep 17 00:00:00 2001
From: Fuwn <contact@fuwn.net>
Date: Fri, 29 May 2026 23:05:37 +0000
Subject: feat(analytics): track umami events across core actions

Add a guarded track() wrapper (src/lib/analytics.ts) so programmatic
events no-op instead of throwing when umami is absent (localhost),
lazily loaded, or ad-blocked. Instrument the core loop (progress
increment, roulette, list filter, force refresh), the auth funnel
(log in/out, command palette), settings toggles/selects at the wrapper
level, sync/debug/feed actions, and tool/sharing actions.
---
 src/lib/List/Anime/CleanAnimeList.svelte | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

(limited to 'src/lib/List/Anime/CleanAnimeList.svelte')

diff --git a/src/lib/List/Anime/CleanAnimeList.svelte b/src/lib/List/Anime/CleanAnimeList.svelte
index e27378eb..c8bf1b7d 100644
--- a/src/lib/List/Anime/CleanAnimeList.svelte
+++ b/src/lib/List/Anime/CleanAnimeList.svelte
@@ -21,6 +21,7 @@ import stateBin from "$stores/stateBin";
 import localforage from "localforage";
 import MediaRoulette from "../MediaRoulette.svelte";
 import type { Title } from "../mediaTitle";
+import { track } from "$lib/analytics";
 
 export let media: Media[];
 export let title: Title;
@@ -117,6 +118,10 @@ $: if (browser && !dummy && media && previousAnimeList !== media)
 const updateSelectedList = (event: Event) => {
 	const nextSelectedList = (event.currentTarget as HTMLSelectElement).value;
 
+	track("Filter Anime List", {
+		scope: nextSelectedList === "All" ? "all" : "custom",
+	});
+
 	selectedList = nextSelectedList;
 
 	if (!disableFilter && $stateBin[filterKey] !== nextSelectedList)
@@ -213,6 +218,8 @@ onDestroy(() => clearAiringRefreshTimeout());
 const increment = (anime: Media, progress: number) => {
 	if (dummy || pendingUpdate === anime.id) return;
 
+	track("Increment Anime Progress");
+
 	pendingUpdate = anime.id;
 	lastUpdatedMedia = anime.id;
 
@@ -247,6 +254,7 @@ const increment = (anime: Media, progress: number) => {
       class="small-button"
       onclick={() => (showRoulette = true)}
       title={$locale().lists.actions?.pickRandomAnime}
+      data-umami-event="Open Anime Roulette"
     >
       Roulette
     </button>
@@ -255,7 +263,10 @@ const increment = (anime: Media, progress: number) => {
 
 {#if media.length === 0}
   {$locale().lists.empty?.anime}
-  <button onclick={() => (animeLists = cleanCache(user, $identity))}>
+  <button
+    onclick={() => (animeLists = cleanCache(user, $identity))}
+    data-umami-event="Force Refresh Anime"
+  >
     {$locale().lists.actions?.forceRefresh}
   </button>
 {:else if $settings.displayMediaListFilter && !disableFilter && hasDistinguishingList}
-- 
cgit v1.2.3

