import Element from './element.js'; import { EMPTY_STRING, KEY_CODE } from '../consts.js'; import { hasClass, addClass, removeClass, getPaddingTop, getFullHeight, xssEscape } from '../utils.js'; const MESSAGE_PREFIX = ' : '; const LAST_MESSAGE_YESTERDAY = 'YESTERDAY'; const MORE_MESSAGE_BELOW = 'More message below.'; const MAX_HEIGHT_INPUT_OUTER = 50; const MAX_HEIGHT_INPUT_INNER = 39; const MIN_HEIGHT_INPUT_INNER = 14; class MessageBoard extends Element{ constructor() { super(); this._create(); this.senderColor = {}; this.kr = null; } reset() { this.senderColor = {}; this.kr = null; } _create() { let board = this._createDiv(); this._setClass(board, [this.classes.MESSAGE_BOARD]); let content = this._createDiv(); this._setClass(content, [this.classes.CONTENT]); board.appendChild(content); let contentInput = this._createDiv(); this._setClass(contentInput, [this.classes.CONTENT_INPUT]); let input = this._createDiv(); this._setClass(input, [this.classes.INPUT]); input.setAttribute('contenteditable', true); this._setFocusEvent(input, () => { if (!hasClass(contentInput, this.classes.ACTIVE)) { addClass(contentInput, this.classes.ACTIVE); } }); this._setFocusOutEvent(input, () => { if (hasClass(contentInput, this.classes.ACTIVE)) { removeClass(contentInput, this.classes.ACTIVE); } }); this._setKeydownEvent(input, (event) => { this._responsiveTextInput(); if (event.keyCode == KEY_CODE.KR) { this.kr = this.input.textContent; } if (event.keyCode == KEY_CODE.ENTER && !event.shiftKey) { event.preventDefault(); this.icon.click(); this.clearInput(); } }); this._setKeyupEvent(input, () => { this._responsiveTextInput(); }); this._setPasteEvent(input, (event) => { let clipboardData; let pastedData; event.stopPropagation(); event.preventDefault(); clipboardData = event.clipboardData || window.clipboardData; pastedData = clipboardData.getData('Text'); input.textContent += pastedData; }); contentInput.appendChild(input); let icon = this._createDiv(); this._setClass(icon, [this.classes.ICON]); contentInput.appendChild(icon); board.appendChild(contentInput); this.self = board; this.content = content; this.input = input; this.icon = icon; } getMessage() { if (this.input.textContent || this.kr) { let textMessage = this.input.textContent || this.kr; return textMessage.trim(); } } clearInput() { let items = this.input.querySelectorAll(this.tags.DIV); for (var i = 0 ; i < items.length ; i++) { let item = items[i]; item.remove(); } this._setContent(this.input, EMPTY_STRING); this.kr = null; this._iconToggle(); } iconClickEvent(action) { this._setClickEvent(this.icon, action); } _responsiveTextInput() { let outerHeight = this.input.scrollHeight; let paddingTop = getPaddingTop(this.input); let innerHeight = (outerHeight - (paddingTop * 2)); let expectPadding = (MAX_HEIGHT_INPUT_OUTER - innerHeight); if (innerHeight < MIN_HEIGHT_INPUT_INNER) { this._setPaddingTopBottom(this.input, ((MAX_HEIGHT_INPUT_OUTER - MIN_HEIGHT_INPUT_INNER)/2)); } else if (innerHeight > MAX_HEIGHT_INPUT_INNER) { this._setPaddingTopBottom(this.input, ((MAX_HEIGHT_INPUT_OUTER - MAX_HEIGHT_INPUT_INNER)/2)); } else { this._setPaddingTopBottom(this.input, (expectPadding/2)); } this._iconToggle(); } _iconToggle() { if (this.input.textContent.length > 0) { if (!hasClass(this.icon, this.classes.ACTIVE)) { addClass(this.icon, this.classes.ACTIVE); } } else { removeClass(this.icon, this.classes.ACTIVE); } } setScrollEvent(action) { let _self = this; _self._setScrollEvent(_self.content, () => { if (_self.content.scrollTop == 0) { action(); } if (_self.isBottom()) { this._removeToBottomBtn(); } }); } renderMessage(messageList, isScrollToBottom, isLoadMore) { let firstChild = this.content.firstChild; var moveScroll = 0; var i; for (i = 0 ; i < messageList.length ; i++) { let message = messageList[i]; if (message.isUserMessage()) { let item = this._createMessageItem(message); isLoadMore ? this.content.insertBefore(item, firstChild) : this.content.appendChild(item); moveScroll += getFullHeight(item); } else { // do something... } } if (isLoadMore) { this.content.scrollTop = moveScroll; } if (isScrollToBottom) { this._scrollToBottom(); } } _createMessageItem(message) { let item = this._createDiv(); this._setClass(item, [this.classes.MESSAGE_ITEM]); item.setAttribute('id', message.messageId); let text = this._createDiv(); this._setClass(text, [this.classes.MESSAGE_TEXT]); let nickname = this._createLabel(); let nicknameColor = this.senderColor[message.sender.userId]; if (!nicknameColor) { nicknameColor = Math.floor((Math.random() * 12) + 1); nicknameColor = (nicknameColor < 10) ? '0' + nicknameColor.toString() : nicknameColor.toString(); this.senderColor[message.sender.userId] = nicknameColor; } this._setClass(nickname, [this.classes.NICKNAME, this.classes.NICKNAME_COLOR + nicknameColor]); this._setContent(nickname, xssEscape(message.sender.nickname)); text.appendChild(nickname); this._addContent(text, MESSAGE_PREFIX + xssEscape(message.message)); item.appendChild(text); let time = this._createDiv(); this._setClass(time, [this.classes.TIME]); this._setContent(time, this._getTime(message)); item.appendChild(time); return item; } createBottomBtn() { let btn = this._createDiv(); this._setClass(btn, [this.classes.BTN]); this._setContent(btn, MORE_MESSAGE_BELOW); if (!this.bottomBtn) { this.self.appendChild(btn); this.bottomBtn = btn; } this._setClickEvent(btn, () => { this._scrollToBottom(); this._removeToBottomBtn(); }); } _removeToBottomBtn() { if (this.bottomBtn) { this.self.removeChild(this.bottomBtn); this.bottomBtn = null; } } isBottom() { return this.content.scrollTop == this.content.scrollHeight - this.content.clientHeight; } _scrollToBottom() { this.content.scrollTop = this.content.scrollHeight - this.content.clientHeight; } _getTime(message) { const months = [ 'JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC' ]; var _getDay = (val) => { let day = parseInt(val); if (day == 1) { return day + 'st'; } else if (day == 2) { return day + 'en'; } else if (day == 3) { return day + 'rd'; } else { return day + 'th'; } }; var _checkTime = (val) => { return (+val < 10) ? '0' + val : val; }; if (message) { var _nowDate = new Date(); var _date = new Date(message.createdAt); if (_nowDate.getDate() - _date.getDate() == 1) { return LAST_MESSAGE_YESTERDAY; } else if (_nowDate.getFullYear() == _date.getFullYear() && _nowDate.getMonth() == _date.getMonth() && _nowDate.getDate() == _date.getDate()) { return _checkTime(_date.getHours()) + ':' + _checkTime(_date.getMinutes()); } else { return months[_date.getMonth()] + ' ' + _getDay(_date.getDate()); } } return ''; } } export { MessageBoard as default };