diff --git a/projects/ars/src/lib/services/ars-compose.service.ts b/projects/ars/src/lib/services/ars-compose.service.ts index 36ad1aba090d7bd5a2180c3087183736ca2afffd..12addc545af510d502f67404ea8882d308ace3d7 100644 --- a/projects/ars/src/lib/services/ars-compose.service.ts +++ b/projects/ars/src/lib/services/ars-compose.service.ts @@ -75,7 +75,9 @@ export class ArsComposeService{ altToggle(onFalse: ArsMatMenuItemConfig, onTrue: ArsMatMenuItemConfig, obs: ArsObserver<boolean>, condition: () => boolean): ArsObserver<boolean>{ onFalse.condition = () => !obs.get() && condition(); + onFalse.callback = () => obs.set(true); onTrue.condition = () => obs.get() && condition(); + onTrue.callback = () => obs.set(false); this.menuItem(onFalse); this.menuItem(onTrue); return obs; diff --git a/src/app/components/creator/_dialogs/tags/tags.component.html b/src/app/components/creator/_dialogs/tags/tags.component.html index ab35ec17fb64c99fca1e6a6e8b2793769be1ee08..57f69fb5ea3956d13665c85ade917ef440ce3e60 100644 --- a/src/app/components/creator/_dialogs/tags/tags.component.html +++ b/src/app/components/creator/_dialogs/tags/tags.component.html @@ -12,9 +12,9 @@ aria-labelledby="tag-new" [formControl]="tagFormControl" name="taginput" - maxlength="75"/> + maxlength="20"/> <mat-placeholder class="placeholder">{{ 'room-page.tag-new' | translate }}</mat-placeholder> - <mat-hint align="end"><span aria-hidden="true">{{tag.value.length}} / 30</span></mat-hint> + <mat-hint align="end"><span aria-hidden="true">{{tag.value.length}} / 20</span></mat-hint> <mat-error *ngIf="!tagFormControl.valid"> {{ 'room-page.tag-error' | translate }} </mat-error> diff --git a/src/app/components/creator/_dialogs/tags/tags.component.ts b/src/app/components/creator/_dialogs/tags/tags.component.ts index 00d7cd493052867dbdd9ed0eeca9e07f15872b5c..2af881260a334d9f6e0d12c7c2c89f9845429938 100644 --- a/src/app/components/creator/_dialogs/tags/tags.component.ts +++ b/src/app/components/creator/_dialogs/tags/tags.component.ts @@ -15,7 +15,7 @@ export class TagsComponent { tags: string[]; tagFormControl = new FormControl('', [ - Validators.minLength(3), Validators.maxLength(50) + Validators.minLength(3), Validators.maxLength(20) ]); private _closeSubscription: Subscription; diff --git a/src/app/components/creator/room-creator-page/room-creator-page.component.ts b/src/app/components/creator/room-creator-page/room-creator-page.component.ts index a4d1c17977747bdf2abb46c22d1d766d371fc339..a79feab2c2f0cdfa80287704ab4bfbf5bf483788 100644 --- a/src/app/components/creator/room-creator-page/room-creator-page.component.ts +++ b/src/app/components/creator/room-creator-page/room-creator-page.component.ts @@ -174,14 +174,14 @@ export class RoomCreatorPageComponent extends RoomPageComponent implements OnIni e.altToggle( { translate:this.headerService.getTranslate(), - text:'header.unlock', + text:'header.block', icon:'block', iconColor:Palette.RED, color:Palette.RED }, { translate:this.headerService.getTranslate(), - text:'header.block', + text:'header.unlock', icon:'block', iconColor:Palette.RED }, diff --git a/src/app/components/shared/comment/comment.component.html b/src/app/components/shared/comment/comment.component.html index c056b7ef015961973f3e3b05b6de8758f55a83bf..7ded0d2e6a8564510143addf2ee31727c7b16f27 100644 --- a/src/app/components/shared/comment/comment.component.html +++ b/src/app/components/shared/comment/comment.component.html @@ -40,7 +40,7 @@ <span class="fill-remaining-space"></span> <ng-container> <button mat-icon-button - *ngIf="(isCreator || isModerator)" + *ngIf="(isCreator || isModerator) && isProfanity" (click)="changeProfanityShowForModerators(comment)"> <mat-icon class="not-marked" [matTooltip]="filterProfanityForModerators ? ('comment-page.show-comment-with-filter' | translate) : diff --git a/src/app/components/shared/comment/comment.component.ts b/src/app/components/shared/comment/comment.component.ts index a1838d4a874aea4be5b43679d5634f610205d49f..563184abe51f96c93b7da93dba4a4d06805cb18e 100644 --- a/src/app/components/shared/comment/comment.component.ts +++ b/src/app/components/shared/comment/comment.component.ts @@ -49,9 +49,9 @@ export class CommentComponent implements OnInit, AfterViewInit { @Output() clickedOnKeyword = new EventEmitter<string>(); @Output() clickedUserNumber = new EventEmitter<number>(); @Output() votedComment = new EventEmitter<string>(); - @ViewChild('commentBody', { static: true })commentBody: RowComponent; - @ViewChild('commentBodyInner', { static: true })commentBodyInner: RowComponent; - @ViewChild('commentExpander', { static: true })commentExpander: RowComponent; + @ViewChild('commentBody', { static: true }) commentBody: RowComponent; + @ViewChild('commentBodyInner', { static: true }) commentBodyInner: RowComponent; + @ViewChild('commentExpander', { static: true }) commentExpander: RowComponent; isStudent = false; isCreator = false; isModerator = false; @@ -65,21 +65,22 @@ export class CommentComponent implements OnInit, AfterViewInit { isExpanded = false; isExpandable = false; filterProfanityForModerators = false; + isProfanity = false; constructor(protected authenticationService: AuthenticationService, - private route: ActivatedRoute, - private location: Location, - protected router: Router, - private commentService: CommentService, - private notification: NotificationService, - private translateService: TranslateService, - private roomDataService: RoomDataService, - public dialog: MatDialog, - protected langService: LanguageService) { + private route: ActivatedRoute, + private location: Location, + protected router: Router, + private commentService: CommentService, + private notification: NotificationService, + private translateService: TranslateService, + private roomDataService: RoomDataService, + public dialog: MatDialog, + protected langService: LanguageService) { langService.langEmitter.subscribe(lang => { translateService.use(lang); this.language = lang; - } ); + }); } ngOnInit() { @@ -103,22 +104,19 @@ export class CommentComponent implements OnInit, AfterViewInit { this.inAnswerView = !this.router.url.includes('comments'); } - checkProfanity(){ + checkProfanity() { if (!this.router.url.includes('moderator/comments')) { - this.roomDataService.checkProfanity(this.comment); + const subscription = this.roomDataService.checkProfanity(this.comment).subscribe(e => { + if (e !== null) { + this.isProfanity = e; + subscription.unsubscribe(); + } + }); } } changeProfanityShowForModerators(comment: Comment) { - let newBody: string; - if (this.filterProfanityForModerators) { - newBody = this.roomDataService.getFilteredBody(comment.id); - } else { - newBody = this.roomDataService.getUnFilteredBody(comment.id); - } - if (newBody) { - comment.body = newBody; - } + this.roomDataService.applyStateToComment(comment, !this.filterProfanityForModerators); this.filterProfanityForModerators = !this.filterProfanityForModerators; } @@ -132,18 +130,18 @@ export class CommentComponent implements OnInit, AfterViewInit { } } - sortKeywords(keywords: SpacyKeyword[]){ - return keywords.sort((a,b) => a.text.localeCompare(b.text)); + sortKeywords(keywords: SpacyKeyword[]) { + return keywords.sort((a, b) => a.text.localeCompare(b.text)); } toggleExpand(evt: MouseEvent) { this.isExpanded = !this.isExpanded; if (this.isExpanded) { this.commentBody.setPx(this.commentBodyInner.getRenderedHeight()); - this.commentBody.setOverflow('visible'); + this.commentBody.setOverflow('visible'); } else { this.commentBody.setPx(CommentComponent.COMMENT_MAX_HEIGHT); - this.commentBody.setOverflow('hidden'); + this.commentBody.setOverflow('hidden'); } } @@ -166,11 +164,11 @@ export class CommentComponent implements OnInit, AfterViewInit { } markCorrect(comment: Comment, type: CorrectWrong): void { - if (comment.correct === type) { - comment.correct = CorrectWrong.NULL; - } else { - comment.correct = type; - } + if (comment.correct === type) { + comment.correct = CorrectWrong.NULL; + } else { + comment.correct = type; + } this.commentService.markCorrect(comment).subscribe(c => { this.comment = c; this.checkProfanity(); @@ -218,18 +216,18 @@ export class CommentComponent implements OnInit, AfterViewInit { width: '400px' }); dialogRef.afterClosed() - .subscribe(result => { - if (result === 'delete') { - this.delete(); - } - }); + .subscribe(result => { + if (result === 'delete') { + this.delete(); + } + }); } resetVotingAnimation() { setTimeout(() => { - this.currentVote = ''; - }, - 1000); + this.currentVote = ''; + }, + 1000); } answerComment() { @@ -289,17 +287,17 @@ export class CommentComponent implements OnInit, AfterViewInit { }); dialogRef.componentInstance.body = comment.body; dialogRef.afterClosed() - .subscribe(result => { - this.commentService.lowlight(comment).subscribe(); - this.exitFullScreen(); + .subscribe(result => { + this.commentService.lowlight(comment).subscribe(); + this.exitFullScreen(); - }); + }); } openBonusStarDialog() { - const dialogRef = this.dialog.open(UserBonusTokenComponent, { - width: '600px' - }); - dialogRef.componentInstance.userId = this.user.id; + const dialogRef = this.dialog.open(UserBonusTokenComponent, { + width: '600px' + }); + dialogRef.componentInstance.userId = this.user.id; } } diff --git a/src/app/services/util/profanity-filter.service.ts b/src/app/services/util/profanity-filter.service.ts index 3d710236f1c748f182ee6de2f2463f3ed72e834b..0e1237e348979f6a7ef645127c2320529d40aa60 100644 --- a/src/app/services/util/profanity-filter.service.ts +++ b/src/app/services/util/profanity-filter.service.ts @@ -77,7 +77,7 @@ export class ProfanityFilterService { profWords = this.profanityWords; } const list = profWords.concat(this.getProfanityListFromStorage()); - if (list.length < 1) { + if (list.length < 1 || !str) { return [str, false]; } const escapeRegex = /[.*+\-?^${}()|\[\]\\]/g; diff --git a/src/app/services/util/room-data.service.ts b/src/app/services/util/room-data.service.ts index 12e7f984cc3acd9ff3879722fb2c0dff6e75df4c..6465af45aae2340bb87019aba083f63e19e2a12f 100644 --- a/src/app/services/util/room-data.service.ts +++ b/src/app/services/util/room-data.service.ts @@ -89,6 +89,8 @@ interface CommentFilterData { genKeywordsCensored?: boolean[]; userKeywords: SpacyKeyword[]; userKeywordsCensored?: boolean[]; + questionerName: string; + questionerNameCensored?: boolean; } @Injectable({ @@ -152,43 +154,47 @@ export class RoomDataService { return tempSubject.asObservable(); } - public checkProfanity(comment: Comment) { - const finish = new Subject<boolean>(); - const subscription = finish.asObservable().subscribe(_ => { - let obj; - if (this.room.profanityFilter !== ProfanityFilter.deactivated) { - obj = this._savedCommentsAfterFilter.get(comment.id); - } else { - obj = this._savedCommentsBeforeFilter.get(comment.id); - } - comment.body = obj.body; - comment.keywordsFromSpacy = obj.genKeywords; - comment.keywordsFromQuestioner = obj.userKeywords; - subscription.unsubscribe(); - }); - + public checkProfanity(comment: Comment): Observable<boolean> { + const subject = new BehaviorSubject<boolean>(null); if (!this._savedCommentsAfterFilter.get(comment.id) || !this.room) { if (!this.room) { this.roomService.getRoom(localStorage.getItem('roomId')).subscribe(room => { this.room = room; this.setCommentBody(comment); - finish.next(true); + this.applyStateToComment(comment, this.room.profanityFilter === ProfanityFilter.deactivated); + subject.next(this.isCommentProfane(comment)); }); } else { this.setCommentBody(comment); - finish.next(true); + this.applyStateToComment(comment, this.room.profanityFilter === ProfanityFilter.deactivated); + subject.next(this.isCommentProfane(comment)); } } else { - finish.next(true); + this.applyStateToComment(comment, this.room.profanityFilter === ProfanityFilter.deactivated); + subject.next(this.isCommentProfane(comment)); } + return subject; } - getUnFilteredBody(id: string): string { - return this._savedCommentsBeforeFilter.get(id).body; + applyStateToComment(comment: Comment, beforeFilter: boolean) { + let data: CommentFilterData; + if (beforeFilter) { + data = this._savedCommentsBeforeFilter.get(comment.id); + } else { + data = this._savedCommentsAfterFilter.get(comment.id); + } + comment.body = data.body; + comment.keywordsFromSpacy = data.genKeywords; + comment.keywordsFromQuestioner = data.userKeywords; + comment.questionerName = data.questionerName; } - getFilteredBody(id: string): string { - return this._savedCommentsAfterFilter.get(id).body; + isCommentProfane(comment: Comment): boolean { + const data = this._savedCommentsAfterFilter.get(comment.id); + return data.bodyCensored || + data.questionerNameCensored || + data.userKeywordsCensored.some(e => e) || + data.genKeywordsCensored.some(e => e); } getCensoredInformation(comment: Comment): CommentFilterData { @@ -201,7 +207,8 @@ export class RoomDataService { this._savedCommentsBeforeFilter.set(comment.id, { body: comment.body, genKeywords, - userKeywords + userKeywords, + questionerName: comment.questionerName }); this._savedCommentsAfterFilter.set(comment.id, this.filterCommentOfProfanity(this.room, comment)); } @@ -226,13 +233,17 @@ export class RoomDataService { .checkKeywords(comment.keywordsFromSpacy, partialWords, languageSpecific, comment.language); const [userKeywords, userKeywordsCensored] = this .checkKeywords(comment.keywordsFromQuestioner, partialWords, languageSpecific, comment.language); + const [questionerName, questionerNameCensored] = this.profanityFilterService + .filterProfanityWords(comment.questionerName, partialWords, languageSpecific, comment.language); return { body, bodyCensored, genKeywords, genKeywordsCensored, userKeywords, - userKeywordsCensored + userKeywordsCensored, + questionerName, + questionerNameCensored }; }