From 5c32ec8f6b1723604456ccabc3417f1e3c2c9227 Mon Sep 17 00:00:00 2001 From: Leon Jiang <35908040+leonyjiang@users.noreply.github.com> Date: Thu, 1 Apr 2021 14:18:24 -0400 Subject: Add dummy chat screens --- src/screens/chat/ChatListScreen.tsx | 48 +++++++++++++++++++++++++++++++++++++ src/screens/chat/ChatScreen.tsx | 34 ++++++++++++++++++++++++++ src/screens/chat/index.ts | 2 ++ 3 files changed, 84 insertions(+) create mode 100644 src/screens/chat/ChatListScreen.tsx create mode 100644 src/screens/chat/ChatScreen.tsx create mode 100644 src/screens/chat/index.ts (limited to 'src/screens/chat') diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx new file mode 100644 index 00000000..c49c790d --- /dev/null +++ b/src/screens/chat/ChatListScreen.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import {View, StyleSheet, Text, TouchableOpacity} from 'react-native'; +import {StackNavigationProp} from '@react-navigation/stack'; + +import {MainStackParams} from '../../routes'; + +type ChatListScreenNavigationProp = StackNavigationProp< + MainStackParams, + 'ChatList' +>; +interface ChatListScreenProps { + navigation: ChatListScreenNavigationProp; +} +/* + * Screen that displays all of the user's active conversations. + */ +const ChatListScreen: React.FC = ({navigation}) => { + return ( + + I am the chat list. + navigation.navigate('Chat')}> + Let's go to a conversation! + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + placeholder: { + fontSize: 14, + fontWeight: 'bold', + marginBottom: 10, + }, + button: { + backgroundColor: '#CCE4FC', + padding: 15, + borderRadius: 5, + }, +}); + +export default ChatListScreen; diff --git a/src/screens/chat/ChatScreen.tsx b/src/screens/chat/ChatScreen.tsx new file mode 100644 index 00000000..af83f504 --- /dev/null +++ b/src/screens/chat/ChatScreen.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import {View, StyleSheet, Text} from 'react-native'; +import {StackNavigationProp} from '@react-navigation/stack'; + +import {MainStackParams} from '../../routes'; + +type ChatScreenNavigationProp = StackNavigationProp; +interface ChatScreenProps { + navigation: ChatScreenNavigationProp; +} +/* + * Screen that displays all of the user's active conversations. + */ +const ChatScreen: React.FC = () => { + return ( + + I am a chat! + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + placeholder: { + fontSize: 14, + fontWeight: 'bold', + }, +}); + +export default ChatScreen; diff --git a/src/screens/chat/index.ts b/src/screens/chat/index.ts new file mode 100644 index 00000000..d2ccb02b --- /dev/null +++ b/src/screens/chat/index.ts @@ -0,0 +1,2 @@ +export {default as ChatListScreen} from './ChatListScreen'; +export {default as ChatScreen} from './ChatScreen'; -- cgit v1.2.3-70-g09d2 From a98147d9783da605a155aac5846cdfd8389fc9d6 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 2 Apr 2021 15:42:04 -0400 Subject: added stream-chat, working sample --- babel.config.js | 1 + package.json | 22 ++++++++---- src/screens/chat/ChatListScreen.tsx | 68 ++++++++++++++++++++++++++++++++++++- 3 files changed, 84 insertions(+), 7 deletions(-) (limited to 'src/screens/chat') diff --git a/babel.config.js b/babel.config.js index f842b77f..983e075d 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,3 +1,4 @@ module.exports = { presets: ['module:metro-react-native-babel-preset'], + plugins: ['react-native-reanimated/plugin'], }; diff --git a/package.json b/package.json index 0451e743..658ed62c 100644 --- a/package.json +++ b/package.json @@ -13,13 +13,16 @@ "dependencies": { "@react-native-community/async-storage": "^1.12.1", "@react-native-community/blur": "^3.6.0", + "@react-native-community/cameraroll": "^4.0.4", "@react-native-community/masked-view": "^0.1.10", + "@react-native-community/netinfo": "^6.0.0", "@react-native-firebase/app": "^10.0.0", "@react-native-firebase/messaging": "^10.0.0", "@react-navigation/bottom-tabs": "^5.7.2", "@react-navigation/native": "^5.6.1", "@react-navigation/stack": "^5.6.2", "@reduxjs/toolkit": "^1.4.0", + "@stream-io/flat-list-mvcp": "^0.0.9", "@types/react-native-vector-icons": "^6.4.5", "moment": "^2.29.1", "react": "16.13.1", @@ -30,17 +33,22 @@ "react-native-contacts": "^6.0.4", "react-native-date-picker": "^3.2.5", "react-native-device-info": "^7.3.1", + "react-native-document-picker": "^5.0.3", "react-native-elements": "^2.3.2", - "react-native-gesture-handler": "^1.6.1", + "react-native-fs": "^2.16.6", + "react-native-gesture-handler": "^1.10.3", + "react-native-haptic-feedback": "^1.11.0", "react-native-hyperlink": "^0.0.19", - "react-native-image-crop-picker": "^0.32.2", + "react-native-image-crop-picker": "^0.36.0", + "react-native-image-resizer": "^1.4.4", "react-native-inappbrowser-reborn": "^3.4.0", "react-native-linear-gradient": "^2.5.6", "react-native-picker-select": "^7.0.0", "react-native-push-notifications": "^3.0.10", - "react-native-reanimated": "^1.9.0", - "react-native-safe-area-context": "^3.0.6", + "react-native-reanimated": "2.0.0-rc.0", + "react-native-safe-area-context": "^3.2.0", "react-native-screens": "^2.9.0", + "react-native-share": "^5.1.7", "react-native-snap-carousel": "^3.9.1", "react-native-splash-screen": "^3.2.0", "react-native-svg": "^12.1.0", @@ -48,7 +56,9 @@ "react-promise-tracker": "^2.1.0", "react-redux": "^7.2.2", "reanimated-bottom-sheet": "^1.0.0-alpha.22", - "rn-fetch-blob": "^0.12.0" + "rn-fetch-blob": "^0.12.0", + "stream-chat-react-native": "^3.2.0", + "stream-chat-react-native-core": "^3.2.0" }, "devDependencies": { "@babel/core": "^7.6.2", @@ -88,4 +98,4 @@ "./node_modules/react-native-gesture-handler/jestSetup.js" ] } -} +} \ No newline at end of file diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index c49c790d..416e7936 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -1,6 +1,20 @@ -import React from 'react'; +import {StreamChat} from 'stream-chat'; +import React, {useEffect, useMemo, useState} from 'react'; import {View, StyleSheet, Text, TouchableOpacity} from 'react-native'; import {StackNavigationProp} from '@react-navigation/stack'; +import { + Channel, + ChannelList, + Chat, + MessageInput, + MessageList, + OverlayProvider, + Streami18n, + Thread, + ThreadContextValue, + useAttachmentPickerContext, + useOverlayContext, +} from 'stream-chat-react-native'; import {MainStackParams} from '../../routes'; @@ -15,6 +29,36 @@ interface ChatListScreenProps { * Screen that displays all of the user's active conversations. */ const ChatListScreen: React.FC = ({navigation}) => { + const filters = { + example: 'example-apps', + members: {$in: ['ron']}, + type: 'messaging', + }; + const [clientReady, setClientReady] = useState(false); + + const chatClient = StreamChat.getInstance('q95x9hkbyd6p'); + const userToken = + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoicm9uIn0.eRVjxLvd4aqCEHY_JRa97g6k7WpHEhxL7Z4K4yTot1c'; + const user = { + id: 'ron', + }; + + useEffect(() => { + const setupClient = async () => { + await chatClient.connectUser(user, userToken); + + return setClientReady(true); + }; + + setupClient(); + }, []); + + const streami18n = new Streami18n({ + language: 'en', + }); + + const memoizedFilters = useMemo(() => filters, []); + return ( I am the chat list. @@ -23,6 +67,28 @@ const ChatListScreen: React.FC = ({navigation}) => { onPress={() => navigation.navigate('Chat')}> Let's go to a conversation! + {clientReady && ( + <> + Fooooo + + + { + // setChannel(channel); + // navigation.navigate('Channel'); + }} + options={{ + presence: true, + state: true, + watch: true, + }} + sort={{last_message_at: -1}} + /> + + + + )} ); }; -- cgit v1.2.3-70-g09d2 From 4edcaf03ae6e41ba9eb11a381540db4692375463 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 2 Apr 2021 16:06:20 -0400 Subject: added initial styling --- src/components/index.ts | 1 + src/components/messages/MessagesHeader.tsx | 51 ++++++++++++++++++++++++++++ src/components/messages/index.ts | 1 + src/screens/chat/ChatListScreen.tsx | 54 ++++++++++++------------------ 4 files changed, 75 insertions(+), 32 deletions(-) create mode 100644 src/components/messages/MessagesHeader.tsx create mode 100644 src/components/messages/index.ts (limited to 'src/screens/chat') diff --git a/src/components/index.ts b/src/components/index.ts index d5649323..47dc583b 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -6,3 +6,4 @@ export * from './taggs'; export * from './comments'; export * from './moments'; export * from './suggestedPeople'; +export * from './messages'; diff --git a/src/components/messages/MessagesHeader.tsx b/src/components/messages/MessagesHeader.tsx new file mode 100644 index 00000000..47a84bf3 --- /dev/null +++ b/src/components/messages/MessagesHeader.tsx @@ -0,0 +1,51 @@ +import * as React from 'react'; +import {Alert, StyleSheet, View} from 'react-native'; +import {Text} from 'react-native-animatable'; +import {TouchableOpacity} from 'react-native-gesture-handler'; +import {normalize} from '../../utils'; + +type MessagesHeaderProps = {}; + +const MessagesHeader: React.FC = () => { + return ( + + Messages + 2 unread + + { + Alert.alert('hi'); + }}> + Compose + + + ); +}; + +const styles = StyleSheet.create({ + flex: { + flex: 1, + }, + header: { + marginHorizontal: '8%', + marginTop: '5%', + alignItems: 'center', + flexDirection: 'row', + }, + headerText: { + fontWeight: '700', + fontSize: normalize(18), + lineHeight: normalize(21), + }, + unreadText: { + color: '#8F01FF', + marginLeft: 10, + fontWeight: '700', + lineHeight: normalize(17), + fontSize: normalize(14), + }, + compose: {}, +}); + +export default MessagesHeader; diff --git a/src/components/messages/index.ts b/src/components/messages/index.ts new file mode 100644 index 00000000..2d6bb581 --- /dev/null +++ b/src/components/messages/index.ts @@ -0,0 +1 @@ +export {default as MessagesHeader} from './MessagesHeader'; diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index 416e7936..56493cf7 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -1,21 +1,9 @@ -import {StreamChat} from 'stream-chat'; -import React, {useEffect, useMemo, useState} from 'react'; -import {View, StyleSheet, Text, TouchableOpacity} from 'react-native'; import {StackNavigationProp} from '@react-navigation/stack'; -import { - Channel, - ChannelList, - Chat, - MessageInput, - MessageList, - OverlayProvider, - Streami18n, - Thread, - ThreadContextValue, - useAttachmentPickerContext, - useOverlayContext, -} from 'stream-chat-react-native'; - +import React, {useEffect, useMemo, useState} from 'react'; +import {SafeAreaView, StatusBar, StyleSheet, View} from 'react-native'; +import {StreamChat} from 'stream-chat'; +import {ChannelList, Chat, Streami18n} from 'stream-chat-react-native'; +import {MessagesHeader} from '../../components/messages'; import {MainStackParams} from '../../routes'; type ChatListScreenNavigationProp = StackNavigationProp< @@ -60,23 +48,17 @@ const ChatListScreen: React.FC = ({navigation}) => { const memoizedFilters = useMemo(() => filters, []); return ( - - I am the chat list. - navigation.navigate('Chat')}> - Let's go to a conversation! - - {clientReady && ( - <> - Fooooo + + + + + {clientReady && ( - + { - // setChannel(channel); - // navigation.navigate('Channel'); + console.log('Navigate to chat screen here'); }} options={{ presence: true, @@ -87,13 +69,17 @@ const ChatListScreen: React.FC = ({navigation}) => { /> - - )} + )} + ); }; const styles = StyleSheet.create({ + background: { + flex: 1, + backgroundColor: 'white', + }, container: { flex: 1, justifyContent: 'center', @@ -109,6 +95,10 @@ const styles = StyleSheet.create({ padding: 15, borderRadius: 5, }, + chatContainer: { + height: '100%', + marginTop: 10, + }, }); export default ChatListScreen; -- cgit v1.2.3-70-g09d2 From c03eba730ad99bbadc49601f5f9387c1ca4c0eac Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 2 Apr 2021 17:00:11 -0400 Subject: created navigation to chat --- src/components/messages/MessagesHeader.tsx | 10 ++++--- src/routes/main/MainStackNavigator.tsx | 2 +- src/screens/chat/ChatListScreen.tsx | 44 +++++++++++++++++++++++------- src/screens/chat/ChatScreen.tsx | 9 +++++- 4 files changed, 49 insertions(+), 16 deletions(-) (limited to 'src/screens/chat') diff --git a/src/components/messages/MessagesHeader.tsx b/src/components/messages/MessagesHeader.tsx index 47a84bf3..3b8144f7 100644 --- a/src/components/messages/MessagesHeader.tsx +++ b/src/components/messages/MessagesHeader.tsx @@ -1,12 +1,14 @@ import * as React from 'react'; -import {Alert, StyleSheet, View} from 'react-native'; +import {StyleSheet, View} from 'react-native'; import {Text} from 'react-native-animatable'; import {TouchableOpacity} from 'react-native-gesture-handler'; import {normalize} from '../../utils'; -type MessagesHeaderProps = {}; +type MessagesHeaderProps = { + createChannel: () => void; +}; -const MessagesHeader: React.FC = () => { +const MessagesHeader: React.FC = ({createChannel}) => { return ( Messages @@ -15,7 +17,7 @@ const MessagesHeader: React.FC = () => { { - Alert.alert('hi'); + createChannel(); }}> Compose diff --git a/src/routes/main/MainStackNavigator.tsx b/src/routes/main/MainStackNavigator.tsx index 021c0688..36c6fb57 100644 --- a/src/routes/main/MainStackNavigator.tsx +++ b/src/routes/main/MainStackNavigator.tsx @@ -93,7 +93,7 @@ export type MainStackParams = { }; SPWelcomeScreen: {}; ChatList: undefined; - Chat: undefined; + Chat: {channel: any; chatClient: any}; }; export const MainStack = createStackNavigator(); diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index 56493cf7..106995e0 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -19,26 +19,37 @@ interface ChatListScreenProps { const ChatListScreen: React.FC = ({navigation}) => { const filters = { example: 'example-apps', - members: {$in: ['ron']}, + members: {$in: ['john']}, type: 'messaging', }; const [clientReady, setClientReady] = useState(false); - const chatClient = StreamChat.getInstance('q95x9hkbyd6p'); - const userToken = - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoicm9uIn0.eRVjxLvd4aqCEHY_JRa97g6k7WpHEhxL7Z4K4yTot1c'; - const user = { - id: 'ron', - }; + const chatClient = StreamChat.getInstance('t823wwqn2wuk'); + // const chatClient = StreamChat.getInstance('q95x9hkbyd6p'); useEffect(() => { const setupClient = async () => { - await chatClient.connectUser(user, userToken); + // await chatClient.connectUser( + // { + // id: 'ron', + // }, + // 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoicm9uIn0.eRVjxLvd4aqCEHY_JRa97g6k7WpHEhxL7Z4K4yTot1c', + // ); + await chatClient.connectUser( + { + id: 'john', + name: 'John Doe', + image: 'https://getstream.io/random_svg/?name=John', + }, + chatClient.devToken('john'), + ); return setClientReady(true); }; - setupClient(); + setupClient().catch((err) => { + console.error(err); + }); }, []); const streami18n = new Streami18n({ @@ -51,7 +62,16 @@ const ChatListScreen: React.FC = ({navigation}) => { - + { + const channel = chatClient.channel('messaging', 'travel2', { + name: 'Awesome channel about traveling', + members: ['john'], + }); + // console.log(JSON.stringify(channel)); + channel.create(); + }} + /> {clientReady && ( @@ -59,6 +79,10 @@ const ChatListScreen: React.FC = ({navigation}) => { filters={memoizedFilters} onSelect={(channel) => { console.log('Navigate to chat screen here'); + navigation.navigate('Chat', { + channel, + chatClient, + }); }} options={{ presence: true, diff --git a/src/screens/chat/ChatScreen.tsx b/src/screens/chat/ChatScreen.tsx index af83f504..08145b89 100644 --- a/src/screens/chat/ChatScreen.tsx +++ b/src/screens/chat/ChatScreen.tsx @@ -3,15 +3,22 @@ import {View, StyleSheet, Text} from 'react-native'; import {StackNavigationProp} from '@react-navigation/stack'; import {MainStackParams} from '../../routes'; +import {navigationRef} from '../../RootNavigation'; +import {RouteProp} from '@react-navigation/native'; type ChatScreenNavigationProp = StackNavigationProp; +type ChatScreenRouteProp = RouteProp; interface ChatScreenProps { navigation: ChatScreenNavigationProp; + route: ChatScreenRouteProp; } /* * Screen that displays all of the user's active conversations. */ -const ChatScreen: React.FC = () => { +const ChatScreen: React.FC = ({route}) => { + const {channel, chatClient} = route.params; + console.log(channel); + console.log(chatClient); return ( I am a chat! -- cgit v1.2.3-70-g09d2 From 69613af86a9364f72dc2ce5f24722a3eb4b94ed2 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 2 Apr 2021 18:59:00 -0400 Subject: finished chat poc --- src/App.tsx | 43 ++++++++++++++++++++++++++++-- src/routes/main/MainStackNavigator.tsx | 2 +- src/screens/chat/ChatListScreen.tsx | 48 +++++++++++++--------------------- src/screens/chat/ChatScreen.tsx | 45 ++++++++++++++++--------------- src/types/types.ts | 39 +++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 54 deletions(-) (limited to 'src/screens/chat') diff --git a/src/App.tsx b/src/App.tsx index ea3617dc..d0276dd2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,18 +1,57 @@ import {NavigationContainer} from '@react-navigation/native'; -import React from 'react'; +import React, {useState} from 'react'; import {Provider} from 'react-redux'; +import {Channel as ChannelType, StreamChat} from 'stream-chat'; +import {OverlayProvider} from 'stream-chat-react-native'; import {navigationRef} from './RootNavigation'; import Routes from './routes'; import store from './store/configureStore'; +import { + ChatContextType, + LocalAttachmentType, + LocalChannelType, + LocalCommandType, + LocalEventType, + LocalMessageType, + LocalResponseType, + LocalUserType, +} from './types'; + +export const ChatContext = React.createContext({} as ChatContextType); const App = () => { + const [channel, setChannel] = useState< + ChannelType< + LocalAttachmentType, + LocalChannelType, + LocalCommandType, + LocalEventType, + LocalMessageType, + LocalResponseType, + LocalUserType + > + >(); + // TODO: (CHAT) change me + const chatClient = StreamChat.getInstance< + LocalAttachmentType, + LocalChannelType, + LocalCommandType, + LocalEventType, + LocalMessageType, + LocalResponseType, + LocalUserType + >('t823wwqn2wuk'); return ( /** * This is the provider from the redux store, it acts as the root provider for our application */ - + + + + + ); diff --git a/src/routes/main/MainStackNavigator.tsx b/src/routes/main/MainStackNavigator.tsx index 36c6fb57..021c0688 100644 --- a/src/routes/main/MainStackNavigator.tsx +++ b/src/routes/main/MainStackNavigator.tsx @@ -93,7 +93,7 @@ export type MainStackParams = { }; SPWelcomeScreen: {}; ChatList: undefined; - Chat: {channel: any; chatClient: any}; + Chat: undefined; }; export const MainStack = createStackNavigator(); diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index 106995e0..8bced236 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -1,8 +1,8 @@ import {StackNavigationProp} from '@react-navigation/stack'; -import React, {useEffect, useMemo, useState} from 'react'; +import React, {useContext, useEffect, useMemo, useState} from 'react'; import {SafeAreaView, StatusBar, StyleSheet, View} from 'react-native'; -import {StreamChat} from 'stream-chat'; -import {ChannelList, Chat, Streami18n} from 'stream-chat-react-native'; +import {ChannelList, Chat} from 'stream-chat-react-native'; +import {ChatContext} from '../../App'; import {MessagesHeader} from '../../components/messages'; import {MainStackParams} from '../../routes'; @@ -17,24 +17,21 @@ interface ChatListScreenProps { * Screen that displays all of the user's active conversations. */ const ChatListScreen: React.FC = ({navigation}) => { - const filters = { - example: 'example-apps', - members: {$in: ['john']}, - type: 'messaging', - }; + const {chatClient, setChannel} = useContext(ChatContext); const [clientReady, setClientReady] = useState(false); - const chatClient = StreamChat.getInstance('t823wwqn2wuk'); - // const chatClient = StreamChat.getInstance('q95x9hkbyd6p'); + // TODO: (CHAT) change this filter to filter for user-ids, or usernames?! + const memoizedFilters = useMemo( + () => ({ + members: {$in: ['john']}, + type: 'messaging', + }), + [], + ); useEffect(() => { const setupClient = async () => { - // await chatClient.connectUser( - // { - // id: 'ron', - // }, - // 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoicm9uIn0.eRVjxLvd4aqCEHY_JRa97g6k7WpHEhxL7Z4K4yTot1c', - // ); + // TODO: (CHAT) change me await chatClient.connectUser( { id: 'john', @@ -43,7 +40,6 @@ const ChatListScreen: React.FC = ({navigation}) => { }, chatClient.devToken('john'), ); - return setClientReady(true); }; @@ -52,37 +48,29 @@ const ChatListScreen: React.FC = ({navigation}) => { }); }, []); - const streami18n = new Streami18n({ - language: 'en', - }); - - const memoizedFilters = useMemo(() => filters, []); - return ( { + // TODO: (CHAT) change me const channel = chatClient.channel('messaging', 'travel2', { name: 'Awesome channel about traveling', members: ['john'], }); - // console.log(JSON.stringify(channel)); channel.create(); }} /> {clientReady && ( - + { - console.log('Navigate to chat screen here'); - navigation.navigate('Chat', { - channel, - chatClient, - }); + // TODO: (CHAT) fix type issue + setChannel(channel); + navigation.navigate('Chat'); }} options={{ presence: true, diff --git a/src/screens/chat/ChatScreen.tsx b/src/screens/chat/ChatScreen.tsx index 08145b89..eeb1a7d6 100644 --- a/src/screens/chat/ChatScreen.tsx +++ b/src/screens/chat/ChatScreen.tsx @@ -1,40 +1,43 @@ -import React from 'react'; -import {View, StyleSheet, Text} from 'react-native'; -import {StackNavigationProp} from '@react-navigation/stack'; - +import {useBottomTabBarHeight} from '@react-navigation/bottom-tabs'; +import {StackNavigationProp, useHeaderHeight} from '@react-navigation/stack'; +import React, {useContext} from 'react'; +import {StyleSheet, View} from 'react-native'; +import { + Channel, + Chat, + MessageInput, + MessageList, +} from 'stream-chat-react-native'; +import {ChatContext} from '../../App'; import {MainStackParams} from '../../routes'; -import {navigationRef} from '../../RootNavigation'; -import {RouteProp} from '@react-navigation/native'; type ChatScreenNavigationProp = StackNavigationProp; -type ChatScreenRouteProp = RouteProp; interface ChatScreenProps { navigation: ChatScreenNavigationProp; - route: ChatScreenRouteProp; } /* * Screen that displays all of the user's active conversations. */ -const ChatScreen: React.FC = ({route}) => { - const {channel, chatClient} = route.params; - console.log(channel); - console.log(chatClient); +const ChatScreen: React.FC = () => { + const {channel, chatClient} = useContext(ChatContext); + const headerHeight = useHeaderHeight(); + const tabbarHeight = useBottomTabBarHeight(); + return ( - - I am a chat! + + + + {}} /> + + + ); }; const styles = StyleSheet.create({ container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - }, - placeholder: { - fontSize: 14, - fontWeight: 'bold', + backgroundColor: 'white', }, }); diff --git a/src/types/types.ts b/src/types/types.ts index e7acd6e0..b5dc6373 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1,4 +1,5 @@ import Animated from 'react-native-reanimated'; +import {Channel as ChannelType, StreamChat} from 'stream-chat'; export interface UserType { userId: string; @@ -288,3 +289,41 @@ export type ContactType = { export type UniversityBadgeType = 'Search' | 'Crest'; export type BadgeDataType = Record; + +// Stream Chat Types +export type LocalAttachmentType = Record; +export type LocalChannelType = Record; +export type LocalCommandType = string; +export type LocalEventType = Record; +export type LocalMessageType = Record; +export type LocalResponseType = Record; +export type LocalUserType = Record; + +export type ChatContextType = { + channel: + | ChannelType< + LocalAttachmentType, + LocalChannelType, + LocalCommandType, + LocalEventType, + LocalMessageType, + LocalResponseType, + LocalUserType + > + | undefined; + setChannel: React.Dispatch< + React.SetStateAction< + | ChannelType< + LocalAttachmentType, + LocalChannelType, + LocalCommandType, + LocalEventType, + LocalMessageType, + LocalResponseType, + LocalUserType + > + | undefined + > + >; + chatClient: StreamChat; +}; -- cgit v1.2.3-70-g09d2 From 88d1ec9dff5674e8759ca33e4255af16b4bf51a5 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Mon, 5 Apr 2021 15:29:11 -0400 Subject: code cleanup --- src/components/messages/MessagesHeader.tsx | 4 +--- src/screens/chat/ChatListScreen.tsx | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'src/screens/chat') diff --git a/src/components/messages/MessagesHeader.tsx b/src/components/messages/MessagesHeader.tsx index 3b8144f7..d8445580 100644 --- a/src/components/messages/MessagesHeader.tsx +++ b/src/components/messages/MessagesHeader.tsx @@ -16,9 +16,7 @@ const MessagesHeader: React.FC = ({createChannel}) => { { - createChannel(); - }}> + onPress={createChannel}> Compose diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index 8bced236..8fa6998c 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -68,7 +68,6 @@ const ChatListScreen: React.FC = ({navigation}) => { { - // TODO: (CHAT) fix type issue setChannel(channel); navigation.navigate('Chat'); }} -- cgit v1.2.3-70-g09d2 From 28218a67a6630863d57f1699e8453155ee5f2aa3 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 6 Apr 2021 15:23:14 -0400 Subject: using tagg user id --- src/screens/chat/ChatListScreen.tsx | 21 ++++++++++++--------- src/store/actions/user.ts | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src/screens/chat') diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index 8fa6998c..0d180b98 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -1,10 +1,13 @@ +import AsyncStorage from '@react-native-community/async-storage'; import {StackNavigationProp} from '@react-navigation/stack'; import React, {useContext, useEffect, useMemo, useState} from 'react'; import {SafeAreaView, StatusBar, StyleSheet, View} from 'react-native'; +import {useStore} from 'react-redux'; import {ChannelList, Chat} from 'stream-chat-react-native'; import {ChatContext} from '../../App'; import {MessagesHeader} from '../../components/messages'; import {MainStackParams} from '../../routes'; +import {RootState} from '../../store/rootReducer'; type ChatListScreenNavigationProp = StackNavigationProp< MainStackParams, @@ -19,11 +22,13 @@ interface ChatListScreenProps { const ChatListScreen: React.FC = ({navigation}) => { const {chatClient, setChannel} = useContext(ChatContext); const [clientReady, setClientReady] = useState(false); + const state: RootState = useStore().getState(); + const loggedInUserId = state.user.user.userId; // TODO: (CHAT) change this filter to filter for user-ids, or usernames?! const memoizedFilters = useMemo( () => ({ - members: {$in: ['john']}, + members: {$in: [loggedInUserId]}, type: 'messaging', }), [], @@ -31,14 +36,12 @@ const ChatListScreen: React.FC = ({navigation}) => { useEffect(() => { const setupClient = async () => { - // TODO: (CHAT) change me + const chatToken = await AsyncStorage.getItem('chatToken'); await chatClient.connectUser( { - id: 'john', - name: 'John Doe', - image: 'https://getstream.io/random_svg/?name=John', + id: loggedInUserId, }, - chatClient.devToken('john'), + chatToken, ); return setClientReady(true); }; @@ -55,9 +58,9 @@ const ChatListScreen: React.FC = ({navigation}) => { { // TODO: (CHAT) change me - const channel = chatClient.channel('messaging', 'travel2', { - name: 'Awesome channel about traveling', - members: ['john'], + const channel = chatClient.channel('messaging', 'test1', { + name: 'Awesome channel about test1', + members: [loggedInUserId], }); channel.create(); }} diff --git a/src/store/actions/user.ts b/src/store/actions/user.ts index 4faa2206..3ebd4190 100644 --- a/src/store/actions/user.ts +++ b/src/store/actions/user.ts @@ -173,7 +173,7 @@ export const logout = ( try { // do our best effort here to gracefully disconnect the user if (client) { - await client.disconnectUser(); + client.disconnectUser(); } await AsyncStorage.clear(); dispatch({type: userLoggedIn.type, payload: {userId: '', username: ''}}); -- cgit v1.2.3-70-g09d2 From 4b0e55cd751bd77e05b8158177a74bd190974218 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 6 Apr 2021 15:35:22 -0400 Subject: added check for client ready --- src/screens/chat/ChatListScreen.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/screens/chat') diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index 0d180b98..801a9d19 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -45,10 +45,11 @@ const ChatListScreen: React.FC = ({navigation}) => { ); return setClientReady(true); }; - - setupClient().catch((err) => { - console.error(err); - }); + if (!clientReady) { + setupClient().catch((err) => { + console.error(err); + }); + } }, []); return ( -- cgit v1.2.3-70-g09d2 From 6db092b4b88a71c53088a14e330ec73e208ad958 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Wed, 7 Apr 2021 14:56:42 -0400 Subject: cleaned up TODO, updated sample --- src/screens/chat/ChatListScreen.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/screens/chat') diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index 801a9d19..9011ed4a 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -25,7 +25,6 @@ const ChatListScreen: React.FC = ({navigation}) => { const state: RootState = useStore().getState(); const loggedInUserId = state.user.user.userId; - // TODO: (CHAT) change this filter to filter for user-ids, or usernames?! const memoizedFilters = useMemo( () => ({ members: {$in: [loggedInUserId]}, @@ -59,9 +58,9 @@ const ChatListScreen: React.FC = ({navigation}) => { { // TODO: (CHAT) change me - const channel = chatClient.channel('messaging', 'test1', { - name: 'Awesome channel about test1', - members: [loggedInUserId], + const channel = chatClient.channel('messaging', { + name: 'Awesome channel with foobar', + members: [loggedInUserId, 'd5295557-59ce-49fc-aa8a-442874dbffc3'], }); channel.create(); }} -- cgit v1.2.3-70-g09d2 From 6e456b97cbdc8c13b586a939ddcdfbf2587ed3cf Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Wed, 7 Apr 2021 16:58:23 -0400 Subject: updated unread styling --- src/components/messages/MessagesHeader.tsx | 4 +++- src/screens/chat/ChatListScreen.tsx | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/screens/chat') diff --git a/src/components/messages/MessagesHeader.tsx b/src/components/messages/MessagesHeader.tsx index 2b20f48c..18c89de3 100644 --- a/src/components/messages/MessagesHeader.tsx +++ b/src/components/messages/MessagesHeader.tsx @@ -17,7 +17,9 @@ const MessagesHeader: React.FC = ({createChannel}) => { Messages {unread && unread !== 0 && ( - {unread} unread + + {unread > 99 ? '99+' : unread} unread + )} diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index 9011ed4a..98a7f097 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -80,6 +80,7 @@ const ChatListScreen: React.FC = ({navigation}) => { watch: true, }} sort={{last_message_at: -1}} + maxUnreadCount={99} /> -- cgit v1.2.3-70-g09d2 From e3483bcf735c2a65ab53d5ee10e43ca6c5e33864 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Wed, 7 Apr 2021 18:22:26 -0400 Subject: added figma styling --- src/components/messages/ChannelPreview.tsx | 136 +++++++++++++++++++++++++++++ src/components/messages/MessagesHeader.tsx | 6 +- src/components/messages/index.ts | 1 + src/screens/chat/ChatListScreen.tsx | 30 +++++-- src/types/types.ts | 1 + 5 files changed, 164 insertions(+), 10 deletions(-) create mode 100644 src/components/messages/ChannelPreview.tsx (limited to 'src/screens/chat') diff --git a/src/components/messages/ChannelPreview.tsx b/src/components/messages/ChannelPreview.tsx new file mode 100644 index 00000000..11408dc1 --- /dev/null +++ b/src/components/messages/ChannelPreview.tsx @@ -0,0 +1,136 @@ +import {useNavigation} from '@react-navigation/core'; +import React, {useContext} from 'react'; +import {Image, StyleSheet, Text, View} from 'react-native'; +import {TouchableOpacity} from 'react-native-gesture-handler'; +import {useSelector} from 'react-redux'; +import {ChannelPreviewMessengerProps} from 'stream-chat-react-native'; +import {ChatContext} from '../../App'; +import {RootState} from '../../store/rootReducer'; +import { + LocalAttachmentType, + LocalChannelType, + LocalCommandType, + LocalEventType, + LocalMessageType, + LocalReactionType, + LocalUserType, +} from '../../types'; +import {normalize, SCREEN_HEIGHT} from '../../utils'; + +const ChannelPreview: React.FC< + ChannelPreviewMessengerProps< + LocalAttachmentType, + LocalChannelType, + LocalCommandType, + LocalEventType, + LocalMessageType, + LocalReactionType, + LocalUserType + > +> = (props) => { + const navigation = useNavigation(); + const {setChannel} = useContext(ChatContext); + const {channel} = props; + const {userId: loggedInUserId} = useSelector( + (state: RootState) => state.user.user, + ); + const otherMembers = channel + ? Object.values(channel.state.members).filter( + (member) => member.user?.id !== loggedInUserId, + ) + : []; + const member = otherMembers.length === 1 ? otherMembers[0] : undefined; + const online = member?.user?.online; + const unread = channel.state.unreadCount > 0; + + return ( + { + setChannel(channel); + navigation.navigate('Chat'); + }}> + + + {online && } + + + + {member?.user?.first_name} {member?.user?.last_name} + + + {channel.state.messages[channel.state.messages.length - 1].text} + + + {unread && } + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + flexDirection: 'row', + height: Math.round(SCREEN_HEIGHT / 10), + alignItems: 'center', + paddingHorizontal: '8%', + paddingVertical: '5%', + }, + avatar: { + width: normalize(62), + height: normalize(62), + borderRadius: normalize(62) / 2, + }, + online: { + position: 'absolute', + backgroundColor: '#6EE7E7', + width: normalize(18), + height: normalize(18), + borderRadius: normalize(18) / 2, + borderColor: 'white', + borderWidth: 2, + bottom: 0, + right: 0, + }, + content: { + flex: 1, + height: '100%', + justifyContent: 'space-between', + flexDirection: 'column', + marginLeft: '5%', + }, + name: { + fontWeight: '500', + fontSize: normalize(14), + lineHeight: normalize(17), + }, + lastMessage: { + color: '#828282', + fontWeight: '500', + fontSize: normalize(12), + lineHeight: normalize(14), + }, + unread: { + fontWeight: '700', + color: 'black', + }, + purpleDot: { + backgroundColor: '#8F01FF', + width: normalize(10), + height: normalize(10), + borderRadius: normalize(10) / 2, + }, +}); + +export default ChannelPreview; diff --git a/src/components/messages/MessagesHeader.tsx b/src/components/messages/MessagesHeader.tsx index 18c89de3..660da97d 100644 --- a/src/components/messages/MessagesHeader.tsx +++ b/src/components/messages/MessagesHeader.tsx @@ -1,4 +1,4 @@ -import React, {useContext} from 'react'; +import React, {Fragment, useContext} from 'react'; import {StyleSheet, View} from 'react-native'; import {Text} from 'react-native-animatable'; import {TouchableOpacity} from 'react-native-gesture-handler'; @@ -16,10 +16,12 @@ const MessagesHeader: React.FC = ({createChannel}) => { return ( Messages - {unread && unread !== 0 && ( + {unread && unread !== 0 ? ( {unread > 99 ? '99+' : unread} unread + ) : ( + )} diff --git a/src/components/messages/index.ts b/src/components/messages/index.ts index 2d6bb581..e194093c 100644 --- a/src/components/messages/index.ts +++ b/src/components/messages/index.ts @@ -1 +1,2 @@ export {default as MessagesHeader} from './MessagesHeader'; +export {default as ChannelPreview} from './ChannelPreview'; diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index 98a7f097..637c6231 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -5,9 +5,18 @@ import {SafeAreaView, StatusBar, StyleSheet, View} from 'react-native'; import {useStore} from 'react-redux'; import {ChannelList, Chat} from 'stream-chat-react-native'; import {ChatContext} from '../../App'; -import {MessagesHeader} from '../../components/messages'; +import {ChannelPreview, MessagesHeader} from '../../components/messages'; import {MainStackParams} from '../../routes'; import {RootState} from '../../store/rootReducer'; +import { + LocalAttachmentType, + LocalChannelType, + LocalCommandType, + LocalEventType, + LocalMessageType, + LocalReactionType, + LocalUserType, +} from '../../types'; type ChatListScreenNavigationProp = StackNavigationProp< MainStackParams, @@ -19,8 +28,8 @@ interface ChatListScreenProps { /* * Screen that displays all of the user's active conversations. */ -const ChatListScreen: React.FC = ({navigation}) => { - const {chatClient, setChannel} = useContext(ChatContext); +const ChatListScreen: React.FC = () => { + const {chatClient} = useContext(ChatContext); const [clientReady, setClientReady] = useState(false); const state: RootState = useStore().getState(); const loggedInUserId = state.user.user.userId; @@ -68,12 +77,16 @@ const ChatListScreen: React.FC = ({navigation}) => { {clientReady && ( - filters={memoizedFilters} - onSelect={(channel) => { - setChannel(channel); - navigation.navigate('Chat'); - }} options={{ presence: true, state: true, @@ -81,6 +94,7 @@ const ChatListScreen: React.FC = ({navigation}) => { }} sort={{last_message_at: -1}} maxUnreadCount={99} + Preview={ChannelPreview} /> diff --git a/src/types/types.ts b/src/types/types.ts index 1a352808..582eefac 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -298,6 +298,7 @@ export type LocalCommandType = string; export type LocalEventType = Record; export type LocalMessageType = Record; export type LocalResponseType = Record; +export type LocalReactionType = Record; export type LocalUserType = Record; export type ChatContextType = { -- cgit v1.2.3-70-g09d2 From 4d5e79c7bc6e5112684506047954a47f3a97e891 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Thu, 8 Apr 2021 14:35:41 -0400 Subject: added tabs gradient --- src/screens/chat/ChatListScreen.tsx | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/screens/chat') diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index 637c6231..3290116b 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -5,6 +5,7 @@ import {SafeAreaView, StatusBar, StyleSheet, View} from 'react-native'; import {useStore} from 'react-redux'; import {ChannelList, Chat} from 'stream-chat-react-native'; import {ChatContext} from '../../App'; +import {TabsGradient} from '../../components'; import {ChannelPreview, MessagesHeader} from '../../components/messages'; import {MainStackParams} from '../../routes'; import {RootState} from '../../store/rootReducer'; @@ -100,6 +101,7 @@ const ChatListScreen: React.FC = () => { )} + ); }; -- cgit v1.2.3-70-g09d2 From bb16e95e15f6ea9b8941cae764570bdf7c0fdb59 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Thu, 8 Apr 2021 16:10:14 -0400 Subject: created util functions, updated isOnline --- src/components/messages/ChannelPreview.tsx | 3 +- src/screens/chat/ChatScreen.tsx | 11 ++++++ src/utils/messages.ts | 59 ++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/utils/messages.ts (limited to 'src/screens/chat') diff --git a/src/components/messages/ChannelPreview.tsx b/src/components/messages/ChannelPreview.tsx index 11408dc1..867e0a38 100644 --- a/src/components/messages/ChannelPreview.tsx +++ b/src/components/messages/ChannelPreview.tsx @@ -16,6 +16,7 @@ import { LocalUserType, } from '../../types'; import {normalize, SCREEN_HEIGHT} from '../../utils'; +import {isOnline} from '../../utils/messages'; const ChannelPreview: React.FC< ChannelPreviewMessengerProps< @@ -40,7 +41,7 @@ const ChannelPreview: React.FC< ) : []; const member = otherMembers.length === 1 ? otherMembers[0] : undefined; - const online = member?.user?.online; + const online = isOnline(member?.user?.last_active); const unread = channel.state.unreadCount > 0; return ( diff --git a/src/screens/chat/ChatScreen.tsx b/src/screens/chat/ChatScreen.tsx index eeb1a7d6..8e6c1575 100644 --- a/src/screens/chat/ChatScreen.tsx +++ b/src/screens/chat/ChatScreen.tsx @@ -2,6 +2,7 @@ import {useBottomTabBarHeight} from '@react-navigation/bottom-tabs'; import {StackNavigationProp, useHeaderHeight} from '@react-navigation/stack'; import React, {useContext} from 'react'; import {StyleSheet, View} from 'react-native'; +import {useSelector} from 'react-redux'; import { Channel, Chat, @@ -10,6 +11,7 @@ import { } from 'stream-chat-react-native'; import {ChatContext} from '../../App'; import {MainStackParams} from '../../routes'; +import {RootState} from '../../store/rootReducer'; type ChatScreenNavigationProp = StackNavigationProp; interface ChatScreenProps { @@ -22,6 +24,15 @@ const ChatScreen: React.FC = () => { const {channel, chatClient} = useContext(ChatContext); const headerHeight = useHeaderHeight(); const tabbarHeight = useBottomTabBarHeight(); + const {userId: loggedInUserId} = useSelector( + (state: RootState) => state.user.user, + ); + const otherMembers = channel + ? Object.values(channel.state.members).filter( + (member) => member.user?.id !== loggedInUserId, + ) + : []; + const member = otherMembers.length === 1 ? otherMembers[0] : undefined; return ( diff --git a/src/utils/messages.ts b/src/utils/messages.ts new file mode 100644 index 00000000..ae8e7cec --- /dev/null +++ b/src/utils/messages.ts @@ -0,0 +1,59 @@ +import moment from 'moment'; + +/** + * Finds the difference in time in minutes + * @param lastActive given time e.g. "2021-04-08T19:07:09.361300983Z" + * @returns diff in minutes + */ +const _diffInMinutes = (lastActive: string | undefined) => { + if (!lastActive) { + return undefined; + } + return moment().diff(moment(lastActive), 'minutes'); +}; + +/** + * Formats the last activity status. + * - "Active now" (≤ 5 minutes) + * - "Seen X minutes ago" (5 > x ≥ 59 minutes) + * - "Seen X hours ago" (x = [1, 2]) + * - "Offline" + * @param lastActive given time e.g. "2021-04-08T19:07:09.361300983Z" + * @returns + */ +export const formatLastSeenText = (lastActive: string | undefined) => { + const diff = _diffInMinutes(lastActive); + if (!diff) { + return 'Offline'; + } + if (diff <= 5) { + return 'Active now'; + } + if (diff <= 59) { + return `Seen ${diff} minutes ago`; + } + if (diff <= 180) { + const hours = Math.floor(diff / 60); + return `Seen ${hours} hours ago`; + } + return 'Offline'; +}; + +/** + * Checks if a lastActive timestamp is considered Online or not. + * + * A user is online if last active is ≤ 15 minutes. + * + * @param lastActive given time e.g. "2021-04-08T19:07:09.361300983Z" + * @returns True if active + */ +export const isOnline = (lastActive: string | undefined) => { + if (!lastActive) { + return false; + } + const diff = _diffInMinutes(lastActive); + if (!diff) { + return false; + } + return diff <= 15; +}; -- cgit v1.2.3-70-g09d2 From fab86f9b874524a4beabb3c45a9e59e8b00ca495 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Thu, 8 Apr 2021 18:42:28 -0400 Subject: added chat header, created isMember util, fixed KB padding issue --- src/App.tsx | 15 ++---- src/components/messages/ChannelPreview.tsx | 25 ++++----- src/components/messages/ChatHeader.tsx | 84 ++++++++++++++++++++++++++++++ src/routes/main/MainStackScreen.tsx | 7 ++- src/screens/chat/ChatScreen.tsx | 31 +++++------ src/types/types.ts | 21 ++++---- src/utils/layouts.ts | 1 + src/utils/messages.ts | 24 +++++++++ 8 files changed, 151 insertions(+), 57 deletions(-) create mode 100644 src/components/messages/ChatHeader.tsx (limited to 'src/screens/chat') diff --git a/src/App.tsx b/src/App.tsx index 9510c193..b8d64461 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,13 +1,14 @@ import {NavigationContainer} from '@react-navigation/native'; import React, {useState} from 'react'; import {Provider} from 'react-redux'; -import {Channel as ChannelType, StreamChat} from 'stream-chat'; +import {StreamChat} from 'stream-chat'; import {OverlayProvider} from 'stream-chat-react-native'; import {STREAM_CHAT_API} from './constants'; import {navigationRef} from './RootNavigation'; import Routes from './routes'; import store from './store/configureStore'; import { + ChannelGroupedType, ChatContextType, LocalAttachmentType, LocalChannelType, @@ -21,17 +22,7 @@ import { export const ChatContext = React.createContext({} as ChatContextType); const App = () => { - const [channel, setChannel] = useState< - ChannelType< - LocalAttachmentType, - LocalChannelType, - LocalCommandType, - LocalEventType, - LocalMessageType, - LocalResponseType, - LocalUserType - > - >(); + const [channel, setChannel] = useState(); const chatClient = StreamChat.getInstance< LocalAttachmentType, LocalChannelType, diff --git a/src/components/messages/ChannelPreview.tsx b/src/components/messages/ChannelPreview.tsx index 867e0a38..8ec6060a 100644 --- a/src/components/messages/ChannelPreview.tsx +++ b/src/components/messages/ChannelPreview.tsx @@ -2,7 +2,7 @@ import {useNavigation} from '@react-navigation/core'; import React, {useContext} from 'react'; import {Image, StyleSheet, Text, View} from 'react-native'; import {TouchableOpacity} from 'react-native-gesture-handler'; -import {useSelector} from 'react-redux'; +import {useSelector, useStore} from 'react-redux'; import {ChannelPreviewMessengerProps} from 'stream-chat-react-native'; import {ChatContext} from '../../App'; import {RootState} from '../../store/rootReducer'; @@ -16,7 +16,7 @@ import { LocalUserType, } from '../../types'; import {normalize, SCREEN_HEIGHT} from '../../utils'; -import {isOnline} from '../../utils/messages'; +import {getMember, isOnline} from '../../utils/messages'; const ChannelPreview: React.FC< ChannelPreviewMessengerProps< @@ -29,18 +29,11 @@ const ChannelPreview: React.FC< LocalUserType > > = (props) => { - const navigation = useNavigation(); const {setChannel} = useContext(ChatContext); + const state = useStore().getState(); + const navigation = useNavigation(); const {channel} = props; - const {userId: loggedInUserId} = useSelector( - (state: RootState) => state.user.user, - ); - const otherMembers = channel - ? Object.values(channel.state.members).filter( - (member) => member.user?.id !== loggedInUserId, - ) - : []; - const member = otherMembers.length === 1 ? otherMembers[0] : undefined; + const member = getMember(channel, state); const online = isOnline(member?.user?.last_active); const unread = channel.state.unreadCount > 0; @@ -55,8 +48,8 @@ const ChannelPreview: React.FC< @@ -71,7 +64,9 @@ const ChannelPreview: React.FC< - {channel.state.messages[channel.state.messages.length - 1].text} + {channel.state.messages.length > 0 + ? channel.state.messages[channel.state.messages.length - 1].text + : ''} {unread && } diff --git a/src/components/messages/ChatHeader.tsx b/src/components/messages/ChatHeader.tsx new file mode 100644 index 00000000..2bc096ec --- /dev/null +++ b/src/components/messages/ChatHeader.tsx @@ -0,0 +1,84 @@ +import React, {useContext} from 'react'; +import {Image, StyleSheet, View} from 'react-native'; +import {Text} from 'react-native-animatable'; +import {useStore} from 'react-redux'; +import {ChatContext} from '../../App'; +import {ChatHeaderHeight, normalize, StatusBarHeight} from '../../utils'; +import {formatLastSeenText, getMember, isOnline} from '../../utils/messages'; + +type ChatHeaderProps = {}; + +const ChatHeader: React.FC = () => { + const {channel} = useContext(ChatContext); + const state = useStore().getState(); + const member = getMember(channel, state); + const online = isOnline(member?.user?.last_active); + const lastSeen = formatLastSeenText(member?.user?.last_active); + + return ( + + + + {online && } + + + + {member?.user?.first_name} {member?.user?.last_name} + + {lastSeen} + + + ); +}; + +const styles = StyleSheet.create({ + container: { + height: ChatHeaderHeight - StatusBarHeight, + flexDirection: 'row', + alignItems: 'center', + paddingLeft: '15%', + }, + avatar: { + width: normalize(40), + height: normalize(40), + borderRadius: normalize(40) / 2, + }, + online: { + position: 'absolute', + backgroundColor: '#6EE7E7', + width: normalize(16), + height: normalize(16), + borderRadius: normalize(16) / 2, + borderColor: 'white', + borderWidth: 3, + top: 0, + right: 0, + }, + content: { + flex: 1, + height: '80%', + justifyContent: 'space-between', + flexDirection: 'column', + marginLeft: '5%', + }, + name: { + fontWeight: '700', + fontSize: normalize(15), + lineHeight: normalize(18), + }, + lastSeen: { + color: '#828282', + fontWeight: '500', + fontSize: normalize(12), + lineHeight: normalize(14), + }, +}); + +export default ChatHeader; diff --git a/src/routes/main/MainStackScreen.tsx b/src/routes/main/MainStackScreen.tsx index 8068b893..48c57920 100644 --- a/src/routes/main/MainStackScreen.tsx +++ b/src/routes/main/MainStackScreen.tsx @@ -34,7 +34,7 @@ import { } from '../../screens'; import MutualBadgeHolders from '../../screens/suggestedPeople/MutualBadgeHolders'; import {ScreenType} from '../../types'; -import {AvatarHeaderHeight, SCREEN_WIDTH} from '../../utils'; +import {AvatarHeaderHeight, ChatHeaderHeight, SCREEN_WIDTH} from '../../utils'; import {MainStack, MainStackParams} from './MainStackNavigator'; /** @@ -306,7 +306,10 @@ const MainStackScreen: React.FC = ({route}) => { ); diff --git a/src/screens/chat/ChatScreen.tsx b/src/screens/chat/ChatScreen.tsx index 8e6c1575..386feb03 100644 --- a/src/screens/chat/ChatScreen.tsx +++ b/src/screens/chat/ChatScreen.tsx @@ -1,8 +1,8 @@ import {useBottomTabBarHeight} from '@react-navigation/bottom-tabs'; -import {StackNavigationProp, useHeaderHeight} from '@react-navigation/stack'; +import {StackNavigationProp} from '@react-navigation/stack'; import React, {useContext} from 'react'; -import {StyleSheet, View} from 'react-native'; -import {useSelector} from 'react-redux'; +import {StyleSheet} from 'react-native'; +import {SafeAreaView} from 'react-native-safe-area-context'; import { Channel, Chat, @@ -10,8 +10,9 @@ import { MessageList, } from 'stream-chat-react-native'; import {ChatContext} from '../../App'; +import ChatHeader from '../../components/messages/ChatHeader'; import {MainStackParams} from '../../routes'; -import {RootState} from '../../store/rootReducer'; +import {isIPhoneX} from '../../utils'; type ChatScreenNavigationProp = StackNavigationProp; interface ChatScreenProps { @@ -22,33 +23,29 @@ interface ChatScreenProps { */ const ChatScreen: React.FC = () => { const {channel, chatClient} = useContext(ChatContext); - const headerHeight = useHeaderHeight(); const tabbarHeight = useBottomTabBarHeight(); - const {userId: loggedInUserId} = useSelector( - (state: RootState) => state.user.user, - ); - const otherMembers = channel - ? Object.values(channel.state.members).filter( - (member) => member.user?.id !== loggedInUserId, - ) - : []; - const member = otherMembers.length === 1 ? otherMembers[0] : undefined; return ( - + + - + {}} /> - + ); }; const styles = StyleSheet.create({ container: { backgroundColor: 'white', + flex: 1, }, }); diff --git a/src/types/types.ts b/src/types/types.ts index 582eefac..376c4be0 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -300,19 +300,18 @@ export type LocalMessageType = Record; export type LocalResponseType = Record; export type LocalReactionType = Record; export type LocalUserType = Record; +export type ChannelGroupedType = ChannelType< + LocalAttachmentType, + LocalChannelType, + LocalCommandType, + LocalEventType, + LocalMessageType, + LocalResponseType, + LocalUserType +>; export type ChatContextType = { - channel: - | ChannelType< - LocalAttachmentType, - LocalChannelType, - LocalCommandType, - LocalEventType, - LocalMessageType, - LocalResponseType, - LocalUserType - > - | undefined; + channel: ChannelGroupedType | undefined; setChannel: React.Dispatch< React.SetStateAction< | ChannelType< diff --git a/src/utils/layouts.ts b/src/utils/layouts.ts index e2f1f0b1..4d0d557d 100644 --- a/src/utils/layouts.ts +++ b/src/utils/layouts.ts @@ -31,6 +31,7 @@ export const StatusBarHeight = Platform.select({ }); export const AvatarHeaderHeight = (HeaderHeight + StatusBarHeight) * 1.3; +export const ChatHeaderHeight = (HeaderHeight + StatusBarHeight) * 1.1; /** * This is a function for normalizing the font size for different devices, based on iphone 8. diff --git a/src/utils/messages.ts b/src/utils/messages.ts index ae8e7cec..d63f2b7a 100644 --- a/src/utils/messages.ts +++ b/src/utils/messages.ts @@ -1,4 +1,6 @@ import moment from 'moment'; +import {RootState} from '../store/rootReducer'; +import {ChannelGroupedType} from '../types'; /** * Finds the difference in time in minutes @@ -57,3 +59,25 @@ export const isOnline = (lastActive: string | undefined) => { } return diff <= 15; }; + +/** + * Gets the other member in the channel. + * @param channel the current chat channel + * @param state the current redux state + * @returns other member or undefined + */ +export const getMember = ( + channel: ChannelGroupedType | undefined, + state: RootState, +) => { + if (!channel) { + return undefined; + } + const loggedInUserId = state.user.user.userId; + const otherMembers = channel + ? Object.values(channel.state.members).filter( + (member) => member.user?.id !== loggedInUserId, + ) + : []; + return otherMembers.length === 1 ? otherMembers[0] : undefined; +}; -- cgit v1.2.3-70-g09d2 From 3e5b961fd372efb6234af89176781114fa6f0625 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Thu, 8 Apr 2021 18:44:36 -0400 Subject: added comment --- src/screens/chat/ChatScreen.tsx | 1 + 1 file changed, 1 insertion(+) (limited to 'src/screens/chat') diff --git a/src/screens/chat/ChatScreen.tsx b/src/screens/chat/ChatScreen.tsx index 386feb03..59c53c99 100644 --- a/src/screens/chat/ChatScreen.tsx +++ b/src/screens/chat/ChatScreen.tsx @@ -29,6 +29,7 @@ const ChatScreen: React.FC = () => { -- cgit v1.2.3-70-g09d2 From 84c103614247ab7dc8b86767f3bfa83c13f224aa Mon Sep 17 00:00:00 2001 From: ankit-thanekar007 Date: Thu, 8 Apr 2021 17:38:55 -0700 Subject: Modal viw added --- src/constants/api.ts | 3 +- src/constants/strings.ts | 1 + src/routes/main/MainStackNavigator.tsx | 1 + src/routes/main/MainStackScreen.tsx | 419 +++++++++++++++++---------------- src/screens/chat/ChatListScreen.tsx | 15 +- src/screens/chat/ChatResultsCell.tsx | 122 ++++++++++ src/screens/chat/ChatResultsList.tsx | 107 +++++++++ src/screens/chat/ChatSearchBar.tsx | 119 ++++++++++ src/screens/chat/NewChatModal.tsx | 137 +++++++++++ src/screens/chat/index.ts | 4 + src/screens/search/SearchScreen.tsx | 4 +- src/utils/common.ts | 30 ++- 12 files changed, 746 insertions(+), 216 deletions(-) create mode 100644 src/screens/chat/ChatResultsCell.tsx create mode 100644 src/screens/chat/ChatResultsList.tsx create mode 100644 src/screens/chat/ChatSearchBar.tsx create mode 100644 src/screens/chat/NewChatModal.tsx (limited to 'src/screens/chat') diff --git a/src/constants/api.ts b/src/constants/api.ts index ffe47687..ef33631a 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -24,7 +24,8 @@ export const PROFILE_PHOTO_THUMBNAIL_ENDPOINT: string = export const GET_IG_POSTS_ENDPOINT: string = API_URL + 'posts-ig/'; export const GET_FB_POSTS_ENDPOINT: string = API_URL + 'posts-fb/'; export const GET_TWITTER_POSTS_ENDPOINT: string = API_URL + 'posts-twitter/'; -export const SEARCH_ENDPOINT: string = API_URL + 'search/v2/'; +export const SEARCH_ENDPOINT: string = API_URL + 'search/'; +export const SEARCH_ENDPOINT_V2: string = API_URL + 'search/v2/'; export const MOMENTS_ENDPOINT: string = API_URL + 'moments/'; export const MOMENT_THUMBNAIL_ENDPOINT: string = API_URL + 'moment-thumbnail/'; export const VERIFY_INVITATION_CODE_ENDPOUNT: string = API_URL + 'verify-code/'; diff --git a/src/constants/strings.ts b/src/constants/strings.ts index 4f792dcc..300ceb90 100644 --- a/src/constants/strings.ts +++ b/src/constants/strings.ts @@ -17,6 +17,7 @@ export const ERROR_DUP_OLD_PWD = 'You may not use a previously used password'; export const ERROR_EMAIL_IN_USE = 'Email already in use, please try another one'; export const ERROR_FAILED_LOGIN_INFO = 'Login failed, please try re-entering your login information'; export const ERROR_FAILED_TO_COMMENT = 'Unable to post comment, refresh and try again!'; +export const ERROR_FAILED_TO_CREATE_CHANNEL = 'Failed to create a channel, Please try again!'; export const ERROR_FAILED_TO_DELETE_COMMENT = 'Unable to delete comment, refresh and try again!'; export const ERROR_INVALID_INVITATION_CODE = 'Invitation code invalid, try again or talk to the friend that sent it 😬'; export const ERROR_INVALID_LOGIN = 'Invalid login, Please login again'; diff --git a/src/routes/main/MainStackNavigator.tsx b/src/routes/main/MainStackNavigator.tsx index 01b28fd4..64ad9198 100644 --- a/src/routes/main/MainStackNavigator.tsx +++ b/src/routes/main/MainStackNavigator.tsx @@ -95,6 +95,7 @@ export type MainStackParams = { SPWelcomeScreen: {}; ChatList: undefined; Chat: undefined; + NewChatModal: undefined; }; export const MainStack = createStackNavigator(); diff --git a/src/routes/main/MainStackScreen.tsx b/src/routes/main/MainStackScreen.tsx index 48c57920..1d222040 100644 --- a/src/routes/main/MainStackScreen.tsx +++ b/src/routes/main/MainStackScreen.tsx @@ -1,7 +1,12 @@ import AsyncStorage from '@react-native-community/async-storage'; import {RouteProp} from '@react-navigation/native'; -import {StackNavigationOptions} from '@react-navigation/stack'; -import React, {useState} from 'react'; +import { + StackNavigationOptions, + createStackNavigator, + TransitionSpecs, +} from '@react-navigation/stack'; +import {NavigationContainer} from '@react-navigation/native'; +import React, {useEffect, useState} from 'react'; import {StyleSheet, Text} from 'react-native'; import {normalize} from 'react-native-elements'; import BackIcon from '../../assets/icons/back-arrow.svg'; @@ -31,6 +36,7 @@ import { SettingsScreen, ChatListScreen, ChatScreen, + NewChatModal, } from '../../screens'; import MutualBadgeHolders from '../../screens/suggestedPeople/MutualBadgeHolders'; import {ScreenType} from '../../types'; @@ -52,7 +58,8 @@ type MainStackRouteProps = RouteProp; interface MainStackProps { route: MainStackRouteProps; } - +const RootStack = createStackNavigator(); +const tempStack = createStackNavigator(); const MainStackScreen: React.FC = ({route}) => { const {screenType} = route.params; @@ -64,6 +71,10 @@ const MainStackScreen: React.FC = ({route}) => { 'true', ); + useEffect(() => { + loadResponseToAccessContacts(); + }, []); + const loadResponseToAccessContacts = () => { AsyncStorage.getItem('respondedToAccessContacts') .then((value) => { @@ -75,8 +86,6 @@ const MainStackScreen: React.FC = ({route}) => { }); }; - loadResponseToAccessContacts(); - const initialRouteName = (() => { switch (screenType) { case ScreenType.Profile: @@ -106,213 +115,225 @@ const MainStackScreen: React.FC = ({route}) => { }), }; - return ( - - { + return ( + - {isSuggestedPeopleTab && - (respondedToAccessContacts && respondedToAccessContacts === 'true' ? ( + mode="card" + initialRouteName={initialRouteName}> + + {isSuggestedPeopleTab && + (respondedToAccessContacts && respondedToAccessContacts === 'true' ? ( + + ) : ( + + ))} + {isNotificationsTab && ( - ) : ( + )} + {isSearchTab && ( - ))} - {isNotificationsTab && ( + )} + + + + - )} - {isSearchTab && ( + - )} - - - - - - - - - - - - - - - - - - - - - - - - ); + + + + + + + + + + + + + + + + + + ); + }; + + return mainStackScreen(); }; export const headerBarOptions: ( diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index 3290116b..ca1461fe 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -19,6 +19,7 @@ import { LocalUserType, } from '../../types'; +import NewChatModal from './NewChatModal'; type ChatListScreenNavigationProp = StackNavigationProp< MainStackParams, 'ChatList' @@ -29,8 +30,10 @@ interface ChatListScreenProps { /* * Screen that displays all of the user's active conversations. */ -const ChatListScreen: React.FC = () => { - const {chatClient} = useContext(ChatContext); +const ChatListScreen: React.FC = ({navigation}) => { + const {chatClient, setChannel} = useContext(ChatContext); + const [modalVisible, setChatModalVisible] = useState(false); + const [clientReady, setClientReady] = useState(false); const state: RootState = useStore().getState(); const loggedInUserId = state.user.user.userId; @@ -67,12 +70,7 @@ const ChatListScreen: React.FC = () => { { - // TODO: (CHAT) change me - const channel = chatClient.channel('messaging', { - name: 'Awesome channel with foobar', - members: [loggedInUserId, 'd5295557-59ce-49fc-aa8a-442874dbffc3'], - }); - channel.create(); + setChatModalVisible(true); }} /> {clientReady && ( @@ -100,6 +98,7 @@ const ChatListScreen: React.FC = () => { )} + {modalVisible && } diff --git a/src/screens/chat/ChatResultsCell.tsx b/src/screens/chat/ChatResultsCell.tsx new file mode 100644 index 00000000..00f7130d --- /dev/null +++ b/src/screens/chat/ChatResultsCell.tsx @@ -0,0 +1,122 @@ +import {useNavigation} from '@react-navigation/native'; +import React, {useContext, useEffect, useState} from 'react'; +import {Alert, Image, StyleSheet, Text, View} from 'react-native'; +import {TouchableOpacity} from 'react-native-gesture-handler'; +import {useDispatch, useSelector, useStore} from 'react-redux'; +import {loadImageFromURL} from '../../services'; +import {RootState} from '../../store/rootReducer'; +import {ProfilePreviewType, UserType} from '../../types'; +import {createChannel, normalize, SCREEN_WIDTH} from '../../utils'; +import {defaultUserProfile} from '../../utils/users'; +import {ChatContext} from '../../App'; +import {ERROR_FAILED_TO_CREATE_CHANNEL} from '../../constants/strings'; + +interface ChatResults { + profileData: ProfilePreviewType; + loggedInUser: UserType; + setChatModalVisible: Function; +} + +const ChatResultsCell: React.FC = ({ + profileData: {id, username, first_name, last_name, thumbnail_url}, + loggedInUser, + setChatModalVisible, +}) => { + const [avatar, setAvatar] = useState(undefined); + const {chatClient, setChannel} = useContext(ChatContext); + const {university} = useSelector((state: RootState) => state.user.profile); + + useEffect(() => { + (async () => { + if (thumbnail_url !== undefined) { + try { + const response = await loadImageFromURL(thumbnail_url); + if (response) { + setAvatar(response); + } + } catch (error) { + console.log('Error while downloading ', error); + throw error; + } + } + })(); + }, [thumbnail_url]); + + const dispatch = useDispatch(); + const state: RootState = useStore().getState(); + const navigation = useNavigation(); + const createChannelIfNotPresentAndNavigate = async () => { + try { + const channel = await createChannel(loggedInUser.userId, id, chatClient); + setChannel(channel); + setTimeout(() => { + setChatModalVisible(false); + navigation.navigate('Chat'); + }, 500); + } catch (error) { + Alert.alert(ERROR_FAILED_TO_CREATE_CHANNEL); + } + }; + + const userCell = () => { + return ( + + + + {`@${username}`} + + {first_name + ' ' + last_name} + + + + ); + }; + + return userCell(); +}; + +const styles = StyleSheet.create({ + cellContainer: { + flexDirection: 'row', + paddingHorizontal: 25, + paddingVertical: 15, + width: SCREEN_WIDTH, + }, + imageContainer: { + width: SCREEN_WIDTH * 0.112, + height: SCREEN_WIDTH * 0.112, + borderRadius: (SCREEN_WIDTH * 0.112) / 2, + }, + categoryBackground: { + backgroundColor: 'rgba(196, 196, 196, 0.45)', + justifyContent: 'center', + alignItems: 'center', + }, + categoryImage: { + width: '40%', + height: '40%', + }, + initialTextContainer: { + marginLeft: SCREEN_WIDTH * 0.08, + flexDirection: 'column', + justifyContent: 'center', + }, + initialTextStyle: { + fontWeight: '500', + fontSize: normalize(14), + }, + secondaryTextStyle: { + fontWeight: '500', + fontSize: normalize(12), + color: '#828282', + }, + multiText: {justifyContent: 'space-between'}, +}); + +export default ChatResultsCell; diff --git a/src/screens/chat/ChatResultsList.tsx b/src/screens/chat/ChatResultsList.tsx new file mode 100644 index 00000000..17a16572 --- /dev/null +++ b/src/screens/chat/ChatResultsList.tsx @@ -0,0 +1,107 @@ +import {useBottomTabBarHeight} from '@react-navigation/bottom-tabs'; +import React, {useEffect, useState} from 'react'; +import { + Keyboard, + SectionList, + SectionListData, + StyleSheet, + Text, + View, +} from 'react-native'; +import {useSelector} from 'react-redux'; +import {NO_RESULTS_FOUND} from '../../constants/strings'; +import {RootState} from '../../store/rootreducer'; +import {PreviewType, ScreenType} from '../../types'; +import {normalize, SCREEN_WIDTH} from '../../utils'; +import ChatResultsCell from './ChatResultsCell'; + +interface ChatResultsProps { + // TODO: make sure results come in as same type, regardless of profile, category, badges + results: SectionListData[]; + previewType: PreviewType; + screenType: ScreenType; + setChatModalVisible: Function; +} + +const sectionHeader: React.FC = () => { + return null; +}; + +const ChatResultsList: React.FC = ({ + results, + setChatModalVisible, +}) => { + const [showEmptyView, setshowEmptyView] = useState(false); + const {user: loggedInUser} = useSelector((state: RootState) => state.user); + + useEffect(() => { + if (results && results.length > 0) { + let showEmpty = true; + + results.forEach((e) => { + if (e.data.length > 0) { + showEmpty = false; + } + }); + setshowEmptyView(showEmpty); + } + }, [results]); + + return showEmptyView ? ( + + {NO_RESULTS_FOUND} + + ) : ( + item.id + index} + renderItem={({item}) => { + return ( + + ); + }} + stickySectionHeadersEnabled={false} + ListEmptyComponent={() => ( + + Start a new chat by searching for someone + + )} + /> + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: 30, + alignItems: 'center', + }, + sectionHeaderStyle: { + width: '100%', + height: 0.5, + marginVertical: 5, + backgroundColor: '#C4C4C4', + }, + noResultsTextContainer: { + justifyContent: 'center', + flexDirection: 'row', + width: SCREEN_WIDTH, + }, + noResultsTextStyle: { + fontWeight: '500', + fontSize: normalize(14), + }, +}); + +export default ChatResultsList; diff --git a/src/screens/chat/ChatSearchBar.tsx b/src/screens/chat/ChatSearchBar.tsx new file mode 100644 index 00000000..294efa57 --- /dev/null +++ b/src/screens/chat/ChatSearchBar.tsx @@ -0,0 +1,119 @@ +import React, {useEffect, useState} from 'react'; +import { + Keyboard, + NativeSyntheticEvent, + StyleSheet, + Text, + TextInput, + TextInputProps, + TextInputSubmitEditingEventData, + TouchableOpacity, + View, + ViewStyle, + LayoutChangeEvent, +} from 'react-native'; +import {normalize} from 'react-native-elements'; +import Animated, {useAnimatedStyle} from 'react-native-reanimated'; +import Icon from 'react-native-vector-icons/Feather'; +import {useSelector} from 'react-redux'; +import {RootState} from '../../store/rootReducer'; +import {getSearchSuggestions} from '../../utils'; + +const AnimatedIcon = Animated.createAnimatedComponent(Icon); + +interface SearchBarProps extends TextInputProps { + onCancel: () => void; + animationProgress: Animated.SharedValue; + searching: boolean; + placeholder: string; +} +const ChatSearchBar: React.FC = ({ + onFocus, + onBlur, + onChangeText, + value, + onCancel, + searching, + animationProgress, + onLayout, + placeholder, +}) => { + const handleSubmit = ( + e: NativeSyntheticEvent, + ) => { + e.preventDefault(); + Keyboard.dismiss(); + }; + + /* + * On-search marginRight style ("cancel" button slides and fades in). + */ + const animatedStyles = useAnimatedStyle(() => ({ + marginRight: animationProgress.value * 58, + opacity: animationProgress.value, + })); + + return ( + + + + To: + + + + + + Cancel + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + height: 40, + paddingHorizontal: 20, + flexDirection: 'row', + zIndex: 2, + }, + searchTextContainer: {marginHorizontal: 12}, + searchTextStyes: {fontWeight: 'bold', fontSize: 14, lineHeight: 17}, + inputContainer: { + flexGrow: 1, + flexDirection: 'row', + alignItems: 'center', + paddingHorizontal: 8, + borderRadius: 20, + backgroundColor: '#F0F0F0', + }, + searchIcon: { + marginRight: 8, + }, + input: { + flex: 1, + fontSize: 16, + color: '#000', + letterSpacing: normalize(0.5), + }, + cancelButton: { + height: '100%', + position: 'absolute', + justifyContent: 'center', + paddingHorizontal: 8, + }, + cancelText: { + color: '#818181', + fontWeight: '500', + }, +}); + +export default ChatSearchBar; diff --git a/src/screens/chat/NewChatModal.tsx b/src/screens/chat/NewChatModal.tsx new file mode 100644 index 00000000..2bbaf8d2 --- /dev/null +++ b/src/screens/chat/NewChatModal.tsx @@ -0,0 +1,137 @@ +import {useNavigation} from '@react-navigation/core'; +import React, {useEffect, useRef, useState} from 'react'; +import { + Keyboard, + SectionListData, + StatusBar, + StyleSheet, + Text, + View, +} from 'react-native'; +import {useSharedValue} from 'react-native-reanimated'; +import {BottomDrawer} from '../../components'; +import {SEARCH_ENDPOINT} from '../../constants'; +import {loadSearchResults} from '../../services'; +import {ScreenType} from '../../types'; +import {normalize} from '../../utils'; +import {ChatResultsList, ChatSearchBar} from './index'; +interface NewChatModalProps { + setChatModalVisible: (open: boolean) => void; +} + +const NewChatModal: React.FC = ({setChatModalVisible}) => { + const [modalVisible, setModalVisible] = useState(true); + const navigation = useNavigation(); + const sheetRef = useRef(null); + const [searching, setSearching] = useState(false); + /* + * Animated value + */ + const animationProgress = useSharedValue(0); + const [results, setResults] = useState[]>([]); + const [query, setQuery] = useState(''); + const handleFocus = () => { + setSearching(true); + }; + const handleBlur = () => { + Keyboard.dismiss(); + }; + const handleCancel = () => { + setSearching(false); + }; + + useEffect(() => { + if (!searching) { + return; + } + if (query.length < 3) { + return; + } + (async () => { + const searchResults = await loadSearchResults( + `${SEARCH_ENDPOINT}?query=${query}`, + ); + if (query.length > 2) { + const sanitizedResult = [ + { + title: 'users', + data: searchResults?.users, + }, + ]; + setResults(sanitizedResult); + } else { + setResults([]); + } + })(); + }, [query]); + + const _modalContent = () => { + return ( + + + New Message + + + {results.length > 0 && ( + + Suggested + + )} + + + ); + }; + + return ( + + + + {_modalContent()} + + + ); +}; + +const styles = StyleSheet.create({ + modalShadowContainer: { + height: '100%', + borderRadius: 9, + backgroundColor: 'white', + }, + titleContainerStyles: {marginVertical: 24}, + titleTextStyles: { + fontWeight: 'bold', + fontSize: normalize(18), + lineHeight: normalize(21), + textAlign: 'center', + }, + headerContainerStyles: { + marginTop: 26, + marginBottom: 10, + marginHorizontal: 28, + }, + headerTextStyles: { + fontWeight: 'bold', + fontSize: normalize(17), + lineHeight: normalize(20), + }, +}); + +export default NewChatModal; diff --git a/src/screens/chat/index.ts b/src/screens/chat/index.ts index d2ccb02b..328eb8bf 100644 --- a/src/screens/chat/index.ts +++ b/src/screens/chat/index.ts @@ -1,2 +1,6 @@ export {default as ChatListScreen} from './ChatListScreen'; export {default as ChatScreen} from './ChatScreen'; +export {default as NewChatModal} from './NewChatModal'; +export {default as ChatSearchBar} from './ChatSearchBar'; +export {default as ChatResultsList} from './ChatResultsList'; +export {default as ChatResultsCell} from './ChatResultsCell'; diff --git a/src/screens/search/SearchScreen.tsx b/src/screens/search/SearchScreen.tsx index f7e1c467..6d8e4848 100644 --- a/src/screens/search/SearchScreen.tsx +++ b/src/screens/search/SearchScreen.tsx @@ -24,7 +24,7 @@ import { SearchResultsBackground, TabsGradient, } from '../../components'; -import {SEARCH_ENDPOINT} from '../../constants'; +import {SEARCH_ENDPOINT_V2} from '../../constants'; import {loadSearchResults} from '../../services'; import {resetScreenType} from '../../store/actions'; import {RootState} from '../../store/rootReducer'; @@ -71,7 +71,7 @@ const SearchScreen: React.FC = () => { } (async () => { const searchResults = await loadSearchResults( - `${SEARCH_ENDPOINT}?query=${query}`, + `${SEARCH_ENDPOINT_V2}?query=${query}`, ); if (query.length > 2) { const sanitizedResult = [ diff --git a/src/utils/common.ts b/src/utils/common.ts index 4f31af8e..0900a084 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -1,14 +1,14 @@ +import AsyncStorage from '@react-native-community/async-storage'; +import moment from 'moment'; +import {Linking} from 'react-native'; +import {getAll} from 'react-native-contacts'; +import {BROWSABLE_SOCIAL_URLS, TOGGLE_BUTTON_TYPE} from '../constants'; import { ContactType, NotificationType, - UniversityType, UniversityBadgeType, + UniversityType, } from './../types/types'; -import moment from 'moment'; -import {Linking} from 'react-native'; -import {BROWSABLE_SOCIAL_URLS, TOGGLE_BUTTON_TYPE} from '../constants'; -import AsyncStorage from '@react-native-community/async-storage'; -import {getAll} from 'react-native-contacts'; export const getToggleButtonText: ( buttonType: string, @@ -173,3 +173,21 @@ const _crestIcon = (university: UniversityType) => { return require('../assets/images/bwbadges.png'); } }; + +export const createChannel = async ( + loggedInUser: string, + id: string, + chatClient: any, +) => { + console.log(loggedInUser, id, chatClient); + try { + const channel = chatClient.channel('messaging', { + members: [loggedInUser, id], + }); + await channel.watch(); + return channel; + } catch (error) { + console.log(error); + throw error; + } +}; -- cgit v1.2.3-70-g09d2 From 0ebd64161da70d5d417886d7026ec8e0f4691db3 Mon Sep 17 00:00:00 2001 From: ankit-thanekar007 Date: Fri, 9 Apr 2021 09:46:55 -0700 Subject: Changes for default suggested --- src/screens/chat/ChatListScreen.tsx | 2 +- src/screens/chat/NewChatModal.tsx | 64 +++++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 22 deletions(-) (limited to 'src/screens/chat') diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index ca1461fe..daea9984 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -98,7 +98,7 @@ const ChatListScreen: React.FC = ({navigation}) => { )} - {modalVisible && } + diff --git a/src/screens/chat/NewChatModal.tsx b/src/screens/chat/NewChatModal.tsx index 2bbaf8d2..32a9b667 100644 --- a/src/screens/chat/NewChatModal.tsx +++ b/src/screens/chat/NewChatModal.tsx @@ -16,13 +16,14 @@ import {ScreenType} from '../../types'; import {normalize} from '../../utils'; import {ChatResultsList, ChatSearchBar} from './index'; interface NewChatModalProps { + modalVisible: boolean; setChatModalVisible: (open: boolean) => void; } -const NewChatModal: React.FC = ({setChatModalVisible}) => { - const [modalVisible, setModalVisible] = useState(true); - const navigation = useNavigation(); - const sheetRef = useRef(null); +const NewChatModal: React.FC = ({ + modalVisible, + setChatModalVisible, +}) => { const [searching, setSearching] = useState(false); /* * Animated value @@ -40,29 +41,51 @@ const NewChatModal: React.FC = ({setChatModalVisible}) => { setSearching(false); }; + const getDefaultSuggested = async () => { + const searchResults = await loadSearchResults( + `${SEARCH_ENDPOINT}?query=&requestType=suggested`, + ); + console.log(searchResults); + const sanitizedResult = [ + { + title: 'users', + data: searchResults?.users, + }, + ]; + console.log(searchResults, sanitizedResult); + setResults(sanitizedResult); + }; + + const getQuerySuggested = async () => { + const searchResults = await loadSearchResults( + `${SEARCH_ENDPOINT}?query=${query}&requestType='search'`, + ); + if (query.length > 2) { + const sanitizedResult = [ + { + title: 'users', + data: searchResults?.users, + }, + ]; + setResults(sanitizedResult); + } else { + setResults([]); + } + }; + useEffect(() => { + if (query.length === 0) { + getDefaultSuggested(); + } + if (!searching) { return; } + if (query.length < 3) { return; } - (async () => { - const searchResults = await loadSearchResults( - `${SEARCH_ENDPOINT}?query=${query}`, - ); - if (query.length > 2) { - const sanitizedResult = [ - { - title: 'users', - data: searchResults?.users, - }, - ]; - setResults(sanitizedResult); - } else { - setResults([]); - } - })(); + getQuerySuggested(); }, [query]); const _modalContent = () => { @@ -100,7 +123,6 @@ const NewChatModal: React.FC = ({setChatModalVisible}) => { {_modalContent()} -- cgit v1.2.3-70-g09d2 From c54a25dc05eeb70780bc3a3ec05cb8cbed3f334b Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 9 Apr 2021 13:27:45 -0400 Subject: code cleanup --- src/routes/main/MainStackScreen.tsx | 24 ++++++++++-------------- src/screens/chat/ChatResultsCell.tsx | 9 ++------- src/screens/chat/ChatResultsList.tsx | 19 ++++++++----------- src/screens/chat/ChatSearchBar.tsx | 9 +-------- src/screens/chat/NewChatModal.tsx | 3 +-- 5 files changed, 22 insertions(+), 42 deletions(-) (limited to 'src/screens/chat') diff --git a/src/routes/main/MainStackScreen.tsx b/src/routes/main/MainStackScreen.tsx index 1d222040..37867151 100644 --- a/src/routes/main/MainStackScreen.tsx +++ b/src/routes/main/MainStackScreen.tsx @@ -1,11 +1,6 @@ import AsyncStorage from '@react-native-community/async-storage'; import {RouteProp} from '@react-navigation/native'; -import { - StackNavigationOptions, - createStackNavigator, - TransitionSpecs, -} from '@react-navigation/stack'; -import {NavigationContainer} from '@react-navigation/native'; +import {StackNavigationOptions} from '@react-navigation/stack'; import React, {useEffect, useState} from 'react'; import {StyleSheet, Text} from 'react-native'; import {normalize} from 'react-native-elements'; @@ -16,6 +11,8 @@ import { BadgeSelection, CaptionScreen, CategorySelection, + ChatListScreen, + ChatScreen, CreateCustomCategory, DiscoverUsers, EditProfile, @@ -24,19 +21,17 @@ import { InviteFriendsScreen, MomentCommentsScreen, MomentUploadPromptScreen, + NewChatModal, NotificationsScreen, - ProfileScreen, PrivacyScreen, + ProfileScreen, RequestContactsAccess, SearchScreen, + SettingsScreen, SocialMediaTaggs, SuggestedPeopleScreen, SuggestedPeopleUploadPictureScreen, SuggestedPeopleWelcomeScreen, - SettingsScreen, - ChatListScreen, - ChatScreen, - NewChatModal, } from '../../screens'; import MutualBadgeHolders from '../../screens/suggestedPeople/MutualBadgeHolders'; import {ScreenType} from '../../types'; @@ -58,8 +53,6 @@ type MainStackRouteProps = RouteProp; interface MainStackProps { route: MainStackRouteProps; } -const RootStack = createStackNavigator(); -const tempStack = createStackNavigator(); const MainStackScreen: React.FC = ({route}) => { const {screenType} = route.params; @@ -322,7 +315,10 @@ const MainStackScreen: React.FC = ({route}) => { = ({ }) => { const [avatar, setAvatar] = useState(undefined); const {chatClient, setChannel} = useContext(ChatContext); - const {university} = useSelector((state: RootState) => state.user.profile); useEffect(() => { (async () => { @@ -42,8 +39,6 @@ const ChatResultsCell: React.FC = ({ })(); }, [thumbnail_url]); - const dispatch = useDispatch(); - const state: RootState = useStore().getState(); const navigation = useNavigation(); const createChannelIfNotPresentAndNavigate = async () => { try { diff --git a/src/screens/chat/ChatResultsList.tsx b/src/screens/chat/ChatResultsList.tsx index 17a16572..0c6d58e4 100644 --- a/src/screens/chat/ChatResultsList.tsx +++ b/src/screens/chat/ChatResultsList.tsx @@ -23,16 +23,13 @@ interface ChatResultsProps { setChatModalVisible: Function; } -const sectionHeader: React.FC = () => { - return null; -}; - const ChatResultsList: React.FC = ({ results, setChatModalVisible, }) => { const [showEmptyView, setshowEmptyView] = useState(false); const {user: loggedInUser} = useSelector((state: RootState) => state.user); + const tabbarHeight = useBottomTabBarHeight(); useEffect(() => { if (results && results.length > 0) { @@ -54,7 +51,7 @@ const ChatResultsList: React.FC = ({ ) : ( item.id + index} renderItem={({item}) => { @@ -68,12 +65,7 @@ const ChatResultsList: React.FC = ({ }} stickySectionHeadersEnabled={false} ListEmptyComponent={() => ( - + Start a new chat by searching for someone )} @@ -102,6 +94,11 @@ const styles = StyleSheet.create({ fontWeight: '500', fontSize: normalize(14), }, + empty: { + marginTop: 20, + justifyContent: 'center', + alignItems: 'center', + }, }); export default ChatResultsList; diff --git a/src/screens/chat/ChatSearchBar.tsx b/src/screens/chat/ChatSearchBar.tsx index 294efa57..4916ec45 100644 --- a/src/screens/chat/ChatSearchBar.tsx +++ b/src/screens/chat/ChatSearchBar.tsx @@ -1,4 +1,4 @@ -import React, {useEffect, useState} from 'react'; +import React from 'react'; import { Keyboard, NativeSyntheticEvent, @@ -10,16 +10,9 @@ import { TouchableOpacity, View, ViewStyle, - LayoutChangeEvent, } from 'react-native'; import {normalize} from 'react-native-elements'; import Animated, {useAnimatedStyle} from 'react-native-reanimated'; -import Icon from 'react-native-vector-icons/Feather'; -import {useSelector} from 'react-redux'; -import {RootState} from '../../store/rootReducer'; -import {getSearchSuggestions} from '../../utils'; - -const AnimatedIcon = Animated.createAnimatedComponent(Icon); interface SearchBarProps extends TextInputProps { onCancel: () => void; diff --git a/src/screens/chat/NewChatModal.tsx b/src/screens/chat/NewChatModal.tsx index 32a9b667..a7754d3a 100644 --- a/src/screens/chat/NewChatModal.tsx +++ b/src/screens/chat/NewChatModal.tsx @@ -1,5 +1,4 @@ -import {useNavigation} from '@react-navigation/core'; -import React, {useEffect, useRef, useState} from 'react'; +import React, {useEffect, useState} from 'react'; import { Keyboard, SectionListData, -- cgit v1.2.3-70-g09d2 From c8d5992ca659a1984194718703dd1b036e1fb59e Mon Sep 17 00:00:00 2001 From: ankit-thanekar007 Date: Fri, 9 Apr 2021 11:14:46 -0700 Subject: Changes for default suggested --- src/constants/api.ts | 24 +++++++++++++++--------- src/screens/chat/NewChatModal.tsx | 9 ++++++--- src/screens/search/SearchScreen.tsx | 4 ++-- 3 files changed, 23 insertions(+), 14 deletions(-) (limited to 'src/screens/chat') diff --git a/src/constants/api.ts b/src/constants/api.ts index ef33631a..43294386 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -2,7 +2,7 @@ // Dev const BASE_URL: string = 'http://127.0.0.1:8000/'; -export const STREAM_CHAT_API = 'g2hvnyqx9cmv' +export const STREAM_CHAT_API = 'g2hvnyqx9cmv'; // Prod // const BASE_URL: string = 'http://app-prod.tagg.id/'; @@ -25,7 +25,8 @@ export const GET_IG_POSTS_ENDPOINT: string = API_URL + 'posts-ig/'; export const GET_FB_POSTS_ENDPOINT: string = API_URL + 'posts-fb/'; export const GET_TWITTER_POSTS_ENDPOINT: string = API_URL + 'posts-twitter/'; export const SEARCH_ENDPOINT: string = API_URL + 'search/'; -export const SEARCH_ENDPOINT_V2: string = API_URL + 'search/v2/'; +export const SEARCH_ENDPOINT_MESSAGES: string = API_URL + 'search/messages/'; +export const SEARCH_ENDPOINT_SUGGESTED: string = API_URL + 'search/suggested/'; export const MOMENTS_ENDPOINT: string = API_URL + 'moments/'; export const MOMENT_THUMBNAIL_ENDPOINT: string = API_URL + 'moment-thumbnail/'; export const VERIFY_INVITATION_CODE_ENDPOUNT: string = API_URL + 'verify-code/'; @@ -38,20 +39,24 @@ export const PASSWORD_RESET_ENDPOINT: string = API_URL + 'password-reset/'; export const MOMENT_CATEGORY_ENDPOINT: string = API_URL + 'moment-category/'; export const NOTIFICATIONS_ENDPOINT: string = API_URL + 'notifications/'; export const DISCOVER_ENDPOINT: string = API_URL + 'discover/'; -export const SEARCH_BUTTONS_ENDPOPINT: string = DISCOVER_ENDPOINT + 'search_buttons/'; +export const SEARCH_BUTTONS_ENDPOPINT: string = + DISCOVER_ENDPOINT + 'search_buttons/'; export const WAITLIST_USER_ENDPOINT: string = API_URL + 'waitlist-user/'; export const COMMENT_THREAD_ENDPOINT: string = API_URL + 'reply/'; export const USERS_FROM_CONTACTS_ENDPOINT: string = API_URL + 'user_contacts/find_friends/'; export const INVITE_FRIEND_ENDPOINT: string = -API_URL + 'user_contacts/invite_friend/'; + API_URL + 'user_contacts/invite_friend/'; // Suggested People export const SP_USERS_ENDPOINT: string = API_URL + 'suggested_people/'; -export const SP_UPDATE_PICTURE_ENDPOINT: string = SP_USERS_ENDPOINT + 'update_picture/'; -export const SP_MUTUAL_BADGE_HOLDERS_ENDPOINT: string = SP_USERS_ENDPOINT + 'get_mutual_badge_holders/'; +export const SP_UPDATE_PICTURE_ENDPOINT: string = + SP_USERS_ENDPOINT + 'update_picture/'; +export const SP_MUTUAL_BADGE_HOLDERS_ENDPOINT: string = + SP_USERS_ENDPOINT + 'get_mutual_badge_holders/'; export const ADD_BADGES_ENDPOINT: string = SP_USERS_ENDPOINT + 'add_badges/'; -export const UPDATE_BADGES_ENDPOINT: string = SP_USERS_ENDPOINT + 'update_badges/'; +export const UPDATE_BADGES_ENDPOINT: string = + SP_USERS_ENDPOINT + 'update_badges/'; // Register as FCM device export const FCM_ENDPOINT: string = API_URL + 'fcm/'; @@ -72,6 +77,7 @@ export const LINK_IG_OAUTH: string = `https://www.instagram.com/oauth/authorize/ export const LINK_FB_OAUTH: string = `https://www.facebook.com/v8.0/dialog/oauth?client_id=1308555659343609&redirect_uri=${DEEPLINK}&scope=user_posts,public_profile&response_type=code`; export const LINK_TWITTER_OAUTH: string = API_URL + 'link-twitter-request/'; -// Profile Links -export const COMMUNITY_GUIDELINES: string = 'https://www.tagg.id/community-guidelines'; +// Profile Links +export const COMMUNITY_GUIDELINES: string = + 'https://www.tagg.id/community-guidelines'; export const PRIVACY_POLICY: string = 'https://www.tagg.id/privacy-policy'; diff --git a/src/screens/chat/NewChatModal.tsx b/src/screens/chat/NewChatModal.tsx index a7754d3a..95e46ecd 100644 --- a/src/screens/chat/NewChatModal.tsx +++ b/src/screens/chat/NewChatModal.tsx @@ -9,7 +9,10 @@ import { } from 'react-native'; import {useSharedValue} from 'react-native-reanimated'; import {BottomDrawer} from '../../components'; -import {SEARCH_ENDPOINT} from '../../constants'; +import { + SEARCH_ENDPOINT_MESSAGES, + SEARCH_ENDPOINT_SUGGESTED, +} from '../../constants'; import {loadSearchResults} from '../../services'; import {ScreenType} from '../../types'; import {normalize} from '../../utils'; @@ -42,7 +45,7 @@ const NewChatModal: React.FC = ({ const getDefaultSuggested = async () => { const searchResults = await loadSearchResults( - `${SEARCH_ENDPOINT}?query=&requestType=suggested`, + `${SEARCH_ENDPOINT_SUGGESTED}`, ); console.log(searchResults); const sanitizedResult = [ @@ -57,7 +60,7 @@ const NewChatModal: React.FC = ({ const getQuerySuggested = async () => { const searchResults = await loadSearchResults( - `${SEARCH_ENDPOINT}?query=${query}&requestType='search'`, + `${SEARCH_ENDPOINT_MESSAGES}?query=${query}`, ); if (query.length > 2) { const sanitizedResult = [ diff --git a/src/screens/search/SearchScreen.tsx b/src/screens/search/SearchScreen.tsx index 6d8e4848..f7e1c467 100644 --- a/src/screens/search/SearchScreen.tsx +++ b/src/screens/search/SearchScreen.tsx @@ -24,7 +24,7 @@ import { SearchResultsBackground, TabsGradient, } from '../../components'; -import {SEARCH_ENDPOINT_V2} from '../../constants'; +import {SEARCH_ENDPOINT} from '../../constants'; import {loadSearchResults} from '../../services'; import {resetScreenType} from '../../store/actions'; import {RootState} from '../../store/rootReducer'; @@ -71,7 +71,7 @@ const SearchScreen: React.FC = () => { } (async () => { const searchResults = await loadSearchResults( - `${SEARCH_ENDPOINT_V2}?query=${query}`, + `${SEARCH_ENDPOINT}?query=${query}`, ); if (query.length > 2) { const sanitizedResult = [ -- cgit v1.2.3-70-g09d2 From db51757cb968564dbc1554e0f10880eb009db7bc Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 9 Apr 2021 16:27:54 -0400 Subject: tweaked animation --- src/screens/chat/ChatResultsCell.tsx | 4 ++-- src/screens/chat/ChatResultsList.tsx | 16 +++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) (limited to 'src/screens/chat') diff --git a/src/screens/chat/ChatResultsCell.tsx b/src/screens/chat/ChatResultsCell.tsx index 3678a2d7..d947c122 100644 --- a/src/screens/chat/ChatResultsCell.tsx +++ b/src/screens/chat/ChatResultsCell.tsx @@ -42,12 +42,12 @@ const ChatResultsCell: React.FC = ({ const navigation = useNavigation(); const createChannelIfNotPresentAndNavigate = async () => { try { + setChatModalVisible(false); const channel = await createChannel(loggedInUser.userId, id, chatClient); setChannel(channel); setTimeout(() => { - setChatModalVisible(false); navigation.navigate('Chat'); - }, 500); + }, 100); } catch (error) { Alert.alert(ERROR_FAILED_TO_CREATE_CHANNEL); } diff --git a/src/screens/chat/ChatResultsList.tsx b/src/screens/chat/ChatResultsList.tsx index 0c6d58e4..b9970772 100644 --- a/src/screens/chat/ChatResultsList.tsx +++ b/src/screens/chat/ChatResultsList.tsx @@ -54,15 +54,13 @@ const ChatResultsList: React.FC = ({ contentContainerStyle={[{paddingBottom: tabbarHeight}]} sections={results} keyExtractor={(item, index) => item.id + index} - renderItem={({item}) => { - return ( - - ); - }} + renderItem={({item}) => ( + + )} stickySectionHeadersEnabled={false} ListEmptyComponent={() => ( -- cgit v1.2.3-70-g09d2