src/app/modules/shared-feature/components/collection-player/collection-player.component.ts
OnInit
OnDestroy
AfterViewInit
selector | app-collection-player |
styleUrls | ./collection-player.component.scss |
templateUrl | ./collection-player.component.html |
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 :
|
callinitPlayer | ||||
callinitPlayer(event)
|
||||
Parameters :
Returns :
void
|
checkDownloadStatus |
checkDownloadStatus()
|
Returns :
void
|
checkStatus | ||||
checkStatus(status)
|
||||
Parameters :
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 :
Returns :
void
|
createCourse |
createCourse()
|
Returns :
void
|
deleteCollection | ||||
deleteCollection(collectionData)
|
||||
Parameters :
Returns :
void
|
downloadCollection | ||||
downloadCollection(collection)
|
||||
Parameters :
Returns :
void
|
exportCollection | ||||
exportCollection(collection)
|
||||
Parameters :
Returns :
void
|
Private findContentById |
findContentById(collection: any, id: string)
|
Returns :
any
|
Private getCollectionHierarchy | ||||||
getCollectionHierarchy(collectionId: string)
|
||||||
Parameters :
Returns :
Observable<literal type>
|
Private getContent |
getContent()
|
Returns :
void
|
getContentRollUp | ||||||
getContentRollUp(rollup: string[])
|
||||||
Parameters :
Returns :
{}
|
getGeneraliseResourceBundle | ||||
getGeneraliseResourceBundle(data)
|
||||
Parameters :
Returns :
void
|
Private getPlayerConfig | ||||||
getPlayerConfig(contentId: string)
|
||||||
Parameters :
Returns :
Observable<PlayerConfig>
|
handleSelectAll | ||||
handleSelectAll(event)
|
||||
Parameters :
Returns :
void
|
handleSelectedItem | ||||
handleSelectedItem(event)
|
||||
Parameters :
Returns :
void
|
initLayout |
initLayout()
|
Returns :
void
|
Private initPlayer | ||||||
initPlayer(id: string)
|
||||||
Parameters :
Returns :
void
|
isYoutubeContentPresent | ||||
isYoutubeContentPresent(collection)
|
||||
Parameters :
Returns :
void
|
logTelemetry | ||||
logTelemetry(id)
|
||||
Parameters :
Returns :
void
|
Private navigateToContent | |||||||||
navigateToContent(content?: literal type, id?: string)
|
|||||||||
Parameters :
Returns :
void
|
ngAfterViewInit |
ngAfterViewInit()
|
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
Public OnPlayContent | |||||||||
OnPlayContent(content: literal type, isClicked?: boolean)
|
|||||||||
Parameters :
Returns :
void
|
onShareLink |
onShareLink()
|
Returns :
void
|
Private parseChildContent | ||||||
parseChildContent(collection: any)
|
||||||
Parameters :
Returns :
void
|
Public playContent | ||||||
playContent(data: any)
|
||||||
Parameters :
Returns :
void
|
printPdf | ||||||
printPdf(pdfUrl: string)
|
||||||
Parameters :
Returns :
void
|
selectAllItem |
selectAllItem()
|
Returns :
void
|
selectedFilter | ||||
selectedFilter(event)
|
||||
Parameters :
Returns :
void
|
Private setContentNavigators |
setContentNavigators()
|
Returns :
void
|
Private setMimeTypeFilters |
setMimeTypeFilters()
|
Returns :
void
|
setTelemetryData |
setTelemetryData()
|
Returns :
void
|
setTelemetryInteractData |
setTelemetryInteractData()
|
Returns :
void
|
setTelemetryShareData | ||||
setTelemetryShareData(param)
|
||||
Parameters :
Returns :
void
|
Private setTelemetryStartEndData |
setTelemetryStartEndData()
|
Returns :
void
|
showChapter |
showChapter()
|
Returns :
void
|
showNoContent | ||||
showNoContent(event)
|
||||
Parameters :
Returns :
void
|
tocCardClickHandler | ||||
tocCardClickHandler(event)
|
||||
Parameters :
Returns :
void
|
tocChapterClickHandler | ||||
tocChapterClickHandler(event)
|
||||
Parameters :
Returns :
void
|
updateCollection | ||||
updateCollection(collection)
|
||||
Parameters :
Returns :
void
|
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>×</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>×</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;
}
}
}
}