Messages

A channel's messages live in channel.messagePaginator, pinned messages in channel.pinnedMessagesPaginator, and a thread's replies in thread.messagePaginator. Every loaded message, reply included, is also in client.messageStore.

Reading

// Messages on screen, loading and pagination flags
const { items, isLoading, hasMoreTail } =
  channel.messagePaginator.state.getLatestValue();

// Latest message of the channel
const lastMessage = channel.messagePaginator.latestMessage;

// Any loaded message by id
const message = client.messageStore.get(messageId);

// Did it send? "sending", "received" or "failed"
console.log(message?.status);

// Pinned messages
const { items: pinnedMessages } =
  channel.pinnedMessagesPaginator.state.getLatestValue();

Subscribe to render changes:

const unsubscribe = channel.messagePaginator.state.subscribeWithSelector(
  (state) => ({ items: state.items }),
  ({ items }) => renderMessages(items),
);

// The latest message is reactive through `aggregateState`
const unsubscribeLastMessage =
  channel.messagePaginator.aggregateState.subscribeWithSelector(
    (state) => ({ latestMessage: state.latestMessage }),
    ({ latestMessage }) => renderPreview(latestMessage),
  );

Loading older messages

toTail() loads the next page of older messages into items. hasMoreTail tells you whether there are more to load.

const { hasMoreTail } = channel.messagePaginator.state.getLatestValue();

if (hasMoreTail) {
  await channel.messagePaginator.toTail();
}

Jumping to a message

After a jump, items is the window around the target. messageFocusSignal tells you where to scroll.

await channel.messagePaginator.jumpToMessage(messageId);

const { signal } = channel.messagePaginator.messageFocusSignal.getLatestValue();
scrollToMessage(signal?.messageId);

Thread replies

A thread's replies are in thread.messagePaginator, the same paginator as a channel's messages, so everything on this page works for replies too. See Thread for how to get a thread.

// Replies on screen, loading and pagination flags
const {
  items: replies,
  isLoading,
  hasMoreTail,
} = thread.messagePaginator.state.getLatestValue();

// Load older replies
if (hasMoreTail) {
  await thread.messagePaginator.toTail();
}

// Jump to a reply
await thread.messagePaginator.jumpToMessage(replyId);

Configure the query

For message lists you can configure the page size. By default, a page is 100 messages in a channel, 50 replies in a thread and 100 pinned messages. Set it in the client configuration, before you load channels and threads.

client.config.set({
  // Every channel message list and thread reply list
  messagePaginator: { pageSize: 50 },
  // Overrides for thread replies and pinned messages
  thread: { messagePaginator: { pageSize: 25 } },
  channel: { pinnedMessagesPaginator: { pageSize: 20 } },
});

The first page that channel.watch() loads has the same size.