Tutorial: How to Build a Slack Clone with React Native β Part 3
Vishal Narkhede
Posted on November 17, 2020
In Part 2 of this tutorial, we covered how to build Slack-like navigation, channel list screen, channel screen, reaction picker, and action sheet. In this tutorial, Part 3, we will build various search screens and thread screen.
Resources π
Below are a few helpful links if you get stuck along the way:
- Official Slack Clone Repo
- Official Slack Clone Repo for Expo
- Documentation for React Navigation
- Stream Chat Component Library
Thread Screen
The
MessageList
component accepts the prop functiononThreadSelect
, which is attached to the onPress handler for reply count text below the message bubble. If you check ourChannelScreen
component, you will see navigation logic toThreadScreen
added to theonThreadSelect
prop on theMesaageList
component.Thread
is provided out-of-the-box fromstream-chat-react-native
. If you look at the source code, it's a set ofMessage
(parent message bubble),MessageList
, and aMessageInput
component. You can customize these underlying components using props βadditionalParentMessageProps
,additionalMessageListProps
andadditionalMessageInputProps
. We can use this Thread component easily for our purpose.We need to implement a checkbox labeled "Also send to {channel_name}" (as shown in the screenshot below). When ticked, the message should appear on the channel as well. We can use
show_in_channel
property on the message object for this, as mentioned in docs for threads and replies
If you specify
show_in_channel
, the message will be visible both in a thread of replies and the main channel.
If the checkbox is ticked, add show_in_channel: true
to the message object before sending it. We can achieve this by providing a doSendMessageRequest
prop function, which overrides Channel components default sendMessage handler.
Use the Animated API by React Native to achieve the sliding animation of the checkbox and other action buttons.
Now assign the ThreadScreen
component to its respective HomeStack.Screen
in App.js
.
Search Screens
There are four modal search screens that we are going to implement in this tutorial:
Jump to Channel Screen & Channel Search Screen
We can create a standard component for Jump to channel screen and Channel search screen.
Let's first create a common component needed across the search screens.
Direct Messaging Avatar
This is a component for the avatar of direct messaging conversation:
- For one to one conversations, it shows other member's picture with his presence indicator
- For group conversation, it shows stacked avatars of two of its members.
Modal Screen Header
This is a common header for modal screens, with a close button on the left and title in the center.
Now let's build a ChannelSearchScreen
, which can be used as "Jump to channel screen" and "Channel search." There are two main differences between these screens, which we will control through a prop β channelsOnly
.
- "Jump to channel screen" doesn't have a header
- "Channel search screen" doesn't have a horizontal list of recent direct messaging conversation members.
Also, we need to display a list of recent conversations when the user opens this modal. We can use the cached list of recent conversations in CacheService
(which we populated in the ChannelList
component via the useWatchedChannels
hook) to avoid extra calls to the queryChannels
API endpoint.
Assign the ChannelSearchScreen
component to its respective ModalStack.Screen
in App.js
.
New Message Screen
Highlights of this screen (NewMessageScreen
) are as following:
- Inputbox on top is a multi-select input. One can select multiple users there. This can be quickly built as a separate component β
UserSearch
. ExposeonChangeTags
callback as a prop function to give parent component access to selected users. -
UserSearch
component usesqueryUsers
endpoint provided available on chat client. Please check docs forqueryUser
endpoint - When the user focuses on the input box at the bottom of the screen, the app should create a conversation between the already selected users in the top (
UserSearch
) input box. We handle this in theonFocus
handler for the input box at the bottom of the screen.
Now assign the NewMessageScreen
component to its respective ModalStack.Screen
in App.js
.
Message Search Screen
We are going to implement a global search for message text on this screen β MessageSearchScreen
.
Note: The official Slack app provides richer features such as search in a specific channel or search by attachments. Here, we are keeping it limited to a global search, although channel-specific search is also possible using Stream Search API
- Global message search is relatively heavy for the backend so that search won't happen onChangeText, but when the user presses the search button explicitly. TextInput component has
returnKeyType
prop which we need for our use case. - Component uses
search
endpoint available on chat clients. Please check docs for message endpoint - Search results display a list of messages; when pressed, they should go to the channel screen on that particular message. We are going to build a separate screen for this β
TargettedMessageChannelScreen
. This component is quite similar toChannelScreen
, but it queries the channel at a specific message (provided through props) instead of the latest message as follows:
- When the user lands on this screen, he can see the list of past searches. Store every search text in AsyncStorage.
Copy the following components in your app:
Assign the MessageSearchScreen
and TargettedMessageChannelScreen
component to its respective ModalStack.Screen
in App.js
.
Implementation for additional more screens (shown in screenshots below) is available in slack-clone-react-native repository. If you managed to follow the tutorial so far, implementation of following screens should be easy to understand.
Congratulations! π
You've completed Part 3, the final step, of our tutorial on building a Slack clone using the Streamβs Chat API with React Native. I hope you found this tutorial helpful!
Happy coding!
Posted on November 17, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.