UNPKG

metro4

Version:

The front-end framework for Build responsive, mobile-first projects on the web with the first front-end component library in Metro Style

287 lines (235 loc) 11.1 kB
/* global Metro, Datetime, datetime, Cake, METRO_LOCALE */ (function(Metro, $) { 'use strict'; var Utils = Metro.utils; var defaultAvatar = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFRyB2NjIpLCBxdWFsaXR5ID0gOTAK/9sAQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU/9sAQwEDBAQFBAUJBQUJFA0LDRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8AAEQgAUABQAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A+t+KKPxo/GgA70Yo/Gj8aADFH4VesdC1HUl3WtjcXCf344yV/PGKW+0HUtNXddWNzbp/fkjIX88YoAofhR+FH40fjQAfhR+FH40fjQAUUUUAFepeAPh5D9li1LVYhK8g3Q27j5VXszDuT6f5HA+FtOXVvEWn2rjMcko3j1UckfkDX0MBgYHAoARVCKFUBVHAA6ClZQwKkZBGCDS0UAec+Pvh3BJay6lpUQimjBeW3QYVx3Kjsfbv/PyqvpuvnvxfpqaT4l1C1QbY0lJUDsrfMB+RoAyKKKKACiiigDa8GXq6f4p02eQgIJQpJ7Bvlz+tfQP4V8yDg17P4A8cw65ZxWV5IE1KMbfmP+uA7j39R+NAHaUfhSUUAL+FeA+OL1NQ8WalNGQU83YCO+0Bf6V6b498cQ6BZyWlrIJNSkXaApz5QP8AEff0FeKk5OTyTQAUUUUAH40fjRU1naTX93DbQIXmlYIijuTQBc0Dw/eeI74W1mm49XkbhUHqTXsHhz4eaXoCpI8YvbscmaYZAP8Asr0H8/etHwv4cg8M6XHaxANIfmllxy7dz9PStigA/Gk/GlooA5bxJ8PdL19XkWMWd43PnwjGT/tL0P8AP3rx/X/D954cvjbXibT1SReVceoNfRFZHijw5B4m0uS1lAWQfNFLjlG7H6etAHz5+NH41NeWk1hdzW06FJonKMp7EGoaACvQfhBowudTudRkXK2y7I8j+Nup/Afzrz6vafhRaCDwmkgHM8zufwO3/wBloA7Kiij8KACkpaSgBaSj8KKAPJvi/owttTttRjXC3K7JMf3l6H8R/KvPq9p+K1qJ/CbyEcwTI4P1O3/2avFqAP/Z"; var ChatDefaultConfig = { chatDeferred: 0, inputTimeFormat: null, timeFormat: "D MMM hh:mm A", name: "John Doe", avatar: defaultAvatar, welcome: null, welcomeAvatar: defaultAvatar, title: null, width: "100%", height: "auto", messages: null, sendButtonTitle: "Send", readonly: false, locale: METRO_LOCALE, clsChat: "", clsName: "", clsTime: "", clsInput: "", clsSendButton: "", clsMessageLeft: "default", clsMessageRight: "default", onMessage: Metro.noop, onSend: Metro.noop, onSendButtonClick: Metro.noop, onChatCreate: Metro.noop }; Metro.chatSetup = function (options) { ChatDefaultConfig = $.extend({}, ChatDefaultConfig, options); }; if (typeof window["metroChatSetup"] !== undefined) { Metro.chatSetup(window["metroChatSetup"]); } Metro.Component('chat', { init: function( options, elem ) { this._super(elem, options, ChatDefaultConfig, { input: null, classes: "primary secondary success alert warning yellow info dark light".split(" "), lastMessage: null }); return this; }, _create: function(){ var element = this.element; this._createStructure(); this._createEvents(); this._fireEvent("chat-create", { element: element }); }, _createStructure: function(){ var that = this, element = this.element, o = this.options; var messages, messageInput, input; var customButtons = [ { html: o.sendButtonTitle, cls: o.clsSendButton+" js-chat-send-button", onclick: o.onSendButtonClick } ]; element.addClass("chat").addClass(o.clsChat); element.css({ width: o.width, height: o.height }); if (Utils.isValue(o.title)) { $("<div>").addClass("title").html(o.title).appendTo(element); } messages = $("<div>").addClass("messages"); messages.appendTo(element); messageInput = $("<div>").addClass("message-input").appendTo(element); input = $("<input type='text'>"); input.appendTo(messageInput); setTimeout(() => { Metro.makePlugin(input[0], 'input', { customButtons: customButtons, clsInput: o.clsInput }) }) if (o.welcome) { this.add({ text: o.welcome, time: datetime(), position: "left", name: "Chat Bot", avatar: o.welcomeAvatar }) } if (Utils.isValue(o.messages) && typeof o.messages === "string") { o.messages = Utils.isObject(o.messages); } if (!Utils.isNull(o.messages) && typeof o.messages === "object" && Utils.objectLength(o.messages) > 0) { $.each(o.messages, function(){ that.add(this); }); } element.find(".message-input")[o.readonly ? 'addClass':'removeClass']("disabled"); }, _createEvents: function(){ var that = this, element = this.element, o = this.options; var sendButton = element.find(".js-chat-send-button"); var input = element.find("input[type=text]"); var send = function(){ var msg = ""+input.val(), m; if (msg.trim() === "") {return false;} m = { id: Utils.elementId("chat-message"), name: o.name, avatar: o.avatar, text: msg, position: "right", time: datetime() }; that.add(m); input.val(""); that._fireEvent("send", { msg: m }); input.focus(); }; sendButton.on(Metro.events.click, function () { send(); }); input.on(Metro.events.keyup, function(e){ if (e.keyCode === Metro.keyCode.ENTER) { send(); } }) }, add: function(msg){ var that = this, element = this.element, o = this.options; var message, sender, time, item, avatar, text; var messages = element.find(".messages"); var messageDate; messageDate = o.inputTimeFormat ? Datetime.from(msg.time, o.inputTimeFormat, o.locale) : datetime(msg.time); message = $("<div>").addClass("message").addClass(msg.position).appendTo(messages); item = $("<div>").addClass("message-item").appendTo(message); avatar = $("<img>").attr("src", msg.avatar).addClass("message-avatar").appendTo(item); text = $("<div>").addClass("message-text").append($("<div>").addClass("message-text-inner").html(Str.escapeHtml(msg.text))).appendTo(item); time = $("<div>").addClass("message-time").addClass(o.clsTime).text(messageDate.format(o.timeFormat)).appendTo(text); sender = $("<div>").addClass("message-sender").addClass(o.clsName).text(msg.name).appendTo(text); if (Utils.isValue(msg.id)) { message.attr("id", msg.id); } if (msg.position === 'left' && Utils.isValue(o.clsMessageLeft)) { text.addClass(o.clsMessageLeft); } if (msg.position === 'right' && Utils.isValue(o.clsMessageRight)) { text.addClass(o.clsMessageRight); } if (this.lastMessage && this.lastMessage.position === msg.position) { text.addClass("--next"); avatar.visible(false); sender.hide(); } that._fireEvent("message", { msg: msg, el: { message: message, sender: sender, time: time, item: item, avatar: avatar, text: text } }); messages.animate({ draw: { scrollTop: messages[0].scrollHeight }, dur: 1000 }); this.lastMessage = msg; return this; }, addMessages: function(messages){ var that = this; if (Utils.isValue(messages) && typeof messages === "string") { messages = Utils.isObject(messages); } if (typeof messages === "object" && Utils.objectLength(messages) > 0) { $.each(messages, function(){ that.add(this); }); } return this; }, delMessage: function(id){ var element = this.element; element.find(".messages").find("#"+id).remove(); return this; }, updMessage: function(msg){ var element = this.element; var message = element.find(".messages").find("#"+msg.id); let o = this.options; if (message.length === 0) return this; let messageDate = o.inputTimeFormat ? Datetime.from(msg.time, o.inputTimeFormat, o.locale) : datetime(msg.time); message.find(".message-text-inner").html(msg.text); message.find(".message-time").html(messageDate.format(o.timeFormat)); return this; }, clear: function(){ var element = this.element; var messages = element.find(".messages"); messages.html(""); this.lastMessage = null; }, toggleReadonly: function(readonly){ var element = this.element, o = this.options; o.readonly = typeof readonly === "undefined" ? !o.readonly : readonly; element.find(".message-input")[o.readonly ? 'addClass':'removeClass']("disabled"); }, changeAttribute: function(attributeName){ switch (attributeName) { case "data-readonly": this.toggleReadonly(); break; } }, destroy: function(){ var element = this.element; var sendButton = element.find(".js-chat-send-button"); var input = element.find("input[type=text]"); sendButton.off(Metro.events.click); input.off(Metro.events.keyup); return element; } }); Metro.defaults.Chat = ChatDefaultConfig; Metro.defaults.ChatAvatar = defaultAvatar; }(Metro, m4q));