@banta/sdk 4.7.10 → 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/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 +108 -45
- package/fesm2015/banta-sdk.mjs.map +1 -1
- package/fesm2020/banta-sdk.mjs +106 -45
- 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/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) {
|
|
@@ -512,6 +523,14 @@ const COMPONENTS$3 = [
|
|
|
512
523
|
BantaAttachmentsComponent
|
|
513
524
|
];
|
|
514
525
|
class BantaCommonModule {
|
|
526
|
+
static forRoot() {
|
|
527
|
+
return {
|
|
528
|
+
ngModule: BantaCommonModule,
|
|
529
|
+
providers: [
|
|
530
|
+
TimerPool
|
|
531
|
+
]
|
|
532
|
+
};
|
|
533
|
+
}
|
|
515
534
|
}
|
|
516
535
|
BantaCommonModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaCommonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
517
536
|
BantaCommonModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: BantaCommonModule, declarations: [TimestampComponent,
|
|
@@ -7128,12 +7147,12 @@ class EmojiSelectorPanelComponent {
|
|
|
7128
7147
|
this.categories = this.pairs(cats).map(pair => pair[1]);
|
|
7129
7148
|
}
|
|
7130
7149
|
}
|
|
7131
|
-
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 });
|
|
7132
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"] }] });
|
|
7133
7152
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorPanelComponent, decorators: [{
|
|
7134
7153
|
type: Component,
|
|
7135
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"] }]
|
|
7136
|
-
}], ctorParameters: function () { return [{ type: i1.DomSanitizer }, { type: undefined, decorators: [{
|
|
7155
|
+
}], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }, { type: undefined, decorators: [{
|
|
7137
7156
|
type: Inject,
|
|
7138
7157
|
args: [BANTA_SDK_OPTIONS]
|
|
7139
7158
|
}, {
|
|
@@ -7207,7 +7226,7 @@ class EmojiSelectorButtonComponent {
|
|
|
7207
7226
|
this.overlayRef.attach(this.selectorPanelTemplate);
|
|
7208
7227
|
}
|
|
7209
7228
|
}
|
|
7210
|
-
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 });
|
|
7211
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: `
|
|
7212
7231
|
<button #button type="button" mat-icon-button (click)="show()">
|
|
7213
7232
|
<mat-icon>emoji_emotions</mat-icon>
|
|
@@ -7232,7 +7251,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
7232
7251
|
></emoji-selector-panel>
|
|
7233
7252
|
</ng-template>
|
|
7234
7253
|
`, styles: [":host{display:block;position:relative}button{color:#666}\n"] }]
|
|
7235
|
-
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1$
|
|
7254
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1$2.Overlay }]; }, propDecorators: { selectorPanelTemplate: [{
|
|
7236
7255
|
type: ViewChild,
|
|
7237
7256
|
args: ['selectorPanelTemplate']
|
|
7238
7257
|
}], selected: [{
|
|
@@ -7947,12 +7966,12 @@ class AttachmentButtonComponent {
|
|
|
7947
7966
|
}
|
|
7948
7967
|
}
|
|
7949
7968
|
}
|
|
7950
|
-
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 });
|
|
7951
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"] }] });
|
|
7952
7971
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AttachmentButtonComponent, decorators: [{
|
|
7953
7972
|
type: Component,
|
|
7954
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"] }]
|
|
7955
|
-
}], ctorParameters: function () { return [{ type: i1$
|
|
7974
|
+
}], ctorParameters: function () { return [{ type: i1$3.CDNProvider }]; }, propDecorators: { fileInput: [{
|
|
7956
7975
|
type: ViewChild,
|
|
7957
7976
|
args: ['fileUpload', { static: false }]
|
|
7958
7977
|
}], addedAttachment: [{
|
|
@@ -8105,7 +8124,10 @@ class CommentFieldComponent {
|
|
|
8105
8124
|
if (this._source.connectionStateChanged) {
|
|
8106
8125
|
this._subs.add(this._source.connectionStateChanged.subscribe(state => {
|
|
8107
8126
|
if (state === 'lost') {
|
|
8108
|
-
this.
|
|
8127
|
+
if (this._source.errorState === 'server-issue')
|
|
8128
|
+
this.transientMessage = `Error occurred, trying again...`;
|
|
8129
|
+
else
|
|
8130
|
+
this.transientMessage = `Reconnecting...`;
|
|
8109
8131
|
}
|
|
8110
8132
|
else if (state === 'restored') {
|
|
8111
8133
|
this.transientMessage = undefined;
|
|
@@ -8696,7 +8718,7 @@ class BantaCommentsComponent {
|
|
|
8696
8718
|
return this.threadView;
|
|
8697
8719
|
}
|
|
8698
8720
|
updateLoading() {
|
|
8699
|
-
if (this.source?.state && this.source?.state
|
|
8721
|
+
if (this.source?.state && !['connecting', 'lost'].includes(this.source?.state)) {
|
|
8700
8722
|
clearInterval(this._loadingTimer);
|
|
8701
8723
|
this.loadingMessage = `Here we go!`;
|
|
8702
8724
|
setTimeout(() => {
|
|
@@ -10064,6 +10086,8 @@ class ChatSource extends SocketRPC {
|
|
|
10064
10086
|
this.subscription = new Subscription();
|
|
10065
10087
|
this._state = 'connecting';
|
|
10066
10088
|
this._connectionStateChanged = new Subject();
|
|
10089
|
+
this.wasRestored = false;
|
|
10090
|
+
this.subscribeAttempt = 0;
|
|
10067
10091
|
this.messageMap = new Map();
|
|
10068
10092
|
this._messageReceived = new Subject();
|
|
10069
10093
|
this._messageUpdated = new Subject();
|
|
@@ -10084,21 +10108,19 @@ class ChatSource extends SocketRPC {
|
|
|
10084
10108
|
}
|
|
10085
10109
|
async bind(socket) {
|
|
10086
10110
|
super.bind(socket);
|
|
10087
|
-
this.state = 'connected';
|
|
10088
|
-
this.markReady();
|
|
10089
|
-
await this.subscribeToTopic();
|
|
10090
10111
|
this.subscription.add(this.backend.userChanged.subscribe(() => this.authenticate()));
|
|
10091
10112
|
socket.addEventListener('open', async () => {
|
|
10092
|
-
this.
|
|
10113
|
+
console.log(`[Banta/${this.identifier}] Socket is open`);
|
|
10093
10114
|
});
|
|
10094
10115
|
socket.addEventListener('lost', async () => {
|
|
10095
10116
|
this.state = 'lost';
|
|
10096
10117
|
});
|
|
10097
10118
|
socket.addEventListener('restore', async () => {
|
|
10098
|
-
this.
|
|
10119
|
+
this.wasRestored = true;
|
|
10099
10120
|
await this.authenticate();
|
|
10100
10121
|
await this.subscribeToTopic();
|
|
10101
10122
|
});
|
|
10123
|
+
await this.subscribeToTopic();
|
|
10102
10124
|
return this;
|
|
10103
10125
|
}
|
|
10104
10126
|
mapOrUpdateMessages(messages) {
|
|
@@ -10116,9 +10138,16 @@ class ChatSource extends SocketRPC {
|
|
|
10116
10138
|
return message;
|
|
10117
10139
|
}
|
|
10118
10140
|
async getExistingMessages() {
|
|
10119
|
-
|
|
10120
|
-
|
|
10121
|
-
|
|
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
|
+
}
|
|
10122
10151
|
}
|
|
10123
10152
|
async ensureConnection(errorMessage) {
|
|
10124
10153
|
let reason = `Connection to chat services is not currently available.`;
|
|
@@ -10133,8 +10162,30 @@ class ChatSource extends SocketRPC {
|
|
|
10133
10162
|
await this.ensureConnection();
|
|
10134
10163
|
await this.peer.editMessage(messageId, text);
|
|
10135
10164
|
}
|
|
10165
|
+
get errorState() {
|
|
10166
|
+
return this._errorState;
|
|
10167
|
+
}
|
|
10136
10168
|
async subscribeToTopic() {
|
|
10137
|
-
|
|
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
|
+
}
|
|
10138
10189
|
}
|
|
10139
10190
|
async authenticate() {
|
|
10140
10191
|
if (this.backend.user) {
|
|
@@ -10252,12 +10303,24 @@ class ChatBackend extends ChatBackendBase {
|
|
|
10252
10303
|
return await new ChatSource(this, topicId, messageId, options?.sortOrder || CommentsOrder.NEWEST)
|
|
10253
10304
|
.bind(await this.connectToService());
|
|
10254
10305
|
}
|
|
10306
|
+
/**
|
|
10307
|
+
* Get the count of the given topic
|
|
10308
|
+
* @param topicId
|
|
10309
|
+
* @returns
|
|
10310
|
+
*/
|
|
10255
10311
|
async getSourceCountForTopic(topicId) {
|
|
10256
|
-
|
|
10257
|
-
|
|
10258
|
-
|
|
10259
|
-
|
|
10260
|
-
|
|
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
|
+
}
|
|
10261
10324
|
}
|
|
10262
10325
|
refreshMessage(message) {
|
|
10263
10326
|
throw new Error("Method not implemented.");
|
|
@@ -10427,9 +10490,7 @@ BantaSdkModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version:
|
|
|
10427
10490
|
BantaSdkModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: BantaSdkModule, declarations: [BantaComponent,
|
|
10428
10491
|
BantaLogoComponent,
|
|
10429
10492
|
LiveMessageComponent], imports: [CommonModule,
|
|
10430
|
-
FormsModule,
|
|
10431
|
-
BantaCommonModule,
|
|
10432
|
-
CommentsModule,
|
|
10493
|
+
FormsModule, BantaCommonModule, CommentsModule,
|
|
10433
10494
|
ChatModule,
|
|
10434
10495
|
EmojiModule,
|
|
10435
10496
|
MatIconModule,
|
|
@@ -10451,7 +10512,7 @@ BantaSdkModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
|
|
|
10451
10512
|
EmojiModule] });
|
|
10452
10513
|
BantaSdkModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaSdkModule, imports: [CommonModule,
|
|
10453
10514
|
FormsModule,
|
|
10454
|
-
BantaCommonModule,
|
|
10515
|
+
BantaCommonModule.forRoot(),
|
|
10455
10516
|
CommentsModule,
|
|
10456
10517
|
ChatModule,
|
|
10457
10518
|
EmojiModule,
|
|
@@ -10475,7 +10536,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
10475
10536
|
imports: [
|
|
10476
10537
|
CommonModule,
|
|
10477
10538
|
FormsModule,
|
|
10478
|
-
BantaCommonModule,
|
|
10539
|
+
BantaCommonModule.forRoot(),
|
|
10479
10540
|
CommentsModule,
|
|
10480
10541
|
ChatModule,
|
|
10481
10542
|
EmojiModule,
|