@@ -3,6 +3,7 @@ import { log, storage } from '@guardian/libs';
33import { SvgAudio , SvgAudioMute } from '@guardian/source/react-components' ;
44import { useCallback , useEffect , useRef , useState } from 'react' ;
55import {
6+ getOphan ,
67 submitClickComponentEvent ,
78 submitComponentEvent ,
89} from '../client/ophan/ophan' ;
@@ -52,6 +53,13 @@ const logAndReportError = (src: string, error: Error) => {
5253 log ( 'dotcom' , message ) ;
5354} ;
5455
56+ const dispatchOphanAttentionEvent = (
57+ eventType : 'videoPlaying' | 'videoPause' ,
58+ ) => {
59+ const event = new Event ( eventType , { bubbles : true } ) ;
60+ document . dispatchEvent ( event ) ;
61+ } ;
62+
5563type Props = {
5664 src : string ;
5765 atomId : string ;
@@ -103,9 +111,11 @@ export const LoopVideo = ({
103111 */
104112 const [ hasBeenInView , setHasBeenInView ] = useState ( false ) ;
105113
114+ const VISIBILITY_THRESHOLD = 0.5 ;
115+
106116 const [ isInView , setNode ] = useIsInView ( {
107117 repeat : true ,
108- threshold : 0.5 ,
118+ threshold : VISIBILITY_THRESHOLD ,
109119 } ) ;
110120
111121 const playVideo = useCallback ( async ( ) => {
@@ -119,6 +129,7 @@ export const LoopVideo = ({
119129 await startPlayPromise
120130 . then ( ( ) => {
121131 // Autoplay succeeded
132+ dispatchOphanAttentionEvent ( 'videoPlaying' ) ;
122133 setPlayerState ( 'PLAYING' ) ;
123134 } )
124135 . catch ( ( error : Error ) => {
@@ -145,6 +156,7 @@ export const LoopVideo = ({
145156 }
146157
147158 setPlayerState ( reason ) ;
159+ dispatchOphanAttentionEvent ( 'videoPause' ) ;
148160 void vidRef . current . pause ( ) ;
149161 } ;
150162
@@ -239,6 +251,29 @@ export const LoopVideo = ({
239251 } ;
240252 } , [ uniqueId ] ) ;
241253
254+ /**
255+ * Initiates attention tracking for ophan
256+ */
257+ useEffect ( ( ) => {
258+ const video = vidRef . current ;
259+ if ( ! video ) return ;
260+ const trackAttention = async ( ) => {
261+ try {
262+ const ophan = await getOphan ( 'Web' ) ;
263+ ophan . trackComponentAttention (
264+ `gu-video-loop-${ atomId } ` ,
265+ video ,
266+ VISIBILITY_THRESHOLD ,
267+ true ,
268+ ) ;
269+ } catch ( error ) {
270+ console . error ( 'Failed to track video attention:' , error ) ;
271+ }
272+ } ;
273+
274+ void trackAttention ( ) ;
275+ } , [ atomId ] ) ;
276+
242277 /**
243278 * Keeps track of whether the video has been in view or not.
244279 */
0 commit comments