import { Injectable , OnDestroy , Inject , PLATFORM_ID } from '@angular/core' ; import { isPlatformServer } from '@angular/common' ; import { Subscription } from 'rxjs' ; import { MindsVideoPlayerComponent } from '../../video-player/player.component' ; import { ScrollService } from '../../../../../services/ux/scroll' ; import { Session } from '../../../../../services/session' ; @ Injectable ( ) export class VideoAutoplayService implements OnDestroy { public muted : boolean = true ; protected scroll$ : Subscription ; protected enabled : boolean = true ; /**
     * This is set when the player manually triggers a playback
     */ protected userPlaying : MindsVideoPlayerComponent ; /**
     * This is the current autoplaying video (only for autoplay on scroll)
     */ protected currentlyPlaying : MindsVideoPlayerComponent ; /**
     * List of registered players for autoplay on scroll
     */ protected players : MindsVideoPlayerComponent [ ] = [ ] ; constructor ( protected scroll , protected session , @ Inject ( PLATFORM_ID ) protected platformId ) { const user = this . session . getLoggedInUser ( ) ; this . setEnabled ( user . plus && ! user . disable_autoplay_videos ) ; this . init ( ) ; } setEnabled ( enabled ) { this . enabled = enabled ; return this ; } param player registerPlayer ( player ) { if ( isPlatformServer ( this . platformId ) ) return ; this . players . push ( player ) ; this . players . sort ( ( a , b ) => { const rect1 = a . elementRef . nativeElement . getBoundingClientRect ( ) ; const rect2 = a . elementRef . nativeElement . getBoundingClientRect ( ) ; return rect1 . top - rect2 . top ; } ) ; return this ; } param player unregisterPlayer ( player ) { const index = this . players . findIndex ( value => value === player ) ; if ( index !== - 1 ) { this . players . splice ( index , 1 ) ; } return this ; } init ( ) { this . scroll$ = this . scroll . listenForView ( ) . subscribe ( ( ) => { this . checkVisibility ( ) ; } ) ; } /**
     * Checks the visibility of all registered players
     */ checkVisibility ( ) { if ( ! this . enabled ) { return ; } const offsetRange = this . scroll . view . clientHeight / 3 ; const clientTop = this . scroll . view . getBoundingClientRect ( ) . top ; const offsetTop = clientTop + this . scroll . view . scrollTop + offsetRange ; const offsetBottom = offsetTop + offsetRange ; let foundSuitablePlayer = false ; for ( const item of this . players ) { const htmlElement = item . elementRef . nativeElement ; if ( ! htmlElement ) { continue ; } if ( foundSuitablePlayer ) { this . stopPlaying ( item ) ; continue ; } const rect = htmlElement . getBoundingClientRect ( ) ; const y1 = rect . top ; const y2 = offsetTop ; if ( y1 + rect . height < y2 || y1 > offsetBottom ) { this . stopPlaying ( item ) ; } else { this . tryAutoplay ( item ) ; foundSuitablePlayer = true ; } } } param player tryAutoplay ( player ) { if ( ! this . userPlaying || ! this . userPlaying . isPlaying ( ) ) { if ( this . currentlyPlaying && this . currentlyPlaying !== player ) { this . currentlyPlaying . stop ( ) ; } if ( player && ! player . isPlaying ( ) ) { this . currentlyPlaying = player ; } } } param player stopPlaying ( player ) { if ( ! this . userPlaying && player ) { } } param player userPlay ( player ) { const user = this . session . getLoggedInUser ( ) ; if ( user . plus && ! user . disable_autoplay_videos ) { this . userPlaying = player ; } } ngOnDestroy ( ) { this . scroll . unListen ( this . scroll$ ) ; } }