@banta/sdk 3.0.1 → 3.1.2
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/bundles/banta-sdk.umd.js +501 -46
- 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/lib/banta/banta.component.js +2 -4
- package/esm2015/lib/chat/banta-chat/banta-chat.component.js +5 -1
- package/esm2015/lib/comments/banta-comments/banta-comments.component.js +106 -22
- package/esm2015/lib/comments/comment/comment.component.js +24 -5
- package/esm2015/lib/comments/comment-field/comment-field.component.js +235 -0
- package/esm2015/lib/comments/comment-view/comment-view.component.js +4 -4
- package/esm2015/lib/comments/comments.module.js +4 -2
- package/esm2015/lib/comments/index.js +2 -1
- package/esm2015/lib/emoji/emoji-selector-button.component.js +22 -8
- package/esm2015/lib/emoji/emoji-selector-panel/emoji-selector-panel.component.js +31 -3
- package/esm2015/lib/emoji/emoji.module.js +8 -2
- package/fesm2015/banta-sdk.js +426 -44
- package/fesm2015/banta-sdk.js.map +1 -1
- package/lib/comments/banta-comments/banta-comments.component.d.ts +25 -4
- package/lib/comments/comment/comment.component.d.ts +4 -0
- package/lib/comments/comment-field/comment-field.component.d.ts +51 -0
- package/lib/comments/comment-view/comment-view.component.d.ts +1 -1
- package/lib/comments/index.d.ts +1 -0
- package/lib/emoji/emoji-selector-button.component.d.ts +4 -0
- package/lib/emoji/emoji-selector-panel/emoji-selector-panel.component.d.ts +8 -0
- package/package.json +1 -1
package/bundles/banta-sdk.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs'), require('rxjs/operators'), require('@angular/core'), require('@angular/common'), require('@angular/platform-browser'), require('@angular/material/icon'), require('@angular/material/button'), require('
|
|
3
|
-
typeof define === 'function' && define.amd ? define('@banta/sdk', ['exports', 'rxjs', 'rxjs/operators', '@angular/core', '@angular/common', '@angular/platform-browser', '@angular/material/icon', '@angular/material/button', '
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.banta = global.banta || {}, global.banta.sdk = {}), global.rxjs, global.rxjs.operators, global.ng.core, global.ng.common, global.ng.platformBrowser, global.ng.material.icon, global.ng.material.button, global.
|
|
5
|
-
}(this, (function (exports, rxjs, operators, core, common, platformBrowser, icon, button,
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs'), require('rxjs/operators'), require('@angular/core'), require('@angular/common'), require('@angular/platform-browser'), require('@angular/material/icon'), require('@angular/material/button'), require('@angular/material/form-field'), require('@angular/material/input'), require('@angular/forms'), require('subsink'), require('@angular/material/dialog'), require('@angular/material/menu'), require('@angular/material/progress-spinner'), require('@angular/cdk/text-field'), require('@angular/material/tooltip')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define('@banta/sdk', ['exports', 'rxjs', 'rxjs/operators', '@angular/core', '@angular/common', '@angular/platform-browser', '@angular/material/icon', '@angular/material/button', '@angular/material/form-field', '@angular/material/input', '@angular/forms', 'subsink', '@angular/material/dialog', '@angular/material/menu', '@angular/material/progress-spinner', '@angular/cdk/text-field', '@angular/material/tooltip'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.banta = global.banta || {}, global.banta.sdk = {}), global.rxjs, global.rxjs.operators, global.ng.core, global.ng.common, global.ng.platformBrowser, global.ng.material.icon, global.ng.material.button, global.ng.material.formField, global.ng.material.input, global.ng.forms, global.subsink, global.ng.material.dialog, global.ng.material.menu, global.ng.material.progressSpinner, global.ng.cdk.textField, global.ng.material.tooltip));
|
|
5
|
+
}(this, (function (exports, rxjs, operators, core, common, platformBrowser, icon, button, formField, input, forms, subsink, dialog, menu, progressSpinner, textField, tooltip) { 'use strict';
|
|
6
6
|
|
|
7
7
|
function lazyConnection(options) {
|
|
8
8
|
var obs = new rxjs.Observable(function (observer) {
|
|
@@ -7006,14 +7006,49 @@
|
|
|
7006
7006
|
function EmojiSelectorPanelComponent(sanitizer) {
|
|
7007
7007
|
this.sanitizer = sanitizer;
|
|
7008
7008
|
this.activeCategory = 'people';
|
|
7009
|
+
this.searchResults = [];
|
|
7010
|
+
this.searchVisible = false;
|
|
7009
7011
|
this.selected = new rxjs.Subject();
|
|
7010
7012
|
}
|
|
7013
|
+
Object.defineProperty(EmojiSelectorPanelComponent.prototype, "searchQuery", {
|
|
7014
|
+
get: function () {
|
|
7015
|
+
return this._searchQuery;
|
|
7016
|
+
},
|
|
7017
|
+
set: function (value) {
|
|
7018
|
+
var _this = this;
|
|
7019
|
+
this._searchQuery = value;
|
|
7020
|
+
setTimeout(function () {
|
|
7021
|
+
_this.searchResults = Object.keys(EMOJIS).filter(function (k) { return k.includes(value); }).map(function (k) { return EMOJIS[k]; });
|
|
7022
|
+
_this.searchResults.splice(50, _this.searchResults.length);
|
|
7023
|
+
console.log("looking for '" + value + "' => " + _this.searchResults.length + " results");
|
|
7024
|
+
});
|
|
7025
|
+
},
|
|
7026
|
+
enumerable: false,
|
|
7027
|
+
configurable: true
|
|
7028
|
+
});
|
|
7029
|
+
EmojiSelectorPanelComponent.prototype.humanize = function (str) {
|
|
7030
|
+
return str.replace(/(^| )[a-z]/g, function (k) { return k.toUpperCase(); }).replace(/_/g, ' ');
|
|
7031
|
+
};
|
|
7011
7032
|
EmojiSelectorPanelComponent.prototype.select = function (char) {
|
|
7012
7033
|
this.selected.next(char);
|
|
7013
7034
|
};
|
|
7014
7035
|
EmojiSelectorPanelComponent.prototype.pairs = function (object) {
|
|
7015
7036
|
return Object.keys(object).map(function (key) { return [key, object[key]]; });
|
|
7016
7037
|
};
|
|
7038
|
+
EmojiSelectorPanelComponent.prototype.hideSearch = function () {
|
|
7039
|
+
var _this = this;
|
|
7040
|
+
// because of the "outside click detection"
|
|
7041
|
+
setTimeout(function () {
|
|
7042
|
+
_this.searchVisible = false;
|
|
7043
|
+
});
|
|
7044
|
+
};
|
|
7045
|
+
EmojiSelectorPanelComponent.prototype.showSearch = function () {
|
|
7046
|
+
var _this = this;
|
|
7047
|
+
// because of the "outside click detection"
|
|
7048
|
+
setTimeout(function () {
|
|
7049
|
+
_this.searchVisible = true;
|
|
7050
|
+
});
|
|
7051
|
+
};
|
|
7017
7052
|
EmojiSelectorPanelComponent.prototype.ngOnInit = function () {
|
|
7018
7053
|
var e_1, _a;
|
|
7019
7054
|
var cats = {};
|
|
@@ -7057,8 +7092,8 @@
|
|
|
7057
7092
|
EmojiSelectorPanelComponent.decorators = [
|
|
7058
7093
|
{ type: core.Component, args: [{
|
|
7059
7094
|
selector: 'emoji-selector-panel',
|
|
7060
|
-
template: "<div class=\"categories\">\r\n\t<a title=\"
|
|
7061
|
-
styles: [":host{background:#111;border:1px solid #333;border-radius:5px;display:flex;flex-direction:column;padding:.5em;width:calc(
|
|
7095
|
+
template: "<ng-container *ngIf=\"searchVisible\">\r\n\t<div class=\"search-box\" *ngIf=\"searchVisible\">\r\n\t\t<a mat-icon-button href=\"javascript:;\" (click)=\"hideSearch()\">\r\n\t\t\t<mat-icon>arrow_back</mat-icon>\r\n\t\t</a>\r\n\t\t<mat-form-field appearance=\"outline\" floatLabel=\"always\">\r\n\t\t\t<mat-label>Search for emoji</mat-label>\r\n\t\t\t<input name=\"search\" type=\"text\" matInput placeholder=\"Start typing\" [(ngModel)]=\"searchQuery\" />\r\n\t\t</mat-form-field>\r\n\t</div>\r\n\t<div class=\"emoji-list\">\r\n\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t*ngFor=\"let emoji of searchResults\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t</a>\r\n\t</div>\r\n</ng-container>\r\n<ng-container *ngIf=\"!searchVisible\">\r\n\t<div class=\"categories\">\r\n\t\t<ng-container *ngIf=\"!searchVisible\">\r\n\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<mat-icon>{{category.icon}}</mat-icon>\r\n\t\t\t</a>\r\n\r\n\t\t\t<a title=\"Search\" [class.active] mat-icon-button (click)=\"showSearch()\">\r\n\t\t\t\t<mat-icon>search</mat-icon>\r\n\t\t\t</a>\r\n\t\t</ng-container>\r\n\t</div>\r\n\t<div *ngFor=\"let category of categories\">\r\n\t\t<div class=\"emoji-list\" *ngIf=\"activeCategory && activeCategory == category.name\">\r\n\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t*ngFor=\"let emoji of category.emojis\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t</a>\r\n\t\t</div>\r\n\t</div>\r\n</ng-container>",
|
|
7096
|
+
styles: [":host{background:#111;border:1px solid #333;border-radius:5px;color:#fff;display:flex;flex-direction:column;padding:.5em;width:calc(288px + 9em)}.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;height:20em;overflow-y:auto}.emoji-list a{background-color:#111;display:inline-block;margin:4px;padding:2px}.emoji-list a ::ng-deep .emoji{height:32px;width:32px}.emoji-list a:hover{background-color:#333}.search-box{align-items:baseline;display:flex}.search-box mat-form-field{flex-grow:1}"]
|
|
7062
7097
|
},] }
|
|
7063
7098
|
];
|
|
7064
7099
|
EmojiSelectorPanelComponent.ctorParameters = function () { return [
|
|
@@ -7082,6 +7117,11 @@
|
|
|
7082
7117
|
});
|
|
7083
7118
|
EmojiSelectorButtonComponent.prototype.ngOnDestroy = function () {
|
|
7084
7119
|
this.removeListener();
|
|
7120
|
+
this.panelElement.nativeElement.remove();
|
|
7121
|
+
};
|
|
7122
|
+
EmojiSelectorButtonComponent.prototype.ngAfterViewInit = function () {
|
|
7123
|
+
var root = document.body.querySelector('[ng-version]') || document.body;
|
|
7124
|
+
root.appendChild(this.panelElement.nativeElement);
|
|
7085
7125
|
};
|
|
7086
7126
|
EmojiSelectorButtonComponent.prototype.removeListener = function () {
|
|
7087
7127
|
document.removeEventListener('click', this.clickListener);
|
|
@@ -7093,6 +7133,12 @@
|
|
|
7093
7133
|
return;
|
|
7094
7134
|
}
|
|
7095
7135
|
this.showEmojiPanel = true;
|
|
7136
|
+
var pos = this.buttonElement.nativeElement.getBoundingClientRect();
|
|
7137
|
+
var size = this.panelElement.nativeElement.getBoundingClientRect();
|
|
7138
|
+
Object.assign(this.panelElement.nativeElement.style, {
|
|
7139
|
+
top: pos.top + pos.height + "px",
|
|
7140
|
+
right: Math.max(0, window.innerWidth - pos.left - pos.width) + "px"
|
|
7141
|
+
});
|
|
7096
7142
|
setTimeout(function () {
|
|
7097
7143
|
_this.clickListener = function (ev) {
|
|
7098
7144
|
var parent = ev.target;
|
|
@@ -7118,12 +7164,14 @@
|
|
|
7118
7164
|
EmojiSelectorButtonComponent.decorators = [
|
|
7119
7165
|
{ type: core.Component, args: [{
|
|
7120
7166
|
selector: 'emoji-selector-button',
|
|
7121
|
-
template: "\n <button mat-icon-button (click)=\"show()\">\n <mat-icon>emoji_emotions</mat-icon>\n </button>\n <emoji-selector-panel \n (selected)=\"insert($event)\"\n [class.visible]=\"showEmojiPanel\"\n ></emoji-selector-panel>\n ",
|
|
7122
|
-
styles: ["\n :host {\n display: block;\n position: relative;\n }\n\n emoji-selector-panel {\n position: absolute;\n bottom: 2.5em;\n right: 0
|
|
7167
|
+
template: "\n <button #button type=\"button\" mat-icon-button (click)=\"show()\">\n <mat-icon>emoji_emotions</mat-icon>\n </button>\n <emoji-selector-panel \n #panel\n (selected)=\"insert($event)\"\n [class.visible]=\"showEmojiPanel\"\n ></emoji-selector-panel>\n ",
|
|
7168
|
+
styles: ["\n :host {\n display: block;\n position: relative;\n }\n\n emoji-selector-panel {\n position: absolute;\n /* bottom: 2.5em;\n right: 0; */\n opacity: 0;\n pointer-events: none;\n z-index: 10;\n }\n\n emoji-selector-panel.visible {\n pointer-events: initial;\n opacity: 1;\n }\n\n button {\n color: #666\n }\n\n /* :host.bottom-left emoji-selector-panel {\n right: auto;\n left: 0;\n }\n\n :host.top-right emoji-selector-panel {\n top: 2.4em;\n bottom: auto;\n }\n\n :host.top-left emoji-selector-panel {\n top: 2.4em;\n bottom: auto;\n left: 0;\n right: auto;\n } */\n "]
|
|
7123
7169
|
},] }
|
|
7124
7170
|
];
|
|
7125
7171
|
EmojiSelectorButtonComponent.propDecorators = {
|
|
7126
|
-
selected: [{ type: core.Output }]
|
|
7172
|
+
selected: [{ type: core.Output }],
|
|
7173
|
+
panelElement: [{ type: core.ViewChild, args: ['panel', { read: core.ElementRef },] }],
|
|
7174
|
+
buttonElement: [{ type: core.ViewChild, args: ['button', { read: core.ElementRef },] }]
|
|
7127
7175
|
};
|
|
7128
7176
|
|
|
7129
7177
|
var COMPONENTS$1 = [
|
|
@@ -7140,8 +7188,11 @@
|
|
|
7140
7188
|
declarations: COMPONENTS$1,
|
|
7141
7189
|
imports: [
|
|
7142
7190
|
common.CommonModule,
|
|
7191
|
+
forms.FormsModule,
|
|
7143
7192
|
icon.MatIconModule,
|
|
7144
|
-
button.MatButtonModule
|
|
7193
|
+
button.MatButtonModule,
|
|
7194
|
+
formField.MatFormFieldModule,
|
|
7195
|
+
input.MatInputModule
|
|
7145
7196
|
],
|
|
7146
7197
|
exports: COMPONENTS$1
|
|
7147
7198
|
},] }
|
|
@@ -7168,8 +7219,6 @@
|
|
|
7168
7219
|
this.pointSubChat = null;
|
|
7169
7220
|
this.newPointSubMessage = {};
|
|
7170
7221
|
this.genericAvatarUrl = 'https://gravatar.com/avatar/915c804e0be607a4ad766ddadea5c48a?s=512&d=https://codepen.io/assets/avatars/user-avatar-512x512-6e240cf350d2f1cc07c2bed234c3a3bb5f1b237023c204c782622e80d6b212ba.png';
|
|
7171
|
-
// this.firehoseSource = new MockFirehoseSource();
|
|
7172
|
-
// this.pointSource = new MockPointSource();
|
|
7173
7222
|
}
|
|
7174
7223
|
BantaComponent.prototype.ngOnInit = function () {
|
|
7175
7224
|
var _this = this;
|
|
@@ -7387,7 +7436,7 @@
|
|
|
7387
7436
|
BantaComponent.decorators = [
|
|
7388
7437
|
{ type: core.Component, args: [{
|
|
7389
7438
|
selector: "banta",
|
|
7390
|
-
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\r\n <pre>{{profileUser | json}}</pre>\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>",
|
|
7439
|
+
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>",
|
|
7391
7440
|
styles: [":host{display:flex;flex-direction:row;height:40em;padding:.5em;position:relative}.counted-action{align-items:center;display:flex}.count-indicator{border:1px solid #333;border-radius:3px;font-size:9pt;padding:0 3px}header{margin-bottom:1em;position:relative}header div{align-items:center;display:flex;height:30px}header button{color:#666}header label{color:#333;font-size:12pt;font-weight:100;letter-spacing:2px;margin:0 auto 0 0;overflow-x:hidden;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;z-index:1}header:after,header label{display:block;position:relative}header:after{border:1px solid #ccc;content:\"\";height:0;width:100%;z-index:0}.points{display:flex;flex-direction:column;max-width:50em}:host.point-focus .points{max-width:50em;width:66%}: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{flex-shrink:0;font-size:12pt;margin-left:.5em;max-width:30em;position:relative;transition:width .2s ease-in,max-width .2s ease-in;width:33%}.points .points-section{opacity:1;z-index:2}.points .point-focus,.points .points-section{display:flex;flex-direction:column;flex-grow:1;transition:opacity .2s ease-in}.points .point-focus{bottom:0;left:0;opacity:0;padding:.5em;position:absolute;right:0;top:1.75em;width:100%}.firehose{display:flex;flex-direction:column;flex-grow:1;font-size:10pt}form{align-items:center;display:flex;padding:.5em 0}form textarea{font-size:14pt;min-height:6em}form input[type=text],form textarea{background:#000;border:1px solid #333;color:#fff;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{display:flex;flex-direction:column;min-width:0;overflow-x:hidden;transition:width .4s ease-out,min-width .4s ease-out;width:0}.aux.open{min-width:18em;width:30em}.aux .aux-contents{align-items:center;display:flex;flex-direction:column;flex-grow:1;justify-content:center;max-width:100%;min-width:10em;width:30em}.notifications .notification{border-bottom:1px solid #333;padding:1em}.notifications .notification banta-timestamp{color:#999;display:block;font-size:9pt;text-align:right}.message.reply{padding:1em}.tabs{display:none}@media (max-width:1015px){:host{flex-direction:column}.tabs{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:rgba(0,0,0,.5);display:flex;left:0;position:absolute;right:0;top:0;width:100%;z-index:10}.points{margin-left:0;max-width:100%;width:100%}header{display:none}.aux,:host.point-focus .points{max-width:100%;width:100%}.aux{min-width:0}.aux,.firehose,.points{background:#000;bottom:0;left:0;position:absolute;right:0;top:2em;z-index:0}.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}"]
|
|
7392
7441
|
},] }
|
|
7393
7442
|
];
|
|
@@ -7876,8 +7925,12 @@
|
|
|
7876
7925
|
Object.defineProperty(BantaChatComponent.prototype, "canChat", {
|
|
7877
7926
|
get: function () {
|
|
7878
7927
|
var _a;
|
|
7928
|
+
if (!this.user)
|
|
7929
|
+
return false;
|
|
7879
7930
|
if (!this.user.permissions)
|
|
7880
7931
|
return true;
|
|
7932
|
+
if (!this.user.permissions.canChat)
|
|
7933
|
+
return true;
|
|
7881
7934
|
return (_a = this.user.permissions) === null || _a === void 0 ? void 0 : _a.canChat(this.source);
|
|
7882
7935
|
},
|
|
7883
7936
|
enumerable: false,
|
|
@@ -8049,8 +8102,21 @@
|
|
|
8049
8102
|
this._selected = new rxjs.Subject();
|
|
8050
8103
|
this._upvoted = new rxjs.Subject();
|
|
8051
8104
|
this._userSelected = new rxjs.Subject();
|
|
8105
|
+
this.isNew = false;
|
|
8106
|
+
this.visible = false;
|
|
8052
8107
|
this.showReplyAction = true;
|
|
8053
8108
|
}
|
|
8109
|
+
CommentComponent.prototype.ngOnInit = function () {
|
|
8110
|
+
var _this = this;
|
|
8111
|
+
var maxTime = 500;
|
|
8112
|
+
var minTime = 0;
|
|
8113
|
+
var randomTime = minTime + Math.random() * (maxTime - minTime);
|
|
8114
|
+
setTimeout(function () {
|
|
8115
|
+
_this.isNew = true;
|
|
8116
|
+
_this.visible = true;
|
|
8117
|
+
setTimeout(function () { return _this.isNew = false; }, 1000);
|
|
8118
|
+
}, randomTime);
|
|
8119
|
+
};
|
|
8054
8120
|
Object.defineProperty(CommentComponent.prototype, "userSelected", {
|
|
8055
8121
|
get: function () {
|
|
8056
8122
|
return this._userSelected;
|
|
@@ -8079,6 +8145,14 @@
|
|
|
8079
8145
|
enumerable: false,
|
|
8080
8146
|
configurable: true
|
|
8081
8147
|
});
|
|
8148
|
+
Object.defineProperty(CommentComponent.prototype, "commentId", {
|
|
8149
|
+
get: function () {
|
|
8150
|
+
var _a;
|
|
8151
|
+
return (_a = this.message) === null || _a === void 0 ? void 0 : _a.id;
|
|
8152
|
+
},
|
|
8153
|
+
enumerable: false,
|
|
8154
|
+
configurable: true
|
|
8155
|
+
});
|
|
8082
8156
|
CommentComponent.prototype.report = function () {
|
|
8083
8157
|
this._reported.next();
|
|
8084
8158
|
};
|
|
@@ -8103,17 +8177,20 @@
|
|
|
8103
8177
|
CommentComponent.decorators = [
|
|
8104
8178
|
{ type: core.Component, args: [{
|
|
8105
8179
|
selector: 'banta-comment',
|
|
8106
|
-
template: "\r\n<mat-menu #pointItemMenu=\"matMenu\">\r\n <button mat-menu-item (click)=\"report()\">Report</button>\r\n <button mat-menu-item>Help</button>\r\n</mat-menu>\r\n\r\n<div class=\"message-content\">\r\n <div class=\"user\">\r\n <
|
|
8107
|
-
styles: [":host{display:flex;flex-direction:column;padding:.5em;position:relative}:host:hover{background:#eee}:host .message-content .content{margin-left:4em;margin-right:3em}:host.abbreviated .message-content .content{max-height:8.5em;overflow-y:hidden;text-overflow:ellipsis}:host .actions{align-items:center;display:flex;margin-left:4em;padding-right:10px}:host .actions button{color:#666}:host .actions banta-timestamp{color:#666;font-size:10pt}.user{align-items:center;display:flex;margin:1em 0 0;position:relative}.user
|
|
8180
|
+
template: "\r\n<mat-menu #pointItemMenu=\"matMenu\">\r\n <button mat-menu-item (click)=\"report()\">Report</button>\r\n <button mat-menu-item>Help</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)=\"selectUser()\"\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)=\"selectUser()\">@{{message.user.username}}</a>\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 class=\"content\">\r\n {{message.message}}\r\n </div>\r\n \r\n <div class=\"actions\">\r\n <banta-timestamp [value]=\"message.sentAt\"></banta-timestamp>\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 || 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\">\r\n <div class=\"count-indicator\"> \r\n {{message.upvotes}}\r\n </div>\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 </div>\r\n </div>\r\n</div>\r\n",
|
|
8181
|
+
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;position:relative;visibility:hidden}:host.new{-webkit-animation-duration:.4s;-webkit-animation-fill-mode:both;-webkit-animation-name:comment-appear;animation-duration:.4s;animation-fill-mode:both;animation-name:comment-appear}:host.new,:host.visible{visibility:visible}:host:hover{background:#eee}:host .message-content .content{margin-left:4em;margin-right:3em}:host.abbreviated .message-content .content{max-height:8.5em;overflow-y:hidden;text-overflow:ellipsis}:host .actions{align-items:center;display:flex;margin-left:4em;padding-right:10px}:host .actions button{color:#666}:host .actions banta-timestamp{color:#666;font-size:10pt}.user{align-items:center;display:flex;margin:1em 0 0;position:relative}.user .display-name,.user .username{color:#000;display:block;flex-grow:0;flex-shrink:1;font-size:10pt;margin:0 auto 0 0;max-width:100%;overflow:hidden;padding:0 0 0 1em;position:relative;text-overflow:ellipsis;white-space:nowrap;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;z-index:1}.user .display-name.username,.user .username.username{color:#666;flex-grow:1;flex-shrink:0}.avatar{background-color:#333;background-position:50%;background-size:cover;border-radius:100%;flex-grow:0;flex-shrink:0;height:3em;width:3em}.counted-action{align-items:center;display:flex}.count-indicator{border:1px solid #ccc;border-radius:3px;color:#666;font-size:9pt;padding:0 3px}: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}"]
|
|
8108
8182
|
},] }
|
|
8109
8183
|
];
|
|
8110
8184
|
CommentComponent.propDecorators = {
|
|
8185
|
+
isNew: [{ type: core.HostBinding, args: ['class.new',] }],
|
|
8186
|
+
visible: [{ type: core.HostBinding, args: ['class.visible',] }],
|
|
8111
8187
|
message: [{ type: core.Input }],
|
|
8112
8188
|
showReplyAction: [{ type: core.Input }],
|
|
8113
8189
|
userSelected: [{ type: core.Output }],
|
|
8114
8190
|
reported: [{ type: core.Output }],
|
|
8115
8191
|
upvoted: [{ type: core.Output }],
|
|
8116
|
-
selected: [{ type: core.Output }]
|
|
8192
|
+
selected: [{ type: core.Output }],
|
|
8193
|
+
commentId: [{ type: core.HostBinding, args: ['attr.data-comment-id',] }]
|
|
8117
8194
|
};
|
|
8118
8195
|
|
|
8119
8196
|
var CommentViewComponent = /** @class */ (function () {
|
|
@@ -8210,7 +8287,7 @@
|
|
|
8210
8287
|
CommentViewComponent.prototype.selectMessageUser = function (message) {
|
|
8211
8288
|
this._userSelected.next(message);
|
|
8212
8289
|
};
|
|
8213
|
-
CommentViewComponent.prototype.messageIdentity = function (chatMessage) {
|
|
8290
|
+
CommentViewComponent.prototype.messageIdentity = function (index, chatMessage) {
|
|
8214
8291
|
return chatMessage.id;
|
|
8215
8292
|
};
|
|
8216
8293
|
CommentViewComponent.prototype.showNew = function () {
|
|
@@ -8321,8 +8398,8 @@
|
|
|
8321
8398
|
CommentViewComponent.decorators = [
|
|
8322
8399
|
{ type: core.Component, args: [{
|
|
8323
8400
|
selector: 'banta-comment-view',
|
|
8324
|
-
template: "<div class=\"message-container\">\r\n <ng-content select=\"[data-before]\"></ng-content>\r\n \r\n <a mat-button class=\"nav\"
|
|
8325
|
-
styles: [":host{display:flex;flex-direction:column;flex-grow:1;opacity:1;transition:opacity .2s ease-in}.message-container{background:#fff;color:#
|
|
8401
|
+
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 Show \r\n <ng-container *ngIf=\"newMessages.length === 1\">\r\n {{newMessages.length}} new message\r\n </ng-container>\r\n <ng-container *ngIf=\"newMessages.length > 1\">\r\n {{newMessages.length}} new messages\r\n </ng-container>\r\n <ng-container *ngIf=\"newMessages.length === 0\">\r\n new messages\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 <banta-comment \r\n *ngFor=\"let message of messages; trackBy: messageIdentity\"\r\n class=\"abbreviated\"\r\n [message]=\"message\"\r\n (click)=\"isViewingMore = true\"\r\n [showReplyAction]=\"allowReplies\"\r\n (userSelected)=\"selectMessageUser(message)\"\r\n (upvoted)=\"upvoteMessage(message)\"\r\n (reported)=\"reportMessage(message)\"\r\n (selected)=\"selectMessage(message)\"\r\n ></banta-comment>\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>",
|
|
8402
|
+
styles: [":host{display:flex;flex-direction:column;flex-grow:1;opacity:1;transition:opacity .2s ease-in}.message-container{background:#fff;color:#111;flex-grow:1;opacity:1;overflow-x:hidden;padding:.5em 1em .5em .5em;position:relative;transition:opacity .5s ease-in-out}.message-container.no-scroll{height:auto;overflow-y:visible}.message-container.faded{opacity:.25}.message-container .overlay{bottom:0;left:0;position:absolute;right:0;top:0;z-index:10}:host.fixed-height .message-container{overflow-y:auto}:host-context(.mat-dark-theme) .message-container{background:#111;color:#fff}.empty-state{color:#666;margin:3em;text-align:center}:host-context(.mat-dark-theme) .empty-state{color:#666}a.nav{opacity:0;pointer-events:none;text-align:center;text-transform:uppercase;transition:opacity .4s ease-in-out;width:100%}a.nav.visible{opacity:1;pointer-events:auto}.loading-more{margin:0 auto;padding:2em;text-align:center;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}"]
|
|
8326
8403
|
},] }
|
|
8327
8404
|
];
|
|
8328
8405
|
CommentViewComponent.ctorParameters = function () { return [
|
|
@@ -8348,19 +8425,34 @@
|
|
|
8348
8425
|
* Comments component
|
|
8349
8426
|
*/
|
|
8350
8427
|
var BantaCommentsComponent = /** @class */ (function () {
|
|
8351
|
-
function BantaCommentsComponent(banta, backend) {
|
|
8428
|
+
function BantaCommentsComponent(banta, backend, elementRef) {
|
|
8352
8429
|
this.banta = banta;
|
|
8353
8430
|
this.backend = backend;
|
|
8431
|
+
this.elementRef = elementRef;
|
|
8354
8432
|
this._upvoted = new rxjs.Subject();
|
|
8355
8433
|
this._reported = new rxjs.Subject();
|
|
8356
8434
|
this._selected = new rxjs.Subject();
|
|
8357
8435
|
this._userSelected = new rxjs.Subject();
|
|
8358
8436
|
this._subs = new subsink.SubSink();
|
|
8437
|
+
this.hashtags = [
|
|
8438
|
+
{ hashtag: 'error', description: 'Cause an error' },
|
|
8439
|
+
{ hashtag: 'timeout', description: 'Cause a slow timeout error' },
|
|
8440
|
+
{ hashtag: 'slow', description: 'Be slow when this message is posted' },
|
|
8441
|
+
];
|
|
8442
|
+
this.participants = [];
|
|
8359
8443
|
this.signInLabel = 'Sign In';
|
|
8360
8444
|
this.sendLabel = 'Send';
|
|
8445
|
+
this.replyLabel = 'Reply';
|
|
8446
|
+
this.sendingLabel = 'Sending';
|
|
8361
8447
|
this.permissionDeniedLabel = 'Send';
|
|
8448
|
+
this.postCommentLabel = 'Post a comment';
|
|
8449
|
+
this.postReplyLabel = 'Post a reply';
|
|
8362
8450
|
this._signInSelected = new rxjs.Subject();
|
|
8363
8451
|
this._permissionDeniedError = new rxjs.Subject();
|
|
8452
|
+
this._editAvatarSelected = new rxjs.Subject();
|
|
8453
|
+
this.sending = false;
|
|
8454
|
+
this.expandError = false;
|
|
8455
|
+
this.selectedMessageVisible = false;
|
|
8364
8456
|
}
|
|
8365
8457
|
BantaCommentsComponent.prototype.ngOnInit = function () {
|
|
8366
8458
|
var _this = this;
|
|
@@ -8392,6 +8484,7 @@
|
|
|
8392
8484
|
BantaCommentsComponent.prototype.setSourceFromTopicID = function (topicID) {
|
|
8393
8485
|
return __awaiter(this, void 0, void 0, function () {
|
|
8394
8486
|
var _b;
|
|
8487
|
+
var _this = this;
|
|
8395
8488
|
return __generator(this, function (_c) {
|
|
8396
8489
|
switch (_c.label) {
|
|
8397
8490
|
case 0:
|
|
@@ -8402,14 +8495,41 @@
|
|
|
8402
8495
|
return [4 /*yield*/, this.backend.getSourceForTopic(topicID)];
|
|
8403
8496
|
case 1:
|
|
8404
8497
|
_b._source = _c.sent();
|
|
8498
|
+
this._source.messageReceived.subscribe(function (m) { return _this.addParticipant(m); });
|
|
8499
|
+
this._source.messageSent.subscribe(function (m) { return _this.addParticipant(m); });
|
|
8500
|
+
this._source.messages.forEach(function (m) { return _this.addParticipant(m); });
|
|
8405
8501
|
return [2 /*return*/];
|
|
8406
8502
|
}
|
|
8407
8503
|
});
|
|
8408
8504
|
});
|
|
8409
8505
|
};
|
|
8506
|
+
BantaCommentsComponent.prototype.addParticipant = function (message) {
|
|
8507
|
+
if (!message || !message.user || !message.user.id)
|
|
8508
|
+
return;
|
|
8509
|
+
var existing = this.participants.find(function (x) { return x.id === message.user.id; });
|
|
8510
|
+
if (existing)
|
|
8511
|
+
return;
|
|
8512
|
+
this.participants.push(message.user);
|
|
8513
|
+
};
|
|
8410
8514
|
BantaCommentsComponent.prototype.showSignIn = function () {
|
|
8411
8515
|
this._signInSelected.next();
|
|
8412
8516
|
};
|
|
8517
|
+
BantaCommentsComponent.prototype.showEditAvatar = function () {
|
|
8518
|
+
this._editAvatarSelected.next();
|
|
8519
|
+
};
|
|
8520
|
+
Object.defineProperty(BantaCommentsComponent.prototype, "newMessageText", {
|
|
8521
|
+
get: function () {
|
|
8522
|
+
return this._newMessageText;
|
|
8523
|
+
},
|
|
8524
|
+
set: function (value) {
|
|
8525
|
+
var _this = this;
|
|
8526
|
+
this._newMessageText = value;
|
|
8527
|
+
if (this._newMessageText === '' && this.sendError)
|
|
8528
|
+
setTimeout(function () { return _this.sendError = null; });
|
|
8529
|
+
},
|
|
8530
|
+
enumerable: false,
|
|
8531
|
+
configurable: true
|
|
8532
|
+
});
|
|
8413
8533
|
Object.defineProperty(BantaCommentsComponent.prototype, "signInSelected", {
|
|
8414
8534
|
get: function () {
|
|
8415
8535
|
return this._signInSelected;
|
|
@@ -8417,6 +8537,13 @@
|
|
|
8417
8537
|
enumerable: false,
|
|
8418
8538
|
configurable: true
|
|
8419
8539
|
});
|
|
8540
|
+
Object.defineProperty(BantaCommentsComponent.prototype, "editAvatarSelected", {
|
|
8541
|
+
get: function () {
|
|
8542
|
+
return this._editAvatarSelected;
|
|
8543
|
+
},
|
|
8544
|
+
enumerable: false,
|
|
8545
|
+
configurable: true
|
|
8546
|
+
});
|
|
8420
8547
|
Object.defineProperty(BantaCommentsComponent.prototype, "permissionDeniedError", {
|
|
8421
8548
|
get: function () {
|
|
8422
8549
|
return this._permissionDeniedError;
|
|
@@ -8430,8 +8557,12 @@
|
|
|
8430
8557
|
Object.defineProperty(BantaCommentsComponent.prototype, "canComment", {
|
|
8431
8558
|
get: function () {
|
|
8432
8559
|
var _a;
|
|
8560
|
+
if (!this.user)
|
|
8561
|
+
return false;
|
|
8433
8562
|
if (!this.user.permissions)
|
|
8434
8563
|
return true;
|
|
8564
|
+
if (!this.user.permissions.canComment)
|
|
8565
|
+
return true;
|
|
8435
8566
|
return (_a = this.user.permissions) === null || _a === void 0 ? void 0 : _a.canComment(this.source);
|
|
8436
8567
|
},
|
|
8437
8568
|
enumerable: false,
|
|
@@ -8475,6 +8606,16 @@
|
|
|
8475
8606
|
BantaCommentsComponent.prototype.insertReplyEmoji = function (text) {
|
|
8476
8607
|
this.replyMessage += text;
|
|
8477
8608
|
};
|
|
8609
|
+
BantaCommentsComponent.prototype.indicateError = function (message) {
|
|
8610
|
+
var _this = this;
|
|
8611
|
+
this.sendError = new Error(message);
|
|
8612
|
+
setTimeout(function () {
|
|
8613
|
+
_this.expandError = true;
|
|
8614
|
+
setTimeout(function () {
|
|
8615
|
+
_this.expandError = false;
|
|
8616
|
+
}, 5 * 1000);
|
|
8617
|
+
});
|
|
8618
|
+
};
|
|
8478
8619
|
BantaCommentsComponent.prototype.sendMessage = function () {
|
|
8479
8620
|
return __awaiter(this, void 0, void 0, function () {
|
|
8480
8621
|
var text, message, e_1;
|
|
@@ -8483,8 +8624,12 @@
|
|
|
8483
8624
|
case 0:
|
|
8484
8625
|
if (!this.source)
|
|
8485
8626
|
return [2 /*return*/];
|
|
8627
|
+
this.sending = true;
|
|
8628
|
+
this.sendError = null;
|
|
8629
|
+
_b.label = 1;
|
|
8630
|
+
case 1:
|
|
8631
|
+
_b.trys.push([1, , 6, 7]);
|
|
8486
8632
|
text = (this.newMessageText || '').trim();
|
|
8487
|
-
this.newMessageText = '';
|
|
8488
8633
|
if (text === '')
|
|
8489
8634
|
return [2 /*return*/];
|
|
8490
8635
|
message = {
|
|
@@ -8493,32 +8638,52 @@
|
|
|
8493
8638
|
upvotes: 0,
|
|
8494
8639
|
message: text
|
|
8495
8640
|
};
|
|
8496
|
-
_b.label =
|
|
8497
|
-
case 1:
|
|
8498
|
-
_b.trys.push([1, 3, , 4]);
|
|
8499
|
-
return [4 /*yield*/, this.source.send(message)];
|
|
8641
|
+
_b.label = 2;
|
|
8500
8642
|
case 2:
|
|
8501
|
-
_b.
|
|
8502
|
-
return [
|
|
8643
|
+
_b.trys.push([2, 4, , 5]);
|
|
8644
|
+
return [4 /*yield*/, this.source.send(message)];
|
|
8503
8645
|
case 3:
|
|
8646
|
+
_b.sent();
|
|
8647
|
+
this.newMessageText = '';
|
|
8648
|
+
return [3 /*break*/, 5];
|
|
8649
|
+
case 4:
|
|
8504
8650
|
e_1 = _b.sent();
|
|
8651
|
+
this.indicateError("Could not send: " + e_1.message);
|
|
8505
8652
|
console.error("Failed to send message: ", message);
|
|
8506
8653
|
console.error(e_1);
|
|
8507
|
-
return [3 /*break*/,
|
|
8508
|
-
case
|
|
8654
|
+
return [3 /*break*/, 5];
|
|
8655
|
+
case 5: return [3 /*break*/, 7];
|
|
8656
|
+
case 6:
|
|
8657
|
+
this.sending = false;
|
|
8658
|
+
return [7 /*endfinally*/];
|
|
8659
|
+
case 7: return [2 /*return*/];
|
|
8509
8660
|
}
|
|
8510
8661
|
});
|
|
8511
8662
|
});
|
|
8512
8663
|
};
|
|
8513
8664
|
BantaCommentsComponent.prototype.upvoteMessage = function (message) {
|
|
8514
|
-
this
|
|
8665
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
8666
|
+
return __generator(this, function (_b) {
|
|
8667
|
+
switch (_b.label) {
|
|
8668
|
+
case 0:
|
|
8669
|
+
this._upvoted.next(message);
|
|
8670
|
+
return [4 /*yield*/, this.backend.upvoteMessage(message.topicId, message.parentMessageId ? message.parentMessageId : message.id, message.parentMessageId ? message.id : undefined)];
|
|
8671
|
+
case 1:
|
|
8672
|
+
_b.sent();
|
|
8673
|
+
return [2 /*return*/];
|
|
8674
|
+
}
|
|
8675
|
+
});
|
|
8676
|
+
});
|
|
8515
8677
|
};
|
|
8516
8678
|
BantaCommentsComponent.prototype.reportMessage = function (message) {
|
|
8517
8679
|
this._reported.next(message);
|
|
8518
8680
|
};
|
|
8519
8681
|
BantaCommentsComponent.prototype.unselectMessage = function () {
|
|
8520
8682
|
return __awaiter(this, void 0, void 0, function () {
|
|
8683
|
+
var message;
|
|
8684
|
+
var _this = this;
|
|
8521
8685
|
return __generator(this, function (_b) {
|
|
8686
|
+
message = this.selectedMessage;
|
|
8522
8687
|
this._selected.next(null);
|
|
8523
8688
|
this.selectedMessage = null;
|
|
8524
8689
|
if (this.selectedMessageThread) {
|
|
@@ -8526,24 +8691,33 @@
|
|
|
8526
8691
|
this.selectedMessageThread.close();
|
|
8527
8692
|
this.selectedMessageThread = null;
|
|
8528
8693
|
}
|
|
8694
|
+
if (message)
|
|
8695
|
+
setTimeout(function () { return _this.scrollToMessage(message); });
|
|
8529
8696
|
return [2 /*return*/];
|
|
8530
8697
|
});
|
|
8531
8698
|
});
|
|
8532
8699
|
};
|
|
8533
8700
|
BantaCommentsComponent.prototype.selectMessage = function (message) {
|
|
8534
8701
|
return __awaiter(this, void 0, void 0, function () {
|
|
8535
|
-
var
|
|
8536
|
-
return __generator(this, function (
|
|
8537
|
-
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
8546
|
-
|
|
8702
|
+
var _this = this;
|
|
8703
|
+
return __generator(this, function (_b) {
|
|
8704
|
+
this._selected.next(message);
|
|
8705
|
+
this.selectedMessage = message;
|
|
8706
|
+
setTimeout(function () { return _this.selectedMessageVisible = true; });
|
|
8707
|
+
setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
8708
|
+
var _b;
|
|
8709
|
+
return __generator(this, function (_c) {
|
|
8710
|
+
switch (_c.label) {
|
|
8711
|
+
case 0:
|
|
8712
|
+
_b = this;
|
|
8713
|
+
return [4 /*yield*/, this.backend.getSourceForThread(this.topicID, message.id)];
|
|
8714
|
+
case 1:
|
|
8715
|
+
_b.selectedMessageThread = _c.sent();
|
|
8716
|
+
return [2 /*return*/];
|
|
8717
|
+
}
|
|
8718
|
+
});
|
|
8719
|
+
}); }, 250);
|
|
8720
|
+
return [2 /*return*/];
|
|
8547
8721
|
});
|
|
8548
8722
|
});
|
|
8549
8723
|
};
|
|
@@ -8572,20 +8746,29 @@
|
|
|
8572
8746
|
});
|
|
8573
8747
|
});
|
|
8574
8748
|
};
|
|
8749
|
+
BantaCommentsComponent.prototype.scrollToMessage = function (message) {
|
|
8750
|
+
var el = this.elementRef.nativeElement.querySelector("[data-comment-id=\"" + message.id + "\"]");
|
|
8751
|
+
if (!el)
|
|
8752
|
+
return;
|
|
8753
|
+
el.scrollIntoView({ block: 'center', inline: 'start' });
|
|
8754
|
+
};
|
|
8575
8755
|
return BantaCommentsComponent;
|
|
8576
8756
|
}());
|
|
8577
8757
|
BantaCommentsComponent.decorators = [
|
|
8578
8758
|
{ type: core.Component, args: [{
|
|
8579
8759
|
selector: 'banta-comments',
|
|
8580
|
-
template: "\r\n<div class=\"focused\" *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 ></banta-comment>\r\n\r\n <div class=\"replies\">\r\n
|
|
8581
|
-
styles: [":host{flex-direction:column}
|
|
8760
|
+
template: "\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 ></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 ></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]=\"canComment\"\r\n [signInLabel]=\"signInLabel\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\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]=\"canComment\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [label]=\"postCommentLabel\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (signInSelected)=\"showSignIn()\"\r\n ></banta-comment-field>\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 (selected)=\"selectMessage($event)\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n ></banta-comment-view>\r\n</div>",
|
|
8761
|
+
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-duration:.4s;-webkit-animation-fill-mode:both;-webkit-animation-name:select-comment;animation-duration:.4s;animation-fill-mode:both;animation-name:select-comment}.focused .replies{margin-left:4em;margin-top:1em}banta-comment-view{opacity:1;transition:opacity .4s ease-in-out}banta-comment-view.faded{opacity:.25}.loading{display:block;margin:0 auto;min-height:16em;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.main.hidden{display:none}"]
|
|
8582
8762
|
},] }
|
|
8583
8763
|
];
|
|
8584
8764
|
BantaCommentsComponent.ctorParameters = function () { return [
|
|
8585
8765
|
{ type: BantaService },
|
|
8586
|
-
{ type: ChatBackendService }
|
|
8766
|
+
{ type: ChatBackendService },
|
|
8767
|
+
{ type: core.ElementRef }
|
|
8587
8768
|
]; };
|
|
8588
8769
|
BantaCommentsComponent.propDecorators = {
|
|
8770
|
+
hashtags: [{ type: core.Input }],
|
|
8771
|
+
participants: [{ type: core.Input }],
|
|
8589
8772
|
source: [{ type: core.Input }],
|
|
8590
8773
|
fixedHeight: [{ type: core.Input }],
|
|
8591
8774
|
maxMessages: [{ type: core.Input }],
|
|
@@ -8594,8 +8777,13 @@
|
|
|
8594
8777
|
topicID: [{ type: core.Input }],
|
|
8595
8778
|
signInLabel: [{ type: core.Input }],
|
|
8596
8779
|
sendLabel: [{ type: core.Input }],
|
|
8780
|
+
replyLabel: [{ type: core.Input }],
|
|
8781
|
+
sendingLabel: [{ type: core.Input }],
|
|
8597
8782
|
permissionDeniedLabel: [{ type: core.Input }],
|
|
8783
|
+
postCommentLabel: [{ type: core.Input }],
|
|
8784
|
+
postReplyLabel: [{ type: core.Input }],
|
|
8598
8785
|
signInSelected: [{ type: core.Output }],
|
|
8786
|
+
editAvatarSelected: [{ type: core.Output }],
|
|
8599
8787
|
permissionDeniedError: [{ type: core.Output }],
|
|
8600
8788
|
upvoted: [{ type: core.Output }],
|
|
8601
8789
|
reported: [{ type: core.Output }],
|
|
@@ -8681,11 +8869,277 @@
|
|
|
8681
8869
|
message: [{ type: core.Input }]
|
|
8682
8870
|
};
|
|
8683
8871
|
|
|
8872
|
+
var CommentFieldComponent = /** @class */ (function () {
|
|
8873
|
+
function CommentFieldComponent() {
|
|
8874
|
+
this.canComment = true;
|
|
8875
|
+
this.signInSelected = new rxjs.Subject();
|
|
8876
|
+
this.editAvatarSelected = new rxjs.Subject();
|
|
8877
|
+
this.sending = false;
|
|
8878
|
+
this.expandError = false;
|
|
8879
|
+
this.text = '';
|
|
8880
|
+
this.sendLabel = 'Send';
|
|
8881
|
+
this.sendingLabel = 'Sending';
|
|
8882
|
+
this.label = 'Post a comment';
|
|
8883
|
+
this.permissionDeniedLabel = 'Unavailable';
|
|
8884
|
+
this.signInLabel = 'Sign In';
|
|
8885
|
+
this.participants = [];
|
|
8886
|
+
this.autocompleteVisible = false;
|
|
8887
|
+
this.autocompleteOptions = [];
|
|
8888
|
+
this.autoCompleteSelected = 0;
|
|
8889
|
+
}
|
|
8890
|
+
CommentFieldComponent.prototype.ngAfterViewInit = function () {
|
|
8891
|
+
var root = document.body.querySelector('[ng-version]') || document.body;
|
|
8892
|
+
root.appendChild(this.autocompleteEl.nativeElement);
|
|
8893
|
+
};
|
|
8894
|
+
CommentFieldComponent.prototype.showAutoComplete = function (options) {
|
|
8895
|
+
this.autoCompleteSelected = 0;
|
|
8896
|
+
this.autocompleteOptions = options;
|
|
8897
|
+
var pos = this.autocompleteContainerEl.nativeElement.getBoundingClientRect();
|
|
8898
|
+
var size = this.autocompleteEl.nativeElement.getBoundingClientRect();
|
|
8899
|
+
this.autocompleteEl.nativeElement.style.left = pos.left + "px";
|
|
8900
|
+
this.autocompleteEl.nativeElement.style.top = pos.top + "px";
|
|
8901
|
+
this.autocompleteEl.nativeElement.style.width = pos.width + "px";
|
|
8902
|
+
this.autocompleteVisible = true;
|
|
8903
|
+
};
|
|
8904
|
+
CommentFieldComponent.prototype.activateAutoComplete = function (option) {
|
|
8905
|
+
option.action();
|
|
8906
|
+
this.dismissAutoComplete();
|
|
8907
|
+
};
|
|
8908
|
+
CommentFieldComponent.prototype.dismissAutoComplete = function () {
|
|
8909
|
+
this.autocompleteVisible = false;
|
|
8910
|
+
this.completionFunc = null;
|
|
8911
|
+
this.completionPrefix = '';
|
|
8912
|
+
};
|
|
8913
|
+
CommentFieldComponent.prototype.indicateError = function (message) {
|
|
8914
|
+
var _this = this;
|
|
8915
|
+
this.sendError = new Error(message);
|
|
8916
|
+
setTimeout(function () {
|
|
8917
|
+
_this.expandError = true;
|
|
8918
|
+
setTimeout(function () {
|
|
8919
|
+
_this.expandError = false;
|
|
8920
|
+
}, 5 * 1000);
|
|
8921
|
+
});
|
|
8922
|
+
};
|
|
8923
|
+
CommentFieldComponent.prototype.autocomplete = function (replacement) {
|
|
8924
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
8925
|
+
var el;
|
|
8926
|
+
return __generator(this, function (_a) {
|
|
8927
|
+
el = this.textareaEl.nativeElement;
|
|
8928
|
+
this.text = this.text.slice(0, el.selectionStart - this.completionPrefix.length) + replacement + this.text.slice(el.selectionStart);
|
|
8929
|
+
return [2 /*return*/];
|
|
8930
|
+
});
|
|
8931
|
+
});
|
|
8932
|
+
};
|
|
8933
|
+
CommentFieldComponent.prototype.insert = function (str) {
|
|
8934
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
8935
|
+
var el;
|
|
8936
|
+
return __generator(this, function (_a) {
|
|
8937
|
+
el = this.textareaEl.nativeElement;
|
|
8938
|
+
this.text = this.text.slice(0, el.selectionStart) + str + this.text.slice(el.selectionStart);
|
|
8939
|
+
return [2 /*return*/];
|
|
8940
|
+
});
|
|
8941
|
+
});
|
|
8942
|
+
};
|
|
8943
|
+
CommentFieldComponent.prototype.onKeyDown = function (event) {
|
|
8944
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
8945
|
+
var _this = this;
|
|
8946
|
+
return __generator(this, function (_a) {
|
|
8947
|
+
switch (_a.label) {
|
|
8948
|
+
case 0:
|
|
8949
|
+
console.log(event.key);
|
|
8950
|
+
if (this.autocompleteVisible) {
|
|
8951
|
+
if (event.key === 'Escape') {
|
|
8952
|
+
this.dismissAutoComplete();
|
|
8953
|
+
return [2 /*return*/];
|
|
8954
|
+
}
|
|
8955
|
+
if (event.key === 'Shift') {
|
|
8956
|
+
return [2 /*return*/];
|
|
8957
|
+
}
|
|
8958
|
+
if (event.key === 'Enter') {
|
|
8959
|
+
this.activateAutoComplete(this.autocompleteOptions[this.autoCompleteSelected]);
|
|
8960
|
+
event.stopPropagation();
|
|
8961
|
+
event.preventDefault();
|
|
8962
|
+
return [2 /*return*/];
|
|
8963
|
+
}
|
|
8964
|
+
if (event.key === 'ArrowUp') {
|
|
8965
|
+
if (this.autoCompleteSelected === 0)
|
|
8966
|
+
this.autoCompleteSelected = this.autocompleteOptions.length - 1;
|
|
8967
|
+
else
|
|
8968
|
+
this.autoCompleteSelected = this.autoCompleteSelected - 1;
|
|
8969
|
+
event.stopPropagation();
|
|
8970
|
+
event.preventDefault();
|
|
8971
|
+
return [2 /*return*/];
|
|
8972
|
+
}
|
|
8973
|
+
else if (event.key === 'ArrowDown') {
|
|
8974
|
+
this.autoCompleteSelected = (this.autoCompleteSelected + 1) % this.autocompleteOptions.length;
|
|
8975
|
+
event.stopPropagation();
|
|
8976
|
+
event.preventDefault();
|
|
8977
|
+
return [2 /*return*/];
|
|
8978
|
+
}
|
|
8979
|
+
}
|
|
8980
|
+
if (!(event.key === 'Enter' && event.ctrlKey)) return [3 /*break*/, 2];
|
|
8981
|
+
return [4 /*yield*/, this.sendMessage()];
|
|
8982
|
+
case 1:
|
|
8983
|
+
_a.sent();
|
|
8984
|
+
return [2 /*return*/];
|
|
8985
|
+
case 2:
|
|
8986
|
+
if (this.completionFunc) {
|
|
8987
|
+
if (event.key === 'Backspace') {
|
|
8988
|
+
this.completionPrefix = this.completionPrefix.slice(0, this.completionPrefix.length - 1);
|
|
8989
|
+
if (this.completionPrefix === '') {
|
|
8990
|
+
this.dismissAutoComplete();
|
|
8991
|
+
return [2 /*return*/];
|
|
8992
|
+
}
|
|
8993
|
+
}
|
|
8994
|
+
else if (event.key === ' ' || event.key.length > 1) {
|
|
8995
|
+
this.dismissAutoComplete();
|
|
8996
|
+
return [2 /*return*/];
|
|
8997
|
+
}
|
|
8998
|
+
else {
|
|
8999
|
+
this.completionPrefix += event.key;
|
|
9000
|
+
}
|
|
9001
|
+
this.showAutoComplete(this.completionFunc(this.completionPrefix));
|
|
9002
|
+
}
|
|
9003
|
+
else {
|
|
9004
|
+
if (event.key === ':') {
|
|
9005
|
+
this.startAutoComplete(event, function (prefix) {
|
|
9006
|
+
prefix = prefix.slice(1);
|
|
9007
|
+
// makes :-), :-( etc work (as they are ":)" etc in the db)
|
|
9008
|
+
if (prefix.startsWith('-'))
|
|
9009
|
+
prefix = prefix.slice(1);
|
|
9010
|
+
return Object.keys(EMOJIS)
|
|
9011
|
+
.filter(function (k) { return k.includes(prefix) || EMOJIS[k].keywords.some(function (kw) { return kw.includes(prefix); }); })
|
|
9012
|
+
.map(function (k) { return ({
|
|
9013
|
+
label: EMOJIS[k].char + " " + k,
|
|
9014
|
+
action: function () { return _this.autocomplete(EMOJIS[k].char); }
|
|
9015
|
+
}); })
|
|
9016
|
+
.slice(0, 5);
|
|
9017
|
+
});
|
|
9018
|
+
}
|
|
9019
|
+
else if (event.key === '@') {
|
|
9020
|
+
this.startAutoComplete(event, function (prefix) {
|
|
9021
|
+
prefix = prefix.slice(1);
|
|
9022
|
+
return _this.participants.filter(function (x) { return x.username.includes(prefix); })
|
|
9023
|
+
.map(function (p) { return ({
|
|
9024
|
+
label: "@" + p.username + " -- " + p.displayName,
|
|
9025
|
+
action: function () { return _this.autocomplete("@" + p.username); }
|
|
9026
|
+
}); });
|
|
9027
|
+
});
|
|
9028
|
+
}
|
|
9029
|
+
else if (event.key === '#') {
|
|
9030
|
+
this.startAutoComplete(event, function (prefix) {
|
|
9031
|
+
prefix = prefix.slice(1);
|
|
9032
|
+
return _this.hashtags
|
|
9033
|
+
.filter(function (ht) { return ht.hashtag.includes(prefix); })
|
|
9034
|
+
.map(function (ht) { return ({
|
|
9035
|
+
label: "#" + ht.hashtag + (ht.description ? " -- " + ht.description : ""),
|
|
9036
|
+
action: function () { return _this.autocomplete("#" + ht.hashtag); }
|
|
9037
|
+
}); })
|
|
9038
|
+
.slice(0, 5);
|
|
9039
|
+
});
|
|
9040
|
+
}
|
|
9041
|
+
}
|
|
9042
|
+
return [2 /*return*/];
|
|
9043
|
+
}
|
|
9044
|
+
});
|
|
9045
|
+
});
|
|
9046
|
+
};
|
|
9047
|
+
CommentFieldComponent.prototype.startAutoComplete = function (event, completionFunc) {
|
|
9048
|
+
this.completionPrefix = event.key;
|
|
9049
|
+
this.completionFunc = completionFunc;
|
|
9050
|
+
this.showAutoComplete(this.completionFunc(this.completionPrefix));
|
|
9051
|
+
};
|
|
9052
|
+
CommentFieldComponent.prototype.onBlur = function () {
|
|
9053
|
+
var _this = this;
|
|
9054
|
+
setTimeout(function () { return _this.dismissAutoComplete(); }, 250);
|
|
9055
|
+
};
|
|
9056
|
+
CommentFieldComponent.prototype.insertEmoji = function (text) {
|
|
9057
|
+
this.text += text;
|
|
9058
|
+
};
|
|
9059
|
+
CommentFieldComponent.prototype.showSignIn = function () {
|
|
9060
|
+
this.signInSelected.next();
|
|
9061
|
+
};
|
|
9062
|
+
CommentFieldComponent.prototype.showEditAvatar = function () {
|
|
9063
|
+
this.editAvatarSelected.next();
|
|
9064
|
+
};
|
|
9065
|
+
CommentFieldComponent.prototype.sendMessage = function () {
|
|
9066
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
9067
|
+
var text, message, e_1;
|
|
9068
|
+
return __generator(this, function (_a) {
|
|
9069
|
+
switch (_a.label) {
|
|
9070
|
+
case 0:
|
|
9071
|
+
if (!this.source)
|
|
9072
|
+
return [2 /*return*/];
|
|
9073
|
+
this.sending = true;
|
|
9074
|
+
this.sendError = null;
|
|
9075
|
+
_a.label = 1;
|
|
9076
|
+
case 1:
|
|
9077
|
+
_a.trys.push([1, , 6, 7]);
|
|
9078
|
+
text = (this.text || '').trim();
|
|
9079
|
+
if (text === '')
|
|
9080
|
+
return [2 /*return*/];
|
|
9081
|
+
message = {
|
|
9082
|
+
user: this.user,
|
|
9083
|
+
sentAt: Date.now(),
|
|
9084
|
+
upvotes: 0,
|
|
9085
|
+
message: text
|
|
9086
|
+
};
|
|
9087
|
+
_a.label = 2;
|
|
9088
|
+
case 2:
|
|
9089
|
+
_a.trys.push([2, 4, , 5]);
|
|
9090
|
+
return [4 /*yield*/, this.source.send(message)];
|
|
9091
|
+
case 3:
|
|
9092
|
+
_a.sent();
|
|
9093
|
+
this.text = '';
|
|
9094
|
+
return [3 /*break*/, 5];
|
|
9095
|
+
case 4:
|
|
9096
|
+
e_1 = _a.sent();
|
|
9097
|
+
this.indicateError("Could not send: " + e_1.message);
|
|
9098
|
+
console.error("Failed to send message: ", message);
|
|
9099
|
+
console.error(e_1);
|
|
9100
|
+
return [3 /*break*/, 5];
|
|
9101
|
+
case 5: return [3 /*break*/, 7];
|
|
9102
|
+
case 6:
|
|
9103
|
+
this.sending = false;
|
|
9104
|
+
return [7 /*endfinally*/];
|
|
9105
|
+
case 7: return [2 /*return*/];
|
|
9106
|
+
}
|
|
9107
|
+
});
|
|
9108
|
+
});
|
|
9109
|
+
};
|
|
9110
|
+
return CommentFieldComponent;
|
|
9111
|
+
}());
|
|
9112
|
+
CommentFieldComponent.decorators = [
|
|
9113
|
+
{ type: core.Component, args: [{
|
|
9114
|
+
selector: 'banta-comment-field',
|
|
9115
|
+
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=\"Type your comment\"\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 <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 <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\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",
|
|
9116
|
+
styles: ["@-webkit-keyframes comment-field-appear{0%{opacity:0;transform:translateY(128px)}to{opacity:1;transform:translate(0)}}@keyframes comment-field-appear{0%{opacity:0;transform:translateY(128px)}to{opacity:1;transform:translate(0)}}:host{-webkit-animation-delay:.4s;-webkit-animation-duration:.8s;-webkit-animation-fill-mode:both;-webkit-animation-name:comment-field-appear;animation-delay:.4s;animation-duration:.8s;animation-fill-mode:both;animation-name:comment-field-appear;display:block;margin:0 2em 0 0}.avatar-container{display:flex;justify-content:flex-end;width:calc(48px + 1.75em)}.avatar-container .avatar{background:pink;background-position:50%;background-repeat:no-repeat;background-size:cover;border-radius:100%;height:48px;margin-right:.75em;margin-top:.75em;width:48px}form{align-items:center;display:flex;padding:.5em 0}form .text-container{display:flex;flex-grow:1;position:relative}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;position:absolute;right:0}form .text-container .error-message,form .text-container mat-spinner.loading{bottom:.5em;left:.5em;position:absolute}form .text-container .error-message{color:#683333;max-width:1.5em;overflow-x:hidden;transition:max-width 2s ease-in-out;white-space:nowrap}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;border:1px solid #333;color:#fff;height:1em;width:100%}form .actions{margin-left:1em}form button{display:block;margin:0 0 0 auto}form.new-message{align-items:flex-start;display:flex}form.new-message .field-container{display:flex;flex-direction:column;flex-grow:1}form.new-message mat-form-field{width:100%}form.new-message button{margin:1.25em 0 0 1em}button.send{min-width:9em}textarea{max-height:7em}.autocomplete-container{pointer-events:none;position:relative;top:-2em;width:calc(100% - 2em)}.autocomplete{background:#333;display:flex;flex-direction:column;padding:.5em;pointer-events:none;position:absolute;visibility:hidden;z-index:100}.autocomplete.visible{pointer-events:auto;visibility:visible}.autocomplete a{text-align:left;width:100%}.autocomplete a.active{background:#555}"]
|
|
9117
|
+
},] }
|
|
9118
|
+
];
|
|
9119
|
+
CommentFieldComponent.propDecorators = {
|
|
9120
|
+
source: [{ type: core.Input }],
|
|
9121
|
+
user: [{ type: core.Input }],
|
|
9122
|
+
canComment: [{ type: core.Input }],
|
|
9123
|
+
signInSelected: [{ type: core.Output }],
|
|
9124
|
+
editAvatarSelected: [{ type: core.Output }],
|
|
9125
|
+
sendLabel: [{ type: core.Input }],
|
|
9126
|
+
sendingLabel: [{ type: core.Input }],
|
|
9127
|
+
label: [{ type: core.Input }],
|
|
9128
|
+
permissionDeniedLabel: [{ type: core.Input }],
|
|
9129
|
+
signInLabel: [{ type: core.Input }],
|
|
9130
|
+
autocompleteEl: [{ type: core.ViewChild, args: ['autocomplete',] }],
|
|
9131
|
+
autocompleteContainerEl: [{ type: core.ViewChild, args: ['autocompleteContainer',] }],
|
|
9132
|
+
textareaEl: [{ type: core.ViewChild, args: ['textarea',] }],
|
|
9133
|
+
hashtags: [{ type: core.Input }],
|
|
9134
|
+
participants: [{ type: core.Input }]
|
|
9135
|
+
};
|
|
9136
|
+
|
|
8684
9137
|
var COMPONENTS$3 = [
|
|
8685
9138
|
CommentComponent,
|
|
8686
9139
|
CommentViewComponent,
|
|
8687
9140
|
BantaCommentsComponent,
|
|
8688
|
-
LiveCommentComponent
|
|
9141
|
+
LiveCommentComponent,
|
|
9142
|
+
CommentFieldComponent
|
|
8689
9143
|
];
|
|
8690
9144
|
var CommentsModule = /** @class */ (function () {
|
|
8691
9145
|
function CommentsModule() {
|
|
@@ -8778,6 +9232,7 @@
|
|
|
8778
9232
|
exports.ChatModule = ChatModule;
|
|
8779
9233
|
exports.ChatViewComponent = ChatViewComponent;
|
|
8780
9234
|
exports.CommentComponent = CommentComponent;
|
|
9235
|
+
exports.CommentFieldComponent = CommentFieldComponent;
|
|
8781
9236
|
exports.CommentViewComponent = CommentViewComponent;
|
|
8782
9237
|
exports.CommentsModule = CommentsModule;
|
|
8783
9238
|
exports.EMOJIS = EMOJIS;
|