@banta/sdk 3.3.9 → 4.0.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.
- package/banta-sdk.metadata.json +1 -1
- package/bundles/banta-sdk.umd.js +1142 -410
- package/bundles/banta-sdk.umd.js.map +1 -1
- package/bundles/banta-sdk.umd.min.js +1 -1
- package/bundles/banta-sdk.umd.min.js.map +1 -1
- package/esm2015/banta-sdk.js +1 -1
- package/esm2015/lib/banta/banta.component.js +10 -16
- package/esm2015/lib/banta-logo.component.js +1 -1
- package/esm2015/lib/banta-sdk.module.js +10 -4
- package/esm2015/lib/chat/banta-chat/banta-chat.component.js +15 -18
- package/esm2015/lib/chat/chat-message/chat-message.component.js +3 -3
- package/esm2015/lib/chat/chat-view/chat-view.component.js +8 -7
- package/esm2015/lib/chat/chat.module.js +1 -1
- package/esm2015/lib/chat/index.js +1 -1
- package/esm2015/lib/chat/live-chat-message.component.js +3 -3
- package/esm2015/lib/chat-backend-base.js +17 -0
- package/esm2015/lib/chat-backend.js +74 -0
- package/esm2015/lib/chat-source-base.js +2 -0
- package/esm2015/lib/chat-source.js +151 -0
- package/esm2015/lib/comments/banta-comments/banta-comments.component.js +331 -172
- package/esm2015/lib/comments/comment/comment.component.js +56 -18
- package/esm2015/lib/comments/comment-field/comment-field.component.js +17 -15
- package/esm2015/lib/comments/comment-sort/comment-sort.component.js +1 -1
- package/esm2015/lib/comments/comment-view/comment-view.component.js +78 -40
- package/esm2015/lib/comments/comments.module.js +1 -1
- package/esm2015/lib/comments/index.js +1 -1
- package/esm2015/lib/comments/live-comment.component.js +3 -3
- package/esm2015/lib/common/common.module.js +1 -1
- package/esm2015/lib/common/index.js +1 -3
- package/esm2015/lib/common/lazy-connection.js +1 -1
- package/esm2015/lib/common/timestamp.component.js +1 -1
- package/esm2015/lib/emoji/emoji-selector-button.component.js +1 -1
- package/esm2015/lib/emoji/emoji-selector-panel/emoji-selector-panel.component.js +2 -2
- package/esm2015/lib/emoji/emoji.module.js +1 -1
- package/esm2015/lib/emoji/emojis.js +1 -1
- package/esm2015/lib/emoji/index.js +1 -1
- package/esm2015/lib/index.js +6 -1
- package/esm2015/lib/live-message.component.js +1 -1
- package/esm2015/lib/sdk-options.js +2 -0
- package/esm2015/public-api.js +1 -1
- package/fesm2015/banta-sdk.js +750 -308
- package/fesm2015/banta-sdk.js.map +1 -1
- package/lib/banta/banta.component.d.ts +8 -9
- package/lib/banta-sdk.module.d.ts +2 -1
- package/lib/chat/banta-chat/banta-chat.component.d.ts +8 -10
- package/lib/chat/chat-view/chat-view.component.d.ts +7 -4
- package/lib/chat/live-chat-message.component.d.ts +2 -2
- package/lib/chat-backend-base.d.ts +22 -0
- package/lib/chat-backend.d.ts +21 -0
- package/lib/chat-source-base.d.ts +31 -0
- package/lib/chat-source.d.ts +38 -0
- package/lib/comments/banta-comments/banta-comments.component.d.ts +65 -60
- package/lib/comments/comment/comment.component.d.ts +25 -5
- package/lib/comments/comment-field/comment-field.component.d.ts +7 -3
- package/lib/comments/comment-view/comment-view.component.d.ts +26 -8
- package/lib/comments/live-comment.component.d.ts +2 -2
- package/lib/common/index.d.ts +0 -2
- package/lib/index.d.ts +5 -0
- package/lib/sdk-options.d.ts +4 -0
- package/package.json +2 -2
- package/esm2015/lib/common/banta.service.js +0 -21
- package/esm2015/lib/common/chat-backend.service.js +0 -7
- package/lib/common/banta.service.d.ts +0 -9
- package/lib/common/chat-backend.service.d.ts +0 -14
package/fesm2015/banta-sdk.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Observable, Subject, BehaviorSubject, Subscription } from 'rxjs';
|
|
2
2
|
import { publish } from 'rxjs/operators';
|
|
3
|
-
import {
|
|
3
|
+
import { Component, Input, NgModule, Output, ViewChild, ElementRef, HostBinding, Injectable, Inject } from '@angular/core';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
6
6
|
import { MatIconModule } from '@angular/material/icon';
|
|
@@ -8,9 +8,9 @@ import { MatButtonModule } from '@angular/material/button';
|
|
|
8
8
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
9
9
|
import { MatInputModule } from '@angular/material/input';
|
|
10
10
|
import { FormsModule } from '@angular/forms';
|
|
11
|
-
import { __awaiter } from 'tslib';
|
|
11
|
+
import { __awaiter, __decorate, __metadata } from 'tslib';
|
|
12
12
|
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
|
13
|
-
import { CommentsOrder } from '@banta/common';
|
|
13
|
+
import { CommentsOrder, SocketRPC, RpcEvent, DurableSocket } from '@banta/common';
|
|
14
14
|
import { ActivatedRoute } from '@angular/router';
|
|
15
15
|
import { MatMenuModule } from '@angular/material/menu';
|
|
16
16
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
@@ -31,25 +31,6 @@ function lazyConnection(options) {
|
|
|
31
31
|
return obs.pipe(publish()).refCount();
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
class BantaService {
|
|
35
|
-
constructor() {
|
|
36
|
-
this._userChanged = new BehaviorSubject(null);
|
|
37
|
-
}
|
|
38
|
-
get userChanged() {
|
|
39
|
-
return this._userChanged;
|
|
40
|
-
}
|
|
41
|
-
set user(user) {
|
|
42
|
-
this._user = user;
|
|
43
|
-
this._userChanged.next(user);
|
|
44
|
-
}
|
|
45
|
-
get user() {
|
|
46
|
-
return this._user;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
BantaService.decorators = [
|
|
50
|
-
{ type: Injectable }
|
|
51
|
-
];
|
|
52
|
-
|
|
53
34
|
class TimestampComponent {
|
|
54
35
|
constructor() {
|
|
55
36
|
this.relative = '';
|
|
@@ -155,12 +136,6 @@ TimestampComponent.propDecorators = {
|
|
|
155
136
|
value: [{ type: Input }]
|
|
156
137
|
};
|
|
157
138
|
|
|
158
|
-
class ChatBackendService {
|
|
159
|
-
}
|
|
160
|
-
ChatBackendService.decorators = [
|
|
161
|
-
{ type: Injectable }
|
|
162
|
-
];
|
|
163
|
-
|
|
164
139
|
const COMPONENTS = [
|
|
165
140
|
TimestampComponent
|
|
166
141
|
];
|
|
@@ -6756,7 +6731,7 @@ EmojiSelectorPanelComponent.decorators = [
|
|
|
6756
6731
|
{ type: Component, args: [{
|
|
6757
6732
|
selector: 'emoji-selector-panel',
|
|
6758
6733
|
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>",
|
|
6759
|
-
styles: [":host{background:#111;border:1px solid #333;border-radius:5px;
|
|
6734
|
+
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)}.selector{display:flex;flex-direction:column}.categories a{opacity:.25;transition:opacity .4s 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}}"]
|
|
6760
6735
|
},] }
|
|
6761
6736
|
];
|
|
6762
6737
|
EmojiSelectorPanelComponent.ctorParameters = () => [
|
|
@@ -6956,8 +6931,8 @@ class ChatMessageComponent {
|
|
|
6956
6931
|
ChatMessageComponent.decorators = [
|
|
6957
6932
|
{ type: Component, args: [{
|
|
6958
6933
|
selector: 'banta-chat-message',
|
|
6959
|
-
template: "<div class=\"message-content\">\r\n <div class=\"user\" (click)=\"selectUser()\">\r\n <div class=\"avatar\" [style.background-image]=\"avatarForUser(message.user)\"></div>\r\n <label>{{message.user.username}}</label>\r\n </div>\r\n <div class=\"content\">\r\n <div (click)=\"select()\">\r\n {{message.message}}\r\n </div>\r\n <div class=\"status\">\r\n <div class=\"count-indicator\" *ngIf=\"message.
|
|
6960
|
-
styles: [":host{align-items:center;background-color:#fff;color:#000;
|
|
6934
|
+
template: "<div class=\"message-content\">\r\n <div class=\"user\" (click)=\"selectUser()\">\r\n <div class=\"avatar\" [style.background-image]=\"avatarForUser(message.user)\"></div>\r\n <label>{{message.user.username}}</label>\r\n </div>\r\n <div class=\"content\">\r\n <div (click)=\"select()\">\r\n {{message.message}}\r\n </div>\r\n <div class=\"status\">\r\n <div class=\"count-indicator\" *ngIf=\"message.likes > 0\">\r\n {{message.likes}} <mat-icon [inline]=\"true\">star</mat-icon>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"actions\">\r\n <button mat-icon-button matTooltip=\"Upvote\" matTooltipPosition=\"below\" (click)=\"upvote()\">\r\n <mat-icon [inline]=\"true\">thumb_up</mat-icon>\r\n </button>\r\n <button mat-icon-button matTooltip=\"Report\" matTooltipPosition=\"below\" (click)=\"report()\">\r\n <mat-icon [inline]=\"true\">report</mat-icon>\r\n </button>\r\n</div>",
|
|
6935
|
+
styles: [":host{display:flex;flex-direction:row;align-items:center;padding:0 1em;background-color:#fff;color:#000;transition:background-color .4s ease-out}:host .message-content .content{color:#111}:host:hover{background-color:#ddd}:host.highlight{background:#00121b}:host.highlight:hover{background:#01324d}:host:nth-child(2n){background-color:#eee}:host:nth-child(2n):hover{background:#ddd}:host:nth-child(2n) .message-content .content{color:#222}:host:nth-child(2n).highlight{background:#001a2a}:host:nth-child(2n).highlight:hover{background:#002b44}:host .message-content{display:flex;flex-direction:row;flex-grow:1;align-items:center}:host .message-content .content{display:flex;flex-direction:row;padding:5px 0}:host .message-content .content .status{display:flex;flex-direction:row;align-items:center;margin-left:1em}:host .message-content .content .status mat-icon{margin-left:.5em}:host .user{color:#999;font-weight:400;text-align:right;margin-right:.25em;flex-shrink:0;display:flex;align-items:center}:host .user .avatar{background-position:50%;background-size:cover;background-color:#333;border-radius:100%;flex-shrink:0;flex-grow:0;margin-right:1em;width:2em;height:2em}:host .user:after{content:\":\";margin-right:1em}:host .content{flex-grow:1}:host .actions{flex-shrink:0;white-space:nowrap;opacity:0;transition:opacity .4s ease-out}:host:hover .actions{opacity:1}.count-indicator{white-space:nowrap}:host-context(.mat-dark-theme){background-color:#000;color:#fff}:host-context(.mat-dark-theme) .message-content .content{color:#ddd}:host-context(.mat-dark-theme):hover{background-color:#111}:host-context(.mat-dark-theme):nth-child(2n).highlight{background:#001a2a}:host-context(.mat-dark-theme):nth-child(2n).highlight:hover{background:#002b44}:host-context(.mat-dark-theme):nth-child(2n):hover{background-color:#111}:host-context(.mat-dark-theme):nth-child(2n){background-color:#080808}:host-context(.mat-dark-theme):nth-child(2n) .message-content .content{color:#eee}label{margin:0}"]
|
|
6961
6936
|
},] }
|
|
6962
6937
|
];
|
|
6963
6938
|
ChatMessageComponent.propDecorators = {
|
|
@@ -6968,6 +6943,22 @@ ChatMessageComponent.propDecorators = {
|
|
|
6968
6943
|
upvoted: [{ type: Output }]
|
|
6969
6944
|
};
|
|
6970
6945
|
|
|
6946
|
+
class ChatBackendBase {
|
|
6947
|
+
constructor() {
|
|
6948
|
+
this._userChanged = new BehaviorSubject(null);
|
|
6949
|
+
}
|
|
6950
|
+
get userChanged() {
|
|
6951
|
+
return this._userChanged;
|
|
6952
|
+
}
|
|
6953
|
+
set user(user) {
|
|
6954
|
+
this._user = user;
|
|
6955
|
+
this._userChanged.next(user);
|
|
6956
|
+
}
|
|
6957
|
+
get user() {
|
|
6958
|
+
return this._user;
|
|
6959
|
+
}
|
|
6960
|
+
}
|
|
6961
|
+
|
|
6971
6962
|
class LiveChatMessageComponent {
|
|
6972
6963
|
constructor(backend) {
|
|
6973
6964
|
this.backend = backend;
|
|
@@ -7027,7 +7018,7 @@ LiveChatMessageComponent.decorators = [
|
|
|
7027
7018
|
},] }
|
|
7028
7019
|
];
|
|
7029
7020
|
LiveChatMessageComponent.ctorParameters = () => [
|
|
7030
|
-
{ type:
|
|
7021
|
+
{ type: ChatBackendBase }
|
|
7031
7022
|
];
|
|
7032
7023
|
LiveChatMessageComponent.propDecorators = {
|
|
7033
7024
|
upvoted: [{ type: Output }],
|
|
@@ -7037,7 +7028,8 @@ LiveChatMessageComponent.propDecorators = {
|
|
|
7037
7028
|
};
|
|
7038
7029
|
|
|
7039
7030
|
class ChatViewComponent {
|
|
7040
|
-
constructor(elementRef) {
|
|
7031
|
+
constructor(backend, elementRef) {
|
|
7032
|
+
this.backend = backend;
|
|
7041
7033
|
this.elementRef = elementRef;
|
|
7042
7034
|
this._sourceSubs = new Subscription();
|
|
7043
7035
|
this._selected = new Subject();
|
|
@@ -7078,10 +7070,8 @@ class ChatViewComponent {
|
|
|
7078
7070
|
console.dir(this.messages);
|
|
7079
7071
|
this._sourceSubs.add(this._source.messageReceived.subscribe(msg => this.messageReceived(msg)));
|
|
7080
7072
|
this._sourceSubs.add(this._source.messageSent.subscribe(msg => this.messageSent(msg)));
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
.subscribe(user => this.currentUser = user));
|
|
7084
|
-
}
|
|
7073
|
+
this._sourceSubs.add(this.backend.userChanged
|
|
7074
|
+
.subscribe(user => this.currentUser = user));
|
|
7085
7075
|
}
|
|
7086
7076
|
}
|
|
7087
7077
|
addMessage(message) {
|
|
@@ -7163,10 +7153,11 @@ ChatViewComponent.decorators = [
|
|
|
7163
7153
|
{ type: Component, args: [{
|
|
7164
7154
|
selector: 'banta-chat-view',
|
|
7165
7155
|
template: "<div class=\"message-container\" #messageContainer>\r\n <ng-content select=\"[data-before]\"></ng-content>\r\n <ng-container *ngFor=\"let message of messages\">\r\n <banta-chat-message\r\n *ngIf=\"!message.hidden\"\r\n [message]=\"message\"\r\n [class.highlight]=\"mentionsMe(message)\" \r\n [class.flash]=\"message.id === flashedMessageId\"\r\n (selected)=\"selectMessage(message)\"\r\n (upvoted)=\"upvoteMessage(message)\"\r\n (reported)=\"reportMessage(message)\"\r\n (userSelected)=\"selectMessageUser(message)\"\r\n [attr.data-id]=\"message.id\"\r\n >\r\n </banta-chat-message>\r\n </ng-container>\r\n <ng-content select=\":not([data-before])\"></ng-content>\r\n</div>",
|
|
7166
|
-
styles: [":host{display:flex;flex-direction:column;flex-grow:1}.message-container{
|
|
7156
|
+
styles: [":host{display:flex;flex-direction:column;flex-grow:1}.message-container{flex-grow:1;overflow-y:auto;overflow-x:hidden;height:10em;color:#000;background:#fff;padding:.5em 1em .5em .5em}.message-container.no-scroll{height:auto;overflow-y:visible}:host-context(.mat-dark-theme) .message-container{color:#fff;background:#000}banta-chat-message.flash{-webkit-animation:flash;animation:flash;-webkit-animation-duration:2.5s;animation-duration:2.5s;-webkit-animation-iteration-count:1;animation-iteration-count:1}@-webkit-keyframes flash{0%{transform:scale(1);background:#425700}25%{transform:scale(1.05)}50%{transform:scale(1)}75%{transform:scale(1.05)}to{transform:scale(1)}}@keyframes flash{0%{transform:scale(1);background:#425700}25%{transform:scale(1.05)}50%{transform:scale(1)}75%{transform:scale(1.05)}to{transform:scale(1)}}"]
|
|
7167
7157
|
},] }
|
|
7168
7158
|
];
|
|
7169
7159
|
ChatViewComponent.ctorParameters = () => [
|
|
7160
|
+
{ type: ChatBackendBase },
|
|
7170
7161
|
{ type: ElementRef }
|
|
7171
7162
|
];
|
|
7172
7163
|
ChatViewComponent.propDecorators = {
|
|
@@ -7183,10 +7174,8 @@ ChatViewComponent.propDecorators = {
|
|
|
7183
7174
|
* Chat component
|
|
7184
7175
|
*/
|
|
7185
7176
|
class BantaChatComponent {
|
|
7186
|
-
constructor(
|
|
7187
|
-
this.banta = banta;
|
|
7177
|
+
constructor(backend) {
|
|
7188
7178
|
this.backend = backend;
|
|
7189
|
-
this.elementRef = elementRef;
|
|
7190
7179
|
this._subs = new Subscription();
|
|
7191
7180
|
this.user = null;
|
|
7192
7181
|
this.signInLabel = 'Sign In';
|
|
@@ -7202,7 +7191,7 @@ class BantaChatComponent {
|
|
|
7202
7191
|
this.newMessage = {};
|
|
7203
7192
|
}
|
|
7204
7193
|
ngOnInit() {
|
|
7205
|
-
this._subs.add(this.
|
|
7194
|
+
this._subs.add(this.backend.userChanged.subscribe(user => this.user = user));
|
|
7206
7195
|
}
|
|
7207
7196
|
ngOnDestroy() {
|
|
7208
7197
|
this._subs.unsubscribe();
|
|
@@ -7275,14 +7264,15 @@ class BantaChatComponent {
|
|
|
7275
7264
|
return this._userSelected;
|
|
7276
7265
|
}
|
|
7277
7266
|
get canChat() {
|
|
7278
|
-
var _a;
|
|
7279
7267
|
if (!this.user)
|
|
7280
7268
|
return false;
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
return
|
|
7269
|
+
// TODO
|
|
7270
|
+
// if (!this.user.permissions)
|
|
7271
|
+
// return true;
|
|
7272
|
+
// if (!this.user.permissions.canChat)
|
|
7273
|
+
// return true;
|
|
7274
|
+
// return this.user.permissions?.canChat(this.source);
|
|
7275
|
+
return true;
|
|
7286
7276
|
}
|
|
7287
7277
|
sendMessage() {
|
|
7288
7278
|
var _a;
|
|
@@ -7296,7 +7286,7 @@ class BantaChatComponent {
|
|
|
7296
7286
|
let message = {
|
|
7297
7287
|
user: null,
|
|
7298
7288
|
sentAt: Date.now(),
|
|
7299
|
-
|
|
7289
|
+
likes: 0,
|
|
7300
7290
|
url: location.href,
|
|
7301
7291
|
message: text
|
|
7302
7292
|
};
|
|
@@ -7317,13 +7307,11 @@ BantaChatComponent.decorators = [
|
|
|
7317
7307
|
{ type: Component, args: [{
|
|
7318
7308
|
selector: 'banta-chat',
|
|
7319
7309
|
template: "<banta-chat-view \r\n #chatView\r\n [source]=\"source\"\r\n (upvoted)=\"upvote($event)\"\r\n (reported)=\"report($event)\"\r\n (selected)=\"select($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 type=\"text\"\r\n name=\"message\" \r\n (keydown)=\"onKeyDown($event)\"\r\n [(ngModel)]=\"newMessage.message\" />\r\n \r\n <emoji-selector-button\r\n (selected)=\"insertEmoji($event)\"\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>",
|
|
7320
|
-
styles: [":host{border-radius:5px;
|
|
7310
|
+
styles: [":host{flex-direction:column;border-radius:5px;padding:10px;font-size:10pt}.entry-container,:host{display:flex;flex-grow:1}.entry-container{flex-direction:row;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:focus,.entry-container input:-webkit-autofill:hover{outline:1px solid #9da302;-webkit-text-fill-color:#9da302;-webkit-box-shadow:0 0 0 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:auto}form{display:flex;padding:.5em 0;align-items:center}form textarea{font-size:14pt;background:#000;color:#fff;border:1px solid #333;min-height:6em;width:100%}form input[type=text]{background:#fff;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:#000;color:#fff;border:1px solid #333}"]
|
|
7321
7311
|
},] }
|
|
7322
7312
|
];
|
|
7323
7313
|
BantaChatComponent.ctorParameters = () => [
|
|
7324
|
-
{ type:
|
|
7325
|
-
{ type: ChatBackendService },
|
|
7326
|
-
{ type: ElementRef }
|
|
7314
|
+
{ type: ChatBackendBase }
|
|
7327
7315
|
];
|
|
7328
7316
|
BantaChatComponent.propDecorators = {
|
|
7329
7317
|
shouldInterceptMessageSend: [{ type: Input }],
|
|
@@ -7367,8 +7355,7 @@ ChatModule.decorators = [
|
|
|
7367
7355
|
* Unified chat and comments component
|
|
7368
7356
|
*/
|
|
7369
7357
|
class BantaComponent {
|
|
7370
|
-
constructor(
|
|
7371
|
-
this.banta = banta;
|
|
7358
|
+
constructor(backend, matDialog) {
|
|
7372
7359
|
this.backend = backend;
|
|
7373
7360
|
this.matDialog = matDialog;
|
|
7374
7361
|
this._subs = new Subscription();
|
|
@@ -7386,7 +7373,7 @@ class BantaComponent {
|
|
|
7386
7373
|
this.genericAvatarUrl = 'https://gravatar.com/avatar/915c804e0be607a4ad766ddadea5c48a?s=512&d=https://codepen.io/assets/avatars/user-avatar-512x512-6e240cf350d2f1cc07c2bed234c3a3bb5f1b237023c204c782622e80d6b212ba.png';
|
|
7387
7374
|
}
|
|
7388
7375
|
ngOnInit() {
|
|
7389
|
-
this._subs.add(this.
|
|
7376
|
+
this._subs.add(this.backend.userChanged.subscribe(user => this.currentUser = user));
|
|
7390
7377
|
this._subs.add(this.backend.notificationsChanged.subscribe(notifs => this.notifications = notifs));
|
|
7391
7378
|
this._subs.add(this.backend.newNotification.subscribe(notif => {
|
|
7392
7379
|
this.newNotifications = true;
|
|
@@ -7401,7 +7388,7 @@ class BantaComponent {
|
|
|
7401
7388
|
let message = {
|
|
7402
7389
|
user: null,
|
|
7403
7390
|
sentAt: Date.now(),
|
|
7404
|
-
|
|
7391
|
+
likes: 0,
|
|
7405
7392
|
message: text
|
|
7406
7393
|
};
|
|
7407
7394
|
try {
|
|
@@ -7514,11 +7501,8 @@ class BantaComponent {
|
|
|
7514
7501
|
}
|
|
7515
7502
|
upvoteMessage(message) {
|
|
7516
7503
|
return __awaiter(this, void 0, void 0, function* () {
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
else
|
|
7520
|
-
yield this.backend.upvoteMessage(message.topicId, message.id);
|
|
7521
|
-
//message.upvotes += 1;
|
|
7504
|
+
// TODO
|
|
7505
|
+
//await this.backend.likeMessage(message.id);
|
|
7522
7506
|
});
|
|
7523
7507
|
}
|
|
7524
7508
|
showProfile(user) {
|
|
@@ -7537,13 +7521,12 @@ class BantaComponent {
|
|
|
7537
7521
|
BantaComponent.decorators = [
|
|
7538
7522
|
{ type: Component, args: [{
|
|
7539
7523
|
selector: `banta`,
|
|
7540
|
-
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 \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.upvotes}}\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>",
|
|
7541
|
-
styles: [":host{display:flex;flex-direction:row;height:40em;
|
|
7524
|
+
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 \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>",
|
|
7525
|
+
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;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis}header:after,header label{display:block;position:relative}header:after{content:\"\";border:1px solid #ccc;height:0;width:100%;z-index:0}.points{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:auto}: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:width .2s ease-in,max-width .2s ease-in;position:relative}.points .points-section{opacity:1;z-index:2}.points .point-focus,.points .points-section{flex-grow:1;display:flex;flex-direction:column;transition:opacity .2s ease-in}.points .point-focus{position:absolute;width:100%;bottom:0;top:1.75em;right:0;left:0;padding:.5em;opacity:0}.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;min-height:6em}form input[type=text],form textarea{background:#000;color:#fff;border:1px solid #333;width:100%}form input[type=text]{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:0;min-width:0;overflow-x:hidden;transition:width .4s ease-out,min-width .4s 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}.aux,:host.point-focus .points{width:100%;max-width:100%}.aux{min-width:0}.aux,.firehose,.points{position:absolute;top:2em;left:0;right:0;bottom:0;z-index:0;background:#000}.aux.focus,.firehose.focus,.points.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}"]
|
|
7542
7526
|
},] }
|
|
7543
7527
|
];
|
|
7544
7528
|
BantaComponent.ctorParameters = () => [
|
|
7545
|
-
{ type:
|
|
7546
|
-
{ type: ChatBackendService },
|
|
7529
|
+
{ type: ChatBackendBase },
|
|
7547
7530
|
{ type: MatDialog }
|
|
7548
7531
|
];
|
|
7549
7532
|
BantaComponent.propDecorators = {
|
|
@@ -7650,7 +7633,8 @@ class CommentComponent {
|
|
|
7650
7633
|
constructor() {
|
|
7651
7634
|
this._reported = new Subject();
|
|
7652
7635
|
this._selected = new Subject();
|
|
7653
|
-
this.
|
|
7636
|
+
this._liked = new Subject();
|
|
7637
|
+
this._unliked = new Subject();
|
|
7654
7638
|
this._shared = new Subject();
|
|
7655
7639
|
this._userSelected = new Subject();
|
|
7656
7640
|
this._avatarSelected = new Subject();
|
|
@@ -7658,6 +7642,12 @@ class CommentComponent {
|
|
|
7658
7642
|
this.isNew = false;
|
|
7659
7643
|
this.visible = false;
|
|
7660
7644
|
this.showReplyAction = true;
|
|
7645
|
+
this.mine = false;
|
|
7646
|
+
this.editing = false;
|
|
7647
|
+
this._editStarted = new Subject();
|
|
7648
|
+
this._deleted = new Subject();
|
|
7649
|
+
this._editEnded = new Subject();
|
|
7650
|
+
this._edited = new Subject();
|
|
7661
7651
|
}
|
|
7662
7652
|
ngOnInit() {
|
|
7663
7653
|
let maxTime = 500;
|
|
@@ -7669,6 +7659,10 @@ class CommentComponent {
|
|
|
7669
7659
|
setTimeout(() => this.isNew = false, 1000);
|
|
7670
7660
|
}, randomTime);
|
|
7671
7661
|
}
|
|
7662
|
+
get isHighlighted() {
|
|
7663
|
+
var _a, _b, _c;
|
|
7664
|
+
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;
|
|
7665
|
+
}
|
|
7672
7666
|
get userSelected() {
|
|
7673
7667
|
return this._userSelected.asObservable();
|
|
7674
7668
|
}
|
|
@@ -7681,24 +7675,42 @@ class CommentComponent {
|
|
|
7681
7675
|
get reported() {
|
|
7682
7676
|
return this._reported.asObservable();
|
|
7683
7677
|
}
|
|
7684
|
-
|
|
7685
|
-
|
|
7678
|
+
saveEdit() {
|
|
7679
|
+
this._edited.next(this.editedMessage);
|
|
7686
7680
|
}
|
|
7687
|
-
|
|
7688
|
-
|
|
7681
|
+
endEditing() {
|
|
7682
|
+
this._editEnded.next();
|
|
7689
7683
|
}
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7684
|
+
startEdit() {
|
|
7685
|
+
this._editStarted.next();
|
|
7686
|
+
this.editedMessage = this.message.message;
|
|
7687
|
+
}
|
|
7688
|
+
delete() {
|
|
7689
|
+
this._deleted.next();
|
|
7693
7690
|
}
|
|
7694
|
-
get
|
|
7695
|
-
return this.
|
|
7691
|
+
get liked() {
|
|
7692
|
+
return this._liked.asObservable();
|
|
7696
7693
|
}
|
|
7694
|
+
get unliked() {
|
|
7695
|
+
return this._unliked.asObservable();
|
|
7696
|
+
}
|
|
7697
|
+
get selected() {
|
|
7698
|
+
return this._selected.asObservable();
|
|
7699
|
+
}
|
|
7700
|
+
get edited() { return this._edited.asObservable(); }
|
|
7701
|
+
get deleted() { return this._deleted.asObservable(); }
|
|
7702
|
+
get editStarted() { return this._editStarted.asObservable(); }
|
|
7703
|
+
get editEnded() { return this._editEnded.asObservable(); }
|
|
7704
|
+
get shared() { return this._shared.asObservable(); }
|
|
7705
|
+
get commentId() { var _a; return (_a = this.message) === null || _a === void 0 ? void 0 : _a.id; }
|
|
7697
7706
|
report() {
|
|
7698
7707
|
this._reported.next();
|
|
7699
7708
|
}
|
|
7700
|
-
|
|
7701
|
-
this.
|
|
7709
|
+
like() {
|
|
7710
|
+
this._liked.next();
|
|
7711
|
+
}
|
|
7712
|
+
unlike() {
|
|
7713
|
+
this._unliked.next();
|
|
7702
7714
|
}
|
|
7703
7715
|
share() {
|
|
7704
7716
|
this._shared.next(this.message);
|
|
@@ -7728,12 +7740,13 @@ class CommentComponent {
|
|
|
7728
7740
|
CommentComponent.decorators = [
|
|
7729
7741
|
{ type: Component, args: [{
|
|
7730
7742
|
selector: 'banta-comment',
|
|
7731
|
-
template: "\r\n<mat-menu #pointItemMenu=\"matMenu\">\r\n <button mat-menu-item (click)=\"report()\">Report</button>\r\n <button mat-menu-item>
|
|
7732
|
-
styles: ["@-webkit-keyframes comment-appear{0%{transform:translate(100vw)}to{transform:translate(0)}}@keyframes comment-appear{0%{transform:translate(100vw)}to{transform:translate(0)}}:host{display:flex;flex-direction:column;padding:.5em;
|
|
7743
|
+
template: "\r\n<mat-menu #pointItemMenu=\"matMenu\">\r\n <button *ngIf=\"!mine\" mat-menu-item (click)=\"report()\">Report</button>\r\n <button *ngIf=\"mine\" [disabled]=\"!permissions?.canEdit\" mat-menu-item (click)=\"startEdit()\">Edit</button>\r\n <button *ngIf=\"mine\" [disabled]=\"!permissions?.canDelete\" mat-menu-item (click)=\"delete()\">Delete</button>\r\n</mat-menu>\r\n\r\n<div class=\"message-content\">\r\n <div class=\"user\">\r\n <a\r\n href=\"javascript:;\"\r\n class=\"avatar\"\r\n (click)=\"selectAvatar(message.user)\"\r\n [style.background-image]=\"avatarForUser(message.user)\"></a>\r\n <a href=\"javascript:;\" class=\"display-name\" (click)=\"selectUser()\">{{message.user.displayName}}</a>\r\n <a href=\"javascript:;\" class=\"username\" (click)=\"selectUsername(message.user)\">@{{message.user.username}}</a>\r\n <span class=\"user-tag\" *ngIf=\"message.user.tag\">{{message.user.tag}}</span>\r\n <span class=\"spacer\"></span>\r\n </div>\r\n <div class=\"content\" *ngIf=\"!editing\">\r\n {{message.message}}\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\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n <button mat-raised-button (click)=\"saveEdit()\">Save</button> \r\n <button mat-button (click)=\"endEditing()\">Cancel</button>\r\n </div>\r\n\r\n <div class=\"actions\">\r\n <banta-timestamp [value]=\"message.sentAt\"></banta-timestamp>\r\n <ul class=\"message-facts\">\r\n <li *ngIf=\"message.edits?.length > 0\">Edited</li>\r\n </ul>\r\n <div class=\"spacer\"></div>\r\n <div class=\"counted-action\" *ngIf=\"showReplyAction\">\r\n <div class=\"count-indicator\">\r\n {{message.submessages?.length || message.submessageCount || 0}}\r\n </div>\r\n <button mat-icon-button matTooltip=\"Comment\" matTooltipPosition=\"below\" (click)=\"select()\">\r\n <mat-icon [inline]=\"true\">comment</mat-icon>\r\n </button>\r\n </div>\r\n <div class=\"counted-action\" [class.active]=\"message.userState?.liked\">\r\n <div class=\"count-indicator\">\r\n {{message.likes}}\r\n </div>\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-icon-button \r\n [disabled]=\"!permissions?.canLike\" \r\n [matTooltip]=\"upvoting ? 'Please wait...' : 'Like'\" \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 </button>\r\n </div>\r\n\r\n <div class=\"counted-action\">\r\n <button mat-icon-button matTooltip=\"Share this comment\" matTooltipPosition=\"below\" (click)=\"share()\">\r\n <mat-icon [inline]=\"true\" >share</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <button mat-icon-button [matMenuTriggerFor]=\"pointItemMenu\">\r\n <mat-icon [inline]=\"true\">more_vert</mat-icon>\r\n </button>\r\n </div>\r\n</div>\r\n",
|
|
7744
|
+
styles: ["@-webkit-keyframes comment-appear{0%{transform:translate(100vw)}to{transform:translate(0)}}@keyframes comment-appear{0%{transform:translate(100vw)}to{transform:translate(0)}}:host{display:flex;flex-direction:column;position:relative;padding:.5em;visibility:hidden}:host.new{visibility:visible;-webkit-animation-name:comment-appear;animation-name:comment-appear;-webkit-animation-duration:.4s;animation-duration:.4s;-webkit-animation-fill-mode:both;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.abbreviated .message-content .content{max-height:8.5em;text-overflow:ellipsis;overflow-y:hidden}:host .actions{display:flex;padding-right:10px;margin-left:60px;align-items:center}:host .actions button{color:#666}:host .actions banta-timestamp{color:#666;font-size:10pt}.user{position:relative;margin:1em 0 0;display:flex;align-items:center}.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:-webkit-fit-content;width:-moz-fit-content;width:fit-content;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex-shrink:1;flex-grow:0}.user .display-name.username.username.username,.user .username.username.username.username{color:#666}.avatar{height:48px;width:48px;background-position:50%;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 .count-indicator,.counted-action.active button{color:#00a5ff}.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}@media (max-width:400px){.avatar{height:32px;width:32px}:host .actions{margin-left:44px}:host .message-content .content{margin-left:44px;margin-right:.5em}}.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}"]
|
|
7733
7745
|
},] }
|
|
7734
7746
|
];
|
|
7735
7747
|
CommentComponent.propDecorators = {
|
|
7736
7748
|
isNew: [{ type: HostBinding, args: ['class.new',] }],
|
|
7749
|
+
isHighlighted: [{ type: HostBinding, args: ['class.highlighted',] }],
|
|
7737
7750
|
visible: [{ type: HostBinding, args: ['class.visible',] }],
|
|
7738
7751
|
message: [{ type: Input }],
|
|
7739
7752
|
showReplyAction: [{ type: Input }],
|
|
@@ -7741,10 +7754,18 @@ CommentComponent.propDecorators = {
|
|
|
7741
7754
|
usernameSelected: [{ type: Output }],
|
|
7742
7755
|
avatarSelected: [{ type: Output }],
|
|
7743
7756
|
reported: [{ type: Output }],
|
|
7744
|
-
|
|
7757
|
+
permissions: [{ type: Input }],
|
|
7758
|
+
mine: [{ type: Input }],
|
|
7759
|
+
editing: [{ type: Input }],
|
|
7760
|
+
liked: [{ type: Output }],
|
|
7761
|
+
unliked: [{ type: Output }],
|
|
7745
7762
|
selected: [{ type: Output }],
|
|
7746
|
-
|
|
7747
|
-
|
|
7763
|
+
edited: [{ type: Output }],
|
|
7764
|
+
deleted: [{ type: Output }],
|
|
7765
|
+
editStarted: [{ type: Output }],
|
|
7766
|
+
editEnded: [{ type: Output }],
|
|
7767
|
+
shared: [{ type: Output }],
|
|
7768
|
+
commentId: [{ type: HostBinding, args: ['attr.data-comment-id',] }]
|
|
7748
7769
|
};
|
|
7749
7770
|
|
|
7750
7771
|
class CommentViewComponent {
|
|
@@ -7752,16 +7773,20 @@ class CommentViewComponent {
|
|
|
7752
7773
|
this.backend = backend;
|
|
7753
7774
|
this._sourceSubs = new Subscription();
|
|
7754
7775
|
this._selected = new Subject();
|
|
7755
|
-
this.
|
|
7776
|
+
this._liked = new Subject();
|
|
7777
|
+
this._unliked = new Subject();
|
|
7756
7778
|
this._reported = new Subject();
|
|
7757
7779
|
this._userSelected = new Subject();
|
|
7758
7780
|
this._usernameSelected = new Subject();
|
|
7759
7781
|
this._avatarSelected = new Subject();
|
|
7760
7782
|
this._shared = new Subject();
|
|
7783
|
+
this._deleted = new Subject();
|
|
7784
|
+
this._messageEdited = new Subject();
|
|
7761
7785
|
this.showEmptyState = true;
|
|
7762
7786
|
this.allowReplies = true;
|
|
7763
7787
|
this.menuMessage = null;
|
|
7764
7788
|
this.messages = [];
|
|
7789
|
+
this.customSortEnabled = false;
|
|
7765
7790
|
this.maxMessages = 2000;
|
|
7766
7791
|
this.maxVisibleMessages = 200;
|
|
7767
7792
|
this.newestLast = false;
|
|
@@ -7770,33 +7795,33 @@ class CommentViewComponent {
|
|
|
7770
7795
|
this.hasMore = false;
|
|
7771
7796
|
this.newMessages = [];
|
|
7772
7797
|
this.olderMessages = [];
|
|
7798
|
+
this.sortOrderChanged = new Subject();
|
|
7773
7799
|
}
|
|
7774
7800
|
get selected() {
|
|
7775
7801
|
return this._selected;
|
|
7776
7802
|
}
|
|
7777
|
-
get
|
|
7778
|
-
return this.
|
|
7803
|
+
get messageEdited() {
|
|
7804
|
+
return this._messageEdited.asObservable();
|
|
7779
7805
|
}
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
}
|
|
7783
|
-
get upvoted() {
|
|
7784
|
-
return this._upvoted;
|
|
7785
|
-
}
|
|
7786
|
-
get usernameSelected() {
|
|
7787
|
-
return this._usernameSelected;
|
|
7788
|
-
}
|
|
7789
|
-
get avatarSelected() {
|
|
7790
|
-
return this._avatarSelected;
|
|
7791
|
-
}
|
|
7792
|
-
get shared() {
|
|
7793
|
-
return this._shared;
|
|
7806
|
+
saveEdit(message, newMessage) {
|
|
7807
|
+
this._messageEdited.next({ message, newMessage });
|
|
7794
7808
|
}
|
|
7809
|
+
get userSelected() { return this._userSelected; }
|
|
7810
|
+
get reported() { return this._reported; }
|
|
7811
|
+
get liked() { return this._liked; }
|
|
7812
|
+
get unliked() { return this._unliked; }
|
|
7813
|
+
get usernameSelected() { return this._usernameSelected; }
|
|
7814
|
+
get avatarSelected() { return this._avatarSelected; }
|
|
7815
|
+
get shared() { return this._shared; }
|
|
7816
|
+
get deleted() { return this._deleted; }
|
|
7795
7817
|
get source() {
|
|
7796
7818
|
return this._source;
|
|
7797
7819
|
}
|
|
7798
|
-
|
|
7799
|
-
this.
|
|
7820
|
+
likeMessage(message) {
|
|
7821
|
+
this._liked.next(message);
|
|
7822
|
+
}
|
|
7823
|
+
unlikeMessage(message) {
|
|
7824
|
+
this._unliked.next(message);
|
|
7800
7825
|
}
|
|
7801
7826
|
reportMessage(message) {
|
|
7802
7827
|
this._reported.next(message);
|
|
@@ -7816,31 +7841,51 @@ class CommentViewComponent {
|
|
|
7816
7841
|
sharedMessage(message) {
|
|
7817
7842
|
this._shared.next(message);
|
|
7818
7843
|
}
|
|
7844
|
+
startEditing(message) {
|
|
7845
|
+
this.messages.forEach(m => m.transientState.editing = false);
|
|
7846
|
+
message.transientState.editing = true;
|
|
7847
|
+
}
|
|
7848
|
+
deleteMessage(message) {
|
|
7849
|
+
this._deleted.next(message);
|
|
7850
|
+
}
|
|
7819
7851
|
set source(value) {
|
|
7852
|
+
this.customSortEnabled = (value === null || value === void 0 ? void 0 : value.sortOrder) !== CommentsOrder.NEWEST;
|
|
7853
|
+
this.newMessages = [];
|
|
7854
|
+
this.olderMessages = [];
|
|
7855
|
+
window.bantaSourceDebug = value;
|
|
7820
7856
|
if (this._sourceSubs) {
|
|
7821
7857
|
this._sourceSubs.unsubscribe();
|
|
7822
7858
|
this._sourceSubs = null;
|
|
7823
7859
|
}
|
|
7824
7860
|
this._source = value;
|
|
7825
7861
|
if (value) {
|
|
7826
|
-
console.log(`[banta-comment-view] Subscribing to source...`);
|
|
7827
7862
|
const messages = (value.messages || []).slice();
|
|
7828
7863
|
this.messages = messages;
|
|
7829
7864
|
this.olderMessages = messages.splice(this.maxVisibleMessages, messages.length);
|
|
7830
|
-
this.hasMore = this.olderMessages.length > 0;
|
|
7865
|
+
this.hasMore = true; //this.olderMessages.length > 0;
|
|
7831
7866
|
this._sourceSubs = new Subscription();
|
|
7832
7867
|
this._sourceSubs.add(this._source.messageReceived.subscribe(msg => this.messageReceived(msg)));
|
|
7833
7868
|
this._sourceSubs.add(this._source.messageSent.subscribe(msg => this.messageSent(msg)));
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
}
|
|
7869
|
+
this._sourceSubs.add(this.backend.userChanged.subscribe(user => this.currentUser = user));
|
|
7870
|
+
this.getInitialMessages();
|
|
7837
7871
|
}
|
|
7838
7872
|
}
|
|
7873
|
+
getInitialMessages() {
|
|
7874
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7875
|
+
let messages = (yield this._source.getExistingMessages());
|
|
7876
|
+
messages.forEach(m => { var _a; return (_a = m.transientState) !== null && _a !== void 0 ? _a : (m.transientState = {}); });
|
|
7877
|
+
this.messages = messages;
|
|
7878
|
+
});
|
|
7879
|
+
}
|
|
7839
7880
|
messageIdentity(index, chatMessage) {
|
|
7840
7881
|
return chatMessage.id;
|
|
7841
7882
|
}
|
|
7842
7883
|
showNew() {
|
|
7843
7884
|
return __awaiter(this, void 0, void 0, function* () {
|
|
7885
|
+
if (this.source && this.source.sortOrder !== CommentsOrder.NEWEST) {
|
|
7886
|
+
this.sortOrderChanged.next(CommentsOrder.NEWEST);
|
|
7887
|
+
return;
|
|
7888
|
+
}
|
|
7844
7889
|
this.isViewingMore = false;
|
|
7845
7890
|
this.messages = this.newMessages.splice(0, this.newMessages.length).concat(this.messages);
|
|
7846
7891
|
let overflow = this.messages.splice(this.maxVisibleMessages, this.messages.length);
|
|
@@ -7856,29 +7901,38 @@ class CommentViewComponent {
|
|
|
7856
7901
|
this.messages = this.messages.concat(this.olderMessages.splice(0, 50));
|
|
7857
7902
|
}
|
|
7858
7903
|
else {
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7862
|
-
|
|
7863
|
-
|
|
7904
|
+
this.isLoadingMore = true;
|
|
7905
|
+
let nextPageSize = 20;
|
|
7906
|
+
let lastMessage;
|
|
7907
|
+
lastMessage = this.messages[this.messages.length - 1];
|
|
7908
|
+
if (!lastMessage) {
|
|
7864
7909
|
this.isLoadingMore = false;
|
|
7865
|
-
|
|
7866
|
-
|
|
7910
|
+
this.hasMore = false;
|
|
7911
|
+
return;
|
|
7867
7912
|
}
|
|
7868
|
-
|
|
7913
|
+
let messages = yield this.source.loadAfter(lastMessage, nextPageSize);
|
|
7914
|
+
messages.forEach(m => { var _a; return (_a = m.transientState) !== null && _a !== void 0 ? _a : (m.transientState = {}); });
|
|
7915
|
+
this.messages = this.messages.concat(messages);
|
|
7916
|
+
this.isLoadingMore = false;
|
|
7917
|
+
if (messages.length === 0) {
|
|
7918
|
+
console.log(`Reached the end of the list.`);
|
|
7869
7919
|
this.hasMore = false;
|
|
7870
7920
|
}
|
|
7871
7921
|
}
|
|
7872
7922
|
});
|
|
7873
7923
|
}
|
|
7874
7924
|
addMessage(message) {
|
|
7925
|
+
var _a;
|
|
7926
|
+
if (!message.transientState)
|
|
7927
|
+
(_a = message.transientState) !== null && _a !== void 0 ? _a : (message.transientState = {});
|
|
7875
7928
|
let destination = this.messages;
|
|
7876
7929
|
let bucket = this.olderMessages;
|
|
7877
7930
|
if (this.isViewingMore) {
|
|
7878
7931
|
destination = this.newMessages;
|
|
7879
7932
|
bucket = null;
|
|
7880
7933
|
}
|
|
7881
|
-
|
|
7934
|
+
let newestLast = this.newestLast;
|
|
7935
|
+
if (newestLast) {
|
|
7882
7936
|
destination.push(message);
|
|
7883
7937
|
let overflow = destination.splice(this.maxVisibleMessages, destination.length);
|
|
7884
7938
|
bucket === null || bucket === void 0 ? void 0 : bucket.push(...overflow);
|
|
@@ -7933,41 +7987,65 @@ class CommentViewComponent {
|
|
|
7933
7987
|
CommentViewComponent.decorators = [
|
|
7934
7988
|
{ type: Component, args: [{
|
|
7935
7989
|
selector: 'banta-comment-view',
|
|
7936
|
-
template: "<div class=\"message-container\">\r\n <ng-content select=\"[data-before]\"></ng-content>\r\n\r\n <a mat-button class=\"nav\" [class.visible]=\"isViewingMore\" href=\"javascript:;\" (click)=\"showNew()\">\r\n <mat-icon>file_upload</mat-icon>\r\n New\r\n <ng-container *ngIf=\"newMessages.length >= 1\">\r\n ({{newMessages.length}})\r\n </ng-container>\r\n </a>\r\n\r\n <ng-container *ngIf=\"messages.length === 0\">\r\n <div class=\"empty-state\" *ngIf=\"showEmptyState\">\r\n Be the first to comment!\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let message of messages; trackBy: messageIdentity\">\r\n <banta-comment\r\n *ngIf=\"!message.hidden\"\r\n class=\"abbreviated\"\r\n [message]=\"message\"\r\n (click)=\"isViewingMore = true\"\r\n [showReplyAction]=\"allowReplies\"\r\n (userSelected)=\"selectMessageUser(message)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (
|
|
7937
|
-
styles: [":host{display:flex;flex-direction:column;
|
|
7990
|
+
template: "<div class=\"message-container\">\r\n <ng-content select=\"[data-before]\"></ng-content>\r\n\r\n <a mat-button class=\"nav\" [class.visible]=\"isViewingMore || customSortEnabled\" href=\"javascript:;\" (click)=\"showNew()\">\r\n <mat-icon>file_upload</mat-icon>\r\n New\r\n <ng-container *ngIf=\"newMessages.length >= 1\">\r\n ({{newMessages.length}})\r\n </ng-container>\r\n </a>\r\n\r\n <ng-container *ngIf=\"messages.length === 0\">\r\n <div class=\"empty-state\" *ngIf=\"showEmptyState\">\r\n Be the first to comment!\r\n </div>\r\n </ng-container>\r\n <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 [message]=\"message\"\r\n [mine]=\"currentUser?.id === message.user?.id\"\r\n [permissions]=\"source?.permissions\"\r\n (click)=\"isViewingMore = true\"\r\n [showReplyAction]=\"allowReplies\"\r\n [editing]=\"message.transientState.editing\"\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 </ng-container>\r\n\r\n <a mat-button class=\"nav\" [class.visible]=\"hasMore && !isLoadingMore\" href=\"javascript:;\" (click)=\"showMore()\">Show more</a>\r\n\r\n <div class=\"loading-more\" *ngIf=\"isLoadingMore\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n\r\n <!-- <div style=\"color: #666\">\r\n n={{newMessages.length}}, m={{messages.length}}, o={{olderMessages.length}},\r\n v={{maxVisibleMessages}}, M={{maxMessages}}\r\n </div> -->\r\n\r\n <ng-content select=\":not([data-before])\"></ng-content>\r\n</div>\r\n",
|
|
7991
|
+
styles: [":host{flex-grow:1;display:flex;flex-direction:column;opacity:1;transition:opacity .2s ease-in}.message-container{flex-grow:1;overflow-x:hidden;color:#111;background:#fff;padding:.5em 1em 3em .5em;opacity:1;transition:opacity .5s ease-in-out;position:relative}.message-container.no-scroll{height:auto;overflow-y:visible}.message-container.faded{opacity:.25}.message-container .overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:10}:host.fixed-height .message-container{overflow-y:auto}:host-context(.mat-dark-theme) .message-container{color:#fff;background:#111}.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:opacity .4s ease-in-out;pointer-events:none;border-radius:2em;background:#222}a.nav.visible{opacity:1;pointer-events:auto}.loading-more{padding:2em;text-align:center;margin:0 auto;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}@media (max-width:400px){.message-container{padding:0 0 3em}}"]
|
|
7938
7992
|
},] }
|
|
7939
7993
|
];
|
|
7940
7994
|
CommentViewComponent.ctorParameters = () => [
|
|
7941
|
-
{ type:
|
|
7995
|
+
{ type: ChatBackendBase }
|
|
7942
7996
|
];
|
|
7943
7997
|
CommentViewComponent.propDecorators = {
|
|
7944
7998
|
showEmptyState: [{ type: Input }],
|
|
7945
7999
|
allowReplies: [{ type: Input }],
|
|
7946
8000
|
fixedHeight: [{ type: Input }, { type: HostBinding, args: ['class.fixed-height',] }],
|
|
7947
8001
|
selected: [{ type: Output }],
|
|
8002
|
+
messageEdited: [{ type: Output }],
|
|
7948
8003
|
userSelected: [{ type: Output }],
|
|
7949
8004
|
reported: [{ type: Output }],
|
|
7950
|
-
|
|
8005
|
+
liked: [{ type: Output }],
|
|
8006
|
+
unliked: [{ type: Output }],
|
|
7951
8007
|
usernameSelected: [{ type: Output }],
|
|
7952
8008
|
avatarSelected: [{ type: Output }],
|
|
7953
8009
|
shared: [{ type: Output }],
|
|
8010
|
+
deleted: [{ type: Output }],
|
|
7954
8011
|
source: [{ type: Input }],
|
|
7955
8012
|
genericAvatarUrl: [{ type: Input }],
|
|
7956
8013
|
messageContainer: [{ type: ViewChild, args: ['messageContainer',] }],
|
|
7957
8014
|
maxMessages: [{ type: Input }],
|
|
7958
8015
|
maxVisibleMessages: [{ type: Input }],
|
|
7959
|
-
newestLast: [{ type: Input }]
|
|
8016
|
+
newestLast: [{ type: Input }],
|
|
8017
|
+
sortOrderChanged: [{ type: Output }]
|
|
7960
8018
|
};
|
|
7961
8019
|
|
|
7962
8020
|
/**
|
|
7963
8021
|
* Comments component
|
|
7964
8022
|
*/
|
|
7965
8023
|
class BantaCommentsComponent {
|
|
7966
|
-
constructor(
|
|
7967
|
-
this.banta = banta;
|
|
8024
|
+
constructor(backend, elementRef, activatedRoute) {
|
|
7968
8025
|
this.backend = backend;
|
|
7969
8026
|
this.elementRef = elementRef;
|
|
7970
8027
|
this.activatedRoute = activatedRoute;
|
|
8028
|
+
// Loading Screen
|
|
8029
|
+
this._loadingMessage = '';
|
|
8030
|
+
this.loadingMessageVisible = false;
|
|
8031
|
+
this.loading = true;
|
|
8032
|
+
this.showLoadingScreen = false;
|
|
8033
|
+
this._loadingMessageIndex = 0;
|
|
8034
|
+
this.loadingMessages = [
|
|
8035
|
+
`Just a second...`,
|
|
8036
|
+
`We're definitely working on it.`,
|
|
8037
|
+
`There's no need to refresh.`,
|
|
8038
|
+
`It's definitely worth the wait!`,
|
|
8039
|
+
`This has never happened before.`,
|
|
8040
|
+
`We'll keep trying, but it's not looking great.
|
|
8041
|
+
Commenting & chat services may be down.
|
|
8042
|
+
If you continue to experience issues, please contact support.
|
|
8043
|
+
`
|
|
8044
|
+
];
|
|
8045
|
+
// Properties
|
|
8046
|
+
this._signInSelected = new Subject();
|
|
8047
|
+
this._permissionDeniedError = new Subject();
|
|
8048
|
+
this._editAvatarSelected = new Subject();
|
|
7971
8049
|
this._upvoted = new Subject();
|
|
7972
8050
|
this._reported = new Subject();
|
|
7973
8051
|
this._selected = new Subject();
|
|
@@ -7977,12 +8055,8 @@ class BantaCommentsComponent {
|
|
|
7977
8055
|
this._avatarSelected = new Subject();
|
|
7978
8056
|
this._subs = new Subscription();
|
|
7979
8057
|
this._sortOrder = CommentsOrder.NEWEST;
|
|
7980
|
-
this.
|
|
7981
|
-
|
|
7982
|
-
{ hashtag: 'timeout', description: 'Cause a slow timeout error' },
|
|
7983
|
-
{ hashtag: 'slow', description: 'Be slow when this message is posted' },
|
|
7984
|
-
];
|
|
7985
|
-
this.participants = [];
|
|
8058
|
+
this.selectedMessageVisible = false;
|
|
8059
|
+
// Inputs
|
|
7986
8060
|
this.signInLabel = 'Sign In';
|
|
7987
8061
|
this.sendLabel = 'Send';
|
|
7988
8062
|
this.replyLabel = 'Reply';
|
|
@@ -7990,16 +8064,166 @@ class BantaCommentsComponent {
|
|
|
7990
8064
|
this.permissionDeniedLabel = 'Send';
|
|
7991
8065
|
this.postCommentLabel = 'Post a comment';
|
|
7992
8066
|
this.postReplyLabel = 'Post a reply';
|
|
7993
|
-
this.
|
|
7994
|
-
this.
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
|
|
8067
|
+
this.participants = [];
|
|
8068
|
+
this.hashtags = [
|
|
8069
|
+
{ hashtag: 'error', description: 'Cause an error' },
|
|
8070
|
+
{ hashtag: 'timeout', description: 'Cause a slow timeout error' },
|
|
8071
|
+
{ hashtag: 'slow', description: 'Be slow when this message is posted' },
|
|
8072
|
+
];
|
|
8073
|
+
this.sendMessage = (message) => __awaiter(this, void 0, void 0, function* () {
|
|
8074
|
+
var _a;
|
|
8075
|
+
try {
|
|
8076
|
+
const intercept = yield ((_a = this.shouldInterceptMessageSend) === null || _a === void 0 ? void 0 : _a.call(this, message, this.source));
|
|
8077
|
+
if (!intercept) {
|
|
8078
|
+
yield this.source.send(message);
|
|
8079
|
+
}
|
|
8080
|
+
if (this.source.sortOrder !== CommentsOrder.NEWEST) {
|
|
8081
|
+
this.sortOrder = CommentsOrder.NEWEST;
|
|
8082
|
+
}
|
|
8083
|
+
return true;
|
|
8084
|
+
}
|
|
8085
|
+
catch (e) {
|
|
8086
|
+
console.error(`Failed to send message: `, message);
|
|
8087
|
+
console.error(e);
|
|
8088
|
+
throw new Error(`Could not send: ${e.message}`);
|
|
8089
|
+
}
|
|
8090
|
+
});
|
|
8091
|
+
this.sendReply = (message) => __awaiter(this, void 0, void 0, function* () {
|
|
8092
|
+
var _b;
|
|
8093
|
+
try {
|
|
8094
|
+
const intercept = yield ((_b = this.shouldInterceptMessageSend) === null || _b === void 0 ? void 0 : _b.call(this, message, this.source));
|
|
8095
|
+
if (!intercept) {
|
|
8096
|
+
yield this.selectedMessageThread.send(message);
|
|
8097
|
+
}
|
|
8098
|
+
return true;
|
|
8099
|
+
}
|
|
8100
|
+
catch (e) {
|
|
8101
|
+
console.error(`Failed to send message: `, message);
|
|
8102
|
+
console.error(e);
|
|
8103
|
+
throw new Error(`Could not send reply: ${e.message}`);
|
|
8104
|
+
}
|
|
8105
|
+
});
|
|
8106
|
+
}
|
|
8107
|
+
// Lifecycle Events / Initialization
|
|
8108
|
+
ngOnInit() {
|
|
8109
|
+
this._subs.add(this.backend.userChanged.subscribe(user => this.user = user));
|
|
8110
|
+
this.startLoading();
|
|
8111
|
+
console.log(`Checking...`);
|
|
8112
|
+
if (typeof window !== 'undefined') {
|
|
8113
|
+
let queryString = window.location.search.substring(1);
|
|
8114
|
+
let query = queryString.split('&')
|
|
8115
|
+
.map(s => s.split('='))
|
|
8116
|
+
.reduce((o, [k, v]) => (o[k] = v, o), {});
|
|
8117
|
+
console.log('here:');
|
|
8118
|
+
console.dir(query);
|
|
8119
|
+
const commentID = query['comment'];
|
|
8120
|
+
if (commentID) {
|
|
8121
|
+
this.sharedCommentID = commentID;
|
|
8122
|
+
}
|
|
8123
|
+
}
|
|
7999
8124
|
}
|
|
8000
|
-
|
|
8001
|
-
|
|
8125
|
+
ngOnDestroy() {
|
|
8126
|
+
this._subs.unsubscribe();
|
|
8127
|
+
}
|
|
8128
|
+
setSourceFromTopicID(topicID) {
|
|
8129
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8130
|
+
if (this._source) {
|
|
8131
|
+
this._source.close();
|
|
8132
|
+
this._source = null;
|
|
8133
|
+
}
|
|
8134
|
+
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
8135
|
+
console.log(`[banta-comments] Subscribing to topic source '${topicID}'`);
|
|
8136
|
+
this._source = yield this.backend.getSourceForTopic(topicID, { sortOrder: this.sortOrder });
|
|
8137
|
+
if (this.sharedCommentID) {
|
|
8138
|
+
this.navigateToSharedComment(this.sharedCommentID);
|
|
8139
|
+
this.sharedCommentID = null;
|
|
8140
|
+
}
|
|
8141
|
+
this._source.messageReceived.subscribe(m => this.addParticipant(m));
|
|
8142
|
+
this._source.messageSent.subscribe(m => this.addParticipant(m));
|
|
8143
|
+
this._source.messages.forEach(m => this.addParticipant(m));
|
|
8144
|
+
}));
|
|
8145
|
+
});
|
|
8002
8146
|
}
|
|
8147
|
+
get loadingMessage() {
|
|
8148
|
+
return this._loadingMessage;
|
|
8149
|
+
}
|
|
8150
|
+
set loadingMessage(value) {
|
|
8151
|
+
this.loadingMessageVisible = false;
|
|
8152
|
+
setTimeout(() => {
|
|
8153
|
+
this._loadingMessage = value;
|
|
8154
|
+
this._loadingMessage = value;
|
|
8155
|
+
setTimeout(() => {
|
|
8156
|
+
this.loadingMessageVisible = true;
|
|
8157
|
+
});
|
|
8158
|
+
}, 500);
|
|
8159
|
+
}
|
|
8160
|
+
startLoading() {
|
|
8161
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8162
|
+
this.loadingStartedAt = this.messageChangedAt = Date.now();
|
|
8163
|
+
if (this.updateLoading())
|
|
8164
|
+
return;
|
|
8165
|
+
yield new Promise(resolve => setTimeout(() => resolve(), 100));
|
|
8166
|
+
if (this.updateLoading())
|
|
8167
|
+
return;
|
|
8168
|
+
yield new Promise(resolve => setTimeout(() => resolve(), 250));
|
|
8169
|
+
if (this.updateLoading())
|
|
8170
|
+
return;
|
|
8171
|
+
yield new Promise(resolve => setTimeout(() => resolve(), 500));
|
|
8172
|
+
if (this.updateLoading())
|
|
8173
|
+
return;
|
|
8174
|
+
console.log(`[Banta] Loading is taking a long time! Showing loading screen.`);
|
|
8175
|
+
this.showLoadingScreen = true;
|
|
8176
|
+
if (typeof window !== 'undefined')
|
|
8177
|
+
this._loadingTimer = setInterval(() => this.updateLoading(), 1000);
|
|
8178
|
+
});
|
|
8179
|
+
}
|
|
8180
|
+
updateLoading() {
|
|
8181
|
+
var _a, _b, _c;
|
|
8182
|
+
if (((_a = this.source) === null || _a === void 0 ? void 0 : _a.state) && ((_b = this.source) === null || _b === void 0 ? void 0 : _b.state) !== 'connecting') {
|
|
8183
|
+
clearInterval(this._loadingTimer);
|
|
8184
|
+
this.loadingMessage = `Here we go!`;
|
|
8185
|
+
setTimeout(() => {
|
|
8186
|
+
this.loading = false;
|
|
8187
|
+
}, 750);
|
|
8188
|
+
return true;
|
|
8189
|
+
}
|
|
8190
|
+
console.log(`[Banta] Status check: ${((_c = this.source) === null || _c === void 0 ? void 0 : _c.state) || 'connecting'}`);
|
|
8191
|
+
let messageSwitchTime = 5 * 1000;
|
|
8192
|
+
if (this.messageChangedAt + messageSwitchTime < Date.now()) {
|
|
8193
|
+
if (this.loadingMessages[this._loadingMessageIndex]) {
|
|
8194
|
+
this.loadingMessage = this.loadingMessages[this._loadingMessageIndex++];
|
|
8195
|
+
this.messageChangedAt = Date.now();
|
|
8196
|
+
}
|
|
8197
|
+
}
|
|
8198
|
+
return false;
|
|
8199
|
+
}
|
|
8200
|
+
get source() { return this._source; }
|
|
8201
|
+
set source(value) {
|
|
8202
|
+
this._source = value;
|
|
8203
|
+
if (value && this.sharedCommentID) {
|
|
8204
|
+
this.navigateToSharedComment(this.sharedCommentID);
|
|
8205
|
+
this.sharedCommentID = null;
|
|
8206
|
+
}
|
|
8207
|
+
}
|
|
8208
|
+
get topicID() { return this._topicID; }
|
|
8209
|
+
set topicID(value) {
|
|
8210
|
+
if (this._topicID !== value) {
|
|
8211
|
+
this._topicID = value;
|
|
8212
|
+
setTimeout(() => this.setSourceFromTopicID(value));
|
|
8213
|
+
}
|
|
8214
|
+
}
|
|
8215
|
+
// Outputs
|
|
8216
|
+
get signInSelected() { return this._signInSelected; }
|
|
8217
|
+
get editAvatarSelected() { return this._editAvatarSelected; }
|
|
8218
|
+
get permissionDeniedError() { return this._permissionDeniedError; }
|
|
8219
|
+
get upvoted() { return this._upvoted.asObservable(); }
|
|
8220
|
+
get reported() { return this._reported.asObservable(); }
|
|
8221
|
+
get selected() { return this._selected.asObservable(); }
|
|
8222
|
+
get userSelected() { return this._userSelected.asObservable(); }
|
|
8223
|
+
get usernameSelected() { return this._usernameSelected.asObservable(); }
|
|
8224
|
+
get avatarSelected() { return this._avatarSelected.asObservable(); }
|
|
8225
|
+
get shared() { return this._shared.asObservable(); }
|
|
8226
|
+
get sortOrder() { return this._sortOrder; }
|
|
8003
8227
|
set sortOrder(value) {
|
|
8004
8228
|
if (this._sortOrder !== value) {
|
|
8005
8229
|
this._sortOrder = value;
|
|
@@ -8008,60 +8232,62 @@ class BantaCommentsComponent {
|
|
|
8008
8232
|
});
|
|
8009
8233
|
}
|
|
8010
8234
|
}
|
|
8011
|
-
|
|
8012
|
-
this._subs.add(this.banta.userChanged.subscribe(user => this.user = user));
|
|
8013
|
-
}
|
|
8014
|
-
ngAfterViewInit() {
|
|
8015
|
-
if (typeof window !== 'undefined')
|
|
8016
|
-
this.checkForSharedComment();
|
|
8017
|
-
}
|
|
8235
|
+
// UI Interactions
|
|
8018
8236
|
scrollToComment(commentId) {
|
|
8019
8237
|
setTimeout(() => {
|
|
8020
8238
|
const comment = document.querySelectorAll(`[data-comment-id="${commentId}"]`);
|
|
8021
|
-
console.
|
|
8239
|
+
console.dir(comment);
|
|
8022
8240
|
if (comment.length > 0) {
|
|
8023
8241
|
// comment.item(0).scroll({behavior: 'smooth'});
|
|
8024
8242
|
comment.item(0).scrollIntoView();
|
|
8025
8243
|
}
|
|
8026
8244
|
}, 1000);
|
|
8027
8245
|
}
|
|
8028
|
-
|
|
8029
|
-
|
|
8030
|
-
if (commentID)
|
|
8031
|
-
this.scrollToComment(commentID);
|
|
8032
|
-
}
|
|
8033
|
-
ngOnDestroy() {
|
|
8034
|
-
this._subs.unsubscribe();
|
|
8035
|
-
}
|
|
8036
|
-
get source() {
|
|
8037
|
-
return this._source;
|
|
8038
|
-
}
|
|
8039
|
-
set source(value) {
|
|
8040
|
-
this._source = value;
|
|
8041
|
-
}
|
|
8042
|
-
get topicID() {
|
|
8043
|
-
return this._topicID;
|
|
8044
|
-
}
|
|
8045
|
-
set topicID(value) {
|
|
8046
|
-
if (this._topicID !== value) {
|
|
8047
|
-
this._topicID = value;
|
|
8048
|
-
setTimeout(() => this.setSourceFromTopicID(value));
|
|
8049
|
-
}
|
|
8050
|
-
}
|
|
8051
|
-
setSourceFromTopicID(topicID) {
|
|
8052
|
-
var _a, _b;
|
|
8246
|
+
navigateToSharedComment(id) {
|
|
8247
|
+
var _a, _b, _c;
|
|
8053
8248
|
return __awaiter(this, void 0, void 0, function* () {
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8249
|
+
let source = this.source;
|
|
8250
|
+
yield source.ready;
|
|
8251
|
+
console.log(`Navigating to shared comment with ID '${id}'...`);
|
|
8252
|
+
let message;
|
|
8253
|
+
try {
|
|
8254
|
+
message = yield this.source.get(id);
|
|
8255
|
+
}
|
|
8256
|
+
catch (e) {
|
|
8257
|
+
console.error(`Failed to find comment from URL: ${e.message}`);
|
|
8258
|
+
return;
|
|
8259
|
+
}
|
|
8260
|
+
(_a = message.transientState) !== null && _a !== void 0 ? _a : (message.transientState = {});
|
|
8261
|
+
// If there is a parent message, we should instead focus that and let the
|
|
8262
|
+
// scrollToComment and highlight do the work.
|
|
8263
|
+
if (message.parentMessageId) {
|
|
8264
|
+
let parentMessage = yield this.source.get(message.parentMessageId);
|
|
8265
|
+
(_b = parentMessage.transientState) !== null && _b !== void 0 ? _b : (parentMessage.transientState = {});
|
|
8266
|
+
let thread = yield this.selectMessage(parentMessage);
|
|
8267
|
+
// Need to re-retrieve the message within the new chat source to affect its
|
|
8268
|
+
// transient state.
|
|
8269
|
+
yield thread.ready;
|
|
8270
|
+
message = yield thread.get(message.id);
|
|
8271
|
+
(_c = message.transientState) !== null && _c !== void 0 ? _c : (message.transientState = {});
|
|
8272
|
+
message.transientState.highlighted = true;
|
|
8273
|
+
console.dir(message);
|
|
8274
|
+
yield new Promise(resolve => setTimeout(() => resolve(), 500));
|
|
8275
|
+
}
|
|
8276
|
+
else {
|
|
8277
|
+
this.selectMessage(message);
|
|
8278
|
+
}
|
|
8279
|
+
this.scrollToComment(id);
|
|
8063
8280
|
});
|
|
8064
8281
|
}
|
|
8282
|
+
showPermissionDenied() {
|
|
8283
|
+
this._permissionDeniedError.next();
|
|
8284
|
+
}
|
|
8285
|
+
scrollToMessage(message) {
|
|
8286
|
+
let el = this.elementRef.nativeElement.querySelector(`[data-comment-id="${message.id}"]`);
|
|
8287
|
+
if (!el)
|
|
8288
|
+
return;
|
|
8289
|
+
el.scrollIntoView({ block: 'center', inline: 'start' });
|
|
8290
|
+
}
|
|
8065
8291
|
addParticipant(message) {
|
|
8066
8292
|
if (!message || !message.user || !message.user.id)
|
|
8067
8293
|
return;
|
|
@@ -8070,90 +8296,46 @@ class BantaCommentsComponent {
|
|
|
8070
8296
|
return;
|
|
8071
8297
|
this.participants.push(message.user);
|
|
8072
8298
|
}
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
}
|
|
8076
|
-
showEditAvatar() {
|
|
8077
|
-
this._editAvatarSelected.next();
|
|
8078
|
-
}
|
|
8079
|
-
get newMessageText() {
|
|
8080
|
-
return this._newMessageText;
|
|
8081
|
-
}
|
|
8082
|
-
set newMessageText(value) {
|
|
8083
|
-
this._newMessageText = value;
|
|
8084
|
-
if (this._newMessageText === '' && this.sendError)
|
|
8085
|
-
setTimeout(() => this.sendError = null);
|
|
8086
|
-
}
|
|
8087
|
-
get signInSelected() {
|
|
8088
|
-
return this._signInSelected;
|
|
8089
|
-
}
|
|
8090
|
-
get editAvatarSelected() {
|
|
8091
|
-
return this._editAvatarSelected;
|
|
8092
|
-
}
|
|
8093
|
-
get permissionDeniedError() {
|
|
8094
|
-
return this._permissionDeniedError;
|
|
8095
|
-
}
|
|
8096
|
-
showPermissionDenied() {
|
|
8097
|
-
this._permissionDeniedError.next();
|
|
8098
|
-
}
|
|
8099
|
-
get canComment() {
|
|
8299
|
+
// Actions
|
|
8300
|
+
likeMessage(source, message) {
|
|
8100
8301
|
var _a;
|
|
8101
|
-
|
|
8102
|
-
|
|
8103
|
-
|
|
8104
|
-
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
|
|
8108
|
-
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
get selected() {
|
|
8116
|
-
return this._selected.asObservable();
|
|
8117
|
-
}
|
|
8118
|
-
get userSelected() {
|
|
8119
|
-
return this._userSelected.asObservable();
|
|
8120
|
-
}
|
|
8121
|
-
get usernameSelected() {
|
|
8122
|
-
return this._usernameSelected.asObservable();
|
|
8123
|
-
}
|
|
8124
|
-
get avatarSelected() {
|
|
8125
|
-
return this._avatarSelected.asObservable();
|
|
8126
|
-
}
|
|
8127
|
-
get shared() {
|
|
8128
|
-
return this._shared.asObservable();
|
|
8129
|
-
}
|
|
8130
|
-
onKeyDown(event) {
|
|
8131
|
-
}
|
|
8132
|
-
insertEmoji(text) {
|
|
8133
|
-
this.newMessageText += text;
|
|
8134
|
-
}
|
|
8135
|
-
onReplyKeyDown(event) {
|
|
8136
|
-
}
|
|
8137
|
-
insertReplyEmoji(text) {
|
|
8138
|
-
this.replyMessage += text;
|
|
8139
|
-
}
|
|
8140
|
-
indicateError(message) {
|
|
8141
|
-
this.sendError = new Error(message);
|
|
8142
|
-
setTimeout(() => {
|
|
8143
|
-
this.expandError = true;
|
|
8144
|
-
setTimeout(() => {
|
|
8145
|
-
this.expandError = false;
|
|
8146
|
-
}, 5 * 1000);
|
|
8302
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8303
|
+
this._upvoted.next(message);
|
|
8304
|
+
message.transientState.liking = true;
|
|
8305
|
+
if (!((_a = message.userState) === null || _a === void 0 ? void 0 : _a.liked))
|
|
8306
|
+
message.likes = (message.likes || 0) + 1;
|
|
8307
|
+
try {
|
|
8308
|
+
yield source.likeMessage(message.id);
|
|
8309
|
+
}
|
|
8310
|
+
catch (e) {
|
|
8311
|
+
alert(`Could not like this message: ${e.message}`);
|
|
8312
|
+
return;
|
|
8313
|
+
}
|
|
8314
|
+
yield new Promise(resolve => setTimeout(() => resolve(), 250));
|
|
8315
|
+
message.transientState.liking = false;
|
|
8147
8316
|
});
|
|
8148
8317
|
}
|
|
8149
|
-
|
|
8318
|
+
unlikeMessage(source, message) {
|
|
8319
|
+
var _a;
|
|
8150
8320
|
return __awaiter(this, void 0, void 0, function* () {
|
|
8151
8321
|
this._upvoted.next(message);
|
|
8152
|
-
|
|
8322
|
+
message.transientState.liking = true;
|
|
8323
|
+
if ((_a = message.userState) === null || _a === void 0 ? void 0 : _a.liked)
|
|
8324
|
+
message.likes = (message.likes || 0) - 1;
|
|
8325
|
+
try {
|
|
8326
|
+
yield source.unlikeMessage(message.id);
|
|
8327
|
+
}
|
|
8328
|
+
catch (e) {
|
|
8329
|
+
alert(`Failed to unlike message: ${e.message}`);
|
|
8330
|
+
}
|
|
8331
|
+
yield new Promise(resolve => setTimeout(() => resolve(), 250));
|
|
8332
|
+
message.transientState.liking = false;
|
|
8153
8333
|
});
|
|
8154
8334
|
}
|
|
8155
8335
|
reportMessage(message) {
|
|
8156
|
-
this
|
|
8336
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8337
|
+
this._reported.next(message);
|
|
8338
|
+
});
|
|
8157
8339
|
}
|
|
8158
8340
|
unselectMessage() {
|
|
8159
8341
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -8173,69 +8355,96 @@ class BantaCommentsComponent {
|
|
|
8173
8355
|
return __awaiter(this, void 0, void 0, function* () {
|
|
8174
8356
|
this._selected.next(message);
|
|
8175
8357
|
this.selectedMessage = message;
|
|
8358
|
+
let selectedMessageThread = yield this.backend.getSourceForThread(this.topicID, message.id);
|
|
8176
8359
|
setTimeout(() => this.selectedMessageVisible = true);
|
|
8177
8360
|
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
8178
|
-
this.selectedMessageThread =
|
|
8361
|
+
this.selectedMessageThread = selectedMessageThread;
|
|
8179
8362
|
}), 250);
|
|
8363
|
+
return selectedMessageThread;
|
|
8364
|
+
});
|
|
8365
|
+
}
|
|
8366
|
+
showSignIn() {
|
|
8367
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8368
|
+
this._signInSelected.next();
|
|
8369
|
+
});
|
|
8370
|
+
}
|
|
8371
|
+
showEditAvatar() {
|
|
8372
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8373
|
+
this._editAvatarSelected.next();
|
|
8180
8374
|
});
|
|
8181
8375
|
}
|
|
8182
8376
|
selectMessageUser(message) {
|
|
8183
|
-
this
|
|
8377
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8378
|
+
this._userSelected.next(message);
|
|
8379
|
+
});
|
|
8184
8380
|
}
|
|
8185
8381
|
selectUsername(user) {
|
|
8186
|
-
this
|
|
8382
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8383
|
+
this._usernameSelected.next(user);
|
|
8384
|
+
});
|
|
8187
8385
|
}
|
|
8188
8386
|
selectAvatar(user) {
|
|
8189
|
-
this
|
|
8387
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8388
|
+
this._avatarSelected.next(user);
|
|
8389
|
+
});
|
|
8190
8390
|
}
|
|
8191
8391
|
shareMessage(message) {
|
|
8192
|
-
this
|
|
8392
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8393
|
+
this._shared.next(message);
|
|
8394
|
+
});
|
|
8193
8395
|
}
|
|
8194
|
-
|
|
8396
|
+
deleteMessage(message) {
|
|
8195
8397
|
return __awaiter(this, void 0, void 0, function* () {
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8199
|
-
upvotes: 0,
|
|
8200
|
-
user: this.user,
|
|
8201
|
-
submessages: [],
|
|
8202
|
-
topicId: this.topicID,
|
|
8203
|
-
sentAt: Date.now(),
|
|
8204
|
-
updatedAt: Date.now()
|
|
8205
|
-
});
|
|
8206
|
-
this.replyMessage = '';
|
|
8398
|
+
if (!confirm("Are you sure you want to delete this comment? You cannot undo this action."))
|
|
8399
|
+
return;
|
|
8400
|
+
this.source.deleteMessage(message.id);
|
|
8207
8401
|
});
|
|
8208
8402
|
}
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8403
|
+
editMessage(source, message, newText) {
|
|
8404
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8405
|
+
try {
|
|
8406
|
+
yield source.editMessage(message.id, newText);
|
|
8407
|
+
}
|
|
8408
|
+
catch (e) {
|
|
8409
|
+
alert(e.message);
|
|
8410
|
+
return;
|
|
8411
|
+
}
|
|
8412
|
+
message.message = newText;
|
|
8413
|
+
message.transientState.editing = false;
|
|
8414
|
+
});
|
|
8415
|
+
}
|
|
8416
|
+
startEditing(message) {
|
|
8417
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8418
|
+
this.selectedMessage.transientState.editing = false;
|
|
8419
|
+
message.transientState.editing = true;
|
|
8420
|
+
});
|
|
8421
|
+
}
|
|
8422
|
+
saveEdit(message, text) {
|
|
8423
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8424
|
+
try {
|
|
8425
|
+
yield this.source.editMessage(message.id, text);
|
|
8426
|
+
message.transientState.editing = false;
|
|
8427
|
+
}
|
|
8428
|
+
catch (e) {
|
|
8429
|
+
alert(`Could not edit message: ${e.message}`);
|
|
8430
|
+
}
|
|
8431
|
+
});
|
|
8214
8432
|
}
|
|
8215
8433
|
}
|
|
8216
8434
|
BantaCommentsComponent.decorators = [
|
|
8217
8435
|
{ type: Component, args: [{
|
|
8218
8436
|
selector: 'banta-comments',
|
|
8219
|
-
template: "\r\n<div class=\"focused\" [class.visible]=\"selectedMessageVisible\" *ngIf=\"selectedMessage\">\r\n\r\n
|
|
8220
|
-
styles: [":host{display:flex;flex-direction:column}@-webkit-keyframes select-comment{0%{transform:scale(1.15)}to{transform:scale(1)}}@keyframes select-comment{0%{transform:scale(1.15)}to{transform:scale(1)}}.focused{-webkit-animation-
|
|
8437
|
+
template: "<ng-container *ngIf=\"loading\">\r\n <div class=\"loading-screen\" [class.visible]=\"showLoadingScreen\">\r\n <h1>Loading Comments</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\">\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 (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(selectedMessage)\"\r\n (unliked)=\"unlikeMessage(selectedMessage)\"\r\n (reported)=\"reportMessage(selectedMessage)\"\r\n (selected)=\"selectMessage(selectedMessage)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage(selectedMessage)\"\r\n ></banta-comment>\r\n\r\n <div class=\"replies\">\r\n\r\n <ng-container *ngIf=\"!selectedMessageThread\">\r\n <div class=\"loading\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedMessageThread\">\r\n <banta-comment-view\r\n [source]=\"selectedMessageThread\"\r\n [allowReplies]=\"false\"\r\n [fixedHeight]=\"false\"\r\n [showEmptyState]=\"false\"\r\n [newestLast]=\"true\"\r\n (liked)=\"likeMessage(selectedMessageThread, $event)\"\r\n (unliked)=\"unlikeMessage(selectedMessageThread, $event)\"\r\n (messageEdited)=\"editMessage(selectedMessageThread, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage($event)\"\r\n ></banta-comment-view>\r\n\r\n <banta-comment-field\r\n [sendLabel]=\"replyLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n (signInSelected)=\"showSignIn()\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n [source]=\"selectedMessageThread\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"permissionDeniedLabel\"\r\n (permissionDeniedError)=\"showPermissionDenied()\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\r\n [submit]=\"sendReply\"\r\n >\r\n <ng-content select=\".reply-send-options\"></ng-content>\r\n </banta-comment-field>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div class=\"main\" [class.hidden]=\"selectedMessage\">\r\n <banta-comment-field\r\n [source]=\"source\"\r\n [user]=\"user\"\r\n [sendLabel]=\"sendLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signInLabel]=\"signInLabel\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [label]=\"postCommentLabel\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (signInSelected)=\"showSignIn()\"\r\n [permissionDeniedLabel]=\"permissionDeniedLabel\"\r\n (permissionDeniedError)=\"showPermissionDenied()\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [submit]=\"sendMessage\"\r\n >\r\n \r\n </banta-comment-field>\r\n\r\n <banta-comment-sort\r\n [(sort)]=\"sortOrder\"></banta-comment-sort>\r\n\r\n <banta-comment-view\r\n [class.faded]=\"selectedMessage\"\r\n [source]=\"source\"\r\n [fixedHeight]=\"fixedHeight\"\r\n [maxMessages]=\"maxMessages\"\r\n [maxVisibleMessages]=\"maxVisibleMessages\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (userSelected)=\"selectMessageUser($event)\"\r\n (sortOrderChanged)=\"sortOrder = $event\"\r\n (selected)=\"selectMessage($event)\"\r\n (liked)=\"likeMessage(source, $event)\"\r\n (unliked)=\"unlikeMessage(source, $event)\"\r\n (messageEdited)=\"editMessage(source, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage($event)\"\r\n ></banta-comment-view>\r\n </div>\r\n</ng-container>",
|
|
8438
|
+
styles: [":host{display:flex;flex-direction:column}@-webkit-keyframes select-comment{0%{transform:scale(1.15)}to{transform:scale(1)}}@keyframes select-comment{0%{transform:scale(1.15)}to{transform:scale(1)}}.focused{-webkit-animation-name:select-comment;animation-name:select-comment;-webkit-animation-duration:.4s;animation-duration:.4s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.focused .replies{margin-top:1em;margin-left:4em}banta-comment-view{opacity:1;transition:opacity .4s ease-in-out}banta-comment-view.faded{opacity:.25}.loading{display:block;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;margin:0 auto;min-height:16em}.main.hidden{display:none}@media (max-width:500px){.focused .replies{margin-left:0}}.loading-screen{text-align:center;opacity:0;transition:opacity .25s ease-in-out}.loading-screen.visible{opacity:1}.loading-screen h1{font-weight:100}.loading-screen mat-spinner{margin:5em auto}.loading-screen .loading-message{opacity:0;transition:opacity .25s ease-in-out;width:500px;max-width:100%;margin:0 auto}.loading-screen .loading-message.visible{opacity:1}"]
|
|
8221
8439
|
},] }
|
|
8222
8440
|
];
|
|
8223
8441
|
BantaCommentsComponent.ctorParameters = () => [
|
|
8224
|
-
{ type:
|
|
8225
|
-
{ type: ChatBackendService },
|
|
8442
|
+
{ type: ChatBackendBase },
|
|
8226
8443
|
{ type: ElementRef },
|
|
8227
8444
|
{ type: ActivatedRoute }
|
|
8228
8445
|
];
|
|
8229
8446
|
BantaCommentsComponent.propDecorators = {
|
|
8230
|
-
|
|
8231
|
-
participants: [{ type: Input }],
|
|
8232
|
-
source: [{ type: Input }],
|
|
8233
|
-
fixedHeight: [{ type: Input }],
|
|
8234
|
-
maxMessages: [{ type: Input }],
|
|
8235
|
-
maxVisibleMessages: [{ type: Input }],
|
|
8236
|
-
genericAvatarUrl: [{ type: Input }],
|
|
8237
|
-
shouldInterceptMessageSend: [{ type: Input }],
|
|
8238
|
-
topicID: [{ type: Input }],
|
|
8447
|
+
loadingMessages: [{ type: Input }],
|
|
8239
8448
|
signInLabel: [{ type: Input }],
|
|
8240
8449
|
sendLabel: [{ type: Input }],
|
|
8241
8450
|
replyLabel: [{ type: Input }],
|
|
@@ -8243,6 +8452,15 @@ BantaCommentsComponent.propDecorators = {
|
|
|
8243
8452
|
permissionDeniedLabel: [{ type: Input }],
|
|
8244
8453
|
postCommentLabel: [{ type: Input }],
|
|
8245
8454
|
postReplyLabel: [{ type: Input }],
|
|
8455
|
+
fixedHeight: [{ type: Input }],
|
|
8456
|
+
maxMessages: [{ type: Input }],
|
|
8457
|
+
maxVisibleMessages: [{ type: Input }],
|
|
8458
|
+
genericAvatarUrl: [{ type: Input }],
|
|
8459
|
+
shouldInterceptMessageSend: [{ type: Input }],
|
|
8460
|
+
participants: [{ type: Input }],
|
|
8461
|
+
source: [{ type: Input }],
|
|
8462
|
+
hashtags: [{ type: Input }],
|
|
8463
|
+
topicID: [{ type: Input }],
|
|
8246
8464
|
signInSelected: [{ type: Output }],
|
|
8247
8465
|
editAvatarSelected: [{ type: Output }],
|
|
8248
8466
|
permissionDeniedError: [{ type: Output }],
|
|
@@ -8314,7 +8532,7 @@ LiveCommentComponent.decorators = [
|
|
|
8314
8532
|
},] }
|
|
8315
8533
|
];
|
|
8316
8534
|
LiveCommentComponent.ctorParameters = () => [
|
|
8317
|
-
{ type:
|
|
8535
|
+
{ type: ChatBackendBase }
|
|
8318
8536
|
];
|
|
8319
8537
|
LiveCommentComponent.propDecorators = {
|
|
8320
8538
|
upvoted: [{ type: Output }],
|
|
@@ -8337,6 +8555,7 @@ class CommentFieldComponent {
|
|
|
8337
8555
|
this.permissionDeniedLabel = 'Unavailable';
|
|
8338
8556
|
this.signInLabel = 'Sign In';
|
|
8339
8557
|
this.placeholder = '';
|
|
8558
|
+
this.textChanged = new Subject();
|
|
8340
8559
|
this.participants = [];
|
|
8341
8560
|
this._permissionDeniedError = new Subject();
|
|
8342
8561
|
this.autocompleteVisible = false;
|
|
@@ -8374,12 +8593,14 @@ class CommentFieldComponent {
|
|
|
8374
8593
|
}
|
|
8375
8594
|
indicateError(message) {
|
|
8376
8595
|
this.sendError = new Error(message);
|
|
8377
|
-
|
|
8596
|
+
this.expandError = false;
|
|
8597
|
+
clearTimeout(this.errorTimeout);
|
|
8598
|
+
this.errorTimeout = setTimeout(() => {
|
|
8378
8599
|
this.expandError = true;
|
|
8379
|
-
setTimeout(() => {
|
|
8600
|
+
this.errorTimeout = setTimeout(() => {
|
|
8380
8601
|
this.expandError = false;
|
|
8381
8602
|
}, 5 * 1000);
|
|
8382
|
-
});
|
|
8603
|
+
}, 100);
|
|
8383
8604
|
}
|
|
8384
8605
|
autocomplete(replacement) {
|
|
8385
8606
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -8505,7 +8726,6 @@ class CommentFieldComponent {
|
|
|
8505
8726
|
this.editAvatarSelected.next();
|
|
8506
8727
|
}
|
|
8507
8728
|
sendMessage() {
|
|
8508
|
-
var _a;
|
|
8509
8729
|
return __awaiter(this, void 0, void 0, function* () {
|
|
8510
8730
|
if (!this.source)
|
|
8511
8731
|
return;
|
|
@@ -8519,20 +8739,16 @@ class CommentFieldComponent {
|
|
|
8519
8739
|
user: this.user,
|
|
8520
8740
|
sentAt: Date.now(),
|
|
8521
8741
|
url: location.href,
|
|
8522
|
-
|
|
8742
|
+
likes: 0,
|
|
8523
8743
|
message: text
|
|
8524
8744
|
};
|
|
8525
8745
|
try {
|
|
8526
|
-
|
|
8527
|
-
if (!intercept) {
|
|
8528
|
-
yield this.source.send(message);
|
|
8529
|
-
}
|
|
8746
|
+
yield this.submit(message);
|
|
8530
8747
|
this.text = '';
|
|
8531
8748
|
}
|
|
8532
8749
|
catch (e) {
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
console.error(e);
|
|
8750
|
+
yield new Promise(resolve => setTimeout(() => resolve(), 1000));
|
|
8751
|
+
this.indicateError(e.message);
|
|
8536
8752
|
}
|
|
8537
8753
|
}
|
|
8538
8754
|
finally {
|
|
@@ -8545,7 +8761,7 @@ CommentFieldComponent.decorators = [
|
|
|
8545
8761
|
{ type: Component, args: [{
|
|
8546
8762
|
selector: 'banta-comment-field',
|
|
8547
8763
|
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(' + user?.avatarUrl + ')'\"\r\n ></a>\r\n </div>\r\n <div class=\"text-container\">\r\n <div class=\"field-container\">\r\n <mat-form-field appearance=\"outline\" floatLabel=\"always\">\r\n <mat-label>{{label}}</mat-label>\r\n <textarea\r\n #textarea\r\n name=\"message\"\r\n [placeholder]=\"placeholder\"\r\n matInput\r\n cdkTextareaAutosize\r\n (keydown)=\"onKeyDown($event)\"\r\n (blur)=\"onBlur()\"\r\n [disabled]=\"sending\"\r\n [(ngModel)]=\"text\"></textarea>\r\n </mat-form-field>\r\n <ng-content></ng-content>\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\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 </div>\r\n\r\n <mat-spinner *ngIf=\"sending\" class=\"icon loading\" diameter=\"18\" strokeWidth=\"2\"></mat-spinner>\r\n <div *ngIf=\"sendError\" class=\"error-message\" [class.expanded]=\"expandError\">\r\n <mat-icon *ngIf=\"sendError\">error</mat-icon>\r\n {{sendError.message}}\r\n </div>\r\n <emoji-selector-button\r\n class=\"top-right\"\r\n (selected)=\"insertEmoji($event)\"\r\n ></emoji-selector-button>\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 *ngIf=\"canComment\"\r\n mat-raised-button\r\n class=\"send\"\r\n color=\"primary\"\r\n [disabled]=\"!text || sending\"\r\n >\r\n <mat-icon *ngIf=\"!sending\">chevron_right</mat-icon>\r\n <mat-spinner *ngIf=\"sending\" class=\"icon\" diameter=\"18\" strokeWidth=\"2\"></mat-spinner>\r\n <span class=\"label\">\r\n <ng-container *ngIf=\"!sending\">\r\n {{sendLabel}}\r\n </ng-container>\r\n <ng-container *ngIf=\"sending\">\r\n {{sendingLabel}}\r\n </ng-container>\r\n </span>\r\n\r\n </button>\r\n <button\r\n *ngIf=\"!canComment\"\r\n type=\"button\"\r\n (click)=\"showPermissionDenied()\"\r\n mat-raised-button\r\n color=\"primary\"\r\n >{{permissionDeniedLabel}}</button>\r\n </ng-container>\r\n </div>\r\n</form>\r\n",
|
|
8548
|
-
styles: ["@-webkit-keyframes comment-field-appear{0%{
|
|
8764
|
+
styles: ["@-webkit-keyframes comment-field-appear{0%{transform:translateY(128px);opacity:0}to{transform:translate(0);opacity:1}}@keyframes comment-field-appear{0%{transform:translateY(128px);opacity:0}to{transform:translate(0);opacity:1}}:host{margin:0 2em 0 0;display:block;-webkit-animation-name:comment-field-appear;animation-name:comment-field-appear;-webkit-animation-duration:.8s;animation-duration:.8s;-webkit-animation-delay:.4s;animation-delay:.4s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.avatar-container{width:calc(48px + 1.75em);display:flex;justify-content:flex-end}.avatar-container .avatar{width:48px;height:48px;background:pink;border-radius:100%;background-size:cover;background-repeat:no-repeat;background-position:50%;margin-top:.75em;margin-right:.75em}form{display:flex;padding:.5em;align-items:center}form .text-container{position:relative;display:flex;flex-grow:1}form .text-container textarea{font-size:14pt;width:100%}form .text-container textarea[disabled]{opacity:.5}form .text-container mat-form-field{margin-bottom:1em}form .text-container emoji-selector-button{bottom:0;right:0;position:absolute}form .text-container .error-message,form .text-container mat-spinner.loading{position:absolute;left:.5em;bottom:.5em}form .text-container .error-message{color:#683333;overflow-x:hidden;max-width:1.5em;white-space:nowrap;transition:max-width 2s ease-in-out}form .text-container .error-message.expanded,form .text-container .error-message:hover{max-width:100%}form .text-container .error-message mat-icon{vertical-align:middle}form input[type=text]{background:#000;color:#fff;border:1px solid #333;width:100%;height:1em}form .actions{margin-left:1em}form button{display:block;margin:0 0 0 auto}form.new-message{display:flex;align-items:flex-start}form.new-message .field-container{flex-grow:1;display:flex;flex-direction:column}form.new-message mat-form-field{width:100%}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:auto}.autocomplete a{width:100%;text-align:left}.autocomplete a.active{background:#555}@media (max-width:500px){:host{margin:0}.avatar-container{width:auto}.avatar-container .avatar{width:32px;height:32px;margin-top:1.5em}button.send{min-width:auto;margin-top:1.5em}button.send .label{display:none}}"]
|
|
8549
8765
|
},] }
|
|
8550
8766
|
];
|
|
8551
8767
|
CommentFieldComponent.propDecorators = {
|
|
@@ -8554,19 +8770,23 @@ CommentFieldComponent.propDecorators = {
|
|
|
8554
8770
|
canComment: [{ type: Input }],
|
|
8555
8771
|
signInSelected: [{ type: Output }],
|
|
8556
8772
|
editAvatarSelected: [{ type: Output }],
|
|
8773
|
+
sendError: [{ type: Input }],
|
|
8774
|
+
expandError: [{ type: Input }],
|
|
8557
8775
|
sendLabel: [{ type: Input }],
|
|
8558
8776
|
sendingLabel: [{ type: Input }],
|
|
8559
8777
|
label: [{ type: Input }],
|
|
8560
8778
|
permissionDeniedLabel: [{ type: Input }],
|
|
8561
8779
|
signInLabel: [{ type: Input }],
|
|
8562
8780
|
placeholder: [{ type: Input }],
|
|
8781
|
+
textChanged: [{ type: Output }],
|
|
8563
8782
|
shouldInterceptMessageSend: [{ type: Input }],
|
|
8564
8783
|
autocompleteEl: [{ type: ViewChild, args: ['autocomplete',] }],
|
|
8565
8784
|
autocompleteContainerEl: [{ type: ViewChild, args: ['autocompleteContainer',] }],
|
|
8566
8785
|
textareaEl: [{ type: ViewChild, args: ['textarea',] }],
|
|
8567
8786
|
hashtags: [{ type: Input }],
|
|
8568
8787
|
participants: [{ type: Input }],
|
|
8569
|
-
permissionDeniedError: [{ type: Output }]
|
|
8788
|
+
permissionDeniedError: [{ type: Output }],
|
|
8789
|
+
submit: [{ type: Input }]
|
|
8570
8790
|
};
|
|
8571
8791
|
|
|
8572
8792
|
class CommentSortComponent {
|
|
@@ -8632,12 +8852,234 @@ CommentsModule.decorators = [
|
|
|
8632
8852
|
},] }
|
|
8633
8853
|
];
|
|
8634
8854
|
|
|
8855
|
+
class ChatSource extends SocketRPC {
|
|
8856
|
+
constructor(backend, identifier, parentIdentifier, sortOrder) {
|
|
8857
|
+
super();
|
|
8858
|
+
this.backend = backend;
|
|
8859
|
+
this.identifier = identifier;
|
|
8860
|
+
this.parentIdentifier = parentIdentifier;
|
|
8861
|
+
this.sortOrder = sortOrder;
|
|
8862
|
+
this.subscription = new Subscription();
|
|
8863
|
+
this.state = 'connecting';
|
|
8864
|
+
this.messageMap = new Map();
|
|
8865
|
+
this._messageReceived = new Subject();
|
|
8866
|
+
this._messageSent = new Subject();
|
|
8867
|
+
this.messages = [];
|
|
8868
|
+
this.ready = new Promise(resolve => this.markReady = resolve);
|
|
8869
|
+
}
|
|
8870
|
+
bind(socket) {
|
|
8871
|
+
const _super = Object.create(null, {
|
|
8872
|
+
bind: { get: () => super.bind }
|
|
8873
|
+
});
|
|
8874
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8875
|
+
_super.bind.call(this, socket);
|
|
8876
|
+
this.state = 'connected';
|
|
8877
|
+
this.markReady();
|
|
8878
|
+
yield this.subscribeToTopic();
|
|
8879
|
+
this.subscription.add(this.backend.userChanged.subscribe(() => this.authenticate()));
|
|
8880
|
+
socket.addEventListener('open', () => __awaiter(this, void 0, void 0, function* () {
|
|
8881
|
+
this.state = 'connected';
|
|
8882
|
+
}));
|
|
8883
|
+
socket.addEventListener('lost', () => __awaiter(this, void 0, void 0, function* () {
|
|
8884
|
+
this.state = 'lost';
|
|
8885
|
+
}));
|
|
8886
|
+
socket.addEventListener('restore', () => __awaiter(this, void 0, void 0, function* () {
|
|
8887
|
+
this.state = 'restored';
|
|
8888
|
+
yield this.authenticate();
|
|
8889
|
+
yield this.subscribeToTopic();
|
|
8890
|
+
}));
|
|
8891
|
+
return this;
|
|
8892
|
+
});
|
|
8893
|
+
}
|
|
8894
|
+
getExistingMessages() {
|
|
8895
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8896
|
+
let messages = yield this.peer.getExistingMessages();
|
|
8897
|
+
messages = messages.map(message => {
|
|
8898
|
+
let existingMessage = this.messageMap.get(message.id);
|
|
8899
|
+
if (existingMessage)
|
|
8900
|
+
message = Object.assign(existingMessage, message);
|
|
8901
|
+
else
|
|
8902
|
+
this.messageMap.set(message.id, message);
|
|
8903
|
+
return message;
|
|
8904
|
+
});
|
|
8905
|
+
return messages;
|
|
8906
|
+
});
|
|
8907
|
+
}
|
|
8908
|
+
editMessage(messageId, text) {
|
|
8909
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8910
|
+
this.peer.editMessage(messageId, text);
|
|
8911
|
+
});
|
|
8912
|
+
}
|
|
8913
|
+
subscribeToTopic() {
|
|
8914
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8915
|
+
yield this.peer.subscribe(this.identifier, this.parentIdentifier, this.sortOrder);
|
|
8916
|
+
});
|
|
8917
|
+
}
|
|
8918
|
+
authenticate() {
|
|
8919
|
+
var _a;
|
|
8920
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8921
|
+
yield this.peer.authenticate((_a = this.backend.user) === null || _a === void 0 ? void 0 : _a.token);
|
|
8922
|
+
});
|
|
8923
|
+
}
|
|
8924
|
+
close() {
|
|
8925
|
+
super.close();
|
|
8926
|
+
this.subscription.unsubscribe();
|
|
8927
|
+
}
|
|
8928
|
+
onPermissions(permissions) {
|
|
8929
|
+
window.bantaPermissionsDebug = permissions;
|
|
8930
|
+
this.permissions = permissions;
|
|
8931
|
+
}
|
|
8932
|
+
onChatMessage(message) {
|
|
8933
|
+
if (this.messageMap.has(message.id)) {
|
|
8934
|
+
Object.assign(this.messageMap.get(message.id), message);
|
|
8935
|
+
}
|
|
8936
|
+
else if (!message.hidden) {
|
|
8937
|
+
// Only process non-hidden messages through here.
|
|
8938
|
+
// Hidden messages may be sent to us when they become hidden (ie moderation is occurring).
|
|
8939
|
+
// But if we never had the message to begin with, we should discard it.
|
|
8940
|
+
this.messageMap.set(message.id, message);
|
|
8941
|
+
this._messageReceived.next(message);
|
|
8942
|
+
}
|
|
8943
|
+
}
|
|
8944
|
+
get messageReceived() { return this._messageReceived.asObservable(); }
|
|
8945
|
+
get messageSent() { return this._messageSent.asObservable(); }
|
|
8946
|
+
send(message) {
|
|
8947
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8948
|
+
return yield this.peer.sendMessage(message);
|
|
8949
|
+
});
|
|
8950
|
+
}
|
|
8951
|
+
loadAfter(message, count) {
|
|
8952
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8953
|
+
if (!message)
|
|
8954
|
+
return;
|
|
8955
|
+
if (!message.pagingCursor)
|
|
8956
|
+
return [];
|
|
8957
|
+
return this.peer.loadAfter(Number(message.pagingCursor), count);
|
|
8958
|
+
});
|
|
8959
|
+
}
|
|
8960
|
+
get(id) {
|
|
8961
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8962
|
+
if (this.messageMap.has(id))
|
|
8963
|
+
return this.messageMap.get(id);
|
|
8964
|
+
let message = yield this.peer.getMessage(id);
|
|
8965
|
+
this.messageMap.set(id, message);
|
|
8966
|
+
return message;
|
|
8967
|
+
});
|
|
8968
|
+
}
|
|
8969
|
+
getCount() {
|
|
8970
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8971
|
+
return yield this.peer.getCount();
|
|
8972
|
+
});
|
|
8973
|
+
}
|
|
8974
|
+
likeMessage(messageId) {
|
|
8975
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8976
|
+
return yield this.peer.likeMessage(messageId);
|
|
8977
|
+
});
|
|
8978
|
+
}
|
|
8979
|
+
unlikeMessage(messageId) {
|
|
8980
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8981
|
+
return yield this.peer.unlikeMessage(messageId);
|
|
8982
|
+
});
|
|
8983
|
+
}
|
|
8984
|
+
deleteMessage(messageId) {
|
|
8985
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8986
|
+
return yield this.peer.deleteMessage(messageId);
|
|
8987
|
+
});
|
|
8988
|
+
}
|
|
8989
|
+
}
|
|
8990
|
+
__decorate([
|
|
8991
|
+
RpcEvent(),
|
|
8992
|
+
__metadata("design:type", Function),
|
|
8993
|
+
__metadata("design:paramtypes", [Object]),
|
|
8994
|
+
__metadata("design:returntype", void 0)
|
|
8995
|
+
], ChatSource.prototype, "onPermissions", null);
|
|
8996
|
+
__decorate([
|
|
8997
|
+
RpcEvent(),
|
|
8998
|
+
__metadata("design:type", Function),
|
|
8999
|
+
__metadata("design:paramtypes", [Object]),
|
|
9000
|
+
__metadata("design:returntype", void 0)
|
|
9001
|
+
], ChatSource.prototype, "onChatMessage", null);
|
|
9002
|
+
|
|
9003
|
+
const BANTA_SDK_OPTIONS = 'BANTA_SDK_OPTIONS';
|
|
9004
|
+
|
|
9005
|
+
class ChatBackend extends ChatBackendBase {
|
|
9006
|
+
constructor(options) {
|
|
9007
|
+
super();
|
|
9008
|
+
this.options = options;
|
|
9009
|
+
}
|
|
9010
|
+
get serviceUrl() {
|
|
9011
|
+
var _a, _b;
|
|
9012
|
+
return `${(_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.serviceUrl) !== null && _b !== void 0 ? _b : 'http://localhost:3422'}`;
|
|
9013
|
+
}
|
|
9014
|
+
connectToService() {
|
|
9015
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
9016
|
+
let socket = new DurableSocket(`${this.serviceUrl.replace(/^http/, 'ws')}/socket`);
|
|
9017
|
+
yield new Promise((resolve, reject) => {
|
|
9018
|
+
socket.onopen = () => {
|
|
9019
|
+
resolve();
|
|
9020
|
+
};
|
|
9021
|
+
socket.onclose = e => {
|
|
9022
|
+
if (e.code === 503) {
|
|
9023
|
+
console.error(`Failed to connect to chat service!`);
|
|
9024
|
+
reject(e);
|
|
9025
|
+
}
|
|
9026
|
+
};
|
|
9027
|
+
});
|
|
9028
|
+
socket.onerror = undefined;
|
|
9029
|
+
return socket;
|
|
9030
|
+
});
|
|
9031
|
+
}
|
|
9032
|
+
getSourceForTopic(topicId, options) {
|
|
9033
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
9034
|
+
return yield new ChatSource(this, topicId, undefined, (options === null || options === void 0 ? void 0 : options.sortOrder) || CommentsOrder.NEWEST)
|
|
9035
|
+
.bind(yield this.connectToService());
|
|
9036
|
+
});
|
|
9037
|
+
}
|
|
9038
|
+
getSourceForThread(topicId, messageId, options) {
|
|
9039
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
9040
|
+
return yield new ChatSource(this, topicId, messageId, (options === null || options === void 0 ? void 0 : options.sortOrder) || CommentsOrder.NEWEST)
|
|
9041
|
+
.bind(yield this.connectToService());
|
|
9042
|
+
});
|
|
9043
|
+
}
|
|
9044
|
+
getSourceCountForTopic(topicId) {
|
|
9045
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
9046
|
+
let response = yield fetch(`${this.serviceUrl}/topics/${topicId}`);
|
|
9047
|
+
if (response.status >= 400)
|
|
9048
|
+
return 0;
|
|
9049
|
+
let topic = yield response.json();
|
|
9050
|
+
return topic.messageCount || 0;
|
|
9051
|
+
});
|
|
9052
|
+
}
|
|
9053
|
+
refreshMessage(message) {
|
|
9054
|
+
throw new Error("Method not implemented.");
|
|
9055
|
+
}
|
|
9056
|
+
getMessage(topicId, messageId) {
|
|
9057
|
+
throw new Error("Method not implemented.");
|
|
9058
|
+
}
|
|
9059
|
+
getSubMessage(topicId, parentMessageId, messageId) {
|
|
9060
|
+
throw new Error("Method not implemented.");
|
|
9061
|
+
}
|
|
9062
|
+
watchMessage(message, handler) {
|
|
9063
|
+
throw new Error("Method not implemented.");
|
|
9064
|
+
}
|
|
9065
|
+
}
|
|
9066
|
+
ChatBackend.decorators = [
|
|
9067
|
+
{ type: Injectable }
|
|
9068
|
+
];
|
|
9069
|
+
ChatBackend.ctorParameters = () => [
|
|
9070
|
+
{ type: undefined, decorators: [{ type: Inject, args: [BANTA_SDK_OPTIONS,] }] }
|
|
9071
|
+
];
|
|
9072
|
+
|
|
8635
9073
|
class BantaSdkModule {
|
|
8636
|
-
static
|
|
9074
|
+
static configure(options) {
|
|
8637
9075
|
return {
|
|
8638
9076
|
ngModule: BantaSdkModule,
|
|
8639
9077
|
providers: [
|
|
8640
|
-
|
|
9078
|
+
{
|
|
9079
|
+
provide: BANTA_SDK_OPTIONS,
|
|
9080
|
+
useValue: options || {}
|
|
9081
|
+
},
|
|
9082
|
+
{ provide: ChatBackendBase, useClass: ChatBackend }
|
|
8641
9083
|
]
|
|
8642
9084
|
};
|
|
8643
9085
|
}
|
|
@@ -8683,5 +9125,5 @@ BantaSdkModule.decorators = [
|
|
|
8683
9125
|
* Generated bundle index. Do not edit.
|
|
8684
9126
|
*/
|
|
8685
9127
|
|
|
8686
|
-
export { BantaChatComponent, BantaCommentsComponent, BantaCommonModule, BantaComponent, BantaLogoComponent, BantaSdkModule,
|
|
9128
|
+
export { BANTA_SDK_OPTIONS, BantaChatComponent, BantaCommentsComponent, BantaCommonModule, BantaComponent, BantaLogoComponent, BantaSdkModule, ChatBackend, ChatBackendBase, ChatMessageComponent, ChatModule, ChatSource, ChatViewComponent, CommentComponent, CommentFieldComponent, CommentSortComponent, CommentViewComponent, CommentsModule, EMOJIS, EmojiModule, EmojiSelectorButtonComponent, EmojiSelectorPanelComponent, LiveChatMessageComponent, LiveCommentComponent, LiveMessageComponent, TimestampComponent, lazyConnection };
|
|
8687
9129
|
//# sourceMappingURL=banta-sdk.js.map
|