preview.page.ts 6.27 KB
Newer Older
1
2
3
4
5
6
import {AnnisResponse} from 'src/app/models/annisResponse';
import {ExerciseType, FileType} from 'src/app/models/enum';
import {HelperService} from 'src/app/helper.service';
import {NavController} from '@ionic/angular';
import {ExerciseService} from 'src/app/exercise.service';
import {CorpusService} from 'src/app/corpus.service';
7
import {Component, OnDestroy} from '@angular/core';
8
9
10
import {TranslateService} from '@ngx-translate/core';
import {Solution} from 'src/app/models/solution';
import {HttpClient} from '@angular/common/http';
11
import {XAPIevent} from "src/app/models/xAPIevent";
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

declare var H5P: any;
// dirty hack to prevent H5P access errors after resize events
window.onresize = () => {
    /* tslint:disable:prefer-const */
    /* tslint:disable:no-shadowed-variable */
    let H5P: any;
    /* tslint:enable:prefer-const */
    /* tslint:enable:no-shadowed-variable */
};

@Component({
    selector: 'app-preview',
    templateUrl: './preview.page.html',
    styleUrls: ['./preview.page.scss'],
})
28
export class PreviewPage implements OnDestroy {
29
30
31
32
33
34
35
36
    HelperService = HelperService;
    public ExerciseType = ExerciseType;
    public FileType = FileType;
    public ObjectKeys = Object.keys;
    public currentSolutions: Solution[];
    public maxGapLength = 0;
    public showInstructions = false;
    public solutionIndicesString: string;
37
38
    public solutionNodeIdSet: Set<string> = new Set<string>();
    public urlBase: string;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

    constructor(public navCtrl: NavController,
                public http: HttpClient,
                public exerciseService: ExerciseService,
                public translateService: TranslateService,
                public corpusService: CorpusService) {
        this.currentSolutions = [];
        if (!HelperService.isVocabularyCheck) {
            this.exerciseService.excludeOOV = false;
        }
        this.processAnnisResponse(this.exerciseService.annisResponse);
        this.initH5P();
    }

    public initH5P() {
        if ([ExerciseType.cloze, ExerciseType.matching].includes(this.exerciseService.exercise.type)) {
            const solutionIndicesString: string = this.exerciseService.excludeOOV ? '&solution_indices=' +
                JSON.stringify(this.currentSolutions.map(x => this.exerciseService.annisResponse.solutions.indexOf(x))) : '';
            // this will be called via GET request from the h5p standalone javascript library
            const url: string = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiH5pPath'] + '?' + 'eid='
                + this.exerciseService.annisResponse.exercise_id + '&lang=' + this.translateService.getBrowserLang() +
                solutionIndicesString;
            window.localStorage.setItem(HelperService.config['localStorageKeyH5P'], url);
            // dirty hack to get H5P going without explicit button click on the new page
            setTimeout(() => {
                (function ($) {
                    $(function () {
                        // $('.h5p-container').empty();
                        $('.h5p-container').empty().h5p({
                            frameJs: 'assets/dist/js/h5p-standalone-frame.min.js',
                            frameCss: 'assets/dist/styles/h5p.css',
70
                            h5pContent: 'assets/h5p/drag_text'
71
72
73
                        });
                    });
                })(H5P.jQuery);
74
75
76
77
78
79
80
                H5P.externalDispatcher.on('xAPI', (event: XAPIevent) => {
                    // 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) {
                        // TODO: SAVE THIS SCORE BY SENDING IT TO THE BACKEND? OR WRITE THE WHOLE STATEMENT?
                        // console.log(event.data.statement.result.score.scaled);
                    }
                });
81
82
            }, 50);
        }
83
        this.updateFileUrl();
84
85
    }

86
87
88
89
    ngOnDestroy(): void {
        H5P.externalDispatcher.off('xAPI');
    }

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    public processAnnisResponse(ar: AnnisResponse) {
        this.exerciseService.annisResponse.solutions = ar.solutions;
        this.processSolutions(ar.solutions);
        this.exerciseService.annisResponse.uri = ar.uri;
        this.exerciseService.annisResponse.graph = this.exerciseService.currentUrn.startsWith('urn:') ?
            this.exerciseService.annisResponse.graph : ar.graph;
    }

    public processSolutions(solutions: Solution[]) {
        const isCloze: boolean = this.exerciseService.exercise.type === ExerciseType.cloze;
        if (this.exerciseService.excludeOOV) {
            const nodeIdSet: Set<string> = new Set(this.exerciseService.annisResponse.graph.nodes.filter(x => !x.is_oov).map(x => x.id));
            solutions = this.exerciseService.annisResponse.solutions.filter(
                x => nodeIdSet.has(x.target.salt_id) && (isCloze || nodeIdSet.has(x.value.salt_id)));
        }
        let newSolutions: Solution[] = [];
        if (isCloze) {
            this.maxGapLength = Math.max.apply(Math, solutions.map(x => x.target.content.length));
            this.solutionNodeIdSet = new Set(solutions.map(x => x.target.salt_id));
            newSolutions = solutions.concat();
        } else {
            newSolutions = solutions.concat().sort((s1, s2) => {
                return s1.target.content < s2.target.content ? -1 : (s1.target.content > s2.target.content ? 1 : 0);
            });
        }
        this.currentSolutions = newSolutions;
    }

    switchOOV() {
        this.exerciseService.excludeOOV = !this.exerciseService.excludeOOV;
        this.currentSolutions = [];
        this.processSolutions(this.exerciseService.annisResponse.solutions);
        this.initH5P();
    }

    private updateFileUrl() {
        const uriParts: string[] = this.exerciseService.annisResponse.uri.split('/');
        const fileId: string = uriParts[uriParts.length - 1];
        const fileTypeBase = '?type=';
        this.urlBase = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiFilePath'] + '/' + fileId + fileTypeBase;
        this.solutionIndicesString = this.exerciseService.excludeOOV ? '&solution_indices=' +
            JSON.stringify(this.currentSolutions.map(x => this.exerciseService.annisResponse.solutions.indexOf(x))) : '';
    }
}