[Problem/Question]
OpenChannelProvider scrolls its message list to the bottom on every send published to the
shared pubSub, including sends that belong to a different channel or a different module.
In src/modules/OpenChannel/context/OpenChannelProvider.tsx, the SEND_USER_MESSAGE and SEND_FILE_MESSAGE subscribers call scrollIntoLast before the guard that checks whether the send actually belongs to this channel:
subscriber.set(topics.SEND_USER_MESSAGE, pubSub.subscribe(topics.SEND_USER_MESSAGE, (msg) => {
const { channel, message } = msg;
scrollIntoLast(0, conversationScrollRef); // <-- runs for every send, in every channel
if (channel && (channelUrl === channel?.url)) {
messagesDispatcher({ type: messageActionTypes.SENDING_MESSAGE_SUCCEEDED, payload: message });
}
}));
The same shape is at the SEND_FILE_MESSAGE subscriber a few lines below. Because the pubSub is shared across the whole SendbirdProvider, a GroupChannel send publishes SEND_USER_MESSAGE with
publishingModules: [PublishingModuleType.CHANNEL] and every mounted OpenChannel scrolls itself to the bottom in response. Neither channel.url nor publishingModules is consulted first.
Suggested fix: move the scrollIntoLast call inside the existing if (channel && channelUrl === channel?.url) block in both subscribers.
Secondary note: when conversationScrollRef.current is null, scrollIntoLast (in
src/modules/OpenChannel/context/utils.ts) falls back to
document.querySelector('.sendbird-openchannel-conversation-scroll__container__item-container'), which returns the first match in the document. With more than one open channel mounted that can be a different channel’s container than the one the provider intended to scroll.
[UIKit Version]
@sendbird/uikit-react 3.17.12 (the version we pin). I also checked the current main, where both
subscribers are unchanged, so this is still present as of 3.18.4.
[Reproduction Steps]
-
Under a single, mount an open channel and a group channel at the same time.
In our app the open channel is the routed page and the group channel is a floating DM window, but any layout that mounts both concurrently reproduces it.<SendbirdProvider appId={APP_ID} userId={USER_ID}> <OpenChannelProvider channelUrl={OPEN_CHANNEL_URL}> <OpenChannelUI /> </OpenChannelProvider> <GroupChannelProvider channelUrl={GROUP_CHANNEL_URL}> <GroupChannelUI /> </GroupChannelProvider> </SendbirdProvider> -
Send any message from the group channel.
-
The open channel jumps to the bottom, losing the reader’s scroll position. The group channel behaves correctly.
[Frequency]
Deterministic. It happens on every send, every time, in every open channel mounted at that moment.
[Current impact]
Users reading back through an open channel are pulled to the bottom whenever a message is sent in another chat window, which loses their place in the history.
We are shipping a client-side workaround: a hook subscribes to the same two topics, ignores events whose channel.url matches our own, and for foreign ones temporarily shadows scrollTop on the scroll container with a no-op setter so the upstream write is dropped. We shadow rather than record and restore the offset because applyScroll is deferred with setTimeout, so restoring afterwards lands after the browser has painted the jump and visibly flickers.
That workaround depends on the pubSub topic names, the scroll container’s class name, and the
timing of that deferral, so it is fragile across UIKit upgrades. We would much rather drop it and
rely on the ordering fix upstream.
Every claim in it is checked against source rather than recalled: the subscriber shape from upstream main, the version from npm view, the publishingModules: [PublishingModuleType.CHANNEL] payload from the GroupChannel send path in the installed 3.17.12, and the document.querySelector fallback from scrollIntoLast itself.