From 637749d9fcbae13b915e28a7f8993508e79cd905 Mon Sep 17 00:00:00 2001
From: Ruben Bimberg <ruben.bimberg@mni.thm.de>
Date: Wed, 27 Oct 2021 11:12:13 +0200
Subject: [PATCH] Resolve "The question list as input for the topic cloud is
 always zero"

---
 .../moderator-comment-list.component.ts       |   4 +-
 .../topic-cloud-filter.component.ts           |  18 +-
 .../comment-list/comment-list.component.ts    |  24 +--
 .../comment-list/comment-list.filter.ts       |  31 +++-
 .../shared/header/header.component.ts         |  16 +-
 .../question-wall/question-wall.component.ts  |   2 +-
 .../tag-cloud-pop-up.component.ts             |   7 +-
 src/app/services/http/comment.service.ts      |   1 -
 .../services/util/tag-cloud-data.service.ts   |  10 +-
 src/app/utils/RoleChecker.ts                  |  15 ++
 src/app/utils/filter-options.ts               | 175 ------------------
 11 files changed, 70 insertions(+), 233 deletions(-)
 create mode 100644 src/app/utils/RoleChecker.ts
 delete mode 100644 src/app/utils/filter-options.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 7cf488d0a..8e8a8fe0f 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
@@ -21,12 +21,11 @@ import { DeleteCommentsComponent } from '../../creator/_dialogs/delete-comments/
 import { Export } from '../../../models/export';
 import { NotificationService } from '../../../services/util/notification.service';
 import { BonusTokenService } from '../../../services/http/bonus-token.service';
-import { Period } from '../../../utils/filter-options';
 import { PageEvent } from '@angular/material/paginator';
 import {
   CommentListFilter,
   FilterType,
-  FilterTypeKey,
+  FilterTypeKey, Period,
   SortType,
   SortTypeKey
 } from '../../shared/comment-list/comment-list.filter';
@@ -199,7 +198,6 @@ export class ModeratorCommentListComponent implements OnInit, OnDestroy {
     this.translateService.use(localStorage.getItem('currentLang'));
     this.deviceType = localStorage.getItem('deviceType');
     this.isSafari = localStorage.getItem('isSafari');
-    this.filter.sortType = SortType.votedesc;
     this.moderationService.get(this.roomId)
       .subscribe((mods) => {
         this.filter.updateModerators(mods.map(mod => mod.accountId));
diff --git a/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts b/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts
index 2bb415a75..9cbb6c256 100644
--- a/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts
+++ b/src/app/components/shared/_dialogs/topic-cloud-filter/topic-cloud-filter.component.ts
@@ -6,7 +6,6 @@ import { RoomCreatorPageComponent } from '../../../creator/room-creator-page/roo
 import { LanguageService } from '../../../../services/util/language.service';
 import { EventService } from '../../../../services/util/event.service';
 import { Router } from '@angular/router';
-import { CommentFilter, Period } from '../../../../utils/filter-options';
 import { RoomService } from '../../../../services/http/room.service';
 import { Comment } from '../../../../models/comment';
 import { CommentListData } from '../../comment-list/comment-list.component';
@@ -22,6 +21,7 @@ import { ModeratorService } from '../../../../services/http/moderator.service';
 import { UserRole } from '../../../../models/user-roles.enum';
 import { RoomDataService } from '../../../../services/util/room-data.service';
 import { Subscription } from 'rxjs';
+import { CommentListFilter, Period } from '../../comment-list/comment-list.filter';
 
 class CommentsCount {
   comments: number;
@@ -47,7 +47,7 @@ export class TopicCloudFilterComponent implements OnInit, OnDestroy {
   question = '';
   continueFilter = 'continueWithAll';
   comments: Comment[];
-  tmpFilter: CommentFilter;
+  tmpFilter: CommentListFilter;
   allComments: CommentsCount;
   filteredComments: CommentsCount;
   disableCurrentFiltersOptions = false;
@@ -84,6 +84,7 @@ export class TopicCloudFilterComponent implements OnInit, OnDestroy {
     this.translationService.use(localStorage.getItem('currentLang'));
     const subscriptionEventService = this.eventService.on<CommentListData>('currentRoomData').subscribe(data => {
       subscriptionEventService.unsubscribe();
+      console.log(data.currentFilter);
       this.tmpFilter = data.currentFilter;
       this._room = data.room;
       this.roomDataService.getRoomData(data.room.id).subscribe(roomData => {
@@ -110,7 +111,7 @@ export class TopicCloudFilterComponent implements OnInit, OnDestroy {
       return;
     }
     this.allComments = this.getCommentCounts(this.comments);
-    this.filteredComments = this.getCommentCounts(this.comments.filter(comment => this.tmpFilter.checkComment(comment)));
+    this.filteredComments = this.getCommentCounts(this.tmpFilter.checkAll(this.comments));
     if (isNew) {
       this.hasNoKeywords = this.isUpdatable();
     }
@@ -159,17 +160,18 @@ export class TopicCloudFilterComponent implements OnInit, OnDestroy {
 
   confirmButtonActionCallback() {
     return () => {
-      let filter: CommentFilter;
+      let filter: CommentListFilter;
 
       switch (this.continueFilter) {
         case 'continueWithAll':
           // all questions allowed
-          filter = new CommentFilter();
-          filter.periodSet = Period.all;
+          filter = new CommentListFilter(null);
           break;
 
         case 'continueWithAllFromNow':
-          filter = CommentFilter.generateFilterNow(this.tmpFilter.filterSelected);
+          filter = new CommentListFilter(null);
+          filter.period = Period.fromNow;
+          filter.fromNow = new Date().getTime();
           break;
 
         case 'continueWithCurr':
@@ -182,7 +184,7 @@ export class TopicCloudFilterComponent implements OnInit, OnDestroy {
 
       localStorage.setItem('tag-cloud-question', this.question);
 
-      CommentFilter.currentFilter = filter;
+      filter.save();
 
       this.dialogRef.close(this.router.navigateByUrl(this.target));
     };
diff --git a/src/app/components/shared/comment-list/comment-list.component.ts b/src/app/components/shared/comment-list/comment-list.component.ts
index c9721acae..eb8fcf507 100644
--- a/src/app/components/shared/comment-list/comment-list.component.ts
+++ b/src/app/components/shared/comment-list/comment-list.component.ts
@@ -24,7 +24,6 @@ import { DeleteCommentsComponent } from '../../creator/_dialogs/delete-comments/
 import { Export } from '../../../models/export';
 import { BonusTokenService } from '../../../services/http/bonus-token.service';
 import { ModeratorService } from '../../../services/http/moderator.service';
-import { CommentFilter, Period } from '../../../utils/filter-options';
 import { CreateCommentWrapper } from '../../../utils/create-comment-wrapper';
 import { TopicCloudAdminService } from '../../../services/util/topic-cloud-admin.service';
 import { RoomDataService } from '../../../services/util/room-data.service';
@@ -33,10 +32,10 @@ import { ActiveUserService } from '../../../services/http/active-user.service';
 import { OnboardingService } from '../../../services/util/onboarding.service';
 import { WorkerDialogComponent } from '../_dialogs/worker-dialog/worker-dialog.component';
 import { PageEvent } from '@angular/material/paginator';
-import { CommentListFilter, FilterType, FilterTypeKey, SortType, SortTypeKey } from './comment-list.filter';
+import { CommentListFilter, FilterType, FilterTypeKey, Period, SortType, SortTypeKey } from './comment-list.filter';
 
 export interface CommentListData {
-  currentFilter: CommentFilter;
+  currentFilter: CommentListFilter;
   room: Room;
 }
 
@@ -131,7 +130,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
     });
     this._subscriptionEventServiceRoomData = this.eventService.on<string>('pushCurrentRoomData').subscribe(_ => {
       this.eventService.broadcast('currentRoomData', {
-        currentFilter: this.getCurrentFilter(),
+        currentFilter: this.filter,
         room: this.room
       } as CommentListData);
     });
@@ -377,6 +376,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
 
   activateCommentStream(freezed: boolean) {
     this.freeze = freezed;
+    this.filter.freezedAt = freezed ? new Date().getTime() : null;
     this.roomDataService.getRoomData(this.roomId, freezed).subscribe(comments => {
       if (comments === null) {
         return;
@@ -466,22 +466,6 @@ export class CommentListComponent implements OnInit, OnDestroy {
     this.commentsEnabled = (this.userRole > UserRole.PARTICIPANT) || !room.questionsBlocked;
   }
 
-  private getCurrentFilter(): CommentFilter {
-    const filter = new CommentFilter();
-    filter.filterSelected = this.filter.filterType;
-    filter.paused = this.freeze;
-    filter.periodSet = this.filter.period;
-    filter.keywordSelected = this.filter.filterCompare;
-    filter.tagSelected = this.filter.filterCompare;
-    filter.userNumberSelected = this.filter.filterCompare;
-
-    if (filter.periodSet === Period.fromNow) {
-      filter.timeStampNow = new Date().getTime();
-    }
-
-    return filter;
-  }
-
   private generateKeywordsIfEmpty() {
     if (this.comments.length > 0 && this.userRole === UserRole.CREATOR) {
       const count = this.comments.reduce((acc, comment) =>
diff --git a/src/app/components/shared/comment-list/comment-list.filter.ts b/src/app/components/shared/comment-list/comment-list.filter.ts
index bc544b0ae..32ce9d479 100644
--- a/src/app/components/shared/comment-list/comment-list.filter.ts
+++ b/src/app/components/shared/comment-list/comment-list.filter.ts
@@ -1,8 +1,17 @@
-import { Period } from '../../../utils/filter-options';
 import { Comment } from '../../../models/comment';
 import { CorrectWrong } from '../../../models/correct-wrong.enum';
 import { Room } from '../../../models/room';
 
+export enum Period {
+  fromNow = 'from-now',
+  oneHour = 'time-1h',
+  threeHours = 'time-3h',
+  oneDay = 'time-1d',
+  oneWeek = 'time-1w',
+  twoWeeks = 'time-2w',
+  all = 'time-all'
+}
+
 export enum FilterType {
   voteasc = 'voteasc',
   votedesc = 'votedesc',
@@ -41,6 +50,7 @@ export class CommentListFilter {
   //own properties
   period: Period;
   fromNow: number;
+  freezedAt: number;
   filterType: FilterType;
   filterCompare: any;
   sortType: SortType;
@@ -59,6 +69,7 @@ export class CommentListFilter {
     }
     this.period = obj.period;
     this.fromNow = obj.fromNow;
+    this.freezedAt = obj.freezedAt;
     this.filterType = obj.filterType;
     this.filterCompare = obj.filterCompare;
     this.sortType = obj.sortType;
@@ -73,6 +84,7 @@ export class CommentListFilter {
   resetToDefault() {
     this.period = DEFAULT_PERIOD;
     this.fromNow = null;
+    this.freezedAt = null;
     this.filterType = null;
     this.filterCompare = null;
     this.sortType = DEFAULT_SORT;
@@ -117,6 +129,14 @@ export class CommentListFilter {
     return this.moderatorIds;
   }
 
+  checkAll(comments: Comment[], moderation = false): Comment[] {
+    const filterComments = this.filterCommentsByTime(comments, moderation);
+    if (this.currentSearch) {
+      return this.filterCommentsBySearch(filterComments);
+    }
+    return this.sortCommentsBySortType(this.filterCommentsByType(filterComments));
+  }
+
   filterCommentsBySearch(comments: Comment[]): Comment[] {
     const search = this.currentSearch.toLowerCase();
     return comments
@@ -136,7 +156,9 @@ export class CommentListFilter {
       this.period = DEFAULT_PERIOD;
     }
     if (this.period === Period.all) {
-      return thresholdComments;
+      return this.freezedAt ?
+        thresholdComments.filter(c => new Date(c.timestamp).getTime() < this.freezedAt) :
+        thresholdComments;
     }
     const currentTime = new Date().getTime();
     let periodInSeconds;
@@ -166,7 +188,10 @@ export class CommentListFilter {
         throw new Error('Time period is invalid.');
     }
     const filterTime = (this.period === Period.fromNow ? this.fromNow : currentTime - periodInSeconds);
-    return thresholdComments.filter(c => new Date(c.timestamp).getTime() >= filterTime);
+    return thresholdComments.filter(c => {
+      const time = new Date(c.timestamp).getTime();
+      return time >= filterTime && (!this.freezedAt || time < this.freezedAt);
+    });
   }
 
   filterCommentsByType(comment: Comment[]): Comment[] {
diff --git a/src/app/components/shared/header/header.component.ts b/src/app/components/shared/header/header.component.ts
index b522154bc..91bcbd193 100644
--- a/src/app/components/shared/header/header.component.ts
+++ b/src/app/components/shared/header/header.component.ts
@@ -31,6 +31,7 @@ import { OnboardingService } from '../../../services/util/onboarding.service';
 import { WorkerConfigDialogComponent } from '../_dialogs/worker-config-dialog/worker-config-dialog.component';
 import { ArsComposeHostDirective } from '../../../../../projects/ars/src/lib/compose/ars-compose-host.directive';
 import { ThemeService } from '../../../../theme/theme.service';
+import { RoleChecker } from '../../../utils/RoleChecker';
 
 @Component({
   selector: 'app-header',
@@ -85,20 +86,7 @@ export class HeaderComponent implements OnInit, AfterViewInit {
   ngOnInit() {
     this.router.events.subscribe(e => {
       if (e instanceof NavigationEnd) {
-        const url = e.url.toLowerCase();
-        if (url.startsWith('/participant/')) {
-          this.userRole = UserRole.PARTICIPANT;
-          this.isInRouteWithRoles = true;
-        } else if (url.startsWith('/moderator/')) {
-          this.userRole = UserRole.EXECUTIVE_MODERATOR;
-          this.isInRouteWithRoles = !url.endsWith('/moderator/comments');
-        } else if (url.startsWith('/creator/')) {
-          this.userRole = UserRole.CREATOR;
-          this.isInRouteWithRoles = !url.endsWith('/moderator/comments');
-        } else {
-          this.userRole = this.user ? this.user.role : UserRole.PARTICIPANT;
-          this.isInRouteWithRoles = false;
-        }
+        [this.userRole, this.isInRouteWithRoles] = RoleChecker.checkRole(e.url, this.user?.role);
       }
     });
     this.topicCloudAdminService.getAdminData.subscribe(data => {
diff --git a/src/app/components/shared/questionwall/question-wall/question-wall.component.ts b/src/app/components/shared/questionwall/question-wall/question-wall.component.ts
index 4506a8b84..49c01882d 100644
--- a/src/app/components/shared/questionwall/question-wall/question-wall.component.ts
+++ b/src/app/components/shared/questionwall/question-wall/question-wall.component.ts
@@ -13,8 +13,8 @@ import { TranslateService } from '@ngx-translate/core';
 import { Rescale } from '../../../../models/rescale';
 import { QuestionWallKeyEventSupport } from '../QuestionWallKeyEventSupport';
 import { MatSliderChange } from '@angular/material/slider';
-import { Period } from '../../../../utils/filter-options';
 import { RoomDataService } from '../../../../services/util/room-data.service';
+import { Period } from '../../comment-list/comment-list.filter';
 
 @Component({
   selector: 'app-question-wall',
diff --git a/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.ts b/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.ts
index 682a9374b..ec9c78ece 100644
--- a/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.ts
+++ b/src/app/components/shared/tag-cloud/tag-cloud-pop-up/tag-cloud-pop-up.component.ts
@@ -10,7 +10,8 @@ import { NotificationService } from '../../../../services/util/notification.serv
 import { MatAutocompleteTrigger } from '@angular/material/autocomplete';
 import { UserRole } from '../../../../models/user-roles.enum';
 import { SpacyKeyword } from '../../../../services/http/spacy.service';
-import { ActivatedRoute } from '@angular/router';
+import { Router } from '@angular/router';
+import { RoleChecker } from '../../../../utils/RoleChecker';
 
 const CLOSE_TIME = 1500;
 
@@ -41,7 +42,7 @@ export class TagCloudPopUpComponent implements OnInit, AfterViewInit {
               private tagCloudDataService: TagCloudDataService,
               private languagetoolService: LanguagetoolService,
               private commentService: CommentService,
-              private route: ActivatedRoute,
+              private router: Router,
               private notificationService: NotificationService) {
     this.langService.langEmitter.subscribe(lang => {
       this.translateService.use(lang);
@@ -49,7 +50,7 @@ export class TagCloudPopUpComponent implements OnInit, AfterViewInit {
   }
 
   ngOnInit(): void {
-    this.userRole = this.route.snapshot.data.roles[0];
+    [this.userRole] = RoleChecker.checkRole(decodeURI(this.router.url));
     this.timePeriodText = '...';
   }
 
diff --git a/src/app/services/http/comment.service.ts b/src/app/services/http/comment.service.ts
index 0de32cdb2..8841ca6bf 100644
--- a/src/app/services/http/comment.service.ts
+++ b/src/app/services/http/comment.service.ts
@@ -6,7 +6,6 @@ import { catchError, tap, map } from 'rxjs/operators';
 import { BaseHttpService } from './base-http.service';
 import { TSMap } from 'typescript-map';
 import { Vote } from '../../models/vote';
-import { CommentFilter } from '../../utils/filter-options';
 
 const httpOptions = {
   // eslint-disable-next-line @typescript-eslint/naming-convention
diff --git a/src/app/services/util/tag-cloud-data.service.ts b/src/app/services/util/tag-cloud-data.service.ts
index f737f79d0..84a267bd9 100644
--- a/src/app/services/util/tag-cloud-data.service.ts
+++ b/src/app/services/util/tag-cloud-data.service.ts
@@ -2,7 +2,6 @@ import { Injectable } from '@angular/core';
 import { TopicCloudAdminData } from '../../components/shared/_dialogs/topic-cloud-administration/TopicCloudAdminData';
 import { BehaviorSubject, Observable, Subscription } from 'rxjs';
 import { TopicCloudAdminService } from './topic-cloud-admin.service';
-import { CommentFilter } from '../../utils/filter-options';
 import { TranslateService } from '@ngx-translate/core';
 import { Comment } from '../../models/comment';
 import { RoomDataService } from './room-data.service';
@@ -11,6 +10,7 @@ import { UserRole } from '../../models/user-roles.enum';
 import { CloudParameters } from '../../utils/cloud-parameters';
 import { SmartDebounce } from '../../utils/smart-debounce';
 import { ModeratorService } from '../http/moderator.service';
+import { CommentListFilter } from '../../components/shared/comment-list/comment-list.filter';
 
 export interface TagCloudDataTagEntry {
   weight: number;
@@ -81,7 +81,7 @@ export class TagCloudDataService {
   private _demoData: TagCloudData = null;
   private _adminData: TopicCloudAdminData = null;
   private _subscriptionAdminData: Subscription;
-  private _currentFilter: CommentFilter;
+  private _currentFilter: CommentListFilter;
   private _currentModerators: string[];
   private _currentOwner: string;
   private readonly _smartDebounce = new SmartDebounce(200, 3_000);
@@ -176,7 +176,7 @@ export class TagCloudDataService {
       throw new Error('Room already bound.');
     }
     this._currentModerators = null;
-    this._currentFilter = CommentFilter.currentFilter;
+    this._currentFilter = CommentListFilter.loadCurrentFilter();
     this._roomId = roomId;
     this._currentOwner = roomOwner;
     this._moderatorService.get(roomId).subscribe(moderators => {
@@ -190,7 +190,7 @@ export class TagCloudDataService {
     this._tagCloudAdmin.ensureRoomBound(roomId, userRole);
 
     this.fetchData();
-    if (!this._currentFilter.paused) {
+    if (!this._currentFilter.freezedAt) {
       this._commentSubscription = this._roomDataService.receiveUpdates([
         { type: 'CommentCreated', finished: true },
         { type: 'CommentDeleted' },
@@ -360,7 +360,7 @@ export class TagCloudDataService {
       return;
     }
     const currentMeta = this._isDemoActive ? this._lastMetaData : this._currentMetaData;
-    const filteredComments = this._lastFetchedComments.filter(comment => this._currentFilter.checkComment(comment));
+    const filteredComments = this._currentFilter.checkAll(this._lastFetchedComments);
     currentMeta.commentCount = filteredComments.length;
     const [data, users] = TagCloudDataService.buildDataFromComments(this._currentOwner, this._currentModerators,
       this._adminData, this._roomDataService, filteredComments);
diff --git a/src/app/utils/RoleChecker.ts b/src/app/utils/RoleChecker.ts
new file mode 100644
index 000000000..e04d8b10a
--- /dev/null
+++ b/src/app/utils/RoleChecker.ts
@@ -0,0 +1,15 @@
+import { UserRole } from '../models/user-roles.enum';
+
+export class RoleChecker {
+  static checkRole(url: string, fallback = UserRole.PARTICIPANT): [userRole: UserRole, routeWithRoles: boolean] {
+    url = url.toLowerCase();
+    if (url.startsWith('/participant/')) {
+      return [UserRole.PARTICIPANT, true];
+    } else if (url.startsWith('/moderator/')) {
+      return [UserRole.EXECUTIVE_MODERATOR, !url.endsWith('/moderator/comments')];
+    } else if (url.startsWith('/creator/')) {
+      return [UserRole.CREATOR, !url.endsWith('/moderator/comments')];
+    }
+    return [fallback ?? UserRole.PARTICIPANT, false];
+  }
+}
diff --git a/src/app/utils/filter-options.ts b/src/app/utils/filter-options.ts
deleted file mode 100644
index 6e815f550..000000000
--- a/src/app/utils/filter-options.ts
+++ /dev/null
@@ -1,175 +0,0 @@
-import { Comment } from '../models/comment';
-import { CorrectWrong } from '../models/correct-wrong.enum';
-
-export const enum FilterNames {
-  read = 'read',
-  unread = 'unread',
-  favorite = 'favorite',
-  correct = 'correct',
-  wrong = 'wrong',
-  bookmark = 'bookmark',
-  answer = 'answer',
-  unanswered = 'unanswered'
-}
-
-export enum Period {
-  fromNow = 'from-now',
-  oneHour = 'time-1h',
-  threeHours = 'time-3h',
-  oneDay = 'time-1d',
-  oneWeek = 'time-1w',
-  twoWeeks = 'time-2w',
-  all = 'time-all'
-}
-
-export class CommentFilter {
-  filterSelected = '';
-  keywordSelected = '';
-  tagSelected = '';
-  userNumberSelected = 0;
-
-  paused = false;
-  timeStampUntil = 0;
-
-  periodSet: Period = Period.twoWeeks;
-  timeStampNow = 0;
-
-  constructor(obj?: any) {
-    if (obj) {
-      this.filterSelected = obj.filterSelected;
-      this.keywordSelected = obj.keywordSelected;
-      this.tagSelected = obj.tagSelected;
-      this.paused = obj.paused;
-      this.timeStampUntil = obj.timeStampUntil;
-      this.periodSet = obj.periodSet;
-      this.timeStampNow = obj.timeStampNow;
-      this.userNumberSelected = obj.userNumberSelected;
-    }
-  }
-
-  public static set currentFilter(filter: CommentFilter) {
-    localStorage.setItem('filter', JSON.stringify(filter));
-  }
-
-  public static get currentFilter(): CommentFilter {
-    return new CommentFilter(JSON.parse(localStorage.getItem('filter')));
-  }
-
-  public static generateFilterNow(filterSelected: string): CommentFilter {
-    const filter = new CommentFilter();
-
-    filter.userNumberSelected = 0;
-    filter.filterSelected = filterSelected;
-    filter.paused = false;
-
-    filter.tagSelected = '';
-    filter.keywordSelected = '';
-
-    filter.periodSet = Period.fromNow;
-    filter.timeStampNow = new Date().getTime();
-
-    return filter;
-  }
-
-  public static generateFilterUntil(filterSelected: string, periodSelected: Period, untilTime: number,
-                                    tagSelected: string, keywordSelected: string): CommentFilter {
-    const filter = new CommentFilter();
-
-
-    filter.userNumberSelected = 0;
-    filter.filterSelected = filterSelected;
-
-    filter.paused = true;
-    filter.timeStampUntil = untilTime;
-
-    filter.tagSelected = tagSelected;
-    filter.keywordSelected = keywordSelected;
-
-    filter.periodSet = periodSelected;
-
-    return filter;
-  }
-
-  public checkComment(com: Comment): boolean {
-    return (this.checkPeriod(com) && this.checkFilters(com));
-  }
-
-  private checkPeriod(com: Comment): boolean {
-    /* Filter by Period */
-    const currentTime = new Date();
-    const hourInSeconds = 3600000;
-    let periodInSeconds;
-
-    if (this.periodSet === Period.all) {
-      return true;
-    }
-
-    switch (this.periodSet) {
-      case Period.fromNow:
-        break;
-      case Period.oneHour:
-        periodInSeconds = hourInSeconds;
-        break;
-      case Period.threeHours:
-        periodInSeconds = hourInSeconds * 3;
-        break;
-      case Period.oneDay:
-        periodInSeconds = hourInSeconds * 24;
-        break;
-      case Period.oneWeek:
-        periodInSeconds = hourInSeconds * 168;
-        break;
-      case Period.twoWeeks:
-        periodInSeconds = hourInSeconds * 336;
-        break;
-    }
-
-    const commentTime = new Date(com.timestamp).getTime();
-
-    if (this.periodSet === Period.fromNow) {
-      return commentTime > this.timeStampNow;
-    }
-
-    if (this.paused) {
-      return commentTime < this.timeStampUntil;
-    }
-
-    return commentTime > (currentTime.getTime() - periodInSeconds);
-  }
-
-  private checkFilters(com: Comment): boolean {
-    if (this.filterSelected) {  // no filters => return true
-      switch (this.filterSelected) {
-        case FilterNames.correct:
-          return com.correct === CorrectWrong.CORRECT;
-        case FilterNames.wrong:
-          return com.correct === CorrectWrong.WRONG;
-        case FilterNames.favorite:
-          return com.favorite;
-        case FilterNames.bookmark:
-          return com.bookmark;
-        case FilterNames.read:
-          return com.read;
-        case FilterNames.unread:
-          return !com.read;
-        case FilterNames.answer:
-          return com.answer !== '';
-        case FilterNames.unanswered:
-          return !com.answer;
-      }
-    }
-
-    if (this.userNumberSelected !== 0) {
-      return com.userNumber === this.userNumberSelected;
-    }
-
-    if (this.keywordSelected !== '') {
-      return com.keywordsFromQuestioner.findIndex(e => e.text === this.keywordSelected) >= 0;
-    }
-
-    if (this.tagSelected !== '') {
-      return com.tag === this.tagSelected;
-    }
-    return true;
-  }
-}
-- 
GitLab