@banta/sdk 4.6.2 → 4.6.4

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.
@@ -8620,6 +8620,7 @@
8620
8620
 
8621
8621
  var CommentViewComponent = /** @class */ (function () {
8622
8622
  function CommentViewComponent(backend) {
8623
+ var _this = this;
8623
8624
  this.backend = backend;
8624
8625
  this._sourceSubs = new rxjs.Subscription();
8625
8626
  this._selected = new rxjs.Subject();
@@ -8638,6 +8639,7 @@
8638
8639
  this.menuMessage = null;
8639
8640
  this.messages = [];
8640
8641
  this.customSortEnabled = false;
8642
+ this.sourceLoaded = new Promise(function (r) { return _this.markSourceLoaded = r; });
8641
8643
  this.maxMessages = 2000;
8642
8644
  this.maxVisibleMessages = 200;
8643
8645
  this.newestLast = false;
@@ -8655,6 +8657,61 @@
8655
8657
  enumerable: false,
8656
8658
  configurable: true
8657
8659
  });
8660
+ /**
8661
+ * Returns true if this message can be found within one of the message buffers (older, current, newer)
8662
+ * @param message
8663
+ */
8664
+ CommentViewComponent.prototype.isMessageLoadedInContext = function (message) {
8665
+ return this.olderMessages.find(function (x) { return x.id === message.id; })
8666
+ || this.messages.find(function (x) { return x.id === message.id; })
8667
+ || this.newMessages.find(function (x) { return x.id === message.id; });
8668
+ };
8669
+ CommentViewComponent.prototype.loadMessageInContext = function (message) {
8670
+ return __awaiter(this, void 0, void 0, function () {
8671
+ var pageSize, items, index, startIndex;
8672
+ return __generator(this, function (_c) {
8673
+ switch (_c.label) {
8674
+ case 0: return [4 /*yield*/, this.sourceLoaded];
8675
+ case 1:
8676
+ _c.sent();
8677
+ console.log("Loading message " + message.id + " in context...");
8678
+ _c.label = 2;
8679
+ case 2:
8680
+ if (!(this.hasMore && !this.isMessageLoadedInContext(message))) return [3 /*break*/, 4];
8681
+ console.log("...Need to load more comments to find " + message.id);
8682
+ return [4 /*yield*/, this.showMore()];
8683
+ case 3:
8684
+ _c.sent();
8685
+ return [3 /*break*/, 2];
8686
+ case 4:
8687
+ console.log("Finished loading comments, hasMore=" + this.hasMore);
8688
+ if (!this.isMessageLoadedInContext(message)) {
8689
+ console.error("Error while loading message in context: Failed to find message " + message.id + ", maybe it was deleted!");
8690
+ return [2 /*return*/, false];
8691
+ }
8692
+ pageSize = this.maxVisibleMessages;
8693
+ items = [].concat(this.olderMessages, this.messages, this.newMessages);
8694
+ index = items.findIndex(function (x) { return x.id === message.id; });
8695
+ if (index < 0) {
8696
+ console.error("Error while loading message in context: Message was not present in message list!");
8697
+ return [2 /*return*/, false];
8698
+ }
8699
+ console.log("Total messages: " + items.length);
8700
+ console.log("Page size: " + pageSize);
8701
+ console.log("Message index: " + index);
8702
+ startIndex = Math.max(0, index - pageSize / 2);
8703
+ console.log("Start index: " + index);
8704
+ this.newMessages = items.splice(0, startIndex);
8705
+ this.messages = items.splice(0, pageSize);
8706
+ this.olderMessages = items;
8707
+ console.log(this.olderMessages.length + " older messages");
8708
+ console.log(this.messages.length + " current messages");
8709
+ console.log(this.newMessages.length + " newer messages");
8710
+ return [2 /*return*/];
8711
+ }
8712
+ });
8713
+ });
8714
+ };
8658
8715
  /**
8659
8716
  * Get the CommentComponent instantiated for the given ChatMessage,
8660
8717
  * if it exists in the current view. Note that messages which are not
@@ -8796,6 +8853,8 @@
8796
8853
  messages.forEach(function (m) { var _a; return (_a = m.transientState) !== null && _a !== void 0 ? _a : (m.transientState = {}); });
8797
8854
  this.messages = this.newestLast ? messages.slice().reverse() : messages;
8798
8855
  this.sortMessages();
8856
+ if (this.markSourceLoaded)
8857
+ this.markSourceLoaded();
8799
8858
  return [2 /*return*/];
8800
8859
  }
8801
8860
  });
@@ -8821,6 +8880,7 @@
8821
8880
  overflow = this.messages.splice(this.maxVisibleMessages, this.messages.length);
8822
8881
  this.olderMessages = overflow.concat(this.olderMessages);
8823
8882
  this.olderMessages.splice(this.maxMessages - this.maxVisibleMessages, this.olderMessages.length);
8883
+ this.hasMore = this.olderMessages.length > 0;
8824
8884
  return [2 /*return*/];
8825
8885
  });
8826
8886
  });
@@ -9040,6 +9100,7 @@
9040
9100
  this.activatedRoute = activatedRoute;
9041
9101
  this.matSnackBar = matSnackBar;
9042
9102
  this.ngZone = ngZone;
9103
+ this.viewReady = new Promise(function (r) { return _this.markViewReady = r; });
9043
9104
  // Loading Screen
9044
9105
  this._loadingMessage = '';
9045
9106
  this.loadingMessageVisible = false;
@@ -9057,6 +9118,7 @@
9057
9118
  "We'll keep trying, but it's not looking great. \n Commenting & chat services may be down. \n If you continue to experience issues, please contact support.\n "
9058
9119
  ];
9059
9120
  this.useInlineReplies = true;
9121
+ this.loaded = new Promise(function (r) { return _this.markLoaded = r; });
9060
9122
  // Properties
9061
9123
  this._signInSelected = new rxjs.Subject();
9062
9124
  this._permissionDeniedError = new rxjs.Subject();
@@ -9093,6 +9155,7 @@
9093
9155
  { hashtag: 'timeout', description: 'Cause a slow timeout error' },
9094
9156
  { hashtag: 'slow', description: 'Be slow when this message is posted' },
9095
9157
  ];
9158
+ this.loadingSharedComment = false;
9096
9159
  this.sendMessage = function (message) { return __awaiter(_this, void 0, void 0, function () {
9097
9160
  var _a, intercept, e_1;
9098
9161
  return __generator(this, function (_e) {
@@ -9225,6 +9288,7 @@
9225
9288
  }
9226
9289
  callback();
9227
9290
  }
9291
+ this.markViewReady();
9228
9292
  };
9229
9293
  BantaCommentsComponent.prototype.ngOnDestroy = function () {
9230
9294
  this._subs.unsubscribe();
@@ -9344,6 +9408,7 @@
9344
9408
  this.loadingMessage = "Here we go!";
9345
9409
  setTimeout(function () {
9346
9410
  _this.loading = false;
9411
+ _this.markLoaded();
9347
9412
  }, 750);
9348
9413
  return true;
9349
9414
  }
@@ -9378,6 +9443,7 @@
9378
9443
  this._source.messages.forEach(function (m) { return _this.addParticipant(m); });
9379
9444
  this._sourceSubscription.add(this._source.messageReceived.subscribe(function (m) { return _this.addParticipant(m); }));
9380
9445
  this._sourceSubscription.add(this._source.messageSent.subscribe(function (m) { return _this.addParticipant(m); }));
9446
+ this._sourceSubscription.add(this._source.messageObserved.subscribe(function (m) { return _this.addParticipant(m); }));
9381
9447
  this._sourceSubscription.add(this._source.messageUpdated.subscribe(function (msg) {
9382
9448
  var _a;
9383
9449
  console.log("comments received message: ", msg);
@@ -9478,7 +9544,10 @@
9478
9544
  var comment = document.querySelectorAll("[data-comment-id=\"" + commentId + "\"]");
9479
9545
  if (comment.length > 0) {
9480
9546
  // comment.item(0).scroll({behavior: 'smooth'});
9481
- comment.item(0).scrollIntoView();
9547
+ comment.item(0).scrollIntoView({
9548
+ inline: 'center',
9549
+ block: 'center'
9550
+ });
9482
9551
  }
9483
9552
  }, 1000);
9484
9553
  };
@@ -9489,55 +9558,74 @@
9489
9558
  return __generator(this, function (_e) {
9490
9559
  switch (_e.label) {
9491
9560
  case 0:
9561
+ this.loadingSharedComment = true;
9492
9562
  source = this.source;
9493
9563
  return [4 /*yield*/, source.ready];
9494
9564
  case 1:
9495
9565
  _e.sent();
9496
- console.log("Navigating to shared comment with ID '" + id + "'...");
9497
- _e.label = 2;
9566
+ return [4 /*yield*/, this.viewReady];
9498
9567
  case 2:
9499
- _e.trys.push([2, 4, , 5]);
9500
- return [4 /*yield*/, this.source.get(id)];
9568
+ _e.sent();
9569
+ return [4 /*yield*/, this.loaded];
9501
9570
  case 3:
9502
- message = _e.sent();
9503
- return [3 /*break*/, 5];
9571
+ _e.sent();
9572
+ console.log("Navigating to shared comment with ID '" + id + "'...");
9573
+ _e.label = 4;
9504
9574
  case 4:
9575
+ _e.trys.push([4, 6, , 7]);
9576
+ return [4 /*yield*/, this.source.get(id)];
9577
+ case 5:
9578
+ message = _e.sent();
9579
+ return [3 /*break*/, 7];
9580
+ case 6:
9505
9581
  e_3 = _e.sent();
9506
9582
  console.error("Failed to find comment from URL: " + e_3.message);
9583
+ alert("Could not load desired comment. It may have been removed.");
9507
9584
  return [2 /*return*/];
9508
- case 5:
9585
+ case 7:
9509
9586
  (_a = message.transientState) !== null && _a !== void 0 ? _a : (message.transientState = {});
9510
- if (!message.parentMessageId) return [3 /*break*/, 11];
9587
+ if (!message.parentMessageId) return [3 /*break*/, 14];
9511
9588
  return [4 /*yield*/, this.source.get(message.parentMessageId)];
9512
- case 6:
9589
+ case 8:
9513
9590
  parentMessage = _e.sent();
9514
9591
  (_b = parentMessage.transientState) !== null && _b !== void 0 ? _b : (parentMessage.transientState = {});
9592
+ // Make sure that this message is loaded and visible to the user
9593
+ return [4 /*yield*/, this.commentView.loadMessageInContext(parentMessage)];
9594
+ case 9:
9595
+ // Make sure that this message is loaded and visible to the user
9596
+ _e.sent();
9515
9597
  return [4 /*yield*/, this.selectMessage(parentMessage)];
9516
- case 7:
9598
+ case 10:
9517
9599
  thread = _e.sent();
9518
9600
  // Need to re-retrieve the message within the new chat source to affect its
9519
9601
  // transient state.
9520
9602
  return [4 /*yield*/, thread.ready];
9521
- case 8:
9603
+ case 11:
9522
9604
  // Need to re-retrieve the message within the new chat source to affect its
9523
9605
  // transient state.
9524
9606
  _e.sent();
9525
9607
  return [4 /*yield*/, thread.get(message.id)];
9526
- case 9:
9608
+ case 12:
9527
9609
  message = _e.sent();
9528
9610
  (_c = message.transientState) !== null && _c !== void 0 ? _c : (message.transientState = {});
9529
9611
  message.transientState.highlighted = true;
9530
9612
  console.dir(message);
9531
9613
  return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(function () { return resolve(); }, 500); })];
9532
- case 10:
9614
+ case 13:
9615
+ _e.sent();
9616
+ return [3 /*break*/, 16];
9617
+ case 14:
9618
+ // Make sure that this message is loaded and visible to the user
9619
+ return [4 /*yield*/, this.commentView.loadMessageInContext(message)];
9620
+ case 15:
9621
+ // Make sure that this message is loaded and visible to the user
9533
9622
  _e.sent();
9534
- return [3 /*break*/, 12];
9535
- case 11:
9536
9623
  (_d = message.transientState) !== null && _d !== void 0 ? _d : (message.transientState = {});
9537
9624
  message.transientState.highlighted = true;
9538
- _e.label = 12;
9539
- case 12:
9625
+ _e.label = 16;
9626
+ case 16:
9540
9627
  this.scrollToComment(id);
9628
+ this.loadingSharedComment = false;
9541
9629
  return [2 /*return*/];
9542
9630
  }
9543
9631
  });
@@ -9849,8 +9937,8 @@
9849
9937
  BantaCommentsComponent.decorators = [
9850
9938
  { type: core.Component, args: [{
9851
9939
  selector: 'banta-comments',
9852
- template: "<ng-container *ngIf=\"loading\">\r\n <div class=\"loading-screen\" [class.visible]=\"showLoadingScreen\">\r\n <h1>Loading...</h1>\r\n <div>\r\n <mat-spinner [diameter]=\"300\" [strokeWidth]=\"2\"></mat-spinner>\r\n </div>\r\n\r\n <p class=\"loading-message\" [class.visible]=\"loadingMessageVisible\">{{loadingMessage}}</p>\r\n </div>\r\n</ng-container>\r\n<ng-container *ngIf=\"!loading\">\r\n <div class=\"focused\" [class.visible]=\"selectedMessageVisible\" *ngIf=\"selectedMessage && !useInlineReplies\">\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 [liking]=\"selectedMessage.transientState.liking\"\r\n [mine]=\"user?.id === selectedMessage.user?.id\"\r\n [permissions]=\"source?.permissions\"\r\n [showReplyAction]=\"false\"\r\n [editing]=\"selectedMessage.transientState.editing\"\r\n [maxLength]=\"maxCommentLength\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (editStarted)=\"startEditing(selectedMessage)\"\r\n (editEnded)=\"selectedMessage.transientState.editing = false\"\r\n (edited)=\"saveEdit(selectedMessage, $event)\"\r\n (userSelected)=\"selectMessageUser(selectedMessage)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (liked)=\"likeMessage(source, selectedMessage)\"\r\n (unliked)=\"unlikeMessage(source, selectedMessage)\"\r\n (reported)=\"reportMessage(selectedMessage)\"\r\n (selected)=\"selectMessage(selectedMessage)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage(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 class=\"replies\"\r\n #threadView\r\n [source]=\"selectedMessageThread\"\r\n [allowReplies]=\"false\"\r\n [fixedHeight]=\"false\"\r\n [showEmptyState]=\"false\"\r\n [newestLast]=\"true\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (liked)=\"likeMessage(selectedMessageThread, $event)\"\r\n (unliked)=\"unlikeMessage(selectedMessageThread, $event)\"\r\n (messageEdited)=\"editMessage(selectedMessageThread, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage($event)\"\r\n [customMenuItems]=\"customMenuItems\"\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 [maxLength]=\"maxCommentLength\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\r\n [submit]=\"sendReply\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sendReplyOptionsTemplate\"></ng-container>\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 && !useInlineReplies\">\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]=\"source?.permissions?.canPost\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [label]=\"postCommentLabel\"\r\n [maxLength]=\"maxCommentLength\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (signInSelected)=\"showSignIn()\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [submit]=\"sendMessage\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n >\r\n \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 #commentView\r\n [class.faded]=\"selectedMessage && !useInlineReplies\"\r\n [source]=\"source\"\r\n [fixedHeight]=\"fixedHeight\"\r\n [maxMessages]=\"maxMessages\"\r\n [maxVisibleMessages]=\"maxVisibleMessages\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n [customMenuItems]=\"customMenuItems\"\r\n (userSelected)=\"selectMessageUser($event)\"\r\n (sortOrderChanged)=\"sortOrder = $event\"\r\n (selected)=\"selectMessage($event)\"\r\n (liked)=\"likeMessage(source, $event)\"\r\n (unliked)=\"unlikeMessage(source, $event)\"\r\n (messageEdited)=\"editMessage(source, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n [selectedMessage]=\"selectedMessage\"\r\n (deleted)=\"deleteMessage($event)\"\r\n >\r\n <div class=\"inline-replies\">\r\n <div class=\"focused\" [class.visible]=\"selectedMessageVisible\" *ngIf=\"selectedMessage\">\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 [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (liked)=\"likeMessage(selectedMessageThread, $event)\"\r\n (unliked)=\"unlikeMessage(selectedMessageThread, $event)\"\r\n (messageEdited)=\"editMessage(selectedMessageThread, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage($event)\"\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 [maxLength]=\"maxCommentLength\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n [source]=\"selectedMessageThread\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\r\n [submit]=\"sendReply\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sendReplyOptionsTemplate\"></ng-container>\r\n </banta-comment-field>\r\n </ng-container>\r\n </div>\r\n </div> \r\n </div>\r\n </banta-comment-view>\r\n </div>\r\n</ng-container>\r\n",
9853
- 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-name:select-comment;animation-name:select-comment;-webkit-animation-duration:.4s;animation-duration:.4s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.focused .replies{margin-top:1em;margin-left:2em;border-left:2px solid #333;padding-left:2em}banta-comment-view{opacity:1;transition:opacity .4s ease-in-out}banta-comment-view.faded{opacity:.25}.loading{display:block;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;margin:0 auto;min-height:16em}.main.hidden{display:none}.loading-screen{text-align:center;opacity:0;transition:opacity .25s ease-in-out}.loading-screen.visible{opacity:1}.loading-screen h1{font-weight:100}.loading-screen mat-spinner{margin:5em auto}.loading-screen .loading-message{opacity:0;transition:opacity .25s ease-in-out;width:500px;max-width:100%;margin:0 auto}.loading-screen .loading-message.visible{opacity:1}banta-comment-sort{margin:0 0 0 auto;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:block}.inline-replies{margin-left:4em}@media (max-width:500px){.focused .replies{margin-left:0}.inline-replies{margin-left:1em}.focused .replies{padding-left:.5em}banta-comment-sort{margin:0;width:100%}}:host-context(.banta-mobile) .focused .replies{margin-left:0}:host-context(.banta-mobile) .inline-replies{margin-left:1em}:host-context(.banta-mobile) .focused .replies{padding-left:.5em}:host-context(.banta-mobile) banta-comment-sort{margin:0;width:100%}"]
9940
+ template: "<ng-container *ngIf=\"loading\">\r\n <div class=\"loading-screen\" [class.visible]=\"showLoadingScreen\">\r\n <h1>Loading...</h1>\r\n <div>\r\n <mat-spinner [diameter]=\"300\" [strokeWidth]=\"2\"></mat-spinner>\r\n </div>\r\n\r\n <p class=\"loading-message\" [class.visible]=\"loadingMessageVisible\">{{loadingMessage}}</p>\r\n </div>\r\n</ng-container>\r\n<ng-container *ngIf=\"!loading\">\r\n <div class=\"focused\" [class.visible]=\"selectedMessageVisible\" *ngIf=\"selectedMessage && !useInlineReplies\">\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 [liking]=\"selectedMessage.transientState.liking\"\r\n [mine]=\"user?.id === selectedMessage.user?.id\"\r\n [permissions]=\"source?.permissions\"\r\n [showReplyAction]=\"false\"\r\n [editing]=\"selectedMessage.transientState.editing\"\r\n [maxLength]=\"maxCommentLength\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (editStarted)=\"startEditing(selectedMessage)\"\r\n (editEnded)=\"selectedMessage.transientState.editing = false\"\r\n (edited)=\"saveEdit(selectedMessage, $event)\"\r\n (userSelected)=\"selectMessageUser(selectedMessage)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (liked)=\"likeMessage(source, selectedMessage)\"\r\n (unliked)=\"unlikeMessage(source, selectedMessage)\"\r\n (reported)=\"reportMessage(selectedMessage)\"\r\n (selected)=\"selectMessage(selectedMessage)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage(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 class=\"replies\"\r\n #threadView\r\n [source]=\"selectedMessageThread\"\r\n [allowReplies]=\"false\"\r\n [fixedHeight]=\"false\"\r\n [showEmptyState]=\"false\"\r\n [newestLast]=\"true\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (liked)=\"likeMessage(selectedMessageThread, $event)\"\r\n (unliked)=\"unlikeMessage(selectedMessageThread, $event)\"\r\n (messageEdited)=\"editMessage(selectedMessageThread, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage($event)\"\r\n [customMenuItems]=\"customMenuItems\"\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 [maxLength]=\"maxCommentLength\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\r\n [submit]=\"sendReply\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sendReplyOptionsTemplate\"></ng-container>\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 && !useInlineReplies\">\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]=\"source?.permissions?.canPost\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [label]=\"postCommentLabel\"\r\n [maxLength]=\"maxCommentLength\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (signInSelected)=\"showSignIn()\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [submit]=\"sendMessage\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n >\r\n \r\n </banta-comment-field>\r\n\r\n <banta-comment-sort\r\n [(sort)]=\"sortOrder\"></banta-comment-sort>\r\n\r\n <div class=\"loading-comment\" *ngIf=\"loadingSharedComment\">\r\n <h1>Loading desired comment...</h1>\r\n <mat-spinner [diameter]=\"300\" [strokeWidth]=\"2\"></mat-spinner>\r\n <p>\r\n If there are a lot of comments, this might take awhile!\r\n </p>\r\n </div>\r\n <banta-comment-view\r\n #commentView\r\n [class.faded]=\"selectedMessage && !useInlineReplies\"\r\n [source]=\"source\"\r\n [fixedHeight]=\"fixedHeight\"\r\n [maxMessages]=\"maxMessages\"\r\n [maxVisibleMessages]=\"maxVisibleMessages\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n [customMenuItems]=\"customMenuItems\"\r\n (userSelected)=\"selectMessageUser($event)\"\r\n (sortOrderChanged)=\"sortOrder = $event\"\r\n (selected)=\"selectMessage($event)\"\r\n (liked)=\"likeMessage(source, $event)\"\r\n (unliked)=\"unlikeMessage(source, $event)\"\r\n (messageEdited)=\"editMessage(source, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n [selectedMessage]=\"selectedMessage\"\r\n (deleted)=\"deleteMessage($event)\"\r\n >\r\n <div class=\"inline-replies\">\r\n <div class=\"focused\" [class.visible]=\"selectedMessageVisible\" *ngIf=\"selectedMessage\">\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 [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (liked)=\"likeMessage(selectedMessageThread, $event)\"\r\n (unliked)=\"unlikeMessage(selectedMessageThread, $event)\"\r\n (messageEdited)=\"editMessage(selectedMessageThread, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage($event)\"\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 [maxLength]=\"maxCommentLength\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n [source]=\"selectedMessageThread\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\r\n [submit]=\"sendReply\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sendReplyOptionsTemplate\"></ng-container>\r\n </banta-comment-field>\r\n </ng-container>\r\n </div>\r\n </div> \r\n </div>\r\n </banta-comment-view>\r\n </div>\r\n</ng-container>\r\n",
9941
+ 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-name:select-comment;animation-name:select-comment;-webkit-animation-duration:.4s;animation-duration:.4s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.focused .replies{margin-top:1em;margin-left:2em;border-left:2px solid #333;padding-left:2em}banta-comment-view{opacity:1;transition:opacity .4s ease-in-out}banta-comment-view.faded{opacity:.25}.loading{display:block;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;margin:0 auto;min-height:16em}.main.hidden{display:none}.loading-screen{text-align:center;opacity:0;transition:opacity .25s ease-in-out}.loading-screen.visible{opacity:1}.loading-screen h1{font-weight:100}.loading-screen mat-spinner{margin:5em auto}.loading-screen .loading-message{opacity:0;transition:opacity .25s ease-in-out;width:500px;max-width:100%;margin:0 auto}.loading-screen .loading-message.visible{opacity:1}banta-comment-sort{margin:0 0 0 auto;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:block}.inline-replies{margin-left:4em}@media (max-width:500px){.focused .replies{margin-left:0}.inline-replies{margin-left:1em}.focused .replies{padding-left:.5em}banta-comment-sort{margin:0;width:100%}}:host-context(.banta-mobile) .focused .replies{margin-left:0}:host-context(.banta-mobile) .inline-replies{margin-left:1em}:host-context(.banta-mobile) .focused .replies{padding-left:.5em}:host-context(.banta-mobile) banta-comment-sort{margin:0;width:100%}.loading-comment{z-index:100;border:1px solid #333;background:#000;color:#fff;padding:1em;border-radius:4px;text-align:center}.loading-comment h1{font-weight:100;text-align:center}.loading-comment mat-spinner{margin:0 auto}"]
9854
9942
  },] }
9855
9943
  ];
9856
9944
  BantaCommentsComponent.ctorParameters = function () { return [
@@ -10326,10 +10414,12 @@
10326
10414
  return [2 /*return*/];
10327
10415
  }
10328
10416
  if (event.key === 'Enter') {
10329
- this.activateAutoComplete(this.autocompleteOptions[this.autoCompleteSelected]);
10330
- event.stopPropagation();
10331
- event.preventDefault();
10332
- return [2 /*return*/];
10417
+ if (this.autocompleteOptions[this.autoCompleteSelected]) {
10418
+ this.activateAutoComplete(this.autocompleteOptions[this.autoCompleteSelected]);
10419
+ event.stopPropagation();
10420
+ event.preventDefault();
10421
+ return [2 /*return*/];
10422
+ }
10333
10423
  }
10334
10424
  if (event.key === 'ArrowUp') {
10335
10425
  if (this.autoCompleteSelected === 0)
@@ -10721,6 +10811,7 @@
10721
10811
  _this._messageReceived = new rxjs.Subject();
10722
10812
  _this._messageUpdated = new rxjs.Subject();
10723
10813
  _this._messageSent = new rxjs.Subject();
10814
+ _this._messageObserved = new rxjs.Subject();
10724
10815
  _this.messages = [];
10725
10816
  _this.ready = new Promise(function (resolve) { return _this.markReady = resolve; });
10726
10817
  return _this;
@@ -10798,10 +10889,13 @@
10798
10889
  };
10799
10890
  ChatSource.prototype.mapOrUpdateMessage = function (message) {
10800
10891
  var existingMessage = this.messageMap.get(message.id);
10801
- if (existingMessage)
10892
+ if (existingMessage) {
10802
10893
  message = Object.assign(existingMessage, message);
10803
- else
10894
+ }
10895
+ else {
10804
10896
  this.messageMap.set(message.id, message);
10897
+ this._messageObserved.next(message);
10898
+ }
10805
10899
  return message;
10806
10900
  };
10807
10901
  ChatSource.prototype.getExistingMessages = function () {
@@ -10920,6 +11014,11 @@
10920
11014
  enumerable: false,
10921
11015
  configurable: true
10922
11016
  });
11017
+ Object.defineProperty(ChatSource.prototype, "messageObserved", {
11018
+ get: function () { return this._messageObserved.asObservable(); },
11019
+ enumerable: false,
11020
+ configurable: true
11021
+ });
10923
11022
  ChatSource.prototype.send = function (message) {
10924
11023
  return __awaiter(this, void 0, void 0, function () {
10925
11024
  return __generator(this, function (_b) {