Takumon/mean-blog

View on GitHub
src/app/articles/comment-list/comment-list.component.ts

Summary

Maintainability
C
1 day
Test Coverage
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import {
  MatSnackBar,
  MatDialog,
} from '@angular/material';

import { Constant } from '../../shared/constant';
import { AuthenticationService } from '../../shared/services';
import { ConfirmDialogComponent } from '../../shared/components';

import {
  CommentModel,
  CommentWithUserModel,
  ReplyModel,
  ReplyWithUserModel
} from '../../shared/models';
import { CommentService } from '../shared/comment.service';
import { ReplyService } from '../shared/reply.service';

@Component({
  selector: 'app-comment-list',
  templateUrl: './comment-list.component.html',
  styleUrls: ['./comment-list.component.scss'],
})
export class CommentListComponent implements OnInit {
  /** 定数クラス、HTMLで使用するのでコンポーネントのメンバとしている */
  public Constant = Constant;

  @Input() replyCommentIndentMargin: Number = 42;
  @Input() replyCommentIndentLimit: Number = 4;
  @Input() _idOfArticle: string;
  @Input() comments: CommentWithUserModel[];
  @Output() refresh = new EventEmitter();


  constructor(
    public snackBar: MatSnackBar,
    public auth: AuthenticationService,
    public commentService: CommentService,
    private replyService: ReplyService,
    public dialog: MatDialog,
  ) {
  }

  ngOnInit(): void {
    if (!this._idOfArticle) {
      throw new Error(`Attribute '_idOfArticle' is required`);
    }

    if (!this.comments) {
      this.refreshComments();
    }
  }


  refreshComments(): void {
    const withUser = true;
    this.commentService
      .getOfArticle(this._idOfArticle, withUser)
      .subscribe(comments => {
        this.comments = comments as CommentWithUserModel[];
        this.refresh.emit({comments: comments});
      });
  }

  commentOfForm(commentWithUserModel: CommentWithUserModel = null): CommentModel {
    // 追加の場合
    if (commentWithUserModel === null) {
      const newComment = new CommentModel();
      newComment.user = this.auth.loginUser._id;
      newComment.articleId = this._idOfArticle;
      return newComment;
    }

    // 更新の場合(差分更新なので必要なのは_idとテキスト情報のみ)
    const commentModel = new CommentModel();
    commentModel._id = commentWithUserModel._id;
    commentModel.text = commentWithUserModel.text;
    commentModel.created = commentWithUserModel.created;
    return commentModel;
  }

  replyOfForm(comment: CommentWithUserModel, isReplyToReoly: boolean, replyWithUserModel: ReplyWithUserModel = null): ReplyModel {
    // 追加の場合
    if (replyWithUserModel === null) {
      const newReply = new ReplyModel();
      newReply.user = this.auth.loginUser._id;
      newReply.articleId = this._idOfArticle;
      newReply.commentId = comment._id;
      newReply.text = isReplyToReoly ? `> ${comment.user.userId} さん\n` : '';
      return newReply;
    }

    // 更新の場合(差分更新なので必要なのは_idとテキスト情報のみ)
    const replyModel = new ReplyModel();
    replyModel._id = replyWithUserModel._id;
    replyModel.text = replyWithUserModel.text;
    replyModel.created = replyWithUserModel.created;
    return replyModel;
  }


  deleteComment(commentId: string): void {
    const dialogRef = this.dialog.open(ConfirmDialogComponent, {
      data: {
        title: 'コメント削除',
        message: `コメントを削除しますか?`
      }
    });

    dialogRef.afterClosed().subscribe(result => {
      if (!result) {
        return;
      }

      this.commentService
      .delete(commentId)
      .subscribe(res => {
        this.snackBar.open('コメントを削除しました。', null, this.Constant.SNACK_BAR_DEFAULT_OPTION);
        this.refreshComments();
      });
    });
  }

  deleteReply(replyId: String): void {
    const dialogRef = this.dialog.open(ConfirmDialogComponent, {
      data: {
        title: 'リプライ削除',
        message: `リプライを削除しますか?`
      }
    });

    dialogRef.afterClosed().subscribe(result => {
      if (!result) {
        return;
      }

      this.replyService
      .delete(replyId)
      .subscribe(res => {
        this.snackBar.open('リプライを削除しました。', null, this.Constant.SNACK_BAR_DEFAULT_OPTION);
        this.refreshComments();
      });
    });
  }
}