@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.
- package/README.md +45 -1
- package/dist/{ChatProfileModal-Pr4--RdW.js → ChatProfileModal-3UH0H5Ec.js} +725 -714
- package/dist/{FilePreviewModal-CYHlKzRc.js → FilePreviewModal-Cgj1iHry.js} +161 -161
- package/dist/{ManageDataModal-BE1eGlYh.js → ManageDataModal-BblTuE9g.js} +14 -14
- package/dist/{MarkdownBody-G0_J0NL6.js → MarkdownBody-RMEx8yW2.js} +1 -1
- package/dist/MessageSearchModal-CrYR2EH8.js +381 -0
- package/dist/PublicChatsModal-Bi5r4mrV.js +202 -0
- package/dist/{SideDrawer-BG2m7Bcm.js → SideDrawer-CDAoobvX.js} +34 -34
- package/dist/{UserProfileModal-B2Hp5bAF.js → UserProfileModal-4Frgvam-.js} +3 -3
- package/dist/{UserSettingsModal-D871FDAT.js → UserSettingsModal-C-mb-9cb.js} +2 -2
- package/dist/{VideoCallOverlay-Br0ji0nZ.js → VideoCallOverlay-92dFLb9U.js} +1 -1
- package/dist/{VisibilityModal-DdFBV1_g.js → VisibilityModal-zIAV6dAP.js} +9 -9
- package/dist/assets/icons.d.ts +9 -0
- package/dist/components/InputComponents/MentionDropdown.d.ts +2 -0
- package/dist/components/InputComponents/Search.d.ts +4 -0
- package/dist/components/MainComponents/ArchivedMessageCard.d.ts +11 -0
- package/dist/components/MainComponents/scrollAnchor.d.ts +19 -0
- package/dist/components/MainComponents/useJumpToMessage.d.ts +94 -0
- package/dist/components/MainComponents/useScrollAnchor.d.ts +29 -0
- package/dist/components/MainComponents/useStickToBottom.d.ts +27 -0
- package/dist/components/Modals/MessageSearchModal/MessageHitResults.d.ts +27 -0
- package/dist/components/Modals/MessageSearchModal/MessageSearchModal.d.ts +6 -0
- package/dist/components/Modals/MessageSearchModal/resolveSender.d.ts +33 -0
- package/dist/components/Modals/MessageSearchModal/searchFilters.d.ts +34 -0
- package/dist/components/Modals/MessageSearchModal/snippet.d.ts +14 -0
- package/dist/components/Modals/MessageSearchModal/useMessageSearch.d.ts +22 -0
- package/dist/components/Modals/PublicChatsModal/PublicChatsModal.d.ts +13 -0
- package/dist/components/Modals/styledModalComponents.d.ts +0 -8
- package/dist/components/styled/RoomListComponents/index.d.ts +3 -0
- package/dist/context/ToastContext.d.ts +7 -0
- package/dist/firebase-messaging-sw.js +21 -3
- package/dist/{handleCopyClick-DPjxMoJn.js → handleCopyClick-BtXos0AJ.js} +1 -1
- package/dist/helpers/checkUniqueUsers.d.ts +2 -2
- package/dist/helpers/constants/MODAL_TYPES.d.ts +2 -0
- package/dist/helpers/dedupeMembers.d.ts +10 -0
- package/dist/helpers/historyPreloadConfig.d.ts +25 -0
- package/dist/helpers/historyPreloadScheduler.d.ts +3 -0
- package/dist/helpers/insertMessageWithDelimiter.d.ts +1 -0
- package/dist/helpers/isMessageSearchEnabled.d.ts +9 -0
- package/dist/helpers/jumpThread.d.ts +56 -0
- package/dist/helpers/jumpWindow.d.ts +73 -0
- package/dist/helpers/nanoToMs.d.ts +1 -1
- package/dist/helpers/openRoomAtMessage.d.ts +17 -0
- package/dist/helpers/openThreadForJump.d.ts +26 -0
- package/dist/helpers/pdf/loadPdfjs.d.ts +8 -1
- package/dist/helpers/roomUserCount.d.ts +19 -0
- package/dist/helpers/userResolver.d.ts +57 -0
- package/dist/helpers/xmppIdShape.d.ts +1 -1
- package/dist/hooks/useChatWrapperInit.d.ts +6 -0
- package/dist/hooks/useMessageSearchShortcut.d.ts +14 -0
- package/dist/hooks/usePdfThumbnail.d.ts +2 -1
- package/dist/hooks/useRoomDirectory.d.ts +11 -0
- package/dist/hooks/useRoomState.d.ts +1 -0
- package/dist/{main-BRIZ98KV.js → main-BnLtessp.js} +24764 -21859
- package/dist/main.css +1 -1
- package/dist/main.js +16 -16
- package/dist/networking/api-requests/messageSearch.api.d.ts +56 -0
- package/dist/networking/api-requests/publicChats.api.d.ts +23 -0
- package/dist/networking/api-requests/roomMembers.api.d.ts +18 -0
- package/dist/networking/api-requests/xmppToken.api.d.ts +1 -0
- package/dist/networking/ethoraEvents.d.ts +44 -0
- package/dist/networking/stanzaHandlers.d.ts +2 -2
- package/dist/networking/xmpp/allRoomPresences.xmpp.d.ts +18 -1
- package/dist/networking/xmpp/presenceInRoom.xmpp.d.ts +1 -1
- package/dist/networking/xmppClient.d.ts +58 -2
- package/dist/roomStore/Middleware/jumpThreadMiddleware.d.ts +2 -0
- package/dist/roomStore/chatSettingsSlice.d.ts +1 -1
- package/dist/roomStore/index.d.ts +12 -0
- package/dist/roomStore/roomsSlice.d.ts +70 -1
- package/dist/roomStore/safeKey.d.ts +12 -0
- package/dist/roomStore/usersSetCap.d.ts +15 -0
- package/dist/styles/classNames.d.ts +2 -0
- package/dist/types/models/config.model.d.ts +78 -0
- package/dist/types/models/room.model.d.ts +14 -0
- package/dist/types/models/xmpp.model.d.ts +21 -1
- package/dist/utils/notificationUtils.d.ts +12 -0
- package/dist/version.d.ts +1 -1
- package/package.json +2 -1
- package/public/firebase-messaging-sw.js +21 -3
- package/dist/components/Modals/NewChatModal/UpdNewChatModal.d.ts +0 -3
- package/dist/components/SortDropDown/index.d.ts +0 -8
package/README.md
CHANGED
|
@@ -295,6 +295,19 @@ If no `googleLogin`, no `jwtLogin`, no `userLogin`, and no `defaultLogin`, `Logi
|
|
|
295
295
|
`setRoomJidInPath` syncs room identity to URL path.
|
|
296
296
|
`useQRCodeChat` / `handleQRChatId` support QR/deep-link room opening.
|
|
297
297
|
|
|
298
|
+
#### Deep link to a chat and a message (`?chatId=` and `?messageId=`)
|
|
299
|
+
|
|
300
|
+
When no `roomJID` is passed, the chat reads these query parameters of the page URL on load:
|
|
301
|
+
|
|
302
|
+
| Parameter | Meaning |
|
|
303
|
+
| --- | --- |
|
|
304
|
+
| `chatId` | Room to open. A bare id is expanded with `config.xmppSettings.conference`; a full JID (contains `@`) is used as is. Without a conference domain in config a bare id is ignored. |
|
|
305
|
+
| `messageId` (alias `msgId`) | Optional. Open the room and jump to that message, loading older history around it if it is not in memory yet, then briefly highlight it. Matched against the message `id` and `xmppId`. Without it the link just opens the room. |
|
|
306
|
+
|
|
307
|
+
Example: `https://your-app.example/chat?chatId=ROOM_ID&messageId=1781702272543611`.
|
|
308
|
+
|
|
309
|
+
The same link shape is what a push notification click opens (see [Push Notifications](#push-notifications)), so tapping a push lands on the exact message. Search results use the same jump.
|
|
310
|
+
|
|
298
311
|
## Behavior Notes and Legacy Quirks
|
|
299
312
|
|
|
300
313
|
- `newArch` is now default-on. If omitted, runtime uses new architecture paths.
|
|
@@ -302,6 +315,7 @@ If no `googleLogin`, no `jwtLogin`, no `userLogin`, and no `defaultLogin`, `Logi
|
|
|
302
315
|
- `defaultLogin` currently has legacy inverted behavior in `LoginWrapper`:
|
|
303
316
|
- internal fallback login runs when login modes are not configured and `defaultLogin` is not set.
|
|
304
317
|
- keep this in mind when migrating; prefer explicit `userLogin` / `jwtLogin` / `googleLogin`.
|
|
318
|
+
- Protocol: clients omit `isSystemMessage` on the `<data>` element of normal messages; `isSystemMessage="true"` marks system messages (call logs etc.). An absent or legacy `"false"` value is read as a normal message.
|
|
305
319
|
|
|
306
320
|
## Chat Props Reference
|
|
307
321
|
|
|
@@ -336,6 +350,11 @@ Below is a grouped reference for all `config` options.
|
|
|
336
350
|
| `initBeforeLoad` | `boolean` | Initialize XMPP before normal chat load flow. |
|
|
337
351
|
| `newArch` | `boolean` | Defaults to `true`; set `false` to explicitly force legacy/old architecture paths. |
|
|
338
352
|
| `useStoreConsoleEnabled` | `boolean` | Enable verbose internal logging in console. |
|
|
353
|
+
| `userLookupRoute` | `'auto' \| 'v1' \| 'v2'` | Route used to look up one sender that is not in the room member list. Default `'auto'`: `GET /v1/apps/users/<xmppUsername>` first; if the backend refuses the user token there (400/401, missing route) the chat uses `GET /v2/chats/users?xmppUsername=` for 10 minutes, then tries v1 again. A 403 from v1 is treated as a per-user "not allowed" and shows the name carried on the message, or "Unknown user". `'v1'` / `'v2'` pin one route. |
|
|
354
|
+
| `trustedEventSenders` | `string[]` | Who may push server `ethora-event` headlines (see Server events). Default (unset): any bare JID without a resource on the account's own XMPP domain, which is how the server sends them. Set it to pin the exact sender(s) as full bare JIDs (`admin@xmpp.example.com`) or local parts (`admin`). |
|
|
355
|
+
| `historyPreload` | `{ mode?: 'staged' \| 'all' \| 'off'; topRooms?: number; concurrency?: number }` | Background message-history preload after connect, for accounts with many rooms. Default `{ mode: 'staged', topRooms: 8, concurrency: 3 }`. `staged`: the `topRooms` most recently active rooms get a full page loaded, `concurrency` at a time, and rooms the backend gave no `lastMessage` for get a one-message preview (up to 4x `topRooms` of them); every other room loads the moment it is opened. A room the user opens jumps the queue, and a reconnect only re-queues rooms that are not already preloaded. `all`: preload every room (the old behaviour; fine for a handful of rooms). `off`: no background preload at all. The room list's last message, time and unread badge come from `GET /v1/chats/my` (`lastMessage`, `unreadCount`) when the backend sends them, so they render without waiting for any history; a backend without those fields falls back to the history preload. The older `historyQoS.preloadTopKRooms` / `stagedPreloadConcurrency` are still honoured when the matching field here is not set; pinning `historyQoS.stagedPreloadEnabled: false` keeps the legacy startup catch-up path. |
|
|
356
|
+
| `historyQoS.joinHistoryStanzas` | `number` | Messages the MUC service replays on every room join (sent as `<history maxstanzas="N"/>`). Default `0`: history comes from the message archive only, so connecting an account with many rooms no longer pulls the server default (up to 20 messages) per room. Raise it only if a room of yours has no archiving and relies on the join replay. |
|
|
357
|
+
| `historyQoS.joinConcurrency` | `number` | Rooms joined in parallel by the background join sweep. The room list is shown as soon as `/chats/my` returns; every room is then joined in the background (the open room first, then most recent activity; a room you open while it is queued jumps the queue). Default `5`. |
|
|
339
358
|
|
|
340
359
|
### UI and Layout
|
|
341
360
|
|
|
@@ -344,12 +363,14 @@ Below is a grouped reference for all `config` options.
|
|
|
344
363
|
| `disableHeader` | `boolean` | Hide chat header. |
|
|
345
364
|
| `disableMedia` | `boolean` | Disable media sending/processing paths. |
|
|
346
365
|
| `attachments` | `{ maxFiles?; maxFileSizeMb?; accept? }` | Composer attachment limits. `maxFiles` defaults to `5` (hard cap `10`, the stanza payload size); `maxFileSizeMb` adds a client-side per-file check (omit for none); `accept` is passed straight to the file picker. Picking several files sends them as **one** message. |
|
|
347
|
-
| `pdfPreview` | `{ enabled?; workerSrc?; maxFileSizeMb? }` | First-page PDF thumbnails inside bubbles and in the composer tray. On by default; `enabled: false` keeps the static document card. pdf.js is code-split and only fetched when a PDF actually shows up. By default it runs on the main thread, which needs no bundler asset wiring: set `workerSrc` to a pdf.js worker URL you host to move parsing off it. `maxFileSizeMb` (default `25`) is the size past which a document is not auto-rendered. |
|
|
366
|
+
| `pdfPreview` | `{ enabled?; workerSrc?; libUrl?; maxFileSizeMb? }` | First-page PDF thumbnails inside bubbles and in the composer tray. On by default; `enabled: false` keeps the static document card. pdf.js is code-split and only fetched when a PDF actually shows up. By default it runs on the main thread, which needs no bundler asset wiring: set `workerSrc` to a pdf.js worker URL you host to move parsing off it. Set `libUrl` to the URL of a pdf.js ES module build to load it at runtime instead of the copy bundled with the component (pair it with `workerSrc`); useful when you ship the component as one self-contained script and do not want pdf.js (about 1.7 MB) inside it. `maxFileSizeMb` (default `25`) is the size past which a document is not auto-rendered. |
|
|
348
367
|
| `disableRooms` | `boolean` | Hide/disable room list area. |
|
|
349
368
|
| `disableRoomMenu` | `boolean` | Disable room menu controls. |
|
|
350
369
|
| `disableRoomMute` | `boolean` | Hide the "Mute/Unmute notifications" toggle from the chat header menu and room profile, even on a backend that supports it. |
|
|
351
370
|
| `disableRoomConfig` | `boolean` | Hide every control that mutates a room's configuration, leaving the chat-details panel read-only: room avatar upload/remove, the "Delete chat" menu entry, the add-members action, and the per-member moderator menu (appoint as admin / remove member). |
|
|
352
371
|
| `disableNewChatButton` | `boolean` | Hide new chat/create room action. |
|
|
372
|
+
| `enableMessageSearch` | `boolean` | Opt in to message search (default off): the "Search messages" button in the chat header and chat profile, Ctrl/Cmd+F inside the chat, and message matches under the chat-list search box. The panel searches the platform's message archive (`GET /v2/apps/{appId}/messages/search`, available on the QA/prod backend) for the current chat or all chats and jumps to the hit. Needs `appId`; without one it stays off. A leftover `disableMessageSearch: true` (deprecated) still forces it off. |
|
|
373
|
+
| `disablePublicChatsDirectory` | `boolean` | Hide the "Discover chats" entry (in the room list menu, or as its own button when the host hides that menu with `chatHeaderSettings.disableMenu` or takes it over with `headerMenu`; `disableRoomMenu` removes it entirely): a directory of the app's public chats (`GET /v1/chats/public`, 50 per page, filtered client-side) where a chat can be joined without a link or QR code. |
|
|
353
374
|
| `disableUserCount` | `boolean` | Hide the member-count subtitle in the chat header ("N users", plus the online-users popover attached to it). The 1:1 online/offline line is a presence state, not a count, so it stays. |
|
|
354
375
|
| `disableChatInfo` | `{ disableHeader?; disableDescription?; disableType?; disableMembers?; hideMembers?; disableChatHeaderMenu? }` | Fine-grained chat info panel toggles. |
|
|
355
376
|
| `chatHeaderBurgerMenu` | `boolean` | Toggle burger menu in chat header. |
|
|
@@ -487,6 +508,17 @@ object to the provider as to `<Chat>` (which the [single XMPP initialization
|
|
|
487
508
|
contract](#single-xmpp-initialization-contract) already recommends) if you want
|
|
488
509
|
`'call-overlay'` crashes to reach your `onError` too.
|
|
489
510
|
|
|
511
|
+
### Server events (`urn:ethora:events:1`)
|
|
512
|
+
|
|
513
|
+
The server tells a user that something they display changed by sending a `type="headline"` message from its admin account with an `<ethora-event xmlns="urn:ethora:events:1" type="..." .../>` child. The payload is a pointer only; the chat re-reads the data through the normal API and never shows or stores anything from the stanza itself.
|
|
514
|
+
|
|
515
|
+
| Event | Attributes | What the chat does |
|
|
516
|
+
| --- | --- | --- |
|
|
517
|
+
| `user-profile-updated` | `xmppUsername` (`<appId>_<userId>`), `uuid`, `appId`, `ts` | Re-fetches that user, bypassing the cache and any "not found" memory, through the same lookup route as unknown senders (`userLookupRoute`). Existing bubbles are re-named and re-pictured. If it is the signed-in user, their own profile data is updated too. Bursts within 500 ms collapse into one request. |
|
|
518
|
+
| `chat-meta-updated` | `chatName` (`<appId>_<roomId>`), `appId`, `ts` | Re-fetches `GET /v1/chats/my/<chatName>` and applies only title, description, picture, type and user count to the room. Members, messages, last message and unread counters are never replaced, and the user count is never lowered. Events for rooms the chat does not hold are ignored. Debounced per room (500 ms), one request in flight, backoff after errors. |
|
|
519
|
+
|
|
520
|
+
Unknown event types and malformed attributes are ignored. Trust rule: the stanza must come from a bare JID (no resource) on the session's own XMPP domain, so room occupants, other users, the `conference.` domain and other servers are ignored; `trustedEventSenders` narrows this to named senders. `xmppUsername` and `chatName` are validated (charset, length, `<appId>_` prefix) before use. The older `<user-update>` / `<chat-update>` headlines (namespace `your:custom:ns`) are still handled as before.
|
|
521
|
+
|
|
490
522
|
## Custom Widgets and Overrides
|
|
491
523
|
|
|
492
524
|
You can replace key UI parts without forking the package.
|
|
@@ -600,6 +632,18 @@ function PushPermissionButton() {
|
|
|
600
632
|
|
|
601
633
|
`iconPath` and `badgePath` should point to public, reachable assets (for example, files from your app `public/` directory).
|
|
602
634
|
|
|
635
|
+
#### Which icon a web push shows
|
|
636
|
+
|
|
637
|
+
`public/firebase-messaging-sw.js` picks the notification icon in this order:
|
|
638
|
+
|
|
639
|
+
1. An icon the push itself carries: `data.icon`, then `notification.icon`, then `icon` on the payload. A push about a specific chat or sender can therefore show that chat's avatar. Only `http(s)` URLs and same-origin paths (starting with a single `/`) are accepted; anything else (`data:`, `javascript:`, a bare word) is ignored.
|
|
640
|
+
2. `pushNotifications.iconPath`.
|
|
641
|
+
3. The default, `/favicon-192.png` on your origin.
|
|
642
|
+
|
|
643
|
+
The badge has no per-push override: it is `pushNotifications.badgePath`, then the default `/favicon-192.png`. Make sure the fallback file exists on your origin, or the OS shows a generic icon.
|
|
644
|
+
|
|
645
|
+
Clicking a push opens `<origin>/chat?chatId=<room>&messageId=<message>` (or the `url` carried by the push) and calls `pushNotifications.onClick`; see the deep link section above.
|
|
646
|
+
|
|
603
647
|
## Auth Strategies
|
|
604
648
|
|
|
605
649
|
| Strategy | Config shape | Best for |
|