ai-bot-snippet
Version:
A package for fast AI Chat for your website
324 lines (319 loc) • 20.8 kB
JavaScript
import * as i0 from '@angular/core';
import { Component, ViewChild, Input, NgModule } from '@angular/core';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i2 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import gsap from 'gsap';
import axios from 'axios';
import Cookies from 'js-cookie';
/**
* @input {string} backgroundColor - Background color of the chat window.
* @input {string} inputColor - Color of the text in the input field.
* @input {string} botMassageColor - Color of the bot's messages.
* @input {string} userMassageColor - Color of the user's messages.
* @input {string} sendColor - Color of the send button (button to send a message).
* @input {string} scrollbarColor - Color of the scrollbar.
* @input {string} scrollbarTrackColor - Color of the scrollbar track.
* @input {string} aiUrl - URL endpoint for the AI service to handle chat requests.
* @input {string} left - The left position of the chat window on the screen.
* @input {string} bottom - The bottom position of the chat window on the screen.
* @input {string} top - The top position of the chat window on the screen.
* @input {string} right - The right position of the chat window on the screen.
* @input {string} width - Width of the chat window.
* @input {string} height - Height of the chat window.
* @input {string} borderRadius - The border radius of the chat window for rounded corners.
* @input {string} boxShadow - The box shadow applied to the chat window for a 3D effect.
* @input {string} placeholder - Just placeholder for chat input.
* @input {boolean} show - Determines whether the chat window is shown (true) or hidden (false).
* @input {string} btnBackgroundImage - Background image of the button that opens the chat window.
* @input {string} btnBackgroundSize - The size of the background image on the open button.
* @input {string} btnLeft - The left position of the button that opens the chat window.
* @input {string} btnBottom - The bottom position of the button that opens the chat window.
* @input {string} btnTop - The top position of the button that opens the chat window.
* @input {string} btnRight - The right position of the button that opens the chat window.
* @input {string} btnWidth - The width of the button that opens the chat window.
* @input {string} btnHeight - The height of the button that opens the chat window.
* @input {string} btnBorderRadius - The border radius of the button that opens the chat window for rounded corners.
* @input {string} btnBoxShadow - The box shadow applied to the button that opens the chat window.
* @input {string} btnText - The text displayed on the button that opens the chat window.
*/
class ChatBotComponent {
chatContainer;
backgroundColor = '#333';
inputColor = 'white';
botMassageColor = 'blue';
userMassageColor = 'green';
sendColor = 'green';
scrollbarColor = 'gray';
scrollbarTrackColor = '#333';
aiUrl = 'http://localhost:5555';
left = '10px';
bottom = '';
top = '';
right = '';
width = '300px';
height = '400px';
borderRadius = '10px';
boxShadow = '0px 4px 10px rgba(0, 0, 0, 0.2)';
placeholder = 'Write message...';
show = false;
btnBackgroundImage = '';
btnBackgroundSize = '';
btnLeft = '';
btnBottom = '10px';
btnTop = '';
btnRight = '10px';
btnWidth = '70px';
btnHeight = '70px';
btnBorderRadius = '999px';
startMessage = "Hi, I'm your personal assistant, how can I help you?";
btnBoxShadow = '0px 4px 10px rgba(0, 0, 0, 0.2)';
btnText = 'Open Chat';
errorCon = '';
webSiteUrl = 'https://www.quellwerke.de/';
messages = [];
inputText = '';
error = '';
loading = false;
isClosing = false;
isClearing = false;
showBlock = true;
constructor() { }
get widthInPixels() {
const numericWidth = parseInt(this.width, 10);
return numericWidth / 1.5;
}
toggleChat() {
if (this.show) {
this.animateClose();
}
else {
this.animateOpen();
}
}
ngAfterViewInit() {
if (this.startMessage.trim() === '') {
this.startMessage =
"Hi, I'm your personal assistant, how can I help you?";
}
if (this.show === false) {
this.showBlock = false;
}
else {
if (this.show) {
this.animateOpen();
}
else {
this.animateClose();
}
}
setTimeout(() => {
this.loadMessages();
this.show = true;
this.showBlock = true;
});
}
startAnimation() {
const chatBotElement = document.getElementById('chatBot');
if (chatBotElement) {
gsap.to(chatBotElement, {
scale: 0,
duration: 0.001,
onComplete: () => {
this.show = false;
},
});
}
}
ngOnDestroy() {
this.animateClose();
}
loadMessages() {
const savedMessages = Cookies.get('chatMessages');
this.messages = savedMessages
? JSON.parse(savedMessages)
: [
{
sender: 'bot',
text: this.startMessage,
},
];
}
saveMessages() {
Cookies.set('chatMessages', JSON.stringify(this.messages), { expires: 7 });
}
animateOpen() {
if (this.chatContainer) {
const chatBotElement = this.chatContainer.nativeElement;
gsap.to(chatBotElement, {
opacity: 1,
scale: 1,
y: 0,
duration: 0.6,
onComplete: () => {
this.show = true;
},
});
}
}
animateClose() {
const chatBotElement = document.getElementById('chatBot');
if (chatBotElement) {
gsap.to(chatBotElement, {
opacity: 0,
scale: 0,
duration: 0.6,
y: -100,
onComplete: () => {
this.show = false;
},
});
}
}
async sendMessage() {
if (this.isClearing || !this.inputText.trim())
return;
this.error = '';
this.messages.push({ sender: 'user', text: this.inputText });
const userInput = this.inputText;
this.inputText = '';
this.loading = true;
try {
const response = await axios.post(this.aiUrl, {
text: userInput,
url: this.webSiteUrl,
});
this.messages.push({ sender: 'bot', text: response.data.reply });
}
catch (error) {
if (axios.isAxiosError(error)) {
if (error.response &&
error.response.data &&
error.response.data.reply) {
this.messages.push({
sender: 'bot',
text: error.response.data.reply,
});
}
else {
this.messages.push({ sender: 'bot', text: 'Error, server problem.' });
this.error = this.errorCon;
}
}
else {
this.messages.push({
sender: 'bot',
text: this.errorCon,
});
this.error = this.errorCon;
}
}
finally {
this.loading = false;
this.saveMessages();
}
}
clearChat() {
this.isClearing = true;
this.messages = [
{
sender: 'bot',
text: this.startMessage,
},
];
this.error = '';
this.loading = false;
this.isClearing = false;
this.saveMessages();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: ChatBotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.5", type: ChatBotComponent, isStandalone: true, selector: "app-chat-bot", inputs: { backgroundColor: "backgroundColor", inputColor: "inputColor", botMassageColor: "botMassageColor", userMassageColor: "userMassageColor", sendColor: "sendColor", scrollbarColor: "scrollbarColor", scrollbarTrackColor: "scrollbarTrackColor", aiUrl: "aiUrl", left: "left", bottom: "bottom", top: "top", right: "right", width: "width", height: "height", borderRadius: "borderRadius", boxShadow: "boxShadow", placeholder: "placeholder", show: "show", btnBackgroundImage: "btnBackgroundImage", btnBackgroundSize: "btnBackgroundSize", btnLeft: "btnLeft", btnBottom: "btnBottom", btnTop: "btnTop", btnRight: "btnRight", btnWidth: "btnWidth", btnHeight: "btnHeight", btnBorderRadius: "btnBorderRadius", startMessage: "startMessage", btnBoxShadow: "btnBoxShadow", btnText: "btnText", errorCon: "errorCon", webSiteUrl: "webSiteUrl" }, viewQueries: [{ propertyName: "chatContainer", first: true, predicate: ["chatContainer"], descendants: true }], ngImport: i0, template: "<div\r\n *ngIf=\"showBlock\"\r\n id=\"chatBot\"\r\n #chatContainer\r\n class=\"chat-container\"\r\n [style.background-color]=\"backgroundColor\"\r\n [style.scrollbar-color]=\"scrollbarColor + ' ' + scrollbarTrackColor\"\r\n [style.top]=\"top\"\r\n [style.bottom]=\"bottom\"\r\n [style.right]=\"right\"\r\n [style.left]=\"left\"\r\n [style.width]=\"width\"\r\n [style.height]=\"height\"\r\n [style.border-radius]=\"borderRadius\"\r\n [style.box-shadow]=\"boxShadow\"\r\n>\r\n <button class=\"close-btn\" (click)=\"animateClose()\">\u2716</button>\r\n <button class=\"clear-btn\" (click)=\"clearChat()\">\uD83D\uDDD1</button>\r\n\r\n <div class=\"chat-messages\">\r\n <div\r\n *ngFor=\"let msg of messages\"\r\n [ngClass]=\"{ user: msg.sender === 'user', bot: msg.sender === 'bot' }\"\r\n [style.background-color]=\"\r\n msg.sender === 'user' ? userMassageColor : botMassageColor\r\n \"\r\n [style.margin-left]=\"msg.sender === 'user' ? 'auto' : 'none'\"\r\n [style.width]=\"widthInPixels + 'px'\"\r\n >\r\n {{ msg.text }}\r\n </div>\r\n <p *ngIf=\"loading\">Loading...</p>\r\n <p *ngIf=\"error\" class=\"error\">{{ error }}</p>\r\n </div>\r\n\r\n <div class=\"chat-input\" [style.background-color]=\"backgroundColor\">\r\n <input\r\n type=\"text\"\r\n [(ngModel)]=\"inputText\"\r\n (keydown.enter)=\"sendMessage()\"\r\n [style.background-color]=\"inputColor\"\r\n [placeholder]=\"placeholder\"\r\n />\r\n <button\r\n (click)=\"sendMessage()\"\r\n [disabled]=\"!inputText.trim() || loading\"\r\n [style.background-color]=\"sendColor\"\r\n >\r\n \u27A4\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div\r\n id=\"showChatBtn\"\r\n [style.background-color]=\"backgroundColor\"\r\n [style.border-radius]=\"borderRadius\"\r\n [style.background-image]=\"'url(' + btnBackgroundImage + ')'\"\r\n [style.background-size]=\"btnBackgroundSize\"\r\n [style.top]=\"btnTop\"\r\n [style.bottom]=\"btnBottom\"\r\n [style.right]=\"btnRight\"\r\n [style.left]=\"btnLeft\"\r\n [style.width]=\"btnWidth\"\r\n [style.height]=\"btnHeight\"\r\n [style.border-radius]=\"btnBorderRadius\"\r\n [style.box-shadow]=\"btnBoxShadow\"\r\n (click)=\"toggleChat()\"\r\n>\r\n {{ btnText }}\r\n</div>\r\n", styles: [".chat-container{position:fixed;bottom:20px;left:20px;width:300px;height:400px;background:#1e1e2e;color:#fff;padding:15px;border-radius:10px;box-shadow:0 4px 10px #0003;display:flex;flex-direction:column;justify-content:flex-end}#showChatBtn{position:fixed;border-radius:100%;width:60px;height:60px;display:flex;align-items:center;justify-content:center;text-align:center;background-image:url(/assets/images/chatbot.png);background-repeat:no-repeat;background-color:#535353a4;background-size:25px;background-position:center;cursor:pointer}.chat-messages{flex:1;overflow-y:auto;max-height:300px;padding:10px}.chat-messages .user{background:green;align-self:flex-end;padding:5px;border-radius:8px;margin:5px 0}.chat-messages .bot{background:gray;align-self:flex-start;padding:5px;border-radius:8px;margin:5px 0}.chat-input{display:flex;gap:5px;padding:10px 0;background:#000}.chat-input input{width:100%;padding:8px;border-radius:5px;border:none}.chat-input button{background:green;color:#fff;border:none;padding:8px;border-radius:5px;cursor:pointer}.close-btn,.clear-btn{position:absolute;top:5px;padding:5px;border:none;background:none;cursor:pointer;font-size:16px}.close-btn{right:10px}.clear-btn{right:40px}.error{color:red;font-size:12px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: ChatBotComponent, decorators: [{
type: Component,
args: [{ selector: 'app-chat-bot', standalone: true, imports: [CommonModule, FormsModule], template: "<div\r\n *ngIf=\"showBlock\"\r\n id=\"chatBot\"\r\n #chatContainer\r\n class=\"chat-container\"\r\n [style.background-color]=\"backgroundColor\"\r\n [style.scrollbar-color]=\"scrollbarColor + ' ' + scrollbarTrackColor\"\r\n [style.top]=\"top\"\r\n [style.bottom]=\"bottom\"\r\n [style.right]=\"right\"\r\n [style.left]=\"left\"\r\n [style.width]=\"width\"\r\n [style.height]=\"height\"\r\n [style.border-radius]=\"borderRadius\"\r\n [style.box-shadow]=\"boxShadow\"\r\n>\r\n <button class=\"close-btn\" (click)=\"animateClose()\">\u2716</button>\r\n <button class=\"clear-btn\" (click)=\"clearChat()\">\uD83D\uDDD1</button>\r\n\r\n <div class=\"chat-messages\">\r\n <div\r\n *ngFor=\"let msg of messages\"\r\n [ngClass]=\"{ user: msg.sender === 'user', bot: msg.sender === 'bot' }\"\r\n [style.background-color]=\"\r\n msg.sender === 'user' ? userMassageColor : botMassageColor\r\n \"\r\n [style.margin-left]=\"msg.sender === 'user' ? 'auto' : 'none'\"\r\n [style.width]=\"widthInPixels + 'px'\"\r\n >\r\n {{ msg.text }}\r\n </div>\r\n <p *ngIf=\"loading\">Loading...</p>\r\n <p *ngIf=\"error\" class=\"error\">{{ error }}</p>\r\n </div>\r\n\r\n <div class=\"chat-input\" [style.background-color]=\"backgroundColor\">\r\n <input\r\n type=\"text\"\r\n [(ngModel)]=\"inputText\"\r\n (keydown.enter)=\"sendMessage()\"\r\n [style.background-color]=\"inputColor\"\r\n [placeholder]=\"placeholder\"\r\n />\r\n <button\r\n (click)=\"sendMessage()\"\r\n [disabled]=\"!inputText.trim() || loading\"\r\n [style.background-color]=\"sendColor\"\r\n >\r\n \u27A4\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div\r\n id=\"showChatBtn\"\r\n [style.background-color]=\"backgroundColor\"\r\n [style.border-radius]=\"borderRadius\"\r\n [style.background-image]=\"'url(' + btnBackgroundImage + ')'\"\r\n [style.background-size]=\"btnBackgroundSize\"\r\n [style.top]=\"btnTop\"\r\n [style.bottom]=\"btnBottom\"\r\n [style.right]=\"btnRight\"\r\n [style.left]=\"btnLeft\"\r\n [style.width]=\"btnWidth\"\r\n [style.height]=\"btnHeight\"\r\n [style.border-radius]=\"btnBorderRadius\"\r\n [style.box-shadow]=\"btnBoxShadow\"\r\n (click)=\"toggleChat()\"\r\n>\r\n {{ btnText }}\r\n</div>\r\n", styles: [".chat-container{position:fixed;bottom:20px;left:20px;width:300px;height:400px;background:#1e1e2e;color:#fff;padding:15px;border-radius:10px;box-shadow:0 4px 10px #0003;display:flex;flex-direction:column;justify-content:flex-end}#showChatBtn{position:fixed;border-radius:100%;width:60px;height:60px;display:flex;align-items:center;justify-content:center;text-align:center;background-image:url(/assets/images/chatbot.png);background-repeat:no-repeat;background-color:#535353a4;background-size:25px;background-position:center;cursor:pointer}.chat-messages{flex:1;overflow-y:auto;max-height:300px;padding:10px}.chat-messages .user{background:green;align-self:flex-end;padding:5px;border-radius:8px;margin:5px 0}.chat-messages .bot{background:gray;align-self:flex-start;padding:5px;border-radius:8px;margin:5px 0}.chat-input{display:flex;gap:5px;padding:10px 0;background:#000}.chat-input input{width:100%;padding:8px;border-radius:5px;border:none}.chat-input button{background:green;color:#fff;border:none;padding:8px;border-radius:5px;cursor:pointer}.close-btn,.clear-btn{position:absolute;top:5px;padding:5px;border:none;background:none;cursor:pointer;font-size:16px}.close-btn{right:10px}.clear-btn{right:40px}.error{color:red;font-size:12px}\n"] }]
}], ctorParameters: () => [], propDecorators: { chatContainer: [{
type: ViewChild,
args: ['chatContainer']
}], backgroundColor: [{
type: Input
}], inputColor: [{
type: Input
}], botMassageColor: [{
type: Input
}], userMassageColor: [{
type: Input
}], sendColor: [{
type: Input
}], scrollbarColor: [{
type: Input
}], scrollbarTrackColor: [{
type: Input
}], aiUrl: [{
type: Input
}], left: [{
type: Input
}], bottom: [{
type: Input
}], top: [{
type: Input
}], right: [{
type: Input
}], width: [{
type: Input
}], height: [{
type: Input
}], borderRadius: [{
type: Input
}], boxShadow: [{
type: Input
}], placeholder: [{
type: Input
}], show: [{
type: Input
}], btnBackgroundImage: [{
type: Input
}], btnBackgroundSize: [{
type: Input
}], btnLeft: [{
type: Input
}], btnBottom: [{
type: Input
}], btnTop: [{
type: Input
}], btnRight: [{
type: Input
}], btnWidth: [{
type: Input
}], btnHeight: [{
type: Input
}], btnBorderRadius: [{
type: Input
}], startMessage: [{
type: Input
}], btnBoxShadow: [{
type: Input
}], btnText: [{
type: Input
}], errorCon: [{
type: Input
}], webSiteUrl: [{
type: Input
}] } });
class SharedModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SharedModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.5", ngImport: i0, type: SharedModule, imports: [CommonModule, FormsModule] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SharedModule, imports: [CommonModule, FormsModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SharedModule, decorators: [{
type: NgModule,
args: [{
imports: [CommonModule, FormsModule],
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { ChatBotComponent, SharedModule };
//# sourceMappingURL=ai-bot-snippet.mjs.map