From cedc45b08eb535d6099d9dffbce3ae97c57710fd Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Wed, 24 Sep 2025 13:40:29 -0300 Subject: [PATCH 01/15] fix: update lastMesssage as thread and avoid load more --- app/lib/methods/loadMessagesForRoom.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/lib/methods/loadMessagesForRoom.ts b/app/lib/methods/loadMessagesForRoom.ts index b69e36aae1f..63f8c808c69 100644 --- a/app/lib/methods/loadMessagesForRoom.ts +++ b/app/lib/methods/loadMessagesForRoom.ts @@ -42,7 +42,8 @@ export function loadMessagesForRoom(args: { if (data?.length) { const lastMessage = data[data.length - 1]; const lastMessageRecord = await getMessageById(lastMessage._id as string); - if (!lastMessageRecord && data.length === COUNT) { + const uniqueTmids = [...new Set(data.map(m => m.tmid).filter(Boolean))]; + if (!lastMessageRecord && data.length === COUNT && !uniqueTmids) { const loadMoreMessage = { _id: generateLoadMoreId(lastMessage._id as string), rid: lastMessage.rid, @@ -52,6 +53,16 @@ export function loadMessagesForRoom(args: { } as IMessage; data.push(loadMoreMessage); } + + if (uniqueTmids) { + await Promise.allSettled( + uniqueTmids.map(async tmid => { + const threadMessageRecord = (await sdk.get('chat.getMessage', { msgId: tmid as string })) as any; + data.push(threadMessageRecord?.message as IMessage); + }) + ); + } + await updateMessages({ rid: args.rid, update: data, loaderItem: args.loaderItem }); return resolve(); } From 26da0482c86b0749792f541639c6fa5570355241 Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Wed, 24 Sep 2025 13:40:36 -0300 Subject: [PATCH 02/15] fix: new loading --- app/views/RoomView/List/hooks/useMessages.ts | 27 +++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/app/views/RoomView/List/hooks/useMessages.ts b/app/views/RoomView/List/hooks/useMessages.ts index 047c09d5e56..e79eef81ff2 100644 --- a/app/views/RoomView/List/hooks/useMessages.ts +++ b/app/views/RoomView/List/hooks/useMessages.ts @@ -2,6 +2,7 @@ import { useCallback, useLayoutEffect, useRef, useState } from 'react'; import { Q } from '@nozbe/watermelondb'; import { Subscription } from 'rxjs'; +import { loadMissedMessages } from '../../../../lib/methods'; import { TAnyMessageModel } from '../../../../definitions'; import database from '../../../../lib/database'; import { getMessageById } from '../../../../lib/database/services/Message'; @@ -32,6 +33,7 @@ export const useMessages = ({ const fetchMessages = useCallback(async () => { unsubscribe(); count.current += QUERY_SIZE; + const prevIds = messagesIds.current; if (!rid) { return; @@ -66,7 +68,7 @@ export const useMessages = ({ .observe(); } - subscription.current = observable.subscribe(result => { + subscription.current = observable.subscribe(async result => { let newMessages: TAnyMessageModel[] = result; if (tmid && thread.current) { newMessages.push(thread.current); @@ -83,6 +85,29 @@ export const useMessages = ({ readThread(); setMessages(newMessages); messagesIds.current = newMessages.map(m => m.id); + + const newIds = newMessages.map(m => m.id); + const addedIds = newIds.filter(id => !prevIds.includes(id)); + if (!addedIds.length) { + const tsNumbers = newMessages + .map(m => { + const { ts } = m as any; + if (typeof ts === 'number') return ts; + if (typeof ts === 'string') { + const n = Number(ts); + return Number.isFinite(n) ? n : Date.parse(ts); + } + if (ts instanceof Date) return ts.getTime(); + return NaN; + }) + .filter(n => Number.isFinite(n)) as number[]; + + const oldestTsNumber = tsNumbers.length > 0 ? Math.min(...tsNumbers) : undefined; + if (oldestTsNumber) { + console.log('loadMissedMessages'); + await loadMissedMessages({ rid, lastOpen: new Date(oldestTsNumber) }); + } + } }); }, [rid, tmid, showMessageInMainThread, serverVersion, hideSystemMessages]); From 370e90e2d2a996db75a8be5946dca474d36adfa1 Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Wed, 24 Sep 2025 14:11:23 -0300 Subject: [PATCH 03/15] chore: update thread messages if only have threads --- app/lib/methods/loadMessagesForRoom.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/lib/methods/loadMessagesForRoom.ts b/app/lib/methods/loadMessagesForRoom.ts index 63f8c808c69..acd64b70aa7 100644 --- a/app/lib/methods/loadMessagesForRoom.ts +++ b/app/lib/methods/loadMessagesForRoom.ts @@ -53,8 +53,8 @@ export function loadMessagesForRoom(args: { } as IMessage; data.push(loadMoreMessage); } - - if (uniqueTmids) { + const onlyThreadMessages = !data.find(item => !item.tmid); + if (uniqueTmids && onlyThreadMessages) { await Promise.allSettled( uniqueTmids.map(async tmid => { const threadMessageRecord = (await sdk.get('chat.getMessage', { msgId: tmid as string })) as any; From af3bd46bb0f3bcb567c3fd236302cc6c1432173d Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Wed, 24 Sep 2025 14:34:31 -0300 Subject: [PATCH 04/15] fix: use loadPreviousMessages to avoid duplicated requests --- app/lib/methods/loadPreviousMessages.ts | 71 ++++++++++++++++++++ app/views/RoomView/List/hooks/useMessages.ts | 27 +++----- 2 files changed, 80 insertions(+), 18 deletions(-) create mode 100644 app/lib/methods/loadPreviousMessages.ts diff --git a/app/lib/methods/loadPreviousMessages.ts b/app/lib/methods/loadPreviousMessages.ts new file mode 100644 index 00000000000..69f5accb271 --- /dev/null +++ b/app/lib/methods/loadPreviousMessages.ts @@ -0,0 +1,71 @@ +import { compareServerVersion } from './helpers'; +import updateMessages from './updateMessages'; +import sdk from '../services/sdk'; +import { store } from '../store/auxStore'; +import { getSubscriptionByRoomId } from '../database/services/Subscription'; + +const count = 50; + +const syncMessages = async ({ roomId, previous, type }: { roomId: string; previous: number; type: 'UPDATED' | 'DELETED' }) => { + // @ts-ignore // this method dont have type + const { result } = await sdk.get('chat.syncMessages', { roomId, previous, count, type }); + return result; +}; + +const getSyncMessagesFromCursor = async (roomId: string, lastOpen: number) => { + const promises = []; + + if (lastOpen) { + promises.push(syncMessages({ roomId, previous: lastOpen, type: 'UPDATED' })); + promises.push(syncMessages({ roomId, previous: lastOpen, type: 'DELETED' })); + } + + const [updatedMessages, deletedMessages] = await Promise.all(promises); + return { + deleted: deletedMessages?.deleted ?? [], + deletedNext: deletedMessages?.cursor.next, + updated: updatedMessages?.updated ?? [], + updatedNext: updatedMessages?.cursor.next + }; +}; + +const getLastUpdate = async (rid: string) => { + const sub = await getSubscriptionByRoomId(rid); + if (!sub) { + return null; + } + return sub.lastOpen; +}; + +async function loadPreviousMessages({ rid: roomId, lastOpen }: { rid: string; lastOpen?: Date }) { + const { version: serverVersion } = store.getState().server; + if (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '7.1.0')) { + let lastOpenTimestamp; + if (lastOpen) { + lastOpenTimestamp = new Date(lastOpen).getTime(); + } else { + const lastUpdate = await getLastUpdate(roomId); + lastOpenTimestamp = lastUpdate?.getTime(); + } + if (!lastOpenTimestamp) { + return; + } + const result = await getSyncMessagesFromCursor(roomId, lastOpenTimestamp); + + await updateMessages({ rid: roomId, update: result.updated, remove: result.deleted }); + } + + let lastOpenISOString; + if (lastOpen) { + lastOpenISOString = new Date(lastOpen).toISOString(); + } else { + const lastUpdate = await getLastUpdate(roomId); + lastOpenISOString = lastUpdate?.toISOString(); + } + // RC 0.60.0 + // @ts-ignore // this method dont have type + const { result } = await sdk.get('chat.syncMessages', { roomId, lastUpdate: lastOpenISOString }); + return result; +} + +export default loadPreviousMessages; diff --git a/app/views/RoomView/List/hooks/useMessages.ts b/app/views/RoomView/List/hooks/useMessages.ts index e79eef81ff2..4d5695de115 100644 --- a/app/views/RoomView/List/hooks/useMessages.ts +++ b/app/views/RoomView/List/hooks/useMessages.ts @@ -2,7 +2,6 @@ import { useCallback, useLayoutEffect, useRef, useState } from 'react'; import { Q } from '@nozbe/watermelondb'; import { Subscription } from 'rxjs'; -import { loadMissedMessages } from '../../../../lib/methods'; import { TAnyMessageModel } from '../../../../definitions'; import database from '../../../../lib/database'; import { getMessageById } from '../../../../lib/database/services/Message'; @@ -10,6 +9,7 @@ import { getThreadById } from '../../../../lib/database/services/Thread'; import { compareServerVersion, useDebounce } from '../../../../lib/methods/helpers'; import { Services } from '../../../../lib/services'; import { QUERY_SIZE } from '../constants'; +import loadPreviousMessages from '../../../../lib/methods/loadPreviousMessages'; export const useMessages = ({ rid, @@ -86,26 +86,17 @@ export const useMessages = ({ setMessages(newMessages); messagesIds.current = newMessages.map(m => m.id); - const newIds = newMessages.map(m => m.id); - const addedIds = newIds.filter(id => !prevIds.includes(id)); - if (!addedIds.length) { - const tsNumbers = newMessages - .map(m => { - const { ts } = m as any; - if (typeof ts === 'number') return ts; - if (typeof ts === 'string') { - const n = Number(ts); - return Number.isFinite(n) ? n : Date.parse(ts); - } - if (ts instanceof Date) return ts.getTime(); - return NaN; - }) - .filter(n => Number.isFinite(n)) as number[]; + const addedIds = messagesIds.current?.filter(id => !prevIds.includes(id)); + if (!addedIds.length) { + const tsNumbers = newMessages.map(m => { + const { ts } = m as any; + return ts?.getTime(); + }); const oldestTsNumber = tsNumbers.length > 0 ? Math.min(...tsNumbers) : undefined; if (oldestTsNumber) { - console.log('loadMissedMessages'); - await loadMissedMessages({ rid, lastOpen: new Date(oldestTsNumber) }); + console.log('here'); + await loadPreviousMessages({ rid, lastOpen: new Date(oldestTsNumber) }); } } }); From 369e401674e71a31705be2cfc02b91fcdbf396f4 Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Fri, 10 Oct 2025 13:12:39 -0300 Subject: [PATCH 05/15] chore: code improvements --- app/views/RoomView/List/hooks/useMessages.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/app/views/RoomView/List/hooks/useMessages.ts b/app/views/RoomView/List/hooks/useMessages.ts index 4d5695de115..9e0ee26ba7a 100644 --- a/app/views/RoomView/List/hooks/useMessages.ts +++ b/app/views/RoomView/List/hooks/useMessages.ts @@ -95,7 +95,6 @@ export const useMessages = ({ }); const oldestTsNumber = tsNumbers.length > 0 ? Math.min(...tsNumbers) : undefined; if (oldestTsNumber) { - console.log('here'); await loadPreviousMessages({ rid, lastOpen: new Date(oldestTsNumber) }); } } From 0707ed38cd3100d7b8dcc7dffe3a6f3dd60a4e34 Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Fri, 10 Oct 2025 14:46:06 -0300 Subject: [PATCH 06/15] fix: rollback fetch on useMessages --- app/lib/methods/loadPreviousMessages.ts | 71 -------------------- app/views/RoomView/List/hooks/useMessages.ts | 21 +----- 2 files changed, 3 insertions(+), 89 deletions(-) delete mode 100644 app/lib/methods/loadPreviousMessages.ts diff --git a/app/lib/methods/loadPreviousMessages.ts b/app/lib/methods/loadPreviousMessages.ts deleted file mode 100644 index 69f5accb271..00000000000 --- a/app/lib/methods/loadPreviousMessages.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { compareServerVersion } from './helpers'; -import updateMessages from './updateMessages'; -import sdk from '../services/sdk'; -import { store } from '../store/auxStore'; -import { getSubscriptionByRoomId } from '../database/services/Subscription'; - -const count = 50; - -const syncMessages = async ({ roomId, previous, type }: { roomId: string; previous: number; type: 'UPDATED' | 'DELETED' }) => { - // @ts-ignore // this method dont have type - const { result } = await sdk.get('chat.syncMessages', { roomId, previous, count, type }); - return result; -}; - -const getSyncMessagesFromCursor = async (roomId: string, lastOpen: number) => { - const promises = []; - - if (lastOpen) { - promises.push(syncMessages({ roomId, previous: lastOpen, type: 'UPDATED' })); - promises.push(syncMessages({ roomId, previous: lastOpen, type: 'DELETED' })); - } - - const [updatedMessages, deletedMessages] = await Promise.all(promises); - return { - deleted: deletedMessages?.deleted ?? [], - deletedNext: deletedMessages?.cursor.next, - updated: updatedMessages?.updated ?? [], - updatedNext: updatedMessages?.cursor.next - }; -}; - -const getLastUpdate = async (rid: string) => { - const sub = await getSubscriptionByRoomId(rid); - if (!sub) { - return null; - } - return sub.lastOpen; -}; - -async function loadPreviousMessages({ rid: roomId, lastOpen }: { rid: string; lastOpen?: Date }) { - const { version: serverVersion } = store.getState().server; - if (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '7.1.0')) { - let lastOpenTimestamp; - if (lastOpen) { - lastOpenTimestamp = new Date(lastOpen).getTime(); - } else { - const lastUpdate = await getLastUpdate(roomId); - lastOpenTimestamp = lastUpdate?.getTime(); - } - if (!lastOpenTimestamp) { - return; - } - const result = await getSyncMessagesFromCursor(roomId, lastOpenTimestamp); - - await updateMessages({ rid: roomId, update: result.updated, remove: result.deleted }); - } - - let lastOpenISOString; - if (lastOpen) { - lastOpenISOString = new Date(lastOpen).toISOString(); - } else { - const lastUpdate = await getLastUpdate(roomId); - lastOpenISOString = lastUpdate?.toISOString(); - } - // RC 0.60.0 - // @ts-ignore // this method dont have type - const { result } = await sdk.get('chat.syncMessages', { roomId, lastUpdate: lastOpenISOString }); - return result; -} - -export default loadPreviousMessages; diff --git a/app/views/RoomView/List/hooks/useMessages.ts b/app/views/RoomView/List/hooks/useMessages.ts index 9e0ee26ba7a..07c0eca1c8d 100644 --- a/app/views/RoomView/List/hooks/useMessages.ts +++ b/app/views/RoomView/List/hooks/useMessages.ts @@ -7,9 +7,8 @@ import database from '../../../../lib/database'; import { getMessageById } from '../../../../lib/database/services/Message'; import { getThreadById } from '../../../../lib/database/services/Thread'; import { compareServerVersion, useDebounce } from '../../../../lib/methods/helpers'; -import { Services } from '../../../../lib/services'; +import { readThreads } from '../../../../lib/services/restApi'; import { QUERY_SIZE } from '../constants'; -import loadPreviousMessages from '../../../../lib/methods/loadPreviousMessages'; export const useMessages = ({ rid, @@ -33,7 +32,6 @@ export const useMessages = ({ const fetchMessages = useCallback(async () => { unsubscribe(); count.current += QUERY_SIZE; - const prevIds = messagesIds.current; if (!rid) { return; @@ -68,7 +66,7 @@ export const useMessages = ({ .observe(); } - subscription.current = observable.subscribe(async result => { + subscription.current = observable.subscribe(result => { let newMessages: TAnyMessageModel[] = result; if (tmid && thread.current) { newMessages.push(thread.current); @@ -85,26 +83,13 @@ export const useMessages = ({ readThread(); setMessages(newMessages); messagesIds.current = newMessages.map(m => m.id); - - const addedIds = messagesIds.current?.filter(id => !prevIds.includes(id)); - - if (!addedIds.length) { - const tsNumbers = newMessages.map(m => { - const { ts } = m as any; - return ts?.getTime(); - }); - const oldestTsNumber = tsNumbers.length > 0 ? Math.min(...tsNumbers) : undefined; - if (oldestTsNumber) { - await loadPreviousMessages({ rid, lastOpen: new Date(oldestTsNumber) }); - } - } }); }, [rid, tmid, showMessageInMainThread, serverVersion, hideSystemMessages]); const readThread = useDebounce(async () => { if (tmid) { try { - await Services.readThreads(tmid); + await readThreads(tmid); } catch { // Do nothing } From be4cf3083a94d7111ddab06191911dbc2663d13f Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Fri, 10 Oct 2025 15:14:41 -0300 Subject: [PATCH 07/15] chore: refactor loadMessagesForRoom --- app/lib/methods/loadMessagesForRoom.ts | 62 +++++++++++++++++--------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/app/lib/methods/loadMessagesForRoom.ts b/app/lib/methods/loadMessagesForRoom.ts index acd64b70aa7..09d06f53919 100644 --- a/app/lib/methods/loadMessagesForRoom.ts +++ b/app/lib/methods/loadMessagesForRoom.ts @@ -11,23 +11,52 @@ import { generateLoadMoreId } from './helpers/generateLoadMoreId'; const COUNT = 50; -async function load({ rid: roomId, latest, t }: { rid: string; latest?: Date; t: RoomTypes }): Promise { - let params = { roomId, count: COUNT } as { roomId: string; count: number; latest?: string }; - if (latest) { - params = { ...params, latest: new Date(latest).toISOString() }; - } +interface HistoryParams { + roomId: string; + count: number; + latest?: string; +} +async function load({ rid: roomId, latest, t }: { rid: string; latest?: Date; t: RoomTypes }): Promise { const apiType = roomTypeToApiType(t); if (!apiType) { return []; } - // RC 0.48.0 - const data = await sdk.get(`${apiType}.history`, params); - if (!data.success) { - return []; + const allMessages: IMessage[] = []; + let mainMessagesCount = 0; + + async function fetchBatch(lastTs?: string): Promise { + const params: HistoryParams = { roomId, count: COUNT }; + if (lastTs) { + params.latest = lastTs; + } + + const data = await sdk.get(`${apiType}.history`, params); + + if (!data?.success || !data.messages?.length) { + return; + } + + const batch = data.messages as IMessage[]; + allMessages.push(...batch); + + const mainMessagesInBatch = batch.filter(message => !message.tmid); + mainMessagesCount += mainMessagesInBatch.length; + + const needsMoreMainMessages = mainMessagesCount < COUNT; + const hasMoreMessages = batch.length === COUNT; + + if (needsMoreMainMessages && hasMoreMessages) { + const lastMessage = batch[batch.length - 1]; + return fetchBatch(lastMessage.ts as string); + } } - return data.messages as IMessage[]; + + const startTimestamp = latest ? new Date(latest).toISOString() : undefined; + await fetchBatch(startTimestamp); + + return allMessages; } export function loadMessagesForRoom(args: { @@ -42,8 +71,7 @@ export function loadMessagesForRoom(args: { if (data?.length) { const lastMessage = data[data.length - 1]; const lastMessageRecord = await getMessageById(lastMessage._id as string); - const uniqueTmids = [...new Set(data.map(m => m.tmid).filter(Boolean))]; - if (!lastMessageRecord && data.length === COUNT && !uniqueTmids) { + if (!lastMessageRecord && data.length === COUNT) { const loadMoreMessage = { _id: generateLoadMoreId(lastMessage._id as string), rid: lastMessage.rid, @@ -53,16 +81,6 @@ export function loadMessagesForRoom(args: { } as IMessage; data.push(loadMoreMessage); } - const onlyThreadMessages = !data.find(item => !item.tmid); - if (uniqueTmids && onlyThreadMessages) { - await Promise.allSettled( - uniqueTmids.map(async tmid => { - const threadMessageRecord = (await sdk.get('chat.getMessage', { msgId: tmid as string })) as any; - data.push(threadMessageRecord?.message as IMessage); - }) - ); - } - await updateMessages({ rid: args.rid, update: data, loaderItem: args.loaderItem }); return resolve(); } From 20c7da6aa6a163454c2d0eedc7d5da10af85ccae Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Mon, 13 Oct 2025 16:26:10 -0300 Subject: [PATCH 08/15] fix: load messages for room code improvements --- app/lib/methods/loadMessagesForRoom.ts | 35 +++++++++++++++----------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/app/lib/methods/loadMessagesForRoom.ts b/app/lib/methods/loadMessagesForRoom.ts index 3b32717bda8..94ea7d74798 100644 --- a/app/lib/methods/loadMessagesForRoom.ts +++ b/app/lib/methods/loadMessagesForRoom.ts @@ -11,12 +11,6 @@ import { generateLoadMoreId } from './helpers/generateLoadMoreId'; const COUNT = 50; -interface HistoryParams { - roomId: string; - count: number; - latest?: string; -} - async function load({ rid: roomId, latest, t }: { rid: string; latest?: Date; t: RoomTypes }): Promise { const apiType = roomTypeToApiType(t); if (!apiType) { @@ -27,12 +21,26 @@ async function load({ rid: roomId, latest, t }: { rid: string; latest?: Date; t: let mainMessagesCount = 0; async function fetchBatch(lastTs?: string): Promise { - const params: HistoryParams = { roomId, count: COUNT }; - if (lastTs) { - params.latest = lastTs; + if (allMessages.length >= COUNT * 10) { + return; } - const data = await sdk.get(`${apiType}.history`, params); + const params = { roomId, count: COUNT, ...(lastTs && { latest: lastTs }) }; + + let data; + switch (apiType) { + case 'channels': + data = await sdk.get('channels.history', params); + break; + case 'groups': + data = await sdk.get('groups.history', params); + break; + case 'im': + data = await sdk.get('im.history', params); + break; + default: + return; + } if (!data?.success || !data.messages?.length) { return; @@ -45,17 +53,16 @@ async function load({ rid: roomId, latest, t }: { rid: string; latest?: Date; t: mainMessagesCount += mainMessagesInBatch.length; const needsMoreMainMessages = mainMessagesCount < COUNT; - const hasMoreMessages = batch.length === COUNT; - if (needsMoreMainMessages && hasMoreMessages) { + if (needsMoreMainMessages) { const lastMessage = batch[batch.length - 1]; - return fetchBatch(lastMessage.ts as string); + await fetchBatch(lastMessage.ts as string); } } const startTimestamp = latest ? new Date(latest).toISOString() : undefined; await fetchBatch(startTimestamp); - + console.log('allMessages', allMessages); return allMessages; } From 79a4bcefb6ffaf6286558dfcdf9f918d558cbe97 Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Mon, 13 Oct 2025 16:26:19 -0300 Subject: [PATCH 09/15] chore: e2e tests --- .../room-last-message-thread-50-plus.yaml | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .maestro/tests/room/room-last-message-thread-50-plus.yaml diff --git a/.maestro/tests/room/room-last-message-thread-50-plus.yaml b/.maestro/tests/room/room-last-message-thread-50-plus.yaml new file mode 100644 index 00000000000..f49bb0a35d0 --- /dev/null +++ b/.maestro/tests/room/room-last-message-thread-50-plus.yaml @@ -0,0 +1,32 @@ +appId: chat.rocket.reactnative +name: Open room with last message as thread with more than 50 messages +onFlowStart: + - runFlow: '../../helpers/setup.yaml' +tags: + - test-12 + +--- +- runFlow: + file: '../../helpers/login-with-deeplink.yaml' + env: + USERNAME: ${output.account.adminUser} + PASSWORD: ${output.account.adminPassword} + +# should open a room where the last message is a thread containing more than 50 messages. +- runFlow: + file: '../../helpers/navigate-to-room.yaml' + env: + ROOM: 'maestro_test_load_threads' +- extendedWaitUntil: + visible: + text: '.*message 50.*' + timeout: 60000 +- extendedWaitUntil: + visible: + id: 'thread-count-55' + timeout: 60000 +- scrollUntilVisible: + element: + id: 'message-content-message 1' + direction: UP + timeout: 60000 From 48e876d5084ba5b480992ad583cff8f21d579db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ot=C3=A1vio=20Stasiak?= <91474186+OtavioStasiak@users.noreply.github.com> Date: Mon, 13 Oct 2025 16:43:45 -0300 Subject: [PATCH 10/15] fix: remove unused logs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- app/lib/methods/loadMessagesForRoom.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/lib/methods/loadMessagesForRoom.ts b/app/lib/methods/loadMessagesForRoom.ts index 94ea7d74798..f1ce0bd7091 100644 --- a/app/lib/methods/loadMessagesForRoom.ts +++ b/app/lib/methods/loadMessagesForRoom.ts @@ -62,7 +62,9 @@ async function load({ rid: roomId, latest, t }: { rid: string; latest?: Date; t: const startTimestamp = latest ? new Date(latest).toISOString() : undefined; await fetchBatch(startTimestamp); - console.log('allMessages', allMessages); + const startTimestamp = latest ? new Date(latest).toISOString() : undefined; + await fetchBatch(startTimestamp); + return allMessages; return allMessages; } From 4bfe21cba1efda177c17e3e0943001404dd27d48 Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Mon, 13 Oct 2025 19:44:47 +0000 Subject: [PATCH 11/15] chore: format code with Prettier [skip ci] --- app/lib/methods/loadMessagesForRoom.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/lib/methods/loadMessagesForRoom.ts b/app/lib/methods/loadMessagesForRoom.ts index f1ce0bd7091..0f7b5538b86 100644 --- a/app/lib/methods/loadMessagesForRoom.ts +++ b/app/lib/methods/loadMessagesForRoom.ts @@ -62,9 +62,9 @@ async function load({ rid: roomId, latest, t }: { rid: string; latest?: Date; t: const startTimestamp = latest ? new Date(latest).toISOString() : undefined; await fetchBatch(startTimestamp); - const startTimestamp = latest ? new Date(latest).toISOString() : undefined; - await fetchBatch(startTimestamp); - return allMessages; + const startTimestamp = latest ? new Date(latest).toISOString() : undefined; + await fetchBatch(startTimestamp); + return allMessages; return allMessages; } From 8cccb16c5cf3c73fb918b6cbda7ab9a910015555 Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Tue, 14 Oct 2025 16:33:08 -0300 Subject: [PATCH 12/15] fix: duplicaded code --- app/lib/methods/loadMessagesForRoom.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/lib/methods/loadMessagesForRoom.ts b/app/lib/methods/loadMessagesForRoom.ts index 0f7b5538b86..232c42b2959 100644 --- a/app/lib/methods/loadMessagesForRoom.ts +++ b/app/lib/methods/loadMessagesForRoom.ts @@ -62,9 +62,6 @@ async function load({ rid: roomId, latest, t }: { rid: string; latest?: Date; t: const startTimestamp = latest ? new Date(latest).toISOString() : undefined; await fetchBatch(startTimestamp); - const startTimestamp = latest ? new Date(latest).toISOString() : undefined; - await fetchBatch(startTimestamp); - return allMessages; return allMessages; } From 9c8e8ea8dbb0642c90da0904c422415f9f836724 Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Thu, 16 Oct 2025 18:41:15 -0300 Subject: [PATCH 13/15] fix: loadMoreMessage not added --- app/lib/methods/loadMessagesForRoom.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/lib/methods/loadMessagesForRoom.ts b/app/lib/methods/loadMessagesForRoom.ts index 232c42b2959..fb0f759bd4f 100644 --- a/app/lib/methods/loadMessagesForRoom.ts +++ b/app/lib/methods/loadMessagesForRoom.ts @@ -53,7 +53,10 @@ async function load({ rid: roomId, latest, t }: { rid: string; latest?: Date; t: mainMessagesCount += mainMessagesInBatch.length; const needsMoreMainMessages = mainMessagesCount < COUNT; - + console.log('needsMoreMainMessages', needsMoreMainMessages); + console.log('mainMessagesCount', mainMessagesCount); + console.log('batch', batch.length); + console.log('allMessages', allMessages.length); if (needsMoreMainMessages) { const lastMessage = batch[batch.length - 1]; await fetchBatch(lastMessage.ts as string); @@ -77,7 +80,7 @@ export function loadMessagesForRoom(args: { if (data?.length) { const lastMessage = data[data.length - 1]; const lastMessageRecord = await getMessageById(lastMessage._id as string); - if (!lastMessageRecord && data.length === COUNT) { + if (!lastMessageRecord && (data.length === COUNT || data.length >= COUNT * 10)) { const loadMoreMessage = { _id: generateLoadMoreId(lastMessage._id as string), rid: lastMessage.rid, From 5b9d71f1d1b66374c6db1c4ccdcea1020719df33 Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Fri, 17 Oct 2025 12:25:18 -0300 Subject: [PATCH 14/15] fix: remove unused logs --- app/lib/methods/loadMessagesForRoom.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/lib/methods/loadMessagesForRoom.ts b/app/lib/methods/loadMessagesForRoom.ts index 55f7f9f32f7..f6178d4432c 100644 --- a/app/lib/methods/loadMessagesForRoom.ts +++ b/app/lib/methods/loadMessagesForRoom.ts @@ -53,10 +53,7 @@ async function load({ rid: roomId, latest, t }: { rid: string; latest?: Date; t: mainMessagesCount += mainMessagesInBatch.length; const needsMoreMainMessages = mainMessagesCount < COUNT; - console.log('needsMoreMainMessages', needsMoreMainMessages); - console.log('mainMessagesCount', mainMessagesCount); - console.log('batch', batch.length); - console.log('allMessages', allMessages.length); + if (needsMoreMainMessages) { const lastMessage = batch[batch.length - 1]; await fetchBatch(lastMessage.ts as string); From b75405406da220d2a1bcf20d7956294376fbc401 Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Fri, 17 Oct 2025 17:46:23 -0300 Subject: [PATCH 15/15] chore: code improvements --- app/lib/methods/loadMessagesForRoom.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/lib/methods/loadMessagesForRoom.ts b/app/lib/methods/loadMessagesForRoom.ts index f6178d4432c..501ed034f26 100644 --- a/app/lib/methods/loadMessagesForRoom.ts +++ b/app/lib/methods/loadMessagesForRoom.ts @@ -10,6 +10,7 @@ import updateMessages from './updateMessages'; import { generateLoadMoreId } from './helpers/generateLoadMoreId'; const COUNT = 50; +const COUNT_LIMIT = COUNT * 10; async function load({ rid: roomId, latest, t }: { rid: string; latest?: Date; t: RoomTypes }): Promise { const apiType = roomTypeToApiType(t); @@ -21,7 +22,7 @@ async function load({ rid: roomId, latest, t }: { rid: string; latest?: Date; t: let mainMessagesCount = 0; async function fetchBatch(lastTs?: string): Promise { - if (allMessages.length >= COUNT * 10) { + if (allMessages.length >= COUNT_LIMIT) { return; } @@ -77,7 +78,7 @@ export function loadMessagesForRoom(args: { if (data?.length) { const lastMessage = data[data.length - 1]; const lastMessageRecord = await getMessageById(lastMessage._id as string); - if (!lastMessageRecord && (data.length === COUNT || data.length >= COUNT * 10)) { + if (!lastMessageRecord && (data.length === COUNT || data.length >= COUNT_LIMIT)) { const loadMoreMessage = { _id: generateLoadMoreId(lastMessage._id as string), rid: lastMessage.rid,