@ethora/chat-component 26.9.5 → 26.9.8

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 (81) hide show
  1. package/README.md +45 -1
  2. package/dist/{ChatProfileModal-Pr4--RdW.js → ChatProfileModal-3UH0H5Ec.js} +725 -714
  3. package/dist/{FilePreviewModal-CYHlKzRc.js → FilePreviewModal-Cgj1iHry.js} +161 -161
  4. package/dist/{ManageDataModal-BE1eGlYh.js → ManageDataModal-BblTuE9g.js} +14 -14
  5. package/dist/{MarkdownBody-G0_J0NL6.js → MarkdownBody-RMEx8yW2.js} +1 -1
  6. package/dist/MessageSearchModal-CrYR2EH8.js +381 -0
  7. package/dist/PublicChatsModal-Bi5r4mrV.js +202 -0
  8. package/dist/{SideDrawer-BG2m7Bcm.js → SideDrawer-CDAoobvX.js} +34 -34
  9. package/dist/{UserProfileModal-B2Hp5bAF.js → UserProfileModal-4Frgvam-.js} +3 -3
  10. package/dist/{UserSettingsModal-D871FDAT.js → UserSettingsModal-C-mb-9cb.js} +2 -2
  11. package/dist/{VideoCallOverlay-Br0ji0nZ.js → VideoCallOverlay-92dFLb9U.js} +1 -1
  12. package/dist/{VisibilityModal-DdFBV1_g.js → VisibilityModal-zIAV6dAP.js} +9 -9
  13. package/dist/assets/icons.d.ts +9 -0
  14. package/dist/components/InputComponents/MentionDropdown.d.ts +2 -0
  15. package/dist/components/InputComponents/Search.d.ts +4 -0
  16. package/dist/components/MainComponents/ArchivedMessageCard.d.ts +11 -0
  17. package/dist/components/MainComponents/scrollAnchor.d.ts +19 -0
  18. package/dist/components/MainComponents/useJumpToMessage.d.ts +94 -0
  19. package/dist/components/MainComponents/useScrollAnchor.d.ts +29 -0
  20. package/dist/components/MainComponents/useStickToBottom.d.ts +27 -0
  21. package/dist/components/Modals/MessageSearchModal/MessageHitResults.d.ts +27 -0
  22. package/dist/components/Modals/MessageSearchModal/MessageSearchModal.d.ts +6 -0
  23. package/dist/components/Modals/MessageSearchModal/resolveSender.d.ts +33 -0
  24. package/dist/components/Modals/MessageSearchModal/searchFilters.d.ts +34 -0
  25. package/dist/components/Modals/MessageSearchModal/snippet.d.ts +14 -0
  26. package/dist/components/Modals/MessageSearchModal/useMessageSearch.d.ts +22 -0
  27. package/dist/components/Modals/PublicChatsModal/PublicChatsModal.d.ts +13 -0
  28. package/dist/components/Modals/styledModalComponents.d.ts +0 -8
  29. package/dist/components/styled/RoomListComponents/index.d.ts +3 -0
  30. package/dist/context/ToastContext.d.ts +7 -0
  31. package/dist/firebase-messaging-sw.js +21 -3
  32. package/dist/{handleCopyClick-DPjxMoJn.js → handleCopyClick-BtXos0AJ.js} +1 -1
  33. package/dist/helpers/checkUniqueUsers.d.ts +2 -2
  34. package/dist/helpers/constants/MODAL_TYPES.d.ts +2 -0
  35. package/dist/helpers/dedupeMembers.d.ts +10 -0
  36. package/dist/helpers/historyPreloadConfig.d.ts +25 -0
  37. package/dist/helpers/historyPreloadScheduler.d.ts +3 -0
  38. package/dist/helpers/insertMessageWithDelimiter.d.ts +1 -0
  39. package/dist/helpers/isMessageSearchEnabled.d.ts +9 -0
  40. package/dist/helpers/jumpThread.d.ts +56 -0
  41. package/dist/helpers/jumpWindow.d.ts +73 -0
  42. package/dist/helpers/nanoToMs.d.ts +1 -1
  43. package/dist/helpers/openRoomAtMessage.d.ts +17 -0
  44. package/dist/helpers/openThreadForJump.d.ts +26 -0
  45. package/dist/helpers/pdf/loadPdfjs.d.ts +8 -1
  46. package/dist/helpers/roomUserCount.d.ts +19 -0
  47. package/dist/helpers/userResolver.d.ts +57 -0
  48. package/dist/helpers/xmppIdShape.d.ts +1 -1
  49. package/dist/hooks/useChatWrapperInit.d.ts +6 -0
  50. package/dist/hooks/useMessageSearchShortcut.d.ts +14 -0
  51. package/dist/hooks/usePdfThumbnail.d.ts +2 -1
  52. package/dist/hooks/useRoomDirectory.d.ts +11 -0
  53. package/dist/hooks/useRoomState.d.ts +1 -0
  54. package/dist/{main-BRIZ98KV.js → main-BnLtessp.js} +24764 -21859
  55. package/dist/main.css +1 -1
  56. package/dist/main.js +16 -16
  57. package/dist/networking/api-requests/messageSearch.api.d.ts +56 -0
  58. package/dist/networking/api-requests/publicChats.api.d.ts +23 -0
  59. package/dist/networking/api-requests/roomMembers.api.d.ts +18 -0
  60. package/dist/networking/api-requests/xmppToken.api.d.ts +1 -0
  61. package/dist/networking/ethoraEvents.d.ts +44 -0
  62. package/dist/networking/stanzaHandlers.d.ts +2 -2
  63. package/dist/networking/xmpp/allRoomPresences.xmpp.d.ts +18 -1
  64. package/dist/networking/xmpp/presenceInRoom.xmpp.d.ts +1 -1
  65. package/dist/networking/xmppClient.d.ts +58 -2
  66. package/dist/roomStore/Middleware/jumpThreadMiddleware.d.ts +2 -0
  67. package/dist/roomStore/chatSettingsSlice.d.ts +1 -1
  68. package/dist/roomStore/index.d.ts +12 -0
  69. package/dist/roomStore/roomsSlice.d.ts +70 -1
  70. package/dist/roomStore/safeKey.d.ts +12 -0
  71. package/dist/roomStore/usersSetCap.d.ts +15 -0
  72. package/dist/styles/classNames.d.ts +2 -0
  73. package/dist/types/models/config.model.d.ts +78 -0
  74. package/dist/types/models/room.model.d.ts +14 -0
  75. package/dist/types/models/xmpp.model.d.ts +21 -1
  76. package/dist/utils/notificationUtils.d.ts +12 -0
  77. package/dist/version.d.ts +1 -1
  78. package/package.json +2 -1
  79. package/public/firebase-messaging-sw.js +21 -3
  80. package/dist/components/Modals/NewChatModal/UpdNewChatModal.d.ts +0 -3
  81. package/dist/components/SortDropDown/index.d.ts +0 -8
@@ -63,6 +63,16 @@ export interface IRoom {
63
63
  lastViewedTimestamp?: number;
64
64
  unreadBaselineTimestamp?: number;
65
65
  unreadMessages?: number;
66
+ /**
67
+ * Unread count the server reported for this room in `GET /v1/chats/my`
68
+ * (`unreadCount`) and when it was read. Only present on backends that send
69
+ * it. The unread middleware uses it as a floor while the local message
70
+ * list is too short to count from (history not loaded yet): it lets the
71
+ * room list show a badge without a MAM round-trip per room. Ignored once
72
+ * the user has read past the API's last message, and cleared on open.
73
+ */
74
+ apiUnreadCount?: number;
75
+ apiUnreadSeededAt?: number;
66
76
  noMessages?: boolean;
67
77
  role?: string;
68
78
  messageStats?: {
@@ -109,6 +119,8 @@ export interface ApiRoom {
109
119
  description?: string;
110
120
  picture?: string;
111
121
  members?: RoomMember[];
122
+ /** True total; `members` is capped at 30 for big public rooms. */
123
+ usersCnt?: number;
112
124
  createdBy?: string;
113
125
  appId?: any;
114
126
  _id?: string;
@@ -118,6 +130,8 @@ export interface ApiRoom {
118
130
  __v?: string;
119
131
  /** See IRoom.muted - only present when the backend supports per-chat mute. */
120
132
  muted?: boolean;
133
+ /** See IRoom.apiUnreadCount - only present when the backend sends it. */
134
+ unreadCount?: number;
121
135
  /** See ApiRoomLastMessage - only present when the backend supports it. */
122
136
  lastMessage?: ApiRoomLastMessage;
123
137
  }
@@ -1,6 +1,6 @@
1
1
  import { Client } from '@xmpp/client';
2
2
  import { Iso639_1Codes } from './language.model';
3
- import { default as XmppClient } from '../../networking/xmppClient';
3
+ import { default as XmppClient, HistoryWindowPage } from '../../networking/xmppClient';
4
4
  import { IMessage } from './message.model';
5
5
  export interface XmppState {
6
6
  client: XmppClient | null;
@@ -27,6 +27,20 @@ export interface xmppSettingsInterface {
27
27
  stagedPreloadFirstPassSize?: number;
28
28
  stagedPreloadSecondPassSize?: number;
29
29
  stagedPreloadConcurrency?: number;
30
+ /**
31
+ * Messages the MUC service replays on every room join, sent as
32
+ * `<history maxstanzas="N"/>`. Default 0: history comes from MAM only, so
33
+ * joining many rooms no longer pulls up to the server default (20) per
34
+ * room. Raise it only if a host relies on the join replay (a room without
35
+ * MAM archiving).
36
+ */
37
+ joinHistoryStanzas?: number;
38
+ /**
39
+ * Rooms joined in parallel by the background join sweep that runs after
40
+ * the room list is shown (active room first, then most recent activity).
41
+ * Default 5.
42
+ */
43
+ joinConcurrency?: number;
30
44
  };
31
45
  }
32
46
  export interface MediaUploadData {
@@ -65,6 +79,12 @@ export interface XmppClientInterface {
65
79
  skipIfPreloaded?: boolean;
66
80
  source?: 'active' | 'send_ack' | 'background' | 'default';
67
81
  }): Promise<IMessage[] | undefined>;
82
+ getHistoryWindow(chatJID: string, max: number, cursor: {
83
+ before?: number;
84
+ after?: number;
85
+ start?: string;
86
+ end?: string;
87
+ }): Promise<HistoryWindowPage>;
68
88
  promoteRoomHistory(roomJID: string): void;
69
89
  setActiveRoomJid(roomJID: string | null): void;
70
90
  isActiveRoomGateOpen(): boolean;
@@ -9,6 +9,18 @@ import { PushPayloadLike } from './notificationPolicy';
9
9
  export declare function showBrowserNotification(title: string, options: NotificationOptions & {
10
10
  data?: any;
11
11
  }, serviceWorkerScope?: string, onClick?: (event: Event) => void): Promise<void>;
12
+ /**
13
+ * Only http(s) URLs and same-origin paths are usable as a notification icon;
14
+ * anything else is dropped rather than handed to the browser.
15
+ */
16
+ export declare function sanitizeIconUrl(value: unknown): string;
17
+ /**
18
+ * The icon a push asks for: its own icon first (data.icon, notification.icon),
19
+ * then the picture it carries (notification.image, what this used to return
20
+ * unconditionally), then the favicon. The service worker applies the same
21
+ * preference for a backgrounded tab.
22
+ */
23
+ export declare function pickPushIcon(payload: PushPayloadLike): string;
12
24
  /**
13
25
  * Helper to extract common data from a message/payload for browser notifications.
14
26
  */
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const ETHORA_CHAT_COMPONENT_VERSION = "26.9.1";
1
+ export declare const ETHORA_CHAT_COMPONENT_VERSION = "26.9.8";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ethora/chat-component",
3
- "version": "26.9.5",
3
+ "version": "26.9.8",
4
4
  "type": "module",
5
5
  "main": "dist/main.js",
6
6
  "types": "dist/main.d.ts",
@@ -97,6 +97,7 @@
97
97
  "eslint-plugin-prettier": "^5.5.0",
98
98
  "eslint-plugin-react-hooks": "^5.2.0",
99
99
  "eslint-plugin-react-refresh": "^0.4.20",
100
+ "globals": "^11.12.0",
100
101
  "jsdom": "^24.1.0",
101
102
  "prettier": "3.6.0",
102
103
  "react": "^18.3.1",
@@ -172,8 +172,26 @@ function pickUrl(raw = {}, data = {}, notification = {}) {
172
172
  );
173
173
  }
174
174
 
175
- function pickIcon() {
176
- return CUSTOM_ICON || DEFAULT_ICON;
175
+ // An icon the push itself carries (data.icon, notification.icon or icon on
176
+ // the payload) wins over the one configured for the whole app: a push about a
177
+ // specific chat or sender knows better than the app-wide default. Only http(s)
178
+ // and same-origin paths are accepted; anything else (data:, javascript:, a
179
+ // bare word) is ignored and the configured/default icon is used instead.
180
+ function sanitizeIconUrl(value) {
181
+ const url = typeof value === 'string' ? value.trim() : '';
182
+ if (!url) return '';
183
+ if (url.charAt(0) === '/' && url.charAt(1) !== '/') return url;
184
+ return /^https?:\/\/[^\s]+$/i.test(url) ? url : '';
185
+ }
186
+
187
+ function pickIcon(raw = {}, data = {}, notification = {}) {
188
+ return (
189
+ sanitizeIconUrl(data.icon) ||
190
+ sanitizeIconUrl(notification.icon) ||
191
+ sanitizeIconUrl(raw.icon) ||
192
+ CUSTOM_ICON ||
193
+ DEFAULT_ICON
194
+ );
177
195
  }
178
196
 
179
197
  function pickBadge() {
@@ -332,7 +350,7 @@ async function handlePush(raw = {}, source = 'push') {
332
350
  const title = pickTitle(raw, data, notification);
333
351
  const body = pickBody(raw, data, notification);
334
352
  const url = pickUrl(raw, data, notification);
335
- const icon = pickIcon();
353
+ const icon = pickIcon(raw, data, notification);
336
354
  const badge = pickBadge();
337
355
  const image = pickImage(raw, data, notification);
338
356
 
@@ -1,3 +0,0 @@
1
- import { default as React } from 'react';
2
- declare const NewChatModal: React.FC;
3
- export default NewChatModal;
@@ -1,8 +0,0 @@
1
- import { default as React } from 'react';
2
- interface DropdownProps {
3
- sortFunction: (value: string) => void;
4
- icon: string;
5
- values: string[];
6
- }
7
- declare const DropdownMenu: React.FC<DropdownProps>;
8
- export default DropdownMenu;