@banta/sdk 4.7.9 → 4.7.11
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.
- package/esm2020/lib/banta-sdk.module.mjs +5 -6
- package/esm2020/lib/chat-backend.mjs +18 -6
- package/esm2020/lib/chat-source-base.mjs +1 -1
- package/esm2020/lib/chat-source.mjs +39 -10
- package/esm2020/lib/comments/banta-comments/banta-comments.component.mjs +2 -2
- package/esm2020/lib/comments/comment-field/comment-field.component.mjs +5 -2
- package/esm2020/lib/common/attachment/attachment.component.mjs +3 -5
- package/esm2020/lib/common/attachments/attachments.component.mjs +6 -3
- package/esm2020/lib/common/common.module.mjs +10 -1
- package/esm2020/lib/common/timer-pool.service.mjs +83 -0
- package/esm2020/lib/common/timestamp.component.mjs +24 -14
- package/fesm2015/banta-sdk.mjs +117 -51
- package/fesm2015/banta-sdk.mjs.map +1 -1
- package/fesm2020/banta-sdk.mjs +113 -51
- package/fesm2020/banta-sdk.mjs.map +1 -1
- package/lib/chat-backend.d.ts +5 -0
- package/lib/chat-source-base.d.ts +1 -0
- package/lib/chat-source.d.ts +4 -0
- package/lib/common/attachments/attachments.component.d.ts +1 -0
- package/lib/common/common.module.d.ts +2 -0
- package/lib/common/timer-pool.service.d.ts +15 -0
- package/lib/common/timestamp.component.d.ts +6 -1
- package/package.json +1 -1
package/fesm2020/banta-sdk.mjs
CHANGED
|
@@ -2,6 +2,8 @@ import { Observable, Subject, BehaviorSubject, Subscription } from 'rxjs';
|
|
|
2
2
|
import { publish, take } from 'rxjs/operators';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
4
|
import { Component, Input, ViewChild, Pipe, Inject, Optional, Output, HostBinding, NgModule, ViewChildren, Directive, TemplateRef, ContentChild, Injectable } from '@angular/core';
|
|
5
|
+
import * as i1 from 'projects/sdk/src/lib/common/timer-pool.service';
|
|
6
|
+
import { TimerPool } from 'projects/sdk/src/lib/common/timer-pool.service';
|
|
5
7
|
import * as i2 from '@angular/common';
|
|
6
8
|
import { CommonModule } from '@angular/common';
|
|
7
9
|
import * as i2$1 from '@angular/material/icon';
|
|
@@ -9,7 +11,7 @@ import { MatIconModule } from '@angular/material/icon';
|
|
|
9
11
|
import * as marked from 'marked';
|
|
10
12
|
import createDOMPurify from 'dompurify';
|
|
11
13
|
import twemoji$1 from 'twemoji';
|
|
12
|
-
import * as i1 from '@angular/platform-browser';
|
|
14
|
+
import * as i1$1 from '@angular/platform-browser';
|
|
13
15
|
import * as i3 from '@angular/cdk/bidi';
|
|
14
16
|
import * as i4 from '@angular/material/progress-spinner';
|
|
15
17
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
@@ -21,7 +23,7 @@ import * as i6$1 from '@angular/material/form-field';
|
|
|
21
23
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
22
24
|
import * as i7 from '@angular/material/input';
|
|
23
25
|
import { MatInputModule } from '@angular/material/input';
|
|
24
|
-
import * as i1$
|
|
26
|
+
import * as i1$2 from '@angular/cdk/overlay';
|
|
25
27
|
import { OverlayModule } from '@angular/cdk/overlay';
|
|
26
28
|
import * as i4$2 from '@angular/cdk/portal';
|
|
27
29
|
import { PortalModule } from '@angular/cdk/portal';
|
|
@@ -31,7 +33,7 @@ import * as i7$1 from '@angular/material/menu';
|
|
|
31
33
|
import { MatMenuModule } from '@angular/material/menu';
|
|
32
34
|
import * as i11 from '@angular/material/tooltip';
|
|
33
35
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
34
|
-
import * as i1$
|
|
36
|
+
import * as i1$3 from '@banta/common';
|
|
35
37
|
import { CommentsOrder, SocketRPC, RpcEvent, DurableSocket } from '@banta/common';
|
|
36
38
|
import * as i2$3 from '@angular/router';
|
|
37
39
|
import * as i3$3 from '@angular/material/snack-bar';
|
|
@@ -57,20 +59,24 @@ function lazyConnection(options) {
|
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
class TimestampComponent {
|
|
60
|
-
constructor() {
|
|
62
|
+
constructor(timerPool) {
|
|
63
|
+
this.timerPool = timerPool;
|
|
61
64
|
this.relative = '';
|
|
62
65
|
this.tooltip = '';
|
|
63
|
-
this.
|
|
66
|
+
this.timerInterval = 0;
|
|
67
|
+
this._destroyed = false;
|
|
64
68
|
this.showAbsolute = false;
|
|
65
69
|
}
|
|
66
70
|
ngOnDestroy() {
|
|
67
|
-
|
|
68
|
-
|
|
71
|
+
this._destroyed = true;
|
|
72
|
+
this.timerUnsubscribe?.();
|
|
69
73
|
}
|
|
70
74
|
get value() {
|
|
71
75
|
return this._value;
|
|
72
76
|
}
|
|
73
77
|
update() {
|
|
78
|
+
if (this._destroyed)
|
|
79
|
+
return;
|
|
74
80
|
let now = Date.now();
|
|
75
81
|
let diff = now - this.value;
|
|
76
82
|
let minute = 1000 * 60;
|
|
@@ -132,18 +138,23 @@ class TimestampComponent {
|
|
|
132
138
|
updateTime = 1000 * 30;
|
|
133
139
|
}
|
|
134
140
|
if (typeof window !== 'undefined') {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
this.
|
|
141
|
+
if (this.timerInterval !== updateTime) {
|
|
142
|
+
this.timerInterval = updateTime;
|
|
143
|
+
this.timerUnsubscribe?.();
|
|
144
|
+
if (updateTime > 0) {
|
|
145
|
+
this.timerUnsubscribe = this.timerPool.addTimer(updateTime, () => this.update());
|
|
146
|
+
}
|
|
138
147
|
}
|
|
139
148
|
}
|
|
140
149
|
}
|
|
141
150
|
set value(v) {
|
|
142
|
-
this._value
|
|
143
|
-
|
|
151
|
+
if (this._value !== v) {
|
|
152
|
+
this._value = v;
|
|
153
|
+
this.update();
|
|
154
|
+
}
|
|
144
155
|
}
|
|
145
156
|
}
|
|
146
|
-
TimestampComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: TimestampComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
157
|
+
TimestampComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: TimestampComponent, deps: [{ token: i1.TimerPool }], target: i0.ɵɵFactoryTarget.Component });
|
|
147
158
|
TimestampComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: TimestampComponent, selector: "banta-timestamp", inputs: { value: "value" }, ngImport: i0, template: `
|
|
148
159
|
<span *ngIf="showAbsolute" [title]="value | date : 'short'">
|
|
149
160
|
{{value | date : 'shortDate'}}
|
|
@@ -162,7 +173,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
162
173
|
{{relative}}
|
|
163
174
|
</span>
|
|
164
175
|
` }]
|
|
165
|
-
}], propDecorators: { value: [{
|
|
176
|
+
}], ctorParameters: function () { return [{ type: i1.TimerPool }]; }, propDecorators: { value: [{
|
|
166
177
|
type: Input
|
|
167
178
|
}] } });
|
|
168
179
|
|
|
@@ -264,14 +275,14 @@ class BantaMarkdownToHtmlPipe {
|
|
|
264
275
|
}));
|
|
265
276
|
}
|
|
266
277
|
}
|
|
267
|
-
BantaMarkdownToHtmlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaMarkdownToHtmlPipe, deps: [{ token: i1.DomSanitizer }, { token: BANTA_SDK_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
|
|
278
|
+
BantaMarkdownToHtmlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaMarkdownToHtmlPipe, deps: [{ token: i1$1.DomSanitizer }, { token: BANTA_SDK_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
|
|
268
279
|
BantaMarkdownToHtmlPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: BantaMarkdownToHtmlPipe, name: "markdownToHtml" });
|
|
269
280
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaMarkdownToHtmlPipe, decorators: [{
|
|
270
281
|
type: Pipe,
|
|
271
282
|
args: [{
|
|
272
283
|
name: 'markdownToHtml'
|
|
273
284
|
}]
|
|
274
|
-
}], ctorParameters: function () { return [{ type: i1.DomSanitizer }, { type: undefined, decorators: [{
|
|
285
|
+
}], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }, { type: undefined, decorators: [{
|
|
275
286
|
type: Inject,
|
|
276
287
|
args: [BANTA_SDK_OPTIONS]
|
|
277
288
|
}, {
|
|
@@ -288,14 +299,14 @@ class BantaTrustResourceUrlPipe {
|
|
|
288
299
|
return this.sanitizer.bypassSecurityTrustResourceUrl(value);
|
|
289
300
|
}
|
|
290
301
|
}
|
|
291
|
-
BantaTrustResourceUrlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaTrustResourceUrlPipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
|
|
302
|
+
BantaTrustResourceUrlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaTrustResourceUrlPipe, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
|
|
292
303
|
BantaTrustResourceUrlPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: BantaTrustResourceUrlPipe, name: "trustResourceUrl" });
|
|
293
304
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaTrustResourceUrlPipe, decorators: [{
|
|
294
305
|
type: Pipe,
|
|
295
306
|
args: [{
|
|
296
307
|
name: 'trustResourceUrl'
|
|
297
308
|
}]
|
|
298
|
-
}], ctorParameters: function () { return [{ type: i1.DomSanitizer }]; } });
|
|
309
|
+
}], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }]; } });
|
|
299
310
|
|
|
300
311
|
class BantaMentionLinkerPipe {
|
|
301
312
|
transform(value, links) {
|
|
@@ -386,15 +397,13 @@ class BantaAttachmentComponent {
|
|
|
386
397
|
|| !this.attachment.url);
|
|
387
398
|
}
|
|
388
399
|
get isImageAttachment() {
|
|
389
|
-
|
|
390
|
-
return true;
|
|
391
|
-
return false;
|
|
400
|
+
return this.attachment?.type?.startsWith('image/');
|
|
392
401
|
}
|
|
393
402
|
get hasFrame() {
|
|
394
403
|
if (!this.attachment)
|
|
395
404
|
return false;
|
|
396
405
|
return this.attachment.type === 'iframe' || (this.attachment.type === 'card'
|
|
397
|
-
&& this.attachment.card
|
|
406
|
+
&& this.attachment.card?.player);
|
|
398
407
|
}
|
|
399
408
|
get frameUrl() {
|
|
400
409
|
if (!this.attachment)
|
|
@@ -473,11 +482,14 @@ class BantaAttachmentsComponent {
|
|
|
473
482
|
.filter(x => x.type === 'image/png')
|
|
474
483
|
.map(x => x.url));
|
|
475
484
|
}
|
|
485
|
+
get validAttachments() {
|
|
486
|
+
return this.attachments.filter(x => x.type);
|
|
487
|
+
}
|
|
476
488
|
get inlineAttachments() {
|
|
477
|
-
return this.
|
|
489
|
+
return this.validAttachments.filter(x => x.type !== 'card' && (x.style === 'inline' || !x.style));
|
|
478
490
|
}
|
|
479
491
|
get blockAttachments() {
|
|
480
|
-
return this.
|
|
492
|
+
return this.validAttachments.filter(x => x.style === 'block' || x.type === 'card');
|
|
481
493
|
}
|
|
482
494
|
attachmentId(index, attachment) {
|
|
483
495
|
return attachment.url;
|
|
@@ -511,6 +523,14 @@ const COMPONENTS$3 = [
|
|
|
511
523
|
BantaAttachmentsComponent
|
|
512
524
|
];
|
|
513
525
|
class BantaCommonModule {
|
|
526
|
+
static forRoot() {
|
|
527
|
+
return {
|
|
528
|
+
ngModule: BantaCommonModule,
|
|
529
|
+
providers: [
|
|
530
|
+
TimerPool
|
|
531
|
+
]
|
|
532
|
+
};
|
|
533
|
+
}
|
|
514
534
|
}
|
|
515
535
|
BantaCommonModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaCommonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
516
536
|
BantaCommonModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: BantaCommonModule, declarations: [TimestampComponent,
|
|
@@ -7127,12 +7147,12 @@ class EmojiSelectorPanelComponent {
|
|
|
7127
7147
|
this.categories = this.pairs(cats).map(pair => pair[1]);
|
|
7128
7148
|
}
|
|
7129
7149
|
}
|
|
7130
|
-
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 });
|
|
7150
|
+
EmojiSelectorPanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorPanelComponent, deps: [{ token: i1$1.DomSanitizer }, { token: BANTA_SDK_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
7131
7151
|
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$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: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4$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"] }] });
|
|
7132
7152
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorPanelComponent, decorators: [{
|
|
7133
7153
|
type: Component,
|
|
7134
7154
|
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"] }]
|
|
7135
|
-
}], ctorParameters: function () { return [{ type: i1.DomSanitizer }, { type: undefined, decorators: [{
|
|
7155
|
+
}], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }, { type: undefined, decorators: [{
|
|
7136
7156
|
type: Inject,
|
|
7137
7157
|
args: [BANTA_SDK_OPTIONS]
|
|
7138
7158
|
}, {
|
|
@@ -7206,7 +7226,7 @@ class EmojiSelectorButtonComponent {
|
|
|
7206
7226
|
this.overlayRef.attach(this.selectorPanelTemplate);
|
|
7207
7227
|
}
|
|
7208
7228
|
}
|
|
7209
|
-
EmojiSelectorButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorButtonComponent, deps: [{ token: i0.ElementRef }, { token: i1$
|
|
7229
|
+
EmojiSelectorButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorButtonComponent, deps: [{ token: i0.ElementRef }, { token: i1$2.Overlay }], target: i0.ɵɵFactoryTarget.Component });
|
|
7210
7230
|
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: `
|
|
7211
7231
|
<button #button type="button" mat-icon-button (click)="show()">
|
|
7212
7232
|
<mat-icon>emoji_emotions</mat-icon>
|
|
@@ -7231,7 +7251,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
7231
7251
|
></emoji-selector-panel>
|
|
7232
7252
|
</ng-template>
|
|
7233
7253
|
`, styles: [":host{display:block;position:relative}button{color:#666}\n"] }]
|
|
7234
|
-
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1$
|
|
7254
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1$2.Overlay }]; }, propDecorators: { selectorPanelTemplate: [{
|
|
7235
7255
|
type: ViewChild,
|
|
7236
7256
|
args: ['selectorPanelTemplate']
|
|
7237
7257
|
}], selected: [{
|
|
@@ -7946,12 +7966,12 @@ class AttachmentButtonComponent {
|
|
|
7946
7966
|
}
|
|
7947
7967
|
}
|
|
7948
7968
|
}
|
|
7949
|
-
AttachmentButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AttachmentButtonComponent, deps: [{ token: i1$
|
|
7969
|
+
AttachmentButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AttachmentButtonComponent, deps: [{ token: i1$3.CDNProvider }], target: i0.ɵɵFactoryTarget.Component });
|
|
7950
7970
|
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"] }] });
|
|
7951
7971
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AttachmentButtonComponent, decorators: [{
|
|
7952
7972
|
type: Component,
|
|
7953
7973
|
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"] }]
|
|
7954
|
-
}], ctorParameters: function () { return [{ type: i1$
|
|
7974
|
+
}], ctorParameters: function () { return [{ type: i1$3.CDNProvider }]; }, propDecorators: { fileInput: [{
|
|
7955
7975
|
type: ViewChild,
|
|
7956
7976
|
args: ['fileUpload', { static: false }]
|
|
7957
7977
|
}], addedAttachment: [{
|
|
@@ -8104,7 +8124,10 @@ class CommentFieldComponent {
|
|
|
8104
8124
|
if (this._source.connectionStateChanged) {
|
|
8105
8125
|
this._subs.add(this._source.connectionStateChanged.subscribe(state => {
|
|
8106
8126
|
if (state === 'lost') {
|
|
8107
|
-
this.
|
|
8127
|
+
if (this._source.errorState === 'server-issue')
|
|
8128
|
+
this.transientMessage = `Error occurred, trying again...`;
|
|
8129
|
+
else
|
|
8130
|
+
this.transientMessage = `Reconnecting...`;
|
|
8108
8131
|
}
|
|
8109
8132
|
else if (state === 'restored') {
|
|
8110
8133
|
this.transientMessage = undefined;
|
|
@@ -8695,7 +8718,7 @@ class BantaCommentsComponent {
|
|
|
8695
8718
|
return this.threadView;
|
|
8696
8719
|
}
|
|
8697
8720
|
updateLoading() {
|
|
8698
|
-
if (this.source?.state && this.source?.state
|
|
8721
|
+
if (this.source?.state && !['connecting', 'lost'].includes(this.source?.state)) {
|
|
8699
8722
|
clearInterval(this._loadingTimer);
|
|
8700
8723
|
this.loadingMessage = `Here we go!`;
|
|
8701
8724
|
setTimeout(() => {
|
|
@@ -10063,6 +10086,8 @@ class ChatSource extends SocketRPC {
|
|
|
10063
10086
|
this.subscription = new Subscription();
|
|
10064
10087
|
this._state = 'connecting';
|
|
10065
10088
|
this._connectionStateChanged = new Subject();
|
|
10089
|
+
this.wasRestored = false;
|
|
10090
|
+
this.subscribeAttempt = 0;
|
|
10066
10091
|
this.messageMap = new Map();
|
|
10067
10092
|
this._messageReceived = new Subject();
|
|
10068
10093
|
this._messageUpdated = new Subject();
|
|
@@ -10083,21 +10108,19 @@ class ChatSource extends SocketRPC {
|
|
|
10083
10108
|
}
|
|
10084
10109
|
async bind(socket) {
|
|
10085
10110
|
super.bind(socket);
|
|
10086
|
-
this.state = 'connected';
|
|
10087
|
-
this.markReady();
|
|
10088
|
-
await this.subscribeToTopic();
|
|
10089
10111
|
this.subscription.add(this.backend.userChanged.subscribe(() => this.authenticate()));
|
|
10090
10112
|
socket.addEventListener('open', async () => {
|
|
10091
|
-
this.
|
|
10113
|
+
console.log(`[Banta/${this.identifier}] Socket is open`);
|
|
10092
10114
|
});
|
|
10093
10115
|
socket.addEventListener('lost', async () => {
|
|
10094
10116
|
this.state = 'lost';
|
|
10095
10117
|
});
|
|
10096
10118
|
socket.addEventListener('restore', async () => {
|
|
10097
|
-
this.
|
|
10119
|
+
this.wasRestored = true;
|
|
10098
10120
|
await this.authenticate();
|
|
10099
10121
|
await this.subscribeToTopic();
|
|
10100
10122
|
});
|
|
10123
|
+
await this.subscribeToTopic();
|
|
10101
10124
|
return this;
|
|
10102
10125
|
}
|
|
10103
10126
|
mapOrUpdateMessages(messages) {
|
|
@@ -10115,9 +10138,16 @@ class ChatSource extends SocketRPC {
|
|
|
10115
10138
|
return message;
|
|
10116
10139
|
}
|
|
10117
10140
|
async getExistingMessages() {
|
|
10118
|
-
|
|
10119
|
-
|
|
10120
|
-
|
|
10141
|
+
try {
|
|
10142
|
+
let messages = await this.peer.getExistingMessages();
|
|
10143
|
+
messages = this.mapOrUpdateMessages(messages);
|
|
10144
|
+
return messages;
|
|
10145
|
+
}
|
|
10146
|
+
catch (e) {
|
|
10147
|
+
console.error(`[Banta/${this.identifier}] Error occurred while trying to get existing messages:`);
|
|
10148
|
+
console.error(e);
|
|
10149
|
+
return [];
|
|
10150
|
+
}
|
|
10121
10151
|
}
|
|
10122
10152
|
async ensureConnection(errorMessage) {
|
|
10123
10153
|
let reason = `Connection to chat services is not currently available.`;
|
|
@@ -10132,8 +10162,30 @@ class ChatSource extends SocketRPC {
|
|
|
10132
10162
|
await this.ensureConnection();
|
|
10133
10163
|
await this.peer.editMessage(messageId, text);
|
|
10134
10164
|
}
|
|
10165
|
+
get errorState() {
|
|
10166
|
+
return this._errorState;
|
|
10167
|
+
}
|
|
10135
10168
|
async subscribeToTopic() {
|
|
10136
|
-
|
|
10169
|
+
try {
|
|
10170
|
+
await this.peer.subscribe(this.identifier, this.parentIdentifier, this.sortOrder);
|
|
10171
|
+
this.subscribeAttempt = 0;
|
|
10172
|
+
this._errorState = undefined;
|
|
10173
|
+
this.state = this.wasRestored ? 'restored' : 'connected';
|
|
10174
|
+
this.markReady();
|
|
10175
|
+
}
|
|
10176
|
+
catch (e) {
|
|
10177
|
+
console.error(`[Banta/${this.identifier}] Error while subscribing to topic`);
|
|
10178
|
+
console.error(e);
|
|
10179
|
+
this.state = 'lost';
|
|
10180
|
+
this._errorState = 'server-issue';
|
|
10181
|
+
this.subscribeAttempt += 1;
|
|
10182
|
+
let delay = Math.min(30 * 1000, (3 * 1000 * this.subscribeAttempt) * (1 + Math.random()));
|
|
10183
|
+
console.error(`[Banta/${this.identifier}] Waiting ${delay}ms before attempting to reconnect...`);
|
|
10184
|
+
setTimeout(() => {
|
|
10185
|
+
console.info(`Attempting reconnection after error in subscribeToTopic...`);
|
|
10186
|
+
this.reconnect();
|
|
10187
|
+
}, delay);
|
|
10188
|
+
}
|
|
10137
10189
|
}
|
|
10138
10190
|
async authenticate() {
|
|
10139
10191
|
if (this.backend.user) {
|
|
@@ -10251,12 +10303,24 @@ class ChatBackend extends ChatBackendBase {
|
|
|
10251
10303
|
return await new ChatSource(this, topicId, messageId, options?.sortOrder || CommentsOrder.NEWEST)
|
|
10252
10304
|
.bind(await this.connectToService());
|
|
10253
10305
|
}
|
|
10306
|
+
/**
|
|
10307
|
+
* Get the count of the given topic
|
|
10308
|
+
* @param topicId
|
|
10309
|
+
* @returns
|
|
10310
|
+
*/
|
|
10254
10311
|
async getSourceCountForTopic(topicId) {
|
|
10255
|
-
|
|
10256
|
-
|
|
10257
|
-
|
|
10258
|
-
|
|
10259
|
-
|
|
10312
|
+
try {
|
|
10313
|
+
let response = await fetch(`${this.serviceUrl}/topics/${topicId}`);
|
|
10314
|
+
if (response.status >= 400)
|
|
10315
|
+
return 0;
|
|
10316
|
+
let topic = await response.json();
|
|
10317
|
+
return topic.messageCount || 0;
|
|
10318
|
+
}
|
|
10319
|
+
catch (e) {
|
|
10320
|
+
console.error(`[Banta/${topicId}] Failed to get message count for topic:`);
|
|
10321
|
+
console.error(e);
|
|
10322
|
+
return undefined;
|
|
10323
|
+
}
|
|
10260
10324
|
}
|
|
10261
10325
|
refreshMessage(message) {
|
|
10262
10326
|
throw new Error("Method not implemented.");
|
|
@@ -10426,9 +10490,7 @@ BantaSdkModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version:
|
|
|
10426
10490
|
BantaSdkModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: BantaSdkModule, declarations: [BantaComponent,
|
|
10427
10491
|
BantaLogoComponent,
|
|
10428
10492
|
LiveMessageComponent], imports: [CommonModule,
|
|
10429
|
-
FormsModule,
|
|
10430
|
-
BantaCommonModule,
|
|
10431
|
-
CommentsModule,
|
|
10493
|
+
FormsModule, BantaCommonModule, CommentsModule,
|
|
10432
10494
|
ChatModule,
|
|
10433
10495
|
EmojiModule,
|
|
10434
10496
|
MatIconModule,
|
|
@@ -10450,7 +10512,7 @@ BantaSdkModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
|
|
|
10450
10512
|
EmojiModule] });
|
|
10451
10513
|
BantaSdkModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaSdkModule, imports: [CommonModule,
|
|
10452
10514
|
FormsModule,
|
|
10453
|
-
BantaCommonModule,
|
|
10515
|
+
BantaCommonModule.forRoot(),
|
|
10454
10516
|
CommentsModule,
|
|
10455
10517
|
ChatModule,
|
|
10456
10518
|
EmojiModule,
|
|
@@ -10474,7 +10536,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
10474
10536
|
imports: [
|
|
10475
10537
|
CommonModule,
|
|
10476
10538
|
FormsModule,
|
|
10477
|
-
BantaCommonModule,
|
|
10539
|
+
BantaCommonModule.forRoot(),
|
|
10478
10540
|
CommentsModule,
|
|
10479
10541
|
ChatModule,
|
|
10480
10542
|
EmojiModule,
|