@cometchat/chat-uikit-angular
Version:
Ready-to-use Chat UI Components for Angular (JavaScript/Web)
785 lines • 121 kB
JavaScript
import { ChangeDetectionStrategy, Component, ElementRef, Input, ViewChildren, } from "@angular/core";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import { AvatarStyle, ListItemStyle, } from "@cometchat/uikit-elements";
import { SelectionMode, localize, TitleAlignment, States, CometChatUserEvents, fontHelper, } from "@cometchat/uikit-resources";
import { UsersStyle, SelectedUserPreviewStyle } from "@cometchat/uikit-shared";
import { CometChatException } from "../../Shared/Utils/ComeChatException";
import { UserPresencePlacement } from "@cometchat/uikit-resources";
import { MessageUtils } from "../../Shared/Utils/MessageUtils";
import * as i0 from "@angular/core";
import * as i1 from "../../CometChatTheme.service";
import * as i2 from "../../CometChatList/cometchat-list.component";
import * as i3 from "@angular/common";
export class CometChatUsersComponent {
constructor(ref, themeService) {
this.ref = ref;
this.themeService = themeService;
this.disableUsersPresence = false;
this.hideSeparator = false;
this.searchPlaceholder = localize("SEARCH");
this.hideError = false;
this.selectionMode = SelectionMode.none;
this.searchIconURL = "assets/search.svg";
this.hideSearch = false;
this.title = localize("USERS");
this.onError = (error) => {
console.log(error);
};
this.loadingIconURL = "assets/Spinner.svg";
this.showSectionHeader = true;
this.sectionHeaderField = "name";
this.emptyStateText = localize("NO_USERS_FOUND");
this.errorStateText = localize("SOMETHING_WRONG");
this.titleAlignment = TitleAlignment.left;
this.usersStyle = {
width: "100%",
height: "100%",
separatorColor: "rgb(222 222 222 / 46%)",
};
this.listItemStyle = {
height: "100%",
width: "100%",
};
this.statusIndicatorStyle = {
height: "10px",
width: "10px",
borderRadius: "16px",
};
this.avatarStyle = {
borderRadius: "16px",
width: "28px",
height: "28px",
};
this.selectedUserPreviewStyle = {};
this.showSelectedUsersPreview = false;
this.searchKeyword = "";
this.userPresencePlacement = UserPresencePlacement.bottom;
this.disableLoadingState = false;
this.fetchingUsers = false;
this.userChecked = "";
this.listStyle = {};
this.state = States.loading;
this.selectionmodeEnum = SelectionMode;
this.usersList = [];
this.limit = 30;
this.userListenerId = "userlist_" + new Date().getTime();
this.firstReload = false;
this.connectionListenerId = "connection_" + new Date().getTime();
this.previousSearchKeyword = "";
this.isWebsocketReconnected = false;
this.selectedUsers = {};
this.checkboxStyle = {
height: "24px",
width: "24px",
border: "none",
borderRadius: "4px",
checkedBackgroundColor: "#2196F3",
uncheckedBackgroundColor: "#ccc"
};
this.removeMemberButtonStyle = {
height: "16px",
width: "16px",
iconHeight: "16px",
iconWidth: "16px",
border: "none",
borderRadius: "50%",
background: "transparent",
buttonIconTint: "black"
};
this.selectedUsersPreviewWrapper = {};
// Bulk selection properties
this.lastSelectedIndex = -1;
this.isShiftPressed = false;
this.selectedUserPillStyle = {};
this.onScrolledToBottom = null;
this.fetchUsersOnSearchKeyWordChange = () => {
if (this.fetchingUsers) {
clearTimeout(this.fetchTimeOut);
this.fetchTimeOut = setTimeout(() => {
this.searchForUser();
}, 800);
}
else {
this.searchForUser();
}
};
this.searchForUser = () => {
this.setRequestBuilder();
if (!this.disableLoadingState) {
this.usersList = [];
}
this.fetchNextUsersList();
};
/**
* @param {CometChat.User} user
*/
this.onClick = (user) => {
if (this.onItemClick) {
this.onItemClick(user);
}
this.onRowClicked(user.getUid());
};
/**
* @param {CometChat.User} user
*/
this.getActiveUser = (user) => {
if (this.selectionMode == SelectionMode.none || !this.selectionMode) {
if (user.getUid() == this.activeUser?.getUid()) {
return true;
}
else {
return false;
}
}
else
return false;
};
/**
* @param {CometChat.User} user
*/
this.getStatusIndicatorColor = (user) => {
let userStatusVisibility = new MessageUtils().getUserStatusVisibility(user) || this.disableUsersPresence;
if (!userStatusVisibility) {
return (this.usersStyle?.onlineStatusColor ??
this.themeService?.theme.palette.getSuccess());
}
return null;
};
/**
* @param {CometChat.User} user
*/
this.getStatusIndicatorStyle = (user) => {
let userStatusVisibility = new MessageUtils().getUserStatusVisibility(user) || this.disableUsersPresence;
if (!userStatusVisibility) {
return (this.statusIndicatorStyle);
}
return null;
};
/**
* @param {CometChat.User} user
*/
this.updateUser = (user) => {
let userlist = [...this.usersList];
//search for user
let userKey = userlist.findIndex((u, k) => u.getUid() == user.getUid());
//if found in the list, update user object
if (userKey > -1) {
userlist.splice(userKey, 1, user);
this.usersList = [...userlist];
this.ref.detectChanges();
}
};
this.addMembersToList = (user, event) => {
let selected = event?.detail?.checked;
const currentIndex = this.usersList.findIndex(u => u.getUid() === user.getUid());
// Check if shift key was pressed for bulk selection
if (this.isShiftPressed && this.lastSelectedIndex !== -1 && currentIndex !== -1) {
this.handleBulkSelection(currentIndex, selected);
}
else {
// Regular single selection
if (this.selectionMode === this.selectionmodeEnum.single) {
this.userChecked = user.getUid();
}
if (this.onSelect) {
this.onSelect(user, selected);
}
if (selected) {
this.selectedUsers[user.getUid()] = user;
}
else {
delete this.selectedUsers[user.getUid()];
}
this.lastSelectedIndex = currentIndex;
}
this.ref.detectChanges();
};
/**
* Handle checkbox click to detect shift key
*/
this.onCheckboxClick = (user, event) => {
this.isShiftPressed = event.shiftKey;
};
/**
* Handle checkbox changed event
*/
this.onCheckboxChanged = (user, event) => {
this.addMembersToList(user, event);
// Reset shift flag after processing
this.isShiftPressed = false;
};
/**
* Handle keyboard events for accessibility
*/
this.onKeyDown = (event) => {
// Track shift key state for keyboard navigation
if (event.key === 'Shift') {
this.isShiftPressed = true;
}
};
/**
* Handle keyboard events for accessibility
*/
this.onKeyUp = (event) => {
if (event.key === 'Shift') {
this.isShiftPressed = false;
}
};
this.fetchNextUsersList = (state = States.loading) => {
this.onScrolledToBottom = null;
if (!(this.disableLoadingState && state == States.loading)) {
this.state = state;
}
if (this.requestBuilder &&
this.requestBuilder.pagination &&
(this.requestBuilder.pagination.current_page == 0 ||
this.requestBuilder.pagination.current_page !=
this.requestBuilder.pagination.total_pages)) {
this.fetchingUsers = true;
this.onScrolledToBottom = this.fetchNextUsersList;
this.ref.detectChanges();
try {
this.requestBuilder.fetchNext().then((userList) => {
console.log(userList);
if (userList.length <= 0) {
if (this.onEmpty) {
this.onEmpty();
this.previousSearchKeyword = "";
}
}
if (userList.length <= 0 &&
(this.usersList?.length <= 0 || this.disableLoadingState)) {
this.state = States.empty;
this.ref.detectChanges();
}
else {
if (!this.disableLoadingState) {
if (this.isWebsocketReconnected) {
this.usersList = userList;
this.isWebsocketReconnected = false;
}
else {
this.usersList = [...this.usersList, ...userList];
}
}
else {
if (this.searchKeyword != this.previousSearchKeyword ||
[0, 1].includes(this.requestBuilder.pagination.current_page)) {
this.usersList = userList;
}
else {
this.usersList = [...this.usersList, ...userList];
}
}
this.state = States.loaded;
this.ref.detectChanges();
}
if (this.firstReload) {
this.attachConnectionListeners();
this.firstReload = false;
}
this.fetchingUsers = false;
this.previousSearchKeyword = this.searchKeyword;
}, (error) => {
if (this.onError) {
this.onError(CometChatException(error));
}
this.state = States.error;
this.fetchingUsers = false;
this.ref.detectChanges();
});
}
catch (error) {
if (this.onError) {
this.onError(CometChatException(error));
}
if (this.usersList?.length <= 0) {
this.state = States.error;
this.ref.detectChanges();
}
this.fetchingUsers = false;
}
}
};
/**
* @param {string} key
*/
this.onSearch = (key) => {
try {
this.searchKeyword = key;
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.setRequestBuilder();
if (!this.disableLoadingState) {
this.usersList = [];
this.ref.detectChanges();
}
if (!this.fetchingUsers || (this.fetchingUsers && key == "")) {
this.usersList = [];
this.fetchNextUsersList();
}
}, 500);
}
catch (error) {
if (this.onError) {
this.onError(CometChatException(error));
}
}
};
this.userStyle = () => {
return {
height: this.usersStyle.height,
width: this.usersStyle.width,
background: this.usersStyle.background,
border: this.usersStyle.border,
borderRadius: this.usersStyle.borderRadius,
};
};
this.state = States.loading;
}
ngOnInit() {
this.firstReload = true;
this.state = States.loading;
this.isWebsocketReconnected = false;
this.setThemeStyle();
this.subscribeToEvents();
CometChat.getLoggedinUser()
.then((user) => {
this.setRequestBuilder();
if (!this.fetchingUsers) {
this.fetchNextUsersList();
}
this.attachListeners();
this.loggedInUser = user;
this.onScrolledToBottom = this.fetchNextUsersList;
})
.catch((error) => {
if (this.onError) {
this.onError(error);
}
});
}
ngOnChanges(changes) {
if (changes["searchKeyword"]) {
this.fetchUsersOnSearchKeyWordChange();
}
}
onUserSelected(user, event) {
let selected = event?.detail?.checked;
if (this.onSelect) {
this.onSelect(user, selected);
}
}
fetchNewUsers() {
this.setRequestBuilder();
let state = this.firstReload ? States.loading : States.loaded;
this.fetchNextUsersList(state);
}
// subscribe to global events
subscribeToEvents() {
this.ccUserBlocked = CometChatUserEvents.ccUserBlocked.subscribe((user) => {
if (this.activeUser && user.getUid() == this.activeUser.getUid()) {
this.activeUser = user;
this.updateUser(user);
this.ref.detectChanges();
}
});
this.ccUserUnBlocked = CometChatUserEvents.ccUserUnblocked.subscribe((user) => {
if (this.activeUser && user.getUid() == this.activeUser.getUid()) {
this.activeUser = user;
this.updateUser(user);
this.ref.detectChanges();
}
});
}
unsubscribeToEvents() {
this.ccUserBlocked?.unsubscribe();
this.ccUserUnBlocked?.unsubscribe();
}
ngOnDestroy() {
this.usersRequest = null;
this.ref.detach();
this.removeListener();
this.state = States.loaded;
this.unsubscribeToEvents();
}
isUserSelected(user) {
return user.getUid() === this.userChecked
|| this.selectedUsers?.[user.getUid()];
}
onRowClicked(uid) {
const userCheckbox = this.checkboxes.find(checkboxRef => uid === checkboxRef.nativeElement.getAttribute('data-uid'));
const userRadio = this.radios.find(radioRef => uid === radioRef.nativeElement.getAttribute('data-uid'));
let input = null;
if (userCheckbox && this.selectionMode === this.selectionmodeEnum.multiple) {
const root = userCheckbox.nativeElement.shadowRoot || userCheckbox.nativeElement;
input = root.querySelector('input[type="checkbox"]');
}
else if (userRadio && this.selectionMode === this.selectionmodeEnum.single) {
const root = userRadio.nativeElement.shadowRoot || userRadio.nativeElement;
input = root.querySelector('input[type="radio"]');
}
if (input)
input.click();
}
attachConnectionListeners() {
CometChat.addConnectionListener(this.connectionListenerId, new CometChat.ConnectionListener({
onConnected: () => {
this.isWebsocketReconnected = true;
console.log("ConnectionListener =>connected");
this.fetchNewUsers();
},
inConnecting: () => {
console.log("ConnectionListener => In connecting");
},
onDisconnected: () => {
this.isWebsocketReconnected = false;
console.log("ConnectionListener => On Disconnected");
},
}));
}
attachListeners() {
this.state = States.loading;
this.ref.detectChanges();
//Attaching User Listeners to dynamilcally update when a user comes online and goes offline
CometChat.addUserListener(this.userListenerId, new CometChat.UserListener({
onUserOnline: (onlineUser) => {
/* when someuser/friend comes online, user will be received here */
this.updateUser(onlineUser);
},
onUserOffline: (offlineUser) => {
/* when someuser/friend went offline, user will be received here */
this.updateUser(offlineUser);
},
}));
}
removeListener() {
CometChat.removeUserListener(this.userListenerId);
this.userListenerId = "";
CometChat.removeConnectionListener(this.connectionListenerId);
}
getUserNameStyle() {
return {
font: this.selectedUserPreviewStyle.textFont || fontHelper(this.themeService.theme.typography.name),
color: this.selectedUserPreviewStyle.textColor || this.themeService.theme.palette.getAccent(),
};
}
/**
* Handle bulk selection when shift+click is used
*/
handleBulkSelection(currentIndex, selected) {
const startIndex = Math.min(this.lastSelectedIndex, currentIndex);
const endIndex = Math.max(this.lastSelectedIndex, currentIndex);
const shouldSelect = selected;
// Apply selection/deselection to all users in range
for (let i = startIndex; i <= endIndex; i++) {
const user = this.usersList[i];
if (user) {
const wasSelected = !!this.selectedUsers[user.getUid()];
if (shouldSelect && !wasSelected) {
this.selectedUsers[user.getUid()] = user;
if (this.onSelect) {
this.onSelect(user, true);
}
this.updateCheckboxState(user.getUid(), true);
}
else if (!shouldSelect && wasSelected) {
delete this.selectedUsers[user.getUid()];
if (this.onSelect) {
this.onSelect(user, false);
}
this.updateCheckboxState(user.getUid(), false);
}
}
}
this.lastSelectedIndex = currentIndex;
}
/**
* Update checkbox state programmatically
*/
updateCheckboxState(userId, checked) {
setTimeout(() => {
if (this.checkboxes) {
const userCheckbox = this.checkboxes.find(checkboxRef => userId === checkboxRef.nativeElement.getAttribute('data-uid'));
if (userCheckbox) {
const root = userCheckbox.nativeElement.shadowRoot || userCheckbox.nativeElement;
const input = root.querySelector('input[type="checkbox"]');
if (input && input.checked !== checked) {
input.checked = checked;
const changeEvent = new Event('change', { bubbles: true });
input.dispatchEvent(changeEvent);
}
}
}
}, 0);
}
/**
* Get array of selected users for preview
*/
getSelectedUsersArray() {
return Object.values(this.selectedUsers);
}
/**
* Get count of selected users
*/
getSelectedUsersCount() {
return Object.keys(this.selectedUsers).length;
}
/**
* Remove user from selection by triggering checkbox click
*/
removeSelectedUser(user) {
const userCheckbox = this.checkboxes.find(checkboxRef => user.getUid() === checkboxRef.nativeElement.getAttribute('data-uid'));
if (userCheckbox) {
const root = userCheckbox.nativeElement.shadowRoot || userCheckbox.nativeElement;
const input = root.querySelector('input[type="checkbox"]');
if (input) {
input.click();
}
}
}
/**
* Track by function for ngFor performance
*/
trackByUserId(index, user) {
return user.getUid();
}
setRequestBuilder() {
if (!this.searchKeyword) {
this.previousSearchKeyword = "";
}
if (this.searchRequestBuilder && this.searchKeyword) {
this.requestBuilder = this.searchRequestBuilder
.setSearchKeyword(this.searchKeyword)
.build();
}
else if (this.usersRequestBuilder) {
this.requestBuilder = this.usersRequestBuilder
.setSearchKeyword(this.searchKeyword)
.build();
}
else {
this.requestBuilder = new CometChat.UsersRequestBuilder()
.setLimit(this.limit)
.setSearchKeyword(this.searchKeyword)
.build();
}
return this.requestBuilder;
}
setThemeStyle() {
this.setUsersStyle();
this.setListItemStyle();
this.setAvatarStyle();
this.setStatusStyle();
this.setSelectedUserStyle();
this.listStyle = {
titleTextFont: this.usersStyle.titleTextFont,
titleTextColor: this.usersStyle.titleTextColor,
emptyStateTextFont: this.usersStyle.emptyStateTextFont,
emptyStateTextColor: this.usersStyle.emptyStateTextColor,
errorStateTextFont: this.usersStyle.errorStateTextFont,
errorStateTextColor: this.usersStyle.errorStateTextColor,
loadingIconTint: this.usersStyle.loadingIconTint,
separatorColor: this.usersStyle.separatorColor,
searchIconTint: this.usersStyle.searchIconTint,
searchBorder: this.usersStyle.searchBorder,
searchBorderRadius: this.usersStyle.searchBorderRadius,
searchBackground: this.usersStyle.searchBackground,
searchPlaceholderTextFont: this.usersStyle.searchPlaceholderTextFont,
searchPlaceholderTextColor: this.usersStyle.searchPlaceholderTextColor,
searchTextFont: this.usersStyle.searchTextFont,
searchTextColor: this.usersStyle.searchTextColor,
sectionHeaderTextColor: this.usersStyle.sectionHeaderTextColor,
sectionHeaderTextFont: this.usersStyle.sectionHeaderTextFont,
};
this.ref.detectChanges();
}
setListItemStyle() {
let defaultStyle = new ListItemStyle({
height: "45px",
width: "100%",
background: this.themeService.theme.palette.getBackground(),
activeBackground: this.themeService.theme.palette.getAccent100(),
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: "28px",
height: "28px",
border: "none",
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,
};
}
setUsersStyle() {
let defaultStyle = new UsersStyle({
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(),
separatorColor: this.themeService.theme.palette.getAccent400(),
onlineStatusColor: this.themeService.theme.palette.getSuccess(),
sectionHeaderTextColor: this.themeService.theme.palette.getAccent600(),
sectionHeaderTextFont: fontHelper(this.themeService.theme.typography.subtitle2),
searchIconTint: this.themeService.theme.palette.getAccent600(),
searchPlaceholderTextColor: this.themeService.theme.palette.getAccent600(),
searchBackground: this.themeService.theme.palette.getAccent100(),
searchPlaceholderTextFont: fontHelper(this.themeService.theme.typography.text3),
searchTextColor: this.themeService.theme.palette.getAccent600(),
searchTextFont: fontHelper(this.themeService.theme.typography.text3),
});
this.usersStyle = { ...defaultStyle, ...this.usersStyle };
this.checkboxStyle = {
height: "24px",
width: "24px",
border: "none",
borderRadius: "4px",
checkedBackgroundColor: this.themeService.theme.palette.getPrimary(),
uncheckedBackgroundColor: this.themeService.theme.palette.getAccent400()
};
}
setSelectedUserStyle() {
let defaultStyle = new SelectedUserPreviewStyle({
borderRadius: "1000px",
width: "140px",
height: "fit-content",
border: `1px solid ${this.themeService.theme.palette.getAccent50()}`,
textColor: this.themeService.theme.palette.getAccent(),
textFont: fontHelper(this.themeService.theme.typography.name),
background: this.themeService.theme.palette.getBackground(),
closeIconTint: this.themeService.theme.palette.getPrimary(),
});
this.selectedUserPreviewStyle = { ...defaultStyle, ...this.selectedUserPreviewStyle };
this.removeMemberButtonStyle.buttonIconTint = this.selectedUserPreviewStyle.closeIconTint || this.themeService.theme.palette.getAccent600();
this.selectedUserPillStyle = {
borderRadius: this.selectedUserPreviewStyle.borderRadius || "1000px",
width: this.selectedUserPreviewStyle.width || "140px",
height: this.selectedUserPreviewStyle.height || "fit-content",
border: this.selectedUserPreviewStyle.border || `none`,
color: this.selectedUserPreviewStyle.textColor || this.themeService.theme.palette.getAccent(),
font: this.selectedUserPreviewStyle.textFont || fontHelper(this.themeService.theme.typography.name),
background: this.selectedUserPreviewStyle.background || this.themeService.theme.palette.getBackground(),
};
this.selectedUsersPreviewWrapper = {
borderTop: `1px solid ${this.themeService.theme.palette.getAccent100()}`,
borderBottom: `none`,
background: this.usersStyle.background || "transparent"
};
}
}
CometChatUsersComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: CometChatUsersComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.CometChatThemeService }], target: i0.ɵɵFactoryTarget.Component });
CometChatUsersComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: CometChatUsersComponent, selector: "cometchat-users", inputs: { usersRequestBuilder: "usersRequestBuilder", searchRequestBuilder: "searchRequestBuilder", subtitleView: "subtitleView", disableUsersPresence: "disableUsersPresence", listItemView: "listItemView", menu: "menu", options: "options", activeUser: "activeUser", hideSeparator: "hideSeparator", searchPlaceholder: "searchPlaceholder", hideError: "hideError", selectionMode: "selectionMode", searchIconURL: "searchIconURL", hideSearch: "hideSearch", title: "title", onError: "onError", emptyStateView: "emptyStateView", onSelect: "onSelect", errorStateView: "errorStateView", loadingIconURL: "loadingIconURL", showSectionHeader: "showSectionHeader", sectionHeaderField: "sectionHeaderField", loadingStateView: "loadingStateView", emptyStateText: "emptyStateText", errorStateText: "errorStateText", titleAlignment: "titleAlignment", usersStyle: "usersStyle", listItemStyle: "listItemStyle", statusIndicatorStyle: "statusIndicatorStyle", avatarStyle: "avatarStyle", selectedUserPreviewStyle: "selectedUserPreviewStyle", showSelectedUsersPreview: "showSelectedUsersPreview", onItemClick: "onItemClick", searchKeyword: "searchKeyword", onEmpty: "onEmpty", userPresencePlacement: "userPresencePlacement", disableLoadingState: "disableLoadingState" }, viewQueries: [{ propertyName: "checkboxes", predicate: ["checkboxElement"], descendants: true, read: ElementRef }, { propertyName: "radios", predicate: ["radioElement"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cc-users\" [ngStyle]=\"userStyle()\" (keydown)=\"onKeyDown($event)\" (keyup)=\"onKeyUp($event)\" tabindex=\"0\">\n <div class=\"cc-menus\" *ngIf=\"menu\">\n <ng-container *ngTemplateOutlet=\"menu\">\n </ng-container>\n </div>\n\n <!-- Users List -->\n <div class=\"cc-users__list\" [class.cc-users__list--with-selection]=\"getSelectedUsersCount() > 0\">\n <cometchat-list [listItemView]=\"listItemView ? listItemView : listItem\" [onScrolledToBottom]=\"onScrolledToBottom\" [onSearch]=\"onSearch\"\n [list]=\"usersList\" [searchText]=\"searchKeyword\" [searchPlaceholderText]=\"searchPlaceholder\"\n [searchIconURL]=\"searchIconURL\" [hideSearch]=\"hideSearch\" [hideError]=\"hideError\" [title]=\"title\"\n [sectionHeaderField]=\"sectionHeaderField\" [showSectionHeader]=\"showSectionHeader\"\n [emptyStateText]=\"emptyStateText\" [loadingIconURL]=\"loadingIconURL\"\n [titleAlignment]=\"titleAlignment\" [loadingStateView]=\"loadingStateView\" [emptyStateView]=\"emptyStateView\"\n [errorStateText]=\"errorStateText\" [errorStateView]=\"errorStateView\" [listStyle]=\"listStyle\" [state]=\"state\">\n </cometchat-list>\n </div>\n\n <!-- Selected Users Preview Section -->\n <div class=\"cc-selected-users\" [style]=\"selectedUsersPreviewWrapper\" *ngIf=\"showSelectedUsersPreview && getSelectedUsersCount() > 0\">\n <div class=\"cc-selected-users__list\">\n <div class=\"cc-selected-user\" *ngFor=\"let user of getSelectedUsersArray(); trackBy: trackByUserId\" [style]=\"selectedUserPillStyle\">\n <div class=\"cc-selected-user__avatar\">\n <cometchat-avatar \n [image]=\"user?.getAvatar() || ''\" \n [name]=\"user?.getName()\" \n [avatarStyle]=\"avatarStyle\">\n </cometchat-avatar>\n </div>\n <div class=\"cc-selected-user__name\" [style]=\"getUserNameStyle()\">{{user?.getName()}}</div>\n <div class=\"cc-selected-user__remove\" (click)=\"removeSelectedUser(user)\">\n <cometchat-button \n [iconURL]=\"'assets/close2x.svg'\" \n [buttonStyle]=\"removeMemberButtonStyle\">\n </cometchat-button>\n </div>\n </div>\n </div>\n </div>\n <ng-template #listItem let-user>\n <cometchat-list-item [title]=\"user?.name\" [avatarURL]=\"user?.avatar\" [avatarName]=\"user?.name\"\n [listItemStyle]=\"listItemStyle\" [avatarStyle]=\"avatarStyle\" [statusIndicatorStyle]=\"getStatusIndicatorStyle(user)\"\n [statusIndicatorColor]=\"getStatusIndicatorColor(user)\" [hideSeparator]=\"hideSeparator\" (cc-listitem-clicked)=\"onClick(user)\" [isActive]=\"getActiveUser(user)\"\n [userPresencePlacement]=\"userPresencePlacement\">\n <div slot=\"subtitleView\" *ngIf=\"subtitleView\">\n <ng-container *ngTemplateOutlet=\"subtitleView;context:{ $implicit: user }\">\n </ng-container>\n </div>\n\n <div slot=\"menuView\" class=\"cc-users__options\" *ngIf=\"options\">\n <cometchat-menu-list [data]=\"options(user)\">\n\n </cometchat-menu-list>\n </div>\n <div slot=\"tailView\" *ngIf=\"selectionMode != selectionmodeEnum.none\" class=\"cc-users__tail-view\">\n <ng-container *ngTemplateOutlet=\"tailView\">\n </ng-container>\n </div>\n <ng-template #tailView>\n <div *ngIf=\"selectionMode == selectionmodeEnum.single\" class=\"cc-users__selection--single\">\n <cometchat-radio-button [attr.data-uid]=\"user?.uid\" #radioElement (cc-radio-button-changed)=\"addMembersToList(user,$event)\" [checked]=\"isUserSelected(user)\" ></cometchat-radio-button>\n\n </div>\n <div *ngIf=\"selectionMode == selectionmodeEnum.multiple\" class=\"cc-users__selection--multiple\">\n <cometchat-checkbox \n [attr.data-uid]=\"user?.uid\" \n #checkboxElement \n [checkboxStyle]=\"checkboxStyle\" \n (cc-checkbox-changed)=\"onCheckboxChanged(user, $event)\"\n (click)=\"onCheckboxClick(user, $event)\" \n [checked]=\"isUserSelected(user)\">\n </cometchat-checkbox>\n </div>\n </ng-template>\n </cometchat-list-item>\n\n </ng-template>\n</div>\n", styles: [".cc-users{height:100%;width:100%;box-sizing:border-box;display:flex;flex-direction:column;overflow:hidden}.cc-menus{position:absolute;right:12px;padding:12px;cursor:pointer}.cc-selected-users{padding:12px;background:transparent;max-height:150px;overflow-x:hidden;overflow-y:auto}.cc-selected-users__list{display:flex;flex-wrap:wrap;gap:8px}.cc-selected-user{display:flex;align-items:center;border-radius:20px;padding:4px 8px 4px 4px;width:140px;animation:slideInUp .3s ease-out}.cc-selected-user__avatar{flex-shrink:0}.cc-selected-user__name{flex:1;margin:0 8px;font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cc-selected-user__remove{flex-shrink:0;cursor:pointer}.cc-selected-user__remove:hover{opacity:.7}.cc-users__list{flex:1;overflow:hidden}.cc-selected-users::-webkit-scrollbar{background:transparent;width:8px}.cc-selected-users::-webkit-scrollbar-thumb{background:#e8e5e5;border-radius:8px}.cc-users__list--with-selection .cc-users__selection--multiple{position:relative}@keyframes slideInUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}\n"], components: [{ type: i2.CometchatListComponent, selector: "cometchat-list", inputs: ["listItemView", "onScrolledToBottom", "onScrolledToTop", "list", "onSearch", "getSectionHeader", "searchText", "searchIconURL", "listStyle", "searchPlaceholderText", "hideSearch", "hideError", "title", "titleAlignment", "errorStateView", "loadingStateView", "emptyStateView", "state", "errorStateText", "emptyStateText", "loadingIconURL", "showSectionHeader", "sectionHeaderField", "DateSeparatorPattern", "dateSeparatorStyle"] }], directives: [{ type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: CometChatUsersComponent, decorators: [{
type: Component,
args: [{ selector: "cometchat-users", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cc-users\" [ngStyle]=\"userStyle()\" (keydown)=\"onKeyDown($event)\" (keyup)=\"onKeyUp($event)\" tabindex=\"0\">\n <div class=\"cc-menus\" *ngIf=\"menu\">\n <ng-container *ngTemplateOutlet=\"menu\">\n </ng-container>\n </div>\n\n <!-- Users List -->\n <div class=\"cc-users__list\" [class.cc-users__list--with-selection]=\"getSelectedUsersCount() > 0\">\n <cometchat-list [listItemView]=\"listItemView ? listItemView : listItem\" [onScrolledToBottom]=\"onScrolledToBottom\" [onSearch]=\"onSearch\"\n [list]=\"usersList\" [searchText]=\"searchKeyword\" [searchPlaceholderText]=\"searchPlaceholder\"\n [searchIconURL]=\"searchIconURL\" [hideSearch]=\"hideSearch\" [hideError]=\"hideError\" [title]=\"title\"\n [sectionHeaderField]=\"sectionHeaderField\" [showSectionHeader]=\"showSectionHeader\"\n [emptyStateText]=\"emptyStateText\" [loadingIconURL]=\"loadingIconURL\"\n [titleAlignment]=\"titleAlignment\" [loadingStateView]=\"loadingStateView\" [emptyStateView]=\"emptyStateView\"\n [errorStateText]=\"errorStateText\" [errorStateView]=\"errorStateView\" [listStyle]=\"listStyle\" [state]=\"state\">\n </cometchat-list>\n </div>\n\n <!-- Selected Users Preview Section -->\n <div class=\"cc-selected-users\" [style]=\"selectedUsersPreviewWrapper\" *ngIf=\"showSelectedUsersPreview && getSelectedUsersCount() > 0\">\n <div class=\"cc-selected-users__list\">\n <div class=\"cc-selected-user\" *ngFor=\"let user of getSelectedUsersArray(); trackBy: trackByUserId\" [style]=\"selectedUserPillStyle\">\n <div class=\"cc-selected-user__avatar\">\n <cometchat-avatar \n [image]=\"user?.getAvatar() || ''\" \n [name]=\"user?.getName()\" \n [avatarStyle]=\"avatarStyle\">\n </cometchat-avatar>\n </div>\n <div class=\"cc-selected-user__name\" [style]=\"getUserNameStyle()\">{{user?.getName()}}</div>\n <div class=\"cc-selected-user__remove\" (click)=\"removeSelectedUser(user)\">\n <cometchat-button \n [iconURL]=\"'assets/close2x.svg'\" \n [buttonStyle]=\"removeMemberButtonStyle\">\n </cometchat-button>\n </div>\n </div>\n </div>\n </div>\n <ng-template #listItem let-user>\n <cometchat-list-item [title]=\"user?.name\" [avatarURL]=\"user?.avatar\" [avatarName]=\"user?.name\"\n [listItemStyle]=\"listItemStyle\" [avatarStyle]=\"avatarStyle\" [statusIndicatorStyle]=\"getStatusIndicatorStyle(user)\"\n [statusIndicatorColor]=\"getStatusIndicatorColor(user)\" [hideSeparator]=\"hideSeparator\" (cc-listitem-clicked)=\"onClick(user)\" [isActive]=\"getActiveUser(user)\"\n [userPresencePlacement]=\"userPresencePlacement\">\n <div slot=\"subtitleView\" *ngIf=\"subtitleView\">\n <ng-container *ngTemplateOutlet=\"subtitleView;context:{ $implicit: user }\">\n </ng-container>\n </div>\n\n <div slot=\"menuView\" class=\"cc-users__options\" *ngIf=\"options\">\n <cometchat-menu-list [data]=\"options(user)\">\n\n </cometchat-menu-list>\n </div>\n <div slot=\"tailView\" *ngIf=\"selectionMode != selectionmodeEnum.none\" class=\"cc-users__tail-view\">\n <ng-container *ngTemplateOutlet=\"tailView\">\n </ng-container>\n </div>\n <ng-template #tailView>\n <div *ngIf=\"selectionMode == selectionmodeEnum.single\" class=\"cc-users__selection--single\">\n <cometchat-radio-button [attr.data-uid]=\"user?.uid\" #radioElement (cc-radio-button-changed)=\"addMembersToList(user,$event)\" [checked]=\"isUserSelected(user)\" ></cometchat-radio-button>\n\n </div>\n <div *ngIf=\"selectionMode == selectionmodeEnum.multiple\" class=\"cc-users__selection--multiple\">\n <cometchat-checkbox \n [attr.data-uid]=\"user?.uid\" \n #checkboxElement \n [checkboxStyle]=\"checkboxStyle\" \n (cc-checkbox-changed)=\"onCheckboxChanged(user, $event)\"\n (click)=\"onCheckboxClick(user, $event)\" \n [checked]=\"isUserSelected(user)\">\n </cometchat-checkbox>\n </div>\n </ng-template>\n </cometchat-list-item>\n\n </ng-template>\n</div>\n", styles: [".cc-users{height:100%;width:100%;box-sizing:border-box;display:flex;flex-direction:column;overflow:hidden}.cc-menus{position:absolute;right:12px;padding:12px;cursor:pointer}.cc-selected-users{padding:12px;background:transparent;max-height:150px;overflow-x:hidden;overflow-y:auto}.cc-selected-users__list{display:flex;flex-wrap:wrap;gap:8px}.cc-selected-user{display:flex;align-items:center;border-radius:20px;padding:4px 8px 4px 4px;width:140px;animation:slideInUp .3s ease-out}.cc-selected-user__avatar{flex-shrink:0}.cc-selected-user__name{flex:1;margin:0 8px;font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cc-selected-user__remove{flex-shrink:0;cursor:pointer}.cc-selected-user__remove:hover{opacity:.7}.cc-users__list{flex:1;overflow:hidden}.cc-selected-users::-webkit-scrollbar{background:transparent;width:8px}.cc-selected-users::-webkit-scrollbar-thumb{background:#e8e5e5;border-radius:8px}.cc-users__list--with-selection .cc-users__selection--multiple{position:relative}@keyframes slideInUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}\n"] }]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1.CometChatThemeService }]; }, propDecorators: { usersRequestBuilder: [{
type: Input
}], searchRequestBuilder: [{
type: Input
}], subtitleView: [{
type: Input
}], disableUsersPresence: [{
type: Input
}], listItemView: [{
type: Input
}], menu: [{
type: Input
}], options: [{
type: Input
}], activeUser: [{
type: Input
}], hideSeparator: [{
type: Input
}], searchPlaceholder: [{
type: Input
}], hideError: [{
type: Input
}], selectionMode: [{
type: Input
}], searchIconURL: [{
type: Input
}], hideSearch: [{
type: Input
}], title: [{
type: Input
}], onError: [{
type: Input
}], emptyStateView: [{
type: Input
}], onSelect: [{
type: Input
}], errorStateView: [{
type: Input
}], loadingIconURL: [{
type: Input
}], showSectionHeader: [{
type: Input
}], sectionHeaderField: [{
type: Input
}], loadingStateView: [{
type: Input
}], emptyStateText: [{
type: Input
}], errorStateText: [{
type: Input
}], titleAlignment: [{
type: Input
}], usersStyle: [{
type: Input
}], listItemStyle: [{
type: Input
}], statusIndicatorStyle: [{
type: Input
}], avatarStyle: [{
type: Input
}], selectedUserPreviewStyle: [{
type: Input
}], showSelectedUsersPreview: [{
type: Input
}], onItemClick: [{
type: Input
}], searchKeyword: [{
type: Input
}], onEmpty: [{
type: Input
}], userPresencePlacement: [{
type: Input
}], disableLoadingState: [{
type: Input
}], checkboxes: [{
type: ViewChildren,
args: ['checkboxElement', { read: ElementRef }]
}], radios: [{
type: ViewChildren,
args: ['radioElement', { read: ElementRef }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tZXRjaGF0LXVzZXJzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NoYXQtdWlraXQtYW5ndWxhci9zcmMvQ29tZXRDaGF0VXNlcnMvY29tZXRjaGF0LXVzZXJzL2NvbWV0Y2hhdC11c2Vycy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jaGF0LXVpa2l0LWFuZ3VsYXIvc3JjL0NvbWV0Q2hhdFVzZXJzL2NvbWV0Y2hhdC11c2Vycy9jb21ldGNoYXQtdXNlcnMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsVUFBVSxFQUNWLEtBQUssRUFNTCxZQUFZLEdBQ2IsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzNELE9BQU8sRUFDTCxXQUFXLEVBR1gsYUFBYSxHQUNkLE1BQU0sMkJBQTJCLENBQUM7QUFFbkMsT0FBTyxFQUVMLGFBQWEsRUFDYixRQUFRLEVBQ1IsY0FBYyxFQUNkLE1BQU0sRUFDTixtQkFBbUIsRUFFbkIsVUFBVSxHQUNYLE1BQU0sNEJBQTRCLENBQUM7QUFDcEMsT0FBTyxFQUFFLFVBQVUsRUFBYSx3QkFBd0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRTFGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ25FLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQzs7Ozs7QUFPL0QsTUFBTSxPQUFPLHVCQUF1QjtJQWdIbEMsWUFDVSxHQUFzQixFQUN0QixZQUFtQztRQURuQyxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUN0QixpQkFBWSxHQUFaLFlBQVksQ0FBdUI7UUE5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