diff --git a/lib/hooks/message-hooks.js b/lib/hooks/message-hooks.js --- a/lib/hooks/message-hooks.js +++ b/lib/hooks/message-hooks.js @@ -16,9 +16,23 @@ ); } +type MessageInfoForPreview = { + +messageInfoForPreview: ?MessageInfo, + // If showInMessagePreview rejects all of the messages in the local store, + // then we'll ignore it and return the most recent message (if there is one) + // as messageInfoForPreview. In this case, we'll also set + // shouldFetchOlderMessages to tell the caller to fetch more messages. + +shouldFetchOlderMessages: boolean, +}; + +const emptyMessageInfoForPreview = { + messageInfoForPreview: undefined, + shouldFetchOlderMessages: false, +}; + function useGetMessageInfoForPreview(): ( threadInfo: ThreadInfo, -) => Promise { +) => Promise { const messageInfos = useSelector(messageInfoSelector); const messageStore = useSelector(state => state.messageStore); const viewerID = useSelector(state => state.currentUserInfo?.id); @@ -26,53 +40,69 @@ return React.useCallback( async threadInfo => { if (!viewerID) { - return null; + return emptyMessageInfoForPreview; } const thread = messageStore.threads[threadInfo.id]; if (!thread) { - return null; + return emptyMessageInfoForPreview; } const showInMessagePreviewParams = { threadInfo, viewerID, fetchMessage, }; + let mostRecentMessageInfo; for (const messageID of thread.messageIDs) { const messageInfo = messageInfos[messageID]; if (!messageInfo) { continue; } + if (!mostRecentMessageInfo) { + mostRecentMessageInfo = messageInfo; + } const { showInMessagePreview } = messageSpecs[messageInfo.type]; if (!showInMessagePreview) { - return messageInfo; + return { + messageInfoForPreview: messageInfo, + shouldFetchOlderMessages: false, + }; } const shouldShow = await showInMessagePreview( messageInfo, showInMessagePreviewParams, ); if (shouldShow) { - return messageInfo; + return { + messageInfoForPreview: messageInfo, + shouldFetchOlderMessages: false, + }; } } - return null; + // If we get here, that means showInMessagePreview rejected all of the + // messages in the local store + return { + messageInfoForPreview: mostRecentMessageInfo, + shouldFetchOlderMessages: true, + }; }, [messageInfos, messageStore, viewerID, fetchMessage], ); } function useMessageInfoForPreview(threadInfo: ThreadInfo): ?MessageInfo { - const [messageInfo, setMessageInfo] = React.useState(); + const [messageInfoForPreview, setMessageInfoForPreview] = + React.useState(); const getMessageInfoForPreview = useGetMessageInfoForPreview(); React.useEffect(() => { void (async () => { const newMessageInfoForPreview = await getMessageInfoForPreview(threadInfo); - setMessageInfo(newMessageInfoForPreview); + setMessageInfoForPreview(newMessageInfoForPreview); })(); }, [threadInfo, getMessageInfoForPreview]); - return messageInfo; + return messageInfoForPreview?.messageInfoForPreview; } export { useOldestMessageServerID, useMessageInfoForPreview };