diff --git a/proxy.conf.js b/proxy.conf.js index 94414ef324d14a7934ae79c17326c9e896f7baff..0e8ad30a14695255691c4e0df14a9fc1cca51dc4 100644 --- a/proxy.conf.js +++ b/proxy.conf.js @@ -4,10 +4,11 @@ const PROXY_CONFIG = { "secure": true, "changeOrigin": true, "logLevel": "debug", - "router": function (req) { - const DEEPL_API_KEY = 'DEEPL_API_KEY'; - req.url = req.url.substr(6) + '&auth_key=' + DEEPL_API_KEY; - return 'https://api-free.deepl.com/v2'; + "pathRewrite": { + "^/deepl": "" + }, + "onProxyReq": function (proxyRes, req, res) { + proxyRes.setHeader('Authorization', 'DeepL-Auth-Key DEEPL_API_KEY'); } }, "/languagetool": { diff --git a/src/app/components/shared/_dialogs/room-create/room-create.component.ts b/src/app/components/shared/_dialogs/room-create/room-create.component.ts index f0f7a36d8a0d221f8464e6df56b9b59bbbaefc1f..abd3aebb0458fb3b8f9a52117257e82ca44035be 100644 --- a/src/app/components/shared/_dialogs/room-create/room-create.component.ts +++ b/src/app/components/shared/_dialogs/room-create/room-create.component.ts @@ -75,7 +75,7 @@ export class RoomCreateComponent implements OnInit { newRoom.description = ''; newRoom.blacklist = '[]'; newRoom.questionsBlocked = false; - newRoom.profanityFilter = ProfanityFilter.none; + newRoom.profanityFilter = ProfanityFilter.languageSpecific; if (this.hasCustomShortId && this.customShortIdName && this.customShortIdName.length > 0) { if (!new RegExp('[1-9a-z,A-Z,\s,\-,\.,\_,\~]+').test(this.customShortIdName) || this.customShortIdName.startsWith(' ') || this.customShortIdName.endsWith(' ')) { diff --git a/src/app/components/shared/view-comment-data/view-comment-data.component.ts b/src/app/components/shared/view-comment-data/view-comment-data.component.ts index c0aa27c30fd0c6d698aaee9e86d507c8a391af8e..689b42d07f87a954431b6eca24ce7bd0382344a7 100644 --- a/src/app/components/shared/view-comment-data/view-comment-data.component.ts +++ b/src/app/components/shared/view-comment-data/view-comment-data.component.ts @@ -142,19 +142,6 @@ export class ViewCommentDataComponent implements OnInit, AfterViewInit { } this._currentData = ViewCommentDataComponent.getDataFromDelta(e.content); this.currentText = e.text; - // remove background - const data = e.content; - let changed = false; - data.ops.forEach(op => { - if (op.attributes && op.attributes.background) { - changed = true; - op.attributes.background = null; - delete op.attributes.background; - } - }); - if (changed) { - this.editor.quillEditor.setContents(data); - } }); this.editor.onEditorCreated.subscribe(_ => { if (this.markEvents && this.markEvents.onCreate) { @@ -163,7 +150,11 @@ export class ViewCommentDataComponent implements OnInit, AfterViewInit { if (this._currentData) { this.set(this._currentData); } - (this.editor.editorElem.firstElementChild as HTMLElement).focus(); + const elem = this.editor.editorElem.firstElementChild as HTMLElement; + elem.focus(); + elem.addEventListener('paste', (e) => { + setTimeout(this.cleanContentOnPaste.bind(this)); + }); this.syncErrorLayer(); setTimeout(() => this.syncErrorLayer(), 200); // animations? }); @@ -228,6 +219,29 @@ export class ViewCommentDataComponent implements OnInit, AfterViewInit { }); } + private cleanContentOnPaste() { + const data = this.editor.quillEditor.getContents(); + let changed = false; + data.ops.forEach(op => { + if (!op.attributes) { + return; + } + if (op.attributes.background) { + changed = true; + op.attributes.background = null; + delete op.attributes.background; + } + if (op.attributes.color) { + changed = true; + op.attributes.color = null; + delete op.attributes.color; + } + }); + if (changed) { + this.editor.quillEditor.setContents(data); + } + } + private syncErrorLayer(): void { const pos = this.editor.elementRef.nativeElement.getBoundingClientRect(); const elem = this.editorErrorLayer.nativeElement; diff --git a/src/app/services/http/base-http.service.ts b/src/app/services/http/base-http.service.ts index ed667e0795cff96cf0445d56a9b986ba45089ec3..77b29ce5b2122f95bdb86e5220c6da08eee2788c 100644 --- a/src/app/services/http/base-http.service.ts +++ b/src/app/services/http/base-http.service.ts @@ -15,8 +15,10 @@ export class BaseHttpService { if (error instanceof TimeoutError) { this.nextRequest = new Date().getTime() + 1_000; } else if (error instanceof HttpErrorResponse) { - if (error.status === 429 || error.status === 456) { + if (error.status === 429) { this.nextRequest = new Date().getTime() + 30_000; + } else if (error.status === 456) { + this.nextRequest = new Date().getTime() + 86_400_000; } } console.error(error); @@ -24,6 +26,10 @@ export class BaseHttpService { }; } + protected setTimeout(ms: number): void { + this.nextRequest = new Date().getTime() + ms; + } + protected checkCanSendRequest(operation = 'operation'): Observable<any> { if (new Date().getTime() < this.nextRequest) { console.error(operation + ' is in timeout'); diff --git a/src/app/services/http/deep-l.service.ts b/src/app/services/http/deep-l.service.ts index f55238f5250b4cf707930883a0f8ff856a34e332..bd87610ab9d35a4c2746f2a0d59df34d76ba39bc 100644 --- a/src/app/services/http/deep-l.service.ts +++ b/src/app/services/http/deep-l.service.ts @@ -31,6 +31,11 @@ export class DeepLService extends BaseHttpService { constructor(private http: HttpClient) { super(); + this.checkAPIStatus().subscribe(hasQuota => { + if (!hasQuota) { + this.setTimeout(86_400_000); + } + }); } private static transformSourceToTarget(lang: SourceLang): TargetLang { @@ -72,16 +77,27 @@ export class DeepLService extends BaseHttpService { ); } + private checkAPIStatus(): Observable<boolean> { + const url = '/deepl/usage'; + return this.http.post<any>(url, '', httpOptions) + .pipe( + tap(_ => ''), + timeout(1500), + map(obj => obj.character_count < obj.character_limit), + catchError(this.handleError<any>('checkAPIStatus')), + ); + } + private makeXMLTranslateRequest(text: string, targetLang: TargetLang): Observable<DeepLResult> { const url = '/deepl/translate'; const formality = DeepLService.supportsFormality(targetLang) ? '&formality=more' : ''; - const additional = '?target_lang=' + encodeURIComponent(targetLang) + + const data = 'target_lang=' + encodeURIComponent(targetLang) + '&tag_handling=xml' + formality + '&text=' + encodeURIComponent(text); - return this.http.get<string>(url + additional, httpOptions) + return this.http.post<DeepLResult>(url, data, httpOptions) .pipe( tap(_ => ''), - timeout(5000), + timeout(4500), catchError(this.handleError<any>('makeXMLTranslateRequest')), ); } diff --git a/src/app/services/http/languagetool.service.ts b/src/app/services/http/languagetool.service.ts index b2258ccebdc80bd3ed2f583bea458b3b68394be4..195349853d6f61fd707c37ab9d1e894dd6e0a6c1 100644 --- a/src/app/services/http/languagetool.service.ts +++ b/src/app/services/http/languagetool.service.ts @@ -124,7 +124,7 @@ export class LanguagetoolService extends BaseHttpService { } }).pipe( tap(_ => ''), - timeout(5000), + timeout(4500), catchError(this.handleError<any>('checkSpellings')) ); } diff --git a/src/app/services/http/spacy.service.ts b/src/app/services/http/spacy.service.ts index 7b2d776aec96ed8923fbd3ea8f40852106dd050f..b5519c386bb1dab2876af2fff5350c4da7e84499 100644 --- a/src/app/services/http/spacy.service.ts +++ b/src/app/services/http/spacy.service.ts @@ -54,7 +54,7 @@ export class SpacyService extends BaseHttpService { .post<KeywordList>(url, { text, model }, httpOptions) .pipe( tap(_ => ''), - timeout(500), + timeout(2500), catchError(this.handleError<any>('getKeywords')), map((elem: KeywordList) => { const keywordsMap = new Map<string, { lemma: string; dep: Set<string> }>();