Skip to content
Snippets Groups Projects
comment-list.component.ts 7.95 KiB
Newer Older
import { Component, Input, OnInit } from '@angular/core';
import { Comment } from '../../../models/comment';
import { CommentService } from '../../../services/http/comment.service';
import { TranslateService } from '@ngx-translate/core';
import { LanguageService } from '../../../services/util/language.service';
import { Message } from '@stomp/stompjs';
import { SubmitCommentComponent } from '../_dialogs/submit-comment/submit-comment.component';
import { MatDialog } from '@angular/material';
import { WsCommentServiceService } from '../../../services/websockets/ws-comment-service.service';
import { User } from '../../../models/user';
Thisari Muthuwahandi's avatar
Thisari Muthuwahandi committed
import { UserRole } from '../../../models/user-roles.enum';
import { AuthenticationService } from '../../../services/http/authentication.service';
import { Room } from '../../../models/room';
import { RoomService } from '../../../services/http/room.service';
Lukas Mauß's avatar
Lukas Mauß committed
import { CommentExportComponent } from '../../creator/_dialogs/comment-export/comment-export.component';
  selector: 'app-comment-list',
  templateUrl: './comment-list.component.html',
  styleUrls: ['./comment-list.component.scss']
export class CommentListComponent implements OnInit {
  @Input() user: User;
  @Input() roomId: string;
  comments: Comment[];
  isLoading = true;
  hideCommentsList = false;
  filteredComments: Comment[];
Thisari Muthuwahandi's avatar
Thisari Muthuwahandi committed
  userRole: UserRole;
  constructor(private commentService: CommentService,
Thisari Muthuwahandi's avatar
Thisari Muthuwahandi committed
    private translateService: TranslateService,
    public dialog: MatDialog,
    protected langService: LanguageService,
    private authenticationService: AuthenticationService,
    private wsCommentService: WsCommentServiceService,
    protected roomService: RoomService
  ) {
    langService.langEmitter.subscribe(lang => translateService.use(lang));
    this.roomId = localStorage.getItem(`roomId`);
    this.roomService.getRoom(this.roomId).subscribe( room => this.room = room);
    this.comments = [];
    this.hideCommentsList = false;
Tom Käsler's avatar
Tom Käsler committed
    this.wsCommentService.getCommentStream(this.roomId).subscribe((message: Message) => {
      this.parseIncomingMessage(message);
    });
Lukas Mauß's avatar
Lukas Mauß committed
    this.getComments();
    this.translateService.use(localStorage.getItem('currentLang'));
Thisari Muthuwahandi's avatar
Thisari Muthuwahandi committed
    this.userRole = this.authenticationService.getRole();
Lukas Mauß's avatar
Lukas Mauß committed
  getComments(): void {
    this.commentService.getComments(this.roomId)
      .subscribe(comments => {
        this.comments = comments;
        this.isLoading = false;
      });
  }

  searchComments(term: string): void {
Lukas Mauß's avatar
Lukas Mauß committed
    if (term && term.length > 2) {
Lukas Mauß's avatar
Lukas Mauß committed
      this.hideCommentsList = true;
Lukas Mauß's avatar
Lukas Mauß committed
      this.filteredComments = this.comments.filter(c => c.body.toLowerCase().includes(term.toLowerCase()));
Lukas Mauß's avatar
Lukas Mauß committed
    } else {
      this.hideCommentsList = false;
    }
Tom Käsler's avatar
Tom Käsler committed
    let commentThreshold = -10;
    if (this.room.extensions && this.room.extensions['comments']) {
      commentThreshold = this.room.extensions['comments'].commentThreshold;
      if (this.hideCommentsList) {
        return this.filteredComments.filter( x => x.score >= commentThreshold );
      } else {
        return this.comments.filter( x => x.score >= commentThreshold );
      }
      if (this.hideCommentsList) {
        return this.filteredComments;
      } else {
        return this.comments;
      }
    if (this.hideCommentsList) {
  parseIncomingMessage(message: Message) {
    const msg = JSON.parse(message.body);
    const payload = msg.payload;
    switch (msg.type) {
      case 'CommentCreated':
        const c = new Comment();
        c.roomId = this.roomId;
        c.body = payload.body;
        c.id = payload.id;
        c.timestamp = payload.timestamp;
        this.comments = this.comments.concat(c);
        break;
      case 'CommentPatched':
Tom Käsler's avatar
Tom Käsler committed
        // ToDo: Use a map for comments w/ key = commentId
        for (let i = 0; i < this.comments.length; i++) {
          if (payload.id === this.comments[i].id) {
            for (const [key, value] of Object.entries(payload.changes)) {
              switch (key) {
                case 'read':
                  this.comments[i].read = <boolean>value;
                  break;
Thisari Muthuwahandi's avatar
Thisari Muthuwahandi committed
                case 'correct':
                  this.comments[i].correct = <boolean>value;
                  break;
Thisari Muthuwahandi's avatar
Thisari Muthuwahandi committed
                case 'favorite':
                  this.comments[i].favorite = <boolean>value;
                  break;
Thisari Muthuwahandi's avatar
Thisari Muthuwahandi committed
                case 'score':
                  this.comments[i].score = <number>value;
                  break;
Tom Käsler's avatar
Tom Käsler committed
        break;
      case 'CommentHighlighted':
      // ToDo: Use a map for comments w/ key = commentId
        for (let i = 0; i < this.comments.length; i++) {
          if (payload.id === this.comments[i].id) {
            this.comments[i].highlighted = <boolean>payload.lights;
Tom Käsler's avatar
Tom Käsler committed
          }
        }
        break;
Lukas Mauß's avatar
Lukas Mauß committed
      case 'CommentDeleted':
        for (let i = 0; i < this.comments.length; i++) {
          this.comments = this.comments.filter(function (el) {
            return el.id !== payload.id;
          });
        }
        break;

  openSubmitDialog(): void {
    const dialogRef = this.dialog.open(SubmitCommentComponent, {
      width: '400px'
    });
    dialogRef.componentInstance.user = this.user;
    dialogRef.componentInstance.roomId = this.roomId;
    dialogRef.afterClosed()
      .subscribe(result => {
        if (result) {
          this.send(result);
        } else {
          return;
        }
      });
  }

  send(comment: Comment): void {
    this.wsCommentService.add(comment);
  }
Lukas Mauß's avatar
Lukas Mauß committed
  exportCsv(delimiter: string, date: string): void {
    const exportComments = JSON.parse(JSON.stringify(this.comments));
Lukas Mauß's avatar
Lukas Mauß committed
    let csv: string;
    let keyFields = '';
    let valueFields = '';
    keyFields = Object.keys(exportComments[0]).slice(3).join(delimiter) + '\r\n';
    exportComments.forEach(element => {
      element.body = '"' + element.body.replace(/[\r\n]/g, ' ').replace(/ +/g, ' ').replace(/"/g, '""') + '"';
      valueFields += Object.values(element).slice(3).join(delimiter) + '\r\n';
    });
    csv = keyFields + valueFields;
    const myBlob = new Blob([csv], { type: 'text/csv' });
    const link = document.createElement('a');
    const fileName = 'comments_' + date + '.csv';
    link.setAttribute('download', fileName);
    link.href = window.URL.createObjectURL(myBlob);
    link.click();
  }

  onExport(exportType: string): void {
    const date = new Date();
    const dateString = date.getFullYear() + '_' + ('0' + (date.getMonth() + 1)).slice(-2) + '_' + ('0' + date.getDate()).slice(-2);
    const timeString = ('0' + date.getHours()).slice(-2) + ('0' + date.getMinutes()).slice(-2) + ('0' + date.getSeconds()).slice(-2);
    const timestamp = dateString + '_' + timeString;
      if (exportType === 'comma') {
        this.exportCsv(',', timestamp);
      }
      if (exportType === 'semicolon') {
        this.exportCsv(';', timestamp);
      }
  }


Lukas Mauß's avatar
Lukas Mauß committed
  openExportDialog(): void {
    const dialogRef = this.dialog.open(CommentExportComponent, {
      width: '400px'
    });
Lukas Mauß's avatar
Lukas Mauß committed
    dialogRef.afterClosed().subscribe(result => {
      this.onExport(result);
    });

  filterFavorite(): void {
    this.filteredComments = this.comments.filter(c => c.favorite);
  }

  filterMarkAsRead(): void {
    this.filteredComments = this.comments.filter(c => c.read);
  }

  filterMarkAsCorrect(): void {
    this.filteredComments = this.comments.filter(c => c.correct);
  }

Lukas Mauß's avatar
Lukas Mauß committed
  sortVote(): void {
    this.comments.sort((a, b) => {
        return a.score - b.score;
    });
  }

Lukas Mauß's avatar
Lukas Mauß committed
  sortVoteDesc(): void {
    this.comments.sort((a, b) => {
        return b.score - a.score;
    });
  }

  sortTimeStamp(): void {
    this.comments.sort((a, b) => {
Lukas Mauß's avatar
Lukas Mauß committed
      const dateA = new Date(a.timestamp), dateB = new Date(b.timestamp);
      return +dateB - +dateA;
Lukas Mauß's avatar
Lukas Mauß committed

  deleteComments(): void {
    this.commentService.deleteCommentsByRoomId(this.roomId).subscribe();
  }