@corva/chat-core 0.1.4 → 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
@@ -78,6 +78,7 @@ interface AskCorvaData {
78
78
  isTruncated?: boolean;
79
79
  assetId?: number;
80
80
  agentName?: string;
81
+ note?: string;
81
82
  }
82
83
 
83
84
  type ChatAssetType = 'rig' | 'frac_fleet' | 'intervention_unit';
@@ -165,6 +166,7 @@ interface AskCorvaWirePayload {
165
166
  trunc?: boolean;
166
167
  assetId?: number;
167
168
  agentName?: string;
169
+ n?: string;
168
170
  }
169
171
  /**
170
172
  * One attachment on the wire. Keys are single letters like every other field in these payloads:
@@ -580,6 +582,7 @@ interface User {
580
582
  roles?: string[];
581
583
  active?: boolean;
582
584
  isBot?: boolean;
585
+ nickname?: string;
583
586
  displayName?: string;
584
587
  displayAvatar?: string;
585
588
  email?: string;
@@ -764,7 +767,7 @@ interface ParsedCorvaMessage {
764
767
  /**
765
768
  * Builds the wire-format content string for an AskCorva response.
766
769
  */
767
- declare function buildAskCorvaMessageContent(requestId: string, answer: string, answerRef?: string, isTruncated?: boolean, assetId?: number, agentName?: string, companyId?: number): string;
770
+ declare function buildAskCorvaMessageContent(requestId: string, answer: string, answerRef?: string, isTruncated?: boolean, assetId?: number, agentName?: string, companyId?: number, note?: string): string;
768
771
  /**
769
772
  * Builds the wire-format content string for a forwarded message.
770
773
  */
@@ -1170,6 +1173,8 @@ interface CorvaRevoltAuthResponse {
1170
1173
  revolt_user_id: string;
1171
1174
  revolt_company_server_id: string;
1172
1175
  revolt_channel_id: string;
1176
+ revolt_channel_server_id?: string;
1177
+ revolt_channel_company_id?: number;
1173
1178
  revolt_chat_channels?: AssetChatChannel[];
1174
1179
  chat_used?: boolean | null;
1175
1180
  }
@@ -1231,6 +1236,18 @@ declare function isValidPausePreset(value: unknown): value is PausePreset;
1231
1236
 
1232
1237
  declare function waitForNextPaint(): Promise<void>;
1233
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>;
1234
1251
  declare function getAssetChatChannel(assetId: string, assetType: ChatAssetType): Promise<string>;
1235
1252
 
1236
1253
  type StoredCorvaUser = CorvaUser | CorvaAPIUser;
@@ -1280,9 +1297,14 @@ declare const sharedRefs: SharedRefs;
1280
1297
  */
1281
1298
  declare const initChat: () => void;
1282
1299
 
1300
+ interface ExternalChannel {
1301
+ serverId: string;
1302
+ companyId: number | null;
1303
+ }
1283
1304
  interface AuthStore {
1284
1305
  user: User | null;
1285
1306
  serverId: string | null;
1307
+ externalChannels: Record<string, ExternalChannel>;
1286
1308
  isConnected: boolean;
1287
1309
  hasEverConnected: boolean;
1288
1310
  connectionGaveUp: boolean;
@@ -1292,6 +1314,7 @@ interface AuthStore {
1292
1314
  setConnected: (connected: boolean) => void;
1293
1315
  setHasEverConnected: (hasConnected: boolean) => void;
1294
1316
  addAssetChatChannel: (channel: AssetChatChannel) => void;
1317
+ setChannelServer: (channelId: string, serverId: string | null, companyId: number | null) => void;
1295
1318
  markChatUsed: () => void;
1296
1319
  login: (credentials: LoginCredentials) => Promise<{
1297
1320
  success: boolean;
@@ -1310,6 +1333,8 @@ interface AuthStore {
1310
1333
  }
1311
1334
  declare function keepChatUsed(current: boolean | null, incoming: boolean | null | undefined): boolean | null;
1312
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;
1313
1338
  /** @public */
1314
1339
  declare const resetAuthStore: () => void;
1315
1340
 
@@ -1697,4 +1722,4 @@ declare const createSocketEventHandlers: (config: SocketEventHandlersConfig) =>
1697
1722
 
1698
1723
  declare const installUnreadWatcher: () => void;
1699
1724
 
1700
- 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
 
@@ -419,7 +419,8 @@ function mapAskCorvaPayload(d) {
419
419
  companyId: d.cId,
420
420
  isTruncated: d.trunc,
421
421
  assetId: d.assetId,
422
- agentName: d.agentName
422
+ agentName: d.agentName,
423
+ note: d.n || void 0
423
424
  };
424
425
  }
425
426
  function mapForwardPayload(d) {
@@ -450,7 +451,7 @@ function mapAppCommentPayload(d) {
450
451
  isTruncated: d.trunc
451
452
  };
452
453
  }
453
- function buildAskCorvaMessageContent(requestId, answer, answerRef, isTruncated, assetId, agentName, companyId) {
454
+ function buildAskCorvaMessageContent(requestId, answer, answerRef, isTruncated, assetId, agentName, companyId, note) {
454
455
  const payload = {
455
456
  id: requestId,
456
457
  a: answerRef ? "" : answer,
@@ -458,7 +459,8 @@ function buildAskCorvaMessageContent(requestId, answer, answerRef, isTruncated,
458
459
  ...answerRef && companyId && { cId: companyId },
459
460
  ...isTruncated && { trunc: true },
460
461
  ...assetId && { assetId },
461
- ...agentName && { agentName }
462
+ ...agentName && { agentName },
463
+ ...note?.trim() && { n: note.trim() }
462
464
  };
463
465
  return `${CORVA_SYS_PREFIX}${JSON.stringify({ t: CORVA_MESSAGE_TYPES.ASK_CORVA, v: 1, d: payload })}`;
464
466
  }
@@ -563,7 +565,7 @@ function enrichWithCorvaData(message) {
563
565
  if (!parsed) return message;
564
566
  return {
565
567
  ...message,
566
- msg: parsed.forwardedFrom?.note || "",
568
+ msg: parsed.forwardedFrom?.note || parsed.askCorva?.note || "",
567
569
  t: parsed.messageType,
568
570
  alert: parsed.alert,
569
571
  feedItem: parsed.feedItem,
@@ -1647,11 +1649,15 @@ function createGroupsAPI(http) {
1647
1649
  async function getServerMembers(serverId) {
1648
1650
  try {
1649
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
+ );
1650
1655
  const users = response?.users || [];
1651
1656
  return users.map((member) => ({
1652
1657
  _id: member._id,
1653
1658
  username: member.username,
1654
1659
  name: member.display_name || member.username,
1660
+ nickname: nicknames.get(member._id),
1655
1661
  status: member.online ? "online" : "offline",
1656
1662
  isBot: !!member.bot
1657
1663
  }));
@@ -2982,7 +2988,7 @@ var ASSET_ID_PARAM = {
2982
2988
  frac_fleet: "frac_fleet_id",
2983
2989
  intervention_unit: "intervention_unit_id"
2984
2990
  };
2985
- async function getAssetChatChannel(assetId, assetType) {
2991
+ async function getAssetChatSession(assetId, assetType) {
2986
2992
  if (!assetId || Number.isNaN(Number(assetId))) {
2987
2993
  throw new Error("Asset ID is required");
2988
2994
  }
@@ -2994,7 +3000,15 @@ async function getAssetChatChannel(assetId, assetType) {
2994
3000
  if (!response?.revolt_channel_id) {
2995
3001
  throw new Error("No revolt_channel_id returned from asset chat API");
2996
3002
  }
2997
- 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;
2998
3012
  }
2999
3013
 
3000
3014
  // src/services/corvaUserService.ts
@@ -3026,6 +3040,9 @@ function createCorvaUserService() {
3026
3040
  enrichUser(user) {
3027
3041
  const corvaUser = revoltToCorva.get(user._id);
3028
3042
  if (!corvaUser) {
3043
+ if (user.nickname) {
3044
+ return { ...user, displayName: user.nickname, displayAvatar: void 0 };
3045
+ }
3029
3046
  return {
3030
3047
  ...user,
3031
3048
  displayName: user.name || user.username || "Unknown User",
@@ -3276,6 +3293,8 @@ var invalidateVisibleUsers = () => {
3276
3293
  visibleUsersGeneration += 1;
3277
3294
  visibleUsersRequest = null;
3278
3295
  };
3296
+ var syncedExternalCompanies = /* @__PURE__ */ new Set();
3297
+ var ownCompanyId = null;
3279
3298
  var seedSocketUsers = (members) => {
3280
3299
  sharedRefs.socket?.seedUsers(members);
3281
3300
  sharedRefs.api?.seedUserCache(members);
@@ -3390,7 +3409,25 @@ var memberStore = createStore()((set, get) => ({
3390
3409
  const { api } = sharedRefs;
3391
3410
  if (!api) return;
3392
3411
  const { serverId } = authStore.getState();
3412
+ const external = getExternalChannel(roomId);
3393
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
+ }
3394
3431
  const useServerMembers = (isAssetChat || roomType === "c") && serverId;
3395
3432
  if (useServerMembers) {
3396
3433
  const { serverMembersCache, serverMembersLoaded } = get();
@@ -3400,9 +3437,10 @@ var memberStore = createStore()((set, get) => ({
3400
3437
  return;
3401
3438
  }
3402
3439
  const members2 = await api.getServerMembers(serverId);
3440
+ set({ serverMembersLoaded: true, serverMembersCache: members2 });
3441
+ if (getExternalChannel(roomId)) return;
3403
3442
  get().setMembers(members2, roomId);
3404
3443
  seedSocketUsers(members2.map((m) => ({ _id: m._id, username: m.username })));
3405
- set({ serverMembersLoaded: true, serverMembersCache: members2 });
3406
3444
  return;
3407
3445
  }
3408
3446
  const channel = await api.getChannel(roomId);
@@ -3428,12 +3466,20 @@ var memberStore = createStore()((set, get) => ({
3428
3466
  },
3429
3467
  searchUsers: async (query) => {
3430
3468
  try {
3431
- 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();
3432
3475
  const q = query.trim().toLowerCase();
3433
3476
  if (!q) return allUsers;
3434
- return allUsers.filter(
3435
- (u) => u.username?.toLowerCase().includes(q) || u.name?.toLowerCase().includes(q) || u.displayName?.toLowerCase().includes(q)
3436
- );
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
+ });
3437
3483
  } catch (e) {
3438
3484
  console.error("Failed to search users:", e);
3439
3485
  return [];
@@ -3466,71 +3512,89 @@ var memberStore = createStore()((set, get) => ({
3466
3512
  return visibleUsersRequest;
3467
3513
  },
3468
3514
  syncCorvaUsers: async (companyId) => {
3469
- const { api } = sharedRefs;
3470
- if (!api) return false;
3471
- try {
3472
- const corvaUsersResponse = await getChatHost().corvaApi.get(
3473
- "/v2/users",
3474
- {
3475
- company_id: companyId ?? 1,
3476
- per_page: 500,
3477
- fields: [
3478
- "user.first_name",
3479
- "user.last_name",
3480
- "user.email",
3481
- "user.profile_photo",
3482
- "user.title",
3483
- "user.role",
3484
- "user.company"
3485
- ]
3486
- }
3487
- );
3488
- const corvaUsers = corvaUsersResponse?.data || [];
3489
- const allUsers = await get().getAllVisibleUsers();
3490
- const currentMembers = get().members;
3491
- const userMap = /* @__PURE__ */ new Map();
3492
- allUsers.forEach((u) => userMap.set(u._id, u));
3493
- 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) => {
3494
3523
  if (!userMap.has(u._id)) userMap.set(u._id, u);
3495
3524
  });
3496
- const usersToSync = Array.from(userMap.values());
3497
- if (usersToSync.length === 0) return false;
3498
- const corvaUsersByUsername = /* @__PURE__ */ new Map();
3499
- corvaUsers.forEach((corvaUser) => {
3500
- const email = corvaUser.attributes?.email;
3501
- if (email) {
3502
- const username = email.split("@")[0].toLowerCase();
3503
- corvaUsersByUsername.set(username, corvaUser);
3504
- }
3505
- });
3506
- const mappings = [];
3507
- usersToSync.forEach((revoltUser) => {
3508
- if (!revoltUser.username) return;
3509
- const username = revoltUser.username.toLowerCase();
3510
- const corvaUser = corvaUsersByUsername.get(username);
3511
- if (corvaUser) {
3512
- mappings.push({ revoltUserId: revoltUser._id, corvaUser });
3513
- }
3514
- });
3515
- get().bulkSetCorvaUserMappings(mappings);
3516
- mappings.forEach(({ revoltUserId, corvaUser }) => {
3517
- 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);
3518
3568
  });
3519
- if (mappings.length > 0) {
3520
- const refreshedMembers = get().members;
3521
- const currentRoomId = roomStore.getState().currentRoom?._id;
3522
- get().setMembers(refreshedMembers, currentRoomId);
3523
- set({ allVisibleUsersCache: null });
3524
- 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 });
3525
3576
  }
3526
- return true;
3527
- } catch (error) {
3528
- console.error("Failed to sync Corva users:", error);
3529
- 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();
3530
3588
  }
3589
+ return true;
3590
+ } catch (error) {
3591
+ console.error("Failed to sync Corva users:", error);
3592
+ return false;
3531
3593
  }
3532
- }));
3594
+ }
3533
3595
  var resetMemberStore = () => {
3596
+ syncedExternalCompanies.clear();
3597
+ ownCompanyId = null;
3534
3598
  invalidateVisibleUsers();
3535
3599
  memberStore.setState(getInitialState());
3536
3600
  };
@@ -3544,6 +3608,15 @@ var registerAssetChatChannel = (channelId, assetId, assetType) => {
3544
3608
  intervention_unit_id: assetType === "intervention_unit" ? id : null
3545
3609
  });
3546
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
+ };
3547
3620
  var openRoomLockedAsset = () => {
3548
3621
  const room = roomStore.getState().currentRoom;
3549
3622
  if (!room?._id) return null;
@@ -3589,8 +3662,10 @@ var assetStore = createStore()((set, get) => ({
3589
3662
  });
3590
3663
  const isStale = () => get().currentAssetId !== assetId;
3591
3664
  try {
3592
- const chatId = await getAssetChatChannel(assetId, assetType);
3665
+ const session = await getAssetChatSession(assetId, assetType);
3593
3666
  if (isStale()) return;
3667
+ const chatId = session.channelId;
3668
+ registerChannelServer(session);
3594
3669
  registerAssetChatChannel(chatId, assetId, assetType);
3595
3670
  set({
3596
3671
  assetChatId: chatId,
@@ -3643,7 +3718,9 @@ var assetStore = createStore()((set, get) => ({
3643
3718
  let chatId = get().assetChatId;
3644
3719
  if (!chatId) {
3645
3720
  try {
3646
- chatId = await getAssetChatChannel(currentAssetId, currentAssetType);
3721
+ const session = await getAssetChatSession(currentAssetId, currentAssetType);
3722
+ chatId = session.channelId;
3723
+ registerChannelServer(session);
3647
3724
  registerAssetChatChannel(chatId, currentAssetId, currentAssetType);
3648
3725
  set({
3649
3726
  assetChatId: chatId,
@@ -4478,6 +4555,7 @@ onChatStorageConfigured(() => uiStore.setState(loadAttentionBudget()));
4478
4555
  var getInitialState6 = () => ({
4479
4556
  user: null,
4480
4557
  serverId: null,
4558
+ externalChannels: {},
4481
4559
  isConnected: false,
4482
4560
  hasEverConnected: false,
4483
4561
  connectionGaveUp: false,
@@ -4500,6 +4578,13 @@ var authStore = createStore()((set, get) => ({
4500
4578
  channel
4501
4579
  ]
4502
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
+ }),
4503
4588
  markChatUsed: () => {
4504
4589
  if (get().chatUsed === true) return;
4505
4590
  set({ chatUsed: true });
@@ -4667,6 +4752,8 @@ var authStore = createStore()((set, get) => ({
4667
4752
  isAuthenticated: () => !!get().user,
4668
4753
  isSocketConnected: () => !!sharedRefs.socket?.isConnected()
4669
4754
  }));
4755
+ var getExternalChannel = (roomId) => roomId && authStore.getState().externalChannels[roomId] || null;
4756
+ var isExternalServerChannel = (roomId) => !!getExternalChannel(roomId);
4670
4757
  var resetAuthStore = () => authStore.setState(getInitialState6());
4671
4758
 
4672
4759
  // src/store/stores/messageStore.ts
@@ -5753,6 +5840,6 @@ function ensureChatSession(corvaUser) {
5753
5840
  return inFlight;
5754
5841
  }
5755
5842
 
5756
- 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 };
5757
5844
  //# sourceMappingURL=index.js.map
5758
5845
  //# sourceMappingURL=index.js.map