aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/App.tsx9
-rw-r--r--src/assets/images/camera.pngbin0 -> 99285 bytes
-rw-r--r--src/assets/images/gif.pngbin0 -> 103397 bytes
-rw-r--r--src/components/messages/ChatInput.tsx101
-rw-r--r--src/components/messages/ChatInputSubmit.tsx49
-rw-r--r--src/components/messages/index.ts2
-rw-r--r--src/components/profile/Content.tsx16
-rw-r--r--src/screens/chat/ChatScreen.tsx161
8 files changed, 155 insertions, 183 deletions
diff --git a/src/App.tsx b/src/App.tsx
index b8d64461..8d823e1f 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -18,6 +18,7 @@ import {
LocalResponseType,
LocalUserType,
} from './types';
+import {isIPhoneX} from './utils';
export const ChatContext = React.createContext({} as ChatContextType);
@@ -38,11 +39,11 @@ const App = () => {
*/
<Provider store={store}>
<NavigationContainer ref={navigationRef}>
- <ChatContext.Provider value={{channel, setChannel, chatClient}}>
- <OverlayProvider>
+ <OverlayProvider bottomInset={isIPhoneX() ? 80 : 50}>
+ <ChatContext.Provider value={{channel, setChannel, chatClient}}>
<Routes />
- </OverlayProvider>
- </ChatContext.Provider>
+ </ChatContext.Provider>
+ </OverlayProvider>
</NavigationContainer>
</Provider>
);
diff --git a/src/assets/images/camera.png b/src/assets/images/camera.png
new file mode 100644
index 00000000..16dbeb3a
--- /dev/null
+++ b/src/assets/images/camera.png
Binary files differ
diff --git a/src/assets/images/gif.png b/src/assets/images/gif.png
new file mode 100644
index 00000000..f3d11a0c
--- /dev/null
+++ b/src/assets/images/gif.png
Binary files differ
diff --git a/src/components/messages/ChatInput.tsx b/src/components/messages/ChatInput.tsx
index 9aeb9c62..005d4401 100644
--- a/src/components/messages/ChatInput.tsx
+++ b/src/components/messages/ChatInput.tsx
@@ -1,18 +1,14 @@
import React from 'react';
-import {
- Image,
- StyleSheet,
- TextInput,
- TouchableOpacity,
- View,
-} from 'react-native';
+import {Image, StyleSheet, View} from 'react-native';
+import {TouchableOpacity} from 'react-native-gesture-handler';
+import ImagePicker from 'react-native-image-crop-picker';
import {useStore} from 'react-redux';
import {
+ AutoCompleteInput,
MessageInputProps,
+ useAttachmentPickerContext,
useMessageInputContext,
} from 'stream-chat-react-native';
-import UpArrowIcon from '../../assets/icons/up_arrow.svg';
-import {TAGG_LIGHT_BLUE} from '../../constants';
import {RootState} from '../../store/rootReducer';
import {
LocalAttachmentType,
@@ -23,6 +19,8 @@ import {
LocalReactionType,
LocalUserType,
} from '../../types';
+import {normalize} from '../../utils';
+import {ChatInputSubmit} from '../messages';
const ChatInput: React.FC<
MessageInputProps<
@@ -37,7 +35,35 @@ const ChatInput: React.FC<
> = () => {
const state: RootState = useStore().getState();
const avatar = state.user.avatar;
- const {sendMessage, setText, text} = useMessageInputContext();
+ const {sendMessage, text, setText, uploadNewImage} = useMessageInputContext();
+ const {
+ setSelectedImages,
+ selectedImages,
+ openPicker,
+ } = useAttachmentPickerContext();
+
+ const selectImage = () => {
+ ImagePicker.openPicker({
+ cropping: true,
+ freeStyleCropEnabled: true,
+ mediaType: 'photo',
+ multiple: true,
+ // includeBase64: true,
+ })
+ .then((pictures) => {
+ pictures.map((pic) =>
+ uploadNewImage({
+ width: pic.width,
+ height: pic.height,
+ source: 'picker',
+ uri: 'ph://' + pic.localIdentifier,
+ }),
+ );
+ })
+ .catch((error) => {
+ console.log(error);
+ });
+ };
return (
<View style={styles.container}>
@@ -50,18 +76,23 @@ const ChatInput: React.FC<
: require('../../assets/images/avatar-placeholder.png')
}
/>
- <TextInput
- style={styles.text}
- placeholder={'Message...'}
- placeholderTextColor="grey"
- multiline={true}
- value={text}
- onChangeText={setText}
- />
- <View style={styles.submitButton}>
- <TouchableOpacity style={styles.submitButton} onPress={sendMessage}>
- <UpArrowIcon width={35} height={35} color={'white'} />
+ <AutoCompleteInput />
+ <View style={styles.actionButtons}>
+ {/* TODO: Not working, toggled off for now */}
+ {/* <TouchableOpacity onPress={openPicker}> */}
+ {/* <TouchableOpacity onPress={selectImage}>
+ <Image
+ style={{width: normalize(23), height: normalize(23)}}
+ source={require('../../assets/images/camera.png')}
+ />
+ </TouchableOpacity> */}
+ <TouchableOpacity onPress={() => setText('/')}>
+ <Image
+ style={{width: normalize(23), height: normalize(23)}}
+ source={require('../../assets/images/gif.png')}
+ />
</TouchableOpacity>
+ <ChatInputSubmit onPress={sendMessage} outlined={text.length === 0} />
</View>
</View>
</View>
@@ -72,6 +103,7 @@ const styles = StyleSheet.create({
container: {
alignItems: 'center',
width: '100%',
+ top: -10,
},
textContainer: {
width: '95%',
@@ -88,28 +120,27 @@ const styles = StyleSheet.create({
marginHorizontal: '1%',
},
avatar: {
- height: 35,
- width: 35,
+ height: normalize(30),
+ width: normalize(30),
borderRadius: 30,
marginRight: 10,
marginLeft: '3%',
- marginVertical: '2%',
- alignSelf: 'flex-end',
- },
- submitButton: {
- height: 35,
- width: 35,
- backgroundColor: TAGG_LIGHT_BLUE,
- borderRadius: 999,
- justifyContent: 'center',
- alignItems: 'center',
- marginRight: '3%',
- marginVertical: '2%',
+ marginVertical: 5,
alignSelf: 'flex-end',
},
whiteBackround: {
backgroundColor: '#fff',
},
+ actionButtons: {
+ height: normalize(30) + 10,
+ flexDirection: 'row',
+ justifyContent: 'space-evenly',
+ alignItems: 'center',
+ marginRight: 10,
+ width: 100,
+ alignSelf: 'flex-end',
+ // borderWidth: 1,
+ },
});
export default ChatInput;
diff --git a/src/components/messages/ChatInputSubmit.tsx b/src/components/messages/ChatInputSubmit.tsx
new file mode 100644
index 00000000..9e29ad4d
--- /dev/null
+++ b/src/components/messages/ChatInputSubmit.tsx
@@ -0,0 +1,49 @@
+import React from 'react';
+import {StyleSheet, TouchableOpacity} from 'react-native';
+import UpArrowIcon from '../../assets/icons/up_arrow.svg';
+import {TAGG_LIGHT_BLUE} from '../../constants';
+import {normalize} from '../../utils';
+
+interface ChatInputSubmitProps {
+ outlined: boolean;
+ onPress: () => void;
+}
+
+const SIZE = normalize(25);
+
+const ChatInputSubmit: React.FC<ChatInputSubmitProps> = (props) => {
+ const {outlined, onPress} = props;
+
+ return outlined ? (
+ <TouchableOpacity
+ style={[styles.submitButton, styles.outline]}
+ onPress={onPress}>
+ <UpArrowIcon width={SIZE} height={SIZE} color={TAGG_LIGHT_BLUE} />
+ </TouchableOpacity>
+ ) : (
+ <TouchableOpacity
+ style={[styles.submitButton, styles.background]}
+ onPress={onPress}>
+ <UpArrowIcon width={SIZE} height={SIZE} color={'white'} />
+ </TouchableOpacity>
+ );
+};
+
+const styles = StyleSheet.create({
+ submitButton: {
+ height: SIZE,
+ aspectRatio: 1,
+ borderRadius: 999,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ background: {
+ backgroundColor: TAGG_LIGHT_BLUE,
+ },
+ outline: {
+ borderWidth: 1,
+ borderColor: TAGG_LIGHT_BLUE,
+ },
+});
+
+export default ChatInputSubmit;
diff --git a/src/components/messages/index.ts b/src/components/messages/index.ts
index 83ecd2ad..c809d3d1 100644
--- a/src/components/messages/index.ts
+++ b/src/components/messages/index.ts
@@ -1,3 +1,5 @@
export {default as MessagesHeader} from './MessagesHeader';
export {default as ChannelPreview} from './ChannelPreview';
export {default as ChatInput} from './ChatInput';
+export {default as ChatHeader} from './ChatHeader';
+export {default as ChatInputSubmit} from './ChatInputSubmit';
diff --git a/src/components/profile/Content.tsx b/src/components/profile/Content.tsx
index 0052b61d..c70d6df5 100644
--- a/src/components/profile/Content.tsx
+++ b/src/components/profile/Content.tsx
@@ -1,14 +1,9 @@
-import React, {
- useCallback,
- useContext,
- useEffect,
- useRef,
- useState,
-} from 'react';
+import {useScrollToTop} from '@react-navigation/native';
+import React, {useCallback, useEffect, useRef, useState} from 'react';
import {LayoutChangeEvent, RefreshControl, StyleSheet} from 'react-native';
import Animated, {
- useSharedValue,
useAnimatedScrollHandler,
+ useSharedValue,
} from 'react-native-reanimated';
import {useDispatch, useSelector, useStore} from 'react-redux';
import {
@@ -36,8 +31,6 @@ import ProfileBody from './ProfileBody';
import ProfileCutout from './ProfileCutout';
import ProfileHeader from './ProfileHeader';
import PublicProfile from './PublicProfile';
-import {useScrollToTop} from '@react-navigation/native';
-import {ChatContext} from '../../App';
interface ContentProps {
userXId: string | undefined;
@@ -59,8 +52,6 @@ const Content: React.FC<ContentProps> = ({userXId, screenType}) => {
);
const state: RootState = useStore().getState();
- const {chatClient} = useContext(ChatContext);
-
/*
* Used to imperatively scroll to the top when presenting the moment tutorial.
*/
@@ -77,7 +68,6 @@ const Content: React.FC<ContentProps> = ({userXId, screenType}) => {
const [isBlocked, setIsBlocked] = useState<boolean>(false);
const [profileBodyHeight, setProfileBodyHeight] = useState(0);
const [socialsBarHeight, setSocialsBarHeight] = useState(0);
- const [shouldBounce, setShouldBounce] = useState<boolean>(true);
const [refreshing, setRefreshing] = useState<boolean>(false);
const onRefresh = useCallback(() => {
diff --git a/src/screens/chat/ChatScreen.tsx b/src/screens/chat/ChatScreen.tsx
index 682906ee..161bd07d 100644
--- a/src/screens/chat/ChatScreen.tsx
+++ b/src/screens/chat/ChatScreen.tsx
@@ -1,24 +1,20 @@
import {useBottomTabBarHeight} from '@react-navigation/bottom-tabs';
import {StackNavigationProp} from '@react-navigation/stack';
-import React, {useContext} from 'react';
-import {Image, StyleSheet, Text, View} from 'react-native';
-import {SafeAreaView} from 'react-native-safe-area-context';
-import {useStore} from 'react-redux';
+import React, {useContext, useEffect} from 'react';
+import {StyleSheet} from 'react-native';
+import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
import {
Channel,
Chat,
MessageInput,
MessageList,
- OverlayProvider,
- useMessageContext,
+ useAttachmentPickerContext,
} from 'stream-chat-react-native';
import {ChatContext} from '../../App';
-import ChatHeader from '../../components/messages/ChatHeader';
-import {TAGG_LIGHT_BLUE} from '../../constants';
+import {ChatHeader, ChatInput, TabsGradient} from '../../components';
import {MainStackParams} from '../../routes';
-import {RootState} from '../../store/rootReducer';
import {ScreenType} from '../../types';
-import {isIPhoneX, SCREEN_WIDTH} from '../../utils';
+import {HeaderHeight, isIPhoneX} from '../../utils';
type ChatScreenNavigationProp = StackNavigationProp<MainStackParams, 'Chat'>;
interface ChatScreenProps {
@@ -29,9 +25,9 @@ interface ChatScreenProps {
*/
const ChatScreen: React.FC<ChatScreenProps> = () => {
const {channel, chatClient} = useContext(ChatContext);
- const state: RootState = useStore().getState();
- const loggedInUserId = state.user.user.userId;
const tabbarHeight = useBottomTabBarHeight();
+ const {setTopInset} = useAttachmentPickerContext();
+ const insets = useSafeAreaInsets();
const chatTheme = {
messageList: {
@@ -39,52 +35,17 @@ const ChatScreen: React.FC<ChatScreenProps> = () => {
backgroundColor: 'white',
},
},
+ messageInput: {
+ container: {
+ backgroundColor: '#f8f8f8',
+ height: 70,
+ },
+ },
};
- const isOwnMessage = (message) => {
- if (message.user.id === loggedInUserId) {
- return true;
- } else {
- return false;
- }
- };
-
- const OwnMessageBubble = ({message}) => (
- <View style={[styles.mainBubbleContainer, styles.mainOwnBubbleContainer]}>
- <View style={styles.ownBubbleContainer}>
- <View style={styles.ownBubble}>
- <Text style={styles.messageText}>{message.text}</Text>
- </View>
- </View>
- {/* TODO: Timestamp */}
- </View>
- );
-
- const UserXMessageBubble = ({message}) => (
- <View style={[styles.mainBubbleContainer, styles.mainUserXBubbleContainer]}>
- <Image
- style={styles.avatar}
- source={
- message.user.thumbnail_url
- ? {uri: message.user.thumbnail_url}
- : require('../../assets/images/avatar-placeholder.png')
- }
- />
- <View style={styles.userXBubble}>
- <Text style={styles.messageText}>{message.text}</Text>
- </View>
- {/* TODO: Timestamp */}
- </View>
- );
-
- const CustomMessageUIComponent = () => {
- const {message} = useMessageContext();
- if (isOwnMessage(message)) {
- return <OwnMessageBubble message={message} />;
- } else {
- return <UserXMessageBubble message={message} />;
- }
- };
+ useEffect(() => {
+ setTopInset(insets.top + HeaderHeight);
+ });
return (
<SafeAreaView
@@ -95,23 +56,20 @@ const ChatScreen: React.FC<ChatScreenProps> = () => {
]}>
<ChatHeader screenType={ScreenType.Chat} />
<Chat client={chatClient} style={chatTheme}>
- <OverlayProvider topInset={0} bottomInset={0}>
- <Channel
- channel={channel}
- keyboardVerticalOffset={0}
- OverlayReactionList={() => null}
- // MessageSimple={CustomMessageUIComponent}
- messageActions={({copyMessage, deleteMessage}) => [
- copyMessage,
- deleteMessage,
- ]}
- // AttachButton={() => null}
- >
- <MessageList onThreadSelect={() => {}} />
- <MessageInput />
- </Channel>
- </OverlayProvider>
+ <Channel
+ channel={channel}
+ keyboardVerticalOffset={0}
+ OverlayReactionList={() => null}
+ messageActions={({copyMessage, deleteMessage}) => [
+ copyMessage,
+ deleteMessage,
+ ]}>
+ <MessageList onThreadSelect={() => {}} />
+ {/* <MessageInput /> */}
+ <MessageInput Input={ChatInput} />
+ </Channel>
</Chat>
+ <TabsGradient />
</SafeAreaView>
);
};
@@ -121,65 +79,6 @@ const styles = StyleSheet.create({
backgroundColor: 'white',
flex: 1,
},
-
- submitButton: {
- height: 35,
- width: 35,
- backgroundColor: TAGG_LIGHT_BLUE,
- borderRadius: 999,
- justifyContent: 'center',
- alignItems: 'center',
- bottom: -5,
- alignSelf: 'flex-end',
- },
- messageText: {
- width: 196,
- paddingHorizontal: 23,
- paddingTop: 7.35,
- paddingBottom: 12,
- },
- mainBubbleContainer: {
- marginVertical: 1,
- width: SCREEN_WIDTH,
- flexDirection: 'row',
- },
- mainOwnBubbleContainer: {
- justifyContent: 'flex-end', // Different
- marginTop: 22,
- },
- mainUserXBubbleContainer: {
- justifyContent: 'flex-start',
- },
- avatar: {
- width: 40,
- height: 40,
- borderRadius: 20,
- right: -19,
- zIndex: 1,
- position: 'absolute',
- top: 0,
- left: 0,
- },
- ownBubbleContainer: {width: 241, marginBottom: 9},
- ownBubble: {
- maxWidth: 270,
- backgroundColor: '#DEE6F4',
- borderColor: '#DEE6F4',
- borderWidth: 1,
- borderRadius: 10,
- alignSelf: 'center',
- },
- userXBubble: {
- maxWidth: 235,
- backgroundColor: '#E4F0F2',
- borderColor: '#E4F0F2',
- borderWidth: 1,
- borderRadius: 10,
- zIndex: 0,
- alignSelf: 'flex-end',
- marginLeft: 25,
- marginTop: 14,
- },
});
export default ChatScreen;