UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

554 lines (551 loc) • 21 kB
/** * DevExtreme (cjs/__internal/ui/chat/chat.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 = void 0; var _common = require("../../../common"); var _message = _interopRequireDefault(require("../../../common/core/localization/message")); var _component_registrator = _interopRequireDefault(require("../../../core/component_registrator")); var _renderer = _interopRequireDefault(require("../../../core/renderer")); var _type = require("../../../core/utils/type"); var _data_helper = _interopRequireDefault(require("../../../data_helper")); var _conditional_invoke = require("../../core/utils/conditional_invoke"); var _widget = _interopRequireDefault(require("../../core/widget/widget")); var _alertlist = _interopRequireDefault(require("../../ui/chat/alertlist")); var _confirmationpopup = _interopRequireDefault(require("../../ui/chat/confirmationpopup")); var _messagebox = _interopRequireDefault(require("../../ui/chat/messagebox")); var _messagelist = _interopRequireDefault(require("../../ui/chat/messagelist")); 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_CLASS = "dx-chat"; const TEXTEDITOR_INPUT_CLASS = "dx-texteditor-input"; class Chat extends _widget.default { _getDefaultOptions() { return _extends({}, super._getDefaultOptions(), { showDayHeaders: true, activeStateEnabled: true, editing: { allowUpdating: false, allowDeleting: false }, focusStateEnabled: true, hoverStateEnabled: true, items: [], dataSource: null, user: { id: (new _common.Guid).toString() }, dayHeaderFormat: "shortdate", messageTemplate: null, messageTimestampFormat: "shorttime", alerts: [], showAvatar: true, showUserName: true, showMessageTimestamp: true, typingUsers: [], onMessageEntered: void 0, reloadOnChange: true, onTypingStart: void 0, onTypingEnd: void 0, onMessageEditingStart: void 0, onMessageEditCanceled: void 0, onMessageDeleting: void 0, onMessageDeleted: void 0 }) } _init() { super._init(); this._initDataController(); this._refreshDataSource(); this._createMessageEnteredAction(); this._createMessageEditingStartAction(); this._createMessageEditCanceledAction(); this._createMessageDeletingAction(); this._createMessageDeletedAction(); this._createMessageUpdatingAction(); this._createMessageUpdatedAction(); this._createTypingStartAction(); this._createTypingEndAction() } _dataSourceLoadErrorHandler() { this.option("items", []) } _dataSourceChangedHandler(newItems, e) { if (null !== e && void 0 !== e && e.changes) { this._messageList._modifyByChanges(e.changes); this._setOptionWithoutOptionChange("items", newItems.slice()); this._messageList._setOptionWithoutOptionChange("items", newItems.slice()); this._messageList._toggleEmptyView() } else { this.option("items", newItems.slice()) } } _dataSourceLoadingChangedHandler(isLoading) { var _this$_messageList; null === (_this$_messageList = this._messageList) || void 0 === _this$_messageList || _this$_messageList.option("isLoading", isLoading) } _dataSourceOptions() { return { paginate: false } } _initMarkup() { (0, _renderer.default)(this.element()).addClass("dx-chat"); super._initMarkup(); this._renderMessageList(); this._renderAlertList(); this._renderMessageBox(); this._updateRootAria(); this._updateMessageBoxAria() } _renderMessageList() { const $messageList = (0, _renderer.default)("<div>"); this.$element().append($messageList); this._messageList = this._createComponent($messageList, _messagelist.default, this._getMessageListOptions()) } _getMessageListOptions() { const { items: items = [], user: user, showDayHeaders: showDayHeaders = false, showAvatar: showAvatar = false, showUserName: showUserName = false, showMessageTimestamp: showMessageTimestamp = false, dayHeaderFormat: dayHeaderFormat, messageTimestampFormat: messageTimestampFormat, typingUsers: typingUsers = [] } = this.option(); const isLoading = this._dataController.isLoading(); const currentUserId = null === user || void 0 === user ? void 0 : user.id; const options = { items: items, currentUserId: currentUserId, allowUpdating: message => this._allowEditAction(message), allowDeleting: message => this._allowDeleteAction(message), isEditActionDisabled: message => this._messageToEdit === message, messageTemplate: this._getMessageTemplate(), showDayHeaders: showDayHeaders, showAvatar: showAvatar, showUserName: showUserName, showMessageTimestamp: showMessageTimestamp, dayHeaderFormat: dayHeaderFormat, messageTimestampFormat: messageTimestampFormat, typingUsers: typingUsers, isLoading: isLoading, onMessageEditingStart: e => { this._messageEditingStartHandler(e); return () => this.focus() }, onMessageDeleting: e => { this._messageDeletingHandler(e) }, onEscapeKeyPressed: () => { this.focus() } }; return options } _allowEditAction(message) { const { editing: editing } = this.option(); if (!editing) { return false } const { allowUpdating: allowUpdating } = editing; if ("function" === typeof allowUpdating) { return allowUpdating({ component: this, message: message }) } return allowUpdating ?? false } _allowDeleteAction(message) { const { editing: editing } = this.option(); if (!editing) { return false } const { allowDeleting: allowDeleting } = editing; if ("function" === typeof allowDeleting) { return allowDeleting({ component: this, message: message }) } return allowDeleting ?? false } _getMessageTemplate() { const { messageTemplate: messageTemplate } = this.option(); if (messageTemplate) { return (message, $container) => { const template = this._getTemplateByOption("messageTemplate"); template.render({ container: $container, model: { component: this, message: message } }) } } return null } _messageEditingStartHandler(e) { var _this$_messageEditing; if (this._messageToEdit) { var _this$_messageEditCan; null === (_this$_messageEditCan = this._messageEditCanceledAction) || void 0 === _this$_messageEditCan || _this$_messageEditCan.call(this, { message: this._messageToEdit }) } const messageEditingStartArgs = { message: e.message, cancel: false }; null === (_this$_messageEditing = this._messageEditingStartAction) || void 0 === _this$_messageEditing || _this$_messageEditing.call(this, messageEditingStartArgs); (0, _conditional_invoke.invokeConditionally)(messageEditingStartArgs.cancel, (() => { this._messageBox.option("text", e.message.text); this._messageToEdit = e.message })) } _messageEditCanceledHandler() { if (this._messageToEdit) { var _this$_messageEditCan2; null === (_this$_messageEditCan2 = this._messageEditCanceledAction) || void 0 === _this$_messageEditCan2 || _this$_messageEditCan2.call(this, { message: this._messageToEdit }); this._messageToEdit = void 0 } } _showDeleteConfirmationPopup(e) { this._messageToDelete = e.message; if (!this._deleteConfirmationPopup) { this._deleteConfirmationPopup = new _confirmationpopup.default(this.$element(), { onApplyButtonClick: () => { var _this$_messageDeleted; if (this._messageToEdit === this._messageToDelete) { var _this$_messageEditCan3; this._messageBox.option("text", ""); null === (_this$_messageEditCan3 = this._messageEditCanceledAction) || void 0 === _this$_messageEditCan3 || _this$_messageEditCan3.call(this, { message: this._messageToEdit }); this._messageToEdit = void 0 } null === (_this$_messageDeleted = this._messageDeletedAction) || void 0 === _this$_messageDeleted || _this$_messageDeleted.call(this, { message: this._messageToDelete }) }, rtlEnabled: this.option().rtlEnabled, onHidden: () => { this._messageToDelete = void 0; this._focusTarget()[0].focus() } }) } this._deleteConfirmationPopup.show() } _messageDeletingHandler(e) { var _this$_messageDeletin; const { message: message } = e; const messageDeletingArgs = { message: message, cancel: false }; null === (_this$_messageDeletin = this._messageDeletingAction) || void 0 === _this$_messageDeletin || _this$_messageDeletin.call(this, messageDeletingArgs); (0, _conditional_invoke.invokeConditionally)(messageDeletingArgs.cancel, (() => { this._showDeleteConfirmationPopup(messageDeletingArgs) })) } _messageUpdatingHandler(e) { var _this$_messageUpdatin; const { text: text } = e; const eventArgs = { message: this._messageToEdit, text: text, cancel: false }; null === (_this$_messageUpdatin = this._messageUpdatingAction) || void 0 === _this$_messageUpdatin || _this$_messageUpdatin.call(this, eventArgs); (0, _conditional_invoke.invokeConditionally)(eventArgs.cancel, (() => { var _this$_messageUpdated; this._messageBox.option("text", ""); null === (_this$_messageUpdated = this._messageUpdatedAction) || void 0 === _this$_messageUpdated || _this$_messageUpdated.call(this, eventArgs); this._messageToEdit = void 0 })) } _renderAlertList() { const $errors = (0, _renderer.default)("<div>"); this.$element().append($errors); const { alerts: alerts = [] } = this.option(); this._alertList = this._createComponent($errors, _alertlist.default, { items: alerts }) } _renderMessageBox() { const { activeStateEnabled: activeStateEnabled, focusStateEnabled: focusStateEnabled, hoverStateEnabled: hoverStateEnabled } = this.option(); const $messageBox = (0, _renderer.default)("<div>"); this.$element().append($messageBox); const configuration = { activeStateEnabled: activeStateEnabled, focusStateEnabled: focusStateEnabled, hoverStateEnabled: hoverStateEnabled, onMessageEntered: e => { this._messageEnteredHandler(e) }, onTypingStart: e => { this._typingStartHandler(e) }, onTypingEnd: () => { this._typingEndHandler() }, onMessageEditCanceled: () => { this._messageEditCanceledHandler() }, onMessageUpdating: e => { this._messageUpdatingHandler(e) } }; this._messageBox = this._createComponent($messageBox, _messagebox.default, configuration) } _updateRootAria() { const aria = { role: "group", label: _message.default.format("dxChat-elementAriaLabel") }; this.setAria(aria, this.$element()) } _updateMessageBoxAria() { const emptyViewId = this._messageList.getEmptyViewId(); this._messageBox.updateInputAria(emptyViewId) } _createMessageEnteredAction() { this._messageEnteredAction = this._createActionByOption("onMessageEntered", { excludeValidators: ["disabled"] }) } _createMessageEditingStartAction() { this._messageEditingStartAction = this._createActionByOption("onMessageEditingStart", { excludeValidators: ["disabled"] }) } _createMessageEditCanceledAction() { this._messageEditCanceledAction = this._createActionByOption("onMessageEditCanceled", { excludeValidators: ["disabled"] }) } _createMessageDeletingAction() { this._messageDeletingAction = this._createActionByOption("onMessageDeleting", { excludeValidators: ["disabled"] }) } _createMessageDeletedAction() { this._messageDeletedAction = this._createActionByOption("onMessageDeleted", { excludeValidators: ["disabled"] }) } _createMessageUpdatingAction() { this._messageUpdatingAction = this._createActionByOption("onMessageUpdating", { excludeValidators: ["disabled"] }) } _createMessageUpdatedAction() { this._messageUpdatedAction = this._createActionByOption("onMessageUpdated", { excludeValidators: ["disabled"] }) } _createTypingStartAction() { this._typingStartAction = this._createActionByOption("onTypingStart", { excludeValidators: ["disabled"] }) } _createTypingEndAction() { this._typingEndAction = this._createActionByOption("onTypingEnd", { excludeValidators: ["disabled"] }) } _messageEnteredHandler(e) { var _this$_messageEntered; const { text: text, event: event } = e; const { user: user } = this.option(); const message = { timestamp: new Date, author: user, text: text }; const dataSource = this.getDataSource(); if ((0, _type.isDefined)(dataSource)) { dataSource.store().insert(message).done((() => { const { reloadOnChange: reloadOnChange } = this.option(); if (reloadOnChange) { dataSource.reload() } })) } null === (_this$_messageEntered = this._messageEnteredAction) || void 0 === _this$_messageEntered || _this$_messageEntered.call(this, { message: message, event: event }) } _typingStartHandler(e) { var _this$_typingStartAct; const { event: event } = e; const { user: user } = this.option(); null === (_this$_typingStartAct = this._typingStartAction) || void 0 === _this$_typingStartAct || _this$_typingStartAct.call(this, { user: user, event: event }) } _typingEndHandler() { var _this$_typingEndActio; const { user: user } = this.option(); null === (_this$_typingEndActio = this._typingEndAction) || void 0 === _this$_typingEndActio || _this$_typingEndActio.call(this, { user: user }) } _focusTarget() { const $input = (0, _renderer.default)(this.element()).find(".dx-texteditor-input"); return $input } _optionChanged(args) { const { name: name, value: value } = args; switch (name) { case "activeStateEnabled": case "focusStateEnabled": case "hoverStateEnabled": this._messageBox.option(name, value); break; case "user": { const author = value; this._messageList.option("currentUserId", null === author || void 0 === author ? void 0 : author.id); break } case "editing": case "reloadOnChange": break; case "items": this._messageList.option(name, this.option("items")); this._updateMessageBoxAria(); break; case "dataSource": this._refreshDataSource(); break; case "alerts": this._alertList.option("items", value ?? []); break; case "onMessageEntered": this._createMessageEnteredAction(); break; case "onMessageUpdating": case "onMessageUpdated": case "onMessageEditCanceled": this._createMessageEditCanceledAction(); break; case "onMessageEditingStart": this._createMessageEditingStartAction(); break; case "onMessageDeleting": this._createMessageDeletingAction(); break; case "onMessageDeleted": this._createMessageDeletedAction(); break; case "onTypingStart": this._createTypingStartAction(); break; case "onTypingEnd": this._createTypingEndAction(); break; case "showDayHeaders": case "showAvatar": case "showUserName": case "showMessageTimestamp": this._messageList.option(name, !!value); break; case "dayHeaderFormat": case "messageTimestampFormat": case "typingUsers": this._messageList.option(name, value); break; case "messageTemplate": this._messageList.option(name, this._getMessageTemplate()); break; default: super._optionChanged(args) } } _insertNewItem(item) { const { items: items } = this.option(); const newItems = [...items ?? [], item]; this.option("items", newItems) } renderMessage() { let message = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}; this._insertNewItem(message) } _dispose() { var _this$_deleteConfirma; null === (_this$_deleteConfirma = this._deleteConfirmationPopup) || void 0 === _this$_deleteConfirma || _this$_deleteConfirma.dispose(); super._dispose() } } Chat.include(_data_helper.default); (0, _component_registrator.default)("dxChat", Chat); var _default = exports.default = Chat;