src/app/qrcoderesult/qrcoderesult.page.ts
OnDestroy
selector | app-qrcoderesult |
styleUrls | ./qrcoderesult.page.scss |
templateUrl | ./qrcoderesult.page.html |
constructor(contentService: ContentService, profileService: ProfileService, frameworkService: FrameworkService, frameworkUtilService: FrameworkUtilService, eventsBusService: EventsBusService, playerService: PlayerService, zone: NgZone, translate: TranslateService, platform: Platform, telemetryGeneratorService: TelemetryGeneratorService, appGlobalService: AppGlobalService, events: Events, commonUtilService: CommonUtilService, canvasPlayerService: CanvasPlayerService, location: Location, file: File, headerService: AppHeaderService, navService: NavigationService, router: Router, navCtrl: NavController, ratingHandler: RatingHandler, contentPlayerHandler: ContentPlayerHandler, textbookTocService: TextbookTocService)
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Parameters :
|
addElipsesInLongText | ||||||
addElipsesInLongText(msg: string)
|
||||||
Parameters :
Returns :
any
|
calculateAvailableUserCount |
calculateAvailableUserCount()
|
Returns :
void
|
cancelDownload |
cancelDownload()
|
Returns :
void
|
findCode | ||||||||||||||||
findCode(categoryList: Array
|
||||||||||||||||
categoryList data return the code of board,medium and subject based on Name
Parameters :
Returns :
any
|
Private findContentNode | ||||||
findContentNode(data: any)
|
||||||
Parameters :
Returns :
boolean
|
Private generateAuditEventForAutoFill |
generateAuditEventForAutoFill()
|
Returns :
void
|
generateNewImpressionEvent | ||||
generateNewImpressionEvent(dialcode?)
|
||||
Parameters :
Returns :
void
|
getChildContents |
getChildContents()
|
Returns :
void
|
getFirstChildOfChapter | ||||
getFirstChildOfChapter(unit)
|
||||
Parameters :
Returns :
void
|
getImportContentRequestBody | |||||||||
getImportContentRequestBody(identifiers: Array
|
|||||||||
Parameters :
Returns :
Array<ContentImport>
|
getNavData |
getNavData()
|
Returns :
void
|
goBack |
goBack()
|
Returns :
void
|
Async handleBackButton | ||||
handleBackButton(clickSource?)
|
||||
Parameters :
Returns :
any
|
handleHeaderEvents | ||||
handleHeaderEvents($event)
|
||||
Parameters :
Returns :
void
|
importContent | |||||||||
importContent(identifiers: Array
|
|||||||||
Parameters :
Returns :
void
|
Private interactEventForPlayAndDownload | ||||||
interactEventForPlayAndDownload(content, play)
|
||||||
Parameters :
Returns :
void
|
ionViewDidEnter |
ionViewDidEnter()
|
Returns :
void
|
ionViewWillEnter |
ionViewWillEnter()
|
Ionic life cycle hook
Returns :
void
|
ionViewWillLeave |
ionViewWillLeave()
|
Returns :
void
|
navigateToDetailsPage | ||||||||
navigateToDetailsPage(content, paths?, contentIdentifier?)
|
||||||||
Parameters :
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
onScroll | ||||
onScroll(event)
|
||||
Parameters :
Returns :
void
|
openTextbookToc |
openTextbookToc()
|
Returns :
void
|
playContent | ||||||||||||
playContent(content: Content, isStreaming: boolean, contentInfo?: ContentInfo)
|
||||||||||||
Play content
Parameters :
Returns :
void
|
playOnline | |||||||||
playOnline(content, isStreaming: boolean)
|
|||||||||
Parameters :
Returns :
void
|
Private populateCData | ||||||
populateCData(formControllerValues, correlationType)
|
||||||
Parameters :
Returns :
Array<CorrelationData>
|
setContentDetails | |||||||||
setContentDetails(identifier, refreshContentDetails: boolean)
|
|||||||||
Parameters :
Returns :
void
|
setGrade | ||||||
setGrade(reset, grades)
|
||||||
Parameters :
Returns :
void
|
setMedium | ||||||
setMedium(reset, mediums)
|
||||||
Parameters :
Returns :
void
|
Private showAllChild | ||||||
showAllChild(content: any)
|
||||||
Parameters :
Returns :
void
|
skipSteps |
skipSteps()
|
Returns :
void
|
subscribeSdkEvent |
subscribeSdkEvent()
|
Subscribe genie event to get content download progress
Returns :
void
|
Public appGlobalService |
Type : AppGlobalService
|
backToPreviusPage |
Default value : true
|
boardList |
Type : Array<any>
|
Default value : []
|
cardData |
Type : any
|
categories |
Type : Array<any>
|
Default value : []
|
chapterFirstChildId |
Type : string
|
Optional childrenData |
Type : Array<any>
|
Public commonUtilService |
Type : CommonUtilService
|
content |
Type : any
|
Defined in src/app/qrcoderesult/qrcoderesult.page.ts:89
|
Contains card data of previous state |
corRelationList |
Type : Array<CorrelationData>
|
defaultImg |
Default value : this.commonUtilService.convertFileSrc('assets/imgs/ic_launcher.png')
|
dialCode |
Type : string
|
downloadProgress |
Type : any
|
Default value : 0
|
eventSubscription |
Type : Subscription
|
gradeList |
Type : Array<any>
|
Default value : []
|
headerObservable |
Type : any
|
identifier |
Type : string
|
Defined in src/app/qrcoderesult/qrcoderesult.page.ts:74
|
To hold identifier |
ionContent |
Type : iContent
|
Decorators :
@ViewChild(iContent, {static: false})
|
isDownloadStarted |
Type : boolean
|
isParentContentAvailable |
Default value : false
|
Defined in src/app/qrcoderesult/qrcoderesult.page.ts:99
|
Contains |
isProfileUpdated |
Type : boolean
|
isQrCodeLinkToContent |
Type : any
|
isSingleContent |
Default value : false
|
isUpdateAvailable |
Type : boolean
|
latestParents |
Type : Array<any>
|
Default value : []
|
mediumList |
Type : Array<any>
|
Default value : []
|
navData |
Type : any
|
onboarding |
Default value : false
|
parentContent |
Type : any
|
Defined in src/app/qrcoderesult/qrcoderesult.page.ts:94
|
Contains Parent Content Details |
parents |
Type : Array<any>
|
Default value : []
|
paths |
Type : Array<any>
|
Default value : []
|
Public platform |
Type : Platform
|
profile |
Type : Profile
|
results |
Type : Array<any>
|
Default value : []
|
searchIdentifier |
Type : string
|
Defined in src/app/qrcoderesult/qrcoderesult.page.ts:79
|
To hold identifier |
shouldGenerateEndTelemetry |
Default value : false
|
showChildrenLoader |
Type : boolean
|
Defined in src/app/qrcoderesult/qrcoderesult.page.ts:84
|
Show loader while importing content |
showLoading |
Type : boolean
|
showSheenAnimation |
Default value : true
|
source |
Type : string
|
Default value : ''
|
stckyindex |
Type : string
|
stckyParent |
Type : any
|
Optional stckyUnitTitle |
Type : string
|
stickyPillsRef |
Type : ElementRef
|
Decorators :
@ViewChild('stickyPillsRef', {static: false})
|
Defined in src/app/qrcoderesult/qrcoderesult.page.ts:69
|
Public translate |
Type : TranslateService
|
unregisterBackButton |
Type : any
|
Defined in src/app/qrcoderesult/qrcoderesult.page.ts:70
|
userCount |
Type : number
|
Default value : 0
|
Public zone |
Type : NgZone
|
import { TextbookTocService } from './../collection-detail-etb/textbook-toc-service';
import { CommonUtilService } from './../../services/common-util.service';
import {
Component, Inject, NgZone, OnDestroy,
ViewChild, ElementRef
} from '@angular/core';
import {
MimeType,
RouterLinks, EventTopics
} from '../../app/app.constant';
import { TranslateService } from '@ngx-translate/core';
import { AppGlobalService } from '../../services/app-global-service.service';
import { TelemetryGeneratorService } from '../../services/telemetry-generator.service';
import find from 'lodash/find';
import each from 'lodash/each';
import { IonContent as iContent, Platform, NavController } from '@ionic/angular';
import {
ChildContentRequest,
Content,
ContentDetailRequest,
ContentEventType,
ContentImport,
ContentImportRequest,
ContentImportResponse,
ContentMarkerRequest,
ContentService,
CorrelationData,
DownloadEventType,
DownloadProgress,
EventsBusEvent,
EventsBusService,
FrameworkService,
FrameworkUtilService,
GetAllProfileRequest,
MarkerType,
NetworkError,
PlayerService,
Profile,
ProfileService,
AuditState,
TrackingEnabled
} from 'sunbird-sdk';
import { Subscription } from 'rxjs';
import {
Environment, ImpressionType, InteractSubtype, InteractType,
PageId, CorReleationDataType, Mode, ObjectType,
AuditType, ImpressionSubtype
} from '../../services/telemetry-constants';
import { CanvasPlayerService } from '../../services/canvas-player.service';
import { File } from '@ionic-native/file/ngx';
import { AppHeaderService } from '../../services/app-header.service';
import { Location } from '@angular/common';
import { NavigationExtras, Router } from '@angular/router';
import { Events } from '@app/util/events';
import { RatingHandler } from '@app/services/rating/rating-handler';
import { ContentPlayerHandler } from '@app/services/content/player/content-player-handler';
import { map } from 'rxjs/operators';
import { ContentUtil } from '@app/util/content-util';
import { NavigationService } from '@app/services/navigation-handler.service';
import {ContentInfo} from '@app/services/content/content-info';
declare const cordova;
@Component({
selector: 'app-qrcoderesult',
templateUrl: './qrcoderesult.page.html',
styleUrls: ['./qrcoderesult.page.scss'],
})
export class QrcoderesultPage implements OnDestroy {
@ViewChild('stickyPillsRef', { static: false }) stickyPillsRef: ElementRef;
unregisterBackButton: any;
/**
* To hold identifier
*/
identifier: string;
/**
* To hold identifier
*/
searchIdentifier: string;
/**
* Show loader while importing content
*/
showChildrenLoader: boolean;
/**
* Contains card data of previous state
*/
content: any;
/**
* Contains Parent Content Details
*/
parentContent: any;
/**
* Contains
*/
isParentContentAvailable = false;
profile: Profile;
corRelationList: Array<CorrelationData>;
shouldGenerateEndTelemetry = false;
source = '';
results: Array<any> = [];
defaultImg = this.commonUtilService.convertFileSrc('assets/imgs/ic_launcher.png');
parents: Array<any> = [];
paths: Array<any> = [];
categories: Array<any> = [];
boardList: Array<any> = [];
mediumList: Array<any> = [];
gradeList: Array<any> = [];
isSingleContent = false;
showLoading: boolean;
isDownloadStarted: boolean;
userCount = 0;
cardData: any;
downloadProgress: any = 0;
isUpdateAvailable: boolean;
eventSubscription: Subscription;
headerObservable: any;
navData: any;
backToPreviusPage = true;
isProfileUpdated: boolean;
isQrCodeLinkToContent: any;
childrenData?: Array<any>;
stckyUnitTitle?: string;
stckyParent: any;
latestParents: Array<any> = [];
stckyindex: string;
chapterFirstChildId: string;
showSheenAnimation = true;
@ViewChild(iContent, { static: false }) ionContent: iContent;
onboarding = false;
dialCode: string;
constructor(
@Inject('CONTENT_SERVICE') private contentService: ContentService,
@Inject('PROFILE_SERVICE') private profileService: ProfileService,
@Inject('FRAMEWORK_SERVICE') private frameworkService: FrameworkService,
@Inject('FRAMEWORK_UTIL_SERVICE') private frameworkUtilService: FrameworkUtilService,
@Inject('EVENTS_BUS_SERVICE') private eventsBusService: EventsBusService,
@Inject('PLAYER_SERVICE') private playerService: PlayerService,
public zone: NgZone,
public translate: TranslateService,
public platform: Platform,
private telemetryGeneratorService: TelemetryGeneratorService,
public appGlobalService: AppGlobalService,
private events: Events,
public commonUtilService: CommonUtilService,
private canvasPlayerService: CanvasPlayerService,
private location: Location,
private file: File,
private headerService: AppHeaderService,
private navService: NavigationService,
private router: Router,
private navCtrl: NavController,
private ratingHandler: RatingHandler,
private contentPlayerHandler: ContentPlayerHandler,
private textbookTocService: TextbookTocService
) {
this.getNavData();
}
getNavData() {
const navigation = this.router.getCurrentNavigation();
if (navigation && navigation.extras && navigation.extras.state) {
this.navData = navigation.extras.state;
}
}
/**
* Ionic life cycle hook
*/
ionViewWillEnter(): void {
if (this.textbookTocService.textbookIds.unit) {
this.chapterFirstChildId = '';
this.getFirstChildOfChapter(this.textbookTocService.textbookIds.unit);
if (this.chapterFirstChildId) {
setTimeout(() => {
if (document.getElementById(this.chapterFirstChildId)) {
this.ionContent.getScrollElement().then((v) => {
v.scrollTo({
top: document.getElementById(this.chapterFirstChildId).offsetTop - 50,
left: 0,
behavior: 'smooth'
});
});
this.textbookTocService.resetTextbookIds();
}
}, 100);
}
}
this.headerService.hideHeader();
this.content = this.navData.content;
this.corRelationList = this.navData.corRelation;
this.shouldGenerateEndTelemetry = this.navData.shouldGenerateEndTelemetry;
this.source = this.navData.source;
this.isSingleContent = this.navData.isSingleContent;
this.onboarding = this.navData.onboarding;
this.dialCode = this.navData.dialCode;
// check for parent content
this.parentContent = this.navData.parentContent;
this.isProfileUpdated = this.navData.isProfileUpdated;
this.searchIdentifier = this.content.identifier;
this.isQrCodeLinkToContent = this.navData.isQrCodeLinkToContent;
this.telemetryGeneratorService.generateImpressionTelemetry(
ImpressionType.PAGE_REQUEST, '',
PageId.QR_CONTENT_RESULT,
this.source === PageId.ONBOARDING_PROFILE_PREFERENCES ? Environment.ONBOARDING : Environment.HOME,
'', '', '', undefined,
this.corRelationList
);
if (this.parentContent) {
this.isParentContentAvailable = true;
this.identifier = this.parentContent.identifier;
} else {
this.isParentContentAvailable = false;
this.identifier = this.content.identifier;
}
if (this.backToPreviusPage) {
if (this.navData.isAvailableLocally) {
this.getChildContents();
} else {
this.telemetryGeneratorService.generatefastLoadingTelemetry(
InteractSubtype.FAST_LOADING_INITIATED,
PageId.DIAL_CODE_SCAN_RESULT,
undefined,
undefined,
undefined,
this.corRelationList
);
const getContentHeirarchyRequest: ContentDetailRequest = {
contentId: this.identifier
};
this.contentService.getContentHeirarchy(getContentHeirarchyRequest).toPromise()
.then((content: Content) => {
this.showSheenAnimation = false;
this.childrenData = content.children;
this.parents.splice(0, this.parents.length);
this.parents.push(content);
this.results = [];
this.findContentNode(content);
this.telemetryGeneratorService.generatefastLoadingTelemetry(
InteractSubtype.FAST_LOADING_FINISHED,
PageId.DIAL_CODE_SCAN_RESULT,
undefined,
undefined,
undefined,
this.corRelationList
);
if (this.results && this.results.length === 1 &&
!(this.results[0].contentData.trackable && this.results[0].contentData.trackable.enabled === TrackingEnabled.YES)) {
this.backToPreviusPage = false;
this.events.unsubscribe(EventTopics.PLAYER_CLOSED);
this.navCtrl.navigateForward([RouterLinks.CONTENT_DETAILS], {
state: {
content: this.results[0],
isSingleContent: this.isSingleContent,
resultsSize: this.results.length,
corRelation: this.corRelationList,
onboarding: this.onboarding,
source: this.source
}
});
}
}).catch((err) => {
this.showSheenAnimation = false;
});
}
this.backToPreviusPage = false;
}
this.unregisterBackButton = this.platform.backButton.subscribeWithPriority(10, () => {
this.handleBackButton(InteractSubtype.DEVICE_BACK_CLICKED);
this.unregisterBackButton.unsubscribe();
});
this.generateNewImpressionEvent(this.dialCode);
this.subscribeSdkEvent();
this.headerObservable = this.headerService.headerEventEmitted$.subscribe(eventName => {
this.handleHeaderEvents(eventName);
});
}
ionViewDidEnter() {
this.telemetryGeneratorService.generateImpressionTelemetry(ImpressionType.VIEW, '',
PageId.DIAL_CODE_SCAN_RESULT,
!this.appGlobalService.isProfileSettingsCompleted ? Environment.ONBOARDING : this.appGlobalService.getPageIdForTelemetry());
if (this.corRelationList && this.corRelationList.length) {
this.corRelationList.push({
id: this.content.children ? this.content.children.length.toString() : '0',
type: CorReleationDataType.COUNT_CONTENT
});
}
this.telemetryGeneratorService.generatePageLoadedTelemetry(
PageId.QR_CONTENT_RESULT,
this.source === PageId.ONBOARDING_PROFILE_PREFERENCES ? Environment.ONBOARDING : Environment.HOME,
this.content.identifier,
ObjectType.CONTENT,
undefined, undefined,
this.corRelationList
);
if (!AppGlobalService.isPlayerLaunched) {
this.calculateAvailableUserCount();
}
}
ionViewWillLeave() {
this.headerObservable.unsubscribe();
if (this.unregisterBackButton) {
this.unregisterBackButton.unsubscribe();
}
this.downloadProgress = 0;
if (this.eventSubscription) {
this.eventSubscription.unsubscribe();
}
}
ngOnDestroy() {
this.textbookTocService.resetTextbookIds();
if (this.eventSubscription) {
this.eventSubscription.unsubscribe();
}
}
async handleBackButton(clickSource?) {
this.telemetryGeneratorService.generateBackClickedNewTelemetry(
clickSource === InteractSubtype.DEVICE_BACK_CLICKED ? true : false,
this.source === PageId.ONBOARDING_PROFILE_PREFERENCES ? Environment.ONBOARDING : Environment.HOME,
PageId.QR_CONTENT_RESULT
);
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.TOUCH,
clickSource || InteractSubtype.NAV_BACK_CLICKED,
!this.appGlobalService.isOnBoardingCompleted ? Environment.ONBOARDING : Environment.HOME,
PageId.DIAL_CODE_SCAN_RESULT);
if (this.source === PageId.LIBRARY || this.source === PageId.COURSES || !this.isSingleContent) {
this.goBack();
} else if (this.isSingleContent && this.appGlobalService.isProfileSettingsCompleted) {
if (await this.commonUtilService.isDeviceLocationAvailable()) {
this.navCtrl.pop();
const navigationExtras: NavigationExtras = { state: { loginMode: 'guest' }, replaceUrl: true };
this.router.navigate([`/${RouterLinks.TABS}`], navigationExtras);
} else {
const navigationExtras: NavigationExtras = {
state: {
isShowBackButton: false
}
};
this.navCtrl.navigateForward([`/${RouterLinks.DISTRICT_MAPPING}`], navigationExtras);
}
} else if (this.appGlobalService.isGuestUser
&& this.isSingleContent
&& !this.appGlobalService.isProfileSettingsCompleted) {
const navigationExtras: NavigationExtras = {
state: {
isCreateNavigationStack: false,
hideBackButton: true,
showFrameworkCategoriesMenu: true
}
};
this.router.navigate([`/${RouterLinks.PROFILE_SETTINGS}`], navigationExtras);
} else {
this.goBack();
}
}
getChildContents() {
this.showSheenAnimation = false;
const request: ChildContentRequest = { contentId: this.identifier, hierarchyInfo: [] };
this.profile = this.appGlobalService.getCurrentUser();
this.contentService.getChildContents(
request).toPromise()
.then(async (data: Content) => {
console.log('getChildContents', data);
if (data && data.contentData) {
this.childrenData = data.children;
}
this.parents.splice(0, this.parents.length);
this.parents.push(data);
this.results = [];
const contentData = data.contentData;
this.findContentNode(data);
if (this.results && this.results.length === 0) {
this.telemetryGeneratorService.generateImpressionTelemetry(ImpressionType.VIEW,
'',
PageId.DIAL_LINKED_NO_CONTENT,
Environment.HOME);
if (this.isProfileUpdated) {
if (!await this.commonUtilService.isDeviceLocationAvailable()) {
const navigationExtras: NavigationExtras = {
state: {
isShowBackButton: false
}
};
this.navCtrl.navigateForward([`/${RouterLinks.DISTRICT_MAPPING}`], navigationExtras);
} else {
this.navCtrl.navigateBack([RouterLinks.TABS]);
}
this.commonUtilService.showContentComingSoonAlert(this.source, data, this.dialCode);
} else {
this.commonUtilService.showContentComingSoonAlert(this.source, data, this.dialCode);
window.history.go(-2);
}
} else if (this.results && this.results.length === 1 &&
!(this.results[0].contentData.trackable && this.results[0].contentData.trackable.enabled === TrackingEnabled.YES)) {
this.backToPreviusPage = false;
this.events.unsubscribe(EventTopics.PLAYER_CLOSED);
this.navCtrl.navigateForward([RouterLinks.CONTENT_DETAILS], {
state: {
content: this.results[0],
isSingleContent: this.isSingleContent,
resultsSize: this.results.length,
corRelation: this.corRelationList,
onboarding: this.onboarding
}
});
}
})
.catch((err) => {
console.log('err1-->', err);
this.zone.run(() => {
this.showChildrenLoader = false;
});
this.commonUtilService.showContentComingSoonAlert(this.source);
this.location.back();
});
}
calculateAvailableUserCount() {
const profileRequest: GetAllProfileRequest = {
local: true,
server: false
};
this.profileService.getAllProfiles(profileRequest).pipe(
map((profiles) => profiles.filter((profile) => !!profile.handle))
).subscribe(profiles => {
if (profiles) {
this.userCount = profiles.length;
}
if (this.appGlobalService.isUserLoggedIn()) {
this.userCount += 1;
}
}, () => {
});
}
/**
* Play content
*/
playContent(content: Content, isStreaming: boolean, contentInfo?: ContentInfo) {
if (!content.isAvailableLocally && !this.commonUtilService.networkInfo.isNetworkAvailable) {
this.commonUtilService.showToast('ERROR_OFFLINE_MODE');
return;
}
const extraInfoMap = { hierarchyInfo: [] };
if (this.cardData && this.cardData.hierarchyInfo) {
extraInfoMap.hierarchyInfo = this.cardData.hierarchyInfo;
}
const req: ContentMarkerRequest = {
uid: this.appGlobalService.getCurrentUser().uid,
contentId: content.identifier,
data: JSON.stringify(content.contentData),
marker: MarkerType.PREVIEWED,
isMarked: true,
extraInfo: extraInfoMap
};
this.contentService.setContentMarker(req).toPromise()
.then(() => {
}).catch(() => {
});
AppGlobalService.isPlayerLaunched = true;
const values = new Map();
values['isStreaming'] = isStreaming;
const localContentInfo: ContentInfo = {
telemetryObject: ContentUtil.getTelemetryObject(content),
rollUp: ContentUtil.generateRollUp(content.hierarchyInfo, content.identifier),
correlationList: this.corRelationList,
hierachyInfo: content.hierarchyInfo,
course: undefined
};
this.interactEventForPlayAndDownload(content, true);
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.TOUCH,
content.isAvailableLocally ? InteractSubtype.PLAY_FROM_DEVICE : InteractSubtype.PLAY_ONLINE,
!this.appGlobalService.isOnBoardingCompleted ? Environment.ONBOARDING : Environment.HOME,
PageId.DIAL_CODE_SCAN_RESULT,
ContentUtil.getTelemetryObject(content),
undefined,
undefined,
this.corRelationList);
this.contentPlayerHandler.launchContentPlayer(content,
isStreaming,
false,
contentInfo ? contentInfo : localContentInfo,
false,
false);
}
playOnline(content, isStreaming: boolean) {
const telemetryObject = ContentUtil.getTelemetryObject(content);
this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
InteractSubtype.CONTENT_CLICKED,
!this.appGlobalService.isOnBoardingCompleted ? Environment.ONBOARDING : Environment.HOME,
PageId.DIAL_CODE_SCAN_RESULT,
telemetryObject);
if (content.contentData.streamingUrl && !content.isAvailableLocally) {
if (!this.commonUtilService.networkInfo.isNetworkAvailable) {
this.commonUtilService.showToast('ERROR_OFFLINE_MODE');
return;
}
const rollup = ContentUtil.generateRollUp(content.hierarchyInfo, content.identifier);
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.SELECT_CARD, '',
this.source === PageId.ONBOARDING_PROFILE_PREFERENCES ? Environment.ONBOARDING : Environment.HOME,
PageId.QR_CONTENT_RESULT,
telemetryObject,
undefined,
rollup,
this.corRelationList
);
const contentInfo: ContentInfo = {
telemetryObject,
rollUp: rollup,
correlationList: this.corRelationList,
hierachyInfo: content.hierarchyInfo,
course: undefined
};
this.playContent(content, isStreaming, contentInfo);
} else {
this.navigateToDetailsPage(content);
}
}
navigateToDetailsPage(content, paths?, contentIdentifier?) {
if (!content.isAvailableLocally && !this.commonUtilService.networkInfo.isNetworkAvailable) {
this.commonUtilService.showToast('ERROR_OFFLINE_MODE');
return;
}
this.interactEventForPlayAndDownload(content, false);
if (!(content.contentData.downloadUrl) && !paths && ContentUtil.isTrackable(content.contentData) === -1) {
this.commonUtilService.showToast('DOWNLOAD_NOT_ALLOWED_FOR_QUIZ');
return;
}
const corRelationList = [...this.corRelationList];
if (paths && paths.length) {
const rootId = paths[0].identifier ? paths[0].identifier : '';
corRelationList.push({
id: rootId || '',
type: CorReleationDataType.ROOT_ID
});
}
switch (ContentUtil.isTrackable(content)) {
case 1:
this.navService.navigateToTrackableCollection({
content,
corRelation: corRelationList
});
break;
case 0:
if (paths && paths.length && paths.length >= 2) {
this.textbookTocService.setTextbookIds({ rootUnitId: paths[1].identifier, contentId: contentIdentifier });
}
this.navService.navigateToCollection({
content,
corRelation: corRelationList
});
break;
case -1:
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.TOUCH,
Boolean(content.isAvailableLocally) ? InteractSubtype.PLAY_FROM_DEVICE : InteractSubtype.DOWNLOAD_PLAY_CLICKED,
!this.appGlobalService.isOnBoardingCompleted ? Environment.ONBOARDING : Environment.HOME,
PageId.DIAL_CODE_SCAN_RESULT);
this.navService.navigateToContent({
content,
depth: '1',
isChildContent: true,
downloadAndPlay: true,
corRelation: corRelationList,
onboarding: this.onboarding,
source: this.source
});
break;
}
}
addElipsesInLongText(msg: string) {
if (this.commonUtilService.translateMessage(msg).length >= 12) {
return this.commonUtilService.translateMessage(msg).slice(0, 8) + '....';
} else {
return this.commonUtilService.translateMessage(msg);
}
}
setContentDetails(identifier, refreshContentDetails: boolean) {
const option: ContentDetailRequest = {
contentId: identifier,
attachFeedback: true,
attachContentAccess: true,
emitUpdateIfAny: refreshContentDetails
};
this.contentService.getContentDetails(option).toPromise()
.then((data: any) => {
if (data) {
this.content.contentAccess = data.contentAccess ? data.contentAccess : [];
}
this.contentPlayerHandler.setContentPlayerLaunchStatus(false);
this.ratingHandler.showRatingPopup(false, this.content, 'automatic', this.corRelationList, null);
this.contentPlayerHandler.setLastPlayedContentId('');
})
.catch((error: any) => {
});
}
setGrade(reset, grades) {
if (reset) {
this.profile.grade = [];
this.profile.gradeValue = {};
}
each(grades, (grade) => {
if (grade && this.profile.grade.indexOf(grade) === -1) {
if (this.profile.grade && this.profile.grade.length) {
this.profile.grade.push(grade);
} else {
this.profile.grade = [grade];
}
}
});
}
setMedium(reset, mediums) {
if (reset) {
this.profile.medium = [];
}
each(mediums, (medium) => {
if (medium && this.profile.medium.indexOf(medium) === -1) {
if (this.profile.medium && this.profile.medium.length) {
this.profile.medium.push(medium);
} else {
this.profile.medium = [medium];
}
}
});
}
/**
* categoryList
* data
* @param categoryType
* return the code of board,medium and subject based on Name
*/
findCode(categoryList: Array<any>, data, categoryType) {
if (find(categoryList, (category) => category.name === data[categoryType])) {
return find(categoryList, (category) => category.name === data[categoryType]).code;
} else {
return undefined;
}
}
/**
* Subscribe genie event to get content download progress
*/
subscribeSdkEvent() {
this.eventSubscription = this.eventsBusService.events().subscribe((event: EventsBusEvent) => {
this.zone.run(() => {
if (event.type === DownloadEventType.PROGRESS && event.payload.progress) {
const downloadEvent = event as DownloadProgress;
if (downloadEvent.payload.progress === -1) {
this.downloadProgress = 0;
} else if (downloadEvent.payload.identifier === this.content.identifier) {
this.downloadProgress = downloadEvent.payload.progress;
}
}
// Get child content
// if (res.data && res.data.status === 'IMPORT_COMPLETED' && res.type === 'contentImport') {
if (event.payload && event.type === ContentEventType.IMPORT_COMPLETED) {
const corRelationList: Array<CorrelationData> = [];
corRelationList.push({ id: this.dialCode ? this.dialCode : '', type: CorReleationDataType.QR });
corRelationList.push({
id: this.content.leafNodesCount ? this.content.leafNodesCount.toString() : '0',
type: CorReleationDataType.COUNT_NODE
});
this.telemetryGeneratorService.generatePageLoadedTelemetry(
PageId.TEXTBOOK_IMPORT,
this.source === PageId.ONBOARDING_PROFILE_PREFERENCES ? Environment.ONBOARDING : Environment.HOME,
this.content.identifier,
ObjectType.TEXTBOOK,
undefined, undefined,
corRelationList
);
this.showLoading = false;
this.isDownloadStarted = false;
this.results = [];
this.parents = [];
this.paths = [];
this.getChildContents();
this.generateAuditEventForAutoFill();
}
// For content update available
// if (res.data && res.type === 'contentUpdateAvailable' && res.data.identifier === this.identifier) {
if (event.payload && event.type === ContentEventType.UPDATE && event.payload.contentId === this.identifier) {
this.zone.run(() => {
if (this.parentContent) {
const parentIdentifier = this.parentContent.contentId || this.parentContent.identifier;
this.showLoading = true;
this.importContent([parentIdentifier], false);
}
});
}
});
}) as any;
}
importContent(identifiers: Array<string>, isChild: boolean) {
const contentImportRequest: ContentImportRequest = {
contentImportArray: this.getImportContentRequestBody(identifiers, isChild),
contentStatusArray: [],
fields: ['appIcon', 'name', 'subject', 'size', 'gradeLevel']
};
// Call content service
this.contentService.importContent(contentImportRequest).toPromise()
.then((data: ContentImportResponse[]) => {
})
.catch((error: any) => {
this.zone.run(() => {
this.isDownloadStarted = false;
this.showLoading = false;
if (NetworkError.isInstance(error)) {
this.commonUtilService.showToast('NEED_INTERNET_TO_CHANGE');
} else {
this.commonUtilService.showToast('UNABLE_TO_FETCH_CONTENT');
}
});
});
}
getImportContentRequestBody(identifiers: Array<string>, isChild: boolean): Array<ContentImport> {
const requestParams = [];
const folderPath = this.platform.is('ios') ? cordova.file.documentsDirectory : cordova.file.externalDataDirectory;
identifiers.forEach((value) => {
requestParams.push({
isChildContent: isChild,
destinationFolder: folderPath,
contentId: value,
correlationData: this.corRelationList !== undefined ? this.corRelationList : []
});
});
return requestParams;
}
cancelDownload() {
this.telemetryGeneratorService.generateCancelDownloadTelemetry(this.content);
this.contentService.cancelDownload(this.identifier).toPromise()
.then(() => {
this.zone.run(() => {
this.showLoading = false;
this.location.back();
});
}).catch(() => {
this.zone.run(() => {
this.showLoading = false;
this.location.back();
});
});
}
skipSteps() {
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.TOUCH,
InteractSubtype.NO_QR_CODE_CLICKED,
!this.appGlobalService.isOnBoardingCompleted ? Environment.ONBOARDING : Environment.HOME,
PageId.DIAL_CODE_SCAN_RESULT
);
if (this.appGlobalService.isOnBoardingCompleted && this.appGlobalService.isProfileSettingsCompleted) {
const navigationExtras: NavigationExtras = { state: { loginMode: 'guest' } };
this.router.navigate([`/${RouterLinks.TABS}`], navigationExtras);
} else {
this.router.navigate([`/${RouterLinks.PROFILE_SETTINGS}`], { state: { showFrameworkCategoriesMenu: true } });
}
}
private showAllChild(content: any) {
this.zone.run(() => {
if (content.children === undefined || !content.children.length || ContentUtil.isTrackable(content.contentData) === 1) {
if (content.mimeType !== MimeType.COLLECTION || ContentUtil.isTrackable(content.contentData) === 1) {
if (content.contentData.appIcon) {
if (content.contentData.appIcon.includes('http:') || content.contentData.appIcon.includes('https:')) {
if (!this.commonUtilService.networkInfo.isNetworkAvailable) {
content.contentData.appIcon = this.defaultImg;
}
} else if (content.basePath) {
content.contentData.appIcon = content.basePath + '/' + content.contentData.appIcon;
}
}
this.results.push(content);
const path = [];
let latestParent = [];
latestParent = this.parents[this.parents.length - 2];
this.parents.forEach(ele => {
path.push(ele);
});
path.splice(-1, 1);
this.paths.push(path);
this.latestParents.push(latestParent);
}
return;
}
content.children.forEach(child => {
this.parents.push(child);
this.showAllChild(child);
this.parents.splice(-1, 1);
});
});
}
private findContentNode(data: any) {
if (data && data.identifier === this.searchIdentifier) {
this.showAllChild(data);
return true;
}
if (data && data.children !== undefined) {
data.children.forEach(child => {
this.parents.push(child);
const isFound = this.findContentNode(child);
if (isFound === true) {
return true;
}
this.parents.splice(-1, 1);
});
}
return false;
}
handleHeaderEvents($event) {
if($event.name === 'back'){
this.handleBackButton(InteractSubtype.NAV_BACK_CLICKED);
}
}
goBack() {
this.telemetryGeneratorService.generateBackClickedTelemetry(
PageId.DIAL_CODE_SCAN_RESULT, Environment.HOME,
true, this.content.identifier, this.corRelationList);
if (this.isQrCodeLinkToContent) {
window.history.go(-2);
} else {
this.location.back();
}
}
openTextbookToc() {
this.navService.navigateTo([`/${RouterLinks.COLLECTION_DETAIL_ETB}/${RouterLinks.TEXTBOOK_TOC}`], {
childrenData: this.childrenData, parentId: this.identifier,
stckyUnitTitle: this.stckyUnitTitle, stckyindex: this.stckyindex,
latestParentNodes: this.latestParents
});
const values = new Map();
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.TOUCH,
InteractSubtype.DROPDOWN_CLICKED,
Environment.HOME,
PageId.DIAL_CODE_SCAN_RESULT,
undefined,
values
);
}
onScroll(event) {
const titles = document.querySelectorAll('[data-sticky-unit]');
const currentTitle = Array.from(titles).filter((title) => {
return title.getBoundingClientRect().top < 200;
}).slice(-1)[0];
if (currentTitle) {
this.zone.run(() => {
this.stckyUnitTitle = currentTitle.getAttribute('data-sticky-unit');
this.stckyindex = currentTitle.getAttribute('data-index');
this.stckyParent = this.latestParents[this.stckyindex].contentData.name;
});
}
if (event.scrollTop >= 205) {
(this.stickyPillsRef.nativeElement as HTMLDivElement).classList.add('sticky');
return;
}
(this.stickyPillsRef.nativeElement as HTMLDivElement).classList.remove('sticky');
}
// when coming back from toc page it has to scroll to the firstcontent of the selected chapter
getFirstChildOfChapter(unit) {
if (!this.chapterFirstChildId) {
if (unit.children === undefined) {
if (unit.mimeType !== MimeType.COLLECTION) {
this.chapterFirstChildId = unit.identifier;
}
return;
}
unit.children.forEach(child => {
this.getFirstChildOfChapter(child);
});
}
}
private interactEventForPlayAndDownload(content, play) {
const telemetryObject = ContentUtil.getTelemetryObject(content);
if (this.corRelationList && this.corRelationList.length) {
this.corRelationList.push({ id: Mode.PLAY, type: CorReleationDataType.MODE });
this.corRelationList.push({ id: telemetryObject.type || '', type: CorReleationDataType.TYPE });
this.corRelationList.push({
id: this.commonUtilService.networkInfo.isNetworkAvailable ?
Mode.ONLINE : Mode.OFFLINE, type: InteractSubtype.NETWORK_STATUS
});
}
const rollup = ContentUtil.generateRollUp(content.hierarchyInfo, content.identifier);
this.telemetryGeneratorService.generateInteractTelemetry(
play ? InteractType.PLAY : InteractType.DOWNLOAD,
undefined,
this.source === PageId.ONBOARDING_PROFILE_PREFERENCES ? Environment.ONBOARDING : Environment.HOME,
PageId.QR_CONTENT_RESULT,
telemetryObject,
undefined,
rollup,
this.corRelationList
);
}
generateNewImpressionEvent(dialcode?) {
const corRelationList: Array<CorrelationData> = [];
if (dialcode) {
corRelationList.push({ id: dialcode, type: CorReleationDataType.QR });
}
this.telemetryGeneratorService.generateImpressionTelemetry(
dialcode ? ImpressionType.PAGE_REQUEST : InteractType.PLAY,
dialcode ? '' : InteractSubtype.DOWNLOAD,
dialcode ? PageId.TEXTBOOK_IMPORT : PageId.QR_CONTENT_RESULT,
this.source === PageId.ONBOARDING_PROFILE_PREFERENCES ? Environment.ONBOARDING : Environment.HOME,
dialcode ? this.content.identifier : undefined,
dialcode ? ObjectType.TEXTBOOK : undefined,
undefined, undefined,
dialcode ? corRelationList : undefined
);
}
private generateAuditEventForAutoFill() {
if (this.source === PageId.ONBOARDING_PROFILE_PREFERENCES && this.appGlobalService.isOnBoardingCompleted) {
let correlationlist: Array<CorrelationData> = this.populateCData(this.profile.board, CorReleationDataType.BOARD);
correlationlist = correlationlist.concat(this.populateCData(this.profile.medium, CorReleationDataType.MEDIUM));
correlationlist = correlationlist.concat(this.populateCData(this.profile.grade, CorReleationDataType.CLASS));
correlationlist.push({ id: ImpressionSubtype.AUTO, type: CorReleationDataType.FILL_MODE });
const rollup = ContentUtil.generateRollUp(this.content.hierarchyInfo, this.content.identifier);
this.telemetryGeneratorService.generateAuditTelemetry(
Environment.ONBOARDING,
AuditState.AUDIT_UPDATED,
undefined,
AuditType.SET_PROFILE,
undefined,
undefined,
undefined,
correlationlist,
rollup
);
}
}
private populateCData(formControllerValues, correlationType): Array<CorrelationData> {
const correlationList: Array<CorrelationData> = [];
if (formControllerValues) {
formControllerValues.forEach((value) => {
correlationList.push({
id: value,
type: correlationType
});
});
}
return correlationList;
}
}
<ion-header>
<ion-toolbar style="min-height: 3.5rem;">
<ion-buttons class="sb-hamburger" slot="start">
<ion-button icon-only (click)="handleBackButton()">
<ion-icon role="button" aria-label="back" name="arrow-back"></ion-icon>
</ion-button>
</ion-buttons>
<ion-title>{{'RESULTS' | translate}}</ion-title>
<ion-buttons slot="primary">
<ion-button fill="clear"
*ngIf="!appGlobalService?.isUserLoggedIn() && !appGlobalService?.isProfileSettingsCompleted"
(click)="skipSteps()">
{{'SKIP' | translate}}
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<div #stickyPillsRef class="sb-chapter-dd" (click)="openTextbookToc()" *ngIf="(results.length>1 || (results.length===1 && results[0].contentData.trackable.enabled === 'Yes'))">
<span class="pull-left">{{stckyParent || ('SELECT_CHAPTER' | translate)}}</span>
<span class="pull-right">
<ion-icon md="caret-forward-circle" ios="chevron-forward-circle"></ion-icon>
</span>
</div>
<div class="m-n" *ngIf="showSheenAnimation" style="margin-top: 50px;">
<div class="skeleton-search-card" *ngFor="let i of [0,1,2,3,4,5,6,7,8,9,10,11,12,13]" style="display: flex;padding-left: 10px;">
<ion-avatar slot="start" class="skleton-avatar">
<app-skeleton-item height="3.5rem" width="3.5rem" style="height:3.5rem; width:3.5rem;"></app-skeleton-item>
</ion-avatar>
<div style=" flex: 1;">
<app-skeleton-item height="0.75rem" width="80%" style="height:0.75rem; width:100%; padding-bottom: 8px;">
</app-skeleton-item>
<app-skeleton-item height="0.75rem" width="50%"
style="height:0.75rem; width:100%; padding-bottom: 16px;margin-top:8px;"></app-skeleton-item>
</div>
</div>
</div>
<ion-content *ngIf="(results.length>1 || (results.length===1 && results[0].contentData.trackable.enabled === 'Yes'))" class="ion-padding" [scrollEvents]="true" (ionScroll)="onScroll($event)">
<div class="card-container" *ngFor="let content of results; let i = index"
[ngClass]="{'offline': !content?.isAvailableLocally && !commonUtilService.networkInfo.isNetworkAvailable}">
<ion-row class="P010">
<ul class="breadcrumbs">
<li *ngFor="let result of paths[i]" (click)="navigateToDetailsPage(paths[i][0], paths[i], content?.identifier)">
{{ (result?.contentData?.name?.length>30)? (result?.contentData?.name | slice:0:30)+'...' :
(result?.contentData?.name) }}
</li>
</ul>
</ion-row>
<ion-card [id]="content.identifier">
<ion-row [attr.data-sticky-unit]="content.contentData.name" [attr.data-index]="i">
<ion-col size="12">
<ion-card-content (click)="playOnline(content, true)">
<ion-row class="top">
<ion-col size="3" class="img-container">
<img class="app-icon" alt="app-icon"
[src]="commonUtilService.convertFileSrc(content?.contentData?.appIcon) || defaultImg" />
</ion-col>
<ion-col size="9">
<ion-row>
<ion-col size="12" class="PT0">
<h6 class="name font-size-20">{{content?.contentData?.name}}</h6>
<p class="author">{{content?.contentData?.creator}}</p>
</ion-col>
<ion-col size="12" class="bottom-fix">
<span class="badge" *ngIf="content?.contentData?.resourceType">
{{content?.contentData?.resourceType}} </span>
<span class="size" *ngIf="content?.contentData?.size"> {{content?.contentData?.size | fileSize}}
</span>
</ion-col>
</ion-row>
</ion-col>
</ion-row>
</ion-card-content>
</ion-col>
</ion-row>
<!-- download and play online -->
<div class="ion-no-padding" *ngIf="content.contentData?.streamingUrl && !content.isAvailableLocally">
<ion-row class="ion-no-padding">
<ion-col class="ion-no-padding btn-space" style="z-index: 100;" *ngIf="!content?.downloadable"
(click)="navigateToDetailsPage(content)">
<button class="qr-result-btn download-info ion-no-padding ion-text-uppercase" expand="block" color="light"
style="color:#0D7DFC; z-index: 100;" [ngClass]="!(content.contentData?.downloadUrl) ? 'download-disabled' : null">
<ion-icon class="downloadicon" name="arrow-down"></ion-icon>
{{'DOWNLOAD'| translate}}
</button>
</ion-col>
<ion-col class="ion-no-padding"
*ngIf="content.contentData?.streamingUrl && !(content.mimeType === 'application/vnd.ekstep.h5p-archive')">
<button class="custom-btn play qr-result-btn ion-no-padding" expand="block" (click)="playContent(content, true)">
<ion-icon name="play" style="margin-left: -1rem;"></ion-icon> <span class="play-btn-info">{{'PLAY' | translate}}</span>
</button>
</ion-col>
</ion-row>
</div>
<!-- play locally if content downloaded -->
<div class="ion-no-padding" *ngIf="content.isAvailableLocally && !content.isUpdateAvailable">
<button class="qr-result-btn default ion-no-padding ion-text-uppercase" expand="block"
(click)="navigateToDetailsPage(content)" [disabled]="isDownloadStarted">
<ion-icon name="play" style="margin-left: -1rem;"></ion-icon> <span class="play-btn-info">{{'PLAY' | translate}}</span>
</button>
</div>
<!-- Download content if not available locally -->
<div class="ion-no-padding" *ngIf="!content.contentData?.streamingUrl && !content.isAvailableLocally">
<button class="qr-result-btn download-info ion-no-padding ion-text-uppercase" expand="block" color="light"
style="color:#0D7DFC" (click)="navigateToDetailsPage(content)">
<ion-icon class="downloadicon" name="arrow-down"></ion-icon> {{'DOWNLOAD'| translate}}
</button>
</div>
<!-- Update and play on device -->
<div class="ion-no-padding" *ngIf="content.isUpdateAvailable && content.isAvailableLocally">
<ion-row class="ion-no-padding">
<ion-col style="z-index: 100;" *ngIf="content.isUpdateAvailable" (click)="navigateToDetailsPage(content)"
class="ion-no-padding">
<button class="qr-result-btn ion-text-uppercase ion-no-margin" expand="block" color="light"
style="color:#0D7DFC; z-index: 100;">
<ion-icon class="downloadicon" name="arrow-down"></ion-icon> {{ 'UPDATE' | translate }}
</button>
</ion-col>
<ion-col class="ion-no-padding" *ngIf="content.contentData?.streamingUrl">
<button class="custom-btn play qr-result-btn default ion-no-margin" expand="block"
(click)="navigateToDetailsPage(content)">
<ion-icon name="play" style="margin-left: -1rem;"></ion-icon> <span class="play-btn-info">{{'PLAY' | translate}}</span>
</button>
</ion-col>
</ion-row>
</div>
</ion-card>
</div>
</ion-content>
./qrcoderesult.page.scss
@import "src/assets/styles/_custom-mixins.scss";
@import "src/assets/styles/base/_variables.scss";
@import "src/assets/styles/_variables.scss";
:host{
.toolbar-md{
min-height: auto;
}
.card-container{
margin-bottom: 20px;
padding: 0 !important;
}
.P010{
padding:0 10px;
}
.PT0{
padding-top: 0 !important;
}
[dir="ltr"] .card-content-md, [dir="rtl"] .card-content-md{
padding: 5px !important;
}
.badge {
@include padding(5px, 15px);
color: map-get($colors, primary_black);
border-radius: 100px;
border: solid 0.5px map-get($colors, pale_cyan);
font-size: 0.688rem;
@include margin(null, 10px, null, null);
}
.sc-ion-card-md-h.sc-ion-card-md-s {
border-radius: 4px;
box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.16);
background-color: map-get($colors, white);
border: solid 0.5px map-get($colors, medium_gray);
position: relative;
.card-content-md {
padding: 7px !important;
}
.button.button-block.button-block-md {
margin: 0;
border-radius: 0px !important;
}
.author {
font-size: 0.688rem;
font-weight: normal;
font-style: normal;
font-stretch: normal;
line-height: normal;
letter-spacing: normal;
color: map-get($colors, granite_gray);
}
.size{
font-size: 0.688rem;
color: map-get($colors, granite_gray);
}
.name, .author{
margin-bottom: 5px;
}
.name{
// min-height: 48px;
display: -webkit-box;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
font-size: 0.875rem !important;
color: map-get($colors, primary_black);
min-height: 2rem;
}
.bottom-fix{
position: absolute;
bottom: 0;
}
.top {
min-height:15vh;
// background: #E9E9E9;
.img-container {
border: 1px solid map-get($colors, pale_cyan);
padding: 0 !important;
background: map-get($colors, white_e9);
min-height: 18vh;
max-height: 18vh;
border-radius: 4px;
img {
max-height: 100%;
margin: 0 auto;
width: auto;
transform: translateY(-56%);
position: relative;
top: 50%;
}
}
}
}
ul.breadcrumbs{
list-style: none;
padding: 0;
margin: 0;
li{
display: inline-block;
color: map-get($colors, primary_blue);
font-weight: bold !important;
font-size: 0.625rem;
}
li:after{
content: '\003e';
color: map-get($colors, dark_gray);
height: 0;
width: 0;
margin: 0 5px;
}
li:last-child:after{
content: none;
}
}
.custom-btn, .default{
background-color: map-get($colors, vived_blue_fe);
color: map-get($colors, white);
}
.default {
color: map-get($colors, white);
}
.custom-btn.play .arrow-right{
width: 0;
height: 0;
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
border-left: 14px solid map-get($colors, white);
margin-right: 8px;
}
.loading-backdrop {
.backdrop-container {
width: 100%;
padding: 16px;
text-align: center;
position: absolute;
top: 50%;
margin-top: -50px;
}
.backdrop-footer {
position: absolute;
width: 100%;
bottom: 0;
padding-bottom: 16px;
}
background-color: map-get($colors, white);
height: 100%;
z-index: 1000;
opacity: 1 !important;
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.downloadicon {
display: inline-block;
font-size: 1.1rem;
margin-top: -2px;
font-weight: 700;
vertical-align: middle;
}
.qr-result-btn{
display: block;
width: 100%;
padding: $base-block-space * 1;
font-weight: 700;
height: 3.2rem;
}
.sb-chapter-dd{
@include clearfix;
color: $blue;
font-weight: bolder;
box-shadow: 0 3px 5px 4px rgba(0, 0, 0, 0.05);
background-color: map-get($colors, white);
position: relative;
z-index: 10;
padding: 8px 8px 0px 16px;
font-size: 1.25rem;
.pull-left{
line-height: 1.88rem;
}
ion-icon{
height: 1.5rem;
width: 1.5rem;
border-radius: 12px;
font-size: 1.75rem;
color: orangered;
}
}
.offline{
opacity: 0.5;
}
.download-disabled{
opacity: 0.5 !important;
cursor: default;
}
.play-btn-info{
position: absolute;
margin-top: 2px;
}
}