@ermis-network/ermis-chat-react 1.0.9 → 2.0.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 +144 -0
- package/dist/index.cjs +8320 -3427
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1277 -291
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +1131 -99
- package/dist/index.d.ts +1131 -99
- package/dist/index.mjs +8168 -3319
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -4
- package/src/channelTypeUtils.ts +1 -1
- package/src/components/Avatar.tsx +2 -1
- package/src/components/Channel.tsx +6 -5
- package/src/components/ChannelActions.tsx +67 -3
- package/src/components/ChannelHeader.tsx +27 -37
- package/src/components/ChannelInfo/AddMemberModal.tsx +12 -2
- package/src/components/ChannelInfo/ChannelInfo.tsx +410 -187
- package/src/components/ChannelInfo/ChannelInfoTabs.tsx +59 -297
- package/src/components/ChannelInfo/ChannelSettingsPanel.tsx +30 -174
- package/src/components/ChannelInfo/EditChannelModal.tsx +6 -3
- package/src/components/ChannelInfo/MediaGridItem.tsx +215 -68
- package/src/components/ChannelInfo/MemberListItem.tsx +2 -3
- package/src/components/ChannelInfo/MessageSearchPanel.tsx +27 -126
- package/src/components/ChannelInfo/States.tsx +1 -1
- package/src/components/ChannelInfo/index.ts +3 -0
- package/src/components/ChannelInfo/useChannelInfoTabs.tsx +427 -0
- package/src/components/ChannelInfo/useChannelSettings.ts +212 -0
- package/src/components/ChannelInfo/useMessageSearch.tsx +141 -0
- package/src/components/ChannelList.tsx +247 -301
- package/src/components/CreateChannelModal.tsx +290 -93
- package/src/components/Dropdown.tsx +1 -16
- package/src/components/EditPreview.tsx +1 -0
- package/src/components/ErmisCallProvider.tsx +72 -17
- package/src/components/ErmisCallUI.tsx +43 -20
- package/src/components/FilesPreview.tsx +8 -12
- package/src/components/FlatTopicGroupItem.tsx +243 -0
- package/src/components/ForwardMessageModal.tsx +43 -81
- package/src/components/MediaLightbox.tsx +454 -292
- package/src/components/MentionSuggestions.tsx +47 -35
- package/src/components/MessageActionsBox.tsx +6 -1
- package/src/components/MessageInput.tsx +165 -17
- package/src/components/MessageInputDefaults.tsx +127 -1
- package/src/components/MessageItem.tsx +155 -43
- package/src/components/MessageQuickReactions.tsx +153 -23
- package/src/components/MessageReactions.tsx +49 -3
- package/src/components/MessageRenderers.tsx +1114 -445
- package/src/components/Panel.tsx +1 -14
- package/src/components/PinnedMessages.tsx +55 -15
- package/src/components/PreviewOverlay.tsx +24 -0
- package/src/components/QuotedMessagePreview.tsx +99 -8
- package/src/components/ReadReceipts.tsx +2 -1
- package/src/components/RecoveryPin/RecoveryPin.tsx +279 -0
- package/src/components/RecoveryPin/index.ts +19 -0
- package/src/components/TopicList.tsx +236 -0
- package/src/components/TopicModal.tsx +4 -1
- package/src/components/TypingIndicator.tsx +17 -8
- package/src/components/UserPicker.tsx +94 -16
- package/src/components/VirtualMessageList.tsx +419 -113
- package/src/context/ChatComponentsContext.tsx +14 -0
- package/src/context/ChatProvider.tsx +44 -14
- package/src/context/ErmisCallContext.tsx +4 -0
- package/src/hooks/useChannelCapabilities.ts +7 -4
- package/src/hooks/useChannelData.ts +10 -3
- package/src/hooks/useChannelListUpdates.ts +94 -21
- package/src/hooks/useChannelMessages.ts +391 -42
- package/src/hooks/useChannelRowUpdates.ts +36 -5
- package/src/hooks/useChatUser.ts +39 -0
- package/src/hooks/useContactChannels.ts +45 -0
- package/src/hooks/useContactCount.ts +50 -0
- package/src/hooks/useDownloadHandler.ts +36 -0
- package/src/hooks/useDragAndDrop.ts +79 -0
- package/src/hooks/useE2eeAttachmentRenderer.ts +204 -0
- package/src/hooks/useE2eeFileUpload.ts +38 -0
- package/src/hooks/useFileUpload.ts +25 -5
- package/src/hooks/useForwardMessage.ts +309 -0
- package/src/hooks/useInviteChannels.ts +88 -0
- package/src/hooks/useInviteCount.ts +104 -0
- package/src/hooks/useLoadMessages.ts +16 -4
- package/src/hooks/useMentions.ts +60 -7
- package/src/hooks/useMessageActions.ts +19 -10
- package/src/hooks/useMessageSend.ts +64 -12
- package/src/hooks/usePendingE2eeSends.ts +29 -0
- package/src/hooks/usePendingState.ts +21 -4
- package/src/hooks/usePreviewState.ts +69 -0
- package/src/hooks/useRecoveryPin.ts +287 -0
- package/src/hooks/useScrollToMessage.ts +29 -4
- package/src/hooks/useStickerPicker.ts +62 -0
- package/src/hooks/useTopicGroupUpdates.ts +235 -0
- package/src/index.ts +79 -6
- package/src/messageTypeUtils.ts +27 -1
- package/src/styles/_base.css +0 -1
- package/src/styles/_call-ui.css +59 -2
- package/src/styles/_channel-info.css +50 -4
- package/src/styles/_channel-list.css +131 -68
- package/src/styles/_create-channel-modal.css +10 -0
- package/src/styles/_forward-modal.css +16 -1
- package/src/styles/_media-lightbox.css +67 -2
- package/src/styles/_mentions.css +1 -1
- package/src/styles/_message-actions.css +3 -4
- package/src/styles/_message-bubble.css +631 -112
- package/src/styles/_message-input.css +139 -0
- package/src/styles/_message-list.css +91 -18
- package/src/styles/_message-quick-reactions.css +105 -32
- package/src/styles/_message-reactions.css +22 -32
- package/src/styles/_modal.css +2 -1
- package/src/styles/_preview-overlay.css +38 -0
- package/src/styles/_recovery-pin.css +97 -0
- package/src/styles/_tokens.css +22 -20
- package/src/styles/_typing-indicator.css +26 -10
- package/src/styles/index.css +2 -0
- package/src/types.ts +477 -15
- package/src/utils/avatarColors.ts +48 -0
- package/src/utils.ts +219 -16
package/src/types.ts
CHANGED
|
@@ -6,7 +6,11 @@ import type {
|
|
|
6
6
|
ChannelFilters,
|
|
7
7
|
ChannelSort,
|
|
8
8
|
ChannelQueryOptions,
|
|
9
|
+
E2eeRecoveryPolicy,
|
|
10
|
+
E2eeAttachmentManifest,
|
|
9
11
|
UserCallInfo,
|
|
12
|
+
SystemMessageTranslations,
|
|
13
|
+
SignalMessageTranslations,
|
|
10
14
|
} from '@ermis-network/ermis-chat-sdk';
|
|
11
15
|
import type { ErmisChat } from '@ermis-network/ermis-chat-sdk';
|
|
12
16
|
|
|
@@ -54,11 +58,21 @@ export type ChatContextValue = {
|
|
|
54
58
|
setJumpToMessageId: (id: string | null) => void;
|
|
55
59
|
/** Indicates whether the direct call feature is enabled */
|
|
56
60
|
enableCall?: boolean;
|
|
61
|
+
/** Save a draft message (innerHTML and files) for a specific channel */
|
|
62
|
+
setDraft: (cid: string, draft: { html: string; files: any[] }) => void;
|
|
63
|
+
/** Retrieve the saved draft for a specific channel */
|
|
64
|
+
getDraft: (cid: string) => { html: string; files: any[] } | undefined;
|
|
65
|
+
/** Clear all saved drafts (e.g. on logout) */
|
|
66
|
+
clearAllDrafts: () => void;
|
|
57
67
|
};
|
|
58
68
|
|
|
69
|
+
import type { ChatComponentsContextValue } from './context/ChatComponentsContext';
|
|
70
|
+
|
|
59
71
|
export type ChatProviderProps = {
|
|
60
72
|
client: ErmisChat;
|
|
61
73
|
children: React.ReactNode;
|
|
74
|
+
/** Global UI primitive components registry */
|
|
75
|
+
components?: ChatComponentsContextValue;
|
|
62
76
|
/** Initial theme, defaults to 'dark' */
|
|
63
77
|
initialTheme?: Theme;
|
|
64
78
|
/** Enable direct call feature (Audio/Video). If enabled, configures internal CallProvider */
|
|
@@ -193,6 +207,9 @@ export type ErmisCallRingingProps = {
|
|
|
193
207
|
endCallLabel: string;
|
|
194
208
|
audioCallBadgeLabel: string;
|
|
195
209
|
videoCallBadgeLabel: string;
|
|
210
|
+
isAccepting?: boolean;
|
|
211
|
+
isRejecting?: boolean;
|
|
212
|
+
isEnding?: boolean;
|
|
196
213
|
};
|
|
197
214
|
|
|
198
215
|
/** Props for the Connected Audio state view */
|
|
@@ -240,6 +257,7 @@ export type ErmisCallControlsBarProps = {
|
|
|
240
257
|
selectedVideoDeviceId: string;
|
|
241
258
|
switchAudioDevice: (id: string) => Promise<void>;
|
|
242
259
|
switchVideoDevice: (id: string) => Promise<void>;
|
|
260
|
+
isEnding?: boolean;
|
|
243
261
|
};
|
|
244
262
|
|
|
245
263
|
/* ----------------------------------------------------------
|
|
@@ -337,8 +355,10 @@ export type ChannelActionLabels = {
|
|
|
337
355
|
closeTopic?: string;
|
|
338
356
|
reopenTopic?: string;
|
|
339
357
|
createTopic?: string;
|
|
358
|
+
deleteTopic?: string;
|
|
340
359
|
deleteChannel?: string;
|
|
341
360
|
leaveChannel?: string;
|
|
361
|
+
truncateChannel?: string;
|
|
342
362
|
};
|
|
343
363
|
|
|
344
364
|
export type ChannelActionIcons = {
|
|
@@ -350,8 +370,10 @@ export type ChannelActionIcons = {
|
|
|
350
370
|
CloseTopicIcon?: React.ReactNode;
|
|
351
371
|
ReopenTopicIcon?: React.ReactNode;
|
|
352
372
|
CreateTopicIcon?: React.ReactNode;
|
|
373
|
+
DeleteTopicIcon?: React.ReactNode;
|
|
353
374
|
DeleteChannelIcon?: React.ReactNode;
|
|
354
375
|
LeaveChannelIcon?: React.ReactNode;
|
|
376
|
+
TruncateChannelIcon?: React.ReactNode;
|
|
355
377
|
};
|
|
356
378
|
|
|
357
379
|
export type ChannelActionsProps = {
|
|
@@ -365,7 +387,7 @@ export type ChannelItemProps = {
|
|
|
365
387
|
isActive: boolean;
|
|
366
388
|
hasUnread: boolean;
|
|
367
389
|
unreadCount: number;
|
|
368
|
-
lastMessageText:
|
|
390
|
+
lastMessageText: React.ReactNode;
|
|
369
391
|
lastMessageUser: string;
|
|
370
392
|
lastMessageTimestamp?: Date | string | null;
|
|
371
393
|
onSelect: (channel: Channel) => void;
|
|
@@ -388,6 +410,10 @@ export type ChannelItemProps = {
|
|
|
388
410
|
onEditTopic?: (channel: Channel) => void;
|
|
389
411
|
/** Handler when Close/Reopen Topic action is triggered */
|
|
390
412
|
onToggleCloseTopic?: (channel: Channel, isClosed: boolean) => void;
|
|
413
|
+
/** Handler when Delete Topic action is triggered */
|
|
414
|
+
onDeleteTopic?: (channel: Channel) => void;
|
|
415
|
+
/** Handler when Truncate Channel action is triggered */
|
|
416
|
+
onTruncateChannel?: (channel: Channel) => void;
|
|
391
417
|
/** Array of action IDs to hide from the actions dropdown */
|
|
392
418
|
hiddenActions?: string[];
|
|
393
419
|
/** Custom labels for default channel actions */
|
|
@@ -398,6 +424,70 @@ export type ChannelItemProps = {
|
|
|
398
424
|
isOnline?: boolean;
|
|
399
425
|
};
|
|
400
426
|
|
|
427
|
+
/* ----------------------------------------------------------
|
|
428
|
+
TopicPill types (for FlatTopicGroupItem)
|
|
429
|
+
---------------------------------------------------------- */
|
|
430
|
+
export type TopicPillProps = {
|
|
431
|
+
/** The topic channel to display as a pill */
|
|
432
|
+
topic: Channel;
|
|
433
|
+
/** Size of the topic avatar in pixels (default: 16) */
|
|
434
|
+
avatarSize?: number;
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
/* ----------------------------------------------------------
|
|
438
|
+
TopicList types
|
|
439
|
+
---------------------------------------------------------- */
|
|
440
|
+
export type TopicListProps = {
|
|
441
|
+
/** Parent channel that has topics enabled */
|
|
442
|
+
channel: Channel;
|
|
443
|
+
/** Custom channel item component for each topic row */
|
|
444
|
+
ChannelItemComponent?: React.ComponentType<ChannelItemProps>;
|
|
445
|
+
/** Custom avatar for the general (parent) topic */
|
|
446
|
+
GeneralAvatarComponent?: React.ComponentType<AvatarProps>;
|
|
447
|
+
/** Custom avatar for sub-topic items */
|
|
448
|
+
TopicAvatarComponent?: React.ComponentType<AvatarProps>;
|
|
449
|
+
/** Custom avatar component (fallback) */
|
|
450
|
+
AvatarComponent?: React.ComponentType<AvatarProps>;
|
|
451
|
+
/** Label for the general topic (default: 'general') */
|
|
452
|
+
generalTopicLabel?: string;
|
|
453
|
+
/** Pinned icon component */
|
|
454
|
+
PinnedIconComponent?: React.ComponentType;
|
|
455
|
+
/** Custom channel actions component */
|
|
456
|
+
ChannelActionsComponent?: React.ComponentType<ChannelActionsProps>;
|
|
457
|
+
/** Called when a topic is selected */
|
|
458
|
+
onSelectTopic?: (topic: Channel) => void;
|
|
459
|
+
/** Handler for Edit Topic action */
|
|
460
|
+
onEditTopic?: (channel: Channel) => void;
|
|
461
|
+
/** Handler for Close/Reopen Topic action */
|
|
462
|
+
onToggleCloseTopic?: (channel: Channel, isClosed: boolean) => void;
|
|
463
|
+
/** Handler for Delete Topic action */
|
|
464
|
+
onDeleteTopic?: (channel: Channel) => void;
|
|
465
|
+
/** Actions to hide */
|
|
466
|
+
hiddenActions?: string[];
|
|
467
|
+
/** Custom action labels */
|
|
468
|
+
actionLabels?: ChannelActionLabels;
|
|
469
|
+
/** Custom action icons */
|
|
470
|
+
actionIcons?: ChannelActionIcons;
|
|
471
|
+
/** Icon for closed topics */
|
|
472
|
+
closedTopicIcon?: React.ReactNode;
|
|
473
|
+
/** Badge label for pending members */
|
|
474
|
+
pendingBadgeLabel?: string;
|
|
475
|
+
/** Badge label for blocked members */
|
|
476
|
+
blockedBadgeLabel?: string;
|
|
477
|
+
/** Auto-scroll the topic list to the top when the current user sends a message (default: true) */
|
|
478
|
+
scrollToTopOnOwnMessage?: boolean;
|
|
479
|
+
deletedMessageLabel?: React.ReactNode;
|
|
480
|
+
stickerMessageLabel?: React.ReactNode;
|
|
481
|
+
photoMessageLabel?: React.ReactNode;
|
|
482
|
+
videoMessageLabel?: React.ReactNode;
|
|
483
|
+
voiceRecordingMessageLabel?: React.ReactNode;
|
|
484
|
+
fileMessageLabel?: React.ReactNode;
|
|
485
|
+
encryptedMessageLabel?: React.ReactNode;
|
|
486
|
+
encryptedMessageUnavailableLabel?: React.ReactNode;
|
|
487
|
+
systemMessageTranslations?: SystemMessageTranslations;
|
|
488
|
+
signalMessageTranslations?: SignalMessageTranslations;
|
|
489
|
+
};
|
|
490
|
+
|
|
401
491
|
export type ChannelListProps = {
|
|
402
492
|
filters?: ChannelFilters;
|
|
403
493
|
sort?: ChannelSort;
|
|
@@ -405,6 +495,8 @@ export type ChannelListProps = {
|
|
|
405
495
|
renderChannel?: (channel: Channel, isActive: boolean) => React.ReactNode;
|
|
406
496
|
onChannelSelect?: (channel: Channel) => void;
|
|
407
497
|
className?: string;
|
|
498
|
+
/** Whether to show pending invites visually in the main list (default: true) */
|
|
499
|
+
showPendingInvites?: boolean;
|
|
408
500
|
/** Array of action IDs to hide from the actions dropdown */
|
|
409
501
|
hiddenActions?: string[];
|
|
410
502
|
LoadingIndicator?: React.ComponentType<{ text?: string }>;
|
|
@@ -420,18 +512,34 @@ export type ChannelListProps = {
|
|
|
420
512
|
pendingBadgeLabel?: string;
|
|
421
513
|
/** Label for the loading indicator */
|
|
422
514
|
loadingLabel?: string;
|
|
423
|
-
/**
|
|
515
|
+
/** Component to display when there is an error loading channels */
|
|
516
|
+
ErrorIndicator?: React.ComponentType<{ text?: string; onRetry?: () => void }>;
|
|
517
|
+
/** Label to display in the error indicator */
|
|
518
|
+
errorLabel?: string;
|
|
519
|
+
/** Label to display in the empty state indicator */
|
|
424
520
|
emptyStateLabel?: string;
|
|
425
521
|
/** Label for the blocked channel badge hover */
|
|
426
522
|
blockedBadgeLabel?: string;
|
|
427
|
-
/**
|
|
428
|
-
|
|
429
|
-
/**
|
|
430
|
-
|
|
431
|
-
/**
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
|
|
523
|
+
/** Label for deleted messages in the preview strip (default: 'This message was deleted') */
|
|
524
|
+
deletedMessageLabel?: React.ReactNode;
|
|
525
|
+
/** Label for sticker messages in the preview strip (default: 'Sticker') */
|
|
526
|
+
stickerMessageLabel?: React.ReactNode;
|
|
527
|
+
/** Label for photo messages in the preview strip (default: '📷 Photo') */
|
|
528
|
+
photoMessageLabel?: React.ReactNode;
|
|
529
|
+
/** Label for video messages in the preview strip (default: '🎬 Video') */
|
|
530
|
+
videoMessageLabel?: React.ReactNode;
|
|
531
|
+
/** Label for voice message in the preview strip (default: '🎤 Voice message') */
|
|
532
|
+
voiceRecordingMessageLabel?: React.ReactNode;
|
|
533
|
+
/** Label for file messages in the preview strip (default: '📎 File') */
|
|
534
|
+
fileMessageLabel?: React.ReactNode;
|
|
535
|
+
/** Label for encrypted messages in the preview strip (default: 'Encrypted message') */
|
|
536
|
+
encryptedMessageLabel?: React.ReactNode;
|
|
537
|
+
/** Label for encrypted messages that failed in the preview strip (default: 'Encrypted message unavailable') */
|
|
538
|
+
encryptedMessageUnavailableLabel?: React.ReactNode;
|
|
539
|
+
/** Custom translation templates for system messages in the preview strip */
|
|
540
|
+
systemMessageTranslations?: SystemMessageTranslations;
|
|
541
|
+
/** Custom translation templates for signal (call) messages in the preview strip */
|
|
542
|
+
signalMessageTranslations?: SignalMessageTranslations;
|
|
435
543
|
/** Handler when Add Topic button is clicked on a team channel */
|
|
436
544
|
onAddTopic?: (channel: Channel) => void;
|
|
437
545
|
/** Optional custom emoji picker for TopicModal */
|
|
@@ -444,12 +552,32 @@ export type ChannelListProps = {
|
|
|
444
552
|
onEditTopic?: (channel: Channel) => void;
|
|
445
553
|
/** Handler when Close/Reopen Topic action is triggered */
|
|
446
554
|
onToggleCloseTopic?: (channel: Channel, isClosed: boolean) => void;
|
|
555
|
+
/** Handler when Delete Topic action is triggered */
|
|
556
|
+
onDeleteTopic?: (channel: Channel) => void;
|
|
557
|
+
/** Handler when Truncate action is triggered */
|
|
558
|
+
onTruncateChannel?: (channel: Channel) => void;
|
|
447
559
|
/** Custom labels for default channel actions */
|
|
448
560
|
actionLabels?: ChannelActionLabels;
|
|
449
561
|
/** Custom icons for default channel actions */
|
|
450
562
|
actionIcons?: ChannelActionIcons;
|
|
451
563
|
/** Show online/offline indicator dots on channel item avatars for friend channels (default: true) */
|
|
452
564
|
showOnlineStatus?: boolean;
|
|
565
|
+
/** Handler when a topic-enabled channel is clicked — enables drill-down mode */
|
|
566
|
+
onTopicDrillDown?: (channel: Channel) => void;
|
|
567
|
+
/** Max number of topic pills shown in the preview strip (default: 3) */
|
|
568
|
+
maxVisibleTopics?: number;
|
|
569
|
+
/** Label for the overflow indicator when topics exceed maxVisibleTopics (default: '...') */
|
|
570
|
+
moreTopicsLabel?: string;
|
|
571
|
+
/** Label for the general topic pill (default: 'general') */
|
|
572
|
+
generalTopicLabel?: string;
|
|
573
|
+
/** Custom component for rendering each topic pill in the preview strip */
|
|
574
|
+
TopicPillComponent?: React.ComponentType<TopicPillProps>;
|
|
575
|
+
/** Custom component to replace the entire flat topic group item */
|
|
576
|
+
FlatTopicGroupItemComponent?: React.ComponentType<any>;
|
|
577
|
+
/** Auto-scroll the channel list to the top when the current user sends a message (default: true) */
|
|
578
|
+
scrollToTopOnOwnMessage?: boolean;
|
|
579
|
+
/** Whether to show topic pills on team channels (default: false) */
|
|
580
|
+
showTopicPills?: boolean;
|
|
453
581
|
};
|
|
454
582
|
|
|
455
583
|
/* ----------------------------------------------------------
|
|
@@ -464,6 +592,15 @@ export type AttachmentProps = {
|
|
|
464
592
|
export type MessageRendererProps = {
|
|
465
593
|
message: FormatMessageResponse;
|
|
466
594
|
isOwnMessage: boolean;
|
|
595
|
+
systemMessageTranslations?: SystemMessageTranslations;
|
|
596
|
+
signalMessageTranslations?: SignalMessageTranslations;
|
|
597
|
+
onMentionClick?: (userId: string) => void;
|
|
598
|
+
/** I18n Label for encrypted messages (default: 'Encrypted message') */
|
|
599
|
+
encryptedMessageLabel?: string;
|
|
600
|
+
/** I18n Label for encrypted messages that failed to decrypt (default: 'Encrypted message could not be decrypted') */
|
|
601
|
+
encryptedMessageFailedLabel?: string;
|
|
602
|
+
/** I18n Label for encrypted messages being decrypted (default: 'Decrypting encrypted message...') */
|
|
603
|
+
encryptedMessageDecryptingLabel?: string;
|
|
467
604
|
};
|
|
468
605
|
|
|
469
606
|
export type MessageBubbleProps = {
|
|
@@ -485,9 +622,14 @@ export type JumpToLatestProps = {
|
|
|
485
622
|
---------------------------------------------------------- */
|
|
486
623
|
export type MediaLightboxItem = {
|
|
487
624
|
type: 'image' | 'video';
|
|
488
|
-
src
|
|
625
|
+
src?: string;
|
|
489
626
|
alt?: string;
|
|
490
627
|
posterSrc?: string;
|
|
628
|
+
loading?: boolean;
|
|
629
|
+
progressLabel?: string;
|
|
630
|
+
download?: () => Promise<void> | void;
|
|
631
|
+
onPlaybackError?: (context?: { currentTime?: number }) => Promise<void> | void;
|
|
632
|
+
onDispose?: () => Promise<void> | void;
|
|
491
633
|
};
|
|
492
634
|
|
|
493
635
|
export type MediaLightboxProps = {
|
|
@@ -503,6 +645,12 @@ export type MediaLightboxProps = {
|
|
|
503
645
|
export type MessageListProps = {
|
|
504
646
|
/** Fully custom render for each message */
|
|
505
647
|
renderMessage?: (message: FormatMessageResponse, isOwnMessage: boolean) => React.ReactNode;
|
|
648
|
+
/** Handler when a mention is clicked */
|
|
649
|
+
onMentionClick?: (userId: string) => void;
|
|
650
|
+
/** Handler when a sender's username is clicked in the message list */
|
|
651
|
+
onUserNameClick?: (userId: string) => void;
|
|
652
|
+
/** Handler when clicking to add a custom reaction */
|
|
653
|
+
onAddReactionClick?: (e: React.MouseEvent, messageId: string) => void;
|
|
506
654
|
/** Additional CSS class name */
|
|
507
655
|
className?: string;
|
|
508
656
|
/** Custom empty state component */
|
|
@@ -517,6 +665,8 @@ export type MessageListProps = {
|
|
|
517
665
|
loadMoreLimit?: number;
|
|
518
666
|
/** Custom date separator component */
|
|
519
667
|
DateSeparatorComponent?: React.ComponentType<DateSeparatorProps>;
|
|
668
|
+
/** Locale string for date separator labels (e.g. 'vi', 'en-US'). Falls back to browser default. */
|
|
669
|
+
dateLocale?: string;
|
|
520
670
|
/** Custom message item component (replaces the entire row) */
|
|
521
671
|
MessageItemComponent?: React.ComponentType<MessageItemProps>;
|
|
522
672
|
/** Custom system message item component */
|
|
@@ -572,9 +722,42 @@ export type MessageListProps = {
|
|
|
572
722
|
closedTopicReopenLabel?: string;
|
|
573
723
|
|
|
574
724
|
/** Custom component for pending invitee notification in direct channels */
|
|
575
|
-
PendingInviteeNotificationComponent?: React.ComponentType<{ inviteeName?: string
|
|
725
|
+
PendingInviteeNotificationComponent?: React.ComponentType<{ inviteeName?: string; label?: string }>;
|
|
576
726
|
/** I18n Label for pending invitee notification */
|
|
577
727
|
pendingInviteeLabel?: string | ((inviteeName?: string) => string);
|
|
728
|
+
|
|
729
|
+
/** I18n Label for pinned messages header */
|
|
730
|
+
pinnedMessagesLabel?: string | ((count: number) => string);
|
|
731
|
+
/** I18n Label for seeing all pinned messages */
|
|
732
|
+
seeAllLabel?: string;
|
|
733
|
+
/** I18n Label for collapsing pinned messages */
|
|
734
|
+
collapseLabel?: string;
|
|
735
|
+
/** I18n Label for unpinning a message */
|
|
736
|
+
unpinLabel?: string;
|
|
737
|
+
/** I18n Label for sticker message preview */
|
|
738
|
+
stickerLabel?: string;
|
|
739
|
+
/** I18n Label for typing indicator */
|
|
740
|
+
typingIndicatorLabel?: (users: Array<{ id: string; name?: string }>) => string;
|
|
741
|
+
/** I18n Label for deleted display messages (display_type === 'deleted') */
|
|
742
|
+
deletedMessageLabel?: string;
|
|
743
|
+
/** I18n Label for attachment-only previews */
|
|
744
|
+
attachmentLabel?: string;
|
|
745
|
+
/** I18n Label for messages whose contents are unavailable */
|
|
746
|
+
unavailableMessageLabel?: string;
|
|
747
|
+
/** I18n Label for encrypted messages (default: 'Encrypted message') */
|
|
748
|
+
encryptedMessageLabel?: string;
|
|
749
|
+
/** I18n Label for encrypted messages that failed to decrypt (default: 'Encrypted message could not be decrypted') */
|
|
750
|
+
encryptedMessageFailedLabel?: string;
|
|
751
|
+
/** I18n Label for encrypted messages being decrypted (default: 'Decrypting encrypted message...') */
|
|
752
|
+
encryptedMessageDecryptingLabel?: string;
|
|
753
|
+
/** I18n Label for encrypted messages unavailable in sidebar preview (default: 'Encrypted message unavailable') */
|
|
754
|
+
encryptedMessageUnavailableLabel?: string;
|
|
755
|
+
/** Custom translation templates for system messages */
|
|
756
|
+
systemMessageTranslations?: SystemMessageTranslations;
|
|
757
|
+
/** Custom translation templates for signal (call) messages */
|
|
758
|
+
signalMessageTranslations?: SignalMessageTranslations;
|
|
759
|
+
/** Whether to include hidden (deleted) messages in the initial channel query. Defaults to true. */
|
|
760
|
+
includeHiddenMessages?: boolean;
|
|
578
761
|
};
|
|
579
762
|
|
|
580
763
|
/* ----------------------------------------------------------
|
|
@@ -604,6 +787,8 @@ export type MessageReactionsProps = {
|
|
|
604
787
|
onClickReaction?: (type: string) => void;
|
|
605
788
|
/** Whether interactions are disabled */
|
|
606
789
|
disabled?: boolean;
|
|
790
|
+
/** Whether the message is from the current user */
|
|
791
|
+
isOwnMessage?: boolean;
|
|
607
792
|
};
|
|
608
793
|
|
|
609
794
|
/* ----------------------------------------------------------
|
|
@@ -667,16 +852,44 @@ export type MessageItemProps = {
|
|
|
667
852
|
forwardedLabel?: string;
|
|
668
853
|
/** I18n Label for edited state */
|
|
669
854
|
editedLabel?: string;
|
|
855
|
+
/** I18n Label for deleted display messages (display_type === 'deleted') */
|
|
856
|
+
deletedMessageLabel?: React.ReactNode;
|
|
857
|
+
/** I18n Label for attachment-only previews */
|
|
858
|
+
attachmentLabel?: string;
|
|
859
|
+
/** I18n Label for messages whose contents are unavailable */
|
|
860
|
+
unavailableMessageLabel?: string;
|
|
861
|
+
/** I18n Label for sticker message previews */
|
|
862
|
+
stickerLabel?: string;
|
|
863
|
+
/** I18n Label for encrypted messages (default: 'Encrypted message') */
|
|
864
|
+
encryptedMessageLabel?: string;
|
|
865
|
+
/** I18n Label for encrypted messages that failed to decrypt (default: 'Encrypted message could not be decrypted') */
|
|
866
|
+
encryptedMessageFailedLabel?: string;
|
|
867
|
+
/** I18n Label for encrypted messages being decrypted (default: 'Decrypting encrypted message...') */
|
|
868
|
+
encryptedMessageDecryptingLabel?: string;
|
|
869
|
+
/** Custom translation templates for system messages */
|
|
870
|
+
systemMessageTranslations?: SystemMessageTranslations;
|
|
871
|
+
/** Custom translation templates for signal (call) messages */
|
|
872
|
+
signalMessageTranslations?: SignalMessageTranslations;
|
|
873
|
+
/** Handler when a mention is clicked */
|
|
874
|
+
onMentionClick?: (userId: string) => void;
|
|
875
|
+
/** Handler when a sender's username is clicked in the message list */
|
|
876
|
+
onUserNameClick?: (userId: string) => void;
|
|
877
|
+
/** Handler when clicking to add a custom reaction */
|
|
878
|
+
onAddReactionClick?: (e: React.MouseEvent, messageId: string) => void;
|
|
879
|
+
/** When true, the avatar column is not rendered (handled by group wrapper) */
|
|
880
|
+
hideAvatar?: boolean;
|
|
670
881
|
};
|
|
671
882
|
|
|
672
883
|
export type SystemMessageItemProps = {
|
|
673
884
|
message: FormatMessageResponse;
|
|
674
885
|
isOwnMessage: boolean;
|
|
675
886
|
SystemRenderer: React.ComponentType<MessageRendererProps>;
|
|
887
|
+
systemMessageTranslations?: SystemMessageTranslations;
|
|
676
888
|
};
|
|
677
889
|
|
|
678
890
|
export type SendButtonProps = { disabled: boolean; onClick: () => void };
|
|
679
891
|
export type AttachButtonProps = { disabled: boolean; onClick: () => void };
|
|
892
|
+
export type VoiceRecordButtonProps = { disabled: boolean; onRecordComplete: (file: File) => void };
|
|
680
893
|
|
|
681
894
|
/** Props passed to a consumer-provided emoji picker component */
|
|
682
895
|
export type EmojiPickerProps = {
|
|
@@ -686,6 +899,18 @@ export type EmojiPickerProps = {
|
|
|
686
899
|
onClose: () => void;
|
|
687
900
|
};
|
|
688
901
|
|
|
902
|
+
/** Props for the preview overlay when a user has not joined a public channel */
|
|
903
|
+
export type PreviewOverlayProps = {
|
|
904
|
+
/** Title shown in the preview overlay */
|
|
905
|
+
title?: string;
|
|
906
|
+
/** Label for the join button */
|
|
907
|
+
buttonLabel?: string;
|
|
908
|
+
/** Action when the join button is clicked */
|
|
909
|
+
onJoin?: () => void;
|
|
910
|
+
/** Custom class name */
|
|
911
|
+
className?: string;
|
|
912
|
+
};
|
|
913
|
+
|
|
689
914
|
/** Props passed to the emoji button component */
|
|
690
915
|
export type EmojiButtonProps = {
|
|
691
916
|
/** Whether the picker is currently open */
|
|
@@ -705,6 +930,8 @@ export type MessageInputProps = {
|
|
|
705
930
|
SendButton?: React.ComponentType<SendButtonProps>;
|
|
706
931
|
/** Custom attach button component */
|
|
707
932
|
AttachButton?: React.ComponentType<AttachButtonProps>;
|
|
933
|
+
/** Custom voice record button component */
|
|
934
|
+
VoiceRecordButtonComponent?: React.ComponentType<VoiceRecordButtonProps>;
|
|
708
935
|
/** Custom file preview component */
|
|
709
936
|
FilesPreviewComponent?: React.ComponentType<FilesPreviewProps>;
|
|
710
937
|
/** Custom mention suggestions component */
|
|
@@ -743,6 +970,32 @@ export type MessageInputProps = {
|
|
|
743
970
|
slowModeLabel?: (cooldown: number) => React.ReactNode;
|
|
744
971
|
/** I18n Label for closed topic */
|
|
745
972
|
closedTopicLabel?: string;
|
|
973
|
+
/** I18n Label for replying state */
|
|
974
|
+
replyingToLabel?: string;
|
|
975
|
+
/** I18n Label for editing state */
|
|
976
|
+
editingMessageLabel?: string;
|
|
977
|
+
/** I18n Label for Drag and Drop overlay */
|
|
978
|
+
dragAndDropLabel?: string;
|
|
979
|
+
/** Custom component for Drag and Drop overlay */
|
|
980
|
+
DragAndDropOverlayComponent?: React.ComponentType<{ dragAndDropLabel: string }>;
|
|
981
|
+
|
|
982
|
+
/** Custom component for the Preview Overlay (shown instead of input in unjoined public channels) */
|
|
983
|
+
PreviewOverlayComponent?: React.ComponentType<PreviewOverlayProps>;
|
|
984
|
+
/** I18n Title for Preview Overlay */
|
|
985
|
+
previewOverlayTitle?: string;
|
|
986
|
+
/** I18n Label for Join Button in Preview Overlay */
|
|
987
|
+
joinChannelLabel?: string;
|
|
988
|
+
|
|
989
|
+
/** Disable stickers entirely */
|
|
990
|
+
disableStickers?: boolean;
|
|
991
|
+
/** URL for the sticker picker iframe (default: https://sticker.ermis.network) */
|
|
992
|
+
stickerIframeUrl?: string;
|
|
993
|
+
/** Custom sticker picker component */
|
|
994
|
+
StickerPickerComponent?: React.ComponentType<{ stickerIframeUrl: string; onClose: () => void }>;
|
|
995
|
+
/** Custom sticker button component */
|
|
996
|
+
StickerButtonComponent?: React.ComponentType<{ active: boolean; onClick: () => void }>;
|
|
997
|
+
/** I18n Label for maximum characters exceeded error */
|
|
998
|
+
maxCharsLabel?: string;
|
|
746
999
|
};
|
|
747
1000
|
|
|
748
1001
|
/* ----------------------------------------------------------
|
|
@@ -805,6 +1058,10 @@ export type PinnedMessageItemProps = {
|
|
|
805
1058
|
onClickMessage?: (messageId: string) => void;
|
|
806
1059
|
onUnpin?: (messageId: string) => void;
|
|
807
1060
|
AvatarComponent: React.ComponentType<AvatarProps>;
|
|
1061
|
+
unpinLabel?: string;
|
|
1062
|
+
stickerLabel?: string;
|
|
1063
|
+
attachmentLabel?: string;
|
|
1064
|
+
unavailableMessageLabel?: string;
|
|
808
1065
|
};
|
|
809
1066
|
|
|
810
1067
|
export type PinnedMessagesProps = {
|
|
@@ -818,6 +1075,14 @@ export type PinnedMessagesProps = {
|
|
|
818
1075
|
onClickMessage?: (messageId: string) => void;
|
|
819
1076
|
/** Max messages to show in collapsed state (default: 1) */
|
|
820
1077
|
maxCollapsed?: number;
|
|
1078
|
+
/** I18n Labels */
|
|
1079
|
+
pinnedMessagesLabel?: string | ((count: number) => string);
|
|
1080
|
+
seeAllLabel?: string;
|
|
1081
|
+
collapseLabel?: string;
|
|
1082
|
+
unpinLabel?: string;
|
|
1083
|
+
stickerLabel?: string;
|
|
1084
|
+
attachmentLabel?: string;
|
|
1085
|
+
unavailableMessageLabel?: string;
|
|
821
1086
|
};
|
|
822
1087
|
|
|
823
1088
|
/* ----------------------------------------------------------
|
|
@@ -829,11 +1094,28 @@ export type QuotedMessagePreviewProps = {
|
|
|
829
1094
|
id: string;
|
|
830
1095
|
text?: string;
|
|
831
1096
|
user?: { id?: string; name?: string };
|
|
1097
|
+
attachments?: Attachment[];
|
|
1098
|
+
content_type?: string;
|
|
1099
|
+
mls_ciphertext?: unknown;
|
|
1100
|
+
e2ee_status?: string;
|
|
1101
|
+
sticker_url?: string;
|
|
1102
|
+
type?: string;
|
|
1103
|
+
display_type?: string;
|
|
1104
|
+
mentioned_users?: string[];
|
|
1105
|
+
mentioned_all?: boolean;
|
|
832
1106
|
};
|
|
833
1107
|
/** Whether the parent message is from the current user */
|
|
834
1108
|
isOwnMessage: boolean;
|
|
835
1109
|
/** Callback when the quote box is clicked */
|
|
836
1110
|
onClick: (messageId: string) => void;
|
|
1111
|
+
/** I18n Label for attachment-only quoted messages */
|
|
1112
|
+
attachmentLabel?: string;
|
|
1113
|
+
/** I18n Label for quoted messages whose contents are unavailable */
|
|
1114
|
+
unavailableMessageLabel?: string;
|
|
1115
|
+
/** I18n Label for sticker quoted messages */
|
|
1116
|
+
stickerLabel?: string;
|
|
1117
|
+
/** I18n Label for deleted messages */
|
|
1118
|
+
deletedMessageLabel?: string;
|
|
837
1119
|
};
|
|
838
1120
|
|
|
839
1121
|
/* ----------------------------------------------------------
|
|
@@ -903,6 +1185,10 @@ export type FilePreviewItem = {
|
|
|
903
1185
|
previewUrl?: string;
|
|
904
1186
|
/** Upload status */
|
|
905
1187
|
status: 'pending' | 'uploading' | 'done' | 'error';
|
|
1188
|
+
/** E2EE upload phase when the file is handled by MLS attachment flow */
|
|
1189
|
+
e2eePhase?: 'generating_preview' | 'encrypting' | 'uploading' | 'completing' | 'sending' | 'retrying' | 'failed';
|
|
1190
|
+
/** Upload progress percentage (0-100) */
|
|
1191
|
+
progress?: number;
|
|
906
1192
|
/** Error message if upload failed */
|
|
907
1193
|
error?: string;
|
|
908
1194
|
/** URL returned after successful upload */
|
|
@@ -921,7 +1207,7 @@ export type FilesPreviewProps = {
|
|
|
921
1207
|
};
|
|
922
1208
|
|
|
923
1209
|
/* --------------------------------------------------------------------------
|
|
924
|
-
*
|
|
1210
|
+
* Primitive Components Props
|
|
925
1211
|
* -------------------------------------------------------------------------- */
|
|
926
1212
|
|
|
927
1213
|
export interface ModalProps {
|
|
@@ -935,6 +1221,38 @@ export interface ModalProps {
|
|
|
935
1221
|
closeOnOutsideClick?: boolean;
|
|
936
1222
|
}
|
|
937
1223
|
|
|
1224
|
+
export interface DropdownProps {
|
|
1225
|
+
/** Whether the dropdown is open */
|
|
1226
|
+
isOpen: boolean;
|
|
1227
|
+
/** Rect from getBoundingClientRect() of the anchor element */
|
|
1228
|
+
anchorRect: DOMRect | null;
|
|
1229
|
+
/** Callback when dropdown requests to close (e.g., click outside, scroll, Escape) */
|
|
1230
|
+
onClose: () => void;
|
|
1231
|
+
/** Dropdown menu content */
|
|
1232
|
+
children: React.ReactNode;
|
|
1233
|
+
/** Horizontal alignment relative to the anchor. Default: 'left' */
|
|
1234
|
+
align?: 'left' | 'right';
|
|
1235
|
+
/** Optional custom CSS class for the container */
|
|
1236
|
+
className?: string;
|
|
1237
|
+
/** Optional custom CSS style for the container */
|
|
1238
|
+
style?: React.CSSProperties;
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
export type PanelProps = {
|
|
1242
|
+
/** Whether the panel is visible */
|
|
1243
|
+
isOpen: boolean;
|
|
1244
|
+
/** Called when user clicks the back button */
|
|
1245
|
+
onClose: () => void;
|
|
1246
|
+
/** Panel title shown in the header */
|
|
1247
|
+
title?: string;
|
|
1248
|
+
/** Panel body content */
|
|
1249
|
+
children: React.ReactNode;
|
|
1250
|
+
/** Optional header content (replaces default title + back button) */
|
|
1251
|
+
headerContent?: React.ReactNode;
|
|
1252
|
+
/** Additional CSS class name */
|
|
1253
|
+
className?: string;
|
|
1254
|
+
};
|
|
1255
|
+
|
|
938
1256
|
/* ----------------------------------------------------------
|
|
939
1257
|
Channel Info types
|
|
940
1258
|
---------------------------------------------------------- */
|
|
@@ -960,10 +1278,19 @@ export type AttachmentItem = {
|
|
|
960
1278
|
og_scrape_url?: string;
|
|
961
1279
|
image_url?: string;
|
|
962
1280
|
text?: string;
|
|
1281
|
+
e2ee_manifest?: E2eeAttachmentManifest;
|
|
1282
|
+
e2ee_manifest_missing?: boolean;
|
|
963
1283
|
};
|
|
964
1284
|
|
|
965
1285
|
export type MediaTab = 'members' | 'media' | 'links' | 'files';
|
|
966
1286
|
|
|
1287
|
+
export type ChannelInfoTabHeaderProps = {
|
|
1288
|
+
activeTab: MediaTab;
|
|
1289
|
+
onTabChange: (tab: MediaTab) => void;
|
|
1290
|
+
availableTabs: MediaTab[];
|
|
1291
|
+
tabCounts: Record<MediaTab, number>;
|
|
1292
|
+
};
|
|
1293
|
+
|
|
967
1294
|
/* Sub-component prop types for consumer customization */
|
|
968
1295
|
|
|
969
1296
|
export type ChannelInfoMemberItemProps = {
|
|
@@ -979,6 +1306,8 @@ export type ChannelInfoMemberItemProps = {
|
|
|
979
1306
|
canPromote?: boolean;
|
|
980
1307
|
onDemote?: (id: string) => void;
|
|
981
1308
|
canDemote?: boolean;
|
|
1309
|
+
/** Custom labels for member roles (owner, moder, member, pending) */
|
|
1310
|
+
roleLabels?: Record<string, string>;
|
|
982
1311
|
};
|
|
983
1312
|
|
|
984
1313
|
export type ChannelInfoMediaItemProps = {
|
|
@@ -1023,30 +1352,56 @@ export type ChannelInfoCoverProps = {
|
|
|
1023
1352
|
isTopic?: boolean;
|
|
1024
1353
|
/** Whether the channel is a team channel */
|
|
1025
1354
|
isTeamChannel?: boolean;
|
|
1355
|
+
/** Whether this channel or inherited parent topic is E2EE enabled */
|
|
1356
|
+
isE2ee?: boolean;
|
|
1357
|
+
/** Current encryption epoch, if available */
|
|
1358
|
+
encryptionEpoch?: number;
|
|
1026
1359
|
};
|
|
1027
1360
|
|
|
1028
1361
|
export type ChannelInfoActionsProps = {
|
|
1362
|
+
channel?: Channel;
|
|
1029
1363
|
onSearchClick?: () => void;
|
|
1030
1364
|
onSettingsClick?: () => void;
|
|
1031
1365
|
onLeaveChannel?: () => void;
|
|
1032
1366
|
onDeleteChannel?: () => void;
|
|
1367
|
+
onTruncateChannel?: () => void;
|
|
1033
1368
|
onBlockUser?: () => void;
|
|
1034
1369
|
onUnblockUser?: () => void;
|
|
1370
|
+
onPin?: () => void;
|
|
1371
|
+
onUnpin?: () => void;
|
|
1035
1372
|
isTeamChannel?: boolean;
|
|
1036
1373
|
isTopic?: boolean;
|
|
1037
1374
|
isClosedTopic?: boolean;
|
|
1038
1375
|
isBlocked?: boolean;
|
|
1376
|
+
isPinned?: boolean;
|
|
1039
1377
|
currentUserRole?: string;
|
|
1040
1378
|
searchLabel?: string;
|
|
1041
1379
|
settingsLabel?: string;
|
|
1042
1380
|
deleteLabel?: string;
|
|
1381
|
+
truncateLabel?: string;
|
|
1043
1382
|
leaveLabel?: string;
|
|
1044
1383
|
blockLabel?: string;
|
|
1045
1384
|
unblockLabel?: string;
|
|
1385
|
+
pinLabel?: string;
|
|
1386
|
+
unpinLabel?: string;
|
|
1046
1387
|
onCloseTopic?: () => void;
|
|
1047
1388
|
onReopenTopic?: () => void;
|
|
1048
1389
|
closeTopicLabel?: string;
|
|
1049
1390
|
reopenTopicLabel?: string;
|
|
1391
|
+
onDeleteTopic?: () => void;
|
|
1392
|
+
deleteTopicLabel?: string;
|
|
1393
|
+
onCreateTopic?: () => void;
|
|
1394
|
+
createTopicLabel?: string;
|
|
1395
|
+
topicsEnabled?: boolean;
|
|
1396
|
+
isE2ee?: boolean;
|
|
1397
|
+
encryptionInitialized?: boolean;
|
|
1398
|
+
encryptionEpoch?: number;
|
|
1399
|
+
onRotateKey?: () => void;
|
|
1400
|
+
rotateKeyLabel?: string;
|
|
1401
|
+
rotateKeyDisabled?: boolean;
|
|
1402
|
+
onEnableE2ee?: () => void;
|
|
1403
|
+
enableE2eeLabel?: string;
|
|
1404
|
+
enableE2eeDisabled?: boolean;
|
|
1050
1405
|
};
|
|
1051
1406
|
|
|
1052
1407
|
export type ChannelInfoMember = {
|
|
@@ -1060,6 +1415,7 @@ export type ChannelInfoMember = {
|
|
|
1060
1415
|
export type EditChannelData = {
|
|
1061
1416
|
name?: string;
|
|
1062
1417
|
image?: string;
|
|
1418
|
+
banner?: string;
|
|
1063
1419
|
description?: string;
|
|
1064
1420
|
public?: boolean;
|
|
1065
1421
|
};
|
|
@@ -1167,6 +1523,7 @@ export type ChannelInfoTabsProps = {
|
|
|
1167
1523
|
onUnbanMember?: (id: string) => void;
|
|
1168
1524
|
onPromoteMember?: (id: string) => void;
|
|
1169
1525
|
onDemoteMember?: (id: string) => void;
|
|
1526
|
+
isPreviewMode?: boolean;
|
|
1170
1527
|
|
|
1171
1528
|
/** Label for the 'Add Member' button in the Members tab (default: 'Add Member') */
|
|
1172
1529
|
addMemberButtonLabel?: string;
|
|
@@ -1179,7 +1536,14 @@ export type ChannelInfoTabsProps = {
|
|
|
1179
1536
|
LinkItemComponent?: React.ComponentType<ChannelInfoLinkItemProps>;
|
|
1180
1537
|
FileItemComponent?: React.ComponentType<ChannelInfoFileItemProps>;
|
|
1181
1538
|
EmptyStateComponent?: React.ComponentType<ChannelInfoEmptyStateProps>;
|
|
1182
|
-
LoadingComponent?: React.ComponentType
|
|
1539
|
+
LoadingComponent?: React.ComponentType<{ tab?: string }>;
|
|
1540
|
+
/** Custom component for the tab header buttons */
|
|
1541
|
+
TabHeaderComponent?: React.ComponentType<ChannelInfoTabHeaderProps>;
|
|
1542
|
+
/** Whether the tabs panel is currently visible — controls data fetching (default: true) */
|
|
1543
|
+
isVisible?: boolean;
|
|
1544
|
+
roleLabels?: Record<string, string>;
|
|
1545
|
+
/** Ref or Element of the parent scrollable container — used for virtualization sync (default: undefined) */
|
|
1546
|
+
scrollContainerRef?: React.RefObject<HTMLDivElement | null> | HTMLDivElement | null;
|
|
1183
1547
|
};
|
|
1184
1548
|
|
|
1185
1549
|
export type ChannelInfoProps = {
|
|
@@ -1193,6 +1557,8 @@ export type ChannelInfoProps = {
|
|
|
1193
1557
|
onClose?: () => void;
|
|
1194
1558
|
/** Custom Title String for the banner */
|
|
1195
1559
|
title?: string;
|
|
1560
|
+
/** Whether the panel is visible — controls data fetching timing (default: true) */
|
|
1561
|
+
isVisible?: boolean;
|
|
1196
1562
|
|
|
1197
1563
|
/** Custom components to replace internal sections */
|
|
1198
1564
|
HeaderComponent?: React.ComponentType<ChannelInfoHeaderProps>;
|
|
@@ -1203,6 +1569,8 @@ export type ChannelInfoProps = {
|
|
|
1203
1569
|
AddMemberModalComponent?: React.ComponentType<AddMemberModalProps>;
|
|
1204
1570
|
/** Custom component replacing the entire EditChannelModal */
|
|
1205
1571
|
EditChannelModalComponent?: React.ComponentType<EditChannelModalProps>;
|
|
1572
|
+
/** Custom component replacing the entire EditTopicModal */
|
|
1573
|
+
EditTopicModalComponent?: React.ComponentType<TopicModalProps>;
|
|
1206
1574
|
|
|
1207
1575
|
/** Custom sub-component overrides (passed through to TabsComponent) */
|
|
1208
1576
|
MemberItemComponent?: React.ComponentType<ChannelInfoMemberItemProps>;
|
|
@@ -1210,7 +1578,9 @@ export type ChannelInfoProps = {
|
|
|
1210
1578
|
LinkItemComponent?: React.ComponentType<ChannelInfoLinkItemProps>;
|
|
1211
1579
|
FileItemComponent?: React.ComponentType<ChannelInfoFileItemProps>;
|
|
1212
1580
|
EmptyStateComponent?: React.ComponentType<ChannelInfoEmptyStateProps>;
|
|
1213
|
-
LoadingComponent?: React.ComponentType
|
|
1581
|
+
LoadingComponent?: React.ComponentType<{ tab?: string }>;
|
|
1582
|
+
/** Custom component for the tab header buttons (passed through to TabsComponent) */
|
|
1583
|
+
TabHeaderComponent?: React.ComponentType<ChannelInfoTabHeaderProps>;
|
|
1214
1584
|
|
|
1215
1585
|
/** Add Member customization (passed through to AddMemberModal) */
|
|
1216
1586
|
addMemberModalTitle?: string;
|
|
@@ -1243,15 +1613,27 @@ export type ChannelInfoProps = {
|
|
|
1243
1613
|
editChannelMaxImageSizeError?: string;
|
|
1244
1614
|
|
|
1245
1615
|
/** Action Labels */
|
|
1616
|
+
/** Custom component for the search panel */
|
|
1617
|
+
MessageSearchPanelComponent?: React.ComponentType<MessageSearchPanelProps>;
|
|
1618
|
+
/** Custom component for the channel settings panel */
|
|
1619
|
+
ChannelSettingsPanelComponent?: React.ComponentType<ChannelSettingsPanelProps>;
|
|
1246
1620
|
actionsSearchLabel?: string;
|
|
1247
1621
|
actionsSettingsLabel?: string;
|
|
1248
1622
|
actionsDeleteLabel?: string;
|
|
1623
|
+
actionsTruncateLabel?: string;
|
|
1249
1624
|
actionsLeaveLabel?: string;
|
|
1625
|
+
actionsPinLabel?: string;
|
|
1626
|
+
actionsUnpinLabel?: string;
|
|
1627
|
+
actionsPinTopicLabel?: string;
|
|
1628
|
+
actionsUnpinTopicLabel?: string;
|
|
1250
1629
|
|
|
1251
1630
|
/** Action callbacks */
|
|
1252
1631
|
onSearchClick?: () => void;
|
|
1253
1632
|
onLeaveChannel?: () => void;
|
|
1254
1633
|
onDeleteChannel?: () => void;
|
|
1634
|
+
onTruncateChannel?: (channel: Channel) => void;
|
|
1635
|
+
onPinChannel?: () => void;
|
|
1636
|
+
onUnpinChannel?: () => void;
|
|
1255
1637
|
onAddMemberClick?: () => void;
|
|
1256
1638
|
onRemoveMember?: (id: string) => void;
|
|
1257
1639
|
onBanMember?: (id: string) => void;
|
|
@@ -1267,11 +1649,17 @@ export type ChannelInfoProps = {
|
|
|
1267
1649
|
actionsUnblockLabel?: string;
|
|
1268
1650
|
actionsCloseTopicLabel?: string;
|
|
1269
1651
|
actionsReopenTopicLabel?: string;
|
|
1652
|
+
actionsDeleteTopicLabel?: string;
|
|
1653
|
+
actionsCreateTopicLabel?: string;
|
|
1654
|
+
onDeleteTopic?: (channel: Channel) => void;
|
|
1655
|
+
onCreateTopic?: (channel: Channel) => void;
|
|
1270
1656
|
|
|
1271
1657
|
/** Settings Panel Topics Labels */
|
|
1272
1658
|
settingsWorkspaceTopicsTitle?: string;
|
|
1273
1659
|
settingsTopicsFeatureName?: string;
|
|
1274
1660
|
settingsTopicsFeatureDescription?: string;
|
|
1661
|
+
/** Custom labels for member roles (owner, moder, member, pending) */
|
|
1662
|
+
roleLabels?: Record<string, string>;
|
|
1275
1663
|
};
|
|
1276
1664
|
|
|
1277
1665
|
/* ----------------------------------------------------------
|
|
@@ -1385,20 +1773,88 @@ export type UserPickerProps = {
|
|
|
1385
1773
|
emptyText?: string;
|
|
1386
1774
|
loadingMoreText?: string;
|
|
1387
1775
|
selectedEmptyLabel?: string;
|
|
1776
|
+
friendsOnly?: boolean;
|
|
1388
1777
|
};
|
|
1389
1778
|
|
|
1390
1779
|
/* ----------------------------------------------------------
|
|
1391
1780
|
Create Channel Modal Props
|
|
1392
1781
|
---------------------------------------------------------- */
|
|
1393
1782
|
|
|
1783
|
+
export type CreateChannelTabsProps = {
|
|
1784
|
+
activeTab: 'messaging' | 'team';
|
|
1785
|
+
onTabChange: (tab: 'messaging' | 'team') => void;
|
|
1786
|
+
disabled?: boolean;
|
|
1787
|
+
directTabLabel?: string;
|
|
1788
|
+
groupTabLabel?: string;
|
|
1789
|
+
};
|
|
1790
|
+
|
|
1791
|
+
export type CreateChannelFooterProps = {
|
|
1792
|
+
tab: 'messaging' | 'team';
|
|
1793
|
+
step: 1 | 2;
|
|
1794
|
+
onCancel: () => void;
|
|
1795
|
+
onNext: () => void;
|
|
1796
|
+
onBack: () => void;
|
|
1797
|
+
onCreate: () => void;
|
|
1798
|
+
isCreating: boolean;
|
|
1799
|
+
isValid: boolean;
|
|
1800
|
+
hasExistingDirectChannel?: boolean;
|
|
1801
|
+
cancelButtonLabel?: string;
|
|
1802
|
+
createButtonLabel?: string;
|
|
1803
|
+
creatingButtonLabel?: string;
|
|
1804
|
+
messageButtonLabel?: string;
|
|
1805
|
+
nextButtonLabel?: string;
|
|
1806
|
+
backButtonLabel?: string;
|
|
1807
|
+
e2eeEnabled?: boolean;
|
|
1808
|
+
};
|
|
1809
|
+
|
|
1810
|
+
export type CreateChannelGroupFieldsProps = {
|
|
1811
|
+
name: string;
|
|
1812
|
+
onNameChange: (name: string) => void;
|
|
1813
|
+
description: string;
|
|
1814
|
+
onDescriptionChange: (desc: string) => void;
|
|
1815
|
+
isPublic: boolean;
|
|
1816
|
+
onPublicChange: (isPublic: boolean) => void;
|
|
1817
|
+
disabled?: boolean;
|
|
1818
|
+
groupNameLabel?: string;
|
|
1819
|
+
groupNamePlaceholder?: string;
|
|
1820
|
+
groupDescriptionLabel?: string;
|
|
1821
|
+
groupDescriptionPlaceholder?: string;
|
|
1822
|
+
groupPublicLabel?: string;
|
|
1823
|
+
e2eeEnabled?: boolean;
|
|
1824
|
+
onE2eeChange?: (enabled: boolean) => void;
|
|
1825
|
+
e2eeLabel?: string;
|
|
1826
|
+
e2eeDescription?: string;
|
|
1827
|
+
e2eeDisabled?: boolean;
|
|
1828
|
+
};
|
|
1829
|
+
|
|
1830
|
+
export type CreateChannelE2eeToggleProps = {
|
|
1831
|
+
enabled: boolean;
|
|
1832
|
+
onChange: (enabled: boolean) => void;
|
|
1833
|
+
disabled?: boolean;
|
|
1834
|
+
label?: string;
|
|
1835
|
+
description?: string;
|
|
1836
|
+
};
|
|
1837
|
+
|
|
1394
1838
|
export type CreateChannelModalProps = {
|
|
1395
1839
|
isOpen: boolean;
|
|
1396
1840
|
onClose: () => void;
|
|
1397
1841
|
onSuccess?: (channel: any) => void; // Uses 'any' or 'Channel' based on context
|
|
1842
|
+
/** Recovery coverage policy for newly created E2EE channels. Defaults to member_assisted. */
|
|
1843
|
+
e2eeRecoveryPolicy?: E2eeRecoveryPolicy;
|
|
1398
1844
|
|
|
1399
1845
|
/** Override visual components */
|
|
1400
1846
|
AvatarComponent?: React.ComponentType<AvatarProps>;
|
|
1401
1847
|
UserItemComponent?: React.ComponentType<UserPickerItemProps>;
|
|
1848
|
+
TabsComponent?: React.ComponentType<CreateChannelTabsProps>;
|
|
1849
|
+
FooterComponent?: React.ComponentType<CreateChannelFooterProps>;
|
|
1850
|
+
GroupFieldsComponent?: React.ComponentType<CreateChannelGroupFieldsProps>;
|
|
1851
|
+
SearchInputComponent?: React.ComponentType<{
|
|
1852
|
+
value: string;
|
|
1853
|
+
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
1854
|
+
placeholder: string;
|
|
1855
|
+
}>;
|
|
1856
|
+
SelectedBoxComponent?: React.ComponentType<UserPickerSelectedBoxProps>;
|
|
1857
|
+
E2eeToggleComponent?: React.ComponentType<CreateChannelE2eeToggleProps>;
|
|
1402
1858
|
|
|
1403
1859
|
/** i18n labels */
|
|
1404
1860
|
title?: string;
|
|
@@ -1415,6 +1871,12 @@ export type CreateChannelModalProps = {
|
|
|
1415
1871
|
createButtonLabel?: string;
|
|
1416
1872
|
creatingButtonLabel?: string;
|
|
1417
1873
|
messageButtonLabel?: string;
|
|
1874
|
+
nextButtonLabel?: string;
|
|
1875
|
+
backButtonLabel?: string;
|
|
1876
|
+
emptyStateLabel?: string;
|
|
1877
|
+
e2eeLabel?: string;
|
|
1878
|
+
e2eeDescription?: string;
|
|
1879
|
+
e2eeUnavailableLabel?: string;
|
|
1418
1880
|
|
|
1419
1881
|
/** File upload configuration for group channel images */
|
|
1420
1882
|
imageAccept?: string;
|