diff options
author | Ivan Chen <ivan@tagg.id> | 2021-04-14 23:13:37 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-14 23:13:37 -0400 |
commit | 2137c337f372e55d204b33f9f7a6f081af2c9892 (patch) | |
tree | d01b5b581c9eebec93731ec51be5f8a9aa4d1a0e /src | |
parent | 2051515252c335ff71242830bdbd30331ab783d1 (diff) | |
parent | 0dc9a8cc06ec8e0208989ceb007faad201d89f28 (diff) |
Merge pull request #363 from shravyaramesh/chat-theme
[TMA-770, 776] Message Bubble and Tagg Indicator
Diffstat (limited to 'src')
-rw-r--r-- | src/components/messages/MessageAvatar.tsx | 44 | ||||
-rw-r--r-- | src/components/messages/TypingIndicator.tsx | 30 | ||||
-rw-r--r-- | src/components/messages/index.ts | 2 | ||||
-rw-r--r-- | src/screens/chat/ChatScreen.tsx | 72 |
4 files changed, 143 insertions, 5 deletions
diff --git a/src/components/messages/MessageAvatar.tsx b/src/components/messages/MessageAvatar.tsx new file mode 100644 index 00000000..d275eae5 --- /dev/null +++ b/src/components/messages/MessageAvatar.tsx @@ -0,0 +1,44 @@ +import React, {useContext} from 'react'; +import {Image, StyleSheet, View} from 'react-native'; +import {getMember, normalize} from '../../utils'; +import {useMessageContext} from 'stream-chat-react-native-core'; +import {useStore} from 'react-redux'; +import {ChatContext} from '../../App'; + +const MessageAvatar: React.FC = () => { + const {channel} = useContext(ChatContext); + const state = useStore().getState(); + const member = getMember(channel, state); + const message = useMessageContext(); + + return ( + <View style={styles.messageAvatarContainer}> + {message.lastGroupMessage === true && ( + <Image + style={styles.messageAvatar} + source={ + member + ? {uri: member.user?.thumbnail_url} + : require('../../assets/images/avatar-placeholder.png') + } + /> + )} + </View> + ); +}; + +const styles = StyleSheet.create({ + messageAvatarContainer: { + width: normalize(20), + zIndex: 1, + bottom: 20, + marginRight: '2%', + }, + messageAvatar: { + borderRadius: 50, + width: normalize(18), + height: normalize(18), + }, +}); + +export default MessageAvatar; diff --git a/src/components/messages/TypingIndicator.tsx b/src/components/messages/TypingIndicator.tsx new file mode 100644 index 00000000..be7141a2 --- /dev/null +++ b/src/components/messages/TypingIndicator.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import {View, Image, StyleSheet} from 'react-native'; +import {SCREEN_WIDTH} from '../../utils'; + +const TypingIndicator: React.FC = () => { + return ( + <View style={styles.typingIndicatorContainer}> + <Image + source={require('../../assets/gifs/loading-animation.gif')} + style={{width: 88, height: 49}} + /> + </View> + ); +}; + +const styles = StyleSheet.create({ + typingIndicatorContainer: { + backgroundColor: '#E4F0F2', + width: 88, + height: 32, + borderRadius: 10, + marginBottom: 10, + marginLeft: SCREEN_WIDTH * 0.09, + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', + }, +}); + +export default TypingIndicator; diff --git a/src/components/messages/index.ts b/src/components/messages/index.ts index c809d3d1..d08e9454 100644 --- a/src/components/messages/index.ts +++ b/src/components/messages/index.ts @@ -3,3 +3,5 @@ export {default as ChannelPreview} from './ChannelPreview'; export {default as ChatInput} from './ChatInput'; export {default as ChatHeader} from './ChatHeader'; export {default as ChatInputSubmit} from './ChatInputSubmit'; +export {default as MessageAvatar} from './MessageAvatar'; +export {default as TypingIndicator} from './TypingIndicator'; diff --git a/src/screens/chat/ChatScreen.tsx b/src/screens/chat/ChatScreen.tsx index 161bd07d..656c1c47 100644 --- a/src/screens/chat/ChatScreen.tsx +++ b/src/screens/chat/ChatScreen.tsx @@ -6,15 +6,23 @@ import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context'; import { Channel, Chat, + DeepPartial, MessageInput, MessageList, useAttachmentPickerContext, + Theme, } from 'stream-chat-react-native'; import {ChatContext} from '../../App'; -import {ChatHeader, ChatInput, TabsGradient} from '../../components'; +import { + ChatHeader, + ChatInput, + MessageAvatar, + TabsGradient, + TypingIndicator, +} from '../../components'; import {MainStackParams} from '../../routes'; import {ScreenType} from '../../types'; -import {HeaderHeight, isIPhoneX} from '../../utils'; +import {HeaderHeight, isIPhoneX, normalize, SCREEN_WIDTH} from '../../utils'; type ChatScreenNavigationProp = StackNavigationProp<MainStackParams, 'Chat'>; interface ChatScreenProps { @@ -28,11 +36,12 @@ const ChatScreen: React.FC<ChatScreenProps> = () => { const tabbarHeight = useBottomTabBarHeight(); const {setTopInset} = useAttachmentPickerContext(); const insets = useSafeAreaInsets(); - - const chatTheme = { + const chatTheme: DeepPartial<Theme> = { messageList: { container: { backgroundColor: 'white', + width: SCREEN_WIDTH * 0.95, + alignSelf: 'center', }, }, messageInput: { @@ -41,6 +50,56 @@ const ChatScreen: React.FC<ChatScreenProps> = () => { height: 70, }, }, + avatar: { + container: { + borderRadius: 10, + width: normalize(18), + height: normalize(18), + }, + }, + messageSimple: { + avatarWrapper: { + container: { + width: normalize(20), + zIndex: 1, + bottom: 20, + }, + }, + container: { + paddingTop: 8, + flexDirection: 'row', + }, + content: { + metaContainer: { + marginLeft: 5, + }, + container: {}, + containerInner: { + backgroundColor: '#E4F0F2', + borderColor: 'transparent', + borderBottomLeftRadius: 10, + borderTopLeftRadius: 10, + borderBottomRightRadius: 10, + borderTopRightRadius: 10, + }, + }, + status: { + statusContainer: {}, + }, + }, + }; + + const loggedInUsersMessageTheme = { + messageSimple: { + content: { + containerInner: { + backgroundColor: '#DEE6F4', + }, + container: { + left: 0, + }, + }, + }, }; useEffect(() => { @@ -63,7 +122,10 @@ const ChatScreen: React.FC<ChatScreenProps> = () => { messageActions={({copyMessage, deleteMessage}) => [ copyMessage, deleteMessage, - ]}> + ]} + TypingIndicator={TypingIndicator} + myMessageTheme={loggedInUsersMessageTheme} + MessageAvatar={MessageAvatar}> <MessageList onThreadSelect={() => {}} /> {/* <MessageInput /> */} <MessageInput Input={ChatInput} /> |