@corva/chat-core 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -582,6 +582,7 @@ interface User {
582
582
  roles?: string[];
583
583
  active?: boolean;
584
584
  isBot?: boolean;
585
+ nickname?: string;
585
586
  displayName?: string;
586
587
  displayAvatar?: string;
587
588
  email?: string;
@@ -1172,6 +1173,8 @@ interface CorvaRevoltAuthResponse {
1172
1173
  revolt_user_id: string;
1173
1174
  revolt_company_server_id: string;
1174
1175
  revolt_channel_id: string;
1176
+ revolt_channel_server_id?: string;
1177
+ revolt_channel_company_id?: number;
1175
1178
  revolt_chat_channels?: AssetChatChannel[];
1176
1179
  chat_used?: boolean | null;
1177
1180
  }
@@ -1233,6 +1236,18 @@ declare function isValidPausePreset(value: unknown): value is PausePreset;
1233
1236
 
1234
1237
  declare function waitForNextPaint(): Promise<void>;
1235
1238
 
1239
+ /**
1240
+ * Asset Chats API Module
1241
+ *
1242
+ * Fetches or creates a Revolt channel for a specific rig / frac fleet /
1243
+ * intervention unit. The backend will return the associated revolt_channel_id.
1244
+ */
1245
+ interface AssetChatSession {
1246
+ channelId: string;
1247
+ serverId: string | null;
1248
+ companyId: number | null;
1249
+ }
1250
+ declare function getAssetChatSession(assetId: string, assetType: ChatAssetType): Promise<AssetChatSession>;
1236
1251
  declare function getAssetChatChannel(assetId: string, assetType: ChatAssetType): Promise<string>;
1237
1252
 
1238
1253
  type StoredCorvaUser = CorvaUser | CorvaAPIUser;
@@ -1282,9 +1297,14 @@ declare const sharedRefs: SharedRefs;
1282
1297
  */
1283
1298
  declare const initChat: () => void;
1284
1299
 
1300
+ interface ExternalChannel {
1301
+ serverId: string;
1302
+ companyId: number | null;
1303
+ }
1285
1304
  interface AuthStore {
1286
1305
  user: User | null;
1287
1306
  serverId: string | null;
1307
+ externalChannels: Record<string, ExternalChannel>;
1288
1308
  isConnected: boolean;
1289
1309
  hasEverConnected: boolean;
1290
1310
  connectionGaveUp: boolean;
@@ -1294,6 +1314,7 @@ interface AuthStore {
1294
1314
  setConnected: (connected: boolean) => void;
1295
1315
  setHasEverConnected: (hasConnected: boolean) => void;
1296
1316
  addAssetChatChannel: (channel: AssetChatChannel) => void;
1317
+ setChannelServer: (channelId: string, serverId: string | null, companyId: number | null) => void;
1297
1318
  markChatUsed: () => void;
1298
1319
  login: (credentials: LoginCredentials) => Promise<{
1299
1320
  success: boolean;
@@ -1312,6 +1333,8 @@ interface AuthStore {
1312
1333
  }
1313
1334
  declare function keepChatUsed(current: boolean | null, incoming: boolean | null | undefined): boolean | null;
1314
1335
  declare const authStore: zustand_vanilla.StoreApi<AuthStore>;
1336
+ declare const getExternalChannel: (roomId: string | null | undefined) => ExternalChannel | null;
1337
+ declare const isExternalServerChannel: (roomId: string | null | undefined) => boolean;
1315
1338
  /** @public */
1316
1339
  declare const resetAuthStore: () => void;
1317
1340
 
@@ -1699,4 +1722,4 @@ declare const createSocketEventHandlers: (config: SocketEventHandlersConfig) =>
1699
1722
 
1700
1723
  declare const installUnreadWatcher: () => void;
1701
1724
 
1702
- export { ALERT_SEVERITY, ASSET_API_FIELDS, ASSET_CHAT_PREFIXES, ASSET_NOUN, type AckScheduler, type AlertData, type AlertSeverity, type AlertWirePayload, type AppCommentAttachment, type AppCommentData, type AppCommentWirePayload, type AppStateAdapter, type AskCorvaData, type AskCorvaWirePayload, type AssetChatChannel, type AssetStore, type Attachment, type AuthStore, CHANNEL_NAME_MAX_LENGTH, CHANNEL_TYPES, CORVA_MESSAGE_TYPES, CORVA_SYS_PREFIX, type ChannelAsset, type ChannelContentFilter, type ChannelContentFilterStore, type ChannelContentFilters, type ChannelNameValidation, type ChannelNotificationPreference, type ChannelNotificationSetting, type ChannelUnread, type ChatAsset, type ChatAssetIdentity, type ChatAssetType, type ChatDates, type ChatHost, type ChatNotifier, type ChatPlatform, type CorvaAPIUser, type CorvaApiAdapter, type CorvaRevoltAuthResponse, type CorvaSystemMessage, type CorvaUser, type CorvaUserService, DATE_SEPARATOR_LABELS, DEFAULT_CHANNEL_CONTENT_FILTER, DEFAULT_CHANNEL_CONTENT_FILTERS, DEFAULT_CHANNEL_PREFERENCE, DEFAULT_FAVORITE_ROOMS_SETTINGS, DEFAULT_HIDDEN_ROOMS_SETTINGS, DEFAULT_NOTIFICATION_PREFERENCES, DEFAULT_NOTIFICATION_SETTINGS, DEFAULT_ROOM_LIST_ORDER, DIRECT_MESSAGE_PLACEHOLDER, type FavoriteRoomsSettings, type FavoriteRoomsStore, type FeedItemData, type FeedWirePayload, type FileAttachment, type FilterEntityWindow, type ForwardWirePayload, type ForwardedFrom, GENERAL_CHAT_NAME, type HiddenRoomsSettings, type HttpClient, type HttpClientConfig, HttpError, type HttpRequestInit, type HttpResponseLike, type KeyValueStorage, type LocatorContext, type LoginCredentials, MAX_ATTACHMENT_SIZE_BYTES, MAX_ATTACHMENT_SIZE_MB, MAX_NAVIGATION_HISTORY, MENTION_REPLACE_PATTERN, MENTION_SPLIT_PATTERN, MUTE_PRESET_OPTIONS, type MemberStore, type Message, type MessageCache, type MessageFormData, type MessageStore, NOTIFICATION_DESTINATIONS, NOTIFICATION_SETTING_ALL, NOTIFICATION_SETTING_MENTIONS, NOTIFICATION_SETTING_NOTHING, type NavigationEntry, type NavigationHistoryStore, type NotificationDestination, type NotificationPreferences, type NotificationSettings, type NotificationStore, PAUSE_INDEFINITELY, PAUSE_PRESETS, PAUSE_PRESET_OPTIONS, type PausePreset, type PausePresetOption, REVOLT_SYSTEM_USER_ID, ROOM_LIST_ORDER, type ReadyChannelData, type RevoltAPIInstance, type RevoltChannel, type RevoltIncomingMessagePayload, type RevoltLoginResponse, type RevoltMessage, type RevoltMessageResponse, type RevoltSocketConfig, type RevoltSocketEventHandlers, type RevoltSocketInstance, type RevoltUploadResponse, type RevoltUserResponse, type Room, type RoomListOrder, type RoomStore, type RoomType, SESSION_STORAGE_KEY, SIDEBAR_SECTIONS, SIDEBAR_TABS, SOFT_DELETE_MARKER, SYSTEM_MESSAGE_TEXTS, type SaveSessionParams, type SelectableAssetType, type SessionData, SessionManager, type SharedFile, type SharedRefs, type SidebarSectionKey, type SidebarTabKey, type SocketCloseEventLike, type SocketEventHandlersConfig, type StoredChannelPreference, type Subscription, type TracesViewportRequest, type TypingManager, type UIStore, type UploadAndSendResult, type UploadFile, type UploadedFile, type User, type UserStatus, type ViewportDeepLink, type ViewportIndexCurve, type ViewportMode, WEBSOCKET_CONNECTING, WEBSOCKET_OPEN, type WebSocketLike, type WireSeverity, addMessage, addOrUpdateSubscription, alertMessageAsText, assetStore, authStore, buildAppCommentMessageContent, buildAskCorvaMessageContent, buildFinalMessage, buildForwardMessageContent, buildGroupChannelName, canDeleteMessage, canEditMessage, channelContentFilterStore, channelToAsset, chatToastStore, clearLastOpenedRoom, compareByActivity, compareByName, compareByRecencyDesc, configureChat, configureChatStorage, createAckScheduler, createCorvaUserService, createDMSubscription, createGroupSubscription, createHttpClient, createLatestWinsQueue, createMemoryStorage, createMessageCache, createRevoltAPI, createRevoltSocket, createRoomTaskQueue, createSocketEventHandlers, createSoftDeletedMessage, createTypingManager, deriveAllowedChatAsset, enrichWithCorvaData, ensureChatSession, extractTimestampFromULID, failOptimisticMessage, favoriteRoomsStore, findGeneralRoom, formatAssetChatName, getAppCommentAttachments, getAssetChatChannel, getAssetTypeFromDisplayName, getChatHost, getChatStorage, getCorvaUserFields, getLastOpenedRoom, getMessageTimestamp, getPauseUntil, getReactionCount, getRoomDisplayName, getSystemMessageWithCorvaNames, getUserDisplayName, getUserSecondaryText, handleUnauthorized, hasReactions, hasUserReacted, initChat, installUnreadWatcher, isAlertMessage, isAppCommentMessage, isAskCorvaMessage, isChannelMuted, isChatAssetTypeAllowed, isChatStorageConfigured, isCurrentRoomSelection, isDeepEqual, isDefaultChannelPreference, isDisallowedAssetChatRoom, isDmGroup, isForwardedMessage, isGeneralRoom, isNotificationsPaused, isPauseActive, isSoftDeletedMessage, isSystemMessage, isUnread, isUserOnline, isValidPausePreset, isVisibleUnread, keepChatUsed, loadUntilFound, memberStore, messageStore, navigationHistoryStore, notificationStore, onChatStorageConfigured, parseCorvaSystemMessage, prepareRoomSelection, removeMessageFromList, removeSubscription, resetAssetStore, resetAuthStore, resetChannelContentFilterStore, resetChatAssetPermissionsSnapshot, resetChatHost, resetFavoriteRoomsStore, resetMemberStore, resetMessageStore, resetNavigationHistoryStore, resetNotificationStore, resetRoomStore, resetUIStore, roomStore, saveLastChatActivity, saveLastOpenedRoom, searchMessages, searchRooms, searchUsers, selectCanGoBack, selectCanGoForward, setAllowedChatAssetTypes, settleOptimisticMessage, sharedRefs, sortChannels, sortDMs, sortMessagesByTime, sortUsersByStatus, stripPlatformMentions, uiStore, updateMessageInList, uploadAndSend, validateChannelName, waitForNextPaint, wasRecentlyActive, withChannelPreferenceDefaults };
1725
+ export { ALERT_SEVERITY, ASSET_API_FIELDS, ASSET_CHAT_PREFIXES, ASSET_NOUN, type AckScheduler, type AlertData, type AlertSeverity, type AlertWirePayload, type AppCommentAttachment, type AppCommentData, type AppCommentWirePayload, type AppStateAdapter, type AskCorvaData, type AskCorvaWirePayload, type AssetChatChannel, type AssetChatSession, type AssetStore, type Attachment, type AuthStore, CHANNEL_NAME_MAX_LENGTH, CHANNEL_TYPES, CORVA_MESSAGE_TYPES, CORVA_SYS_PREFIX, type ChannelAsset, type ChannelContentFilter, type ChannelContentFilterStore, type ChannelContentFilters, type ChannelNameValidation, type ChannelNotificationPreference, type ChannelNotificationSetting, type ChannelUnread, type ChatAsset, type ChatAssetIdentity, type ChatAssetType, type ChatDates, type ChatHost, type ChatNotifier, type ChatPlatform, type CorvaAPIUser, type CorvaApiAdapter, type CorvaRevoltAuthResponse, type CorvaSystemMessage, type CorvaUser, type CorvaUserService, DATE_SEPARATOR_LABELS, DEFAULT_CHANNEL_CONTENT_FILTER, DEFAULT_CHANNEL_CONTENT_FILTERS, DEFAULT_CHANNEL_PREFERENCE, DEFAULT_FAVORITE_ROOMS_SETTINGS, DEFAULT_HIDDEN_ROOMS_SETTINGS, DEFAULT_NOTIFICATION_PREFERENCES, DEFAULT_NOTIFICATION_SETTINGS, DEFAULT_ROOM_LIST_ORDER, DIRECT_MESSAGE_PLACEHOLDER, type ExternalChannel, type FavoriteRoomsSettings, type FavoriteRoomsStore, type FeedItemData, type FeedWirePayload, type FileAttachment, type FilterEntityWindow, type ForwardWirePayload, type ForwardedFrom, GENERAL_CHAT_NAME, type HiddenRoomsSettings, type HttpClient, type HttpClientConfig, HttpError, type HttpRequestInit, type HttpResponseLike, type KeyValueStorage, type LocatorContext, type LoginCredentials, MAX_ATTACHMENT_SIZE_BYTES, MAX_ATTACHMENT_SIZE_MB, MAX_NAVIGATION_HISTORY, MENTION_REPLACE_PATTERN, MENTION_SPLIT_PATTERN, MUTE_PRESET_OPTIONS, type MemberStore, type Message, type MessageCache, type MessageFormData, type MessageStore, NOTIFICATION_DESTINATIONS, NOTIFICATION_SETTING_ALL, NOTIFICATION_SETTING_MENTIONS, NOTIFICATION_SETTING_NOTHING, type NavigationEntry, type NavigationHistoryStore, type NotificationDestination, type NotificationPreferences, type NotificationSettings, type NotificationStore, PAUSE_INDEFINITELY, PAUSE_PRESETS, PAUSE_PRESET_OPTIONS, type PausePreset, type PausePresetOption, REVOLT_SYSTEM_USER_ID, ROOM_LIST_ORDER, type ReadyChannelData, type RevoltAPIInstance, type RevoltChannel, type RevoltIncomingMessagePayload, type RevoltLoginResponse, type RevoltMessage, type RevoltMessageResponse, type RevoltSocketConfig, type RevoltSocketEventHandlers, type RevoltSocketInstance, type RevoltUploadResponse, type RevoltUserResponse, type Room, type RoomListOrder, type RoomStore, type RoomType, SESSION_STORAGE_KEY, SIDEBAR_SECTIONS, SIDEBAR_TABS, SOFT_DELETE_MARKER, SYSTEM_MESSAGE_TEXTS, type SaveSessionParams, type SelectableAssetType, type SessionData, SessionManager, type SharedFile, type SharedRefs, type SidebarSectionKey, type SidebarTabKey, type SocketCloseEventLike, type SocketEventHandlersConfig, type StoredChannelPreference, type Subscription, type TracesViewportRequest, type TypingManager, type UIStore, type UploadAndSendResult, type UploadFile, type UploadedFile, type User, type UserStatus, type ViewportDeepLink, type ViewportIndexCurve, type ViewportMode, WEBSOCKET_CONNECTING, WEBSOCKET_OPEN, type WebSocketLike, type WireSeverity, addMessage, addOrUpdateSubscription, alertMessageAsText, assetStore, authStore, buildAppCommentMessageContent, buildAskCorvaMessageContent, buildFinalMessage, buildForwardMessageContent, buildGroupChannelName, canDeleteMessage, canEditMessage, channelContentFilterStore, channelToAsset, chatToastStore, clearLastOpenedRoom, compareByActivity, compareByName, compareByRecencyDesc, configureChat, configureChatStorage, createAckScheduler, createCorvaUserService, createDMSubscription, createGroupSubscription, createHttpClient, createLatestWinsQueue, createMemoryStorage, createMessageCache, createRevoltAPI, createRevoltSocket, createRoomTaskQueue, createSocketEventHandlers, createSoftDeletedMessage, createTypingManager, deriveAllowedChatAsset, enrichWithCorvaData, ensureChatSession, extractTimestampFromULID, failOptimisticMessage, favoriteRoomsStore, findGeneralRoom, formatAssetChatName, getAppCommentAttachments, getAssetChatChannel, getAssetChatSession, getAssetTypeFromDisplayName, getChatHost, getChatStorage, getCorvaUserFields, getExternalChannel, getLastOpenedRoom, getMessageTimestamp, getPauseUntil, getReactionCount, getRoomDisplayName, getSystemMessageWithCorvaNames, getUserDisplayName, getUserSecondaryText, handleUnauthorized, hasReactions, hasUserReacted, initChat, installUnreadWatcher, isAlertMessage, isAppCommentMessage, isAskCorvaMessage, isChannelMuted, isChatAssetTypeAllowed, isChatStorageConfigured, isCurrentRoomSelection, isDeepEqual, isDefaultChannelPreference, isDisallowedAssetChatRoom, isDmGroup, isExternalServerChannel, isForwardedMessage, isGeneralRoom, isNotificationsPaused, isPauseActive, isSoftDeletedMessage, isSystemMessage, isUnread, isUserOnline, isValidPausePreset, isVisibleUnread, keepChatUsed, loadUntilFound, memberStore, messageStore, navigationHistoryStore, notificationStore, onChatStorageConfigured, parseCorvaSystemMessage, prepareRoomSelection, removeMessageFromList, removeSubscription, resetAssetStore, resetAuthStore, resetChannelContentFilterStore, resetChatAssetPermissionsSnapshot, resetChatHost, resetFavoriteRoomsStore, resetMemberStore, resetMessageStore, resetNavigationHistoryStore, resetNotificationStore, resetRoomStore, resetUIStore, roomStore, saveLastChatActivity, saveLastOpenedRoom, searchMessages, searchRooms, searchUsers, selectCanGoBack, selectCanGoForward, setAllowedChatAssetTypes, settleOptimisticMessage, sharedRefs, sortChannels, sortDMs, sortMessagesByTime, sortUsersByStatus, stripPlatformMentions, uiStore, updateMessageInList, uploadAndSend, validateChannelName, waitForNextPaint, wasRecentlyActive, withChannelPreferenceDefaults };
package/dist/index.js CHANGED
@@ -307,7 +307,7 @@ var getUserSecondaryText = (user) => {
307
307
  }
308
308
  if (email) return email;
309
309
  if (titleOrRole) return titleOrRole;
310
- if (user.username) return `@${user.username}`;
310
+ if (user.username && !user.nickname) return `@${user.username}`;
311
311
  return void 0;
312
312
  };
313
313
 
@@ -1649,11 +1649,15 @@ function createGroupsAPI(http) {
1649
1649
  async function getServerMembers(serverId) {
1650
1650
  try {
1651
1651
  const response = await http.request(`/servers/${serverId}/members`);
1652
+ const nicknames = new Map(
1653
+ (response?.members || []).map((m) => [m._id.user, m.nickname || void 0])
1654
+ );
1652
1655
  const users = response?.users || [];
1653
1656
  return users.map((member) => ({
1654
1657
  _id: member._id,
1655
1658
  username: member.username,
1656
1659
  name: member.display_name || member.username,
1660
+ nickname: nicknames.get(member._id),
1657
1661
  status: member.online ? "online" : "offline",
1658
1662
  isBot: !!member.bot
1659
1663
  }));
@@ -2984,7 +2988,7 @@ var ASSET_ID_PARAM = {
2984
2988
  frac_fleet: "frac_fleet_id",
2985
2989
  intervention_unit: "intervention_unit_id"
2986
2990
  };
2987
- async function getAssetChatChannel(assetId, assetType) {
2991
+ async function getAssetChatSession(assetId, assetType) {
2988
2992
  if (!assetId || Number.isNaN(Number(assetId))) {
2989
2993
  throw new Error("Asset ID is required");
2990
2994
  }
@@ -2996,7 +3000,15 @@ async function getAssetChatChannel(assetId, assetType) {
2996
3000
  if (!response?.revolt_channel_id) {
2997
3001
  throw new Error("No revolt_channel_id returned from asset chat API");
2998
3002
  }
2999
- return response.revolt_channel_id;
3003
+ return {
3004
+ channelId: response.revolt_channel_id,
3005
+ serverId: response.revolt_channel_server_id ?? null,
3006
+ companyId: response.revolt_channel_company_id ?? null
3007
+ };
3008
+ }
3009
+ async function getAssetChatChannel(assetId, assetType) {
3010
+ const { channelId } = await getAssetChatSession(assetId, assetType);
3011
+ return channelId;
3000
3012
  }
3001
3013
 
3002
3014
  // src/services/corvaUserService.ts
@@ -3028,6 +3040,9 @@ function createCorvaUserService() {
3028
3040
  enrichUser(user) {
3029
3041
  const corvaUser = revoltToCorva.get(user._id);
3030
3042
  if (!corvaUser) {
3043
+ if (user.nickname) {
3044
+ return { ...user, displayName: user.nickname, displayAvatar: void 0 };
3045
+ }
3031
3046
  return {
3032
3047
  ...user,
3033
3048
  displayName: user.name || user.username || "Unknown User",
@@ -3278,6 +3293,8 @@ var invalidateVisibleUsers = () => {
3278
3293
  visibleUsersGeneration += 1;
3279
3294
  visibleUsersRequest = null;
3280
3295
  };
3296
+ var syncedExternalCompanies = /* @__PURE__ */ new Set();
3297
+ var ownCompanyId = null;
3281
3298
  var seedSocketUsers = (members) => {
3282
3299
  sharedRefs.socket?.seedUsers(members);
3283
3300
  sharedRefs.api?.seedUserCache(members);
@@ -3392,7 +3409,25 @@ var memberStore = createStore()((set, get) => ({
3392
3409
  const { api } = sharedRefs;
3393
3410
  if (!api) return;
3394
3411
  const { serverId } = authStore.getState();
3412
+ const external = getExternalChannel(roomId);
3395
3413
  try {
3414
+ if (external) {
3415
+ const members2 = await api.getServerMembers(external.serverId);
3416
+ get().setMembers(members2, roomId);
3417
+ seedSocketUsers(members2.map((m) => ({ _id: m._id, username: m.username })));
3418
+ const { companyId } = external;
3419
+ if (companyId != null && !syncedExternalCompanies.has(companyId)) {
3420
+ const colleagues = members2.filter((m) => m.nickname);
3421
+ const customers = members2.filter((m) => !m.nickname);
3422
+ const canMapColleagues = colleagues.length === 0 || ownCompanyId != null;
3423
+ if (ownCompanyId != null && ownCompanyId !== companyId && colleagues.length > 0) {
3424
+ await mapCorvaUsers(ownCompanyId, colleagues);
3425
+ }
3426
+ const synced = await mapCorvaUsers(companyId, customers);
3427
+ if (synced && canMapColleagues) syncedExternalCompanies.add(companyId);
3428
+ }
3429
+ return;
3430
+ }
3396
3431
  const useServerMembers = (isAssetChat || roomType === "c") && serverId;
3397
3432
  if (useServerMembers) {
3398
3433
  const { serverMembersCache, serverMembersLoaded } = get();
@@ -3402,9 +3437,10 @@ var memberStore = createStore()((set, get) => ({
3402
3437
  return;
3403
3438
  }
3404
3439
  const members2 = await api.getServerMembers(serverId);
3440
+ set({ serverMembersLoaded: true, serverMembersCache: members2 });
3441
+ if (getExternalChannel(roomId)) return;
3405
3442
  get().setMembers(members2, roomId);
3406
3443
  seedSocketUsers(members2.map((m) => ({ _id: m._id, username: m.username })));
3407
- set({ serverMembersLoaded: true, serverMembersCache: members2 });
3408
3444
  return;
3409
3445
  }
3410
3446
  const channel = await api.getChannel(roomId);
@@ -3430,12 +3466,20 @@ var memberStore = createStore()((set, get) => ({
3430
3466
  },
3431
3467
  searchUsers: async (query) => {
3432
3468
  try {
3433
- const allUsers = await get().getAllVisibleUsers();
3469
+ const currentRoomId = roomStore.getState().currentRoom?._id;
3470
+ const { members, membersRoomId } = get();
3471
+ const external = getExternalChannel(currentRoomId);
3472
+ let allUsers;
3473
+ if (external) allUsers = membersRoomId === currentRoomId ? members : [];
3474
+ else allUsers = await get().getAllVisibleUsers();
3434
3475
  const q = query.trim().toLowerCase();
3435
3476
  if (!q) return allUsers;
3436
- return allUsers.filter(
3437
- (u) => u.username?.toLowerCase().includes(q) || u.name?.toLowerCase().includes(q) || u.displayName?.toLowerCase().includes(q)
3438
- );
3477
+ return allUsers.filter((u) => {
3478
+ if (u.nickname && u.displayName === u.nickname) {
3479
+ return u.nickname.toLowerCase().includes(q);
3480
+ }
3481
+ return u.username?.toLowerCase().includes(q) || u.name?.toLowerCase().includes(q) || u.displayName?.toLowerCase().includes(q);
3482
+ });
3439
3483
  } catch (e) {
3440
3484
  console.error("Failed to search users:", e);
3441
3485
  return [];
@@ -3468,71 +3512,89 @@ var memberStore = createStore()((set, get) => ({
3468
3512
  return visibleUsersRequest;
3469
3513
  },
3470
3514
  syncCorvaUsers: async (companyId) => {
3471
- const { api } = sharedRefs;
3472
- if (!api) return false;
3473
- try {
3474
- const corvaUsersResponse = await getChatHost().corvaApi.get(
3475
- "/v2/users",
3476
- {
3477
- company_id: companyId ?? 1,
3478
- per_page: 500,
3479
- fields: [
3480
- "user.first_name",
3481
- "user.last_name",
3482
- "user.email",
3483
- "user.profile_photo",
3484
- "user.title",
3485
- "user.role",
3486
- "user.company"
3487
- ]
3488
- }
3489
- );
3490
- const corvaUsers = corvaUsersResponse?.data || [];
3491
- const allUsers = await get().getAllVisibleUsers();
3492
- const currentMembers = get().members;
3493
- const userMap = /* @__PURE__ */ new Map();
3494
- allUsers.forEach((u) => userMap.set(u._id, u));
3495
- currentMembers.forEach((u) => {
3515
+ if (!sharedRefs.api) return false;
3516
+ ownCompanyId = companyId ?? 1;
3517
+ const allUsers = await get().getAllVisibleUsers();
3518
+ const userMap = /* @__PURE__ */ new Map();
3519
+ allUsers.forEach((u) => userMap.set(u._id, u));
3520
+ const { members, membersRoomId } = get();
3521
+ if (!getExternalChannel(membersRoomId)) {
3522
+ members.forEach((u) => {
3496
3523
  if (!userMap.has(u._id)) userMap.set(u._id, u);
3497
3524
  });
3498
- const usersToSync = Array.from(userMap.values());
3499
- if (usersToSync.length === 0) return false;
3500
- const corvaUsersByUsername = /* @__PURE__ */ new Map();
3501
- corvaUsers.forEach((corvaUser) => {
3502
- const email = corvaUser.attributes?.email;
3503
- if (email) {
3504
- const username = email.split("@")[0].toLowerCase();
3505
- corvaUsersByUsername.set(username, corvaUser);
3506
- }
3507
- });
3508
- const mappings = [];
3509
- usersToSync.forEach((revoltUser) => {
3510
- if (!revoltUser.username) return;
3511
- const username = revoltUser.username.toLowerCase();
3512
- const corvaUser = corvaUsersByUsername.get(username);
3513
- if (corvaUser) {
3514
- mappings.push({ revoltUserId: revoltUser._id, corvaUser });
3515
- }
3516
- });
3517
- get().bulkSetCorvaUserMappings(mappings);
3518
- mappings.forEach(({ revoltUserId, corvaUser }) => {
3519
- sharedRefs.corvaUserService.setMapping(revoltUserId, corvaUser);
3525
+ }
3526
+ const usersToSync = Array.from(userMap.values());
3527
+ if (usersToSync.length === 0) return false;
3528
+ return mapCorvaUsers(ownCompanyId, usersToSync);
3529
+ }
3530
+ }));
3531
+ var CORVA_USERS_PAGE_SIZE = 500;
3532
+ var CORVA_USERS_MAX_PAGES = 10;
3533
+ async function fetchCompanyCorvaUsers(companyId) {
3534
+ const users = [];
3535
+ for (let page = 1; page <= CORVA_USERS_MAX_PAGES; page += 1) {
3536
+ const response = await getChatHost().corvaApi.get("/v2/users", {
3537
+ company_id: companyId,
3538
+ per_page: CORVA_USERS_PAGE_SIZE,
3539
+ page,
3540
+ fields: [
3541
+ "user.first_name",
3542
+ "user.last_name",
3543
+ "user.email",
3544
+ "user.profile_photo",
3545
+ "user.title",
3546
+ "user.role",
3547
+ "user.company"
3548
+ ]
3549
+ });
3550
+ const data = response?.data || [];
3551
+ users.push(...data);
3552
+ if (data.length < CORVA_USERS_PAGE_SIZE) break;
3553
+ }
3554
+ return users;
3555
+ }
3556
+ var revoltUsernamesForEmail = (email) => {
3557
+ const username = email.split("@")[0].toLowerCase().slice(0, 32);
3558
+ return [username, username.replace(/\+/g, ".")];
3559
+ };
3560
+ async function mapCorvaUsers(companyId, revoltUsers) {
3561
+ try {
3562
+ const corvaUsersByUsername = /* @__PURE__ */ new Map();
3563
+ (await fetchCompanyCorvaUsers(companyId)).forEach((corvaUser) => {
3564
+ const email = corvaUser.attributes?.email;
3565
+ if (!email) return;
3566
+ revoltUsernamesForEmail(email).forEach((username) => {
3567
+ if (!corvaUsersByUsername.has(username)) corvaUsersByUsername.set(username, corvaUser);
3520
3568
  });
3521
- if (mappings.length > 0) {
3522
- const refreshedMembers = get().members;
3523
- const currentRoomId = roomStore.getState().currentRoom?._id;
3524
- get().setMembers(refreshedMembers, currentRoomId);
3525
- set({ allVisibleUsersCache: null });
3526
- invalidateVisibleUsers();
3569
+ });
3570
+ const mappings = [];
3571
+ revoltUsers.forEach((revoltUser) => {
3572
+ if (!revoltUser.username) return;
3573
+ const corvaUser = corvaUsersByUsername.get(revoltUser.username.toLowerCase());
3574
+ if (corvaUser) {
3575
+ mappings.push({ revoltUserId: revoltUser._id, corvaUser });
3527
3576
  }
3528
- return true;
3529
- } catch (error) {
3530
- console.error("Failed to sync Corva users:", error);
3531
- return false;
3577
+ });
3578
+ const store = memberStore.getState();
3579
+ store.bulkSetCorvaUserMappings(mappings);
3580
+ mappings.forEach(({ revoltUserId, corvaUser }) => {
3581
+ sharedRefs.corvaUserService.setMapping(revoltUserId, corvaUser);
3582
+ });
3583
+ if (mappings.length > 0) {
3584
+ const currentRoomId = roomStore.getState().currentRoom?._id;
3585
+ store.setMembers(memberStore.getState().members, currentRoomId);
3586
+ memberStore.setState({ allVisibleUsersCache: null });
3587
+ invalidateVisibleUsers();
3532
3588
  }
3589
+ return true;
3590
+ } catch (error) {
3591
+ console.error("Failed to sync Corva users:", error);
3592
+ return false;
3533
3593
  }
3534
- }));
3594
+ }
3535
3595
  var resetMemberStore = () => {
3596
+ syncedExternalCompanies.clear();
3597
+ ownCompanyId = null;
3536
3598
  invalidateVisibleUsers();
3537
3599
  memberStore.setState(getInitialState());
3538
3600
  };
@@ -3546,6 +3608,15 @@ var registerAssetChatChannel = (channelId, assetId, assetType) => {
3546
3608
  intervention_unit_id: assetType === "intervention_unit" ? id : null
3547
3609
  });
3548
3610
  };
3611
+ var registerChannelServer = ({ channelId, serverId, companyId }) => {
3612
+ const wasExternal = isExternalServerChannel(channelId);
3613
+ authStore.getState().setChannelServer(channelId, serverId, companyId);
3614
+ if (wasExternal === isExternalServerChannel(channelId)) return;
3615
+ const room = roomStore.getState().currentRoom;
3616
+ if (room?._id === channelId) {
3617
+ memberStore.getState().loadRoomMembers(channelId, room.t, true).catch((e) => console.error("Failed to reload asset chat members:", e));
3618
+ }
3619
+ };
3549
3620
  var openRoomLockedAsset = () => {
3550
3621
  const room = roomStore.getState().currentRoom;
3551
3622
  if (!room?._id) return null;
@@ -3591,8 +3662,10 @@ var assetStore = createStore()((set, get) => ({
3591
3662
  });
3592
3663
  const isStale = () => get().currentAssetId !== assetId;
3593
3664
  try {
3594
- const chatId = await getAssetChatChannel(assetId, assetType);
3665
+ const session = await getAssetChatSession(assetId, assetType);
3595
3666
  if (isStale()) return;
3667
+ const chatId = session.channelId;
3668
+ registerChannelServer(session);
3596
3669
  registerAssetChatChannel(chatId, assetId, assetType);
3597
3670
  set({
3598
3671
  assetChatId: chatId,
@@ -3645,7 +3718,9 @@ var assetStore = createStore()((set, get) => ({
3645
3718
  let chatId = get().assetChatId;
3646
3719
  if (!chatId) {
3647
3720
  try {
3648
- chatId = await getAssetChatChannel(currentAssetId, currentAssetType);
3721
+ const session = await getAssetChatSession(currentAssetId, currentAssetType);
3722
+ chatId = session.channelId;
3723
+ registerChannelServer(session);
3649
3724
  registerAssetChatChannel(chatId, currentAssetId, currentAssetType);
3650
3725
  set({
3651
3726
  assetChatId: chatId,
@@ -4480,6 +4555,7 @@ onChatStorageConfigured(() => uiStore.setState(loadAttentionBudget()));
4480
4555
  var getInitialState6 = () => ({
4481
4556
  user: null,
4482
4557
  serverId: null,
4558
+ externalChannels: {},
4483
4559
  isConnected: false,
4484
4560
  hasEverConnected: false,
4485
4561
  connectionGaveUp: false,
@@ -4502,6 +4578,13 @@ var authStore = createStore()((set, get) => ({
4502
4578
  channel
4503
4579
  ]
4504
4580
  })),
4581
+ setChannelServer: (channelId, serverId, companyId) => set((state) => {
4582
+ const { [channelId]: previous, ...rest } = state.externalChannels;
4583
+ const isExternal = !!serverId && !!state.serverId && serverId !== state.serverId;
4584
+ if (!isExternal) return previous ? { externalChannels: rest } : state;
4585
+ if (previous?.serverId === serverId && previous.companyId === companyId) return state;
4586
+ return { externalChannels: { ...rest, [channelId]: { serverId, companyId } } };
4587
+ }),
4505
4588
  markChatUsed: () => {
4506
4589
  if (get().chatUsed === true) return;
4507
4590
  set({ chatUsed: true });
@@ -4669,6 +4752,8 @@ var authStore = createStore()((set, get) => ({
4669
4752
  isAuthenticated: () => !!get().user,
4670
4753
  isSocketConnected: () => !!sharedRefs.socket?.isConnected()
4671
4754
  }));
4755
+ var getExternalChannel = (roomId) => roomId && authStore.getState().externalChannels[roomId] || null;
4756
+ var isExternalServerChannel = (roomId) => !!getExternalChannel(roomId);
4672
4757
  var resetAuthStore = () => authStore.setState(getInitialState6());
4673
4758
 
4674
4759
  // src/store/stores/messageStore.ts
@@ -5755,6 +5840,6 @@ function ensureChatSession(corvaUser) {
5755
5840
  return inFlight;
5756
5841
  }
5757
5842
 
5758
- export { ALERT_SEVERITY, ASSET_API_FIELDS, ASSET_CHAT_PREFIXES, ASSET_NOUN, CHANNEL_NAME_MAX_LENGTH, CHANNEL_TYPES, CORVA_MESSAGE_TYPES, CORVA_SYS_PREFIX, DATE_SEPARATOR_LABELS, DEFAULT_CHANNEL_CONTENT_FILTER, DEFAULT_CHANNEL_CONTENT_FILTERS, DEFAULT_CHANNEL_PREFERENCE, DEFAULT_FAVORITE_ROOMS_SETTINGS, DEFAULT_HIDDEN_ROOMS_SETTINGS, DEFAULT_NOTIFICATION_PREFERENCES, DEFAULT_NOTIFICATION_SETTINGS, DEFAULT_ROOM_LIST_ORDER, DIRECT_MESSAGE_PLACEHOLDER, GENERAL_CHAT_NAME, HttpError, MAX_ATTACHMENT_SIZE_BYTES, MAX_ATTACHMENT_SIZE_MB, MAX_NAVIGATION_HISTORY, MENTION_REPLACE_PATTERN, MENTION_SPLIT_PATTERN, MUTE_PRESET_OPTIONS, NOTIFICATION_DESTINATIONS, NOTIFICATION_SETTING_ALL, NOTIFICATION_SETTING_MENTIONS, NOTIFICATION_SETTING_NOTHING, PAUSE_INDEFINITELY, PAUSE_PRESETS, PAUSE_PRESET_OPTIONS, REVOLT_SYSTEM_USER_ID, ROOM_LIST_ORDER, SESSION_STORAGE_KEY, SIDEBAR_SECTIONS, SIDEBAR_TABS, SOFT_DELETE_MARKER, SYSTEM_MESSAGE_TEXTS, SessionManager, WEBSOCKET_CONNECTING, WEBSOCKET_OPEN, addMessage, addOrUpdateSubscription, alertMessageAsText, assetStore, authStore, buildAppCommentMessageContent, buildAskCorvaMessageContent, buildFinalMessage, buildForwardMessageContent, buildGroupChannelName, canDeleteMessage, canEditMessage, channelContentFilterStore, channelToAsset, chatToastStore, clearLastOpenedRoom, compareByActivity, compareByName, compareByRecencyDesc, configureChat, configureChatStorage, createAckScheduler, createCorvaUserService, createDMSubscription, createGroupSubscription, createHttpClient, createLatestWinsQueue, createMemoryStorage, createMessageCache, createRevoltAPI, createRevoltSocket, createRoomTaskQueue, createSocketEventHandlers, createSoftDeletedMessage, createTypingManager, deriveAllowedChatAsset, enrichWithCorvaData, ensureChatSession, extractTimestampFromULID, failOptimisticMessage, favoriteRoomsStore, findGeneralRoom, formatAssetChatName, getAppCommentAttachments, getAssetChatChannel, getAssetTypeFromDisplayName, getChatHost, getChatStorage, getCorvaUserFields, getLastOpenedRoom, getMessageTimestamp, getPauseUntil, getReactionCount, getRoomDisplayName, getSystemMessageWithCorvaNames, getUserDisplayName, getUserSecondaryText, handleUnauthorized, hasReactions, hasUserReacted, initChat, installUnreadWatcher, isAlertMessage, isAppCommentMessage, isAskCorvaMessage, isChannelMuted, isChatAssetTypeAllowed, isChatStorageConfigured, isCurrentRoomSelection, isDeepEqual, isDefaultChannelPreference, isDisallowedAssetChatRoom, isDmGroup, isForwardedMessage, isGeneralRoom, isNotificationsPaused, isPauseActive, isSoftDeletedMessage, isSystemMessage, isUnread, isUserOnline, isValidPausePreset, isVisibleUnread, keepChatUsed, loadUntilFound, memberStore, messageStore, navigationHistoryStore, notificationStore, onChatStorageConfigured, parseCorvaSystemMessage, prepareRoomSelection, removeMessageFromList, removeSubscription, resetAssetStore, resetAuthStore, resetChannelContentFilterStore, resetChatAssetPermissionsSnapshot, resetChatHost, resetFavoriteRoomsStore, resetMemberStore, resetMessageStore, resetNavigationHistoryStore, resetNotificationStore, resetRoomStore, resetUIStore, roomStore, saveLastChatActivity, saveLastOpenedRoom, searchMessages, searchRooms, searchUsers, selectCanGoBack, selectCanGoForward, setAllowedChatAssetTypes, settleOptimisticMessage, sharedRefs, sortChannels, sortDMs, sortMessagesByTime, sortUsersByStatus, stripPlatformMentions, uiStore, updateMessageInList, uploadAndSend, validateChannelName, waitForNextPaint, wasRecentlyActive, withChannelPreferenceDefaults };
5843
+ export { ALERT_SEVERITY, ASSET_API_FIELDS, ASSET_CHAT_PREFIXES, ASSET_NOUN, CHANNEL_NAME_MAX_LENGTH, CHANNEL_TYPES, CORVA_MESSAGE_TYPES, CORVA_SYS_PREFIX, DATE_SEPARATOR_LABELS, DEFAULT_CHANNEL_CONTENT_FILTER, DEFAULT_CHANNEL_CONTENT_FILTERS, DEFAULT_CHANNEL_PREFERENCE, DEFAULT_FAVORITE_ROOMS_SETTINGS, DEFAULT_HIDDEN_ROOMS_SETTINGS, DEFAULT_NOTIFICATION_PREFERENCES, DEFAULT_NOTIFICATION_SETTINGS, DEFAULT_ROOM_LIST_ORDER, DIRECT_MESSAGE_PLACEHOLDER, GENERAL_CHAT_NAME, HttpError, MAX_ATTACHMENT_SIZE_BYTES, MAX_ATTACHMENT_SIZE_MB, MAX_NAVIGATION_HISTORY, MENTION_REPLACE_PATTERN, MENTION_SPLIT_PATTERN, MUTE_PRESET_OPTIONS, NOTIFICATION_DESTINATIONS, NOTIFICATION_SETTING_ALL, NOTIFICATION_SETTING_MENTIONS, NOTIFICATION_SETTING_NOTHING, PAUSE_INDEFINITELY, PAUSE_PRESETS, PAUSE_PRESET_OPTIONS, REVOLT_SYSTEM_USER_ID, ROOM_LIST_ORDER, SESSION_STORAGE_KEY, SIDEBAR_SECTIONS, SIDEBAR_TABS, SOFT_DELETE_MARKER, SYSTEM_MESSAGE_TEXTS, SessionManager, WEBSOCKET_CONNECTING, WEBSOCKET_OPEN, addMessage, addOrUpdateSubscription, alertMessageAsText, assetStore, authStore, buildAppCommentMessageContent, buildAskCorvaMessageContent, buildFinalMessage, buildForwardMessageContent, buildGroupChannelName, canDeleteMessage, canEditMessage, channelContentFilterStore, channelToAsset, chatToastStore, clearLastOpenedRoom, compareByActivity, compareByName, compareByRecencyDesc, configureChat, configureChatStorage, createAckScheduler, createCorvaUserService, createDMSubscription, createGroupSubscription, createHttpClient, createLatestWinsQueue, createMemoryStorage, createMessageCache, createRevoltAPI, createRevoltSocket, createRoomTaskQueue, createSocketEventHandlers, createSoftDeletedMessage, createTypingManager, deriveAllowedChatAsset, enrichWithCorvaData, ensureChatSession, extractTimestampFromULID, failOptimisticMessage, favoriteRoomsStore, findGeneralRoom, formatAssetChatName, getAppCommentAttachments, getAssetChatChannel, getAssetChatSession, getAssetTypeFromDisplayName, getChatHost, getChatStorage, getCorvaUserFields, getExternalChannel, getLastOpenedRoom, getMessageTimestamp, getPauseUntil, getReactionCount, getRoomDisplayName, getSystemMessageWithCorvaNames, getUserDisplayName, getUserSecondaryText, handleUnauthorized, hasReactions, hasUserReacted, initChat, installUnreadWatcher, isAlertMessage, isAppCommentMessage, isAskCorvaMessage, isChannelMuted, isChatAssetTypeAllowed, isChatStorageConfigured, isCurrentRoomSelection, isDeepEqual, isDefaultChannelPreference, isDisallowedAssetChatRoom, isDmGroup, isExternalServerChannel, isForwardedMessage, isGeneralRoom, isNotificationsPaused, isPauseActive, isSoftDeletedMessage, isSystemMessage, isUnread, isUserOnline, isValidPausePreset, isVisibleUnread, keepChatUsed, loadUntilFound, memberStore, messageStore, navigationHistoryStore, notificationStore, onChatStorageConfigured, parseCorvaSystemMessage, prepareRoomSelection, removeMessageFromList, removeSubscription, resetAssetStore, resetAuthStore, resetChannelContentFilterStore, resetChatAssetPermissionsSnapshot, resetChatHost, resetFavoriteRoomsStore, resetMemberStore, resetMessageStore, resetNavigationHistoryStore, resetNotificationStore, resetRoomStore, resetUIStore, roomStore, saveLastChatActivity, saveLastOpenedRoom, searchMessages, searchRooms, searchUsers, selectCanGoBack, selectCanGoForward, setAllowedChatAssetTypes, settleOptimisticMessage, sharedRefs, sortChannels, sortDMs, sortMessagesByTime, sortUsersByStatus, stripPlatformMentions, uiStore, updateMessageInList, uploadAndSend, validateChannelName, waitForNextPaint, wasRecentlyActive, withChannelPreferenceDefaults };
5759
5844
  //# sourceMappingURL=index.js.map
5760
5845
  //# sourceMappingURL=index.js.map