diff --git a/ui/src/components/DetectionsTable.tsx b/ui/src/components/DetectionsTable.tsx index dbdd5fe8..1e0064ed 100644 --- a/ui/src/components/DetectionsTable.tsx +++ b/ui/src/components/DetectionsTable.tsx @@ -7,7 +7,8 @@ import { TableRow, } from "@mui/material"; -import { Detection, Feed } from "@/graphql/generated"; +import { Candidate, Detection, Feed } from "@/graphql/generated"; +import { analytics } from "@/utils/analytics"; import { formatTimestamp } from "@/utils/time"; import { DetectionsPlayer } from "./Player/DetectionsPlayer"; @@ -15,15 +16,18 @@ import { DetectionsPlayer } from "./Player/DetectionsPlayer"; export default function DetectionsTable({ detections, feed, + candidate }: { detections: Detection[]; feed: Pick; + candidate: Pick; }) { const offsetPadding = 15; const minOffset = Math.min(...detections.map((d) => +d.playerOffset)); const maxOffset = Math.max(...detections.map((d) => +d.playerOffset)); const startOffset = Math.max(0, minOffset - offsetPadding); const endOffset = maxOffset + offsetPadding; + return ( d.playlistTimestamp))} startOffset={startOffset} endOffset={endOffset} + onAudioPlay={() => { + if (candidate.id) { + analytics.reports.reportAudioPlayed(candidate.id); + } + }} /> diff --git a/ui/src/components/Player/DetectionsPlayer.tsx b/ui/src/components/Player/DetectionsPlayer.tsx index af52a66f..1c5c2911 100644 --- a/ui/src/components/Player/DetectionsPlayer.tsx +++ b/ui/src/components/Player/DetectionsPlayer.tsx @@ -22,12 +22,14 @@ export function DetectionsPlayer({ timestamp, startOffset, endOffset, + onAudioPlay }: { feed: Pick; marks: { label: string; value: number }[]; timestamp: number; startOffset: number; endOffset: number; + onAudioPlay?: () => void; }) { const [playerStatus, setPlayerStatus] = useState("idle"); const playerRef = useRef(null); @@ -113,6 +115,7 @@ export function DetectionsPlayer({ player.pause(); } else { player.play(); + onAudioPlay?.(); } } catch (e) { console.error(e); diff --git a/ui/src/pages/reports/[candidateId].tsx b/ui/src/pages/reports/[candidateId].tsx index d99b3199..86e9c317 100644 --- a/ui/src/pages/reports/[candidateId].tsx +++ b/ui/src/pages/reports/[candidateId].tsx @@ -13,6 +13,7 @@ import DetectionsTable from "@/components/DetectionsTable"; import Header from "@/components/Header"; import { useCandidateQuery } from "@/graphql/generated"; import type { NextPageWithLayout } from "@/pages/_app"; +import { analytics } from "@/utils/analytics"; const CandidatePage: NextPageWithLayout = () => { const router = useRouter(); @@ -23,6 +24,10 @@ const CandidatePage: NextPageWithLayout = () => { }); const candidate = candidatesQuery.data?.candidate; + if (candidateId && typeof candidateId === "string") { + analytics.reports.reportOpened(candidateId); + } + return (
Report {candidateId} | Orcasound @@ -62,6 +67,7 @@ const CandidatePage: NextPageWithLayout = () => { )} diff --git a/ui/src/pages/reports/index.tsx b/ui/src/pages/reports/index.tsx index 21b58d1c..1de4fb83 100644 --- a/ui/src/pages/reports/index.tsx +++ b/ui/src/pages/reports/index.tsx @@ -22,6 +22,7 @@ import DetectionsTable from "@/components/DetectionsTable"; import Header from "@/components/Header"; import { CandidatesQuery, useCandidatesQuery } from "@/graphql/generated"; import type { NextPageWithLayout } from "@/pages/_app"; +import { analytics } from "@/utils/analytics"; import { formatTimestamp } from "@/utils/time"; type CandidateQueryCandidates = NonNullable; @@ -73,6 +74,7 @@ const DetectionsPage: NextPageWithLayout = () => { if (candidate) { setSelectedCandidate(candidate); setDetectionModalOpen(true); + analytics.reports.reportOpened(candidateIdParam); } } }, [candidates, candidateIdParam]); @@ -122,6 +124,7 @@ const DetectionsPage: NextPageWithLayout = () => { )} diff --git a/ui/src/utils/analytics.ts b/ui/src/utils/analytics.ts index a6bf65cd..5a72ba00 100644 --- a/ui/src/utils/analytics.ts +++ b/ui/src/utils/analytics.ts @@ -91,10 +91,26 @@ const form = { sendEvent({ category: "Form", action: "Feedback button clicked" }), }; +const reports = { + reportOpened: (candidateId: string) => + sendEvent({ + category: "Reports", + action: "Report opened", + label: candidateId, + }), + reportAudioPlayed: (candidateId: string) => + sendEvent({ + category: "Reports", + action: "Report audio played", + label: candidateId, + }), +}; + export const analytics = { about, detection, stream, nav, form, + reports, };