@bloonio/chat-angular 0.1.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/README.md +112 -0
- package/esm2022/bloonio-chat-angular.mjs +5 -0
- package/esm2022/index.mjs +25 -0
- package/esm2022/lib/bloonio-chat.service.mjs +311 -0
- package/esm2022/lib/bloonio-chat.token.mjs +46 -0
- package/esm2022/lib/components/input-bar.component.mjs +91 -0
- package/esm2022/lib/components/launcher.component.mjs +81 -0
- package/esm2022/lib/components/message-list.component.mjs +58 -0
- package/esm2022/lib/components/panel.component.mjs +211 -0
- package/esm2022/lib/components/quick-replies.component.mjs +58 -0
- package/esm2022/lib/components/thread.component.mjs +103 -0
- package/fesm2022/bloonio-chat-angular.mjs +958 -0
- package/fesm2022/bloonio-chat-angular.mjs.map +1 -0
- package/index.d.ts +27 -0
- package/lib/bloonio-chat.service.d.ts +79 -0
- package/lib/bloonio-chat.token.d.ts +67 -0
- package/lib/components/input-bar.component.d.ts +18 -0
- package/lib/components/launcher.component.d.ts +14 -0
- package/lib/components/message-list.component.d.ts +8 -0
- package/lib/components/panel.component.d.ts +31 -0
- package/lib/components/quick-replies.component.d.ts +10 -0
- package/lib/components/thread.component.d.ts +27 -0
- package/package.json +38 -0
- package/src/lib/styles/chat.css +268 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<bloonio-chat-thread>` — headless variant of the panel. Renders just
|
|
3
|
+
* the message log + input, no header, no floating chrome. Used when the
|
|
4
|
+
* tenant wants to embed the chat *inside* their own layout (e.g. inside
|
|
5
|
+
* a support modal, a sidebar, a help center page).
|
|
6
|
+
*
|
|
7
|
+
* Theming and behaviour are otherwise identical — the same
|
|
8
|
+
* `BloonioChatService` drives state, so a thread and a panel side-by-side
|
|
9
|
+
* stay in sync.
|
|
10
|
+
*/
|
|
11
|
+
import { ChangeDetectionStrategy, Component, computed, inject, ViewChild, signal, } from '@angular/core';
|
|
12
|
+
import { BloonioChatService } from '../bloonio-chat.service';
|
|
13
|
+
import { InputBarComponent } from './input-bar.component';
|
|
14
|
+
import { MessageListComponent } from './message-list.component';
|
|
15
|
+
import { QuickRepliesComponent } from './quick-replies.component';
|
|
16
|
+
import * as i0 from "@angular/core";
|
|
17
|
+
export class BloonioChatThreadComponent {
|
|
18
|
+
chat = inject(BloonioChatService);
|
|
19
|
+
messagesRef;
|
|
20
|
+
lastScrollLen = signal(-1);
|
|
21
|
+
themeStyle = computed(() => {
|
|
22
|
+
const color = this.chat.bootstrap()?.branding_primary_color;
|
|
23
|
+
return color ? `--bch-primary: ${color}` : '';
|
|
24
|
+
});
|
|
25
|
+
visibleMessages = computed(() => {
|
|
26
|
+
const b = this.chat.bootstrap();
|
|
27
|
+
const messages = this.chat.messages();
|
|
28
|
+
if (b && !b.is_online && messages.length === 0) {
|
|
29
|
+
return [
|
|
30
|
+
{
|
|
31
|
+
id: 'sys_offline',
|
|
32
|
+
from: 'system',
|
|
33
|
+
content: b.offline_message,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
return messages;
|
|
38
|
+
});
|
|
39
|
+
ngAfterViewChecked() {
|
|
40
|
+
const el = this.messagesRef?.nativeElement;
|
|
41
|
+
if (!el)
|
|
42
|
+
return;
|
|
43
|
+
const len = this.visibleMessages().length + (this.chat.botTyping() ? 1 : 0);
|
|
44
|
+
if (len !== this.lastScrollLen()) {
|
|
45
|
+
el.scrollTop = el.scrollHeight;
|
|
46
|
+
this.lastScrollLen.set(len);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Convenience: thread is meant to be always-on, so it opens the
|
|
50
|
+
* service-level session as soon as it's instantiated.
|
|
51
|
+
* (Floating panel waits for the launcher click.) */
|
|
52
|
+
constructor() {
|
|
53
|
+
void this.chat.openPanel();
|
|
54
|
+
}
|
|
55
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BloonioChatThreadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
56
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: BloonioChatThreadComponent, isStandalone: true, selector: "bloonio-chat-thread", viewQueries: [{ propertyName: "messagesRef", first: true, predicate: ["messages"], descendants: true }], ngImport: i0, template: `
|
|
57
|
+
<div class="bch-root" data-mode="inline" [style]="themeStyle()">
|
|
58
|
+
<div class="bch-panel">
|
|
59
|
+
<div class="bch-messages" #messages>
|
|
60
|
+
<bloonio-chat-message-list
|
|
61
|
+
[messages]="visibleMessages()"
|
|
62
|
+
[botTyping]="chat.botTyping()"
|
|
63
|
+
/>
|
|
64
|
+
</div>
|
|
65
|
+
<bloonio-chat-quick-replies />
|
|
66
|
+
<bloonio-chat-input-bar
|
|
67
|
+
[disabled]="chat.connecting()"
|
|
68
|
+
(send)="chat.sendMessage($event)"
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
`, isInline: true, dependencies: [{ kind: "component", type: InputBarComponent, selector: "bloonio-chat-input-bar", inputs: ["disabled"], outputs: ["send"] }, { kind: "component", type: MessageListComponent, selector: "bloonio-chat-message-list", inputs: ["messages", "botTyping"] }, { kind: "component", type: QuickRepliesComponent, selector: "bloonio-chat-quick-replies" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
73
|
+
}
|
|
74
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BloonioChatThreadComponent, decorators: [{
|
|
75
|
+
type: Component,
|
|
76
|
+
args: [{
|
|
77
|
+
selector: 'bloonio-chat-thread',
|
|
78
|
+
standalone: true,
|
|
79
|
+
imports: [InputBarComponent, MessageListComponent, QuickRepliesComponent],
|
|
80
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
81
|
+
template: `
|
|
82
|
+
<div class="bch-root" data-mode="inline" [style]="themeStyle()">
|
|
83
|
+
<div class="bch-panel">
|
|
84
|
+
<div class="bch-messages" #messages>
|
|
85
|
+
<bloonio-chat-message-list
|
|
86
|
+
[messages]="visibleMessages()"
|
|
87
|
+
[botTyping]="chat.botTyping()"
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
<bloonio-chat-quick-replies />
|
|
91
|
+
<bloonio-chat-input-bar
|
|
92
|
+
[disabled]="chat.connecting()"
|
|
93
|
+
(send)="chat.sendMessage($event)"
|
|
94
|
+
/>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
`,
|
|
98
|
+
}]
|
|
99
|
+
}], ctorParameters: () => [], propDecorators: { messagesRef: [{
|
|
100
|
+
type: ViewChild,
|
|
101
|
+
args: ['messages']
|
|
102
|
+
}] } });
|
|
103
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhyZWFkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy90aHJlYWQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7R0FTRztBQUNILE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFFBQVEsRUFDUixNQUFNLEVBR04sU0FBUyxFQUNULE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7QUF5QmxFLE1BQU0sT0FBTywwQkFBMEI7SUFDbEIsSUFBSSxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBRXRCLFdBQVcsQ0FBOEI7SUFDaEUsYUFBYSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRWhCLFVBQVUsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1FBQzVDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsc0JBQXNCLENBQUM7UUFDNUQsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ2hELENBQUMsQ0FBQyxDQUFDO0lBRWdCLGVBQWUsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1FBQ2pELE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDaEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMvQyxPQUFPO2dCQUNMO29CQUNFLEVBQUUsRUFBRSxhQUFhO29CQUNqQixJQUFJLEVBQUUsUUFBaUI7b0JBQ3ZCLE9BQU8sRUFBRSxDQUFDLENBQUMsZUFBZTtpQkFDM0I7YUFDRixDQUFDO1FBQ0osQ0FBQztRQUNELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUMsQ0FBQyxDQUFDO0lBRUgsa0JBQWtCO1FBQ2hCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsYUFBYSxDQUFDO1FBQzNDLElBQUksQ0FBQyxFQUFFO1lBQUUsT0FBTztRQUNoQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RSxJQUFJLEdBQUcsS0FBSyxJQUFJLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQztZQUNqQyxFQUFFLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUM7WUFDL0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUIsQ0FBQztJQUNILENBQUM7SUFFRDs7eURBRXFEO0lBQ3JEO1FBQ0UsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQzdCLENBQUM7d0dBekNVLDBCQUEwQjs0RkFBMUIsMEJBQTBCLHdMQWxCM0I7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQlQsNERBbEJTLGlCQUFpQiw0R0FBRSxvQkFBb0IseUdBQUUscUJBQXFCOzs0RkFvQjdELDBCQUEwQjtrQkF2QnRDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLHFCQUFxQjtvQkFDL0IsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLE9BQU8sRUFBRSxDQUFDLGlCQUFpQixFQUFFLG9CQUFvQixFQUFFLHFCQUFxQixDQUFDO29CQUN6RSxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtvQkFDL0MsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JUO2lCQUNGO3dEQUlnQyxXQUFXO3NCQUF6QyxTQUFTO3VCQUFDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGA8Ymxvb25pby1jaGF0LXRocmVhZD5gIOKAlCBoZWFkbGVzcyB2YXJpYW50IG9mIHRoZSBwYW5lbC4gUmVuZGVycyBqdXN0XG4gKiB0aGUgbWVzc2FnZSBsb2cgKyBpbnB1dCwgbm8gaGVhZGVyLCBubyBmbG9hdGluZyBjaHJvbWUuIFVzZWQgd2hlbiB0aGVcbiAqIHRlbmFudCB3YW50cyB0byBlbWJlZCB0aGUgY2hhdCAqaW5zaWRlKiB0aGVpciBvd24gbGF5b3V0IChlLmcuIGluc2lkZVxuICogYSBzdXBwb3J0IG1vZGFsLCBhIHNpZGViYXIsIGEgaGVscCBjZW50ZXIgcGFnZSkuXG4gKlxuICogVGhlbWluZyBhbmQgYmVoYXZpb3VyIGFyZSBvdGhlcndpc2UgaWRlbnRpY2FsIOKAlCB0aGUgc2FtZVxuICogYEJsb29uaW9DaGF0U2VydmljZWAgZHJpdmVzIHN0YXRlLCBzbyBhIHRocmVhZCBhbmQgYSBwYW5lbCBzaWRlLWJ5LXNpZGVcbiAqIHN0YXkgaW4gc3luYy5cbiAqL1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgY29tcHV0ZWQsXG4gIGluamVjdCxcbiAgQWZ0ZXJWaWV3Q2hlY2tlZCxcbiAgRWxlbWVudFJlZixcbiAgVmlld0NoaWxkLFxuICBzaWduYWwsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBCbG9vbmlvQ2hhdFNlcnZpY2UgfSBmcm9tICcuLi9ibG9vbmlvLWNoYXQuc2VydmljZSc7XG5pbXBvcnQgeyBJbnB1dEJhckNvbXBvbmVudCB9IGZyb20gJy4vaW5wdXQtYmFyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBNZXNzYWdlTGlzdENvbXBvbmVudCB9IGZyb20gJy4vbWVzc2FnZS1saXN0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBRdWlja1JlcGxpZXNDb21wb25lbnQgfSBmcm9tICcuL3F1aWNrLXJlcGxpZXMuY29tcG9uZW50JztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYmxvb25pby1jaGF0LXRocmVhZCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtJbnB1dEJhckNvbXBvbmVudCwgTWVzc2FnZUxpc3RDb21wb25lbnQsIFF1aWNrUmVwbGllc0NvbXBvbmVudF0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJiY2gtcm9vdFwiIGRhdGEtbW9kZT1cImlubGluZVwiIFtzdHlsZV09XCJ0aGVtZVN0eWxlKClcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJiY2gtcGFuZWxcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImJjaC1tZXNzYWdlc1wiICNtZXNzYWdlcz5cbiAgICAgICAgICA8Ymxvb25pby1jaGF0LW1lc3NhZ2UtbGlzdFxuICAgICAgICAgICAgW21lc3NhZ2VzXT1cInZpc2libGVNZXNzYWdlcygpXCJcbiAgICAgICAgICAgIFtib3RUeXBpbmddPVwiY2hhdC5ib3RUeXBpbmcoKVwiXG4gICAgICAgICAgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxibG9vbmlvLWNoYXQtcXVpY2stcmVwbGllcyAvPlxuICAgICAgICA8Ymxvb25pby1jaGF0LWlucHV0LWJhclxuICAgICAgICAgIFtkaXNhYmxlZF09XCJjaGF0LmNvbm5lY3RpbmcoKVwiXG4gICAgICAgICAgKHNlbmQpPVwiY2hhdC5zZW5kTWVzc2FnZSgkZXZlbnQpXCJcbiAgICAgICAgLz5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBCbG9vbmlvQ2hhdFRocmVhZENvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0NoZWNrZWQge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2hhdCA9IGluamVjdChCbG9vbmlvQ2hhdFNlcnZpY2UpO1xuXG4gIEBWaWV3Q2hpbGQoJ21lc3NhZ2VzJykgcHJpdmF0ZSBtZXNzYWdlc1JlZj86IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuICBwcml2YXRlIGxhc3RTY3JvbGxMZW4gPSBzaWduYWwoLTEpO1xuXG4gIHByb3RlY3RlZCByZWFkb25seSB0aGVtZVN0eWxlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGNvbG9yID0gdGhpcy5jaGF0LmJvb3RzdHJhcCgpPy5icmFuZGluZ19wcmltYXJ5X2NvbG9yO1xuICAgIHJldHVybiBjb2xvciA/IGAtLWJjaC1wcmltYXJ5OiAke2NvbG9yfWAgOiAnJztcbiAgfSk7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHZpc2libGVNZXNzYWdlcyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBiID0gdGhpcy5jaGF0LmJvb3RzdHJhcCgpO1xuICAgIGNvbnN0IG1lc3NhZ2VzID0gdGhpcy5jaGF0Lm1lc3NhZ2VzKCk7XG4gICAgaWYgKGIgJiYgIWIuaXNfb25saW5lICYmIG1lc3NhZ2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnc3lzX29mZmxpbmUnLFxuICAgICAgICAgIGZyb206ICdzeXN0ZW0nIGFzIGNvbnN0LFxuICAgICAgICAgIGNvbnRlbnQ6IGIub2ZmbGluZV9tZXNzYWdlLFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICB9XG4gICAgcmV0dXJuIG1lc3NhZ2VzO1xuICB9KTtcblxuICBuZ0FmdGVyVmlld0NoZWNrZWQoKTogdm9pZCB7XG4gICAgY29uc3QgZWwgPSB0aGlzLm1lc3NhZ2VzUmVmPy5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghZWwpIHJldHVybjtcbiAgICBjb25zdCBsZW4gPSB0aGlzLnZpc2libGVNZXNzYWdlcygpLmxlbmd0aCArICh0aGlzLmNoYXQuYm90VHlwaW5nKCkgPyAxIDogMCk7XG4gICAgaWYgKGxlbiAhPT0gdGhpcy5sYXN0U2Nyb2xsTGVuKCkpIHtcbiAgICAgIGVsLnNjcm9sbFRvcCA9IGVsLnNjcm9sbEhlaWdodDtcbiAgICAgIHRoaXMubGFzdFNjcm9sbExlbi5zZXQobGVuKTtcbiAgICB9XG4gIH1cblxuICAvKiogQ29udmVuaWVuY2U6IHRocmVhZCBpcyBtZWFudCB0byBiZSBhbHdheXMtb24sIHNvIGl0IG9wZW5zIHRoZVxuICAgKiAgc2VydmljZS1sZXZlbCBzZXNzaW9uIGFzIHNvb24gYXMgaXQncyBpbnN0YW50aWF0ZWQuXG4gICAqICAoRmxvYXRpbmcgcGFuZWwgd2FpdHMgZm9yIHRoZSBsYXVuY2hlciBjbGljay4pICovXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHZvaWQgdGhpcy5jaGF0Lm9wZW5QYW5lbCgpO1xuICB9XG59XG4iXX0=
|