UNPKG

@cometchat/chat-uikit-angular

Version:

Ready-to-use Chat UI Components for Angular (JavaScript/Web)

1,229 lines (1,228 loc) 304 kB
import "@cometchat/uikit-shared"; import "@cometchat/uikit-elements"; import { CometChatMentionsFormatter, CometChatSoundManager, CometChatUIKitUtility, MessageComposerStyle, StickersConstants, UserMemberWrapperConfiguration, UserMentionStyle, } from "@cometchat/uikit-shared"; import { MediaRecorderStyle, } from "@cometchat/uikit-elements"; import { AuxiliaryButtonAlignment, CometChatMessageEvents, CometChatUIEvents, CometChatUIKitConstants, MessageStatus, Placement, PreviewMessageMode, States, UserMemberListType, fontHelper, localize, } from "@cometchat/uikit-resources"; import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewChild, } from "@angular/core"; import { ChatConfigurator } from "../../Shared/Framework/ChatConfigurator"; import { CometChat } from "@cometchat/chat-sdk-javascript"; import { CometChatException } from "../../Shared/Utils/ComeChatException"; import * as i0 from "@angular/core"; import * as i1 from "../../CometChatTheme.service"; import * as i2 from "../../CometChatUserMemberWrapper/cometchat-user-member-wrapper.component"; import * as i3 from "@angular/common"; /** * * CometChatMessageComposer is used to send message to user or group. * * @version 1.0.0 * @author CometChatTeam * @copyright © 2022 CometChat Inc. * */ export class CometChatMessageComposerComponent { constructor(ref, themeService) { this.ref = ref; this.themeService = themeService; this.disableSoundForMessages = false; /** * @deprecated * * This property is deprecated as of version 4.3.19 due to newer property 'customSoundForMessages'. It will be removed in subsequent versions. */ this.customSoundForMessage = ""; this.customSoundForMessages = ""; this.disableTypingEvents = false; this.text = ""; this.placeholderText = localize("ENTER_YOUR_MESSAGE_HERE"); this.attachmentIconURL = "assets/Plus.svg"; this.auxiliaryButtonsAlignment = AuxiliaryButtonAlignment.right; this.parentMessageId = 0; this.hideLiveReaction = true; this.LiveReactionIconURL = "assets/heart-reaction.png"; this.backButtonIconURL = "assets/backbutton.svg"; this.InfoSimpleIcon = "assets/InfoSimpleIcon.svg"; this.messageComposerStyle = { height: "100%", width: "100%", borderRadius: "12px", maxInputHeight: "100px", }; this.onError = (error) => { console.log(error); }; this.backdropStyle = { height: "100%", width: "100%", background: "rgba(0, 0, 0, 0.5)", position: "fixed", }; this.actionSheetStyle = { layoutModeIconTint: "rgba(20, 20, 20, 0.04)", borderRadius: "inherit", background: "rgb(255,255,255)", border: "none", width: "100%", height: "100%", titleFont: "500 15px Inter, sans-serif", titleColor: "#141414", listItemBackground: "", ActionSheetSeparatorTint: "1px solid RGBA(20, 20, 20, 0.08)", listItemIconBackground: "", listItemIconTint: "" }; this.aiActionSheetStyle = { layoutModeIconTint: "rgba(20, 20, 20, 0.04)", borderRadius: "inherit", background: "rgb(255,255,255)", border: "none", width: "100%", height: "100%", titleFont: "500 15px Inter, sans-serif", titleColor: "#141414", listItemBackground: "transparent", ActionSheetSeparatorTint: "1px solid RGBA(20, 20, 20, 0.08)", }; this.hideVoiceRecording = false; this.mediaRecorderStyle = {}; this.aiOptionsStyle = {}; this.aiIconURL = "assets/ai-bot.svg"; this.voiceRecordingIconURL = "assets/mic.svg"; this.voiceRecordingCloseIconURL = "assets/close2x.svg"; this.voiceRecordingStartIconURL = "assets/mic.svg"; this.voiceRecordingStopIconURL = "assets/stop.svg"; this.voiceRecordingSubmitIconURL = "assets/Send.svg"; this.hideLayoutMode = false; this.emojiIconURL = "assets/Stipop.svg"; this.childEvent = new EventEmitter(); this.userMemberWrapperConfiguration = new UserMemberWrapperConfiguration({}); this.textFormatters = []; this.sendButtonIconURL = "assets/Send.svg"; this.mentionsFormatterInstanceId = "composer_" + Date.now(); this.composerActions = []; this.states = States; this.mentionsSearchTerm = ""; this.showListForMentions = false; this.mentionsSearchCount = 1; this.lastEmptySearchTerm = ""; this.smartReplyState = States.loading; this.showMentionsCountWarning = false; this.initialText = ""; this.loadingStateText = localize("GENERATING_REPLIES"); this.errorStateText = localize("SOMETHING_WRONG"); this.emptyStateText = localize("NO_MESSAGES_FOUND"); this.showCreatePolls = false; this.showStickerKeyboard = false; this.showActionSheetItem = false; this.showActionSheetItemAI = false; this.showSmartReply = false; this.showAiFeatures = false; this.repliesArray = []; this.aiBotList = []; this.currentAskAIBot = ""; this.isAiMoreThanOne = false; this.showPreview = false; this.aiFeaturesCloseCallback = null; this.textFormatterList = this.textFormatters ? [...this.textFormatters] : []; this.mentionedUsers = []; this.acceptHandlers = { "image/*": this.onImageChange.bind(this), "video/*": this.onVideoChange.bind(this), "audio/*": this.onAudioChange.bind(this), "file/*": this.onFileChange.bind(this), }; this.enableStickerKeyboard = false; this.toggleMediaRecorded = false; this.showAiBotList = false; this.mentionsTypeSetByUser = false; this.stickerConfiguration = {}; this.closeButtonIconURL = "assets/plus-rotated.svg"; this.buttons = []; this.aiActionButtons = []; this.smartReplyStyle = { width: "100%", height: "fit-content", border: "none", }; this.sendButtonStyle = { height: "24px", width: "24px", border: "none", borderRadius: "0", buttonIconTint: "rgba(20, 20, 20, 0.58)", background: "transparent", }; this.liveReactionStyle = { height: "24px", width: "24px", border: "none", borderRadius: "0", buttonIconTint: "red", background: "transparent", display: "flex", justifyContent: "center", alignItems: "center", }; this.localize = localize; this.emojiButtonStyle = { height: "24px", width: "24px", border: "none", borderRadius: "0", buttonIconTint: "grey", background: "transparent", }; this.stickerButtonStyle = { height: "24px", width: "24px", border: "none", borderRadius: "0", buttonIconTint: "grey", background: "transparent", }; this.mediaRecorderButtonStyle = { height: "24px", width: "24px", border: "none", borderRadius: "0", buttonIconTint: "grey", background: "transparent", }; this.emojiKeyboardStyle = { width: "100%", height: "100%", border: "none", textFont: this.messageComposerStyle?.emojiKeyboardTextFont, textColor: this.messageComposerStyle?.emojiKeyboardTextColor, background: this.themeService.theme.palette.getBackground(), borderRadius: "12px", activeIconTint: this.themeService.theme.palette.getPrimary(), iconTint: this.themeService.theme.palette.getAccent600() }; this.stickerKeyboardStyle = {}; this.textInputStyle = {}; this.previewStyle = { height: "100%", width: "100%", }; this.createPollStyle = {}; this.emojiPopover = { width: "315px", height: "320px", border: "none", background: "transparent", borderRadius: "8px", boxShadow: "0px 0px 8px rgba(20, 20, 20, 0.2)", }; this.stickerPopover = { width: "300px", height: "320px", border: "none", background: "transparent", borderRadius: "8px", boxShadow: "0px 0px 8px rgba(20, 20, 20, 0.2)", }; this.aiPopover = { width: "280px", height: "280px", border: "none", background: "transparent", borderRadius: "8px", boxShadow: "0px 0px 8px rgba(20, 20, 20, 0.2)", }; this.mediaRecordedPopover = { width: "250px", height: "100px", borderRadius: "8px", boxShadow: "0px 0px 8px rgba(20, 20, 20, 0.2)", }; this.popoverStyle = { width: "275px", height: "280px", border: "none", background: "transparent", borderRadius: "8px", boxShadow: "0px 0px 8px rgba(20, 20, 20, 0.2)", }; this.emojiButtonIconURL = "assets/Stipop.svg"; this.stickerButtonIconURL = "assets/Stickers.svg"; this.messageText = ""; this.attachmentButtonStyle = { height: "24px", width: "24px", border: "none", borderRadius: "0", buttonIconTint: "grey", background: "transparent", }; this.auxilaryPlacement = Placement.top; this.messageSending = false; this.editPreviewText = ""; this.showSendButton = false; this.showEmojiKeyboard = false; this.isAiEnabled = false; this.smartReplies = []; this.mentionStyleLocal = new UserMentionStyle({}); this.sendMessageOnEnter = (event) => { this.showMentionsCountWarning = false; this.showListForMentions = false; this.sendTextMessage(event.detail.value); this.clearComposer(); this.showSendButton = false; this.disableSendButton(); }; this.messageInputChanged = (event) => { const text = event?.detail?.value?.trim(); this.sendButtonStyle = { height: "24px", width: "24px", border: "none", borderRadius: "0", buttonIconTint: text ? this.messageComposerStyle?.sendIconTint : this.themeService.theme.palette.getAccent200(), background: "transparent", }; if (!text) { this.showSendButton = false; } else { this.showSendButton = true; } if (this.onTextChange) { this.onTextChange(text); } this.messageText = text; if (text) { this.startTyping(); } else { this.endTyping(); } }; this.appendEmoji = (event) => { if (this.text === event?.detail.id) { this.text = "" + ""; this.ref.detectChanges(); } this.text = event?.detail.id; this.ref.detectChanges(); }; this.openCreatePolls = () => { this.showCreatePolls = true; if (this.showActionSheetItem) { this.actionSheetRef.nativeElement.click(); this.showActionSheetItem = !this.showActionSheetItem; } this.ref.detectChanges(); }; this.closeCreatePolls = () => { this.showCreatePolls = false; this.ref.detectChanges(); }; this.sendRecordedMedia = (event) => { let file = event?.detail?.file; if (file) { this.sendRecordedAudio(file); } this.closeMediaRecorder(); this.ref.detectChanges(); }; this.sendRecordedAudio = (file) => { try { const uploadedFile = file; const reader = new FileReader(); reader.addEventListener("load", () => { const newFile = new File([reader.result], `audio-recording-${this.getFormattedDate()}.wav`, uploadedFile); this.sendMediaMessage(newFile, CometChatUIKitConstants.MessageTypes.audio); }, false); reader.readAsArrayBuffer(uploadedFile); } catch (error) { if (this.onError) { this.onError(CometChatException(error)); } } return true; }; /* * isPartOfCurrentChatForUIEvent: To check if the message belongs for this list and is not part of thread even for current list it only runs for UI event because it assumes logged in user is always sender * @param: message: CometChat.BaseMessage */ this.isPartOfCurrentChatForUIEvent = (message) => { if (this.parentMessageId) { if (message.getParentMessageId() === this.parentMessageId) { return true; } else { return false; } } else { if (message.getParentMessageId()) { return false; } if (this.user) { if (message.getReceiverType() === CometChatUIKitConstants.MessageReceiverType.user && message?.getReceiverId() === this.user.getUid()) { return true; } } else if (this.group) { if (message.getReceiverType() === CometChatUIKitConstants.MessageReceiverType.group && message?.getReceiverId() === this.group.getGuid()) { return true; } } return false; } }; this.handleActions = (event) => { let action = event?.detail?.action; this.showAiFeatures = false; if (action.onClick) { action.onClick(); } if (this.showActionSheetItem) { this.showActionSheetItem = false; this.actionSheetRef.nativeElement.click(); } }; this.inputChangeHandler = (event) => { const handler = this.acceptHandlers[this.inputElementRef.nativeElement.accept] || this.onFileChange.bind(this); handler(event); if (this.inputElementRef?.nativeElement && this.inputElementRef.nativeElement?.value) { this.inputElementRef.nativeElement.value = ""; } }; this.sendSticker = (event) => { this.stickerButtonRef?.nativeElement?.click(); this.showStickerKeyboard = false; let sticker = event?.detail?.stickerURL; let stickerName = event?.detail?.stickerName; if (this.stickerConfiguration?.configuration?.ccStickerClicked) { this.stickerConfiguration?.configuration?.ccStickerClicked({ name: stickerName, url: sticker, }, this.loggedInUser, this.user, this.group, this.parentMessageId, this.onError, this.customSoundForMessage || this.customSoundForMessages, this.disableSoundForMessages); } }; this.openImagePicker = () => { this.inputElementRef.nativeElement.type = "file"; this.inputElementRef.nativeElement.accept = "image/*"; this.inputElementRef.nativeElement.click(); this.closePopovers(); }; this.openFilePicker = () => { this.inputElementRef.nativeElement.type = "file"; this.inputElementRef.nativeElement.accept = "file/*"; this.inputElementRef.nativeElement.click(); this.closePopovers(); }; this.openvideoPicker = () => { this.inputElementRef.nativeElement.type = "file"; this.inputElementRef.nativeElement.accept = "video/*"; this.inputElementRef.nativeElement.click(); this.closePopovers(); }; this.openAudioPicker = () => { this.inputElementRef.nativeElement.type = "file"; this.inputElementRef.nativeElement.accept = "audio/*"; this.inputElementRef.nativeElement.click(); this.closePopovers(); }; this.openActionSheet = (event) => { if (event?.detail?.hasOwnProperty("isOpen")) { this.showActionSheetItem = false; this.ref.detectChanges(); return; } this.showActionSheetItem = !this.showActionSheetItem; this.closeMediaRecorder(); if (this.showEmojiKeyboard) { this.emojiButtonRef.nativeElement.click(); this.showEmojiKeyboard = !this.showEmojiKeyboard; } if (this.showStickerKeyboard) { this.stickerButtonRef.nativeElement.click(); this.showStickerKeyboard = !this.showStickerKeyboard; this.ref.detectChanges(); } if (this.showAiFeatures) { this.aiButtonRef.nativeElement.click(); this.showAiFeatures = !this.showAiFeatures; this.ref.detectChanges(); } else { return; } }; this.handleAiFeaturesClose = (callback) => { this.aiFeaturesCloseCallback = callback; }; this.closeSmartReply = () => { this.showAiFeatures = false; this.ref.detectChanges(); return; }; this.openAiFeatures = (event) => { if (this.aiFeaturesCloseCallback) { this.aiFeaturesCloseCallback(); } if (event?.detail?.hasOwnProperty("isOpen")) { this.showAiFeatures = false; this.ref.detectChanges(); return; } this.showAiFeatures = !this.showAiFeatures; this.closeMediaRecorder(); if (this.showEmojiKeyboard) { this.emojiButtonRef.nativeElement.click(); this.showEmojiKeyboard = !this.showEmojiKeyboard; } if (this.showStickerKeyboard) { this.stickerButtonRef.nativeElement.click(); this.showStickerKeyboard = !this.showStickerKeyboard; this.ref.detectChanges(); } if (this.showActionSheetItem) { this.actionSheetRef.nativeElement.click(); this.showActionSheetItem = !this.showActionSheetItem; this.ref.detectChanges(); } else { this.showActionSheetItemAI = true; return; } }; this.openEmojiKeyboard = (event) => { if (event?.detail?.hasOwnProperty("isOpen")) { this.showEmojiKeyboard = false; this.ref.detectChanges(); return; } this.showEmojiKeyboard = !this.showEmojiKeyboard; this.closeMediaRecorder(); if (this.showActionSheetItem) { this.actionSheetRef.nativeElement.click(); this.showActionSheetItem = !this.showActionSheetItem; this.ref.detectChanges(); } if (this.showStickerKeyboard) { this.stickerButtonRef.nativeElement.click(); this.showStickerKeyboard = !this.showStickerKeyboard; this.ref.detectChanges(); } if (this.showAiFeatures) { this.aiButtonRef.nativeElement.click(); this.showAiFeatures = !this.showAiFeatures; this.ref.detectChanges(); } else { return; } }; this.openMediaRecorded = (event) => { if (event?.detail?.hasOwnProperty("isOpen")) { this.toggleMediaRecorded = false; this.ref.detectChanges(); return; } this.toggleMediaRecorded = !this.toggleMediaRecorded; this.ref.detectChanges(); if (this.showActionSheetItem) { this.actionSheetRef.nativeElement.click(); this.showActionSheetItem = !this.showActionSheetItem; this.ref.detectChanges(); } if (this.showEmojiKeyboard) { this.emojiButtonRef.nativeElement.click(); this.showEmojiKeyboard = !this.showEmojiKeyboard; this.ref.detectChanges(); } if (this.showStickerKeyboard) { this.stickerButtonRef.nativeElement.click(); this.showStickerKeyboard = !this.showStickerKeyboard; this.ref.detectChanges(); } if (this.showAiFeatures) { this.aiButtonRef.nativeElement.click(); this.showAiFeatures = !this.showAiFeatures; this.ref.detectChanges(); } else { return; } }; this.openStickerKeyboard = (event) => { if (event?.detail?.hasOwnProperty("isOpen")) { this.showStickerKeyboard = false; this.ref.detectChanges(); return; } this.showStickerKeyboard = !this.showStickerKeyboard; this.closeMediaRecorder(); this.ref.detectChanges(); if (this.showActionSheetItem) { this.actionSheetRef.nativeElement.click(); this.showActionSheetItem = !this.showActionSheetItem; this.ref.detectChanges(); } if (this.showEmojiKeyboard) { this.emojiButtonRef.nativeElement.click(); this.showEmojiKeyboard = !this.showEmojiKeyboard; this.ref.detectChanges(); } else { return; } }; /** * Check for developer provided instance of MentionsTextFormatter * If not provided, add default * If provided, check if style is provided via configuration, then add style. */ this.initializeMentionsFormatter = () => { if (!this.disableMentions) { this.mentionsTextFormatterInstance.setMentionsTextStyle(this.getMentionsStyle()); let foundMentionsFormatter; if (this.textFormatters.length) { for (let i = 0; i < this.textFormatterList.length; i++) { if (this.textFormatterList[i] instanceof CometChatMentionsFormatter) { foundMentionsFormatter = this.textFormatterList[i]; this.mentionsTextFormatterInstance = foundMentionsFormatter; break; } } } if (foundMentionsFormatter) { this.mentionsTextFormatterInstance = foundMentionsFormatter; } if (!this.mentionsTextFormatterInstance.getKeyUpCallBack() || this.mentionsTextFormatterInstance.getKeyDownCallBack()) { this.mentionsTextFormatterInstance.setKeyUpCallBack(this.searchMentions); this.mentionsTextFormatterInstance.setKeyDownCallBack(this.searchMentions); this.mentionsTextFormatterInstance.setId(this.mentionsFormatterInstanceId); } if (!foundMentionsFormatter) { this.textFormatterList.push(this.mentionsTextFormatterInstance); } } }; this.getMentionsStyle = () => { return this.mentionStyleLocal; }; this.getSmartReplies = () => { this.showSmartReply = true; this.repliesArray = []; this.showActionSheetItemAI = false; this.showAiBotList = false; this.smartReplyState = States.loading; this.ref.detectChanges(); return new Promise((resolve, reject) => { let receiverId = this.user ? this.user?.getUid() : this.group?.getGuid(); let receiverType = this.user ? CometChatUIKitConstants.MessageReceiverType.user : CometChatUIKitConstants.MessageReceiverType.group; CometChat.getSmartReplies(receiverId, receiverType) .then((response) => { let repliesArray = []; Object.keys(response).forEach((reply) => { if (response[reply] && response[reply] != "") { this.repliesArray.push(response[reply]); repliesArray.push(response[reply]); } }); resolve(repliesArray); this.smartReplyState = States.loaded; this.ref.detectChanges(); }) .catch((err) => { this.smartReplyState = States.error; this.ref.detectChanges(); return reject(err); }); }); }; this.showAiBotMessageListMethod = (action) => { this.aiBotList = action; this.showActionSheetItemAI = false; this.showAiBotList = true; this.aiActionButtons.length = 0; this.aiBotList.forEach((e, i) => { const newButton = { id: e.id, title: e.title, onClick: async () => { CometChatUIEvents.ccShowPanel.next({ child: { bot: e, showBotView: true }, }); }, }; this.aiActionButtons.push(newButton); }); this.ref.detectChanges(); }; this.sendReply = (event) => { let reply = event?.detail?.reply; CometChatUIEvents.ccComposeMessage.next(reply); this.repliesArray = []; this.showActionSheetItemAI = false; this.showAiFeatures = false; this.aiButtonRef.nativeElement.click(); this.ref.detectChanges(); }; this.backButtonStyle = () => { return { height: "24px", width: "24px", border: "none", borderRadius: "0", background: "transparent", buttonIconTint: this.themeService.theme.palette.getPrimary(), }; }; /** * Accepts search term from mentionsTextFormatter and opens the mentions select list * * @param {string} searchTerm * @returns {void} */ this.searchMentions = (searchTerm) => { if (!(searchTerm && searchTerm.length)) { this.mentionsSearchTerm = ""; this.showListForMentions = false; this.mentionsSearchCount = 1; this.ref.detectChanges(); return; } if (!this.lastEmptySearchTerm || !searchTerm .split("@")[1] .toLowerCase() .startsWith(this.lastEmptySearchTerm.toLowerCase())) { this.mentionsSearchTerm = searchTerm.split("@")[1] && searchTerm.split("@")[1].length ? searchTerm.split("@")[1] : ""; this.showListForMentions = true; this.mentionsSearchCount++; this.lastEmptySearchTerm = undefined; this.ref.detectChanges(); } }; /** * Called when clicking a user from the mentions list. * Add the user to mentions text formatter instance and then call rerender to style the mention * within message input. * * @param {CometChat.User} user */ this.defaultMentionsItemClickHandler = (user) => { let cometChatUsers = [user]; this.mentionsTextFormatterInstance.setCometChatUserGroupMembers(cometChatUsers); this.mentionsTextFormatterInstance.setLoggedInUser(this.loggedInUser); this.mentionedUsers = [ ...this.mentionsTextFormatterInstance.getCometChatUserGroupMembers(), ]; this.mentionsTextFormatterInstance.reRender(); this.showListForMentions = false; this.mentionsSearchTerm = ""; this.ref.detectChanges(); }; /** * Close mentions list if search returns empty list */ this.defaultOnEmptyForMentions = () => { this.lastEmptySearchTerm = this.mentionsSearchTerm; this.showListForMentions = false; this.mentionsSearchTerm = ""; this.ref.detectChanges(); }; this.getMentionInfoIconStyle = () => { return { height: "fit-content", width: "fit-content", buttonTextFont: fontHelper(this.themeService.theme.typography.subtitle2), buttonTextColor: this.themeService.theme.palette.getAccent600(), borderRadius: "8px", border: "none", buttonIconTint: this.themeService.theme.palette.getAccent600(), padding: "8px", iconHeight: "20px", iconWidth: "20px", iconBackground: "transparent", gap: "5px", }; }; this.handleClickOutside = (event) => { if (this.userMemberWrapperRef) { const userMemberWrapperRect = this.userMemberWrapperRef?.nativeElement?.getBoundingClientRect(); const isOutsideClick = event?.clientX <= userMemberWrapperRect?.left || event?.clientX >= userMemberWrapperRect?.right || event?.clientY >= userMemberWrapperRect?.top || event?.clientY <= userMemberWrapperRect?.bottom; if (isOutsideClick) { this.showListForMentions = false; this.mentionsSearchTerm = ""; this.ref.detectChanges(); } } }; } disableSendButton() { this.sendButtonStyle = { height: "24px", width: "24px", border: "none", borderRadius: "0", buttonIconTint: this.themeService.theme.palette.getAccent200(), background: "transparent", }; this.ref.detectChanges(); } sendReaction() { let receiverId = this.user ? this.user?.getUid() : this.group?.getGuid(); let receiverType = this.user ? CometChatUIKitConstants.MessageReceiverType.user : CometChatUIKitConstants.MessageReceiverType.group; let data = { type: "live_reaction", reaction: "heart", }; let transientMessage = new CometChat.TransientMessage(receiverId, receiverType, data); CometChat.sendTransientMessage(transientMessage); CometChatMessageEvents.ccLiveReaction.next("heart"); return; } closeMediaRecorder(event) { if (this.toggleMediaRecorded) { this.mediaRecordedRef.nativeElement.click(); this.toggleMediaRecorded = !this.toggleMediaRecorded; this.ref.detectChanges(); } } getFormattedDate() { const currentDate = new Date(); const year = currentDate.getFullYear().toString(); const month = this.padZero(currentDate.getMonth() + 1); const day = this.padZero(currentDate.getDate()); const hours = this.padZero(currentDate.getHours()); const minutes = this.padZero(currentDate.getMinutes()); const seconds = this.padZero(currentDate.getSeconds()); return `${year}${month}${day}${hours}${minutes}${seconds}`; } padZero(num) { return num.toString().padStart(2, "0"); } addAttachmentCallback() { this.composerActions?.forEach((element) => { switch (element.id) { case CometChatUIKitConstants.MessageTypes.audio: if (!element.onClick) { element.onClick = this.openAudioPicker; } break; case CometChatUIKitConstants.MessageTypes.video: if (!element.onClick) { element.onClick = this.openvideoPicker; } break; case CometChatUIKitConstants.MessageTypes.file: if (!element.onClick) { element.onClick = this.openFilePicker; } break; case CometChatUIKitConstants.MessageTypes.image: if (!element.onClick) { element.onClick = this.openImagePicker; } break; case "extension_poll": if (!element.onClick) { element.onClick = this.openCreatePolls; } break; } }); } subscribeToEvents() { this.ccMessageEdit = CometChatMessageEvents.ccMessageEdited.subscribe((object) => { let parentId = object?.message?.getParentMessageId(); if ((this.parentMessageId && parentId && parentId == this.parentMessageId) || (!this.parentMessageId && !parentId)) { if (object?.status == MessageStatus.inprogress) { this.messageToBeEdited = object.message; if (this.isPartOfCurrentChatForUIEvent(object?.message)) { this.openEditPreview(); } } if (object?.status === MessageStatus.success && object.message instanceof CometChat.TextMessage) { this.closePreview(); } } }); this.ccComposeMessage = CometChatUIEvents.ccComposeMessage.subscribe((text) => { this.text = text; this.ref.detectChanges(); }); this.ccShowMentionsCountWarning = CometChatUIEvents.ccShowMentionsCountWarning.subscribe((data) => { if (data.id == this.mentionsFormatterInstanceId) { if (data.showWarning) { this.showMentionsCountWarning = true; return; } this.showMentionsCountWarning = false; } }); } openEditPreview() { let messageTextWithMentionTags = this.checkForMentions(this.messageToBeEdited); this.clearComposer(); this.inputRef.nativeElement.text = ""; this.text = this.messageToBeEdited.getText(); this.editPreviewText = messageTextWithMentionTags; this.showPreview = true; this.ref.detectChanges(); } /** * Adds @ for every mention the message by matching uid * * @param {string} message * @returns {void} */ checkForMentions(message) { const regex = /<@uid:(.*?)>/g; let messageText = message.getText(); let messageTextTmp = messageText; let match = regex.exec(messageText); let mentionedUsers = message.getMentionedUsers(); let cometChatUsersGroupMembers = []; while (match !== null) { let user; for (let i = 0; i < mentionedUsers.length; i++) { if (match[1] == mentionedUsers[i].getUid()) { user = mentionedUsers[i]; } } if (user) { messageTextTmp = messageTextTmp.replace(match[0], "@" + user.getName()); cometChatUsersGroupMembers.push(user); } match = regex.exec(messageText); } this.mentionsTextFormatterInstance.setCometChatUserGroupMembers(cometChatUsersGroupMembers); this.mentionsTextFormatterInstance.setLoggedInUser(this.loggedInUser); return messageTextTmp; } unsubscribeToEvents() { this.ccMessageEdit?.unsubscribe(); this.ccShowMentionsCountWarning?.unsubscribe(); } closeModals() { if (this.showActionSheetItem) { this.actionSheetRef?.nativeElement?.click(); this.showActionSheetItem = false; } if (this.showEmojiKeyboard) { this.emojiButtonRef?.nativeElement?.click(); this.showEmojiKeyboard = false; } if (this.showStickerKeyboard) { this.stickerButtonRef?.nativeElement?.click(); this.showStickerKeyboard = false; } if (this.toggleMediaRecorded) { this.mediaRecordedRef?.nativeElement?.click(); this.toggleMediaRecorded = false; } if (this.showAiFeatures) { this.aiButtonRef?.nativeElement?.click(); this.showAiFeatures = false; this.showAiBotList = false; } } callConversationSummaryMethod() { this.showAiFeatures = false; this.aiButtonRef.nativeElement.click(); CometChatUIEvents.ccShowPanel.next({ child: { showConversationSummaryView: true }, }); } clearComposer() { this.text = ""; this.messageText = ""; this.inputRef?.nativeElement?.emptyInputField(); } ngOnChanges(changes) { if (changes["user"] || changes["group"]) { this.userOrGroupChanged(changes); if (this.initialText !== this.text) { this.clearComposer(); } this.text = this.initialText || ""; } if (changes["text"]?.currentValue) { this.initialText = changes["text"].currentValue; this.text = this.initialText; } } userOrGroupChanged(changes) { if (this.showPreview) { this.closePreview(); } if (!this.disableMentions) { this.showListForMentions = false; if (changes["group"] && this.group) { if (this.userMemberWrapperConfiguration?.userMemberListType == undefined) { this.userMemberListType = UserMemberListType.groupmembers; } this.groupMembersRequestBuilder = this.userMemberWrapperConfiguration .groupMemberRequestBuilder ? this.userMemberWrapperConfiguration.groupMemberRequestBuilder : new CometChat.GroupMembersRequestBuilder(this.group.getGuid()).setLimit(15); } if (changes["user"] && this.user) { if (this.userMemberWrapperConfiguration?.userMemberListType == undefined) { this.userMemberListType = UserMemberListType.users; } this.usersRequestBuilder = this.userMemberWrapperConfiguration .usersRequestBuilder ? this.userMemberWrapperConfiguration.usersRequestBuilder : new CometChat.UsersRequestBuilder().setLimit(15); } } this.showAiBotList = false; this.showSmartReply = false; this.closeModals(); this.messageText = this.text; if (this.inputRef && this.inputRef.nativeElement) { setTimeout(() => { this.inputRef?.nativeElement?.emptyInputField(); this.inputRef?.nativeElement?.pasteHtmlAtCaret(this.text); }, 0); } this.showSendButton = false; this.composerId = this.getComposerId(); if (this.attachmentOptions) { this.composerActions = this.attachmentOptions(this.user || this.group, this.composerId); this.addAttachmentCallback(); } else { this.composerActions = ChatConfigurator.getDataSource()?.getAttachmentOptions(this.themeService.theme, this.user, this.group, this.composerId); this.addAttachmentCallback(); } for (let i = 0; i < this.textFormatterList.length; i++) { this.textFormatterList[i].setComposerConfig(this.user, this.group, this.composerId); } } ngOnDestroy() { this.unsubscribeToEvents(); this.mentionsTextFormatterInstance.cleanup(); } customSendMethod(message) { this.showSendButton = false; this.sendTextMessage(message); this.disableSendButton(); this.ref.detectChanges(); } /** * @param {String=""} textMsg */ sendTextMessage(textMsg = "") { this.endTyping(); try { // Dont Send Blank text messages -- i.e --- messages that only contain spaces if (this.messageText?.trim()?.length == 0 && textMsg?.trim()?.length == 0) { return false; } // wait for the previous message to be sent before sending the current message if (this.messageSending) { return false; } this.messageSending = true; // If its an Edit and Send Message Operation , use Edit Message Function if (this.messageToBeEdited) { this.editMessage(); this.ref.detectChanges(); return false; } let { receiverId, receiverType } = this.getReceiverDetails(); let messageInput; if (textMsg !== null) { messageInput = textMsg.trim(); } else { messageInput = this.messageText.trim(); } let textMessage = new CometChat.TextMessage(receiverId, messageInput, receiverType); if (this.parentMessageId) { textMessage.setParentMessageId(this.parentMessageId); } if (this.mentionedUsers.length) { let userObjects = []; for (let i = 0; i < this.mentionedUsers.length; i++) { userObjects.push(this.mentionedUsers[i] instanceof CometChat.GroupMember ? this.mentionedUsers[i] : this.mentionedUsers[i]); } textMessage.setMentionedUsers(userObjects); this.mentionedUsers = []; } textMessage.setSentAt(CometChatUIKitUtility.getUnixTimestamp()); textMessage.setMuid(CometChatUIKitUtility.ID()); if (this.loggedInUser) { textMessage.setSender(this.loggedInUser); } this.showMentionsCountWarning = false; // play audio after action generation if (!this.disableSoundForMessages) { this.playAudio(); } //clearing Message Input Box this.clearComposer(); this.messageSending = false; for (let i = 0; i < this.textFormatterList.length; i++) { textMessage = this.textFormatterList[i].formatMessageForSending(textMessage); } // End Typing Indicator Function this.closePopovers(); if (!this.onSendButtonClick) { CometChatMessageEvents.ccMessageSent.next({ message: textMessage, status: MessageStatus.inprogress, }); CometChat.sendMessage(textMessage) .then((message) => { let messageObject = message; CometChatMessageEvents.ccMessageSent.next({ message: messageObject, status: MessageStatus.success, }); // Change the send button to reaction button setTimeout(() => { this.showSendButton = false; this.ref.detectChanges(); }, 500); this.mentionsTextFormatterInstance.resetCometChatUserGroupMembers(); }) .catch((error) => { textMessage.setMetadata({ error: true, }); CometChatMessageEvents.ccMessageSent.next({ message: textMessage, status: MessageStatus.error, }); }); } else { this.onSendButtonClick(textMessage, PreviewMessageMode.none); } } catch (error) { if (this.onError) { this.onError(CometChatException(error)); } } return true; } onAiBackButtonClick() { this.showActionSheetItemAI = true; this.ref.detectChanges(); } editMessage() { try { const messageToBeEdited = this.messageToBeEdited; let { receiverId, receiverType } = this.getReceiverDetails(); let messageText = this.messageText.trim(); let mentionedUsers = []; if (messageToBeEdited.getMentionedUsers()) { mentionedUsers = messageToBeEdited.getMentionedUsers(); messageText = this.mentionsTextFormatterInstance.getOriginalText(messageText); this.mentionsTextFormatterInstance.setCometChatUserGroupMembers(mentionedUsers); messageText = this.mentionsTextFormatterInstance.getOriginalText(messageText); } let textMessage = new CometChat.TextMessage(receiverId, messageText, receiverType); if (mentionedUsers.length) { textMessage.setMentionedUsers(mentionedUsers); } textMessage.setId(messageToBeEdited.id); this.closePreview(); this.endTyping(); this.showMentionsCountWarning = false; for (let i = 0; i < this.textFormatterList.length; i++) { textMessage = this.textFormatterList[i].formatMessageForSending(textMessage); } if (!this.onSendButtonClick) { CometChat.editMessage(textMessage) .then((message) => { this.messageSending = false; CometChatMessageEvents.ccMessageEdited.next({ message: message, status: MessageStatus.success, }); this.mentionsTextFormatterInstance.resetCometChatUserGroupMembers(); }) .catch((error) => { this.messageSending = false; if (this.onError) { this.onError(error); } }); } else { this.onSendButtonClick(textMessage, PreviewMessageMode.edit); this.mentionsTextFormatterInstance.resetCometChatUserGroupMembers(); } } catch (error) { if (this.onError) { this.onError(CometChatException(error)); } } } getReceiverDetails() { let receiverId; let receiverType; let isBlocked = false; if (this.user && this.user.getUid()) { receiverId = this.user.getUid(); receiverType = CometChatUIKitConstants.MessageReceiverType.user; isBlocked = this.user.getBlockedByMe() || this.user.getHasBlockedMe(); } else if (this.group && this.group.getGuid()) { receiverId = this.group.getGuid(); receiverType = CometChatUIKitConstants.MessageReceiverType.group; } return { receiverId: receiverId, receiverType: receiverType, isBlocked }; } playAudio() { if (!this.disableSoundForMessages) { if (this.customSoundForMessage || this.customSoundForMessages) { CometChatSoundManager.play(CometChatSoundManager.Sound.outgoingMessage, this.customSoundForMessage || this.customSoundForMessages); } else { CometChatSoundManager.play(CometChatSoundManager.Sound.outgoingMessage); } } } /** * @param {} timer=null * @param {string=""} metadata */ startTyping(timer = null, metadata = "") { if (!this.disableTypingEvents) { try {