UNPKG

@project-sunbird/sunbird-epub-player-v9

Version:

The Epub player library is powered by Angular. This player is primarily designed to be used on Sunbird consumption platforms _(mobile app, web portal, offline desktop app)_ to drive reusability and maintainability, hence reducing the redundant development

918 lines (907 loc) 48.9 kB
import * as i0 from '@angular/core'; import { Injectable, EventEmitter, Component, ViewChild, Input, Output, HostListener, NgModule } from '@angular/core'; import { CsTelemetryModule } from '@project-sunbird/client-services/telemetry'; import * as i3$1 from '@project-sunbird/sunbird-player-sdk-v9'; import { errorCode, errorMessage, PLAYER_CONFIG, SunbirdPlayerSdkModule } from '@project-sunbird/sunbird-player-sdk-v9'; import * as i3 from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http'; import * as i5 from '@angular/common'; import { CommonModule } from '@angular/common'; import Epub from 'epubjs'; var epubPlayerConstants; (function (epubPlayerConstants) { epubPlayerConstants["LOADING"] = "LOADING"; epubPlayerConstants["START"] = "START"; epubPlayerConstants["END"] = "END"; epubPlayerConstants["EPUBLOADED"] = "epubLoaded"; epubPlayerConstants["PAGECHANGE"] = "pageChange"; epubPlayerConstants["NEXT"] = "NEXT"; epubPlayerConstants["PREVIOUS"] = "PREVIOUS"; epubPlayerConstants["ERROR"] = "error"; epubPlayerConstants["UNABLE_TO_FETCH_URL_ONLINE"] = "Internet is avialable but unable to fetch the url"; epubPlayerConstants["NAVIGATE_TO_PAGE"] = "NAVIGATE_TO_PAGE"; epubPlayerConstants["INVALID_PAGE_ERROR"] = "INVALID_PAGE_ERROR"; })(epubPlayerConstants || (epubPlayerConstants = {})); var telemetryType; (function (telemetryType) { telemetryType["INTERACT"] = "INTERACT"; telemetryType["IMPRESSION"] = "IMPRESSION"; })(telemetryType || (telemetryType = {})); class UtilService { constructor() { this.fromConst = epubPlayerConstants; } uniqueId(length = 32) { let result = ''; const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; const charactersLength = characters.length; for (let i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; } getTimeSpentText(pdfPlayerStartTime) { const duration = new Date().getTime() - pdfPlayerStartTime; const minutes = Math.floor(duration / 60000); const seconds = Number(((duration % 60000) / 1000).toFixed(0)); return (minutes + ':' + (seconds < 10 ? '0' : '') + seconds); } getCurrentIndex(event, currentPageIndex) { if (event?.interaction === this.fromConst.NEXT) { return currentPageIndex + 1; } if (event?.interaction === this.fromConst.PREVIOUS) { return currentPageIndex - 1 === 0 ? 1 : currentPageIndex - 1; } } async fulfillWithTimeLimit(timeLimit, task, failureValue) { let timeout; const timeoutPromise = new Promise((resolve, reject) => { timeout = setTimeout(() => { resolve(failureValue); }, timeLimit); }); const response = await Promise.race([task, timeoutPromise]); if (timeout) { clearTimeout(timeout); } return response; } /** @nocollapse */ static { this.ɵfac = function UtilService_Factory(t) { return new (t || UtilService)(); }; } /** @nocollapse */ static { this.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: UtilService, factory: UtilService.ɵfac, providedIn: 'root' }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(UtilService, [{ type: Injectable, args: [{ providedIn: 'root' }] }], () => [], null); })(); class EpubPlayerService { constructor(utilService) { this.utilService = utilService; this.contentSessionId = this.utilService.uniqueId(); } initialize({ context, config, metadata }) { this.context = context; this.config = config; this.playSessionId = this.utilService.uniqueId(); this.channel = this.context.channel; this.pdata = this.context.pdata; this.sid = this.context.sid; this.uid = this.context.uid; this.rollup = this.context.rollup; if (!CsTelemetryModule.instance.isInitialised) { CsTelemetryModule.instance.init({}); const telemetryConfig = { config: { pdata: context.pdata, env: 'contentplayer', channel: context.channel, did: context.did, authtoken: context.authToken || '', uid: context.uid || '', sid: context.sid, batchsize: 20, mode: context.mode, host: context.host || '', endpoint: context.endpoint || '/data/v3/telemetry', tags: context.tags, cdata: [{ id: this.contentSessionId, type: 'ContentSession' }, { id: this.playSessionId, type: 'PlaySession' }, { id: '2.0', type: 'PlayerVersion' }], }, userOrgDetails: {} }; if (context.dispatcher) { telemetryConfig.config.dispatcher = context.dispatcher; } CsTelemetryModule.instance.telemetryService.initTelemetry(telemetryConfig); } this.telemetryObject = { id: metadata.identifier, type: 'Content', ver: metadata.pkgVersion + '' || '1.0', rollup: context.objectRollup || {} }; } start(duration) { CsTelemetryModule.instance.telemetryService.raiseStartTelemetry({ options: this.getEventOptions(), edata: { type: 'content', mode: 'play', pageid: '', duration: Number((duration / 1e3).toFixed(2)) } }); } interact(id, currentPage) { CsTelemetryModule.instance.telemetryService.raiseInteractTelemetry({ options: this.getEventOptions(), edata: { type: 'TOUCH', subtype: '', id, pageid: currentPage + '' } }); } impression(currentPage) { CsTelemetryModule.instance.telemetryService.raiseImpressionTelemetry({ options: this.getEventOptions(), edata: { type: 'workflow', subtype: '', pageid: currentPage + '', uri: '' } }); } end(duration, percentage, curentPage, endpageseen) { const durationSec = Number((duration / 1e3).toFixed(2)); CsTelemetryModule.instance.telemetryService.raiseEndTelemetry({ edata: { type: 'content', mode: 'play', pageid: 'sunbird-player-Endpage', summary: [ { progress: percentage }, { totallength: (percentage === 100 ? curentPage : 1) }, { visitedlength: curentPage }, { visitedcontentend: (percentage === 100) }, { totalseekedlength: 0 }, { endpageseen } ], duration: durationSec }, options: this.getEventOptions() }); } error(errorCode, errorType, pageid, stacktrace) { CsTelemetryModule.instance.telemetryService.raiseErrorTelemetry({ options: this.getEventOptions(), edata: { err: errorCode, errtype: errorType, stacktrace: stacktrace.toString(), pageid: pageid || '' } }); } getEventOptions() { return ({ object: this.telemetryObject, context: { channel: this.channel, pdata: this.pdata, env: 'contentplayer', sid: this.sid, uid: this.uid, cdata: [{ id: this.contentSessionId, type: 'ContentSession' }, { id: this.playSessionId, type: 'PlaySession' }, { id: '2.0', type: 'PlayerVersion' }], rollup: this.rollup || {} } }); } /** @nocollapse */ static { this.ɵfac = function EpubPlayerService_Factory(t) { return new (t || EpubPlayerService)(i0.ɵɵinject(UtilService)); }; } /** @nocollapse */ static { this.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: EpubPlayerService, factory: EpubPlayerService.ɵfac, providedIn: 'root' }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EpubPlayerService, [{ type: Injectable, args: [{ providedIn: 'root' }] }], () => [{ type: UtilService }], null); })(); class ViwerService { constructor(utilService, epubPlayerService, http) { this.utilService = utilService; this.epubPlayerService = epubPlayerService; this.http = http; this.currentIndex = 0; this.totalNumberOfPages = 0; this.endPageSeen = false; this.timeSpent = '0:0'; this.version = '1.0'; this.playerEvent = new EventEmitter(); this.isAvailableLocally = false; this.isEndEventRaised = false; } initialize({ context, config, metadata }) { this.epubPlayerStartTime = this.epubLastPageTime = new Date().getTime(); this.totalNumberOfPages = 0; this.currentIndex = 0; this.contentName = metadata.name; this.identifier = metadata.identifier; this.artifactUrl = metadata.artifactUrl; this.isAvailableLocally = metadata.isAvailableLocally; if (this.isAvailableLocally) { const basePath = (metadata.streamingUrl) ? (metadata.streamingUrl) : (metadata.basePath || metadata.baseDir); this.src = `${basePath}/${metadata.artifactUrl}`; } else { this.src = metadata.streamingUrl || metadata.artifactUrl; } if (context.userData) { const { userData: { firstName, lastName } } = context; this.userName = firstName === lastName ? firstName : `${firstName} ${lastName}`; } this.metaData = { pagesVisited: [], totalPages: 0, duration: [], zoom: [], rotation: [] }; this.showDownloadPopup = false; this.endPageSeen = false; } raiseStartEvent(event) { this.currentIndex = event.items[0].index; const duration = new Date().getTime() - this.epubPlayerStartTime; const startEvent = { eid: 'START', ver: this.version, edata: { type: 'START', currentPage: this.currentIndex, duration }, metaData: this.metaData }; this.playerEvent.emit(startEvent); this.epubLastPageTime = this.epubPlayerStartTime = new Date().getTime(); this.epubPlayerService.start(duration); } raiseHeartBeatEvent(event, teleType) { if (event.data) { this.currentIndex = event.data.index; } const eventType = event.type ? event.type : event; const heartBeatEvent = { eid: 'HEARTBEAT', ver: this.version, edata: { type: eventType, currentPage: this.currentIndex }, metaData: this.metaData }; this.playerEvent.emit(heartBeatEvent); if (telemetryType.IMPRESSION === teleType) { this.epubPlayerService.impression(this.currentIndex); } if (telemetryType.INTERACT === teleType) { this.epubPlayerService.interact(eventType.toLowerCase(), this.currentIndex); } } raiseEndEvent(event) { if (!this.isEndEventRaised) { this.currentIndex = event.data.index; const percentage = event.data.percentage || 0; if (event.data.percentage) { this.endPageSeen = true; } const duration = new Date().getTime() - this.epubPlayerStartTime; this.metaData.duration = duration; this.metaData.totalPages = this.totalNumberOfPages; const endEvent = { eid: 'END', ver: this.version, edata: { type: 'END', currentPage: event.data.index, totalPages: this.totalNumberOfPages, duration }, metaData: this.metaData }; this.playerEvent.emit(endEvent); const visitedlength = this.currentIndex; this.timeSpent = this.utilService.getTimeSpentText(this.epubPlayerStartTime); this.epubPlayerService.end(duration, percentage, this.currentIndex, this.endPageSeen); } } raiseExceptionLog(errorCode, pageIndex, errorType, traceId, stacktrace) { const exceptionLogEvent = { eid: 'ERROR', edata: { err: errorCode, errtype: errorType, requestid: traceId || '', stacktrace } }; this.playerEvent.emit(exceptionLogEvent); this.epubPlayerService.error(errorCode, errorType, pageIndex, stacktrace); } isValidEpubSrc(src) { return new Promise(async (resolve, reject) => { this.http.get(src, { responseType: 'blob' }).toPromise().then((res) => { resolve(res); }).catch((error) => { reject(error); }); }); } /** @nocollapse */ static { this.ɵfac = function ViwerService_Factory(t) { return new (t || ViwerService)(i0.ɵɵinject(UtilService), i0.ɵɵinject(EpubPlayerService), i0.ɵɵinject(i3.HttpClient)); }; } /** @nocollapse */ static { this.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: ViwerService, factory: ViwerService.ɵfac, providedIn: 'root' }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViwerService, [{ type: Injectable, args: [{ providedIn: 'root' }] }], () => [{ type: UtilService }, { type: EpubPlayerService }, { type: i3.HttpClient }], null); })(); const _c0$1 = ["epubViewer"]; const MAX_TIME_TO_LOAD_SPINE = 5 * 60 * 1000; // 5 minutes class EpubViewerComponent { constructor(viwerService, utilService) { this.viwerService = viwerService; this.utilService = utilService; this.actions = new EventEmitter(); this.showFullScreen = false; this.viewerEvent = new EventEmitter(); } ngOnInit() { this.idForRendition = `${this.identifier}-content`; } ngOnChanges(changes) { if (this.rendition && !changes?.showFullScreen?.firstChange) { this.rendition.resize(); } } async ngAfterViewInit() { try { if (!this.viwerService.isAvailableLocally) { this.epubBlob = await this.viwerService.isValidEpubSrc(this.epubSrc); this.eBook = Epub(this.epubBlob); } else if (this.viwerService.isAvailableLocally) { this.eBook = Epub(this.epubSrc); } this.rendition = this.eBook.renderTo(this.idForRendition, { flow: 'paginated', width: '100%', }); this.rendition.on('layout', (layout) => { this.viwerService.totalNumberOfPages = this.eBook?.navigation?.length; if (this.eBook.navigation.length > 2) { this.rendition.spread('none'); this.rendition.flow('scrolled'); this.scrolled = true; } else { this.rendition.spread('auto'); this.scrolled = false; } }); this.rendition.on('displayError', (error) => { this.emitErrorEvent(); }); const spine = await this.utilService.fulfillWithTimeLimit(MAX_TIME_TO_LOAD_SPINE, this.eBook.loaded.spine, null); if (spine) { this.displayEpub(); this.lastSection = spine.last(); this.viewerEvent.emit({ type: epubPlayerConstants.EPUBLOADED, data: spine }); this.handleActions(spine); } else { this.emitErrorEvent(); } } catch (error) { this.emitErrorEvent(); } } displayEpub() { const { currentLocation } = this.config; if (!currentLocation) { this.rendition.display(); } this.eBook.ready.then(() => { return this.eBook.locations.generate(1000); }).then((locations) => { const totalPages = this.eBook?.spine?.length; this.viwerService.totalNumberOfPages = totalPages ? (totalPages - 1) : 0; if (currentLocation) { const cfi = this.eBook.locations.cfiFromPercentage(Number(currentLocation)); this.rendition.display(cfi); } }); } handleActions(spine) { this.actions.subscribe((event) => { const type = event.type; if (this.rendition?.location?.start) { const data = this.rendition.location.start; if (this.scrolled && data.href === this.lastSection.href) { this.viwerService.metaData.currentLocation = 0; this.emitEndEvent(); } else { if (this.rendition.location.atEnd || (spine.length === 1 && (this.rendition.location.end.displayed.page + 1 >= this.rendition.location.end.displayed.total))) { this.viwerService.metaData.currentLocation = 0; this.emitEndEvent(); } } if (type === epubPlayerConstants.NEXT) { this.rendition.next().then(() => { this.saveCurrentLocation(); this.viewerEvent.emit({ type: epubPlayerConstants.PAGECHANGE, data, interaction: epubPlayerConstants.NEXT }); }); } else if (type === epubPlayerConstants.PREVIOUS) { this.rendition.prev().then(() => { this.saveCurrentLocation(); this.viewerEvent.emit({ type: epubPlayerConstants.PAGECHANGE, data, interaction: epubPlayerConstants.PREVIOUS }); }); } if (type === epubPlayerConstants.NAVIGATE_TO_PAGE) { this.rendition.display(event.data); this.viewerEvent.emit({ type: epubPlayerConstants.NAVIGATE_TO_PAGE, event, interaction: epubPlayerConstants.NAVIGATE_TO_PAGE }); } if (type === epubPlayerConstants.INVALID_PAGE_ERROR) { this.viewerEvent.emit({ type: epubPlayerConstants.INVALID_PAGE_ERROR, event, interaction: epubPlayerConstants.INVALID_PAGE_ERROR }); } } }); } saveCurrentLocation() { const currentLocation = this.rendition.currentLocation(); if (currentLocation?.start?.cfi) { // Get the Percentage (or location) from that CFI const currentPageLocation = this.eBook.locations.percentageFromCfi(currentLocation.start.cfi); this.viwerService.metaData.currentLocation = currentPageLocation; } } emitEndEvent() { this.viewerEvent.emit({ type: epubPlayerConstants.END, data: { percentage: 100 } }); } emitErrorEvent() { this.viewerEvent.emit({ type: epubPlayerConstants.ERROR, errorCode: errorCode.contentLoadFails, errorMessage: errorMessage.contentLoadFails }); } ngOnDestroy() { this.eBook?.destroy(); } /** @nocollapse */ static { this.ɵfac = function EpubViewerComponent_Factory(t) { return new (t || EpubViewerComponent)(i0.ɵɵdirectiveInject(ViwerService), i0.ɵɵdirectiveInject(UtilService)); }; } /** @nocollapse */ static { this.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: EpubViewerComponent, selectors: [["epub-viewer"]], viewQuery: function EpubViewerComponent_Query(rf, ctx) { if (rf & 1) { i0.ɵɵviewQuery(_c0$1, 7); } if (rf & 2) { let _t; i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.epubViewer = _t.first); } }, inputs: { epubSrc: "epubSrc", config: "config", identifier: "identifier", actions: "actions", showFullScreen: "showFullScreen" }, outputs: { viewerEvent: "viewerEvent" }, features: [i0.ɵɵNgOnChangesFeature], decls: 2, vars: 1, consts: [["epubViewer", ""], [1, "rendition", 3, "id"]], template: function EpubViewerComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelement(0, "div", 1, 0); } if (rf & 2) { i0.ɵɵproperty("id", ctx.idForRendition); } } }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EpubViewerComponent, [{ type: Component, args: [{ selector: 'epub-viewer', template: "<div class=\"rendition\" [id]=\"idForRendition\" #epubViewer></div>" }] }], () => [{ type: ViwerService }, { type: UtilService }], { epubViewer: [{ type: ViewChild, args: ['epubViewer', { static: true }] }], epubSrc: [{ type: Input }], config: [{ type: Input }], identifier: [{ type: Input }], actions: [{ type: Input }], showFullScreen: [{ type: Input }], viewerEvent: [{ type: Output }] }); })(); (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EpubViewerComponent, { className: "EpubViewerComponent", filePath: "lib/epub-viewer/epub-viewer.component.ts", lineNumber: 16 }); })(); const _c0 = ["epubPlayer"]; const _c1 = a0 => ({ "isVisible": a0 }); function EpubPlayerComponent_div_2_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div"); i0.ɵɵelement(1, "sb-player-start-page", 6); i0.ɵɵelementEnd(); } if (rf & 2) { const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵadvance(); i0.ɵɵproperty("title", ctx_r0.viwerService.contentName)("progress", ctx_r0.progress); } } function EpubPlayerComponent_div_3_ng_container_1_div_4_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 13); i0.ɵɵtext(1); i0.ɵɵelement(2, "span"); i0.ɵɵtext(3); i0.ɵɵelementEnd(); } if (rf & 2) { const ctx_r0 = i0.ɵɵnextContext(3); i0.ɵɵadvance(); i0.ɵɵtextInterpolate2(" Page ", ctx_r0.currentPageIndex, " of ", ctx_r0.viwerService == null ? null : ctx_r0.viwerService.totalNumberOfPages, " "); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate1(" ", (ctx_r0.currentPageIndex / (ctx_r0.viwerService == null ? null : ctx_r0.viwerService.totalNumberOfPages) * 100).toFixed(0), "% "); } } function EpubPlayerComponent_div_3_ng_container_1_Template(rf, ctx) { if (rf & 1) { const _r3 = i0.ɵɵgetCurrentView(); i0.ɵɵelementContainerStart(0); i0.ɵɵelementStart(1, "sb-player-header", 9); i0.ɵɵlistener("actions", function EpubPlayerComponent_div_3_ng_container_1_Template_sb_player_header_actions_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.headerActions($event)); }); i0.ɵɵelementEnd(); i0.ɵɵelementStart(2, "sb-player-side-menu-icon", 10); i0.ɵɵlistener("sidebarMenuEvent", function EpubPlayerComponent_div_3_ng_container_1_Template_sb_player_side_menu_icon_sidebarMenuEvent_2_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.sidebarMenuEvent($event)); }); i0.ɵɵelementEnd(); i0.ɵɵelementStart(3, "sb-player-sidebar", 11); i0.ɵɵlistener("sidebarEvent", function EpubPlayerComponent_div_3_ng_container_1_Template_sb_player_sidebar_sidebarEvent_3_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.sideBarEvents($event)); }); i0.ɵɵelementEnd(); i0.ɵɵtemplate(4, EpubPlayerComponent_div_3_ng_container_1_div_4_Template, 4, 3, "div", 12); i0.ɵɵelementContainerEnd(); } if (rf & 2) { const ctx_r0 = i0.ɵɵnextContext(2); i0.ɵɵadvance(); i0.ɵɵproperty("totalPages", ctx_r0.viwerService == null ? null : ctx_r0.viwerService.totalNumberOfPages)("pageNumber", ctx_r0.currentPageIndex)("config", ctx_r0.headerConfiguration)("ngClass", i0.ɵɵpureFunction1(8, _c1, ctx_r0.showControls)); i0.ɵɵadvance(); i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(10, _c1, ctx_r0.showControls)); i0.ɵɵadvance(); i0.ɵɵproperty("title", ctx_r0.viwerService.contentName)("config", ctx_r0.sideMenuConfig); i0.ɵɵadvance(); i0.ɵɵproperty("ngIf", ctx_r0.currentPageIndex && (ctx_r0.viwerService == null ? null : ctx_r0.viwerService.totalNumberOfPages)); } } function EpubPlayerComponent_div_3_Template(rf, ctx) { if (rf & 1) { const _r2 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div", 7); i0.ɵɵtemplate(1, EpubPlayerComponent_div_3_ng_container_1_Template, 5, 12, "ng-container", 2); i0.ɵɵelementStart(2, "epub-viewer", 8); i0.ɵɵlistener("viewerEvent", function EpubPlayerComponent_div_3_Template_epub_viewer_viewerEvent_2_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.viewerEvent($event)); }); i0.ɵɵelementEnd()(); } if (rf & 2) { const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵadvance(); i0.ɵɵproperty("ngIf", ctx_r0.viewState === ctx_r0.fromConst.START); i0.ɵɵadvance(); i0.ɵɵproperty("actions", ctx_r0.headerActionsEvent)("epubSrc", ctx_r0.viwerService.src)("identifier", ctx_r0.viwerService.identifier)("config", ctx_r0.playerConfig.config)("showFullScreen", ctx_r0.showFullScreen); } } function EpubPlayerComponent_sb_player_end_page_4_Template(rf, ctx) { if (rf & 1) { const _r4 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "sb-player-end-page", 14); i0.ɵɵlistener("replayContent", function EpubPlayerComponent_sb_player_end_page_4_Template_sb_player_end_page_replayContent_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.replayContent($event)); })("exitContent", function EpubPlayerComponent_sb_player_end_page_4_Template_sb_player_end_page_exitContent_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.exitContent($event)); }); i0.ɵɵelementEnd(); } if (rf & 2) { const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵproperty("contentName", ctx_r0.viwerService.contentName)("outcomeLabel", "Pages read: ")("outcome", ctx_r0.currentPageIndex - 1)("showExit", ctx_r0.sideMenuConfig.showExit)("userName", ctx_r0.viwerService.userName)("timeSpentLabel", ctx_r0.viwerService.timeSpent); } } function EpubPlayerComponent_sb_player_contenterror_5_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelement(0, "sb-player-contenterror"); } } function EpubPlayerComponent_div_6_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 15); i0.ɵɵelement(1, "div", 16); i0.ɵɵelementStart(2, "div", 17); i0.ɵɵtext(3, "Page Not Found"); i0.ɵɵelementEnd()(); } } class EpubPlayerComponent { constructor(viwerService, epubPlayerService, errorService, utilService, renderer2) { this.viwerService = viwerService; this.epubPlayerService = epubPlayerService; this.errorService = errorService; this.utilService = utilService; this.renderer2 = renderer2; this.fromConst = epubPlayerConstants; this.showFullScreen = false; this.headerActionsEvent = new EventEmitter(); this.telemetryEvent = new EventEmitter(); this.showControls = true; this.validPage = true; this.sideMenuConfig = { showShare: false, showDownload: false, showReplay: false, showExit: false, showPrint: false }; this.isInitialized = false; this.viewState = this.fromConst.LOADING; this.progress = 0; this.currentPageIndex = 1; this.headerConfiguration = { rotation: false, goto: true, navigation: true, zoom: false }; this.playerEvent = this.viwerService.playerEvent; } onTelemetryEvent(event) { this.telemetryEvent.emit(event.detail); } async ngOnInit() { this.isInitialized = true; if (this.playerConfig) { if (typeof this.playerConfig === 'string') { try { this.playerConfig = JSON.parse(this.playerConfig); } catch (error) { console.error('Invalid playerConfig: ', error); } } // initializing services this.viwerService.initialize(this.playerConfig); this.epubPlayerService.initialize(this.playerConfig); this.traceId = this.playerConfig?.config?.traceId; // checks online error while loading epub if (!navigator.onLine && !this.viwerService.isAvailableLocally) { // eslint-disable-next-line max-len this.viwerService.raiseExceptionLog(errorCode.internetConnectivity, this.currentPageIndex, errorMessage.internetConnectivity, this.traceId, new Error(errorMessage.internetConnectivity)); } // checks content compatibility error const contentCompabilityLevel = this.playerConfig?.metadata?.compatibilityLevel; if (contentCompabilityLevel) { const checkContentCompatible = this.errorService.checkContentCompatibility(contentCompabilityLevel); if (!checkContentCompatible?.isCompitable) { // eslint-disable-next-line max-len this.viwerService.raiseExceptionLog(errorCode.contentCompatibility, this.currentPageIndex, errorCode.contentCompatibility, this.traceId, checkContentCompatible.error); } } this.showEpubViewer = true; this.sideMenuConfig = { ...this.sideMenuConfig, ...this.playerConfig.config.sideMenu }; this.getEpubLoadingProgress(); } } ngOnChanges(changes) { if (changes.showFullScreen && !changes?.showFullScreen?.firstChange) { this.showFullScreen = changes.showFullScreen.currentValue; } if (changes.playerConfig.firstChange && this.isInitialized) { // Calling for web component explicitly and life cycle works in different order this.ngOnInit(); } } ngAfterViewInit() { const epubPlayerElement = this.epubPlayerRef.nativeElement; this.unlistenMouseEnter = this.renderer2.listen(epubPlayerElement, 'mouseenter', () => { this.showControls = true; }); this.unlistenMouseLeave = this.renderer2.listen(epubPlayerElement, 'mouseleave', () => { this.showControls = false; }); } headerActions(eventdata) { this.headerActionsEvent.emit(eventdata); } viewerEvent(event) { if (event.type === this.fromConst.EPUBLOADED) { this.onEpubLoaded(event); } if (event.type === this.fromConst.PAGECHANGE) { this.onPageChange(event); } if (event.type === this.fromConst.END) { this.onEpubEnded(event); } if (event.type === this.fromConst.ERROR) { this.onEpubLoadFailed(event); } if (event.type === this.fromConst.NAVIGATE_TO_PAGE) { this.onJumpToPage(event); } if (event.type === this.fromConst.INVALID_PAGE_ERROR) { this.validPage = event.data; this.resetValidPage(); } } resetValidPage() { setTimeout(() => { this.validPage = true; }, 5000); } onEpubLoaded(event) { clearInterval(this.intervalRef); this.viewState = this.fromConst.START; this.viwerService.raiseStartEvent(event.data); if (this.playerConfig.config?.pagesVisited?.length && this.playerConfig.config?.currentLocation) { this.currentPageIndex = this.playerConfig.config.pagesVisited[this.playerConfig.config.pagesVisited.length - 1]; } this.viwerService.metaData.pagesVisited.push(this.currentPageIndex); } onPageChange(event) { if (event?.data?.index) { this.currentPageIndex = event.data.index; } this.currentPageIndex = this.utilService.getCurrentIndex(event, this.currentPageIndex); this.viwerService.raiseHeartBeatEvent(event, telemetryType.INTERACT); this.viwerService.raiseHeartBeatEvent(event, telemetryType.IMPRESSION); this.viwerService.metaData.pagesVisited.push(this.currentPageIndex); } onJumpToPage(type) { this.currentPageIndex = type?.event?.data; this.viwerService.raiseHeartBeatEvent(type, telemetryType.INTERACT); this.viwerService.raiseHeartBeatEvent(type, telemetryType.IMPRESSION); this.viwerService.metaData.pagesVisited.push(this.currentPageIndex); } onEpubEnded(event) { this.viewState = this.fromConst.END; this.showEpubViewer = false; event.data.index = this.currentPageIndex; this.viwerService.raiseEndEvent(event); } onEpubLoadFailed(error) { this.showContentError = true; this.viewState = this.fromConst.LOADING; // eslint-disable-next-line max-len this.viwerService.raiseExceptionLog(error.errorCode, this.currentPageIndex, error.errorMessage, this.traceId, new Error(error.errorMessage)); } replayContent(event) { this.currentPageIndex = 1; this.viwerService.raiseHeartBeatEvent(event, telemetryType.INTERACT); this.viewState = this.fromConst.START; this.viwerService.metaData.pagesVisited.push(this.currentPageIndex); this.ngOnInit(); } exitContent(event) { this.viwerService.raiseHeartBeatEvent(event, telemetryType.INTERACT); } sideBarEvents(event) { this.viwerService.raiseHeartBeatEvent(event, telemetryType.INTERACT); if (event.type === 'DOWNLOAD') { this.downloadEpub(); } } sidebarMenuEvent(event) { this.viwerService.raiseHeartBeatEvent(event, telemetryType.INTERACT); } getEpubLoadingProgress() { this.intervalRef = setInterval(() => { if (this.progress < 95) { this.progress = this.progress + 5; } }, 10); } downloadEpub() { const a = document.createElement('a'); a.href = this.viwerService.artifactUrl; a.download = this.viwerService.contentName; a.target = '_blank'; document.body.appendChild(a); a.click(); a.remove(); this.viwerService.raiseHeartBeatEvent('DOWNLOAD'); } ngOnDestroy() { const EndEvent = { type: this.fromConst.END, data: { index: this.currentPageIndex } }; this.viwerService.raiseEndEvent(EndEvent); this.viwerService.isEndEventRaised = false; this.unlistenMouseEnter(); this.unlistenMouseLeave(); } /** @nocollapse */ static { this.ɵfac = function EpubPlayerComponent_Factory(t) { return new (t || EpubPlayerComponent)(i0.ɵɵdirectiveInject(ViwerService), i0.ɵɵdirectiveInject(EpubPlayerService), i0.ɵɵdirectiveInject(i3$1.ErrorService), i0.ɵɵdirectiveInject(UtilService), i0.ɵɵdirectiveInject(i0.Renderer2)); }; } /** @nocollapse */ static { this.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: EpubPlayerComponent, selectors: [["sunbird-epub-player"]], viewQuery: function EpubPlayerComponent_Query(rf, ctx) { if (rf & 1) { i0.ɵɵviewQuery(_c0, 7); } if (rf & 2) { let _t; i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.epubPlayerRef = _t.first); } }, hostBindings: function EpubPlayerComponent_HostBindings(rf, ctx) { if (rf & 1) { i0.ɵɵlistener("TelemetryEvent", function EpubPlayerComponent_TelemetryEvent_HostBindingHandler($event) { return ctx.onTelemetryEvent($event); }, false, i0.ɵɵresolveDocument)("beforeunload", function EpubPlayerComponent_beforeunload_HostBindingHandler() { return ctx.ngOnDestroy(); }, false, i0.ɵɵresolveWindow); } }, inputs: { playerConfig: "playerConfig", showFullScreen: "showFullScreen" }, outputs: { headerActionsEvent: "headerActionsEvent", telemetryEvent: "telemetryEvent", playerEvent: "playerEvent" }, features: [i0.ɵɵNgOnChangesFeature], decls: 7, vars: 5, consts: [["epubPlayer", ""], [1, "sunbird-epub-container"], [4, "ngIf"], ["class", "epub-container", 4, "ngIf"], [3, "contentName", "outcomeLabel", "outcome", "showExit", "userName", "timeSpentLabel", "replayContent", "exitContent", 4, "ngIf"], ["class", "pagenotfound__tooltip", 4, "ngIf"], [3, "title", "progress"], [1, "epub-container"], [3, "viewerEvent", "actions", "epubSrc", "identifier", "config", "showFullScreen"], [1, "notVisible", 3, "actions", "totalPages", "pageNumber", "config", "ngClass"], [1, "notVisible", 3, "sidebarMenuEvent", "ngClass"], [3, "sidebarEvent", "title", "config"], ["class", "sb-epub-reading-status", 4, "ngIf"], [1, "sb-epub-reading-status"], [3, "replayContent", "exitContent", "contentName", "outcomeLabel", "outcome", "showExit", "userName", "timeSpentLabel"], [1, "pagenotfound__tooltip"], [1, "pagenotfound__icon"], [1, "pagenotfound__text"]], template: function EpubPlayerComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 1, 0); i0.ɵɵtemplate(2, EpubPlayerComponent_div_2_Template, 2, 2, "div", 2)(3, EpubPlayerComponent_div_3_Template, 3, 6, "div", 3)(4, EpubPlayerComponent_sb_player_end_page_4_Template, 1, 6, "sb-player-end-page", 4)(5, EpubPlayerComponent_sb_player_contenterror_5_Template, 1, 0, "sb-player-contenterror", 2); i0.ɵɵelementEnd(); i0.ɵɵtemplate(6, EpubPlayerComponent_div_6_Template, 4, 0, "div", 5); } if (rf & 2) { i0.ɵɵadvance(2); i0.ɵɵproperty("ngIf", ctx.viewState === ctx.fromConst.LOADING); i0.ɵɵadvance(); i0.ɵɵproperty("ngIf", ctx.showEpubViewer); i0.ɵɵadvance(); i0.ɵɵproperty("ngIf", ctx.viewState === ctx.fromConst.END); i0.ɵɵadvance(); i0.ɵɵproperty("ngIf", ctx.showContentError); i0.ɵɵadvance(); i0.ɵɵproperty("ngIf", !ctx.validPage); } }, dependencies: [i5.NgClass, i5.NgIf, i3$1.StartPageComponent, i3$1.EndPageComponent, i3$1.SidebarComponent, i3$1.SideMenuIconComponent, i3$1.HeaderComponent, i3$1.ContenterrorComponent, EpubViewerComponent], styles: [".sunbird-epub-container[_ngcontent-%COMP%]{height:100%;width:100%;background-color:#fff}.sunbird-epub-palyer-container[_ngcontent-%COMP%]{width:100%;height:100%;overflow:hidden;position:relative}.sb-epub-reading-status[_ngcontent-%COMP%]{color:var(--gray-800);font-size:.75rem;position:absolute;left:1rem;bottom:.75rem;display:flex;-webkit-box-align:center;align-items:center;background:var(--white);border-radius:.5rem;padding:.25em .5rem;z-index:5;line-height:normal}.sb-epub-reading-status[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{background:var(--gray-800);width:4px;height:4px;display:block;margin:0 .5em;border-radius:50%}.notVisible[_ngcontent-%COMP%], .BtmNotVisible[_ngcontent-%COMP%]{transition:all .3s ease-in-out;position:absolute;width:100%}.notVisible[_ngcontent-%COMP%]{top:-10rem}.notVisible.isVisible[_ngcontent-%COMP%]{top:0rem}.BtmNotVisible[_ngcontent-%COMP%]{bottom:-10rem}.BtmNotVisible.isVisible[_ngcontent-%COMP%]{bottom:0rem}[_nghost-%COMP%] .sb-player-splash-container{height:100vh!important}[_nghost-%COMP%] epub-viewer{position:absolute;top:48px;width:100%;height:calc(100% - 48px);overflow-y:auto;overflow-x:hidden;left:0;background-color:#fff;overflow-y:scroll!important}[_nghost-%COMP%] .epub-container{height:100%;position:relative;overflow-x:hidden!important}.pagenotfound__tooltip[_ngcontent-%COMP%]{position:absolute;top:10%;left:50%;transform:translate(-50%);background:#333;z-index:11111;padding:calculateRem(8px) calculateRem(20px);font-size:calculateRem(14px);color:#fff;border-radius:calculateRem(4px);display:flex;align-items:center}.pagenotfound__icon[_ngcontent-%COMP%]{width:calculateRem(22px);height:calculateRem(22px);margin-right:calculateRem(12px);background:#fff;border-radius:50%;position:relative}.pagenotfound__icon[_ngcontent-%COMP%]:after{content:\"!\";position:absolute;top:50%;left:50%;color:#333;font-size:18px;transform:translate(-50%,-50%)}"] }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EpubPlayerComponent, [{ type: Component, args: [{ selector: 'sunbird-epub-player', template: "<div class=\"sunbird-epub-container\" #epubPlayer>\n<div *ngIf=\"viewState === fromConst.LOADING\">\n <sb-player-start-page [title]=\"viwerService.contentName\" [progress]=\"progress\"></sb-player-start-page>\n</div>\n<div class=\"epub-container\" *ngIf=\"showEpubViewer\">\n <ng-container *ngIf=\"viewState === fromConst.START\">\n <sb-player-header class=\"notVisible\" [totalPages]=\"viwerService?.totalNumberOfPages\" [pageNumber]=\"currentPageIndex\" [config]=\"headerConfiguration\" (actions)=\"headerActions($event)\" [ngClass]=\"{'isVisible': showControls}\"></sb-player-header>\n <sb-player-side-menu-icon class=\"notVisible\" [ngClass]=\"{'isVisible': showControls}\" (sidebarMenuEvent)=\"sidebarMenuEvent($event)\">\n </sb-player-side-menu-icon>\n <sb-player-sidebar [title]=\"viwerService.contentName\" (sidebarEvent)=\"sideBarEvents($event)\"\n [config]=\"sideMenuConfig\"></sb-player-sidebar>\n <div class=\"sb-epub-reading-status\" *ngIf=\"currentPageIndex && viwerService?.totalNumberOfPages\">\n Page {{currentPageIndex}} of {{viwerService?.totalNumberOfPages}} <span></span> {{((currentPageIndex/viwerService?.totalNumberOfPages) * 100).toFixed(0)}}%\n </div>\n \n </ng-container>\n <epub-viewer [actions]=\"headerActionsEvent\" [epubSrc]=\"viwerService.src\" [identifier]=\"viwerService.identifier\"\n (viewerEvent)=\"viewerEvent($event)\" [config]=\"playerConfig.config\" [showFullScreen]=\"showFullScreen\">\n </epub-viewer>\n</div>\n<sb-player-end-page *ngIf=\"viewState === fromConst.END\" [contentName]=\"viwerService.contentName\"\n [outcomeLabel]=\"'Pages read: '\" [outcome]=\"(currentPageIndex -1)\" [showExit]=\"sideMenuConfig.showExit\" [userName]=\"viwerService.userName\"\n [timeSpentLabel]=\"viwerService.timeSpent\" (replayContent)=\"replayContent($event)\" (exitContent)=\"exitContent($event)\">\n</sb-player-end-page>\n<sb-player-contenterror *ngIf=\"showContentError\"></sb-player-contenterror>\n</div>\n<div class=\"pagenotfound__tooltip\" *ngIf=\"!validPage\">\n <div class=\"pagenotfound__icon\"></div>\n <div class=\"pagenotfound__text\">Page Not Found</div>\n</div>\n", styles: [".sunbird-epub-container{height:100%;width:100%;background-color:#fff}.sunbird-epub-palyer-container{width:100%;height:100%;overflow:hidden;position:relative}.sb-epub-reading-status{color:var(--gray-800);font-size:.75rem;position:absolute;left:1rem;bottom:.75rem;display:flex;-webkit-box-align:center;align-items:center;background:var(--white);border-radius:.5rem;padding:.25em .5rem;z-index:5;line-height:normal}.sb-epub-reading-status span{background:var(--gray-800);width:4px;height:4px;display:block;margin:0 .5em;border-radius:50%}.notVisible,.BtmNotVisible{transition:all .3s ease-in-out;position:absolute;width:100%}.notVisible{top:-10rem}.notVisible.isVisible{top:0rem}.BtmNotVisible{bottom:-10rem}.BtmNotVisible.isVisible{bottom:0rem}:host::ng-deep .sb-player-splash-container{height:100vh!important}:host::ng-deep epub-viewer{position:absolute;top:48px;width:100%;height:calc(100% - 48px);overflow-y:auto;overflow-x:hidden;left:0;background-color:#fff;overflow-y:scroll!important}:host::ng-deep .epub-container{height:100%;position:relative;overflow-x:hidden!important}.pagenotfound__tooltip{position:absolute;top:10%;left:50%;transform:translate(-50%);background:#333;z-index:11111;padding:calculateRem(8px) calculateRem(20px);font-size:calculateRem(14px);color:#fff;border-radius:calculateRem(4px);display:flex;align-items:center}.pagenotfound__icon{width:calculateRem(22px);height:calculateRem(22px);margin-right:calculateRem(12px);background:#fff;border-radius:50%;position:relative}.pagenotfound__icon:after{content:\"!\";position:absolute;top:50%;left:50%;color:#333;font-size:18px;transform:translate(-50%,-50%)}\n"] }] }], () => [{ type: ViwerService }, { type: EpubPlayerService }, { type: i3$1.ErrorService }, { type: UtilService }, { type: i0.Renderer2 }], { epubPlayerRef: [{ type: ViewChild, args: ['epubPlayer', { static: true }] }], playerConfig: [{ type: Input }], showFullScreen: [{ type: Input }], headerActionsEvent: [{ type: Output }], telemetryEvent: [{ type: Output }], playerEvent: [{ type: Output }], onTelemetryEvent: [{ type: HostListener, args: ['document:TelemetryEvent', ['$event']] }], ngOnDestroy: [{ type: HostListener, args: ['window:beforeunload'] }] }); })(); (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EpubPlayerComponent, { className: "EpubPlayerComponent", filePath: "lib/sunbird-epub-player.component.ts", lineNumber: 17 }); })(); class SunbirdEpubPlayerModule { /** @nocollapse */ static { this.ɵfac = function SunbirdEpubPlayerModule_Factory(t) { return new (t || SunbirdEpubPlayerModule)(); }; } /** @nocollapse */ static { this.ɵmod = /** @pureOrBreakMyCode */ i0.ɵɵdefineNgModule({ type: SunbirdEpubPlayerModule }); } /** @nocollapse */ static { this.ɵinj = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjector({ providers: [{ provide: PLAYER_CONFIG, useValue: { contentCompatibilityLevel: 5 } }], imports: [CommonModule, SunbirdPlayerSdkModule, HttpClientModule] }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SunbirdEpubPlayerModule, [{ type: NgModule, args: [{ declarations: [EpubPlayerComponent, EpubViewerComponent], imports: [ CommonModule, SunbirdPlayerSdkModule, HttpClientModule ], providers: [{ provide: PLAYER_CONFIG, useValue: { contentCompatibilityLevel: 5 } }], exports: [EpubPlayerComponent] }] }], null, null); })(); (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(SunbirdEpubPlayerModule, { declarations: [EpubPlayerComponent, EpubViewerComponent], imports: [CommonModule, SunbirdPlayerSdkModule, HttpClientModule], exports: [EpubPlayerComponent] }); })(); /* * Public API Surface of epub-player */ /** * Generated bundle index. Do not edit. */ export { EpubPlayerComponent, EpubPlayerService, SunbirdEpubPlayerModule }; //# sourceMappingURL=project-sunbird-sunbird-epub-player-v9.mjs.map