client/src/pages/add-word/add-word.ts (102 lines of code) (raw):
import { AfterViewInit, Component, Inject, NgZone } from '@angular/core';
import { Location } from '@angular/common';
import { Router } from '@angular/router';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ErrorPopUpComponent } from '../../components/error-popup/error-popup';
import { ANALYTICS_SERVICE, IAnalyticsService } from '../../services/analytics';
import { FEEDBACK_SERVICE, IFeedbackService } from '../../services/feedback';
import { LoadingPopUpComponent } from '../../components/loading-popup/loading-popup';
import { WordTranslation } from '../../services/entities/translation';
import { environment } from '../../environments/environment';
import { DEFAULT_LOCALE } from '../../util/locale';
import { I18nService } from '../../i18n/i18n.service';
import { EndangeredLanguageService } from '../../services/endangered-language';
import { AddedWord } from '../../services/entities/feedback';
import { getLogger } from '../../util/logging';
const logger = getLogger('AddWordPageComponent');
@Component({
selector: 'app-page-add-word',
templateUrl: './add-word.html',
styleUrls: ['./add-word.scss']
})
export class AddWordPageComponent implements AfterViewInit {
public readonly form: FormGroup;
private readonly prevPageCssClass?: string;
public submittingForm = false;
public get endangeredLanguage(): string { return this.endangeredLanguageService.currentLanguage.name; }
constructor(private router: Router,
private location: Location,
private dialog: MatDialog,
private snackBar: MatSnackBar,
private zone: NgZone,
private i18n: I18nService,
private endangeredLanguageService: EndangeredLanguageService,
@Inject(FEEDBACK_SERVICE) private feedbackService: IFeedbackService,
@Inject(ANALYTICS_SERVICE) private analyticsService: IAnalyticsService) {
const word: WordTranslation = history.state.word;
this.form = new FormGroup({
word: new FormControl(word ? word.original : '', this.i18n.currentLanguage.code !== DEFAULT_LOCALE ? [
Validators.required
] : []),
nativeWord: new FormControl(word ? word.translation : '', [
Validators.required
]),
englishWord: new FormControl(word ? word.english : '', [
Validators.required
]),
transliteration: new FormControl(word ? word.transliteration : '', [
]),
recording: new FormControl(null, [
]),
});
this.prevPageCssClass = history.state.prevPageCssClass;
}
ngAfterViewInit() {
this.analyticsService.logPageView(this.router.url, 'Add word');
}
onFormSubmit() {
// Force validation of all fields
for (const k of Object.keys(this.form.controls)) {
this.form.controls[k].markAsDirty();
}
if (!this.form.valid) {
return;
}
this.submittingForm = true;
const loadingPopup = this.dialog.open(LoadingPopUpComponent, { panelClass: 'loading-popup' });
const addedWord: AddedWord = this.form.value;
if (!addedWord.word && this.i18n.currentLanguage.code == DEFAULT_LOCALE) {
addedWord.word = addedWord.englishWord;
}
addedWord.language = this.i18n.currentLanguage.code;
addedWord.nativeLanguage = this.endangeredLanguageService.currentLanguage.code;
this.feedbackService.addWord(this.form.value).then(
() => {
logger.log('Added word submitted');
this.location.back();
const snackbarCssClass = this.prevPageCssClass ? `${this.prevPageCssClass}-snack-bar` : '';
this.snackBar.open(this.i18n.getTranslation('wordSubmitted') || 'Submitted for review', '',
{ duration: environment.components.snackBar.duration, panelClass: snackbarCssClass });
// HACK: fix snackbar not closing on some iOS devices
setTimeout(() => {
(document.getElementsByTagName('snack-bar-container')[0].parentNode as Element).remove();
}, environment.components.snackBar.duration + 500);
},
err => {
logger.warn('Failed adding word', err);
const errorMessage = this.i18n.getTranslation('addWordError') || 'Unable to add word';
this.dialog.open(ErrorPopUpComponent, { data: { message: errorMessage } });
}
).finally(
() => {
this.submittingForm = false;
loadingPopup.close();
}
);
}
onCloseClick(ev: Event) {
ev.preventDefault();
ev.stopPropagation();
history.back();
}
}