diff --git a/lib/actions/message-actions.js b/lib/actions/message-actions.js --- a/lib/actions/message-actions.js +++ b/lib/actions/message-actions.js @@ -29,7 +29,10 @@ RawMessageInfo, MessageTruncationStatuses, } from '../types/message-types.js'; -import { defaultNumberPerThread } from '../types/message-types.js'; +import { + defaultNumberPerThread, + messageTruncationStatus, +} from '../types/message-types.js'; import type { MediaMessageServerDBContent } from '../types/messages/media.js'; import type { ThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js'; import { threadTypeIsThick } from '../types/thread-types-enum.js'; @@ -40,6 +43,7 @@ import { getConfig } from '../utils/config.js'; import { translateClientDBMessageInfoToRawMessageInfo } from '../utils/message-ops-utils.js'; import { useDispatchActionPromise } from '../utils/redux-promise-utils.js'; +import { useSelector } from '../utils/redux-utils.js'; const fetchMessagesBeforeCursorActionTypes = Object.freeze({ started: 'FETCH_MESSAGES_BEFORE_CURSOR_STARTED', @@ -545,6 +549,29 @@ return useKeyserverCall(toggleMessagePin); } +async function fetchThickThreadMessages( + threadID: string, + limit: number, + offset: number, +): Promise { + const { sqliteAPI } = getConfig(); + const dbMessages = await sqliteAPI.fetchMessages(threadID, limit + 1, offset); + const isFetchExhaustive = dbMessages.length !== limit + 1; + const messagesToReturn = isFetchExhaustive + ? dbMessages + : dbMessages.slice(0, -1); + const messages = messagesToReturn.map( + translateClientDBMessageInfoToRawMessageInfo, + ); + return { + threadID, + rawMessageInfos: messages, + truncationStatus: isFetchExhaustive + ? messageTruncationStatus.EXHAUSTIVE + : messageTruncationStatus.UNCHANGED, + }; +} + function useFetchMessages(threadInfo: ThreadInfo): () => Promise { const oldestMessageServerID = useOldestMessageServerID(threadInfo.id); const callFetchMessagesBeforeCursor = useFetchMessagesBeforeCursor(); @@ -556,9 +583,31 @@ registerFetchKey(fetchMostRecentMessagesActionTypes); }, []); + const threadID = threadInfo.id; + const messageIDs = useSelector( + state => state.messageStore.threads[threadID].messageIDs, + ); + const numberOfFetchedMessages = React.useRef(messageIDs?.length ?? 0); + + React.useEffect(() => { + numberOfFetchedMessages.current = 0; + }, [threadInfo.id]); + return React.useCallback(async () => { - const threadID = threadInfo.id; if (threadTypeIsThick(threadInfo.type)) { + const promise = (async () => { + const fetchResult = await fetchThickThreadMessages( + threadID, + defaultNumberPerThread, + numberOfFetchedMessages.current, + ); + numberOfFetchedMessages.current += fetchResult.rawMessageInfos.length; + return fetchResult; + })(); + await dispatchActionPromise( + fetchMessagesBeforeCursorActionTypes, + promise, + ); return; } if (oldestMessageServerID) { @@ -580,7 +629,7 @@ callFetchMostRecentMessages, dispatchActionPromise, oldestMessageServerID, - threadInfo.id, + threadID, threadInfo.type, ]); } diff --git a/lib/reducers/message-reducer.js b/lib/reducers/message-reducer.js --- a/lib/reducers/message-reducer.js +++ b/lib/reducers/message-reducer.js @@ -606,6 +606,26 @@ updatedThreads[threadID] = threads[threadID]; } + const dbOps = [ + ...newMessageOps, + { + type: 'replace_threads', + payload: { + threads: Object.fromEntries( + Object.entries(updatedThreads).map(([threadID, thread]) => [ + threadID, + threadInfos[threadID].thick + ? { + ...thread, + startReached: + thread.messageIDs.length < defaultNumberPerThread, + } + : thread, + ]), + ), + }, + }, + ]; newMessageOps.push({ type: 'replace_threads', payload: { @@ -640,10 +660,7 @@ }; return { - messageStoreOperations: [ - ...updateWithLatestThreadInfosOps, - ...newMessageOps, - ], + messageStoreOperations: [...updateWithLatestThreadInfosOps, ...dbOps], messageStore, }; }