@ethora/chat-component 25.12.1 → 26.1.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.
Files changed (49) hide show
  1. package/README.md +587 -145
  2. package/dist/components/MainComponents/MessageContainer.d.ts +1 -0
  3. package/dist/components/MessageBubble/MessageReply.d.ts +2 -2
  4. package/dist/components/MessageNotification/MessageNotificationToast.d.ts +17 -0
  5. package/dist/components/MessageNotification/index.d.ts +2 -0
  6. package/dist/components/Modals/SettingsModals/SharedStyledComponents.d.ts +22 -0
  7. package/dist/components/Modals/styledModalComponents.d.ts +28 -0
  8. package/dist/components/styled/Button.d.ts +2 -2
  9. package/dist/components/styled/DateLabel.d.ts +2 -2
  10. package/dist/components/styled/StyledComponents.d.ts +10 -10
  11. package/dist/components/styled/StyledInputComponents/StyledInputComponents.d.ts +6 -6
  12. package/dist/context/MessageNotificationContext.d.ts +12 -0
  13. package/dist/firebase-config.d.ts +6 -2
  14. package/dist/firebase-messaging-sw.js +351 -0
  15. package/dist/helpers/getDataFromXml.d.ts +1 -0
  16. package/dist/helpers/initRoomsPresence.d.ts +1 -1
  17. package/dist/helpers/storeConsole.d.ts +6 -0
  18. package/dist/hooks/useInAppNotifications.d.ts +18 -0
  19. package/dist/hooks/usePushNotifications.d.ts +45 -0
  20. package/dist/hooks/useTabVisibility.d.ts +1 -0
  21. package/dist/main.css +1 -1
  22. package/dist/main.d.ts +5 -0
  23. package/dist/main.js +14698 -11894
  24. package/dist/main.js.map +1 -1
  25. package/dist/networking/api-requests/push.api.d.ts +18 -0
  26. package/dist/networking/stanzaHandlers.d.ts +4 -2
  27. package/dist/networking/xmpp/allRoomPresences.xmpp.d.ts +11 -1
  28. package/dist/networking/xmpp/presenceInRoom.xmpp.d.ts +1 -1
  29. package/dist/networking/xmpp/sendTextMessage.xmpp.d.ts +1 -1
  30. package/dist/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.d.ts +1 -1
  31. package/dist/networking/xmpp/subscribeToRoomMessages.xmpp.d.ts +9 -0
  32. package/dist/networking/xmppClient.d.ts +13 -3
  33. package/dist/roomStore/chatSettingsSlice.d.ts +1 -0
  34. package/dist/roomStore/index.d.ts +28 -0
  35. package/dist/roomStore/roomHeapSlice.d.ts +1 -1
  36. package/dist/roomStore/roomsSlice.d.ts +11 -1
  37. package/dist/types/models/config.model.d.ts +36 -1
  38. package/dist/types/models/room.model.d.ts +4 -1
  39. package/dist/types/models/xmpp.model.d.ts +3 -1
  40. package/dist/utils/firebasePushNotifications.d.ts +34 -0
  41. package/dist/utils/formatError.d.ts +1 -0
  42. package/dist/utils/messageNotificationManager.d.ts +16 -0
  43. package/dist/utils/notificationPolicy.d.ts +45 -0
  44. package/dist/utils/notificationUtils.d.ts +22 -0
  45. package/dist/utils/pushSubscriptionService.d.ts +12 -0
  46. package/dist/version.d.ts +1 -1
  47. package/package.json +7 -4
  48. package/public/firebase-messaging-sw.js +351 -0
  49. package/scripts/init-push.js +48 -0
@@ -4,6 +4,7 @@ interface MessageContainerProps {
4
4
  CustomMessage?: React.ComponentType<{
5
5
  message: IMessage;
6
6
  isUser: boolean;
7
+ $isUser?: boolean;
7
8
  isReply: boolean;
8
9
  }>;
9
10
  message: IMessage;
@@ -1,7 +1,7 @@
1
1
  import { FC } from 'react';
2
2
  export declare const StyledMessageReply: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
3
- isUser: boolean;
4
- configColor: string;
3
+ $isUser: boolean;
4
+ $configColor: string;
5
5
  }>> & string;
6
6
  interface MessageReplyProps {
7
7
  isUser: boolean;
@@ -0,0 +1,17 @@
1
+ import { default as React } from 'react';
2
+ import { IMessage } from '../../types/models/message.model';
3
+ export interface MessageNotificationData {
4
+ id: string;
5
+ message: IMessage;
6
+ roomName: string;
7
+ senderName: string;
8
+ roomJID: string;
9
+ timestamp: number;
10
+ }
11
+ export interface MessageNotificationToastProps extends MessageNotificationData {
12
+ onClose: () => void;
13
+ onNavigateToMessage: (roomJID: string, messageId: string, message: IMessage, roomName: string, senderName: string) => void;
14
+ duration: number;
15
+ }
16
+ declare const MessageNotificationToast: React.FC<MessageNotificationToastProps>;
17
+ export default MessageNotificationToast;
@@ -0,0 +1,2 @@
1
+ export { default as MessageNotificationToast } from './MessageNotificationToast';
2
+ export type { MessageNotificationData } from './MessageNotificationToast';
@@ -0,0 +1,22 @@
1
+ import { ButtonProps } from '../../styled/Button';
2
+ export declare const SharedSettingsCenterContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('styled-components').FastOmit<Omit<import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>, "ref"> & {
3
+ ref?: import('react').Ref<HTMLDivElement>;
4
+ }, never>, never>> & string;
5
+ export declare const SharedSettingsColumnContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
6
+ export declare const SharedSettingsSectionContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
7
+ export declare const SharedSettingsStyledLabel: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<Omit<import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>, "ref"> & {
8
+ ref?: import('react').Ref<HTMLSpanElement>;
9
+ }, never>> & string;
10
+ export declare const RowWrapper: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
11
+ export declare const SharedSettingsLabelData: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<Omit<import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>, "ref"> & {
12
+ ref?: import('react').Ref<HTMLSpanElement>;
13
+ }, never>> & string;
14
+ export declare const SharedSettingsStyledButton: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<Omit<ButtonProps & import('react').RefAttributes<HTMLButtonElement>, "ref"> & {
15
+ ref?: import('react').Ref<HTMLButtonElement>;
16
+ }, {
17
+ borderColor: string;
18
+ }>> & string & Omit<import('react').ForwardRefExoticComponent<ButtonProps & import('react').RefAttributes<HTMLButtonElement>>, keyof import('react').Component<any, {}, any>>;
19
+ export declare const SharedSettingsInfoPanel: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
20
+ bgColor: string;
21
+ }>> & string;
22
+ export declare const SharedSettingsInfoText: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
@@ -0,0 +1,28 @@
1
+ import { ButtonProps } from '../styled/Button';
2
+ export declare const ModalBackground: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
3
+ export declare const CloseButton: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
4
+ export declare const ModalContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
5
+ export declare const ModalTitle: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, never>> & string;
6
+ export declare const ModalDescription: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
7
+ export declare const GroupContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
8
+ export declare const ModalContainerFullScreen: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
9
+ export declare const HeaderContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<Omit<import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>, "ref"> & {
10
+ ref?: import('react').Ref<HTMLDivElement>;
11
+ }, never>> & string;
12
+ export declare const HeaderLeft: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
13
+ export declare const HeaderRight: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
14
+ export declare const CenterContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<Omit<import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>, "ref"> & {
15
+ ref?: import('react').Ref<HTMLDivElement>;
16
+ }, never>> & string;
17
+ export declare const ProfileImage: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
18
+ export declare const UserInfo: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
19
+ export declare const UserName: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
20
+ export declare const UserStatus: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
21
+ export declare const BorderedContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
22
+ export declare const LabelData: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
23
+ export declare const Label: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
24
+ export declare const ActionButton: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<Omit<ButtonProps & import('react').RefAttributes<HTMLButtonElement>, "ref"> & {
25
+ ref?: import('react').Ref<HTMLButtonElement>;
26
+ }, never>> & string & Omit<import('react').ForwardRefExoticComponent<ButtonProps & import('react').RefAttributes<HTMLButtonElement>>, keyof import('react').Component<any, {}, any>>;
27
+ export declare const EmptySection: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
28
+ export declare const Divider: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
@@ -1,5 +1,5 @@
1
1
  import { default as React, ReactElement } from 'react';
2
- interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
2
+ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
3
3
  text?: string | ReactElement;
4
4
  EndIcon?: ReactElement;
5
5
  StartIcon?: ReactElement;
@@ -8,5 +8,5 @@ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
8
8
  variant?: 'default' | 'filled' | 'outlined';
9
9
  children?: React.ReactNode;
10
10
  }
11
- declare const Button: React.FC<ButtonProps>;
11
+ declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
12
12
  export default Button;
@@ -7,8 +7,8 @@ interface DateLabelProps {
7
7
  };
8
8
  }
9
9
  export declare const StyledDateLabel: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
10
- primary?: string;
11
- secondary?: string;
10
+ $primary?: string;
11
+ $secondary?: string;
12
12
  }>> & string;
13
13
  declare const DateLabel: React.FC<DateLabelProps>;
14
14
  export default DateLabel;
@@ -10,7 +10,7 @@ export declare const MessagesScroll: import('styled-components/dist/types').ISty
10
10
  export declare const MessagesList: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
11
11
  export declare const MessageTimestamp: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
12
12
  export declare const Message: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
13
- isUser: boolean;
13
+ $isUser: boolean;
14
14
  }>> & string;
15
15
  export declare const MessageText: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
16
16
  export declare const UserName: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
@@ -18,18 +18,18 @@ export declare const InputContainer: import('styled-components/dist/types').ISty
18
18
  export declare const MessageInput: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
19
19
  export declare const SendButton: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
20
20
  export declare const CustomMessageContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
21
- isUser: boolean;
22
- reply: boolean;
23
- reaction: boolean;
21
+ $isUser: boolean;
22
+ $reply: boolean;
23
+ $reaction: boolean;
24
24
  }>> & string;
25
25
  export declare const CustomMessageBubble: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
26
- isUser: boolean;
27
- deleted: boolean;
26
+ $isUser: boolean;
27
+ $deleted: boolean;
28
28
  }>> & string;
29
- export declare const CustomMessageText: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
29
+ export declare const CustomMessageText: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
30
30
  export declare const CustomUserName: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, {
31
- isUser: boolean;
32
- color?: string;
31
+ $isUser: boolean;
32
+ $color?: string;
33
33
  }>> & string;
34
34
  export declare const CustomMessageTimestamp: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
35
35
  export declare const CustomMessagePhoto: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, never>> & string;
@@ -38,7 +38,7 @@ export declare const CustomSystemMessage: import('styled-components/dist/types')
38
38
  export declare const CustomSystemMessageText: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
39
39
  export declare const IconButton: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
40
40
  export declare const MessageFooter: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
41
- isUser: boolean;
41
+ $isUser: boolean;
42
42
  }>> & string;
43
43
  export declare const Line: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
44
44
  export declare const StyledLoaderWrapper: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
@@ -1,7 +1,7 @@
1
1
  export declare const InputContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
2
2
  export declare const MessageInputContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
3
3
  export declare const MessageInput: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, {
4
- color?: string;
4
+ $color?: string;
5
5
  }>> & string;
6
6
  export declare const HiddenFileInput: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
7
7
  export declare const Timer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
@@ -13,11 +13,11 @@ export declare const ImagePreview: import('styled-components/dist/types').IStyle
13
13
  export declare const VideoPreview: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').VideoHTMLAttributes<HTMLVideoElement>, HTMLVideoElement>, never>> & string;
14
14
  export declare const StyledInput: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
15
15
  export declare const TextareaWrapper: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
16
- dynamicHeight?: number;
17
- color?: string;
18
- isFocused?: boolean;
16
+ $dynamicHeight?: number;
17
+ $color?: string;
18
+ $isFocused?: boolean;
19
19
  }>> & string;
20
20
  export declare const TextareaInput: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>, {
21
- dynamicHeight?: number;
22
- color?: string;
21
+ $dynamicHeight?: number;
22
+ $color?: string;
23
23
  }>> & string;
@@ -0,0 +1,12 @@
1
+ import { default as React, ReactNode } from 'react';
2
+ import { IMessage } from '../types/models/message.model';
3
+ import { IConfig } from '../types/types';
4
+ interface MessageNotificationContextType {
5
+ showMessageNotification: (message: IMessage, roomName: string, senderName: string, roomJID: string) => void;
6
+ }
7
+ export declare const MessageNotificationProvider: React.FC<{
8
+ children: ReactNode;
9
+ config?: IConfig;
10
+ }>;
11
+ export declare const useMessageNotification: () => MessageNotificationContextType;
12
+ export {};
@@ -1,4 +1,6 @@
1
- export declare const config: {
1
+ import { FirebaseApp } from 'firebase/app';
2
+ import { Messaging } from 'firebase/messaging';
3
+ export declare const defaultConfig: {
2
4
  apiKey: any;
3
5
  authDomain: any;
4
6
  projectId: any;
@@ -6,4 +8,6 @@ export declare const config: {
6
8
  messagingSenderId: any;
7
9
  appId: any;
8
10
  };
9
- export declare const app: import('@firebase/app').FirebaseApp;
11
+ export declare const getFirebaseMessaging: (customConfig?: any) => Messaging | null;
12
+ export declare const app: FirebaseApp;
13
+ export declare const messaging: Messaging;
@@ -0,0 +1,351 @@
1
+ /* ============================================================
2
+ * Unified Service Worker
3
+ * Handles BOTH Firebase Cloud Messaging (FCM) background pushes
4
+ * AND generic Web Push API events, so all push notifications
5
+ * are captured regardless of origin.
6
+ * ============================================================ */
7
+
8
+ // ── Firebase SDK ──────────────────────────────────────────────
9
+ importScripts('https://www.gstatic.com/firebasejs/10.12.0/firebase-app-compat.js');
10
+ importScripts('https://www.gstatic.com/firebasejs/10.12.0/firebase-messaging-compat.js');
11
+
12
+ // ── Dynamic Configuration ─────────────────────────────────────
13
+ const params = new URL(self.location).searchParams;
14
+ const firebaseConfig = {
15
+ apiKey: params.get('apiKey'),
16
+ authDomain: params.get('authDomain'),
17
+ projectId: params.get('projectId'),
18
+ storageBucket: params.get('storageBucket'),
19
+ messagingSenderId: params.get('messagingSenderId'),
20
+ appId: params.get('appId'),
21
+ };
22
+
23
+ // Only initialize if we have at least apiKey and appId
24
+ if (firebaseConfig.apiKey && firebaseConfig.appId) {
25
+ firebase.initializeApp(firebaseConfig);
26
+ }
27
+
28
+ const messaging = firebase.messaging();
29
+ const APP_URL = self.location.origin;
30
+
31
+ // ── Deduplication ─────────────────────────────────────────────
32
+ // Track message IDs handled by FCM so the generic `push` listener
33
+ // can skip them and avoid duplicate notifications.
34
+ const _handledByFcm = new Set();
35
+ const DEDUP_TTL_MS = 60_000; // auto-cleanup after 60 s
36
+
37
+ function markHandledByFcm(id) {
38
+ if (!id) return;
39
+ _handledByFcm.add(id);
40
+ console.log('[SW] FCM message marked as handled:', id);
41
+ setTimeout(() => _handledByFcm.delete(id), DEDUP_TTL_MS);
42
+ }
43
+
44
+ function wasHandledByFcm(id) {
45
+ return id ? _handledByFcm.has(id) : false;
46
+ }
47
+
48
+ // ── Shared Helpers ────────────────────────────────────────────
49
+ function isSystemPayload(data) {
50
+ return !data?.msgID && !data?.jid && !!data?.userJid;
51
+ }
52
+
53
+ function buildTargetUrl(data, notification, fallbackUrl) {
54
+ if (fallbackUrl && String(fallbackUrl).startsWith('http')) return fallbackUrl;
55
+
56
+ const title = notification?.title || data?.title || '';
57
+ if (title.startsWith('http')) return title;
58
+
59
+ if (isSystemPayload(data)) return APP_URL;
60
+ if (!data?.jid) return APP_URL;
61
+ const chatId = String(data.jid).split('@')[0];
62
+ return `${APP_URL}/chat?chatId=${encodeURIComponent(chatId)}`;
63
+ }
64
+
65
+ function postBridgeToClients(windowClients, bridgePayload) {
66
+ windowClients.forEach((client) => {
67
+ client.postMessage({
68
+ type: 'PUSH_FOREGROUND_BRIDGE',
69
+ payload: bridgePayload,
70
+ });
71
+ });
72
+ }
73
+
74
+ function isAnyClientVisible(windowClients) {
75
+ return windowClients.some((c) => c.visibilityState === 'visible');
76
+ }
77
+
78
+ // ── 1. FCM Background Messages ───────────────────────────────
79
+ // This fires for pushes delivered through Firebase Cloud Messaging
80
+ // when no foreground tab is handling them via onMessage().
81
+ messaging.onBackgroundMessage((payload) => {
82
+ console.log('[SW] FCM onBackgroundMessage received', payload);
83
+
84
+ const data = payload.data || {};
85
+ const notification = payload.notification || {};
86
+ const messageId = payload.messageId || data.msgID || null;
87
+
88
+ // Mark so the generic push handler skips this one
89
+ markHandledByFcm(messageId);
90
+
91
+ const isSystem = isSystemPayload(data);
92
+ const title =
93
+ (isSystem ? 'System' : undefined) ||
94
+ notification.title ||
95
+ data.title ||
96
+ 'New Message';
97
+ const body =
98
+ notification.body || data.body || 'You have a new message.';
99
+ const url = buildTargetUrl(data, notification, data.url);
100
+
101
+ const bridgePayload = {
102
+ messageId,
103
+ notification: { title, body, image: notification.image || '/favicon.ico' },
104
+ data: {
105
+ ...data,
106
+ jid: data.jid || '',
107
+ userJid: data.userJid || '',
108
+ msgID: data.msgID || '',
109
+ workspaceId: data.workspaceId || data.workspace_id || '',
110
+ },
111
+ };
112
+
113
+ const options = {
114
+ body,
115
+ icon: notification.image || '/favicon.ico',
116
+ badge: '/favicon.ico',
117
+ tag: data.tag || 'ethora-notification',
118
+ data: {
119
+ url,
120
+ roomJid: data.jid || null,
121
+ senderId: data.userJid || null,
122
+ messageId,
123
+ workspaceId: data.workspaceId || data.workspace_id || null,
124
+ },
125
+ requireInteraction: false,
126
+ silent: false,
127
+ };
128
+
129
+ return clients
130
+ .matchAll({ type: 'window', includeUncontrolled: true })
131
+ .then((windowClients) => {
132
+ postBridgeToClients(windowClients, bridgePayload);
133
+
134
+ if (!isAnyClientVisible(windowClients)) {
135
+ console.log(
136
+ `[NotifyPolicy] source=fcm_bg action=show reason=${isSystem ? 'system' : 'background'} msgId=${messageId || ''}`
137
+ );
138
+ return self.registration.showNotification(title, options);
139
+ } else {
140
+ console.log(
141
+ `[NotifyPolicy] source=fcm_bg action=skip reason=tab_visible msgId=${messageId || ''}`
142
+ );
143
+ }
144
+ });
145
+ });
146
+
147
+ // ── 2. Generic Web Push API ───────────────────────────────────
148
+ // This fires for ANY push delivered via the Web Push protocol,
149
+ // including direct backend pushes for XMPP messages that are
150
+ // NOT routed through FCM.
151
+ self.addEventListener('push', (event) => {
152
+ console.log('[SW] Generic push event received');
153
+
154
+ let raw = {};
155
+ try {
156
+ if (event.data) {
157
+ raw = event.data.json();
158
+ }
159
+ } catch (err) {
160
+ console.warn('[SW] Failed to parse push payload as JSON:', err);
161
+ raw = { title: 'New message', body: event.data ? event.data.text() : '' };
162
+ }
163
+
164
+ const notification = raw.notification || {};
165
+ const payloadData = raw.data || {};
166
+ const messageId = raw.messageId || payloadData.msgID || null;
167
+
168
+ // Skip if FCM already handled this exact message
169
+ if (wasHandledByFcm(messageId)) {
170
+ console.log(`[SW] push event skipped – already handled by FCM (msgId=${messageId})`);
171
+ return;
172
+ }
173
+
174
+ const isSystem = isSystemPayload(payloadData);
175
+ const title =
176
+ (isSystem ? 'System' : undefined) ||
177
+ notification.title ||
178
+ raw.title ||
179
+ 'Ethora Chat';
180
+ const body =
181
+ notification.body ||
182
+ raw.body ||
183
+ raw.message ||
184
+ payloadData.body ||
185
+ 'You have a new message.';
186
+ const url = buildTargetUrl(
187
+ payloadData,
188
+ notification,
189
+ raw.url || raw.clickAction
190
+ );
191
+
192
+ const bridgePayload = {
193
+ messageId,
194
+ notification: {
195
+ title,
196
+ body,
197
+ image: raw.icon || '/favicon.ico',
198
+ },
199
+ data: {
200
+ ...payloadData,
201
+ jid: raw.roomJid || payloadData.jid || '',
202
+ userJid: raw.senderId || payloadData.userJid || '',
203
+ msgID: messageId || '',
204
+ workspaceId: raw.workspaceId || payloadData.workspaceId || payloadData.workspace_id || '',
205
+ },
206
+ };
207
+
208
+ const options = {
209
+ body,
210
+ icon: raw.icon || '/favicon.ico',
211
+ badge: raw.badge || '/favicon.ico',
212
+ tag: raw.tag || 'ethora-notification',
213
+ data: {
214
+ url,
215
+ roomJid: raw.roomJid || payloadData.jid || null,
216
+ senderId: raw.senderId || payloadData.userJid || null,
217
+ messageId,
218
+ workspaceId: raw.workspaceId || payloadData.workspaceId || payloadData.workspace_id || null,
219
+ },
220
+ requireInteraction: false,
221
+ silent: false,
222
+ };
223
+
224
+ event.waitUntil(
225
+ clients
226
+ .matchAll({ type: 'window', includeUncontrolled: true })
227
+ .then((windowClients) => {
228
+ postBridgeToClients(windowClients, bridgePayload);
229
+
230
+ if (!isAnyClientVisible(windowClients)) {
231
+ console.log(
232
+ `[NotifyPolicy] source=push_bg action=show reason=${isSystem ? 'system' : 'background'} msgId=${messageId || ''}`
233
+ );
234
+ return self.registration.showNotification(title, options);
235
+ } else {
236
+ console.log(
237
+ `[NotifyPolicy] source=push_bg action=skip reason=tab_visible msgId=${messageId || ''}`
238
+ );
239
+ }
240
+ })
241
+ );
242
+ });
243
+
244
+ // ── 3. Notification Click ─────────────────────────────────────
245
+ self.addEventListener('notificationclick', (event) => {
246
+ console.log('[NotifyPolicy] source=push_bg action=click_start');
247
+ event.notification.close();
248
+
249
+ const targetUrl =
250
+ (event.notification.data && event.notification.data.url) || APP_URL;
251
+ console.log('[NotifyPolicy] source=push_bg action=click_url', {
252
+ url: targetUrl,
253
+ });
254
+
255
+ async function handleClick() {
256
+ try {
257
+ const windowClients = await clients.matchAll({
258
+ type: 'window',
259
+ includeUncontrolled: true,
260
+ });
261
+ console.log('[NotifyPolicy] source=push_bg action=clients_found', {
262
+ count: windowClients.length,
263
+ });
264
+
265
+ // 1. Try to find an exactly matching URL
266
+ for (const client of windowClients) {
267
+ if (client.url === targetUrl && 'focus' in client) {
268
+ console.log('[NotifyPolicy] source=push_bg action=focus_exact', {
269
+ url: client.url,
270
+ });
271
+ return client.focus();
272
+ }
273
+ }
274
+
275
+ // 2. Try to find any client on our origin, focus it, and navigate
276
+ for (const client of windowClients) {
277
+ try {
278
+ const clientOrigin = new URL(client.url).origin;
279
+ const swOrigin = self.location.origin;
280
+ if (clientOrigin === swOrigin && 'focus' in client) {
281
+ console.log(
282
+ '[NotifyPolicy] source=push_bg action=focus_and_navigate',
283
+ { from: client.url, to: targetUrl }
284
+ );
285
+ const focusedClient = await client.focus();
286
+ if (focusedClient && 'navigate' in focusedClient) {
287
+ return focusedClient.navigate(targetUrl);
288
+ }
289
+ }
290
+ } catch (e) {
291
+ // Ignore invalid URLs
292
+ }
293
+ }
294
+
295
+ // 3. Fallback: Open a new window
296
+ if (clients.openWindow) {
297
+ console.log('[NotifyPolicy] source=push_bg action=open_new_window', {
298
+ url: targetUrl,
299
+ });
300
+ return clients.openWindow(targetUrl);
301
+ }
302
+ } catch (err) {
303
+ console.error('[NotifyPolicy] source=push_bg action=click_error', err);
304
+ if (clients.openWindow) {
305
+ return clients.openWindow(targetUrl);
306
+ }
307
+ }
308
+ }
309
+
310
+ event.waitUntil(handleClick());
311
+ });
312
+
313
+ // ── 4. Push Subscription Change ───────────────────────────────
314
+ // Fired when the browser automatically re-creates a subscription
315
+ // (e.g. after expiry). Notify clients so they can re-register.
316
+ self.addEventListener('pushsubscriptionchange', (event) => {
317
+ console.log('[SW] Push subscription changed – re-subscribing');
318
+
319
+ event.waitUntil(
320
+ self.registration.pushManager
321
+ .subscribe({ userVisibleOnly: true })
322
+ .then((subscription) => {
323
+ console.log(
324
+ '[SW] New subscription obtained:',
325
+ subscription.endpoint
326
+ );
327
+ return clients.matchAll().then((allClients) => {
328
+ allClients.forEach((client) => {
329
+ client.postMessage({
330
+ type: 'PUSH_SUBSCRIPTION_CHANGED',
331
+ subscription: subscription.toJSON(),
332
+ });
333
+ });
334
+ });
335
+ })
336
+ .catch((err) => {
337
+ console.error('[SW] pushsubscriptionchange – failed to re-subscribe:', err);
338
+ })
339
+ );
340
+ });
341
+
342
+ // ── 5. Lifecycle ──────────────────────────────────────────────
343
+ self.addEventListener('activate', (event) => {
344
+ console.log('[SW] Service worker activated');
345
+ event.waitUntil(clients.claim());
346
+ });
347
+
348
+ self.addEventListener('install', () => {
349
+ console.log('[SW] Service worker installed');
350
+ self.skipWaiting();
351
+ });
@@ -11,6 +11,7 @@ interface DataXml {
11
11
  langSource?: Iso639_1Codes;
12
12
  xmppId?: string;
13
13
  xmppFrom?: string;
14
+ isHistory?: boolean;
14
15
  data: {
15
16
  [x: string]: any;
16
17
  };
@@ -2,4 +2,4 @@ import { default as XmppClient } from '../networking/xmppClient';
2
2
  import { IRoom } from '../types/types';
3
3
  export declare const initRoomsPresence: (client: XmppClient, rooms: {
4
4
  [jid: string]: IRoom;
5
- }) => Promise<any>;
5
+ }) => Promise<void>;
@@ -0,0 +1,6 @@
1
+ import { roomHeapSliceState } from '../roomStore/roomHeapSlice';
2
+ export declare const useStoreConsole: () => {
3
+ chatSettingStore: any;
4
+ rooms: any;
5
+ roomHeapSlice: roomHeapSliceState & import('redux-persist/es/persistReducer').PersistPartial;
6
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Hook to enable in-app notifications globally
3
+ * Call this hook in your app root or XMPP provider to enable notifications
4
+ * even when the chat component isn't mounted
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * import { useInAppNotifications } from '@ethora/chat-component';
9
+ *
10
+ * function App() {
11
+ * useInAppNotifications();
12
+ * return <YourApp />;
13
+ * }
14
+ * ```
15
+ */
16
+ export declare const useInAppNotifications: () => {
17
+ navigateToMessage: (roomJID: string, messageId: string) => void;
18
+ };