import { HostListener , Inject , Injectable , OnDestroy , PLATFORM_ID , RendererFactory2 , } from '@angular/core' ; import { NavigationEnd , Router } from '@angular/router' ; import { Client } from './api/client' ; import { SiteService } from '../common/services/site.service' ; import { isPlatformServer } from '@angular/common' ; import { delay } from 'rxjs/operators' ; import { CookieService } from '../common/services/cookie.service' ; import { Session } from './session' ; import * as snowplow from '@snowplow/browser-tracker' ; import { SelfDescribingJson } from '@snowplow/tracker-core' ; export type SnowplowContext = SelfDescribingJson < Record < string , unknown > > ; @ Injectable ( ) export class AnalyticsService implements OnDestroy { private defaultPrevented : boolean = false ; contexts : SnowplowContext [ ] = [ ] ; unlistenDocumentClickEventListener : ( ) => void ; constructor ( public router , public client , public site , @ Inject ( PLATFORM_ID ) private platformId , private cookieService , private sessionService , private rendererFactory2 ) { this . initSnowplow ( ) ; this . onRouterInit ( ) ; this . router . events . subscribe ( navigationState => { if ( navigationState instanceof NavigationEnd ) { try { this . onRouteChanged ( navigationState . urlAfterRedirects ) ; } catch ( e ) { console . error ( 'Minds: router hook(AnalyticsService)' , e ) ; } } } ) ; this . sessionService . loggedinEmitter ?. subscribe ( isLoggedIn => { if ( isLoggedIn ) { this . initPseudoId ( ) ; } } ) ; /**
         * We need access to the dom to record click events
         */ const renderer = this . rendererFactory2 . createRenderer ( null , null ) ; this . unlistenDocumentClickEventListener = renderer . listen ( 'document' , 'click' , this . onDocumentClick . bind ( this ) ) ; } ngOnDestroy ( ) { if ( this . unlistenDocumentClickEventListener ) this . unlistenDocumentClickEventListener ( ) ; } initSnowplow ( ) { if ( isPlatformServer ( this . platformId ) ) return ; const snowplowUrl = 'https://sp.minds.com' ; snowplow . newTracker ( 'ma' , snowplowUrl , { appId : 'minds' , postPath : '/com.minds/t' , } ) ; snowplow . enableActivityTracking ( { minimumVisitLength : 30 , heartbeatDelay : 10 , } ) ; this . initPseudoId ( ) ; } async send ( type , fields = { } , entityGuid = null ) { if ( isPlatformServer ( this . platformId ) ) return ; if ( type === 'pageview' ) { this . client . post ( 'api/v2/mwa/pv' , fields ) ; snowplow . trackPageView ( { context : this . getContexts ( ) , } ) ; } else { this . client . post ( 'api/v1/analytics' , { type , fields , entityGuid } ) ; } } param event returns onDocumentClick ( event ) { const el = event ?. target as HTMLElement ; const dataRef = el ?. closest ( '[data-ref]' ) ; const dataRefVal = dataRef ?. getAttribute ( 'data-ref' ) ; if ( ! dataRef ) return ; snowplow . trackSelfDescribingEvent ( { event : { schema : 'iglu:com.minds/click_event/jsonschema/1-0-0' , data : { ref : dataRefVal , } , } , context : this . getContexts ( ) , } ) ; } async onRouterInit ( ) { } onRouteChanged ( path ) { if ( ! this . defaultPrevented ) { let url = path ; if ( this . site . isProDomain ) { url = `/pro/${ this . site . pro . user_guid }${ url }` ; } this . send ( 'pageview' , { url , referrer : document . referrer , } ) ; } this . defaultPrevented = false ; } preventDefault ( ) { this . defaultPrevented = true ; } wasDefaultPrevented ( ) { return this . defaultPrevented ; } returns getContexts ( ) { return this . contexts . length > 0 ? this . contexts . slice ( 0 ) : undefined ; } /**
     * Set a psuedonymous id, if one is available
     * This one-way id is created on login and only available to user
     */ initPseudoId ( ) { if ( this . pseudoId ) snowplow . setUserId ( this . pseudoId ) ; } /**
     * Returns a pseudoId from a cookie value
     */ private get pseudoId ( ) : string { return this . cookieService . get ( 'minds_pseudoid' ) ; } }