src/app/components/content-rating-alert/content-rating-alert.component.ts
selector | app-content-rating-alert |
styleUrls | ./content-rating-alert.component.scss |
templateUrl | ./content-rating-alert.component.html |
Properties |
|
Methods |
constructor(contentService: ContentFeedbackService, telemetryService: TelemetryService, formService: FormService, preferences: SharedPreferences, popOverCtrl: PopoverController, platform: Platform, navParams: NavParams, telemetryGeneratorService: TelemetryGeneratorService, appGlobalService: AppGlobalService, commonUtilService: CommonUtilService, location: Location, formAndFrameworkUtilService: FormAndFrameworkUtilService)
|
|||||||||||||||||||||||||||||||||||||||
Parameters :
|
cancel |
cancel()
|
Returns :
void
|
closePopover |
closePopover()
|
Returns :
void
|
createRatingForm | ||||
createRatingForm(rating)
|
||||
Parameters :
Returns :
void
|
extractComments | ||||
extractComments(comments)
|
||||
Parameters :
Returns :
void
|
generateContentFeedbackTelemetry | ||||
generateContentFeedbackTelemetry(option1)
|
||||
Parameters :
Returns :
void
|
generateContentRatingTelemetry | ||||
generateContentRatingTelemetry(option)
|
||||
Parameters :
Returns :
void
|
Async getDefaultContentRatingFormApi |
getDefaultContentRatingFormApi()
|
Returns :
any
|
getUserId |
getUserId()
|
Get user id
Returns :
void
|
Async invokeContentRatingFormApi |
invokeContentRatingFormApi()
|
Returns :
any
|
ionViewWillEnter |
ionViewWillEnter()
|
Returns :
void
|
ionViewWillLeave |
ionViewWillLeave()
|
Returns :
void
|
populateComments | ||||
populateComments(data)
|
||||
Parameters :
Returns :
void
|
rateContent | ||||
rateContent(ratingCount)
|
||||
Parameters :
Returns :
void
|
ratingOptsChanged | ||||
ratingOptsChanged(key)
|
||||
Parameters :
Returns :
void
|
showMessage | ||||
showMessage(msg)
|
||||
Parameters :
Returns :
void
|
submit |
submit()
|
Returns :
void
|
allComments |
backButtonFunc |
Default value : undefined
|
comment |
Type : string
|
Default value : ''
|
Private Readonly COMMENT_PREFIX |
Type : string
|
Default value : 'OTHER-'
|
commentText |
content |
Type : any
|
contentRatingOptions |
isDisable |
Default value : false
|
navigateBack |
Private pageId |
Type : string
|
Default value : ''
|
Public platform |
Type : Platform
|
Private popupType |
Type : string
|
ratingCount |
Type : any
|
ratingMetaInfo |
ratingOptions |
showCommentBox |
Default value : false
|
telemetryObject |
Type : TelemetryObject
|
userId |
Type : string
|
Default value : ''
|
userRating |
Type : number
|
Default value : 0
|
import { Location } from '@angular/common';
import { Component, Inject } from '@angular/core';
import { PreferenceKey, ProfileConstants } from '@app/app/app.constant';
import { FormConstants } from '@app/app/form.constants';
import { FormAndFrameworkUtilService } from '@app/services';
import { AppGlobalService } from '@app/services/app-global-service.service';
import { CommonUtilService } from '@app/services/common-util.service';
import {
Environment,
ImpressionSubtype,
ImpressionType,
InteractSubtype,
InteractType,
LogLevel,
LogType
} from '@app/services/telemetry-constants';
import { TelemetryGeneratorService } from '@app/services/telemetry-generator.service';
import { ContentUtil } from '@app/util/content-util';
import { NavParams, Platform, PopoverController } from '@ionic/angular';
import {
ContentFeedback,
ContentFeedbackService,
FormService,
SharedPreferences,
TelemetryFeedbackRequest, TelemetryLogRequest,
TelemetryObject, TelemetryService
} from 'sunbird-sdk';
@Component({
selector: 'app-content-rating-alert',
templateUrl: './content-rating-alert.component.html',
styleUrls: ['./content-rating-alert.component.scss'],
})
export class ContentRatingAlertComponent {
private readonly COMMENT_PREFIX = 'OTHER-';
isDisable = false;
userId = '';
comment = '';
backButtonFunc = undefined;
ratingCount: any;
content: any;
showCommentBox = false;
private pageId = '';
userRating = 0;
private popupType: string;
telemetryObject: TelemetryObject;
contentRatingOptions;
ratingMetaInfo;
ratingOptions;
allComments;
commentText;
navigateBack;
constructor(
@Inject('CONTENT_FEEDBACK_SERVICE') private contentService: ContentFeedbackService,
@Inject('TELEMETRY_SERVICE') private telemetryService: TelemetryService,
@Inject('FORM_SERVICE') private formService: FormService,
@Inject('SHARED_PREFERENCES') private preferences: SharedPreferences,
private popOverCtrl: PopoverController,
public platform: Platform,
private navParams: NavParams,
private telemetryGeneratorService: TelemetryGeneratorService,
private appGlobalService: AppGlobalService,
private commonUtilService: CommonUtilService,
private location: Location,
private formAndFrameworkUtilService: FormAndFrameworkUtilService
) {
this.getUserId();
this.backButtonFunc = this.platform.backButton.subscribeWithPriority(11, () => {
this.popOverCtrl.dismiss();
this.backButtonFunc.unsubscribe();
});
this.content = this.navParams.get('content');
this.userRating = this.navParams.get('rating');
this.allComments = this.navParams.get('comment');
this.popupType = this.navParams.get('popupType');
this.pageId = this.navParams.get('pageId');
this.telemetryObject = ContentUtil.getTelemetryObject(this.content);
this.navigateBack = this.navParams.get('navigateBack');
}
ionViewWillEnter() {
this.telemetryGeneratorService.generateImpressionTelemetry(
ImpressionType.VIEW,
ImpressionSubtype.RATING_POPUP,
this.pageId,
Environment.HOME, this.telemetryObject.id,
this.telemetryObject.type,
this.telemetryObject.version
);
const log = new TelemetryLogRequest();
log.level = LogLevel.INFO;
log.message = this.pageId;
log.env = Environment.HOME;
log.type = LogType.NOTIFICATION;
const params = new Array<any>();
const paramsMap = new Map();
paramsMap['PopupType'] = this.popupType;
params.push(paramsMap);
log.params = params;
this.telemetryService.log(log).subscribe((val) => {
console.log(val);
}, err => {
console.log(err);
});
this.invokeContentRatingFormApi();
const ratingDomTag = document.getElementsByTagName('rating');
this.commonUtilService.setRatingStarAriaLabel(ratingDomTag, this.userRating);
}
ionViewWillLeave() {
if (this.backButtonFunc) {
this.backButtonFunc.unsubscribe();
}
}
/**
* Get user id
*/
getUserId() {
if (this.appGlobalService.getSessionData()) {
this.userId = this.appGlobalService.getSessionData()[ProfileConstants.USER_TOKEN];
} else {
this.userId = '';
}
}
rateContent(ratingCount) {
this.ratingCount = ratingCount;
this.createRatingForm(ratingCount);
const ratingDomTag = document.getElementsByTagName('rating');
this.commonUtilService.setRatingStarAriaLabel(ratingDomTag, ratingCount);
}
cancel() {
this.popOverCtrl.dismiss();
}
closePopover() {
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.TOUCH,
InteractSubtype.CLOSE_CLICKED,
Environment.HOME,
ImpressionSubtype.RATING_POPUP, this.telemetryObject
);
this.popOverCtrl.dismiss();
}
submit() {
let comment = '';
this.ratingOptions.forEach(element => {
if (element.key.toLowerCase() !== 'other' && element.isChecked) {
comment += comment.length ? ',' + element.key : element.key;
}
});
if (this.commentText) {
const text = 'OTHER,' + this.COMMENT_PREFIX + this.commentText;
comment += comment.length ? ',' + text : text;
}
this.allComments = comment;
const option: ContentFeedback = {
contentId: this.content.identifier,
rating: this.ratingCount ? this.ratingCount : this.userRating,
comments: this.allComments,
contentVersion: this.content.contentData ? this.content.contentData.pkgVersion : this.content.pkgVersion
};
const paramsMap = new Map();
paramsMap['Ratings'] = this.ratingCount ? this.ratingCount : this.userRating;
paramsMap['Comment'] = this.allComments;
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.TOUCH,
InteractSubtype.RATING_SUBMITTED,
Environment.HOME,
this.pageId, this.telemetryObject, paramsMap
);
this.generateContentRatingTelemetry(option);
if (this.allComments) {
this.generateContentFeedbackTelemetry(option);
}
}
showMessage(msg) {
this.commonUtilService.showToast(this.commonUtilService.translateMessage(msg));
}
createRatingForm(rating) {
if (rating === 0) {
return;
}
console.log('this.contentRatingOptions[rating].ratingText', this.contentRatingOptions[rating].ratingText)
this.ratingMetaInfo = {
ratingText: this.contentRatingOptions[rating].ratingText,
ratingQuestion: this.contentRatingOptions[rating].question
};
this.ratingOptions = this.contentRatingOptions[rating].options;
this.ratingOptions.forEach(element => {
element.isChecked = false;
});
this.commentText = '';
this.showCommentBox = false;
}
ratingOptsChanged(key) {
if (key.toLowerCase() === 'other') {
this.showCommentBox = !this.showCommentBox;
}
}
extractComments(comments) {
const options = comments.split(',');
options.forEach(e => {
if (e.indexOf(this.COMMENT_PREFIX) !== -1) {
this.commentText = e.substring(this.COMMENT_PREFIX.length);
} else {
const opt = this.ratingOptions.find((v) => e === v.key);
if (opt) {
opt.isChecked = true;
}
}
});
}
async invokeContentRatingFormApi() {
const selectedLanguage = await this.preferences.getString(PreferenceKey.SELECTED_LANGUAGE_CODE).toPromise();
await this.formAndFrameworkUtilService.getFormFields({...FormConstants.CONTENT_FEEDBACK, subType: selectedLanguage}).then((res) => {
this.populateComments(res);
}).catch((error) => {
this.getDefaultContentRatingFormApi();
});
}
async getDefaultContentRatingFormApi() {
await this.formAndFrameworkUtilService.getFormFields(FormConstants.CONTENT_FEEDBACK).then((res) => {
this.populateComments(res);
}).catch((error) => {
this.getDefaultContentRatingFormApi();
});
}
populateComments(data) {
if (data.length) {
this.contentRatingOptions = data[0];
this.createRatingForm(this.userRating);
if (this.allComments) {
this.extractComments(this.allComments);
}
}
}
generateContentRatingTelemetry(option) {
const viewDismissData = {
rating: this.ratingCount ? this.ratingCount : this.userRating,
comment: this.allComments ? this.allComments : '',
message: ''
};
this.contentService.sendFeedback(option).subscribe((res) => {
viewDismissData.message = 'rating.success';
this.popOverCtrl.dismiss(viewDismissData);
this.commonUtilService.showToast('THANK_FOR_RATING', false, 'green-toast');
if (this.navigateBack) {
this.location.back();
}
}, (data) => {
viewDismissData.message = 'rating.error';
this.popOverCtrl.dismiss(viewDismissData);
});
}
generateContentFeedbackTelemetry(option1) {
this.ratingOptions.forEach(opt => {
const option: TelemetryFeedbackRequest = {
objId: this.content.identifier,
comments: this.allComments,
env: Environment.HOME,
objType: this.content.contentData.primaryCategory,
objVer: this.content.contentData.pkgVersion,
};
if (opt.isChecked) {
if (opt.key.toLowerCase() === 'other') {
option.commentid = opt.key;
option.commenttxt = this.commentText;
} else {
option.commentid = opt.key;
option.commenttxt = opt.value;
}
this.telemetryService.feedback(option).subscribe((res) => {
}, (err) => {
});
}
});
}
}
<ion-content class="sb-popover-container ion-no-padding" [ngClass]="{'rating-full-height': userRating}">
<ion-header [ngClass]="{ 'sb-popover-header': platform.is('android'), 'sb-popover-header-ios': platform.is('ios')}">
<ion-toolbar class="sb-popover-toolbar">
<ion-title class="sb-popover-title" role="heading" aria-level="2">{{'RATE_THE_CONTENT' | translate}}
<ion-icon name="close" role="button" tabindex="0" aria-label="close" class="sb-modal-close" (click)="closePopover()"></ion-icon>
</ion-title>
</ion-toolbar>
</ion-header>
<div class="sb-popover-items popover-ratings">
<rating [(ngModel)]="userRating" (ngModelChange)="rateContent($event)"></rating>
<p class="content-rating-detail ion-padding-bottom ion-padding-top" *ngIf="!userRating">
{{'CONTENT_RATING_SUB_HEADING' | translate}}</p>
<div class="sb-popover-content-details" *ngIf="userRating">
<div class="main-title">
<div class="meta-info">
{{ratingMetaInfo?.ratingText}}
</div>
<div class="rating-qstn" role="heading" aria-level="2">
{{ratingMetaInfo?.question ? ratingMetaInfo.question : 'RATING_QUESTION' | translate}}
</div>
</div>
<div class="rating-opts">
<div *ngFor="let opt of ratingOptions | sortBy: 'idx' : 'asc'">
<div class="rating-item" (ionChange)="ratingOptsChanged(opt.key)" role="checkbox" tabindex="0" [ngClass]="{'active': opt.isChecked}">
<ion-label class="rating-label" [ngClass]="{'active-label': opt.isChecked}"
(click)="opt.isChecked=!opt.isChecked">{{opt.value}}</ion-label>
<ion-checkbox [(ngModel)]="opt.isChecked" slot="end">
</ion-checkbox>
</div>
</div>
<div *ngIf="showCommentBox" class="rate-content">
<textarea [(ngModel)]="commentText" name="" id="" cols="30" rows="4"
placeholder="{{'TELL_US_MORE' | translate}}"></textarea>
</div>
</div>
</div>
</div>
<ion-footer [ngClass]="{ 'footer-ios': platform.is('ios') }">
<div class="sb-popover-footer" *ngIf="userRating">
<button class="sb-popover-action-btn popover-color" (click)="submit()">{{ 'BTN_SUBMIT' | translate }}</button>
</div>
</ion-footer>
</ion-content>
./content-rating-alert.component.scss
@import "src/assets/styles/base/_variables.scss";
@import "src/assets/styles/_custom-mixins.scss";
@import "src/assets/styles/variables";
@import "src/assets/styles/_variables.scss";
:host {
/* Sb-Rating Component Styling */
ul {
@include padding($base-block-space);
&.rating li {
@include padding($base-block-space * 2 !important);
background: none;
color: $info-color;
ion-icon {
font-size: (($font-size-base * 3) - 0.125);
}
}
}
.main-title{
.meta-info{
padding: 5px 0 16px 0 !important;
font-size: $font-size-base !important;
}
.rating-qstn{
margin-left: 16px;
padding: 16px 0;
border-top: 1px solid map-get($colors, gray_solid);
font-size: 1rem;
}
}
.rating-opts{
.rating-item{
--min-height: 1.88rem;
display: flex;
padding: 8px 8px 8px 0;
border-bottom: 1px solid map-get($colors, light_gray_8c);
margin-left: 16px;
.rating-label{
color: map-get($colors, primary_black);
font-size: $font-size-base;
margin: 0;
flex: 1 1 0;
text-align: left;
&.active-label{
color: map-get($colors, brighter_blue);
}
}
ion-checkbox{
margin: 0;
}
}
.rate-content{
padding: 0 5px 0 16px;
textarea{
padding: 5px;
width: 100%;
margin: 10px 0;
border: 1px solid map-get($colors, empty_color);
border-radius: 5px;
resize: none;
}
}
}
.content-rating-detail{
text-align: center;
}
// ************** iOS start **************
.footer-ios {
bottom: 3.75rem;
}
// ************** iOS end ****************
}