text-range.ts 20.2 KB
Newer Older
Konstantin Schulz's avatar
Konstantin Schulz committed
1
import {Component} from '@angular/core';
2
import {InfiniteScroll, IonicPage, NavController, NavParams, ToastController, ViewController} from 'ionic-angular';
Konstantin Schulz's avatar
Konstantin Schulz committed
3
4
5
import {CorpusProvider} from "../../providers/corpus/corpus";
import {CitationLevel} from "../../models/enum";
import {ShowTextPage} from "../show-text/show-text";
6
7
import {TextRange} from "../../models/textRange";
import {TranslateService} from "@ngx-translate/core";
8
import {Citation} from "../../models/citation";
9
import {BaseInput} from "ionic-angular/es2015/util/base-input";
10
11
import {VocabularyCheckPage} from "../vocabulary-check/vocabulary-check";
import {HelperProvider} from "../../providers/helper/helper";
12
13
14
15
import {HttpErrorResponse} from "@angular/common/http";
import {AnnisResponse} from "../../models/annisResponse";
import {ExerciseProvider} from "../../providers/exercise/exercise";
import {VocabularyProvider} from "../../providers/vocabulary/vocabulary";
Konstantin Schulz's avatar
Konstantin Schulz committed
16
17
18
19
20
21
22
23
24
25
26

/**
 * Generated class for the CorpusDetailPage page.
 *
 * See https://ionicframework.com/docs/components/#navigation for more info on
 * Ionic pages and navigation.
 */

@IonicPage()
@Component({
    selector: 'page-corpus-detail',
27
    templateUrl: 'text-range.html',
Konstantin Schulz's avatar
Konstantin Schulz committed
28
})
29
export class TextRangePage {
30
    public citationsUnavailableString: string;
31
    // TODO: rebuild the system so it works for any corpus of arbitrary citation depth
32
33
    public showMultiPartText: boolean = false;
    public CitationLevel = CitationLevel;
34
35
    public invalidTextRangeString: string;
    ObjectKeys = Object.keys;
36
    currentlyAvailableCitations: string[] = [];
37
    public currentlyVisibleCitations: string[] = [];
38
39
    public citationValuesStart: number[];
    public citationValuesEnd: number[];
40
41
42
    public isTextRangeCheckRunning: boolean = false;
    public showStartList = false;
    public showEndList = false;
43
    HelperProvider = HelperProvider;
Konstantin Schulz's avatar
Konstantin Schulz committed
44
45

    constructor(public navCtrl: NavController, public navParams: NavParams,
46
47
                public corpusProvider: CorpusProvider,
                public toastCtrl: ToastController,
48
                public translateService: TranslateService,
49
50
51
                public viewCtrl: ViewController,
                public exerciseProvider: ExerciseProvider,
                public vocProvider: VocabularyProvider) {
52
        this.currentlyAvailableCitations = [];
53
        this.corpusProvider.isTextRangeCorrect = false;
54
        this.corpusProvider.currentTextRange = new TextRange({start: "", end: ""});
55
        if (Object.keys(this.corpusProvider.currentCorpus.citations).length === 0) {
56
57
            this.addReferences(this.corpusProvider.currentCorpus.citation_level_1).then(() => {
                this.initPage();
58
            }, () => {
59
            });
Konstantin Schulz's avatar
Konstantin Schulz committed
60
        }
61
        else {
62
            this.initPage();
63
        }
64
65
        this.translateService.get("INVALID_TEXT_RANGE").subscribe(value => this.invalidTextRangeString = value);
        this.translateService.get("ERROR_CITATIONS_UNAVAILABLE").subscribe(value => this.citationsUnavailableString = value);
Konstantin Schulz's avatar
Konstantin Schulz committed
66
67
    }

68
    private addMissingCitations(citationLabelsStart: string[], citationLabelsEnd: string[]) {
69
        return new Promise((resolve, reject) => {
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
            this.mapCitationLabelsToValues(citationLabelsStart[0], 0, citationLabelsStart, this.citationValuesStart).then(() => {
                this.mapCitationLabelsToValues(citationLabelsEnd[0], 0, citationLabelsEnd, this.citationValuesEnd).then(() => {
                    if (citationLabelsStart.length > 1) {
                        this.mapCitationLabelsToValues(citationLabelsStart[1], 1, citationLabelsStart, this.citationValuesStart).then(() => {
                            this.mapCitationLabelsToValues(citationLabelsEnd[1], 1, citationLabelsEnd, this.citationValuesEnd).then(() => {
                                if (citationLabelsStart.length > 2) {
                                    this.mapCitationLabelsToValues(citationLabelsStart[2], 2, citationLabelsStart, this.citationValuesStart).then(() => {
                                        this.mapCitationLabelsToValues(citationLabelsEnd[2], 2, citationLabelsEnd, this.citationValuesEnd).then(() => {
                                            resolve();
                                        });
                                    });
                                }
                                else {
                                    resolve();
                                }
                            });
86
                        }, () => reject());
87
                    }
88
89
                    else {
                        resolve();
90
                    }
91
                });
92
            }, () => reject());
93
        });
94
95
    }

96
97
    private addReferences(targetCitationLevel: string, relevantCitations: Citation[] = []) {
        let urnLastPart: string = relevantCitations.map(x => x.value.toString()).join(".");
98
        let fullUrn: string = this.corpusProvider.currentCorpus.source_urn + (urnLastPart ? ":" + urnLastPart : "");
99
100
101
        HelperProvider.currentError = null;
        HelperProvider.isLoading = true;
        return new Promise((resolve, reject) => {
102
            this.corpusProvider.getCTSvalidReff(fullUrn).subscribe((result: string[] | object) => {
103
                HelperProvider.isLoading = false;
104
                let newCitations: Citation[] = [];
105
                if (!Array.isArray(result)) {
106
107
108
                    // this is a custom corpus
                    let textparts: object[] = result["textparts"];
                    newCitations = textparts.map(x => x["citation"]) as Citation[];
109
                }
110
                else {
111
112
113
114
115
116
117
118
119
                    // this is a CTS corpus
                    let urnList: string[] = result as string[];
                    let replaceString: string = fullUrn + (urnLastPart ? "." : ":");
                    urnList.forEach((urn) => {
                        newCitations.push(new Citation({
                            level: targetCitationLevel,
                            label: urn.replace(replaceString, ""),
                            value: +urn.replace(replaceString, "")
                        }));
120
                    });
121
                }
122
123
                newCitations.forEach((citation) => {
                    citation.subcitations = {};
124
                    if (relevantCitations.length === 0) {
125
126
127
                        this.corpusProvider.currentCorpus.citations[citation.label] = citation;
                        this.currentlyAvailableCitations.push(citation.label);
                    }
128
129
130
                    else if (relevantCitations.length === 1) {
                        this.corpusProvider.currentCorpus.citations[relevantCitations[0].label].subcitations[citation.label] = citation;
                        let firstLabel: string = this.corpusProvider.currentCorpus.citations[relevantCitations[0].label].label;
131
132
                        this.currentlyAvailableCitations.push(firstLabel.concat(".", citation.label));
                    }
133
134
135
136
                    else if (relevantCitations.length === 2) {
                        this.corpusProvider.currentCorpus.citations[relevantCitations[0].label].subcitations[relevantCitations[1].label].subcitations[citation.label] = citation;
                        let firstLabel: string = this.corpusProvider.currentCorpus.citations[relevantCitations[0].label].label;
                        let secondLabel: string = this.corpusProvider.currentCorpus.citations[relevantCitations[0].label].subcitations[relevantCitations[1].label].label;
137
138
139
140
                        this.currentlyAvailableCitations.push(firstLabel.concat(".", secondLabel, ".", citation.label));
                    }
                    resolve();
                });
141
142
143
144
145
146
147
148
149
150
            }, (error: HttpErrorResponse) => {
                HelperProvider.isLoading = false;
                HelperProvider.currentError = error;
                let toast = this.toastCtrl.create({
                    message: this.citationsUnavailableString,
                    duration: 3000,
                    position: 'top'
                });
                toast.present().then();
                reject();
151
            });
152
153
154
        });
    }

155
    checkTextRange(citationLabelsStart: string[], citationLabelsEnd: string[]) {
156
157
        return new Promise(resolve => {
            if (this.corpusProvider.currentCorpus.citation_level_2 === CitationLevel[CitationLevel.default]) {
158
159
160
                if (citationLabelsStart.length !== 1 || citationLabelsEnd.length !== 1) {
                    resolve(false);
                    return;
161
162
                }
            }
163
164
            else {
                if (citationLabelsStart.length < 2 || citationLabelsEnd.length < 2) {
165
166
                    resolve(false);
                    return;
167
                }
168
169
170
171
172
173
174
175
176
177
178
179
                else {
                    if (this.corpusProvider.currentCorpus.citation_level_3 === CitationLevel[CitationLevel.default]) {
                        if (citationLabelsStart.length !== 2 || citationLabelsEnd.length !== 2) {
                            resolve(false);
                            return;
                        }
                    }
                    else if (citationLabelsStart.length !== 3 || citationLabelsEnd.length !== 3) {
                        resolve(false);
                        return;
                    }
                }
180
181
182
183
184
185
            }
            this.citationValuesEnd = [];
            this.citationValuesStart = [];
            this.addMissingCitations(citationLabelsStart, citationLabelsEnd).then(() => {
                let citationValuesStart: number[] = this.citationValuesStart;
                let citationValuesEnd: number[] = this.citationValuesEnd;
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

                if (citationValuesStart[0] < citationValuesEnd[0]) {
                    resolve(true);
                }
                else if (citationValuesStart[0] === citationValuesEnd[0]) {
                    if (citationValuesStart.length > 1) {
                        if (citationValuesStart[1] < citationValuesEnd[1]) {
                            resolve(true);
                        }
                        else if (this.citationValuesStart[1] === citationValuesEnd[1]) {
                            if (citationValuesStart.length > 2) {
                                resolve(citationValuesStart[2] <= citationValuesEnd[2]);
                            }
                            else {
                                resolve(true);
                            }
                        }
                        else {
                            resolve(false);
                        }
                    }
                    else {
                        resolve(true);
                    }
                }
                else {
                    resolve(false);
                }
214
215
216
            }, () => {
                // if the citation system does not work, we allow the user to choose the correct citations on his own
                resolve(true);
217
218
            });
        });
Konstantin Schulz's avatar
Konstantin Schulz committed
219
    }
220

221
222
223
224
225
226
    expandCitationList(infiniteScroll: InfiniteScroll) {
        let currentLength: number = this.currentlyVisibleCitations.length;
        this.currentlyVisibleCitations = this.currentlyVisibleCitations.concat(this.currentlyAvailableCitations.slice(currentLength, currentLength + 10));
        infiniteScroll.complete();
    }

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
    private getText() {
        this.corpusProvider.currentText = "";
        if (HelperProvider.isVocabularyCheck) {
            this.navCtrl.push(VocabularyCheckPage).then();
        }
        else {
            HelperProvider.currentError = null;
            HelperProvider.isLoading = true;
            this.corpusProvider.getCTStextPassage(this.corpusProvider.currentUrn).subscribe((ar: AnnisResponse) => {
                HelperProvider.isLoading = false;
                this.exerciseProvider.processAnnisResponse(ar);
                this.navCtrl.push(ShowTextPage).then();
            }, (error: HttpErrorResponse) => {
                HelperProvider.isLoading = false;
                HelperProvider.currentError = error;
                let toast = this.toastCtrl.create({
                    message: HelperProvider.generalErrorAlertMessage,
                    duration: 3000,
                    position: 'top'
                });
                toast.present().then();
            });
        }
    }

252
253
    private initPage() {
        this.currentlyAvailableCitations = Object.keys(this.corpusProvider.currentCorpus.citations);
254
        this.currentlyVisibleCitations = this.currentlyAvailableCitations.slice(0, 10);
255
256
257
258
        if (this.corpusProvider.currentCorpus.citation_level_2 === CitationLevel[CitationLevel.default]) {
            let randomLabel: string = this.corpusProvider.currentCorpus.citations[Object.keys(this.corpusProvider.currentCorpus.citations)[0]].label;
            this.corpusProvider.currentTextRange.start = this.corpusProvider.currentTextRange.end = randomLabel;
        }
259
    }
260

261
    public mapCitationLabelsToValues(label: string, index: number, citationLabels: string[], valueList: number[]) {
262
        return new Promise((resolve, reject) => {
263
            if (index === 0 && this.corpusProvider.currentCorpus.citations[label]) {
264
                valueList.push(this.corpusProvider.currentCorpus.citations[label].value);
265
                resolve();
266
267
            }
            else if (index === 1) {
268
269
270
271
272
273
274
275
276
                if (!this.corpusProvider.currentCorpus.citations[citationLabels[index - 1]]) {
                    if (!!+label) {
                        valueList.push(+label);
                        resolve();
                    }
                    else {
                        reject();
                    }
                }
277
                if (Object.keys(this.corpusProvider.currentCorpus.citations[citationLabels[index - 1]].subcitations).length === 0) {
278
                    this.addReferences(this.corpusProvider.currentCorpus.citation_level_2, [this.corpusProvider.currentCorpus.citations[citationLabels[index - 1]]]).then(() => {
279
280
                        valueList.push(this.corpusProvider.currentCorpus.citations[citationLabels[index - 1]].subcitations[label].value);
                        resolve();
281
                    }, () => reject());
282
283
284
                }
                else {
                    valueList.push(this.corpusProvider.currentCorpus.citations[citationLabels[index - 1]].subcitations[label].value);
285
                    resolve();
286
287
288
                }
            }
            else if (index === 2) {
289
290
291
292
293
294
295
296
297
                if (!this.corpusProvider.currentCorpus.citations[citationLabels[index - 2]] || !this.corpusProvider.currentCorpus.citations[citationLabels[index - 2]].subcitations[citationLabels[index - 1]]) {
                    if (!!+label) {
                        valueList.push(+label);
                        resolve();
                    }
                    else {
                        reject();
                    }
                }
298
                if (Object.keys(this.corpusProvider.currentCorpus.citations[citationLabels[index - 2]].subcitations[citationLabels[index - 1]].subcitations).length === 0) {
299
                    this.addReferences(this.corpusProvider.currentCorpus.citation_level_3, [this.corpusProvider.currentCorpus.citations[citationLabels[index - 2]], this.corpusProvider.currentCorpus.citations[citationLabels[index - 2]].subcitations[citationLabels[index - 1]]]).then(() => {
300
301
                        valueList.push(this.corpusProvider.currentCorpus.citations[citationLabels[index - 2]].subcitations[citationLabels[index - 1]].subcitations[label].value);
                        resolve();
302
                    }, () => reject());
303
304
305
                }
                else {
                    valueList.push(this.corpusProvider.currentCorpus.citations[citationLabels[index - 2]].subcitations[citationLabels[index - 1]].subcitations[label].value);
306
                    resolve();
307
                }
308
            }
309
310
            else if (!!+label) {
                valueList.push(+label);
311
                resolve();
312
            }
313
314
315
        });
    }

316
317
    async showFurtherReferences(event: BaseInput<string>) {
        let value: string = event.value;
318
        if (!value) {
319
            this.currentlyAvailableCitations = Object.keys(this.corpusProvider.currentCorpus.citations);
320
321
322
323
324
        }
        let dotCount: number = (value.match(/\./g) || []).length;
        if (dotCount > 0 && value.endsWith(".")) {
            // remove empty elements from the split array
            let citationLabels: string[] = value.split(".").filter(x => x);
325
            if (citationLabels.length > 0 && this.corpusProvider.currentCorpus.citations[citationLabels[0]]) {
326
327
328
                this.updateReferences(citationLabels).then(() => {
                    this.currentlyVisibleCitations = this.currentlyAvailableCitations.slice(0, 10);
                });
329
330
331
332
            }
        }
    }

333
    showText() {
334
335
336
        if (this.isTextRangeCheckRunning) {
            return;
        }
337
338
        let citationLabelsStart: string[] = this.corpusProvider.currentTextRange.start.split(".").filter(x => x);
        let citationLabelsEnd: string[] = this.corpusProvider.currentTextRange.end.split(".").filter(x => x);
339
        this.isTextRangeCheckRunning = true;
340
        this.checkTextRange(citationLabelsStart, citationLabelsEnd).then((isTextRangeCorrect: boolean) => {
341
            this.isTextRangeCheckRunning = false;
342
343
344
345
346
347
348
349
350
351
352
353
            if (!isTextRangeCorrect) {
                let toast = this.toastCtrl.create({
                    message: this.invalidTextRangeString,
                    duration: 3000,
                    position: 'top'
                });
                toast.present().then();
                return;
            }
            let newUrnBase: string = this.corpusProvider.currentCorpus.source_urn + ":";
            this.corpusProvider.currentUrn = newUrnBase + this.citationValuesStart.join(".") + "-" + this.citationValuesEnd.join(".");
            this.corpusProvider.currentText = "";
354
            this.corpusProvider.isTextRangeCorrect = true;
355
            this.getText();
356
        });
357
    }
358
359
360
361
362
363

    updateReferences(citationLabels: string[]) {
        return new Promise(resolve => {
            if (citationLabels.length === 1 && this.corpusProvider.currentCorpus.citation_level_2 !== CitationLevel[CitationLevel.default]) {
                this.currentlyAvailableCitations = [];
                if (Object.keys(this.corpusProvider.currentCorpus.citations[citationLabels[0]].subcitations).length === 0) {
364
                    this.addReferences(this.corpusProvider.currentCorpus.citation_level_2, [this.corpusProvider.currentCorpus.citations[citationLabels[0]]]).then(() => {
365
                        resolve();
366
367
                    }, () => {
                        resolve();
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
                    });
                }
                else {
                    Object.keys(this.corpusProvider.currentCorpus.citations[citationLabels[0]].subcitations).forEach(key => {
                        let newLabel: string = citationLabels[0].concat(".", key);
                        this.currentlyAvailableCitations.push(newLabel);
                    });
                    resolve();
                }
            }
            else if (citationLabels.length === 2 && this.corpusProvider.currentCorpus.citation_level_3 !== CitationLevel[CitationLevel.default]) {
                this.currentlyAvailableCitations = [];
                if (!this.corpusProvider.currentCorpus.citations[citationLabels[0]].subcitations[citationLabels[1]]) {
                    resolve();
                }
                if (Object.keys(this.corpusProvider.currentCorpus.citations[citationLabels[0]].subcitations[citationLabels[1]].subcitations).length === 0) {
384
                    this.addReferences(this.corpusProvider.currentCorpus.citation_level_3, [this.corpusProvider.currentCorpus.citations[citationLabels[0]], this.corpusProvider.currentCorpus.citations[citationLabels[0]].subcitations[citationLabels[1]]]).then(() => {
385
                        resolve();
386
387
                    }, () => {
                        resolve();
388
389
390
391
392
393
394
395
396
397
398
399
                    });
                }
                else {
                    Object.keys(this.corpusProvider.currentCorpus.citations[citationLabels[0]].subcitations[citationLabels[1]].subcitations).forEach(key => {
                        let newLabel: string = citationLabels[0].concat(".", citationLabels[1], ".", key);
                        this.currentlyAvailableCitations.push(newLabel);
                    });
                    resolve();
                }
            }
        });
    }
Konstantin Schulz's avatar
Konstantin Schulz committed
400
}