Skip to content

Commit

Permalink
[PAY-906] Mobile chats KeyboardAvoidingView (#3122)
Browse files Browse the repository at this point in the history
  • Loading branch information
dharit-tan authored Mar 29, 2023
1 parent fd00bf2 commit f871a38
Showing 1 changed file with 95 additions and 78 deletions.
173 changes: 95 additions & 78 deletions packages/mobile/src/screens/chat-screen/ChatScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import type { ChatMessage } from '@audius/sdk'
import { Portal } from '@gorhom/portal'
import { useFocusEffect } from '@react-navigation/native'
import { View, Text } from 'react-native'
import { Platform, View, Text, KeyboardAvoidingView } from 'react-native'
import { useDispatch, useSelector } from 'react-redux'

import IconKebabHorizontal from 'app/assets/images/iconKebabHorizontal.svg'
Expand Down Expand Up @@ -135,7 +135,8 @@ export const ChatScreen = () => {
const [inputMessage, setInputMessage] = useState('')
const [shouldShowPopup, setShouldShowPopup] = useState(false)
const messageTop = useRef(0)
const containerBottom = useRef(0)
const chatContainerBottom = useRef(0)
const chatContainerTop = useRef(0)
const [popupChatIndex, setPopupChatIndex] = useState<number | null>(null)

const userId = useSelector(getUserId)
Expand All @@ -148,6 +149,7 @@ export const ChatScreen = () => {
const flatListRef = useRef<FlatListT<ChatMessage>>(null)
const itemsRef = useRef<(View | null)[]>([])
const composeRef = useRef<View | null>(null)
const chatContainerRef = useRef<View | null>(null)
const unreadCount = chat?.unread_message_count ?? 0
const isLoading =
chat?.messagesStatus === Status.LOADING && chatMessages?.length === 0
Expand Down Expand Up @@ -323,7 +325,7 @@ export const ChatScreen = () => {
<ReactionPopup
chatId={chatId}
messageTop={messageTop.current}
containerBottom={containerBottom.current}
containerBottom={chatContainerBottom.current}
hasTail={hasTail(
chatMessages[popupChatIndex],
chatMessages[popupChatIndex - 1]
Expand All @@ -337,86 +339,101 @@ export const ChatScreen = () => {
/>
) : null}
</Portal>
<View style={styles.rootContainer}>
{!isLoading ? (
chatMessages?.length > 0 ? (
<View style={styles.listContainer}>
<FlatList
contentContainerStyle={styles.flatListContainer}
data={chatMessages}
keyExtractor={(message) => message.message_id}
renderItem={({ item, index }) => (
<>
{/* When reaction popup opens, hide reaction here so it doesn't
<View
ref={chatContainerRef}
onLayout={() => {
chatContainerRef.current?.measureInWindow((x, y, width, height) => {
chatContainerTop.current = y
})
}}
>
<KeyboardAvoidingView
keyboardVerticalOffset={
Platform.OS === 'ios' ? chatContainerTop.current : 0
}
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
style={styles.rootContainer}
>
{!isLoading ? (
chatMessages?.length > 0 ? (
<View style={styles.listContainer}>
<FlatList
contentContainerStyle={styles.flatListContainer}
data={chatMessages}
keyExtractor={(message) => message.message_id}
renderItem={({ item, index }) => (
<>
{/* When reaction popup opens, hide reaction here so it doesn't
appear underneath the reaction of the message clone inside the
portal. */}
<ChatMessageListItem
message={item}
ref={(el) => (itemsRef.current[index] = el)}
shouldShowReaction={index !== popupChatIndex}
hasTail={hasTail(item, chatMessages[index - 1])}
onLongPress={() => handleMessagePress(index)}
/>
{index === earliestUnreadIndex ? (
<View style={styles.unreadTagContainer}>
<View style={styles.unreadSeparator} />
<Text style={styles.unreadTag}>
{unreadCount}{' '}
{pluralize(messages.newMessage, unreadCount > 1)}
</Text>
<View style={styles.unreadSeparator} />
</View>
) : null}
</>
)}
onEndReached={handleScrollToTop}
inverted
initialNumToRender={chatMessages?.length}
ref={flatListRef}
onScrollToIndexFailed={handleScrollToIndexFailed}
refreshing={chat?.messagesStatus === Status.LOADING}
/>
</View>
<ChatMessageListItem
message={item}
ref={(el) => (itemsRef.current[index] = el)}
shouldShowReaction={index !== popupChatIndex}
hasTail={hasTail(item, chatMessages[index - 1])}
onLongPress={() => handleMessagePress(index)}
/>
{index === earliestUnreadIndex ? (
<View style={styles.unreadTagContainer}>
<View style={styles.unreadSeparator} />
<Text style={styles.unreadTag}>
{unreadCount}{' '}
{pluralize(messages.newMessage, unreadCount > 1)}
</Text>
<View style={styles.unreadSeparator} />
</View>
) : null}
</>
)}
onEndReached={handleScrollToTop}
inverted
initialNumToRender={chatMessages?.length}
ref={flatListRef}
onScrollToIndexFailed={handleScrollToIndexFailed}
refreshing={chat?.messagesStatus === Status.LOADING}
/>
</View>
) : (
<EmptyChatMessages />
)
) : (
<EmptyChatMessages />
)
) : (
<LoadingSpinner />
)}
<LoadingSpinner />
)}

<View
style={styles.composeView}
onLayout={() => {
composeRef.current?.measureInWindow((x, y, width, height) => {
containerBottom.current = y
})
}}
ref={composeRef}
>
<TextInput
placeholder={messages.startNewMessage}
Icon={() => (
<IconSend
fill={palette.primary}
width={styles.icon.width}
height={styles.icon.height}
opacity={iconOpacity}
onPress={() => handleSubmit(inputMessage)}
/>
)}
styles={{
root: styles.composeTextContainer,
input: styles.composeTextInput
<View
style={styles.composeView}
onLayout={() => {
composeRef.current?.measureInWindow((x, y, width, height) => {
chatContainerBottom.current = y
})
}}
onChangeText={(text) => {
setInputMessage(text)
text ? setIconOpacity(ICON_FOCUS) : setIconOpacity(ICON_BLUR)
}}
onBlur={() => setIconOpacity(ICON_BLUR)}
multiline
value={inputMessage}
/>
</View>
ref={composeRef}
>
<TextInput
placeholder={messages.startNewMessage}
Icon={() => (
<IconSend
fill={palette.primary}
width={styles.icon.width}
height={styles.icon.height}
opacity={iconOpacity}
onPress={() => handleSubmit(inputMessage)}
/>
)}
styles={{
root: styles.composeTextContainer,
input: styles.composeTextInput
}}
onChangeText={(text) => {
setInputMessage(text)
text ? setIconOpacity(ICON_FOCUS) : setIconOpacity(ICON_BLUR)
}}
onBlur={() => setIconOpacity(ICON_BLUR)}
multiline
value={inputMessage}
/>
</View>
</KeyboardAvoidingView>
</View>
</ScreenContent>
</Screen>
Expand Down

0 comments on commit f871a38

Please sign in to comment.