@ethora/chat-component 26.9.8 → 26.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{ChatProfileModal-3UH0H5Ec.js → ChatProfileModal-Bf5jGPBZ.js} +44 -44
- package/dist/FilePreviewModal-Bwx0RZZw.js +1763 -0
- package/dist/{ManageDataModal-BblTuE9g.js → ManageDataModal-Dhkp0LWH.js} +17 -17
- package/dist/{MarkdownBody-RMEx8yW2.js → MarkdownBody-_sUhW2O8.js} +1 -1
- package/dist/{MessageSearchModal-CrYR2EH8.js → MessageSearchModal-rwwWrILl.js} +40 -40
- package/dist/{PublicChatsModal-Bi5r4mrV.js → PublicChatsModal-Byso6_vt.js} +19 -19
- package/dist/{SideDrawer-CDAoobvX.js → SideDrawer-CQPOf0ek.js} +35 -35
- package/dist/{UserProfileModal-4Frgvam-.js → UserProfileModal-Vj2kICvc.js} +10 -10
- package/dist/{UserSettingsModal-C-mb-9cb.js → UserSettingsModal-CioX4ZIV.js} +5 -5
- package/dist/{VideoCallOverlay-92dFLb9U.js → VideoCallOverlay-DodAkiam.js} +3824 -3708
- package/dist/{VisibilityModal-zIAV6dAP.js → VisibilityModal-CIl7rkBM.js} +11 -11
- package/dist/assets/icons.d.ts +2 -3
- package/dist/components/Files/fileCategory.d.ts +4 -2
- package/dist/components/MainComponents/AlbumGrid.d.ts +22 -0
- package/dist/components/MainComponents/AttachmentList.d.ts +6 -6
- package/dist/components/MainComponents/ImageUnavailable.d.ts +21 -0
- package/dist/components/MainComponents/MediaUploadOverlay.d.ts +31 -0
- package/dist/components/MainComponents/MessageContainer.d.ts +3 -0
- package/dist/components/MessageBubble/MediaCaption.d.ts +9 -0
- package/dist/components/MessageBubble/MessageAvatarPhoto.d.ts +17 -0
- package/dist/components/MessageBubble/MessageReaction.d.ts +6 -0
- package/dist/components/MessageBubble/QuickReplies.d.ts +2 -0
- package/dist/components/Modals/FilePreviewModal/FilePreviewModal.d.ts +8 -10
- package/dist/components/Modals/FilePreviewModal/ImageLightbox.d.ts +4 -0
- package/dist/components/Modals/FilePreviewModal/PdfView.d.ts +4 -0
- package/dist/components/Modals/FilePreviewModal/ViewerChrome.d.ts +64 -0
- package/dist/components/RoomComponents/LastMessageItem.d.ts +2 -0
- package/dist/components/RoomComponents/styled/LastMessageMedia.d.ts +19 -0
- package/dist/components/RoomComponents/styled/LastTextMessage.d.ts +2 -2
- package/dist/components/RoomComponents/styled/StyledRoomComponents.d.ts +10 -3
- package/dist/components/VideoCalls/VideoCallSession.d.ts +13 -0
- package/dist/components/styled/FileCard.d.ts +20 -0
- package/dist/components/styled/MediaSurface.d.ts +50 -0
- package/dist/components/styled/MessageImage.d.ts +9 -10
- package/dist/components/styled/SendInput.d.ts +12 -2
- package/dist/components/styled/StyledComponents.d.ts +69 -2
- package/dist/components/styled/StyledInputComponents/MediaComponents.d.ts +36 -24
- package/dist/components/styled/UnsupportedType.d.ts +1 -0
- package/dist/components/styled/VideoMessage.d.ts +11 -6
- package/dist/e2ee/callKey.d.ts +32 -0
- package/dist/e2ee/fileEnvelope.d.ts +16 -5
- package/dist/e2ee/omemo.d.ts +18 -0
- package/dist/firebase-messaging-sw.js +20 -3
- package/dist/{handleCopyClick-BtXos0AJ.js → handleCopyClick-DGaZhy_u.js} +1 -1
- package/dist/helpers/albumLayout.d.ts +53 -0
- package/dist/helpers/attachments.d.ts +22 -1
- package/dist/helpers/avatarImageCache.d.ts +9 -0
- package/dist/helpers/caption.d.ts +63 -0
- package/dist/helpers/composerFocus.d.ts +22 -0
- package/dist/helpers/createMainMessageForThread.d.ts +1 -1
- package/dist/helpers/downloadFile.d.ts +19 -0
- package/dist/helpers/fileKind.d.ts +17 -0
- package/dist/helpers/lastMessagePreview.d.ts +55 -0
- package/dist/helpers/mapWithConcurrency.d.ts +8 -0
- package/dist/helpers/mediaBox.d.ts +110 -0
- package/dist/helpers/mediaBubble.d.ts +39 -0
- package/dist/helpers/mediaLabel.d.ts +10 -0
- package/dist/helpers/mediaSendRetry.d.ts +25 -0
- package/dist/helpers/messageRuns.d.ts +10 -0
- package/dist/helpers/repairFilenameEncoding.d.ts +11 -0
- package/dist/helpers/roomImageGallery.d.ts +34 -0
- package/dist/helpers/safeUrl.d.ts +15 -0
- package/dist/helpers/secureFileUrl.d.ts +4 -1
- package/dist/helpers/viewerSender.d.ts +47 -0
- package/dist/hooks/useAvatarImage.d.ts +21 -0
- package/dist/hooks/useIsMobileViewport.d.ts +5 -0
- package/dist/hooks/useMediaProbe.d.ts +40 -0
- package/dist/hooks/usePaneWidthVar.d.ts +11 -0
- package/dist/hooks/usePdfThumbnail.d.ts +0 -1
- package/dist/hooks/usePrefersReducedMotion.d.ts +2 -0
- package/dist/hooks/useSendMessage.d.ts +4 -1
- package/dist/{main-BnLtessp.js → main-CUB_w8AZ.js} +17712 -14488
- package/dist/main.js +10 -10
- package/dist/networking/api-requests/auth.api.d.ts +2 -0
- package/dist/networking/callKeyStanza.d.ts +7 -0
- package/dist/networking/stanzaHandlers.d.ts +4 -2
- package/dist/networking/xmpp/sendDisplayedMarker.xmpp.d.ts +2 -0
- package/dist/networking/xmpp/sendMediaMessage.xmpp.d.ts +8 -0
- package/dist/networking/xmpp/sendReceivedReceipt.xmpp.d.ts +2 -0
- package/dist/networking/xmppClient.d.ts +5 -0
- package/dist/roomStore/callSlice.d.ts +6 -1
- package/dist/roomStore/index.d.ts +10 -0
- package/dist/roomStore/roomsSlice.d.ts +18 -3
- package/dist/styles/motion.d.ts +22 -2
- package/dist/types/models/attachment.model.d.ts +19 -0
- package/dist/types/models/config.model.d.ts +28 -2
- package/dist/types/models/customComponents.model.d.ts +2 -0
- package/dist/types/models/message.model.d.ts +9 -0
- package/dist/types/models/modal.model.d.ts +19 -0
- package/dist/types/models/room.model.d.ts +16 -0
- package/dist/types/models/xmpp.model.d.ts +3 -0
- package/dist/utils/messageNotificationContent.d.ts +34 -0
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/public/firebase-messaging-sw.js +20 -3
- package/dist/FilePreviewModal-Cgj1iHry.js +0 -743
- package/dist/components/RoomComponents/styled/LastAudioMessage.d.ts +0 -6
- package/dist/components/RoomComponents/styled/LastMessageFile.d.ts +0 -6
- package/dist/components/RoomComponents/styled/LastMessagePhoto.d.ts +0 -6
- package/dist/components/RoomComponents/styled/LastMessageVideo.d.ts +0 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs as r, jsx as s } from "react/jsx-runtime";
|
|
2
2
|
import { useState as b, useEffect as x } from "react";
|
|
3
|
-
import {
|
|
4
|
-
import { S as I, D as C, a as $, b as k, e as
|
|
3
|
+
import { E as o, a as L, x as P, u as R, aR as D, aS as z } from "./main-CUB_w8AZ.js";
|
|
4
|
+
import { S as I, D as C, a as $, b as k, e as S, f as p } from "./SideDrawer-CQPOf0ek.js";
|
|
5
5
|
o.div``;
|
|
6
6
|
o.div`
|
|
7
7
|
font-size: 16px;
|
|
@@ -13,7 +13,7 @@ o.p`
|
|
|
13
13
|
color: var(--ethora-color-text-muted, #6b7280);
|
|
14
14
|
margin-bottom: 32px;
|
|
15
15
|
`;
|
|
16
|
-
const
|
|
16
|
+
const w = o.div`
|
|
17
17
|
display: flex;
|
|
18
18
|
flex-direction: column;
|
|
19
19
|
gap: 6px;
|
|
@@ -25,7 +25,7 @@ const O = o.div`
|
|
|
25
25
|
`, u = o.input`
|
|
26
26
|
accent-color: ${({ $radioColor: i }) => i || "var(--ethora-color-primary, #0052CD)"};
|
|
27
27
|
margin: 0px;
|
|
28
|
-
`,
|
|
28
|
+
`, N = o.div`
|
|
29
29
|
padding: 10px 15px;
|
|
30
30
|
margin-top: 16px;
|
|
31
31
|
color: ${({ type: i }) => i === "success" ? "#10b981" : "#ef4444"};
|
|
@@ -39,12 +39,12 @@ const O = o.div`
|
|
|
39
39
|
background: ${({ type: i }) => i === "success" ? "rgba(16, 185, 129, 0.15)" : "rgba(242, 118, 107, 0.15)"};
|
|
40
40
|
border-color: ${({ type: i }) => i === "success" ? "var(--ethora-color-success, #10b981)" : "var(--ethora-color-danger, #ef4444)"};
|
|
41
41
|
}
|
|
42
|
-
`,
|
|
42
|
+
`, M = ({
|
|
43
43
|
handleCloseModal: i
|
|
44
44
|
}) => {
|
|
45
|
-
const
|
|
45
|
+
const O = L(), e = P(), { user: n, config: l } = R(
|
|
46
46
|
(t) => t.chatSettingStore
|
|
47
|
-
), g = (t) =>
|
|
47
|
+
), g = (t) => O(z(t)), [a, m] = b(n?.isProfileOpen), [c, v] = b(n?.isAssetsOpen), [f, y] = b(null), d = (t, A) => {
|
|
48
48
|
y({ message: t, type: A }), setTimeout(() => y(null), 3e3);
|
|
49
49
|
};
|
|
50
50
|
return x(() => {
|
|
@@ -64,7 +64,7 @@ const O = o.div`
|
|
|
64
64
|
children: [
|
|
65
65
|
/* @__PURE__ */ r(C, { children: [
|
|
66
66
|
/* @__PURE__ */ s($, { children: e("settings.visibility.profileLabel") }),
|
|
67
|
-
/* @__PURE__ */ s(k, { children: /* @__PURE__ */ s(
|
|
67
|
+
/* @__PURE__ */ s(k, { children: /* @__PURE__ */ s(S, { children: /* @__PURE__ */ r(w, { children: [
|
|
68
68
|
/* @__PURE__ */ r(h, { children: [
|
|
69
69
|
/* @__PURE__ */ s(
|
|
70
70
|
u,
|
|
@@ -97,7 +97,7 @@ const O = o.div`
|
|
|
97
97
|
] }),
|
|
98
98
|
/* @__PURE__ */ r(C, { children: [
|
|
99
99
|
/* @__PURE__ */ s($, { children: e("settings.visibility.documentsLabel") }),
|
|
100
|
-
/* @__PURE__ */ s(k, { children: /* @__PURE__ */ s(
|
|
100
|
+
/* @__PURE__ */ s(k, { children: /* @__PURE__ */ s(S, { children: /* @__PURE__ */ r(w, { children: [
|
|
101
101
|
/* @__PURE__ */ r(h, { children: [
|
|
102
102
|
/* @__PURE__ */ s(
|
|
103
103
|
u,
|
|
@@ -128,11 +128,11 @@ const O = o.div`
|
|
|
128
128
|
/* @__PURE__ */ s(p, { children: e("settings.visibility.individualDescription") })
|
|
129
129
|
] }) }) })
|
|
130
130
|
] }),
|
|
131
|
-
f && /* @__PURE__ */ s(
|
|
131
|
+
f && /* @__PURE__ */ s(N, { type: f.type, children: f.message })
|
|
132
132
|
]
|
|
133
133
|
}
|
|
134
134
|
);
|
|
135
135
|
};
|
|
136
136
|
export {
|
|
137
|
-
|
|
137
|
+
M as default
|
|
138
138
|
};
|
package/dist/assets/icons.d.ts
CHANGED
|
@@ -148,10 +148,9 @@ export declare const InSendingIcon: ({ fill, color, ...props }: {
|
|
|
148
148
|
fill?: string;
|
|
149
149
|
color?: string;
|
|
150
150
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
151
|
-
export declare const DoubleTick: ({
|
|
151
|
+
export declare const DoubleTick: ({ stroke, ...props }: {
|
|
152
152
|
[x: string]: any;
|
|
153
|
-
|
|
154
|
-
color?: string;
|
|
153
|
+
stroke?: string;
|
|
155
154
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
156
155
|
export declare const RedCross: ({ color, ...props }: {
|
|
157
156
|
[x: string]: any;
|
|
@@ -7,7 +7,9 @@ export type FileCategory = 'media' | 'documents' | 'audio';
|
|
|
7
7
|
* with thumbnails); audio/* gets its own chip; everything else falls back
|
|
8
8
|
* to "Documents".
|
|
9
9
|
*/
|
|
10
|
-
export declare function getFileCategory(mimetype?: string | null): FileCategory;
|
|
11
|
-
export declare function isPreviewable(file: Pick<ApiFile, 'mimetype'>
|
|
10
|
+
export declare function getFileCategory(mimetype?: string | null, name?: string | null): FileCategory;
|
|
11
|
+
export declare function isPreviewable(file: Pick<ApiFile, 'mimetype'> & {
|
|
12
|
+
originalname?: string;
|
|
13
|
+
}): boolean;
|
|
12
14
|
/** Human-readable byte size, e.g. formatBytes(1536) -> "1.5 KB". */
|
|
13
15
|
export declare function formatBytes(bytes?: number | null): string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { IAttachment, ModalFile } from '../../types/types';
|
|
3
|
+
export interface AlbumGridItem {
|
|
4
|
+
attachment: IAttachment;
|
|
5
|
+
/** Position in the message's `attachments`, used for retry. */
|
|
6
|
+
index: number;
|
|
7
|
+
}
|
|
8
|
+
interface AlbumGridProps {
|
|
9
|
+
items: AlbumGridItem[];
|
|
10
|
+
/** Called with the failed tile's index when the user asks to retry it. */
|
|
11
|
+
onRetry?: (index: number) => void;
|
|
12
|
+
/** Who posted the album and when, handed to the viewer header. */
|
|
13
|
+
sender?: ModalFile['sender'];
|
|
14
|
+
date?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Photo/video album for a message with several media files. Layout comes
|
|
18
|
+
* from getAlbumLayout; a tile tap opens that file in the preview modal, and
|
|
19
|
+
* a tile still in flight or failed shows its state over the thumbnail.
|
|
20
|
+
*/
|
|
21
|
+
declare const AlbumGrid: React.FC<AlbumGridProps>;
|
|
22
|
+
export default AlbumGrid;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
import { IAttachment } from '../../types/types';
|
|
2
|
+
import { IAttachment, ModalFile } from '../../types/types';
|
|
3
3
|
interface AttachmentListProps {
|
|
4
4
|
attachments: IAttachment[];
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
/** Re-sends the file at this index of `attachments` after a failed upload. */
|
|
6
|
+
onRetryAttachment?: (index: number) => void;
|
|
7
|
+
/** Who posted the message and when; the viewer header shows both. */
|
|
8
|
+
sender?: ModalFile['sender'];
|
|
9
|
+
date?: string;
|
|
10
10
|
}
|
|
11
11
|
declare const AttachmentList: React.FC<AttachmentListProps>;
|
|
12
12
|
export default AttachmentList;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface ImageUnavailableArtProps {
|
|
3
|
+
/** Rendered width and height in CSS pixels. The viewBox scales crisply. */
|
|
4
|
+
size?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare const ImageUnavailableArt: React.FC<ImageUnavailableArtProps>;
|
|
7
|
+
export interface ImageUnavailableStateProps {
|
|
8
|
+
/**
|
|
9
|
+
* Compact: the glyph only, about 28px, for album grid tiles. Full: the
|
|
10
|
+
* illustration, the caption and a hint, for a solo bubble or the viewer.
|
|
11
|
+
*/
|
|
12
|
+
compact?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Shows a "Try again" action. The picture sits inside the bubble's open
|
|
15
|
+
* button, so the action is a span with button semantics, not a <button>.
|
|
16
|
+
*/
|
|
17
|
+
onRetry?: () => void;
|
|
18
|
+
}
|
|
19
|
+
/** Self-contained "could not load" state that fills its positioned parent. */
|
|
20
|
+
export declare const ImageUnavailableState: React.FC<ImageUnavailableStateProps>;
|
|
21
|
+
export default ImageUnavailableState;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
/** How long the scrim takes to fade once the upload is done. */
|
|
3
|
+
export declare const SCRIM_FADE_MS = 180;
|
|
4
|
+
/** The circular-arrow retry mark, shared by the failed tile and the "+N" badge. */
|
|
5
|
+
export declare const RetryIcon: React.FC<{
|
|
6
|
+
size?: number;
|
|
7
|
+
}>;
|
|
8
|
+
/**
|
|
9
|
+
* Thin circular progress ring. The SVG is a fixed 40px square with a
|
|
10
|
+
* viewBox, so it can never stretch; the arc is drawn by moving the dash
|
|
11
|
+
* offset from the full circumference (empty) down to zero (complete).
|
|
12
|
+
*/
|
|
13
|
+
export declare const ProgressRing: React.FC<{
|
|
14
|
+
percent: number;
|
|
15
|
+
children?: React.ReactNode;
|
|
16
|
+
}>;
|
|
17
|
+
interface MediaUploadOverlayProps {
|
|
18
|
+
/** `uploading` covers "waiting for the siblings" too; `failed` is a retry prompt. */
|
|
19
|
+
status: 'uploading' | 'failed';
|
|
20
|
+
progress?: number;
|
|
21
|
+
/** Upload is done: fade the scrim out instead of leaving it up. */
|
|
22
|
+
leaving?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* State layer over an outgoing attachment: a frosted scrim with a progress
|
|
26
|
+
* ring while it goes up, and a tinted scrim with a retry glyph once it has
|
|
27
|
+
* failed. The parent owns the click, so this stays pointer-transparent and
|
|
28
|
+
* can sit inside a button without nesting interactive elements.
|
|
29
|
+
*/
|
|
30
|
+
export declare const MediaUploadOverlay: React.FC<MediaUploadOverlayProps>;
|
|
31
|
+
export default MediaUploadOverlay;
|
|
@@ -6,6 +6,7 @@ interface MessageContainerProps {
|
|
|
6
6
|
isUser: boolean;
|
|
7
7
|
$isUser?: boolean;
|
|
8
8
|
isReply: boolean;
|
|
9
|
+
isLastInGroup?: boolean;
|
|
9
10
|
}>;
|
|
10
11
|
message: IMessage;
|
|
11
12
|
activeMessage: IMessage;
|
|
@@ -13,6 +14,8 @@ interface MessageContainerProps {
|
|
|
13
14
|
xmppUsername: string;
|
|
14
15
|
isReply: boolean;
|
|
15
16
|
showDateLabel: boolean;
|
|
17
|
+
/** False when the next row is the same sender's message (a run continues). */
|
|
18
|
+
isLastInGroup?: boolean;
|
|
16
19
|
className?: string;
|
|
17
20
|
}
|
|
18
21
|
export declare const MessageContainer: React.NamedExoticComponent<MessageContainerProps>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { MentionClickHandler } from '../../helpers/parseMessageBody';
|
|
3
|
+
interface MediaCaptionProps {
|
|
4
|
+
/** The message: its caption, or the text a legacy sender put in `body`. */
|
|
5
|
+
message: object;
|
|
6
|
+
onMentionClick?: MentionClickHandler;
|
|
7
|
+
}
|
|
8
|
+
declare const MediaCaption: React.FC<MediaCaptionProps>;
|
|
9
|
+
export default MediaCaption;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { default as React, CSSProperties } from 'react';
|
|
2
|
+
interface MessageAvatarPhotoProps {
|
|
3
|
+
/** Sender photo URL; empty renders the initials circle alone. */
|
|
4
|
+
src?: string | null;
|
|
5
|
+
/** Display name, used for the initials. */
|
|
6
|
+
username?: string;
|
|
7
|
+
style?: CSSProperties;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Sender avatar in a message bubble. The initials circle is always rendered
|
|
11
|
+
* (no layout shift, nothing waits on the network); the photo is layered over
|
|
12
|
+
* it and faded in once it has loaded. A photo that fails to load leaves the
|
|
13
|
+
* initials, where the old bare <img> showed a broken-image glyph. A sender
|
|
14
|
+
* with many bubbles shares one load through useAvatarImage's cache.
|
|
15
|
+
*/
|
|
16
|
+
export declare const MessageAvatarPhoto: React.FC<MessageAvatarPhotoProps>;
|
|
17
|
+
export {};
|
|
@@ -5,6 +5,12 @@ interface MessageReactionProps {
|
|
|
5
5
|
reaction: Record<string, ReactionMessage>;
|
|
6
6
|
changeReaction: (reaction: string) => void;
|
|
7
7
|
userName?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Reports how far the chip rows hang below the bubble's bottom edge, in px,
|
|
10
|
+
* whenever their rendered height changes (one row hangs REACTION_HANG_PX).
|
|
11
|
+
* The message row uses it to reserve room for every wrapped row.
|
|
12
|
+
*/
|
|
13
|
+
onHangChange?: (hangPx: number) => void;
|
|
8
14
|
}
|
|
9
15
|
export declare const MessageReaction: FC<MessageReactionProps>;
|
|
10
16
|
export {};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { QuickReply } from '../../helpers/quickReplies';
|
|
3
|
+
import { ChatColorScheme } from '../../types/types';
|
|
3
4
|
interface QuickRepliesProps {
|
|
4
5
|
replies: QuickReply[];
|
|
5
6
|
messageId: string;
|
|
6
7
|
accentColor?: string;
|
|
8
|
+
colorScheme?: ChatColorScheme;
|
|
7
9
|
/** Already answered - the chips are gone for good. */
|
|
8
10
|
answered?: boolean;
|
|
9
11
|
onSelect: (reply: QuickReply, questionId: string) => void;
|
|
@@ -7,17 +7,15 @@ interface FilePreviewModalProps {
|
|
|
7
7
|
*
|
|
8
8
|
* Images get a real lightbox: previous/next across every image loaded for
|
|
9
9
|
* the room (see helpers/roomImageGallery for exactly what that set is),
|
|
10
|
-
* wheel/pinch zoom with bounded panning, double-click
|
|
11
|
-
* fit, arrow
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* a thumbnail strip, wheel/pinch zoom with bounded panning, double-click or
|
|
11
|
+
* double-tap to toggle fit, arrow and swipe navigation, and a blurred
|
|
12
|
+
* low-resolution stand-in while the full picture loads. Video, audio, PDF and
|
|
13
|
+
* other files each get their own view; none of them get gallery chrome.
|
|
14
14
|
*
|
|
15
|
-
* Escape
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* so the only key listener below is for the arrows, and it explicitly leaves
|
|
20
|
-
* every other key (Escape included) alone.
|
|
15
|
+
* Escape and initial focus are handled by useModalDismiss at the modal layer
|
|
16
|
+
* (Modals/Modal/ModalContent.tsx), which also restores focus to the opener on
|
|
17
|
+
* close. This component adds the Tab trap and the arrow and zoom keys, and it
|
|
18
|
+
* leaves Escape alone so the key is not handled twice.
|
|
21
19
|
*/
|
|
22
20
|
declare const FilePreviewModal: React.FC<FilePreviewModalProps>;
|
|
23
21
|
export default FilePreviewModal;
|
|
@@ -11,6 +11,10 @@ export interface ImageLightboxHandle {
|
|
|
11
11
|
interface ImageLightboxProps {
|
|
12
12
|
src: string;
|
|
13
13
|
alt: string;
|
|
14
|
+
/** Low-res stand-in painted blurred until `src` has loaded. */
|
|
15
|
+
previewSrc?: string;
|
|
16
|
+
/** Visually hidden label for the loading spinner (screen readers). */
|
|
17
|
+
loadingLabel?: string;
|
|
14
18
|
/** Swipe (touch) navigation; also used to report gesture direction. */
|
|
15
19
|
onSwipeLeft?: () => void;
|
|
16
20
|
onSwipeRight?: () => void;
|
|
@@ -10,6 +10,10 @@ interface PdfViewerProps {
|
|
|
10
10
|
* opened was handed to a third-party host - and broke outright whenever that
|
|
11
11
|
* page changed or was unreachable. Rendering locally keeps the file URL
|
|
12
12
|
* inside the app and works offline-ish (the PDF itself still has to load).
|
|
13
|
+
*
|
|
14
|
+
* All pages stack in one scroll container. Every page has a placeholder sized
|
|
15
|
+
* from its real aspect, but only the few near the viewport render a canvas,
|
|
16
|
+
* so a 200-page document costs about as much as a 7-page one.
|
|
13
17
|
*/
|
|
14
18
|
declare const PdfViewer: React.FC<PdfViewerProps>;
|
|
15
19
|
export default PdfViewer;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export declare const VIEWER_TEXT = "#f5f7fa";
|
|
3
|
+
export declare const VIEWER_MUTED = "rgba(245, 247, 250, 0.68)";
|
|
4
|
+
export declare const VIEWER_SURFACE = "rgba(255, 255, 255, 0.08)";
|
|
5
|
+
export declare const VIEWER_SURFACE_HOVER = "rgba(255, 255, 255, 0.18)";
|
|
6
|
+
export declare const ViewerSurface: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
7
|
+
$closing: boolean;
|
|
8
|
+
}>> & string;
|
|
9
|
+
export declare const TopBar: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, never>> & string;
|
|
10
|
+
export declare const TopIdentity: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
11
|
+
export declare const SenderText: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
12
|
+
export declare const SenderName: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
|
|
13
|
+
export declare const SubLine: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
|
|
14
|
+
export declare const ActionGroup: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
15
|
+
export declare const IconButton: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
|
|
16
|
+
export declare const Stage: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
17
|
+
export declare const MediaFrame: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
18
|
+
$fit: "media" | "content";
|
|
19
|
+
}>> & string;
|
|
20
|
+
export declare const NavButton: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, {
|
|
21
|
+
$side: "left" | "right";
|
|
22
|
+
}>> & string;
|
|
23
|
+
export declare const BottomBar: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
24
|
+
export declare const ThumbStrip: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
25
|
+
export declare const Thumb: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, {
|
|
26
|
+
$active: boolean;
|
|
27
|
+
}>> & string;
|
|
28
|
+
export declare const ThumbImage: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, never>> & string;
|
|
29
|
+
/** Small play triangle over a video's thumbnail. */
|
|
30
|
+
export declare const ThumbPlayBadge: () => import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
/** Stand-in thumbnail for a video that has no poster image. */
|
|
32
|
+
export declare const ThumbVideoGlyph: () => import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export declare const ControlRow: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
34
|
+
export declare const Counter: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
|
|
35
|
+
export declare const ZoomGroup: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
36
|
+
interface ErrorPanelProps {
|
|
37
|
+
onRetry: () => void;
|
|
38
|
+
onDownload: () => void;
|
|
39
|
+
}
|
|
40
|
+
/** Shown in place of an image that cannot be loaded. No remote fallback image. */
|
|
41
|
+
export declare const ErrorPanel: React.FC<ErrorPanelProps>;
|
|
42
|
+
interface FileCardProps {
|
|
43
|
+
fileName: string;
|
|
44
|
+
unsupportedText: string;
|
|
45
|
+
onDownload: () => void;
|
|
46
|
+
}
|
|
47
|
+
/** Large card for files the viewer cannot render (anything but image/video/audio/PDF). */
|
|
48
|
+
export declare const FileCard: React.FC<FileCardProps>;
|
|
49
|
+
interface AudioCardProps {
|
|
50
|
+
fileName: string;
|
|
51
|
+
src: string;
|
|
52
|
+
}
|
|
53
|
+
/** Audio gets a native player inside a card, so it reads as a clip, not a broken image. */
|
|
54
|
+
export declare const AudioCard: React.FC<AudioCardProps>;
|
|
55
|
+
export declare const ExternalLinkGlyph: () => import("react/jsx-runtime").JSX.Element;
|
|
56
|
+
export declare const RetryGlyph: () => import("react/jsx-runtime").JSX.Element;
|
|
57
|
+
export declare const DownloadGlyph: () => import("react/jsx-runtime").JSX.Element;
|
|
58
|
+
export declare const FileGlyph: () => import("react/jsx-runtime").JSX.Element;
|
|
59
|
+
export declare const AudioGlyph: () => import("react/jsx-runtime").JSX.Element;
|
|
60
|
+
/** Format a message timestamp for the viewer header; empty when unknown. */
|
|
61
|
+
export declare const formatViewerDate: (iso?: string) => string;
|
|
62
|
+
/** Returns the URL with a retry marker, so a retry is not served from the failed cache entry. */
|
|
63
|
+
export declare const withRetryMarker: (url: string, attempt: number) => string;
|
|
64
|
+
export {};
|
|
@@ -2,6 +2,8 @@ import { FC } from 'react';
|
|
|
2
2
|
import { LastMessage } from '../../types/types';
|
|
3
3
|
interface LastMessageItemProps {
|
|
4
4
|
lastMessage: LastMessage;
|
|
5
|
+
/** The room is end-to-end encrypted: media shows an icon and label only. */
|
|
6
|
+
sealed?: boolean;
|
|
5
7
|
}
|
|
6
8
|
declare const LastMessageItem: FC<LastMessageItemProps>;
|
|
7
9
|
export default LastMessageItem;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { MediaPreview } from '../../../helpers/lastMessagePreview';
|
|
3
|
+
/** Edge of the thumbnail tile, and so the height of a thumbnail row. */
|
|
4
|
+
export declare const MEDIA_THUMB_PX = 18;
|
|
5
|
+
interface LastMessageMediaProps {
|
|
6
|
+
preview: MediaPreview;
|
|
7
|
+
/** Sender line, already resolved by ChatRoomItem; empty omits it. */
|
|
8
|
+
name?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Room-list preview for a media last message: a thumbnail (images, videos
|
|
12
|
+
* with a poster) or an inline icon, then a localized label. Thumbnails come
|
|
13
|
+
* from the message's own preview URL only, with the viewer's file token
|
|
14
|
+
* appended; a thumbnail that fails (a secure URL that 404s, an expired
|
|
15
|
+
* token) drops to the icon instead of a broken image, and nothing is ever
|
|
16
|
+
* fetched from a placeholder host.
|
|
17
|
+
*/
|
|
18
|
+
declare const LastMessageMedia: FC<LastMessageMediaProps>;
|
|
19
|
+
export default LastMessageMedia;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
2
|
import { LastMessage } from '../../../types/types';
|
|
3
|
-
interface
|
|
3
|
+
interface LastTextMessageProps extends Pick<LastMessage, 'user' | 'body'> {
|
|
4
4
|
}
|
|
5
|
-
declare const LastTextMessage: FC<
|
|
5
|
+
declare const LastTextMessage: FC<LastTextMessageProps>;
|
|
6
6
|
export default LastTextMessage;
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
+
export declare const PREVIEW_NAME_PX = 16;
|
|
3
|
+
export declare const PREVIEW_LINE_PX = 18;
|
|
4
|
+
export declare const PREVIEW_BLOCK_MIN_PX: number;
|
|
2
5
|
export declare const LastRoomMessageContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
3
|
-
export declare const LastRoomMessageName: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<
|
|
6
|
+
export declare const LastRoomMessageName: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
4
7
|
export declare const LastRoomMessageText: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
|
|
5
|
-
/**
|
|
6
|
-
export declare const
|
|
8
|
+
/** Line 2 when it carries an icon or thumbnail next to its label. */
|
|
9
|
+
export declare const LastRoomMessageLine: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
10
|
+
/** Thumbnail/icon + label for a media preview, on the message line. */
|
|
11
|
+
export declare const LastRoomMessageMedia: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<Omit<import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>, "ref"> & {
|
|
12
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
13
|
+
}, never>> & string;
|
|
7
14
|
export declare const NewMessageMarker: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
8
15
|
export declare const LastMessageImg: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, never>> & string;
|
|
9
16
|
export declare const ShadeWrapper: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
@@ -20,6 +20,19 @@ interface VideoCallSessionProps {
|
|
|
20
20
|
onConnected?: () => void;
|
|
21
21
|
onError?: (message: string) => void;
|
|
22
22
|
onHangup: () => void;
|
|
23
|
+
/** Request end-to-end encryption of the media for this call. */
|
|
24
|
+
e2ee?: boolean;
|
|
25
|
+
/** The shared media key (base64), delivered over OMEMO. May arrive late. */
|
|
26
|
+
e2eeKey?: string | null;
|
|
27
|
+
/** Host-supplied factory for the LiveKit E2EE worker (see VideoCallsConfig). */
|
|
28
|
+
e2eeWorkerFactory?: () => Worker;
|
|
29
|
+
/**
|
|
30
|
+
* A remote participant just joined the LiveKit room. The key owner uses this
|
|
31
|
+
* to re-send the E2EE media key over OMEMO: the newcomer is online now, so a
|
|
32
|
+
* peer who missed the ephemeral key at call start (e.g. woken by push) still
|
|
33
|
+
* receives it. See VideoCallOverlay.
|
|
34
|
+
*/
|
|
35
|
+
onParticipantJoined?: () => void;
|
|
23
36
|
}
|
|
24
37
|
export declare const VideoCallSession: React.FC<VideoCallSessionProps>;
|
|
25
38
|
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface FileCardProps {
|
|
3
|
+
/** Full file name; the card truncates it with an ellipsis. */
|
|
4
|
+
name: string;
|
|
5
|
+
/** Short parts shown under the name, joined with a middle dot. */
|
|
6
|
+
meta: Array<string | undefined>;
|
|
7
|
+
icon: React.ReactNode;
|
|
8
|
+
tone?: 'pdf' | 'neutral';
|
|
9
|
+
compact?: boolean;
|
|
10
|
+
onOpen: () => void;
|
|
11
|
+
title?: string;
|
|
12
|
+
'aria-label'?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A file that is not an image or video: a tile with the type glyph, the name
|
|
16
|
+
* with an ellipsis, a small meta line and a download affordance. One click
|
|
17
|
+
* opens the file in the preview modal.
|
|
18
|
+
*/
|
|
19
|
+
declare const FileCard: React.ForwardRefExoticComponent<FileCardProps & React.RefAttributes<HTMLButtonElement>>;
|
|
20
|
+
export default FileCard;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
/** Frosted circle with a play triangle, centred on a video. */
|
|
3
|
+
export declare const PlayBadge: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
|
|
4
|
+
export declare const DurationChip: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
|
|
5
|
+
/** Small "GIF" pill, bottom-left, on an animated picture. */
|
|
6
|
+
export declare const GifChip: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
|
|
7
|
+
export interface MediaSurfaceProps {
|
|
8
|
+
kind: 'image' | 'video';
|
|
9
|
+
/** Full-resolution URL. Empty while an outgoing upload has no URL yet. */
|
|
10
|
+
src: string;
|
|
11
|
+
/** Low-resolution preview, shown blurred until `src` has loaded. */
|
|
12
|
+
previewSrc?: string;
|
|
13
|
+
alt: string;
|
|
14
|
+
/** `fill` covers its positioned parent (album tile); `solo` sizes itself. */
|
|
15
|
+
variant: 'fill' | 'solo';
|
|
16
|
+
/** Natural size recorded on the attachment, when the storage kept it. */
|
|
17
|
+
dims?: {
|
|
18
|
+
width?: unknown;
|
|
19
|
+
height?: unknown;
|
|
20
|
+
};
|
|
21
|
+
/** Duration in seconds, shown as a chip on videos. */
|
|
22
|
+
duration?: string;
|
|
23
|
+
/** Outgoing upload: shimmer while the URL is pending. */
|
|
24
|
+
pending?: boolean;
|
|
25
|
+
/** CSS border-radius for the stage (per corner for album tiles). */
|
|
26
|
+
radius?: string;
|
|
27
|
+
/** Solo only: opens the preview. Omit for tiles, which own the click. */
|
|
28
|
+
onOpen?: () => void;
|
|
29
|
+
/** The opener exists but cannot act yet (no file URL): keeps the element tree stable. */
|
|
30
|
+
openDisabled?: boolean;
|
|
31
|
+
/** Clickable item: zoom cursor and hover zoom. Defaults to `Boolean(onOpen)`. */
|
|
32
|
+
interactive?: boolean;
|
|
33
|
+
/** Blur and dim the picture, used behind the "+N" count. */
|
|
34
|
+
blurred?: boolean;
|
|
35
|
+
/** MIME type of the file; `image/gif` makes the picture animate in place. */
|
|
36
|
+
mimetype?: string;
|
|
37
|
+
/** Show the play badge and duration chip on videos. Defaults to true. */
|
|
38
|
+
chrome?: boolean;
|
|
39
|
+
/** Sender's own picture (blob URL): shown sharp and at once, ahead of `src`. */
|
|
40
|
+
localSrc?: string;
|
|
41
|
+
/** 0 to 100 download progress of `src`, when known; otherwise a quiet sweep. */
|
|
42
|
+
loadProgress?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The in-bubble picture of one media file: a shimmer while it loads, the
|
|
46
|
+
* preview blurred until the full file is decoded, a 180ms fade to the real
|
|
47
|
+
* image, and a self-contained unavailable state when it cannot be shown.
|
|
48
|
+
*/
|
|
49
|
+
declare const MediaSurface: React.FC<MediaSurfaceProps>;
|
|
50
|
+
export default MediaSurface;
|
|
@@ -4,16 +4,15 @@ interface CustomMessageImageProps {
|
|
|
4
4
|
fileName: string;
|
|
5
5
|
mimetype: string;
|
|
6
6
|
locationPreview?: string;
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* FilesPanel.tsx's handleDelete) - the caller uses this to flip the
|
|
13
|
-
* message to the normal "deleted" placeholder instead of leaving this
|
|
14
|
-
* broken-image card on screen.
|
|
15
|
-
*/
|
|
16
|
-
onUnavailable?: () => void;
|
|
7
|
+
/** Natural size from the attachment, when the storage kept it. */
|
|
8
|
+
width?: number;
|
|
9
|
+
height?: number;
|
|
10
|
+
/** Sender's own blob URL, shown at once while the server copy loads. */
|
|
11
|
+
localUrl?: string;
|
|
17
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* A single picture in a bubble: its natural aspect ratio, sized to the
|
|
15
|
+
* pane's shared media width. A click opens the preview modal at this file.
|
|
16
|
+
*/
|
|
18
17
|
declare const CustomMessageImage: React.FC<CustomMessageImageProps>;
|
|
19
18
|
export default CustomMessageImage;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { IConfig, IMentionSpan } from '../../types/types';
|
|
3
|
+
import { CaptionInput } from '../../helpers/caption';
|
|
3
4
|
export interface SendInputProps {
|
|
4
5
|
sendMessage: (message: string, mentions?: IMentionSpan[]) => void | Promise<void>;
|
|
5
6
|
/**
|
|
6
7
|
* Receives a `File[]` for picked attachments (one message, N files) and a
|
|
7
8
|
* `Blob` for voice notes. Single files still arrive as a one-element array.
|
|
9
|
+
* Text typed with the files arrives as `caption` and is sent inside that
|
|
10
|
+
* same media message, so it can never land as a separate bubble.
|
|
8
11
|
*/
|
|
9
|
-
sendMedia: (data: File[] | File | Blob, type: string) => void | Promise<void>;
|
|
12
|
+
sendMedia: (data: File[] | File | Blob, type: string, caption?: CaptionInput) => void | boolean | Promise<void | boolean>;
|
|
10
13
|
isLoading: boolean;
|
|
11
14
|
editMessage?: string;
|
|
12
15
|
config?: IConfig;
|
|
@@ -19,7 +22,7 @@ export interface SendInputProps {
|
|
|
19
22
|
showPreview?: boolean;
|
|
20
23
|
previewParser?: (text: string) => (string | JSX.Element)[];
|
|
21
24
|
onSendMessage?: (message: string, mentions?: IMentionSpan[]) => void | Promise<void>;
|
|
22
|
-
onSendMedia?: (data: File[] | File | Blob, type: string) => void | Promise<void>;
|
|
25
|
+
onSendMedia?: (data: File[] | File | Blob, type: string, caption?: CaptionInput) => void | boolean | Promise<void | boolean>;
|
|
23
26
|
placeholderText?: string;
|
|
24
27
|
/** Disables the @-mention autocomplete (e.g. for a composer variant that
|
|
25
28
|
* doesn't want it). Defaults to enabled. */
|
|
@@ -31,6 +34,13 @@ export interface SendInputProps {
|
|
|
31
34
|
* live composers would otherwise overwrite each other's text.
|
|
32
35
|
*/
|
|
33
36
|
disableDrafts?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Take focus whenever the room list hands the composer a chat switch (a
|
|
39
|
+
* click on a room row, even one that is already open). Set on the main
|
|
40
|
+
* composer only: a second composer on the same screen must not steal focus.
|
|
41
|
+
* Mobile never requests it, so the keyboard does not pop up uninvited.
|
|
42
|
+
*/
|
|
43
|
+
focusOnRoomSwitch?: boolean;
|
|
34
44
|
}
|
|
35
45
|
declare const SendInput: React.FC<SendInputProps>;
|
|
36
46
|
export default SendInput;
|