From 429ac2235c6d86117ee17324d844fe6c4fb10769 Mon Sep 17 00:00:00 2001 From: Ruben Bimberg <ruben.bimberg@mni.thm.de> Date: Wed, 1 Sep 2021 21:29:51 +0200 Subject: [PATCH] Finish implementing deepl --- .../moderator-comment-list.component.ts | 1 - .../create-comment.component.ts | 34 ++++++- .../deep-ldialog/deep-ldialog.component.html | 25 ++++++ .../deep-ldialog/deep-ldialog.component.scss | 20 +++++ .../deep-ldialog.component.spec.ts | 26 ++++++ .../deep-ldialog/deep-ldialog.component.ts | 90 +++++++++++++++++++ .../spacy-dialog/spacy-dialog.component.ts | 4 +- src/app/components/shared/shared.module.ts | 4 +- .../view-comment-data.component.ts | 12 +-- .../write-comment/write-comment.component.ts | 3 - src/app/utils/create-comment-wrapper.ts | 4 +- src/assets/i18n/creator/de.json | 7 ++ src/assets/i18n/creator/en.json | 7 ++ src/assets/i18n/participant/de.json | 7 ++ src/assets/i18n/participant/en.json | 7 ++ 15 files changed, 232 insertions(+), 19 deletions(-) create mode 100644 src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.html create mode 100644 src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.scss create mode 100644 src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.spec.ts create mode 100644 src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.ts diff --git a/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.ts b/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.ts index 854f7595a..b062e1ea3 100644 --- a/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.ts +++ b/src/app/components/moderator/moderator-comment-list/moderator-comment-list.component.ts @@ -19,7 +19,6 @@ import { ModeratorsComponent } from '../../creator/_dialogs/moderators/moderator import { TagsComponent } from '../../creator/_dialogs/tags/tags.component'; import { DeleteCommentsComponent } from '../../creator/_dialogs/delete-comments/delete-comments.component'; import { Export } from '../../../models/export'; -import { CreateCommentComponent } from '../../shared/_dialogs/create-comment/create-comment.component'; import { NotificationService } from '../../../services/util/notification.service'; import { BonusTokenService } from '../../../services/http/bonus-token.service'; import { CommentFilter, Period } from '../../../utils/filter-options'; diff --git a/src/app/components/shared/_dialogs/create-comment/create-comment.component.ts b/src/app/components/shared/_dialogs/create-comment/create-comment.component.ts index 00d57e8ff..6d2293ef2 100644 --- a/src/app/components/shared/_dialogs/create-comment/create-comment.component.ts +++ b/src/app/components/shared/_dialogs/create-comment/create-comment.component.ts @@ -4,12 +4,13 @@ import { NotificationService } from '../../../../services/util/notification.serv import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; import { User } from '../../../../models/user'; -import { CommentListComponent } from '../../comment-list/comment-list.component'; import { EventService } from '../../../../services/util/event.service'; import { SpacyDialogComponent } from '../spacy-dialog/spacy-dialog.component'; import { LanguagetoolService, Language } from '../../../../services/http/languagetool.service'; import { CreateCommentKeywords } from '../../../../utils/create-comment-keywords'; import { WriteCommentComponent } from '../../write-comment/write-comment.component'; +import { DeepLDialogComponent } from '../deep-ldialog/deep-ldialog.component'; +import { DeepLService } from '../../../../services/http/deep-l.service'; @Component({ selector: 'app-submit-comment', @@ -19,7 +20,6 @@ import { WriteCommentComponent } from '../../write-comment/write-comment.compone export class CreateCommentComponent implements OnInit { @ViewChild(WriteCommentComponent) commentComponent: WriteCommentComponent; - comment: Comment; user: User; roomId: string; tags: string[]; @@ -27,11 +27,12 @@ export class CreateCommentComponent implements OnInit { constructor( private notification: NotificationService, - public dialogRef: MatDialogRef<CommentListComponent>, + public dialogRef: MatDialogRef<CreateCommentComponent>, private translateService: TranslateService, public dialog: MatDialog, public languagetoolService: LanguagetoolService, public eventService: EventService, + private deeplService: DeepLService, @Inject(MAT_DIALOG_DATA) public data: any) { } @@ -51,7 +52,32 @@ export class CreateCommentComponent implements OnInit { comment.createdFromLecturer = this.user.role > 0; comment.tag = tag; this.isSendingToSpacy = true; - this.openSpacyDialog(comment, text); + this.openDeeplDialog(body, text, (newBody: string, newText: string) => { + comment.body = newBody; + this.openSpacyDialog(comment, newText); + }); + } + + openDeeplDialog(body: string, text: string, onClose: (data: string, text: string) => void) { + this.deeplService.improveTextStyle(text).subscribe(improvedText => { + this.isSendingToSpacy = false; + this.dialog.open(DeepLDialogComponent, { + width: '900px', + maxWidth: '100%', + data: { + body, + text, + improvedText + } + }).afterClosed().subscribe((res) => { + if (res) { + onClose(res.body, res.text); + } + }); + }, (_) => { + this.isSendingToSpacy = false; + onClose(body, text); + }); } openSpacyDialog(comment: Comment, rawText: string): void { diff --git a/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.html b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.html new file mode 100644 index 000000000..56e44687a --- /dev/null +++ b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.html @@ -0,0 +1,25 @@ +<h2>{{'deepl.header' | translate}}</h2> +<div mat-dialog-content> + <label id="deepl-radio-group-label">{{'deepl.label' | translate}}</label> + <br> + <mat-radio-group + aria-labelledby="deepl-radio-group-label" + [(ngModel)]="radioButtonValue"> + <mat-radio-button [value]="normalValue"> + <strong>{{'deepl.option-normal' | translate}}</strong> + <app-view-comment-data [currentData]="normalValue.body"></app-view-comment-data> + </mat-radio-button> + <br> + <mat-radio-button [value]="improvedValue"> + <strong>{{'deepl.option-improved' | translate}}</strong> + <app-view-comment-data [currentData]="improvedValue.body"></app-view-comment-data> + </mat-radio-button> + </mat-radio-group> +</div> + +<app-dialog-action-buttons + [buttonsLabelSection]="'comment-page'" + [confirmButtonLabel]="'continue'" + [cancelButtonClickAction]="buildCloseDialogActionCallback()" + [confirmButtonClickAction]="buildSubmitBodyActionCallback()"> +</app-dialog-action-buttons> diff --git a/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.scss b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.scss new file mode 100644 index 000000000..a667f841e --- /dev/null +++ b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.scss @@ -0,0 +1,20 @@ +::ng-deep { + + mat-radio-button { + width: 100%; + } + + .mat-radio-label { + width: calc(100% - 16px) !important; + } + + .mat-radio-label-content { + width: 100%; + } + + app-view-comment-data > div { + background: var(--surface); + border-radius: 10px; + padding: 7px; + } +} diff --git a/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.spec.ts b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.spec.ts new file mode 100644 index 000000000..4b6a83115 --- /dev/null +++ b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.spec.ts @@ -0,0 +1,26 @@ +/*import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DeepLDialogComponent } from './deep-ldialog.component'; + +describe('DeepLDialogComponent', () => { + let component: DeepLDialogComponent; + let fixture: ComponentFixture<DeepLDialogComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ DeepLDialogComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DeepLDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); + */ diff --git a/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.ts b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.ts new file mode 100644 index 000000000..9a835d9ec --- /dev/null +++ b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.ts @@ -0,0 +1,90 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { ViewCommentDataComponent } from '../../view-comment-data/view-comment-data.component'; + +interface ResultValue { + body: string; + text: string; +} + +@Component({ + selector: 'app-deep-ldialog', + templateUrl: './deep-ldialog.component.html', + styleUrls: ['./deep-ldialog.component.scss'] +}) +export class DeepLDialogComponent implements OnInit { + + radioButtonValue: ResultValue; + normalValue: ResultValue; + improvedValue: ResultValue; + + constructor( + private dialogRef: MatDialogRef<DeepLDialogComponent>, + @Inject(MAT_DIALOG_DATA) public data: any) { + } + + ngOnInit(): void { + this.normalValue = { + body: this.data.body, + text: this.data.text + }; + const sentences = this.data.improvedText.split('\n').filter(sent => sent.length > 0); + const delta = ViewCommentDataComponent.getDeltaFromData(this.data.body); + if (delta === null) { + setTimeout(() => this.dialogRef.close(this.normalValue)); + return; + } + const ops = delta.ops; + let i = 0; + let sentenceIndex = 0; + let lastFoundIndex = -1; + for (; i < ops.length && sentenceIndex < sentences.length; i++) { + const data = ops[i]['insert']; + if (typeof data !== 'string') { + continue; + } + if (data === '\n') { + continue; + } + const endsNewline = data.endsWith('\n'); + const mod = (endsNewline ? -1 : 0) + (data.startsWith('\n') ? -1 : 0); + const occurrence = data.split('\n').length + mod; + ops[i]['insert'] = sentences.slice(sentenceIndex, sentenceIndex + occurrence).join('\n') + + (endsNewline ? '\n' : ''); + sentenceIndex += occurrence; + lastFoundIndex = i; + } + for (let j = ops.length - 1; j >= i; j--) { + const data = ops[i]['insert']; + if (data === 'string' && data.trim().length) { + ops.splice(j, 1); + } + } + if (sentenceIndex < sentences.length) { + if (lastFoundIndex < 0) { + setTimeout(() => this.dialogRef.close(this.normalValue)); + return; + } + let data = ops[i]['insert']; + const endsNewline = data.endsWith('\n'); + if (endsNewline) { + data = data.substring(0, data.length - 1); + } + ops[i]['insert'] = data + sentences.slice(sentenceIndex).join('\n') + (endsNewline ? '\n' : ''); + } + this.improvedValue = { + body: ViewCommentDataComponent.getDataFromDelta(delta), + text: this.data.improvedText + }; + this.radioButtonValue = this.normalValue; + } + + buildCloseDialogActionCallback(): () => void { + return () => this.dialogRef.close(); + } + + buildSubmitBodyActionCallback(): () => void { + return () => this.dialogRef.close(this.radioButtonValue); + } + +} diff --git a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts index dd6c33c93..c2bb0e109 100644 --- a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts +++ b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts @@ -1,7 +1,5 @@ import { AfterContentInit, Component, Inject, OnInit, ViewChild } from '@angular/core'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; - -import { CreateCommentComponent } from '../create-comment/create-comment.component'; import { SpacyService, SpacyKeyword } from '../../../../services/http/spacy.service'; import { LanguagetoolService } from '../../../../services/http/languagetool.service'; import { Comment } from '../../../../models/comment'; @@ -39,7 +37,7 @@ export class SpacyDialogComponent implements OnInit, AfterContentInit { constructor( protected langService: LanguagetoolService, private spacyService: SpacyService, - public dialogRef: MatDialogRef<CreateCommentComponent>, + public dialogRef: MatDialogRef<SpacyDialogComponent>, @Inject(MAT_DIALOG_DATA) public data) { } diff --git a/src/app/components/shared/shared.module.ts b/src/app/components/shared/shared.module.ts index 87b4f5a8e..75057040a 100644 --- a/src/app/components/shared/shared.module.ts +++ b/src/app/components/shared/shared.module.ts @@ -51,6 +51,7 @@ import { CustomMarkdownComponent } from './custom-markdown/custom-markdown.compo import { ScrollIntoViewDirective } from '../../directives/scroll-into-view.directive'; import { QuillModule } from 'ngx-quill'; import { ViewCommentDataComponent } from './view-comment-data/view-comment-data.component'; +import { DeepLDialogComponent } from './_dialogs/deep-ldialog/deep-ldialog.component'; @NgModule({ imports: [ @@ -107,7 +108,8 @@ import { ViewCommentDataComponent } from './view-comment-data/view-comment-data. WriteCommentComponent, CustomMarkdownComponent, ScrollIntoViewDirective, - ViewCommentDataComponent + ViewCommentDataComponent, + DeepLDialogComponent ], exports: [ RoomJoinComponent, 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 6f28e5e7b..ccf7af27b 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 @@ -42,7 +42,7 @@ export class ViewCommentDataComponent implements OnInit, AfterViewInit { } get currentData(): string { - return this._currentData; + return this._currentData || ''; } @Input() maxTextCharacters = 500; @@ -66,7 +66,7 @@ export class ViewCommentDataComponent implements OnInit, AfterViewInit { } } }; - private _currentData = ''; + private _currentData = null; constructor(private languageService: LanguageService, private translateService: TranslateService, @@ -79,7 +79,7 @@ export class ViewCommentDataComponent implements OnInit, AfterViewInit { }); } - private static getDataFromDelta(contentDelta) { + public static getDataFromDelta(contentDelta) { return JSON.stringify(contentDelta.ops.map(op => { let hasOnlyInsert = true; for (const key in op) { @@ -92,7 +92,7 @@ export class ViewCommentDataComponent implements OnInit, AfterViewInit { })); } - private static getDeltaFromData(jsonData: string) { + public static getDeltaFromData(jsonData: string) { return { ops: JSON.parse(jsonData).map(elem => { if (!elem['insert']) { @@ -135,7 +135,9 @@ export class ViewCommentDataComponent implements OnInit, AfterViewInit { if (this.markEvents && this.markEvents.onCreate) { this.markEvents.onCreate(this.editorErrorLayer.nativeElement, this.tooltipContainer.nativeElement, this.editor); } - this.set(this._currentData); + if (this._currentData) { + this.set(this._currentData); + } (this.editor.editorElem.firstElementChild as HTMLElement).focus(); this.syncErrorLayer(); setTimeout(() => this.syncErrorLayer(), 200); // animations? diff --git a/src/app/components/shared/write-comment/write-comment.component.ts b/src/app/components/shared/write-comment/write-comment.component.ts index a39b0b731..324be593f 100644 --- a/src/app/components/shared/write-comment/write-comment.component.ts +++ b/src/app/components/shared/write-comment/write-comment.component.ts @@ -93,9 +93,6 @@ export class WriteCommentComponent implements OnInit { } checkGrammar() { - this.deepl.improveTextStyle(this.commentData.currentText).subscribe(str => { - console.log(str); - }); this.grammarCheck(this.commentData.currentText, this.langSelect && this.langSelect.nativeElement); } diff --git a/src/app/utils/create-comment-wrapper.ts b/src/app/utils/create-comment-wrapper.ts index 1408a49eb..93706c1c2 100644 --- a/src/app/utils/create-comment-wrapper.ts +++ b/src/app/utils/create-comment-wrapper.ts @@ -22,8 +22,8 @@ export class CreateCommentWrapper { openCreateDialog(user: User): Observable<Comment> { const dialogRef = this.dialog.open(CreateCommentComponent, { width: '900px', - maxWidth: 'calc( 100% - 50px )', - maxHeight: 'calc( 100vh - 50px )', + maxWidth: '100%', + maxHeight: 'calc( 100vh - 20px )', autoFocus: false, }); dialogRef.componentInstance.user = user; diff --git a/src/assets/i18n/creator/de.json b/src/assets/i18n/creator/de.json index 161e2d184..ef9be59cd 100644 --- a/src/assets/i18n/creator/de.json +++ b/src/assets/i18n/creator/de.json @@ -125,6 +125,7 @@ "answer": "Frage kommentieren", "save-answer": "Speichern", "comment-answered": "Antwort wurde gespeichert.", + "continue": "Weiter", "edit-answer": "Bearbeiten", "delete-answer": "Löschen", "really-delete-answer": "Willst du deine Antwort wirklich löschen?", @@ -235,6 +236,12 @@ "undo": "Rückgängig", "yes": "Ja" }, + "deepl": { + "header": "DeepL Unterstützung", + "label": "Wähle einen Text", + "option-normal": "Eingegebener Text", + "option-improved": "Stilistisch verbesserter Text" + }, "home-page": { "create-session": "Neue Sitzung", "created-1": "Die Sitzung »", diff --git a/src/assets/i18n/creator/en.json b/src/assets/i18n/creator/en.json index 751372cd2..1a1be02ce 100644 --- a/src/assets/i18n/creator/en.json +++ b/src/assets/i18n/creator/en.json @@ -125,6 +125,7 @@ "answer": "Comment this question", "save-answer": "Save", "comment-answered": "Answer has been sent.", + "continue": "Continue", "edit-answer": "Edit", "delete-answer": "Delete", "really-delete-answer": "Do you really want to delete this answer?", @@ -236,6 +237,12 @@ "undo": "Undo", "yes": "Yes" }, + "deepl": { + "header": "DeepL Support", + "label": "Choose a text", + "option-normal": "Entered text", + "option-improved": "Stylistically improved text" + }, "home-page": { "create-session": "New session", "created-1": "Session »", diff --git a/src/assets/i18n/participant/de.json b/src/assets/i18n/participant/de.json index e6ba2fec8..d034aa1e2 100644 --- a/src/assets/i18n/participant/de.json +++ b/src/assets/i18n/participant/de.json @@ -119,6 +119,7 @@ "abort": "Abbrechen", "ask-question-description": "Gib hier deine Frage ein!", "save-answer": "Speichern", + "continue": "Weiter", "delete-answer": "Löschen", "cancel": "Abbrechen", "cancel-description": "Abbrechen", @@ -163,6 +164,12 @@ "upvote": "positiv", "downvote": "negativ" }, + "deepl": { + "header": "DeepL Unterstützung", + "label": "Wähle einen Text", + "option-normal": "Eingegebener Text", + "option-improved": "Stilistisch verbesserter Text" + }, "home-page": { "exactly-8": "Ein Raum-Code hat genau 8 Ziffern.", "no-room-found": "Es wurde kein Raum mit diesem Raum-Code gefunden.", diff --git a/src/assets/i18n/participant/en.json b/src/assets/i18n/participant/en.json index 2a1328180..613bb84bd 100644 --- a/src/assets/i18n/participant/en.json +++ b/src/assets/i18n/participant/en.json @@ -129,6 +129,7 @@ "abort": "Cancel", "ask-question-description": "Enter your question …", "save-answer": "Save", + "continue": "Continue", "delete-answer": "Delete", "cancel": "Cancel", "cancel-description": "Cancel", @@ -172,6 +173,12 @@ "upvote": "upvotes", "downvote": "downvotes" }, + "deepl": { + "header": "DeepL Support", + "label": "Choose a text", + "option-normal": "Entered text", + "option-improved": "Stylistically improved text" + }, "home-page": { "exactly-8": "A key is a combination of 8 digits.", "no-room-found": "No session found with this key", -- GitLab