package com.suno.android.common_analytics.hooks import com.suno.android.common_analytics.ElementType import com.suno.android.common_core_utils.Id import com.suno.android.common_data.mappers.hooks.LocalHookData import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlin.time.Duration @Serializable data class HookAnalyticsEvent( @SerialName("actionName") val actionName: String, @SerialName("userId") val userId: String, @SerialName("elementType") val elementType: ElementType, @SerialName("elementId") val elementId: String, @SerialName("context") val context: HookAnalyticsContext, ) /** * Hook playback events defined by the distinct reason preceding the play/pause, for analytic purposes. */ sealed class HookAnalyticsPlaybackEvent( open val hook: LocalHookData, val action: HookAnalyticsAction, ) { // While on/scrolling through Hook feed data class PlayNewHook( override val hook: LocalHookData, val isHookMuted: Boolean, val timeToFirstFrame: Duration?, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.PlayNewHook) data class PauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.PauseHook) data class PlayHook( override val hook: LocalHookData, val playStartMillis: Duration, val isHookMuted: Boolean, val timeToFirstFrame: Duration?, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.PlayHook) data class AutoRepeatPauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.AutoRepeatPauseHook) data class AutoRepeatPlayHook( override val hook: LocalHookData, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.AutoRepeatPlayHook) data class ScrollUpPauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.ScrollUpPauseHook) data class ScrollDownPauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.ScrollDownPauseHook) data class ScrollUpPlayNewHook( override val hook: LocalHookData, val playStartMillis: Duration, val isHookMuted: Boolean, val timeToFirstFrame: Duration?, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.ScrollUpPlayNewHook) data class ScrollDownPlayNewHook( override val hook: LocalHookData, val playStartMillis: Duration, val isHookMuted: Boolean, val timeToFirstFrame: Duration?, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.ScrollDownPlayNewHook) // Transitioning between Hook and Clip data class TapSongPillPauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.TapSongPillPauseHook) data class CloseClipPlayerPlayHook( override val hook: LocalHookData, val playStartMillis: Duration, val previousClipSessionId: Id, val isHookMuted: Boolean, val timeToFirstFrame: Duration?, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.CloseClipPlayerPlayHook) // Transitioning between Hook Feed and non-Hook tabs data class TapTabPlayHook( override val hook: LocalHookData, val playStartMillis: Duration, val isHookMuted: Boolean, val timeToFirstFrame: Duration?, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.TapTabPlayHook) data class TapTabPauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.TapTabPauseHook) // Transitioning between Hook and "Create Song" data class TapCreateSongPauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.TapCreateSongPauseHook) data class CloseCreateSongPlayHook( override val hook: LocalHookData, val playStartMillis: Duration, val isHookMuted: Boolean, val timeToFirstFrame: Duration?, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.CloseCreateSongPlayHook) // Transitioning between Hook and "Create Hook" modal data class TapCreateHookPauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.TapCreateHookPauseHook) data class CloseCreateHookPlayHook( override val hook: LocalHookData, val playStartMillis: Duration, val isHookMuted: Boolean, val timeToFirstFrame: Duration?, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.CloseCreateHookPlayHook) // Transitioning within a Hooks feed and going in and out of the nested navigation data class TapProfilePauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.TapProfilePauseHook) data class TapBackPlayHook( override val hook: LocalHookData, val playStartMillis: Duration, val isHookMuted: Boolean, val timeToFirstFrame: Duration?, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.TapBackPlayHook) data class TapBackPauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.TapBackPauseHook) // When backgrounding and foregrounding the app data class ForegroundAppPlayHook( override val hook: LocalHookData, val playStartMillis: Duration, val isHookMuted: Boolean, val timeToFirstFrame: Duration?, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.ForegroundAppPlayHook) data class BackgroundAppPauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.BackgroundAppPauseHook) // When deeplinking from a link or notification data class OpenDeeplinkPlayNewHook( override val hook: LocalHookData, val isHookMuted: Boolean, val timeToFirstFrame: Duration?, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.OpenDeeplinkPlayNewHook) data class OpenDeeplinkPauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.OpenDeeplinkPauseHook) // When entering or exiting a Remix flow data class CloseCoverPlayHook( override val hook: LocalHookData, val playStartMillis: Duration, val isHookMuted: Boolean, val timeToFirstFrame: Duration?, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.CloseCoverPlayHook) data class TapExtendPauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.TapExtendPauseHook) data class CloseExtendPlayHook( override val hook: LocalHookData, val playStartMillis: Duration, val isHookMuted: Boolean, val timeToFirstFrame: Duration?, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.CloseExtendPlayHook) data class TapCoverPauseHook( override val hook: LocalHookData, val playStartMillis: Duration, val playEndMillis: Duration, val isHookMuted: Boolean, ) : HookAnalyticsPlaybackEvent(hook, HookAnalyticsAction.TapCoverPauseHook) } enum class HookAnalyticsAction( val actionName: String, ) { // While on/scrolling through Hook feed PlayNewHook("PlayNewHook"), PauseHook("PauseHook"), PlayHook("PlayHook"), AutoRepeatPauseHook("AutoRepeatPauseHook"), AutoRepeatPlayHook("AutoRepeatPlayHook"), ScrollUpPauseHook("ScrollUpPauseHook"), ScrollDownPauseHook("ScrollDownPauseHook"), ScrollUpPlayNewHook("ScrollUpPlayNewHook"), ScrollDownPlayNewHook("ScrollDownPlayNewHook"), // Transitioning between Hook and Clip TapSongPillPauseHook("TapSongPillPauseHook"), CloseClipPlayerPlayHook("CloseOmniPlayerStartHook"), // Transitioning between Hook Feed and non-Hook tabs TapTabPlayHook("TapTabPlayHook"), TapTabPauseHook("TapTabPauseHook"), // Transitioning between Hook and "Create Song" TapCreateSongPauseHook("TapCreateSongPauseHook"), CloseCreateSongPlayHook("CloseCreateSongPlayHook"), // Transitioning between Hook and “Create Hook” modal TapCreateHookPauseHook("TapCreateHookPauseHook"), CloseCreateHookPlayHook("CloseCreateHookPlayHook"), // Transitioning within a Hooks feed and going in and out of the nested navigation TapProfilePauseHook("TapProfilePauseHook"), TapBackPlayHook("TapBackPlayHook"), TapBackPauseHook("TapBackPauseHook"), // When backgrounding and foregrounding the app ForegroundAppPlayHook("ForegroundAppPlayHook"), BackgroundAppPauseHook("BackgroundAppPauseHook"), // When deeplinking from a link or notification OpenDeeplinkPlayNewHook("OpenDeeplinkPlayNewHook"), OpenDeeplinkPauseHook("OpenDeeplinkPauseHook"), // When entering or exiting a Remix flow CloseCoverPlayHook("CloseCoverPlayHook"), TapExtendPauseHook("TapExtendPauseHook"), CloseExtendPlayHook("CloseExtendPlayHook"), TapCoverPauseHook("TapCoverPauseHook"), }