Skip to content

Commit efac0d8

Browse files
committed
refactor: simplify ComponentsContext by deriving type from defaults
- Replace 300-line hand-written ComponentOverrides type with derived type: `Partial<(typeof import('./defaultComponents'))['DEFAULT_COMPONENTS']>` - Remove ~110 type imports from ComponentsContext.tsx (now ~55 lines total) - Add optional component entries to defaultComponents.ts for components with no default (MessageText, PollContent, Input, etc.) - Remove remaining component override props from FileAttachment, StickyHeader, MessageBubble, MessageMenu - Adding a new overridable component now only requires editing defaultComponents.ts — the type is auto-derived
1 parent b90ea46 commit efac0d8

10 files changed

Lines changed: 126 additions & 381 deletions

File tree

package/src/components/Attachment/FileAttachment.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ import { openUrlSafely } from './utils/openUrlSafely';
77

88
import { FileIconProps } from '../../components/Attachment/FileIcon';
99

10-
import {
11-
ComponentOverrides,
12-
useComponentsContext,
13-
} from '../../contexts/componentsContext/ComponentsContext';
10+
import { useComponentsContext } from '../../contexts/componentsContext/ComponentsContext';
1411
import {
1512
MessageContextValue,
1613
useMessageContext,
@@ -25,7 +22,6 @@ export type FileAttachmentPropsWithContext = Pick<
2522
MessageContextValue,
2623
'onLongPress' | 'onPress' | 'onPressIn' | 'preventPress'
2724
> &
28-
Pick<Required<ComponentOverrides>, 'FilePreview'> &
2925
Pick<MessagesContextValue, 'additionalPressableProps'> & {
3026
/** The attachment to render */
3127
attachment: Attachment;
@@ -46,13 +42,13 @@ const FileAttachmentWithContext = (props: FileAttachmentPropsWithContext) => {
4642
additionalPressableProps,
4743
attachment,
4844
attachmentIconSize,
49-
FilePreview,
5045
onLongPress,
5146
onPress,
5247
onPressIn,
5348
preventPress,
5449
styles: stylesProp = styles,
5550
} = props;
51+
const { FilePreview } = useComponentsContext();
5652

5753
const defaultOnPress = () => openUrlSafely(attachment.asset_url);
5854

@@ -104,18 +100,13 @@ export type FileAttachmentProps = Partial<Omit<FileAttachmentPropsWithContext, '
104100
Pick<FileAttachmentPropsWithContext, 'attachment'>;
105101

106102
export const FileAttachment = (props: FileAttachmentProps) => {
107-
const { FilePreview: PropFilePreview } = props;
108103
const { onLongPress, onPress, onPressIn, preventPress } = useMessageContext();
109-
const { FilePreview: ComponentsFilePreview } = useComponentsContext();
110104
const { additionalPressableProps } = useMessagesContext();
111105

112-
const FilePreview = PropFilePreview || ComponentsFilePreview;
113-
114106
return (
115107
<FileAttachmentWithContext
116108
{...{
117109
additionalPressableProps,
118-
FilePreview,
119110
onLongPress,
120111
onPress,
121112
onPressIn,

package/src/components/Message/MessageItemView/MessageBubble.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,23 @@ import Animated, {
1313
import { MessageItemViewPropsWithContext } from './MessageItemView';
1414

1515
import { useTheme } from '../../../contexts';
16-
import type { ComponentOverrides } from '../../../contexts/componentsContext/ComponentsContext';
16+
import { useComponentsContext } from '../../../contexts/componentsContext/ComponentsContext';
1717

1818
import { NativeHandlers } from '../../../native';
1919

2020
const AnimatedWrapper = Animated.createAnimatedComponent(View);
2121

22-
type SwipableMessageWrapperProps = Pick<Required<ComponentOverrides>, 'MessageSwipeContent'> &
23-
Pick<MessageItemViewPropsWithContext, 'messageSwipeToReplyHitSlop'> & {
24-
children: ReactNode;
25-
onSwipe: () => void;
26-
};
22+
type SwipableMessageWrapperProps = Pick<
23+
MessageItemViewPropsWithContext,
24+
'messageSwipeToReplyHitSlop'
25+
> & {
26+
children: ReactNode;
27+
onSwipe: () => void;
28+
};
2729

2830
export const SwipableMessageWrapper = React.memo((props: SwipableMessageWrapperProps) => {
29-
const { MessageSwipeContent, children, messageSwipeToReplyHitSlop, onSwipe } = props;
31+
const { children, messageSwipeToReplyHitSlop, onSwipe } = props;
32+
const { MessageSwipeContent } = useComponentsContext();
3033
const isRTL = I18nManager.isRTL;
3134
const swipeDirectionMultiplier = isRTL ? -1 : 1;
3235

package/src/components/Message/MessageItemView/MessageItemView.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,6 @@ const MessageItemViewWithContext = (props: MessageItemViewPropsWithContext) => {
248248
MessageHeader,
249249
MessageReplies,
250250
MessageSpacer,
251-
MessageSwipeContent,
252251
ReactionListBottom,
253252
ReactionListTop,
254253
} = useComponentsContext();
@@ -366,7 +365,6 @@ const MessageItemViewWithContext = (props: MessageItemViewPropsWithContext) => {
366365

367366
return enableSwipeToReply && !isMessageTypeDeleted ? (
368367
<SwipableMessageWrapper
369-
MessageSwipeContent={MessageSwipeContent}
370368
messageSwipeToReplyHitSlop={messageSwipeToReplyHitSlop}
371369
onSwipe={onSwipeActionHandler}
372370
>

package/src/components/MessageList/MessageFlashList.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,6 @@ const MessageFlashListWithContext = (props: MessageFlashListPropsWithContext) =>
294294
threadList = false,
295295
} = props;
296296
const {
297-
DateHeader,
298297
EmptyStateIndicator,
299298
LoadingIndicator,
300299
NetworkDownIndicator,
@@ -1078,7 +1077,7 @@ const MessageFlashListWithContext = (props: MessageFlashListPropsWithContext) =>
10781077
)}
10791078
<View style={styles.stickyHeaderContainer}>
10801079
{messageListLengthAfterUpdate && StickyHeader ? (
1081-
<StickyHeader date={stickyHeaderDate} DateHeader={DateHeader} />
1080+
<StickyHeader date={stickyHeaderDate} />
10821081
) : null}
10831082
</View>
10841083
<Animated.View

package/src/components/MessageList/MessageList.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,6 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
348348
threadHasMore,
349349
} = props;
350350
const {
351-
DateHeader,
352351
EmptyStateIndicator,
353352
LoadingIndicator,
354353
NetworkDownIndicator,
@@ -1295,7 +1294,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
12951294
)}
12961295
<View style={styles.stickyHeaderContainer}>
12971296
{messageListLengthAfterUpdate && StickyHeader ? (
1298-
<StickyHeader date={stickyHeaderDate} DateHeader={DateHeader} />
1297+
<StickyHeader date={stickyHeaderDate} />
12991298
) : null}
13001299
</View>
13011300
{scrollToBottomButtonVisible ? (

package/src/components/MessageList/StickyHeader.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import React, { useMemo } from 'react';
22

3-
import type { ComponentOverrides } from '../../contexts/componentsContext/ComponentsContext';
3+
import { useComponentsContext } from '../../contexts/componentsContext/ComponentsContext';
44
import { useTranslationContext } from '../../contexts/translationContext/TranslationContext';
55

66
import { getDateString } from '../../utils/i18n/getDateString';
77

88
/**
99
* Props for the StickyHeader component.
1010
*/
11-
export type StickyHeaderProps = Pick<Required<ComponentOverrides>, 'DateHeader'> & {
11+
export type StickyHeaderProps = {
1212
/**
1313
* Date to be displayed in the sticky header.
1414
*/
@@ -19,7 +19,8 @@ export type StickyHeaderProps = Pick<Required<ComponentOverrides>, 'DateHeader'>
1919
dateString?: string | number;
2020
};
2121

22-
export const StickyHeader = ({ date, DateHeader, dateString }: StickyHeaderProps) => {
22+
export const StickyHeader = ({ date, dateString }: StickyHeaderProps) => {
23+
const { DateHeader } = useComponentsContext();
2324
const { t, tDateTimeParser } = useTranslationContext();
2425

2526
const stickyHeaderDateString = useMemo(() => {

package/src/components/MessageMenu/MessageMenu.tsx

Lines changed: 35 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,59 +4,47 @@ import { useWindowDimensions } from 'react-native';
44

55
import { MessageActionType } from './MessageActionListItem';
66

7-
import type { ComponentOverrides } from '../../contexts/componentsContext/ComponentsContext';
87
import { MessageContextValue } from '../../contexts/messageContext/MessageContext';
98
import { useTheme } from '../../contexts/themeContext/ThemeContext';
109
import { BottomSheetModal } from '../UIComponents/BottomSheetModal';
1110

1211
export type MessageMenuProps = PropsWithChildren<
13-
Partial<
14-
Pick<
15-
ComponentOverrides,
16-
| 'MessageActionList'
17-
| 'MessageActionListItem'
18-
| 'MessageReactionPicker'
19-
| 'MessageUserReactions'
20-
| 'MessageUserReactionsAvatar'
21-
| 'MessageUserReactionsItem'
22-
>
23-
> &
24-
Partial<Pick<MessageContextValue, 'message'>> & {
25-
/**
26-
* Function to close the message actions bottom sheet
27-
* @returns void
28-
*/
29-
dismissOverlay: () => void;
30-
/**
31-
* An array of message actions to render
32-
*/
33-
messageActions: MessageActionType[];
34-
/**
35-
* Boolean to determine if there are message actions
36-
*/
37-
showMessageReactions: boolean;
38-
/**
39-
* Boolean to determine if the overlay is visible.
40-
*/
41-
visible: boolean;
42-
/**
43-
* Function to handle reaction on press
44-
* @param reactionType
45-
* @returns
46-
*/
47-
handleReaction?: (reactionType: string) => Promise<void>;
48-
/**
49-
* The selected reaction
50-
*/
51-
selectedReaction?: string;
12+
Partial<Pick<MessageContextValue, 'message'>> & {
13+
/**
14+
* Function to close the message actions bottom sheet
15+
* @returns void
16+
*/
17+
dismissOverlay: () => void;
18+
/**
19+
* An array of message actions to render
20+
*/
21+
messageActions: MessageActionType[];
22+
/**
23+
* Boolean to determine if there are message actions
24+
*/
25+
showMessageReactions: boolean;
26+
/**
27+
* Boolean to determine if the overlay is visible.
28+
*/
29+
visible: boolean;
30+
/**
31+
* Function to handle reaction on press
32+
* @param reactionType
33+
* @returns
34+
*/
35+
handleReaction?: (reactionType: string) => Promise<void>;
36+
/**
37+
* The selected reaction
38+
*/
39+
selectedReaction?: string;
5240

53-
layout: {
54-
x: number;
55-
y: number;
56-
w: number;
57-
h: number;
58-
};
59-
}
41+
layout: {
42+
x: number;
43+
y: number;
44+
w: number;
45+
h: number;
46+
};
47+
}
6048
>;
6149

6250
// TODO: V9: Either remove this or refactor it so that it's useful again, as its logic

0 commit comments

Comments
 (0)