All files / app/page/ref/comments comments.component.ts

75% Statements 42/56
39.28% Branches 11/28
47.05% Functions 8/17
73.33% Lines 33/45

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107          1x 1x 1x     1x         1x 1x 1x                         3x 1x 1x           1x 1x 1x 1x   1x 1x                 1x 1x 1x 1x 1x 1x 1x 1x 1x         1x                 2x 1x 1x       1x         1x         1x         1x                    
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { uniq } from 'lodash-es';
import { autorun, IReactionDisposer, runInAction } from 'mobx';
import { MobxAngularModule } from 'mobx-angular';
import { Subject } from 'rxjs';
import { CommentReplyComponent } from '../../../component/comment/comment-reply/comment-reply.component';
import { CommentThreadComponent } from '../../../component/comment/comment-thread/comment-thread.component';
import { LoadingComponent } from '../../../component/loading/loading.component';
import { HasChanges } from '../../../guard/pending-changes.guard';
import { Ref } from '../../../model/ref';
import { getMailbox, mailboxes } from '../../../mods/mailbox';
import { AdminService } from '../../../service/admin.service';
import { ModService } from '../../../service/mod.service';
import { Store } from '../../../store/store';
import { ThreadStore } from '../../../store/thread';
import { getTitle } from '../../../util/format';
import { memo, MemoCache } from '../../../util/memo';
import { hasTag, removeTag, updateMetadata } from '../../../util/tag';
 
@Component({
  selector: 'app-ref-comments',
  templateUrl: './comments.component.html',
  styleUrls: ['./comments.component.scss'],
  imports: [
    MobxAngularModule,
    CommentReplyComponent,
    CommentThreadComponent,
    LoadingComponent,
  ],
})
export class RefCommentsComponent implements OnInit, OnDestroy, HasChanges {
  private disposers: IReactionDisposer[] = [];
  newComments$ = new Subject<Ref | undefined>();
 
  @ViewChild('reply')
  reply?: CommentReplyComponent;
 
  constructor(
    private mod: ModService,
    public store: Store,
    public thread: ThreadStore,
    private admin: AdminService,
  ) {
    thread.clear();
    runInAction(() => store.view.defaultSort = ['published']);
  }
 
  saveChanges() {
    return !this.reply || this.reply.saveChanges();
  }
 
  ngOnInit(): void {
    // TODO: set title for bare reposts
    this.disposers.push(autorun(() => this.mod.setTitle($localize`Comments: ` + getTitle(this.store.view.ref))));
    this.disposers.push(autorun(() => {
      MemoCache.clear(this);
      const top = this.store.view.url;
      const sort = this.store.view.sort;
      const filter = this.store.view.filter;
      const search = this.store.view.search;
      runInAction(() => this.thread.setArgs(top, sort, filter, search));
      Iif (this.store.view.ref) {
        const commentCount = this.store.view.ref.metadata?.plugins?.['plugin/comment'] || 0;
        this.store.local.setLastSeenCount(this.store.view.url, 'comments', commentCount);
      }
    }));
    this.newComments$.subscribe(c => {
      if (c && this.store.view.ref) {
        runInAction(() => updateMetadata(this.store.view.ref!, c));
        this.store.eventBus.refresh(this.store.view.ref!);
      }
    });
  }
 
  ngOnDestroy() {
    for (const dispose of this.disposers) dispose();
    this.disposers.length = 0;
    this.newComments$.complete();
  }
 
  @memo
  get depth() {
    return this.store.view.depth || 7;
  }
 
  @memo
  get comment() {
    return this.admin.getPlugin('plugin/comment') && hasTag('plugin/comment', this.store.view.ref);
  }
 
  @memo
  get mailboxes() {
    return mailboxes(this.store.view.ref!, this.store.account.tag, this.store.origins.originMap);
  }
 
  @memo
  get replyTags(): string[] {
    const tags = [
      'plugin/comment',
      'internal',
      ...this.admin.reply.filter(p => hasTag(p.tag, this.store.view.ref)).flatMap(p => p.config!.reply as string[]),
      ...this.mailboxes,
    ];
    return removeTag(getMailbox(this.store.account.tag, this.store.account.origin), uniq(tags));
  }
}