@corva/chat-core 0.1.6 → 0.1.7

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
@@ -497,6 +497,10 @@ interface TypingEventData {
497
497
  isTyping: boolean;
498
498
  roomId: string;
499
499
  }
500
+ interface ReadyServerData {
501
+ _id: string;
502
+ name?: string;
503
+ }
500
504
  interface ReadyChannelData {
501
505
  _id: string;
502
506
  channel_type: string;
@@ -514,7 +518,7 @@ interface RevoltSocketEventHandlers {
514
518
  onAuthenticated?: () => void;
515
519
  onDisconnected?: () => void;
516
520
  onInvalidSession?: () => void;
517
- onReady?: (channels: ReadyChannelData[], channelUnreads?: ChannelUnread[]) => void;
521
+ onReady?: (channels: ReadyChannelData[], channelUnreads?: ChannelUnread[], servers?: ReadyServerData[]) => void;
518
522
  onMessage?: (message: Message) => void;
519
523
  onMessageUpdate?: (messageId: string, channelId: string, data: {
520
524
  content?: string;
@@ -1304,7 +1308,9 @@ interface ExternalChannel {
1304
1308
  interface AuthStore {
1305
1309
  user: User | null;
1306
1310
  serverId: string | null;
1311
+ corvaCompanyId: number | null;
1307
1312
  externalChannels: Record<string, ExternalChannel>;
1313
+ serverNames: string[] | null;
1308
1314
  isConnected: boolean;
1309
1315
  hasEverConnected: boolean;
1310
1316
  connectionGaveUp: boolean;
@@ -1315,6 +1321,7 @@ interface AuthStore {
1315
1321
  setHasEverConnected: (hasConnected: boolean) => void;
1316
1322
  addAssetChatChannel: (channel: AssetChatChannel) => void;
1317
1323
  setChannelServer: (channelId: string, serverId: string | null, companyId: number | null) => void;
1324
+ setServerNames: (names: string[]) => void;
1318
1325
  markChatUsed: () => void;
1319
1326
  login: (credentials: LoginCredentials) => Promise<{
1320
1327
  success: boolean;
@@ -1334,6 +1341,7 @@ interface AuthStore {
1334
1341
  declare function keepChatUsed(current: boolean | null, incoming: boolean | null | undefined): boolean | null;
1335
1342
  declare const authStore: zustand_vanilla.StoreApi<AuthStore>;
1336
1343
  declare const getExternalChannel: (roomId: string | null | undefined) => ExternalChannel | null;
1344
+ declare const waitForServerNames: (timeoutMs: number) => Promise<string[] | null>;
1337
1345
  declare const isExternalServerChannel: (roomId: string | null | undefined) => boolean;
1338
1346
  /** @public */
1339
1347
  declare const resetAuthStore: () => void;
@@ -1517,6 +1525,12 @@ interface UIStore {
1517
1525
  declare const uiStore: zustand_vanilla.StoreApi<UIStore>;
1518
1526
  declare const resetUIStore: () => void;
1519
1527
 
1528
+ interface JoinRequired {
1529
+ assetId: string;
1530
+ assetType: ChatAssetType;
1531
+ companyId: number;
1532
+ companyName: string | null;
1533
+ }
1520
1534
  type LockedAsset = ChatAsset & {
1521
1535
  type: ChatAssetType;
1522
1536
  };
@@ -1527,6 +1541,7 @@ interface AssetStore {
1527
1541
  currentAssetStatus: string | null;
1528
1542
  assetChatId: string | null;
1529
1543
  assetChatError: string | null;
1544
+ joinRequired: JoinRequired | null;
1530
1545
  knownAssetChatIds: Set<string>;
1531
1546
  panelSyncedAssetId: string | null;
1532
1547
  isAssetLocked: boolean;
@@ -1534,6 +1549,7 @@ interface AssetStore {
1534
1549
  isAssetSwitching: boolean;
1535
1550
  setAssetContext: (assetId: string, assetType: ChatAssetType, assetName?: string, assetStatus?: string, skipAutoSelect?: boolean) => Promise<void>;
1536
1551
  clearAssetContext: () => void;
1552
+ joinAssetChat: () => Promise<void>;
1537
1553
  ensureAssetChatSubscription: () => Promise<Subscription | null>;
1538
1554
  toggleAssetLock: () => void;
1539
1555
  relockToAsset: (assetId: string, assetType: ChatAssetType, assetName: string) => Promise<void>;
@@ -1700,7 +1716,7 @@ declare const createSocketEventHandlers: (config: SocketEventHandlersConfig) =>
1700
1716
  onConnected: () => void;
1701
1717
  onAuthenticated: () => void;
1702
1718
  onDisconnected: () => void;
1703
- onReady: (channels: ReadyChannelData[], channelUnreads?: ChannelUnread[]) => void;
1719
+ onReady: (channels: ReadyChannelData[], channelUnreads?: ChannelUnread[], servers?: ReadyServerData[]) => void;
1704
1720
  onChannelAck: (channelId: string, messageId: string) => void;
1705
1721
  onMessage: (message: Message) => void;
1706
1722
  onRoomChange: (roomId: string, change: unknown) => void;
@@ -1722,4 +1738,4 @@ declare const createSocketEventHandlers: (config: SocketEventHandlersConfig) =>
1722
1738
 
1723
1739
  declare const installUnreadWatcher: () => void;
1724
1740
 
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 };
1741
+ 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 JoinRequired, 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 ReadyServerData, 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, waitForServerNames, wasRecentlyActive, withChannelPreferenceDefaults };
package/dist/index.js CHANGED
@@ -2091,7 +2091,7 @@ function createEventRouter(userCache2, sessionToken, autumnUrl, handlers, getMem
2091
2091
  break;
2092
2092
  case "Ready": {
2093
2093
  const readyEvent = message;
2094
- handlers.onReady?.(readyEvent.channels, readyEvent.channel_unreads);
2094
+ handlers.onReady?.(readyEvent.channels, readyEvent.channel_unreads, readyEvent.servers);
2095
2095
  break;
2096
2096
  }
2097
2097
  case "Message":
@@ -3598,6 +3598,86 @@ var resetMemberStore = () => {
3598
3598
  invalidateVisibleUsers();
3599
3599
  memberStore.setState(getInitialState());
3600
3600
  };
3601
+
3602
+ // src/store/services/externalChatJoin.ts
3603
+ var ASSET_RESOURCE = {
3604
+ rig: "rigs",
3605
+ frac_fleet: "frac_fleets",
3606
+ intervention_unit: "intervention_units"
3607
+ };
3608
+ var ownerRequests = /* @__PURE__ */ new Map();
3609
+ var joinedThisSession = /* @__PURE__ */ new Set();
3610
+ async function fetchAssetOwnerCompany(assetId, assetType) {
3611
+ const response = await getChatHost().corvaApi.get(
3612
+ `/v2/${ASSET_RESOURCE[assetType]}/${assetId}`,
3613
+ { fields: [`${assetType}.company`, "company.name"], include: "company" }
3614
+ );
3615
+ const companyId = Number(response?.data?.relationships?.company?.data?.id);
3616
+ if (!Number.isFinite(companyId)) throw new Error("Asset company is missing");
3617
+ const company = response?.included?.find(
3618
+ (item) => item.type === "company" && Number(item.id) === companyId
3619
+ );
3620
+ return { id: companyId, name: company?.attributes?.name ?? null };
3621
+ }
3622
+ function getAssetOwnerCompany(assetId, assetType) {
3623
+ const key = `${assetType}:${assetId}`;
3624
+ const cached = ownerRequests.get(key);
3625
+ if (cached) return cached;
3626
+ const request = fetchAssetOwnerCompany(assetId, assetType);
3627
+ request.catch(() => ownerRequests.delete(key));
3628
+ ownerRequests.set(key, request);
3629
+ return request;
3630
+ }
3631
+ var normalizeName = (name) => name.trim().toLowerCase();
3632
+ function isOnCompanyServer(serverNames, companyName) {
3633
+ if (!companyName) return false;
3634
+ const target = normalizeName(companyName);
3635
+ return serverNames.some((name) => normalizeName(name) === target);
3636
+ }
3637
+ var joinedKey = (revoltUserId) => `corva_chat_joined_companies_${revoltUserId}`;
3638
+ function readJoinedCompanies(revoltUserId) {
3639
+ try {
3640
+ const raw = getChatStorage().getItem(joinedKey(revoltUserId));
3641
+ const parsed = raw ? JSON.parse(raw) : [];
3642
+ return Array.isArray(parsed) ? parsed.filter((id) => typeof id === "number") : [];
3643
+ } catch {
3644
+ return [];
3645
+ }
3646
+ }
3647
+ function hasJoinedCompany(revoltUserId, companyId) {
3648
+ return joinedThisSession.has(`${revoltUserId}:${companyId}`) || readJoinedCompanies(revoltUserId).includes(companyId);
3649
+ }
3650
+ function markCompanyJoined(revoltUserId, companyId) {
3651
+ joinedThisSession.add(`${revoltUserId}:${companyId}`);
3652
+ const joined = readJoinedCompanies(revoltUserId);
3653
+ if (joined.includes(companyId)) return;
3654
+ try {
3655
+ getChatStorage().setItem(joinedKey(revoltUserId), JSON.stringify([...joined, companyId]));
3656
+ } catch (error) {
3657
+ console.error("Failed to save joined company:", error);
3658
+ }
3659
+ }
3660
+ function resetAssetOwnerCompanies() {
3661
+ ownerRequests.clear();
3662
+ joinedThisSession.clear();
3663
+ }
3664
+
3665
+ // src/store/stores/assetStore.ts
3666
+ var SERVER_NAMES_WAIT_MS = 5e3;
3667
+ var joinApprovedAssets = /* @__PURE__ */ new Set();
3668
+ async function getJoinRequired(assetId, assetType) {
3669
+ const { corvaCompanyId, user } = authStore.getState();
3670
+ if (!user?._id) return null;
3671
+ if (joinApprovedAssets.has(`${assetType}:${assetId}`)) return null;
3672
+ const owner = await getAssetOwnerCompany(assetId, assetType);
3673
+ if (owner.id === corvaCompanyId || hasJoinedCompany(user._id, owner.id)) return null;
3674
+ const serverNames = await waitForServerNames(SERVER_NAMES_WAIT_MS);
3675
+ if (serverNames && isOnCompanyServer(serverNames, owner.name)) {
3676
+ markCompanyJoined(user._id, owner.id);
3677
+ return null;
3678
+ }
3679
+ return { assetId, assetType, companyId: owner.id, companyName: owner.name };
3680
+ }
3601
3681
  var registerAssetChatChannel = (channelId, assetId, assetType) => {
3602
3682
  const id = Number(assetId);
3603
3683
  if (!Number.isFinite(id)) return;
@@ -3636,6 +3716,7 @@ var getInitialState2 = () => ({
3636
3716
  currentAssetStatus: null,
3637
3717
  assetChatId: null,
3638
3718
  assetChatError: null,
3719
+ joinRequired: null,
3639
3720
  knownAssetChatIds: /* @__PURE__ */ new Set(),
3640
3721
  panelSyncedAssetId: null,
3641
3722
  isAssetLocked: false,
@@ -3648,7 +3729,9 @@ var assetStore = createStore()((set, get) => ({
3648
3729
  setAssetContext: async (assetId, assetType, assetName, assetStatus, skipAutoSelect) => {
3649
3730
  const currentState = get();
3650
3731
  const isSameAsset = currentState.currentAssetId === assetId;
3651
- if (isSameAsset && (currentState.assetChatId || currentState.assetChatError)) return;
3732
+ if (isSameAsset && (currentState.assetChatId || currentState.assetChatError || currentState.joinRequired)) {
3733
+ return;
3734
+ }
3652
3735
  const isAssetChanging = !isSameAsset;
3653
3736
  uiStore.setState({ isLoading: true });
3654
3737
  set({
@@ -3657,11 +3740,19 @@ var assetStore = createStore()((set, get) => ({
3657
3740
  currentAssetName: assetName || assetId,
3658
3741
  currentAssetStatus: assetStatus ?? null,
3659
3742
  assetChatError: null,
3743
+ joinRequired: null,
3660
3744
  ...isSameAsset ? {} : { assetChatId: null },
3661
3745
  ...isAssetChanging && { isAssetSwitching: true }
3662
3746
  });
3663
3747
  const isStale = () => get().currentAssetId !== assetId;
3664
3748
  try {
3749
+ const joinRequired = await getJoinRequired(assetId, assetType);
3750
+ if (isStale()) return;
3751
+ if (joinRequired) {
3752
+ set({ joinRequired });
3753
+ uiStore.setState({ isLoading: false });
3754
+ return;
3755
+ }
3665
3756
  const session = await getAssetChatSession(assetId, assetType);
3666
3757
  if (isStale()) return;
3667
3758
  const chatId = session.channelId;
@@ -3698,7 +3789,8 @@ var assetStore = createStore()((set, get) => ({
3698
3789
  assetChatId: null,
3699
3790
  panelSyncedAssetId: null,
3700
3791
  lockedAsset: null,
3701
- assetChatError: null
3792
+ assetChatError: null,
3793
+ joinRequired: null
3702
3794
  });
3703
3795
  if (currentUser && previousAssetChatId && roomStore.getState().currentRoom?._id === previousAssetChatId) {
3704
3796
  const generalChat = findGeneralRoom(roomStore.getState().subscriptions);
@@ -3707,6 +3799,26 @@ var assetStore = createStore()((set, get) => ({
3707
3799
  }
3708
3800
  }
3709
3801
  },
3802
+ joinAssetChat: async () => {
3803
+ const { joinRequired } = get();
3804
+ const userId = authStore.getState().user?._id;
3805
+ if (!joinRequired || !userId) return;
3806
+ const approvalKey = `${joinRequired.assetType}:${joinRequired.assetId}`;
3807
+ joinApprovedAssets.add(approvalKey);
3808
+ set({ joinRequired: null });
3809
+ const { currentAssetName, currentAssetStatus } = get();
3810
+ try {
3811
+ await get().setAssetContext(
3812
+ joinRequired.assetId,
3813
+ joinRequired.assetType,
3814
+ currentAssetName ?? void 0,
3815
+ currentAssetStatus ?? void 0
3816
+ );
3817
+ if (get().assetChatId) markCompanyJoined(userId, joinRequired.companyId);
3818
+ } finally {
3819
+ joinApprovedAssets.delete(approvalKey);
3820
+ }
3821
+ },
3710
3822
  ensureAssetChatSubscription: async () => {
3711
3823
  const { currentAssetId, currentAssetType } = get();
3712
3824
  if (!currentAssetId || !currentAssetType) return null;
@@ -3717,6 +3829,17 @@ var assetStore = createStore()((set, get) => ({
3717
3829
  try {
3718
3830
  let chatId = get().assetChatId;
3719
3831
  if (!chatId) {
3832
+ let joinRequired;
3833
+ try {
3834
+ joinRequired = await getJoinRequired(currentAssetId, currentAssetType);
3835
+ } catch (e) {
3836
+ console.error("Failed to check asset chat access:", e);
3837
+ return null;
3838
+ }
3839
+ if (joinRequired) {
3840
+ if (get().currentAssetId === currentAssetId) set({ joinRequired });
3841
+ return null;
3842
+ }
3720
3843
  try {
3721
3844
  const session = await getAssetChatSession(currentAssetId, currentAssetType);
3722
3845
  chatId = session.channelId;
@@ -4555,7 +4678,9 @@ onChatStorageConfigured(() => uiStore.setState(loadAttentionBudget()));
4555
4678
  var getInitialState6 = () => ({
4556
4679
  user: null,
4557
4680
  serverId: null,
4681
+ corvaCompanyId: null,
4558
4682
  externalChannels: {},
4683
+ serverNames: null,
4559
4684
  isConnected: false,
4560
4685
  hasEverConnected: false,
4561
4686
  connectionGaveUp: false,
@@ -4585,6 +4710,7 @@ var authStore = createStore()((set, get) => ({
4585
4710
  if (previous?.serverId === serverId && previous.companyId === companyId) return state;
4586
4711
  return { externalChannels: { ...rest, [channelId]: { serverId, companyId } } };
4587
4712
  }),
4713
+ setServerNames: (names) => set({ serverNames: names }),
4588
4714
  markChatUsed: () => {
4589
4715
  if (get().chatUsed === true) return;
4590
4716
  set({ chatUsed: true });
@@ -4685,6 +4811,7 @@ var authStore = createStore()((set, get) => ({
4685
4811
  getChatHost().notifier?.onLogout?.();
4686
4812
  resetRoomStore();
4687
4813
  resetAssetStore();
4814
+ resetAssetOwnerCompanies();
4688
4815
  resetMessageStore();
4689
4816
  resetChatAssetPermissionsSnapshot();
4690
4817
  resetUIStore();
@@ -4753,6 +4880,22 @@ var authStore = createStore()((set, get) => ({
4753
4880
  isSocketConnected: () => !!sharedRefs.socket?.isConnected()
4754
4881
  }));
4755
4882
  var getExternalChannel = (roomId) => roomId && authStore.getState().externalChannels[roomId] || null;
4883
+ var waitForServerNames = (timeoutMs) => {
4884
+ const current = authStore.getState().serverNames;
4885
+ if (current) return Promise.resolve(current);
4886
+ return new Promise((resolve) => {
4887
+ const timer = setTimeout(() => {
4888
+ unsubscribe();
4889
+ resolve(null);
4890
+ }, timeoutMs);
4891
+ const unsubscribe = authStore.subscribe((state) => {
4892
+ if (!state.serverNames) return;
4893
+ clearTimeout(timer);
4894
+ unsubscribe();
4895
+ resolve(state.serverNames);
4896
+ });
4897
+ });
4898
+ };
4756
4899
  var isExternalServerChannel = (roomId) => !!getExternalChannel(roomId);
4757
4900
  var resetAuthStore = () => authStore.setState(getInitialState6());
4758
4901
 
@@ -5228,8 +5371,11 @@ var createSocketEventHandlers = (config) => {
5228
5371
  onDisconnected: () => {
5229
5372
  authStore.setState({ isConnected: false });
5230
5373
  },
5231
- onReady: (channels, channelUnreads) => {
5374
+ onReady: (channels, channelUnreads, servers) => {
5232
5375
  if (!authStore.getState().user?._id) return;
5376
+ authStore.getState().setServerNames(
5377
+ (servers ?? []).map((server) => server.name).filter((name) => !!name)
5378
+ );
5233
5379
  const channelLastMsg = /* @__PURE__ */ new Map();
5234
5380
  channels.forEach((ch) => {
5235
5381
  if (ch.last_message_id) {
@@ -5817,6 +5963,9 @@ async function handleUnauthorized() {
5817
5963
  function ensureChatSession(corvaUser) {
5818
5964
  lastCorvaUser = corvaUser;
5819
5965
  initChat();
5966
+ if (authStore.getState().corvaCompanyId !== corvaUser.company_id) {
5967
+ authStore.setState({ corvaCompanyId: corvaUser.company_id ?? null });
5968
+ }
5820
5969
  sharedRefs.api?.setUnauthorizedHandler(() => {
5821
5970
  handleUnauthorized().catch((error) => console.error("Chat re-authentication failed", error));
5822
5971
  });
@@ -5840,6 +5989,6 @@ function ensureChatSession(corvaUser) {
5840
5989
  return inFlight;
5841
5990
  }
5842
5991
 
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 };
5992
+ 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, waitForServerNames, wasRecentlyActive, withChannelPreferenceDefaults };
5844
5993
  //# sourceMappingURL=index.js.map
5845
5994
  //# sourceMappingURL=index.js.map