UNPKG

@cometchat/chat-uikit-angular

Version:

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

1,097 lines (1,096 loc) 289 kB
import "@cometchat/uikit-elements"; import { AvatarStyle, BadgeStyle, ConfirmDialogStyle, DateStyle, ListItemStyle, ReceiptStyle, } from "@cometchat/uikit-elements"; import { CometChatSoundManager, CometChatUIKitUtility, ConversationUtils, ConversationsStyle, ListStyle, MessageReceiptUtils, } from "@cometchat/uikit-shared"; import { CometChatCallEvents, CometChatConversationEvents, CometChatGroupEvents, CometChatMessageEvents, CometChatUIKitConstants, CometChatUserEvents, DatePatterns, MentionsTargetElement, MessageStatus, SelectionMode, States, TitleAlignment, fontHelper, localize, } from "@cometchat/uikit-resources"; import { ChangeDetectionStrategy, Component, Input, } from "@angular/core"; import { ChatConfigurator } from "../../Shared/Framework/ChatConfigurator"; import { CometChat } from "@cometchat/chat-sdk-javascript"; import { CometChatException } from "../../Shared/Utils/ComeChatException"; import { CometChatUIKit } from "../../Shared/CometChatUIkit/CometChatUIKit"; import { MessageUtils } from "../../Shared/Utils/MessageUtils"; import * as i0 from "@angular/core"; import * as i1 from "../../CometChatTheme.service"; import * as i2 from "@angular/platform-browser"; import * as i3 from "../../CometChatList/cometchat-list.component"; import * as i4 from "@angular/common"; /** * * CometChatConversation is a wrapper component consists of CometChatListBaseComponent and ConversationListComponent. * * @version 1.0.0 * @author CometChatTeam * @copyright © 2022 CometChat Inc. * */ export class CometChatConversationsComponent { constructor(ngZone, ref, themeService, sanitizer) { this.ngZone = ngZone; this.ref = ref; this.themeService = themeService; this.sanitizer = sanitizer; this.title = localize("CHATS"); //Title of the component this.searchPlaceHolder = localize("SEARCH"); // placeholder text of search input this.disableUsersPresence = false; /** * @deprecated * * This property is deprecated as of version 4.3.16 due to newer property 'hideReceipt'. It will be removed in subsequent versions. */ this.disableReceipt = false; this.hideReceipt = false; this.disableTyping = false; this.deliveredIcon = "assets/message-delivered.svg"; this.readIcon = "assets/message-read.svg"; this.errorIcon = "assets/warning-small.svg"; this.datePattern = DatePatterns.DayDateTime; this.onError = (error) => { console.log(error); }; this.sentIcon = "assets/message-sent.svg"; this.privateGroupIcon = "assets/Private.svg"; /** * @deprecated * * This property is deprecated as of version 4.3.7 due to newer property 'passwordGroupIcon'. It will be removed in subsequent versions. */ this.protectedGroupIcon = "assets/Locked.svg"; this.passwordGroupIcon = undefined; this.customSoundForMessages = ""; this.activeConversation = null; //selected conversation this.searchIconURL = "assets/search.svg"; //image URL of the search icon this.hideSearch = true; //switch on/ff search input this.loadingIconURL = "assets/Spinner.svg"; this.emptyStateText = localize("NO_CHATS_FOUND"); this.errorStateText = localize("SOMETHING_WRONG"); this.titleAlignment = TitleAlignment.left; this.hideSeparator = false; this.searchPlaceholder = localize("SEARCH"); this.hideError = false; this.selectionMode = SelectionMode.none; this.disableSoundForMessages = false; this.confirmDialogTitle = localize("DELETE_CONVERSATION"); this.confirmButtonText = localize("DELETE"); this.cancelButtonText = localize("CANCEL"); this.confirmDialogMessage = localize("WOULD__YOU_LIKE_TO_DELETE_THIS_CONVERSATION"); this.deleteConversationDialogStyle = new ConfirmDialogStyle({ confirmButtonBackground: this.themeService.theme.palette.getError(), cancelButtonBackground: this.themeService.theme.palette.getSecondary(), confirmButtonTextColor: this.themeService.theme.palette.getAccent900("light"), confirmButtonTextFont: fontHelper(this.themeService.theme.typography.text2), cancelButtonTextColor: this.themeService.theme.palette.getAccent900("dark"), cancelButtonTextFont: fontHelper(this.themeService.theme.typography.text2), titleFont: fontHelper(this.themeService.theme.typography.title1), titleColor: this.themeService.theme.palette.getAccent(), messageTextFont: fontHelper(this.themeService.theme.typography.subtitle2), messageTextColor: this.themeService.theme.palette.getAccent600(), background: this.themeService.theme.palette.getBackground(), height: "100%", width: "100%", borderRadius: "8px", }); this.backdropStyle = { height: "100%", width: "100%", background: "rgba(0, 0, 0, 0.5)", position: "fixed", }; this.badgeStyle = { width: "25px", height: "15px", background: "#5aaeff", textColor: "white", textFont: "400 13px Inter, sans-serif", borderRadius: "16px", }; this.dateStyle = { textFont: "400 11px Inter, sans-serif", textColor: "rgba(20, 20, 20, 0.58)", }; this.conversationsStyle = { width: "", height: "", border: "", borderRadius: "", }; this.listItemStyle = { height: "97%", width: "100%", }; this.statusIndicatorStyle = { height: "10px", width: "10px", borderRadius: "16px", }; this.typingIndicatorText = localize("IS_TYPING"); this.threadIndicatorText = localize("IN_A_THREAD"); this.avatarStyle = {}; this.receiptStyle = {}; this.iconStyle = { iconTint: "lightgrey", height: "20px", width: "20px", }; this.listStyle = new ListStyle({}); this.menustyle = { width: "", height: "", border: "none", borderRadius: "8px", background: "transparent", textFont: "", textColor: "black", iconTint: "grey", iconBackground: "transparent", iconBorder: "none", iconBorderRadius: "0", submenuWidth: "70px", submenuHeight: "20px", submenuBorder: "1px solid #e8e8e8", submenuBorderRadius: "8px", submenuBackground: "white", }; this.typingListenerId = "conversation__LISTENER" + new Date().getTime(); this.callListenerId = "call_" + new Date().getTime(); this.connectionListenerId = "connection_" + new Date().getTime(); this.selectionmodeEnum = SelectionMode; this.isDialogOpen = false; this.isEmpty = false; this.isLoading = true; this.state = States.loading; this.statusColor = { online: "", private: "", password: "#F7A500", public: "", }; this.limit = 30; this.isError = false; this.conversationList = []; this.scrolledToBottom = false; this.checkItemChange = false; this.showConfirmDialog = false; this.conversationToBeDeleted = null; this.userListenerId = "chatlist_user_" + new Date().getTime(); this.groupListenerId = "chatlist_group_" + new Date().getTime(); this.groupToUpdate = {}; this.conversationType = undefined; this.enablePolls = false; this.enableStickers = false; this.enableWhiteboard = false; this.enableDocument = false; this.threadIconURL = "assets/thread-arrow.svg"; this.confirmDialogStyle = { height: "100%", width: "100%", borderRadius: "8px", }; this.modalStyle = { height: "230px", width: "270px", }; this.firstReload = false; this.isActive = true; this.contactsNotFound = false; this.checkboxStyle = { height: "24px", width: "24px", border: "none", borderRadius: "4px", checkedBackgroundColor: "#2196F3", uncheckedBackgroundColor: "#ccc" }; /** * Properties for internal use */ this.localize = localize; //To be enabled in UMC // @Input() mentionsIconURL!: string; this.disableMentions = false; /** * Properties for internal use */ /** * passing this callback to menuList component on delete click * @param {CometChat.Conversation} conversation */ this.deleteConversationOnClick = () => { this.showConfirmationDialog(this.conversationToBeDeleted); }; // callback for confirmDialogComponent this.onConfirmClick = () => { this.deleteSelectedConversation(); }; this.getStatusIndicatorStyle = (conversation) => { const convWith = conversation.getConversationWith(); if (convWith instanceof CometChat.User) { let userStatusVisibility = new MessageUtils().getUserStatusVisibility(convWith); if (!this.disableUsersPresence && !userStatusVisibility) { return this.statusIndicatorStyle; } return null; } else if (conversation.getConversationType() === CometChatUIKitConstants.MessageReceiverType.group) { return { height: "12px", width: "12px", borderRadius: "16px", }; } else { return null; } }; this.setSubtitle = (conversationObject) => { if (this.typingIndicator) { const isTyping = conversationObject?.conversationWith?.guid == this.typingIndicator.getReceiverId(); if (isTyping) { return `${this.typingIndicator.getSender().getName()} ${this.typingIndicatorText}`; } else if (conversationObject?.conversationWith?.uid == this.typingIndicator?.getSender().getUid() && this.typingIndicator.getReceiverType() !== CometChatUIKitConstants.MessageReceiverType.group) { return this.typingIndicatorText; } } let subtitle = ChatConfigurator.getDataSource().getLastConversationMessage(conversationObject, this.loggedInUser, { disableMentions: this.disableMentions, theme: this.themeService.theme, mentionsTargetElement: MentionsTargetElement.conversation, textFormatters: this.textFormatters }); let icon = conversationObject?.getLastMessage()?.getType() == CometChatUIKitConstants.MessageTypes.audio ? "📞 " : "📹 "; return this.sanitizer.bypassSecurityTrustHtml(conversationObject?.getLastMessage()?.getCategory() == CometChatUIKitConstants.MessageCategory.call ? icon + subtitle : subtitle); }; // callback for confirmDialogComponent this.onCancelClick = () => { this.isDialogOpen = false; this.conversationToBeDeleted = null; this.ref.detectChanges(); }; this.getMessageReceipt = (conversation) => { let receipt = MessageReceiptUtils.getReceiptStatus(conversation.getLastMessage()); return receipt; }; this.optionsStyle = { background: "transparent", border: "none", }; /** * Fetches Conversations Details with all the users */ this.getConversation = (states = States.loading) => { if (this.requestBuilder && this.requestBuilder.pagination && (this.requestBuilder.pagination.current_page == 0 || this.requestBuilder.pagination.current_page != this.requestBuilder.pagination.total_pages)) { try { this.state = states; CometChat.getLoggedinUser() .then((user) => { this.loggedInUser = user; this.fetchNextConversation() .then((conversationList) => { conversationList.forEach((conversation) => { if (this.activeConversation && this.activeConversation !== null && this.activeConversation.getConversationType() === conversation.getConversationType()) { if (this.activeConversation.getConversationId() == conversation.getConversationId()) { conversation.setUnreadMessageCount(0); //conversation.setUnreadMentionInMessageCount(0); } } }); if (states == States.loaded) { this.conversationList = [...conversationList]; } else { this.conversationList = [ ...this.conversationList, ...conversationList, ]; } if (conversationList.length <= 0 && this.conversationList?.length <= 0) { this.ngZone.run(() => { if (this.state != States.empty) { this.state = States.empty; this.ref.detectChanges(); } this.ref.detach(); // Detach the change detector }); } else { this.ngZone.run(() => { this.ref.detectChanges(); if (this.state != States.loaded) { this.state = States.loaded; this.ref.detectChanges(); } this.ref.detach(); // Detach the change detector }); } if (this.firstReload) { this.attachConnectionListeners(); this.firstReload = false; } }) .catch((error) => { if (this.onError) { this.onError(error); } if (this.conversationList?.length <= 0) { this.state = States.error; this.ref.detectChanges(); } }); }) .catch((error) => { if (this.onError) { this.onError(error); } this.state = States.error; this.ref.detectChanges(); }); } catch (error) { if (this.onError) { this.onError(CometChatException(error)); } } } }; /** * Updates the conversation list's last message , badgeCount , user presence based on activities propagated by listeners */ this.conversationUpdated = (key, item = null, message, options = null) => { try { switch (key) { case CometChatUIKitConstants.userStatusType.online: case CometChatUIKitConstants.userStatusType.offline: { this.updateUser(item); break; } case CometChatUIKitConstants.messages.MESSAGE_READ: { this.updateConversation(message, false); break; } case CometChatUIKitConstants.messages.MESSAGE_DELIVERED: { this.updateConversation(message, false); break; } case CometChatUIKitConstants.messages.TEXT_MESSAGE_RECEIVED: case CometChatUIKitConstants.messages.MEDIA_MESSAGE_RECEIVED: case CometChatUIKitConstants.messages.CUSTOM_MESSAGE_RECEIVED: case CometChatUIKitConstants.messages.INTERACTIVE_MESSAGE_RECEIVED: if (!this.disableReceipt) { this.markMessageAsDelivered(message); } this.updateConversation(message); break; case CometChatUIKitConstants.groupMemberAction.ADDED: case CometChatUIKitConstants.groupMemberAction.BANNED: case CometChatUIKitConstants.groupMemberAction.JOINED: case CometChatUIKitConstants.groupMemberAction.KICKED: case CometChatUIKitConstants.groupMemberAction.LEFT: case CometChatUIKitConstants.groupMemberAction.UNBANNED: case CometChatUIKitConstants.groupMemberAction.SCOPE_CHANGE: this.updateConversation(message); break; case CometChatUIKitConstants.messages.MESSAGE_EDITED: case CometChatUIKitConstants.messages.MESSAGE_DELETED: this.conversationEditedDeleted(message); break; } } catch (error) { if (this.onError) { this.onError(CometChatException(error)); } } }; /** * @param {CometChat.BaseMessage} message */ this.markMessageAsDelivered = (message) => { if (!message.hasOwnProperty("deliveredAt")) { CometChat.markAsDelivered(message); } }; /** * @param {CometChat.BaseMessage} readMessage */ this.getUinx = () => { return String(Math.round(+new Date() / 1000)); }; /** * showing dialog for confirm and cancel * @param {CometChat.Conversation|{}} conversation */ this.showConfirmationDialog = (conversation) => { this.isDialogOpen = true; this.conversationToBeDeleted = conversation; this.ref.detectChanges(); }; this.styles = { wrapperStyle: () => { return { height: this.conversationsStyle.height, width: this.conversationsStyle.width, border: this.conversationsStyle.border || `1px solid ${this.themeService.theme.palette.getAccent400()}`, borderRadius: this.conversationsStyle.borderRadius, background: this.conversationsStyle.background || this.themeService.theme.palette.getBackground(), }; }, }; this.subtitleStyle = (conversation) => { if (this.typingIndicator && ((this.typingIndicator.getReceiverType() == CometChatUIKitConstants.MessageReceiverType.user && this.typingIndicator.getSender().getUid() == conversation.conversationWith?.uid) || this.typingIndicator.getReceiverId() == conversation.conversationWith?.guid)) { return { font: this.conversationsStyle.typingIndictorTextColor, color: this.conversationsStyle.typingIndictorTextColor, }; } return { font: this.conversationsStyle.lastMessageTextFont, color: this.conversationsStyle.lastMessageTextColor, }; }; this.itemThreadIndicatorStyle = () => { return { textFont: this.conversationsStyle.threadIndicatorTextFont || fontHelper(this.themeService.theme.typography.caption2), textColor: this.conversationsStyle.threadIndicatorTextColor || this.themeService.theme.palette.getAccent400(), }; }; } onConversationSelected(conversation, event) { let selected = event.detail.checked; if (this.onSelect) { this.onSelect(conversation, selected); } } //To be enabled in UMC // getMentionIconStyle(): IconStyle { // return new IconStyle({ // height: "16px", // width: "16px", // iconTint: // this.conversationsStyle?.mentionIconTint ?? // this.themeService.theme.palette.getPrimary(), // }); // } /** * @param {CometChat.Conversation} conversation */ checkStatusType(conversation) { let item = conversation.getConversationWith(); if (item instanceof CometChat.User) { let userStatusVisibility = new MessageUtils().getUserStatusVisibility(item) || this.disableUsersPresence; if (!userStatusVisibility) return this.statusColor[item?.getStatus()]; else return null; } else { return this.statusColor[item?.getType()]; } } getExtensionData(messageObject) { let messageText; //xss extensions data const xssData = CometChatUIKitUtility.checkMessageForExtensionsData(messageObject, "xss-filter"); if (xssData && CometChatUIKitUtility.checkHasOwnProperty(xssData, "sanitized_text") && CometChatUIKitUtility.checkHasOwnProperty(xssData, "hasXSS") && xssData.hasXSS === "yes") { messageText = xssData.sanitized_text; } //datamasking extensions data const maskedData = CometChatUIKitUtility.checkMessageForExtensionsData(messageObject, "data-masking"); if (maskedData && CometChatUIKitUtility.checkHasOwnProperty(maskedData, "data") && CometChatUIKitUtility.checkHasOwnProperty(maskedData.data, "sensitive_data") && CometChatUIKitUtility.checkHasOwnProperty(maskedData.data, "message_masked") && maskedData.data.sensitive_data === "yes") { messageText = maskedData.data.message_masked; } //profanity extensions data const profaneData = CometChatUIKitUtility.checkMessageForExtensionsData(messageObject, "profanity-filter"); if (profaneData && CometChatUIKitUtility.checkHasOwnProperty(profaneData, "profanity") && CometChatUIKitUtility.checkHasOwnProperty(profaneData, "message_clean") && profaneData.profanity === "yes") { messageText = profaneData.message_clean; } return messageText || messageObject.text; } //To be enabled in UMC // getUnreadMentionsIconStyle() { // return { // paddingRight: "3px", // }; // } checkGroupType(conversation) { let image = ""; if (conversation.getConversationType() == CometChatUIKitConstants.MessageReceiverType.group) { let group = conversation.getConversationWith(); switch (group.getType()) { case CometChatUIKitConstants.GroupTypes.password: image = this.passwordGroupIcon || this.protectedGroupIcon; break; case CometChatUIKitConstants.GroupTypes.private: image = this.privateGroupIcon; break; default: image = ""; break; } } return image; } getDate() { return this.datePattern ?? DatePatterns.DayDateTime; } ngOnInit() { this.firstReload = true; if (!this.conversationsRequestBuilder) { this.conversationsRequestBuilder = new CometChat.ConversationsRequestBuilder() .setLimit(this.limit); } this.setConversationOptions(); this.setThemeStyle(); this.subscribeToEvents(); this.attachListeners(this.conversationUpdated); this.requestBuilder = this.conversationsRequestBuilder.build(); if (this.requestBuilder?.getConversationType()) { this.conversationType = this.requestBuilder.getConversationType(); } this.getConversation(); } /** * Determines if the last message should trigger an update based on its category and type. * * @param message - The last message sent or received in the conversation. * @returns {boolean} - Returns true if the message should trigger an update, false otherwise. */ checkIfLastMessageShouldUpdate(message) { if (this.conversationType && this.conversationType != message.getReceiverType()) { return false; } // Checking if the message is a custom message let isCustomMessage = message?.getCategory() === CometChatUIKitConstants.MessageCategory.custom; // Check if the message is a reply to another message if (message?.getParentMessageId() && !CometChatUIKit.conversationUpdateSettings?.shouldUpdateOnMessageReplies()) { return false; } if (isCustomMessage) { if (message?.getParentMessageId() && CometChatUIKit.conversationUpdateSettings?.shouldUpdateOnMessageReplies() && this.shouldIncrementForCustomMessage(message)) { return true; } return this.shouldIncrementForCustomMessage(message); } // Check if the message is an action message if (message?.getCategory() === CometChatUIKitConstants.MessageCategory.action) { // Check if the message is a group member action if (message?.getType() === CometChatUIKitConstants.MessageTypes.groupMember) { return CometChatUIKit.conversationUpdateSettings?.shouldUpdateOnGroupActions(); } // By default, action messages should trigger an update return true; } // Check if the message is a call (either audio or video) if (message?.getCategory() === CometChatUIKitConstants.MessageCategory.call && (message?.getType() === CometChatUIKitConstants.MessageTypes.audio || message.getType() === CometChatUIKitConstants.MessageTypes.video)) { return CometChatUIKit.conversationUpdateSettings?.shouldUpdateOnCallActivities(); } // By default, messages should trigger an update return true; } shouldIncrementForCustomMessage(message) { const metadata = message.getMetadata(); // Checking if the custom message should increment the unread message counter return message.willUpdateConversation() || (metadata && metadata.hasOwnProperty("incrementUnreadCount") && metadata.incrementUnreadCount) || CometChatUIKit.conversationUpdateSettings?.shouldUpdateOnCustomMessages(); } attachConnectionListeners() { CometChat.addConnectionListener(this.connectionListenerId, new CometChat.ConnectionListener({ onConnected: () => { console.log("ConnectionListener =>connected"); this.fetchNewConversations(); }, inConnecting: () => { console.log("ConnectionListener => In connecting"); }, onDisconnected: () => { console.log("ConnectionListener => On Disconnected"); }, })); } updateConversationObject(conversation) { if (conversation.getLastMessage() && this.checkIfLastMessageShouldUpdate(conversation.getLastMessage())) { let index = this.conversationList.findIndex((element) => element.getConversationId() == conversation.getConversationId()); this.conversationList.splice(index, 1, conversation); this.ref.detectChanges(); } } subscribeToEvents() { if (!this.conversationType || this.conversationType == CometChatUIKitConstants.MessageReceiverType.group) { this.ccGroupMemberScopeChanged = CometChatGroupEvents.ccGroupMemberScopeChanged.subscribe((item) => { let conversation = this.getConversationFromGroup(item.group); if (conversation) { conversation.setLastMessage(item.message); this.updateConversationObject(conversation); } }); this.ccGroupMemberAdded = CometChatGroupEvents.ccGroupMemberAdded.subscribe((item) => { let group = item.userAddedIn; let actionMessage = item.messages; let conversation = this.getConversationFromGroup(item.userAddedIn); conversation?.setConversationWith(group); conversation?.setLastMessage(actionMessage[actionMessage?.length - 1]); this.updateConversationObject(conversation); }); this.ccGroupMemberKicked = CometChatGroupEvents.ccGroupMemberKicked.subscribe((item) => { let conversation = this.getConversationFromGroup(item.kickedFrom); if (conversation) { conversation.setLastMessage(item.message); this.updateConversationObject(conversation); } }); this.ccGroupMemberBanned = CometChatGroupEvents.ccGroupMemberBanned.subscribe((item) => { let conversation = this.getConversationFromGroup(item.kickedFrom); if (conversation) { conversation.setLastMessage(item.message); this.updateConversationObject(conversation); } }); this.ccGroupDeleted = CometChatGroupEvents.ccGroupDeleted.subscribe((item) => { let conversation = this.getConversationFromGroup(item); if (conversation) { this.removeConversation(conversation); } }); this.ccGroupLeft = CometChatGroupEvents.ccGroupLeft.subscribe((item) => { let conversationKey = this.conversationList.findIndex((c) => c?.getConversationType() === CometChatUIKitConstants.MessageReceiverType.group && c?.getConversationWith().getGuid() == item.leftGroup.getGuid()); if (conversationKey >= 0) { let conversation = this.conversationList[conversationKey]; this.removeConversation(conversation); if (this.activeConversation && this.activeConversation?.getConversationId() == conversation?.getConversationId()) { this.activeConversation = null; } } }); } if (!this.conversationType || this.conversationType == CometChatUIKitConstants.MessageReceiverType.user) { this.ccUserBlocked = CometChatUserEvents.ccUserBlocked.subscribe((item) => { let conversation = this.getConversationFromUser(item); if (conversation && !this.requestBuilder?.isIncludeBlockedUsers()) { this.removeConversation(conversation); } else { this.updateUser(item); } this.ref.detectChanges(); }); this.ccUserUnblocked = CometChatUserEvents.ccUserUnblocked.subscribe((item) => { let conversation = this.getConversationFromUser(item); if (conversation && this.requestBuilder?.isIncludeBlockedUsers()) { this.updateUser(item); } this.ref.detectChanges(); }); } this.ccMessageEdit = CometChatMessageEvents.ccMessageEdited.subscribe((object) => { if (!this.conversationType || this.conversationType == object?.message?.getReceiverType()) { let message = object.message; if (object.status == MessageStatus.success) { this.updateEditedMessage(message); } } }); this.ccMessageSent = CometChatMessageEvents.ccMessageSent.subscribe((obj) => { let message = obj.message; if (obj.status == MessageStatus.success) { this.updateConversation(message, false); } }); this.ccMessageDelete = CometChatMessageEvents.ccMessageDeleted.subscribe((messageObject) => { this.updateConversation(messageObject); this.ref.detectChanges(); }); this.ccMessageRead = CometChatMessageEvents.ccMessageRead.subscribe((messageObject) => { if (!this.conversationType || this.conversationType == messageObject.getReceiverType()) { CometChat.CometChatHelper.getConversationFromMessage(messageObject).then((conversation) => { if (conversation && this.activeConversation && conversation?.getConversationId() == this.activeConversation?.getConversationId()) { this.updateEditedMessage(messageObject); this.resetUnreadCount(); } }); } }); this.ccCallEnded = CometChatCallEvents.ccCallEnded.subscribe((call) => { if (call && Object.keys(call).length > 0) { this.updateConversation(call); } }); this.ccCallRejected = CometChatCallEvents.ccCallRejected.subscribe((call) => { this.updateConversation(call); }); this.ccOutgoingCall = CometChatCallEvents.ccOutgoingCall.subscribe((call) => { this.updateConversation(call); }); this.ccCallAccepted = CometChatCallEvents.ccCallAccepted.subscribe((call) => { this.updateConversation(call); }); } unsubscribeToEvents() { this.ccGroupMemberAdded?.unsubscribe(); this.ccGroupMemberKicked?.unsubscribe(); this.ccGroupMemberBanned?.unsubscribe(); this.ccMessageEdit?.unsubscribe(); this.ccMessageSent?.unsubscribe(); this.ccMessageEdited?.unsubscribe(); this.ccMessageDelete?.unsubscribe(); this.ccGroupDeleted?.unsubscribe(); this.ccGroupLeft?.unsubscribe(); this.ccUserBlocked?.unsubscribe(); this.ccUserUnblocked?.unsubscribe(); this.ccMessageRead?.unsubscribe(); } getConversationFromUser(user) { let index = this.conversationList.findIndex((element) => element.getConversationType() == CometChatUIKitConstants.MessageReceiverType.user && element.getConversationWith().getUid() == user.getUid()); if (index >= 0) { return this.conversationList[index]; } return null; } getConversationFromGroup(group) { let index = this.conversationList.findIndex((element) => element.getConversationType() == CometChatUIKitConstants.MessageReceiverType.group && element.getConversationWith().getGuid() == group.getGuid()); if (index >= 0) { return this.conversationList[index]; } return null; } ngOnChanges(change) { try { if (change["activeConversation"]) { this.resetUnreadCount(); this.ref.detectChanges(); } if (change["conversationsStyle"]) { this.setThemeStyle(); } /** * When user sends message conversationList is updated with latest message */ } catch (error) { if (this.onError) { this.onError(CometChatException(error)); } } } ngOnDestroy() { try { this.removeListeners(); this.unsubscribeToEvents(); } catch (error) { if (this.onError) { this.onError(CometChatException(error)); } } this.ref.detectChanges(); } // getting default conversation option and adding callback in it setConversationOptions() { if (this.options) { return; } this.conversationOptions = ConversationUtils.getDefaultOptions(); this.conversationOptions.forEach((element) => { if (!element.onClick && element.id == CometChatUIKitConstants.ConversationOptions.delete) { element.onClick = this.deleteConversationOnClick; } }); return; } // reset unread count onClick(conversation) { if (this.onItemClick) { this.onItemClick(conversation); } } // set unread count resetUnreadCount() { if (this.activeConversation) { const conversationlist = [ ...this.conversationList, ]; //Gets the index of user which comes offline/online const conversationKey = conversationlist.findIndex((conversationObj) => conversationObj?.getConversationId() === this.activeConversation?.getConversationId()); if (conversationKey > -1) { let conversationObj = conversationlist[conversationKey]; let newConversationObj = conversationObj; newConversationObj.setUnreadMessageCount(0); //newConversationObj.setUnreadMentionInMessageCount(0); newConversationObj.getLastMessage()?.setMuid(this.getUinx()); conversationlist.splice(conversationKey, 1, newConversationObj); this.conversationList = [...conversationlist]; this.ref.detectChanges(); } } } // sets property from theme to style object setThemeStyle() { this.setAvatarStyle(); this.setBadgeStyle(); this.setConfirmDialogStyle(); this.setConversationsStyle(); this.setListItemStyle(); this.setDateStyle(); this.setStatusStyle(); this.setReceiptStyle(); this.statusColor.private = this.conversationsStyle?.privateGroupIconBackground; this.statusColor.online = this.conversationsStyle?.onlineStatusColor; this.statusColor.password = this.conversationsStyle?.passwordGroupIconBackground; this.listStyle = { titleTextFont: this.conversationsStyle.titleTextFont, titleTextColor: this.conversationsStyle.titleTextColor, emptyStateTextFont: this.conversationsStyle.emptyStateTextFont, emptyStateTextColor: this.conversationsStyle.emptyStateTextColor, errorStateTextFont: this.conversationsStyle.errorStateTextFont, errorStateTextColor: this.conversationsStyle.errorStateTextColor, loadingIconTint: this.conversationsStyle.loadingIconTint, separatorColor: this.conversationsStyle.separatorColor, }; this.iconStyle.iconTint = this.themeService.theme.palette.getAccent400(); } setListItemStyle() { let defaultStyle = new ListItemStyle({ height: "97%", width: "100%", background: this.themeService.theme.palette.getBackground(), activeBackground: this.themeService.theme.palette.getAccent50(), borderRadius: "0", titleFont: fontHelper(this.themeService.theme.typography.title2), titleColor: this.themeService.theme.palette.getAccent(), border: "none", separatorColor: this.themeService.theme.palette.getAccent200(), hoverBackground: this.themeService.theme.palette.getAccent50(), }); this.listItemStyle = { ...defaultStyle, ...this.listItemStyle }; } setAvatarStyle() { let defaultStyle = new AvatarStyle({ borderRadius: "24px", width: "36px", height: "36px", border: `1px solid ${this.themeService.theme.palette.getAccent200()}`, backgroundColor: this.themeService.theme.palette.getAccent700(), nameTextColor: this.themeService.theme.palette.getAccent900(), backgroundSize: "cover", nameTextFont: fontHelper(this.themeService.theme.typography.subtitle1), outerViewBorderSpacing: "", }); this.avatarStyle = { ...defaultStyle, ...this.avatarStyle }; } setStatusStyle() { let defaultStyle = { height: "12px", width: "12px", border: "none", borderRadius: "24px", }; this.statusIndicatorStyle = { ...defaultStyle, ...this.statusIndicatorStyle, }; } setConversationsStyle() { let defaultStyle = new ConversationsStyle({ lastMessageTextFont: fontHelper(this.themeService.theme.typography.subtitle2), lastMessageTextColor: this.themeService.theme.palette.getAccent600(), background: this.themeService.theme.palette.getBackground(), border: `1px solid ${this.themeService.theme.palette.getAccent50()}`, titleTextFont: fontHelper(this.themeService.theme.typography.title1), titleTextColor: this.themeService.theme.palette.getAccent(), emptyStateTextFont: fontHelper(this.themeService.theme.typography.title1), emptyStateTextColor: this.themeService.theme.palette.getAccent600(), errorStateTextFont: fontHelper(this.themeService.theme.typography.title1), errorStateTextColor: this.themeService.theme.palette.getAccent600(), loadingIconTint: this.themeService.theme.palette.getAccent600(), onlineStatusColor: this.themeService.theme.palette.getSuccess(), separatorColor: this.themeService.theme.palette.getAccent400(), privateGroupIconBackground: this.themeService.theme.palette.getSuccess(), passwordGroupIconBackground: "RGB(247, 165, 0)", typingIndictorTextColor: this.themeService.theme.palette.getPrimary(), typingIndictorTextFont: fontHelper(this.themeService.theme.typography.subtitle2), threadIndicatorTextFont: fontHelper(this.themeService.theme.typography.caption2), threadIndicatorTextColor: this.themeService.theme.palette.getAccent600(), }); this.conversationsStyle = { ...defaultStyle, ...this.conversationsStyle }; this.checkboxStyle = { height: "24px", width: "24px", border: "none", borderRadius: "4px", checkedBackgroundColor: this.themeService.theme.palette.getPrimary(), uncheckedBackgroundColor: this.themeService.theme.palette.getAccent400() }; } setDateStyle() { let defaultStyle = new DateStyle({ textFont: fontHelper(this.themeService.theme.typography.caption2), textColor: this.themeService.theme.palette.getAccent600(), background: "transparent", }); this.dateStyle = { ...defaultStyle, ...this.dateStyle }; } setReceiptStyle() { let defaultStyle = new ReceiptStyle({ waitIconTint: this.themeService.theme.palette.getAccent700(), sentIconTint: this.themeService.theme.palette.getAccent600(), deliveredIconTint: this.themeService.theme.palette.getAccent600(), readIconTint: this.themeService.theme.palette.getPrimary(), errorIconTint: this.themeService.theme.palette.getError(), height: "20px", width: "20px", background: "transparent" }); this.receiptStyle = { ...defaultStyle, ...this.receiptStyle }; } setBadgeStyle() { let defaultStyle = new BadgeStyle({ textFont: fontHelper(this.themeService.theme.typography.subtitle2), textColor: this.themeService.theme.palette.getAccent("dark"), background: this.themeService.theme.palette.getPrimary(), height: "16px", borderRadius: "16px", width: "24px", }); this.badgeStyle = { ...defaultStyle, ...this.badgeStyle }; } setConfirmDialogStyle() { let defaultStyle = new ConfirmDialogStyle({ confirmButtonBackground: this.themeService.theme.palette.getError(), cancelButtonBackground: this.themeService.theme.palette.getSecondary(), confirmButtonTextColor: this.themeService.theme.palette.getAccent900("light"), confirmButtonTextFont: fontHelper(this.themeService.theme.typography.text2), cancelButtonTextColor: this.themeService.theme.palette.getAccent900("dark"), cancelButtonTextFont: fontHelper(this.themeService.theme.typography.text2), titleFont: fontHelper(this.themeService.theme.typography.title1), titleColor: this.themeService.theme.palette.getAccent(), messageTextFont: fontHelper(this.themeService.theme.typography.subtitle2), messageTextColor: this.themeService.theme.palette.getAccent600(), background: this.themeService.theme.palette.getBackground(), height: "100%", width: "350px", borderRadius: "8px", }); this.deleteConversationDialogStyle = { ...defaultStyle, ...this.deleteConversationDialogStyle, }; } // checking if user has his own configuration else will use default configuration /** * @param {Object={}} config * @param {Object} defaultConfig? * @returns defaultConfig */ // calling subtitle callback from configurations /** * @param {CometChat.Conversation} conversation */ /** * Fetches the coversation based on the conversationRequest config */ fetchNextConversation() { try { return this.requestBuilder.fetchNext(); } catch (error) { if (this.onError) { this.onError(CometChatException(error)); } } } updateEditedMessage(message) { let index = this.conversationList.findIndex((conversationObj) => conversationObj.getLastMessage() && conversationObj.getLastMessage().getId() == message?.getId()); if (index >= 0) { this.conversationEditedDeleted(message); } } /** * attaches Listeners for user activity , group activities and calling * @param callback */ /** * @param {Function} callback */ attachListeners(callback) { try { if (!this.disableUsersPresence && (!this.conversationType || this.conversationType == CometChatUIKitConstants.MessageReceiverType.user)) { CometChat.addUserListener(this.userListenerId, new CometChat.UserListener({ onUserOnline: (onlineUser) => { /* when someuser/friend comes online, user will be received here */ callback(CometChatUIKitConstants.userStatusType.online, onlineUser); }, onUserOffline: (offlineUser) => { /* when someuser/friend went offline, user will be received here */ callback(CometChatUIKitConstants.userStatusType.offline, offlineUser); }, })); } if (!this.conversationType || this.conversationType == CometChatUIKitConstants.MessageReceiverType.group) { CometChat.addGroupListener(this.groupListenerId, new CometChat.GroupListener({ onGroupMemberScopeChanged: (message, changedUser, newScope, oldScope, changedGroup) => { this.updateConversation(message); }, onGroupMemberKicked: (message, kickedUser, kickedBy, kickedFrom) => {