From ffe4bae3a8513be1a705d88c38048ac21a8c40bb Mon Sep 17 00:00:00 2001 From: Abhishek Dhatrak Date: Sat, 10 Jan 2026 11:51:01 +0530 Subject: [PATCH] Fix arrow navigation for starred messages not currently loaded --- packages/react/src/lib/scrollToMessage.js | 14 ++++++++ .../react/src/store/pinnedMessageStore.js | 34 ++++++++++++++++++- packages/react/src/views/Message/Message.js | 1 + .../MessageAggregators/StarredMessages.js | 22 +++++++++--- 4 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 packages/react/src/lib/scrollToMessage.js diff --git a/packages/react/src/lib/scrollToMessage.js b/packages/react/src/lib/scrollToMessage.js new file mode 100644 index 0000000000..42ee9e6967 --- /dev/null +++ b/packages/react/src/lib/scrollToMessage.js @@ -0,0 +1,14 @@ +const scrollToMessage = (messageId) => { + requestAnimationFrame(() => { + const element = document.getElementById(messageId); + + if (!element) return; + + element.scrollIntoView({ + behavior: 'smooth', + block: 'center', + }); + }); +}; + +export default scrollToMessage; diff --git a/packages/react/src/store/pinnedMessageStore.js b/packages/react/src/store/pinnedMessageStore.js index 36ee4e3851..a0ddf03c50 100644 --- a/packages/react/src/store/pinnedMessageStore.js +++ b/packages/react/src/store/pinnedMessageStore.js @@ -1,8 +1,40 @@ import { create } from 'zustand'; +import { getMessageById } from '../../lib/api'; +import { useMessageStore } from '../messageStore'; const usePinnedMessageStore = create((set) => ({ showPinned: false, - setShowPinned: (showPinned) => set(() => ({ showPinned })), + isJumping: false, + error: null, + + setShowPinned: (showPinned) => set({ showPinned }), + + resetError: () => set({ error: null }), + jumpToMessage: async (messageId) => { + const { messages, addMessages } = useMessageStore.getState(); + + set({ isJumping: true, error: null }); + + try { + const alreadyLoaded = messages.some( + (msg) => msg._id === messageId + ); + + if (alreadyLoaded) return; + + const message = await getMessageById(messageId); + + if (message) { + addMessages([message]); + } + } catch (err) { + set({ error: 'Failed to load pinned message' }); + console.error(err); + } finally { + set({ isJumping: false }); + } + }, })); export default usePinnedMessageStore; + diff --git a/packages/react/src/views/Message/Message.js b/packages/react/src/views/Message/Message.js index 355cde9b4a..7b589e81bb 100644 --- a/packages/react/src/views/Message/Message.js +++ b/packages/react/src/views/Message/Message.js @@ -231,6 +231,7 @@ const Message = ({ )} { const authenticatedUserId = useUserStore((state) => state.userId); const { variantOverrides } = useComponentOverrides('StarredMessages'); const viewType = variantOverrides.viewType || 'Sidebar'; - const starredMessages = useStarredMessageStore( - (state) => state.starredMessages - ); + + const { + starredMessages, + jumpToMessage, + isJumping, + } = useStarredMessageStore(); + const shouldRender = useCallback( (msg) => msg.starred && msg.starred.some((star) => star._id === authenticatedUserId), [authenticatedUserId] ); + + const handleJumpToMessage = async (message) => { + if (!message?._id || isJumping) return; + + await jumpToMessage(message._id); + scrollToMessage(message._id); + }; + return ( { fetchedMessageList={starredMessages} shouldRender={shouldRender} viewType={viewType} + onJumpToMessage={handleJumpToMessage} /> ); };