Info:
This is release candidate documentation for Stream Chat React Native SDK v10. For the latest stable version, see the latest version (v9).

Channel preview

Each row of a ChannelList is a ChannelPreview. It reads the row's values from the channel's stores, such as whether the channel is muted, the unread count and the latest message, wraps the row in its swipe actions, and renders the ChannelPreview override key with those values as props. The default for that key is ChannelPreviewView, the row's look. Channel list UI explains what each value is read from.

Note:

The exported ChannelPreview component and the ChannelPreview override key are different things. The component is the row wrapper that ChannelListView renders for each channel, and it has no key. The key is the row's content, which the wrapper renders: ChannelPreviewView by default.

Best practices

  • To change the look and keep the values, register your own component as the ChannelPreview key. It gets the same props as ChannelPreviewView, and can render ChannelPreviewView itself.
  • To change only one part, such as the title or the unread badge, override that part's key instead of the whole row. See Parts.
  • Keep a row light, since it renders for every channel in the list.
  • Use the props a row gets, such as unread and lastMessage, rather than reading them from the channel again. They're reactive, and channel.data isn't.
  • A row of your own that doesn't render ChannelPreviewView calls onSelect from useChannelsContext() itself. The SDK doesn't export the registry of open swipe actions, so such a row can't close them on a tap as the default does.

Basic usage

The default row shows the time of the latest message from the timestamp.ChannelPreviewStatus translation key. ChannelPreviewView takes formatLatestMessageDate to format it yourself, but ChannelPreview doesn't pass it, so register a row that does:

src/RowsWithShortDates.tsx
import type { PropsWithChildren } from "react";
import { ChannelPreviewView, WithComponents } from "stream-chat-react-native";
import type {
  ChannelPreviewViewProps,
  ComponentOverrides,
} from "stream-chat-react-native";

const formatLatestMessageDate = (date: Date) =>
  date.toLocaleDateString(undefined, { day: "numeric", month: "short" });

const RowWithShortDate = (props: ChannelPreviewViewProps) => (
  <ChannelPreviewView
    {...props}
    formatLatestMessageDate={formatLatestMessageDate}
  />
);

const overrides: ComponentOverrides = { ChannelPreview: RowWithShortDate };

export const RowsWithShortDates = ({ children }: PropsWithChildren) => (
  <WithComponents overrides={overrides}>{children}</WithComponents>
);

The Preview UI cookbook builds a row from scratch.

What a row does

ChannelPreview:

  • reads muted, pinned and unread from channel.state, and lastMessage from channel.messagePaginator.aggregateState. unread is the current user's unread count, and 0 while the channel is muted.
  • replaces lastMessage with its translation into the user's language, when the message has one.
  • subscribes the channel's composer to draft events, so the row shows the user's draft.
  • wraps the row in its swipe actions, unless swipeActionsEnabled on ChannelList is false.

The default ChannelPreviewView:

  • is a Pressable. A tap closes any open swipe actions in the list, or calls onSelect(channel) when none are open.
  • renders the avatar at the start, and the title with the muted and pinned icons, the time of the latest message and the unread badge on its first line.
  • renders the message line on its second line: who is typing, the draft, "No messages yet", the poll's label, "Message failed to send", or the latest message after its delivery status, the first that applies.
  • places the muted and pinned icons after the title, or at the end of the message line, as mutedStatusPosition and pinnedStatusPosition say.
  • is memoized, so it renders again only when one of its props changes.

Props

ChannelPreview takes these props:

Prop Type Default Description
channel Channel required The row's channel.
client StreamChat the client from ChatContext The client the row reads the current user's id from, to find the user's unread count.

The ChannelPreview key, ChannelPreviewView by default, gets these props. ChannelPreview passes channel, muted, pinned, unread and lastMessage; ChannelPreviewView reads the rest from ChannelsContext unless you pass them.

Prop Type Default Description
channel Channel required The row's channel.
formatLatestMessageDate (date: Date) => string Formats the time of the latest message. Without it, the row uses the timestamp.ChannelPreviewStatus translation: the time today, "Yesterday", the weekday within the last week, and the date before that.
lastMessage LastMessageType The latest message of the channel, translated when the message has a translation. LastMessageType is LocalMessage | MessageResponse.
maxUnreadCount number from ChannelsContext The highest count the unread badge shows.
muted boolean Whether the current user muted the channel.
mutedStatusPosition 'trailingBottom' | 'inlineTitle' from ChannelsContext Where the muted icon shows: after the title, or at the end of the message line.
onSelect (channel: Channel) => void from ChannelsContext Called with the channel when the row is tapped while no swipe actions are open.
pinned boolean Whether the current user pinned the channel.
pinnedStatusPosition 'trailingBottom' | 'inlineTitle' from ChannelsContext Where the pinned icon shows: after the title, or at the end of the message line.
unread number The current user's unread messages in the channel. 0 while the channel is muted.

Parts

ChannelPreviewView renders each part through an override key, with these props:

Override key Default Gets Shows
ChannelPreviewAvatar ChannelAvatar channel, size: 'xl' The channel's image, or its members' avatars
ChannelPreviewTitle ChannelPreviewTitle channel The channel's display name. The default also takes a title that replaces it.
ChannelPreviewMutedStatus ChannelPreviewMutedStatus nothing The muted icon
ChannelPreviewPinnedStatus ChannelPreviewPinnedStatus nothing The pinned icon
ChannelPreviewStatus ChannelPreviewStatus channel, formatLatestMessageDate, lastMessage The time of the latest message
ChannelPreviewUnreadCount ChannelPreviewUnreadCount channel, maxUnreadCount, unread The unread badge, hidden at 0
ChannelPreviewMessage ChannelPreviewMessage channel, lastMessage The message line

ChannelPreviewMessage renders three more keys:

Override key Default Gets Shows
ChannelPreviewTypingIndicator ChannelPreviewTypingIndicator channel, usersTyping Who is typing, in place of the message line
ChannelPreviewLastMessage ChannelLastMessagePreview message The text of the latest message, or of the draft
ChannelPreviewMessageDeliveryStatus ChannelMessagePreviewDeliveryStatus channel, message The sent, delivered or read mark of the user's own latest message, or the sender's name before another member's message in a group channel

Every default is exported under the name in the Default column, so a replacement can render it and add to it.

  • useChannelPreviewDisplayName(channel) returns the title the default row shows.
  • useChannelPreviewDisplayPresence(channel) returns true when the channel has two members and the other one is online.
  • useChannelTypingState({ channel }) returns who is typing in the channel.
  • useChannelPreviewDraftMessage({ channel }) returns the user's draft in the channel.
  • useIsChannelMuted(channel) returns the channel's mute status, { muted, createdAt, expiresAt }, and useIsChannelPinned(channel) whether the user pinned it.

Their signatures are on Channel preview hooks.