From 8f0eb0703f24076796fa6c13e35b5fc8b8de87ab Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Tue, 6 Apr 2021 15:58:44 -0400
Subject: added compose button asset

---
 src/components/messages/MessagesHeader.tsx | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'src/components/messages/MessagesHeader.tsx')

diff --git a/src/components/messages/MessagesHeader.tsx b/src/components/messages/MessagesHeader.tsx
index d8445580..a3b31a22 100644
--- a/src/components/messages/MessagesHeader.tsx
+++ b/src/components/messages/MessagesHeader.tsx
@@ -3,6 +3,7 @@ import {StyleSheet, View} from 'react-native';
 import {Text} from 'react-native-animatable';
 import {TouchableOpacity} from 'react-native-gesture-handler';
 import {normalize} from '../../utils';
+import ComposeIcon from '../../assets/icons/compose.svg';
 
 type MessagesHeaderProps = {
   createChannel: () => void;
@@ -14,10 +15,9 @@ const MessagesHeader: React.FC<MessagesHeaderProps> = ({createChannel}) => {
       <Text style={styles.headerText}>Messages</Text>
       <Text style={styles.unreadText}>2 unread</Text>
       <View style={styles.flex} />
-      <TouchableOpacity
-        style={styles.compose}
-        onPress={createChannel}>
-        <Text>Compose</Text>
+      <TouchableOpacity style={styles.compose} onPress={createChannel}>
+        {/* <Text>Compose</Text> */}
+        <ComposeIcon width={normalize(20)} height={normalize(20)} />
       </TouchableOpacity>
     </View>
   );
-- 
cgit v1.2.3-70-g09d2


From 952329c1ee1ebeee27d86d3dc09f4ceaa0b9f6a1 Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Wed, 7 Apr 2021 15:23:34 -0400
Subject: added unread count

---
 src/components/messages/MessagesHeader.tsx | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

(limited to 'src/components/messages/MessagesHeader.tsx')

diff --git a/src/components/messages/MessagesHeader.tsx b/src/components/messages/MessagesHeader.tsx
index a3b31a22..2b20f48c 100644
--- a/src/components/messages/MessagesHeader.tsx
+++ b/src/components/messages/MessagesHeader.tsx
@@ -1,22 +1,26 @@
-import * as React from 'react';
+import React, {useContext} from 'react';
 import {StyleSheet, View} from 'react-native';
 import {Text} from 'react-native-animatable';
 import {TouchableOpacity} from 'react-native-gesture-handler';
 import {normalize} from '../../utils';
 import ComposeIcon from '../../assets/icons/compose.svg';
+import {ChatContext} from '../../App';
 
 type MessagesHeaderProps = {
   createChannel: () => void;
 };
 
 const MessagesHeader: React.FC<MessagesHeaderProps> = ({createChannel}) => {
+  const {chatClient} = useContext(ChatContext);
+  const unread = chatClient.user?.total_unread_count as number;
   return (
     <View style={styles.header}>
       <Text style={styles.headerText}>Messages</Text>
-      <Text style={styles.unreadText}>2 unread</Text>
+      {unread && unread !== 0 && (
+        <Text style={styles.unreadText}>{unread} unread</Text>
+      )}
       <View style={styles.flex} />
       <TouchableOpacity style={styles.compose} onPress={createChannel}>
-        {/* <Text>Compose</Text> */}
         <ComposeIcon width={normalize(20)} height={normalize(20)} />
       </TouchableOpacity>
     </View>
-- 
cgit v1.2.3-70-g09d2


From 6e456b97cbdc8c13b586a939ddcdfbf2587ed3cf Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
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/components/messages/MessagesHeader.tsx')

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<MessagesHeaderProps> = ({createChannel}) => {
     <View style={styles.header}>
       <Text style={styles.headerText}>Messages</Text>
       {unread && unread !== 0 && (
-        <Text style={styles.unreadText}>{unread} unread</Text>
+        <Text style={styles.unreadText}>
+          {unread > 99 ? '99+' : unread} unread
+        </Text>
       )}
       <View style={styles.flex} />
       <TouchableOpacity style={styles.compose} onPress={createChannel}>
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<ChatListScreenProps> = ({navigation}) => {
                   watch: true,
                 }}
                 sort={{last_message_at: -1}}
+                maxUnreadCount={99}
               />
             </View>
           </Chat>
-- 
cgit v1.2.3-70-g09d2


From e3483bcf735c2a65ab53d5ee10e43ca6c5e33864 Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
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/components/messages/MessagesHeader.tsx')

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 (
+    <TouchableOpacity
+      style={styles.container}
+      onPress={() => {
+        setChannel(channel);
+        navigation.navigate('Chat');
+      }}>
+      <View>
+        <Image
+          style={styles.avatar}
+          source={
+            otherMembers.length === 1
+              ? {uri: member?.user?.thumbnail_url}
+              : require('../../assets/images/avatar-placeholder.png')
+          }
+        />
+        {online && <View style={styles.online} />}
+      </View>
+      <View style={styles.content}>
+        <Text
+          style={[styles.name, unread ? styles.unread : {}]}
+          numberOfLines={1}>
+          {member?.user?.first_name} {member?.user?.last_name}
+        </Text>
+        <Text
+          style={[styles.lastMessage, unread ? styles.unread : {}]}
+          numberOfLines={1}>
+          {channel.state.messages[channel.state.messages.length - 1].text}
+        </Text>
+      </View>
+      {unread && <View style={styles.purpleDot} />}
+    </TouchableOpacity>
+  );
+};
+
+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<MessagesHeaderProps> = ({createChannel}) => {
   return (
     <View style={styles.header}>
       <Text style={styles.headerText}>Messages</Text>
-      {unread && unread !== 0 && (
+      {unread && unread !== 0 ? (
         <Text style={styles.unreadText}>
           {unread > 99 ? '99+' : unread} unread
         </Text>
+      ) : (
+        <Fragment />
       )}
       <View style={styles.flex} />
       <TouchableOpacity style={styles.compose} onPress={createChannel}>
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<ChatListScreenProps> = ({navigation}) => {
-  const {chatClient, setChannel} = useContext(ChatContext);
+const ChatListScreen: React.FC<ChatListScreenProps> = () => {
+  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<ChatListScreenProps> = ({navigation}) => {
         {clientReady && (
           <Chat client={chatClient}>
             <View style={styles.chatContainer}>
-              <ChannelList
+              <ChannelList<
+                LocalAttachmentType,
+                LocalChannelType,
+                LocalCommandType,
+                LocalEventType,
+                LocalMessageType,
+                LocalReactionType,
+                LocalUserType
+              >
                 filters={memoizedFilters}
-                onSelect={(channel) => {
-                  setChannel(channel);
-                  navigation.navigate('Chat');
-                }}
                 options={{
                   presence: true,
                   state: true,
@@ -81,6 +94,7 @@ const ChatListScreen: React.FC<ChatListScreenProps> = ({navigation}) => {
                 }}
                 sort={{last_message_at: -1}}
                 maxUnreadCount={99}
+                Preview={ChannelPreview}
               />
             </View>
           </Chat>
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<string, unknown>;
 export type LocalMessageType = Record<string, unknown>;
 export type LocalResponseType = Record<string, unknown>;
+export type LocalReactionType = Record<string, unknown>;
 export type LocalUserType = Record<string, unknown>;
 
 export type ChatContextType = {
-- 
cgit v1.2.3-70-g09d2

