Skip to content

Commit 15a81ca

Browse files
committed
refactor: extract ChatFooter into own component and file
1 parent 2df5b6f commit 15a81ca

File tree

2 files changed

+86
-57
lines changed

2 files changed

+86
-57
lines changed

src/CuteChat.tsx

Lines changed: 11 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ import {
1515
FlatList,
1616
NativeScrollEvent,
1717
StyleProp,
18-
TouchableOpacity,
19-
View,
2018
ViewStyle,
2119
} from 'react-native';
2220
import type { IMessage } from 'react-native-gifted-chat';
@@ -25,6 +23,7 @@ import { appendSnapshot } from './utils/appendSnapshot';
2523
import { prepareSnapshot } from './utils/prepareSnapshot';
2624
import { isCloseToBottom } from './utils/isCloseToBottom';
2725
import { isCloseToTop } from './utils/isCloseToTop';
26+
import { ChatFooter } from './components/ChatFooter/ChatFooter';
2827

2928
interface CustomCuteChatProps {
3029
chatId: string;
@@ -60,6 +59,8 @@ export function CuteChat(props: CuteChatProps) {
6059
const memoizedUser = useMemo(() => ({ _id: user.id, ...user }), [user]);
6160
const startDate = useMemo(() => new Date(), []);
6261

62+
const chatRef = useRef<FlatList<IMessage>>(null);
63+
6364
const setIsLoadingBool = useCallback(
6465
(isLoading: boolean) => {
6566
setIsLoading?.(isLoading);
@@ -296,12 +297,6 @@ export function CuteChat(props: CuteChatProps) {
296297

297298
console.log('Close to top:', closeToTop);
298299

299-
const chatRef = useRef<FlatList<IMessage>>(null);
300-
301-
const scrollToBottom = () => {
302-
chatRef.current?.scrollToOffset({ offset: 0, animated: true });
303-
};
304-
305300
return (
306301
<GiftedChat
307302
{...props}
@@ -310,55 +305,14 @@ export function CuteChat(props: CuteChatProps) {
310305
// - New messages banner
311306
renderChatFooter={() => (
312307
<>
313-
<View
314-
style={{
315-
display: 'flex',
316-
position: 'absolute',
317-
flexDirection: 'row',
318-
justifyContent: 'flex-start',
319-
backgroundColor: 'rgba(255, 255, 255, 0.8)',
320-
width: '100%',
321-
height: 100,
322-
bottom: 0,
323-
left: 0,
324-
}}
325-
>
326-
<View style={{ display: 'flex', flex: 1 }}></View>
327-
<View style={{ display: 'flex', flex: 1 }}>
328-
{!closeToTop && props.newMessagesBannerComponent && (
329-
<TouchableOpacity
330-
onPress={scrollToBottom}
331-
style={
332-
props.newMessagesBannerStyles ?? {
333-
alignSelf: 'center',
334-
backgroundColor: 'rgba(255, 255, 255, 0.8)',
335-
padding: 10,
336-
borderRadius: 100,
337-
}
338-
}
339-
>
340-
{props.newMessagesBannerComponent()}
341-
</TouchableOpacity>
342-
)}
343-
</View>
344-
<View style={{ display: 'flex', flex: 1 }}>
345-
{!closeToTop && props.scrollToBottomComponent && (
346-
<TouchableOpacity
347-
onPress={scrollToBottom}
348-
style={
349-
props.scrollToBottomStyle ?? {
350-
alignSelf: 'flex-end',
351-
backgroundColor: 'rgba(255, 255, 255, 0.8)',
352-
padding: 10,
353-
borderRadius: 100,
354-
}
355-
}
356-
>
357-
{props.scrollToBottomComponent()}
358-
</TouchableOpacity>
359-
)}
360-
</View>
361-
</View>
308+
<ChatFooter
309+
newMessagesBannerComponent={props.newMessagesBannerComponent}
310+
newMessagesBannerStyles={props.newMessagesBannerStyles}
311+
scrollToBottomComponent={props.scrollToBottomComponent}
312+
scrollToBottomStyle={props.scrollToBottomStyle}
313+
closeToTop={closeToTop}
314+
chatRef={chatRef}
315+
/>
362316
{props.renderChatFooter?.()}
363317
</>
364318
)}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { ReactNode, RefObject } from 'react';
2+
import {
3+
FlatList,
4+
StyleProp,
5+
TouchableOpacity,
6+
View,
7+
ViewStyle,
8+
} from 'react-native';
9+
import { IMessage } from 'react-native-gifted-chat';
10+
11+
export const ChatFooter = (props: {
12+
newMessagesBannerComponent?: () => ReactNode;
13+
newMessagesBannerStyles?: StyleProp<ViewStyle>;
14+
scrollToBottomComponent?: () => ReactNode;
15+
scrollToBottomStyle?: StyleProp<ViewStyle>;
16+
17+
closeToTop: boolean;
18+
chatRef: RefObject<FlatList<IMessage>>;
19+
}) => {
20+
const scrollToBottom = () => {
21+
props.chatRef.current?.scrollToOffset({ offset: 0, animated: true });
22+
};
23+
24+
return (
25+
<View
26+
style={{
27+
display: 'flex',
28+
position: 'absolute',
29+
flexDirection: 'row',
30+
justifyContent: 'flex-start',
31+
backgroundColor: 'rgba(255, 255, 255, 0.8)',
32+
width: '100%',
33+
height: 100,
34+
bottom: 0,
35+
left: 0,
36+
}}
37+
>
38+
<View style={{ display: 'flex', flex: 1 }}></View>
39+
<View style={{ display: 'flex', flex: 1 }}>
40+
{!props.closeToTop && props.newMessagesBannerComponent && (
41+
<TouchableOpacity
42+
onPress={scrollToBottom}
43+
style={
44+
props.newMessagesBannerStyles ?? {
45+
alignSelf: 'center',
46+
backgroundColor: 'rgba(255, 255, 255, 0.8)',
47+
padding: 10,
48+
borderRadius: 100,
49+
}
50+
}
51+
>
52+
{props.newMessagesBannerComponent()}
53+
</TouchableOpacity>
54+
)}
55+
</View>
56+
<View style={{ display: 'flex', flex: 1 }}>
57+
{!props.closeToTop && props.scrollToBottomComponent && (
58+
<TouchableOpacity
59+
onPress={scrollToBottom}
60+
style={
61+
props.scrollToBottomStyle ?? {
62+
alignSelf: 'flex-end',
63+
backgroundColor: 'rgba(255, 255, 255, 0.8)',
64+
padding: 10,
65+
borderRadius: 100,
66+
}
67+
}
68+
>
69+
{props.scrollToBottomComponent()}
70+
</TouchableOpacity>
71+
)}
72+
</View>
73+
</View>
74+
);
75+
};

0 commit comments

Comments
 (0)