Skip to content
Snippets Groups Projects
Commit 522ef96c authored by Klaus-Dieter Quibeldey-Cirkel's avatar Klaus-Dieter Quibeldey-Cirkel
Browse files

Merge branch 'keywords-to-be-selected' into 'staging'

Spacy and LanguageTool improvements

Closes #95, #94, #82, #81, and #80

See merge request arsnova/topic-cloud!44
parents 46af2735 b26e9684
No related merge requests found
Showing
with 125 additions and 37 deletions
......@@ -5,8 +5,13 @@
matTooltip="{{ 'spacy-dialog.lang-button-hint' | translate }}"
matTooltipShowDelay="750">
<i class="material-icons">language</i>
{{'spacy-dialog.' + (selectedLang === 'auto' ? 'auto' : languagetoolService.mapLanguageToSpacyModel(selectedLang)) | translate}}
<mat-select class="select-list" #select [(ngModel)]="selectedLang">
<span *ngIf="!(selectedLang === 'auto')">
{{'spacy-dialog.' + (languagetoolService.mapLanguageToSpacyModel(selectedLang)) | translate}}
</span>
<span *ngIf="(selectedLang === 'auto')" id="langSelect">
auto
</span>
<mat-select class="select-list" #select [(ngModel)]="selectedLang">
<mat-option *ngFor="let lang of languages" [value]="lang">
<span *ngIf="lang == 'de-DE'">{{ 'spacy-dialog.de' | translate }}</span>
<span *ngIf="lang == 'en-US'">{{ 'spacy-dialog.en' | translate }}</span>
......@@ -45,19 +50,18 @@
<ars-row [overflow]="'visible'" style="max-height:calc( 100vh - 250px )">
<mat-form-field style="width:100%;">
<input [disabled]="true" matInput>
<div [contentEditable]="true"
(paste)="clearHTML($event);
maxLength(commentBody)"
[spellcheck]="false"
spellcheck="false"
(focus)="eventService.makeFocusOnInputTrue()"
style="margin-top:15px;width:100%;"
(blur)="eventService.makeFocusOnInputFalse()"
#commentBody
aria-labelledby="ask-question-description"
autofocus
(input)="maxLength(commentBody)"
id="answer-input">
<div
[contentEditable]="true"
(paste)="onPaste($event); maxLength(commentBody)"
[spellcheck]="false"
(focus)="eventService.makeFocusOnInputTrue()"
style="margin-top:15px;width:100%;"
(blur)="eventService.makeFocusOnInputFalse()"
#commentBody
aria-labelledby="ask-question-description"
autofocus
(input)="maxLength(commentBody)"
id="answer-input">
</div>
<mat-placeholder class="placeholder">
{{ 'comment-page.enter-comment' | translate }}
......@@ -73,8 +77,9 @@
</span>
</mat-hint>
<span *ngIf="!this.hasSpellcheckConfidence">
<p>{{ 'spacy-dialog.force-language-selection' | translate }}</p>
<p class="lang-confidence">{{ 'spacy-dialog.force-language-selection' | translate }}</p>
</span>
</mat-form-field>
</ars-row>
</mat-tab>
......
......@@ -21,6 +21,7 @@ app-comment-list {
-webkit-appearance: textarea;
min-height: 50px;
cursor: text;
word-wrap: break-word;
&:focus {
outline: none;
......@@ -133,13 +134,33 @@ mat-hint {
stroke: var(--on-primary);
}
.lang-confidence {
animation: shake 0.8s;
color: var(--red);
font-size: 14px;
}
@keyframes shake {
0% { transform: translate(1px, 1px) rotate(0deg); }
10% { transform: translate(0px, 0) rotate(-1deg); }
20% { transform: translate(0px, 0px) rotate(1deg); }
30% { transform: translate(3px, 2px) rotate(0deg); }
40% { transform: translate(1px, 0) rotate(1deg); }
50% { transform: translate(-1px, 2px) rotate(-1deg); }
60% { transform: translate(-1px, 1px) rotate(0deg); }
70% { transform: translate(3px, 1px) rotate(-1deg); }
80% { transform: translate(-1px, 0) rotate(1deg); }
90% { transform: translate(1px, 2px) rotate(0deg); }
100% { transform: translate(1px, -0) rotate(-1deg); }
}
.spellcheck {
@media screen and (max-width:500px) {
overflow: auto;
display: flex;
justify-content: space-between;
flex-direction: column !important;
flex-wrap: wrap;
flex-wrap: wrap;
align-items: flex-end;
}
}
\ No newline at end of file
}
}
......@@ -36,6 +36,8 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
isSpellchecking = false;
hasSpellcheckConfidence = true;
newLang = 'auto';
constructor(
private notification: NotificationService,
public dialogRef: MatDialogRef<CommentListComponent>,
......@@ -73,10 +75,19 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
this.dialogRef.close();
}
clearHTML(e) {
onPaste(e){
e.preventDefault();
const elem = document.getElementById('answer-input');
const text = e.clipboardData.getData('text');
document.getElementById('answer-input').innerText += text.replace(/<[^>]*>?/gm, '');
elem.innerText += text.replace(/<[^>]*>?/gm, '');
const range = document.createRange();
range.setStart(elem.lastChild, elem.lastChild.textContent.length);
range.collapse(true);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
checkInputData(body: string): boolean {
......@@ -179,7 +190,19 @@ export class CreateCommentComponent implements OnInit, OnDestroy {
this.hasSpellcheckConfidence = false;
return;
}
if(this.selectedLang === 'auto' && (document.getElementById('langSelect').innerText.includes(this.newLang)
|| document.getElementById('langSelect').innerText.includes('auto'))) {
if(wordsCheck.language.name.includes('German')){
this.selectedLang = 'de-DE';
}else if(wordsCheck.language.name.includes('English')){
this.selectedLang= 'en-US';
}else if(wordsCheck.language.name.includes('French')){
this.selectedLang = 'fr';
}else{
this.newLang = wordsCheck.language.name;
}
document.getElementById('langSelect').innerHTML = this.newLang;
}
if (wordsCheck.matches.length > 0) {
wordsCheck.matches.forEach(grammarError => {
const wrongWord = commentBody.innerText.slice(grammarError.offset, grammarError.offset + grammarError.length);
......
......@@ -55,10 +55,15 @@
</mat-list-item>
</mat-list>
</ars-row>
<span *ngIf="keywords.length <= 0 && !this.isLoading">
<p>{{ 'spacy-dialog.empty-nouns' | translate }}</p>
</span>
<ars-row>
<span *ngIf="keywords.length <= 0 && !this.isLoading">
<p>{{ 'spacy-dialog.empty-nouns' | translate }}</p>
</span>
<span *ngIf="!langSupported">
<p class="manual-input-title">{{ 'spacy-dialog.add-manually' | translate }}</p>
<textarea class="manual-input" [(ngModel)]="manualKeywords" (input)="manualKeywordsToKeywords()"></textarea>
</span>
</ars-row>
</div>
</ars-row>
......
......@@ -48,6 +48,17 @@
padding-left: 15px;
cursor: pointer;
}
.manual-input{
background-color: transparent;
border: 1px solid var(--on-dialog);
padding: 5px;
border-radius: 5px;
color: var(--on-dialog);
width: 100%
}
.manual-input-title{
margin-top: 15px;
}
.select-list{
width: calc(100% - 24px);
}
......
......@@ -26,6 +26,8 @@ export class SpacyDialogComponent implements OnInit, AfterContentInit {
keywords: Keyword[] = [];
keywordsOriginal: Keyword[] = [];
isLoading = false;
langSupported = true;
manualKeywords = '';
constructor(
protected langService: LanguageService,
......@@ -53,15 +55,14 @@ export class SpacyDialogComponent implements OnInit, AfterContentInit {
buildCreateCommentActionCallback() {
return () => {
this.comment.keywordsFromQuestioner = this.keywords.filter(kw => kw.selected).map(kw => kw.word);
this.comment.keywordsFromSpacy = this.keywordsOriginal.map(kw => kw.word);
this.comment.keywordsFromQuestioner = this.keywords.filter(kw => kw.selected && kw.word.length).map(kw => kw.word);
this.comment.keywordsFromSpacy = this.keywordsOriginal.filter(kw => kw.word.length).map(kw => kw.word);
this.dialogRef.close(this.comment);
};
}
evalInput(model: Model) {
const keywords: Keyword[] = [];
this.isLoading = true;
// N at first pos = all Nouns(NN de/en) including singular(NN, NNP en), plural (NNPS, NNS en), proper Noun(NNE, NE de)
......@@ -77,8 +78,10 @@ export class SpacyDialogComponent implements OnInit, AfterContentInit {
});
}
}
this.keywords = keywords;
this.keywordsOriginal = keywords;
// Deep copy
this.keywords = JSON.parse(JSON.stringify(keywords));
this.keywordsOriginal = JSON.parse(JSON.stringify(keywords));;
}, () => {
this.keywords = [];
this.keywordsOriginal = [];
......@@ -112,4 +115,20 @@ export class SpacyDialogComponent implements OnInit, AfterContentInit {
});
}
}
manualKeywordsToKeywords(){
const tempKeywords = this.manualKeywords.replace(/\s/g,'');
if(tempKeywords.length) {
this.keywords = tempKeywords.split(',').map((keyword) => (
{
word: keyword,
completed: true,
editing: false,
selected: true
}
));
} else {
this.keywords = [];
}
}
}
......@@ -25,7 +25,7 @@ export class LanguagetoolService extends BaseHttpService {
case 'fr':
return 'fr';
default:
return 'de';
return 'auto';
}
}
......
......@@ -4,7 +4,7 @@ import { Observable } from 'rxjs';
import { BaseHttpService } from './base-http.service';
import { catchError, map, tap } from 'rxjs/operators';
export type Model = 'de' | 'en' | 'fr' | 'es' | 'it' | 'nl' | 'pt';
export type Model = 'de' | 'en' | 'fr' | 'es' | 'it' | 'nl' | 'pt' | 'auto';
//[B]egin, [I]nside, [O]utside or unset
type EntityPosition = 'B' | 'I' | 'O' | '';
......
......@@ -94,7 +94,8 @@
"select-keyword-hint": "Dieses Stickwort auswählen",
"edit-keyword-hint": "Stichwort editieren",
"editing-done-hint": "Editierung abschliessen",
"force-language-selection": "Bitte wähle eine Sprache aus."
"force-language-selection": "Automatische Spracherkennung unpräzise, bitte gewählte Sprache prüfen!",
"add-manually": "Geben Sie bitte die Stichwörter unten mit separatem Komma ein"
},
"comment-page": {
"a11y-comment_delete": "Löscht diese Frage",
......
......@@ -95,7 +95,8 @@
"select-keyword-hint": "Select this keyword",
"edit-keyword-hint": "Edit keyword",
"editing-done-hint": "Finish editing",
"force-language-selection": "Please select a language."
"force-language-selection": "Language detection inaccurate, please check language settings!",
"add-manually": "You can manually enter the keywords separated with a comma "
},
"comment-page": {
"a11y-comment_delete": "Deletes this question",
......
......@@ -99,7 +99,8 @@
"select-keyword-hint": "Dieses Stickwort auswählen",
"edit-keyword-hint": "Stichwort editieren",
"editing-done-hint": "Editierung abschliessen",
"force-language-selection": "Bitte wähle eine Sprache aus."
"force-language-selection": "Automatische Spracherkennung unpräzise, bitte gewählte Sprache prüfen!",
"add-manually": "Geben Sie bitte die Stichwörter unten mit separatem Komma ein"
},
"comment-page": {
"a11y-comment_input": "Gib deine Frage ein",
......
......@@ -109,7 +109,8 @@
"select-keyword-hint": "Select this keyword",
"edit-keyword-hint": "Edit keyword",
"editing-done-hint": "Finish editing",
"force-language-selection": "Please select a language."
"force-language-selection": "Language detection inaccurate, please check language settings!",
"add-manually": "You can manually enter the keywords separated with a comma "
},
"comment-page": {
"a11y-comment_input": "Enter your question",
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment