@realtimexsco/live-chat 1.4.0 → 1.4.1

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.mts CHANGED
@@ -1548,4 +1548,90 @@ declare function Calendar({ className, classNames, showOutsideDays, captionLayou
1548
1548
  }): React.JSX.Element;
1549
1549
  declare function CalendarDayButton({ className, day, modifiers, ...props }: React.ComponentProps<typeof DayButton>): React.JSX.Element;
1550
1550
 
1551
- 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, 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, type PendingJump, type PermissionDrawerSlotProps, type PhoneCallButtonSlotProps, type PinnedMessagesDrawerSlotProps, type StarredMessagesDrawerSlotProps, type UIConfig, type VideoCallButtonSlotProps, capitalizeFirst, clampJumpDate, ChatMain as default, defaultChatClassNames, defaultChatComponents, defaultChatFeatures, defaultChatLayoutConfig, downloadFile, getChatBaseUrl, getChatQueryParamApis, getChatQueryParams, getChatQueryParamsByApi, getChatSocketUrl, getFirstAndLastNameOneCharacter, getResponsiveWidth, getSocketConfig, isEmpty, mergeChatCustomization, mergeChatLayoutConfig, packageDefaultComponents, resolveApiUrl, resolveChatApiKey, 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 };
1551
+ interface PushConfig {
1552
+ /** Firebase credentials present on the backend deployment. */
1553
+ configured: boolean;
1554
+ /** Super-admin ceiling AND client admin toggle, resolved. */
1555
+ enabled: boolean;
1556
+ firebaseConfig: Record<string, string> | null;
1557
+ vapidKey: string | null;
1558
+ }
1559
+ interface PushPreference {
1560
+ enabled: boolean;
1561
+ allowedByWorkspace: boolean;
1562
+ deviceCount: number;
1563
+ }
1564
+ declare const apiGetPushConfig: () => Promise<PushConfig>;
1565
+ declare const apiRegisterPushToken: (token: string, deviceLabel?: string) => Promise<any>;
1566
+ declare const apiRemovePushToken: (token: string) => Promise<any>;
1567
+ declare const apiGetPushPreference: () => Promise<PushPreference>;
1568
+ declare const apiUpdatePushPreference: (enabled: boolean) => Promise<any>;
1569
+ declare const isPushSupported: () => boolean;
1570
+ declare const getStoredPushToken: () => string | null;
1571
+ /**
1572
+ * Full device opt-in: browser permission prompt → FCM token → backend
1573
+ * registration. Returns the registered token.
1574
+ */
1575
+ declare const enablePushOnThisDevice: () => Promise<string>;
1576
+ /** Device opt-out: invalidates the FCM token and removes it server-side. */
1577
+ declare const disablePushOnThisDevice: () => Promise<void>;
1578
+ /**
1579
+ * Foreground messages (tab focused) — FCM does not display these itself.
1580
+ * Returns an unsubscribe function. Typical use: show the in-app toast.
1581
+ */
1582
+ declare const onForegroundPush: (callback: (payload: {
1583
+ title?: string;
1584
+ body?: string;
1585
+ data?: Record<string, string>;
1586
+ }) => void) => Promise<() => void>;
1587
+
1588
+ interface PushNotificationsState {
1589
+ /** Browser supports service workers + the Push API. */
1590
+ supported: boolean;
1591
+ /** Super-admin ceiling AND client admin toggle allow push. */
1592
+ allowedByWorkspace: boolean;
1593
+ /** Firebase credentials are configured on the backend. */
1594
+ configured: boolean;
1595
+ /** Current browser notification permission. */
1596
+ permission: NotificationPermission | "unsupported";
1597
+ /** The user's account-level preference (mute switch). */
1598
+ userEnabled: boolean;
1599
+ /** This browser has a registered push token. */
1600
+ deviceEnabled: boolean;
1601
+ loading: boolean;
1602
+ error: string | null;
1603
+ }
1604
+ interface UsePushNotifications extends PushNotificationsState {
1605
+ /** Prompt for permission and register this device. */
1606
+ enable: () => Promise<boolean>;
1607
+ /** Unregister this device. */
1608
+ disable: () => Promise<void>;
1609
+ /** Account-level mute switch across all of the user's devices. */
1610
+ setUserEnabled: (enabled: boolean) => Promise<void>;
1611
+ refresh: () => Promise<void>;
1612
+ }
1613
+ /**
1614
+ * Per-user push notification opt-in for the embedded chat.
1615
+ *
1616
+ * Renders no UI itself — pair with PushNotificationToggle or your own
1617
+ * control. Requires setChatBaseURL/setChatClientId/setChatAccessToken to be
1618
+ * configured (same as the rest of the chat).
1619
+ */
1620
+ declare const usePushNotifications: () => UsePushNotifications;
1621
+
1622
+ interface PushNotificationToggleProps {
1623
+ className?: string;
1624
+ label?: string;
1625
+ description?: string;
1626
+ }
1627
+ /**
1628
+ * Drop-in per-user push notification switch. Renders nothing while push is
1629
+ * unsupported by the browser, disabled by the workspace admins, or not yet
1630
+ * configured on the backend — users only ever see a switch they can use.
1631
+ *
1632
+ * On: prompts for browser permission and registers this device.
1633
+ * Off: unregisters this device.
1634
+ */
1635
+ declare const PushNotificationToggle: ({ className, label, description, }: PushNotificationToggleProps) => React.JSX.Element | null;
1636
+
1637
+ 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, 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, type PendingJump, type PermissionDrawerSlotProps, type PhoneCallButtonSlotProps, type PinnedMessagesDrawerSlotProps, type PushConfig, PushNotificationToggle, type PushNotificationToggleProps, type PushNotificationsState, type PushPreference, type StarredMessagesDrawerSlotProps, type UIConfig, type UsePushNotifications, type VideoCallButtonSlotProps, apiGetPushConfig, apiGetPushPreference, apiRegisterPushToken, apiRemovePushToken, apiUpdatePushPreference, capitalizeFirst, clampJumpDate, ChatMain 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, socketService, startOfLocalDay, toDateInputValue, uniqueList, useChatAlerts, useChatContext, useChatController, useChatCustomization, useChatCustomizationOptional, useChatFeatures, useChatFeaturesOptional, useChatLocale, useStore as useChatStore, useChatTheme, usePushNotifications };
package/dist/index.d.ts CHANGED
@@ -1548,4 +1548,90 @@ declare function Calendar({ className, classNames, showOutsideDays, captionLayou
1548
1548
  }): React.JSX.Element;
1549
1549
  declare function CalendarDayButton({ className, day, modifiers, ...props }: React.ComponentProps<typeof DayButton>): React.JSX.Element;
1550
1550
 
1551
- 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, 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, type PendingJump, type PermissionDrawerSlotProps, type PhoneCallButtonSlotProps, type PinnedMessagesDrawerSlotProps, type StarredMessagesDrawerSlotProps, type UIConfig, type VideoCallButtonSlotProps, capitalizeFirst, clampJumpDate, ChatMain as default, defaultChatClassNames, defaultChatComponents, defaultChatFeatures, defaultChatLayoutConfig, downloadFile, getChatBaseUrl, getChatQueryParamApis, getChatQueryParams, getChatQueryParamsByApi, getChatSocketUrl, getFirstAndLastNameOneCharacter, getResponsiveWidth, getSocketConfig, isEmpty, mergeChatCustomization, mergeChatLayoutConfig, packageDefaultComponents, resolveApiUrl, resolveChatApiKey, 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 };
1551
+ interface PushConfig {
1552
+ /** Firebase credentials present on the backend deployment. */
1553
+ configured: boolean;
1554
+ /** Super-admin ceiling AND client admin toggle, resolved. */
1555
+ enabled: boolean;
1556
+ firebaseConfig: Record<string, string> | null;
1557
+ vapidKey: string | null;
1558
+ }
1559
+ interface PushPreference {
1560
+ enabled: boolean;
1561
+ allowedByWorkspace: boolean;
1562
+ deviceCount: number;
1563
+ }
1564
+ declare const apiGetPushConfig: () => Promise<PushConfig>;
1565
+ declare const apiRegisterPushToken: (token: string, deviceLabel?: string) => Promise<any>;
1566
+ declare const apiRemovePushToken: (token: string) => Promise<any>;
1567
+ declare const apiGetPushPreference: () => Promise<PushPreference>;
1568
+ declare const apiUpdatePushPreference: (enabled: boolean) => Promise<any>;
1569
+ declare const isPushSupported: () => boolean;
1570
+ declare const getStoredPushToken: () => string | null;
1571
+ /**
1572
+ * Full device opt-in: browser permission prompt → FCM token → backend
1573
+ * registration. Returns the registered token.
1574
+ */
1575
+ declare const enablePushOnThisDevice: () => Promise<string>;
1576
+ /** Device opt-out: invalidates the FCM token and removes it server-side. */
1577
+ declare const disablePushOnThisDevice: () => Promise<void>;
1578
+ /**
1579
+ * Foreground messages (tab focused) — FCM does not display these itself.
1580
+ * Returns an unsubscribe function. Typical use: show the in-app toast.
1581
+ */
1582
+ declare const onForegroundPush: (callback: (payload: {
1583
+ title?: string;
1584
+ body?: string;
1585
+ data?: Record<string, string>;
1586
+ }) => void) => Promise<() => void>;
1587
+
1588
+ interface PushNotificationsState {
1589
+ /** Browser supports service workers + the Push API. */
1590
+ supported: boolean;
1591
+ /** Super-admin ceiling AND client admin toggle allow push. */
1592
+ allowedByWorkspace: boolean;
1593
+ /** Firebase credentials are configured on the backend. */
1594
+ configured: boolean;
1595
+ /** Current browser notification permission. */
1596
+ permission: NotificationPermission | "unsupported";
1597
+ /** The user's account-level preference (mute switch). */
1598
+ userEnabled: boolean;
1599
+ /** This browser has a registered push token. */
1600
+ deviceEnabled: boolean;
1601
+ loading: boolean;
1602
+ error: string | null;
1603
+ }
1604
+ interface UsePushNotifications extends PushNotificationsState {
1605
+ /** Prompt for permission and register this device. */
1606
+ enable: () => Promise<boolean>;
1607
+ /** Unregister this device. */
1608
+ disable: () => Promise<void>;
1609
+ /** Account-level mute switch across all of the user's devices. */
1610
+ setUserEnabled: (enabled: boolean) => Promise<void>;
1611
+ refresh: () => Promise<void>;
1612
+ }
1613
+ /**
1614
+ * Per-user push notification opt-in for the embedded chat.
1615
+ *
1616
+ * Renders no UI itself — pair with PushNotificationToggle or your own
1617
+ * control. Requires setChatBaseURL/setChatClientId/setChatAccessToken to be
1618
+ * configured (same as the rest of the chat).
1619
+ */
1620
+ declare const usePushNotifications: () => UsePushNotifications;
1621
+
1622
+ interface PushNotificationToggleProps {
1623
+ className?: string;
1624
+ label?: string;
1625
+ description?: string;
1626
+ }
1627
+ /**
1628
+ * Drop-in per-user push notification switch. Renders nothing while push is
1629
+ * unsupported by the browser, disabled by the workspace admins, or not yet
1630
+ * configured on the backend — users only ever see a switch they can use.
1631
+ *
1632
+ * On: prompts for browser permission and registers this device.
1633
+ * Off: unregisters this device.
1634
+ */
1635
+ declare const PushNotificationToggle: ({ className, label, description, }: PushNotificationToggleProps) => React.JSX.Element | null;
1636
+
1637
+ 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, 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, type PendingJump, type PermissionDrawerSlotProps, type PhoneCallButtonSlotProps, type PinnedMessagesDrawerSlotProps, type PushConfig, PushNotificationToggle, type PushNotificationToggleProps, type PushNotificationsState, type PushPreference, type StarredMessagesDrawerSlotProps, type UIConfig, type UsePushNotifications, type VideoCallButtonSlotProps, apiGetPushConfig, apiGetPushPreference, apiRegisterPushToken, apiRemovePushToken, apiUpdatePushPreference, capitalizeFirst, clampJumpDate, ChatMain 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, socketService, startOfLocalDay, toDateInputValue, uniqueList, useChatAlerts, useChatContext, useChatController, useChatCustomization, useChatCustomizationOptional, useChatFeatures, useChatFeaturesOptional, useChatLocale, useStore as useChatStore, useChatTheme, usePushNotifications };
package/dist/index.mjs CHANGED
@@ -17750,9 +17750,285 @@ var packageDefaultComponents = {
17750
17750
  ChatSocketStatus: ChatSocketStatus_default
17751
17751
  };
17752
17752
 
17753
+ // src/notifications/push.service.ts
17754
+ init_client();
17755
+ var PUSH_TOKEN_STORAGE_KEY = "realtimex-push-token";
17756
+ var SERVICE_WORKER_PATH = "/firebase-messaging-sw.js";
17757
+ var v2Url = (path) => {
17758
+ const base = (getChatBaseUrl() || String(apiClient.defaults.baseURL || "")).replace(/\/$/, "").replace(/\/v1$/, "/v2");
17759
+ return `${base}${path}`;
17760
+ };
17761
+ var apiGetPushConfig = async () => {
17762
+ const { data } = await apiClient.get(v2Url("/notifications/push/config"));
17763
+ return data?.data;
17764
+ };
17765
+ var apiRegisterPushToken = async (token, deviceLabel) => {
17766
+ const { data } = await apiClient.post(v2Url("/notifications/push/token"), {
17767
+ token,
17768
+ deviceLabel
17769
+ });
17770
+ return data?.data;
17771
+ };
17772
+ var apiRemovePushToken = async (token) => {
17773
+ const { data } = await apiClient.delete(v2Url("/notifications/push/token"), {
17774
+ data: { token }
17775
+ });
17776
+ return data;
17777
+ };
17778
+ var apiGetPushPreference = async () => {
17779
+ const { data } = await apiClient.get(
17780
+ v2Url("/notifications/push/preference")
17781
+ );
17782
+ return data?.data;
17783
+ };
17784
+ var apiUpdatePushPreference = async (enabled) => {
17785
+ const { data } = await apiClient.patch(
17786
+ v2Url("/notifications/push/preference"),
17787
+ { enabled }
17788
+ );
17789
+ return data?.data;
17790
+ };
17791
+ var isPushSupported = () => typeof window !== "undefined" && "Notification" in window && "serviceWorker" in navigator && "PushManager" in window;
17792
+ var getStoredPushToken = () => {
17793
+ try {
17794
+ return localStorage.getItem(PUSH_TOKEN_STORAGE_KEY);
17795
+ } catch {
17796
+ return null;
17797
+ }
17798
+ };
17799
+ var storePushToken = (token) => {
17800
+ try {
17801
+ if (token) localStorage.setItem(PUSH_TOKEN_STORAGE_KEY, token);
17802
+ else localStorage.removeItem(PUSH_TOKEN_STORAGE_KEY);
17803
+ } catch {
17804
+ }
17805
+ };
17806
+ var defaultDeviceLabel = () => {
17807
+ const ua = navigator.userAgent;
17808
+ const browser = /edg\//i.test(ua) ? "Edge" : /chrome/i.test(ua) ? "Chrome" : /safari/i.test(ua) ? "Safari" : /firefox/i.test(ua) ? "Firefox" : "Browser";
17809
+ const os = /mac/i.test(ua) ? "macOS" : /windows/i.test(ua) ? "Windows" : /android/i.test(ua) ? "Android" : /iphone|ipad/i.test(ua) ? "iOS" : /linux/i.test(ua) ? "Linux" : "Unknown OS";
17810
+ return `${browser} on ${os}`;
17811
+ };
17812
+ var loadFirebaseMessaging = async () => {
17813
+ try {
17814
+ const [{ initializeApp, getApps }, messagingModule] = await Promise.all([
17815
+ import('firebase/app'),
17816
+ import('firebase/messaging')
17817
+ ]);
17818
+ return { initializeApp, getApps, ...messagingModule };
17819
+ } catch {
17820
+ throw new Error(
17821
+ 'Push notifications need the "firebase" package \u2014 run: npm install firebase'
17822
+ );
17823
+ }
17824
+ };
17825
+ var getFirebaseMessaging = async (firebaseConfig) => {
17826
+ const fb = await loadFirebaseMessaging();
17827
+ const app = fb.getApps().length ? fb.getApps()[0] : fb.initializeApp(firebaseConfig);
17828
+ return { fb, messaging: fb.getMessaging(app) };
17829
+ };
17830
+ var enablePushOnThisDevice = async () => {
17831
+ if (!isPushSupported()) {
17832
+ throw new Error("Push notifications are not supported in this browser");
17833
+ }
17834
+ const config = await apiGetPushConfig();
17835
+ if (!config?.enabled) {
17836
+ throw new Error("Push notifications are disabled for this workspace");
17837
+ }
17838
+ if (!config.configured || !config.firebaseConfig || !config.vapidKey) {
17839
+ throw new Error(
17840
+ "Push notifications are not configured on the server yet"
17841
+ );
17842
+ }
17843
+ const permission = await Notification.requestPermission();
17844
+ if (permission !== "granted") {
17845
+ throw new Error("Notification permission was not granted");
17846
+ }
17847
+ let registration;
17848
+ try {
17849
+ registration = await navigator.serviceWorker.register(
17850
+ `${SERVICE_WORKER_PATH}?config=${encodeURIComponent(
17851
+ JSON.stringify(config.firebaseConfig)
17852
+ )}`
17853
+ );
17854
+ } catch {
17855
+ throw new Error(
17856
+ `Could not register ${SERVICE_WORKER_PATH} \u2014 copy it from node_modules/@realtimexsco/live-chat/dist/firebase-messaging-sw.js into your app's public folder`
17857
+ );
17858
+ }
17859
+ const { fb, messaging } = await getFirebaseMessaging(config.firebaseConfig);
17860
+ const token = await fb.getToken(messaging, {
17861
+ vapidKey: config.vapidKey,
17862
+ serviceWorkerRegistration: registration
17863
+ });
17864
+ if (!token) {
17865
+ throw new Error("Could not obtain a push token from Firebase");
17866
+ }
17867
+ await apiRegisterPushToken(token, defaultDeviceLabel());
17868
+ storePushToken(token);
17869
+ return token;
17870
+ };
17871
+ var disablePushOnThisDevice = async () => {
17872
+ const token = getStoredPushToken();
17873
+ if (!token) return;
17874
+ try {
17875
+ const config = await apiGetPushConfig();
17876
+ if (config?.firebaseConfig) {
17877
+ const { fb, messaging } = await getFirebaseMessaging(
17878
+ config.firebaseConfig
17879
+ );
17880
+ await fb.deleteToken(messaging).catch(() => void 0);
17881
+ }
17882
+ } catch {
17883
+ }
17884
+ await apiRemovePushToken(token).catch(() => void 0);
17885
+ storePushToken(null);
17886
+ };
17887
+ var onForegroundPush = async (callback) => {
17888
+ const config = await apiGetPushConfig();
17889
+ if (!config?.configured || !config.firebaseConfig) return () => void 0;
17890
+ const { fb, messaging } = await getFirebaseMessaging(config.firebaseConfig);
17891
+ return fb.onMessage(messaging, (payload) => {
17892
+ callback({
17893
+ title: payload?.notification?.title,
17894
+ body: payload?.notification?.body,
17895
+ data: payload?.data
17896
+ });
17897
+ });
17898
+ };
17899
+ var usePushNotifications = () => {
17900
+ const [state, setState] = useState({
17901
+ supported: false,
17902
+ allowedByWorkspace: false,
17903
+ configured: false,
17904
+ permission: "unsupported",
17905
+ userEnabled: true,
17906
+ deviceEnabled: false,
17907
+ loading: true,
17908
+ error: null
17909
+ });
17910
+ const refresh = useCallback(async () => {
17911
+ if (!isPushSupported()) {
17912
+ setState((prev) => ({
17913
+ ...prev,
17914
+ supported: false,
17915
+ loading: false
17916
+ }));
17917
+ return;
17918
+ }
17919
+ try {
17920
+ const [config, preference] = await Promise.all([
17921
+ apiGetPushConfig(),
17922
+ apiGetPushPreference().catch(() => null)
17923
+ ]);
17924
+ setState({
17925
+ supported: true,
17926
+ allowedByWorkspace: Boolean(config?.enabled),
17927
+ configured: Boolean(config?.configured),
17928
+ permission: Notification.permission,
17929
+ userEnabled: preference?.enabled ?? true,
17930
+ deviceEnabled: Notification.permission === "granted" && Boolean(getStoredPushToken()),
17931
+ loading: false,
17932
+ error: null
17933
+ });
17934
+ } catch (error) {
17935
+ setState((prev) => ({
17936
+ ...prev,
17937
+ supported: true,
17938
+ loading: false,
17939
+ error: error instanceof Error ? error.message : "Could not load push settings"
17940
+ }));
17941
+ }
17942
+ }, []);
17943
+ useEffect(() => {
17944
+ void refresh();
17945
+ }, [refresh]);
17946
+ const enable = useCallback(async () => {
17947
+ setState((prev) => ({ ...prev, loading: true, error: null }));
17948
+ try {
17949
+ await enablePushOnThisDevice();
17950
+ await refresh();
17951
+ return true;
17952
+ } catch (error) {
17953
+ setState((prev) => ({
17954
+ ...prev,
17955
+ loading: false,
17956
+ permission: isPushSupported() ? Notification.permission : "unsupported",
17957
+ error: error instanceof Error ? error.message : "Could not enable push notifications"
17958
+ }));
17959
+ return false;
17960
+ }
17961
+ }, [refresh]);
17962
+ const disable = useCallback(async () => {
17963
+ setState((prev) => ({ ...prev, loading: true, error: null }));
17964
+ try {
17965
+ await disablePushOnThisDevice();
17966
+ } finally {
17967
+ await refresh();
17968
+ }
17969
+ }, [refresh]);
17970
+ const setUserEnabled = useCallback(
17971
+ async (enabled) => {
17972
+ setState((prev) => ({ ...prev, userEnabled: enabled }));
17973
+ try {
17974
+ await apiUpdatePushPreference(enabled);
17975
+ } catch (error) {
17976
+ setState((prev) => ({
17977
+ ...prev,
17978
+ userEnabled: !enabled,
17979
+ error: error instanceof Error ? error.message : "Could not update push preference"
17980
+ }));
17981
+ }
17982
+ },
17983
+ []
17984
+ );
17985
+ return { ...state, enable, disable, setUserEnabled, refresh };
17986
+ };
17987
+ var PushNotificationToggle = ({
17988
+ className,
17989
+ label = "Push notifications",
17990
+ description = "Get notified about new messages on this device"
17991
+ }) => {
17992
+ const push = usePushNotifications();
17993
+ if (!push.supported || !push.allowedByWorkspace || !push.configured) {
17994
+ return null;
17995
+ }
17996
+ const isOn = push.deviceEnabled && push.userEnabled;
17997
+ const permissionBlocked = push.permission === "denied";
17998
+ const handleChange = async (checked) => {
17999
+ if (checked) {
18000
+ if (!push.userEnabled) await push.setUserEnabled(true);
18001
+ if (!push.deviceEnabled) await push.enable();
18002
+ } else {
18003
+ await push.disable();
18004
+ }
18005
+ };
18006
+ return /* @__PURE__ */ jsxs(
18007
+ "div",
18008
+ {
18009
+ className: className ?? "flex items-center justify-between gap-4 rounded-xl border border-border bg-background px-4 py-3",
18010
+ children: [
18011
+ /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
18012
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: label }),
18013
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: permissionBlocked ? "Notifications are blocked in your browser settings" : push.error ?? description })
18014
+ ] }),
18015
+ /* @__PURE__ */ jsx(
18016
+ Switch,
18017
+ {
18018
+ checked: isOn,
18019
+ disabled: push.loading || permissionBlocked,
18020
+ onCheckedChange: (checked) => void handleChange(checked),
18021
+ "aria-label": `Toggle ${label}`
18022
+ }
18023
+ )
18024
+ ]
18025
+ }
18026
+ );
18027
+ };
18028
+
17753
18029
  // src/index.ts
17754
18030
  var index_default = ChatMain_default;
17755
18031
 
17756
- 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, ForwardModalView as ForwardModal, HeaderCallActions_default as HeaderCallActions, LoggedUserDetails_default as LoggedUserDetails, ChannelMessageBoxView_default as MessageInput, MessageItemView as MessageItem, ActiveChannelMessagesView_default as MessageList, capitalizeFirst, clampJumpDate, index_default as default, defaultChatClassNames, defaultChatComponents, defaultChatFeatures, defaultChatLayoutConfig, downloadFile, getChatBaseUrl, getChatQueryParamApis, getChatQueryParams, getChatQueryParamsByApi, getChatSocketUrl, getFirstAndLastNameOneCharacter, getResponsiveWidth, getSocketConfig, isEmpty, mergeChatCustomization, mergeChatLayoutConfig, 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 };
18032
+ 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, ForwardModalView as ForwardModal, HeaderCallActions_default as HeaderCallActions, LoggedUserDetails_default as LoggedUserDetails, ChannelMessageBoxView_default as MessageInput, MessageItemView as MessageItem, ActiveChannelMessagesView_default as MessageList, 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 };
17757
18033
  //# sourceMappingURL=index.mjs.map
17758
18034
  //# sourceMappingURL=index.mjs.map