Commit c8eefdbc authored by Konstantin Schulz's avatar Konstantin Schulz

project configuration is now loaded more securely, i.e. using RxJS

parent 00df96d4
{
"name": "mc_frontend",
"version": "1.5.0",
"version": "1.5.1",
"author": "Ionic Framework",
"homepage": "https://ionicframework.com/",
"scripts": {
......
......@@ -79,7 +79,6 @@ export class CorpusService {
this.helperService.initApplicationState();
this.initCurrentCorpus();
this.initCurrentTextRange();
HelperService.waitForConfig().then(() => {
this.checkForUpdates().finally(() => {
this.checkAnnisResponse().then(() => {
this.restoreLastCorpus().then(() => {
......@@ -89,7 +88,6 @@ export class CorpusService {
this.isMostRecentSetupLoaded = true;
});
});
});
this.initPhenomenonMap();
this.getTranslations();
this.translate.onLangChange.subscribe(() => {
......@@ -147,29 +145,33 @@ export class CorpusService {
checkForUpdates(): Promise<void> {
return new Promise((resolve, reject) => {
HelperService.config.pipe(take(1)).subscribe((config: object) => {
// check local storage for necessary updates
const updateInfoJSON: object = JSON.parse(window.localStorage.getItem(HelperService.config['localStorageKeyUpdateInfo']));
this.getCorpora(updateInfoJSON ? new Date(updateInfoJSON['corpora'].lastAccessTime).getTime() : 0).then(() => {
const updateInfoJSON: object = JSON.parse(window.localStorage.getItem(config['localStorageKeyUpdateInfo']));
this.getCorpora(updateInfoJSON ? new Date(updateInfoJSON['corpora'].lastAccessTime).getTime() : 0)
.then(() => {
return resolve();
}, () => {
return reject();
});
});
});
}
getCorpora(lastUpdateTimeMS: number = 0): Promise<void> {
return new Promise((resolve, reject) => {
this.availableCorpora = [];
this.availableAuthors = [];
HelperService.config.pipe(take(1)).subscribe((config: object) => {
// get corpora from REST API
const url = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiCorporaPath'];
const url: string = config['backendBaseUrl'] + config['backendApiCorporaPath'];
const params: HttpParams = new HttpParams().set('last_update_time', lastUpdateTimeMS.toString());
HelperService.makeGetRequest(this.http, this.toastCtrl, url, params).then((data: object) => {
if (data) {
const corpusList: CorpusMC[] = data['corpora'] as CorpusMC[];
window.localStorage.setItem(HelperService.config['localStorageKeyCorpora'], JSON.stringify(corpusList));
window.localStorage.setItem(config['localStorageKeyCorpora'], JSON.stringify(corpusList));
const updateInfo: object = {corpora: {lastAccessTime: new Date().getTime()}};
window.localStorage.setItem(HelperService.config['localStorageKeyUpdateInfo'], JSON.stringify(updateInfo));
window.localStorage.setItem(config['localStorageKeyUpdateInfo'], JSON.stringify(updateInfo));
this.processCorpora(corpusList);
return resolve();
} else {
......@@ -187,23 +189,27 @@ export class CorpusService {
return reject(error);
});
});
});
}
getCTStextPassage(urn: string): Promise<AnnisResponse> {
return new Promise(((resolve, reject) => {
const url = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiRawtextPath'];
HelperService.config.pipe(take(1)).subscribe((config: object) => {
const url: string = config['backendBaseUrl'] + config['backendApiRawtextPath'];
const params: HttpParams = new HttpParams().set('urn', urn);
HelperService.makeGetRequest(this.http, this.toastCtrl, url, params).then((ar: AnnisResponse) => {
return resolve(ar);
}, (error: HttpErrorResponse) => {
return reject(error);
});
});
}));
}
getCTSvalidReff(urn: string): Promise<string[]> {
return new Promise((resolve, reject) => {
const fullUrl: string = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiValidReffPath'];
HelperService.config.pipe(take(1)).subscribe((config: object) => {
const fullUrl: string = config['backendBaseUrl'] + config['backendApiValidReffPath'];
const params: HttpParams = new HttpParams().set('urn', urn);
HelperService.makeGetRequest(this.http, this.toastCtrl, fullUrl, params).then((reff: string[]) => {
resolve(reff);
......@@ -211,6 +217,7 @@ export class CorpusService {
reject(error);
});
});
});
}
getFrequencyAnalysis() {
......@@ -218,7 +225,8 @@ export class CorpusService {
if (this.annisResponse.frequency_analysis.length) {
return resolve();
} else {
const url: string = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiFrequencyPath'];
HelperService.config.pipe(take(1)).subscribe((config: object) => {
const url: string = config['backendBaseUrl'] + config['backendApiFrequencyPath'];
const params: HttpParams = new HttpParams().set('urn', this.currentUrn);
HelperService.makeGetRequest(this.http, this.toastCtrl, url, params).then((fis: FrequencyItem[]) => {
HelperService.isLoading = false;
......@@ -231,6 +239,7 @@ export class CorpusService {
}, () => {
return reject();
});
});
}
});
}
......@@ -336,11 +345,13 @@ export class CorpusService {
}
public loadCorporaFromLocalStorage() {
HelperService.config.pipe(take(1)).subscribe((config: object) => {
const storedCorporaJSONstring: string = window.localStorage.getItem(HelperService.config['localStorageKeyCorpora']);
if (storedCorporaJSONstring) {
const corpusList: CorpusMC[] = JSON.parse(storedCorporaJSONstring) as CorpusMC[];
this.processCorpora(corpusList);
}
});
}
processAnnisResponse(ar: AnnisResponse, saveToCache: boolean = true) {
......
......@@ -16,6 +16,7 @@ import {TranslateService} from '@ngx-translate/core';
import {AnnisResponse} from 'src/app/models/annisResponse';
import {CorpusService} from 'src/app/corpus.service';
import {VocabularyService} from 'src/app/vocabulary.service';
import {take} from 'rxjs/operators';
@Component({
selector: 'app-exercise-list',
......@@ -82,7 +83,8 @@ export class ExerciseListPage implements OnInit {
}
getExerciseList(): void {
const url: string = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiExerciseListPath'];
HelperService.config.pipe(take(1)).subscribe((config: object) => {
const url: string = config['backendBaseUrl'] + config['backendApiExerciseListPath'];
this.hasVocChanged = false;
let params: HttpParams = new HttpParams().set('lang', this.translateService.currentLang);
if (this.vocService.currentReferenceVocabulary) {
......@@ -101,6 +103,7 @@ export class ExerciseListPage implements OnInit {
this.filterExercises(this.currentSearchValue);
}, () => {
});
});
}
getMatchingDegree(exercise: ExerciseMC): string {
......@@ -113,7 +116,8 @@ export class ExerciseListPage implements OnInit {
}
showExercise(exercise: ExerciseMC) {
const url: string = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiExercisePath'];
HelperService.config.pipe(take(1)).subscribe((config: object) => {
const url: string = config['backendBaseUrl'] + config['backendApiExercisePath'];
const params: HttpParams = new HttpParams().set('eid', exercise.eid);
HelperService.makeGetRequest(this.http, this.toastCtrl, url, params).then((ar: AnnisResponse) => {
// save this exercise only locally in the CorpusService (not as MostRecentSetup in the HelperService) because
......@@ -124,6 +128,7 @@ export class ExerciseListPage implements OnInit {
HelperService.goToPreviewPage(this.navCtrl).then();
}, () => {
});
});
}
sortExercises(): void {
......
......@@ -54,7 +54,8 @@ export class ExerciseParametersPage implements OnInit {
async generateExercise() {
const phenomenon: Phenomenon = this.corpusService.exercise.queryItems[0].phenomenon;
if (0 < HelperService.config['maxTextLength'] && HelperService.config['maxTextLength'] < this.corpusService.currentText.length) {
HelperService.config.pipe(take(1)).subscribe(async (config: object) => {
if (0 < config['maxTextLength'] && config['maxTextLength'] < this.corpusService.currentText.length) {
const toast = await this.toastCtrl.create({
message: this.textTooLongString,
duration: 3000,
......@@ -73,6 +74,7 @@ export class ExerciseParametersPage implements OnInit {
this.corpusService.annisResponse.solutions = null;
this.getExerciseData();
}
});
}
public getDisplayValue(query: QueryMC, key: string, queryIndex: number = 0): string {
......@@ -130,7 +132,8 @@ export class ExerciseParametersPage implements OnInit {
}
getH5Pexercise(formData: FormData) {
const url = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiExercisePath'];
HelperService.config.pipe(take(1)).subscribe((config: object) => {
const url = config['backendBaseUrl'] + config['backendApiExercisePath'];
HelperService.currentError = null;
HelperService.isLoading = true;
this.http.post(url, formData).subscribe((ar: AnnisResponse) => {
......@@ -155,10 +158,12 @@ export class ExerciseParametersPage implements OnInit {
});
toast.present().then();
});
});
}
getKwicExercise(formData: FormData) {
const kwicUrl: string = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiKwicPath'];
HelperService.config.pipe(take(1)).subscribe((config: object) => {
const kwicUrl: string = config['backendBaseUrl'] + config['backendApiKwicPath'];
HelperService.currentError = null;
HelperService.isLoading = true;
this.http.post(kwicUrl, formData).subscribe((svgString: string) => {
......@@ -175,11 +180,14 @@ export class ExerciseParametersPage implements OnInit {
});
toast.present().then();
});
});
}
initTranslation() {
HelperService.config.pipe(take(1)).subscribe((config: object) => {
this.translateService.get('TEXT_TOO_LONG').subscribe(
value => this.textTooLongString = value + HelperService.config['maxTextLength']);
value => this.textTooLongString = value + config['maxTextLength']);
});
this.translateService.get('QUERY_VALUE_EMPTY').subscribe(value => this.emptyQueryValueString = value);
}
......
......@@ -36,8 +36,9 @@ export class ExercisePage implements OnInit {
loadExercise(): void {
this.activatedRoute.queryParams.subscribe((params: object) => {
HelperService.config.pipe(take(1)).subscribe((config: object) => {
if (params['eid']) {
let url: string = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiExercisePath'];
let url: string = config['backendBaseUrl'] + config['backendApiExercisePath'];
const httpParams: HttpParams = new HttpParams().set('eid', params['eid']);
HelperService.makeGetRequest(this.http, this.toastCtrl, url, httpParams).then((ar: AnnisResponse) => {
HelperService.applicationState.pipe(take(1)).subscribe((as: ApplicationState) => {
......@@ -47,9 +48,9 @@ export class ExercisePage implements OnInit {
const met: MoodleExerciseType = MoodleExerciseType[ar.exercise_type];
this.corpusService.exercise.type = ExerciseType[met.toString()];
// this will be called via GET request from the h5p standalone javascript library
url = `${HelperService.config['backendBaseUrl']}${HelperService.config['backendApiH5pPath']}` +
url = `${config['backendBaseUrl']}${config['backendApiH5pPath']}` +
`?eid=${this.corpusService.annisResponse.exercise_id}&lang=${this.translateService.currentLang}`;
window.localStorage.setItem(HelperService.config['localStorageKeyH5P'], url);
window.localStorage.setItem(config['localStorageKeyH5P'], url);
const exerciseTypePath: string = this.corpusService.exercise.type === ExerciseType.markWords ?
'mark_words' : 'drag_text';
this.exerciseService.initH5P(exerciseTypePath);
......@@ -62,11 +63,12 @@ export class ExercisePage implements OnInit {
this.exerciseService.fillBlanksString : exerciseType;
const file: string = params['file'];
const lang: string = this.translateService.currentLang;
window.localStorage.setItem(HelperService.config['localStorageKeyH5P'],
window.localStorage.setItem(config['localStorageKeyH5P'],
HelperService.baseUrl + '/assets/h5p/' + exerciseType + '/content/' + file + '_' + lang + '.json');
this.exerciseService.initH5P(exerciseTypePath);
}
});
});
}
ngOnInit() {
......
......@@ -10,6 +10,7 @@ import {Storage} from '@ionic/storage';
import {Language} from 'src/app/models/language';
import {ReplaySubject} from 'rxjs';
import {TextData} from './models/textData';
import {take} from 'rxjs/operators';
@Injectable({
providedIn: 'root'
......@@ -29,7 +30,7 @@ export class HelperService {
Voc: CaseValue.vocative,
Loc: CaseValue.locative,
};
public static config: object;
public static config: ReplaySubject<object>;
public static corpusUpdateCompletedString: string;
public static currentError: HttpErrorResponse;
public static currentLanguage: Language;
......@@ -109,7 +110,7 @@ export class HelperService {
private storage: Storage,
public translate: TranslateService,
) {
this.initConfig().then();
this.initConfig();
this.initLanguage();
}
......@@ -269,21 +270,11 @@ export class HelperService {
return array;
}
static waitForConfig() {
return new Promise(async (resolve) => {
while (!HelperService.config) {
await new Promise((resolveWait) => {
setTimeout(resolveWait, 50);
});
}
return resolve();
});
}
initApplicationState(): void {
HelperService.applicationState = new ReplaySubject<ApplicationState>(1);
if (!HelperService.applicationStateCache) {
this.storage.get(HelperService.config['localStorageKeyApplicationState']).then((jsonString: string) => {
HelperService.config.pipe(take(1)).subscribe((config: object) => {
this.storage.get(config['localStorageKeyApplicationState']).then((jsonString: string) => {
HelperService.applicationStateCache = new ApplicationState({
currentSetup: new TextData()
});
......@@ -293,21 +284,20 @@ export class HelperService {
}
HelperService.applicationState.next(HelperService.applicationStateCache);
});
});
} else {
HelperService.applicationState.next(HelperService.applicationStateCache);
}
}
initConfig() {
return new Promise((resolve) => {
HelperService.config = new ReplaySubject<object>(1);
this.http.get('assets/config.json').subscribe((config: object) => {
HelperService.config = config;
if (!HelperService.config['backendBaseUrl']) {
if (!config['backendBaseUrl']) {
const part1: string = location.protocol.concat('//').concat(window.location.host);
HelperService.config['backendBaseUrl'] = part1.concat(HelperService.config['backendBaseApiPath']).concat('/');
config['backendBaseUrl'] = part1.concat(config['backendBaseApiPath']).concat('/');
}
return resolve();
});
HelperService.config.next(config);
});
}
......@@ -323,9 +313,11 @@ export class HelperService {
return new Promise((resolve) => {
HelperService.applicationStateCache = mrs;
HelperService.applicationState.next(HelperService.applicationStateCache);
this.storage.set(HelperService.config['localStorageKeyApplicationState'], JSON.stringify(mrs)).then(() => {
HelperService.config.pipe(take(1)).subscribe((config: object) => {
this.storage.set(config['localStorageKeyApplicationState'], JSON.stringify(mrs)).then(() => {
return resolve();
});
});
});
}
}
......@@ -21,11 +21,11 @@
<ion-content padding>
<div *ngIf="corpusService.annisResponse?.solutions; else loading">
<ion-grid>
<ion-grid *ngIf="HelperService.config | async as config">
<ion-row *ngIf="HelperService.isVocabularyCheck">
<ion-col>
<label>
<input type="checkbox" [(ngModel)]="exerciseService.excludeOOV" (ngModelChange)="switchOOV()" />
<input type="checkbox" [(ngModel)]="exerciseService.excludeOOV" (ngModelChange)="switchOOV()"/>
<span class="checkbox">{{ "EXERCISE_NO_OOV" | translate}}</span>
</label>
<br>
......@@ -54,7 +54,7 @@ beginning that it is going to be a download (instead of an ordinary link or clic
translate }}</a>
</ion-col>
<ion-col>
<a href="{{HelperService.config['developerMailTo']}}">{{ 'EMAIL_ERROR' | translate }}</a>
<a href="{{config['developerMailTo']}}">{{ 'EMAIL_ERROR' | translate }}</a>
</ion-col>
</ion-row>
<br>
......@@ -70,14 +70,15 @@ beginning that it is going to be a download (instead of an ordinary link or clic
</ion-col>
<ion-col style="text-align: left;">
<ion-button (click)="showShareLink = !showShareLink">
<ion-icon slot="start" name="share"></ion-icon>{{ "SHARE" | translate}}
<ion-icon slot="start" name="share"></ion-icon>
{{ "SHARE" | translate}}
</ion-button>
</ion-col>
<ion-col *ngIf="showShareLink">
<div>
<label>
<input type="text" (focus)="selectLink()"
value="{{HelperService.baseUrl + '/' + HelperService.config['frontendExercisePage'] + '?eid=' + this.corpusService.annisResponse.exercise_id}}" />
value="{{HelperService.baseUrl + '/' + config['frontendExercisePage'] + '?eid=' + this.corpusService.annisResponse.exercise_id}}"/>
</label>
</div>
<div>
......
......@@ -11,6 +11,7 @@ import {Solution} from 'src/app/models/solution';
import {HttpClient, HttpErrorResponse} from '@angular/common/http';
import {XAPIevent} from 'src/app/models/xAPIevent';
import {TestResultMC} from 'src/app/models/testResultMC';
import {take} from 'rxjs/operators';
declare var H5P: any;
......@@ -43,13 +44,11 @@ export class PreviewPage implements OnDestroy, OnInit {
if (!HelperService.isVocabularyCheck) {
this.exerciseService.excludeOOV = false;
}
HelperService.waitForConfig().then(() => {
this.corpusService.checkAnnisResponse().then(() => {
this.processAnnisResponse(this.corpusService.annisResponse);
this.initH5P();
}, () => {
});
});
}
async copyLink(): Promise<void> {
......@@ -68,13 +67,15 @@ export class PreviewPage implements OnDestroy, OnInit {
initH5P(): void {
const solutionIndicesString: string = this.exerciseService.excludeOOV ? '&solution_indices=' +
JSON.stringify(this.currentSolutions.map(x => this.corpusService.annisResponse.solutions.indexOf(x))) : '';
HelperService.config.pipe(take(1)).subscribe((config: object) => {
// this will be called via GET request from the h5p standalone javascript library
const url: string = `${HelperService.config['backendBaseUrl'] + HelperService.config['backendApiH5pPath']}` +
const url: string = `${config['backendBaseUrl'] + config['backendApiH5pPath']}` +
`?eid=${this.corpusService.annisResponse.exercise_id}&lang=${this.translateService.currentLang + solutionIndicesString}`;
window.localStorage.setItem(HelperService.config['localStorageKeyH5P'], url);
window.localStorage.setItem(config['localStorageKeyH5P'], url);
const exerciseTypePath: string = this.corpusService.exercise.type === ExerciseType.markWords ? 'mark_words' : 'drag_text';
this.exerciseService.initH5P(exerciseTypePath);
this.updateFileUrl();
});
}
ngOnDestroy(): void {
......@@ -83,8 +84,9 @@ export class PreviewPage implements OnDestroy, OnInit {
ngOnInit(): void {
H5P.externalDispatcher.on('xAPI', (event: XAPIevent) => {
HelperService.config.pipe(take(1)).subscribe((config: object) => {
// results are only available when a task has been completed/answered, not in the "attempted" or "interacted" stages
if (event.data.statement.verb.id === HelperService.config['xAPIverbIDanswered'] && event.data.statement.result) {
if (event.data.statement.verb.id === config['xAPIverbIDanswered'] && event.data.statement.result) {
const iframe: HTMLIFrameElement = document.querySelector(this.exerciseService.h5pIframeString);
if (iframe) {
const iframeDoc: Document = iframe.contentWindow.document;
......@@ -97,6 +99,7 @@ export class PreviewPage implements OnDestroy, OnInit {
}
}
});
});
}
processAnnisResponse(ar: AnnisResponse): void {
......@@ -135,7 +138,8 @@ export class PreviewPage implements OnDestroy, OnInit {
}
sendData(result: TestResultMC): void {
const fileUrl: string = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiFilePath'];
HelperService.config.pipe(take(1)).subscribe((config: object) => {
const fileUrl: string = config['backendBaseUrl'] + config['backendApiFilePath'];
HelperService.currentError = null;
HelperService.isLoading = true;
const formData = new FormData();
......@@ -147,6 +151,7 @@ export class PreviewPage implements OnDestroy, OnInit {
HelperService.currentError = error;
console.log('ERROR: COULD NOT SEND EXERCISE RESULTS TO SERVER.');
});
});
}
switchOOV(): void {
......@@ -158,7 +163,9 @@ export class PreviewPage implements OnDestroy, OnInit {
updateFileUrl(): void {
const fileId: string = this.corpusService.annisResponse.exercise_id;
const fileTypeBase = '&type=';
this.urlBase = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiFilePath'] + '?id=' + fileId + fileTypeBase;
HelperService.config.pipe(take(1)).subscribe((config: object) => {
this.urlBase = config['backendBaseUrl'] + config['backendApiFilePath'] + '?id=' + fileId + fileTypeBase;
});
this.solutionIndicesString = this.exerciseService.excludeOOV ? '&solution_indices=' +
JSON.stringify(this.currentSolutions.map(x => this.corpusService.annisResponse.solutions.indexOf(x))) : '';
}
......
......@@ -51,8 +51,8 @@ export class ShowTextPage implements OnInit {
public translateService: TranslateService,
public vocService: VocabularyService,
public http: HttpClient) {
HelperService.waitForConfig().then(() => {
this.urlBase = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiFilePath'];
HelperService.config.pipe(take(1)).subscribe((config: object) => {
this.urlBase = config['backendBaseUrl'] + config['backendApiFilePath'];
});
}
......@@ -72,9 +72,11 @@ export class ShowTextPage implements OnInit {
this.isDownloading = false;
const responseParts: string[] = response.split('.');
const link: HTMLLinkElement = document.querySelector('#download');
link.href = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiFilePath'] + '?id='
+ responseParts[0] + '&type=' + responseParts[1];
HelperService.config.pipe(take(1)).subscribe((config: object) => {
link.href = config['backendBaseUrl'] + config['backendApiFilePath'] + '?id=' + responseParts[0]
+ '&type=' + responseParts[1];
link.style.display = 'block';
});
}, async (error: any) => {
this.isDownloading = false;
HelperService.currentError = error;
......
......@@ -78,8 +78,8 @@
<ion-col>{{ 'UNIT_DATA_SECURITY' | translate}}</ion-col>
</ion-row>
<ion-row>
<ion-col>{{ 'TEST_MODULE_LINK_TO_CONCEPT' | translate}}
<a href="{{HelperService.config['machinaCallidaConceptUrl']}}" target="_blank">Link</a>!
<ion-col *ngIf="HelperService.config | async as config">{{ 'TEST_MODULE_LINK_TO_CONCEPT' | translate}}
<a href="{{config['machinaCallidaConceptUrl']}}" target="_blank">Link</a>!
</ion-col>
</ion-row>
<ion-row class="button-continue">
......
......@@ -14,6 +14,7 @@ import {HttpClient, HttpErrorResponse} from '@angular/common/http';
import Context from 'src/app/models/xAPI/Context';
import {TestResultMC} from 'src/app/models/testResultMC';
import {ExerciseService} from 'src/app/exercise.service';
import {take} from 'rxjs/operators';
declare var H5P: any;
......@@ -364,13 +365,15 @@ export class TestPage implements OnDestroy, OnInit {
toast.present().then();
return;
}
const fileUrl: string = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiFilePath'];
HelperService.config.pipe(take(1)).subscribe((config: object) => {
const fileUrl: string = config['backendBaseUrl'] + config['backendApiFilePath'];
HelperService.currentError = null;
HelperService.isLoading = true;
const formData = new FormData();
// tslint:disable-next-line:prefer-const
let learningResult: object = {};
Object.keys(this.vocService.currentTestResults).forEach(i => learningResult[i] = this.vocService.currentTestResults[i].statement);
Object.keys(this.vocService.currentTestResults)
.forEach(i => learningResult[i] = this.vocService.currentTestResults[i].statement);
formData.append('learning_result', JSON.stringify(learningResult));
this.http.post(fileUrl, formData).subscribe(async () => {
HelperService.isLoading = false;
......@@ -391,6 +394,7 @@ export class TestPage implements OnDestroy, OnInit {
});
toast.present().then();
});
});
}
setH5PeventHandlers() {
......@@ -398,11 +402,13 @@ export class TestPage implements OnDestroy, OnInit {
if (this.currentState !== TestModuleState.inProgress) {
return;
}
HelperService.config.pipe(take(1)).subscribe((config: object) => {
// results are only available when a task has been completed/answered, not in the "attempted" or "interacted" stages
if (event.data.statement.verb.id === HelperService.config['xAPIverbIDanswered'] && event.data.statement.result) {
if (event.data.statement.verb.id === config['xAPIverbIDanswered'] && event.data.statement.result) {
this.finishExercise(event);
}
});
});
H5P.externalDispatcher.on('domChanged', (event: any) => {
// dirty hack because domChanged events are triggered twice for every new H5P exercise
if (!this.areEventHandlersSet) {
......@@ -447,12 +453,14 @@ export class TestPage implements OnDestroy, OnInit {
}
const fileName: string = currentExerciseName.split('_').slice(-1) + '_' + this.translate.currentLang + '.json';
let exerciseType = currentExerciseName.split('_').slice(0, 2).join('_');
window.localStorage.setItem(HelperService.config['localStorageKeyH5P'],
HelperService.baseUrl + '/assets/h5p/' + exerciseType + '/content/' + fileName);
HelperService.config.pipe(take(1)).subscribe((config: object) => {
window.localStorage.setItem(config['localStorageKeyH5P'], HelperService.baseUrl + '/assets/h5p/'
+ exerciseType + '/content/' + fileName);
if (exerciseType.startsWith(this.exerciseService.vocListString)) {
exerciseType = this.exerciseService.fillBlanksString;
}
this.exerciseService.initH5P(exerciseType);
});
}
triggerInputEventHandler() {
......