File

src/app/modules/core/services/player/player.service.ts

Description

helper services to fetch content details and preparing content player config

Index

Properties
Methods

Constructor

constructor(userService: UserService, contentService: ContentService, configService: ConfigService, router: Router, navigationHelperService: NavigationHelperService, publicDataService: PublicDataService, utilService: UtilService, activatedRoute: ActivatedRoute)
Parameters :
Name Type Optional
userService UserService No
contentService ContentService No
configService ConfigService No
router Router No
navigationHelperService NavigationHelperService No
publicDataService PublicDataService No
utilService UtilService No
activatedRoute ActivatedRoute No

Methods

Public getCollectionHierarchy
getCollectionHierarchy(identifier: string, option: any)
Parameters :
Name Type Optional Default value
identifier string No
option any No { params: {} }
Returns : Observable<CollectionHierarchyAPI.Get>
getConfig
getConfig(contentDetails: ContentDetails)

returns player config details.

Parameters :
Name Type Optional
contentDetails ContentDetails No
Returns : PlayerConfig
getConfigByContent
getConfigByContent(id: string, option: any)
Parameters :
Name Type Optional Default value
id string No
option any No { params: {} }
getContent
getContent(contentId: string, option: any)

Return content details

Parameters :
Name Type Optional Default value
contentId string No
option any No { params: {} }
Private getRollUpData
getRollUpData(data: Array)
Parameters :
Name Type Optional Default value
data Array<string> No []
Returns : {}
handleNavigation
handleNavigation(content, isTrackable, queryParams?)
Parameters :
Name Optional
content No
isTrackable No
queryParams Yes
Returns : void
playContent
playContent(content, queryParams?)
Parameters :
Name Optional
content No
queryParams Yes
Returns : void
updateContentBodyForReviewer
updateContentBodyForReviewer(data)
Parameters :
Name Optional
data No
Returns : any

Properties

collectionData
Type : ContentData

stores collection/course details

Public configService
Type : ConfigService
contentData
Type : ContentData

stores content details

Public contentService
Type : ContentService
Public navigationHelperService
Type : NavigationHelperService
previewCdnUrl
Type : string
Public publicDataService
Type : PublicDataService
Public router
Type : Router
Public userService
Type : UserService
import { of as observableOf, Observable } from 'rxjs';
import { mergeMap, map } from 'rxjs/operators';
import { ActivatedRoute, Router } from '@angular/router';
import { ContentService } from './../content/content.service';
import { UserService } from './../user/user.service';
import { Injectable } from '@angular/core';
import {
  ConfigService, ServerResponse, UtilService,
  ContentDetails, PlayerConfig, ContentData, NavigationHelperService
} from '@sunbird/shared';
import { CollectionHierarchyAPI } from '../../interfaces';
import * as _ from 'lodash-es';
import { environment } from '@sunbird/environment';
import { PublicDataService } from './../public-data/public-data.service';
/**
 * helper services to fetch content details and preparing content player config
 */
@Injectable({
  providedIn: 'root'
})
export class PlayerService {
  /**
   * stores content details
   */
  contentData: ContentData;
  /**
   * stores collection/course details
   */
  collectionData: ContentData;
  previewCdnUrl: string;
  constructor(public userService: UserService, public contentService: ContentService,
    public configService: ConfigService, public router: Router, public navigationHelperService: NavigationHelperService,
    public publicDataService: PublicDataService, private utilService: UtilService, private activatedRoute: ActivatedRoute) {
      this.previewCdnUrl = (<HTMLInputElement>document.getElementById('previewCdnUrl'))
      ? (<HTMLInputElement>document.getElementById('previewCdnUrl')).value : undefined;
  }

  /**
   *
   *
   * @param {string} id
   * @returns {Observable<{contentId: string, contentData: ContentData }>}
   */
  getConfigByContent(id: string, option: any = { params: {} }): Observable<PlayerConfig> {
    return this.getContent(id, option).pipe(
      mergeMap((content) => {
        const contentDetails: ContentDetails = {
          contentId: content.result.content.identifier,
          contentData: content.result.content
        };
        if (option.courseId) {
          contentDetails.courseId = option.courseId;
        }
        if (option.courseId && option.batchId) {
          contentDetails.batchId = option.batchId;
        }
        return observableOf(this.getConfig(contentDetails));
      }));
  }

  /**
   * Return content details
   * @param {string} contentId
   * @returns {Observable<ServerResponse>}
   */
  getContent(contentId: string, option: any = { params: {} }): Observable<ServerResponse> {
    const licenseParam = {
      licenseDetails: 'name,description,url'
    };
    let param = { fields: this.configService.urlConFig.params.contentGet };
    if (this.userService.isDesktopApp) {
      param.fields = `${param.fields},downloadUrl`;
    }
    param = { ...param, ...option.params, ...licenseParam};
    const req = {
      url: `${this.configService.urlConFig.URLS.CONTENT.GET}/${contentId}`,
      param: { ...param, ...option.params }
    };
    return this.publicDataService.get(req).pipe(map((response: ServerResponse) => {
      this.contentData = response.result.content;
      return response;
    }));
  }
  /**
   * returns player config details.
   * @param {ContentDetails} contentDetails
   * @memberof PlayerService
   */
  getConfig(contentDetails: ContentDetails): PlayerConfig {
    const configuration: any = _.cloneDeep(this.configService.appConfig.PLAYER_CONFIG.playerConfig);
    configuration.context.contentId = contentDetails.contentId;
    configuration.context.sid = this.userService.sessionId;
    configuration.context.uid = this.userService.userid;
    configuration.context.timeDiff = this.userService.getServerTimeDiff;
    configuration.context.contextRollup = this.getRollUpData(_.get(this.userService, 'userProfile.hashTagIds'));
    configuration.context.channel = this.userService.channel;
    const deviceId = (<HTMLInputElement>document.getElementById('deviceId'));
    configuration.context.did = deviceId ? deviceId.value : '';
    const buildNumber = (<HTMLInputElement>document.getElementById('buildNumber'));
    configuration.context.pdata.ver = buildNumber && buildNumber.value ?
    buildNumber.value.slice(0, buildNumber.value.lastIndexOf('.')) : '1.0';
    if (_.isUndefined(contentDetails.courseId)) {
      configuration.context.dims = this.userService.dims;
    } else {
      const cloneDims = _.cloneDeep(this.userService.dims) || [];
      cloneDims.push(contentDetails.courseId);
      if (contentDetails.batchId) {
        cloneDims.push(contentDetails.batchId);
      }
      configuration.context.dims = cloneDims;
    }
    const tags = [];
    _.forEach(_.get(this.userService, 'userProfile.organisations'), (org) => {
      if (org.hashTagId) {
        tags.push(org.hashTagId);
      }
    });
    configuration.context.tags = tags;
    configuration.context.app = [this.userService.channel];
    if (contentDetails.courseId) {
      configuration.context.cdata = [{
        id: contentDetails.courseId,
        type: 'course'
      }];
      if (contentDetails.batchId) {
        configuration.context.cdata.push({ type: 'batch',
        id: contentDetails.batchId} );
      }
    }
    configuration.context.pdata.id = this.userService.appId;
    configuration.metadata = contentDetails.contentData;
    configuration.data = contentDetails.contentData.mimeType !== this.configService.appConfig.PLAYER_CONFIG.MIME_TYPE.ecmlContent ?
      {} : contentDetails.contentData.body;
    configuration.config.enableTelemetryValidation = environment.enableTelemetryValidation; // telemetry validation
    configuration.config.previewCdnUrl = this.previewCdnUrl;
    return configuration;
  }

  /**
   *
   *
   * @private
   * @param {Array<string>} [data=[]]
   * @returns
   * @memberof TelemetryService
   */
  private getRollUpData(data: Array<string> = []) {
    const rollUp = {};
    data.forEach((element, index) => rollUp['l' + (index + 1)] = element);
    return rollUp;
  }

  public getCollectionHierarchy(identifier: string, option: any = { params: {} }): Observable<CollectionHierarchyAPI.Get> {
    const req = {
      url: `${this.configService.urlConFig.URLS.COURSE.HIERARCHY}/${identifier}`,
      param: option.params
    };
    // add the content id to the tag array here
    // window['TagManger'].SBTagService.pushTag(identifier, 'CONTENT_', false);
    return this.publicDataService.get(req).pipe(map((response: ServerResponse) => {
      if (response.result.content) {
        response.result.content = this.utilService.sortChildrenWithIndex(response.result.content);
      }
      this.collectionData = response.result.content;
      return response;
    }));
  }
  updateContentBodyForReviewer(data) {
    // data object is body of the content after JSON.parse()
    let parsedData;
    try {
      parsedData = JSON.parse(data);
    } catch {
      parsedData = null;
    }
    if (!parsedData) {
      return data;
    }
    const questionSetPluginId = 'org.ekstep.questionset';
    const questionPluginId = 'org.ekstep.question';
    // checking content has questionset plugin dependency
    const isQuestionSetPluginExist = parsedData.theme['plugin-manifest']['plugin'].filter((plugin) => {
        return plugin.id !== questionSetPluginId;
    });

    if (isQuestionSetPluginExist) {
        // checking each stage for questionset plugin
        parsedData.theme['stage'].forEach((stage) =>  {
            if (stage[questionSetPluginId]) {
                // checking each questionset plugin inside a stage
                stage[questionSetPluginId].forEach( (questionSetData) => {
                    const questionSetConfigData = JSON.parse(questionSetData.config.__cdata);
                    const actualNumberOfQuestions = questionSetData[questionPluginId].length;
                    // ensuring total items (display items ) always equval to number of questions inside question set
                    questionSetConfigData.total_items = actualNumberOfQuestions;
                    // ensuring shuffle is always off for the reviewer
                    questionSetConfigData.shuffle_questions = false;
                    questionSetData.config.__cdata = JSON.stringify(questionSetConfigData);
                });
            }
        });
    }
    return JSON.stringify(parsedData);
  }

  playContent(content, queryParams?) {
    this.navigationHelperService.storeResourceCloseUrl();
    setTimeout(() => { // setTimeOut is used to trigger telemetry interact event as changeDetectorRef.detectChanges() not working.
      if (content.mimeType === this.configService.appConfig.PLAYER_CONFIG.MIME_TYPE.collection ||
        _.get(content, 'metaData.mimeType') === this.configService.appConfig.PLAYER_CONFIG.MIME_TYPE.collection) {
          if (!content.trackable && content.primaryCategory !== 'Course') {
            this.handleNavigation(content, false, queryParams);
          } else {
            const isTrackable = content.trackable && content.trackable.enabled === 'No' ? false : true;
            this.handleNavigation(content, isTrackable, queryParams);
          }
      } else if (content.mimeType === this.configService.appConfig.PLAYER_CONFIG.MIME_TYPE.ecmlContent) {
        this.router.navigate(['/resources/play/content', content.identifier]);
      } else if (content.mimeType === this.configService.appConfig.PLAYER_CONFIG.MIME_TYPE.questionset) {
        this.router.navigate(['/resources/play/questionset', content.identifier]);
      } else {
        this.router.navigate(['/resources/play/content', content.identifier]);
      }
    }, 0);
  }

  handleNavigation(content, isTrackable, queryParams?) {
    if (!isTrackable) {
      this.router.navigate(['/resources/play/collection', content.courseId || content.identifier],
      {queryParams: {contentType: content.contentType}});
    } else if (content.batchId) {
      this.router.navigate(['/learn/course', content.courseId || content.identifier, 'batch', content.batchId],
        { queryParams });
    } else {
      this.router.navigate(['/learn/course', content.identifier], { queryParams });
    }
  }
}

results matching ""

    No results matching ""