@ethora/chat-component 26.7.4 → 26.7.6
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 +72 -16
- package/dist/ChatProfileModal-hxsWI8cx.js +2139 -0
- package/dist/FilePreviewModal-CwWnHsB1.js +736 -0
- package/dist/ManageDataModal-CDPXcC93.js +159 -0
- package/dist/MarkdownBody-DBJGraWM.js +16874 -0
- package/dist/SideDrawer-Dr_lkaOW.js +226 -0
- package/dist/UserProfileModal-Q_jhXpsX.js +568 -0
- package/dist/UserSettingsModal-OcAJao-d.js +50 -0
- package/dist/{VideoCallOverlay-BUfKp87t.js → VideoCallOverlay-CC4sShdK.js} +9 -10
- package/dist/VisibilityModal-DkMhx_2k.js +132 -0
- package/dist/assets/icons.d.ts +30 -0
- package/dist/components/ContextMenu/ContextMenuComponents.d.ts +1 -3
- package/dist/components/EmojiPicker/LazyEmojiPicker.d.ts +3 -0
- package/dist/components/ExampleComponents/CustomMessage.d.ts +3 -3
- package/dist/components/Files/FilesList.d.ts +12 -0
- package/dist/components/Files/FilesPanel.d.ts +3 -0
- package/dist/components/Files/fileCategory.d.ts +13 -0
- package/dist/components/InputComponents/AttachmentPreview.d.ts +17 -0
- package/dist/components/InputComponents/MentionDropdown.d.ts +13 -0
- package/dist/components/InputComponents/MentionPickerModal.d.ts +19 -0
- package/dist/components/MainComponents/AttachmentList.d.ts +7 -0
- package/dist/components/MainComponents/ChatErrorBoundary.d.ts +53 -0
- package/dist/components/MainComponents/ChatErrorScreen.d.ts +24 -0
- package/dist/components/MainComponents/HeaderLogo.d.ts +18 -0
- package/dist/components/MainComponents/MediaMessage.d.ts +5 -0
- package/dist/components/MainComponents/MessageContainer.d.ts +2 -2
- package/dist/components/MainComponents/ReduxWrapper.d.ts +1 -2
- package/dist/components/MainComponents/SystemMessage.d.ts +1 -2
- package/dist/components/MenuRoom/MenuRoom.d.ts +1 -0
- package/dist/components/MessageBubble/CustomDivider.d.ts +3 -3
- package/dist/components/MessageBubble/Message.d.ts +2 -2
- package/dist/components/MessageBubble/MessageTranslate.d.ts +28 -10
- package/dist/components/MessageBubble/QuickReplies.d.ts +19 -0
- package/dist/components/Modals/ChatProfileModal/ChatProfileMemberRow.d.ts +18 -0
- package/dist/components/Modals/FilePreviewModal/FilePreviewModal.d.ts +17 -0
- package/dist/components/Modals/FilePreviewModal/ImageLightbox.d.ts +35 -0
- package/dist/components/Modals/FilePreviewModal/PdfView.d.ts +14 -3
- package/dist/components/Modals/NewChatModal/styledNewChatComponents.d.ts +12 -0
- package/dist/components/Modals/SettingsModals/Visibility/StyledComponents.d.ts +1 -1
- package/dist/components/Modals/SideDrawer/DrawerProfileParts.d.ts +13 -0
- package/dist/components/Modals/SideDrawer/SideDrawer.d.ts +44 -0
- package/dist/components/Modals/modalComponents.d.ts +6 -0
- package/dist/components/Modals/styledModalComponents.d.ts +14 -3
- package/dist/components/RoomComponents/ChatRoomItem.d.ts +0 -1
- package/dist/components/RoomComponents/OnlineUsersPopover.d.ts +0 -1
- package/dist/components/UsersList/StyledComponents.d.ts +5 -1
- package/dist/components/UsersList/UsersList.d.ts +23 -0
- package/dist/components/styled/Button.d.ts +11 -1
- package/dist/components/styled/ChatWrapperBox.d.ts +3 -1
- package/dist/components/styled/PdfMessage.d.ts +13 -0
- package/dist/components/styled/RoomListComponents/index.d.ts +22 -1
- package/dist/components/styled/SendInput.d.ts +19 -5
- package/dist/components/styled/StyledComponents.d.ts +1 -1
- package/dist/components/styled/StyledInputComponents/MediaComponents.d.ts +18 -0
- package/dist/components/styled/StyledInputComponents/StyledInputComponents.d.ts +21 -0
- package/dist/components/styled/TreadLabel.d.ts +2 -2
- package/dist/components/styled/UnsupportedType.d.ts +1 -1
- package/dist/examples/quiz/QuizDemo.d.ts +3 -0
- package/dist/examples/quiz/quizScript.d.ts +38 -0
- package/dist/examples/quiz/useDemoSession.d.ts +42 -0
- package/dist/examples/quiz/useQuizFlow.d.ts +47 -0
- package/dist/firebase-config.d.ts +2 -4
- package/dist/handleCopyClick-CpmPa6VI.js +32 -0
- package/dist/helpers/MarkdownBody.d.ts +7 -0
- package/dist/helpers/attachments.d.ts +33 -0
- package/dist/helpers/botMarkup.d.ts +30 -0
- package/dist/helpers/constants/MODAL_TYPES.d.ts +11 -7
- package/dist/helpers/ethoraLogger.d.ts +8 -0
- package/dist/helpers/fileKind.d.ts +17 -0
- package/dist/helpers/hiddenRooms.d.ts +1 -1
- package/dist/helpers/historyPreloadScheduler.d.ts +1 -0
- package/dist/helpers/lazyEmoji.d.ts +3 -0
- package/dist/helpers/localStorageUser.d.ts +1 -1
- package/dist/helpers/markdownSanitizeSchema.d.ts +3 -0
- package/dist/helpers/mentions.d.ts +63 -0
- package/dist/helpers/parseMessageBody.d.ts +12 -2
- package/dist/helpers/pdf/loadPdfjs.d.ts +64 -0
- package/dist/helpers/quickReplies.d.ts +31 -0
- package/dist/helpers/remarkLineBreaks.d.ts +42 -0
- package/dist/helpers/resolveMessageTranslation.d.ts +34 -0
- package/dist/helpers/roomImageGallery.d.ts +53 -0
- package/dist/helpers/secureFileUrl.d.ts +8 -0
- package/dist/helpers/sendFailureWatchdog.d.ts +62 -0
- package/dist/helpers/transformTranslatations.d.ts +1 -2
- package/dist/hooks/pushSubscriptionSweep.d.ts +41 -0
- package/dist/hooks/useChatWrapperInit.d.ts +1 -0
- package/dist/hooks/useFilesEndpointSupport.d.ts +9 -0
- package/dist/hooks/useInView.d.ts +17 -0
- package/dist/hooks/useMentionComposer.d.ts +45 -0
- package/dist/hooks/useMessageHeapState.d.ts +1 -1
- package/dist/hooks/useMessageTranslation.d.ts +4 -3
- package/dist/hooks/useModalDismiss.d.ts +27 -0
- package/dist/hooks/useMyFiles.d.ts +16 -0
- package/dist/hooks/usePdfThumbnail.d.ts +22 -0
- package/dist/hooks/useRoomMute.d.ts +19 -0
- package/dist/hooks/useRoomState.d.ts +1 -1
- package/dist/hooks/useSendMessage.d.ts +4 -3
- package/dist/hooks/useTypography.d.ts +1 -1
- package/dist/hooks/useUnreadMessagesCounter.d.ts +11 -2
- package/dist/index.esm-B-3fyDHY.js +28 -0
- package/dist/index.esm-CRM4VCRa.js +943 -0
- package/dist/index.esm-msbp26WN.js +3352 -0
- package/dist/index.esm2017-CL0mvq6y.js +1578 -0
- package/dist/main-B-8IhwaP.js +31837 -0
- package/dist/main.css +1 -1
- package/dist/main.d.ts +16 -0
- package/dist/main.js +19 -18
- package/dist/module-DGXkb0R_.js +2960 -0
- package/dist/native-CDi4YD_s.js +13 -0
- package/dist/networking/api-requests/files.api.d.ts +19 -0
- package/dist/networking/api-requests/rooms.api.d.ts +10 -2
- package/dist/networking/api-requests/translate.api.d.ts +15 -0
- package/dist/networking/api-requests/user.api.d.ts +2 -0
- package/dist/networking/sharedRequest.d.ts +4 -0
- package/dist/networking/xmpp/allRoomPresences.xmpp.d.ts +3 -1
- package/dist/networking/xmpp/createTimeoutPromise.xmpp.d.ts +14 -0
- package/dist/networking/xmpp/sendTextMessage.xmpp.d.ts +2 -1
- package/dist/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.d.ts +2 -1
- package/dist/networking/xmppClient.d.ts +12 -3
- package/dist/pdf-B5b7qHu6.js +17130 -0
- package/dist/pdf.worker.min-COYn-gId.js +24385 -0
- package/dist/roomStore/index.d.ts +20 -0
- package/dist/roomStore/persistEncryption.d.ts +51 -0
- package/dist/roomStore/roomsSlice.d.ts +49 -6
- package/dist/styles/classNames.d.ts +35 -0
- package/dist/styles/motion.d.ts +44 -0
- package/dist/styles/tokens.d.ts +27 -0
- package/dist/testIds.d.ts +1 -1
- package/dist/types/models/attachment.model.d.ts +33 -0
- package/dist/types/models/config.model.d.ts +179 -19
- package/dist/types/models/file.model.d.ts +20 -0
- package/dist/types/models/message.model.d.ts +16 -6
- package/dist/types/models/room.model.d.ts +12 -2
- package/dist/types/types.d.ts +3 -1
- package/dist/utils/resendMessage.d.ts +22 -1
- package/dist/utils/translateModePolicy.d.ts +1 -0
- package/dist/wavesurfer.esm-D_a19qBW.js +952 -0
- package/package.json +22 -2
- package/dist/VideoCallOverlay-BUfKp87t.js.map +0 -1
- package/dist/components/MainComponents/VirtualList.d.ts +0 -10
- package/dist/components/Modals/SettingsModals/BlockedUsers/BlockedUsersModal.d.ts +0 -6
- package/dist/components/Modals/SettingsModals/DocumentShares/DocumentSharesModal.d.ts +0 -6
- package/dist/components/Modals/SettingsModals/ManageDataModal/StyledComponents.d.ts +0 -0
- package/dist/components/Modals/SettingsModals/ProfileShares/ProfileShares.d.ts +0 -6
- package/dist/components/Modals/SettingsModals/Referrals/Referrals.d.ts +0 -6
- package/dist/hooks/useMessageQueue.d.ts +0 -4
- package/dist/main-DFqqDiy-.js +0 -55707
- package/dist/main-DFqqDiy-.js.map +0 -1
- package/dist/main.js.map +0 -1
- package/dist/networking/xmpp/getHistory.xmpp.d.ts +0 -3
- package/dist/networking/xmpp/listenerManager.d.ts +0 -17
- package/dist/utils/xmppMemoryMonitor.d.ts +0 -16
|
@@ -3,6 +3,26 @@ import { IMessage, IRoom } from '../types/types';
|
|
|
3
3
|
export declare const sanitizeRoomsMap: (roomsMap: Record<string, any>) => Record<string, IRoom>;
|
|
4
4
|
export declare const MAX_MESSAGES_PER_ROOM = 100;
|
|
5
5
|
export declare const MAX_PERSISTED_ROOMS = 100;
|
|
6
|
+
/**
|
|
7
|
+
* Composer drafts are a NEW top-level key of the rooms slice, so they are
|
|
8
|
+
* persisted deliberately rather than by accident: they are the one piece of
|
|
9
|
+
* live composer state worth surviving a reload, and unlike `members` (see
|
|
10
|
+
* REFETCHED_ROOM_FIELDS below) nothing on the server can rebuild them.
|
|
11
|
+
*
|
|
12
|
+
* They are also kept OFF the room objects on purpose. The rooms map is what
|
|
13
|
+
* the char budget fights over, and its last-resort eviction can only drop
|
|
14
|
+
* `messages` - a draft riding on a room would compete with the message
|
|
15
|
+
* cache for that budget and could not be evicted independently. As its own
|
|
16
|
+
* key it is bounded on its own terms by the caps in roomsSlice:
|
|
17
|
+
* MAX_PERSISTED_DRAFTS (30, least recently typed dropped first, using the
|
|
18
|
+
* map's insertion order as recency) x MAX_DRAFT_LENGTH (2,000 chars) =
|
|
19
|
+
* 60,000 chars, i.e. 6% of PERSISTED_ROOMS_CHAR_BUDGET even at the worst
|
|
20
|
+
* case, and typically a few hundred bytes.
|
|
21
|
+
*
|
|
22
|
+
* Applied on the way out AND on the way back in (sanitizeRoomsSliceKey), so
|
|
23
|
+
* an older or hand-edited blob cannot rehydrate an unbounded map either.
|
|
24
|
+
*/
|
|
25
|
+
export declare const compactDraftsForPersist: (drafts: unknown) => Record<string, string>;
|
|
6
26
|
export declare const PERSISTED_ROOMS_CHAR_BUDGET = 1000000;
|
|
7
27
|
/** ~1.4x: AES + base64 overhead the encrypt transform adds on top. */
|
|
8
28
|
export declare const ENCRYPTION_INFLATION_FACTOR = 1.4;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { User } from '../types/types';
|
|
2
|
+
/**
|
|
3
|
+
* WHICH CLAIMS, AND WHY NOT THE WHOLE TOKEN.
|
|
4
|
+
*
|
|
5
|
+
* The obvious input, `user.token`, is the wrong one: it rotates.
|
|
6
|
+
* `authRefresh.ts` runs refresh-token rotation with reuse detection, so
|
|
7
|
+
* the access token string changes several times an hour. Key the
|
|
8
|
+
* encryption on the whole token and every rotation orphans the blob
|
|
9
|
+
* that the previous token wrote: the user would lose their entire chat
|
|
10
|
+
* cache on a schedule, silently, and each reload would start from an
|
|
11
|
+
* empty transcript until MAM caught up.
|
|
12
|
+
*
|
|
13
|
+
* So we derive from the parts of the token that are stable for the life
|
|
14
|
+
* of the ACCOUNT rather than the life of the credential: the `userId`
|
|
15
|
+
* and `appId` claims out of the JWT payload (Ethora issues
|
|
16
|
+
* `{ data: { userId, appId }, iat, exp }`). `iat` / `exp` / the
|
|
17
|
+
* signature are deliberately excluded - they are exactly the parts that
|
|
18
|
+
* change on refresh.
|
|
19
|
+
*
|
|
20
|
+
* `appToken` joins them as a build-time constant so two different apps
|
|
21
|
+
* embedding the SDK on one origin never derive the same key. It adds no
|
|
22
|
+
* secrecy on its own (it is in the bundle), which is why it is a
|
|
23
|
+
* component of the key and not the key.
|
|
24
|
+
*/
|
|
25
|
+
export interface PersistKeyIdentity {
|
|
26
|
+
userId: string;
|
|
27
|
+
appId: string;
|
|
28
|
+
}
|
|
29
|
+
/** The key used when there is no session: SSR, logged out, first paint. */
|
|
30
|
+
export declare const ANONYMOUS_PERSIST_SECRET_KEY: string;
|
|
31
|
+
/**
|
|
32
|
+
* Stable account identity for the key, read from the JWT payload first
|
|
33
|
+
* and from the stored user record second. The fallback matters for
|
|
34
|
+
* hosts that hand the SDK a user object without an Ethora access token
|
|
35
|
+
* (they run their own auth and supply `refreshTokens.refreshFunction`).
|
|
36
|
+
*/
|
|
37
|
+
export declare const readStableIdentity: (user?: Partial<User> | null) => PersistKeyIdentity | null;
|
|
38
|
+
export declare const derivePersistSecretKey: (identity?: PersistKeyIdentity | null) => string;
|
|
39
|
+
export declare const getPersistSecretKey: () => string;
|
|
40
|
+
/** Test seam, and the hook logout could use if it ever needs to. */
|
|
41
|
+
export declare const resetPersistSecretKeyCache: () => void;
|
|
42
|
+
/**
|
|
43
|
+
* Drop-in replacement for the old fixed-key `encryptTransform`.
|
|
44
|
+
*
|
|
45
|
+
* It has to resolve the key lazily, per call: `encryptTransform`
|
|
46
|
+
* captures `secretKey` when it is constructed, and this module is
|
|
47
|
+
* imported at store-creation time, long before a `<Chat>` consumer has
|
|
48
|
+
* logged anybody in. Resolving on each in/out means the first write
|
|
49
|
+
* after login already uses that user's key.
|
|
50
|
+
*/
|
|
51
|
+
export declare const sessionEncryptTransform: import('redux-persist').Transform<any, any, any, any>;
|
|
@@ -1,5 +1,21 @@
|
|
|
1
|
-
import { AddRoomMessageAction, ApiRoom, EditAction, IMessage, IRoom, ReactionAction, RoomMember } from '../types/types';
|
|
1
|
+
import { AddRoomMessageAction, ApiRoom, EditAction, IMessage, IRoom, ReactionAction, RoomMember, Translation } from '../types/types';
|
|
2
2
|
import { default as XmppClient } from '../networking/xmppClient';
|
|
3
|
+
/**
|
|
4
|
+
* Draft caps. Drafts ride along in the persisted rooms slice, so they have
|
|
5
|
+
* to be bounded before they are written, not after:
|
|
6
|
+
*
|
|
7
|
+
* 30 rooms x 2,000 chars = 60,000 chars worst case, ~84,000 after the
|
|
8
|
+
* encrypt transform's ~1.4x inflation (~168 KB of the origin's ~5 MB).
|
|
9
|
+
*
|
|
10
|
+
* That is small next to PERSISTED_ROOMS_CHAR_BUDGET (1,000,000 chars) and,
|
|
11
|
+
* because drafts are their own top-level slice key, it can never squeeze
|
|
12
|
+
* the message cache the way the member roster once did. 2,000 chars is far
|
|
13
|
+
* longer than any message anyone actually leaves half-typed; anything past
|
|
14
|
+
* it is truncated rather than dropped, so the user still gets most of it
|
|
15
|
+
* back.
|
|
16
|
+
*/
|
|
17
|
+
export declare const MAX_DRAFT_LENGTH = 2000;
|
|
18
|
+
export declare const MAX_PERSISTED_DRAFTS = 30;
|
|
3
19
|
interface RoomMessagesState {
|
|
4
20
|
rooms: {
|
|
5
21
|
[jid: string]: IRoom;
|
|
@@ -16,12 +32,13 @@ interface RoomMessagesState {
|
|
|
16
32
|
subscribedRooms: string[];
|
|
17
33
|
pushSubscriptionStatus: Record<string, 'pending' | 'subscribed' | 'error' | 'blocked'>;
|
|
18
34
|
loadingText?: string;
|
|
35
|
+
drafts: Record<string, string>;
|
|
19
36
|
}
|
|
20
37
|
interface PreloadRoomUpdate {
|
|
21
38
|
jid: string;
|
|
22
39
|
messages?: IMessage[];
|
|
23
40
|
unreadCapped?: boolean;
|
|
24
|
-
historyPreloadState?: 'idle' | 'loading' | 'done' | 'error';
|
|
41
|
+
historyPreloadState?: 'idle' | 'loading' | 'partial' | 'done' | 'error';
|
|
25
42
|
}
|
|
26
43
|
export declare const addRoomViaApi: import('@reduxjs/toolkit').AsyncThunk<void, {
|
|
27
44
|
room: IRoom;
|
|
@@ -48,11 +65,26 @@ export declare const addRoom: import('@reduxjs/toolkit').ActionCreatorWithOption
|
|
|
48
65
|
}, "roomMessages/replaceRoomMessages">, addRoomMessage: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<AddRoomMessageAction, "roomMessages/addRoomMessage">, deleteRoomMessage: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
49
66
|
roomJID: string;
|
|
50
67
|
messageId: string;
|
|
51
|
-
}, "roomMessages/deleteRoomMessage">,
|
|
68
|
+
}, "roomMessages/deleteRoomMessage">, removeRoomMessage: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
69
|
+
roomJID: string;
|
|
70
|
+
messageId: string;
|
|
71
|
+
}, "roomMessages/removeRoomMessage">, setEditAction: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<EditAction, "roomMessages/setEditAction">, setMessageSendFailed: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
72
|
+
roomJID: string;
|
|
73
|
+
messageId: string;
|
|
74
|
+
}, "roomMessages/setMessageSendFailed">, setMessageSendRetrying: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
75
|
+
roomJID: string;
|
|
76
|
+
messageId: string;
|
|
77
|
+
}, "roomMessages/setMessageSendRetrying">, editRoomMessage: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
52
78
|
roomJID: string;
|
|
53
79
|
messageId: string;
|
|
54
80
|
text: string;
|
|
55
|
-
|
|
81
|
+
isEdited?: boolean;
|
|
82
|
+
}, "roomMessages/editRoomMessage">, setMessageTranslation: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
83
|
+
roomJID: string;
|
|
84
|
+
messageId: string;
|
|
85
|
+
locale: string;
|
|
86
|
+
entry: Translation;
|
|
87
|
+
}, "roomMessages/setMessageTranslation">, setComposing: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
56
88
|
chatJID: string;
|
|
57
89
|
composing: boolean;
|
|
58
90
|
composingList?: string[];
|
|
@@ -87,7 +119,10 @@ export declare const addRoom: import('@reduxjs/toolkit').ActionCreatorWithOption
|
|
|
87
119
|
}, "roomMessages/deleteRoom">, updateRoom: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
88
120
|
jid: string;
|
|
89
121
|
updates: Partial<IRoom>;
|
|
90
|
-
}, "roomMessages/updateRoom">,
|
|
122
|
+
}, "roomMessages/updateRoom">, updateRooms: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
123
|
+
jid: string;
|
|
124
|
+
updates: Partial<IRoom>;
|
|
125
|
+
}[], "roomMessages/updateRooms">, updateUsersSet: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
91
126
|
rooms: ApiRoom[];
|
|
92
127
|
}, "roomMessages/updateUsersSet">, setOpenReportModal: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
93
128
|
isOpen: boolean;
|
|
@@ -98,6 +133,14 @@ export declare const addRoom: import('@reduxjs/toolkit').ActionCreatorWithOption
|
|
|
98
133
|
status: "pending" | "subscribed" | "error" | "blocked";
|
|
99
134
|
}, "roomMessages/setPushSubscriptionStatus">, clearPushSubscriptions: import('@reduxjs/toolkit').ActionCreatorWithoutPayload<"roomMessages/clearPushSubscriptions">, applyRoomsPreloadBatch: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
100
135
|
rooms: PreloadRoomUpdate[];
|
|
101
|
-
}, "roomMessages/applyRoomsPreloadBatch"
|
|
136
|
+
}, "roomMessages/applyRoomsPreloadBatch">, setRoomDraft: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
137
|
+
jid: string;
|
|
138
|
+
text: string;
|
|
139
|
+
}, "roomMessages/setRoomDraft">, clearRoomDraft: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
140
|
+
jid: string;
|
|
141
|
+
}, "roomMessages/clearRoomDraft">, setRoomMuted: import('@reduxjs/toolkit').ActionCreatorWithOptionalPayload<{
|
|
142
|
+
jid: string;
|
|
143
|
+
muted: boolean | undefined;
|
|
144
|
+
}, "roomMessages/setRoomMuted">;
|
|
102
145
|
declare const _default: import('redux').Reducer<RoomMessagesState>;
|
|
103
146
|
export default _default;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global CSS class names owned by this SDK.
|
|
3
|
+
*
|
|
4
|
+
* This package is embedded into host applications, so every class name it
|
|
5
|
+
* writes into the DOM shares a namespace with the host's own stylesheet.
|
|
6
|
+
* Anything declared in `src/index.css` must therefore be prefixed with
|
|
7
|
+
* `ethora-` (so it cannot collide with a host class of the same name) and,
|
|
8
|
+
* where possible, nested under {@link CHAT_ROOT_CLASS} (so it cannot leak
|
|
9
|
+
* styling onto host markup).
|
|
10
|
+
*
|
|
11
|
+
* Keep these constants as the single source of truth: `index.css` and every
|
|
12
|
+
* component that adds/removes one of these classes must agree, and a plain
|
|
13
|
+
* string literal in a `classList.add(...)` call is easy to drift.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Marks a subtree as "owned by the chat".
|
|
17
|
+
*
|
|
18
|
+
* Applied to:
|
|
19
|
+
* - the invisible (`display: contents`) wrapper `<Chat>` renders around its
|
|
20
|
+
* whole tree, so every chat node is a descendant, and
|
|
21
|
+
* - UI the SDK renders OUTSIDE that tree (the in-app notification container,
|
|
22
|
+
* the portalled language modal), which would otherwise lose the chat's
|
|
23
|
+
* scrollbar/typography defaults.
|
|
24
|
+
*
|
|
25
|
+
* Everything in `index.css` that is not itself `ethora-`-prefixed (scrollbars,
|
|
26
|
+
* base font) is scoped to this class, which is what keeps the host page's own
|
|
27
|
+
* scrollbars and body typography untouched.
|
|
28
|
+
*/
|
|
29
|
+
export declare const CHAT_ROOT_CLASS = "ethora-chat-root";
|
|
30
|
+
/** Transient highlight flashed on a message when a notification is opened. */
|
|
31
|
+
export declare const MESSAGE_HIGHLIGHT_CLASS = "ethora-message-highlight";
|
|
32
|
+
/** Fixed-position container holding the in-app notification toasts. */
|
|
33
|
+
export declare const NOTIFICATION_CONTAINER_CLASS = "ethora-message-notification-container";
|
|
34
|
+
/** Forces the colour-emoji font on nodes that render a bare emoji glyph. */
|
|
35
|
+
export declare const APPLE_EMOJI_CLASS = "ethora-apple-emoji";
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared motion primitives for the chat UI.
|
|
3
|
+
*
|
|
4
|
+
* Keep durations/easing in sync with the tokens published by
|
|
5
|
+
* `styles/tokens.ts` (`--ethora-motion-fast` = 150ms, `--ethora-motion-base`
|
|
6
|
+
* = 220ms, `--ethora-motion-ease`). The literal values are duplicated here
|
|
7
|
+
* (rather than reading the CSS variables inside `@keyframes`, which most
|
|
8
|
+
* browsers don't support) but must stay numerically identical.
|
|
9
|
+
*/
|
|
10
|
+
export declare const MOTION_FAST = "150ms";
|
|
11
|
+
export declare const MOTION_BASE = "220ms";
|
|
12
|
+
export declare const MOTION_EASE = "cubic-bezier(.2,.8,.2,1)";
|
|
13
|
+
export declare const fadeIn: import('styled-components/dist/models/Keyframes').default;
|
|
14
|
+
export declare const fadeInUp: import('styled-components/dist/models/Keyframes').default;
|
|
15
|
+
export declare const scaleIn: import('styled-components/dist/models/Keyframes').default;
|
|
16
|
+
export declare const shimmer: import('styled-components/dist/models/Keyframes').default;
|
|
17
|
+
/**
|
|
18
|
+
* Right-hand side drawer entrance. Travels further than `fadeInUp` (a panel
|
|
19
|
+
* sliding in from the screen edge reads as motion only if it actually
|
|
20
|
+
* covers some distance) but keeps the same duration/easing as everything
|
|
21
|
+
* else, so a drawer does not feel like a different app.
|
|
22
|
+
*/
|
|
23
|
+
export declare const slideInRight: import('styled-components/dist/models/Keyframes').default;
|
|
24
|
+
/**
|
|
25
|
+
* Disables all animations/transitions when the user prefers reduced motion.
|
|
26
|
+
* Spread this LAST in a styled-components template so it wins the cascade,
|
|
27
|
+
* e.g.:
|
|
28
|
+
*
|
|
29
|
+
* const Row = styled.div`
|
|
30
|
+
* animation: ${fadeInUp} ${MOTION_BASE} ${MOTION_EASE};
|
|
31
|
+
* ${reducedMotion}
|
|
32
|
+
* `;
|
|
33
|
+
*/
|
|
34
|
+
export declare const reducedMotion: import('styled-components').RuleSet<object>;
|
|
35
|
+
/** Convenience: fade+rise-in animation shorthand, respecting reduced motion. */
|
|
36
|
+
export declare const fadeInUpAnimation: import('styled-components').RuleSet<object>;
|
|
37
|
+
/** Convenience: cross-fade animation shorthand, respecting reduced motion. */
|
|
38
|
+
export declare const fadeInAnimation: import('styled-components').RuleSet<object>;
|
|
39
|
+
/** Convenience: scale-in animation shorthand, respecting reduced motion. */
|
|
40
|
+
export declare const scaleInAnimation: import('styled-components').RuleSet<object>;
|
|
41
|
+
/** Convenience: side-drawer slide-in shorthand, respecting reduced motion. */
|
|
42
|
+
export declare const slideInRightAnimation: import('styled-components').RuleSet<object>;
|
|
43
|
+
/** Shimmering skeleton background, respecting reduced motion (stays static). */
|
|
44
|
+
export declare const shimmerBackground: import('styled-components').RuleSet<object>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
import { IConfig, TypographyConfig } from '../types/types';
|
|
3
|
+
/** Mix `hex` toward white by `amount` (0-1). Used for soft tints. */
|
|
4
|
+
export declare const tintColor: (hex: string, amount: number) => string;
|
|
5
|
+
/** Mix `hex` toward black by `amount` (0-1). Used for hover/pressed shades. */
|
|
6
|
+
export declare const shadeColor: (hex: string, amount: number) => string;
|
|
7
|
+
export type ThemeTokenMap = Record<string, string>;
|
|
8
|
+
/**
|
|
9
|
+
* Build the full `--ethora-*` CSS variable map from the host's config.
|
|
10
|
+
* Pure function - safe to call outside the browser (SSR, tests).
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildThemeTokens(colors?: IConfig['colors'], typography?: TypographyConfig): ThemeTokenMap;
|
|
13
|
+
/**
|
|
14
|
+
* The class the chat's root element carries; useful for scoping global CSS.
|
|
15
|
+
* Re-exported from `styles/classNames`, which owns every class name this
|
|
16
|
+
* SDK writes into the DOM, so the literal exists in exactly one place.
|
|
17
|
+
*/
|
|
18
|
+
export { CHAT_ROOT_CLASS } from './classNames';
|
|
19
|
+
/**
|
|
20
|
+
* Memoized React.CSSProperties built from the token map - spread this onto
|
|
21
|
+
* the chat root element's inline `style` so the variables are scoped to the
|
|
22
|
+
* chat subtree wherever the root can carry them.
|
|
23
|
+
*/
|
|
24
|
+
export declare function useThemeTokenStyle(colors?: IConfig['colors'], typography?: TypographyConfig): CSSProperties;
|
|
25
|
+
export declare function ThemeTokens({ config, }: {
|
|
26
|
+
config?: Pick<IConfig, 'colors' | 'typography'>;
|
|
27
|
+
}): null;
|
package/dist/testIds.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Kotlin objects (in `chat-ui/src/main/.../components/*Kt`) and iOS's
|
|
7
7
|
* `*AccessibilityID` Swift enums (in `XMPPChatUI/AccessibilityIdentifiers.swift`),
|
|
8
8
|
* so a single Maestro YAML flow exercises the same intent on either
|
|
9
|
-
* mobile platform
|
|
9
|
+
* mobile platform - and Playwright tests in host apps using this
|
|
10
10
|
* component (e.g. `ethora-app-reactjs`) can resolve the same nodes
|
|
11
11
|
* via `data-testid`.
|
|
12
12
|
*
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One uploaded file carried by a media message.
|
|
3
|
+
*
|
|
4
|
+
* Historically a media message described exactly one file through flat
|
|
5
|
+
* `IMessage` fields (`location`, `mimetype`, `originalName`, ...). Those
|
|
6
|
+
* fields are still written (they are what every already-shipped client
|
|
7
|
+
* reads), and they now double as attachment #0 of `IMessage.attachments`.
|
|
8
|
+
* Anything past #0 only exists in the `attachments` payload, so old clients
|
|
9
|
+
* degrade to "shows the first file" instead of breaking.
|
|
10
|
+
*/
|
|
11
|
+
export interface IAttachment {
|
|
12
|
+
/** `_id` returned by POST /files/ - stable per upload, used as a render key. */
|
|
13
|
+
attachmentId?: string;
|
|
14
|
+
/** Canonical file URL. */
|
|
15
|
+
location: string;
|
|
16
|
+
/** Server-side generated preview (images always, other types sometimes). */
|
|
17
|
+
locationPreview?: string;
|
|
18
|
+
mimetype?: string;
|
|
19
|
+
/** Name the user picked. */
|
|
20
|
+
originalName?: string;
|
|
21
|
+
/** Name on the storage side. */
|
|
22
|
+
fileName?: string;
|
|
23
|
+
/** Bytes, as a string - that is how it travels on the wire. */
|
|
24
|
+
size?: string;
|
|
25
|
+
duration?: string;
|
|
26
|
+
ownerKey?: string;
|
|
27
|
+
userId?: string;
|
|
28
|
+
createdAt?: string;
|
|
29
|
+
updatedAt?: string;
|
|
30
|
+
expiresAt?: string;
|
|
31
|
+
isVisible?: boolean;
|
|
32
|
+
isPrivate?: boolean;
|
|
33
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { User } from './user.model';
|
|
2
2
|
import { xmppSettingsInterface } from './xmpp.model';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { ConfigRoom } from './room.model';
|
|
4
|
+
import { MessageProps, IMessage } from './message.model';
|
|
5
5
|
import { Iso639_1Codes } from './language.model';
|
|
6
|
+
import { QuickReply } from '../../helpers/quickReplies';
|
|
6
7
|
import { default as React } from 'react';
|
|
7
8
|
import { MessageNotificationToastProps } from '../../components/MessageNotification/MessageNotificationToast';
|
|
8
9
|
/**
|
|
@@ -55,7 +56,7 @@ export interface FBConfig {
|
|
|
55
56
|
}
|
|
56
57
|
/**
|
|
57
58
|
* A single self-hosted font file to register via an injected `@font-face`
|
|
58
|
-
* rule. Use this for fonts that are not on Google Fonts
|
|
59
|
+
* rule. Use this for fonts that are not on Google Fonts - e.g. the Ukrainian
|
|
59
60
|
* government "e-Ukraine" family distributed from thedigital.gov.ua. Host the
|
|
60
61
|
* `.woff2`/`.ttf` somewhere reachable and point `src` at it.
|
|
61
62
|
*/
|
|
@@ -113,10 +114,54 @@ export interface TypographyConfig {
|
|
|
113
114
|
bold?: number;
|
|
114
115
|
};
|
|
115
116
|
}
|
|
117
|
+
/** Which part of the SDK an uncaught render error came from. */
|
|
118
|
+
export type ChatErrorScope = 'chat' | 'call-overlay';
|
|
119
|
+
/**
|
|
120
|
+
* What the SDK reports when its error boundary catches an uncaught render
|
|
121
|
+
* error: the error itself, React's component stack (when the runtime gives
|
|
122
|
+
* one) and which subtree crashed.
|
|
123
|
+
*/
|
|
124
|
+
export interface ChatErrorInfo {
|
|
125
|
+
error: Error;
|
|
126
|
+
componentStack?: string;
|
|
127
|
+
scope: ChatErrorScope;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Render-prop form of `fallbackScreens.error`. `reset()` clears the boundary
|
|
131
|
+
* and re-mounts the chat subtree, so a host can build its own "try again".
|
|
132
|
+
*/
|
|
133
|
+
export type ChatErrorFallbackRenderer = (context: ChatErrorInfo & {
|
|
134
|
+
reset: () => void;
|
|
135
|
+
}) => React.ReactNode;
|
|
116
136
|
export interface IConfig {
|
|
117
137
|
appId?: string;
|
|
118
138
|
disableHeader?: boolean;
|
|
119
139
|
disableMedia?: boolean;
|
|
140
|
+
/** Composer attachment limits. Applies to the built-in SendInput. */
|
|
141
|
+
attachments?: {
|
|
142
|
+
/**
|
|
143
|
+
* How many files one message may carry. Defaults to 5 and is hard-capped
|
|
144
|
+
* at 10 by the stanza payload (MAX_ATTACHMENTS_PER_MESSAGE).
|
|
145
|
+
*/
|
|
146
|
+
maxFiles?: number;
|
|
147
|
+
/** Per-file ceiling in MB. Omit to skip the client-side size check. */
|
|
148
|
+
maxFileSizeMb?: number;
|
|
149
|
+
/** `accept` attribute handed to the file picker. Omit to allow anything. */
|
|
150
|
+
accept?: string;
|
|
151
|
+
};
|
|
152
|
+
/** First-page PDF thumbnails inside message bubbles. */
|
|
153
|
+
pdfPreview?: {
|
|
154
|
+
/** Set false to always show the static document card. Default true. */
|
|
155
|
+
enabled?: boolean;
|
|
156
|
+
/**
|
|
157
|
+
* URL of a pdf.js worker script. Omit and pdf.js runs on the main
|
|
158
|
+
* thread, which needs no bundler-specific asset wiring - fine for
|
|
159
|
+
* thumbnails, worth overriding if your users open large documents.
|
|
160
|
+
*/
|
|
161
|
+
workerSrc?: string;
|
|
162
|
+
/** Documents above this are not auto-rendered. Default 25. */
|
|
163
|
+
maxFileSizeMb?: number;
|
|
164
|
+
};
|
|
120
165
|
colors?: {
|
|
121
166
|
primary: string;
|
|
122
167
|
secondary: string;
|
|
@@ -156,6 +201,25 @@ export interface IConfig {
|
|
|
156
201
|
noConnection?: React.ReactNode;
|
|
157
202
|
/** Shown when the user has no chat room to display. */
|
|
158
203
|
noRoom?: React.ReactNode;
|
|
204
|
+
/**
|
|
205
|
+
* Shown when an uncaught render error inside the chat is caught by the
|
|
206
|
+
* SDK's error boundary (instead of white-screening the host app).
|
|
207
|
+
*
|
|
208
|
+
* Same shape as the screens above (string = centered text, React node =
|
|
209
|
+
* rendered as-is) plus a render-function form, which is what you want if
|
|
210
|
+
* the replacement screen needs its own retry control or wants to show
|
|
211
|
+
* something about the error:
|
|
212
|
+
*
|
|
213
|
+
* fallbackScreens: {
|
|
214
|
+
* error: ({ error, reset }) => (
|
|
215
|
+
* <MyErrorPanel message={error.message} onRetry={reset} />
|
|
216
|
+
* ),
|
|
217
|
+
* }
|
|
218
|
+
*
|
|
219
|
+
* Omit it to keep the built-in calm, themed, translated screen with its
|
|
220
|
+
* own "try again" button.
|
|
221
|
+
*/
|
|
222
|
+
error?: React.ReactNode | ChatErrorFallbackRenderer;
|
|
159
223
|
};
|
|
160
224
|
/**
|
|
161
225
|
* Hide specific rooms from the room list and unread counters without
|
|
@@ -192,13 +256,35 @@ export interface IConfig {
|
|
|
192
256
|
defaultLogin?: boolean;
|
|
193
257
|
disableInteractions?: boolean;
|
|
194
258
|
chatHeaderBurgerMenu?: boolean;
|
|
195
|
-
forceSetRoom?: boolean;
|
|
196
259
|
roomListStyles?: React.CSSProperties;
|
|
197
260
|
chatRoomStyles?: React.CSSProperties;
|
|
198
261
|
noMessagesPlaceholder?: React.ComponentType;
|
|
199
262
|
setRoomJidInPath?: boolean;
|
|
200
263
|
disableRoomMenu?: boolean;
|
|
264
|
+
/**
|
|
265
|
+
* Hide the "Mute/Unmute notifications" toggle from the chat header menu
|
|
266
|
+
* and the room profile drawer. The toggle is only ever offered when the
|
|
267
|
+
* backend has reported a `muted` boolean for the room in the first place
|
|
268
|
+
* (see IRoom.muted) - this flag is for a host that wants to hide it
|
|
269
|
+
* outright even then, e.g. because it renders its own mute control.
|
|
270
|
+
*/
|
|
271
|
+
disableRoomMute?: boolean;
|
|
201
272
|
defaultRooms?: ConfigRoom[];
|
|
273
|
+
/**
|
|
274
|
+
* The "Files" tab shown in the sidebar alongside "Chats". Backed by
|
|
275
|
+
* `GET /v2/files`, which not every backend has yet, so this defaults to
|
|
276
|
+
* an auto-detecting mode rather than always-on:
|
|
277
|
+
* - `enabled: true` always shows the tab - use this once you know your
|
|
278
|
+
* backend has /v2/files.
|
|
279
|
+
* - `enabled: false` always hides it.
|
|
280
|
+
* - omitted (default): the tab shows optimistically and only hides
|
|
281
|
+
* itself if the first files list request (when the user opens the tab)
|
|
282
|
+
* comes back 404/501, meaning this backend doesn't have the endpoint.
|
|
283
|
+
* No extra probe request is made just to decide this up front.
|
|
284
|
+
*/
|
|
285
|
+
filesTab?: {
|
|
286
|
+
enabled?: boolean;
|
|
287
|
+
};
|
|
202
288
|
refreshTokens?: {
|
|
203
289
|
enabled: boolean;
|
|
204
290
|
/**
|
|
@@ -226,15 +312,27 @@ export interface IConfig {
|
|
|
226
312
|
color?: string;
|
|
227
313
|
image?: string | File;
|
|
228
314
|
};
|
|
229
|
-
|
|
315
|
+
/**
|
|
316
|
+
* Host logo rendered at the left of the chat header, before the back
|
|
317
|
+
* button / burger menu. A plain string is treated as an image URL and
|
|
318
|
+
* rendered as an `<img>` (32px tall, aspect preserved); any other React
|
|
319
|
+
* element is rendered as-is. Same string-or-node duality as
|
|
320
|
+
* `fallbackScreens`. Omit to render no logo (the default).
|
|
321
|
+
*/
|
|
230
322
|
headerLogo?: string | React.ReactElement;
|
|
323
|
+
/**
|
|
324
|
+
* Takes over the room-list burger menu. When set, the built-in
|
|
325
|
+
* Profile/Settings/Logout dropdown is not rendered at all: the same burger
|
|
326
|
+
* button just calls this handler, so the host can open its own account
|
|
327
|
+
* menu or drawer.
|
|
328
|
+
*/
|
|
231
329
|
headerMenu?: () => void;
|
|
330
|
+
/**
|
|
331
|
+
* Same idea for the chat header's room menu (the "more" button carrying
|
|
332
|
+
* Report and Leave). When set, that dropdown is not rendered and the
|
|
333
|
+
* button calls this handler instead.
|
|
334
|
+
*/
|
|
232
335
|
headerChatMenu?: () => void;
|
|
233
|
-
customRooms?: {
|
|
234
|
-
rooms: PartialRoomWithMandatoryKeys[];
|
|
235
|
-
disableGetRooms?: boolean;
|
|
236
|
-
singleRoom: boolean;
|
|
237
|
-
};
|
|
238
336
|
translates?: {
|
|
239
337
|
enabled: boolean;
|
|
240
338
|
translations?: Iso639_1Codes;
|
|
@@ -243,11 +341,17 @@ export interface IConfig {
|
|
|
243
341
|
* "Translate" link the reader clicks (LinkedIn-style), then renders the
|
|
244
342
|
* result inline with a "Show original" toggle. Default 'auto'.
|
|
245
343
|
*
|
|
246
|
-
*
|
|
344
|
+
* 'auto' is purely a display choice: it only ever reads
|
|
247
345
|
* `message.translations`, whatever arrived attached to the stanza (see
|
|
248
|
-
* `readerLocale` below
|
|
249
|
-
*
|
|
250
|
-
*
|
|
346
|
+
* `readerLocale` below), and never calls a translation service itself.
|
|
347
|
+
* 'manual' shows exactly the same thing on click, via the same lookup -
|
|
348
|
+
* no host function and no `endpoint` means no network request, just the
|
|
349
|
+
* translation already attached (if any). 'manual' does one thing more:
|
|
350
|
+
* on a click, if nothing is attached and the host hasn't supplied
|
|
351
|
+
* `onTranslate`, it fetches a translation from `endpoint` ONLY when the
|
|
352
|
+
* host has set that explicitly (see below) and caches the result onto
|
|
353
|
+
* `message.translations` so a second click - and 'auto' mode, if the
|
|
354
|
+
* reader switches to it - see it for free.
|
|
251
355
|
*/
|
|
252
356
|
mode?: 'auto' | 'manual';
|
|
253
357
|
/**
|
|
@@ -294,8 +398,9 @@ export interface IConfig {
|
|
|
294
398
|
/**
|
|
295
399
|
* Host-provided translation function. When set, the manual Translate
|
|
296
400
|
* action calls this - wire it to your own service - instead of reading
|
|
297
|
-
* `message.translations
|
|
298
|
-
* arrived over XMPP
|
|
401
|
+
* `message.translations` or falling back to the built-in translate
|
|
402
|
+
* service. Optional; omit to use only what already arrived over XMPP
|
|
403
|
+
* (and, in manual mode, the fetch described on `endpoint` below).
|
|
299
404
|
*/
|
|
300
405
|
onTranslate?: (text: string, ctx: {
|
|
301
406
|
sourceLocale?: string;
|
|
@@ -305,9 +410,30 @@ export interface IConfig {
|
|
|
305
410
|
/**
|
|
306
411
|
* Host predicate deciding whether to show the Translate action for a given
|
|
307
412
|
* message. When omitted, the component compares base languages (message
|
|
308
|
-
* source vs reader, region ignored) and shows the action when they differ
|
|
413
|
+
* source vs reader, region ignored) and shows the action when they differ,
|
|
414
|
+
* AND only when something could actually answer the click (a translation
|
|
415
|
+
* is already attached, `onTranslate` is set, or `endpoint` is set below) -
|
|
416
|
+
* otherwise no Translate link is shown at all, rather than one that could
|
|
417
|
+
* only ever end in "Could not translate".
|
|
309
418
|
*/
|
|
310
419
|
showTranslateForMessage?: (message: IMessage) => boolean;
|
|
420
|
+
/**
|
|
421
|
+
* Explicit opt-in override for the built-in translate service's URL (e.g.
|
|
422
|
+
* "https://translate.api.example.com/translate"), used by manual mode's
|
|
423
|
+
* on-demand fetch (see `mode` above) when nothing is attached to the
|
|
424
|
+
* message and the host hasn't supplied `onTranslate`.
|
|
425
|
+
*
|
|
426
|
+
* This is strictly opt-in: the built-in HTTP call is never made unless
|
|
427
|
+
* this is set explicitly - there is no default derived from
|
|
428
|
+
* `config.baseUrl`. Leave it unset to rely only on `onTranslate` and
|
|
429
|
+
* whatever translation already arrived over XMPP. The call is made
|
|
430
|
+
* directly from the browser, so a self-hosted endpoint must send
|
|
431
|
+
* `Access-Control-Allow-Origin` for this origin or the fetch is blocked
|
|
432
|
+
* with no error shown beyond the "Could not translate" retry link; if you
|
|
433
|
+
* can't set that on the endpoint, use `onTranslate` and proxy the call
|
|
434
|
+
* through your own backend instead.
|
|
435
|
+
*/
|
|
436
|
+
endpoint?: string;
|
|
311
437
|
};
|
|
312
438
|
/**
|
|
313
439
|
* Static UI i18n (interface captions like "Search...", "Type message").
|
|
@@ -321,10 +447,20 @@ export interface IConfig {
|
|
|
321
447
|
locale?: string;
|
|
322
448
|
strings?: Record<string, string>;
|
|
323
449
|
};
|
|
450
|
+
/**
|
|
451
|
+
* Hide every control that mutates a room's configuration: the room avatar
|
|
452
|
+
* upload/remove overlay, the "Delete chat" entry in the chat-details menu,
|
|
453
|
+
* the add-members action and the per-member moderator menu (appoint as
|
|
454
|
+
* admin / remove member). Read-only room details stay visible.
|
|
455
|
+
*/
|
|
324
456
|
disableRoomConfig?: boolean;
|
|
325
457
|
disableProfilesInteractions?: boolean;
|
|
458
|
+
/**
|
|
459
|
+
* Hide the member-count subtitle in the chat header ("N users", plus the
|
|
460
|
+
* online-users popover that hangs off it). The 1:1 online/offline line is
|
|
461
|
+
* a presence state, not a count, so it is unaffected.
|
|
462
|
+
*/
|
|
326
463
|
disableUserCount?: boolean;
|
|
327
|
-
clearStoreBeforeInit?: boolean;
|
|
328
464
|
disableSentLogic?: boolean;
|
|
329
465
|
initBeforeLoad?: boolean;
|
|
330
466
|
initBeforeLoadAuth?: {
|
|
@@ -350,7 +486,6 @@ export interface IConfig {
|
|
|
350
486
|
enabled: boolean;
|
|
351
487
|
element: any;
|
|
352
488
|
};
|
|
353
|
-
botMessageAutoScroll?: boolean;
|
|
354
489
|
messageTextFilter?: {
|
|
355
490
|
enabled: boolean;
|
|
356
491
|
filterFunction: (text: string) => string;
|
|
@@ -375,6 +510,31 @@ export interface IConfig {
|
|
|
375
510
|
roomJID: string;
|
|
376
511
|
user: any;
|
|
377
512
|
}) => void;
|
|
513
|
+
/**
|
|
514
|
+
* Called after the user taps a button a bot attached to its message.
|
|
515
|
+
* The answer has ALREADY been sent into the room as an ordinary message
|
|
516
|
+
* by the time this fires - this is a notification, not an interception
|
|
517
|
+
* point, and a throw inside it is caught and logged.
|
|
518
|
+
*
|
|
519
|
+
* It exists so a host can drive a scripted flow (quiz, intake form,
|
|
520
|
+
* onboarding) on top of the same buttons a bot would send.
|
|
521
|
+
*/
|
|
522
|
+
onQuickReply?: (event: {
|
|
523
|
+
/** Id of the bot message that offered the buttons. */
|
|
524
|
+
messageId: string;
|
|
525
|
+
roomJID: string;
|
|
526
|
+
/** The button that was tapped. */
|
|
527
|
+
reply: QuickReply;
|
|
528
|
+
/** `reply.questionId`, or the button's index when the bot sent none. */
|
|
529
|
+
questionId: string;
|
|
530
|
+
}) => void | Promise<void>;
|
|
531
|
+
/**
|
|
532
|
+
* Called when the SDK's error boundary catches an uncaught render error,
|
|
533
|
+
* i.e. the crash that would otherwise have taken the host app down with
|
|
534
|
+
* it. Wire it to your own crash reporter (Sentry, Datadog, ...). A throw
|
|
535
|
+
* inside this handler is caught and logged, never rethrown.
|
|
536
|
+
*/
|
|
537
|
+
onError?: (event: ChatErrorInfo) => void;
|
|
378
538
|
};
|
|
379
539
|
disableTypingIndicator?: boolean;
|
|
380
540
|
blockMessageSendingWhenProcessing?: boolean | {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type ApiFile = {
|
|
2
|
+
_id: string;
|
|
3
|
+
userId: string;
|
|
4
|
+
ownerKey?: string;
|
|
5
|
+
roomName?: string;
|
|
6
|
+
location: string;
|
|
7
|
+
locationPreview?: string;
|
|
8
|
+
originalname: string;
|
|
9
|
+
filename?: string;
|
|
10
|
+
mimetype?: string;
|
|
11
|
+
size?: number;
|
|
12
|
+
expiresAt?: number;
|
|
13
|
+
isPrivate?: boolean;
|
|
14
|
+
duration?: string;
|
|
15
|
+
encrypted?: boolean;
|
|
16
|
+
key?: string;
|
|
17
|
+
iv?: string;
|
|
18
|
+
createdAt?: string;
|
|
19
|
+
updatedAt?: string;
|
|
20
|
+
};
|