File

src/app/modules/shared-feature/components/content-player/content-player.component.ts

Implements

OnInit AfterViewInit OnDestroy ComponentCanDeactivate

Metadata

Index

Properties
Methods
HostListeners

Constructor

constructor(activatedRoute: ActivatedRoute, navigationHelperService: NavigationHelperService, userService: UserService, resourceService: ResourceService, router: Router, toasterService: ToasterService, windowScrollService: WindowScrollService, playerService: PlayerService, publicPlayerService: PublicPlayerService, copyContentService: CopyContentService, permissionService: PermissionService, contentUtilsServiceService: ContentUtilsServiceService, popupControlService: PopupControlService, configService: ConfigService, layoutService: LayoutService, telemetryService: TelemetryService)
Parameters :
Name Type Optional
activatedRoute ActivatedRoute No
navigationHelperService NavigationHelperService No
userService UserService No
resourceService ResourceService No
router Router No
toasterService ToasterService No
windowScrollService WindowScrollService No
playerService PlayerService No
publicPlayerService PublicPlayerService No
copyContentService CopyContentService No
permissionService PermissionService No
contentUtilsServiceService ContentUtilsServiceService No
popupControlService PopupControlService No
configService ConfigService No
layoutService LayoutService No
telemetryService TelemetryService No

HostListeners

window:beforeunload
window:beforeunload()

Methods

canDeactivate
canDeactivate()
Decorators :
@HostListener('window:beforeunload')
Returns : boolean
copyContent
copyContent(contentData: ContentData)
Parameters :
Name Type Optional
contentData ContentData No
Returns : void
getContent
getContent()
Returns : void
getPublicContent
getPublicContent()
Returns : void
getQuestionSetHierarchy
getQuestionSetHierarchy()
Returns : void
goBack
goBack()
Returns : void
initLayout
initLayout()
Returns : void
ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
onShareLink
onShareLink()
Returns : void
setTelemetryData
setTelemetryData()
Returns : void
setTelemetryShareData
setTelemetryShareData(param)
Parameters :
Name Optional
param No
Returns : void

Properties

Public activatedRoute
Type : ActivatedRoute
contentData
Type : ContentData
contentId
Type : string
contentStatus
Type : string
Public contentUtilsServiceService
Type : ContentUtilsServiceService
copyContentInteractEdata
Type : IInteractEventEdata
Public copyContentService
Type : CopyContentService
Public dialCode
Type : string
errorMessage
Type : string
groupId
Type : string
isDesktopApp
Default value : false
isFullScreenView
Default value : false
isGroupAdmin
Type : boolean
isQuestionSet
Default value : false
isTypeCopyQuestionset
Type : boolean
Default value : false
layoutConfiguration
Public layoutService
Type : LayoutService
Public navigationHelperService
Type : NavigationHelperService
objectInteract
Type : IInteractEventObject
Public objectRollup
Type : object
Default value : {}
Public pageLoadDuration
Type : Number
Public permissionService
Type : PermissionService
playerConfig
Type : PlayerConfig
playerOption
Type : any
Public playerService
Type : PlayerService
Public popupControlService
Type : PopupControlService
Public publicPlayerService
Type : PublicPlayerService
Public resourceService
Type : ResourceService
Public router
Type : Router
shareLink
Type : string
sharelinkModal
Type : boolean
showError
Default value : false
showLoader
Default value : true
showPlayer
Default value : false
telemetryImpression
Type : IImpressionEventInput
Public telemetryService
Type : TelemetryService
telemetryShareData
Type : Array<ITelemetryShare>
Public toasterService
Type : ToasterService
Public unsubscribe
Default value : new Subject<void>()
Public unsubscribe$
Default value : new Subject<void>()
Public userService
Type : UserService
Public windowScrollService
Type : WindowScrollService
import { ActivatedRoute } from '@angular/router';
import { Component, OnInit, AfterViewInit, OnDestroy, HostListener } from '@angular/core';
import { Router } from '@angular/router';
import { UserService, PlayerService, CopyContentService, PermissionService } from '@sunbird/core';
import * as _ from 'lodash-es';
import {
  ConfigService, ResourceService, ToasterService, WindowScrollService, NavigationHelperService,
  PlayerConfig, ContentData, ContentUtilsServiceService, ITelemetryShare, LayoutService
} from '@sunbird/shared';
import { IInteractEventObject, IInteractEventEdata, IImpressionEventInput, TelemetryService } from '@sunbird/telemetry';
import { PopupControlService } from '../../../../service/popup-control.service';
import { takeUntil, mergeMap } from 'rxjs/operators';
import { Subject, of, throwError } from 'rxjs';
import { PublicPlayerService, ComponentCanDeactivate } from '@sunbird/public';
import { CsGroupAddableBloc } from '@project-sunbird/client-services/blocs';

@Component({
  selector: 'app-content-player',
  templateUrl: './content-player.component.html',
  styleUrls: ['./content-player.component.scss']
})

export class ContentPlayerComponent implements OnInit, AfterViewInit, OnDestroy, ComponentCanDeactivate {
  telemetryImpression: IImpressionEventInput;
  objectInteract: IInteractEventObject;
  copyContentInteractEdata: IInteractEventEdata;
  sharelinkModal: boolean;
  shareLink: string;
  contentId: string;
  contentStatus: string;
  playerConfig: PlayerConfig;
  showPlayer = false;
  showError = false;
  errorMessage: string;
  contentData: ContentData;
  telemetryShareData: Array<ITelemetryShare>;
  public pageLoadDuration: Number;
  playerOption: any;
  showLoader = true;
  isFullScreenView = false;
  layoutConfiguration;
  public unsubscribe = new Subject<void>();
  public dialCode: string;
  public unsubscribe$ = new Subject<void>();
  public objectRollup = {};
  isGroupAdmin: boolean;
  groupId: string;
  isQuestionSet = false;
  isDesktopApp = false;
  isTypeCopyQuestionset:boolean = false;

  @HostListener('window:beforeunload')
    canDeactivate() {
      // returning true will navigate without confirmation
      // returning false will show a confirm dialog before navigating away
      const deviceType = this.telemetryService.getDeviceType();
      return deviceType === 'Desktop' && this.isQuestionSet && !this.isTypeCopyQuestionset ? false : true;
    }

  constructor(public activatedRoute: ActivatedRoute, public navigationHelperService: NavigationHelperService,
    public userService: UserService, public resourceService: ResourceService, public router: Router,
    public toasterService: ToasterService, public windowScrollService: WindowScrollService,
    public playerService: PlayerService, public publicPlayerService: PublicPlayerService,
    public copyContentService: CopyContentService, public permissionService: PermissionService,
    public contentUtilsServiceService: ContentUtilsServiceService, public popupControlService: PopupControlService,
    private configService: ConfigService,
    public layoutService: LayoutService, public telemetryService: TelemetryService) {
    this.playerOption = {
      showContentRating: true
    };
  }

  ngOnInit() {
    console.log('content');
    this.isQuestionSet = _.includes(this.router.url, 'questionset');
    this.isDesktopApp = this.userService.isDesktopApp;
    this.initLayout();
    this.activatedRoute.params.subscribe((params) => {
      this.showPlayer = false;
      this.contentId = params.contentId;
      this.contentStatus = params.contentStatus;
      this.dialCode = _.get(this.activatedRoute, 'snapshot.queryParams.dialCode');
      if (_.get(this.activatedRoute, 'snapshot.queryParams.l1Parent')) {
        this.objectRollup = {
          l1: _.get(this.activatedRoute, 'snapshot.queryParams.l1Parent')
        };
      }
      CsGroupAddableBloc.instance.state$.pipe(takeUntil(this.unsubscribe$)).subscribe(data => {
        this.groupId = _.get(data, 'groupId') || _.get(this.activatedRoute.snapshot, 'queryParams.groupId');
      });
      this.getContent();
      CsGroupAddableBloc.instance.state$.pipe(takeUntil(this.unsubscribe$)).subscribe(data => {
        this.isGroupAdmin = !_.isEmpty(_.get(this.activatedRoute.snapshot, 'queryParams.groupId'))
        && _.get(data.params, 'groupData.isAdmin');
      });
    });

    this.navigationHelperService.contentFullScreenEvent.
      pipe(takeUntil(this.unsubscribe)).subscribe(isFullScreen => {
        this.isFullScreenView = isFullScreen;
      });
  }

  initLayout() {
    this.layoutConfiguration = this.layoutService.initlayoutConfig();
    this.layoutService.switchableLayout().
      pipe(takeUntil(this.unsubscribe)).subscribe(layoutConfig => {
        if (layoutConfig != null) {
          this.layoutConfiguration = layoutConfig.layout;
        }
      });
  }

  setTelemetryData() {
    this.telemetryImpression = {
      context: {
        env: this.activatedRoute.snapshot.data.telemetry.env,
        cdata: this.groupId ? [{id: this.groupId, type: 'Group'}] : [],
      },
      object: {
        id: this.contentId,
        type: this.contentData.contentType,
        ver: this.contentData.pkgVersion ? this.contentData.pkgVersion.toString() : '1.0'
      },
      edata: {
        type: this.activatedRoute.snapshot.data.telemetry.type,
        pageid: this.activatedRoute.snapshot.data.telemetry.pageid,
        uri: this.router.url,
        subtype: this.activatedRoute.snapshot.data.telemetry.subtype,
        duration: this.pageLoadDuration
      }
    };
    this.objectInteract = {
      id: this.contentId,
      type: this.contentData.contentType,
      ver: this.contentData.pkgVersion ? this.contentData.pkgVersion.toString() : '1.0'
    };
    this.copyContentInteractEdata = {
      id: 'copy-content-button',
      type: 'click',
      pageid: this.activatedRoute.snapshot.data.telemetry.pageid
    };
  }

  goBack() {
    this.navigationHelperService.goBack();
  }

  getContent() {
    if (this.isQuestionSet) {
      this.getQuestionSetHierarchy();
    } else if (this.userService.loggedIn) {
      const option = { params: this.configService.appConfig.ContentPlayer.contentApiQueryParams };
      if (this.contentStatus && this.contentStatus === 'Unlisted') {
        option.params = { mode: 'edit' };
      }
      this.playerService.getContent(this.contentId, option).subscribe(
        (response) => {
          this.showLoader = false;
          if (response.result.content.status === 'Live' || response.result.content.status === 'Unlisted') {
            this.showPlayer = true;
            const contentDetails = {
              contentId: this.contentId,
              contentData: response.result.content
            };
            this.playerConfig = this.playerService.getConfig(contentDetails);
            this.contentData = response.result.content;
            this.setTelemetryData();
            this.windowScrollService.smoothScroll('content-player');
          } else {
            this.toasterService.warning(this.resourceService.messages.imsg.m0027);
          }
        },
        (err) => {
          this.showLoader = false;
          this.showError = true;
          this.errorMessage = this.resourceService.messages.stmsg.m0009;
        });
    } else {
      this.getPublicContent();
    }
  }

  getQuestionSetHierarchy() {
    const serveiceRef =  this.userService.loggedIn ? this.playerService : this.publicPlayerService;
    this.publicPlayerService.getQuestionSetHierarchy(this.contentId).pipe(
      takeUntil(this.unsubscribe$))
      .subscribe((response) => {
        this.showLoader = false;
        const contentDetails = {
          contentId: this.contentId,
          contentData: response.questionSet
        };
        this.playerConfig = serveiceRef.getConfig(contentDetails);
        this.playerConfig.context.objectRollup = this.objectRollup;
        this.contentData = response.questionSet;
        this.showPlayer = true;
      }, (err) => {
        this.showLoader = false;
        this.showError = true;
        this.errorMessage = this.resourceService.messages.stmsg.m0009;
      });
  }

  getPublicContent() {
    const options: any = { dialCode: this.dialCode };
    const params = { params: this.configService.appConfig.PublicPlayer.contentApiQueryParams };
    this.publicPlayerService.getContent(this.contentId, params).pipe(
      mergeMap((response) => {
        if (_.get(response, 'result.content.status') === 'Unlisted') {
          return throwError({
            code: 'UNLISTED_CONTENT'
          });
        }
        return of(response);
      }),
      takeUntil(this.unsubscribe$))
      .subscribe((response) => {
        this.showLoader = false;
        const contentDetails = {
          contentId: this.contentId,
          contentData: response.result.content
        };
        this.playerConfig = this.publicPlayerService.getConfig(contentDetails, options);
        this.playerConfig.context.objectRollup = this.objectRollup;
        this.contentData = response.result.content;
        this.showPlayer = true;
      }, (err) => {
        this.showLoader = false;
        this.showError = true;
        this.errorMessage = this.resourceService.messages.stmsg.m0009;
      });
  }

  copyContent(contentData: ContentData) {
    let successMsg = '';
    let errorMsg = '';
    this.isTypeCopyQuestionset = _.get(contentData, 'mimeType') === 'application/vnd.sunbird.questionset';
    this.isTypeCopyQuestionset ? (successMsg = this.resourceService.messages.smsg.m0067, errorMsg = this.resourceService.messages.emsg.m0067) : (successMsg = this.resourceService.messages.smsg.m0042, errorMsg = this.resourceService.messages.emsg.m0008);
    this.copyContentService.copyContent(contentData).subscribe(
      (response) => {
        this.toasterService.success(successMsg);
      },
      (err) => {
        this.toasterService.error(errorMsg);
      });
  }

  onShareLink() {
    this.shareLink = this.contentUtilsServiceService.getPublicShareUrl(this.contentId, this.contentData.mimeType);
    this.setTelemetryShareData(this.contentData);
  }

  ngAfterViewInit() {
    this.pageLoadDuration = this.navigationHelperService.getPageLoadTime();
  }

  setTelemetryShareData(param) {
    this.telemetryShareData = [{
      id: param.identifier,
      type: param.contentType,
      ver: param.pkgVersion ? param.pkgVersion.toString() : '1.0'
    }];
  }
  ngOnDestroy() {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }
}
<app-landing-section [textToDisplay]="" [layoutConfiguration]="layoutConfiguration" [noTitle]="true">
</app-landing-section>
<!--CC-Player Content Header -->
<div
  [ngClass]="{'sb-back-actionbar' : layoutConfiguration,'sb-bg-white cc-player__btn-back': !layoutConfiguration,'header-block': isFullScreenView}"
  class="relative position mt-0">
  <div class="ui container py-0 px-0 d-flex flex-ai-center">
    <div class="w-100 d-flex flex-ai-center flex-w-wrap flex-jc-space-between" *ngIf="contentData">
      <div class="d-flex flex-ai-center">
        <button type="button" (click)="goBack()"
          [ngClass]="layoutConfiguration ? 'sb-btn-primary sb-btn-round' : 'sb-btn-link sb-btn-link-primary sb-left-icon-btn px-0'"
          class="sb-btn sb-btn-normal" tabindex="0" attr.aria-label="{{resourceService?.frmelmnts?.btn?.back}}">
          <i class="icon-svg icon-svg--xxs icon-back mr-4"><svg class="icon icon-svg--primary">
              <use xlink:href="assets/images/sprite.svg#arrow-long-left"></use>
            </svg></i>
          <span>{{resourceService?.frmelmnts?.btn?.back}}</span>
        </button>
        <div class="textbook__details d-flex ml-16 flex-basis-1 flex-ai-center">
          <div class="textbook__heading">
            <h5 class="sb-color-primary font-weight-bold mb-0 sb__ellipsis" tabindex="0" role="heading" aria-level="2">
              {{contentData.name}}</h5>
            <div class="content-header__info mt-4">
              <span class="fnormal" *ngIf="contentData?.subject">{{contentData?.subject}}</span>
              <span class="dot-divider" *ngIf="contentData.gradeLevel"></span>
              <span class="fnormal" *ngIf="contentData?.gradeLevel">{{contentData?.gradeLevel}}</span>
            </div>
          </div>
        </div>
      </div>
      <div class="d-flex flex-ai-end flex-w-wrap content-header__buttons ml-auto">
        <a href="javascript:void(0)" tabindex="0" (click)="onShareLink();sharelinkModal=true;"
          class="sb-btn sb-btn-normal sb-btn-outline-primary mr-8">
          <i class="blue share alternate icon"></i>
          {{resourceService?.frmelmnts?.lbl?.share}}
        </a>

        <button type="button" *ngIf='!isDesktopApp && permissionService?.permissionAvailable ' appPermission
          [permission]="['CONTENT_CREATOR', 'CONTENT_REVIEWER']" tabindex="0" (click)="copyContent(contentData)"
          appTelemetryInteract [telemetryInteractEdata]="copyContentInteractEdata"
          [telemetryInteractObject]="objectInteract" class="sb-btn sb-btn-normal sb-btn-outline-primary mr-8">
          <i class="blue clone outline icon"></i> {{resourceService?.frmelmnts?.lbl?.copy}}
        </button>


        <div class="certified-course__btn" *ngIf="isGroupAdmin">
          <button class="sb-btn sb-btn-secondary sb-btn-normal ml-auto textbook__addbtn" appAddToGroup
            [identifier]="contentData?.identifier" [pageId]="contentData?.primaryCategory.toLowerCase()">
            {{resourceService?.frmelmnts?.lbl?.AddtoGroup}}</button>
        </div>
      </div>

    </div>
  </div>
</div>

<div [ngClass]="layoutConfiguration ? 'sbt-inside-page-container' : ''">
  <div class="relative9" [ngStyle]="{'height':'fit-content'}" [style.display]="!showLoader ? 'block' : 'none'"
    *ngIf="contentData">
    <!-- CC-Player Video -->
    <div class="sb-single-resource">
      <div class="ui container">
        <div class="cc-player sb-g">
          <section class="sb-g-col-xs-12 sb-g-col-md-12 sb-g-col-lg-12 sb-g-col-xxxl-16 cc-player__video"
            [appTelemetryImpression]="telemetryImpression">
            <app-contentplayer-page [playerConfig]="playerConfig" [tocPage]="true" [contentDetails]="contentData"
              [isContentPresent]="isContentPresent" [objectRollUp]="objectRollup">
            </app-contentplayer-page>
          </section>
        </div>
      </div>
    </div>
    <div class="twelve wide column" *ngIf="showLoader">
      <app-loader [data]='loaderMessage'></app-loader>
    </div>

    <app-modal-wrapper *ngIf="sharelinkModal" [config]="{disableClose: false, panelClass: 'material-modal'}"
      (dismiss)="sharelinkModal = false">
      <ng-template sbModalContent>
        <app-share-link [shareLink]="shareLink" [telemetryShareData]="telemetryShareData">
        </app-share-link>
      </ng-template>
    </app-modal-wrapper>
  </div>
</div>

./content-player.component.scss

@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;
@use 'pages/content-header' as *;
.sb-single-resource {
	width: 100%;
	height: 100%;
	max-width: calculateRem(896px);
	margin: 0 auto;
  @include respond-above(lg) {
    max-width: calculateRem(960px);
  }
  @include respond-above(xl) {
    max-width: calculateRem(1024px);
  }
  @include respond-above(xxxl) {
    max-width: calculateRem(1088px);
  }
  }

.cc-player {
	&__btn-back {
		z-index: 100;
	}
}

.content-header {
  min-height: calculateRem(80px);
  background-color: var(--gray-0);
  box-shadow: 0 0 calculateRem(10px) 0 rgba(var(--rc-rgba-black), 0.25);
  z-index: 99; 
    &__info {
      max-height: calculateRem(48px);
      overflow-y: auto;
    }
}

@include respond-below(sm) {
	.ui.container.sb-toc-view-container {
		margin-left: 0px !important;
		margin-right: 0px !important;
	}
}

.content-player-landscape {
  position: absolute;
}

.header-block {
	display: none !important;
  }
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""