devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
303 lines (298 loc) • 12.8 kB
JavaScript
/**
* DevExtreme (cjs/__internal/ui/chat/messagegroup.js)
* Version: 25.1.3
* Build date: Wed Jun 25 2025
*
* Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.CHAT_MESSAGEGROUP_CLASS = exports.CHAT_MESSAGEGROUP_ALIGNMENT_START_CLASS = exports.CHAT_MESSAGEGROUP_ALIGNMENT_END_CLASS = void 0;
var _date = _interopRequireDefault(require("../../../common/core/localization/date"));
var _message = _interopRequireDefault(require("../../../common/core/localization/message"));
var _renderer = _interopRequireDefault(require("../../../core/renderer"));
var _date_serialization = _interopRequireDefault(require("../../../core/utils/date_serialization"));
var _type = require("../../../core/utils/type");
var _widget = _interopRequireDefault(require("../../core/widget/widget"));
var _avatar = _interopRequireDefault(require("./avatar"));
var _messagebubble = _interopRequireWildcard(require("./messagebubble"));
function _getRequireWildcardCache(e) {
if ("function" != typeof WeakMap) {
return null
}
var r = new WeakMap,
t = new WeakMap;
return (_getRequireWildcardCache = function(e) {
return e ? t : r
})(e)
}
function _interopRequireWildcard(e, r) {
if (!r && e && e.__esModule) {
return e
}
if (null === e || "object" != typeof e && "function" != typeof e) {
return {
default: e
}
}
var t = _getRequireWildcardCache(r);
if (t && t.has(e)) {
return t.get(e)
}
var n = {
__proto__: null
},
a = Object.defineProperty && Object.getOwnPropertyDescriptor;
for (var u in e) {
if ("default" !== u && {}.hasOwnProperty.call(e, u)) {
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null;
i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]
}
}
return n.default = e, t && t.set(e, n), n
}
function _interopRequireDefault(e) {
return e && e.__esModule ? e : {
default: e
}
}
function _extends() {
return _extends = Object.assign ? Object.assign.bind() : function(n) {
for (var e = 1; e < arguments.length; e++) {
var t = arguments[e];
for (var r in t) {
({}).hasOwnProperty.call(t, r) && (n[r] = t[r])
}
}
return n
}, _extends.apply(null, arguments)
}
const CHAT_MESSAGEGROUP_CLASS = exports.CHAT_MESSAGEGROUP_CLASS = "dx-chat-messagegroup";
const CHAT_MESSAGEGROUP_ALIGNMENT_START_CLASS = exports.CHAT_MESSAGEGROUP_ALIGNMENT_START_CLASS = "dx-chat-messagegroup-alignment-start";
const CHAT_MESSAGEGROUP_ALIGNMENT_END_CLASS = exports.CHAT_MESSAGEGROUP_ALIGNMENT_END_CLASS = "dx-chat-messagegroup-alignment-end";
const CHAT_MESSAGEGROUP_INFORMATION_CLASS = "dx-chat-messagegroup-information";
const CHAT_MESSAGEGROUP_TIME_CLASS = "dx-chat-messagegroup-time";
const CHAT_MESSAGEGROUP_AUTHOR_NAME_CLASS = "dx-chat-messagegroup-author-name";
const CHAT_MESSAGEGROUP_CONTENT_CLASS = "dx-chat-messagegroup-content";
const CHAT_MESSAGE_EDITED_CLASS = "dx-chat-message-edited";
const CHAT_MESSAGE_EDITED_HIDING_CLASS = "dx-chat-message-edited-hiding";
const CHAT_MESSAGE_EDITED_ICON_CLASS = "dx-chat-message-edited-icon";
const CHAT_MESSAGE_EDITED_TEXT_CLASS = "dx-chat-message-edited-text";
class MessageGroup extends _widget.default {
_getDefaultOptions() {
return _extends({}, super._getDefaultOptions(), {
items: [],
alignment: "start",
showAvatar: true,
showUserName: true,
showMessageTimestamp: true,
messageTemplate: null,
messageTimestampFormat: "shorttime"
})
}
_updateAlignmentClass() {
(0, _renderer.default)(this.element()).removeClass(CHAT_MESSAGEGROUP_ALIGNMENT_START_CLASS).removeClass(CHAT_MESSAGEGROUP_ALIGNMENT_END_CLASS);
const alignmentClass = this._isAlignmentStart() ? CHAT_MESSAGEGROUP_ALIGNMENT_START_CLASS : CHAT_MESSAGEGROUP_ALIGNMENT_END_CLASS;
(0, _renderer.default)(this.element()).addClass(alignmentClass)
}
_initMarkup() {
const {
items: items,
showAvatar: showAvatar
} = this.option();
(0, _renderer.default)(this.element()).addClass(CHAT_MESSAGEGROUP_CLASS);
this._updateAlignmentClass();
super._initMarkup();
if (0 === items.length) {
return
}
if (showAvatar && this._isAlignmentStart()) {
this._renderAvatar()
}
this._renderMessageGroupInformation(null === items || void 0 === items ? void 0 : items[0]);
this._renderMessageBubbles(items)
}
_renderAvatar() {
const $avatar = (0, _renderer.default)("<div>").appendTo(this.element());
const {
items: items
} = this.option();
const {
author: author
} = items[0];
const authorName = null === author || void 0 === author ? void 0 : author.name;
const authorAvatarUrl = null === author || void 0 === author ? void 0 : author.avatarUrl;
const authorAvatarAlt = null === author || void 0 === author ? void 0 : author.avatarAlt;
this._avatar = this._createComponent($avatar, _avatar.default, {
name: authorName,
url: authorAvatarUrl,
alt: authorAvatarAlt
})
}
_renderMessageBubble(message) {
const $bubble = (0, _renderer.default)("<div>").data(_messagebubble.MESSAGE_DATA_KEY, message);
this._createComponent($bubble, _messagebubble.default, this._getMessageBubbleOptions(message));
this._$messageBubbleContainer.append($bubble)
}
_getMessageBubbleOptions(message) {
const options = {
isDeleted: message.isDeleted,
type: message.type
};
const {
messageTemplate: messageTemplate
} = this.option();
if ("image" === message.type) {
options.alt = message.alt;
options.src = message.src
} else {
options.text = message.text
}
if (messageTemplate) {
options.template = (messageData, container) => {
messageTemplate(_extends({}, message, messageData), container)
}
}
return options
}
_renderMessageBubbles(items) {
this._$messageBubbleContainer = (0, _renderer.default)("<div>").addClass("dx-chat-messagegroup-content");
items.forEach(((message, index) => {
const shouldCreateEditedElement = 0 !== index && "image" !== message.type && true === message.isEdited && !message.isDeleted;
if (shouldCreateEditedElement) {
const $edited = this._createEditedElement();
$edited.appendTo(this._$messageBubbleContainer)
}
this._renderMessageBubble(message)
}));
this._$messageBubbleContainer.appendTo(this.element())
}
_renderMessageGroupInformation(message, shouldRenderEditedMessage) {
const {
showUserName: showUserName,
showMessageTimestamp: showMessageTimestamp
} = this.option();
const {
timestamp: timestamp,
author: author
} = message;
const isEdited = (0, _type.isDefined)(shouldRenderEditedMessage) ? shouldRenderEditedMessage : "image" !== message.type && message.isEdited;
const isAlignmentStart = this._isAlignmentStart();
this.$element().find(".dx-chat-messagegroup-information").remove();
const $information = (0, _renderer.default)("<div>").addClass("dx-chat-messagegroup-information");
if (showUserName) {
const authorName = (null === author || void 0 === author ? void 0 : author.name) ?? _message.default.format("dxChat-defaultUserName");
const authorNameText = isAlignmentStart ? authorName : "";
(0, _renderer.default)("<div>").addClass("dx-chat-messagegroup-author-name").text(authorNameText).appendTo($information)
}
if (isEdited && !isAlignmentStart) {
$information.append(this._createEditedElement())
}
if (showMessageTimestamp) {
const $time = (0, _renderer.default)("<div>").addClass("dx-chat-messagegroup-time").appendTo($information);
const shouldAddTimeValue = this._shouldAddTimeValue(timestamp);
if (shouldAddTimeValue) {
const timeValue = this._getTimeValue(timestamp);
$time.text(timeValue)
}
}
if (isEdited && isAlignmentStart) {
$information.append(this._createEditedElement())
}
$information.appendTo(this.element())
}
_createEditedElement() {
const $edited = (0, _renderer.default)("<div>").addClass("dx-chat-message-edited");
(0, _renderer.default)("<div>").addClass("dx-chat-message-edited-icon").appendTo($edited);
const editedMessageText = _message.default.format("dxChat-editedMessageText");
(0, _renderer.default)("<div>").addClass("dx-chat-message-edited-text").text(editedMessageText).appendTo($edited);
return $edited
}
_updateMessageEditedText($message) {
let isEdited = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : false;
const $firstMessage = this._$messageBubbleContainer.find(`.${_messagebubble.CHAT_MESSAGEBUBBLE_CLASS}`).first();
const removeWithAnimation = $editedElement => {
$editedElement.get(0).addEventListener("animationend", (() => {
$editedElement.remove()
}), {
once: true
});
$editedElement.addClass("dx-chat-message-edited-hiding")
};
if ($message.is($firstMessage)) {
const items = this.option("items");
const $information = this.$element().find(".dx-chat-messagegroup-information");
const $edited = $information.find(".dx-chat-message-edited");
if ($edited.length && isEdited) {
return
}
if ($edited.length && !isEdited) {
removeWithAnimation($edited);
return
}
if (isEdited) {
this._renderMessageGroupInformation(items[0], true)
}
return
}
const $prevElement = $message.prev();
if ($prevElement.hasClass("dx-chat-message-edited")) {
if (!isEdited) {
removeWithAnimation($prevElement)
}
return
}
if (isEdited) {
const $edited = this._createEditedElement();
$edited.insertBefore($message)
}
}
_isAlignmentStart() {
const {
alignment: alignment
} = this.option();
return "start" === alignment
}
_shouldAddTimeValue(timestamp) {
const deserializedDate = _date_serialization.default.deserializeDate(timestamp);
return (0, _type.isDate)(deserializedDate) && !isNaN(deserializedDate.getTime())
}
_getTimeValue(timestamp) {
const deserializedDate = _date_serialization.default.deserializeDate(timestamp);
const {
messageTimestampFormat: messageTimestampFormat
} = this.option();
const formattedTime = _date.default.format(deserializedDate, messageTimestampFormat);
return formattedTime
}
_optionChanged(args) {
const {
name: name
} = args;
switch (name) {
case "items":
case "alignment":
case "showAvatar":
case "showUserName":
case "showMessageTimestamp":
case "messageTemplate":
case "messageTimestampFormat":
this._invalidate();
break;
default:
super._optionChanged(args)
}
}
renderMessage(message) {
const {
items: items
} = this.option();
const newItems = [...items, message];
this._setOptionWithoutOptionChange("items", newItems);
this._renderMessageBubble(message)
}
}
var _default = exports.default = MessageGroup;