UNPKG

oe-ui-misc

Version:

collection of miscellaneous oe-ui Polymer components

262 lines (241 loc) 7.07 kB
/** * @license * ©2018-2019 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), * Bangalore, India. All Rights Reserved. */ import { html, PolymerElement } from '@polymer/polymer/polymer-element.js'; import '@polymer/paper-icon-button/paper-icon-button.js'; import '@polymer/paper-toolbar/paper-toolbar.js'; import '@polymer/iron-icon/iron-icon.js'; import '@polymer/iron-icons/iron-icons.js'; import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea.js'; import '@polymer/iron-flex-layout/iron-flex-layout-classes.js'; import '@polymer/paper-scroll-header-panel/paper-scroll-header-panel.js'; /** * `chat-bot` * Chat Element. * * @customElement * @polymer * */ class ChatBot extends PolymerElement { static get is() { return 'chat-bot'; } static get template() { return html` <style include="iron-flex iron-flex-alignment"></style> <style> :host { display: block; position: relative; } input { height: 40px; border-radius: 2px; } paper-toolbar { background: var(--primary-color); color: #fff; } .input-container { background: var(--primary-color); height: 52px; padding: 0 16px; color: #fff; } iron-autogrow-textarea { height: 36px; font-size: 14px; border-radius: 4px; border: none; background: #fff; color: var(--primary-text-color); --iron-autogrow-textarea: { padding: 4px 16px; box-sizing: border-box; outline: none; } @apply --chat-bot-input; } .messages-container { min-height: 320px; height: calc(100% - 115px); overflow-x: hidden; overflow-y: auto; padding: 16px; box-sizing: border-box; background: #efefef; @apply --chat-bot-container; } .message { padding: 12px; margin: 12px 0; display: inline-block; box-sizing: border-box; position: relative; box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.15); word-break: break-word; } .user { @apply --layout-end-justified; } .robot .message { background: #fff; border-radius: 4px 4px 4px 0; } .robot .message::before { content: ''; width: 0; height: 0; border-style: solid; border-width: 10px 10px 0 0; border-color: #fff transparent transparent; position: absolute; bottom: -10px; left: 0; } .user .message { border-radius: 4px 4px 0; background: var(--light-primary-color); } .user .message::before { content: ''; width: 0; height: 0; border-style: solid; border-width: 0 10px 10px 0; border-color: transparent var(--light-primary-color) transparent transparent; position: absolute; bottom: -10px; right: 0; } </style> <paper-toolbar> <div class="title" slot="top">[[title]]</div> </paper-toolbar> <paper-scroll-header-panel id="scrollContainer" main fixed class="messages-container"> <div> <template is="dom-repeat" items="{{messages}}"> <!-- inner-h-t-m-l is the trick to allow safe html injection --> <div class$="message-box flex layout horizontal {{item.user}}"><span class="message" inner-h-t-m-l=[[_getMessage(item.message)]]></span></div> </template> </div> </paper-scroll-header-panel> <div class="input-container layout horizontal center"> <iron-autogrow-textarea max-rows=2 class="flex" on-keydown="onEnter" bind-value="{{userMessage}}" placeholder="Type here.." id="input"></iron-autogrow-textarea> <paper-icon-button icon="icons:send" on-tap="sendMessage" class="send-btn"></paper-icon-button> </div> `; } static get properties() { return { messages: { type: Array, value: function () { return []; } }, /** Title of the ChatBot */ title: { type: String, value: 'Chat Bot' }, /** Initial greet message */ initialMessage: { type: String, value: 'Hi, How can I help you?' }, /** Url to post/fetch the messages */ url: { type: String } }; } /** * Fuction invoked in connected callback. */ /*global someFunction attachedFun:true*/ /*eslint no-undef: "error"*/ attachedFun() { if (this.initialMessage && this.initialMessage.trim() != '') { this.push('messages', { 'user': 'robot', 'message': this.initialMessage }); } else { this.push('messages', { 'user': 'robot', 'message': 'Hi, How can I help you?' }); } } /** * Connected callback to handle templating if custom template is present. */ connectedCallback() { super.connectedCallback(); this.addEventListener('change', e => attachedFun()); } onEnter(event) { if (event.which == 13 || event.keyCode == 13) { event.preventDefault(); this.sendMessage(); } } _getMessage(msg) { if (msg.indexOf('http://') >= 0) { var splits = msg.split(' '); splits = splits.map(function (part) { if (part.startsWith('http://')) { part = '<a href="' + part + '" target="_blank">Results</a>'; } return part; }); msg = splits.join(' '); } return msg; } sendMessage() { if (!this.url) return; if (!this.userMessage || this.userMessage.trim() == '') return; this.push('messages', { 'user': 'user', 'message': this.userMessage }); var message = this.userMessage; this.$.input.selectionStart = 0; this.$.input.selectionEnd = 0; this.set('userMessage', ''); var self = this; var xhr = new XMLHttpRequest(); xhr.withCredentials = true; xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { var message = xhr.responseText; self.push('messages', { 'user': 'robot', 'message': message }); Polymer.dom.flush(); //self.$.messageList.scrollTop = self.$.messageList.scrollHeight; self.$.scrollContainer.scroll(self.$.scrollContainer.scroller.scrollHeight, true); } }; xhr.open('POST', this.url, true); xhr.setRequestHeader('Content-Type', 'application/json;charset=encoding'); var body = { 'message': message }; xhr.send(JSON.stringify(body)); } } window.customElements.define(ChatBot.is, ChatBot);