Skip to content
Snippets Groups Projects
Commit 18984746 authored by Lukas Mauß's avatar Lukas Mauß
Browse files

Add filter by time period to comment list

A new button is now displayed in comment list view for creators and participants. A click on the button will open
a menu with which the user can select a time period for the displayed comments. Sorting and filtering actions will
applied to the selected period. Displaying all existing comments is the default setting.
parent 6642dedb
No related merge requests found
...@@ -36,9 +36,9 @@ ...@@ -36,9 +36,9 @@
<div class="button-bar" <div class="button-bar"
fxLayoutAlign="center center"> fxLayoutAlign="center center">
<div *ngIf="comments && comments.length > 0"> <div *ngIf="comments && commentsFilteredByTime.length > 0">
<h3 class="counter" <h3 class="counter"
*ngIf="!hideCommentsList">{{comments.length}}</h3> *ngIf="!hideCommentsList">{{commentsFilteredByTime.length}}</h3>
<h3 class="counter-filtered" <h3 class="counter-filtered"
*ngIf="filteredComments && hideCommentsList">{{filteredComments.length}}</h3> *ngIf="filteredComments && hideCommentsList">{{filteredComments.length}}</h3>
</div> </div>
...@@ -70,6 +70,16 @@ ...@@ -70,6 +70,16 @@
<mat-icon class="searchBarIcon">filter_list</mat-icon> <mat-icon class="searchBarIcon">filter_list</mat-icon>
</button> </button>
<button id="time-button"
mat-icon-button
class="searchBarButton"
aria-labelledby="time_settings"
*ngIf="!searchBox.value && comments && comments.length > 0 && !search"
[matMenuTriggerFor]="timeMenu"
matTooltip="{{ 'comment-list.select-time' | translate }}">
<mat-icon class="searchBarIcon">access_time</mat-icon>
</button>
<button id="pause-comments" <button id="pause-comments"
mat-fab mat-fab
aria-labelledby="pause" aria-labelledby="pause"
...@@ -92,6 +102,16 @@ ...@@ -92,6 +102,16 @@
</div> </div>
<mat-menu #timeMenu="matMenu" xPosition="before">
<div *ngFor="let periodItem of periodsList">
<button mat-menu-item (click)="setTimePeriod(periodItem)" class="period"
[ngClass]="{'selected': periodItem === period}"
aria-labelledby="{{periodItem}}">
<span>{{ ('comment-list.select-' + periodItem) | translate }}</span>
</button>
</div>
</mat-menu>
<mat-menu #sortMenu="matMenu" <mat-menu #sortMenu="matMenu"
xPosition="before"> xPosition="before">
...@@ -185,7 +205,7 @@ ...@@ -185,7 +205,7 @@
</button> </button>
<div *ngIf="!isLoading"> <div *ngIf="!isLoading">
<app-comment *ngFor="let current of hideCommentsList ? filteredComments : comments" <app-comment *ngFor="let current of hideCommentsList ? filteredComments : commentsFilteredByTime"
[comment]="current" [comment]="current"
[parseVote]="getVote(current)" [parseVote]="getVote(current)"
[userRole]="userRole" [userRole]="userRole"
...@@ -197,7 +217,7 @@ ...@@ -197,7 +217,7 @@
</div> </div>
<!-- No Questions Present --> <!-- No Questions Present -->
<div *ngIf="comments && comments.length < 1 && !isLoading" <div *ngIf="comments && commentsFilteredByTime.length < 1 && !isLoading"
fxLayout="row" fxLayout="row"
fxLayoutAlign="center center" fxLayoutAlign="center center"
class="no-comments"> class="no-comments">
...@@ -224,4 +244,10 @@ ...@@ -224,4 +244,10 @@
<div id="play">{{'comment-list.a11y-play' | translate}}</div> <div id="play">{{'comment-list.a11y-play' | translate}}</div>
<div id="close_search">{{'comment-list.a11y-close_search' | translate}}</div> <div id="close_search">{{'comment-list.a11y-close_search' | translate}}</div>
<div id="new-comment">{{ 'comment-page.new-comment' | translate:{comment: newestComment} }}</div> <div id="new-comment">{{ 'comment-page.new-comment' | translate:{comment: newestComment} }}</div>
<div id="select-time">{{ 'comment-list.a11y-select-time' | translate }}</div>
<div id="select-time-1h">{{ 'comment-list.a11y-select-time-1h' | translate }}</div>
<div id="select-time-3h">{{ 'comment-list.a11y-select-time-3h' | translate }}</div>
<div id="select-time-1d">{{ 'comment-list.a11y-select-time-1d' | translate }}</div>
<div id="select-time-1w">{{ 'comment-list.a11y-select-time-1w' | translate }}</div>
<div id="select-time-all">{{ 'comment-list.a11y-select-time-all' | translate }}</div>
</div> </div>
...@@ -202,3 +202,7 @@ h3 { ...@@ -202,3 +202,7 @@ h3 {
.visible { .visible {
transform: scale(1.4); transform: scale(1.4);
} }
.selected {
font-weight: bold;
}
...@@ -24,11 +24,20 @@ import { AuthenticationService } from '../../../services/http/authentication.ser ...@@ -24,11 +24,20 @@ import { AuthenticationService } from '../../../services/http/authentication.ser
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
import { TitleService } from '../../../services/util/title.service'; import { TitleService } from '../../../services/util/title.service';
export enum Period {
ONEHOUR = 'time-1h',
THREEHOURS = 'time-3h',
ONEDAY = 'time-1d',
ONEWEEK = 'time-1w',
ALL = 'time-all'
}
@Component({ @Component({
selector: 'app-comment-list', selector: 'app-comment-list',
templateUrl: './comment-list.component.html', templateUrl: './comment-list.component.html',
styleUrls: ['./comment-list.component.scss'], styleUrls: ['./comment-list.component.scss'],
}) })
export class CommentListComponent implements OnInit, OnDestroy { export class CommentListComponent implements OnInit, OnDestroy {
@ViewChild('searchBox') searchField: ElementRef; @ViewChild('searchBox') searchField: ElementRef;
@Input() user: User; @Input() user: User;
...@@ -36,6 +45,7 @@ export class CommentListComponent implements OnInit, OnDestroy { ...@@ -36,6 +45,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
shortId: string; shortId: string;
AppComponent = AppComponent; AppComponent = AppComponent;
comments: Comment[] = []; comments: Comment[] = [];
commentsFilteredByTime: Comment[] = [];
room: Room; room: Room;
hideCommentsList = false; hideCommentsList = false;
filteredComments: Comment[]; filteredComments: Comment[];
...@@ -70,6 +80,8 @@ export class CommentListComponent implements OnInit, OnDestroy { ...@@ -70,6 +80,8 @@ export class CommentListComponent implements OnInit, OnDestroy {
newestComment: string; newestComment: string;
freeze = false; freeze = false;
commentStream: Subscription; commentStream: Subscription;
periodsList = Object.values(Period);
period: Period = Period.ALL;
constructor( constructor(
private commentService: CommentService, private commentService: CommentService,
...@@ -162,7 +174,7 @@ export class CommentListComponent implements OnInit, OnDestroy { ...@@ -162,7 +174,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
if (this.searchInput) { if (this.searchInput) {
if (this.searchInput.length > 1) { if (this.searchInput.length > 1) {
this.hideCommentsList = true; this.hideCommentsList = true;
this.filteredComments = this.comments.filter(c => c.body.toLowerCase().includes(this.searchInput.toLowerCase())); this.filteredComments = this.commentsFilteredByTime.filter(c => c.body.toLowerCase().includes(this.searchInput.toLowerCase()));
} }
} else if (this.searchInput.length === 0 && this.currentFilter === '') { } else if (this.searchInput.length === 0 && this.currentFilter === '') {
this.hideCommentsList = false; this.hideCommentsList = false;
...@@ -193,7 +205,7 @@ export class CommentListComponent implements OnInit, OnDestroy { ...@@ -193,7 +205,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
this.setComments(this.comments.filter(x => x.score >= commentThreshold)); this.setComments(this.comments.filter(x => x.score >= commentThreshold));
} }
} }
this.sortComments(this.currentSort); this.setTimePeriod(this.period);
} }
getVote(comment: Comment): Vote { getVote(comment: Comment): Vote {
...@@ -220,8 +232,8 @@ export class CommentListComponent implements OnInit, OnDestroy { ...@@ -220,8 +232,8 @@ export class CommentListComponent implements OnInit, OnDestroy {
}); });
this.announceNewComment(c.body); this.announceNewComment(c.body);
this.comments = this.comments.concat(c);
this.setComments(this.comments.concat(c)); this.setComments(this.comments);
break; break;
case 'CommentPatched': case 'CommentPatched':
// ToDo: Use a map for comments w/ key = commentId // ToDo: Use a map for comments w/ key = commentId
...@@ -250,9 +262,10 @@ export class CommentListComponent implements OnInit, OnDestroy { ...@@ -250,9 +262,10 @@ export class CommentListComponent implements OnInit, OnDestroy {
case this.ack: case this.ack:
const isNowAck = <boolean>value; const isNowAck = <boolean>value;
if (!isNowAck) { if (!isNowAck) {
this.setComments(this.comments.filter(function (el) { this.comments = this.comments.filter(function (el) {
return el.id !== payload.id; return el.id !== payload.id;
})); });
this.setTimePeriod(this.period);
} }
break; break;
case this.tag: case this.tag:
...@@ -282,9 +295,10 @@ export class CommentListComponent implements OnInit, OnDestroy { ...@@ -282,9 +295,10 @@ export class CommentListComponent implements OnInit, OnDestroy {
} }
break; break;
} }
this.filterComments(this.currentFilter); this.setTimePeriod(this.period);
this.sortComments(this.currentSort); if (this.hideCommentsList) {
this.searchComments(); this.searchComments();
}
} }
openCreateDialog(): void { openCreateDialog(): void {
...@@ -339,12 +353,12 @@ export class CommentListComponent implements OnInit, OnDestroy { ...@@ -339,12 +353,12 @@ export class CommentListComponent implements OnInit, OnDestroy {
filterComments(type: string, compare?: any): void { filterComments(type: string, compare?: any): void {
this.currentFilter = type; this.currentFilter = type;
if (type === '') { if (type === '') {
this.filteredComments = this.comments; this.filteredComments = this.commentsFilteredByTime;
this.hideCommentsList = false; this.hideCommentsList = false;
this.currentFilter = ''; this.currentFilter = '';
return; return;
} }
this.filteredComments = this.comments.filter(c => { this.filteredComments = this.commentsFilteredByTime.filter(c => {
switch (type) { switch (type) {
case this.correct: case this.correct:
return c.correct === CorrectWrong.CORRECT ? 1 : 0; return c.correct === CorrectWrong.CORRECT ? 1 : 0;
...@@ -387,7 +401,7 @@ export class CommentListComponent implements OnInit, OnDestroy { ...@@ -387,7 +401,7 @@ export class CommentListComponent implements OnInit, OnDestroy {
if (this.hideCommentsList === true) { if (this.hideCommentsList === true) {
this.filteredComments = this.sort(this.filteredComments, type); this.filteredComments = this.sort(this.filteredComments, type);
} else { } else {
this.setComments(this.sort(this.comments, type)); this.setComments(this.sort(this.commentsFilteredByTime, type));
} }
this.currentSort = type; this.currentSort = type;
} }
...@@ -432,8 +446,8 @@ export class CommentListComponent implements OnInit, OnDestroy { ...@@ -432,8 +446,8 @@ export class CommentListComponent implements OnInit, OnDestroy {
} }
setComments(comments: Comment[]) { setComments(comments: Comment[]) {
this.titleService.attachTitle('(' + comments.length + ')'); this.commentsFilteredByTime = comments;
this.comments = comments; this.titleService.attachTitle('(' + this.commentsFilteredByTime.length + ')');
} }
/** /**
...@@ -454,4 +468,32 @@ export class CommentListComponent implements OnInit, OnDestroy { ...@@ -454,4 +468,32 @@ export class CommentListComponent implements OnInit, OnDestroy {
this.liveAnnouncer.announce(newCommentText).catch(err => { /* TODO error handling */ }); this.liveAnnouncer.announce(newCommentText).catch(err => { /* TODO error handling */ });
}, 450); }, 450);
} }
setTimePeriod(period: Period) {
this.period = period;
const currentTime = new Date();
const hourInSeconds = 3600000;
let periodInSeconds;
if (period !== Period.ALL) {
switch (period) {
case Period.ONEHOUR:
periodInSeconds = hourInSeconds;
break;
case Period.THREEHOURS:
periodInSeconds = hourInSeconds * 2;
break;
case Period.ONEDAY:
periodInSeconds = hourInSeconds * 24;
break;
case Period.ONEWEEK:
periodInSeconds = hourInSeconds * 168;
}
this.commentsFilteredByTime = this.comments
.filter(c => new Date(c.timestamp).getTime() >= (currentTime.getTime() - periodInSeconds));
} else {
this.commentsFilteredByTime = this.comments;
}
this.filterComments(this.currentFilter);
this.titleService.attachTitle('(' + this.commentsFilteredByTime.length + ')');
}
} }
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