@banta/sdk 3.2.2 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { Observable, Subject, BehaviorSubject } from 'rxjs';
1
+ import { Observable, Subject, BehaviorSubject, Subscription } from 'rxjs';
2
2
  import { publish } from 'rxjs/operators';
3
3
  import { Injectable, Component, Input, NgModule, Output, ViewChild, ElementRef, HostBinding } from '@angular/core';
4
4
  import { CommonModule } from '@angular/common';
@@ -9,12 +9,14 @@ import { MatFormFieldModule } from '@angular/material/form-field';
9
9
  import { MatInputModule } from '@angular/material/input';
10
10
  import { FormsModule } from '@angular/forms';
11
11
  import { __awaiter } from 'tslib';
12
- import { SubSink } from 'subsink';
13
12
  import { MatDialog, MatDialogModule } from '@angular/material/dialog';
13
+ import { ActivatedRoute } from '@angular/router';
14
14
  import { MatMenuModule } from '@angular/material/menu';
15
15
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
16
16
  import { TextFieldModule } from '@angular/cdk/text-field';
17
17
  import { MatTooltipModule } from '@angular/material/tooltip';
18
+ import { CommentsOrder } from '@banta/common';
19
+ import { MatSelectModule } from '@angular/material/select';
18
20
 
19
21
  function lazyConnection(options) {
20
22
  let obs = new Observable(observer => {
@@ -7037,7 +7039,7 @@ LiveChatMessageComponent.propDecorators = {
7037
7039
  class ChatViewComponent {
7038
7040
  constructor(elementRef) {
7039
7041
  this.elementRef = elementRef;
7040
- this._sourceSubs = new SubSink();
7042
+ this._sourceSubs = new Subscription();
7041
7043
  this._selected = new Subject();
7042
7044
  this._reported = new Subject();
7043
7045
  this._upvoted = new Subject();
@@ -7068,15 +7070,14 @@ class ChatViewComponent {
7068
7070
  this._source = value;
7069
7071
  this.messages = [];
7070
7072
  if (value) {
7071
- this._sourceSubs = new SubSink();
7073
+ this._sourceSubs = new Subscription();
7072
7074
  this.messages = value.messages.slice();
7073
7075
  console.log(`Source set:`);
7074
7076
  console.dir(value);
7075
7077
  console.log(`Messages loaded:`);
7076
7078
  console.dir(this.messages);
7077
- this._sourceSubs.add(this._source.messageReceived
7078
- .subscribe(msg => this.messageReceived(msg)), this._source.messageSent
7079
- .subscribe(msg => this.messageSent(msg)));
7079
+ this._sourceSubs.add(this._source.messageReceived.subscribe(msg => this.messageReceived(msg)));
7080
+ this._sourceSubs.add(this._source.messageSent.subscribe(msg => this.messageSent(msg)));
7080
7081
  if (this._source.currentUserChanged) {
7081
7082
  this._sourceSubs.add(this._source.currentUserChanged
7082
7083
  .subscribe(user => this.currentUser = user));
@@ -7186,7 +7187,7 @@ class BantaChatComponent {
7186
7187
  this.banta = banta;
7187
7188
  this.backend = backend;
7188
7189
  this.elementRef = elementRef;
7189
- this._subs = new SubSink();
7190
+ this._subs = new Subscription();
7190
7191
  this.user = null;
7191
7192
  this.signInLabel = 'Sign In';
7192
7193
  this.sendLabel = 'Send';
@@ -7365,7 +7366,7 @@ class BantaComponent {
7365
7366
  this.banta = banta;
7366
7367
  this.backend = backend;
7367
7368
  this.matDialog = matDialog;
7368
- this._subs = new SubSink();
7369
+ this._subs = new Subscription();
7369
7370
  this.auxOpen = false;
7370
7371
  this.auxTitle = 'Notifications';
7371
7372
  this.auxMode = 'notifications';
@@ -7380,7 +7381,9 @@ class BantaComponent {
7380
7381
  this.genericAvatarUrl = 'https://gravatar.com/avatar/915c804e0be607a4ad766ddadea5c48a?s=512&d=https://codepen.io/assets/avatars/user-avatar-512x512-6e240cf350d2f1cc07c2bed234c3a3bb5f1b237023c204c782622e80d6b212ba.png';
7381
7382
  }
7382
7383
  ngOnInit() {
7383
- this._subs.add(this.banta.userChanged.subscribe(user => this.currentUser = user), this.backend.notificationsChanged.subscribe(notifs => this.notifications = notifs), this.backend.newNotification.subscribe(notif => {
7384
+ this._subs.add(this.banta.userChanged.subscribe(user => this.currentUser = user));
7385
+ this._subs.add(this.backend.notificationsChanged.subscribe(notifs => this.notifications = notifs));
7386
+ this._subs.add(this.backend.newNotification.subscribe(notif => {
7384
7387
  this.newNotifications = true;
7385
7388
  }));
7386
7389
  }
@@ -7643,7 +7646,10 @@ class CommentComponent {
7643
7646
  this._reported = new Subject();
7644
7647
  this._selected = new Subject();
7645
7648
  this._upvoted = new Subject();
7649
+ this._shared = new Subject();
7646
7650
  this._userSelected = new Subject();
7651
+ this._avatarSelected = new Subject();
7652
+ this._usernameSelected = new Subject();
7647
7653
  this.isNew = false;
7648
7654
  this.visible = false;
7649
7655
  this.showReplyAction = true;
@@ -7659,32 +7665,52 @@ class CommentComponent {
7659
7665
  }, randomTime);
7660
7666
  }
7661
7667
  get userSelected() {
7662
- return this._userSelected;
7668
+ return this._userSelected.asObservable();
7669
+ }
7670
+ get usernameSelected() {
7671
+ return this._usernameSelected.asObservable();
7672
+ }
7673
+ get avatarSelected() {
7674
+ return this._avatarSelected.asObservable();
7663
7675
  }
7664
7676
  get reported() {
7665
- return this._reported;
7677
+ return this._reported.asObservable();
7666
7678
  }
7667
7679
  get upvoted() {
7668
- return this._upvoted;
7680
+ return this._upvoted.asObservable();
7669
7681
  }
7670
7682
  get selected() {
7671
- return this._selected;
7683
+ return this._selected.asObservable();
7672
7684
  }
7673
7685
  get commentId() {
7674
7686
  var _a;
7675
7687
  return (_a = this.message) === null || _a === void 0 ? void 0 : _a.id;
7676
7688
  }
7689
+ get shared() {
7690
+ return this._shared.asObservable();
7691
+ }
7677
7692
  report() {
7678
7693
  this._reported.next();
7679
7694
  }
7680
7695
  upvote() {
7681
7696
  this._upvoted.next();
7682
7697
  }
7698
+ share() {
7699
+ this._shared.next(this.message);
7700
+ }
7683
7701
  select() {
7684
7702
  this._selected.next();
7685
7703
  }
7686
7704
  selectUser() {
7687
- return this._userSelected.next();
7705
+ this._userSelected.next();
7706
+ }
7707
+ selectUsername(user) {
7708
+ this._usernameSelected.next(user);
7709
+ this.selectUser();
7710
+ }
7711
+ selectAvatar(user) {
7712
+ this._avatarSelected.next(user);
7713
+ this.selectUser();
7688
7714
  }
7689
7715
  avatarForUser(user) {
7690
7716
  if (user && user.avatarUrl) {
@@ -7697,7 +7723,7 @@ class CommentComponent {
7697
7723
  CommentComponent.decorators = [
7698
7724
  { type: Component, args: [{
7699
7725
  selector: 'banta-comment',
7700
- template: "\r\n<mat-menu #pointItemMenu=\"matMenu\">\r\n <button mat-menu-item (click)=\"report()\">Report</button>\r\n <button mat-menu-item>Help</button>\r\n</mat-menu>\r\n\r\n<div class=\"message-content\">\r\n <div class=\"user\">\r\n <a \r\n href=\"javascript:;\"\r\n class=\"avatar\"\r\n (click)=\"selectUser()\"\r\n [style.background-image]=\"avatarForUser(message.user)\"></a>\r\n <a href=\"javascript:;\" class=\"display-name\" (click)=\"selectUser()\">{{message.user.displayName}}</a>\r\n <a href=\"javascript:;\" class=\"username\" (click)=\"selectUser()\">@{{message.user.username}}</a>\r\n </div>\r\n <div class=\"content\">\r\n {{message.message}}\r\n </div>\r\n \r\n <div class=\"actions\">\r\n <banta-timestamp [value]=\"message.sentAt\"></banta-timestamp>\r\n <div class=\"spacer\"></div>\r\n <div class=\"counted-action\" *ngIf=\"showReplyAction\">\r\n <div class=\"count-indicator\">\r\n {{message.submessages?.length || 0}}\r\n </div>\r\n <button mat-icon-button matTooltip=\"Comment\" matTooltipPosition=\"below\" (click)=\"select()\">\r\n <mat-icon [inline]=\"true\">comment</mat-icon>\r\n </button>\r\n </div>\r\n <div class=\"counted-action\">\r\n <div class=\"count-indicator\"> \r\n {{message.upvotes}}\r\n </div>\r\n <button mat-icon-button matTooltip=\"Upvote\" matTooltipPosition=\"below\" (click)=\"upvote()\">\r\n <mat-icon [inline]=\"true\">thumb_up</mat-icon>\r\n </button>\r\n </div>\r\n \r\n <button mat-icon-button [matMenuTriggerFor]=\"pointItemMenu\">\r\n <mat-icon [inline]=\"true\">more_vert</mat-icon>\r\n </button>\r\n </div>\r\n</div>\r\n",
7726
+ template: "\r\n<mat-menu #pointItemMenu=\"matMenu\">\r\n <button mat-menu-item (click)=\"report()\">Report</button>\r\n <button mat-menu-item>Help</button>\r\n</mat-menu>\r\n\r\n<div class=\"message-content\">\r\n <div class=\"user\">\r\n <a\r\n href=\"javascript:;\"\r\n class=\"avatar\"\r\n (click)=\"selectAvatar(message.user)\"\r\n [style.background-image]=\"avatarForUser(message.user)\"></a>\r\n <a href=\"javascript:;\" class=\"display-name\" (click)=\"selectUser()\">{{message.user.displayName}}</a>\r\n <a href=\"javascript:;\" class=\"username\" (click)=\"selectUsername(message.user)\">@{{message.user.username}}</a>\r\n </div>\r\n <div class=\"content\">\r\n {{message.message}}\r\n </div>\r\n\r\n <div class=\"actions\">\r\n <banta-timestamp [value]=\"message.sentAt\"></banta-timestamp>\r\n <div class=\"spacer\"></div>\r\n <div class=\"counted-action\" *ngIf=\"showReplyAction\">\r\n <div class=\"count-indicator\">\r\n {{message.submessages?.length || 0}}\r\n </div>\r\n <button mat-icon-button matTooltip=\"Comment\" matTooltipPosition=\"below\" (click)=\"select()\">\r\n <mat-icon [inline]=\"true\">comment</mat-icon>\r\n </button>\r\n </div>\r\n <div class=\"counted-action\">\r\n <div class=\"count-indicator\">\r\n {{message.upvotes}}\r\n </div>\r\n <button mat-icon-button matTooltip=\"Upvote\" matTooltipPosition=\"below\" (click)=\"upvote()\">\r\n <mat-icon [inline]=\"true\">thumb_up</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <div class=\"counted-action\">\r\n <button mat-icon-button matTooltip=\"Share this comment\" matTooltipPosition=\"below\" (click)=\"share()\">\r\n <mat-icon [inline]=\"true\" >share</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <button mat-icon-button [matMenuTriggerFor]=\"pointItemMenu\">\r\n <mat-icon [inline]=\"true\">more_vert</mat-icon>\r\n </button>\r\n </div>\r\n</div>\r\n",
7701
7727
  styles: ["@-webkit-keyframes comment-appear{0%{transform:translate(100vw)}to{transform:translate(0)}}@keyframes comment-appear{0%{transform:translate(100vw)}to{transform:translate(0)}}:host{display:flex;flex-direction:column;padding:.5em;position:relative;visibility:hidden}:host.new{-webkit-animation-duration:.4s;-webkit-animation-fill-mode:both;-webkit-animation-name:comment-appear;animation-duration:.4s;animation-fill-mode:both;animation-name:comment-appear}:host.new,:host.visible{visibility:visible}:host:hover{background:#eee}:host .message-content .content{margin-left:60px;margin-right:.5em}:host.abbreviated .message-content .content{max-height:8.5em;overflow-y:hidden;text-overflow:ellipsis}:host .actions{align-items:center;display:flex;margin-left:60px;padding-right:10px}:host .actions button{color:#666}:host .actions banta-timestamp{color:#666;font-size:10pt}.user{align-items:center;display:flex;margin:1em 0 0;position:relative}.user .display-name,.user .username{color:#000;display:block;flex-grow:0;flex-shrink:1;font-size:10pt;margin:0 auto 0 0;max-width:100%;overflow:hidden;padding:0 0 0 1em;position:relative;text-overflow:ellipsis;white-space:nowrap;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;z-index:1}.user .display-name.username,.user .username.username{color:#666;flex-grow:1;flex-shrink:0}.avatar{background-color:#333;background-position:50%;background-size:cover;border-radius:100%;flex-grow:0;flex-shrink:0;height:48px;width:48px}.counted-action{align-items:center;display:flex}.count-indicator{color:#666;font-size:9pt;padding:0 0 0 3px}:host-context(.mat-dark-theme) .count-indicator{border-color:#333}:host-context(.mat-dark-theme):hover{background:#060606}:host-context(.mat-dark-theme) .user .display-name,:host-context(.mat-dark-theme) .user .username{color:#fff}@media (max-width:400px){.avatar{height:32px;width:32px}:host .actions{margin-left:44px}:host .message-content .content{margin-left:44px;margin-right:.5em}}"]
7702
7728
  },] }
7703
7729
  ];
@@ -7707,20 +7733,26 @@ CommentComponent.propDecorators = {
7707
7733
  message: [{ type: Input }],
7708
7734
  showReplyAction: [{ type: Input }],
7709
7735
  userSelected: [{ type: Output }],
7736
+ usernameSelected: [{ type: Output }],
7737
+ avatarSelected: [{ type: Output }],
7710
7738
  reported: [{ type: Output }],
7711
7739
  upvoted: [{ type: Output }],
7712
7740
  selected: [{ type: Output }],
7713
- commentId: [{ type: HostBinding, args: ['attr.data-comment-id',] }]
7741
+ commentId: [{ type: HostBinding, args: ['attr.data-comment-id',] }],
7742
+ shared: [{ type: Output }]
7714
7743
  };
7715
7744
 
7716
7745
  class CommentViewComponent {
7717
7746
  constructor(backend) {
7718
7747
  this.backend = backend;
7719
- this._sourceSubs = new SubSink();
7748
+ this._sourceSubs = new Subscription();
7720
7749
  this._selected = new Subject();
7721
7750
  this._upvoted = new Subject();
7722
7751
  this._reported = new Subject();
7723
7752
  this._userSelected = new Subject();
7753
+ this._usernameSelected = new Subject();
7754
+ this._avatarSelected = new Subject();
7755
+ this._shared = new Subject();
7724
7756
  this.showEmptyState = true;
7725
7757
  this.allowReplies = true;
7726
7758
  this.menuMessage = null;
@@ -7746,6 +7778,15 @@ class CommentViewComponent {
7746
7778
  get upvoted() {
7747
7779
  return this._upvoted;
7748
7780
  }
7781
+ get usernameSelected() {
7782
+ return this._usernameSelected;
7783
+ }
7784
+ get avatarSelected() {
7785
+ return this._avatarSelected;
7786
+ }
7787
+ get shared() {
7788
+ return this._shared;
7789
+ }
7749
7790
  get source() {
7750
7791
  return this._source;
7751
7792
  }
@@ -7756,13 +7797,20 @@ class CommentViewComponent {
7756
7797
  this._reported.next(message);
7757
7798
  }
7758
7799
  selectMessage(message) {
7759
- return __awaiter(this, void 0, void 0, function* () {
7760
- this._selected.next(message);
7761
- });
7800
+ this._selected.next(message);
7762
7801
  }
7763
7802
  selectMessageUser(message) {
7764
7803
  this._userSelected.next(message);
7765
7804
  }
7805
+ selectUsername(user) {
7806
+ this._usernameSelected.next(user);
7807
+ }
7808
+ selectAvatar(user) {
7809
+ this._avatarSelected.next(user);
7810
+ }
7811
+ sharedMessage(message) {
7812
+ this._shared.next(message);
7813
+ }
7766
7814
  set source(value) {
7767
7815
  if (this._sourceSubs) {
7768
7816
  this._sourceSubs.unsubscribe();
@@ -7770,14 +7818,14 @@ class CommentViewComponent {
7770
7818
  }
7771
7819
  this._source = value;
7772
7820
  if (value) {
7773
- let messages = (value.messages || []).slice();
7821
+ console.log(`[banta-comment-view] Subscribing to source...`);
7822
+ const messages = (value.messages || []).slice();
7774
7823
  this.messages = messages;
7775
7824
  this.olderMessages = messages.splice(this.maxVisibleMessages, messages.length);
7776
7825
  this.hasMore = this.olderMessages.length > 0;
7777
- this._sourceSubs = new SubSink();
7778
- this._sourceSubs.add(this._source.messageReceived
7779
- .subscribe(msg => this.messageReceived(msg)), this._source.messageSent
7780
- .subscribe(msg => this.messageSent(msg)));
7826
+ this._sourceSubs = new Subscription();
7827
+ this._sourceSubs.add(this._source.messageReceived.subscribe(msg => this.messageReceived(msg)));
7828
+ this._sourceSubs.add(this._source.messageSent.subscribe(msg => this.messageSent(msg)));
7781
7829
  if (this._source.currentUserChanged) {
7782
7830
  this._sourceSubs.add(this._source.currentUserChanged.subscribe(user => this.currentUser = user));
7783
7831
  }
@@ -7846,9 +7894,9 @@ class CommentViewComponent {
7846
7894
  isScrolledToLatest() {
7847
7895
  if (!this.messageContainer)
7848
7896
  return false;
7849
- let el = this.messageContainer.nativeElement;
7850
- let currentScroll = el.scrollTop;
7851
- let currentTotal = el.scrollHeight - el.offsetHeight;
7897
+ const el = this.messageContainer.nativeElement;
7898
+ const currentScroll = el.scrollTop;
7899
+ const currentTotal = el.scrollHeight - el.offsetHeight;
7852
7900
  return currentScroll > currentTotal - 10;
7853
7901
  }
7854
7902
  messageSent(message) {
@@ -7860,7 +7908,7 @@ class CommentViewComponent {
7860
7908
  scrollToLatest() {
7861
7909
  if (!this.messageContainer)
7862
7910
  return;
7863
- let el = this.messageContainer.nativeElement;
7911
+ const el = this.messageContainer.nativeElement;
7864
7912
  el.scrollTop = el.scrollHeight;
7865
7913
  }
7866
7914
  mentionsMe(message) {
@@ -7880,7 +7928,7 @@ class CommentViewComponent {
7880
7928
  CommentViewComponent.decorators = [
7881
7929
  { type: Component, args: [{
7882
7930
  selector: 'banta-comment-view',
7883
- template: "<div class=\"message-container\">\r\n <ng-content select=\"[data-before]\"></ng-content>\r\n \r\n <a mat-button class=\"nav\" [class.visible]=\"isViewingMore\" href=\"javascript:;\" (click)=\"showNew()\">\r\n <mat-icon>file_upload</mat-icon>\r\n New\r\n <ng-container *ngIf=\"newMessages.length >= 1\">\r\n ({{newMessages.length}})\r\n </ng-container>\r\n </a>\r\n\r\n <ng-container *ngIf=\"messages.length === 0\">\r\n <div class=\"empty-state\" *ngIf=\"showEmptyState\">\r\n Be the first to comment!\r\n </div>\r\n </ng-container>\r\n <banta-comment \r\n *ngFor=\"let message of messages; trackBy: messageIdentity\"\r\n class=\"abbreviated\"\r\n [message]=\"message\"\r\n (click)=\"isViewingMore = true\"\r\n [showReplyAction]=\"allowReplies\"\r\n (userSelected)=\"selectMessageUser(message)\"\r\n (upvoted)=\"upvoteMessage(message)\"\r\n (reported)=\"reportMessage(message)\"\r\n (selected)=\"selectMessage(message)\"\r\n ></banta-comment>\r\n\r\n <a mat-button class=\"nav\" [class.visible]=\"hasMore && !isLoadingMore\" href=\"javascript:;\" (click)=\"showMore()\">Show more</a>\r\n\r\n <div class=\"loading-more\" *ngIf=\"isLoadingMore\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n\r\n <!-- <div style=\"color: #666\">\r\n n={{newMessages.length}}, m={{messages.length}}, o={{olderMessages.length}},\r\n v={{maxVisibleMessages}}, M={{maxMessages}}\r\n </div> -->\r\n\r\n <ng-content select=\":not([data-before])\"></ng-content>\r\n</div>",
7931
+ template: "<div class=\"message-container\">\r\n <ng-content select=\"[data-before]\"></ng-content>\r\n\r\n <a mat-button class=\"nav\" [class.visible]=\"isViewingMore\" href=\"javascript:;\" (click)=\"showNew()\">\r\n <mat-icon>file_upload</mat-icon>\r\n New\r\n <ng-container *ngIf=\"newMessages.length >= 1\">\r\n ({{newMessages.length}})\r\n </ng-container>\r\n </a>\r\n\r\n <ng-container *ngIf=\"messages.length === 0\">\r\n <div class=\"empty-state\" *ngIf=\"showEmptyState\">\r\n Be the first to comment!\r\n </div>\r\n </ng-container>\r\n <banta-comment\r\n *ngFor=\"let message of messages; trackBy: messageIdentity\"\r\n class=\"abbreviated\"\r\n [message]=\"message\"\r\n (click)=\"isViewingMore = true\"\r\n [showReplyAction]=\"allowReplies\"\r\n\t\t(userSelected)=\"selectMessageUser(message)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n\t\t(usernameSelected)=\"selectUsername($event)\"\r\n (upvoted)=\"upvoteMessage(message)\"\r\n (reported)=\"reportMessage(message)\"\r\n (selected)=\"selectMessage(message)\"\r\n (shared)=\"sharedMessage($event)\"\r\n ></banta-comment>\r\n\r\n <a mat-button class=\"nav\" [class.visible]=\"hasMore && !isLoadingMore\" href=\"javascript:;\" (click)=\"showMore()\">Show more</a>\r\n\r\n <div class=\"loading-more\" *ngIf=\"isLoadingMore\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n\r\n <!-- <div style=\"color: #666\">\r\n n={{newMessages.length}}, m={{messages.length}}, o={{olderMessages.length}},\r\n v={{maxVisibleMessages}}, M={{maxMessages}}\r\n </div> -->\r\n\r\n <ng-content select=\":not([data-before])\"></ng-content>\r\n</div>\r\n",
7884
7932
  styles: [":host{display:flex;flex-direction:column;flex-grow:1;opacity:1;transition:opacity .2s ease-in}.message-container{background:#fff;color:#111;flex-grow:1;opacity:1;overflow-x:hidden;padding:.5em 1em 3em .5em;position:relative;transition:opacity .5s ease-in-out}.message-container.no-scroll{height:auto;overflow-y:visible}.message-container.faded{opacity:.25}.message-container .overlay{bottom:0;left:0;position:absolute;right:0;top:0;z-index:10}:host.fixed-height .message-container{overflow-y:auto}:host-context(.mat-dark-theme) .message-container{background:#111;color:#fff}.empty-state{color:#666;margin:3em;text-align:center}:host-context(.mat-dark-theme) .empty-state{color:#666}a.nav{background:#222;border-radius:2em;opacity:0;pointer-events:none;position:absolute;right:.5em;text-align:center;transition:opacity .4s ease-in-out;z-index:10}a.nav.visible{opacity:1;pointer-events:auto}.loading-more{margin:0 auto;padding:2em;text-align:center;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}@media (max-width:400px){.message-container{padding:0 0 3em}}"]
7885
7933
  },] }
7886
7934
  ];
@@ -7895,6 +7943,9 @@ CommentViewComponent.propDecorators = {
7895
7943
  userSelected: [{ type: Output }],
7896
7944
  reported: [{ type: Output }],
7897
7945
  upvoted: [{ type: Output }],
7946
+ usernameSelected: [{ type: Output }],
7947
+ avatarSelected: [{ type: Output }],
7948
+ shared: [{ type: Output }],
7898
7949
  source: [{ type: Input }],
7899
7950
  genericAvatarUrl: [{ type: Input }],
7900
7951
  messageContainer: [{ type: ViewChild, args: ['messageContainer',] }],
@@ -7907,15 +7958,19 @@ CommentViewComponent.propDecorators = {
7907
7958
  * Comments component
7908
7959
  */
7909
7960
  class BantaCommentsComponent {
7910
- constructor(banta, backend, elementRef) {
7961
+ constructor(banta, backend, elementRef, activatedRoute) {
7911
7962
  this.banta = banta;
7912
7963
  this.backend = backend;
7913
7964
  this.elementRef = elementRef;
7965
+ this.activatedRoute = activatedRoute;
7914
7966
  this._upvoted = new Subject();
7915
7967
  this._reported = new Subject();
7916
7968
  this._selected = new Subject();
7917
7969
  this._userSelected = new Subject();
7918
- this._subs = new SubSink();
7970
+ this._shared = new Subject();
7971
+ this._usernameSelected = new Subject();
7972
+ this._avatarSelected = new Subject();
7973
+ this._subs = new Subscription();
7919
7974
  this.hashtags = [
7920
7975
  { hashtag: 'error', description: 'Cause an error' },
7921
7976
  { hashtag: 'timeout', description: 'Cause a slow timeout error' },
@@ -7936,9 +7991,39 @@ class BantaCommentsComponent {
7936
7991
  this.expandError = false;
7937
7992
  this.selectedMessageVisible = false;
7938
7993
  }
7994
+ get sortOrder() {
7995
+ return this._sortOrder;
7996
+ }
7997
+ set sortOrder(value) {
7998
+ if (this._sortOrder !== value) {
7999
+ this._sortOrder = value;
8000
+ setTimeout(() => {
8001
+ this.setSourceFromTopicID(this.topicID);
8002
+ });
8003
+ }
8004
+ }
7939
8005
  ngOnInit() {
7940
8006
  this._subs.add(this.banta.userChanged.subscribe(user => this.user = user));
7941
8007
  }
8008
+ ngAfterViewInit() {
8009
+ if (typeof window !== 'undefined')
8010
+ this.checkForSharedComment();
8011
+ }
8012
+ scrollToComment(commentId) {
8013
+ setTimeout(() => {
8014
+ const comment = document.querySelectorAll(`[data-comment-id="${commentId}"]`);
8015
+ console.log(comment);
8016
+ if (comment.length > 0) {
8017
+ // comment.item(0).scroll({behavior: 'smooth'});
8018
+ comment.item(0).scrollIntoView();
8019
+ }
8020
+ }, 1000);
8021
+ }
8022
+ checkForSharedComment() {
8023
+ const commentID = this.activatedRoute.snapshot.queryParamMap.get('comment');
8024
+ if (commentID)
8025
+ this.scrollToComment(commentID);
8026
+ }
7942
8027
  ngOnDestroy() {
7943
8028
  this._subs.unsubscribe();
7944
8029
  }
@@ -7949,20 +8034,26 @@ class BantaCommentsComponent {
7949
8034
  this._source = value;
7950
8035
  }
7951
8036
  get topicID() {
7952
- return this._source.identifier;
8037
+ return this._topicID;
7953
8038
  }
7954
8039
  set topicID(value) {
7955
- this.setSourceFromTopicID(value);
8040
+ if (this._topicID !== value) {
8041
+ this._topicID = value;
8042
+ setTimeout(() => this.setSourceFromTopicID(value));
8043
+ }
7956
8044
  }
7957
8045
  setSourceFromTopicID(topicID) {
8046
+ var _a, _b;
7958
8047
  return __awaiter(this, void 0, void 0, function* () {
7959
- if (this._source && this._source.close)
7960
- this._source.close();
8048
+ (_b = (_a = this._source) === null || _a === void 0 ? void 0 : _a.close) === null || _b === void 0 ? void 0 : _b.call(_a);
7961
8049
  this._source = null;
7962
- this._source = yield this.backend.getSourceForTopic(topicID);
7963
- this._source.messageReceived.subscribe(m => this.addParticipant(m));
7964
- this._source.messageSent.subscribe(m => this.addParticipant(m));
7965
- this._source.messages.forEach(m => this.addParticipant(m));
8050
+ setTimeout(() => __awaiter(this, void 0, void 0, function* () {
8051
+ this._source = yield this.backend.getSourceForTopic(topicID, { sortOrder: this.sortOrder });
8052
+ console.log(`[banta-comments] Subscribing to source for topic '${topicID}'`);
8053
+ this._source.messageReceived.subscribe(m => this.addParticipant(m));
8054
+ this._source.messageSent.subscribe(m => this.addParticipant(m));
8055
+ this._source.messages.forEach(m => this.addParticipant(m));
8056
+ }));
7966
8057
  });
7967
8058
  }
7968
8059
  addParticipant(message) {
@@ -8010,16 +8101,25 @@ class BantaCommentsComponent {
8010
8101
  return (_a = this.user.permissions) === null || _a === void 0 ? void 0 : _a.canComment(this.source);
8011
8102
  }
8012
8103
  get upvoted() {
8013
- return this._upvoted;
8104
+ return this._upvoted.asObservable();
8014
8105
  }
8015
8106
  get reported() {
8016
- return this._reported;
8107
+ return this._reported.asObservable();
8017
8108
  }
8018
8109
  get selected() {
8019
- return this._selected;
8110
+ return this._selected.asObservable();
8020
8111
  }
8021
8112
  get userSelected() {
8022
- return this._userSelected;
8113
+ return this._userSelected.asObservable();
8114
+ }
8115
+ get usernameSelected() {
8116
+ return this._usernameSelected.asObservable();
8117
+ }
8118
+ get avatarSelected() {
8119
+ return this._avatarSelected.asObservable();
8120
+ }
8121
+ get shared() {
8122
+ return this._shared.asObservable();
8023
8123
  }
8024
8124
  onKeyDown(event) {
8025
8125
  }
@@ -8076,6 +8176,15 @@ class BantaCommentsComponent {
8076
8176
  selectMessageUser(message) {
8077
8177
  this._userSelected.next(message);
8078
8178
  }
8179
+ selectUsername(user) {
8180
+ this._usernameSelected.next(user);
8181
+ }
8182
+ selectAvatar(user) {
8183
+ this._avatarSelected.next(user);
8184
+ }
8185
+ shareMessage(message) {
8186
+ this._shared.next(message);
8187
+ }
8079
8188
  sendReply() {
8080
8189
  return __awaiter(this, void 0, void 0, function* () {
8081
8190
  yield this.selectedMessageThread.send({
@@ -8101,14 +8210,15 @@ class BantaCommentsComponent {
8101
8210
  BantaCommentsComponent.decorators = [
8102
8211
  { type: Component, args: [{
8103
8212
  selector: 'banta-comments',
8104
- template: "\r\n<div class=\"focused\" [class.visible]=\"selectedMessageVisible\" *ngIf=\"selectedMessage\">\r\n\r\n <div>\r\n <a mat-button href=\"javascript:;\" (click)=\"unselectMessage()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n Latest Comments\r\n </a>\r\n </div>\r\n\r\n <banta-comment \r\n [message]=\"selectedMessage\"\r\n ></banta-comment>\r\n\r\n <div class=\"replies\">\r\n\r\n <ng-container *ngIf=\"!selectedMessageThread\">\r\n <div class=\"loading\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedMessageThread\">\r\n <banta-comment-view \r\n [source]=\"selectedMessageThread\"\r\n [allowReplies]=\"false\"\r\n [fixedHeight]=\"false\"\r\n [showEmptyState]=\"false\"\r\n [newestLast]=\"true\"\r\n ></banta-comment-view>\r\n\r\n <banta-comment-field\r\n [sendLabel]=\"replyLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n (signInSelected)=\"showSignIn()\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n [source]=\"selectedMessageThread\"\r\n [canComment]=\"canComment\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"permissionDeniedLabel\"\r\n (permissionDeniedError)=\"showPermissionDenied()\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\r\n ></banta-comment-field>\r\n </ng-container>\r\n </div>\r\n</div>\r\n\r\n<div class=\"main\" [class.hidden]=\"selectedMessage\">\r\n <banta-comment-field\r\n [source]=\"source\"\r\n [user]=\"user\"\r\n [sendLabel]=\"sendLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signInLabel]=\"signInLabel\"\r\n [canComment]=\"canComment\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [label]=\"postCommentLabel\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (signInSelected)=\"showSignIn()\"\r\n [permissionDeniedLabel]=\"permissionDeniedLabel\"\r\n (permissionDeniedError)=\"showPermissionDenied()\"\r\n ></banta-comment-field>\r\n\r\n <banta-comment-view \r\n [class.faded]=\"selectedMessage\"\r\n [source]=\"source\"\r\n [fixedHeight]=\"fixedHeight\"\r\n [maxMessages]=\"maxMessages\"\r\n [maxVisibleMessages]=\"maxVisibleMessages\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (userSelected)=\"selectMessageUser($event)\"\r\n (selected)=\"selectMessage($event)\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n ></banta-comment-view>\r\n</div>",
8213
+ template: "\r\n<div class=\"focused\" [class.visible]=\"selectedMessageVisible\" *ngIf=\"selectedMessage\">\r\n\r\n <div>\r\n <a mat-button href=\"javascript:;\" (click)=\"unselectMessage()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n Latest Comments\r\n </a>\r\n </div>\r\n\r\n <banta-comment\r\n [message]=\"selectedMessage\"\r\n ></banta-comment>\r\n\r\n <div class=\"replies\">\r\n\r\n <ng-container *ngIf=\"!selectedMessageThread\">\r\n <div class=\"loading\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedMessageThread\">\r\n <banta-comment-view\r\n [source]=\"selectedMessageThread\"\r\n [allowReplies]=\"false\"\r\n [fixedHeight]=\"false\"\r\n [showEmptyState]=\"false\"\r\n [newestLast]=\"true\"\r\n ></banta-comment-view>\r\n\r\n <banta-comment-field\r\n [sendLabel]=\"replyLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n (signInSelected)=\"showSignIn()\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n [source]=\"selectedMessageThread\"\r\n [canComment]=\"canComment\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"permissionDeniedLabel\"\r\n (permissionDeniedError)=\"showPermissionDenied()\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\r\n ></banta-comment-field>\r\n </ng-container>\r\n </div>\r\n</div>\r\n\r\n<div class=\"main\" [class.hidden]=\"selectedMessage\">\r\n <banta-comment-field\r\n [source]=\"source\"\r\n [user]=\"user\"\r\n [sendLabel]=\"sendLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signInLabel]=\"signInLabel\"\r\n [canComment]=\"canComment\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [label]=\"postCommentLabel\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (signInSelected)=\"showSignIn()\"\r\n [permissionDeniedLabel]=\"permissionDeniedLabel\"\r\n (permissionDeniedError)=\"showPermissionDenied()\"\r\n ></banta-comment-field>\r\n\r\n <banta-comment-sort\r\n [(sort)]=\"sortOrder\"></banta-comment-sort>\r\n\r\n <banta-comment-view\r\n [class.faded]=\"selectedMessage\"\r\n [source]=\"source\"\r\n [fixedHeight]=\"fixedHeight\"\r\n [maxMessages]=\"maxMessages\"\r\n [maxVisibleMessages]=\"maxVisibleMessages\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (userSelected)=\"selectMessageUser($event)\"\r\n (selected)=\"selectMessage($event)\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n ></banta-comment-view>\r\n</div>\r\n",
8105
8214
  styles: [":host{display:flex;flex-direction:column}@-webkit-keyframes select-comment{0%{transform:scale(1.15)}to{transform:scale(1)}}@keyframes select-comment{0%{transform:scale(1.15)}to{transform:scale(1)}}.focused{-webkit-animation-duration:.4s;-webkit-animation-fill-mode:both;-webkit-animation-name:select-comment;animation-duration:.4s;animation-fill-mode:both;animation-name:select-comment}.focused .replies{margin-left:4em;margin-top:1em}banta-comment-view{opacity:1;transition:opacity .4s ease-in-out}banta-comment-view.faded{opacity:.25}.loading{display:block;margin:0 auto;min-height:16em;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.main.hidden{display:none}@media (max-width:500px){.focused .replies{margin-left:0}}"]
8106
8215
  },] }
8107
8216
  ];
8108
8217
  BantaCommentsComponent.ctorParameters = () => [
8109
8218
  { type: BantaService },
8110
8219
  { type: ChatBackendService },
8111
- { type: ElementRef }
8220
+ { type: ElementRef },
8221
+ { type: ActivatedRoute }
8112
8222
  ];
8113
8223
  BantaCommentsComponent.propDecorators = {
8114
8224
  hashtags: [{ type: Input }],
@@ -8132,7 +8242,10 @@ BantaCommentsComponent.propDecorators = {
8132
8242
  upvoted: [{ type: Output }],
8133
8243
  reported: [{ type: Output }],
8134
8244
  selected: [{ type: Output }],
8135
- userSelected: [{ type: Output }]
8245
+ userSelected: [{ type: Output }],
8246
+ usernameSelected: [{ type: Output }],
8247
+ avatarSelected: [{ type: Output }],
8248
+ shared: [{ type: Output }]
8136
8249
  };
8137
8250
 
8138
8251
  class LiveCommentComponent {
@@ -8445,12 +8558,44 @@ CommentFieldComponent.propDecorators = {
8445
8558
  permissionDeniedError: [{ type: Output }]
8446
8559
  };
8447
8560
 
8561
+ class CommentSortComponent {
8562
+ constructor() {
8563
+ this.commentsOrder = CommentsOrder;
8564
+ this._sortChange = new Subject();
8565
+ this._sort = CommentsOrder.LIKES;
8566
+ }
8567
+ get sort() {
8568
+ return this._sort;
8569
+ }
8570
+ set sort(value) {
8571
+ if (this._sort !== value) {
8572
+ this._sort = value;
8573
+ setTimeout(() => this._sortChange.next(value));
8574
+ }
8575
+ }
8576
+ get sortChange() {
8577
+ return this._sortChange.asObservable();
8578
+ }
8579
+ }
8580
+ CommentSortComponent.decorators = [
8581
+ { type: Component, args: [{
8582
+ selector: 'banta-comment-sort',
8583
+ template: "<div class=\"sort-row\">\r\n <mat-form-field>\r\n <mat-label>Sort by</mat-label>\r\n <mat-select [(value)]=\"sort\" >\r\n <mat-option [value]=\"commentsOrder.NEWEST\">Newest</mat-option>\r\n <mat-option [value]=\"commentsOrder.OLDEST\">Oldest</mat-option>\r\n <mat-option [value]=\"commentsOrder.LIKES\">Likes</mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n</div>\r\n",
8584
+ styles: [".sort-row{display:flex;justify-content:end;padding-right:3em}"]
8585
+ },] }
8586
+ ];
8587
+ CommentSortComponent.propDecorators = {
8588
+ sort: [{ type: Input }],
8589
+ sortChange: [{ type: Output }]
8590
+ };
8591
+
8448
8592
  const COMPONENTS$3 = [
8449
8593
  CommentComponent,
8450
8594
  CommentViewComponent,
8451
8595
  BantaCommentsComponent,
8452
8596
  LiveCommentComponent,
8453
- CommentFieldComponent
8597
+ CommentFieldComponent,
8598
+ CommentSortComponent
8454
8599
  ];
8455
8600
  class CommentsModule {
8456
8601
  }
@@ -8468,7 +8613,9 @@ CommentsModule.decorators = [
8468
8613
  MatMenuModule,
8469
8614
  MatProgressSpinnerModule,
8470
8615
  BantaCommonModule,
8471
- EmojiModule
8616
+ EmojiModule,
8617
+ MatTooltipModule,
8618
+ MatSelectModule
8472
8619
  ],
8473
8620
  exports: COMPONENTS$3
8474
8621
  },] }