@banta/sdk 4.8.1 → 4.9.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.
Files changed (31) hide show
  1. package/esm2020/lib/banta/banta.component.mjs +3 -3
  2. package/esm2020/lib/chat/banta-chat/banta-chat.component.mjs +5 -3
  3. package/esm2020/lib/chat-backend-base.mjs +1 -1
  4. package/esm2020/lib/chat-backend.mjs +80 -12
  5. package/esm2020/lib/chat-source-base.mjs +1 -1
  6. package/esm2020/lib/chat-source.mjs +7 -2
  7. package/esm2020/lib/comments/attachment-button/attachment-button.component.mjs +17 -10
  8. package/esm2020/lib/comments/banta-comments/banta-comments.component.mjs +7 -5
  9. package/esm2020/lib/comments/comment/comment.component.mjs +88 -130
  10. package/esm2020/lib/comments/comment-field/comment-field.component.mjs +124 -144
  11. package/esm2020/lib/comments/comment-view/comment-view.component.mjs +72 -70
  12. package/esm2020/lib/comments/live-comment.component.mjs +1 -1
  13. package/esm2020/lib/emoji/emoji-selector-button.component.mjs +7 -4
  14. package/esm2020/lib/static-chat-source.mjs +71 -0
  15. package/fesm2015/banta-sdk.mjs +500 -382
  16. package/fesm2015/banta-sdk.mjs.map +1 -1
  17. package/fesm2020/banta-sdk.mjs +469 -375
  18. package/fesm2020/banta-sdk.mjs.map +1 -1
  19. package/lib/chat/banta-chat/banta-chat.component.d.ts +2 -1
  20. package/lib/chat-backend-base.d.ts +4 -0
  21. package/lib/chat-backend.d.ts +29 -4
  22. package/lib/chat-source-base.d.ts +8 -0
  23. package/lib/chat-source.d.ts +2 -0
  24. package/lib/comments/attachment-button/attachment-button.component.d.ts +3 -2
  25. package/lib/comments/banta-comments/banta-comments.component.d.ts +5 -1
  26. package/lib/comments/comment/comment.component.d.ts +41 -39
  27. package/lib/comments/comment-field/comment-field.component.d.ts +38 -40
  28. package/lib/comments/comment-view/comment-view.component.d.ts +43 -41
  29. package/lib/emoji/emoji-selector-button.component.d.ts +2 -1
  30. package/lib/static-chat-source.d.ts +42 -0
  31. package/package.json +1 -1
@@ -1,12 +1,12 @@
1
1
  import { Observable, Subject, BehaviorSubject, Subscription } from 'rxjs';
2
2
  import { publish, take } from 'rxjs/operators';
3
3
  import * as i0 from '@angular/core';
4
- import { Component, Input, ViewChild, Pipe, Inject, Optional, Output, HostBinding, NgModule, ViewChildren, Directive, TemplateRef, ContentChild, Injectable as Injectable$1 } from '@angular/core';
4
+ import { Component, Input, ViewChild, Pipe, Inject, Optional, Output, HostBinding, NgModule, ViewChildren, Directive, TemplateRef, ContentChild, PLATFORM_ID, Injectable as Injectable$1 } from '@angular/core';
5
5
  import { __decorate, __awaiter } from 'tslib';
6
6
  import * as i1$2 from '@banta/common';
7
- import { Injectable, FilterMode, CommentsOrder, SocketRPC, RpcEvent, DurableSocket } from '@banta/common';
7
+ import { Injectable, FilterMode, CommentsOrder, SocketRPC, RpcEvent, DurableSocket, buildQuery } from '@banta/common';
8
8
  import * as i2 from '@angular/common';
9
- import { CommonModule } from '@angular/common';
9
+ import { CommonModule, isPlatformServer } from '@angular/common';
10
10
  import * as i2$1 from '@angular/material/icon';
11
11
  import { MatIconModule } from '@angular/material/icon';
12
12
  import * as marked from 'marked';
@@ -18,7 +18,7 @@ import * as i8 from '@angular/material/progress-spinner';
18
18
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
19
19
  import * as i6 from '@angular/material/button';
20
20
  import { MatButtonModule } from '@angular/material/button';
21
- import * as i4 from '@angular/forms';
21
+ import * as i3$1 from '@angular/forms';
22
22
  import { FormsModule } from '@angular/forms';
23
23
  import * as i6$1 from '@angular/material/form-field';
24
24
  import { MatFormFieldModule } from '@angular/material/form-field';
@@ -26,20 +26,20 @@ import * as i7 from '@angular/material/input';
26
26
  import { MatInputModule } from '@angular/material/input';
27
27
  import * as i1$1 from '@angular/cdk/overlay';
28
28
  import { OverlayModule } from '@angular/cdk/overlay';
29
- import * as i4$1 from '@angular/cdk/portal';
29
+ import * as i4 from '@angular/cdk/portal';
30
30
  import { PortalModule } from '@angular/cdk/portal';
31
- import * as i2$3 from '@angular/material/dialog';
31
+ import * as i2$4 from '@angular/material/dialog';
32
32
  import { MatDialogModule } from '@angular/material/dialog';
33
33
  import * as i7$1 from '@angular/material/menu';
34
34
  import { MatMenuModule } from '@angular/material/menu';
35
35
  import * as i11 from '@angular/material/tooltip';
36
36
  import { MatTooltipModule } from '@angular/material/tooltip';
37
- import * as i2$2 from '@angular/router';
37
+ import * as i2$3 from '@angular/router';
38
38
  import * as i3$2 from '@angular/material/snack-bar';
39
39
  import { MatSnackBarModule } from '@angular/material/snack-bar';
40
- import * as i3$1 from '@angular/cdk/text-field';
40
+ import * as i2$2 from '@angular/cdk/text-field';
41
41
  import { TextFieldModule } from '@angular/cdk/text-field';
42
- import * as i2$4 from '@angular/material/select';
42
+ import * as i2$5 from '@angular/material/select';
43
43
  import { MatSelectModule } from '@angular/material/select';
44
44
  import * as i3$3 from '@angular/material/core';
45
45
  import { v4 } from 'uuid';
@@ -7242,7 +7242,7 @@ class EmojiSelectorPanelComponent {
7242
7242
  }
7243
7243
  }
7244
7244
  EmojiSelectorPanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorPanelComponent, deps: [{ token: i1.DomSanitizer }, { token: BANTA_SDK_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
7245
- EmojiSelectorPanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: EmojiSelectorPanelComponent, selector: "emoji-selector-panel", outputs: { selected: "selected" }, ngImport: i0, template: "<div class=\"search-box\" *ngIf=\"searchVisible\">\r\n\t<a mat-icon-button href=\"javascript:;\" (click)=\"hideSearch()\">\r\n\t\t<mat-icon>arrow_back</mat-icon>\r\n\t</a>\r\n\t<mat-form-field appearance=\"outline\" floatLabel=\"always\">\r\n\t\t<mat-label>Search for emoji</mat-label>\r\n\t\t<input name=\"search\" type=\"text\" matInput placeholder=\"Start typing\" [(ngModel)]=\"searchQuery\" />\r\n\t</mat-form-field>\r\n</div>\r\n\r\n<div class=\"selector\">\r\n\t<ng-container *ngIf=\"searchVisible\">\r\n\t\t<div class=\"emoji-list\">\r\n\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t*ngFor=\"let emoji of searchResults\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t</a>\r\n\t\t</div>\r\n\t</ng-container>\r\n\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t<div class=\"categories\">\r\n\t\t\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t\t\t<a [title]=\"humanize(category.name)\" [class.active]=\"activeCategory === category.name\" mat-icon-button *ngFor=\"let category of categories\" (click)=\"activeCategory = category.name\">\r\n\t\t\t\t\t<mat-icon>{{category.icon}}</mat-icon>\r\n\t\t\t\t</a>\r\n\r\n\t\t\t\t<a title=\"Search\" [class.active] mat-icon-button (click)=\"showSearch()\">\r\n\t\t\t\t\t<mat-icon>search</mat-icon>\r\n\t\t\t\t</a>\r\n\t\t\t</ng-container>\r\n\t\t</div>\r\n\t\t<ng-container *ngFor=\"let category of categories\">\r\n\t\t\t<div class=\"emoji-list\" *ngIf=\"activeCategory && activeCategory == category.name\">\r\n\t\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t\t*ngFor=\"let emoji of category.emojis\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t\t</a>\r\n\t\t\t</div>\r\n\t\t</ng-container>\r\n\t</ng-container>\r\n</div>", styles: [":host{background:#111;color:#fff;border:1px solid #333;border-radius:5px;padding:.5em;width:calc(9*(32px + 1em));max-width:calc(100vw - 1.5em - 5px)}.selector{display:flex;flex-direction:column}.categories a{opacity:.25;transition:.4s opacity ease-in-out}.categories a:hover{opacity:.5}.categories a.active{opacity:1}.emoji-list{flex-grow:1;overflow-y:auto;height:20em}.emoji-list a{display:inline-block;padding:2px;margin:4px;background-color:#111}.emoji-list a ::ng-deep .emoji{width:32px;height:32px}.emoji-list a:hover{background-color:#333}.search-box{display:flex;align-items:baseline}.search-box mat-form-field{flex-grow:1}@media (max-width: 500px){.selector{flex-direction:row;height:27em}.emoji-list{height:auto}}:host-context(.banta-mobile) .selector{flex-direction:row;height:27em}:host-context(.banta-mobile) .emoji-list{height:auto}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }] });
7245
+ EmojiSelectorPanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: EmojiSelectorPanelComponent, selector: "emoji-selector-panel", outputs: { selected: "selected" }, ngImport: i0, template: "<div class=\"search-box\" *ngIf=\"searchVisible\">\r\n\t<a mat-icon-button href=\"javascript:;\" (click)=\"hideSearch()\">\r\n\t\t<mat-icon>arrow_back</mat-icon>\r\n\t</a>\r\n\t<mat-form-field appearance=\"outline\" floatLabel=\"always\">\r\n\t\t<mat-label>Search for emoji</mat-label>\r\n\t\t<input name=\"search\" type=\"text\" matInput placeholder=\"Start typing\" [(ngModel)]=\"searchQuery\" />\r\n\t</mat-form-field>\r\n</div>\r\n\r\n<div class=\"selector\">\r\n\t<ng-container *ngIf=\"searchVisible\">\r\n\t\t<div class=\"emoji-list\">\r\n\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t*ngFor=\"let emoji of searchResults\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t</a>\r\n\t\t</div>\r\n\t</ng-container>\r\n\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t<div class=\"categories\">\r\n\t\t\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t\t\t<a [title]=\"humanize(category.name)\" [class.active]=\"activeCategory === category.name\" mat-icon-button *ngFor=\"let category of categories\" (click)=\"activeCategory = category.name\">\r\n\t\t\t\t\t<mat-icon>{{category.icon}}</mat-icon>\r\n\t\t\t\t</a>\r\n\r\n\t\t\t\t<a title=\"Search\" [class.active] mat-icon-button (click)=\"showSearch()\">\r\n\t\t\t\t\t<mat-icon>search</mat-icon>\r\n\t\t\t\t</a>\r\n\t\t\t</ng-container>\r\n\t\t</div>\r\n\t\t<ng-container *ngFor=\"let category of categories\">\r\n\t\t\t<div class=\"emoji-list\" *ngIf=\"activeCategory && activeCategory == category.name\">\r\n\t\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t\t*ngFor=\"let emoji of category.emojis\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t\t</a>\r\n\t\t\t</div>\r\n\t\t</ng-container>\r\n\t</ng-container>\r\n</div>", styles: [":host{background:#111;color:#fff;border:1px solid #333;border-radius:5px;padding:.5em;width:calc(9*(32px + 1em));max-width:calc(100vw - 1.5em - 5px)}.selector{display:flex;flex-direction:column}.categories a{opacity:.25;transition:.4s opacity ease-in-out}.categories a:hover{opacity:.5}.categories a.active{opacity:1}.emoji-list{flex-grow:1;overflow-y:auto;height:20em}.emoji-list a{display:inline-block;padding:2px;margin:4px;background-color:#111}.emoji-list a ::ng-deep .emoji{width:32px;height:32px}.emoji-list a:hover{background-color:#333}.search-box{display:flex;align-items:baseline}.search-box mat-form-field{flex-grow:1}@media (max-width: 500px){.selector{flex-direction:row;height:27em}.emoji-list{height:auto}}:host-context(.banta-mobile) .selector{flex-direction:row;height:27em}:host-context(.banta-mobile) .emoji-list{height:auto}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }] });
7246
7246
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorPanelComponent, decorators: [{
7247
7247
  type: Component,
7248
7248
  args: [{ selector: 'emoji-selector-panel', template: "<div class=\"search-box\" *ngIf=\"searchVisible\">\r\n\t<a mat-icon-button href=\"javascript:;\" (click)=\"hideSearch()\">\r\n\t\t<mat-icon>arrow_back</mat-icon>\r\n\t</a>\r\n\t<mat-form-field appearance=\"outline\" floatLabel=\"always\">\r\n\t\t<mat-label>Search for emoji</mat-label>\r\n\t\t<input name=\"search\" type=\"text\" matInput placeholder=\"Start typing\" [(ngModel)]=\"searchQuery\" />\r\n\t</mat-form-field>\r\n</div>\r\n\r\n<div class=\"selector\">\r\n\t<ng-container *ngIf=\"searchVisible\">\r\n\t\t<div class=\"emoji-list\">\r\n\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t*ngFor=\"let emoji of searchResults\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t</a>\r\n\t\t</div>\r\n\t</ng-container>\r\n\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t<div class=\"categories\">\r\n\t\t\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t\t\t<a [title]=\"humanize(category.name)\" [class.active]=\"activeCategory === category.name\" mat-icon-button *ngFor=\"let category of categories\" (click)=\"activeCategory = category.name\">\r\n\t\t\t\t\t<mat-icon>{{category.icon}}</mat-icon>\r\n\t\t\t\t</a>\r\n\r\n\t\t\t\t<a title=\"Search\" [class.active] mat-icon-button (click)=\"showSearch()\">\r\n\t\t\t\t\t<mat-icon>search</mat-icon>\r\n\t\t\t\t</a>\r\n\t\t\t</ng-container>\r\n\t\t</div>\r\n\t\t<ng-container *ngFor=\"let category of categories\">\r\n\t\t\t<div class=\"emoji-list\" *ngIf=\"activeCategory && activeCategory == category.name\">\r\n\t\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t\t*ngFor=\"let emoji of category.emojis\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t\t</a>\r\n\t\t\t</div>\r\n\t\t</ng-container>\r\n\t</ng-container>\r\n</div>", styles: [":host{background:#111;color:#fff;border:1px solid #333;border-radius:5px;padding:.5em;width:calc(9*(32px + 1em));max-width:calc(100vw - 1.5em - 5px)}.selector{display:flex;flex-direction:column}.categories a{opacity:.25;transition:.4s opacity ease-in-out}.categories a:hover{opacity:.5}.categories a.active{opacity:1}.emoji-list{flex-grow:1;overflow-y:auto;height:20em}.emoji-list a{display:inline-block;padding:2px;margin:4px;background-color:#111}.emoji-list a ::ng-deep .emoji{width:32px;height:32px}.emoji-list a:hover{background-color:#333}.search-box{display:flex;align-items:baseline}.search-box mat-form-field{flex-grow:1}@media (max-width: 500px){.selector{flex-direction:row;height:27em}.emoji-list{height:auto}}:host-context(.banta-mobile) .selector{flex-direction:row;height:27em}:host-context(.banta-mobile) .emoji-list{height:auto}\n"] }]
@@ -7264,6 +7264,7 @@ class EmojiSelectorButtonComponent {
7264
7264
  this.overlay = overlay;
7265
7265
  this._selected = new Subject();
7266
7266
  this.showEmojiPanel = false;
7267
+ this.disabled = false;
7267
7268
  this.overlayX = 'end';
7268
7269
  this.overlayY = 'top';
7269
7270
  this.originX = 'end';
@@ -7323,8 +7324,8 @@ class EmojiSelectorButtonComponent {
7323
7324
  }
7324
7325
  }
7325
7326
  EmojiSelectorButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorButtonComponent, deps: [{ token: i0.ElementRef }, { token: i1$1.Overlay }], target: i0.ɵɵFactoryTarget.Component });
7326
- EmojiSelectorButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: EmojiSelectorButtonComponent, selector: "emoji-selector-button", inputs: { overlayX: "overlayX", overlayY: "overlayY", originX: "originX", originY: "originY" }, outputs: { selected: "selected" }, viewQueries: [{ propertyName: "selectorPanelTemplate", first: true, predicate: ["selectorPanelTemplate"], descendants: true }], ngImport: i0, template: `
7327
- <button #button type="button" mat-icon-button (click)="show()">
7327
+ EmojiSelectorButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: EmojiSelectorButtonComponent, selector: "emoji-selector-button", inputs: { disabled: "disabled", overlayX: "overlayX", overlayY: "overlayY", originX: "originX", originY: "originY" }, outputs: { selected: "selected" }, viewQueries: [{ propertyName: "selectorPanelTemplate", first: true, predicate: ["selectorPanelTemplate"], descendants: true }], ngImport: i0, template: `
7328
+ <button #button type="button" mat-icon-button (click)="show()" [disabled]="disabled">
7328
7329
  <mat-icon>emoji_emotions</mat-icon>
7329
7330
  </button>
7330
7331
  <ng-template cdkPortal #selectorPanelTemplate="cdkPortal">
@@ -7333,11 +7334,11 @@ EmojiSelectorButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14
7333
7334
  (selected)="insert($event)"
7334
7335
  ></emoji-selector-panel>
7335
7336
  </ng-template>
7336
- `, isInline: true, styles: [":host{display:block;position:relative}button{color:#666}\n"], dependencies: [{ kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4$1.CdkPortal, selector: "[cdkPortal]", exportAs: ["cdkPortal"] }, { kind: "component", type: EmojiSelectorPanelComponent, selector: "emoji-selector-panel", outputs: ["selected"] }] });
7337
+ `, isInline: true, styles: [":host{display:block;position:relative}button{color:#666}\n"], dependencies: [{ kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4.CdkPortal, selector: "[cdkPortal]", exportAs: ["cdkPortal"] }, { kind: "component", type: EmojiSelectorPanelComponent, selector: "emoji-selector-panel", outputs: ["selected"] }] });
7337
7338
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorButtonComponent, decorators: [{
7338
7339
  type: Component,
7339
7340
  args: [{ selector: 'emoji-selector-button', template: `
7340
- <button #button type="button" mat-icon-button (click)="show()">
7341
+ <button #button type="button" mat-icon-button (click)="show()" [disabled]="disabled">
7341
7342
  <mat-icon>emoji_emotions</mat-icon>
7342
7343
  </button>
7343
7344
  <ng-template cdkPortal #selectorPanelTemplate="cdkPortal">
@@ -7352,6 +7353,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
7352
7353
  args: ['selectorPanelTemplate']
7353
7354
  }], selected: [{
7354
7355
  type: Output
7356
+ }], disabled: [{
7357
+ type: Input
7355
7358
  }], overlayX: [{
7356
7359
  type: Input
7357
7360
  }], overlayY: [{
@@ -7438,6 +7441,16 @@ class ChatBackendBase {
7438
7441
  class CommentComponent {
7439
7442
  constructor(elementRef) {
7440
7443
  this.elementRef = elementRef;
7444
+ //#endregion
7445
+ //#region Properties
7446
+ this.isLoaded = false;
7447
+ this.showReplyAction = true;
7448
+ this.maxLength = 1500;
7449
+ this.mine = false;
7450
+ this.editing = false;
7451
+ this.readonly = false;
7452
+ //#endregion
7453
+ //#region Outputs
7441
7454
  this._reported = new Subject();
7442
7455
  this._selected = new Subject();
7443
7456
  this._liked = new Subject();
@@ -7446,21 +7459,26 @@ class CommentComponent {
7446
7459
  this._userSelected = new Subject();
7447
7460
  this._avatarSelected = new Subject();
7448
7461
  this._usernameSelected = new Subject();
7449
- this.maxLength = 1500;
7450
- this.isNew = false;
7451
- this.visible = false;
7452
- this.showReplyAction = true;
7453
- this.loaded = new Subject();
7454
- this.isLoaded = false;
7455
- this.mine = false;
7456
- this.editing = false;
7457
7462
  this._editStarted = new Subject();
7458
7463
  this._deleted = new Subject();
7459
7464
  this._editEnded = new Subject();
7460
7465
  this._edited = new Subject();
7461
- }
7462
- get element() {
7463
- return this.elementRef.nativeElement;
7466
+ this._loaded = new Subject();
7467
+ this.liked = this._liked.asObservable();
7468
+ this.unliked = this._unliked.asObservable();
7469
+ this.selected = this._selected.asObservable();
7470
+ this.edited = this._edited.asObservable();
7471
+ this.deleted = this._deleted.asObservable();
7472
+ this.editStarted = this._editStarted.asObservable();
7473
+ this.editEnded = this._editEnded.asObservable();
7474
+ this.shared = this._shared.asObservable();
7475
+ this.userSelected = this._userSelected.asObservable();
7476
+ this.usernameSelected = this._usernameSelected.asObservable();
7477
+ this.avatarSelected = this._avatarSelected.asObservable();
7478
+ this.reported = this._reported.asObservable();
7479
+ this.loaded = this._loaded.asObservable();
7480
+ this.isNew = false;
7481
+ this.visible = false;
7464
7482
  }
7465
7483
  ngOnInit() {
7466
7484
  let maxTime = 100;
@@ -7472,18 +7490,26 @@ class CommentComponent {
7472
7490
  setTimeout(() => this.isNew = false, 1000);
7473
7491
  }, randomTime);
7474
7492
  }
7475
- markAttachmentsLoaded() {
7476
- this.isLoaded = true;
7477
- this.loaded.next();
7478
- }
7479
- get isHighlighted() {
7480
- var _a, _b, _c;
7481
- return (_c = (_b = (_a = this.message) === null || _a === void 0 ? void 0 : _a.transientState) === null || _b === void 0 ? void 0 : _b.highlighted) !== null && _c !== void 0 ? _c : false;
7482
- }
7483
- get message() {
7484
- return this._message;
7493
+ //#region Message
7494
+ get message() { return this._message; }
7495
+ set message(value) { this.setMessage(value); }
7496
+ //#endregion
7497
+ //#region UI Bindings
7498
+ get commentId() { var _a; return (_a = this.message) === null || _a === void 0 ? void 0 : _a.id; }
7499
+ get isHighlighted() { var _a, _b, _c; return (_c = (_b = (_a = this.message) === null || _a === void 0 ? void 0 : _a.transientState) === null || _b === void 0 ? void 0 : _b.highlighted) !== null && _c !== void 0 ? _c : false; }
7500
+ get replyCount() { var _a; return ((_a = this.message.submessages) === null || _a === void 0 ? void 0 : _a.length) || this.message.submessageCount || 0; }
7501
+ get element() { return this.elementRef.nativeElement; }
7502
+ avatarForUser(user) { var _a; return `url(${(_a = user === null || user === void 0 ? void 0 : user.avatarUrl) !== null && _a !== void 0 ? _a : this.genericAvatarUrl})`; }
7503
+ //#endregion
7504
+ //#region Public Component API
7505
+ waitForLoad() {
7506
+ return __awaiter(this, void 0, void 0, function* () {
7507
+ (yield this.isLoaded) ? Promise.resolve() : this.loaded.pipe(take(1)).toPromise();
7508
+ });
7485
7509
  }
7486
- set message(value) {
7510
+ //#endregion
7511
+ //#region Private API
7512
+ setMessage(value) {
7487
7513
  var _a;
7488
7514
  this._message = value;
7489
7515
  if (((_a = this._message.attachments) === null || _a === void 0 ? void 0 : _a.length) > 0) {
@@ -7491,132 +7517,48 @@ class CommentComponent {
7491
7517
  }
7492
7518
  else {
7493
7519
  this.isLoaded = true;
7494
- this.loaded.next();
7520
+ this._loaded.next();
7495
7521
  }
7496
7522
  }
7497
- waitForLoad() {
7498
- return __awaiter(this, void 0, void 0, function* () {
7499
- if (this.isLoaded)
7500
- return true;
7501
- yield this.loaded.pipe(take(1)).toPromise();
7502
- });
7503
- }
7504
- get userSelected() {
7505
- return this._userSelected.asObservable();
7506
- }
7507
- get usernameSelected() {
7508
- return this._usernameSelected.asObservable();
7509
- }
7510
- get avatarSelected() {
7511
- return this._avatarSelected.asObservable();
7512
- }
7513
- get reported() {
7514
- return this._reported.asObservable();
7515
- }
7516
- saveEdit() {
7517
- this._edited.next(this.editedMessage);
7518
- }
7519
- endEditing() {
7520
- this._editEnded.next();
7521
- }
7522
- startEdit() {
7523
- this._editStarted.next();
7524
- this.editedMessage = this.message.message;
7525
- }
7526
- delete() {
7527
- this._deleted.next();
7528
- }
7529
- get liked() {
7530
- return this._liked.asObservable();
7531
- }
7532
- get unliked() {
7533
- return this._unliked.asObservable();
7534
- }
7535
- get selected() {
7536
- return this._selected.asObservable();
7537
- }
7538
- get edited() { return this._edited.asObservable(); }
7539
- get deleted() { return this._deleted.asObservable(); }
7540
- get editStarted() { return this._editStarted.asObservable(); }
7541
- get editEnded() { return this._editEnded.asObservable(); }
7542
- get shared() { return this._shared.asObservable(); }
7543
- get commentId() { var _a; return (_a = this.message) === null || _a === void 0 ? void 0 : _a.id; }
7544
- report() {
7545
- this._reported.next();
7546
- }
7547
- like() {
7548
- this._liked.next();
7549
- }
7550
- unlike() {
7551
- this._unliked.next();
7552
- }
7553
- share() {
7554
- this._shared.next(this.message);
7555
- }
7556
- select() {
7557
- this._selected.next();
7558
- }
7559
- selectUser() {
7560
- this._userSelected.next();
7561
- }
7562
- selectUsername(user) {
7563
- this._usernameSelected.next(user);
7564
- this.selectUser();
7565
- }
7566
- selectAvatar(user) {
7567
- this._avatarSelected.next(user);
7568
- this.selectUser();
7569
- }
7570
- avatarForUser(user) {
7571
- let url = this.genericAvatarUrl;
7572
- if (user && user.avatarUrl) {
7573
- url = user.avatarUrl;
7574
- }
7575
- return `url(${url})`;
7576
- }
7577
- get replyCount() {
7578
- var _a;
7579
- return ((_a = this.message.submessages) === null || _a === void 0 ? void 0 : _a.length) || this.message.submessageCount || 0;
7580
- }
7523
+ //#endregion
7524
+ //#region Actions
7525
+ markAttachmentsLoaded() { this.isLoaded = true; this._loaded.next(); }
7526
+ saveEdit() { this._edited.next(this.editedMessage); }
7527
+ endEditing() { this._editEnded.next(); }
7528
+ delete() { this._deleted.next(); }
7529
+ report() { this._reported.next(); }
7530
+ like() { this._liked.next(); }
7531
+ unlike() { this._unliked.next(); }
7532
+ share() { this._shared.next(this.message); }
7533
+ select() { this._selected.next(); }
7534
+ selectUser() { this._userSelected.next(); }
7535
+ startEdit() { this._editStarted.next(); this.editedMessage = this.message.message; }
7536
+ selectUsername(user) { this._usernameSelected.next(user); this.selectUser(); }
7537
+ selectAvatar(user) { this._avatarSelected.next(user); this.selectUser(); }
7581
7538
  }
7582
7539
  CommentComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CommentComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
7583
- CommentComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CommentComponent, selector: "banta-comment", inputs: { maxLength: "maxLength", message: "message", customMenuItems: "customMenuItems", showReplyAction: "showReplyAction", permissions: "permissions", mine: "mine", editing: "editing", genericAvatarUrl: "genericAvatarUrl" }, outputs: { loaded: "loaded", userSelected: "userSelected", usernameSelected: "usernameSelected", avatarSelected: "avatarSelected", reported: "reported", liked: "liked", unliked: "unliked", selected: "selected", edited: "edited", deleted: "deleted", editStarted: "editStarted", editEnded: "editEnded", shared: "shared" }, host: { properties: { "class.new": "this.isNew", "class.highlighted": "this.isHighlighted", "class.visible": "this.visible", "attr.data-comment-id": "this.commentId" } }, ngImport: i0, template: "\r\n<mat-menu #pointItemMenu=\"matMenu\">\r\n <button mat-menu-item (click)=\"share()\">\r\n <mat-icon>share</mat-icon>\r\n Share\r\n </button>\r\n <button *ngIf=\"!mine\" mat-menu-item (click)=\"report()\">\r\n <mat-icon>warning</mat-icon>\r\n Report\r\n </button>\r\n <button *ngIf=\"mine\" [disabled]=\"!permissions?.canEdit\" mat-menu-item (click)=\"startEdit()\">\r\n <mat-icon>edit</mat-icon>\r\n Edit\r\n </button>\r\n <button *ngIf=\"mine\" [disabled]=\"!permissions?.canDelete\" mat-menu-item (click)=\"delete()\">\r\n <mat-icon>delete</mat-icon>\r\n Delete\r\n </button>\r\n\r\n <button *ngFor=\"let menuItem of customMenuItems\" mat-menu-item (click)=\"menuItem.action(message)\">\r\n <mat-icon>{{menuItem.icon}}</mat-icon>\r\n {{menuItem.label}}\r\n </button>\r\n\r\n</mat-menu>\r\n\r\n<div class=\"message-content\">\r\n <div class=\"user\">\r\n <div class=\"user-1\">\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 <div class=\"user-identity\">\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>\r\n <div class=\"user-2\">\r\n <span class=\"user-tag\" *ngIf=\"message.user.tag\">{{message.user.tag}}</span>\r\n <banta-timestamp [value]=\"message.sentAt\"></banta-timestamp>\r\n <span class=\"spacer\"></span>\r\n </div>\r\n </div>\r\n <div class=\"content\" *ngIf=\"!editing\">\r\n <span class=\"banta-message-content\" [innerHTML]=\"message.message | mentionLinker: message.mentionLinks | markdownToHtml\"></span>\r\n <banta-attachments \r\n [attachments]=\"message.attachments\"\r\n (loaded)=\"markAttachmentsLoaded()\"\r\n ></banta-attachments>\r\n <ul class=\"message-facts\">\r\n <li *ngIf=\"message.edits?.length > 0\">(Edited)</li>\r\n </ul>\r\n </div>\r\n <div class=\"content\" *ngIf=\"editing\" style=\"padding-bottom: 2em;\">\r\n <div>\r\n <mat-form-field floatLabel=\"always\" appearance=\"outline\" style=\"width: 100%;\">\r\n <mat-label>Edit Message</mat-label>\r\n <textarea matInput [(ngModel)]=\"editedMessage\" [maxlength]=\"maxLength\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n <button mat-raised-button (click)=\"saveEdit()\">Save</button> &nbsp;\r\n <button mat-button (click)=\"endEditing()\">Cancel</button>\r\n </div>\r\n\r\n\r\n <div class=\"actions\">\r\n <div class=\"spacer\"></div>\r\n <div class=\"counted-action\" *ngIf=\"showReplyAction\">\r\n <button mat-button [matTooltip]=\"replyCount > 0 ? 'Replies' : 'Reply'\" matTooltipPosition=\"below\" (click)=\"select()\">\r\n <mat-icon [inline]=\"true\">comment</mat-icon>\r\n <span class=\"count-indicator\">\r\n {{replyCount > 0 ? 'Replies' : 'Reply'}}\r\n {{replyCount > 0 ? '(' + replyCount + ')' : ''}}\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"counted-action\" [class.active]=\"message.userState?.liked\">\r\n <button \r\n *ngIf=\"message.transientState?.liking\"\r\n mat-icon-button \r\n [disabled]=\"true\" \r\n [matTooltip]=\"upvoting ? 'Please wait...' : message.userState?.liked ? 'Unlike' : 'Like'\" \r\n matTooltipPosition=\"below\" \r\n >\r\n <mat-spinner [diameter]=\"15\" style=\"margin-left: 1em;\"></mat-spinner>\r\n </button>\r\n <button \r\n *ngIf=\"!message.transientState?.liking\"\r\n mat-button \r\n [matTooltip]=\"permissions?.canLike ? upvoting ? 'Please wait...' : 'Like' : permissions?.canLikeErrorMessage\" \r\n matTooltipPosition=\"below\" \r\n (click)=\"message.userState?.liked ? unlike() : like()\" \r\n >\r\n <mat-icon [inline]=\"true\">thumb_up</mat-icon>\r\n <span class=\"count-indicator\" *ngIf=\"message.likes > 0\">\r\n {{message.likes}}\r\n </span>\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", styles: ["@keyframes comment-appear{0%{transform:translate(6em)}to{transform:translate(0)}}:host{display:flex;flex-direction:column;position:relative;padding:.5em;visibility:hidden}:host.new{visibility:visible;animation-name:comment-appear;animation-duration:.25s;animation-fill-mode:both}:host.highlighted{background:#00223a;outline:2px solid #003277}:host.visible{visibility:visible}:host:hover{background:#eee}:host .message-content .content{margin-left:60px;margin-right:.5em}:host .message-content .attachments-row{margin-top:15px;display:flex;gap:10px}:host .message-content .attachments-row img{border-radius:10px;width:300px;max-width:100%;max-height:20em;-o-object-fit:cover;object-fit:cover}:host.abbreviated .message-content .content{text-overflow:ellipsis;overflow-y:hidden}:host .actions{display:flex;padding-right:10px;margin-left:60px;align-items:center}:host .actions button{color:#666;flex-shrink:0}banta-timestamp{color:#666;font-size:10pt;flex-shrink:0;margin-left:1em;text-align:right}.user{position:relative;margin:1em 0 0;display:flex;align-items:center;flex-wrap:wrap}.user .user-1,.user .user-2{display:flex;flex-wrap:nowrap;align-items:center;min-width:0}.user .user-2{margin:1em 0}.user .user-identity{display:flex;flex-direction:column;min-width:0}.user .display-name,.user .username{z-index:1;position:relative;padding:0 0 0 1em;font-size:10pt;color:#000;margin:0 auto 0 0;display:block;width:-moz-fit-content;width:fit-content;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex-shrink:1;flex-grow:0;min-width:0}.user .display-name.username.username.username,.user .username.username.username.username{color:#666}.avatar{height:48px;width:48px;background-position:center;background-size:cover;background-color:#333;border-radius:100%;flex-shrink:0;flex-grow:0}.counted-action{display:flex;align-items:center}.counted-action.active button,.counted-action.active .count-indicator{color:#00a5ff}.counted-action button .count-indicator{margin-left:.5em}.count-indicator{font-size:9pt;padding:0 0 0 3px;color:#666}: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}.user-tag{text-transform:uppercase;font-size:12px;border:1px solid #b27373;background:#7a412b;color:#fff;padding:3px 5px;margin:0 .5em 0 1em;border-radius:3px}.spacer{flex-shrink:1;flex-grow:1}ul.message-facts{margin:0;padding:0;color:#666}ul.message-facts li{list-style-type:none;border-left:1px solid #666;font-size:10pt;padding-left:.5em;margin-left:.5em}ul.message-facts li{margin-top:.5em}ul.message-facts li:first-child{border-left:1px solid transparent;margin-left:0;padding-left:0}@media (max-width: 400px){.avatar{height:32px;width:32px}:host .actions{margin-left:0;margin-top:.5em}:host .message-content .content{margin-left:44px;margin-right:.5em}}:host-context(.banta-mobile) .avatar{height:32px;width:32px}:host-context(.banta-mobile) :host .actions{margin-left:0;margin-top:.5em}:host-context(.banta-mobile) :host .message-content .content{margin-left:44px;margin-right:.5em}.card-attachment a{display:flex;align-items:flex-start;gap:1em;width:100%;border:1px solid #666;border-radius:4px;padding:1em;box-sizing:border-box;background-color:#191919}.card-attachment a img{width:300px;aspect-ratio:16/9;-o-object-fit:cover;object-fit:cover;border-radius:10px}.card-attachment a h1{margin:0;font-size:30px}::ng-deep .banta-message-content img.emoji{height:1.5em;vertical-align:middle}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i7$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i7$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: TimestampComponent, selector: "banta-timestamp", inputs: ["value"] }, { kind: "component", type: BantaAttachmentsComponent, selector: "banta-attachments", inputs: ["attachments", "editing"], outputs: ["remove", "loaded"] }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "pipe", type: BantaMarkdownToHtmlPipe, name: "markdownToHtml" }, { kind: "pipe", type: BantaMentionLinkerPipe, name: "mentionLinker" }] });
7540
+ CommentComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CommentComponent, selector: "banta-comment", inputs: { message: "message", customMenuItems: "customMenuItems", showReplyAction: "showReplyAction", maxLength: "maxLength", permissions: "permissions", mine: "mine", editing: "editing", genericAvatarUrl: "genericAvatarUrl", readonly: "readonly" }, outputs: { liked: "liked", unliked: "unliked", selected: "selected", edited: "edited", deleted: "deleted", editStarted: "editStarted", editEnded: "editEnded", shared: "shared", userSelected: "userSelected", usernameSelected: "usernameSelected", avatarSelected: "avatarSelected", reported: "reported", loaded: "loaded" }, host: { properties: { "attr.data-comment-id": "this.commentId", "class.new": "this.isNew", "class.highlighted": "this.isHighlighted", "class.visible": "this.visible" } }, ngImport: i0, template: "\r\n<mat-menu #pointItemMenu=\"matMenu\">\r\n <button mat-menu-item (click)=\"share()\">\r\n <mat-icon>share</mat-icon>\r\n Share\r\n </button>\r\n <button *ngIf=\"!mine\" mat-menu-item (click)=\"report()\">\r\n <mat-icon>warning</mat-icon>\r\n Report\r\n </button>\r\n <button *ngIf=\"mine\" [disabled]=\"!permissions?.canEdit || readonly\" mat-menu-item (click)=\"startEdit()\">\r\n <mat-icon>edit</mat-icon>\r\n Edit\r\n </button>\r\n <button *ngIf=\"mine\" [disabled]=\"!permissions?.canDelete || readonly\" mat-menu-item (click)=\"delete()\">\r\n <mat-icon>delete</mat-icon>\r\n Delete\r\n </button>\r\n\r\n <button *ngFor=\"let menuItem of customMenuItems\" mat-menu-item (click)=\"menuItem.action(message)\">\r\n <mat-icon>{{menuItem.icon}}</mat-icon>\r\n {{menuItem.label}}\r\n </button>\r\n\r\n</mat-menu>\r\n\r\n<div class=\"message-content\">\r\n <div class=\"user\">\r\n <div class=\"user-1\">\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 <div class=\"user-identity\">\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>\r\n <div class=\"user-2\">\r\n <span class=\"user-tag\" *ngIf=\"message.user.tag\">{{message.user.tag}}</span>\r\n <banta-timestamp [value]=\"message.sentAt\"></banta-timestamp>\r\n <span class=\"spacer\"></span>\r\n </div>\r\n </div>\r\n <div class=\"content\" *ngIf=\"!editing\">\r\n <span class=\"banta-message-content\" [innerHTML]=\"message.message | mentionLinker: message.mentionLinks | markdownToHtml\"></span>\r\n <banta-attachments \r\n [attachments]=\"message.attachments\"\r\n (loaded)=\"markAttachmentsLoaded()\"\r\n ></banta-attachments>\r\n <ul class=\"message-facts\">\r\n <li *ngIf=\"message.edits?.length > 0\">(Edited)</li>\r\n </ul>\r\n </div>\r\n <div class=\"content\" *ngIf=\"editing\" style=\"padding-bottom: 2em;\">\r\n <div>\r\n <mat-form-field floatLabel=\"always\" appearance=\"outline\" style=\"width: 100%;\">\r\n <mat-label>Edit Message</mat-label>\r\n <textarea matInput [(ngModel)]=\"editedMessage\" [maxlength]=\"maxLength\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n <button mat-raised-button (click)=\"saveEdit()\">Save</button> &nbsp;\r\n <button mat-button (click)=\"endEditing()\">Cancel</button>\r\n </div>\r\n\r\n\r\n <div class=\"actions\">\r\n <div class=\"spacer\"></div>\r\n <div class=\"counted-action\" *ngIf=\"showReplyAction\">\r\n <button mat-button [matTooltip]=\"replyCount > 0 ? 'Replies' : 'Reply'\" matTooltipPosition=\"below\" (click)=\"select()\">\r\n <mat-icon [inline]=\"true\">comment</mat-icon>\r\n <span class=\"count-indicator\">\r\n {{replyCount > 0 ? 'Replies' : 'Reply'}}\r\n {{replyCount > 0 ? '(' + replyCount + ')' : ''}}\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"counted-action\" [class.active]=\"message.userState?.liked\">\r\n <button \r\n *ngIf=\"message.transientState?.liking\"\r\n mat-icon-button \r\n [disabled]=\"true\" \r\n [matTooltip]=\"upvoting ? 'Please wait...' : message.userState?.liked ? 'Unlike' : 'Like'\" \r\n matTooltipPosition=\"below\" \r\n >\r\n <mat-spinner [diameter]=\"15\" style=\"margin-left: 1em;\"></mat-spinner>\r\n </button>\r\n <button \r\n *ngIf=\"!message.transientState?.liking\"\r\n mat-button \r\n [disabled]=\"readonly\"\r\n [matTooltip]=\"permissions?.canLike ? upvoting ? 'Please wait...' : 'Like' : permissions?.canLikeErrorMessage\" \r\n matTooltipPosition=\"below\" \r\n (click)=\"message.userState?.liked ? unlike() : like()\" \r\n >\r\n <mat-icon [inline]=\"true\">thumb_up</mat-icon>\r\n <span class=\"count-indicator\" *ngIf=\"message.likes > 0\">\r\n {{message.likes}}\r\n </span>\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", styles: ["@keyframes comment-appear{0%{transform:translate(6em)}to{transform:translate(0)}}:host{display:flex;flex-direction:column;position:relative;padding:.5em;visibility:hidden}:host.new{visibility:visible;animation-name:comment-appear;animation-duration:.25s;animation-fill-mode:both}:host.highlighted{background:#00223a;outline:2px solid #003277}:host.visible{visibility:visible}:host:hover{background:#eee}:host .message-content .content{margin-left:60px;margin-right:.5em}:host .message-content .attachments-row{margin-top:15px;display:flex;gap:10px}:host .message-content .attachments-row img{border-radius:10px;width:300px;max-width:100%;max-height:20em;-o-object-fit:cover;object-fit:cover}:host.abbreviated .message-content .content{text-overflow:ellipsis;overflow-y:hidden}:host .actions{display:flex;padding-right:10px;margin-left:60px;align-items:center}:host .actions button{color:#666;flex-shrink:0}banta-timestamp{color:#666;font-size:10pt;flex-shrink:0;margin-left:1em;text-align:right}.user{position:relative;margin:1em 0 0;display:flex;align-items:center;flex-wrap:wrap}.user .user-1,.user .user-2{display:flex;flex-wrap:nowrap;align-items:center;min-width:0}.user .user-2{margin:1em 0}.user .user-identity{display:flex;flex-direction:column;min-width:0}.user .display-name,.user .username{z-index:1;position:relative;padding:0 0 0 1em;font-size:10pt;color:#000;margin:0 auto 0 0;display:block;width:-moz-fit-content;width:fit-content;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex-shrink:1;flex-grow:0;min-width:0}.user .display-name.username.username.username,.user .username.username.username.username{color:#666}.avatar{height:48px;width:48px;background-position:center;background-size:cover;background-color:#333;border-radius:100%;flex-shrink:0;flex-grow:0}.counted-action{display:flex;align-items:center}.counted-action.active button,.counted-action.active .count-indicator{color:#00a5ff}.counted-action button .count-indicator{margin-left:.5em}.count-indicator{font-size:9pt;padding:0 0 0 3px;color:#666}: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}.user-tag{text-transform:uppercase;font-size:12px;border:1px solid #b27373;background:#7a412b;color:#fff;padding:3px 5px;margin:0 .5em 0 1em;border-radius:3px}.spacer{flex-shrink:1;flex-grow:1}ul.message-facts{margin:0;padding:0;color:#666}ul.message-facts li{list-style-type:none;border-left:1px solid #666;font-size:10pt;padding-left:.5em;margin-left:.5em}ul.message-facts li{margin-top:.5em}ul.message-facts li:first-child{border-left:1px solid transparent;margin-left:0;padding-left:0}@media (max-width: 400px){.avatar{height:32px;width:32px}:host .actions{margin-left:0;margin-top:.5em}:host .message-content .content{margin-left:44px;margin-right:.5em}}:host-context(.banta-mobile) .avatar{height:32px;width:32px}:host-context(.banta-mobile) :host .actions{margin-left:0;margin-top:.5em}:host-context(.banta-mobile) :host .message-content .content{margin-left:44px;margin-right:.5em}.card-attachment a{display:flex;align-items:flex-start;gap:1em;width:100%;border:1px solid #666;border-radius:4px;padding:1em;box-sizing:border-box;background-color:#191919}.card-attachment a img{width:300px;aspect-ratio:16/9;-o-object-fit:cover;object-fit:cover;border-radius:10px}.card-attachment a h1{margin:0;font-size:30px}::ng-deep .banta-message-content img.emoji{height:1.5em;vertical-align:middle}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i7$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i7$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: TimestampComponent, selector: "banta-timestamp", inputs: ["value"] }, { kind: "component", type: BantaAttachmentsComponent, selector: "banta-attachments", inputs: ["attachments", "editing"], outputs: ["remove", "loaded"] }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "pipe", type: BantaMarkdownToHtmlPipe, name: "markdownToHtml" }, { kind: "pipe", type: BantaMentionLinkerPipe, name: "mentionLinker" }] });
7584
7541
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CommentComponent, decorators: [{
7585
7542
  type: Component,
7586
- args: [{ selector: 'banta-comment', template: "\r\n<mat-menu #pointItemMenu=\"matMenu\">\r\n <button mat-menu-item (click)=\"share()\">\r\n <mat-icon>share</mat-icon>\r\n Share\r\n </button>\r\n <button *ngIf=\"!mine\" mat-menu-item (click)=\"report()\">\r\n <mat-icon>warning</mat-icon>\r\n Report\r\n </button>\r\n <button *ngIf=\"mine\" [disabled]=\"!permissions?.canEdit\" mat-menu-item (click)=\"startEdit()\">\r\n <mat-icon>edit</mat-icon>\r\n Edit\r\n </button>\r\n <button *ngIf=\"mine\" [disabled]=\"!permissions?.canDelete\" mat-menu-item (click)=\"delete()\">\r\n <mat-icon>delete</mat-icon>\r\n Delete\r\n </button>\r\n\r\n <button *ngFor=\"let menuItem of customMenuItems\" mat-menu-item (click)=\"menuItem.action(message)\">\r\n <mat-icon>{{menuItem.icon}}</mat-icon>\r\n {{menuItem.label}}\r\n </button>\r\n\r\n</mat-menu>\r\n\r\n<div class=\"message-content\">\r\n <div class=\"user\">\r\n <div class=\"user-1\">\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 <div class=\"user-identity\">\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>\r\n <div class=\"user-2\">\r\n <span class=\"user-tag\" *ngIf=\"message.user.tag\">{{message.user.tag}}</span>\r\n <banta-timestamp [value]=\"message.sentAt\"></banta-timestamp>\r\n <span class=\"spacer\"></span>\r\n </div>\r\n </div>\r\n <div class=\"content\" *ngIf=\"!editing\">\r\n <span class=\"banta-message-content\" [innerHTML]=\"message.message | mentionLinker: message.mentionLinks | markdownToHtml\"></span>\r\n <banta-attachments \r\n [attachments]=\"message.attachments\"\r\n (loaded)=\"markAttachmentsLoaded()\"\r\n ></banta-attachments>\r\n <ul class=\"message-facts\">\r\n <li *ngIf=\"message.edits?.length > 0\">(Edited)</li>\r\n </ul>\r\n </div>\r\n <div class=\"content\" *ngIf=\"editing\" style=\"padding-bottom: 2em;\">\r\n <div>\r\n <mat-form-field floatLabel=\"always\" appearance=\"outline\" style=\"width: 100%;\">\r\n <mat-label>Edit Message</mat-label>\r\n <textarea matInput [(ngModel)]=\"editedMessage\" [maxlength]=\"maxLength\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n <button mat-raised-button (click)=\"saveEdit()\">Save</button> &nbsp;\r\n <button mat-button (click)=\"endEditing()\">Cancel</button>\r\n </div>\r\n\r\n\r\n <div class=\"actions\">\r\n <div class=\"spacer\"></div>\r\n <div class=\"counted-action\" *ngIf=\"showReplyAction\">\r\n <button mat-button [matTooltip]=\"replyCount > 0 ? 'Replies' : 'Reply'\" matTooltipPosition=\"below\" (click)=\"select()\">\r\n <mat-icon [inline]=\"true\">comment</mat-icon>\r\n <span class=\"count-indicator\">\r\n {{replyCount > 0 ? 'Replies' : 'Reply'}}\r\n {{replyCount > 0 ? '(' + replyCount + ')' : ''}}\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"counted-action\" [class.active]=\"message.userState?.liked\">\r\n <button \r\n *ngIf=\"message.transientState?.liking\"\r\n mat-icon-button \r\n [disabled]=\"true\" \r\n [matTooltip]=\"upvoting ? 'Please wait...' : message.userState?.liked ? 'Unlike' : 'Like'\" \r\n matTooltipPosition=\"below\" \r\n >\r\n <mat-spinner [diameter]=\"15\" style=\"margin-left: 1em;\"></mat-spinner>\r\n </button>\r\n <button \r\n *ngIf=\"!message.transientState?.liking\"\r\n mat-button \r\n [matTooltip]=\"permissions?.canLike ? upvoting ? 'Please wait...' : 'Like' : permissions?.canLikeErrorMessage\" \r\n matTooltipPosition=\"below\" \r\n (click)=\"message.userState?.liked ? unlike() : like()\" \r\n >\r\n <mat-icon [inline]=\"true\">thumb_up</mat-icon>\r\n <span class=\"count-indicator\" *ngIf=\"message.likes > 0\">\r\n {{message.likes}}\r\n </span>\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", styles: ["@keyframes comment-appear{0%{transform:translate(6em)}to{transform:translate(0)}}:host{display:flex;flex-direction:column;position:relative;padding:.5em;visibility:hidden}:host.new{visibility:visible;animation-name:comment-appear;animation-duration:.25s;animation-fill-mode:both}:host.highlighted{background:#00223a;outline:2px solid #003277}:host.visible{visibility:visible}:host:hover{background:#eee}:host .message-content .content{margin-left:60px;margin-right:.5em}:host .message-content .attachments-row{margin-top:15px;display:flex;gap:10px}:host .message-content .attachments-row img{border-radius:10px;width:300px;max-width:100%;max-height:20em;-o-object-fit:cover;object-fit:cover}:host.abbreviated .message-content .content{text-overflow:ellipsis;overflow-y:hidden}:host .actions{display:flex;padding-right:10px;margin-left:60px;align-items:center}:host .actions button{color:#666;flex-shrink:0}banta-timestamp{color:#666;font-size:10pt;flex-shrink:0;margin-left:1em;text-align:right}.user{position:relative;margin:1em 0 0;display:flex;align-items:center;flex-wrap:wrap}.user .user-1,.user .user-2{display:flex;flex-wrap:nowrap;align-items:center;min-width:0}.user .user-2{margin:1em 0}.user .user-identity{display:flex;flex-direction:column;min-width:0}.user .display-name,.user .username{z-index:1;position:relative;padding:0 0 0 1em;font-size:10pt;color:#000;margin:0 auto 0 0;display:block;width:-moz-fit-content;width:fit-content;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex-shrink:1;flex-grow:0;min-width:0}.user .display-name.username.username.username,.user .username.username.username.username{color:#666}.avatar{height:48px;width:48px;background-position:center;background-size:cover;background-color:#333;border-radius:100%;flex-shrink:0;flex-grow:0}.counted-action{display:flex;align-items:center}.counted-action.active button,.counted-action.active .count-indicator{color:#00a5ff}.counted-action button .count-indicator{margin-left:.5em}.count-indicator{font-size:9pt;padding:0 0 0 3px;color:#666}: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}.user-tag{text-transform:uppercase;font-size:12px;border:1px solid #b27373;background:#7a412b;color:#fff;padding:3px 5px;margin:0 .5em 0 1em;border-radius:3px}.spacer{flex-shrink:1;flex-grow:1}ul.message-facts{margin:0;padding:0;color:#666}ul.message-facts li{list-style-type:none;border-left:1px solid #666;font-size:10pt;padding-left:.5em;margin-left:.5em}ul.message-facts li{margin-top:.5em}ul.message-facts li:first-child{border-left:1px solid transparent;margin-left:0;padding-left:0}@media (max-width: 400px){.avatar{height:32px;width:32px}:host .actions{margin-left:0;margin-top:.5em}:host .message-content .content{margin-left:44px;margin-right:.5em}}:host-context(.banta-mobile) .avatar{height:32px;width:32px}:host-context(.banta-mobile) :host .actions{margin-left:0;margin-top:.5em}:host-context(.banta-mobile) :host .message-content .content{margin-left:44px;margin-right:.5em}.card-attachment a{display:flex;align-items:flex-start;gap:1em;width:100%;border:1px solid #666;border-radius:4px;padding:1em;box-sizing:border-box;background-color:#191919}.card-attachment a img{width:300px;aspect-ratio:16/9;-o-object-fit:cover;object-fit:cover;border-radius:10px}.card-attachment a h1{margin:0;font-size:30px}::ng-deep .banta-message-content img.emoji{height:1.5em;vertical-align:middle}\n"] }]
7587
- }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { maxLength: [{
7588
- type: Input
7589
- }], isNew: [{
7590
- type: HostBinding,
7591
- args: ['class.new']
7592
- }], isHighlighted: [{
7593
- type: HostBinding,
7594
- args: ['class.highlighted']
7595
- }], visible: [{
7596
- type: HostBinding,
7597
- args: ['class.visible']
7598
- }], message: [{
7543
+ args: [{ selector: 'banta-comment', template: "\r\n<mat-menu #pointItemMenu=\"matMenu\">\r\n <button mat-menu-item (click)=\"share()\">\r\n <mat-icon>share</mat-icon>\r\n Share\r\n </button>\r\n <button *ngIf=\"!mine\" mat-menu-item (click)=\"report()\">\r\n <mat-icon>warning</mat-icon>\r\n Report\r\n </button>\r\n <button *ngIf=\"mine\" [disabled]=\"!permissions?.canEdit || readonly\" mat-menu-item (click)=\"startEdit()\">\r\n <mat-icon>edit</mat-icon>\r\n Edit\r\n </button>\r\n <button *ngIf=\"mine\" [disabled]=\"!permissions?.canDelete || readonly\" mat-menu-item (click)=\"delete()\">\r\n <mat-icon>delete</mat-icon>\r\n Delete\r\n </button>\r\n\r\n <button *ngFor=\"let menuItem of customMenuItems\" mat-menu-item (click)=\"menuItem.action(message)\">\r\n <mat-icon>{{menuItem.icon}}</mat-icon>\r\n {{menuItem.label}}\r\n </button>\r\n\r\n</mat-menu>\r\n\r\n<div class=\"message-content\">\r\n <div class=\"user\">\r\n <div class=\"user-1\">\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 <div class=\"user-identity\">\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>\r\n <div class=\"user-2\">\r\n <span class=\"user-tag\" *ngIf=\"message.user.tag\">{{message.user.tag}}</span>\r\n <banta-timestamp [value]=\"message.sentAt\"></banta-timestamp>\r\n <span class=\"spacer\"></span>\r\n </div>\r\n </div>\r\n <div class=\"content\" *ngIf=\"!editing\">\r\n <span class=\"banta-message-content\" [innerHTML]=\"message.message | mentionLinker: message.mentionLinks | markdownToHtml\"></span>\r\n <banta-attachments \r\n [attachments]=\"message.attachments\"\r\n (loaded)=\"markAttachmentsLoaded()\"\r\n ></banta-attachments>\r\n <ul class=\"message-facts\">\r\n <li *ngIf=\"message.edits?.length > 0\">(Edited)</li>\r\n </ul>\r\n </div>\r\n <div class=\"content\" *ngIf=\"editing\" style=\"padding-bottom: 2em;\">\r\n <div>\r\n <mat-form-field floatLabel=\"always\" appearance=\"outline\" style=\"width: 100%;\">\r\n <mat-label>Edit Message</mat-label>\r\n <textarea matInput [(ngModel)]=\"editedMessage\" [maxlength]=\"maxLength\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n <button mat-raised-button (click)=\"saveEdit()\">Save</button> &nbsp;\r\n <button mat-button (click)=\"endEditing()\">Cancel</button>\r\n </div>\r\n\r\n\r\n <div class=\"actions\">\r\n <div class=\"spacer\"></div>\r\n <div class=\"counted-action\" *ngIf=\"showReplyAction\">\r\n <button mat-button [matTooltip]=\"replyCount > 0 ? 'Replies' : 'Reply'\" matTooltipPosition=\"below\" (click)=\"select()\">\r\n <mat-icon [inline]=\"true\">comment</mat-icon>\r\n <span class=\"count-indicator\">\r\n {{replyCount > 0 ? 'Replies' : 'Reply'}}\r\n {{replyCount > 0 ? '(' + replyCount + ')' : ''}}\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"counted-action\" [class.active]=\"message.userState?.liked\">\r\n <button \r\n *ngIf=\"message.transientState?.liking\"\r\n mat-icon-button \r\n [disabled]=\"true\" \r\n [matTooltip]=\"upvoting ? 'Please wait...' : message.userState?.liked ? 'Unlike' : 'Like'\" \r\n matTooltipPosition=\"below\" \r\n >\r\n <mat-spinner [diameter]=\"15\" style=\"margin-left: 1em;\"></mat-spinner>\r\n </button>\r\n <button \r\n *ngIf=\"!message.transientState?.liking\"\r\n mat-button \r\n [disabled]=\"readonly\"\r\n [matTooltip]=\"permissions?.canLike ? upvoting ? 'Please wait...' : 'Like' : permissions?.canLikeErrorMessage\" \r\n matTooltipPosition=\"below\" \r\n (click)=\"message.userState?.liked ? unlike() : like()\" \r\n >\r\n <mat-icon [inline]=\"true\">thumb_up</mat-icon>\r\n <span class=\"count-indicator\" *ngIf=\"message.likes > 0\">\r\n {{message.likes}}\r\n </span>\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", styles: ["@keyframes comment-appear{0%{transform:translate(6em)}to{transform:translate(0)}}:host{display:flex;flex-direction:column;position:relative;padding:.5em;visibility:hidden}:host.new{visibility:visible;animation-name:comment-appear;animation-duration:.25s;animation-fill-mode:both}:host.highlighted{background:#00223a;outline:2px solid #003277}:host.visible{visibility:visible}:host:hover{background:#eee}:host .message-content .content{margin-left:60px;margin-right:.5em}:host .message-content .attachments-row{margin-top:15px;display:flex;gap:10px}:host .message-content .attachments-row img{border-radius:10px;width:300px;max-width:100%;max-height:20em;-o-object-fit:cover;object-fit:cover}:host.abbreviated .message-content .content{text-overflow:ellipsis;overflow-y:hidden}:host .actions{display:flex;padding-right:10px;margin-left:60px;align-items:center}:host .actions button{color:#666;flex-shrink:0}banta-timestamp{color:#666;font-size:10pt;flex-shrink:0;margin-left:1em;text-align:right}.user{position:relative;margin:1em 0 0;display:flex;align-items:center;flex-wrap:wrap}.user .user-1,.user .user-2{display:flex;flex-wrap:nowrap;align-items:center;min-width:0}.user .user-2{margin:1em 0}.user .user-identity{display:flex;flex-direction:column;min-width:0}.user .display-name,.user .username{z-index:1;position:relative;padding:0 0 0 1em;font-size:10pt;color:#000;margin:0 auto 0 0;display:block;width:-moz-fit-content;width:fit-content;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex-shrink:1;flex-grow:0;min-width:0}.user .display-name.username.username.username,.user .username.username.username.username{color:#666}.avatar{height:48px;width:48px;background-position:center;background-size:cover;background-color:#333;border-radius:100%;flex-shrink:0;flex-grow:0}.counted-action{display:flex;align-items:center}.counted-action.active button,.counted-action.active .count-indicator{color:#00a5ff}.counted-action button .count-indicator{margin-left:.5em}.count-indicator{font-size:9pt;padding:0 0 0 3px;color:#666}: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}.user-tag{text-transform:uppercase;font-size:12px;border:1px solid #b27373;background:#7a412b;color:#fff;padding:3px 5px;margin:0 .5em 0 1em;border-radius:3px}.spacer{flex-shrink:1;flex-grow:1}ul.message-facts{margin:0;padding:0;color:#666}ul.message-facts li{list-style-type:none;border-left:1px solid #666;font-size:10pt;padding-left:.5em;margin-left:.5em}ul.message-facts li{margin-top:.5em}ul.message-facts li:first-child{border-left:1px solid transparent;margin-left:0;padding-left:0}@media (max-width: 400px){.avatar{height:32px;width:32px}:host .actions{margin-left:0;margin-top:.5em}:host .message-content .content{margin-left:44px;margin-right:.5em}}:host-context(.banta-mobile) .avatar{height:32px;width:32px}:host-context(.banta-mobile) :host .actions{margin-left:0;margin-top:.5em}:host-context(.banta-mobile) :host .message-content .content{margin-left:44px;margin-right:.5em}.card-attachment a{display:flex;align-items:flex-start;gap:1em;width:100%;border:1px solid #666;border-radius:4px;padding:1em;box-sizing:border-box;background-color:#191919}.card-attachment a img{width:300px;aspect-ratio:16/9;-o-object-fit:cover;object-fit:cover;border-radius:10px}.card-attachment a h1{margin:0;font-size:30px}::ng-deep .banta-message-content img.emoji{height:1.5em;vertical-align:middle}\n"] }]
7544
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { message: [{
7599
7545
  type: Input
7600
7546
  }], customMenuItems: [{
7601
7547
  type: Input
7602
7548
  }], showReplyAction: [{
7603
7549
  type: Input
7604
- }], loaded: [{
7605
- type: Output
7606
- }], userSelected: [{
7607
- type: Output
7608
- }], usernameSelected: [{
7609
- type: Output
7610
- }], avatarSelected: [{
7611
- type: Output
7612
- }], reported: [{
7613
- type: Output
7550
+ }], maxLength: [{
7551
+ type: Input
7614
7552
  }], permissions: [{
7615
7553
  type: Input
7616
7554
  }], mine: [{
7617
7555
  type: Input
7618
7556
  }], editing: [{
7619
7557
  type: Input
7558
+ }], genericAvatarUrl: [{
7559
+ type: Input
7560
+ }], readonly: [{
7561
+ type: Input
7620
7562
  }], liked: [{
7621
7563
  type: Output
7622
7564
  }], unliked: [{
@@ -7633,18 +7575,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
7633
7575
  type: Output
7634
7576
  }], shared: [{
7635
7577
  type: Output
7636
- }], genericAvatarUrl: [{
7637
- type: Input
7578
+ }], userSelected: [{
7579
+ type: Output
7580
+ }], usernameSelected: [{
7581
+ type: Output
7582
+ }], avatarSelected: [{
7583
+ type: Output
7584
+ }], reported: [{
7585
+ type: Output
7586
+ }], loaded: [{
7587
+ type: Output
7638
7588
  }], commentId: [{
7639
7589
  type: HostBinding,
7640
7590
  args: ['attr.data-comment-id']
7591
+ }], isNew: [{
7592
+ type: HostBinding,
7593
+ args: ['class.new']
7594
+ }], isHighlighted: [{
7595
+ type: HostBinding,
7596
+ args: ['class.highlighted']
7597
+ }], visible: [{
7598
+ type: HostBinding,
7599
+ args: ['class.visible']
7641
7600
  }] } });
7642
7601
 
7643
7602
  class CommentViewComponent {
7644
7603
  constructor(backend, elementRef) {
7645
7604
  this.backend = backend;
7646
7605
  this.elementRef = elementRef;
7606
+ //#endregion
7607
+ //#region Fields
7647
7608
  this._sourceSubs = new Subscription();
7609
+ this.menuMessage = null;
7610
+ this.messages = [];
7611
+ this.customSortEnabled = false;
7612
+ this.sourceLoaded = new Promise(r => this.markSourceLoaded = r);
7613
+ this.isViewingMore = false;
7614
+ this.isLoadingMore = false;
7615
+ this.hasMore = false;
7616
+ this.newMessages = [];
7617
+ this.olderMessages = [];
7618
+ //#endregion
7619
+ //#region Inputs
7620
+ this.maxMessages = 2000;
7621
+ this.maxVisibleMessages = 200;
7622
+ this.newestLast = false;
7623
+ this.holdNewMessages = false;
7624
+ this.showEmptyState = true;
7625
+ this.allowReplies = true;
7626
+ this.enableHoldOnClick = false;
7627
+ this.enableHoldOnScroll = true;
7628
+ this.customMenuItems = [];
7629
+ //#endregion
7630
+ //#region Outputs
7648
7631
  this._selected = new Subject();
7649
7632
  this._liked = new Subject();
7650
7633
  this._unliked = new Subject();
@@ -7655,30 +7638,25 @@ class CommentViewComponent {
7655
7638
  this._shared = new Subject();
7656
7639
  this._deleted = new Subject();
7657
7640
  this._messageEdited = new Subject();
7658
- this.showEmptyState = true;
7659
- this.allowReplies = true;
7660
- this.enableHoldOnClick = false;
7661
- this.enableHoldOnScroll = true;
7662
- this.customMenuItems = [];
7663
- this.menuMessage = null;
7664
- this.messages = [];
7665
- this.customSortEnabled = false;
7666
- this.sourceLoaded = new Promise(r => this.markSourceLoaded = r);
7667
- this.maxMessages = 2000;
7668
- this.maxVisibleMessages = 200;
7669
- this.newestLast = false;
7670
- this.holdNewMessages = false;
7671
- this.isViewingMore = false;
7672
- this.isLoadingMore = false;
7673
- this.hasMore = false;
7674
- this.newMessages = [];
7675
- this.olderMessages = [];
7676
- this.sortOrderChanged = new Subject();
7677
- this.filterModeChanged = new Subject();
7678
- }
7679
- get comments() {
7680
- return Array.from(this.commentsQuery);
7641
+ this._sortOrderChanged = new Subject();
7642
+ this._filterModeChanged = new Subject();
7643
+ this.userSelected = this._userSelected.asObservable();
7644
+ this.reported = this._reported.asObservable();
7645
+ this.liked = this._liked.asObservable();
7646
+ this.unliked = this._unliked.asObservable();
7647
+ this.usernameSelected = this._usernameSelected.asObservable();
7648
+ this.avatarSelected = this._avatarSelected.asObservable();
7649
+ this.shared = this._shared.asObservable();
7650
+ this.deleted = this._deleted.asObservable();
7651
+ this.selected = this._selected.asObservable();
7652
+ this.messageEdited = this._messageEdited.asObservable();
7653
+ this.sortOrderChanged = this._sortOrderChanged.asObservable();
7654
+ this.filterModeChanged = this._filterModeChanged.asObservable();
7681
7655
  }
7656
+ get source() { return this._source; }
7657
+ set source(value) { this.setSource(value); }
7658
+ get comments() { return Array.from(this.commentsQuery); }
7659
+ //#endregion
7682
7660
  /**
7683
7661
  * Returns true if this message can be found within one of the message buffers (older, current, newer)
7684
7662
  * @param message
@@ -7773,26 +7751,9 @@ class CommentViewComponent {
7773
7751
  throw new Error(`You must pass a valid ChatMessage`);
7774
7752
  return this.comments.find(x => { var _a; return ((_a = x.message) === null || _a === void 0 ? void 0 : _a.id) === message.id; });
7775
7753
  }
7776
- get selected() {
7777
- return this._selected;
7778
- }
7779
- get messageEdited() {
7780
- return this._messageEdited.asObservable();
7781
- }
7782
7754
  saveEdit(message, newMessage) {
7783
7755
  this._messageEdited.next({ message, newMessage });
7784
7756
  }
7785
- get userSelected() { return this._userSelected; }
7786
- get reported() { return this._reported; }
7787
- get liked() { return this._liked; }
7788
- get unliked() { return this._unliked; }
7789
- get usernameSelected() { return this._usernameSelected; }
7790
- get avatarSelected() { return this._avatarSelected; }
7791
- get shared() { return this._shared; }
7792
- get deleted() { return this._deleted; }
7793
- get source() {
7794
- return this._source;
7795
- }
7796
7757
  likeMessage(message) {
7797
7758
  this._liked.next(message);
7798
7759
  }
@@ -7824,7 +7785,7 @@ class CommentViewComponent {
7824
7785
  deleteMessage(message) {
7825
7786
  this._deleted.next(message);
7826
7787
  }
7827
- set source(value) {
7788
+ setSource(value) {
7828
7789
  this.customSortEnabled = (value === null || value === void 0 ? void 0 : value.sortOrder) !== CommentsOrder.NEWEST;
7829
7790
  this.newMessages = [];
7830
7791
  this.olderMessages = [];
@@ -7864,9 +7825,9 @@ class CommentViewComponent {
7864
7825
  let naturalOrder = CommentsOrder.NEWEST;
7865
7826
  if (this.source && (this.source.sortOrder !== naturalOrder || this.source.filterMode !== FilterMode.ALL)) {
7866
7827
  if (this.source.sortOrder !== naturalOrder)
7867
- this.sortOrderChanged.next(naturalOrder);
7828
+ this._sortOrderChanged.next(naturalOrder);
7868
7829
  if (this.source.filterMode !== FilterMode.ALL)
7869
- this.filterModeChanged.next(FilterMode.ALL);
7830
+ this._filterModeChanged.next(FilterMode.ALL);
7870
7831
  return;
7871
7832
  }
7872
7833
  this.isViewingMore = false;
@@ -8046,11 +8007,21 @@ class CommentViewComponent {
8046
8007
  }
8047
8008
  }
8048
8009
  CommentViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CommentViewComponent, deps: [{ token: ChatBackendBase }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
8049
- CommentViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CommentViewComponent, selector: "banta-comment-view", inputs: { showEmptyState: "showEmptyState", allowReplies: "allowReplies", enableHoldOnClick: "enableHoldOnClick", enableHoldOnScroll: "enableHoldOnScroll", customMenuItems: "customMenuItems", fixedHeight: "fixedHeight", selectedMessage: "selectedMessage", source: "source", genericAvatarUrl: "genericAvatarUrl", maxMessages: "maxMessages", maxVisibleMessages: "maxVisibleMessages", newestLast: "newestLast", holdNewMessages: "holdNewMessages" }, outputs: { selected: "selected", messageEdited: "messageEdited", userSelected: "userSelected", reported: "reported", liked: "liked", unliked: "unliked", usernameSelected: "usernameSelected", avatarSelected: "avatarSelected", shared: "shared", deleted: "deleted", sortOrderChanged: "sortOrderChanged", filterModeChanged: "filterModeChanged" }, host: { properties: { "class.fixed-height": "this.fixedHeight" } }, viewQueries: [{ propertyName: "messageContainer", first: true, predicate: ["messageContainer"], descendants: true }, { propertyName: "commentsQuery", predicate: CommentComponent, descendants: true }], ngImport: i0, template: "<div class=\"message-container\" #messageContainer>\r\n <ng-content select=\"[data-before]\"></ng-content>\r\n\r\n <div class=\"top-sticky\">\r\n <a *ngIf=\"!newestLast\" mat-button class=\"nav\" [class.visible]=\"shouldShowNewMessageIndicator\" href=\"javascript:;\" (click)=\"showNew($event)\">\r\n <mat-icon>file_upload</mat-icon>\r\n <ng-container *ngIf=\"newMessages.length >= 1\">\r\n New ({{newMessages.length}})\r\n </ng-container>\r\n <ng-container *ngIf=\"newMessages.length == 0\">\r\n Newest\r\n </ng-container>\r\n </a>\r\n </div>\r\n <a mat-button class=\"nav\" [class.visible]=\"newestLast && hasMore && !isLoadingMore\" href=\"javascript:;\" (click)=\"showMore()\">Show earlier</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 <ng-container *ngFor=\"let message of messages; trackBy: messageIdentity\">\r\n <banta-comment\r\n *ngIf=\"!message.hidden\"\r\n class=\"abbreviated\"\r\n \r\n [customMenuItems]=\"customMenuItems\"\r\n [message]=\"message\"\r\n [mine]=\"currentUser?.id === message.user?.id\"\r\n [permissions]=\"source?.permissions\"\r\n [showReplyAction]=\"allowReplies\"\r\n [editing]=\"message.transientState.editing\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (click)=\"enableHoldOnClick ? (holdNewMessages = true) : undefined\"\r\n (editStarted)=\"startEditing(message)\"\r\n (deleted)=\"deleteMessage(message)\"\r\n (editEnded)=\"message.transientState.editing = false\"\r\n (edited)=\"saveEdit(message, $event)\"\r\n (userSelected)=\"selectMessageUser(message)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (liked)=\"likeMessage(message)\"\r\n (unliked)=\"unlikeMessage(message)\"\r\n (reported)=\"reportMessage(message)\"\r\n (selected)=\"selectMessage(message)\"\r\n (shared)=\"sharedMessage($event)\"\r\n ></banta-comment>\r\n <div class=\"inline-replies-container\" *ngIf=\"selectedMessage === message\">\r\n <ng-content select=\".inline-replies\"></ng-content>\r\n </div>\r\n </ng-container>\r\n\r\n <div class=\"nav-point bottom-sticky\">\r\n <a *ngIf=\"newestLast\" mat-button class=\"nav\" [class.visible]=\"shouldShowNewMessageIndicator\" href=\"javascript:;\" (click)=\"showNew($event)\">\r\n <mat-icon>file_download</mat-icon>\r\n <ng-container *ngIf=\"newMessages.length >= 1\">\r\n New ({{newMessages.length}})\r\n </ng-container>\r\n <ng-container *ngIf=\"newMessages.length == 0\">\r\n Newest\r\n </ng-container>\r\n </a>\r\n </div>\r\n <a mat-button class=\"nav\" [class.visible]=\"!newestLast && 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]):not(.inline-replies)\"></ng-content>\r\n</div>\r\n", styles: [":host{flex-grow:1;display:flex;flex-direction:column;opacity:1;transition:.2s opacity ease-in}.message-container{flex-grow:1;color:#111;background:white;padding:.5em 1em 3em .5em;opacity:1;transition:.5s opacity ease-in-out;position:relative}.message-container.no-scroll{height:auto;overflow-y:visible}.message-container.faded{opacity:.25}.message-container .overlay{position:absolute;inset:0;z-index:10}:host.fixed-height .message-container{overflow-y:auto}:host-context(.mat-dark-theme) .message-container{color:#fff;background:#111111}.empty-state{text-align:center;margin:3em;color:#666}:host-context(.mat-dark-theme) .empty-state{color:#666}a.nav{position:absolute;right:.5em;z-index:10;text-align:center;opacity:0;transition:.4s opacity ease-in-out;pointer-events:none;border-radius:2em;background:#222}a.nav.visible{opacity:1;pointer-events:initial}.top-sticky{position:sticky;top:.5em;z-index:10}.bottom-sticky{position:sticky;bottom:3em;z-index:10}.loading-more{padding:2em;text-align:center;margin:0 auto;width:-moz-fit-content;width:fit-content}@media (max-width: 400px){.message-container{padding:0 0 3em}}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: CommentComponent, selector: "banta-comment", inputs: ["maxLength", "message", "customMenuItems", "showReplyAction", "permissions", "mine", "editing", "genericAvatarUrl"], outputs: ["loaded", "userSelected", "usernameSelected", "avatarSelected", "reported", "liked", "unliked", "selected", "edited", "deleted", "editStarted", "editEnded", "shared"] }] });
8010
+ CommentViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CommentViewComponent, selector: "banta-comment-view", inputs: { source: "source", maxMessages: "maxMessages", maxVisibleMessages: "maxVisibleMessages", newestLast: "newestLast", holdNewMessages: "holdNewMessages", showEmptyState: "showEmptyState", allowReplies: "allowReplies", enableHoldOnClick: "enableHoldOnClick", enableHoldOnScroll: "enableHoldOnScroll", customMenuItems: "customMenuItems", fixedHeight: "fixedHeight", selectedMessage: "selectedMessage", genericAvatarUrl: "genericAvatarUrl" }, outputs: { userSelected: "userSelected", reported: "reported", liked: "liked", unliked: "unliked", usernameSelected: "usernameSelected", avatarSelected: "avatarSelected", shared: "shared", deleted: "deleted", selected: "selected", messageEdited: "messageEdited", sortOrderChanged: "sortOrderChanged", filterModeChanged: "filterModeChanged" }, host: { properties: { "class.fixed-height": "this.fixedHeight" } }, viewQueries: [{ propertyName: "messageContainer", first: true, predicate: ["messageContainer"], descendants: true }, { propertyName: "commentsQuery", predicate: CommentComponent, descendants: true }], ngImport: i0, template: "<div class=\"message-container\" #messageContainer>\r\n <ng-content select=\"[data-before]\"></ng-content>\r\n\r\n <div class=\"top-sticky\">\r\n <a *ngIf=\"!newestLast\" mat-button class=\"nav\" [class.visible]=\"shouldShowNewMessageIndicator\" href=\"javascript:;\" (click)=\"showNew($event)\">\r\n <mat-icon>file_upload</mat-icon>\r\n <ng-container *ngIf=\"newMessages.length >= 1\">\r\n New ({{newMessages.length}})\r\n </ng-container>\r\n <ng-container *ngIf=\"newMessages.length == 0\">\r\n Newest\r\n </ng-container>\r\n </a>\r\n </div>\r\n <a mat-button class=\"nav\" [class.visible]=\"newestLast && hasMore && !isLoadingMore\" href=\"javascript:;\" (click)=\"showMore()\">Show earlier</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 <ng-container *ngFor=\"let message of messages; trackBy: messageIdentity\">\r\n <banta-comment\r\n *ngIf=\"!message.hidden\"\r\n class=\"abbreviated\"\r\n \r\n [customMenuItems]=\"customMenuItems\"\r\n [message]=\"message\"\r\n [mine]=\"currentUser?.id === message.user?.id\"\r\n [permissions]=\"source?.permissions\"\r\n [showReplyAction]=\"allowReplies\"\r\n [editing]=\"message.transientState.editing\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n [readonly]=\"source?.readonly\"\r\n (click)=\"enableHoldOnClick ? (holdNewMessages = true) : undefined\"\r\n (editStarted)=\"startEditing(message)\"\r\n (deleted)=\"deleteMessage(message)\"\r\n (editEnded)=\"message.transientState.editing = false\"\r\n (edited)=\"saveEdit(message, $event)\"\r\n (userSelected)=\"selectMessageUser(message)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (liked)=\"likeMessage(message)\"\r\n (unliked)=\"unlikeMessage(message)\"\r\n (reported)=\"reportMessage(message)\"\r\n (selected)=\"selectMessage(message)\"\r\n (shared)=\"sharedMessage($event)\"\r\n ></banta-comment>\r\n <div class=\"inline-replies-container\" *ngIf=\"selectedMessage === message\">\r\n <ng-content select=\".inline-replies\"></ng-content>\r\n </div>\r\n </ng-container>\r\n\r\n <div class=\"nav-point bottom-sticky\">\r\n <a *ngIf=\"newestLast\" mat-button class=\"nav\" [class.visible]=\"shouldShowNewMessageIndicator\" href=\"javascript:;\" (click)=\"showNew($event)\">\r\n <mat-icon>file_download</mat-icon>\r\n <ng-container *ngIf=\"newMessages.length >= 1\">\r\n New ({{newMessages.length}})\r\n </ng-container>\r\n <ng-container *ngIf=\"newMessages.length == 0\">\r\n Newest\r\n </ng-container>\r\n </a>\r\n </div>\r\n <a mat-button class=\"nav\" [class.visible]=\"!newestLast && 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]):not(.inline-replies)\"></ng-content>\r\n</div>\r\n", styles: [":host{flex-grow:1;display:flex;flex-direction:column;opacity:1;transition:.2s opacity ease-in}.message-container{flex-grow:1;color:#111;background:white;padding:.5em 1em 3em .5em;opacity:1;transition:.5s opacity ease-in-out;position:relative}.message-container.no-scroll{height:auto;overflow-y:visible}.message-container.faded{opacity:.25}.message-container .overlay{position:absolute;inset:0;z-index:10}:host.fixed-height .message-container{overflow-y:auto}:host-context(.mat-dark-theme) .message-container{color:#fff;background:#111111}.empty-state{text-align:center;margin:3em;color:#666}:host-context(.mat-dark-theme) .empty-state{color:#666}a.nav{position:absolute;right:.5em;z-index:10;text-align:center;opacity:0;transition:.4s opacity ease-in-out;pointer-events:none;border-radius:2em;background:#222}a.nav.visible{opacity:1;pointer-events:initial}.top-sticky{position:sticky;top:.5em;z-index:10}.bottom-sticky{position:sticky;bottom:3em;z-index:10}.loading-more{padding:2em;text-align:center;margin:0 auto;width:-moz-fit-content;width:fit-content}@media (max-width: 400px){.message-container{padding:0 0 3em}}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: CommentComponent, selector: "banta-comment", inputs: ["message", "customMenuItems", "showReplyAction", "maxLength", "permissions", "mine", "editing", "genericAvatarUrl", "readonly"], outputs: ["liked", "unliked", "selected", "edited", "deleted", "editStarted", "editEnded", "shared", "userSelected", "usernameSelected", "avatarSelected", "reported", "loaded"] }] });
8050
8011
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CommentViewComponent, decorators: [{
8051
8012
  type: Component,
8052
- args: [{ selector: 'banta-comment-view', template: "<div class=\"message-container\" #messageContainer>\r\n <ng-content select=\"[data-before]\"></ng-content>\r\n\r\n <div class=\"top-sticky\">\r\n <a *ngIf=\"!newestLast\" mat-button class=\"nav\" [class.visible]=\"shouldShowNewMessageIndicator\" href=\"javascript:;\" (click)=\"showNew($event)\">\r\n <mat-icon>file_upload</mat-icon>\r\n <ng-container *ngIf=\"newMessages.length >= 1\">\r\n New ({{newMessages.length}})\r\n </ng-container>\r\n <ng-container *ngIf=\"newMessages.length == 0\">\r\n Newest\r\n </ng-container>\r\n </a>\r\n </div>\r\n <a mat-button class=\"nav\" [class.visible]=\"newestLast && hasMore && !isLoadingMore\" href=\"javascript:;\" (click)=\"showMore()\">Show earlier</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 <ng-container *ngFor=\"let message of messages; trackBy: messageIdentity\">\r\n <banta-comment\r\n *ngIf=\"!message.hidden\"\r\n class=\"abbreviated\"\r\n \r\n [customMenuItems]=\"customMenuItems\"\r\n [message]=\"message\"\r\n [mine]=\"currentUser?.id === message.user?.id\"\r\n [permissions]=\"source?.permissions\"\r\n [showReplyAction]=\"allowReplies\"\r\n [editing]=\"message.transientState.editing\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (click)=\"enableHoldOnClick ? (holdNewMessages = true) : undefined\"\r\n (editStarted)=\"startEditing(message)\"\r\n (deleted)=\"deleteMessage(message)\"\r\n (editEnded)=\"message.transientState.editing = false\"\r\n (edited)=\"saveEdit(message, $event)\"\r\n (userSelected)=\"selectMessageUser(message)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (liked)=\"likeMessage(message)\"\r\n (unliked)=\"unlikeMessage(message)\"\r\n (reported)=\"reportMessage(message)\"\r\n (selected)=\"selectMessage(message)\"\r\n (shared)=\"sharedMessage($event)\"\r\n ></banta-comment>\r\n <div class=\"inline-replies-container\" *ngIf=\"selectedMessage === message\">\r\n <ng-content select=\".inline-replies\"></ng-content>\r\n </div>\r\n </ng-container>\r\n\r\n <div class=\"nav-point bottom-sticky\">\r\n <a *ngIf=\"newestLast\" mat-button class=\"nav\" [class.visible]=\"shouldShowNewMessageIndicator\" href=\"javascript:;\" (click)=\"showNew($event)\">\r\n <mat-icon>file_download</mat-icon>\r\n <ng-container *ngIf=\"newMessages.length >= 1\">\r\n New ({{newMessages.length}})\r\n </ng-container>\r\n <ng-container *ngIf=\"newMessages.length == 0\">\r\n Newest\r\n </ng-container>\r\n </a>\r\n </div>\r\n <a mat-button class=\"nav\" [class.visible]=\"!newestLast && 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]):not(.inline-replies)\"></ng-content>\r\n</div>\r\n", styles: [":host{flex-grow:1;display:flex;flex-direction:column;opacity:1;transition:.2s opacity ease-in}.message-container{flex-grow:1;color:#111;background:white;padding:.5em 1em 3em .5em;opacity:1;transition:.5s opacity ease-in-out;position:relative}.message-container.no-scroll{height:auto;overflow-y:visible}.message-container.faded{opacity:.25}.message-container .overlay{position:absolute;inset:0;z-index:10}:host.fixed-height .message-container{overflow-y:auto}:host-context(.mat-dark-theme) .message-container{color:#fff;background:#111111}.empty-state{text-align:center;margin:3em;color:#666}:host-context(.mat-dark-theme) .empty-state{color:#666}a.nav{position:absolute;right:.5em;z-index:10;text-align:center;opacity:0;transition:.4s opacity ease-in-out;pointer-events:none;border-radius:2em;background:#222}a.nav.visible{opacity:1;pointer-events:initial}.top-sticky{position:sticky;top:.5em;z-index:10}.bottom-sticky{position:sticky;bottom:3em;z-index:10}.loading-more{padding:2em;text-align:center;margin:0 auto;width:-moz-fit-content;width:fit-content}@media (max-width: 400px){.message-container{padding:0 0 3em}}\n"] }]
8053
- }], ctorParameters: function () { return [{ type: ChatBackendBase }, { type: i0.ElementRef }]; }, propDecorators: { showEmptyState: [{
8013
+ args: [{ selector: 'banta-comment-view', template: "<div class=\"message-container\" #messageContainer>\r\n <ng-content select=\"[data-before]\"></ng-content>\r\n\r\n <div class=\"top-sticky\">\r\n <a *ngIf=\"!newestLast\" mat-button class=\"nav\" [class.visible]=\"shouldShowNewMessageIndicator\" href=\"javascript:;\" (click)=\"showNew($event)\">\r\n <mat-icon>file_upload</mat-icon>\r\n <ng-container *ngIf=\"newMessages.length >= 1\">\r\n New ({{newMessages.length}})\r\n </ng-container>\r\n <ng-container *ngIf=\"newMessages.length == 0\">\r\n Newest\r\n </ng-container>\r\n </a>\r\n </div>\r\n <a mat-button class=\"nav\" [class.visible]=\"newestLast && hasMore && !isLoadingMore\" href=\"javascript:;\" (click)=\"showMore()\">Show earlier</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 <ng-container *ngFor=\"let message of messages; trackBy: messageIdentity\">\r\n <banta-comment\r\n *ngIf=\"!message.hidden\"\r\n class=\"abbreviated\"\r\n \r\n [customMenuItems]=\"customMenuItems\"\r\n [message]=\"message\"\r\n [mine]=\"currentUser?.id === message.user?.id\"\r\n [permissions]=\"source?.permissions\"\r\n [showReplyAction]=\"allowReplies\"\r\n [editing]=\"message.transientState.editing\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n [readonly]=\"source?.readonly\"\r\n (click)=\"enableHoldOnClick ? (holdNewMessages = true) : undefined\"\r\n (editStarted)=\"startEditing(message)\"\r\n (deleted)=\"deleteMessage(message)\"\r\n (editEnded)=\"message.transientState.editing = false\"\r\n (edited)=\"saveEdit(message, $event)\"\r\n (userSelected)=\"selectMessageUser(message)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (liked)=\"likeMessage(message)\"\r\n (unliked)=\"unlikeMessage(message)\"\r\n (reported)=\"reportMessage(message)\"\r\n (selected)=\"selectMessage(message)\"\r\n (shared)=\"sharedMessage($event)\"\r\n ></banta-comment>\r\n <div class=\"inline-replies-container\" *ngIf=\"selectedMessage === message\">\r\n <ng-content select=\".inline-replies\"></ng-content>\r\n </div>\r\n </ng-container>\r\n\r\n <div class=\"nav-point bottom-sticky\">\r\n <a *ngIf=\"newestLast\" mat-button class=\"nav\" [class.visible]=\"shouldShowNewMessageIndicator\" href=\"javascript:;\" (click)=\"showNew($event)\">\r\n <mat-icon>file_download</mat-icon>\r\n <ng-container *ngIf=\"newMessages.length >= 1\">\r\n New ({{newMessages.length}})\r\n </ng-container>\r\n <ng-container *ngIf=\"newMessages.length == 0\">\r\n Newest\r\n </ng-container>\r\n </a>\r\n </div>\r\n <a mat-button class=\"nav\" [class.visible]=\"!newestLast && 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]):not(.inline-replies)\"></ng-content>\r\n</div>\r\n", styles: [":host{flex-grow:1;display:flex;flex-direction:column;opacity:1;transition:.2s opacity ease-in}.message-container{flex-grow:1;color:#111;background:white;padding:.5em 1em 3em .5em;opacity:1;transition:.5s opacity ease-in-out;position:relative}.message-container.no-scroll{height:auto;overflow-y:visible}.message-container.faded{opacity:.25}.message-container .overlay{position:absolute;inset:0;z-index:10}:host.fixed-height .message-container{overflow-y:auto}:host-context(.mat-dark-theme) .message-container{color:#fff;background:#111111}.empty-state{text-align:center;margin:3em;color:#666}:host-context(.mat-dark-theme) .empty-state{color:#666}a.nav{position:absolute;right:.5em;z-index:10;text-align:center;opacity:0;transition:.4s opacity ease-in-out;pointer-events:none;border-radius:2em;background:#222}a.nav.visible{opacity:1;pointer-events:initial}.top-sticky{position:sticky;top:.5em;z-index:10}.bottom-sticky{position:sticky;bottom:3em;z-index:10}.loading-more{padding:2em;text-align:center;margin:0 auto;width:-moz-fit-content;width:fit-content}@media (max-width: 400px){.message-container{padding:0 0 3em}}\n"] }]
8014
+ }], ctorParameters: function () { return [{ type: ChatBackendBase }, { type: i0.ElementRef }]; }, propDecorators: { source: [{
8015
+ type: Input
8016
+ }], maxMessages: [{
8017
+ type: Input
8018
+ }], maxVisibleMessages: [{
8019
+ type: Input
8020
+ }], newestLast: [{
8021
+ type: Input
8022
+ }], holdNewMessages: [{
8023
+ type: Input
8024
+ }], showEmptyState: [{
8054
8025
  type: Input
8055
8026
  }], allowReplies: [{
8056
8027
  type: Input
@@ -8060,9 +8031,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
8060
8031
  type: Input
8061
8032
  }], customMenuItems: [{
8062
8033
  type: Input
8063
- }], commentsQuery: [{
8064
- type: ViewChildren,
8065
- args: [CommentComponent]
8066
8034
  }], fixedHeight: [{
8067
8035
  type: Input
8068
8036
  }, {
@@ -8070,10 +8038,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
8070
8038
  args: ['class.fixed-height']
8071
8039
  }], selectedMessage: [{
8072
8040
  type: Input
8073
- }], selected: [{
8074
- type: Output
8075
- }], messageEdited: [{
8076
- type: Output
8041
+ }], genericAvatarUrl: [{
8042
+ type: Input
8077
8043
  }], userSelected: [{
8078
8044
  type: Output
8079
8045
  }], reported: [{
@@ -8090,25 +8056,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
8090
8056
  type: Output
8091
8057
  }], deleted: [{
8092
8058
  type: Output
8093
- }], source: [{
8094
- type: Input
8095
- }], genericAvatarUrl: [{
8096
- type: Input
8097
- }], messageContainer: [{
8098
- type: ViewChild,
8099
- args: ['messageContainer']
8100
- }], maxMessages: [{
8101
- type: Input
8102
- }], maxVisibleMessages: [{
8103
- type: Input
8104
- }], newestLast: [{
8105
- type: Input
8106
- }], holdNewMessages: [{
8107
- type: Input
8059
+ }], selected: [{
8060
+ type: Output
8061
+ }], messageEdited: [{
8062
+ type: Output
8108
8063
  }], sortOrderChanged: [{
8109
8064
  type: Output
8110
8065
  }], filterModeChanged: [{
8111
8066
  type: Output
8067
+ }], commentsQuery: [{
8068
+ type: ViewChildren,
8069
+ args: [CommentComponent]
8070
+ }], messageContainer: [{
8071
+ type: ViewChild,
8072
+ args: ['messageContainer']
8112
8073
  }] } });
8113
8074
 
8114
8075
  class BantaReplySendOptionsDirective {
@@ -8125,14 +8086,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
8125
8086
  class AttachmentButtonComponent {
8126
8087
  constructor(cdnProvider) {
8127
8088
  this.cdnProvider = cdnProvider;
8089
+ //#region Properties
8128
8090
  this._addedAttachment = new Subject();
8129
8091
  this._attachmentError = new Subject();
8092
+ //#endregion
8093
+ //#region Inputs
8094
+ this.disabled = false;
8130
8095
  }
8096
+ //#endregion
8097
+ //#region Outputs
8131
8098
  get addedAttachment() { return this._addedAttachment.asObservable(); }
8132
8099
  get attachmentError() { return this._attachmentError.asObservable(); }
8133
- show() {
8134
- this.fileInput.nativeElement.click();
8135
- }
8100
+ //#endregion
8101
+ show() { this.fileInput.nativeElement.click(); }
8136
8102
  fileChange(event) {
8137
8103
  return __awaiter(this, void 0, void 0, function* () {
8138
8104
  const element = event.currentTarget;
@@ -8173,17 +8139,19 @@ class AttachmentButtonComponent {
8173
8139
  }
8174
8140
  }
8175
8141
  AttachmentButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AttachmentButtonComponent, deps: [{ token: i1$2.CDNProvider }], target: i0.ɵɵFactoryTarget.Component });
8176
- AttachmentButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: AttachmentButtonComponent, selector: "banta-attachment-button", outputs: { addedAttachment: "addedAttachment", attachmentError: "attachmentError" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileUpload"], descendants: true }], ngImport: i0, template: "<button matTooltip=\"Add an image or gif\" #button type=\"button\" mat-icon-button (click)=\"show()\">\r\n\t<mat-icon>image</mat-icon>\r\n</button>\r\n<input style=\"display: none;\" #fileUpload [multiple]=\"false\" (change)=\"fileChange($event)\" type=\"file\" >", styles: ["button{color:#666}\n"], dependencies: [{ kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
8142
+ AttachmentButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: AttachmentButtonComponent, selector: "banta-attachment-button", inputs: { disabled: "disabled" }, outputs: { addedAttachment: "addedAttachment", attachmentError: "attachmentError" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileUpload"], descendants: true }], ngImport: i0, template: "<button matTooltip=\"Add an image or gif\" #button type=\"button\" mat-icon-button (click)=\"show()\" [disabled]=\"disabled\">\r\n\t<mat-icon>image</mat-icon>\r\n</button>\r\n<input style=\"display: none;\" #fileUpload [multiple]=\"false\" (change)=\"fileChange($event)\" type=\"file\" >", styles: ["button{color:#666}\n"], dependencies: [{ kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
8177
8143
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AttachmentButtonComponent, decorators: [{
8178
8144
  type: Component,
8179
- args: [{ selector: 'banta-attachment-button', template: "<button matTooltip=\"Add an image or gif\" #button type=\"button\" mat-icon-button (click)=\"show()\">\r\n\t<mat-icon>image</mat-icon>\r\n</button>\r\n<input style=\"display: none;\" #fileUpload [multiple]=\"false\" (change)=\"fileChange($event)\" type=\"file\" >", styles: ["button{color:#666}\n"] }]
8180
- }], ctorParameters: function () { return [{ type: i1$2.CDNProvider }]; }, propDecorators: { fileInput: [{
8181
- type: ViewChild,
8182
- args: ['fileUpload', { static: false }]
8145
+ args: [{ selector: 'banta-attachment-button', template: "<button matTooltip=\"Add an image or gif\" #button type=\"button\" mat-icon-button (click)=\"show()\" [disabled]=\"disabled\">\r\n\t<mat-icon>image</mat-icon>\r\n</button>\r\n<input style=\"display: none;\" #fileUpload [multiple]=\"false\" (change)=\"fileChange($event)\" type=\"file\" >", styles: ["button{color:#666}\n"] }]
8146
+ }], ctorParameters: function () { return [{ type: i1$2.CDNProvider }]; }, propDecorators: { disabled: [{
8147
+ type: Input
8183
8148
  }], addedAttachment: [{
8184
8149
  type: Output
8185
8150
  }], attachmentError: [{
8186
8151
  type: Output
8152
+ }], fileInput: [{
8153
+ type: ViewChild,
8154
+ args: ['fileUpload', { static: false }]
8187
8155
  }] } });
8188
8156
 
8189
8157
  class AttachmentScraperDirective {
@@ -8291,17 +8259,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
8291
8259
  }] } });
8292
8260
 
8293
8261
  class CommentFieldComponent {
8294
- constructor(chatBackend) {
8295
- this.chatBackend = chatBackend;
8262
+ constructor() {
8263
+ //#endregion
8264
+ //#region Properties
8265
+ this._permissionDeniedError = new Subject();
8296
8266
  this._subs = new Subscription();
8297
- this.canComment = true;
8298
- this.allowAttachments = false;
8299
- this.signInSelected = new Subject();
8300
- this.editAvatarSelected = new Subject();
8301
- this.focusChange = new Subject();
8302
8267
  this.sending = false;
8303
8268
  this.expandError = false;
8304
- this._text = '';
8269
+ this.autocompleteVisible = false;
8270
+ this.autocompleteOptions = [];
8271
+ this.autoCompleteSelected = 0;
8272
+ this.text = '';
8273
+ this.chatMessageAttachments = [];
8274
+ this.canComment = true;
8275
+ this.allowAttachments = false;
8305
8276
  this.sendLabel = 'Send';
8306
8277
  this.signingInLabel = 'Signing in...';
8307
8278
  this.sendingLabel = 'Sending';
@@ -8310,52 +8281,24 @@ class CommentFieldComponent {
8310
8281
  this.signInLabel = 'Sign In';
8311
8282
  this.maxLength = 1500;
8312
8283
  this.placeholder = '';
8313
- this.textChanged = new Subject();
8314
8284
  this.participants = [];
8315
- this._permissionDeniedError = new Subject();
8316
- this.autocompleteVisible = false;
8317
- this.autocompleteOptions = [];
8318
- this.autoCompleteSelected = 0;
8319
- this.chatMessageAttachments = [];
8320
- }
8321
- get source() {
8322
- return this._source;
8285
+ this.readonly = false;
8286
+ //#endregion
8287
+ //#region Outputs
8288
+ this.signInSelected = new Subject();
8289
+ this.editAvatarSelected = new Subject();
8290
+ this.focusChange = new Subject();
8291
+ this.textChanged = new Subject();
8323
8292
  }
8324
- set source(value) {
8325
- var _a;
8326
- if (this._source) {
8327
- (_a = this._subs) === null || _a === void 0 ? void 0 : _a.unsubscribe();
8328
- this._source = null;
8329
- }
8330
- this._source = value;
8331
- this._subs = new Subscription();
8332
- if (this._source) {
8333
- setTimeout(() => {
8334
- if (this._source.connectionStateChanged) {
8335
- this._subs.add(this._source.connectionStateChanged.subscribe(state => {
8336
- if (state === 'lost') {
8337
- if (this._source.errorState === 'server-issue')
8338
- this.transientMessage = `Reconnecting..`;
8339
- else
8340
- this.transientMessage = `Reconnecting...`;
8341
- }
8342
- else if (state === 'restored') {
8343
- this.transientMessage = undefined;
8344
- }
8345
- else if (state === 'connecting') {
8346
- this.transientMessage = `Connecting...`;
8347
- }
8348
- }));
8349
- }
8350
- });
8293
+ ngAfterViewInit() {
8294
+ if (typeof window !== 'undefined') {
8295
+ let root = document.body.querySelector('[ng-version]') || document.body;
8296
+ root.appendChild(this.autocompleteEl.nativeElement);
8351
8297
  }
8352
8298
  }
8353
- get text() {
8354
- return this._text;
8355
- }
8356
- set text(value) {
8357
- this._text = value;
8358
- }
8299
+ get source() { return this._source; }
8300
+ set source(value) { this.setSource(value); }
8301
+ get permissionDeniedError() { return this._permissionDeniedError; }
8359
8302
  get indicatorState() {
8360
8303
  if (this.transientMessage) {
8361
8304
  return 'transient';
@@ -8380,22 +8323,65 @@ class CommentFieldComponent {
8380
8323
  else
8381
8324
  return 'send';
8382
8325
  }
8383
- get userAvatarUrl() {
8384
- var _a;
8385
- return ((_a = this.user) === null || _a === void 0 ? void 0 : _a.avatarUrl) || this.genericAvatarUrl;
8386
- }
8387
- get permissionDeniedError() {
8388
- return this._permissionDeniedError;
8389
- }
8390
- ngAfterViewInit() {
8391
- if (typeof window !== 'undefined') {
8392
- let root = document.body.querySelector('[ng-version]') || document.body;
8393
- root.appendChild(this.autocompleteEl.nativeElement);
8326
+ get sendButtonEnabled() {
8327
+ if (this.readonly)
8328
+ return false;
8329
+ if (this.signInState === 'signing-in')
8330
+ return false;
8331
+ if (!['connected', 'restored'].includes(this.source.state))
8332
+ return false;
8333
+ if (!this.canComment) {
8334
+ // In this case, we want to enable the button because we want to be able to
8335
+ // send the permissionDenied message up to the host.
8336
+ return true;
8394
8337
  }
8338
+ return this.isValidMessage
8339
+ && !this.hasPendingAttachments
8340
+ && !this.sending;
8395
8341
  }
8396
- sendPermissionDenied(message) {
8397
- this._permissionDeniedError.next(message);
8342
+ get userAvatarUrl() { var _a; return ((_a = this.user) === null || _a === void 0 ? void 0 : _a.avatarUrl) || this.genericAvatarUrl; }
8343
+ get isValidMessage() { return (this.text || this.chatMessageAttachments.length > 0); }
8344
+ get hasPendingAttachments() { return this.chatMessageAttachments.some(x => x.transientState); }
8345
+ //#endregion
8346
+ //#region Private Component API
8347
+ setSource(value) {
8348
+ var _a;
8349
+ if (this._source) {
8350
+ (_a = this._subs) === null || _a === void 0 ? void 0 : _a.unsubscribe();
8351
+ this._source = null;
8352
+ }
8353
+ this._source = value;
8354
+ this._subs = new Subscription();
8355
+ if (this._source) {
8356
+ setTimeout(() => {
8357
+ if (this._source.connectionStateChanged) {
8358
+ this._subs.add(this._source.connectionStateChanged.subscribe(state => {
8359
+ if (state === 'lost') {
8360
+ if (this._source.errorState === 'server-issue')
8361
+ this.transientMessage = `Reconnecting..`;
8362
+ else
8363
+ this.transientMessage = `Reconnecting...`;
8364
+ }
8365
+ else if (state === 'restored') {
8366
+ this.transientMessage = undefined;
8367
+ }
8368
+ else if (state === 'connecting') {
8369
+ this.transientMessage = `Connecting...`;
8370
+ }
8371
+ }));
8372
+ }
8373
+ });
8374
+ }
8398
8375
  }
8376
+ //#endregion
8377
+ //#region Actions
8378
+ sendPermissionDenied(message) { this._permissionDeniedError.next(message); }
8379
+ activateAutoComplete(option) { option.action(); this.dismissAutoComplete(); }
8380
+ onFocus() { this.focusChange.next(true); }
8381
+ onBlur() { this.focusChange.next(false); setTimeout(() => this.dismissAutoComplete(), 250); }
8382
+ showSignIn() { this.signInSelected.next(); }
8383
+ showEditAvatar() { this.editAvatarSelected.next(); }
8384
+ insertEmoji(text) { this.text += text; }
8399
8385
  showAutoComplete(options) {
8400
8386
  if (typeof window === 'undefined')
8401
8387
  return;
@@ -8408,10 +8394,6 @@ class CommentFieldComponent {
8408
8394
  this.autocompleteEl.nativeElement.style.width = `${pos.width}px`;
8409
8395
  this.autocompleteVisible = true;
8410
8396
  }
8411
- activateAutoComplete(option) {
8412
- option.action();
8413
- this.dismissAutoComplete();
8414
- }
8415
8397
  dismissAutoComplete() {
8416
8398
  this.autocompleteVisible = false;
8417
8399
  this.completionFunc = null;
@@ -8431,26 +8413,6 @@ class CommentFieldComponent {
8431
8413
  if (typeof window !== 'undefined' && window.innerWidth < 430)
8432
8414
  alert(message);
8433
8415
  }
8434
- get isValidMessage() {
8435
- return (this.text || this.chatMessageAttachments.length > 0);
8436
- }
8437
- get hasPendingAttachments() {
8438
- return this.chatMessageAttachments.some(x => x.transientState);
8439
- }
8440
- get sendButtonEnabled() {
8441
- if (this.signInState === 'signing-in')
8442
- return false;
8443
- if (!['connected', 'restored'].includes(this.source.state))
8444
- return false;
8445
- if (!this.canComment) {
8446
- // In this case, we want to enable the button because we want to be able to
8447
- // send the permissionDenied message up to the host.
8448
- return true;
8449
- }
8450
- return this.isValidMessage
8451
- && !this.hasPendingAttachments
8452
- && !this.sending;
8453
- }
8454
8416
  autocomplete(replacement) {
8455
8417
  return __awaiter(this, void 0, void 0, function* () {
8456
8418
  let el = this.textareaEl.nativeElement;
@@ -8564,23 +8526,8 @@ class CommentFieldComponent {
8564
8526
  this.completionFunc = completionFunc;
8565
8527
  this.showAutoComplete(this.completionFunc(this.completionPrefix));
8566
8528
  }
8567
- onFocus() {
8568
- this.focusChange.next(true);
8569
- }
8570
- onBlur() {
8571
- this.focusChange.next(false);
8572
- setTimeout(() => this.dismissAutoComplete(), 250);
8573
- }
8574
- insertEmoji(text) {
8575
- this.text += text;
8576
- }
8577
- showSignIn() {
8578
- this.signInSelected.next();
8579
- }
8580
- showEditAvatar() {
8581
- this.editAvatarSelected.next();
8582
- }
8583
8529
  sendMessage() {
8530
+ var _a;
8584
8531
  return __awaiter(this, void 0, void 0, function* () {
8585
8532
  if (!this.source)
8586
8533
  return;
@@ -8593,7 +8540,7 @@ class CommentFieldComponent {
8593
8540
  let message = {
8594
8541
  user: this.user,
8595
8542
  sentAt: Date.now(),
8596
- url: typeof window !== 'undefined' ? location.href : undefined,
8543
+ url: (_a = this.url) !== null && _a !== void 0 ? _a : (typeof window !== 'undefined' ? location.href : undefined),
8597
8544
  likes: 0,
8598
8545
  message: text,
8599
8546
  attachments: this.chatMessageAttachments.filter(x => x.url)
@@ -8617,9 +8564,7 @@ class CommentFieldComponent {
8617
8564
  }
8618
8565
  });
8619
8566
  }
8620
- addedAttachment(attachment) {
8621
- this.chatMessageAttachments.push(attachment);
8622
- }
8567
+ addedAttachment(attachment) { this.chatMessageAttachments.push(attachment); }
8623
8568
  attachmentError(attachment) {
8624
8569
  setTimeout(() => {
8625
8570
  this.chatMessageAttachments = this.chatMessageAttachments.filter(x => x !== attachment);
@@ -8636,30 +8581,24 @@ class CommentFieldComponent {
8636
8581
  alert(this.sendError.message);
8637
8582
  }
8638
8583
  }
8639
- CommentFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CommentFieldComponent, deps: [{ token: ChatBackendBase }], target: i0.ɵɵFactoryTarget.Component });
8640
- CommentFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CommentFieldComponent, selector: "banta-comment-field", inputs: { source: "source", user: "user", canComment: "canComment", signInState: "signInState", allowAttachments: "allowAttachments", transientMessage: "transientMessage", sendLabel: "sendLabel", signingInLabel: "signingInLabel", sendingLabel: "sendingLabel", label: "label", permissionDeniedLabel: "permissionDeniedLabel", signInLabel: "signInLabel", maxLength: "maxLength", placeholder: "placeholder", shouldInterceptMessageSend: "shouldInterceptMessageSend", hashtags: "hashtags", participants: "participants", genericAvatarUrl: "genericAvatarUrl", submit: "submit" }, outputs: { signInSelected: "signInSelected", editAvatarSelected: "editAvatarSelected", focusChange: "focusChange", textChanged: "textChanged", permissionDeniedError: "permissionDeniedError" }, host: { properties: { "class.can-comment": "this.canComment" } }, viewQueries: [{ propertyName: "autocompleteEl", first: true, predicate: ["autocomplete"], descendants: true }, { propertyName: "autocompleteContainerEl", first: true, predicate: ["autocompleteContainer"], descendants: true }, { propertyName: "textareaEl", first: true, predicate: ["textarea"], descendants: true }], ngImport: i0, template: "<form class=\"new-message\" (submit)=\"sendMessage()\">\r\n <div class=\"avatar-container\">\r\n <a href=\"javascript:;\"\r\n class=\"avatar\"\r\n (click)=\"showEditAvatar()\"\r\n [style.background-image]=\"'url(' + userAvatarUrl + ')'\"\r\n ></a>\r\n </div>\r\n <div class=\"text-container\">\r\n <div class=\"field-container\">\r\n <div class=\"field-row\">\r\n <mat-form-field class=\"message-field\" appearance=\"outline\" floatLabel=\"always\">\r\n <mat-label>{{label}}</mat-label>\r\n <textarea\r\n #textarea\r\n name=\"message\"\r\n attachmentScraper\r\n [(attachments)]=\"chatMessageAttachments\"\r\n [placeholder]=\"placeholder\"\r\n matInput\r\n cdkTextareaAutosize\r\n [maxlength]=\"maxLength\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n [disabled]=\"sending\"\r\n [(ngModel)]=\"text\"\r\n autocomplete=\"off\"\r\n ></textarea>\r\n </mat-form-field>\r\n <div class=\"options-line\">\r\n <ng-container *ngIf=\"indicatorState === 'transient'\">\r\n <div class=\"transient-message\" [class.expanded]=\"true\" [matTooltip]=\"transientMessage\" (click)=\"alertError()\">\r\n <mat-spinner [inline]=\"true\" [diameter]=\"15\"></mat-spinner>\r\n {{transientMessage}}\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"indicatorState === 'sending'\">\r\n <div class=\"transient-message\" [class.expanded]=\"true\" (click)=\"alertError()\">\r\n <mat-spinner [inline]=\"true\" [diameter]=\"15\"></mat-spinner>\r\n {{sendingLabel}}...\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"indicatorState === 'error'\">\r\n <div class=\"error-message\" [class.expanded]=\"expandError\" [matTooltip]=\"sendError.message\" (click)=\"alertError()\">\r\n <mat-icon *ngIf=\"sendError\">error</mat-icon>\r\n {{sendError.message}}\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <div class=\"spacer\"></div>\r\n <div class=\"custom\">\r\n <ng-content></ng-content>\r\n </div>\r\n <banta-attachment-button \r\n *ngIf=\"allowAttachments\"\r\n (addedAttachment)=\"addedAttachment($event)\"\r\n (attachmentError)=\"attachmentError($event)\"\r\n ></banta-attachment-button>\r\n <emoji-selector-button (selected)=\"insertEmoji($event)\"></emoji-selector-button>\r\n </div>\r\n \r\n </div>\r\n <div #autocompleteContainer class=\"autocomplete-container\">\r\n <div #autocomplete class=\"autocomplete\" [class.visible]=\"autocompleteVisible\">\r\n\r\n <div>\r\n <strong>{{completionPrefix}}</strong>...\r\n </div>\r\n <a\r\n mat-button\r\n *ngFor=\"let option of autocompleteOptions; index as index\"\r\n (click)=\"activateAutoComplete(option)\"\r\n [class.active]=\"autoCompleteSelected === index\"\r\n >\r\n {{option.label}}\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <banta-attachments \r\n [attachments]=\"chatMessageAttachments\"\r\n [editing]=\"true\"\r\n (remove)=\"removeAttachment($event)\"\r\n ></banta-attachments>\r\n </div>\r\n </div>\r\n <div class=\"actions\">\r\n <ng-container *ngIf=\"!user\">\r\n <button\r\n mat-raised-button\r\n color=\"primary\"\r\n type=\"button\"\r\n (click)=\"showSignIn()\"\r\n >{{signInLabel}}</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"user\">\r\n <button\r\n mat-raised-button\r\n class=\"send\"\r\n color=\"primary\"\r\n [disabled]=\"!sendButtonEnabled\"\r\n >\r\n <ng-container *ngIf=\"buttonState === 'send'\">\r\n <mat-icon>chevron_right</mat-icon>\r\n <span class=\"label\">{{sendLabel}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"buttonState === 'sending'\">\r\n <mat-spinner class=\"icon\" diameter=\"18\" strokeWidth=\"2\"></mat-spinner>\r\n <span class=\"label\">{{sendingLabel}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"buttonState === 'signing-in'\">\r\n <mat-spinner class=\"icon\" diameter=\"18\" strokeWidth=\"2\"></mat-spinner>\r\n {{signingInLabel}}\r\n </ng-container>\r\n <ng-container *ngIf=\"buttonState === 'permission-denied'\">\r\n {{permissionDeniedLabel}}\r\n </ng-container>\r\n </button>\r\n </ng-container>\r\n </div>\r\n</form>", styles: ["@keyframes comment-field-appear{0%{transform:translateY(128px);opacity:0}to{transform:translate(0);opacity:1}}:host{margin:0 2em 0 0;display:block;animation-name:comment-field-appear;animation-duration:.8s;animation-delay:.4s;animation-fill-mode:both;position:relative;z-index:20}.avatar-container{width:calc(48px + 1.75em);display:flex;justify-content:flex-end;flex-shrink:0}.avatar-container .avatar{width:48px;height:48px;background:black;border-radius:100%;background-size:cover;background-repeat:no-repeat;background-position:center;margin-top:.75em;margin-right:.75em}form{display:flex;padding:.5em;align-items:center}form .text-container{position:relative;display:flex;flex-grow:1;min-width:0}form .text-container textarea{font-size:14pt;width:100%}form .text-container textarea[disabled]{opacity:.5}form .text-container mat-spinner.loading{position:absolute;left:.5em;bottom:.5em}form .text-container .options-line{display:flex;align-items:center}form .text-container .options-line>*{flex-shrink:0}form .text-container .options-line .transient-message{display:flex;flex-direction:row;align-items:center;gap:.5em}form .text-container .options-line .error-message{left:.5em;bottom:.5em;color:#683333;overflow-x:hidden;max-width:1.5em;white-space:nowrap;transition:2s max-width ease-in-out;text-overflow:ellipsis;overflow:hidden;flex-shrink:1}form .text-container .options-line .error-message.expanded,form .text-container .options-line .error-message:hover{max-width:100%}form .text-container .options-line .error-message mat-icon{vertical-align:middle}form input[type=text]{background:black;color:#fff;border:1px solid #333;width:100%;height:1em}form .actions{margin-left:1em;flex-shrink:0}form button{display:block;margin:0 0 0 auto}form.new-message{display:flex;align-items:flex-start;min-width:0}form.new-message .field-container{flex-grow:1;display:flex;flex-direction:column;min-width:0}form.new-message mat-form-field{width:100%}form.new-message mat-form-field ::ng-deep .mat-form-field-wrapper{padding-bottom:0}form.new-message button{margin:1.25em 0 0}button.send{min-width:9em}textarea{max-height:7em}.autocomplete-container{width:calc(100% - 2em);position:relative;pointer-events:none;top:-2em}.autocomplete{visibility:hidden;pointer-events:none;position:absolute;background:#333;padding:.5em;display:flex;flex-direction:column;z-index:100}.autocomplete.visible{visibility:visible;pointer-events:initial}.autocomplete a{width:100%;text-align:left}.autocomplete a.active{background:#555}.image-attachments-container{display:flex;gap:20px}.image-attachments-container .image-attachment{width:300px;position:relative;text-align:center}.image-attachments-container .image-attachment.with-border{outline:1px solid #333;padding:1em 0}.image-attachments-container .image-attachment mat-spinner{display:block;margin:0 auto .5em;width:-moz-fit-content;width:fit-content}.image-attachments-container .image-attachment mat-icon.error{display:block;font-size:48px;width:48px;height:48px;margin:0 auto .5em}.image-attachments-container .image-attachment .error{color:#b76363}.image-attachments-container .image-attachment img{width:300px;border-radius:10px}.image-attachments-container .image-attachment .remove-img{position:absolute;right:10px;top:10px;margin:0}.field-row,.card-attachment{position:relative}.card-attachment a{display:flex;align-items:flex-start;gap:1em;width:100%;border:1px solid #666;border-radius:4px;padding:2em;box-sizing:border-box;background-color:#191919}.card-attachment a img{width:300px;aspect-ratio:16/9;-o-object-fit:cover;object-fit:cover;border-radius:10px}.card-attachment a h1{margin:0;font-size:30px}.card-attachment .remove-img{position:absolute;right:10px;top:10px;margin:0}@media (max-width: 500px){:host{margin:0}.avatar-container{display:none;width:auto;flex-shrink:0}.avatar-container .avatar{width:32px;height:32px;margin-top:1.5em}:host:not(.can-comment) mat-form-field.message-field{display:none}:host:not(.can-comment) .text-container{display:none}:host.can-comment button.send .label{display:none}button.send{min-width:auto;margin-top:1.5em}}:host-context(.banta-mobile) :host{margin:0}:host-context(.banta-mobile) .avatar-container{display:none;width:auto;flex-shrink:0}:host-context(.banta-mobile) .avatar-container .avatar{width:32px;height:32px;margin-top:1.5em}:host-context(.banta-mobile) :host:not(.can-comment) mat-form-field.message-field{display:none}:host-context(.banta-mobile) :host:not(.can-comment) .text-container{display:none}:host-context(.banta-mobile) :host.can-comment button.send .label{display:none}:host-context(.banta-mobile) button.send{min-width:auto;margin-top:1.5em}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: BantaAttachmentsComponent, selector: "banta-attachments", inputs: ["attachments", "editing"], outputs: ["remove", "loaded"] }, { kind: "component", type: EmojiSelectorButtonComponent, selector: "emoji-selector-button", inputs: ["overlayX", "overlayY", "originX", "originY"], outputs: ["selected"] }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: AttachmentButtonComponent, selector: "banta-attachment-button", outputs: ["addedAttachment", "attachmentError"] }, { kind: "directive", type: AttachmentScraperDirective, selector: "[attachmentScraper]", inputs: ["attachments"], outputs: ["attachmentsChange"] }] });
8584
+ CommentFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CommentFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8585
+ CommentFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CommentFieldComponent, selector: "banta-comment-field", inputs: { source: "source", user: "user", canComment: "canComment", signInState: "signInState", allowAttachments: "allowAttachments", transientMessage: "transientMessage", sendLabel: "sendLabel", signingInLabel: "signingInLabel", sendingLabel: "sendingLabel", label: "label", permissionDeniedLabel: "permissionDeniedLabel", signInLabel: "signInLabel", maxLength: "maxLength", placeholder: "placeholder", shouldInterceptMessageSend: "shouldInterceptMessageSend", hashtags: "hashtags", participants: "participants", genericAvatarUrl: "genericAvatarUrl", url: "url", submit: "submit", readonly: "readonly" }, outputs: { signInSelected: "signInSelected", editAvatarSelected: "editAvatarSelected", focusChange: "focusChange", textChanged: "textChanged", permissionDeniedError: "permissionDeniedError" }, host: { properties: { "class.can-comment": "this.canComment" } }, viewQueries: [{ propertyName: "autocompleteEl", first: true, predicate: ["autocomplete"], descendants: true }, { propertyName: "autocompleteContainerEl", first: true, predicate: ["autocompleteContainer"], descendants: true }, { propertyName: "textareaEl", first: true, predicate: ["textarea"], descendants: true }], ngImport: i0, template: "<form class=\"new-message\" (submit)=\"sendMessage()\">\r\n <div class=\"avatar-container\">\r\n <a href=\"javascript:;\"\r\n class=\"avatar\"\r\n (click)=\"showEditAvatar()\"\r\n [style.background-image]=\"'url(' + userAvatarUrl + ')'\"\r\n ></a>\r\n </div>\r\n <div class=\"text-container\">\r\n <div class=\"field-container\">\r\n <div class=\"field-row\">\r\n <mat-form-field class=\"message-field\" appearance=\"outline\" floatLabel=\"always\">\r\n <mat-label>{{label}}</mat-label>\r\n <textarea\r\n #textarea\r\n name=\"message\"\r\n attachmentScraper\r\n [(attachments)]=\"chatMessageAttachments\"\r\n [placeholder]=\"placeholder\"\r\n matInput\r\n cdkTextareaAutosize\r\n [maxlength]=\"maxLength\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n [disabled]=\"sending || readonly\"\r\n [(ngModel)]=\"text\"\r\n autocomplete=\"off\"\r\n ></textarea>\r\n </mat-form-field>\r\n <div class=\"options-line\">\r\n <ng-container *ngIf=\"indicatorState === 'transient'\">\r\n <div class=\"transient-message\" [class.expanded]=\"true\" [matTooltip]=\"transientMessage\" (click)=\"alertError()\">\r\n <mat-spinner [inline]=\"true\" [diameter]=\"15\"></mat-spinner>\r\n {{transientMessage}}\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"indicatorState === 'sending'\">\r\n <div class=\"transient-message\" [class.expanded]=\"true\" (click)=\"alertError()\">\r\n <mat-spinner [inline]=\"true\" [diameter]=\"15\"></mat-spinner>\r\n {{sendingLabel}}...\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"indicatorState === 'error'\">\r\n <div class=\"error-message\" [class.expanded]=\"expandError\" [matTooltip]=\"sendError.message\" (click)=\"alertError()\">\r\n <mat-icon *ngIf=\"sendError\">error</mat-icon>\r\n {{sendError.message}}\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <div class=\"spacer\"></div>\r\n <div class=\"custom\">\r\n <ng-content></ng-content>\r\n </div>\r\n <banta-attachment-button \r\n *ngIf=\"allowAttachments\"\r\n [disabled]=\"readonly\"\r\n (addedAttachment)=\"addedAttachment($event)\"\r\n (attachmentError)=\"attachmentError($event)\"\r\n ></banta-attachment-button>\r\n <emoji-selector-button [disabled]=\"readonly\" (selected)=\"insertEmoji($event)\"></emoji-selector-button>\r\n </div>\r\n \r\n </div>\r\n <div #autocompleteContainer class=\"autocomplete-container\">\r\n <div #autocomplete class=\"autocomplete\" [class.visible]=\"autocompleteVisible\">\r\n\r\n <div>\r\n <strong>{{completionPrefix}}</strong>...\r\n </div>\r\n <a\r\n mat-button\r\n *ngFor=\"let option of autocompleteOptions; index as index\"\r\n (click)=\"activateAutoComplete(option)\"\r\n [class.active]=\"autoCompleteSelected === index\"\r\n >\r\n {{option.label}}\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <banta-attachments \r\n [attachments]=\"chatMessageAttachments\"\r\n [editing]=\"true\"\r\n (remove)=\"removeAttachment($event)\"\r\n ></banta-attachments>\r\n </div>\r\n </div>\r\n <div class=\"actions\">\r\n <ng-container *ngIf=\"!user\">\r\n <button\r\n mat-raised-button\r\n color=\"primary\"\r\n type=\"button\"\r\n (click)=\"showSignIn()\"\r\n >{{signInLabel}}</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"user\">\r\n <button\r\n mat-raised-button\r\n class=\"send\"\r\n color=\"primary\"\r\n [disabled]=\"!sendButtonEnabled\"\r\n >\r\n <ng-container *ngIf=\"buttonState === 'send'\">\r\n <mat-icon>chevron_right</mat-icon>\r\n <span class=\"label\">{{sendLabel}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"buttonState === 'sending'\">\r\n <mat-spinner class=\"icon\" diameter=\"18\" strokeWidth=\"2\"></mat-spinner>\r\n <span class=\"label\">{{sendingLabel}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"buttonState === 'signing-in'\">\r\n <mat-spinner class=\"icon\" diameter=\"18\" strokeWidth=\"2\"></mat-spinner>\r\n {{signingInLabel}}\r\n </ng-container>\r\n <ng-container *ngIf=\"buttonState === 'permission-denied'\">\r\n {{permissionDeniedLabel}}\r\n </ng-container>\r\n </button>\r\n </ng-container>\r\n </div>\r\n</form>", styles: ["@keyframes comment-field-appear{0%{transform:translateY(128px);opacity:0}to{transform:translate(0);opacity:1}}:host{margin:0 2em 0 0;display:block;animation-name:comment-field-appear;animation-duration:.8s;animation-delay:.4s;animation-fill-mode:both;position:relative;z-index:20}.avatar-container{width:calc(48px + 1.75em);display:flex;justify-content:flex-end;flex-shrink:0}.avatar-container .avatar{width:48px;height:48px;background:black;border-radius:100%;background-size:cover;background-repeat:no-repeat;background-position:center;margin-top:.75em;margin-right:.75em}form{display:flex;padding:.5em;align-items:center}form .text-container{position:relative;display:flex;flex-grow:1;min-width:0}form .text-container textarea{font-size:14pt;width:100%}form .text-container textarea[disabled]{opacity:.5}form .text-container mat-spinner.loading{position:absolute;left:.5em;bottom:.5em}form .text-container .options-line{display:flex;align-items:center}form .text-container .options-line>*{flex-shrink:0}form .text-container .options-line .transient-message{display:flex;flex-direction:row;align-items:center;gap:.5em}form .text-container .options-line .error-message{left:.5em;bottom:.5em;color:#683333;overflow-x:hidden;max-width:1.5em;white-space:nowrap;transition:2s max-width ease-in-out;text-overflow:ellipsis;overflow:hidden;flex-shrink:1}form .text-container .options-line .error-message.expanded,form .text-container .options-line .error-message:hover{max-width:100%}form .text-container .options-line .error-message mat-icon{vertical-align:middle}form input[type=text]{background:black;color:#fff;border:1px solid #333;width:100%;height:1em}form .actions{margin-left:1em;flex-shrink:0}form button{display:block;margin:0 0 0 auto}form.new-message{display:flex;align-items:flex-start;min-width:0}form.new-message .field-container{flex-grow:1;display:flex;flex-direction:column;min-width:0}form.new-message mat-form-field{width:100%}form.new-message mat-form-field ::ng-deep .mat-form-field-wrapper{padding-bottom:0}form.new-message button{margin:1.25em 0 0}button.send{min-width:9em}textarea{max-height:7em}.autocomplete-container{width:calc(100% - 2em);position:relative;pointer-events:none;top:-2em}.autocomplete{visibility:hidden;pointer-events:none;position:absolute;background:#333;padding:.5em;display:flex;flex-direction:column;z-index:100}.autocomplete.visible{visibility:visible;pointer-events:initial}.autocomplete a{width:100%;text-align:left}.autocomplete a.active{background:#555}.image-attachments-container{display:flex;gap:20px}.image-attachments-container .image-attachment{width:300px;position:relative;text-align:center}.image-attachments-container .image-attachment.with-border{outline:1px solid #333;padding:1em 0}.image-attachments-container .image-attachment mat-spinner{display:block;margin:0 auto .5em;width:-moz-fit-content;width:fit-content}.image-attachments-container .image-attachment mat-icon.error{display:block;font-size:48px;width:48px;height:48px;margin:0 auto .5em}.image-attachments-container .image-attachment .error{color:#b76363}.image-attachments-container .image-attachment img{width:300px;border-radius:10px}.image-attachments-container .image-attachment .remove-img{position:absolute;right:10px;top:10px;margin:0}.field-row,.card-attachment{position:relative}.card-attachment a{display:flex;align-items:flex-start;gap:1em;width:100%;border:1px solid #666;border-radius:4px;padding:2em;box-sizing:border-box;background-color:#191919}.card-attachment a img{width:300px;aspect-ratio:16/9;-o-object-fit:cover;object-fit:cover;border-radius:10px}.card-attachment a h1{margin:0;font-size:30px}.card-attachment .remove-img{position:absolute;right:10px;top:10px;margin:0}@media (max-width: 500px){:host{margin:0}.avatar-container{display:none;width:auto;flex-shrink:0}.avatar-container .avatar{width:32px;height:32px;margin-top:1.5em}:host:not(.can-comment) mat-form-field.message-field{display:none}:host:not(.can-comment) .text-container{display:none}:host.can-comment button.send .label{display:none}button.send{min-width:auto;margin-top:1.5em}}:host-context(.banta-mobile) :host{margin:0}:host-context(.banta-mobile) .avatar-container{display:none;width:auto;flex-shrink:0}:host-context(.banta-mobile) .avatar-container .avatar{width:32px;height:32px;margin-top:1.5em}:host-context(.banta-mobile) :host:not(.can-comment) mat-form-field.message-field{display:none}:host-context(.banta-mobile) :host:not(.can-comment) .text-container{display:none}:host-context(.banta-mobile) :host.can-comment button.send .label{display:none}:host-context(.banta-mobile) button.send{min-width:auto;margin-top:1.5em}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$2.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "directive", type: i3$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: BantaAttachmentsComponent, selector: "banta-attachments", inputs: ["attachments", "editing"], outputs: ["remove", "loaded"] }, { kind: "component", type: EmojiSelectorButtonComponent, selector: "emoji-selector-button", inputs: ["disabled", "overlayX", "overlayY", "originX", "originY"], outputs: ["selected"] }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: AttachmentButtonComponent, selector: "banta-attachment-button", inputs: ["disabled"], outputs: ["addedAttachment", "attachmentError"] }, { kind: "directive", type: AttachmentScraperDirective, selector: "[attachmentScraper]", inputs: ["attachments"], outputs: ["attachmentsChange"] }] });
8641
8586
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CommentFieldComponent, decorators: [{
8642
8587
  type: Component,
8643
- args: [{ selector: 'banta-comment-field', template: "<form class=\"new-message\" (submit)=\"sendMessage()\">\r\n <div class=\"avatar-container\">\r\n <a href=\"javascript:;\"\r\n class=\"avatar\"\r\n (click)=\"showEditAvatar()\"\r\n [style.background-image]=\"'url(' + userAvatarUrl + ')'\"\r\n ></a>\r\n </div>\r\n <div class=\"text-container\">\r\n <div class=\"field-container\">\r\n <div class=\"field-row\">\r\n <mat-form-field class=\"message-field\" appearance=\"outline\" floatLabel=\"always\">\r\n <mat-label>{{label}}</mat-label>\r\n <textarea\r\n #textarea\r\n name=\"message\"\r\n attachmentScraper\r\n [(attachments)]=\"chatMessageAttachments\"\r\n [placeholder]=\"placeholder\"\r\n matInput\r\n cdkTextareaAutosize\r\n [maxlength]=\"maxLength\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n [disabled]=\"sending\"\r\n [(ngModel)]=\"text\"\r\n autocomplete=\"off\"\r\n ></textarea>\r\n </mat-form-field>\r\n <div class=\"options-line\">\r\n <ng-container *ngIf=\"indicatorState === 'transient'\">\r\n <div class=\"transient-message\" [class.expanded]=\"true\" [matTooltip]=\"transientMessage\" (click)=\"alertError()\">\r\n <mat-spinner [inline]=\"true\" [diameter]=\"15\"></mat-spinner>\r\n {{transientMessage}}\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"indicatorState === 'sending'\">\r\n <div class=\"transient-message\" [class.expanded]=\"true\" (click)=\"alertError()\">\r\n <mat-spinner [inline]=\"true\" [diameter]=\"15\"></mat-spinner>\r\n {{sendingLabel}}...\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"indicatorState === 'error'\">\r\n <div class=\"error-message\" [class.expanded]=\"expandError\" [matTooltip]=\"sendError.message\" (click)=\"alertError()\">\r\n <mat-icon *ngIf=\"sendError\">error</mat-icon>\r\n {{sendError.message}}\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <div class=\"spacer\"></div>\r\n <div class=\"custom\">\r\n <ng-content></ng-content>\r\n </div>\r\n <banta-attachment-button \r\n *ngIf=\"allowAttachments\"\r\n (addedAttachment)=\"addedAttachment($event)\"\r\n (attachmentError)=\"attachmentError($event)\"\r\n ></banta-attachment-button>\r\n <emoji-selector-button (selected)=\"insertEmoji($event)\"></emoji-selector-button>\r\n </div>\r\n \r\n </div>\r\n <div #autocompleteContainer class=\"autocomplete-container\">\r\n <div #autocomplete class=\"autocomplete\" [class.visible]=\"autocompleteVisible\">\r\n\r\n <div>\r\n <strong>{{completionPrefix}}</strong>...\r\n </div>\r\n <a\r\n mat-button\r\n *ngFor=\"let option of autocompleteOptions; index as index\"\r\n (click)=\"activateAutoComplete(option)\"\r\n [class.active]=\"autoCompleteSelected === index\"\r\n >\r\n {{option.label}}\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <banta-attachments \r\n [attachments]=\"chatMessageAttachments\"\r\n [editing]=\"true\"\r\n (remove)=\"removeAttachment($event)\"\r\n ></banta-attachments>\r\n </div>\r\n </div>\r\n <div class=\"actions\">\r\n <ng-container *ngIf=\"!user\">\r\n <button\r\n mat-raised-button\r\n color=\"primary\"\r\n type=\"button\"\r\n (click)=\"showSignIn()\"\r\n >{{signInLabel}}</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"user\">\r\n <button\r\n mat-raised-button\r\n class=\"send\"\r\n color=\"primary\"\r\n [disabled]=\"!sendButtonEnabled\"\r\n >\r\n <ng-container *ngIf=\"buttonState === 'send'\">\r\n <mat-icon>chevron_right</mat-icon>\r\n <span class=\"label\">{{sendLabel}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"buttonState === 'sending'\">\r\n <mat-spinner class=\"icon\" diameter=\"18\" strokeWidth=\"2\"></mat-spinner>\r\n <span class=\"label\">{{sendingLabel}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"buttonState === 'signing-in'\">\r\n <mat-spinner class=\"icon\" diameter=\"18\" strokeWidth=\"2\"></mat-spinner>\r\n {{signingInLabel}}\r\n </ng-container>\r\n <ng-container *ngIf=\"buttonState === 'permission-denied'\">\r\n {{permissionDeniedLabel}}\r\n </ng-container>\r\n </button>\r\n </ng-container>\r\n </div>\r\n</form>", styles: ["@keyframes comment-field-appear{0%{transform:translateY(128px);opacity:0}to{transform:translate(0);opacity:1}}:host{margin:0 2em 0 0;display:block;animation-name:comment-field-appear;animation-duration:.8s;animation-delay:.4s;animation-fill-mode:both;position:relative;z-index:20}.avatar-container{width:calc(48px + 1.75em);display:flex;justify-content:flex-end;flex-shrink:0}.avatar-container .avatar{width:48px;height:48px;background:black;border-radius:100%;background-size:cover;background-repeat:no-repeat;background-position:center;margin-top:.75em;margin-right:.75em}form{display:flex;padding:.5em;align-items:center}form .text-container{position:relative;display:flex;flex-grow:1;min-width:0}form .text-container textarea{font-size:14pt;width:100%}form .text-container textarea[disabled]{opacity:.5}form .text-container mat-spinner.loading{position:absolute;left:.5em;bottom:.5em}form .text-container .options-line{display:flex;align-items:center}form .text-container .options-line>*{flex-shrink:0}form .text-container .options-line .transient-message{display:flex;flex-direction:row;align-items:center;gap:.5em}form .text-container .options-line .error-message{left:.5em;bottom:.5em;color:#683333;overflow-x:hidden;max-width:1.5em;white-space:nowrap;transition:2s max-width ease-in-out;text-overflow:ellipsis;overflow:hidden;flex-shrink:1}form .text-container .options-line .error-message.expanded,form .text-container .options-line .error-message:hover{max-width:100%}form .text-container .options-line .error-message mat-icon{vertical-align:middle}form input[type=text]{background:black;color:#fff;border:1px solid #333;width:100%;height:1em}form .actions{margin-left:1em;flex-shrink:0}form button{display:block;margin:0 0 0 auto}form.new-message{display:flex;align-items:flex-start;min-width:0}form.new-message .field-container{flex-grow:1;display:flex;flex-direction:column;min-width:0}form.new-message mat-form-field{width:100%}form.new-message mat-form-field ::ng-deep .mat-form-field-wrapper{padding-bottom:0}form.new-message button{margin:1.25em 0 0}button.send{min-width:9em}textarea{max-height:7em}.autocomplete-container{width:calc(100% - 2em);position:relative;pointer-events:none;top:-2em}.autocomplete{visibility:hidden;pointer-events:none;position:absolute;background:#333;padding:.5em;display:flex;flex-direction:column;z-index:100}.autocomplete.visible{visibility:visible;pointer-events:initial}.autocomplete a{width:100%;text-align:left}.autocomplete a.active{background:#555}.image-attachments-container{display:flex;gap:20px}.image-attachments-container .image-attachment{width:300px;position:relative;text-align:center}.image-attachments-container .image-attachment.with-border{outline:1px solid #333;padding:1em 0}.image-attachments-container .image-attachment mat-spinner{display:block;margin:0 auto .5em;width:-moz-fit-content;width:fit-content}.image-attachments-container .image-attachment mat-icon.error{display:block;font-size:48px;width:48px;height:48px;margin:0 auto .5em}.image-attachments-container .image-attachment .error{color:#b76363}.image-attachments-container .image-attachment img{width:300px;border-radius:10px}.image-attachments-container .image-attachment .remove-img{position:absolute;right:10px;top:10px;margin:0}.field-row,.card-attachment{position:relative}.card-attachment a{display:flex;align-items:flex-start;gap:1em;width:100%;border:1px solid #666;border-radius:4px;padding:2em;box-sizing:border-box;background-color:#191919}.card-attachment a img{width:300px;aspect-ratio:16/9;-o-object-fit:cover;object-fit:cover;border-radius:10px}.card-attachment a h1{margin:0;font-size:30px}.card-attachment .remove-img{position:absolute;right:10px;top:10px;margin:0}@media (max-width: 500px){:host{margin:0}.avatar-container{display:none;width:auto;flex-shrink:0}.avatar-container .avatar{width:32px;height:32px;margin-top:1.5em}:host:not(.can-comment) mat-form-field.message-field{display:none}:host:not(.can-comment) .text-container{display:none}:host.can-comment button.send .label{display:none}button.send{min-width:auto;margin-top:1.5em}}:host-context(.banta-mobile) :host{margin:0}:host-context(.banta-mobile) .avatar-container{display:none;width:auto;flex-shrink:0}:host-context(.banta-mobile) .avatar-container .avatar{width:32px;height:32px;margin-top:1.5em}:host-context(.banta-mobile) :host:not(.can-comment) mat-form-field.message-field{display:none}:host-context(.banta-mobile) :host:not(.can-comment) .text-container{display:none}:host-context(.banta-mobile) :host.can-comment button.send .label{display:none}:host-context(.banta-mobile) button.send{min-width:auto;margin-top:1.5em}\n"] }]
8644
- }], ctorParameters: function () { return [{ type: ChatBackendBase }]; }, propDecorators: { source: [{
8588
+ args: [{ selector: 'banta-comment-field', template: "<form class=\"new-message\" (submit)=\"sendMessage()\">\r\n <div class=\"avatar-container\">\r\n <a href=\"javascript:;\"\r\n class=\"avatar\"\r\n (click)=\"showEditAvatar()\"\r\n [style.background-image]=\"'url(' + userAvatarUrl + ')'\"\r\n ></a>\r\n </div>\r\n <div class=\"text-container\">\r\n <div class=\"field-container\">\r\n <div class=\"field-row\">\r\n <mat-form-field class=\"message-field\" appearance=\"outline\" floatLabel=\"always\">\r\n <mat-label>{{label}}</mat-label>\r\n <textarea\r\n #textarea\r\n name=\"message\"\r\n attachmentScraper\r\n [(attachments)]=\"chatMessageAttachments\"\r\n [placeholder]=\"placeholder\"\r\n matInput\r\n cdkTextareaAutosize\r\n [maxlength]=\"maxLength\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n [disabled]=\"sending || readonly\"\r\n [(ngModel)]=\"text\"\r\n autocomplete=\"off\"\r\n ></textarea>\r\n </mat-form-field>\r\n <div class=\"options-line\">\r\n <ng-container *ngIf=\"indicatorState === 'transient'\">\r\n <div class=\"transient-message\" [class.expanded]=\"true\" [matTooltip]=\"transientMessage\" (click)=\"alertError()\">\r\n <mat-spinner [inline]=\"true\" [diameter]=\"15\"></mat-spinner>\r\n {{transientMessage}}\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"indicatorState === 'sending'\">\r\n <div class=\"transient-message\" [class.expanded]=\"true\" (click)=\"alertError()\">\r\n <mat-spinner [inline]=\"true\" [diameter]=\"15\"></mat-spinner>\r\n {{sendingLabel}}...\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"indicatorState === 'error'\">\r\n <div class=\"error-message\" [class.expanded]=\"expandError\" [matTooltip]=\"sendError.message\" (click)=\"alertError()\">\r\n <mat-icon *ngIf=\"sendError\">error</mat-icon>\r\n {{sendError.message}}\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <div class=\"spacer\"></div>\r\n <div class=\"custom\">\r\n <ng-content></ng-content>\r\n </div>\r\n <banta-attachment-button \r\n *ngIf=\"allowAttachments\"\r\n [disabled]=\"readonly\"\r\n (addedAttachment)=\"addedAttachment($event)\"\r\n (attachmentError)=\"attachmentError($event)\"\r\n ></banta-attachment-button>\r\n <emoji-selector-button [disabled]=\"readonly\" (selected)=\"insertEmoji($event)\"></emoji-selector-button>\r\n </div>\r\n \r\n </div>\r\n <div #autocompleteContainer class=\"autocomplete-container\">\r\n <div #autocomplete class=\"autocomplete\" [class.visible]=\"autocompleteVisible\">\r\n\r\n <div>\r\n <strong>{{completionPrefix}}</strong>...\r\n </div>\r\n <a\r\n mat-button\r\n *ngFor=\"let option of autocompleteOptions; index as index\"\r\n (click)=\"activateAutoComplete(option)\"\r\n [class.active]=\"autoCompleteSelected === index\"\r\n >\r\n {{option.label}}\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <banta-attachments \r\n [attachments]=\"chatMessageAttachments\"\r\n [editing]=\"true\"\r\n (remove)=\"removeAttachment($event)\"\r\n ></banta-attachments>\r\n </div>\r\n </div>\r\n <div class=\"actions\">\r\n <ng-container *ngIf=\"!user\">\r\n <button\r\n mat-raised-button\r\n color=\"primary\"\r\n type=\"button\"\r\n (click)=\"showSignIn()\"\r\n >{{signInLabel}}</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"user\">\r\n <button\r\n mat-raised-button\r\n class=\"send\"\r\n color=\"primary\"\r\n [disabled]=\"!sendButtonEnabled\"\r\n >\r\n <ng-container *ngIf=\"buttonState === 'send'\">\r\n <mat-icon>chevron_right</mat-icon>\r\n <span class=\"label\">{{sendLabel}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"buttonState === 'sending'\">\r\n <mat-spinner class=\"icon\" diameter=\"18\" strokeWidth=\"2\"></mat-spinner>\r\n <span class=\"label\">{{sendingLabel}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"buttonState === 'signing-in'\">\r\n <mat-spinner class=\"icon\" diameter=\"18\" strokeWidth=\"2\"></mat-spinner>\r\n {{signingInLabel}}\r\n </ng-container>\r\n <ng-container *ngIf=\"buttonState === 'permission-denied'\">\r\n {{permissionDeniedLabel}}\r\n </ng-container>\r\n </button>\r\n </ng-container>\r\n </div>\r\n</form>", styles: ["@keyframes comment-field-appear{0%{transform:translateY(128px);opacity:0}to{transform:translate(0);opacity:1}}:host{margin:0 2em 0 0;display:block;animation-name:comment-field-appear;animation-duration:.8s;animation-delay:.4s;animation-fill-mode:both;position:relative;z-index:20}.avatar-container{width:calc(48px + 1.75em);display:flex;justify-content:flex-end;flex-shrink:0}.avatar-container .avatar{width:48px;height:48px;background:black;border-radius:100%;background-size:cover;background-repeat:no-repeat;background-position:center;margin-top:.75em;margin-right:.75em}form{display:flex;padding:.5em;align-items:center}form .text-container{position:relative;display:flex;flex-grow:1;min-width:0}form .text-container textarea{font-size:14pt;width:100%}form .text-container textarea[disabled]{opacity:.5}form .text-container mat-spinner.loading{position:absolute;left:.5em;bottom:.5em}form .text-container .options-line{display:flex;align-items:center}form .text-container .options-line>*{flex-shrink:0}form .text-container .options-line .transient-message{display:flex;flex-direction:row;align-items:center;gap:.5em}form .text-container .options-line .error-message{left:.5em;bottom:.5em;color:#683333;overflow-x:hidden;max-width:1.5em;white-space:nowrap;transition:2s max-width ease-in-out;text-overflow:ellipsis;overflow:hidden;flex-shrink:1}form .text-container .options-line .error-message.expanded,form .text-container .options-line .error-message:hover{max-width:100%}form .text-container .options-line .error-message mat-icon{vertical-align:middle}form input[type=text]{background:black;color:#fff;border:1px solid #333;width:100%;height:1em}form .actions{margin-left:1em;flex-shrink:0}form button{display:block;margin:0 0 0 auto}form.new-message{display:flex;align-items:flex-start;min-width:0}form.new-message .field-container{flex-grow:1;display:flex;flex-direction:column;min-width:0}form.new-message mat-form-field{width:100%}form.new-message mat-form-field ::ng-deep .mat-form-field-wrapper{padding-bottom:0}form.new-message button{margin:1.25em 0 0}button.send{min-width:9em}textarea{max-height:7em}.autocomplete-container{width:calc(100% - 2em);position:relative;pointer-events:none;top:-2em}.autocomplete{visibility:hidden;pointer-events:none;position:absolute;background:#333;padding:.5em;display:flex;flex-direction:column;z-index:100}.autocomplete.visible{visibility:visible;pointer-events:initial}.autocomplete a{width:100%;text-align:left}.autocomplete a.active{background:#555}.image-attachments-container{display:flex;gap:20px}.image-attachments-container .image-attachment{width:300px;position:relative;text-align:center}.image-attachments-container .image-attachment.with-border{outline:1px solid #333;padding:1em 0}.image-attachments-container .image-attachment mat-spinner{display:block;margin:0 auto .5em;width:-moz-fit-content;width:fit-content}.image-attachments-container .image-attachment mat-icon.error{display:block;font-size:48px;width:48px;height:48px;margin:0 auto .5em}.image-attachments-container .image-attachment .error{color:#b76363}.image-attachments-container .image-attachment img{width:300px;border-radius:10px}.image-attachments-container .image-attachment .remove-img{position:absolute;right:10px;top:10px;margin:0}.field-row,.card-attachment{position:relative}.card-attachment a{display:flex;align-items:flex-start;gap:1em;width:100%;border:1px solid #666;border-radius:4px;padding:2em;box-sizing:border-box;background-color:#191919}.card-attachment a img{width:300px;aspect-ratio:16/9;-o-object-fit:cover;object-fit:cover;border-radius:10px}.card-attachment a h1{margin:0;font-size:30px}.card-attachment .remove-img{position:absolute;right:10px;top:10px;margin:0}@media (max-width: 500px){:host{margin:0}.avatar-container{display:none;width:auto;flex-shrink:0}.avatar-container .avatar{width:32px;height:32px;margin-top:1.5em}:host:not(.can-comment) mat-form-field.message-field{display:none}:host:not(.can-comment) .text-container{display:none}:host.can-comment button.send .label{display:none}button.send{min-width:auto;margin-top:1.5em}}:host-context(.banta-mobile) :host{margin:0}:host-context(.banta-mobile) .avatar-container{display:none;width:auto;flex-shrink:0}:host-context(.banta-mobile) .avatar-container .avatar{width:32px;height:32px;margin-top:1.5em}:host-context(.banta-mobile) :host:not(.can-comment) mat-form-field.message-field{display:none}:host-context(.banta-mobile) :host:not(.can-comment) .text-container{display:none}:host-context(.banta-mobile) :host.can-comment button.send .label{display:none}:host-context(.banta-mobile) button.send{min-width:auto;margin-top:1.5em}\n"] }]
8589
+ }], propDecorators: { source: [{
8645
8590
  type: Input
8646
8591
  }], user: [{
8647
8592
  type: Input
8648
8593
  }], canComment: [{
8594
+ type: Input
8595
+ }, {
8649
8596
  type: HostBinding,
8650
8597
  args: ['class.can-comment']
8651
- }, {
8652
- type: Input
8653
8598
  }], signInState: [{
8654
8599
  type: Input
8655
8600
  }], allowAttachments: [{
8656
8601
  type: Input
8657
- }], signInSelected: [{
8658
- type: Output
8659
- }], editAvatarSelected: [{
8660
- type: Output
8661
- }], focusChange: [{
8662
- type: Output
8663
8602
  }], transientMessage: [{
8664
8603
  type: Input
8665
8604
  }], sendLabel: [{
@@ -8678,10 +8617,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
8678
8617
  type: Input
8679
8618
  }], placeholder: [{
8680
8619
  type: Input
8681
- }], textChanged: [{
8682
- type: Output
8683
8620
  }], shouldInterceptMessageSend: [{
8684
8621
  type: Input
8622
+ }], hashtags: [{
8623
+ type: Input
8624
+ }], participants: [{
8625
+ type: Input
8626
+ }], genericAvatarUrl: [{
8627
+ type: Input
8628
+ }], url: [{
8629
+ type: Input
8630
+ }], submit: [{
8631
+ type: Input
8632
+ }], readonly: [{
8633
+ type: Input
8634
+ }], signInSelected: [{
8635
+ type: Output
8636
+ }], editAvatarSelected: [{
8637
+ type: Output
8638
+ }], focusChange: [{
8639
+ type: Output
8640
+ }], textChanged: [{
8641
+ type: Output
8642
+ }], permissionDeniedError: [{
8643
+ type: Output
8685
8644
  }], autocompleteEl: [{
8686
8645
  type: ViewChild,
8687
8646
  args: ['autocomplete']
@@ -8691,16 +8650,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
8691
8650
  }], textareaEl: [{
8692
8651
  type: ViewChild,
8693
8652
  args: ['textarea']
8694
- }], hashtags: [{
8695
- type: Input
8696
- }], participants: [{
8697
- type: Input
8698
- }], genericAvatarUrl: [{
8699
- type: Input
8700
- }], permissionDeniedError: [{
8701
- type: Output
8702
- }], submit: [{
8703
- type: Input
8704
8653
  }] } });
8705
8654
 
8706
8655
  /**
@@ -8897,7 +8846,7 @@ class BantaCommentsComponent {
8897
8846
  if (typeof window === 'undefined')
8898
8847
  return;
8899
8848
  setTimeout(() => __awaiter(this, void 0, void 0, function* () {
8900
- console.log(`[banta-comments] Subscribing to topic source '${topicID}'`);
8849
+ console.log(`[Banta/Comments] Subscribing to topic source '${topicID}'`);
8901
8850
  this.source = yield this.backend.getSourceForTopic(topicID, { sortOrder: this.sortOrder, filterMode: this.filterMode });
8902
8851
  this._sourceIsOwned = true;
8903
8852
  }));
@@ -8972,7 +8921,7 @@ class BantaCommentsComponent {
8972
8921
  });
8973
8922
  }
8974
8923
  updateLoading() {
8975
- var _a, _b, _c;
8924
+ var _a, _b;
8976
8925
  if (((_a = this.source) === null || _a === void 0 ? void 0 : _a.state) && !['connecting', 'lost'].includes((_b = this.source) === null || _b === void 0 ? void 0 : _b.state)) {
8977
8926
  clearInterval(this._loadingTimer);
8978
8927
  this.loadingMessage = `Here we go!`;
@@ -8982,7 +8931,7 @@ class BantaCommentsComponent {
8982
8931
  }, 750);
8983
8932
  return true;
8984
8933
  }
8985
- console.log(`[Banta/Loader] State=${(_c = this.source) === null || _c === void 0 ? void 0 : _c.state}`);
8934
+ console.log(`[Banta/Loader] State=${this.source ? this.source.state : 'no-source'}`);
8986
8935
  let messageSwitchTime = 5 * 1000;
8987
8936
  if (this.messageChangedAt + messageSwitchTime < Date.now()) {
8988
8937
  if (this.loadingMessages[this._loadingMessageIndex]) {
@@ -9384,12 +9333,12 @@ class BantaCommentsComponent {
9384
9333
  });
9385
9334
  }
9386
9335
  }
9387
- BantaCommentsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaCommentsComponent, deps: [{ token: ChatBackendBase }, { token: i0.ElementRef }, { token: i2$2.ActivatedRoute }, { token: i3$2.MatSnackBar }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
9388
- BantaCommentsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: BantaCommentsComponent, selector: "banta-comments", inputs: { customMenuItems: "customMenuItems", maxCommentLength: "maxCommentLength", loadingMessages: "loadingMessages", useInlineReplies: "useInlineReplies", signInLabel: "signInLabel", sendLabel: "sendLabel", signingInLabel: "signingInLabel", replyLabel: "replyLabel", sendingLabel: "sendingLabel", permissionDeniedLabel: "permissionDeniedLabel", postCommentLabel: "postCommentLabel", postReplyLabel: "postReplyLabel", allowAttachments: "allowAttachments", fixedHeight: "fixedHeight", maxMessages: "maxMessages", maxVisibleMessages: "maxVisibleMessages", genericAvatarUrl: "genericAvatarUrl", shouldInterceptMessageSend: "shouldInterceptMessageSend", participants: "participants", source: "source", hashtags: "hashtags", topicID: "topicID", sortOrder: "sortOrder", filterMode: "filterMode" }, outputs: { signInSelected: "signInSelected", editAvatarSelected: "editAvatarSelected", permissionDeniedError: "permissionDeniedError", upvoted: "upvoted", reported: "reported", selected: "selected", userSelected: "userSelected", usernameSelected: "usernameSelected", avatarSelected: "avatarSelected", shared: "shared" }, host: { properties: { "class.banta-mobile": "this.isMobileSized" } }, queries: [{ propertyName: "sendReplyOptionsTemplate", first: true, predicate: BantaReplySendOptionsDirective, descendants: true, read: TemplateRef }], viewQueries: [{ propertyName: "commentView", first: true, predicate: ["commentView"], descendants: true }, { propertyName: "threadViewQuery", predicate: CommentViewComponent, descendants: true }], ngImport: i0, template: "<ng-container *ngIf=\"loading\">\r\n <div class=\"loading-screen\" [class.visible]=\"showLoadingScreen\">\r\n <h1>{{loadingTitle}}</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)=\"toggleSelectedMessage(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 [signingInLabel]=\"signingInLabel\"\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 [signInState]=\"source?.signInState\"\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 [signingInLabel]=\"signingInLabel\"\r\n [signInLabel]=\"signInLabel\"\r\n [signInState]=\"source?.signInState\"\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 <mat-menu #filterMenu=\"matMenu\">\r\n <button mat-menu-item *ngFor=\"let filter of filterModes\" (click)=\"filterMode = filter\">\r\n {{filterModeLabels[filter]}}\r\n </button>\r\n </mat-menu>\r\n <mat-menu #sortMenu=\"matMenu\">\r\n <button mat-menu-item *ngFor=\"let sort of sortOrders\" (click)=\"sortOrder = sort\">\r\n {{sortOrderLabels[sort]}}\r\n </button>\r\n </mat-menu>\r\n\r\n <div class=\"settings\">\r\n <button mat-button [matMenuTriggerFor]=\"filterMenu\">\r\n <mat-icon>filter_list</mat-icon>\r\n {{filterModeLabels[filterMode]}}\r\n </button>\r\n <button mat-button [matMenuTriggerFor]=\"sortMenu\">\r\n <mat-icon>sort</mat-icon>\r\n {{sortOrderLabels[sortOrder]}}\r\n </button>\r\n </div>\r\n\r\n <div class=\"loading-comment\" *ngIf=\"loadingSharedComment\">\r\n <h1>Loading the comment you linked to...</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 <div class=\"loading-comment\" *ngIf=\"!loadingSharedComment && lastSharedCommentID\">\r\n <ng-container *ngIf=\"sharedCommentMissing\">\r\n\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n\r\n <h1>\r\n <mat-icon>error</mat-icon>\r\n Uh oh!\r\n </h1>\r\n\r\n <p>The comment you linked to can't be found! It may have been removed.</p>\r\n </ng-container>\r\n <ng-container *ngIf=\"!sharedCommentMissing\">\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n <button mat-button (click)=\"navigateToSharedComment(lastSharedCommentID)\">\r\n <mat-icon>move_down</mat-icon> Jump to shared comment\r\n </button>\r\n </ng-container>\r\n </div>\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 [holdNewMessages]=\"selectedMessageVisible\"\r\n (userSelected)=\"selectMessageUser($event)\"\r\n (sortOrderChanged)=\"sortOrder = $event\"\r\n (filterModeChanged)=\"filterMode = $event\"\r\n (selected)=\"toggleSelectedMessage($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 [enableHoldOnClick]=\"false\"\r\n [holdNewMessages]=\"replyFieldFocused\"\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 [signingInLabel]=\"signingInLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n (signInSelected)=\"showSignIn()\"\r\n [maxLength]=\"maxCommentLength\"\r\n [source]=\"selectedMessageThread\"\r\n [signInState]=\"source?.signInState\"\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 (editAvatarSelected)=\"showEditAvatar()\"\r\n (focusChange)=\"replyFieldFocused = $event\"\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 <div class=\"reconnecting\" *ngIf=\"connectionState === 'lost'\">\r\n <strong>Connection to Live Comments lost.</strong> Reconnecting...\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:flex;flex-direction:column}@keyframes select-comment{0%{transform:scale(1.15)}to{transform:scale(1)}}.focused{animation-name:select-comment;animation-duration:.4s;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:.4s opacity ease-in-out}banta-comment-view.faded{opacity:.25}.loading{display:block;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:.25s ease-in-out opacity}.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:.25s ease-in-out opacity;width:500px;max-width:100%;margin:0 auto}.loading-screen .loading-message.visible{opacity:1}banta-comment-sort{margin:0 0 0 auto;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:black;color:#fff;padding:1em;border-radius:4px;text-align:center;position:relative}.loading-comment a.close{position:absolute;top:1em;right:1em}.loading-comment h1{font-weight:100;text-align:center}.loading-comment mat-spinner{margin:0 auto}.reconnecting{position:sticky;bottom:1em;background:#380a39;color:#926893;padding:1em;z-index:10;border-radius:4px;text-align:center}.settings{display:flex}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i7$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i7$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: CommentComponent, selector: "banta-comment", inputs: ["maxLength", "message", "customMenuItems", "showReplyAction", "permissions", "mine", "editing", "genericAvatarUrl"], outputs: ["loaded", "userSelected", "usernameSelected", "avatarSelected", "reported", "liked", "unliked", "selected", "edited", "deleted", "editStarted", "editEnded", "shared"] }, { kind: "component", type: CommentViewComponent, selector: "banta-comment-view", inputs: ["showEmptyState", "allowReplies", "enableHoldOnClick", "enableHoldOnScroll", "customMenuItems", "fixedHeight", "selectedMessage", "source", "genericAvatarUrl", "maxMessages", "maxVisibleMessages", "newestLast", "holdNewMessages"], outputs: ["selected", "messageEdited", "userSelected", "reported", "liked", "unliked", "usernameSelected", "avatarSelected", "shared", "deleted", "sortOrderChanged", "filterModeChanged"] }, { kind: "component", type: CommentFieldComponent, selector: "banta-comment-field", inputs: ["source", "user", "canComment", "signInState", "allowAttachments", "transientMessage", "sendLabel", "signingInLabel", "sendingLabel", "label", "permissionDeniedLabel", "signInLabel", "maxLength", "placeholder", "shouldInterceptMessageSend", "hashtags", "participants", "genericAvatarUrl", "submit"], outputs: ["signInSelected", "editAvatarSelected", "focusChange", "textChanged", "permissionDeniedError"] }] });
9336
+ BantaCommentsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaCommentsComponent, deps: [{ token: ChatBackendBase }, { token: i0.ElementRef }, { token: i2$3.ActivatedRoute }, { token: i3$2.MatSnackBar }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
9337
+ BantaCommentsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: BantaCommentsComponent, selector: "banta-comments", inputs: { customMenuItems: "customMenuItems", url: "url", maxCommentLength: "maxCommentLength", loadingMessages: "loadingMessages", useInlineReplies: "useInlineReplies", signInLabel: "signInLabel", sendLabel: "sendLabel", signingInLabel: "signingInLabel", replyLabel: "replyLabel", sendingLabel: "sendingLabel", permissionDeniedLabel: "permissionDeniedLabel", postCommentLabel: "postCommentLabel", postReplyLabel: "postReplyLabel", allowAttachments: "allowAttachments", fixedHeight: "fixedHeight", maxMessages: "maxMessages", maxVisibleMessages: "maxVisibleMessages", genericAvatarUrl: "genericAvatarUrl", shouldInterceptMessageSend: "shouldInterceptMessageSend", participants: "participants", source: "source", hashtags: "hashtags", topicID: "topicID", sortOrder: "sortOrder", filterMode: "filterMode" }, outputs: { signInSelected: "signInSelected", editAvatarSelected: "editAvatarSelected", permissionDeniedError: "permissionDeniedError", upvoted: "upvoted", reported: "reported", selected: "selected", userSelected: "userSelected", usernameSelected: "usernameSelected", avatarSelected: "avatarSelected", shared: "shared" }, host: { properties: { "class.banta-mobile": "this.isMobileSized" } }, queries: [{ propertyName: "sendReplyOptionsTemplate", first: true, predicate: BantaReplySendOptionsDirective, descendants: true, read: TemplateRef }], viewQueries: [{ propertyName: "commentView", first: true, predicate: ["commentView"], descendants: true }, { propertyName: "threadViewQuery", predicate: CommentViewComponent, descendants: true }], ngImport: i0, template: "<ng-container *ngIf=\"loading\">\r\n <div class=\"loading-screen\" [class.visible]=\"showLoadingScreen\">\r\n <h1>{{loadingTitle}}</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 [readonly]=\"source?.readonly\"\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)=\"toggleSelectedMessage(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 [url]=\"url\"\r\n [sendLabel]=\"replyLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signingInLabel]=\"signingInLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [readonly]=\"source?.readonly\"\r\n (signInSelected)=\"showSignIn()\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n [source]=\"selectedMessageThread\"\r\n [maxLength]=\"maxCommentLength\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInState]=\"source?.signInState\"\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 [url]=\"url\"\r\n [source]=\"source\"\r\n [user]=\"user\"\r\n [sendLabel]=\"sendLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signingInLabel]=\"signingInLabel\"\r\n [signInLabel]=\"signInLabel\"\r\n [signInState]=\"source?.signInState\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [label]=\"postCommentLabel\"\r\n [maxLength]=\"maxCommentLength\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [submit]=\"sendMessage\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n [readonly]=\"source?.readonly\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (signInSelected)=\"showSignIn()\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n >\r\n \r\n </banta-comment-field>\r\n\r\n <mat-menu #filterMenu=\"matMenu\">\r\n <button mat-menu-item *ngFor=\"let filter of filterModes\" (click)=\"filterMode = filter\">\r\n {{filterModeLabels[filter]}}\r\n </button>\r\n </mat-menu>\r\n <mat-menu #sortMenu=\"matMenu\">\r\n <button mat-menu-item *ngFor=\"let sort of sortOrders\" (click)=\"sortOrder = sort\">\r\n {{sortOrderLabels[sort]}}\r\n </button>\r\n </mat-menu>\r\n\r\n <div class=\"settings\">\r\n <button mat-button [matMenuTriggerFor]=\"filterMenu\">\r\n <mat-icon>filter_list</mat-icon>\r\n {{filterModeLabels[filterMode]}}\r\n </button>\r\n <button mat-button [matMenuTriggerFor]=\"sortMenu\">\r\n <mat-icon>sort</mat-icon>\r\n {{sortOrderLabels[sortOrder]}}\r\n </button>\r\n </div>\r\n\r\n <div class=\"loading-comment\" *ngIf=\"loadingSharedComment\">\r\n <h1>Loading the comment you linked to...</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 <div class=\"loading-comment\" *ngIf=\"!loadingSharedComment && lastSharedCommentID\">\r\n <ng-container *ngIf=\"sharedCommentMissing\">\r\n\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n\r\n <h1>\r\n <mat-icon>error</mat-icon>\r\n Uh oh!\r\n </h1>\r\n\r\n <p>The comment you linked to can't be found! It may have been removed.</p>\r\n </ng-container>\r\n <ng-container *ngIf=\"!sharedCommentMissing\">\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n <button mat-button (click)=\"navigateToSharedComment(lastSharedCommentID)\">\r\n <mat-icon>move_down</mat-icon> Jump to shared comment\r\n </button>\r\n </ng-container>\r\n </div>\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 [holdNewMessages]=\"selectedMessageVisible\"\r\n (userSelected)=\"selectMessageUser($event)\"\r\n (sortOrderChanged)=\"sortOrder = $event\"\r\n (filterModeChanged)=\"filterMode = $event\"\r\n (selected)=\"toggleSelectedMessage($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 [enableHoldOnClick]=\"false\"\r\n [holdNewMessages]=\"replyFieldFocused\"\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 [url]=\"url\"\r\n [sendLabel]=\"replyLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signingInLabel]=\"signingInLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n (signInSelected)=\"showSignIn()\"\r\n [maxLength]=\"maxCommentLength\"\r\n [source]=\"selectedMessageThread\"\r\n [signInState]=\"source?.signInState\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n [readonly]=\"source?.readonly\"\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 (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (focusChange)=\"replyFieldFocused = $event\"\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 <div class=\"reconnecting\" *ngIf=\"connectionState === 'lost'\">\r\n <strong>Connection to Live Comments lost.</strong> Reconnecting...\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:flex;flex-direction:column}@keyframes select-comment{0%{transform:scale(1.15)}to{transform:scale(1)}}.focused{animation-name:select-comment;animation-duration:.4s;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:.4s opacity ease-in-out}banta-comment-view.faded{opacity:.25}.loading{display:block;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:.25s ease-in-out opacity}.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:.25s ease-in-out opacity;width:500px;max-width:100%;margin:0 auto}.loading-screen .loading-message.visible{opacity:1}banta-comment-sort{margin:0 0 0 auto;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:black;color:#fff;padding:1em;border-radius:4px;text-align:center;position:relative}.loading-comment a.close{position:absolute;top:1em;right:1em}.loading-comment h1{font-weight:100;text-align:center}.loading-comment mat-spinner{margin:0 auto}.reconnecting{position:sticky;bottom:1em;background:#380a39;color:#926893;padding:1em;z-index:10;border-radius:4px;text-align:center}.settings{display:flex}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i7$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i7$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: CommentComponent, selector: "banta-comment", inputs: ["message", "customMenuItems", "showReplyAction", "maxLength", "permissions", "mine", "editing", "genericAvatarUrl", "readonly"], outputs: ["liked", "unliked", "selected", "edited", "deleted", "editStarted", "editEnded", "shared", "userSelected", "usernameSelected", "avatarSelected", "reported", "loaded"] }, { kind: "component", type: CommentViewComponent, selector: "banta-comment-view", inputs: ["source", "maxMessages", "maxVisibleMessages", "newestLast", "holdNewMessages", "showEmptyState", "allowReplies", "enableHoldOnClick", "enableHoldOnScroll", "customMenuItems", "fixedHeight", "selectedMessage", "genericAvatarUrl"], outputs: ["userSelected", "reported", "liked", "unliked", "usernameSelected", "avatarSelected", "shared", "deleted", "selected", "messageEdited", "sortOrderChanged", "filterModeChanged"] }, { kind: "component", type: CommentFieldComponent, selector: "banta-comment-field", inputs: ["source", "user", "canComment", "signInState", "allowAttachments", "transientMessage", "sendLabel", "signingInLabel", "sendingLabel", "label", "permissionDeniedLabel", "signInLabel", "maxLength", "placeholder", "shouldInterceptMessageSend", "hashtags", "participants", "genericAvatarUrl", "url", "submit", "readonly"], outputs: ["signInSelected", "editAvatarSelected", "focusChange", "textChanged", "permissionDeniedError"] }] });
9389
9338
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaCommentsComponent, decorators: [{
9390
9339
  type: Component,
9391
- args: [{ selector: 'banta-comments', template: "<ng-container *ngIf=\"loading\">\r\n <div class=\"loading-screen\" [class.visible]=\"showLoadingScreen\">\r\n <h1>{{loadingTitle}}</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)=\"toggleSelectedMessage(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 [signingInLabel]=\"signingInLabel\"\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 [signInState]=\"source?.signInState\"\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 [signingInLabel]=\"signingInLabel\"\r\n [signInLabel]=\"signInLabel\"\r\n [signInState]=\"source?.signInState\"\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 <mat-menu #filterMenu=\"matMenu\">\r\n <button mat-menu-item *ngFor=\"let filter of filterModes\" (click)=\"filterMode = filter\">\r\n {{filterModeLabels[filter]}}\r\n </button>\r\n </mat-menu>\r\n <mat-menu #sortMenu=\"matMenu\">\r\n <button mat-menu-item *ngFor=\"let sort of sortOrders\" (click)=\"sortOrder = sort\">\r\n {{sortOrderLabels[sort]}}\r\n </button>\r\n </mat-menu>\r\n\r\n <div class=\"settings\">\r\n <button mat-button [matMenuTriggerFor]=\"filterMenu\">\r\n <mat-icon>filter_list</mat-icon>\r\n {{filterModeLabels[filterMode]}}\r\n </button>\r\n <button mat-button [matMenuTriggerFor]=\"sortMenu\">\r\n <mat-icon>sort</mat-icon>\r\n {{sortOrderLabels[sortOrder]}}\r\n </button>\r\n </div>\r\n\r\n <div class=\"loading-comment\" *ngIf=\"loadingSharedComment\">\r\n <h1>Loading the comment you linked to...</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 <div class=\"loading-comment\" *ngIf=\"!loadingSharedComment && lastSharedCommentID\">\r\n <ng-container *ngIf=\"sharedCommentMissing\">\r\n\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n\r\n <h1>\r\n <mat-icon>error</mat-icon>\r\n Uh oh!\r\n </h1>\r\n\r\n <p>The comment you linked to can't be found! It may have been removed.</p>\r\n </ng-container>\r\n <ng-container *ngIf=\"!sharedCommentMissing\">\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n <button mat-button (click)=\"navigateToSharedComment(lastSharedCommentID)\">\r\n <mat-icon>move_down</mat-icon> Jump to shared comment\r\n </button>\r\n </ng-container>\r\n </div>\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 [holdNewMessages]=\"selectedMessageVisible\"\r\n (userSelected)=\"selectMessageUser($event)\"\r\n (sortOrderChanged)=\"sortOrder = $event\"\r\n (filterModeChanged)=\"filterMode = $event\"\r\n (selected)=\"toggleSelectedMessage($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 [enableHoldOnClick]=\"false\"\r\n [holdNewMessages]=\"replyFieldFocused\"\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 [signingInLabel]=\"signingInLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n (signInSelected)=\"showSignIn()\"\r\n [maxLength]=\"maxCommentLength\"\r\n [source]=\"selectedMessageThread\"\r\n [signInState]=\"source?.signInState\"\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 (editAvatarSelected)=\"showEditAvatar()\"\r\n (focusChange)=\"replyFieldFocused = $event\"\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 <div class=\"reconnecting\" *ngIf=\"connectionState === 'lost'\">\r\n <strong>Connection to Live Comments lost.</strong> Reconnecting...\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:flex;flex-direction:column}@keyframes select-comment{0%{transform:scale(1.15)}to{transform:scale(1)}}.focused{animation-name:select-comment;animation-duration:.4s;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:.4s opacity ease-in-out}banta-comment-view.faded{opacity:.25}.loading{display:block;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:.25s ease-in-out opacity}.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:.25s ease-in-out opacity;width:500px;max-width:100%;margin:0 auto}.loading-screen .loading-message.visible{opacity:1}banta-comment-sort{margin:0 0 0 auto;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:black;color:#fff;padding:1em;border-radius:4px;text-align:center;position:relative}.loading-comment a.close{position:absolute;top:1em;right:1em}.loading-comment h1{font-weight:100;text-align:center}.loading-comment mat-spinner{margin:0 auto}.reconnecting{position:sticky;bottom:1em;background:#380a39;color:#926893;padding:1em;z-index:10;border-radius:4px;text-align:center}.settings{display:flex}\n"] }]
9392
- }], ctorParameters: function () { return [{ type: ChatBackendBase }, { type: i0.ElementRef }, { type: i2$2.ActivatedRoute }, { type: i3$2.MatSnackBar }, { type: i0.NgZone }]; }, propDecorators: { isMobileSized: [{
9340
+ args: [{ selector: 'banta-comments', template: "<ng-container *ngIf=\"loading\">\r\n <div class=\"loading-screen\" [class.visible]=\"showLoadingScreen\">\r\n <h1>{{loadingTitle}}</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 [readonly]=\"source?.readonly\"\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)=\"toggleSelectedMessage(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 [url]=\"url\"\r\n [sendLabel]=\"replyLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signingInLabel]=\"signingInLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [readonly]=\"source?.readonly\"\r\n (signInSelected)=\"showSignIn()\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n [source]=\"selectedMessageThread\"\r\n [maxLength]=\"maxCommentLength\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInState]=\"source?.signInState\"\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 [url]=\"url\"\r\n [source]=\"source\"\r\n [user]=\"user\"\r\n [sendLabel]=\"sendLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signingInLabel]=\"signingInLabel\"\r\n [signInLabel]=\"signInLabel\"\r\n [signInState]=\"source?.signInState\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [label]=\"postCommentLabel\"\r\n [maxLength]=\"maxCommentLength\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [submit]=\"sendMessage\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n [readonly]=\"source?.readonly\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (signInSelected)=\"showSignIn()\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n >\r\n \r\n </banta-comment-field>\r\n\r\n <mat-menu #filterMenu=\"matMenu\">\r\n <button mat-menu-item *ngFor=\"let filter of filterModes\" (click)=\"filterMode = filter\">\r\n {{filterModeLabels[filter]}}\r\n </button>\r\n </mat-menu>\r\n <mat-menu #sortMenu=\"matMenu\">\r\n <button mat-menu-item *ngFor=\"let sort of sortOrders\" (click)=\"sortOrder = sort\">\r\n {{sortOrderLabels[sort]}}\r\n </button>\r\n </mat-menu>\r\n\r\n <div class=\"settings\">\r\n <button mat-button [matMenuTriggerFor]=\"filterMenu\">\r\n <mat-icon>filter_list</mat-icon>\r\n {{filterModeLabels[filterMode]}}\r\n </button>\r\n <button mat-button [matMenuTriggerFor]=\"sortMenu\">\r\n <mat-icon>sort</mat-icon>\r\n {{sortOrderLabels[sortOrder]}}\r\n </button>\r\n </div>\r\n\r\n <div class=\"loading-comment\" *ngIf=\"loadingSharedComment\">\r\n <h1>Loading the comment you linked to...</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 <div class=\"loading-comment\" *ngIf=\"!loadingSharedComment && lastSharedCommentID\">\r\n <ng-container *ngIf=\"sharedCommentMissing\">\r\n\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n\r\n <h1>\r\n <mat-icon>error</mat-icon>\r\n Uh oh!\r\n </h1>\r\n\r\n <p>The comment you linked to can't be found! It may have been removed.</p>\r\n </ng-container>\r\n <ng-container *ngIf=\"!sharedCommentMissing\">\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n <button mat-button (click)=\"navigateToSharedComment(lastSharedCommentID)\">\r\n <mat-icon>move_down</mat-icon> Jump to shared comment\r\n </button>\r\n </ng-container>\r\n </div>\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 [holdNewMessages]=\"selectedMessageVisible\"\r\n (userSelected)=\"selectMessageUser($event)\"\r\n (sortOrderChanged)=\"sortOrder = $event\"\r\n (filterModeChanged)=\"filterMode = $event\"\r\n (selected)=\"toggleSelectedMessage($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 [enableHoldOnClick]=\"false\"\r\n [holdNewMessages]=\"replyFieldFocused\"\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 [url]=\"url\"\r\n [sendLabel]=\"replyLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signingInLabel]=\"signingInLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n (signInSelected)=\"showSignIn()\"\r\n [maxLength]=\"maxCommentLength\"\r\n [source]=\"selectedMessageThread\"\r\n [signInState]=\"source?.signInState\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n [readonly]=\"source?.readonly\"\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 (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (focusChange)=\"replyFieldFocused = $event\"\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 <div class=\"reconnecting\" *ngIf=\"connectionState === 'lost'\">\r\n <strong>Connection to Live Comments lost.</strong> Reconnecting...\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:flex;flex-direction:column}@keyframes select-comment{0%{transform:scale(1.15)}to{transform:scale(1)}}.focused{animation-name:select-comment;animation-duration:.4s;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:.4s opacity ease-in-out}banta-comment-view.faded{opacity:.25}.loading{display:block;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:.25s ease-in-out opacity}.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:.25s ease-in-out opacity;width:500px;max-width:100%;margin:0 auto}.loading-screen .loading-message.visible{opacity:1}banta-comment-sort{margin:0 0 0 auto;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:black;color:#fff;padding:1em;border-radius:4px;text-align:center;position:relative}.loading-comment a.close{position:absolute;top:1em;right:1em}.loading-comment h1{font-weight:100;text-align:center}.loading-comment mat-spinner{margin:0 auto}.reconnecting{position:sticky;bottom:1em;background:#380a39;color:#926893;padding:1em;z-index:10;border-radius:4px;text-align:center}.settings{display:flex}\n"] }]
9341
+ }], ctorParameters: function () { return [{ type: ChatBackendBase }, { type: i0.ElementRef }, { type: i2$3.ActivatedRoute }, { type: i3$2.MatSnackBar }, { type: i0.NgZone }]; }, propDecorators: { isMobileSized: [{
9393
9342
  type: HostBinding,
9394
9343
  args: ['class.banta-mobile']
9395
9344
  }], sendReplyOptionsTemplate: [{
@@ -9397,6 +9346,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
9397
9346
  args: [BantaReplySendOptionsDirective, { read: TemplateRef }]
9398
9347
  }], customMenuItems: [{
9399
9348
  type: Input
9349
+ }], url: [{
9350
+ type: Input
9400
9351
  }], maxCommentLength: [{
9401
9352
  type: Input
9402
9353
  }], loadingMessages: [{
@@ -9803,7 +9754,7 @@ class BantaChatComponent {
9803
9754
  return true;
9804
9755
  }
9805
9756
  sendMessage() {
9806
- var _a;
9757
+ var _a, _b;
9807
9758
  return __awaiter(this, void 0, void 0, function* () {
9808
9759
  if (!this.source)
9809
9760
  return;
@@ -9815,11 +9766,11 @@ class BantaChatComponent {
9815
9766
  user: null,
9816
9767
  sentAt: Date.now(),
9817
9768
  likes: 0,
9818
- url: typeof window !== 'undefined' ? location.href : undefined,
9769
+ url: (_a = this.url) !== null && _a !== void 0 ? _a : (typeof window !== 'undefined' ? location.href : undefined),
9819
9770
  message: text
9820
9771
  };
9821
9772
  try {
9822
- const intercept = yield ((_a = this.shouldInterceptMessageSend) === null || _a === void 0 ? void 0 : _a.call(this, message, this.source));
9773
+ const intercept = yield ((_b = this.shouldInterceptMessageSend) === null || _b === void 0 ? void 0 : _b.call(this, message, this.source));
9823
9774
  if (!intercept) {
9824
9775
  yield this.source.send(message);
9825
9776
  }
@@ -9834,12 +9785,14 @@ class BantaChatComponent {
9834
9785
  }
9835
9786
  }
9836
9787
  BantaChatComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaChatComponent, deps: [{ token: ChatBackendBase }], target: i0.ɵɵFactoryTarget.Component });
9837
- BantaChatComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: BantaChatComponent, selector: "banta-chat", inputs: { shouldInterceptMessageSend: "shouldInterceptMessageSend", source: "source", topicID: "topicID", signInLabel: "signInLabel", sendLabel: "sendLabel", permissionDeniedLabel: "permissionDeniedLabel", messageFieldPlaceholder: "messageFieldPlaceholder", emptyLabel: "emptyLabel" }, outputs: { selected: "selected", reported: "reported", upvoted: "upvoted", userSelected: "userSelected", permissionDeniedError: "permissionDeniedError", signInSelected: "signInSelected", received: "received" }, viewQueries: [{ propertyName: "chatView", first: true, predicate: ["chatView"], descendants: true }, { propertyName: "inputElementRef", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<banta-chat-view \r\n #chatView\r\n [source]=\"source\"\r\n [emptyLabel]=\"emptyLabel\"\r\n (upvoted)=\"upvote($event)\"\r\n (reported)=\"report($event)\"\r\n (selected)=\"select($event)\"\r\n (received)=\"onReceived($event)\"\r\n (userSelected)=\"selectUser($event)\"\r\n ></banta-chat-view>\r\n\r\n<form class=\"new-message\" (submit)=\"sendMessage()\">\r\n \r\n <div class=\"entry-container\">\r\n <input\r\n #input\r\n type=\"text\"\r\n name=\"message\" \r\n autocomplete=\"off\"\r\n enterkeyhint=\"send\"\r\n [placeholder]=\"messageFieldPlaceholder\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [(ngModel)]=\"newMessage.message\" />\r\n \r\n <emoji-selector-button\r\n (selected)=\"insertEmoji($event)\"\r\n overlayY=\"bottom\"\r\n overlayX=\"end\"\r\n originY=\"top\"\r\n ></emoji-selector-button>\r\n </div>\r\n\r\n <div class=\"actions\">\r\n\r\n <ng-container *ngIf=\"!user\">\r\n <button type=\"button\" (click)=\"showSignIn()\" mat-raised-button color=\"primary\">{{signInLabel}}</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"user\">\r\n <button *ngIf=\"canChat\" [disabled]=\"!newMessage.message\" mat-raised-button color=\"primary\">{{sendLabel}}</button>\r\n <button *ngIf=\"!canChat\" type=\"button\" (click)=\"sendPermissionError()\" mat-raised-button color=\"primary\">{{permissionDeniedLabel}}</button>\r\n </ng-container>\r\n </div>\r\n</form>", styles: [":host{display:flex;flex-direction:column;border-radius:5px;padding:10px;flex-grow:1;font-size:10pt;min-height:1px}.entry-container{display:flex;flex-direction:row;flex-grow:1;position:relative}.entry-container emoji-selector-button{position:absolute;right:0;top:.15em}.entry-container input{height:2.6em;font-size:12pt;padding-left:1em}.entry-container input:-webkit-autofill,.entry-container input:-webkit-autofill:hover,.entry-container input:-webkit-autofill:focus{outline:1px solid #9da302;-webkit-text-fill-color:#9da302;-webkit-box-shadow:0 0 0px 1000px #211e07 inset;-webkit-transition:background-color 5000s ease-in-out 0s;transition:background-color 5000s ease-in-out 0s;caret-color:#9da302}.entry-container emoji-selector-panel{pointer-events:none;opacity:0;position:absolute;bottom:3.5em;right:0}.entry-container emoji-selector-panel.visible{opacity:1;pointer-events:initial}form{display:flex;padding:.5em 0;align-items:center}form textarea{font-size:14pt;background:black;color:#fff;border:1px solid #333;min-height:6em;width:100%}form input[type=text]{background:white;color:#000;border:1px solid #ccc;width:100%;height:2.5em}form .actions{margin-left:1em}form button{display:block;margin:0 0 0 auto}:host-context(.mat-dark-theme) form input[type=text]{background:black;color:#fff;border:1px solid #333}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: EmojiSelectorButtonComponent, selector: "emoji-selector-button", inputs: ["overlayX", "overlayY", "originX", "originY"], outputs: ["selected"] }, { kind: "component", type: ChatViewComponent, selector: "banta-chat-view", inputs: ["source", "maxMessages", "emptyLabel"], outputs: ["selected", "userSelected", "reported", "upvoted", "received"] }] });
9788
+ BantaChatComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: BantaChatComponent, selector: "banta-chat", inputs: { shouldInterceptMessageSend: "shouldInterceptMessageSend", url: "url", source: "source", topicID: "topicID", signInLabel: "signInLabel", sendLabel: "sendLabel", permissionDeniedLabel: "permissionDeniedLabel", messageFieldPlaceholder: "messageFieldPlaceholder", emptyLabel: "emptyLabel" }, outputs: { selected: "selected", reported: "reported", upvoted: "upvoted", userSelected: "userSelected", permissionDeniedError: "permissionDeniedError", signInSelected: "signInSelected", received: "received" }, viewQueries: [{ propertyName: "chatView", first: true, predicate: ["chatView"], descendants: true }, { propertyName: "inputElementRef", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<banta-chat-view \r\n #chatView\r\n [source]=\"source\"\r\n [emptyLabel]=\"emptyLabel\"\r\n (upvoted)=\"upvote($event)\"\r\n (reported)=\"report($event)\"\r\n (selected)=\"select($event)\"\r\n (received)=\"onReceived($event)\"\r\n (userSelected)=\"selectUser($event)\"\r\n ></banta-chat-view>\r\n\r\n<form class=\"new-message\" (submit)=\"sendMessage()\">\r\n \r\n <div class=\"entry-container\">\r\n <input\r\n #input\r\n type=\"text\"\r\n name=\"message\" \r\n autocomplete=\"off\"\r\n enterkeyhint=\"send\"\r\n [placeholder]=\"messageFieldPlaceholder\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [(ngModel)]=\"newMessage.message\" />\r\n \r\n <emoji-selector-button\r\n (selected)=\"insertEmoji($event)\"\r\n overlayY=\"bottom\"\r\n overlayX=\"end\"\r\n originY=\"top\"\r\n ></emoji-selector-button>\r\n </div>\r\n\r\n <div class=\"actions\">\r\n\r\n <ng-container *ngIf=\"!user\">\r\n <button type=\"button\" (click)=\"showSignIn()\" mat-raised-button color=\"primary\">{{signInLabel}}</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"user\">\r\n <button *ngIf=\"canChat\" [disabled]=\"!newMessage.message\" mat-raised-button color=\"primary\">{{sendLabel}}</button>\r\n <button *ngIf=\"!canChat\" type=\"button\" (click)=\"sendPermissionError()\" mat-raised-button color=\"primary\">{{permissionDeniedLabel}}</button>\r\n </ng-container>\r\n </div>\r\n</form>", styles: [":host{display:flex;flex-direction:column;border-radius:5px;padding:10px;flex-grow:1;font-size:10pt;min-height:1px}.entry-container{display:flex;flex-direction:row;flex-grow:1;position:relative}.entry-container emoji-selector-button{position:absolute;right:0;top:.15em}.entry-container input{height:2.6em;font-size:12pt;padding-left:1em}.entry-container input:-webkit-autofill,.entry-container input:-webkit-autofill:hover,.entry-container input:-webkit-autofill:focus{outline:1px solid #9da302;-webkit-text-fill-color:#9da302;-webkit-box-shadow:0 0 0px 1000px #211e07 inset;-webkit-transition:background-color 5000s ease-in-out 0s;transition:background-color 5000s ease-in-out 0s;caret-color:#9da302}.entry-container emoji-selector-panel{pointer-events:none;opacity:0;position:absolute;bottom:3.5em;right:0}.entry-container emoji-selector-panel.visible{opacity:1;pointer-events:initial}form{display:flex;padding:.5em 0;align-items:center}form textarea{font-size:14pt;background:black;color:#fff;border:1px solid #333;min-height:6em;width:100%}form input[type=text]{background:white;color:#000;border:1px solid #ccc;width:100%;height:2.5em}form .actions{margin-left:1em}form button{display:block;margin:0 0 0 auto}:host-context(.mat-dark-theme) form input[type=text]{background:black;color:#fff;border:1px solid #333}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: EmojiSelectorButtonComponent, selector: "emoji-selector-button", inputs: ["disabled", "overlayX", "overlayY", "originX", "originY"], outputs: ["selected"] }, { kind: "component", type: ChatViewComponent, selector: "banta-chat-view", inputs: ["source", "maxMessages", "emptyLabel"], outputs: ["selected", "userSelected", "reported", "upvoted", "received"] }] });
9838
9789
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaChatComponent, decorators: [{
9839
9790
  type: Component,
9840
9791
  args: [{ selector: 'banta-chat', template: "<banta-chat-view \r\n #chatView\r\n [source]=\"source\"\r\n [emptyLabel]=\"emptyLabel\"\r\n (upvoted)=\"upvote($event)\"\r\n (reported)=\"report($event)\"\r\n (selected)=\"select($event)\"\r\n (received)=\"onReceived($event)\"\r\n (userSelected)=\"selectUser($event)\"\r\n ></banta-chat-view>\r\n\r\n<form class=\"new-message\" (submit)=\"sendMessage()\">\r\n \r\n <div class=\"entry-container\">\r\n <input\r\n #input\r\n type=\"text\"\r\n name=\"message\" \r\n autocomplete=\"off\"\r\n enterkeyhint=\"send\"\r\n [placeholder]=\"messageFieldPlaceholder\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [(ngModel)]=\"newMessage.message\" />\r\n \r\n <emoji-selector-button\r\n (selected)=\"insertEmoji($event)\"\r\n overlayY=\"bottom\"\r\n overlayX=\"end\"\r\n originY=\"top\"\r\n ></emoji-selector-button>\r\n </div>\r\n\r\n <div class=\"actions\">\r\n\r\n <ng-container *ngIf=\"!user\">\r\n <button type=\"button\" (click)=\"showSignIn()\" mat-raised-button color=\"primary\">{{signInLabel}}</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"user\">\r\n <button *ngIf=\"canChat\" [disabled]=\"!newMessage.message\" mat-raised-button color=\"primary\">{{sendLabel}}</button>\r\n <button *ngIf=\"!canChat\" type=\"button\" (click)=\"sendPermissionError()\" mat-raised-button color=\"primary\">{{permissionDeniedLabel}}</button>\r\n </ng-container>\r\n </div>\r\n</form>", styles: [":host{display:flex;flex-direction:column;border-radius:5px;padding:10px;flex-grow:1;font-size:10pt;min-height:1px}.entry-container{display:flex;flex-direction:row;flex-grow:1;position:relative}.entry-container emoji-selector-button{position:absolute;right:0;top:.15em}.entry-container input{height:2.6em;font-size:12pt;padding-left:1em}.entry-container input:-webkit-autofill,.entry-container input:-webkit-autofill:hover,.entry-container input:-webkit-autofill:focus{outline:1px solid #9da302;-webkit-text-fill-color:#9da302;-webkit-box-shadow:0 0 0px 1000px #211e07 inset;-webkit-transition:background-color 5000s ease-in-out 0s;transition:background-color 5000s ease-in-out 0s;caret-color:#9da302}.entry-container emoji-selector-panel{pointer-events:none;opacity:0;position:absolute;bottom:3.5em;right:0}.entry-container emoji-selector-panel.visible{opacity:1;pointer-events:initial}form{display:flex;padding:.5em 0;align-items:center}form textarea{font-size:14pt;background:black;color:#fff;border:1px solid #333;min-height:6em;width:100%}form input[type=text]{background:white;color:#000;border:1px solid #ccc;width:100%;height:2.5em}form .actions{margin-left:1em}form button{display:block;margin:0 0 0 auto}:host-context(.mat-dark-theme) form input[type=text]{background:black;color:#fff;border:1px solid #333}\n"] }]
9841
9792
  }], ctorParameters: function () { return [{ type: ChatBackendBase }]; }, propDecorators: { shouldInterceptMessageSend: [{
9842
9793
  type: Input
9794
+ }], url: [{
9795
+ type: Input
9843
9796
  }], source: [{
9844
9797
  type: Input
9845
9798
  }], topicID: [{
@@ -9928,7 +9881,7 @@ LiveCommentComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", v
9928
9881
  (reported)="report()"
9929
9882
  (selected)="select()"
9930
9883
  ></banta-comment>
9931
- `, isInline: true, styles: [""], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CommentComponent, selector: "banta-comment", inputs: ["maxLength", "message", "customMenuItems", "showReplyAction", "permissions", "mine", "editing", "genericAvatarUrl"], outputs: ["loaded", "userSelected", "usernameSelected", "avatarSelected", "reported", "liked", "unliked", "selected", "edited", "deleted", "editStarted", "editEnded", "shared"] }] });
9884
+ `, isInline: true, styles: [""], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CommentComponent, selector: "banta-comment", inputs: ["message", "customMenuItems", "showReplyAction", "maxLength", "permissions", "mine", "editing", "genericAvatarUrl", "readonly"], outputs: ["liked", "unliked", "selected", "edited", "deleted", "editStarted", "editEnded", "shared", "userSelected", "usernameSelected", "avatarSelected", "reported", "loaded"] }] });
9932
9885
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: LiveCommentComponent, decorators: [{
9933
9886
  type: Component,
9934
9887
  args: [{ selector: 'banta-live-comment', template: `
@@ -10288,12 +10241,12 @@ class BantaComponent {
10288
10241
  this.showAux(`Report message from @${message.user.username}`, 'report');
10289
10242
  }
10290
10243
  }
10291
- BantaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaComponent, deps: [{ token: ChatBackendBase }, { token: i2$3.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
10292
- BantaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: BantaComponent, selector: "banta", inputs: { topicID: "topicID", chatLabel: "chatLabel", commentsLabel: "commentsLabel" }, outputs: { signInSelected: "signInSelected" }, host: { properties: { "class.point-focus": "this.hasPoint" } }, viewQueries: [{ propertyName: "firehose", first: true, predicate: ["firehose"], descendants: true, static: true }], ngImport: i0, template: "\r\n<mat-menu #userMenu=\"matMenu\">\r\n <ng-container *ngIf=\"currentUser\">\r\n <button [disabled]=\"true\" mat-menu-item>{{currentUser.displayName}} (@{{currentUser.username}})</button>\r\n <button mat-menu-item (click)=\"signOut()\">Sign Out</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!currentUser\">\r\n <button mat-menu-item>Sign In</button>\r\n </ng-container>\r\n <button mat-menu-item>Help</button>\r\n</mat-menu>\r\n\r\n<div class=\"tabs\">\r\n <div>\r\n <a mat-button (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</a>\r\n <a mat-button (click)=\"mobileFocus = 'comments'\">{{commentsLabel}}</a>\r\n </div>\r\n <div class=\"spacer\"></div>\r\n <div>\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div class=\"firehose\" [class.focus]=\"mobileFocus === 'chat'\">\r\n <header>\r\n <div>\r\n <label (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</label>\r\n <div class=\"spacer\"></div>\r\n\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n </header>\r\n <banta-chat \r\n #firehose\r\n [source]=\"firehoseSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n (reported)=\"reportMessage($event)\"\r\n ></banta-chat>\r\n</div>\r\n\r\n<div class=\"aux\" [class.focus]=\"mobileFocus === 'aux'\" [class.open]=\"auxOpen\">\r\n <header>\r\n <div>\r\n <label>{{auxTitle}}</label>\r\n <div class=\"spacer\"></div>\r\n <button mat-icon-button (click)=\"auxOpen = false\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </header>\r\n <div class=\"aux-contents\">\r\n <ng-container *ngIf=\"auxMode === 'profile'\">\r\n <ng-container *ngIf=\"profileUser\">\r\n\r\n <div>\r\n <strong style=\"font-size: 125%;\">\r\n {{profileUser.displayName}}\r\n </strong>\r\n @{{profileUser.username}}\r\n </div>\r\n\r\n <br/>\r\n <strong>Top Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n\r\n <br/>\r\n <strong>Recent Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'report'\">\r\n <p>Are you sure you want to report this message?</p>\r\n\r\n <banta-live-message [message]=\"reportedMessage\"></banta-live-message>\r\n\r\n <div style=\"text-align: center;\">\r\n <button mat-raised-button color=\"primary\" (click)=\"sendReport(reportedMessage)\">Yes, Report</button>\r\n &nbsp;\r\n <button mat-raised-button color=\"secondary\" (click)=\"auxOpen = false\">No, Cancel</button>\r\n </div>\r\n\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'notifications'\">\r\n\r\n <div *ngIf=\"!notifications || notifications.length === 0\">\r\n <em>You do not have any notifications yet</em>\r\n </div>\r\n \r\n <div class=\"notifications\">\r\n <div class=\"notification\" *ngFor=\"let notif of notifications\">\r\n <div>\r\n <ng-container *ngIf=\"notif.type === 'upvote'\">\r\n @{{notif.message?.user?.username}} upvoted your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'notice'\">\r\n <div>\r\n {{notif.message}}\r\n </div>\r\n <a mat-button target=\"_blank\" href=\"{{notif.actionUrl}}\">\r\n {{notif.actionLabel}}\r\n </a>\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'mention'\">\r\n You were mentioned by @{{notif.message?.user?.username}}\r\n\r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'reply'\">\r\n @{{notif.replyMessage?.user?.username}} replied to your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.replyMessage\"\r\n (upvoted)=\"upvoteMessage(notif.replyMessage)\"\r\n (reported)=\"reportMessage(notif.replyMessage)\"\r\n (selected)=\"goToMessage(notif.replyMessage)\">\r\n </banta-live-message>\r\n </ng-container>\r\n </div>\r\n\r\n <banta-timestamp [value]=\"notif.sentAt\"></banta-timestamp>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n</div>\r\n<div class=\"points\" [class.focus]=\"mobileFocus === 'points'\">\r\n <header>\r\n <div>\r\n <label>{{commentsLabel}}</label>\r\n </div>\r\n </header>\r\n <div class=\"point-focus\">\r\n <div class=\"actions\">\r\n <button mat-button (click)=\"pointUnfocus()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n Back\r\n </button>\r\n\r\n <div class=\"spacer\"></div>\r\n \r\n <ng-container *ngIf=\"pointOpen\">\r\n <div class=\"counted-action\">\r\n <div class=\"count-indicator\"> \r\n {{pointOpen.likes}}\r\n </div>\r\n <button mat-icon-button>\r\n <mat-icon>thumb_up</mat-icon>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"!pointSubChat\">\r\n Error: No subchat\r\n </div>\r\n \r\n <banta-comment-view\r\n class=\"subcomments\"\r\n *ngIf=\"pointSubChat\"\r\n [newestLast]=\"true\"\r\n [allowReplies]=\"false\"\r\n [source]=\"pointSubChat\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n >\r\n \r\n <banta-comment\r\n class=\"focused-comment\"\r\n data-before\r\n *ngIf=\"pointOpen\"\r\n (upvoted)=\"upvoteMessage(pointOpen)\"\r\n (userSelected)=\"showProfile(pointOpen.user)\"\r\n (reported)=\"reportMessage(pointOpen)\"\r\n [showReplyAction]=\"false\"\r\n [message]=\"pointOpen\"\r\n ></banta-comment>\r\n \r\n <div class=\"message reply\">\r\n Reply:\r\n <form class=\"new-message\" (submit)=\"sendPointSubMessage()\">\r\n <textarea \r\n name=\"message\" \r\n (keydown)=\"newPointSubMessageKeyDown($event)\"\r\n [(ngModel)]=\"newPointSubMessage.message\"></textarea>\r\n \r\n <div class=\"actions\">\r\n <button [disabled]=\"!newPointSubMessage.message\" \r\n mat-raised-button color=\"primary\">Send</button>\r\n </div>\r\n </form>\r\n </div>\r\n </banta-comment-view>\r\n </div>\r\n <div class=\"points-section\">\r\n <banta-comments\r\n [source]=\"pointSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (selected)=\"goToMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n ></banta-comments>\r\n </div>\r\n</div>", styles: [":host{display:flex;flex-direction:row;padding:.5em;height:40em;position:relative}.counted-action{display:flex;align-items:center}.count-indicator{font-size:9pt;padding:0 3px;border-radius:3px;border:1px solid #333}header{position:relative;margin-bottom:1em}header div{display:flex;align-items:center;height:30px}header button{color:#666}header label{text-transform:uppercase;z-index:1;font-size:12pt;letter-spacing:2px;font-weight:100;color:#333;margin:0 auto 0 0;display:block;width:-moz-fit-content;width:fit-content;position:relative;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis}header:after{content:\"\";border:1px solid;border-color:#ccc;height:0px;width:100%;display:block;position:relative;z-index:0}.points{width:33%;max-width:50em;display:flex;flex-direction:column}:host.point-focus .points{width:66%;max-width:50em}:host.point-focus .points .points-section{opacity:0;pointer-events:none}:host.point-focus .points .point-focus{opacity:1;pointer-events:initial}:host.point-focus .points .point-focus .actions{display:flex}banta-comments{flex-grow:1}.points{width:33%;margin-left:.5em;font-size:12pt;flex-shrink:0;max-width:30em;transition:.2s width ease-in,.2s max-width ease-in;position:relative}.points .points-section{flex-grow:1;display:flex;flex-direction:column;opacity:1;transition:.2s opacity ease-in;z-index:2}.points .point-focus{position:absolute;width:100%;inset:1.75em 0 0;padding:.5em;opacity:0;transition:.2s opacity ease-in;flex-grow:1;display:flex;flex-direction:column}.firehose{flex-grow:1;font-size:10pt;display:flex;flex-direction:column}form{display:flex;padding:.5em 0;align-items:center}form textarea{font-size:14pt;background:black;color:#fff;border:1px solid #333;min-height:6em;width:100%}form input[type=text]{background:black;color:#fff;border:1px solid #333;width:100%;height:1em}form .actions{margin-left:1em}form button{display:block;margin:0 0 0 auto}.subcomments ::ng-deep banta-comment{font-size:10pt}.subcomments ::ng-deep banta-comment.focused-comment{background:#001321;color:#fff;font-size:12pt}.aux{width:0px;min-width:0px;overflow-x:hidden;transition:.4s width ease-out,.4s min-width ease-out;display:flex;flex-direction:column}.aux.open{width:30em;min-width:18em}.aux .aux-contents{width:30em;min-width:10em;max-width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;flex-grow:1}.notifications .notification{border-bottom:1px solid #333;padding:1em}.notifications .notification banta-timestamp{display:block;text-align:right;font-size:9pt;color:#999}.message.reply{padding:1em}.tabs{display:none}@media (max-width: 1015px){:host{flex-direction:column}.tabs{display:flex;position:absolute;top:0;left:0;right:0;width:100%;z-index:10;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:rgba(0,0,0,.5)}.points{width:100%;max-width:100%;margin-left:0}header{display:none}:host.point-focus .points{width:100%;max-width:100%}.aux{width:100%;min-width:0;min-width:initial;max-width:100%}.points,.firehose,.aux{position:absolute;inset:2em 0 0;z-index:0;background:black}.points.focus,.firehose.focus,.aux.focus{z-index:2}}:host-context(.mat-dark-theme) :host{background:#090909;color:#fff}:host-context(.mat-dark-theme) form textarea{background:#ccc;color:#333}:host-context(.mat-dark-theme) header:after{border-color:#222}:host-context(.mat-dark-theme) header label{color:#aaa}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: TimestampComponent, selector: "banta-timestamp", inputs: ["value"] }, { kind: "component", type: CommentComponent, selector: "banta-comment", inputs: ["maxLength", "message", "customMenuItems", "showReplyAction", "permissions", "mine", "editing", "genericAvatarUrl"], outputs: ["loaded", "userSelected", "usernameSelected", "avatarSelected", "reported", "liked", "unliked", "selected", "edited", "deleted", "editStarted", "editEnded", "shared"] }, { kind: "component", type: CommentViewComponent, selector: "banta-comment-view", inputs: ["showEmptyState", "allowReplies", "enableHoldOnClick", "enableHoldOnScroll", "customMenuItems", "fixedHeight", "selectedMessage", "source", "genericAvatarUrl", "maxMessages", "maxVisibleMessages", "newestLast", "holdNewMessages"], outputs: ["selected", "messageEdited", "userSelected", "reported", "liked", "unliked", "usernameSelected", "avatarSelected", "shared", "deleted", "sortOrderChanged", "filterModeChanged"] }, { kind: "component", type: BantaCommentsComponent, selector: "banta-comments", inputs: ["customMenuItems", "maxCommentLength", "loadingMessages", "useInlineReplies", "signInLabel", "sendLabel", "signingInLabel", "replyLabel", "sendingLabel", "permissionDeniedLabel", "postCommentLabel", "postReplyLabel", "allowAttachments", "fixedHeight", "maxMessages", "maxVisibleMessages", "genericAvatarUrl", "shouldInterceptMessageSend", "participants", "source", "hashtags", "topicID", "sortOrder", "filterMode"], outputs: ["signInSelected", "editAvatarSelected", "permissionDeniedError", "upvoted", "reported", "selected", "userSelected", "usernameSelected", "avatarSelected", "shared"] }, { kind: "component", type: BantaChatComponent, selector: "banta-chat", inputs: ["shouldInterceptMessageSend", "source", "topicID", "signInLabel", "sendLabel", "permissionDeniedLabel", "messageFieldPlaceholder", "emptyLabel"], outputs: ["selected", "reported", "upvoted", "userSelected", "permissionDeniedError", "signInSelected", "received"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i7$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i7$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: LiveMessageComponent, selector: "banta-live-message", inputs: ["message"], outputs: ["upvoted", "reported", "selected"] }] });
10244
+ BantaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaComponent, deps: [{ token: ChatBackendBase }, { token: i2$4.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
10245
+ BantaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: BantaComponent, selector: "banta", inputs: { topicID: "topicID", chatLabel: "chatLabel", commentsLabel: "commentsLabel" }, outputs: { signInSelected: "signInSelected" }, host: { properties: { "class.point-focus": "this.hasPoint" } }, viewQueries: [{ propertyName: "firehose", first: true, predicate: ["firehose"], descendants: true, static: true }], ngImport: i0, template: "\r\n<mat-menu #userMenu=\"matMenu\">\r\n <ng-container *ngIf=\"currentUser\">\r\n <button [disabled]=\"true\" mat-menu-item>{{currentUser.displayName}} (@{{currentUser.username}})</button>\r\n <button mat-menu-item (click)=\"signOut()\">Sign Out</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!currentUser\">\r\n <button mat-menu-item>Sign In</button>\r\n </ng-container>\r\n <button mat-menu-item>Help</button>\r\n</mat-menu>\r\n\r\n<div class=\"tabs\">\r\n <div>\r\n <a mat-button (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</a>\r\n <a mat-button (click)=\"mobileFocus = 'comments'\">{{commentsLabel}}</a>\r\n </div>\r\n <div class=\"spacer\"></div>\r\n <div>\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div class=\"firehose\" [class.focus]=\"mobileFocus === 'chat'\">\r\n <header>\r\n <div>\r\n <label (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</label>\r\n <div class=\"spacer\"></div>\r\n\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n </header>\r\n <banta-chat \r\n #firehose\r\n [source]=\"firehoseSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n (reported)=\"reportMessage($event)\"\r\n ></banta-chat>\r\n</div>\r\n\r\n<div class=\"aux\" [class.focus]=\"mobileFocus === 'aux'\" [class.open]=\"auxOpen\">\r\n <header>\r\n <div>\r\n <label>{{auxTitle}}</label>\r\n <div class=\"spacer\"></div>\r\n <button mat-icon-button (click)=\"auxOpen = false\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </header>\r\n <div class=\"aux-contents\">\r\n <ng-container *ngIf=\"auxMode === 'profile'\">\r\n <ng-container *ngIf=\"profileUser\">\r\n\r\n <div>\r\n <strong style=\"font-size: 125%;\">\r\n {{profileUser.displayName}}\r\n </strong>\r\n @{{profileUser.username}}\r\n </div>\r\n\r\n <br/>\r\n <strong>Top Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n\r\n <br/>\r\n <strong>Recent Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'report'\">\r\n <p>Are you sure you want to report this message?</p>\r\n\r\n <banta-live-message [message]=\"reportedMessage\"></banta-live-message>\r\n\r\n <div style=\"text-align: center;\">\r\n <button mat-raised-button color=\"primary\" (click)=\"sendReport(reportedMessage)\">Yes, Report</button>\r\n &nbsp;\r\n <button mat-raised-button color=\"secondary\" (click)=\"auxOpen = false\">No, Cancel</button>\r\n </div>\r\n\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'notifications'\">\r\n\r\n <div *ngIf=\"!notifications || notifications.length === 0\">\r\n <em>You do not have any notifications yet</em>\r\n </div>\r\n \r\n <div class=\"notifications\">\r\n <div class=\"notification\" *ngFor=\"let notif of notifications\">\r\n <div>\r\n <ng-container *ngIf=\"notif.type === 'upvote'\">\r\n @{{notif.message?.user?.username}} upvoted your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'notice'\">\r\n <div>\r\n {{notif.message}}\r\n </div>\r\n <a mat-button target=\"_blank\" href=\"{{notif.actionUrl}}\">\r\n {{notif.actionLabel}}\r\n </a>\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'mention'\">\r\n You were mentioned by @{{notif.message?.user?.username}}\r\n\r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'reply'\">\r\n @{{notif.replyMessage?.user?.username}} replied to your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.replyMessage\"\r\n (upvoted)=\"upvoteMessage(notif.replyMessage)\"\r\n (reported)=\"reportMessage(notif.replyMessage)\"\r\n (selected)=\"goToMessage(notif.replyMessage)\">\r\n </banta-live-message>\r\n </ng-container>\r\n </div>\r\n\r\n <banta-timestamp [value]=\"notif.sentAt\"></banta-timestamp>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n</div>\r\n<div class=\"points\" [class.focus]=\"mobileFocus === 'points'\">\r\n <header>\r\n <div>\r\n <label>{{commentsLabel}}</label>\r\n </div>\r\n </header>\r\n <div class=\"point-focus\">\r\n <div class=\"actions\">\r\n <button mat-button (click)=\"pointUnfocus()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n Back\r\n </button>\r\n\r\n <div class=\"spacer\"></div>\r\n \r\n <ng-container *ngIf=\"pointOpen\">\r\n <div class=\"counted-action\">\r\n <div class=\"count-indicator\"> \r\n {{pointOpen.likes}}\r\n </div>\r\n <button mat-icon-button>\r\n <mat-icon>thumb_up</mat-icon>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"!pointSubChat\">\r\n Error: No subchat\r\n </div>\r\n \r\n <banta-comment-view\r\n class=\"subcomments\"\r\n *ngIf=\"pointSubChat\"\r\n [newestLast]=\"true\"\r\n [allowReplies]=\"false\"\r\n [source]=\"pointSubChat\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n >\r\n \r\n <banta-comment\r\n class=\"focused-comment\"\r\n data-before\r\n *ngIf=\"pointOpen\"\r\n [showReplyAction]=\"false\"\r\n [message]=\"pointOpen\"\r\n [readonly]=\"pointSubChat?.readonly\"\r\n (upvoted)=\"upvoteMessage(pointOpen)\"\r\n (userSelected)=\"showProfile(pointOpen.user)\"\r\n (reported)=\"reportMessage(pointOpen)\"\r\n ></banta-comment>\r\n \r\n <div class=\"message reply\">\r\n Reply:\r\n <form class=\"new-message\" (submit)=\"sendPointSubMessage()\">\r\n <textarea \r\n name=\"message\" \r\n (keydown)=\"newPointSubMessageKeyDown($event)\"\r\n [(ngModel)]=\"newPointSubMessage.message\"></textarea>\r\n \r\n <div class=\"actions\">\r\n <button [disabled]=\"!newPointSubMessage.message\" \r\n mat-raised-button color=\"primary\">Send</button>\r\n </div>\r\n </form>\r\n </div>\r\n </banta-comment-view>\r\n </div>\r\n <div class=\"points-section\">\r\n <banta-comments\r\n [source]=\"pointSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (selected)=\"goToMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n ></banta-comments>\r\n </div>\r\n</div>", styles: [":host{display:flex;flex-direction:row;padding:.5em;height:40em;position:relative}.counted-action{display:flex;align-items:center}.count-indicator{font-size:9pt;padding:0 3px;border-radius:3px;border:1px solid #333}header{position:relative;margin-bottom:1em}header div{display:flex;align-items:center;height:30px}header button{color:#666}header label{text-transform:uppercase;z-index:1;font-size:12pt;letter-spacing:2px;font-weight:100;color:#333;margin:0 auto 0 0;display:block;width:-moz-fit-content;width:fit-content;position:relative;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis}header:after{content:\"\";border:1px solid;border-color:#ccc;height:0px;width:100%;display:block;position:relative;z-index:0}.points{width:33%;max-width:50em;display:flex;flex-direction:column}:host.point-focus .points{width:66%;max-width:50em}:host.point-focus .points .points-section{opacity:0;pointer-events:none}:host.point-focus .points .point-focus{opacity:1;pointer-events:initial}:host.point-focus .points .point-focus .actions{display:flex}banta-comments{flex-grow:1}.points{width:33%;margin-left:.5em;font-size:12pt;flex-shrink:0;max-width:30em;transition:.2s width ease-in,.2s max-width ease-in;position:relative}.points .points-section{flex-grow:1;display:flex;flex-direction:column;opacity:1;transition:.2s opacity ease-in;z-index:2}.points .point-focus{position:absolute;width:100%;inset:1.75em 0 0;padding:.5em;opacity:0;transition:.2s opacity ease-in;flex-grow:1;display:flex;flex-direction:column}.firehose{flex-grow:1;font-size:10pt;display:flex;flex-direction:column}form{display:flex;padding:.5em 0;align-items:center}form textarea{font-size:14pt;background:black;color:#fff;border:1px solid #333;min-height:6em;width:100%}form input[type=text]{background:black;color:#fff;border:1px solid #333;width:100%;height:1em}form .actions{margin-left:1em}form button{display:block;margin:0 0 0 auto}.subcomments ::ng-deep banta-comment{font-size:10pt}.subcomments ::ng-deep banta-comment.focused-comment{background:#001321;color:#fff;font-size:12pt}.aux{width:0px;min-width:0px;overflow-x:hidden;transition:.4s width ease-out,.4s min-width ease-out;display:flex;flex-direction:column}.aux.open{width:30em;min-width:18em}.aux .aux-contents{width:30em;min-width:10em;max-width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;flex-grow:1}.notifications .notification{border-bottom:1px solid #333;padding:1em}.notifications .notification banta-timestamp{display:block;text-align:right;font-size:9pt;color:#999}.message.reply{padding:1em}.tabs{display:none}@media (max-width: 1015px){:host{flex-direction:column}.tabs{display:flex;position:absolute;top:0;left:0;right:0;width:100%;z-index:10;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:rgba(0,0,0,.5)}.points{width:100%;max-width:100%;margin-left:0}header{display:none}:host.point-focus .points{width:100%;max-width:100%}.aux{width:100%;min-width:0;min-width:initial;max-width:100%}.points,.firehose,.aux{position:absolute;inset:2em 0 0;z-index:0;background:black}.points.focus,.firehose.focus,.aux.focus{z-index:2}}:host-context(.mat-dark-theme) :host{background:#090909;color:#fff}:host-context(.mat-dark-theme) form textarea{background:#ccc;color:#333}:host-context(.mat-dark-theme) header:after{border-color:#222}:host-context(.mat-dark-theme) header label{color:#aaa}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: TimestampComponent, selector: "banta-timestamp", inputs: ["value"] }, { kind: "component", type: CommentComponent, selector: "banta-comment", inputs: ["message", "customMenuItems", "showReplyAction", "maxLength", "permissions", "mine", "editing", "genericAvatarUrl", "readonly"], outputs: ["liked", "unliked", "selected", "edited", "deleted", "editStarted", "editEnded", "shared", "userSelected", "usernameSelected", "avatarSelected", "reported", "loaded"] }, { kind: "component", type: CommentViewComponent, selector: "banta-comment-view", inputs: ["source", "maxMessages", "maxVisibleMessages", "newestLast", "holdNewMessages", "showEmptyState", "allowReplies", "enableHoldOnClick", "enableHoldOnScroll", "customMenuItems", "fixedHeight", "selectedMessage", "genericAvatarUrl"], outputs: ["userSelected", "reported", "liked", "unliked", "usernameSelected", "avatarSelected", "shared", "deleted", "selected", "messageEdited", "sortOrderChanged", "filterModeChanged"] }, { kind: "component", type: BantaCommentsComponent, selector: "banta-comments", inputs: ["customMenuItems", "url", "maxCommentLength", "loadingMessages", "useInlineReplies", "signInLabel", "sendLabel", "signingInLabel", "replyLabel", "sendingLabel", "permissionDeniedLabel", "postCommentLabel", "postReplyLabel", "allowAttachments", "fixedHeight", "maxMessages", "maxVisibleMessages", "genericAvatarUrl", "shouldInterceptMessageSend", "participants", "source", "hashtags", "topicID", "sortOrder", "filterMode"], outputs: ["signInSelected", "editAvatarSelected", "permissionDeniedError", "upvoted", "reported", "selected", "userSelected", "usernameSelected", "avatarSelected", "shared"] }, { kind: "component", type: BantaChatComponent, selector: "banta-chat", inputs: ["shouldInterceptMessageSend", "url", "source", "topicID", "signInLabel", "sendLabel", "permissionDeniedLabel", "messageFieldPlaceholder", "emptyLabel"], outputs: ["selected", "reported", "upvoted", "userSelected", "permissionDeniedError", "signInSelected", "received"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i7$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i7$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: LiveMessageComponent, selector: "banta-live-message", inputs: ["message"], outputs: ["upvoted", "reported", "selected"] }] });
10293
10246
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaComponent, decorators: [{
10294
10247
  type: Component,
10295
- args: [{ selector: `banta`, template: "\r\n<mat-menu #userMenu=\"matMenu\">\r\n <ng-container *ngIf=\"currentUser\">\r\n <button [disabled]=\"true\" mat-menu-item>{{currentUser.displayName}} (@{{currentUser.username}})</button>\r\n <button mat-menu-item (click)=\"signOut()\">Sign Out</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!currentUser\">\r\n <button mat-menu-item>Sign In</button>\r\n </ng-container>\r\n <button mat-menu-item>Help</button>\r\n</mat-menu>\r\n\r\n<div class=\"tabs\">\r\n <div>\r\n <a mat-button (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</a>\r\n <a mat-button (click)=\"mobileFocus = 'comments'\">{{commentsLabel}}</a>\r\n </div>\r\n <div class=\"spacer\"></div>\r\n <div>\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div class=\"firehose\" [class.focus]=\"mobileFocus === 'chat'\">\r\n <header>\r\n <div>\r\n <label (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</label>\r\n <div class=\"spacer\"></div>\r\n\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n </header>\r\n <banta-chat \r\n #firehose\r\n [source]=\"firehoseSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n (reported)=\"reportMessage($event)\"\r\n ></banta-chat>\r\n</div>\r\n\r\n<div class=\"aux\" [class.focus]=\"mobileFocus === 'aux'\" [class.open]=\"auxOpen\">\r\n <header>\r\n <div>\r\n <label>{{auxTitle}}</label>\r\n <div class=\"spacer\"></div>\r\n <button mat-icon-button (click)=\"auxOpen = false\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </header>\r\n <div class=\"aux-contents\">\r\n <ng-container *ngIf=\"auxMode === 'profile'\">\r\n <ng-container *ngIf=\"profileUser\">\r\n\r\n <div>\r\n <strong style=\"font-size: 125%;\">\r\n {{profileUser.displayName}}\r\n </strong>\r\n @{{profileUser.username}}\r\n </div>\r\n\r\n <br/>\r\n <strong>Top Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n\r\n <br/>\r\n <strong>Recent Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'report'\">\r\n <p>Are you sure you want to report this message?</p>\r\n\r\n <banta-live-message [message]=\"reportedMessage\"></banta-live-message>\r\n\r\n <div style=\"text-align: center;\">\r\n <button mat-raised-button color=\"primary\" (click)=\"sendReport(reportedMessage)\">Yes, Report</button>\r\n &nbsp;\r\n <button mat-raised-button color=\"secondary\" (click)=\"auxOpen = false\">No, Cancel</button>\r\n </div>\r\n\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'notifications'\">\r\n\r\n <div *ngIf=\"!notifications || notifications.length === 0\">\r\n <em>You do not have any notifications yet</em>\r\n </div>\r\n \r\n <div class=\"notifications\">\r\n <div class=\"notification\" *ngFor=\"let notif of notifications\">\r\n <div>\r\n <ng-container *ngIf=\"notif.type === 'upvote'\">\r\n @{{notif.message?.user?.username}} upvoted your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'notice'\">\r\n <div>\r\n {{notif.message}}\r\n </div>\r\n <a mat-button target=\"_blank\" href=\"{{notif.actionUrl}}\">\r\n {{notif.actionLabel}}\r\n </a>\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'mention'\">\r\n You were mentioned by @{{notif.message?.user?.username}}\r\n\r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'reply'\">\r\n @{{notif.replyMessage?.user?.username}} replied to your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.replyMessage\"\r\n (upvoted)=\"upvoteMessage(notif.replyMessage)\"\r\n (reported)=\"reportMessage(notif.replyMessage)\"\r\n (selected)=\"goToMessage(notif.replyMessage)\">\r\n </banta-live-message>\r\n </ng-container>\r\n </div>\r\n\r\n <banta-timestamp [value]=\"notif.sentAt\"></banta-timestamp>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n</div>\r\n<div class=\"points\" [class.focus]=\"mobileFocus === 'points'\">\r\n <header>\r\n <div>\r\n <label>{{commentsLabel}}</label>\r\n </div>\r\n </header>\r\n <div class=\"point-focus\">\r\n <div class=\"actions\">\r\n <button mat-button (click)=\"pointUnfocus()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n Back\r\n </button>\r\n\r\n <div class=\"spacer\"></div>\r\n \r\n <ng-container *ngIf=\"pointOpen\">\r\n <div class=\"counted-action\">\r\n <div class=\"count-indicator\"> \r\n {{pointOpen.likes}}\r\n </div>\r\n <button mat-icon-button>\r\n <mat-icon>thumb_up</mat-icon>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"!pointSubChat\">\r\n Error: No subchat\r\n </div>\r\n \r\n <banta-comment-view\r\n class=\"subcomments\"\r\n *ngIf=\"pointSubChat\"\r\n [newestLast]=\"true\"\r\n [allowReplies]=\"false\"\r\n [source]=\"pointSubChat\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n >\r\n \r\n <banta-comment\r\n class=\"focused-comment\"\r\n data-before\r\n *ngIf=\"pointOpen\"\r\n (upvoted)=\"upvoteMessage(pointOpen)\"\r\n (userSelected)=\"showProfile(pointOpen.user)\"\r\n (reported)=\"reportMessage(pointOpen)\"\r\n [showReplyAction]=\"false\"\r\n [message]=\"pointOpen\"\r\n ></banta-comment>\r\n \r\n <div class=\"message reply\">\r\n Reply:\r\n <form class=\"new-message\" (submit)=\"sendPointSubMessage()\">\r\n <textarea \r\n name=\"message\" \r\n (keydown)=\"newPointSubMessageKeyDown($event)\"\r\n [(ngModel)]=\"newPointSubMessage.message\"></textarea>\r\n \r\n <div class=\"actions\">\r\n <button [disabled]=\"!newPointSubMessage.message\" \r\n mat-raised-button color=\"primary\">Send</button>\r\n </div>\r\n </form>\r\n </div>\r\n </banta-comment-view>\r\n </div>\r\n <div class=\"points-section\">\r\n <banta-comments\r\n [source]=\"pointSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (selected)=\"goToMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n ></banta-comments>\r\n </div>\r\n</div>", styles: [":host{display:flex;flex-direction:row;padding:.5em;height:40em;position:relative}.counted-action{display:flex;align-items:center}.count-indicator{font-size:9pt;padding:0 3px;border-radius:3px;border:1px solid #333}header{position:relative;margin-bottom:1em}header div{display:flex;align-items:center;height:30px}header button{color:#666}header label{text-transform:uppercase;z-index:1;font-size:12pt;letter-spacing:2px;font-weight:100;color:#333;margin:0 auto 0 0;display:block;width:-moz-fit-content;width:fit-content;position:relative;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis}header:after{content:\"\";border:1px solid;border-color:#ccc;height:0px;width:100%;display:block;position:relative;z-index:0}.points{width:33%;max-width:50em;display:flex;flex-direction:column}:host.point-focus .points{width:66%;max-width:50em}:host.point-focus .points .points-section{opacity:0;pointer-events:none}:host.point-focus .points .point-focus{opacity:1;pointer-events:initial}:host.point-focus .points .point-focus .actions{display:flex}banta-comments{flex-grow:1}.points{width:33%;margin-left:.5em;font-size:12pt;flex-shrink:0;max-width:30em;transition:.2s width ease-in,.2s max-width ease-in;position:relative}.points .points-section{flex-grow:1;display:flex;flex-direction:column;opacity:1;transition:.2s opacity ease-in;z-index:2}.points .point-focus{position:absolute;width:100%;inset:1.75em 0 0;padding:.5em;opacity:0;transition:.2s opacity ease-in;flex-grow:1;display:flex;flex-direction:column}.firehose{flex-grow:1;font-size:10pt;display:flex;flex-direction:column}form{display:flex;padding:.5em 0;align-items:center}form textarea{font-size:14pt;background:black;color:#fff;border:1px solid #333;min-height:6em;width:100%}form input[type=text]{background:black;color:#fff;border:1px solid #333;width:100%;height:1em}form .actions{margin-left:1em}form button{display:block;margin:0 0 0 auto}.subcomments ::ng-deep banta-comment{font-size:10pt}.subcomments ::ng-deep banta-comment.focused-comment{background:#001321;color:#fff;font-size:12pt}.aux{width:0px;min-width:0px;overflow-x:hidden;transition:.4s width ease-out,.4s min-width ease-out;display:flex;flex-direction:column}.aux.open{width:30em;min-width:18em}.aux .aux-contents{width:30em;min-width:10em;max-width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;flex-grow:1}.notifications .notification{border-bottom:1px solid #333;padding:1em}.notifications .notification banta-timestamp{display:block;text-align:right;font-size:9pt;color:#999}.message.reply{padding:1em}.tabs{display:none}@media (max-width: 1015px){:host{flex-direction:column}.tabs{display:flex;position:absolute;top:0;left:0;right:0;width:100%;z-index:10;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:rgba(0,0,0,.5)}.points{width:100%;max-width:100%;margin-left:0}header{display:none}:host.point-focus .points{width:100%;max-width:100%}.aux{width:100%;min-width:0;min-width:initial;max-width:100%}.points,.firehose,.aux{position:absolute;inset:2em 0 0;z-index:0;background:black}.points.focus,.firehose.focus,.aux.focus{z-index:2}}:host-context(.mat-dark-theme) :host{background:#090909;color:#fff}:host-context(.mat-dark-theme) form textarea{background:#ccc;color:#333}:host-context(.mat-dark-theme) header:after{border-color:#222}:host-context(.mat-dark-theme) header label{color:#aaa}\n"] }]
10296
- }], ctorParameters: function () { return [{ type: ChatBackendBase }, { type: i2$3.MatDialog }]; }, propDecorators: { firehose: [{
10248
+ args: [{ selector: `banta`, template: "\r\n<mat-menu #userMenu=\"matMenu\">\r\n <ng-container *ngIf=\"currentUser\">\r\n <button [disabled]=\"true\" mat-menu-item>{{currentUser.displayName}} (@{{currentUser.username}})</button>\r\n <button mat-menu-item (click)=\"signOut()\">Sign Out</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!currentUser\">\r\n <button mat-menu-item>Sign In</button>\r\n </ng-container>\r\n <button mat-menu-item>Help</button>\r\n</mat-menu>\r\n\r\n<div class=\"tabs\">\r\n <div>\r\n <a mat-button (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</a>\r\n <a mat-button (click)=\"mobileFocus = 'comments'\">{{commentsLabel}}</a>\r\n </div>\r\n <div class=\"spacer\"></div>\r\n <div>\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div class=\"firehose\" [class.focus]=\"mobileFocus === 'chat'\">\r\n <header>\r\n <div>\r\n <label (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</label>\r\n <div class=\"spacer\"></div>\r\n\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n </header>\r\n <banta-chat \r\n #firehose\r\n [source]=\"firehoseSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n (reported)=\"reportMessage($event)\"\r\n ></banta-chat>\r\n</div>\r\n\r\n<div class=\"aux\" [class.focus]=\"mobileFocus === 'aux'\" [class.open]=\"auxOpen\">\r\n <header>\r\n <div>\r\n <label>{{auxTitle}}</label>\r\n <div class=\"spacer\"></div>\r\n <button mat-icon-button (click)=\"auxOpen = false\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </header>\r\n <div class=\"aux-contents\">\r\n <ng-container *ngIf=\"auxMode === 'profile'\">\r\n <ng-container *ngIf=\"profileUser\">\r\n\r\n <div>\r\n <strong style=\"font-size: 125%;\">\r\n {{profileUser.displayName}}\r\n </strong>\r\n @{{profileUser.username}}\r\n </div>\r\n\r\n <br/>\r\n <strong>Top Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n\r\n <br/>\r\n <strong>Recent Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'report'\">\r\n <p>Are you sure you want to report this message?</p>\r\n\r\n <banta-live-message [message]=\"reportedMessage\"></banta-live-message>\r\n\r\n <div style=\"text-align: center;\">\r\n <button mat-raised-button color=\"primary\" (click)=\"sendReport(reportedMessage)\">Yes, Report</button>\r\n &nbsp;\r\n <button mat-raised-button color=\"secondary\" (click)=\"auxOpen = false\">No, Cancel</button>\r\n </div>\r\n\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'notifications'\">\r\n\r\n <div *ngIf=\"!notifications || notifications.length === 0\">\r\n <em>You do not have any notifications yet</em>\r\n </div>\r\n \r\n <div class=\"notifications\">\r\n <div class=\"notification\" *ngFor=\"let notif of notifications\">\r\n <div>\r\n <ng-container *ngIf=\"notif.type === 'upvote'\">\r\n @{{notif.message?.user?.username}} upvoted your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'notice'\">\r\n <div>\r\n {{notif.message}}\r\n </div>\r\n <a mat-button target=\"_blank\" href=\"{{notif.actionUrl}}\">\r\n {{notif.actionLabel}}\r\n </a>\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'mention'\">\r\n You were mentioned by @{{notif.message?.user?.username}}\r\n\r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'reply'\">\r\n @{{notif.replyMessage?.user?.username}} replied to your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.replyMessage\"\r\n (upvoted)=\"upvoteMessage(notif.replyMessage)\"\r\n (reported)=\"reportMessage(notif.replyMessage)\"\r\n (selected)=\"goToMessage(notif.replyMessage)\">\r\n </banta-live-message>\r\n </ng-container>\r\n </div>\r\n\r\n <banta-timestamp [value]=\"notif.sentAt\"></banta-timestamp>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n</div>\r\n<div class=\"points\" [class.focus]=\"mobileFocus === 'points'\">\r\n <header>\r\n <div>\r\n <label>{{commentsLabel}}</label>\r\n </div>\r\n </header>\r\n <div class=\"point-focus\">\r\n <div class=\"actions\">\r\n <button mat-button (click)=\"pointUnfocus()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n Back\r\n </button>\r\n\r\n <div class=\"spacer\"></div>\r\n \r\n <ng-container *ngIf=\"pointOpen\">\r\n <div class=\"counted-action\">\r\n <div class=\"count-indicator\"> \r\n {{pointOpen.likes}}\r\n </div>\r\n <button mat-icon-button>\r\n <mat-icon>thumb_up</mat-icon>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"!pointSubChat\">\r\n Error: No subchat\r\n </div>\r\n \r\n <banta-comment-view\r\n class=\"subcomments\"\r\n *ngIf=\"pointSubChat\"\r\n [newestLast]=\"true\"\r\n [allowReplies]=\"false\"\r\n [source]=\"pointSubChat\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n >\r\n \r\n <banta-comment\r\n class=\"focused-comment\"\r\n data-before\r\n *ngIf=\"pointOpen\"\r\n [showReplyAction]=\"false\"\r\n [message]=\"pointOpen\"\r\n [readonly]=\"pointSubChat?.readonly\"\r\n (upvoted)=\"upvoteMessage(pointOpen)\"\r\n (userSelected)=\"showProfile(pointOpen.user)\"\r\n (reported)=\"reportMessage(pointOpen)\"\r\n ></banta-comment>\r\n \r\n <div class=\"message reply\">\r\n Reply:\r\n <form class=\"new-message\" (submit)=\"sendPointSubMessage()\">\r\n <textarea \r\n name=\"message\" \r\n (keydown)=\"newPointSubMessageKeyDown($event)\"\r\n [(ngModel)]=\"newPointSubMessage.message\"></textarea>\r\n \r\n <div class=\"actions\">\r\n <button [disabled]=\"!newPointSubMessage.message\" \r\n mat-raised-button color=\"primary\">Send</button>\r\n </div>\r\n </form>\r\n </div>\r\n </banta-comment-view>\r\n </div>\r\n <div class=\"points-section\">\r\n <banta-comments\r\n [source]=\"pointSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (selected)=\"goToMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n ></banta-comments>\r\n </div>\r\n</div>", styles: [":host{display:flex;flex-direction:row;padding:.5em;height:40em;position:relative}.counted-action{display:flex;align-items:center}.count-indicator{font-size:9pt;padding:0 3px;border-radius:3px;border:1px solid #333}header{position:relative;margin-bottom:1em}header div{display:flex;align-items:center;height:30px}header button{color:#666}header label{text-transform:uppercase;z-index:1;font-size:12pt;letter-spacing:2px;font-weight:100;color:#333;margin:0 auto 0 0;display:block;width:-moz-fit-content;width:fit-content;position:relative;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis}header:after{content:\"\";border:1px solid;border-color:#ccc;height:0px;width:100%;display:block;position:relative;z-index:0}.points{width:33%;max-width:50em;display:flex;flex-direction:column}:host.point-focus .points{width:66%;max-width:50em}:host.point-focus .points .points-section{opacity:0;pointer-events:none}:host.point-focus .points .point-focus{opacity:1;pointer-events:initial}:host.point-focus .points .point-focus .actions{display:flex}banta-comments{flex-grow:1}.points{width:33%;margin-left:.5em;font-size:12pt;flex-shrink:0;max-width:30em;transition:.2s width ease-in,.2s max-width ease-in;position:relative}.points .points-section{flex-grow:1;display:flex;flex-direction:column;opacity:1;transition:.2s opacity ease-in;z-index:2}.points .point-focus{position:absolute;width:100%;inset:1.75em 0 0;padding:.5em;opacity:0;transition:.2s opacity ease-in;flex-grow:1;display:flex;flex-direction:column}.firehose{flex-grow:1;font-size:10pt;display:flex;flex-direction:column}form{display:flex;padding:.5em 0;align-items:center}form textarea{font-size:14pt;background:black;color:#fff;border:1px solid #333;min-height:6em;width:100%}form input[type=text]{background:black;color:#fff;border:1px solid #333;width:100%;height:1em}form .actions{margin-left:1em}form button{display:block;margin:0 0 0 auto}.subcomments ::ng-deep banta-comment{font-size:10pt}.subcomments ::ng-deep banta-comment.focused-comment{background:#001321;color:#fff;font-size:12pt}.aux{width:0px;min-width:0px;overflow-x:hidden;transition:.4s width ease-out,.4s min-width ease-out;display:flex;flex-direction:column}.aux.open{width:30em;min-width:18em}.aux .aux-contents{width:30em;min-width:10em;max-width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;flex-grow:1}.notifications .notification{border-bottom:1px solid #333;padding:1em}.notifications .notification banta-timestamp{display:block;text-align:right;font-size:9pt;color:#999}.message.reply{padding:1em}.tabs{display:none}@media (max-width: 1015px){:host{flex-direction:column}.tabs{display:flex;position:absolute;top:0;left:0;right:0;width:100%;z-index:10;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:rgba(0,0,0,.5)}.points{width:100%;max-width:100%;margin-left:0}header{display:none}:host.point-focus .points{width:100%;max-width:100%}.aux{width:100%;min-width:0;min-width:initial;max-width:100%}.points,.firehose,.aux{position:absolute;inset:2em 0 0;z-index:0;background:black}.points.focus,.firehose.focus,.aux.focus{z-index:2}}:host-context(.mat-dark-theme) :host{background:#090909;color:#fff}:host-context(.mat-dark-theme) form textarea{background:#ccc;color:#333}:host-context(.mat-dark-theme) header:after{border-color:#222}:host-context(.mat-dark-theme) header label{color:#aaa}\n"] }]
10249
+ }], ctorParameters: function () { return [{ type: ChatBackendBase }, { type: i2$4.MatDialog }]; }, propDecorators: { firehose: [{
10297
10250
  type: ViewChild,
10298
10251
  args: ['firehose', { static: true }]
10299
10252
  }], topicID: [{
@@ -10378,7 +10331,7 @@ class CommentSortComponent {
10378
10331
  }
10379
10332
  }
10380
10333
  CommentSortComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CommentSortComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10381
- CommentSortComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CommentSortComponent, selector: "banta-comment-sort", inputs: { sort: "sort" }, outputs: { sortChange: "sortChange" }, ngImport: i0, template: "<mat-form-field appearance=\"outline\" floatLabel=\"always\">\r\n <mat-label>Sort</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>", styles: ["mat-form-field{width:100%}\n"], dependencies: [{ kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "component", type: i2$4.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i3$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }] });
10334
+ CommentSortComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: CommentSortComponent, selector: "banta-comment-sort", inputs: { sort: "sort" }, outputs: { sortChange: "sortChange" }, ngImport: i0, template: "<mat-form-field appearance=\"outline\" floatLabel=\"always\">\r\n <mat-label>Sort</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>", styles: ["mat-form-field{width:100%}\n"], dependencies: [{ kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "component", type: i2$5.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i3$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }] });
10382
10335
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: CommentSortComponent, decorators: [{
10383
10336
  type: Component,
10384
10337
  args: [{ selector: 'banta-comment-sort', template: "<mat-form-field appearance=\"outline\" floatLabel=\"always\">\r\n <mat-label>Sort</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>", styles: ["mat-form-field{width:100%}\n"] }]
@@ -10480,6 +10433,8 @@ class ChatSource extends SocketRPC {
10480
10433
  this.identifier = identifier;
10481
10434
  this.parentIdentifier = parentIdentifier;
10482
10435
  this.subscription = new Subscription();
10436
+ this.readonly = false;
10437
+ this.canLoadMore = true;
10483
10438
  this._state = 'connecting';
10484
10439
  this._connectionStateChanged = new Subject();
10485
10440
  this._connectionStateChanged$ = this._connectionStateChanged.asObservable();
@@ -10523,6 +10478,9 @@ class ChatSource extends SocketRPC {
10523
10478
  socket.addEventListener('open', () => __awaiter(this, void 0, void 0, function* () {
10524
10479
  console.log(`[Banta/${this.identifier}] Socket is open`);
10525
10480
  }));
10481
+ socket.addEventListener('error', () => __awaiter(this, void 0, void 0, function* () {
10482
+ console.log(`[Banta/${this.identifier}] Socket error`);
10483
+ }));
10526
10484
  socket.addEventListener('lost', () => __awaiter(this, void 0, void 0, function* () {
10527
10485
  this.state = 'lost';
10528
10486
  }));
@@ -10555,9 +10513,10 @@ class ChatSource extends SocketRPC {
10555
10513
  return message;
10556
10514
  }
10557
10515
  getExistingMessages() {
10516
+ var _a;
10558
10517
  return __awaiter(this, void 0, void 0, function* () {
10559
10518
  try {
10560
- let messages = yield this.idempotentPeer.getExistingMessages();
10519
+ let messages = yield this.idempotentPeer.getExistingMessages((_a = this.options.initialMessageCount) !== null && _a !== void 0 ? _a : 20);
10561
10520
  messages = this.mapOrUpdateMessages(messages);
10562
10521
  return messages;
10563
10522
  }
@@ -10730,10 +10689,99 @@ __decorate([
10730
10689
  RpcEvent()
10731
10690
  ], ChatSource.prototype, "onChatMessage", null);
10732
10691
 
10692
+ /**
10693
+ * A special ChatSource which uses the REST API to load a limited number of chat messages, and does not support
10694
+ * sending/editing/deleting messages, liking/unliking, or loading more messages.
10695
+ *
10696
+ * This is used within Banta's SSR support.
10697
+ */
10698
+ class StaticChatSource {
10699
+ constructor(backend, identifier, parentIdentifier, options) {
10700
+ var _a, _b, _c;
10701
+ this.backend = backend;
10702
+ this.identifier = identifier;
10703
+ this.parentIdentifier = parentIdentifier;
10704
+ this.ready = Promise.resolve(); // TODO: should we do more than this?
10705
+ this.readonly = true;
10706
+ this.canLoadMore = false;
10707
+ this.messageReceived = new Subject();
10708
+ this.messageObserved = new Subject();
10709
+ this.messageUpdated = new Subject();
10710
+ this.messageSent = new Subject();
10711
+ this.messages = [];
10712
+ this.connectionStateChanged = new Subject();
10713
+ this.state = 'connected';
10714
+ this.sortOrder = (_a = options === null || options === void 0 ? void 0 : options.sortOrder) !== null && _a !== void 0 ? _a : CommentsOrder.NEWEST;
10715
+ this.filterMode = (_b = options === null || options === void 0 ? void 0 : options.filterMode) !== null && _b !== void 0 ? _b : FilterMode.ALL;
10716
+ this.initialMessageCount = (_c = options === null || options === void 0 ? void 0 : options.initialMessageCount) !== null && _c !== void 0 ? _c : 100;
10717
+ }
10718
+ send(message) {
10719
+ return __awaiter(this, void 0, void 0, function* () {
10720
+ throw new Error(`Cannot send a message in this state.`);
10721
+ });
10722
+ }
10723
+ close() {
10724
+ // no op
10725
+ }
10726
+ getCount() {
10727
+ return __awaiter(this, void 0, void 0, function* () {
10728
+ if (this.parentIdentifier) {
10729
+ // TODO: We need a getReplyCount or something
10730
+ return 0;
10731
+ }
10732
+ this.backend.getSourceCountForTopic(this.identifier);
10733
+ });
10734
+ }
10735
+ getExistingMessages() {
10736
+ return __awaiter(this, void 0, void 0, function* () {
10737
+ if (this.parentIdentifier) {
10738
+ return yield this.backend.getReplies(this.parentIdentifier, this.sortOrder, this.filterMode, 0, this.initialMessageCount);
10739
+ }
10740
+ else {
10741
+ return yield this.backend.getMessages(this.identifier, this.sortOrder, this.filterMode, 0, this.initialMessageCount);
10742
+ }
10743
+ });
10744
+ }
10745
+ loadAfter(message, count) {
10746
+ return __awaiter(this, void 0, void 0, function* () {
10747
+ return []; // no op
10748
+ });
10749
+ }
10750
+ get(id) {
10751
+ return __awaiter(this, void 0, void 0, function* () {
10752
+ return yield this.backend.getMessage(this.identifier, id);
10753
+ });
10754
+ }
10755
+ likeMessage(messageId) {
10756
+ return __awaiter(this, void 0, void 0, function* () {
10757
+ throw new Error(`Cannot perform this action in this state.`);
10758
+ });
10759
+ }
10760
+ unlikeMessage(messageId) {
10761
+ return __awaiter(this, void 0, void 0, function* () {
10762
+ throw new Error(`Cannot perform this action in this state.`);
10763
+ });
10764
+ }
10765
+ editMessage(messageId, text) {
10766
+ return __awaiter(this, void 0, void 0, function* () {
10767
+ throw new Error(`Cannot perform this action in this state.`);
10768
+ });
10769
+ }
10770
+ deleteMessage(messageId) {
10771
+ return __awaiter(this, void 0, void 0, function* () {
10772
+ throw new Error(`Cannot perform this action in this state.`);
10773
+ });
10774
+ }
10775
+ get errorState() {
10776
+ return undefined;
10777
+ }
10778
+ }
10779
+
10733
10780
  class ChatBackend extends ChatBackendBase {
10734
- constructor(options) {
10781
+ constructor(options, platformId) {
10735
10782
  super();
10736
10783
  this.options = options;
10784
+ this.platformId = platformId;
10737
10785
  }
10738
10786
  get serviceUrl() {
10739
10787
  var _a, _b;
@@ -10757,16 +10805,47 @@ class ChatBackend extends ChatBackendBase {
10757
10805
  return socket;
10758
10806
  });
10759
10807
  }
10808
+ isServer() {
10809
+ if (typeof localStorage !== 'undefined' && localStorage['banta:debug:useStaticSource'] === '1')
10810
+ return true;
10811
+ return isPlatformServer(this.platformId);
10812
+ }
10813
+ /**
10814
+ * Check if we are currently running inside a Googlebot user agent or via the Google inspection tool in Search Console.
10815
+ * We'll use this to avoid WebSockets so that comments can be indexable.
10816
+ * @returns
10817
+ */
10818
+ isGooglebot() {
10819
+ return typeof navigator !== 'undefined' && (navigator.userAgent.includes('Googlebot')
10820
+ || navigator.userAgent.includes('Google-InspectionTool'));
10821
+ }
10760
10822
  getSourceForTopic(topicId, options) {
10761
10823
  return __awaiter(this, void 0, void 0, function* () {
10762
- return yield new ChatSource(this, topicId, undefined, Object.assign({ sortOrder: CommentsOrder.NEWEST, filterMode: FilterMode.ALL }, options))
10763
- .bind(yield this.connectToService());
10824
+ // In some cases we need to do a single REST request to fetch the messages
10825
+ // and not use Banta's socket RPC since the open ended lifetime of a WebSocket connection
10826
+ // does not match the use case.
10827
+ // - When running in SSR
10828
+ // - When running in Googlebot (Googlebot also doesn't support WebSockets anyway)
10829
+ if (this.isServer() || this.isGooglebot()) {
10830
+ return new StaticChatSource(this, topicId, undefined, options);
10831
+ }
10832
+ else {
10833
+ return yield new ChatSource(this, topicId, undefined, Object.assign({ sortOrder: CommentsOrder.NEWEST, filterMode: FilterMode.ALL }, options))
10834
+ .bind(yield this.connectToService());
10835
+ }
10764
10836
  });
10765
10837
  }
10766
10838
  getSourceForThread(topicId, messageId, options) {
10767
10839
  return __awaiter(this, void 0, void 0, function* () {
10768
- return yield new ChatSource(this, topicId, messageId, Object.assign({ sortOrder: CommentsOrder.NEWEST, filterMode: FilterMode.ALL }, options))
10769
- .bind(yield this.connectToService());
10840
+ // When running on the server platform, we're just going to do a single REST request to fetch the messages
10841
+ // and not use Banta's socket RPC.
10842
+ if (this.isServer()) {
10843
+ return new StaticChatSource(this, topicId, messageId, options);
10844
+ }
10845
+ else {
10846
+ return yield new ChatSource(this, topicId, messageId, Object.assign({ sortOrder: CommentsOrder.NEWEST, filterMode: FilterMode.ALL }, options))
10847
+ .bind(yield this.connectToService());
10848
+ }
10770
10849
  });
10771
10850
  }
10772
10851
  /**
@@ -10777,10 +10856,7 @@ class ChatBackend extends ChatBackendBase {
10777
10856
  getSourceCountForTopic(topicId) {
10778
10857
  return __awaiter(this, void 0, void 0, function* () {
10779
10858
  try {
10780
- let response = yield fetch(`${this.serviceUrl}/topics/${topicId}`);
10781
- if (response.status >= 400)
10782
- return 0;
10783
- let topic = yield response.json();
10859
+ let topic = yield this.getTopic(topicId);
10784
10860
  return topic.messageCount || 0;
10785
10861
  }
10786
10862
  catch (e) {
@@ -10790,6 +10866,45 @@ class ChatBackend extends ChatBackendBase {
10790
10866
  }
10791
10867
  });
10792
10868
  }
10869
+ /**
10870
+ * Get the count of the given topic
10871
+ * @param topicId
10872
+ * @returns
10873
+ */
10874
+ getTopic(topicId) {
10875
+ return __awaiter(this, void 0, void 0, function* () {
10876
+ let response = yield fetch(`${this.serviceUrl}/topics/${topicId}`);
10877
+ if (response.status >= 400)
10878
+ throw new Error(`Failed to fetch topic: ${response.status}`);
10879
+ return yield response.json();
10880
+ });
10881
+ }
10882
+ /**
10883
+ * Get a set of messages from the given topic.
10884
+ * @param topicId
10885
+ * @returns
10886
+ */
10887
+ getMessages(topicId, sort, filter, offset, limit) {
10888
+ return __awaiter(this, void 0, void 0, function* () {
10889
+ let response = yield fetch(`${this.serviceUrl}/topics/${topicId}/messages?${buildQuery({ sort, filter, offset, limit })}`);
10890
+ if (response.status >= 400)
10891
+ throw new Error(`Failed to fetch messages for topic: ${response.status}`);
10892
+ return yield response.json();
10893
+ });
10894
+ }
10895
+ /**
10896
+ * Get a set of messages from the given topic.
10897
+ * @param topicId
10898
+ * @returns
10899
+ */
10900
+ getReplies(parentMessageId, sort, filter, offset, limit) {
10901
+ return __awaiter(this, void 0, void 0, function* () {
10902
+ let response = yield fetch(`${this.serviceUrl}/messages/${parentMessageId}/replies?${buildQuery({ sort, filter, offset, limit })}`);
10903
+ if (response.status >= 400)
10904
+ throw new Error(`Failed to fetch replies: ${response.status}`);
10905
+ return yield response.json();
10906
+ });
10907
+ }
10793
10908
  refreshMessage(message) {
10794
10909
  throw new Error("Method not implemented.");
10795
10910
  }
@@ -10821,7 +10936,7 @@ class ChatBackend extends ChatBackendBase {
10821
10936
  });
10822
10937
  }
10823
10938
  }
10824
- ChatBackend.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ChatBackend, deps: [{ token: BANTA_SDK_OPTIONS }], target: i0.ɵɵFactoryTarget.Injectable });
10939
+ ChatBackend.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ChatBackend, deps: [{ token: BANTA_SDK_OPTIONS }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable });
10825
10940
  ChatBackend.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ChatBackend });
10826
10941
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ChatBackend, decorators: [{
10827
10942
  type: Injectable$1
@@ -10829,6 +10944,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
10829
10944
  return [{ type: undefined, decorators: [{
10830
10945
  type: Inject,
10831
10946
  args: [BANTA_SDK_OPTIONS]
10947
+ }] }, { type: undefined, decorators: [{
10948
+ type: Inject,
10949
+ args: [PLATFORM_ID]
10832
10950
  }] }];
10833
10951
  } });
10834
10952