Created
June 16, 2026 13:56
-
-
Save mininaim/4ccccd37e42313f8fc8da9782bc6c231 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "use client"; | |
| import { useEffect, useRef } from "react"; | |
| import { trackEvent, updateUserMXProfile } from "@/lib/mixpanel/mixpanel"; | |
| export interface VideoPlayedMetadata { | |
| video_type: | |
| | "show" | |
| | "live match" | |
| | "finished match" | |
| | "moments" | |
| | "movie" | |
| | "summary" | |
| | "episode" | |
| | "highlights" | |
| | "goals" | |
| | "analytics_studio"; | |
| event_source: string; | |
| exclusive_video: boolean; | |
| source_title?: string; | |
| session_id: string; | |
| start_minute?: string; | |
| end_minute?: string; | |
| audio_settings?: "balanced" | "commentator" | "stadium"; | |
| video_quality?: string; | |
| commentator_name?: string; | |
| advanced_mode?: "on" | "off"; | |
| video_id: string; | |
| video_title: string; | |
| teams_names?: string; | |
| league_name?: string; | |
| show_name?: string; | |
| live: boolean; | |
| total_video_duration: string; | |
| subtitles?: "off" | "ar" | "en"; | |
| muted: boolean; | |
| duration_watched?: string; | |
| } | |
| interface Props { | |
| isPlaying: boolean; | |
| currentTime: number; | |
| metadata: VideoPlayedMetadata; | |
| } | |
| function formatDuration(totalSeconds: number) { | |
| const minutes = Math.floor(totalSeconds / 60); | |
| const seconds = totalSeconds % 60; | |
| const paddedMinutes = String(minutes).padStart(2, "0"); | |
| const paddedSeconds = String(seconds).padStart(2, "0"); | |
| return `${paddedMinutes}:${paddedSeconds}`; | |
| } | |
| export const VideoPlayedTracker = ({ isPlaying, currentTime, metadata }: Props) => { | |
| const hasTracked = useRef(false); | |
| const playStartTime = useRef<number | null>(null); | |
| const totalPlayedTimeAtStart = useRef(0); | |
| useEffect(() => { | |
| if (hasTracked.current) return; | |
| if (isPlaying) { | |
| if (playStartTime.current === null) { | |
| playStartTime.current = Date.now(); | |
| totalPlayedTimeAtStart.current = currentTime; | |
| } | |
| const elapsedSinceStart = (Date.now() - playStartTime.current) / 1000; | |
| const elapsedInVideo = currentTime - totalPlayedTimeAtStart.current; | |
| const durationWatched = Math.floor(Math.max(elapsedSinceStart, elapsedInVideo)); | |
| if (durationWatched >= 3) { | |
| trackEvent("video_played", { | |
| ...metadata, | |
| duration_watched: formatDuration(durationWatched), | |
| }); | |
| updateUserMXProfile({ | |
| last_content_watched: metadata.video_title, | |
| }); | |
| hasTracked.current = true; | |
| } | |
| } else { | |
| playStartTime.current = null; | |
| } | |
| }, [isPlaying, currentTime, metadata]); | |
| useEffect(() => { | |
| hasTracked.current = false; | |
| playStartTime.current = null; | |
| totalPlayedTimeAtStart.current = 0; | |
| }, [metadata.video_id]); | |
| return null; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment