From b633ced0fa9332943a3e1efa5c70098ef5d35ddc Mon Sep 17 00:00:00 2001 From: Rajnish Dargan Date: Thu, 8 Feb 2024 19:44:12 +0530 Subject: [PATCH] Quml-player offline play --- .../section-player.component.ts | 14 ++-- .../viewer-service/viewer-service.spec.ts | 27 ++++---- .../services/viewer-service/viewer-service.ts | 69 ++++++++++++++++--- 3 files changed, 80 insertions(+), 30 deletions(-) diff --git a/projects/quml-library/src/lib/section-player/section-player.component.ts b/projects/quml-library/src/lib/section-player/section-player.component.ts index d79551bc..9fe9c8b3 100644 --- a/projects/quml-library/src/lib/section-player/section-player.component.ts +++ b/projects/quml-library/src/lib/section-player/section-player.component.ts @@ -242,9 +242,9 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { if (this.jumpToQuestion) { this.goToQuestion(this.jumpToQuestion); } else if (this.threshold === 1) { - this.viewerService.getQuestion(); + this.viewerService.getQuestion(this.sectionConfig?.metadata?.children); } else if (this.threshold > 1) { - this.viewerService.getQuestions(); + this.viewerService.getQuestions(this.sectionConfig?.metadata?.children); } if (!this.sectionConfig.metadata?.children?.length) { @@ -362,16 +362,16 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { if (this.myCarousel.getCurrentSlideIndex() > 0 && ((this.threshold * this.noOfTimesApiCalled) - 1) === this.myCarousel.getCurrentSlideIndex() && this.threshold * this.noOfTimesApiCalled >= this.questions.length && this.threshold > 1) { - this.viewerService.getQuestions(); + this.viewerService.getQuestions(this.sectionConfig?.metadata?.children); } if (this.myCarousel.getCurrentSlideIndex() > 0 && this.questions[this.myCarousel.getCurrentSlideIndex()] === undefined && this.threshold > 1) { - this.viewerService.getQuestions(); + this.viewerService.getQuestions(this.sectionConfig?.metadata?.children); } if (this.threshold === 1 && this.myCarousel.getCurrentSlideIndex() >= 0) { - this.viewerService.getQuestion(); + this.viewerService.getQuestion(this.sectionConfig?.metadata?.children); } } @@ -767,7 +767,7 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { if (this.questions[index - 1] === undefined) { this.showQuestions = false; - this.viewerService.getQuestions(0, index); + this.viewerService.getQuestions(this.sectionConfig?.metadata?.children, 0, index); this.currentSlideIndex = index; } else if (this.questions[index - 1] !== undefined) { this.myCarousel.selectSlide(index); @@ -783,7 +783,7 @@ export class SectionPlayerComponent implements OnChanges, AfterViewInit { this.disableNext = false; this.initializeTimer = true; const index = event.questionNo; - this.viewerService.getQuestions(0, index); + this.viewerService.getQuestions(this.sectionConfig?.metadata?.children, 0 , index); this.currentSlideIndex = index; this.myCarousel.selectSlide(index); this.highlightQuestion(); diff --git a/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts b/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts index f35e9a65..f37df96e 100644 --- a/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts +++ b/projects/quml-library/src/lib/services/viewer-service/viewer-service.spec.ts @@ -5,6 +5,7 @@ import { QumlLibraryService } from '../../quml-library.service'; import { UtilService } from '../../util-service'; import { QuestionCursor } from '../../quml-question-cursor.service'; import { of, throwError } from 'rxjs'; +import { TransformationService } from '../transformation-service/transformation.service'; describe('ViewerService', () => { class MockQuestionCursor { @@ -205,7 +206,7 @@ describe('ViewerService', () => { service.identifiers = ['do_123', 'do_124']; spyOn(service.questionCursor, 'getQuestion').and.returnValue(of([{ id: 'do_123' }, { id: 'do_124' }] as any)); spyOn(service.qumlQuestionEvent, 'emit'); - service.getQuestion(); + service.getQuestion(mockData.playerConfig.metadata.children); expect(service.qumlQuestionEvent.emit).toHaveBeenCalled(); expect(service.questionCursor.getQuestion).toHaveBeenCalled(); }); @@ -216,7 +217,7 @@ describe('ViewerService', () => { service.identifiers = ['do_123', 'do_124']; spyOn(service.questionCursor, 'getQuestion').and.returnValue(throwError('Error')); spyOn(service.qumlQuestionEvent, 'emit'); - service.getQuestion(); + service.getQuestion(mockData.playerConfig.metadata.children); expect(service.qumlQuestionEvent.emit).toHaveBeenCalled(); expect(service.questionCursor.getQuestion).toHaveBeenCalled(); }); @@ -226,18 +227,20 @@ describe('ViewerService', () => { const qumlLibraryService = TestBed.inject(QumlLibraryService); service.identifiers = []; spyOn(service.questionCursor, 'getQuestion'); - service.getQuestion(); + service.getQuestion(mockData.playerConfig.metadata.children); expect(service.questionCursor.getQuestion).not.toHaveBeenCalled(); }); it('should call getQuestions', () => { const service = TestBed.inject(ViewerService); - service.parentIdentifier = 'do_555'; - service.identifiers = ['do_123', 'do_124']; - spyOn(service.questionCursor, 'getQuestions').and.returnValue(of([{ id: 'do_123' }] as any)); - spyOn(service.qumlQuestionEvent, 'emit'); - service.getQuestions(0, 1) - expect(service.questionCursor.getQuestions).toHaveBeenCalled(); + service.parentIdentifier = 'do_21348431528472576011'; + service.identifiers = ['do_21348431559137689613', 'do_21348431640099225615']; + spyOn(service, 'getSectionQuestionData').and.returnValue(of([{ id: 'do_21348431559137689613' }] as any)); + const getTransformedQuestionMetadata = TestBed.inject(TransformationService); + spyOn(getTransformedQuestionMetadata, 'getTransformedQuestionMetadata').and.returnValue({questions: [{ id: 'do_21348431559137689613' }], count: 1}) + spyOn(service.qumlQuestionEvent, 'emit').and.callFake(() => {}); + service.getQuestions(mockData.playerConfig.metadata.children, 0, 1) + expect(service.getSectionQuestionData).toHaveBeenCalled(); expect(service.qumlQuestionEvent.emit).toHaveBeenCalled(); }); @@ -246,10 +249,10 @@ describe('ViewerService', () => { service.parentIdentifier = 'do_555'; service.identifiers = ['do_123', 'do_124']; service.threshold = 3; - spyOn(service.questionCursor, 'getQuestions').and.returnValue(throwError('Error')); + spyOn(service, 'getSectionQuestionData').and.returnValue(throwError('Error')); spyOn(service.qumlQuestionEvent, 'emit'); - service.getQuestions() - expect(service.questionCursor.getQuestions).toHaveBeenCalled(); + service.getQuestions(mockData.playerConfig.metadata.children) + expect(service.getSectionQuestionData).toHaveBeenCalled(); expect(service.qumlQuestionEvent.emit).toHaveBeenCalled(); }); diff --git a/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts b/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts index 0e251129..2469258d 100644 --- a/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts +++ b/projects/quml-library/src/lib/services/viewer-service/viewer-service.ts @@ -6,7 +6,8 @@ import { TransformationService } from '../transformation-service/transformation. import { eventName, TelemetryType } from '../../telemetry-constants'; import { QuestionCursor } from '../../quml-question-cursor.service'; import * as _ from 'lodash-es'; -import { forkJoin } from 'rxjs'; +import { forkJoin, of } from 'rxjs'; +import { switchMap, map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' @@ -231,8 +232,42 @@ export class ViewerService { this.qumlLibraryService.error(stacktrace, { err: errorCode, errtype: errorType }); } + getSectionQuestionData(sectionChildren, questionIdArr) { + const availableQuestions = []; + let questionsIdNotHavingCompleteData = []; + if (_.isEmpty(sectionChildren)) { + questionsIdNotHavingCompleteData = questionIdArr; + } else { + const foundQuestions = sectionChildren.filter(child => questionIdArr.includes(child.identifier)); + for (const question of foundQuestions) { + if (_.has(question, 'body')) { + availableQuestions.push(question); + } else { + questionsIdNotHavingCompleteData.push(question.identifier); + } + } + } + + if (!_.isEmpty(questionsIdNotHavingCompleteData)) { + return this.fetchIncompleteQuestionsData(availableQuestions, questionsIdNotHavingCompleteData); + } else { + const allQuestions$ = of({ questions: availableQuestions, count: availableQuestions.length }); + return allQuestions$; + } + } + + fetchIncompleteQuestionsData(availableQuestions, questionsIdNotHavingCompleteData) { + return this.questionCursor.getQuestions(questionsIdNotHavingCompleteData, this.parentIdentifier).pipe( + switchMap((questionData: any) => { + const fetchedQuestions = questionData.questions; + const allQuestions = _.concat(availableQuestions, fetchedQuestions); + return of({ questions: allQuestions, count: allQuestions.length }); + }) + ); + } + - getQuestions(currentIndex?: number, index?: number) { + getQuestions(sectionChildren, currentIndex?: number, index?: number) { let indentifersForQuestions; if (currentIndex !== undefined && index) { indentifersForQuestions = this.identifiers.splice(currentIndex, index); @@ -240,10 +275,10 @@ export class ViewerService { indentifersForQuestions = this.identifiers.splice(0, this.threshold); } if (!_.isEmpty(indentifersForQuestions)) { - const requests = []; + let requests: any; const chunkArray = _.chunk(indentifersForQuestions, 10); _.forEach(chunkArray, (value) => { - requests.push(this.questionCursor.getQuestions(value, this.parentIdentifier)); + requests = this.getSectionQuestionData(sectionChildren, value) }); forkJoin(requests).subscribe(questions => { _.forEach(questions, (value) => { @@ -258,16 +293,28 @@ export class ViewerService { } } - getQuestion() { + getQuestion(sectionChildren) { if (this.identifiers.length) { let questionIdentifier = this.identifiers.splice(0, this.threshold); - this.questionCursor.getQuestion(questionIdentifier[0]).subscribe((question) => { - this.qumlQuestionEvent.emit(question); - }, (error) => { - this.qumlQuestionEvent.emit({ - error: error + const getObjectByIdentifier = (identifier: string): any => { + return _.find(sectionChildren, { identifier }); + }; + const fetchedQuestion = getObjectByIdentifier(questionIdentifier); + if (_.has(fetchedQuestion, 'body')) { + const fetchedQuestionData = {questions: [fetchedQuestion], count: 1 }; + const transformedquestionsList = this.transformationService.getTransformedQuestionMetadata(fetchedQuestionData); + this.qumlQuestionEvent.emit(transformedquestionsList); + } else { + this.questionCursor.getQuestion(questionIdentifier[0]).subscribe((question) => { + const fetchedQuestionData = question; + const transformedquestionsList = this.transformationService.getTransformedQuestionMetadata(fetchedQuestionData); + this.qumlQuestionEvent.emit(transformedquestionsList); + }, (error) => { + this.qumlQuestionEvent.emit({ + error: error + }); }); - }); + } } }