UNPKG

@applicaster/zapp-react-native-utils

Version:

Applicaster Zapp React Native utilities package

237 lines (185 loc) 5.65 kB
import * as R from "ramda"; import { isTrue } from "@applicaster/zapp-react-native-utils/booleanUtils"; import { postAnalyticEvent } from "./manager"; import { isLive } from "../playerUtils"; import { extensionsEvents } from "./AnalyticsEvents/helper"; import { AD_EVENT, EVENT_TYPES, PLAYER_DISPLAY_STATES } from "./events"; import { Player } from "../appUtils/playerManager/player"; export interface PlayerAnalyticsTrackerI { handleAnalyticEvent( event: QuickBrickPlayer.Events, eventData?: QuickBrickPlayer.EventData ): void; setPlayer(player: Player): void; } export class PlayerAnalyticsTracker implements PlayerAnalyticsTrackerI { adTime: number | string; mediaTime: number | string; eventType: string; playerState: QuickBrickPlayer.NativePlayerState; private player: Player; setPlayer(player: Player) { this.player = player; } isAdBreak(event: string): boolean { const adBreakEvents = [ AD_EVENT.ad_break_start, AD_EVENT.ad_break_completed, ]; const isAdBreak = adBreakEvents.find( (adBreakEvent) => adBreakEvent === event ); return !!isAdBreak; } get entry(): ZappEntry { return this.player?.getEntry(); } getDuration( event: QuickBrickPlayer.Events, eventData: QuickBrickPlayer.EventData ) { const isAdBreak = this.isAdBreak(event); const isAd = this.setEventType(event) === "ad"; const adDuration = (isAdBreak || isAd) && eventData?.duration; const entryDuration = this.playerState?.duration || this.entry?.extensions?.duration; return adDuration || entryDuration; } getId(event: QuickBrickPlayer.Events, eventData: QuickBrickPlayer.EventData) { const adId = eventData?.id || this.entry?.id; const excludedEvents = [ AD_EVENT.ad_break_start, AD_EVENT.ad_break_completed, ]; const isAnExcludedEvent = excludedEvents.find( (excludedEvent) => excludedEvent === event ); if (isAnExcludedEvent) { return null; } return adId; } getDateTimestamp() { return Math.floor(Date.now() / 1000); } getCurrentPosition( event: QuickBrickPlayer.Events, eventData: QuickBrickPlayer.EventData, streamType: string ) { const isAdType = this.setEventType(event) === "ad" || this.isAdBreak(event) || this.playerState?.isAd; const isLiveType = streamType === "live"; if (isAdType && eventData) { this.adTime = isLiveType ? this.getDateTimestamp() : eventData?.currentTime; return this.adTime; } if (isLiveType) { return this.getDateTimestamp(); } this.mediaTime = this.playerState?.currentTime || eventData?.currentTime; return this.mediaTime; } getPlayerState() { if (this.playerState?.fullscreen) { return PLAYER_DISPLAY_STATES.fullScreen; } if (this.playerState?.inline) { return PLAYER_DISPLAY_STATES.inline; } if (this.playerState?.docked) { return PLAYER_DISPLAY_STATES.docked; } if (this.playerState?.isModal) { return PLAYER_DISPLAY_STATES.isModal; } } checkEventType( eventToCheck: string, analyticEvents: QuickBrickPlayer.Events ): boolean { const events = Object.values(analyticEvents); const isOfType = events.find((event) => event === eventToCheck); if (isOfType) { return true; } return false; } setEventType(event) { const allEventTypes = Object.keys(EVENT_TYPES); allEventTypes.forEach((eventKey) => { if (this.checkEventType(event, EVENT_TYPES[eventKey])) { this.eventType = eventKey; } }); return this.eventType; } checkIfKeyExists(key, arrayOfKeys) { const keyExists = arrayOfKeys.find((arrayKey) => arrayKey === key); if (keyExists) { return true; } return false; } prepareAnalyticPayload( event: QuickBrickPlayer.Events, eventData: QuickBrickPlayer.EventData ) { this.setEventType(event); const id = this.entry?.id; const mediaDuration = this.getDuration(event, eventData); const mediaType = this.entry?.type?.value; const contentType = this.entry?.content?.type; const isFreeItem = this.entry?.extensions?.free || this.entry?.extensions?.isFree; const title = this.entry?.title; const streamType = isLive(this.entry) ? "live" : "vod"; // Todo: determine other types, channel, podcast, aod const currentPosition = this.getCurrentPosition( event, eventData, streamType ); const nativeData = R.omit( [ "currentTime", "seekTime", "seekableDuration", "isLive", "event", "entry", ], eventData ); const playerState = this.getPlayerState(); const analyticsCustomProperties = extensionsEvents(this.entry?.extensions); const payload = { ...nativeData, media_id: id, name: title, media_type: mediaType, stream_type: streamType, duration: mediaDuration, current_position: currentPosition, player_state: playerState, stream_format: contentType, }; if (isFreeItem !== null) { payload.free_or_paid = isTrue(isFreeItem) ? "free" : "paid"; } if (analyticsCustomProperties) { payload.analyticsCustomProperties = analyticsCustomProperties; } return payload; } handleAnalyticEvent( event: QuickBrickPlayer.Events, eventData: QuickBrickPlayer.EventData = {} ) { this.playerState = this.player?.getState(); postAnalyticEvent(event, this.prepareAnalyticPayload(event, eventData)); } }