src/app/modules/player-helper/components/content-actions/content-actions.component.ts
OnInit
OnChanges
OnDestroy
selector | app-content-actions |
styleUrls | ./content-actions.component.scss |
templateUrl | ./content-actions.component.html |
Properties |
|
Methods |
Inputs |
Outputs |
constructor(router: Router, activatedRoute: ActivatedRoute, resourceService: ResourceService, toasterService: ToasterService, contentUtilsServiceService: ContentUtilsServiceService, telemetryService: TelemetryService, navigationHelperService: NavigationHelperService, deviceDetectorService: DeviceDetectorService, contentManagerService: ContentManagerService, offlineCardService: OfflineCardService, utilService: UtilService)
|
||||||||||||||||||||||||||||||||||||
Parameters :
|
assessmentEvents | |
Type : any
|
|
contentData | |
Type : any
|
|
isFullScreen | |
Type : boolean
|
|
Default value : false
|
|
objectRollUp | |
Type : literal type
|
|
Default value : {}
|
|
contentDownloaded | |
Type : EventEmitter
|
|
changeContentStatus |
changeContentStatus()
|
Returns :
void
|
contentPrintable |
contentPrintable()
|
Returns :
void
|
deleteContent | ||||
deleteContent(content)
|
||||
Parameters :
Returns :
void
|
downloadContent | ||||
downloadContent(content)
|
||||
Parameters :
Returns :
void
|
enableDisableactionButtons |
enableDisableactionButtons()
|
Returns :
void
|
exportContent | ||||
exportContent(content)
|
||||
Parameters :
Returns :
void
|
isAvailable |
isAvailable()
|
Returns :
any
|
isYoutubeContentPresent | ||||
isYoutubeContentPresent(content)
|
||||
Parameters :
Returns :
void
|
logTelemetry | ||||||
logTelemetry(id, content)
|
||||||
Parameters :
Returns :
void
|
ngOnChanges | ||||||
ngOnChanges(changes: SimpleChanges)
|
||||||
Parameters :
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
onActionButtonClick | ||||||
onActionButtonClick(event, content)
|
||||||
Parameters :
Returns :
void
|
printPdf | ||||||
printPdf(content: any)
|
||||||
Parameters :
Returns :
void
|
setTelemetryShareData | ||||
setTelemetryShareData(param)
|
||||
Parameters :
Returns :
void
|
shareContent | ||||
shareContent(content)
|
||||
Parameters :
Returns :
void
|
updateContent | ||||
updateContent(content)
|
||||
Parameters :
Returns :
void
|
actionButtons |
Default value : actionButtons
|
Public activatedRoute |
Type : ActivatedRoute
|
collectionId |
contentDownloadStatus |
Type : object
|
Default value : {}
|
contentId |
Public contentManagerService |
Type : ContentManagerService
|
contentRatingModal |
Default value : false
|
Public contentUtilsServiceService |
Type : ContentUtilsServiceService
|
deleteContentIds |
Type : []
|
Default value : []
|
fullScreenActionButtons |
Default value : fullScreenActionButtons
|
Public isConnected |
isDesktopApp |
mimeType |
Type : string
|
Public offlineCardService |
Type : OfflineCardService
|
Public resourceService |
Type : ResourceService
|
Public router |
Type : Router
|
shareLink |
Type : string
|
sharelinkModal |
Default value : false
|
showDeleteModal |
Default value : false
|
showDownloadLoader |
Default value : false
|
showExportLoader |
Default value : false
|
showModal |
Default value : false
|
subscription |
telemetryEventSubscription$ |
Type : EventEmitter<object>
|
telemetryShareData |
Type : Array<ITelemetryShare>
|
Public toasterService |
Type : ToasterService
|
Public unsubscribe$ |
Default value : new Subject<void>()
|
Public utilService |
Type : UtilService
|
import { TelemetryService } from '@sunbird/telemetry';
import { actionButtons } from './actionButtons';
import { fullScreenActionButtons } from './actionButtons';
import { Router, ActivatedRoute } from '@angular/router';
import { ResourceService, ToasterService, ContentUtilsServiceService, ITelemetryShare, NavigationHelperService, OfflineCardService,
UtilService } from '@sunbird/shared';
import { Component, OnInit, Input, Output, EventEmitter, OnChanges, SimpleChanges, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';
import * as _ from 'lodash-es';
import { DeviceDetectorService } from 'ngx-device-detector';
import { ContentManagerService } from '../../../public/module/offline/services';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-content-actions',
templateUrl: './content-actions.component.html',
styleUrls: ['./content-actions.component.scss']
})
export class ContentActionsComponent implements OnInit, OnChanges, OnDestroy {
@Input() contentData;
@Input() isFullScreen = false;
@Output() contentDownloaded = new EventEmitter();
@Input() assessmentEvents;
actionButtons = actionButtons;
fullScreenActionButtons = fullScreenActionButtons;
contentRatingModal = false;
contentId;
collectionId;
showExportLoader = false;
showModal = false;
showDeleteModal = false;
public isConnected;
public unsubscribe$ = new Subject<void>();
telemetryShareData: Array<ITelemetryShare>;
@Input() objectRollUp: {} = {};
contentDownloadStatus = {};
showDownloadLoader = false;
deleteContentIds = [];
sharelinkModal = false;
shareLink: string;
mimeType: string;
subscription;
isDesktopApp;
telemetryEventSubscription$: EventEmitter<object>;
constructor(
public router: Router,
public activatedRoute: ActivatedRoute,
public resourceService: ResourceService,
public toasterService: ToasterService,
public contentUtilsServiceService: ContentUtilsServiceService,
private telemetryService: TelemetryService,
private navigationHelperService: NavigationHelperService,
private deviceDetectorService: DeviceDetectorService,
public contentManagerService: ContentManagerService,
public offlineCardService: OfflineCardService,
public utilService: UtilService,
) { }
ngOnInit() {
this.enableDisableactionButtons();
this.isDesktopApp = this.utilService.isDesktopApp;
const isVideoMimetype = _.includes(['video/mp4', 'video/webm'], _.get(this.contentData, 'mimeType'));
this.activatedRoute.params.subscribe((params) => {
this.collectionId = params.collectionId;
});
this.actionButtons = _.cloneDeep(actionButtons);
this.fullScreenActionButtons = _.cloneDeep(fullScreenActionButtons);
_.find(this.actionButtons, (button) => {
button.disabled = (button.label === 'Fullscreen') ? (isVideoMimetype || this.deviceDetectorService.isMobile() ||
this.deviceDetectorService.isTablet()) : button.disabled;
});
this.collectionId = _.get(this.activatedRoute, 'snapshot.params.collectionId');
this.mimeType = _.get(this.contentData, 'mimeType');
this.contentPrintable();
this.subscription = this.contentUtilsServiceService.contentShareEvent.subscribe((data) => {
if (data === 'open') {
this.shareContent(this.contentData);
}
});
if (this.isDesktopApp) {
this.contentManagerService.contentDownloadStatus$.pipe(takeUntil(this.unsubscribe$)).subscribe( contentDownloadStatus => {
this.contentDownloadStatus = contentDownloadStatus;
this.changeContentStatus();
});
}
}
enableDisableactionButtons() {
if (!this.isFullScreen) {
_.forEach(this.actionButtons, data => {
if (data.name === 'fullscreen') {
data.isInActive = false;
}
});
} else {
_.forEach(this.fullScreenActionButtons, data => {
if (data.name === 'minimize') {
data.isInActive = false;
}
});
}
if (this.assessmentEvents) {
this.telemetryEventSubscription$ = this.assessmentEvents.subscribe(telemetry => {
const eid = _.get(telemetry, 'detail.telemetryData.eid');
if (eid === 'ASSESS') {
if (!this.isFullScreen) {
_.forEach(this.actionButtons, data => {
if (data.name === 'fullscreen') {
data.isInActive = true;
}
});
} else {
_.forEach(this.fullScreenActionButtons, data => {
if (data.name === 'minimize') {
data.isInActive = true;
}
});
}
}
});
}
}
ngOnChanges(changes: SimpleChanges) {
this.enableDisableactionButtons();
this.contentPrintable();
if (this.isDesktopApp && _.get(changes, 'contentData') && !_.get(changes, 'contentData.firstChange')) {
this.contentData = _.get(changes, 'contentData.currentValue');
this.contentManagerService.contentDownloadStatus$.pipe(takeUntil(this.unsubscribe$)).subscribe( contentDownloadStatus => {
this.contentDownloadStatus = contentDownloadStatus;
if (this.contentData &&
(contentDownloadStatus[this.contentData.identifier] === 'COMPLETED' ||
contentDownloadStatus[this.contentData.identifier] === 'DOWNLOADED'
) && this.router.url.includes('mydownloads')) {
this.contentDownloaded.emit(this.contentData);
}
this.changeContentStatus();
});
}
}
onActionButtonClick(event, content) {
switch (event.data.name.toUpperCase()) {
case 'RATE':
this.contentRatingModal = true;
this.logTelemetry('rate-content', content);
break;
case 'SHARE':
if (this.isDesktopApp) {
this.exportContent(content);
} else {
this.shareContent(content);
}
break;
case 'UPDATE':
this.updateContent(content);
this.logTelemetry('update-content', content);
break;
case 'DOWNLOAD':
this.isYoutubeContentPresent(content);
const id = content.mimeType === 'application/vnd.ekstep.content-collection' ? 'download-collection' : 'download-content';
this.logTelemetry(id, content);
break;
case 'DELETE':
this.showDeleteModal = true;
this.logTelemetry('confirm-delete-content', content);
break;
case 'PRINT':
this.printPdf(content);
this.logTelemetry('print-content', content);
break;
case 'FULLSCREEN':
this.navigationHelperService.emitFullScreenEvent(true);
this.logTelemetry('fullscreen-content', content);
break;
case 'MINIMIZE':
this.navigationHelperService.emitFullScreenEvent(false);
this.logTelemetry('minimize-screen-content', content);
break;
}
}
shareContent(content) {
this.sharelinkModal = true;
const param = {
identifier: _.get(content, 'identifier'),
type: _.get(content, 'contentType'),
};
this.setTelemetryShareData(param);
this.shareLink = this.collectionId && _.get(content, 'identifier') ?
this.contentUtilsServiceService.getPublicShareUrl(_.get(content, 'identifier'), _.get(content, 'mimeType'), this.collectionId) :
this.contentUtilsServiceService.getPublicShareUrl(_.get(content, 'identifier'), _.get(content, 'mimeType'));
this.logTelemetry('share-content', content);
}
printPdf(content: any) {
const pdfUrl = _.get(content, 'itemSetPreviewUrl');
window.open(pdfUrl, '_blank');
}
setTelemetryShareData(param) {
this.telemetryShareData = [{
id: param.identifier,
type: param.contentType,
ver: param.pkgVersion ? param.pkgVersion.toString() : '1.0'
}];
}
logTelemetry(id, content) {
const interactData = {
context: {
env: _.get(this.activatedRoute.snapshot.data.telemetry, 'env') || 'content',
cdata: []
},
edata: {
id: id,
type: 'click',
pageid: _.get(this.activatedRoute.snapshot.data.telemetry, 'pageid') || 'play-content',
},
object: {
id: content['identifier'],
type: content['contentType'],
ver: `${content['pkgVersion']}`,
rollup: this.objectRollUp,
}
};
this.telemetryService.interact(interactData);
}
contentPrintable() {
// selectedContent?.model?.itemSetPreviewUrl
_.forEach(this.actionButtons, data => {
if (data.name === 'print') {
if (this.contentData.itemSetPreviewUrl) {
data.disabled = false;
} else {
data.disable = true;
}
}
});
_.forEach(this.fullScreenActionButtons, data => {
if (data.name === 'print') {
if (this.contentData.itemSetPreviewUrl) {
data.disabled = false;
} else {
data.disable = true;
}
}
});
}
ngOnDestroy() {
if (this.subscription.unsubscribe) {
this.subscription.unsubscribe();
}
this.telemetryEventSubscription$ && this.telemetryEventSubscription$.unsubscribe();
}
changeContentStatus() {
const status = {
DOWNLOADING: this.resourceService.messages.stmsg.m0140,
FAILED: this.resourceService.messages.stmsg.m0143,
DOWNLOADED: this.resourceService.messages.stmsg.m0139,
PAUSED: this.resourceService.messages.stmsg.m0142,
CANCELED: this.resourceService.messages.stmsg.m0143,
COMPLETED: this.resourceService.messages.stmsg.m0139,
INPROGRESS: this.resourceService.messages.stmsg.m0140,
RESUME: this.resourceService.messages.stmsg.m0140,
INQUEUE: this.resourceService.messages.stmsg.m0140
};
_.forEach(this.actionButtons, data => {
const disableButton = ['Download', 'Failed', 'Canceled', 'Cancel'];
if (data.name === 'download') {
const contentStatus = status[this.contentDownloadStatus[this.contentData.identifier]];
if (this.contentData) {
data.label = contentStatus ? _.capitalize(contentStatus) : this.isAvailable() ? 'Downloaded' : 'Download';
} else {
data.label = 'Download';
}
data.disabled = _.get(this.contentData, 'downloadUrl') ? !_.includes(disableButton, data.label) : true;
} else if (data.name === 'update') {
data.label = _.capitalize(data.name);
data.disabled =
!(_.has(this.contentData, 'desktopAppMetadata') && _.get(this.contentData, 'desktopAppMetadata.updateAvailable'));
} else if ( data.name === 'fullscreen') {
data.disabled = false;
data.label = 'Full screen';
} else if ( !['rate', 'print'].includes(data.name)) {
const downloaded = _.find(this.actionButtons, {name: 'download'});
data.label = _.capitalize(data.name);
data.disabled = !_.isEqual(downloaded.label, 'Downloaded');
}
});
}
isAvailable() {
return (_.has(this.contentData, 'desktopAppMetadata') ? (!_.has(this.contentData, 'desktopAppMetadata.isAvailable')
|| _.get(this.contentData, 'desktopAppMetadata.isAvailable')) : false);
}
isYoutubeContentPresent(content) {
this.showModal = this.offlineCardService.isYoutubeContent(content);
if (!this.showModal) {
this.downloadContent(content);
}
}
downloadContent(content) {
this.showDownloadLoader = true;
this.contentData['downloadStatus'] = this.resourceService.messages.stmsg.m0140;
this.contentManagerService.downloadContentId = content.identifier;
this.contentManagerService.downloadContentData = content;
this.contentManagerService.failedContentName = content.name;
this.contentManagerService.startDownload({}).subscribe(data => {
this.contentManagerService.downloadContentId = '';
this.contentManagerService.downloadContentData = {};
this.showDownloadLoader = false;
this.contentData['downloadStatus'] = this.resourceService.messages.stmsg.m0140;
}, (error) => {
this.showDownloadLoader = false;
this.contentManagerService.downloadContentId = '';
this.contentManagerService.downloadContentData = {};
this.contentManagerService.failedContentName = '';
this.contentData['downloadStatus'] = this.resourceService.messages.stmsg.m0138;
if (!(error.error.params.err === 'LOW_DISK_SPACE')) {
this.toasterService.error(this.resourceService.messages.fmsg.m0090);
}
});
}
updateContent(content) {
this.contentData.desktopAppMetadata['updateAvailable'] = false;
const request = !_.isEmpty(this.collectionId) ? { contentId: content.identifier, parentId: this.collectionId } :
{ contentId: content.identifier };
this.contentManagerService.updateContent(request).pipe(takeUntil(this.unsubscribe$)).subscribe(data => {
}, (err) => {
this.contentData.desktopAppMetadata['updateAvailable'] = true;
const errorMessage = !this.isConnected ? _.replace(this.resourceService.messages.smsg.m0056, '{contentName}',
content.name) :
this.resourceService.messages.fmsg.m0096;
this.toasterService.error(errorMessage);
});
}
exportContent(content) {
this.showExportLoader = true;
this.contentManagerService.exportContent(content.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);
}
});
}
deleteContent(content) {
const button = _.find(this.actionButtons, {label: 'Delete'});
button.disabled = true;
this.logTelemetry('delete-content', content);
const request = !_.isEmpty(this.collectionId) ? {request: {contents: [content.identifier], visibility: 'Parent'}} :
{request: {contents: [content.identifier]}};
this.contentManagerService.deleteContent(request).subscribe(data => {
if (!_.isEmpty(_.get(data, 'result.deleted'))) {
this.contentData['desktopAppMetadata.isAvailable'] = false;
this.toasterService.success(this.resourceService.messages.stmsg.desktop.deleteContentSuccessMessage);
} else {
this.toasterService.error(this.resourceService.messages.etmsg.desktop.deleteContentErrorMessage);
}
}, err => {
this.toasterService.error(this.resourceService.messages.etmsg.desktop.deleteContentErrorMessage);
});
}
}
<div class="d-flex flex-w-wrap content-video__player__details" #playerInfo *ngIf="contentData">
<div class="d-flex flex-dc flex-basis-1 ml-8">
<div class="content-video__player__title mr-auto sb__ellipsis sb__ellipsis--one">
{{contentData?.name}}
</div>
<div class="content-video__player__title__subtitle fsmall mt-4">
<span class="mr-8" *ngIf="contentData?.board">{{resourceService?.frmelmnts?.lbl?.desktop?.board | interpolate:'{board}': contentData?.board}}</span>
<span class="dot-divider" *ngIf="contentData?.me_averageRating"></span>
<span class="mr-8" *ngIf="contentData?.me_averageRating">{{contentData?.me_averageRating || '0'}}</span>
<span *ngIf="contentData?.me_averageRating"><i class="icon star outline" attr.aria-label="{{resourceService.frmelmnts?.lbl?.arialabelCourserating}}"></i></span>
</div>
</div>
<div class="d-flex flex-w-wrap content-video__player__tools" *ngIf="isFullScreen">
<sb-player-actions [actionButtons]="fullScreenActionButtons" (buttonClick)="onActionButtonClick($event, contentData)">
</sb-player-actions>
</div>
<div class="d-flex flex-w-wrap content-video__player__tools" *ngIf="!isFullScreen">
<sb-player-actions [actionButtons]="actionButtons" (buttonClick)="onActionButtonClick($event, contentData)">
</sb-player-actions>
</div>
</div>
<app-modal-wrapper *ngIf="sharelinkModal" [config]="{disableClose: false, panelClass: 'material-modal'}"
(dismiss)="sharelinkModal = false; contentUtilsServiceService.contentShareEvent.emit('close')">
<ng-template sbModalContent>
<app-share-link [shareLink]="shareLink" [telemetryShareData]="telemetryShareData">
</app-share-link>
</ng-template>
</app-modal-wrapper>
<app-modal-wrapper *ngIf="showDeleteModal" [config]="{disableClose: false, size: 'normal'}"
(dismiss)="showDeleteModal = !showDeleteModal;" #modal>
<ng-template sbModalContent>
<div class="sb-modal">
<div class="transition ui dimmer page modals active visible">
<div class="ui modal transition active visible normal">
<div class="sb-modal-header">
{{resourceService?.frmelmnts?.lbl?.delete}}
</div>
<div class="sb-modal-content">
<p>{{resourceService?.frmelmnts?.lbl?.desktop?.deleteContent | interpolate:'{name}': contentData?.name}}</p>
</div>
<div class="sb-modal-actions">
<button class="sb-btn sb-btn-normal sb-btn-primary" tabindex="0"
(click)="deleteContent(contentData); showDeleteModal = !showDeleteModal;">
{{resourceService?.frmelmnts?.lbl?.delete}}
</button>
<button class="sb-btn sb-btn-normal sb-btn-outline-primary" tabindex="0"
(click)="logTelemetry('cancel-delete-content', contentData); showDeleteModal = !showDeleteModal;">
{{resourceService.frmelmnts?.btn?.cancel}}
</button>
</div>
</div>
</div>
</div>
</ng-template>
</app-modal-wrapper>
./content-actions.component.scss
@use 'components/video' as *;