File

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

Implements

OnInit OnDestroy AfterViewInit

Metadata

Index

Properties
Methods

Constructor

constructor(route: ActivatedRoute, playerService: PlayerService, windowScrollService: WindowScrollService, router: Router, navigationHelperService: NavigationHelperService, toasterService: ToasterService, deviceDetectorService: DeviceDetectorService, resourceService: ResourceService, permissionService: PermissionService, copyContentService: CopyContentService, contentUtilsServiceService: ContentUtilsServiceService, configService: ConfigService, popupControlService: PopupControlService, navigationhelperService: NavigationHelperService, externalUrlPreviewService: ExternalUrlPreviewService, userService: UserService, layoutService: LayoutService, generaliseLabelService: GeneraliseLabelService, publicPlayerService: PublicPlayerService, coursesService: CoursesService, utilService: UtilService, contentManagerService: ContentManagerService, connectionService: ConnectionService, telemetryService: TelemetryService, offlineCardService: OfflineCardService)
Parameters :
Name Type Optional
route ActivatedRoute No
playerService PlayerService No
windowScrollService WindowScrollService No
router Router No
navigationHelperService NavigationHelperService No
toasterService ToasterService No
deviceDetectorService DeviceDetectorService No
resourceService ResourceService No
permissionService PermissionService No
copyContentService CopyContentService No
contentUtilsServiceService ContentUtilsServiceService No
configService ConfigService No
popupControlService PopupControlService No
navigationhelperService NavigationHelperService No
externalUrlPreviewService ExternalUrlPreviewService No
userService UserService No
layoutService LayoutService No
generaliseLabelService GeneraliseLabelService No
publicPlayerService PublicPlayerService No
coursesService CoursesService No
utilService UtilService No
contentManagerService ContentManagerService No
connectionService ConnectionService No
telemetryService TelemetryService No
offlineCardService OfflineCardService No

Methods

callinitPlayer
callinitPlayer(event)
Parameters :
Name Optional
event No
Returns : void
checkDownloadStatus
checkDownloadStatus()
Returns : void
checkStatus
checkStatus(status)
Parameters :
Name Optional
status No
Returns : any
clearSelection
clearSelection()
Returns : void
closeCollectionPlayer
closeCollectionPlayer()
Returns : void
closeContentPlayer
closeContentPlayer()
Returns : void
copyAsCourse
copyAsCourse()
Returns : void
copyContent
copyContent(contentData: ContentData)

This method calls the copy API service

Parameters :
Name Type Optional
contentData ContentData No
Returns : void
createCourse
createCourse()
Returns : void
deleteCollection
deleteCollection(collectionData)
Parameters :
Name Optional
collectionData No
Returns : void
downloadCollection
downloadCollection(collection)
Parameters :
Name Optional
collection No
Returns : void
exportCollection
exportCollection(collection)
Parameters :
Name Optional
collection No
Returns : void
Private findContentById
findContentById(collection: any, id: string)
Parameters :
Name Type Optional
collection any No
id string No
Returns : any
Private getCollectionHierarchy
getCollectionHierarchy(collectionId: string)
Parameters :
Name Type Optional
collectionId string No
Private getContent
getContent()
Returns : void
getContentRollUp
getContentRollUp(rollup: string[])
Parameters :
Name Type Optional
rollup string[] No
Returns : {}
getGeneraliseResourceBundle
getGeneraliseResourceBundle(data)
Parameters :
Name Optional
data No
Returns : void
Private getPlayerConfig
getPlayerConfig(contentId: string)
Parameters :
Name Type Optional
contentId string No
handleSelectAll
handleSelectAll(event)
Parameters :
Name Optional
event No
Returns : void
handleSelectedItem
handleSelectedItem(event)
Parameters :
Name Optional
event No
Returns : void
initLayout
initLayout()
Returns : void
Private initPlayer
initPlayer(id: string)
Parameters :
Name Type Optional
id string No
Returns : void
isYoutubeContentPresent
isYoutubeContentPresent(collection)
Parameters :
Name Optional
collection No
Returns : void
logTelemetry
logTelemetry(id)
Parameters :
Name Optional
id No
Returns : void
Private navigateToContent
navigateToContent(content?: literal type, id?: string)
Parameters :
Name Type Optional
content literal type Yes
id string Yes
Returns : void
ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
Public OnPlayContent
OnPlayContent(content: literal type, isClicked?: boolean)
Parameters :
Name Type Optional
content literal type No
isClicked boolean Yes
Returns : void
onShareLink
onShareLink()
Returns : void
Private parseChildContent
parseChildContent(collection: any)
Parameters :
Name Type Optional
collection any No
Returns : void
Public playContent
playContent(data: any)
Parameters :
Name Type Optional
data any No
Returns : void
printPdf
printPdf(pdfUrl: string)
Parameters :
Name Type Optional
pdfUrl string No
Returns : void
selectAllItem
selectAllItem()
Returns : void
selectedFilter
selectedFilter(event)
Parameters :
Name Optional
event No
Returns : void
Private setContentNavigators
setContentNavigators()
Returns : void
Private setMimeTypeFilters
setMimeTypeFilters()
Returns : void
setTelemetryData
setTelemetryData()
Returns : void
setTelemetryInteractData
setTelemetryInteractData()
Returns : void
setTelemetryShareData
setTelemetryShareData(param)
Parameters :
Name Optional
param No
Returns : void
Private setTelemetryStartEndData
setTelemetryStartEndData()
Returns : void
showChapter
showChapter()
Returns : void
showNoContent
showNoContent(event)
Parameters :
Name Optional
event No
Returns : void
tocCardClickHandler
tocCardClickHandler(event)
Parameters :
Name Optional
event No
Returns : void
tocChapterClickHandler
tocChapterClickHandler(event)
Parameters :
Name Optional
event No
Returns : void
updateCollection
updateCollection(collection)
Parameters :
Name Optional
collection No
Returns : void

Properties

activeContent
Type : any
activeMimeTypeFilter
Type : any
badgeData
Type : Array<object>
cancelInteractEdata
Type : IInteractEventEdata
closeContentIntractEdata
Type : IInteractEventEdata
closeIntractEdata
Type : IInteractEventEdata
collectionData
Type : any
collectionId
Type : string
collectionInteractObject
Type : IInteractEventObject
collectionStatus
Type : string
collectionTitle
Type : string
collectionTreeNodes
Type : any
collectionTreeOptions
Type : ICollectionTreeOptions
Public configService
Type : ConfigService
Public connectionService
Type : ConnectionService
contentData
Type : any
contentDetails
Type : []
Default value : []
contentDownloadStatus
Type : object
Default value : {}
contentId
Type : string
Public contentManagerService
Type : ContentManagerService
contentTitle
Type : string
contentType
Type : string
Public contentUtilsServiceService
Type : ContentUtilsServiceService
copyAsCourseInteractEdata
Type : IInteractEventEdata
copyContentInteractEdata
Type : IInteractEventEdata
Public copyContentService
Type : CopyContentService
Public coursesService
Type : CoursesService
createCourseInteractEdata
Type : IInteractEventEdata
dialCode
Type : string
disableDelete
Type : Boolean
Default value : false
Public externalUrlPreviewService
Type : ExternalUrlPreviewService
Public generaliseLabelService
Type : GeneraliseLabelService
groupId
Type : string
isAvailableLocally
Default value : false
isConnected
Type : Boolean
Default value : true
isContentPresent
Type : Boolean
Default value : false
isCopyAsCourseClicked
Type : Boolean
Default value : false
isDesktopApp
Type : Boolean
Default value : false
isGroupAdmin
Type : boolean
isSelectChapter
Type : Boolean
Default value : false
layoutConfiguration
Type : any
Public layoutService
Type : LayoutService
loaderMessage
Type : ILoaderMessage
Default value : { headerMessage: 'Please wait...', loaderMessage: 'Fetching content details!' }
mimeType
Type : string
mimeTypeFilters
Type : any
Public navigationhelperService
Type : NavigationHelperService
Public navigationHelperService
Type : NavigationHelperService
nextPlaylistItem
Type : any
noContentMessage
Type : string
Default value : ''
objectContentInteract
Type : IInteractEventObject
objectInteract
Type : IInteractEventObject
objectRollUp
Type : any
Public permissionService
Type : PermissionService
PlatformType
Default value : PlatformType
playerConfig
Type : Observable<any>
playerContent
Type : any
playerOption
Type : any
Public playerService
Type : PlayerService
playerServiceReference
Type : any
Public popupControlService
Type : PopupControlService
prevPlaylistItem
Type : any
printPdfInteractEdata
Type : IInteractEventEdata
Public publicPlayerService
Type : PublicPlayerService
queryParams
Type : any
Public route
Type : ActivatedRoute
Public router
Type : Router
selectAll
Type : Boolean
Default value : false
selectedContent
Type : literal type
selectedItems
Type : []
Default value : []
shareLink
Type : string
sharelinkModal
Type : boolean
showCopyLoader
Type : Boolean
Default value : false
showDownloadLoader
Type : Boolean
Default value : false
showExportLoader
Type : Boolean
Default value : false
showLoader
Default value : true
showModal
Type : Boolean
Default value : false
showPlayer
Type : Boolean
Default value : false
showUpdate
Type : Boolean
Default value : false
subscription
Type : Subscription
telemetryCdata
Type : Array<literal type>
telemetryContentImpression
Type : IImpressionEventInput
telemetryCourseEndEvent
Type : IEndEventInput
telemetryCourseStart
Type : IStartEventInput
telemetryImpression
Type : IImpressionEventInput
telemetryShareData
Type : Array<ITelemetryShare>
Public toasterService
Type : ToasterService
TocCardType
Default value : TocCardType
tocList
Type : []
Default value : []
tocTelemetryInteractCdata
tocTelemetryInteractEdata
Type : IInteractEventEdata
treeModel
Type : any
triggerContentImpression
Default value : false
unsubscribe$
Default value : new Subject<void>()
Public userService
Type : UserService
import { mergeMap, filter, map, catchError, takeUntil } from 'rxjs/operators';
import { Component, OnInit, OnDestroy, AfterViewInit } from '@angular/core';
import { PlayerService, CollectionHierarchyAPI, PermissionService, CopyContentService, UserService, GeneraliseLabelService, CoursesService } from '@sunbird/core';
import { Observable, Subscription, Subject } from 'rxjs';
import { ActivatedRoute, Router, NavigationExtras } from '@angular/router';
import * as _ from 'lodash-es';
import {
  WindowScrollService, ILoaderMessage, PlayerConfig, ICollectionTreeOptions, NavigationHelperService,
  ToasterService, ResourceService, ContentData, ContentUtilsServiceService, ITelemetryShare, ConfigService,
  ExternalUrlPreviewService, LayoutService, UtilService, ConnectionService, OfflineCardService,
} from '@sunbird/shared';
import { IInteractEventObject, IInteractEventEdata, IImpressionEventInput, IEndEventInput, IStartEventInput, TelemetryService } from '@sunbird/telemetry';
import TreeModel from 'tree-model';
import { DeviceDetectorService } from 'ngx-device-detector';
import { PopupControlService } from '../../../../service/popup-control.service';
import { PublicPlayerService } from '@sunbird/public';
import { TocCardType, PlatformType } from '@project-sunbird/common-consumption';
import { CsGroupAddableBloc } from '@project-sunbird/client-services/blocs';
import { ContentManagerService } from '../../../public/module/offline/services';

@Component({
  selector: 'app-collection-player',
  templateUrl: './collection-player.component.html',
  styleUrls: ['./collection-player.component.scss']
})
export class CollectionPlayerComponent implements OnInit, OnDestroy, AfterViewInit {
  telemetryImpression: IImpressionEventInput;
  telemetryContentImpression: IImpressionEventInput;
  telemetryCourseEndEvent: IEndEventInput;
  telemetryCourseStart: IStartEventInput;
  telemetryShareData: Array<ITelemetryShare>;
  objectInteract: IInteractEventObject;
  objectContentInteract: IInteractEventObject;
  copyContentInteractEdata: IInteractEventEdata;
  collectionInteractObject: IInteractEventObject;
  closeIntractEdata: IInteractEventEdata;
  printPdfInteractEdata: IInteractEventEdata;
  closeContentIntractEdata: IInteractEventEdata;
  copyAsCourseInteractEdata: IInteractEventEdata;
  cancelInteractEdata: IInteractEventEdata;
  createCourseInteractEdata: IInteractEventEdata;
  tocTelemetryInteractEdata: IInteractEventEdata;
  tocTelemetryInteractCdata;
  showPlayer: Boolean = false;
  collectionId: string;
  collectionStatus: string;
  contentId: string;
  collectionTreeNodes: any;
  layoutConfiguration: any;
  collectionTitle: string;
  contentTitle: string;
  playerConfig: Observable<any>;
  objectRollUp: any;
  triggerContentImpression = false;
  showCopyLoader: Boolean = false;
  subscription: Subscription;
  contentType: string;
  mimeType: string;
  sharelinkModal: boolean;
  badgeData: Array<object>;
  contentData: any;
  dialCode: string;
  collectionData: any;
  collectionTreeOptions: ICollectionTreeOptions;
  shareLink: string;
  playerOption: any;
  treeModel: any;
  contentDetails = [];
  nextPlaylistItem: any;
  prevPlaylistItem: any;
  telemetryCdata: Array<{}>;
  selectedContent: {};
  unsubscribe$ = new Subject<void>();
  mimeTypeFilters: any;
  activeMimeTypeFilter: any;
  isContentPresent: Boolean = false;
  queryParams: any;
  tocList = [];
  playerContent: any;
  activeContent: any;
  isSelectChapter: Boolean = false;
  showLoader = true;
  isCopyAsCourseClicked: Boolean = false;
  selectAll: Boolean = false;
  selectedItems = [];
  loaderMessage: ILoaderMessage = {
    headerMessage: 'Please wait...',
    loaderMessage: 'Fetching content details!'
  };
  playerServiceReference: any;
  TocCardType = TocCardType;
  PlatformType = PlatformType;
  isGroupAdmin: boolean;
  groupId: string;
  isDesktopApp: Boolean = false;
  isConnected: Boolean = true;
  contentDownloadStatus = {};
  showUpdate: Boolean = false;
  showExportLoader: Boolean = false;
  showModal: Boolean = false;
  showDownloadLoader: Boolean = false;
  disableDelete: Boolean = false;
  isAvailableLocally = false;
  noContentMessage = '';

  constructor(public route: ActivatedRoute, public playerService: PlayerService,
    private windowScrollService: WindowScrollService, public router: Router, public navigationHelperService: NavigationHelperService,
    public toasterService: ToasterService, private deviceDetectorService: DeviceDetectorService, private resourceService: ResourceService,
    public permissionService: PermissionService, public copyContentService: CopyContentService,
    public contentUtilsServiceService: ContentUtilsServiceService, public configService: ConfigService,
    public popupControlService: PopupControlService, public navigationhelperService: NavigationHelperService,
    public externalUrlPreviewService: ExternalUrlPreviewService, public userService: UserService,
    public layoutService: LayoutService, public generaliseLabelService: GeneraliseLabelService,
    public publicPlayerService: PublicPlayerService, public coursesService: CoursesService,
    private utilService: UtilService, public contentManagerService: ContentManagerService,
    public connectionService: ConnectionService, private telemetryService: TelemetryService,
    private offlineCardService: OfflineCardService) {
    this.router.onSameUrlNavigation = 'ignore';
    this.collectionTreeOptions = this.configService.appConfig.collectionTreeOptions;
    this.playerOption = { showContentRating: true };
    this.activeMimeTypeFilter = ['all'];
  }

  ngOnInit() {
    this.setMimeTypeFilters();
    this.layoutConfiguration = this.layoutService.initlayoutConfig();
    this.isDesktopApp = this.utilService.isDesktopApp;
    this.noContentMessage = _.get(this.resourceService, 'messages.stmsg.m0121');
    this.playerServiceReference = this.userService.loggedIn ? this.playerService : this.publicPlayerService;
    this.initLayout();

    this.dialCode = _.get(this.route, 'snapshot.queryParams.dialCode');
    this.contentType = _.get(this.route, 'snapshot.queryParams.contentType') || 'Collection';
    this.contentData = this.getContent();
    CsGroupAddableBloc.instance.state$.pipe(takeUntil(this.unsubscribe$)).subscribe(data => {
      this.isGroupAdmin = !_.isEmpty(_.get(this.route.snapshot, 'queryParams.groupId')) && _.get(data.params, 'groupData.isAdmin');
      this.groupId = _.get(data, 'groupId') || _.get(this.route.snapshot, 'queryParams.groupId');
    });

    if (this.isDesktopApp) {
      this.contentManagerService.contentDownloadStatus$.pipe(takeUntil(this.unsubscribe$)).subscribe(contentDownloadStatus => {
        this.contentDownloadStatus = contentDownloadStatus;
        this.checkDownloadStatus();
      });
      this.connectionService.monitor().subscribe(isConnected => {
        this.isConnected = isConnected;
      });
    }
  }

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

  onShareLink() {
    this.shareLink = this.contentUtilsServiceService.getPublicShareUrl(this.collectionId, this.mimeType);
    this.setTelemetryShareData(this.collectionData);
  }

  setTelemetryShareData(param) {
    this.telemetryShareData = [{
      id: param.identifier,
      type: param.contentType,
      ver: param.pkgVersion ? param.pkgVersion.toString() : '1.0'
    }];
  }

  printPdf(pdfUrl: string) {
    window.open(pdfUrl, '_blank');
  }

  ngAfterViewInit() {
    setTimeout(() => {
      const CData: Array<{}> = this.dialCode ? [{ id: this.route.snapshot.params.collectionId, type: this.contentType },
      { id: this.dialCode, type: 'dialCode' }] : [{ id: this.route.snapshot.params.collectionId, type: this.contentType }];
      if (this.groupId) {
        CData.push({ id: this.groupId, type: 'Group' });
      }
      this.telemetryImpression = {
        context: {
          env: this.route.snapshot.data.telemetry.env,
          cdata: CData
        },
        object: {
          id: this.collectionId,
          type: this.contentType,
          ver: '1.0'
        },
        edata: {
          type: this.route.snapshot.data.telemetry.type,
          pageid: this.route.snapshot.data.telemetry.pageid,
          uri: this.router.url,
          subtype: this.route.snapshot.data.telemetry.subtype,
          duration: this.navigationhelperService.getPageLoadTime()
        }
      };
    });
  }

  ngOnDestroy() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }

  private initPlayer(id: string): void {
    this.playerConfig = this.getPlayerConfig(id).pipe(map((content:any) => {

      if(this.activeContent.mimeType === this.configService.appConfig.PLAYER_CONFIG.MIME_TYPE.questionset) {
        const contentDetails = {contentId: id, contentData: content.questionSet };
        content = this.playerServiceReference.getConfig(contentDetails);
        this.publicPlayerService.getQuestionSetRead(id).subscribe((data: any) => {
          content['metadata']['instructions'] = _.get(data, 'result.questionset.instructions');
        });
      }

      const CData: Array<{}> = this.dialCode ? [{ id: this.dialCode, type: 'dialCode' }] : [];
      if (this.groupId) {
        CData.push({ id: this.groupId, type: 'Group' });
      }

      content.context.objectRollup = this.objectRollUp;
      this.telemetryContentImpression = {
        context: {
          env: this.route.snapshot.data.telemetry.env,
          cdata: CData
        },
        edata: {
          type: this.route.snapshot.data.telemetry.env,
          pageid: this.route.snapshot.data.telemetry.env,
          uri: this.router.url
        },
        object: {
          id: content.metadata.identifier,
          type: this.contentType || content.metadata.resourceType || content,
          ver: content.metadata.pkgVersion ? content.metadata.pkgVersion.toString() : '1.0',
          rollup: this.objectRollUp
        }
      };
      this.closeContentIntractEdata = {
        id: 'content-close',
        type: 'click',
        pageid: this.route.snapshot.data.telemetry.pageid
      };
      this.objectContentInteract = {
        id: content.metadata.identifier,
        type: this.contentType || content.metadata.resourceType || 'content',
        ver: content.metadata.pkgVersion ? content.metadata.pkgVersion.toString() : '1.0',
        rollup: this.objectRollUp
      };
      this.triggerContentImpression = true;
      return content;
    }), catchError((error) => {
      console.log(`unable to get player config for content ${id}`, error);
      return error;
    }));
  }

  selectedFilter(event) {
    this.activeMimeTypeFilter = event.data.value;
  }

  showNoContent(event) {
    if (event.message === 'No Content Available') {
      this.isContentPresent = false;
    }
  }

  public playContent(data: any): void {
    this.showPlayer = true;
    this.contentTitle = data.title;
    this.initPlayer(data.id);
  }

  private navigateToContent(content?: { title: string, id: string }, id?: string): void {
    let navigationExtras: NavigationExtras;
    navigationExtras = {
      queryParams: {},
      relativeTo: this.route
    };
    if (id) {
      if (this.queryParams) {
        this.queryParams['contentId'] = id;
      } else {
        this.queryParams = {};
        this.queryParams['contentId'] = id;
      }
      navigationExtras.queryParams = this.queryParams;
    } else
      if (content) {
        navigationExtras.queryParams = { 'contentId': content.id };
      }
    this.router.navigate([], navigationExtras);
  }

  private getPlayerConfig(contentId: string): Observable<PlayerConfig> {

    if(this.activeContent.mimeType === this.configService.appConfig.PLAYER_CONFIG.MIME_TYPE.questionset) {
      return this.publicPlayerService.getQuestionSetHierarchy(contentId);
    } else {
      if (this.dialCode) {
        return this.playerServiceReference.getConfigByContent(contentId, { dialCode: this.dialCode });
      } else {
        return this.playerServiceReference.getConfigByContent(contentId);
      }
    }
  }

  private findContentById(collection: any, id: string) {
    const model = new TreeModel();
    return model.parse(collection.data).first((node) => {
      return node.model.identifier === id;
    });
  }

  private parseChildContent(collection: any) {
    const model = new TreeModel();
    if (collection.data) {
      this.treeModel = model.parse(collection.data);
      this.treeModel.walk((node) => {
        if (node.model.mimeType !== 'application/vnd.ekstep.content-collection') {
          this.contentDetails.push({ id: node.model.identifier, title: node.model.name });
          this.tocList.push({ id: node.model.identifier, title: node.model.name, mimeType: node.model.mimeType });
        }
        this.setContentNavigators();
      });
    }
  }

  private setContentNavigators() {
    const index = _.findIndex(this.contentDetails, ['id', this.contentId]);
    this.prevPlaylistItem = this.contentDetails[index - 1];
    this.nextPlaylistItem = this.contentDetails[index + 1];
  }

  public OnPlayContent(content: { title: string, id: string }, isClicked?: boolean) {
    if (content && content.id) {
      this.navigateToContent(null, content.id);
      this.setContentNavigators();
      this.playContent(content);
      if (!isClicked) {
        const playContentDetails = this.findContentById(this.collectionTreeNodes, content.id);
        if (playContentDetails.model.mimeType === this.configService.appConfig.PLAYER_CONFIG.MIME_TYPE.xUrl) {
          this.externalUrlPreviewService.generateRedirectUrl(playContentDetails.model);
        }
      }
      this.windowScrollService.smoothScroll('app-player-collection-renderer', 10);
    } else {
      throw new Error(`Unable to play collection content for ${this.collectionId}`);
    }
  }

  getGeneraliseResourceBundle(data) {
    this.resourceService.languageSelected$.pipe(takeUntil(this.unsubscribe$)).subscribe(item => {
      this.generaliseLabelService.initialize(data, item.value);
      this.noContentMessage = _.get(this.resourceService, 'messages.stmsg.m0121');
      this.setMimeTypeFilters();
    });
  }

  private getContent(): void {
    this.subscription = this.route.params.pipe(
      filter(params => params.collectionId !== this.collectionId),
      mergeMap((params) => {
        this.showLoader = true;
        this.collectionId = params.collectionId;
        this.telemetryCdata = [{ id: this.collectionId, type: this.contentType }];
        if (this.dialCode) {
          this.telemetryCdata.push({ id: this.dialCode, type: 'dialCode' });
        }
        if (this.groupId) {
          this.telemetryCdata.push({ id: this.groupId, type: 'Group' });
        }
        this.collectionStatus = params.collectionStatus;
        return this.getCollectionHierarchy(params.collectionId);
      }))
      .subscribe((data) => {
        this.collectionTreeNodes = data;
        this.showLoader = false;
        this.isAvailableLocally = Boolean(_.get(data, 'data.desktopAppMetadata.isAvailable'));
        if (this.isDesktopApp && this.isAvailableLocally) {
          this.layoutService.updateSelectedContentType.emit('mydownloads');
        } else {
          this.layoutService.updateSelectedContentType.emit(_.get(data, 'data.contentType'));
        }
        this.getGeneraliseResourceBundle(data.data);
        this.setTelemetryData();
        this.setTelemetryStartEndData();
        this.route.queryParams.subscribe((queryParams) => {
          this.contentId = queryParams.contentId;
          if (this.contentId) {
            const content = this.findContentById(data, this.contentId);
            this.selectedContent = content;
            if (content) {
              this.activeContent = _.get(content, 'model');
              this.objectRollUp = this.contentUtilsServiceService.getContentRollup(content);
              this.OnPlayContent({ title: _.get(content, 'model.name'), id: _.get(content, 'model.identifier') });
            } else {
              this.toasterService.error(this.resourceService.messages.emsg.m0005); // need to change message
            }
          } else {
            this.closeContentPlayer();
          }
        });
        this.parseChildContent(this.collectionTreeNodes);
      }, (error) => {
        this.toasterService.error(this.resourceService.messages.emsg.m0005); // need to change message
      });
  }

  setTelemetryData() {
    this.closeIntractEdata = {
      id: 'collection-close',
      type: 'click',
      pageid: 'collection-player'
    };
    this.printPdfInteractEdata = {
      id: 'print-pdf-button',
      type: 'click',
      pageid: 'collection-player'
    };
    this.copyContentInteractEdata = {
      id: 'copy-content-button',
      type: 'click',
      pageid: 'collection-player'
    };
    this.copyAsCourseInteractEdata = {
      id: 'copy-as-course-button',
      type: 'click',
      pageid: 'collection-player'
    };
    this.cancelInteractEdata = {
      id: 'cancel-button',
      type: 'click',
      pageid: 'collection-player'
    };
    this.createCourseInteractEdata = {
      id: 'create-course-button',
      type: 'click',
      pageid: 'collection-player'
    };
    this.collectionInteractObject = {
      id: this.collectionId,
      type: this.contentType,
      ver: this.collectionData.pkgVersion ? this.collectionData.pkgVersion.toString() : '1.0'
    };
  }

  private getCollectionHierarchy(collectionId: string): Observable<{ data: CollectionHierarchyAPI.Content }> {
    const option: any = { params: {} };
    option.params = this.configService.appConfig.PublicPlayer.contentApiQueryParams;
    if (this.collectionStatus && this.collectionStatus === 'Unlisted') {
      option.params['mode'] = 'edit';
    }
    return this.playerServiceReference.getCollectionHierarchy(collectionId, option).pipe(
      map((response) => {
        this.collectionData = _.get(response, 'result.content');
        this.contentType = _.get(response, 'result.content.contentType');
        this.mimeType = _.get(response, 'result.content.mimeType');
        this.collectionTitle = _.get(response, 'result.content.name') || 'Untitled Collection';
        this.badgeData = _.get(response, 'result.content.badgeAssertions');
        this.showUpdate = _.get(this.collectionData, 'desktopAppMetadata.updateAvailable');
        return { data: _.get(response, 'result.content') };
      }));
  }

  closeCollectionPlayer() {
    if (this.dialCode) {
      this.router.navigate(['/get/dial/', this.dialCode]);
    } else {
      const previousPageUrl = this.navigationHelperService.getPreviousUrl();
      const { url, queryParams: { textbook = null } = {} } = previousPageUrl;
      if (url && ['/explore-course', '/learn'].some(val => url.startsWith(val)) && textbook) {
        const navigateUrl = this.userService.loggedIn ? '/search/Library' : '/explore';
        this.router.navigate([navigateUrl, 1], { queryParams: { key: textbook } });
      } else if (previousPageUrl.queryParams) {
        this.router.navigate([previousPageUrl.url], { queryParams: previousPageUrl.queryParams });
      } else {
        const url = this.userService.loggedIn ? '/resources' : '/explore';
        this.router.navigate([url], { queryParams: { selectedTab: 'textbook' } });
      }
    }
  }

  closeContentPlayer() {
    this.selectedContent = {};
    this.showPlayer = false;
    this.triggerContentImpression = false;
    const contentType = this.isAvailableLocally ? 'mydownloads' : this.contentType;
    const navigationExtras: NavigationExtras = {
      relativeTo: this.route,
      queryParams: { contentType }
    };
    if (this.dialCode) {
      navigationExtras.queryParams['dialCode'] = _.get(this.route, 'snapshot.queryParams.dialCode');
    }
    this.router.navigate([], navigationExtras);
  }

  callinitPlayer(event) {
    if (event.data.identifier !== _.get(this.activeContent, 'identifier')) {
      this.isContentPresent = true;
      this.activeContent = event.data;
      this.objectRollUp = this.getContentRollUp(event.rollup);
      this.initPlayer(_.get(this.activeContent, 'identifier'));
    }
  }

  setTelemetryInteractData() {
    this.tocTelemetryInteractEdata = {
      id: 'library-toc',
      type: 'CLICK',
      pageid: this.route.snapshot.data.telemetry.pageid
    };

    if (this.groupId) {
      this.tocTelemetryInteractEdata.id = 'group-library-toc';
      this.tocTelemetryInteractCdata = [{ id: this.groupId, type: 'Group' }];
    }
  }

  tocCardClickHandler(event) {
    this.setTelemetryInteractData();
    if (event && event.data && event.data.trackable && event.data.trackable.enabled === 'Yes') {
      if (this.userService.loggedIn) {
        const { onGoingBatchCount, expiredBatchCount, openBatch, inviteOnlyBatch } =
          this.coursesService.findEnrolledCourses(event.data.identifier);

        if (!expiredBatchCount && !onGoingBatchCount) { // go to course preview page, if no enrolled batch present
          this.playerService.playContent(event.data, { textbook: this.collectionData.identifier });
        } else if (onGoingBatchCount === 1) { // play course if only one open batch is present
          event.data.batchId = openBatch.ongoing.length ? openBatch.ongoing[0].batchId : inviteOnlyBatch.ongoing[0].batchId;
          this.playerService.playContent(event.data, { textbook: this.collectionData.identifier });
        }

      } else {
        this.publicPlayerService.playContent(event, { textbook: this.collectionData.identifier });
      }
    } else {
      this.callinitPlayer(event);
    }
  }

  tocChapterClickHandler(event) {
    if (this.isSelectChapter) {
      this.isSelectChapter = false;
    }
    this.callinitPlayer(event);
  }

  getContentRollUp(rollup: string[]) {
    const objectRollUp = {};
    if (rollup) {
      for (let i = 0; i < rollup.length; i++) {
        objectRollUp[`l${i + 1}`] = rollup[i];
      }
    }
    return objectRollUp;
  }

  showChapter() {
    this.isSelectChapter = this.isSelectChapter ? false : true;
  }

  /**
   * This method calls the copy API service
   * @param {contentData} ContentData Content data which will be copied
   */
  copyContent(contentData: ContentData) {
    this.showCopyLoader = true;
    this.copyContentService.copyContent(contentData).subscribe(
      (response) => {
        this.toasterService.success(this.resourceService.messages.smsg.m0042);
        this.showCopyLoader = false;
      },
      (err) => {
        this.showCopyLoader = false;
        this.toasterService.error(this.resourceService.messages.emsg.m0008);
      });
  }

  /**
   * @since - #SH-362
   * @description - It will show/hide create course and cancel button also will hide the other action buttons.
   */
  copyAsCourse() {
    this.isCopyAsCourseClicked = !this.isCopyAsCourseClicked;
  }

  /**
   * @since #SH-362
   * @description - This method clears all the intended action and takes the book toc to the default state
   */
  clearSelection() {
    this.isCopyAsCourseClicked = !this.isCopyAsCourseClicked;
    this.selectAll = false;
    this.selectedItems = [];
    this.collectionData['children'].forEach(item => {
      item.selected = false;
    });
  }

  /**
   * @since - SH-362
   * @description - This methods selects/deselects all the textbook units
   */
  selectAllItem() {
    this.selectAll = !this.selectAll;
  }

  private setTelemetryStartEndData() {
    if (this.groupId && !_.find(this.telemetryCdata, { id: this.groupId })) {
      this.telemetryCdata.push({ id: this.groupId, type: 'Group' });
    }
    const deviceInfo = this.deviceDetectorService.getDeviceInfo();
    setTimeout(() => {
      this.telemetryCourseStart = {
        context: {
          env: this.route.snapshot.data.telemetry.env,
          cdata: this.telemetryCdata
        },
        object: {
          id: this.collectionId,
          type: this.contentType,
          ver: '1.0',
        },
        edata: {
          type: this.route.snapshot.data.telemetry.type,
          pageid: this.route.snapshot.data.telemetry.pageid,
          mode: 'play',
          duration: this.navigationhelperService.getPageLoadTime(),
          uaspec: {
            agent: deviceInfo.browser,
            ver: deviceInfo.browser_version,
            system: deviceInfo.os_version,
            platform: deviceInfo.os,
            raw: deviceInfo.userAgent
          }
        }
      };
    }, 100);
    this.telemetryCourseEndEvent = {
      object: {
        id: this.collectionId,
        type: this.contentType,
        ver: '1.0',
      },
      context: {
        env: this.route.snapshot.data.telemetry.env,
        cdata: this.telemetryCdata
      },
      edata: {
        type: this.route.snapshot.data.telemetry.type,
        pageid: this.route.snapshot.data.telemetry.pageid,
        mode: 'play'
      }
    };
  }

  /**
   * @since #SH-362
   * @description - This method handles the creation of course from a textbook (entire or selected units)
   */
  createCourse() {
    let collection = _.assign({}, this.collectionData);
    collection = this.utilService.reduceTreeProps(collection,
      ['mimeType', 'visibility', 'identifier', 'selected', 'name', 'contentType', 'children',
        'primaryCategory', 'additionalCategory', 'parent', 'code', 'framework', 'description']
    );
    this.userService.userOrgDetails$.subscribe(() => {
      this.showCopyLoader = true;
      this.copyContentService.copyAsCourse(collection).subscribe((response) => {
        this.toasterService.success(this.resourceService.messages.smsg.m0042);
        this.showCopyLoader = false;
      }, (err) => {
        this.showCopyLoader = false;
        this.clearSelection();
        this.toasterService.error(this.resourceService.messages.emsg.m0008);
      });
    });
  }

  /**
   * @since #SH-362
   * @param  {} event
   * @description - this method will handle the enable/disable of create course button.
   */
  handleSelectedItem(event) {
    if ('selectAll' in event) {
      this.handleSelectAll(event);
    } else {
      if (_.get(event, 'data.selected') === true) {
        this.selectedItems.push(event.data);
      } else {
        _.remove(this.selectedItems, (item) => {
          return (item === event.data);
        });
      }
    }
  }

  /**
   * @since #SH-362
   * @param  {} event
   * @description - To handle select/deselect all checkbox event particularly
   */
  handleSelectAll(event) {
    if (_.get(event, 'selectAll') === true) {
      event.data.forEach(element => {
        if (this.selectedItems.indexOf(element) === -1) {
          this.selectedItems.push(element);
        }
      });
    } else if (_.get(event, 'selectAll') === false) {
      this.selectedItems = [];
    }
  }

  checkStatus(status) {
    this.checkDownloadStatus();
    return this.utilService.getPlayerDownloadStatus(status, this.collectionData);
  }

  checkDownloadStatus() {
    if (this.collectionData) {
      const downloadStatus = ['CANCELED', 'CANCEL', 'FAILED', 'DOWNLOAD'];
      const status = this.contentDownloadStatus[this.collectionData.identifier];
      this.collectionData['downloadStatus'] = _.isEqual(downloadStatus, status) ? 'DOWNLOAD' :
        (_.includes(['INPROGRESS', 'RESUME', 'INQUEUE'], status) ? 'DOWNLOADING' : _.isEqual(status, 'COMPLETED') ? 'DOWNLOADED' : status);
    }
  }

  updateCollection(collection) {
    collection['downloadStatus'] = this.resourceService.messages.stmsg.m0140;
    this.logTelemetry('update-collection');
    const request = {
      contentId: collection.identifier
    };
    this.contentManagerService.updateContent(request).pipe(takeUntil(this.unsubscribe$)).subscribe(data => {
      collection['downloadStatus'] = this.resourceService.messages.stmsg.m0140;
      this.showUpdate = false;
    }, (err) => {
      this.showUpdate = true;
      const errorMessage = !this.isConnected ? _.replace(this.resourceService.messages.smsg.m0056, '{contentName}', collection.name) :
        this.resourceService.messages.fmsg.m0096;
      this.toasterService.error(errorMessage);
    });
  }

  exportCollection(collection) {
    this.logTelemetry('export-collection');
    this.showExportLoader = true;
    this.contentManagerService.exportContent(collection.identifier)
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe(data => {
        this.showExportLoader = false;
        this.toasterService.success(this.resourceService.messages.smsg.m0059);
      }, error => {
        this.showExportLoader = false;
        if (_.get(error, 'error.responseCode') !== 'NO_DEST_FOLDER') {
          this.toasterService.error(this.resourceService.messages.fmsg.m0091);
        }
      });
  }

  isYoutubeContentPresent(collection) {
    this.logTelemetry('is-youtube-in-collection');
    this.showModal = this.offlineCardService.isYoutubeContent(collection);
    if (!this.showModal) {
      this.downloadCollection(collection);
    }
  }

  downloadCollection(collection) {
    this.showDownloadLoader = true;
    this.disableDelete = false;
    collection['downloadStatus'] = this.resourceService.messages.stmsg.m0140;
    this.logTelemetry('download-collection');
    this.contentManagerService.downloadContentId = collection.identifier;
    this.contentManagerService.downloadContentData = collection;
    this.contentManagerService.failedContentName = collection.name;
    this.contentManagerService.startDownload({}).pipe(takeUntil(this.unsubscribe$)).subscribe(data => {
      this.contentManagerService.downloadContentId = '';
      this.contentManagerService.downloadContentData = {};
      this.showDownloadLoader = false;
      collection['downloadStatus'] = this.resourceService.messages.stmsg.m0140;
    }, error => {
      this.disableDelete = true;
      this.showDownloadLoader = false;
      this.contentManagerService.downloadContentId = '';
      this.contentManagerService.downloadContentData = {};
      this.contentManagerService.failedContentName = '';
      collection['downloadStatus'] = this.resourceService.messages.stmsg.m0138;
      if (!(error.error.params.err === 'LOW_DISK_SPACE')) {
        this.toasterService.error(this.resourceService.messages.fmsg.m0090);
      }
    });
  }

  deleteCollection(collectionData) {
    this.disableDelete = true;
    this.logTelemetry('delete-collection');
    const request = { request: { contents: [collectionData.identifier] } };
    this.contentManagerService.deleteContent(request).pipe(takeUntil(this.unsubscribe$)).subscribe(data => {
      this.toasterService.success(this.resourceService.messages.stmsg.desktop.deleteTextbookSuccessMessage);
      collectionData['downloadStatus'] = 'DOWNLOAD';
      collectionData['desktopAppMetadata.isAvailable'] = false;
      this.closeCollectionPlayer();
    }, err => {
      this.disableDelete = false;
      this.toasterService.error(this.resourceService.messages.etmsg.desktop.deleteTextbookErrorMessage);
    });
  }

  logTelemetry(id) {
    const interactData = {
      context: {
        env: _.get(this.route.snapshot.data.telemetry, 'env') || 'content',
        cdata: [],
      },
      edata: {
        id: id,
        type: 'click',
        pageid: _.get(this.route.snapshot.data.telemetry, 'pageid') || 'play-collection',
      },
      object: {
        id: this.collectionData['identifier'],
        type: this.collectionData['contentType'],
        ver: `${this.collectionData['pkgVersion']}` || '1.0',
      }
    };
    this.telemetryService.interact(interactData);
  }

  private setMimeTypeFilters() {
    this.mimeTypeFilters = [
      { text: _.get(this.resourceService, 'frmelmnts.btn.all', 'All'), value: 'all' },
      { text: _.get(this.resourceService, 'frmelmnts.btn.video', 'Video'), value: 'video' },
      { text: _.get(this.resourceService, 'frmelmnts.btn.interactive', 'Interactive'), value: 'interactive' },
      { text: _.get(this.resourceService, 'frmelmnts.btn.docs', 'Docs'), value: 'docs' }
    ];
  }
}

<app-landing-section [textToDisplay]="" [layoutConfiguration]="layoutConfiguration" [noTitle]="true">
</app-landing-section>
<div *ngIf="collectionData" [style.display]="!showLoader ? 'block' : 'none'"
  [appTelemetryImpression]="telemetryContentImpression">

  <!--CC-Player Back button -->
  <div [ngClass]="layoutConfiguration ? 'sb-back-actionbar' : 'sb-bg-white cc-player__btn-back'"
    class="relative position mt-0">
    <div class="ui container py-0 px-0 d-flex flex-ai-center">
      <button type="button" [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"
        (click)="closeCollectionPlayer()" 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>
      <!--CC-Player Content Header -->
      <div class="content-header flex-basis-1 ml-16 p-0 mb-0" *ngIf="collectionData">
        <div class="content-header__content">
          <div class="d-flex flex-dc flex-basis-1 mr-32 min-w-0 content-header__content__title">
            <div class="content-header__title font-weight-bold ellipsis text-left" role="heading" aria-level="2">
              {{collectionData.name}}</div>
            <div class="content-header__info mt-4" *ngIf="collectionTreeNodes">
              <span *ngIf="collectionTreeNodes?.data?.board">{{collectionTreeNodes?.data?.board}}</span>
              <span class="dot-divider" *ngIf="collectionTreeNodes?.data?.medium"></span>
              <span *ngIf="collectionTreeNodes?.data?.medium">{{collectionTreeNodes?.data?.medium}}</span>
              <span class="dot-divider" *ngIf="collectionTreeNodes?.data?.gradeLevel"></span>
              <span *ngIf="collectionTreeNodes?.data?.gradeLevel">{{collectionTreeNodes?.data?.gradeLevel}}</span>
            </div>
          </div>
          <div class="d-flex flex-ai-end flex-w-wrap content-header__buttons">
            <div *ngIf="isDesktopApp">
              <button type="button" class="sb-btn sb-btn-outline-primary sb-btn-normal mr-8"
                *ngIf="isConnected && (checkStatus('DOWNLOADED')) && showUpdate" tabindex="0"
                (click)="updateCollection(collectionData)">{{resourceService?.frmelmnts?.lbl?.desktop?.updateTextbook}}</button>
              <button type="button" class="sb-btn sb-btn-outline-primary sb-btn-normal mr-8"
                *ngIf="checkStatus('DOWNLOADED')" [disabled]="disableDelete" tabindex="0"
                (click)="logTelemetry('confirm-delete-collection'); showDeleteModal = !showDeleteModal;">{{resourceService?.frmelmnts?.lbl?.desktop?.deleteBook}}</button>
              <button type="button" class="sb-btn sb-btn-outline-primary sb-btn-normal mr-8"
                *ngIf="checkStatus('DOWNLOADED')" tabindex="0"
                (click)="exportCollection(collectionData)">{{resourceService?.frmelmnts?.lbl?.saveToPenDrive}}</button>
              <button type="button" class="sb-btn sb-btn-outline-primary sb-btn-normal mr-8"
                *ngIf="checkStatus('DOWNLOAD')" tabindex="0"
                (click)="isYoutubeContentPresent(collectionData)">{{resourceService?.frmelmnts?.lbl?.desktop?.downloadBook}}</button>
              <button type="button" class="sb-btn sb-btn-outline-primary sb-btn-normal mr-8"
                *ngIf="checkStatus('DOWNLOADING')">{{resourceService?.frmelmnts?.lbl?.downloading}}</button>
              <button type="button" class="sb-btn sb-btn-outline-primary sb-btn-normal mr-8"
                *ngIf="checkStatus('PAUSED')">{{resourceService.frmelmnts?.lbl?.downloadingPaused}}</button>
            </div>

            <button type="button" *ngIf="!isCopyAsCourseClicked" 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}}
            </button>

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

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

            <button type="button" appTelemetryInteract [telemetryInteractObject]="collectionInteractObject"
              [telemetryInteractEdata]="copyAsCourseInteractEdata" href="javascript:void(0)"
              *ngIf="!isDesktopApp && permissionService.permissionAvailable && collectionTreeNodes.data.contentType === 'TextBook' && !isCopyAsCourseClicked"
              appPermission [permission]="['CONTENT_CREATOR']" tabindex="0" (click)="copyAsCourse()"
              class="sb-btn sb-btn-normal sb-btn-outline-primary mr-8">
              <img src="assets/images/copy-clone.svg" alt="copy-clone" class="mr-4 pt-2">
              {{resourceService?.frmelmnts?.lbl?.copyAsCourse}}
            </button>

            <button type="button" appTelemetryInteract [telemetryInteractObject]="collectionInteractObject"
              [telemetryInteractEdata]="cancelInteractEdata" href="javascript:void(0)"
              *ngIf="!isDesktopApp && permissionService.permissionAvailable && collectionTreeNodes.data.contentType === 'TextBook' && isCopyAsCourseClicked"
              appPermission [permission]="['CONTENT_CREATOR']" tabindex="0" (click)="clearSelection()"
              class="sb-btn sb-btn-normal sb-btn-outline-primary mr-8">
              {{resourceService?.frmelmnts?.btn?.cancel}}
            </button>

            <button [ngClass]="{ 'sb-btn-disabled': !(selectedItems.length > 0) }"
              [disabled]="!(selectedItems.length > 0)" type="button" appTelemetryInteract
              [telemetryInteractObject]="collectionInteractObject" [telemetryInteractEdata]="createCourseInteractEdata"
              href="javascript:void(0)"
              *ngIf="!isDesktopApp && permissionService.permissionAvailable && collectionTreeNodes.data.contentType === 'TextBook' && isCopyAsCourseClicked"
              appPermission [permission]="['CONTENT_CREATOR']" tabindex="0" (click)="createCourse()"
              class="sb-btn sb-btn-normal sb-btn-primary">
              {{generaliseLabelService?.frmelmnts?.btn?.create}}
            </button>

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

            <div class="ui active inverted dimmer" *ngIf="!isDesktopApp && showCopyLoader">
              <div class="ui text centered inline loader mt-40">
                {{resourceService.frmelmnts.lbl.copycontent}}
              </div>
            </div>
          </div>
        </div>
      </div>

    </div>
  </div>

  <div [ngClass]="layoutConfiguration ? 'sbt-inside-page-container' : ''" [appTelemetryStart]="telemetryCourseStart"
    [appTelemetryEnd]="telemetryCourseEndEvent">

    <!-- CC-Player Video -->
    <div class="ui container relative9">
      <div class="cc-player sb-g">
        <section [ngClass]="layoutConfiguration ? '' : 'pt-16'"
          class="sb-g-col-xs-12 sb-g-col-md-8 sb-g-col-lg-8 sb-g-col-xxxl-12 cc-player__video sb-toc-player-column"
          [appTelemetryImpression]="telemetryImpression" *ngIf="collectionData">
          <app-contentplayer-page [playerConfig]="playerConfig | async" [tocPage]="true"
            [contentDetails]="activeContent" [collectionData]="collectionData" [isContentPresent]="isContentPresent"
            [objectRollUp]="objectRollUp">
          </app-contentplayer-page>
        </section>
        <section class="sb-g-col-xs-12 sb-g-col-md-4 sb-g-col-lg-4 sb-g-col-xxxl-4 cc-player__list mb-16 relative9"
          *ngIf="collectionData">
          <div class="toc-box-shadow mb-2" *ngIf="isCopyAsCourseClicked">
            <div [ngClass]="layoutConfiguration ? '' : 'sb-bg-color-white'" class="sbselectpopover sbselectpopover--bg-white d-flex flex-ai-center p-16">
              <h6 class="sb-color-primary font-weight-normal">
                {{generaliseLabelService?.frmelmnts?.lbl?.selectContentFromCourse}}</h6>
              <div class="sb-checkbox sb-checkbox-rightaligned sb-checkbox-primary ml-auto m-0">
                <input tabindex="0" (click)="selectAllItem()" type="checkbox" id="checkbox" name="example">
                <label class="mb-0 mr-0 sb-color-primary" for="checkbox">
                  {{resourceService?.frmelmnts?.lbl?.selectAll}}</label>
              </div>
            </div>
          </div>
          <div class="toc-box-shadow mb-2">
            <sb-library-filters [hidden]="isSelectChapter" [tocList]="mimeTypeFilters" [layout]="'round-with-icon'"
              (selectedMimeType)="selectedFilter($event)">
            </sb-library-filters>
          </div>

          <div [hidden]="isSelectChapter" class="main-side-toc-content">
            <sb-toc-item [selectAll]="selectAll" [selectMode]="isCopyAsCourseClicked"
              [activeMimeTypeFilter]="activeMimeTypeFilter" [tocData]="collectionData"
              [noContentMessage]="noContentMessage" (tocCardClick)="tocCardClickHandler($event)"
              [activeContent]="activeContent" (noContent)="showNoContent($event)"
              (selectedItem)="handleSelectedItem($event)" appTelemetryInteract
              [telemetryInteractEdata]="tocTelemetryInteractEdata" [telemetryInteractCdata]="tocTelemetryInteractCdata"
              [platform]="PlatformType.PORTAL" [type]="TocCardType.TRACKABLE"
              [trackableDefaultImage]="'assets/images/mask-image/courses.svg'"></sb-toc-item>
          </div>
          <div [hidden]="!isSelectChapter">
            <span>
              <app-content-chapterlist [activeContent]="activeContent" [contentDetails]="collectionData"
                (tocChapterClick)="tocChapterClickHandler($event)"></app-content-chapterlist>
            </span>
          </div>
          <div>
            <app-content-licence [content]="collectionData"></app-content-licence>
          </div>
        </section>
      </div>
    </div>

    <div class="ui container py-16" *ngIf="showLoader">
      <app-loader [data]='loaderMessage'></app-loader>
    </div>

  </div>
  <div class="ui container py-16" *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 *ngIf="isDesktopApp">

  <app-modal-wrapper *ngIf="showModal" [config]="{disableClose: true, panelClass: 'material-modal'}" (dismiss)="showModal = !showModal;">
    <ng-template sbModalContent>
      <div class="sb-modal">
        <div class="transition ui dimmer page modals active visible">
          <div class="ui modal transition active visible normal">
            <button aria-label="close dialog" mat-dialog-close class="mat-close-btn">
              <span>&times;</span>
            </button>
            <div class="sb-modal-header">
              {{resourceService.frmelmnts?.btn?.download}}
            </div>
            <div class="sb-modal-content">
              <p>{{resourceService?.messages?.stmsg?.m0137}}</p>
            </div>
            <div class="sb-modal-actions">
              <button class="sb-btn sb-btn-normal sb-btn-primary" tabindex="0"
                (click)="downloadCollection(collectionData); showModal = !showModal;">
                {{resourceService.frmelmnts?.btn?.download}}
              </button>
              <button class="sb-btn sb-btn-normal sb-btn-outline-primary" tabindex="0"
                (click)="logTelemetry('cancel-download-collection'); showModal = !showModal;">
                {{resourceService.frmelmnts?.btn?.cancel}}
              </button>
            </div>
          </div>
        </div>
      </div>
    </ng-template>
  </app-modal-wrapper>

  <app-modal-wrapper *ngIf="showDeleteModal" [config]="{disableClose: true, panelClass: 'material-modal'}"
    (dismiss)="showDeleteModal = !showDeleteModal;">
    <ng-template sbModalContent>
      <div class="sb-modal">
        <div class="transition ui dimmer page modals active visible">
          <div class="ui modal transition active visible normal">
            <button aria-label="close dialog" mat-dialog-close class="mat-close-btn">
              <span>&times;</span>
            </button>
            <div class="sb-modal-header">
              {{resourceService?.frmelmnts?.lbl?.delete}}
            </div>
            <div class="sb-modal-content">
              <p>{{resourceService?.frmelmnts?.lbl?.desktop?.deleteCollection | interpolate:'{name}':
                collectionData?.name}}
              </p>
            </div>
            <div class="sb-modal-actions">
              <button class="sb-btn sb-btn-normal sb-btn-primary" tabindex="0"
                (click)="deleteCollection(collectionData); showDeleteModal = !showDeleteModal;">
                {{resourceService?.frmelmnts?.lbl?.delete}}
              </button>
              <button class="sb-btn sb-btn-normal sb-btn-outline-primary" tabindex="0"
                (click)="logTelemetry('cancel-delete-collection'); showDeleteModal = !showDeleteModal;">
                {{resourceService.frmelmnts?.btn?.cancel}}
              </button>
            </div>
          </div>
        </div>
      </div>
    </ng-template>
  </app-modal-wrapper>

  <app-loader *ngIf="showExportLoader"
    [data]="{loaderMessage: resourceService.frmelmnts?.lbl?.exportingContent | interpolate:'{contentName}':collectionData?.name}">
  </app-loader>
  <app-loader *ngIf="showDownloadLoader"
    [data]="{loaderMessage: resourceService.frmelmnts?.lbl?.downloadingContent | interpolate:'{contentName}':collectionData?.name}">
  </app-loader>
</div>

./collection-player.component.scss

@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;
@use 'pages/content-header' as *;


:host {

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

  .main-side-toc-content {
    overflow-y: auto;
    @include respond-below(sm) {
      height: auto;
      max-height: 100%;
    }
  }
}


@media screen and (min-width: 240px) and (max-width: 767px) {
  .toggleInMobile {
    display: none;
  }
}

::ng-deep {
  .sb-toc-items {
    sb-accordion {
      .sbaccordion__panel-content {
        overflow: inherit;
        max-height: 100%;
        border-top: 0px;
        background-color: var(--white);
      }
    }
  }
  .main-side-toc-content{
    sb-toc-item{
      .sb-card-swap{
        flex-direction: unset;
      }
    }
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""