@realtimexsco/live-chat 1.4.7 → 1.4.9
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/firebase-messaging-sw.js +127 -19
- package/dist/index.cjs +363 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +35 -1
- package/dist/index.d.ts +35 -1
- package/dist/index.mjs +346 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1650,4 +1650,38 @@ interface ForegroundPushBridgeProps {
|
|
|
1650
1650
|
}
|
|
1651
1651
|
declare const ForegroundPushBridge: ({ onPush }: ForegroundPushBridgeProps) => React.JSX.Element;
|
|
1652
1652
|
|
|
1653
|
-
|
|
1653
|
+
/** CustomEvent name — detail: `PushOpenRequest` */
|
|
1654
|
+
declare const OPEN_CONVERSATION_EVENT = "realtimex:open-conversation";
|
|
1655
|
+
/** Service-worker → page postMessage / BroadcastChannel type */
|
|
1656
|
+
declare const NOTIFICATION_CLICK_SW_TYPE = "realtimex:notification-click";
|
|
1657
|
+
/** Must match the channel name in firebase-messaging-sw.js */
|
|
1658
|
+
declare const PUSH_BROADCAST_CHANNEL = "realtimex-push";
|
|
1659
|
+
interface PushOpenRequest {
|
|
1660
|
+
conversationId: string;
|
|
1661
|
+
senderId?: string;
|
|
1662
|
+
kind?: string;
|
|
1663
|
+
messageId?: string;
|
|
1664
|
+
title?: string;
|
|
1665
|
+
}
|
|
1666
|
+
declare const resolveConversationIdFromPushData: (data?: Record<string, unknown> | null) => string;
|
|
1667
|
+
/** @deprecated use peekPendingOpenRequest */
|
|
1668
|
+
declare const peekPendingOpenConversation: () => string | null;
|
|
1669
|
+
declare const peekPendingOpenRequest: () => PushOpenRequest | null;
|
|
1670
|
+
/** @deprecated use consumePendingOpenRequest */
|
|
1671
|
+
declare const consumePendingOpenConversation: () => string | null;
|
|
1672
|
+
declare const consumePendingOpenRequest: () => PushOpenRequest | null;
|
|
1673
|
+
/**
|
|
1674
|
+
* Ask the chat UI to open a conversation. Safe to call when ChatMain is not
|
|
1675
|
+
* mounted yet — the request is kept in sessionStorage until the chat consumes it.
|
|
1676
|
+
*/
|
|
1677
|
+
declare const requestOpenConversation: (conversationId: string, meta?: Record<string, unknown> | PushOpenRequest) => void;
|
|
1678
|
+
/** Open immediately when the chat store/controller is already mounted. */
|
|
1679
|
+
declare const buildChannelFromPushRequest: (request: PushOpenRequest, loggedUserId?: string, allUsers?: any[]) => IChannel;
|
|
1680
|
+
interface NotificationClickBridgeOptions {
|
|
1681
|
+
/** Host chat route, default `/chat` */
|
|
1682
|
+
chatPath?: string;
|
|
1683
|
+
onNavigate?: (conversationId: string, pathWithQuery: string) => void;
|
|
1684
|
+
}
|
|
1685
|
+
declare const installNotificationClickBridge: (options?: NotificationClickBridgeOptions) => (() => void);
|
|
1686
|
+
|
|
1687
|
+
export { type ActiveChannelMessagesSlotProps, type AdminsDrawerSlotProps, type AttachmentsDrawerSlotProps, type AvatarSlotProps, CHAT_API_KEYS, CHAT_GET_API_KEYS, Calendar, CalendarDayButton, Channel, type ChannelDetailsDrawerSlotProps, ChannelHeaderView as ChannelHeader, type ChannelHeaderSlotProps, ChannelListView as ChannelList, ChannelListItem, type ChannelListItemSlotProps, type ChannelListSlotProps, type ChannelMessageBoxSlotProps, Chat, type ChatActionModalSlotProps, ChatAlertsProvider, type ChatApiKey, ChatAvatar, type ChatCallContext, type ChatClassNames, type ChatColorMode, type ChatComponents, type ChatCustomizationConfig, ChatCustomizationProvider, ChatDateJumpMenu, type ChatDateTimePreferences, type ChatFeatures, type ChatGetApiKey, ChatLayout, type ChatLayoutConfig, type ChatLayoutSlotProps, ChatLocaleProvider, ChatMain, type ChatPanelAlertsSlotProps, type ChatQueryParams, type ChatQueryParamsByApi, ChatThemeProvider, ChatViewport, type ChatViewportHeight, DefaultChannelListItem, DefaultChatAvatar, DefaultChatLayout, ForegroundPushBridge, type ForegroundPushBridgeProps, type ForegroundPushPayload, ForwardModalView as ForwardModal, type ForwardModalSlotProps, HeaderCallActions, type HeaderCallActionsSlotProps, type HeaderLeftSideSlotProps, type HeaderRightSideSlotProps, type HeaderSearchOverlaySlotProps, type IAttachment, type IChannel, type IDMDelete, type IDMEditMessage, type IDMForward, type IDMMessage, type IDMPin, type IDMReaction, type IDMRead, type IDMStar, type IDMTyping, type IDMUnstar, type IMessage, type ISocketConfig, type JumpToPreset, LoggedUserDetails, type LoggedUserDetailsSlotProps, type MembersDrawerSlotProps, type MessageAttachmentsSlotProps, ChannelMessageBoxView as MessageInput, MessageItemView as MessageItem, type MessageItemSlotProps, ActiveChannelMessagesView as MessageList, type MessageReactionsSlotProps, type MessageReplySnippetSlotProps, type MessageStatusSlotProps, type MessageToolbarSlotProps, NOTIFICATION_CLICK_SW_TYPE, type NotificationClickBridgeOptions, OPEN_CONVERSATION_EVENT, PUSH_BROADCAST_CHANNEL, PUSH_CHANGED_EVENT, type PendingJump, type PermissionDrawerSlotProps, type PhoneCallButtonSlotProps, type PinnedMessagesDrawerSlotProps, type PushConfig, PushNotificationToggle, type PushNotificationToggleProps, type PushNotificationsState, type PushOpenRequest, type PushPreference, type StarredMessagesDrawerSlotProps, type UIConfig, type UsePushNotifications, type VideoCallButtonSlotProps, apiGetPushConfig, apiGetPushPreference, apiRegisterPushToken, apiRemovePushToken, apiUpdatePushPreference, buildChannelFromPushRequest, capitalizeFirst, clampJumpDate, consumePendingOpenConversation, consumePendingOpenRequest, ChatMain as default, defaultChatClassNames, defaultChatComponents, defaultChatFeatures, defaultChatLayoutConfig, disablePushOnThisDevice, downloadFile, enablePushOnThisDevice, getChatBaseUrl, getChatQueryParamApis, getChatQueryParams, getChatQueryParamsByApi, getChatSocketUrl, getFirstAndLastNameOneCharacter, getResponsiveWidth, getSocketConfig, getStoredPushToken, installNotificationClickBridge, isEmpty, isPushSupported, mergeChatCustomization, mergeChatLayoutConfig, onForegroundPush, packageDefaultComponents, peekPendingOpenConversation, peekPendingOpenRequest, requestOpenConversation, resolveApiUrl, resolveChatApiKey, resolveConversationIdFromPushData, resolveJumpDateBounds, resolveJumpPreset, resolveJumpStep, resolveSocketUrl, setChatAccessToken, setChatBaseURL, setChatClientId, setChatQueryParamApis, setChatQueryParams, setChatQueryParamsByApi, setChatSocketUrl, showNotification, smoothScrollToMessage, socketService, startOfLocalDay, toDateInputValue, uniqueList, useChatAlerts, useChatContext, useChatController, useChatCustomization, useChatCustomizationOptional, useChatFeatures, useChatFeaturesOptional, useChatLocale, useStore as useChatStore, useChatTheme, usePushNotifications };
|
package/dist/index.d.ts
CHANGED
|
@@ -1650,4 +1650,38 @@ interface ForegroundPushBridgeProps {
|
|
|
1650
1650
|
}
|
|
1651
1651
|
declare const ForegroundPushBridge: ({ onPush }: ForegroundPushBridgeProps) => React.JSX.Element;
|
|
1652
1652
|
|
|
1653
|
-
|
|
1653
|
+
/** CustomEvent name — detail: `PushOpenRequest` */
|
|
1654
|
+
declare const OPEN_CONVERSATION_EVENT = "realtimex:open-conversation";
|
|
1655
|
+
/** Service-worker → page postMessage / BroadcastChannel type */
|
|
1656
|
+
declare const NOTIFICATION_CLICK_SW_TYPE = "realtimex:notification-click";
|
|
1657
|
+
/** Must match the channel name in firebase-messaging-sw.js */
|
|
1658
|
+
declare const PUSH_BROADCAST_CHANNEL = "realtimex-push";
|
|
1659
|
+
interface PushOpenRequest {
|
|
1660
|
+
conversationId: string;
|
|
1661
|
+
senderId?: string;
|
|
1662
|
+
kind?: string;
|
|
1663
|
+
messageId?: string;
|
|
1664
|
+
title?: string;
|
|
1665
|
+
}
|
|
1666
|
+
declare const resolveConversationIdFromPushData: (data?: Record<string, unknown> | null) => string;
|
|
1667
|
+
/** @deprecated use peekPendingOpenRequest */
|
|
1668
|
+
declare const peekPendingOpenConversation: () => string | null;
|
|
1669
|
+
declare const peekPendingOpenRequest: () => PushOpenRequest | null;
|
|
1670
|
+
/** @deprecated use consumePendingOpenRequest */
|
|
1671
|
+
declare const consumePendingOpenConversation: () => string | null;
|
|
1672
|
+
declare const consumePendingOpenRequest: () => PushOpenRequest | null;
|
|
1673
|
+
/**
|
|
1674
|
+
* Ask the chat UI to open a conversation. Safe to call when ChatMain is not
|
|
1675
|
+
* mounted yet — the request is kept in sessionStorage until the chat consumes it.
|
|
1676
|
+
*/
|
|
1677
|
+
declare const requestOpenConversation: (conversationId: string, meta?: Record<string, unknown> | PushOpenRequest) => void;
|
|
1678
|
+
/** Open immediately when the chat store/controller is already mounted. */
|
|
1679
|
+
declare const buildChannelFromPushRequest: (request: PushOpenRequest, loggedUserId?: string, allUsers?: any[]) => IChannel;
|
|
1680
|
+
interface NotificationClickBridgeOptions {
|
|
1681
|
+
/** Host chat route, default `/chat` */
|
|
1682
|
+
chatPath?: string;
|
|
1683
|
+
onNavigate?: (conversationId: string, pathWithQuery: string) => void;
|
|
1684
|
+
}
|
|
1685
|
+
declare const installNotificationClickBridge: (options?: NotificationClickBridgeOptions) => (() => void);
|
|
1686
|
+
|
|
1687
|
+
export { type ActiveChannelMessagesSlotProps, type AdminsDrawerSlotProps, type AttachmentsDrawerSlotProps, type AvatarSlotProps, CHAT_API_KEYS, CHAT_GET_API_KEYS, Calendar, CalendarDayButton, Channel, type ChannelDetailsDrawerSlotProps, ChannelHeaderView as ChannelHeader, type ChannelHeaderSlotProps, ChannelListView as ChannelList, ChannelListItem, type ChannelListItemSlotProps, type ChannelListSlotProps, type ChannelMessageBoxSlotProps, Chat, type ChatActionModalSlotProps, ChatAlertsProvider, type ChatApiKey, ChatAvatar, type ChatCallContext, type ChatClassNames, type ChatColorMode, type ChatComponents, type ChatCustomizationConfig, ChatCustomizationProvider, ChatDateJumpMenu, type ChatDateTimePreferences, type ChatFeatures, type ChatGetApiKey, ChatLayout, type ChatLayoutConfig, type ChatLayoutSlotProps, ChatLocaleProvider, ChatMain, type ChatPanelAlertsSlotProps, type ChatQueryParams, type ChatQueryParamsByApi, ChatThemeProvider, ChatViewport, type ChatViewportHeight, DefaultChannelListItem, DefaultChatAvatar, DefaultChatLayout, ForegroundPushBridge, type ForegroundPushBridgeProps, type ForegroundPushPayload, ForwardModalView as ForwardModal, type ForwardModalSlotProps, HeaderCallActions, type HeaderCallActionsSlotProps, type HeaderLeftSideSlotProps, type HeaderRightSideSlotProps, type HeaderSearchOverlaySlotProps, type IAttachment, type IChannel, type IDMDelete, type IDMEditMessage, type IDMForward, type IDMMessage, type IDMPin, type IDMReaction, type IDMRead, type IDMStar, type IDMTyping, type IDMUnstar, type IMessage, type ISocketConfig, type JumpToPreset, LoggedUserDetails, type LoggedUserDetailsSlotProps, type MembersDrawerSlotProps, type MessageAttachmentsSlotProps, ChannelMessageBoxView as MessageInput, MessageItemView as MessageItem, type MessageItemSlotProps, ActiveChannelMessagesView as MessageList, type MessageReactionsSlotProps, type MessageReplySnippetSlotProps, type MessageStatusSlotProps, type MessageToolbarSlotProps, NOTIFICATION_CLICK_SW_TYPE, type NotificationClickBridgeOptions, OPEN_CONVERSATION_EVENT, PUSH_BROADCAST_CHANNEL, PUSH_CHANGED_EVENT, type PendingJump, type PermissionDrawerSlotProps, type PhoneCallButtonSlotProps, type PinnedMessagesDrawerSlotProps, type PushConfig, PushNotificationToggle, type PushNotificationToggleProps, type PushNotificationsState, type PushOpenRequest, type PushPreference, type StarredMessagesDrawerSlotProps, type UIConfig, type UsePushNotifications, type VideoCallButtonSlotProps, apiGetPushConfig, apiGetPushPreference, apiRegisterPushToken, apiRemovePushToken, apiUpdatePushPreference, buildChannelFromPushRequest, capitalizeFirst, clampJumpDate, consumePendingOpenConversation, consumePendingOpenRequest, ChatMain as default, defaultChatClassNames, defaultChatComponents, defaultChatFeatures, defaultChatLayoutConfig, disablePushOnThisDevice, downloadFile, enablePushOnThisDevice, getChatBaseUrl, getChatQueryParamApis, getChatQueryParams, getChatQueryParamsByApi, getChatSocketUrl, getFirstAndLastNameOneCharacter, getResponsiveWidth, getSocketConfig, getStoredPushToken, installNotificationClickBridge, isEmpty, isPushSupported, mergeChatCustomization, mergeChatLayoutConfig, onForegroundPush, packageDefaultComponents, peekPendingOpenConversation, peekPendingOpenRequest, requestOpenConversation, resolveApiUrl, resolveChatApiKey, resolveConversationIdFromPushData, resolveJumpDateBounds, resolveJumpPreset, resolveJumpStep, resolveSocketUrl, setChatAccessToken, setChatBaseURL, setChatClientId, setChatQueryParamApis, setChatQueryParams, setChatQueryParamsByApi, setChatSocketUrl, showNotification, smoothScrollToMessage, socketService, startOfLocalDay, toDateInputValue, uniqueList, useChatAlerts, useChatContext, useChatController, useChatCustomization, useChatCustomizationOptional, useChatFeatures, useChatFeaturesOptional, useChatLocale, useStore as useChatStore, useChatTheme, usePushNotifications };
|
package/dist/index.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import { Sun, Moon, Search, X, Loader2, UserPlus, ChevronDown, ArrowLeft, Users,
|
|
|
13
13
|
import { cva } from 'class-variance-authority';
|
|
14
14
|
import EmojiPicker, { Theme } from 'emoji-picker-react';
|
|
15
15
|
import { getDefaultClassNames, DayPicker } from 'react-day-picker';
|
|
16
|
-
import { toast, Toaster } from 'react-hot-toast';
|
|
16
|
+
import toast2, { toast, Toaster } from 'react-hot-toast';
|
|
17
17
|
|
|
18
18
|
var __defProp = Object.defineProperty;
|
|
19
19
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -4626,6 +4626,205 @@ var Chat = ({
|
|
|
4626
4626
|
// src/hooks/useChatController.ts
|
|
4627
4627
|
init_useStore();
|
|
4628
4628
|
init_store_helpers();
|
|
4629
|
+
|
|
4630
|
+
// src/notifications/open-conversation.ts
|
|
4631
|
+
init_store_helpers();
|
|
4632
|
+
var OPEN_CONVERSATION_EVENT = "realtimex:open-conversation";
|
|
4633
|
+
var NOTIFICATION_CLICK_SW_TYPE = "realtimex:notification-click";
|
|
4634
|
+
var PUSH_BROADCAST_CHANNEL = "realtimex-push";
|
|
4635
|
+
var PENDING_STORAGE_KEY = "realtimex:pending-open-conversation";
|
|
4636
|
+
var resolveConversationIdFromPushData = (data) => {
|
|
4637
|
+
if (!data || typeof data !== "object") return "";
|
|
4638
|
+
let fcmMsg = data.FCM_MSG;
|
|
4639
|
+
if (typeof fcmMsg === "string") {
|
|
4640
|
+
try {
|
|
4641
|
+
fcmMsg = JSON.parse(fcmMsg);
|
|
4642
|
+
} catch {
|
|
4643
|
+
fcmMsg = void 0;
|
|
4644
|
+
}
|
|
4645
|
+
}
|
|
4646
|
+
const nested = fcmMsg && typeof fcmMsg === "object" ? fcmMsg.data : void 0;
|
|
4647
|
+
const source = { ...nested || {}, ...data };
|
|
4648
|
+
return String(
|
|
4649
|
+
source.conversationId || source.conversation_id || source.conversationID || ""
|
|
4650
|
+
).trim();
|
|
4651
|
+
};
|
|
4652
|
+
var normalizePushMeta = (meta) => {
|
|
4653
|
+
if (!meta || typeof meta !== "object") return {};
|
|
4654
|
+
return {
|
|
4655
|
+
senderId: String(
|
|
4656
|
+
meta.senderId || meta.sender_id || ""
|
|
4657
|
+
).trim() || void 0,
|
|
4658
|
+
kind: String(meta.kind || "").trim() || void 0,
|
|
4659
|
+
messageId: String(
|
|
4660
|
+
meta.messageId || meta.message_id || ""
|
|
4661
|
+
).trim() || void 0,
|
|
4662
|
+
title: String(meta.title || "").trim() || void 0
|
|
4663
|
+
};
|
|
4664
|
+
};
|
|
4665
|
+
var parsePendingRaw = (raw) => {
|
|
4666
|
+
if (!raw) return null;
|
|
4667
|
+
try {
|
|
4668
|
+
const parsed = JSON.parse(raw);
|
|
4669
|
+
if (parsed?.conversationId) {
|
|
4670
|
+
return {
|
|
4671
|
+
conversationId: String(parsed.conversationId).trim(),
|
|
4672
|
+
...normalizePushMeta(parsed)
|
|
4673
|
+
};
|
|
4674
|
+
}
|
|
4675
|
+
} catch {
|
|
4676
|
+
}
|
|
4677
|
+
const id = String(raw).trim();
|
|
4678
|
+
return id ? { conversationId: id } : null;
|
|
4679
|
+
};
|
|
4680
|
+
var peekPendingOpenConversation = () => peekPendingOpenRequest()?.conversationId ?? null;
|
|
4681
|
+
var peekPendingOpenRequest = () => {
|
|
4682
|
+
try {
|
|
4683
|
+
return parsePendingRaw(sessionStorage.getItem(PENDING_STORAGE_KEY));
|
|
4684
|
+
} catch {
|
|
4685
|
+
return null;
|
|
4686
|
+
}
|
|
4687
|
+
};
|
|
4688
|
+
var consumePendingOpenConversation = () => consumePendingOpenRequest()?.conversationId ?? null;
|
|
4689
|
+
var consumePendingOpenRequest = () => {
|
|
4690
|
+
const request = peekPendingOpenRequest();
|
|
4691
|
+
try {
|
|
4692
|
+
sessionStorage.removeItem(PENDING_STORAGE_KEY);
|
|
4693
|
+
} catch {
|
|
4694
|
+
}
|
|
4695
|
+
return request;
|
|
4696
|
+
};
|
|
4697
|
+
var requestOpenConversation = (conversationId, meta) => {
|
|
4698
|
+
const id = String(conversationId || "").trim();
|
|
4699
|
+
if (!id) return;
|
|
4700
|
+
const request = {
|
|
4701
|
+
conversationId: id,
|
|
4702
|
+
...normalizePushMeta(meta)
|
|
4703
|
+
};
|
|
4704
|
+
console.log("[realtimex-push] requestOpenConversation:", request);
|
|
4705
|
+
try {
|
|
4706
|
+
sessionStorage.setItem(PENDING_STORAGE_KEY, JSON.stringify(request));
|
|
4707
|
+
} catch {
|
|
4708
|
+
}
|
|
4709
|
+
try {
|
|
4710
|
+
window.dispatchEvent(
|
|
4711
|
+
new CustomEvent(OPEN_CONVERSATION_EVENT, { detail: request })
|
|
4712
|
+
);
|
|
4713
|
+
} catch {
|
|
4714
|
+
}
|
|
4715
|
+
};
|
|
4716
|
+
var buildChannelFromPushRequest = (request, loggedUserId, allUsers) => {
|
|
4717
|
+
const conversationId = request.conversationId;
|
|
4718
|
+
const isGroup = request.kind === "group";
|
|
4719
|
+
const senderId = String(request.senderId || "").trim();
|
|
4720
|
+
if (isGroup) {
|
|
4721
|
+
const rawName2 = request.title || "Group Chat";
|
|
4722
|
+
return {
|
|
4723
|
+
id: conversationId,
|
|
4724
|
+
conversationId,
|
|
4725
|
+
name: rawName2.charAt(0).toUpperCase() + rawName2.slice(1),
|
|
4726
|
+
isGroup: true
|
|
4727
|
+
};
|
|
4728
|
+
}
|
|
4729
|
+
const senderUser = senderId ? (allUsers || []).find((user) => String(user._id) === senderId) : null;
|
|
4730
|
+
const rawName = senderUser?.name || request.title || "New message";
|
|
4731
|
+
return {
|
|
4732
|
+
id: senderId || conversationId,
|
|
4733
|
+
conversationId,
|
|
4734
|
+
name: rawName.charAt(0).toUpperCase() + rawName.slice(1),
|
|
4735
|
+
image: senderUser?.image || void 0,
|
|
4736
|
+
email: senderUser?.email,
|
|
4737
|
+
isGroup: false
|
|
4738
|
+
};
|
|
4739
|
+
};
|
|
4740
|
+
var mapConversationToChannel = (conversation, loggedUserId, allUsers) => {
|
|
4741
|
+
const conversationId = String(conversation?._id || conversation?.id || "");
|
|
4742
|
+
const isGroup = isGroupConversation(conversation);
|
|
4743
|
+
if (isGroup) {
|
|
4744
|
+
const rawName2 = conversation.groupName || conversation.name || "Group Chat";
|
|
4745
|
+
return {
|
|
4746
|
+
id: conversationId,
|
|
4747
|
+
conversationId,
|
|
4748
|
+
name: rawName2.charAt(0).toUpperCase() + rawName2.slice(1),
|
|
4749
|
+
image: resolveGroupImage(conversation),
|
|
4750
|
+
isGroup: true,
|
|
4751
|
+
isLeft: !!conversation.isLeft,
|
|
4752
|
+
isBlocked: !!conversation.isBlocked,
|
|
4753
|
+
pinnedCount: conversation.pinnedCount,
|
|
4754
|
+
starredCount: conversation.starredCount
|
|
4755
|
+
};
|
|
4756
|
+
}
|
|
4757
|
+
const { id: otherId, user } = resolveOtherParticipant(
|
|
4758
|
+
conversation,
|
|
4759
|
+
loggedUserId,
|
|
4760
|
+
allUsers
|
|
4761
|
+
);
|
|
4762
|
+
const rawName = user?.name || "Unknown User";
|
|
4763
|
+
return {
|
|
4764
|
+
id: otherId || conversationId,
|
|
4765
|
+
conversationId,
|
|
4766
|
+
name: rawName.charAt(0).toUpperCase() + rawName.slice(1),
|
|
4767
|
+
image: user?.image || void 0,
|
|
4768
|
+
email: user?.email,
|
|
4769
|
+
isGroup: false,
|
|
4770
|
+
isLeft: !!conversation.isLeft,
|
|
4771
|
+
isBlocked: !!conversation.isBlocked,
|
|
4772
|
+
pinnedCount: conversation.pinnedCount,
|
|
4773
|
+
starredCount: conversation.starredCount
|
|
4774
|
+
};
|
|
4775
|
+
};
|
|
4776
|
+
var readConversationIdFromLocation = () => {
|
|
4777
|
+
try {
|
|
4778
|
+
return new URLSearchParams(window.location.search).get("conversationId") || "";
|
|
4779
|
+
} catch {
|
|
4780
|
+
return "";
|
|
4781
|
+
}
|
|
4782
|
+
};
|
|
4783
|
+
var consumedUrlConversationIds = /* @__PURE__ */ new Set();
|
|
4784
|
+
var handleNotificationOpen = (conversationId, pushData, options) => {
|
|
4785
|
+
const id = String(conversationId || "").trim();
|
|
4786
|
+
if (!id) {
|
|
4787
|
+
console.warn("[realtimex-push] notification open ignored \u2014 no conversationId", pushData);
|
|
4788
|
+
return;
|
|
4789
|
+
}
|
|
4790
|
+
requestOpenConversation(id, pushData);
|
|
4791
|
+
const chatPath = options.chatPath || "/chat";
|
|
4792
|
+
const pathWithQuery = `${chatPath}?conversationId=${encodeURIComponent(id)}`;
|
|
4793
|
+
options.onNavigate?.(id, pathWithQuery);
|
|
4794
|
+
};
|
|
4795
|
+
var installNotificationClickBridge = (options = {}) => {
|
|
4796
|
+
if (typeof window === "undefined") return () => void 0;
|
|
4797
|
+
const onSwMessage = (event) => {
|
|
4798
|
+
const data = event.data;
|
|
4799
|
+
console.log("[realtimex-push] SW \u2192 page message:", data);
|
|
4800
|
+
if (!data || data.type !== NOTIFICATION_CLICK_SW_TYPE) return;
|
|
4801
|
+
const pushData = data.data && typeof data.data === "object" ? data.data : void 0;
|
|
4802
|
+
const conversationId = String(data.conversationId || "") || resolveConversationIdFromPushData(pushData);
|
|
4803
|
+
console.log("[realtimex-push] notification click \u2192 open:", {
|
|
4804
|
+
conversationId,
|
|
4805
|
+
pushData
|
|
4806
|
+
});
|
|
4807
|
+
handleNotificationOpen(conversationId, pushData, options);
|
|
4808
|
+
};
|
|
4809
|
+
navigator.serviceWorker?.addEventListener("message", onSwMessage);
|
|
4810
|
+
let broadcast = null;
|
|
4811
|
+
try {
|
|
4812
|
+
broadcast = new BroadcastChannel(PUSH_BROADCAST_CHANNEL);
|
|
4813
|
+
broadcast.onmessage = onSwMessage;
|
|
4814
|
+
} catch {
|
|
4815
|
+
}
|
|
4816
|
+
const fromUrl = readConversationIdFromLocation();
|
|
4817
|
+
if (fromUrl && !consumedUrlConversationIds.has(fromUrl)) {
|
|
4818
|
+
consumedUrlConversationIds.add(fromUrl);
|
|
4819
|
+
handleNotificationOpen(fromUrl, void 0, options);
|
|
4820
|
+
}
|
|
4821
|
+
return () => {
|
|
4822
|
+
navigator.serviceWorker?.removeEventListener("message", onSwMessage);
|
|
4823
|
+
broadcast?.close();
|
|
4824
|
+
};
|
|
4825
|
+
};
|
|
4826
|
+
|
|
4827
|
+
// src/hooks/useChatController.ts
|
|
4629
4828
|
function resolveMessageType(content, attachments) {
|
|
4630
4829
|
if (attachments.length === 0) return "text";
|
|
4631
4830
|
if (!content.trim() && attachments.length === 1) {
|
|
@@ -4698,6 +4897,10 @@ var useChatController = () => {
|
|
|
4698
4897
|
const lastDM = useStore((s) => s.lastDM);
|
|
4699
4898
|
const loggedUserDetails = useStore((s) => s.loggedUserDetails);
|
|
4700
4899
|
const rateLimitResetAt2 = useStore((s) => s.rateLimitResetAt);
|
|
4900
|
+
const allUsers = useStore((s) => s.allUsers);
|
|
4901
|
+
const isFetchingConversations = useStore((s) => s.isFetchingConversations);
|
|
4902
|
+
const conversations = useStore((s) => s.conversations);
|
|
4903
|
+
const [pendingOpenRequest, setPendingOpenRequest] = useState(() => peekPendingOpenRequest());
|
|
4701
4904
|
const conversationsLength = useStore(
|
|
4702
4905
|
(s) => state.activeChannel?.conversationId ? 0 : s.conversations.length
|
|
4703
4906
|
);
|
|
@@ -4726,6 +4929,89 @@ var useChatController = () => {
|
|
|
4726
4929
|
isGroupConversation(latestInfo)
|
|
4727
4930
|
].join("|");
|
|
4728
4931
|
});
|
|
4932
|
+
useEffect(() => {
|
|
4933
|
+
const onOpen = (event) => {
|
|
4934
|
+
const detail = event.detail;
|
|
4935
|
+
if (detail?.conversationId) {
|
|
4936
|
+
console.log("[realtimex-push] OPEN_CONVERSATION_EVENT:", detail);
|
|
4937
|
+
setPendingOpenRequest({
|
|
4938
|
+
conversationId: String(detail.conversationId),
|
|
4939
|
+
senderId: detail.senderId,
|
|
4940
|
+
kind: detail.kind,
|
|
4941
|
+
messageId: detail.messageId,
|
|
4942
|
+
title: detail.title
|
|
4943
|
+
});
|
|
4944
|
+
}
|
|
4945
|
+
};
|
|
4946
|
+
window.addEventListener(OPEN_CONVERSATION_EVENT, onOpen);
|
|
4947
|
+
return () => window.removeEventListener(OPEN_CONVERSATION_EVENT, onOpen);
|
|
4948
|
+
}, []);
|
|
4949
|
+
useEffect(() => {
|
|
4950
|
+
if (!pendingOpenRequest?.conversationId || !loggedUserDetails) return;
|
|
4951
|
+
let cancelled = false;
|
|
4952
|
+
const openPending = async () => {
|
|
4953
|
+
const targetId = String(pendingOpenRequest.conversationId);
|
|
4954
|
+
console.log("[realtimex-push] opening conversation:", pendingOpenRequest);
|
|
4955
|
+
let conversation = conversations.find(
|
|
4956
|
+
(c) => String(c._id || c.id) === targetId
|
|
4957
|
+
) || null;
|
|
4958
|
+
if (!conversation) {
|
|
4959
|
+
conversation = conversationInfos[targetId] || null;
|
|
4960
|
+
}
|
|
4961
|
+
if (!conversation) {
|
|
4962
|
+
if (isFetchingConversations) {
|
|
4963
|
+
console.log("[realtimex-push] waiting for conversations list\u2026");
|
|
4964
|
+
return;
|
|
4965
|
+
}
|
|
4966
|
+
try {
|
|
4967
|
+
await fetchConversationInfo2(targetId);
|
|
4968
|
+
} catch (error) {
|
|
4969
|
+
console.warn("[realtimex-push] fetchConversationInfo failed:", error);
|
|
4970
|
+
}
|
|
4971
|
+
if (cancelled) return;
|
|
4972
|
+
const stateNow = useStore.getState();
|
|
4973
|
+
conversation = stateNow.conversations.find(
|
|
4974
|
+
(c) => String(c._id || c.id) === targetId
|
|
4975
|
+
) || stateNow.conversationInfos[targetId] || null;
|
|
4976
|
+
}
|
|
4977
|
+
const channel = conversation ? mapConversationToChannel(
|
|
4978
|
+
conversation,
|
|
4979
|
+
loggedUserDetails._id,
|
|
4980
|
+
allUsers
|
|
4981
|
+
) : buildChannelFromPushRequest(
|
|
4982
|
+
pendingOpenRequest,
|
|
4983
|
+
loggedUserDetails._id,
|
|
4984
|
+
allUsers
|
|
4985
|
+
);
|
|
4986
|
+
console.log("[realtimex-push] selected channel:", channel);
|
|
4987
|
+
if (cancelled) return;
|
|
4988
|
+
setState((prev) => {
|
|
4989
|
+
if (prev.activeChannel?.conversationId && String(prev.activeChannel.conversationId) === targetId) {
|
|
4990
|
+
return prev;
|
|
4991
|
+
}
|
|
4992
|
+
return {
|
|
4993
|
+
...prev,
|
|
4994
|
+
activeChannel: channel,
|
|
4995
|
+
activeConversationId: targetId
|
|
4996
|
+
};
|
|
4997
|
+
});
|
|
4998
|
+
useStore.getState().setActiveConversationId(targetId);
|
|
4999
|
+
consumePendingOpenRequest();
|
|
5000
|
+
setPendingOpenRequest(null);
|
|
5001
|
+
};
|
|
5002
|
+
void openPending();
|
|
5003
|
+
return () => {
|
|
5004
|
+
cancelled = true;
|
|
5005
|
+
};
|
|
5006
|
+
}, [
|
|
5007
|
+
pendingOpenRequest,
|
|
5008
|
+
loggedUserDetails,
|
|
5009
|
+
conversations,
|
|
5010
|
+
conversationInfos,
|
|
5011
|
+
isFetchingConversations,
|
|
5012
|
+
allUsers,
|
|
5013
|
+
fetchConversationInfo2
|
|
5014
|
+
]);
|
|
4729
5015
|
useEffect(() => {
|
|
4730
5016
|
const handler = setTimeout(() => {
|
|
4731
5017
|
updateState({ debouncedSearch: state.searchQuery });
|
|
@@ -17583,6 +17869,9 @@ var onForegroundPush = async (callback) => {
|
|
|
17583
17869
|
}
|
|
17584
17870
|
const { fb, messaging } = await getFirebaseMessaging(config.firebaseConfig);
|
|
17585
17871
|
return fb.onMessage(messaging, (payload) => {
|
|
17872
|
+
console.log("[realtimex-push] FCM foreground payload (raw):", payload);
|
|
17873
|
+
console.log("[realtimex-push] FCM foreground data:", payload?.data);
|
|
17874
|
+
console.log("[realtimex-push] FCM foreground notification:", payload?.notification);
|
|
17586
17875
|
callback({
|
|
17587
17876
|
title: payload?.notification?.title,
|
|
17588
17877
|
body: payload?.notification?.body,
|
|
@@ -17603,9 +17892,6 @@ var rememberToastId = (id) => {
|
|
|
17603
17892
|
}
|
|
17604
17893
|
return true;
|
|
17605
17894
|
};
|
|
17606
|
-
var resolveIncomingConversationId = (data) => String(
|
|
17607
|
-
data?.conversationId || data?.conversation_id || data?.conversationID || ""
|
|
17608
|
-
);
|
|
17609
17895
|
var resolveToastText = (title, body) => {
|
|
17610
17896
|
if (title && body) return `${title}: ${body}`;
|
|
17611
17897
|
return title || body || "";
|
|
@@ -17615,7 +17901,39 @@ var emitToast = (payload, onPush) => {
|
|
|
17615
17901
|
const title = payload.title || payload.data?.title;
|
|
17616
17902
|
const body = payload.body || payload.data?.body || payload.data?.message;
|
|
17617
17903
|
const text = resolveToastText(title, body);
|
|
17618
|
-
|
|
17904
|
+
const conversationId = resolveConversationIdFromPushData(payload.data);
|
|
17905
|
+
if (!text) return;
|
|
17906
|
+
if (conversationId) {
|
|
17907
|
+
toast2.custom(
|
|
17908
|
+
(t) => /* @__PURE__ */ jsx(
|
|
17909
|
+
"button",
|
|
17910
|
+
{
|
|
17911
|
+
type: "button",
|
|
17912
|
+
onClick: () => {
|
|
17913
|
+
toast2.dismiss(t.id);
|
|
17914
|
+
requestOpenConversation(conversationId, payload.data);
|
|
17915
|
+
},
|
|
17916
|
+
style: {
|
|
17917
|
+
display: "block",
|
|
17918
|
+
width: "100%",
|
|
17919
|
+
textAlign: "left",
|
|
17920
|
+
cursor: "pointer",
|
|
17921
|
+
background: "var(--background, #fff)",
|
|
17922
|
+
color: "var(--foreground, #111)",
|
|
17923
|
+
border: "1px solid rgba(0,0,0,0.08)",
|
|
17924
|
+
borderRadius: 8,
|
|
17925
|
+
padding: "10px 14px",
|
|
17926
|
+
boxShadow: "0 4px 12px rgba(0,0,0,0.12)",
|
|
17927
|
+
font: "inherit"
|
|
17928
|
+
},
|
|
17929
|
+
children: text
|
|
17930
|
+
}
|
|
17931
|
+
),
|
|
17932
|
+
{ duration: 5e3 }
|
|
17933
|
+
);
|
|
17934
|
+
return;
|
|
17935
|
+
}
|
|
17936
|
+
showNotification(text, "info");
|
|
17619
17937
|
};
|
|
17620
17938
|
var ForegroundPushBridge = ({ onPush }) => {
|
|
17621
17939
|
const lastDM = useStore((s) => s.lastDM);
|
|
@@ -17666,22 +17984,29 @@ var ForegroundPushBridge = ({ onPush }) => {
|
|
|
17666
17984
|
let retryTimer = null;
|
|
17667
17985
|
let cancelled = false;
|
|
17668
17986
|
const handlePayload = (payload) => {
|
|
17669
|
-
|
|
17987
|
+
console.log("[realtimex-push] ForegroundPushBridge payload:", payload);
|
|
17988
|
+
console.log("[realtimex-push] ForegroundPushBridge data keys:", payload.data);
|
|
17989
|
+
const incoming = resolveConversationIdFromPushData(payload.data);
|
|
17670
17990
|
const activeId = String(
|
|
17671
17991
|
useStore.getState().activeConversationId || ""
|
|
17672
17992
|
);
|
|
17673
17993
|
const messageId2 = String(
|
|
17674
17994
|
payload.data?.messageId || payload.data?.message_id || payload.data?.messageID || ""
|
|
17675
17995
|
);
|
|
17996
|
+
console.log("[realtimex-push] resolved from backend data:", {
|
|
17997
|
+
conversationId: incoming,
|
|
17998
|
+
messageId: messageId2,
|
|
17999
|
+
activeConversationId: activeId
|
|
18000
|
+
});
|
|
17676
18001
|
if (incoming && activeId && incoming === activeId) {
|
|
17677
|
-
console.
|
|
18002
|
+
console.log(
|
|
17678
18003
|
"[realtimex-push] foreground push suppressed (conversation open):",
|
|
17679
18004
|
incoming
|
|
17680
18005
|
);
|
|
17681
18006
|
return;
|
|
17682
18007
|
}
|
|
17683
18008
|
if (!rememberToastId(messageId2)) return;
|
|
17684
|
-
console.
|
|
18009
|
+
console.log("[realtimex-push] foreground push \u2192 toast:", {
|
|
17685
18010
|
title: payload.title,
|
|
17686
18011
|
conversationId: incoming,
|
|
17687
18012
|
activeConversationId: activeId
|
|
@@ -17730,6 +18055,18 @@ var ForegroundPushBridge = ({ onPush }) => {
|
|
|
17730
18055
|
window.removeEventListener(PUSH_CHANGED_EVENT, onPushChanged);
|
|
17731
18056
|
};
|
|
17732
18057
|
}, []);
|
|
18058
|
+
useEffect(() => {
|
|
18059
|
+
const onOpen = (event) => {
|
|
18060
|
+
const id = String(
|
|
18061
|
+
event.detail?.conversationId || ""
|
|
18062
|
+
);
|
|
18063
|
+
if (id) {
|
|
18064
|
+
console.debug("[realtimex-push] open-conversation event:", id);
|
|
18065
|
+
}
|
|
18066
|
+
};
|
|
18067
|
+
window.addEventListener(OPEN_CONVERSATION_EVENT, onOpen);
|
|
18068
|
+
return () => window.removeEventListener(OPEN_CONVERSATION_EVENT, onOpen);
|
|
18069
|
+
}, []);
|
|
17733
18070
|
return /* @__PURE__ */ jsx(
|
|
17734
18071
|
Toaster,
|
|
17735
18072
|
{
|
|
@@ -18198,6 +18535,6 @@ var PushNotificationToggle = ({
|
|
|
18198
18535
|
// src/index.ts
|
|
18199
18536
|
var index_default = ChatMain_default;
|
|
18200
18537
|
|
|
18201
|
-
export { CHAT_API_KEYS, CHAT_GET_API_KEYS, Calendar, CalendarDayButton, Channel, ChannelHeaderView_default as ChannelHeader, ChannelListView_default as ChannelList, ChannelListItem_default as ChannelListItem, Chat, ChatAlertsProvider, ChatAvatar_default as ChatAvatar, ChatCustomizationProvider, ChatDateJumpMenu, ChatLayout_default as ChatLayout, ChatLocaleProvider, ChatMain_default as ChatMain, ChatThemeProvider, ChatViewport, DefaultChannelListItem, DefaultChatAvatar, DefaultChatLayout_default as DefaultChatLayout, ForegroundPushBridge, ForwardModalView as ForwardModal, HeaderCallActions_default as HeaderCallActions, LoggedUserDetails_default as LoggedUserDetails, ChannelMessageBoxView_default as MessageInput, MessageItemView as MessageItem, ActiveChannelMessagesView_default as MessageList, PUSH_CHANGED_EVENT, PushNotificationToggle, apiGetPushConfig, apiGetPushPreference, apiRegisterPushToken, apiRemovePushToken, apiUpdatePushPreference, capitalizeFirst, clampJumpDate, index_default as default, defaultChatClassNames, defaultChatComponents, defaultChatFeatures, defaultChatLayoutConfig, disablePushOnThisDevice, downloadFile, enablePushOnThisDevice, getChatBaseUrl, getChatQueryParamApis, getChatQueryParams, getChatQueryParamsByApi, getChatSocketUrl, getFirstAndLastNameOneCharacter, getResponsiveWidth, getSocketConfig, getStoredPushToken, isEmpty, isPushSupported, mergeChatCustomization, mergeChatLayoutConfig, onForegroundPush, packageDefaultComponents, resolveApiUrl, resolveChatApiKey, resolveJumpDateBounds, resolveJumpPreset, resolveJumpStep, resolveSocketUrl, setChatAccessToken, setChatBaseURL, setChatClientId, setChatQueryParamApis, setChatQueryParams, setChatQueryParamsByApi, setChatSocketUrl, showNotification, smoothScrollToMessage, socket_service_default as socketService, startOfLocalDay, toDateInputValue, uniqueList, useChatAlerts, useChatContext, useChatController, useChatCustomization, useChatCustomizationOptional, useChatFeatures, useChatFeaturesOptional, useChatLocale, useStore as useChatStore, useChatTheme, usePushNotifications };
|
|
18538
|
+
export { CHAT_API_KEYS, CHAT_GET_API_KEYS, Calendar, CalendarDayButton, Channel, ChannelHeaderView_default as ChannelHeader, ChannelListView_default as ChannelList, ChannelListItem_default as ChannelListItem, Chat, ChatAlertsProvider, ChatAvatar_default as ChatAvatar, ChatCustomizationProvider, ChatDateJumpMenu, ChatLayout_default as ChatLayout, ChatLocaleProvider, ChatMain_default as ChatMain, ChatThemeProvider, ChatViewport, DefaultChannelListItem, DefaultChatAvatar, DefaultChatLayout_default as DefaultChatLayout, ForegroundPushBridge, ForwardModalView as ForwardModal, HeaderCallActions_default as HeaderCallActions, LoggedUserDetails_default as LoggedUserDetails, ChannelMessageBoxView_default as MessageInput, MessageItemView as MessageItem, ActiveChannelMessagesView_default as MessageList, NOTIFICATION_CLICK_SW_TYPE, OPEN_CONVERSATION_EVENT, PUSH_BROADCAST_CHANNEL, PUSH_CHANGED_EVENT, PushNotificationToggle, apiGetPushConfig, apiGetPushPreference, apiRegisterPushToken, apiRemovePushToken, apiUpdatePushPreference, buildChannelFromPushRequest, capitalizeFirst, clampJumpDate, consumePendingOpenConversation, consumePendingOpenRequest, index_default as default, defaultChatClassNames, defaultChatComponents, defaultChatFeatures, defaultChatLayoutConfig, disablePushOnThisDevice, downloadFile, enablePushOnThisDevice, getChatBaseUrl, getChatQueryParamApis, getChatQueryParams, getChatQueryParamsByApi, getChatSocketUrl, getFirstAndLastNameOneCharacter, getResponsiveWidth, getSocketConfig, getStoredPushToken, installNotificationClickBridge, isEmpty, isPushSupported, mergeChatCustomization, mergeChatLayoutConfig, onForegroundPush, packageDefaultComponents, peekPendingOpenConversation, peekPendingOpenRequest, requestOpenConversation, resolveApiUrl, resolveChatApiKey, resolveConversationIdFromPushData, resolveJumpDateBounds, resolveJumpPreset, resolveJumpStep, resolveSocketUrl, setChatAccessToken, setChatBaseURL, setChatClientId, setChatQueryParamApis, setChatQueryParams, setChatQueryParamsByApi, setChatSocketUrl, showNotification, smoothScrollToMessage, socket_service_default as socketService, startOfLocalDay, toDateInputValue, uniqueList, useChatAlerts, useChatContext, useChatController, useChatCustomization, useChatCustomizationOptional, useChatFeatures, useChatFeaturesOptional, useChatLocale, useStore as useChatStore, useChatTheme, usePushNotifications };
|
|
18202
18539
|
//# sourceMappingURL=index.mjs.map
|
|
18203
18540
|
//# sourceMappingURL=index.mjs.map
|