Skip to content

Commit 97a834f

Browse files
committed
fix:typescipt and forwardRef fix
1 parent ae616d6 commit 97a834f

File tree

4 files changed

+172
-117
lines changed

4 files changed

+172
-117
lines changed

examples/SampleApp/src/components/BottomTabs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ export const BottomTabs: React.FC<BottomTabBarProps> = (props) => {
8181

8282
const onPress = () => {
8383
navigation.emit({
84+
canPreventDefault: true,
8485
target: route.key,
8586
type: 'tabPress',
86-
canPreventDefault: true,
8787
});
8888
if (!isFocused) {
8989
navigation.navigate(route.name);

examples/SampleApp/src/components/MessageSearch/MessageSearchList.tsx

Lines changed: 124 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -72,118 +72,133 @@ export type MessageSearchListProps = {
7272
refreshing: boolean;
7373
refreshList: () => void;
7474
showResultCount?: boolean;
75-
scrollRef: React.Ref<FlatList<any>>;
7675
};
77-
export const MessageSearchList: React.FC<MessageSearchListProps> = ({
78-
EmptySearchIndicator,
79-
loading,
80-
loadMore,
81-
messages,
82-
refreshing,
83-
refreshList,
84-
showResultCount = false,
85-
scrollRef,
86-
}) => {
87-
const {
88-
theme: {
89-
colors: { black, border, grey, white_snow },
90-
},
91-
} = useTheme();
92-
const navigation = useNavigation();
93-
94-
if (loading && !refreshing && (!messages || messages.length === 0)) {
95-
return (
96-
<View style={styles.indicatorContainer}>
97-
<Spinner />
98-
</View>
99-
);
100-
}
101-
if (!messages && !refreshing) return null;
76+
export const MessageSearchList: React.FC<MessageSearchListProps> = React.forwardRef(
77+
(
78+
props,
79+
scrollRef: React.Ref<FlatList<
80+
MessageResponse<
81+
LocalAttachmentType,
82+
LocalChannelType,
83+
LocalCommandType,
84+
LocalMessageType,
85+
LocalReactionType,
86+
LocalUserType
87+
>
88+
> | null>,
89+
) => {
90+
const {
91+
EmptySearchIndicator,
92+
loading,
93+
loadMore,
94+
messages,
95+
refreshing,
96+
refreshList,
97+
showResultCount = false,
98+
} = props;
99+
const {
100+
theme: {
101+
colors: { black, border, grey, white_snow },
102+
},
103+
} = useTheme();
104+
const navigation = useNavigation();
102105

103-
return (
104-
<>
105-
{messages && showResultCount && (
106-
<View
107-
style={{
108-
backgroundColor: white_snow,
109-
paddingHorizontal: 10,
110-
paddingVertical: 2,
111-
}}
112-
>
113-
<Text style={{ color: grey }}>
114-
{`${messages.length >= MESSAGE_SEARCH_LIMIT ? MESSAGE_SEARCH_LIMIT : messages.length}${
115-
messages.length >= MESSAGE_SEARCH_LIMIT ? '+ ' : ' '
116-
} result${messages.length === 1 ? '' : 's'}`}
117-
</Text>
106+
if (loading && !refreshing && (!messages || messages.length === 0)) {
107+
return (
108+
<View style={styles.indicatorContainer}>
109+
<Spinner />
118110
</View>
119-
)}
120-
<FlatList
121-
contentContainerStyle={styles.contentContainer}
122-
// TODO: Remove the following filter once we have two way scroll functionality on threads.
123-
data={messages ? messages.filter(({ parent_id }) => !parent_id) : []}
124-
keyboardDismissMode='on-drag'
125-
ListEmptyComponent={EmptySearchIndicator}
126-
onEndReached={loadMore}
127-
onRefresh={refreshList}
128-
refreshing={refreshing}
129-
ref={scrollRef}
130-
renderItem={({ item }) => (
131-
<TouchableOpacity
132-
onPress={() => {
133-
navigation.navigate('ChannelScreen', {
134-
channelId: item.channel?.id,
135-
messageId: item.id,
136-
});
111+
);
112+
}
113+
if (!messages && !refreshing) return null;
114+
115+
return (
116+
<>
117+
{messages && showResultCount && (
118+
<View
119+
style={{
120+
backgroundColor: white_snow,
121+
paddingHorizontal: 10,
122+
paddingVertical: 2,
137123
}}
138-
style={[styles.itemContainer, { borderBottomColor: border }]}
139-
testID='channel-preview-button'
140124
>
141-
<Avatar image={item.user?.image} name={item.user?.name} size={40} />
142-
<View style={styles.flex}>
143-
<View style={styles.row}>
144-
<Text numberOfLines={1} style={[styles.titleContainer, { color: black }]}>
145-
<Text style={styles.title}>{`${item.user?.name} `}</Text>
146-
{!!item.channel?.name && (
147-
<Text style={styles.detailsText}>
148-
in
149-
<Text style={styles.title}>{` ${item.channel?.name}`}</Text>
150-
</Text>
151-
)}
152-
</Text>
153-
</View>
154-
<View style={styles.row}>
155-
<Text
156-
numberOfLines={1}
157-
style={[
158-
styles.message,
159-
{
160-
color: grey,
161-
},
162-
]}
163-
>
164-
{item.text}
165-
</Text>
166-
<Text
167-
style={[
168-
styles.date,
169-
{
170-
color: grey,
171-
},
172-
]}
173-
>
174-
{dayjs(item.created_at).calendar(undefined, {
175-
lastDay: 'DD/MM', // The day before ( Yesterday at 2:30 AM )
176-
lastWeek: 'DD/MM', // Last week ( Last Monday at 2:30 AM )
177-
sameDay: 'h:mm A', // The same day ( Today at 2:30 AM )
178-
sameElse: 'DD/MM/YYYY', // Everything else ( 17/10/2011 )
179-
})}
180-
</Text>
181-
</View>
182-
</View>
183-
</TouchableOpacity>
125+
<Text style={{ color: grey }}>
126+
{`${
127+
messages.length >= MESSAGE_SEARCH_LIMIT ? MESSAGE_SEARCH_LIMIT : messages.length
128+
}${messages.length >= MESSAGE_SEARCH_LIMIT ? '+ ' : ' '} result${
129+
messages.length === 1 ? '' : 's'
130+
}`}
131+
</Text>
132+
</View>
184133
)}
185-
style={styles.flex}
186-
/>
187-
</>
188-
);
189-
};
134+
<FlatList
135+
contentContainerStyle={styles.contentContainer}
136+
// TODO: Remove the following filter once we have two way scroll functionality on threads.
137+
data={messages ? messages.filter(({ parent_id }) => !parent_id) : []}
138+
keyboardDismissMode='on-drag'
139+
ListEmptyComponent={EmptySearchIndicator}
140+
onEndReached={loadMore}
141+
onRefresh={refreshList}
142+
ref={scrollRef}
143+
refreshing={refreshing}
144+
renderItem={({ item }) => (
145+
<TouchableOpacity
146+
onPress={() => {
147+
navigation.navigate('ChannelScreen', {
148+
channelId: item.channel?.id,
149+
messageId: item.id,
150+
});
151+
}}
152+
style={[styles.itemContainer, { borderBottomColor: border }]}
153+
testID='channel-preview-button'
154+
>
155+
<Avatar image={item.user?.image} name={item.user?.name} size={40} />
156+
<View style={styles.flex}>
157+
<View style={styles.row}>
158+
<Text numberOfLines={1} style={[styles.titleContainer, { color: black }]}>
159+
<Text style={styles.title}>{`${item.user?.name} `}</Text>
160+
{!!item.channel?.name && (
161+
<Text style={styles.detailsText}>
162+
in
163+
<Text style={styles.title}>{` ${item.channel?.name}`}</Text>
164+
</Text>
165+
)}
166+
</Text>
167+
</View>
168+
<View style={styles.row}>
169+
<Text
170+
numberOfLines={1}
171+
style={[
172+
styles.message,
173+
{
174+
color: grey,
175+
},
176+
]}
177+
>
178+
{item.text}
179+
</Text>
180+
<Text
181+
style={[
182+
styles.date,
183+
{
184+
color: grey,
185+
},
186+
]}
187+
>
188+
{dayjs(item.created_at).calendar(undefined, {
189+
lastDay: 'DD/MM', // The day before ( Yesterday at 2:30 AM )
190+
lastWeek: 'DD/MM', // Last week ( Last Monday at 2:30 AM )
191+
sameDay: 'h:mm A', // The same day ( Today at 2:30 AM )
192+
sameElse: 'DD/MM/YYYY', // Everything else ( 17/10/2011 )
193+
})}
194+
</Text>
195+
</View>
196+
</View>
197+
</TouchableOpacity>
198+
)}
199+
style={styles.flex}
200+
/>
201+
</>
202+
);
203+
},
204+
);

examples/SampleApp/src/screens/ChannelListScreen.tsx

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useContext, useMemo, useRef, useState } from 'react';
22
import { FlatList, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native';
33
import { useNavigation, useScrollToTop } from '@react-navigation/native';
44
import { ChannelList, CircleClose, Search, useTheme } from 'stream-chat-react-native';
5-
5+
import { Channel } from 'stream-chat';
66
import { ChannelPreview } from '../components/ChannelPreview';
77
import { ChatScreenHeader } from '../components/ChatScreenHeader';
88
import { MessageSearchList } from '../components/MessageSearch/MessageSearchList';
@@ -76,7 +76,17 @@ export const ChannelListScreen: React.FC = () => {
7676
} = useTheme();
7777

7878
const searchInputRef = useRef<TextInput | null>(null);
79-
const scrollRef = useRef<FlatList<any>>(null);
79+
const scrollRef = useRef<FlatList<
80+
Channel<
81+
LocalAttachmentType,
82+
LocalChannelType,
83+
LocalCommandType,
84+
LocalMessageType,
85+
LocalEventType,
86+
LocalReactionType,
87+
LocalUserType
88+
>
89+
> | null>(null);
8090

8191
const [searchInputText, setSearchInputText] = useState('');
8292
const [searchQuery, setSearchQuery] = useState('');
@@ -108,7 +118,19 @@ export const ChannelListScreen: React.FC = () => {
108118

109119
if (!chatClient) return null;
110120

111-
const setScrollRef = (ref: React.RefObject<FlatList<any>>) => {
121+
const setScrollRef = (
122+
ref: React.RefObject<FlatList<
123+
Channel<
124+
LocalAttachmentType,
125+
LocalChannelType,
126+
LocalCommandType,
127+
LocalMessageType,
128+
LocalEventType,
129+
LocalReactionType,
130+
LocalUserType
131+
>
132+
> | null>,
133+
) => {
112134
scrollRef.current = ref;
113135
};
114136

@@ -173,10 +195,10 @@ export const ChannelListScreen: React.FC = () => {
173195
loading={loading}
174196
loadMore={loadMore}
175197
messages={messages}
198+
ref={scrollRef}
176199
refreshing={refreshing}
177200
refreshList={refreshList}
178201
showResultCount
179-
scrollRef={scrollRef}
180202
/>
181203
)}
182204
<View style={{ flex: searchQuery ? 0 : 1 }}>
@@ -208,8 +230,8 @@ export const ChannelListScreen: React.FC = () => {
208230
}}
209231
options={options}
210232
Preview={ChannelPreview}
211-
sort={sort}
212233
setFlatListRef={setScrollRef}
234+
sort={sort}
213235
/>
214236
</View>
215237
</View>

examples/SampleApp/src/screens/MentionsScreen.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { useContext, useMemo, useRef } from 'react';
22
import { FlatList, StyleSheet, Text, View } from 'react-native';
33
import { AtMentions, useTheme } from 'stream-chat-react-native';
4+
import { MessageResponse } from 'stream-chat';
45

56
import { ChatScreenHeader } from '../components/ChatScreenHeader';
67
import { MessageSearchList } from '../components/MessageSearch/MessageSearchList';
@@ -11,6 +12,14 @@ import type { StackNavigationProp } from '@react-navigation/stack';
1112

1213
import type { BottomTabNavigatorParamList } from '../types';
1314
import { AppContext } from '../context/AppContext';
15+
import type {
16+
LocalAttachmentType,
17+
LocalChannelType,
18+
LocalCommandType,
19+
LocalMessageType,
20+
LocalReactionType,
21+
LocalUserType,
22+
} from '../types';
1423

1524
const styles = StyleSheet.create({
1625
container: {
@@ -62,7 +71,16 @@ export const MentionsScreen: React.FC<MentionsScreenProps> = () => {
6271
[chatClient],
6372
);
6473

65-
const scrollRef = useRef<FlatList<any>>(null);
74+
const scrollRef = useRef<FlatList<
75+
MessageResponse<
76+
LocalAttachmentType,
77+
LocalChannelType,
78+
LocalCommandType,
79+
LocalMessageType,
80+
LocalReactionType,
81+
LocalUserType
82+
>
83+
> | null>(null);
6684

6785
useScrollToTop(scrollRef);
6886

@@ -84,9 +102,9 @@ export const MentionsScreen: React.FC<MentionsScreenProps> = () => {
84102
loading={loading}
85103
loadMore={loadMore}
86104
messages={messages}
105+
ref={scrollRef}
87106
refreshing={refreshing}
88107
refreshList={refreshList}
89-
scrollRef={scrollRef}
90108
/>
91109
</View>
92110
);

0 commit comments

Comments
 (0)