text-range.page.ts 19.7 KB
Newer Older
1
/* tslint:disable:no-string-literal */
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import {ApplicationState} from 'src/app/models/applicationState';
import {NavController, ToastController} from '@ionic/angular';
import {Citation} from 'src/app/models/citation';
import {HttpErrorResponse} from '@angular/common/http';
import {Component} from '@angular/core';
import {CitationLevel} from 'src/app/models/enum';
import {TranslateService} from '@ngx-translate/core';
import {HelperService} from '../helper.service';
import {CorpusService} from 'src/app/corpus.service';

@Component({
    selector: 'app-text-range',
    templateUrl: './text-range.page.html',
    styleUrls: ['./text-range.page.scss'],
})
export class TextRangePage {
    // TODO: rebuild the system so it works for any corpus of arbitrary citation depth
    public CitationLevel = CitationLevel;
    ObjectKeys = Object.keys;
    public currentlyAvailableCitations: string[] = [];
    public currentInputId = 0;
    public citationValuesStart: number[];
    public citationValuesEnd: number[];
    public isTextRangeCheckRunning = false;
    HelperService = HelperService;

    constructor(public navCtrl: NavController,
                public corpusService: CorpusService,
                public toastCtrl: ToastController,
31
32
                public translateService: TranslateService,
                public helperService: HelperService) {
33
34
        this.currentlyAvailableCitations = [];
        this.corpusService.isTextRangeCorrect = false;
35
36
37
38
39
40
41
42
43
44
        if (!this.corpusService.currentCorpus) {
            this.corpusService.checkAnnisResponse().then(() => {
                this.corpusService.restoreLastCorpus().then(() => {
                    this.addReferences(this.corpusService.currentCorpus.citation_level_1).then(() => {
                        this.initPage();
                    }, () => {
                    });
                });
            });
        } else if (Object.keys(this.corpusService.currentCorpus.citations).length === 0) {
45
46
47
48
49
50
51
52
53
            this.addReferences(this.corpusService.currentCorpus.citation_level_1).then(() => {
                this.initPage();
            }, () => {
            });
        } else {
            this.initPage();
        }
    }

54
    addMissingCitations(citationLabelsStart: string[], citationLabelsEnd: string[]) {
55
56
57
58
59
60
61
62
63
64
65
66
        return new Promise((resolve, reject) => {
            this.mapCitationLabelsToValues(citationLabelsStart[0], 0, citationLabelsStart, this.citationValuesStart).then(() => {
                this.mapCitationLabelsToValues(citationLabelsEnd[0], 0, citationLabelsEnd, this.citationValuesEnd).then(() => {
                    if (citationLabelsStart.length > 1) {
                        const cls1: string = citationLabelsStart[1];
                        this.mapCitationLabelsToValues(cls1, 1, citationLabelsStart, this.citationValuesStart).then(() => {
                            this.mapCitationLabelsToValues(citationLabelsEnd[1], 1, citationLabelsEnd, this.citationValuesEnd).then(() => {
                                if (citationLabelsStart.length > 2) {
                                    const cls2: string = citationLabelsStart[2];
                                    this.mapCitationLabelsToValues(cls2, 2, citationLabelsStart, this.citationValuesStart).then(() => {
                                        const cle2: string = citationLabelsEnd[2];
                                        this.mapCitationLabelsToValues(cle2, 2, citationLabelsEnd, this.citationValuesEnd).then(() => {
67
                                            return resolve();
68
69
70
                                        });
                                    });
                                } else {
71
                                    return resolve();
72
73
74
75
                                }
                            });
                        }, () => reject());
                    } else {
76
                        return resolve();
77
78
79
80
81
82
                    }
                });
            }, () => reject());
        });
    }

83
    addReferences(targetCitationLevel: string, relevantCitations: Citation[] = []): Promise<void> {
84
        return new Promise((resolve, reject) => {
85
            if (relevantCitations.some(x => !x)) {
86
                return resolve();
87
            }
88
            const urnLastPart: string = relevantCitations.map(x => x.isNumeric ? x.value.toString() : x.label).join('.');
89
            const fullUrn: string = this.corpusService.currentCorpus.source_urn + (urnLastPart ? ':' + urnLastPart : '');
90
            this.corpusService.getCTSvalidReff(fullUrn).then((result: string[]) => {
91
92
93
94
                const newCitations: Citation[] = [];
                const urnList: string[] = result as string[];
                const replaceString: string = fullUrn + (urnLastPart ? '.' : ':');
                urnList.forEach((urn) => {
95
96
                    const urnModified: string = urn.replace(replaceString, '');
                    const isNumeric: boolean = !isNaN(+urnModified);
97
                    newCitations.push(new Citation({
98
                        isNumeric,
99
                        level: targetCitationLevel,
100
                        label: urnModified,
101
                        value: (isNumeric ? +urnModified : newCitations.length + 1)
102
103
                    }));
                });
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
                newCitations.forEach((citation) => {
                    citation.subcitations = {};
                    if (relevantCitations.length === 0) {
                        this.corpusService.currentCorpus.citations[citation.label] = citation;
                        this.currentlyAvailableCitations.push(citation.label);
                    } else if (relevantCitations.length === 1) {
                        this.corpusService.currentCorpus.citations[relevantCitations[0].label].subcitations[citation.label] = citation;
                        const firstLabel: string = this.corpusService.currentCorpus.citations[relevantCitations[0].label].label;
                        this.currentlyAvailableCitations.push(firstLabel.concat('.', citation.label));
                    } else if (relevantCitations.length === 2) {
                        const rc0Label: string = relevantCitations[0].label;
                        const rc1Label: string = relevantCitations[1].label;
                        this.corpusService.currentCorpus.citations[rc0Label].subcitations[rc1Label].subcitations[citation.label] = citation;
                        const firstLabel: string = this.corpusService.currentCorpus.citations[rc0Label].label;
                        const secondLabel: string = this.corpusService.currentCorpus.citations[rc0Label].subcitations[rc1Label].label;
                        this.currentlyAvailableCitations.push(firstLabel.concat('.', secondLabel, '.', citation.label));
                    }
121
                    return resolve();
122
123
                });
            }, async (error: HttpErrorResponse) => {
124
                return reject(error);
125
126
127
128
129
130
131
132
            });
        });
    }

    applyAutoComplete(isStart: boolean) {
        this.showFurtherReferences(isStart).then(() => {
            const newId: string = 'input' + (this.currentInputId + 1).toString();
            this.currentInputId = 0;
133
            const newEl: HTMLInputElement = document.getElementById(newId) as HTMLInputElement;
134
135
136
137
138
139
140
141
142
143
            if (newEl) {
                // adjust disabled state manually because the focus won't work otherwise and the automatic check comes too late
                newEl.disabled = false;
                newEl.focus();
            }
        });
    }

    checkTextRange(citationLabelsStart: string[], citationLabelsEnd: string[]) {
        return new Promise(resolve => {
144
145
            citationLabelsStart = citationLabelsStart.filter(x => x);
            citationLabelsEnd = citationLabelsEnd.filter(x => x);
146
147
            if (this.corpusService.currentCorpus.citation_level_2 === CitationLevel[CitationLevel.default]) {
                if (citationLabelsStart.length !== 1 || citationLabelsEnd.length !== 1) {
148
                    return resolve(false);
149
150
151
                }
            } else {
                if (citationLabelsStart.length < 2 || citationLabelsEnd.length < 2) {
152
                    return resolve(false);
153
154
155
                } else {
                    if (this.corpusService.currentCorpus.citation_level_3 === CitationLevel[CitationLevel.default]) {
                        if (citationLabelsStart.length !== 2 || citationLabelsEnd.length !== 2) {
156
                            return resolve(false);
157
158
                        }
                    } else if (citationLabelsStart.length !== 3 || citationLabelsEnd.length !== 3) {
159
                        return resolve(false);
160
161
162
163
164
165
                    }
                }
            }
            this.citationValuesEnd = [];
            this.citationValuesStart = [];
            this.addMissingCitations(citationLabelsStart, citationLabelsEnd).then(() => {
166
167
168
                this.compareCitationValues().then((result: boolean) => resolve(result));
            }, () => {
                // if the citation system does not work, we allow the user to choose the correct citations on his own
169
                return resolve(true);
170
171
172
            });
        });
    }
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

    compareCitationValues(): Promise<boolean> {
        return new Promise((resolve) => {
            const citationValuesStart: number[] = this.citationValuesStart;
            const citationValuesEnd: number[] = this.citationValuesEnd;
            if (citationValuesStart[0] < citationValuesEnd[0]) {
                resolve(true);
            } else if (citationValuesStart.concat(citationValuesEnd).some(x => isNaN(x))) {
                // there are non-numeric citation values involved, so we cannot easily compare them
                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]);
191
                        } else {
192
                            resolve(true);
193
194
                        }
                    } else {
195
                        resolve(false);
196
197
                    }
                } else {
198
                    resolve(true);
199
                }
200
201
202
            } else {
                resolve(false);
            }
203
204
205
        });
    }

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
    confirmSelection(skipText: boolean = false) {
        if (this.isTextRangeCheckRunning) {
            return;
        }
        this.isTextRangeCheckRunning = true;
        const citationLabelsStart: string[] = this.corpusService.currentTextRange.start;
        const citationLabelsEnd: string[] = this.corpusService.currentTextRange.end;
        this.checkTextRange(citationLabelsStart, citationLabelsEnd).then(async (isTextRangeCorrect: boolean) => {
            this.isTextRangeCheckRunning = false;
            if (!isTextRangeCorrect) {
                const toast = await this.toastCtrl.create({
                    message: this.corpusService.invalidTextRangeString,
                    duration: 3000,
                    position: 'top'
                });
                toast.present().then();
                return;
            }
            const newUrnBase: string = this.corpusService.currentCorpus.source_urn + ':';
            if (this.citationValuesStart.concat(this.citationValuesEnd).some(x => isNaN(x))) {
                this.corpusService.currentUrn = newUrnBase +
                    this.corpusService.currentTextRange.start.filter(x => x).join('.') + '-' +
                    this.corpusService.currentTextRange.end.filter(x => x).join('.');
            } else {
                this.corpusService.currentUrn = newUrnBase + this.citationValuesStart.join('.') + '-' + this.citationValuesEnd.join('.');
            }
            HelperService.mostRecentSetup = new ApplicationState({
                currentUrn: this.corpusService.currentUrn,
                currentCorpus: this.corpusService.currentCorpus,
                currentTextRange: this.corpusService.currentTextRange
            });
            this.helperService.saveMostRecentSetup().then(() => {
                this.corpusService.isTextRangeCorrect = true;
                this.corpusService.getText().then(() => {
                    if (skipText) {
241
                        HelperService.goToExerciseParametersPage(this.navCtrl).then();
242
                    } else if (HelperService.isVocabularyCheck) {
243
                        HelperService.goToVocabularyCheckPage(this.navCtrl).then();
244
                    } else {
245
                        HelperService.goToShowTextPage(this.navCtrl).then();
246
247
248
249
250
251
252
                    }
                }, () => {
                });
            });
        });
    }

253
    initPage() {
254
255
256
257
258
259
260
261
        if (this.corpusService.currentCorpus.citation_level_2 === CitationLevel[CitationLevel.default]) {
            const firstKey: string = Object.keys(this.corpusService.currentCorpus.citations)[0];
            const randomLabel: string = this.corpusService.currentCorpus.citations[firstKey].label;
            this.corpusService.currentTextRange.start[0] = this.corpusService.currentTextRange.end[0] = randomLabel;
        }
    }

    isInputDisabled(isStart: boolean) {
262
263
264
        if (!this.corpusService.currentCorpus) {
            return true;
        }
265
266
267
268
269
270
271
272
273
274
275
276
        const baseCits: { [label: string]: Citation } = this.corpusService.currentCorpus.citations;
        const ctrPart: string[] = isStart ? this.corpusService.currentTextRange.start : this.corpusService.currentTextRange.end;
        if (!baseCits.hasOwnProperty(ctrPart[0])) {
            return true;
        }
        return !baseCits[ctrPart[0]].subcitations.hasOwnProperty(ctrPart[1]);
    }

    public mapCitationLabelsToValues(label: string, index: number, citationLabels: string[], valueList: number[]) {
        return new Promise((resolve, reject) => {
            if (index === 0 && this.corpusService.currentCorpus.citations[label]) {
                valueList.push(this.corpusService.currentCorpus.citations[label].value);
277
                return resolve();
278
279
280
281
            } else if (index === 1) {
                if (!this.corpusService.currentCorpus.citations[citationLabels[index - 1]]) {
                    if (!!+label) {
                        valueList.push(+label);
282
                        return resolve();
283
                    } else {
284
                        return reject();
285
286
287
288
289
290
                    }
                }
                if (Object.keys(this.corpusService.currentCorpus.citations[citationLabels[index - 1]].subcitations).length === 0) {
                    const relevantCitations: Citation[] = [this.corpusService.currentCorpus.citations[citationLabels[index - 1]]];
                    this.addReferences(this.corpusService.currentCorpus.citation_level_2, relevantCitations).then(() => {
                        valueList.push(this.corpusService.currentCorpus.citations[citationLabels[index - 1]].subcitations[label].value);
291
                        return resolve();
292
293
294
                    }, () => {
                        return reject();
                    });
295
296
                } else {
                    valueList.push(this.corpusService.currentCorpus.citations[citationLabels[index - 1]].subcitations[label].value);
297
                    return resolve();
298
299
300
301
302
303
                }
            } else if (index === 2) {
                if (!this.corpusService.currentCorpus.citations[citationLabels[index - 2]] ||
                    !this.corpusService.currentCorpus.citations[citationLabels[index - 2]].subcitations[citationLabels[index - 1]]) {
                    if (!!+label) {
                        valueList.push(+label);
304
                        return resolve();
305
                    } else {
306
                        return reject();
307
308
309
310
311
312
313
                    }
                }
                const citation: Citation = this.corpusService.currentCorpus.citations[citationLabels[index - 2]];
                const subCitation: Citation = citation.subcitations[citationLabels[index - 1]];
                if (Object.keys(subCitation.subcitations).length === 0) {
                    this.addReferences(this.corpusService.currentCorpus.citation_level_3, [citation, subCitation]).then(() => {
                        valueList.push(subCitation.subcitations[label].value);
314
                        return resolve();
315
316
317
                    }, () => reject());
                } else {
                    valueList.push(subCitation.subcitations[label].value);
318
                    return resolve();
319
320
321
                }
            } else if (!!+label) {
                valueList.push(+label);
322
                return resolve();
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
            }
        });
    }

    resetCitations() {
        switch (this.currentInputId) {
            case 1:
                if (this.corpusService.currentCorpus.citation_level_2 !== CitationLevel[CitationLevel.default]) {
                    this.corpusService.currentTextRange.start[1] = '';
                    this.corpusService.currentTextRange.start[2] = '';
                }
                break;
            case 2:
                if (this.corpusService.currentCorpus.citation_level_3 !== CitationLevel[CitationLevel.default]) {
                    this.corpusService.currentTextRange.start[2] = '';
                }
                break;
            case 4:
                if (this.corpusService.currentCorpus.citation_level_2 !== CitationLevel[CitationLevel.default]) {
                    this.corpusService.currentTextRange.end[1] = '';
                    this.corpusService.currentTextRange.end[2] = '';
                }
                break;
            case 5:
                if (this.corpusService.currentCorpus.citation_level_3 !== CitationLevel[CitationLevel.default]) {
                    this.corpusService.currentTextRange.end[2] = '';
                }
                break;
            default:
                break;
        }
    }

    resetCurrentInputId() {
        const oldId: number = this.currentInputId;
        // dirty hack to prevent the blur event from triggering before the click event
        setTimeout(() => {
            if (oldId === this.currentInputId) {
                this.currentInputId = 0;
            }
        }, 50);
    }

366
    async showFurtherReferences(isStart: boolean): Promise<void> {
367
368
369
370
371
        const relTextRangePart: string[] = isStart ? this.corpusService.currentTextRange.start : this.corpusService.currentTextRange.end;
        if (!relTextRangePart[0]) {
            return;
        }
        this.resetCitations();
372
        return new Promise((resolve, reject) => {
373
            const baseCit: Citation = this.corpusService.currentCorpus.citations[relTextRangePart[0]];
374
375
            if (baseCit && (Object.keys(baseCit.subcitations).length ||
                this.corpusService.currentCorpus.citation_level_2 === CitationLevel[CitationLevel.default])) {
376
                return resolve();
377
378
            } else {
                this.addReferences(this.corpusService.currentCorpus.citation_level_2, [baseCit]).then(() => {
379
                    return resolve();
380
381
                }, () => {
                    return resolve();
382
383
384
                });
            }
        }).then(() => {
385
            if ([2, 3, 5, 6].indexOf(this.currentInputId) > -1) {
386
387
                const baseCit: Citation = this.corpusService.currentCorpus.citations[relTextRangePart[0]];
                const relCit: Citation = baseCit.subcitations[relTextRangePart[1]];
388
                const hasLvl3: boolean = this.corpusService.currentCorpus.citation_level_3 !== CitationLevel[CitationLevel.default];
389
                if (relTextRangePart[1] && !(relCit && Object.keys(relCit.subcitations).length) && hasLvl3) {
390
391
392
393
394
395
                    this.addReferences(this.corpusService.currentCorpus.citation_level_3, [baseCit, relCit]).then();
                }
            }
        });
    }
}