Page MenuHomePhorge

D8073.1768405590.diff
No OneTemporary

Size
9 KB
Referenced Files
None
Subscribers
None

D8073.1768405590.diff

diff --git a/keyserver/src/endpoints.js b/keyserver/src/endpoints.js
--- a/keyserver/src/endpoints.js
+++ b/keyserver/src/endpoints.js
@@ -37,6 +37,7 @@
editMessageCreationResponder,
fetchPinnedMessagesResponder,
searchMessagesResponder,
+ fetchLatestMessages,
} from './responders/message-responders.js';
import { updateRelationshipsResponder } from './responders/relationship-responders.js';
import {
@@ -219,6 +220,10 @@
responder: searchMessagesResponder,
requiredPolicies: baseLegalPolicies,
},
+ fetch_latest_messages: {
+ responder: fetchLatestMessages,
+ requiredPolicies: baseLegalPolicies,
+ },
search_users: {
responder: userSearchResponder,
requiredPolicies: baseLegalPolicies,
diff --git a/keyserver/src/fetchers/thread-fetchers.js b/keyserver/src/fetchers/thread-fetchers.js
--- a/keyserver/src/fetchers/thread-fetchers.js
+++ b/keyserver/src/fetchers/thread-fetchers.js
@@ -308,6 +308,44 @@
return threads.threadInfos[threadID];
}
+async function fetchThreadsWithLatestMessages(
+ userID: string,
+ home: boolean,
+ fromMessageID: string,
+): Promise<{
+ +allThreads: $ReadOnlyArray<string>,
+ +threadsExcludingParents: Set<string>,
+}> {
+ const query = SQL`
+ SELECT m.thread, t.type, t.parent_thread_id
+ FROM memberships m
+ LEFT JOIN threads t ON m.thread = t.id
+ WHERE m.user = ${userID} AND
+ m.role > 0 AND
+ m.last_message < ${fromMessageID} AND
+ JSON_EXTRACT(m.subscription, '$.home') IS ${home}
+ ORDER BY m.last_message DESC
+ LIMIT 25
+ `;
+
+ const [result] = await dbQuery(query);
+
+ const allThreads = new Set();
+ const threadsExcludingParents = new Set();
+ for (const row of result) {
+ allThreads.add(row.thread.toString());
+ threadsExcludingParents.add(row.thread.toString());
+ if (row.type === threadTypes.SIDEBAR) {
+ allThreads.add(row.parent_thread_id);
+ }
+ }
+
+ return {
+ allThreads: [...allThreads],
+ threadsExcludingParents,
+ };
+}
+
export {
fetchServerThreadInfos,
fetchThreadInfos,
@@ -318,4 +356,5 @@
personalThreadQuery,
fetchPersonalThreadID,
serverThreadInfoFromMessageInfo,
+ fetchThreadsWithLatestMessages,
};
diff --git a/keyserver/src/responders/message-responders.js b/keyserver/src/responders/message-responders.js
--- a/keyserver/src/responders/message-responders.js
+++ b/keyserver/src/responders/message-responders.js
@@ -1,6 +1,7 @@
// @flow
import invariant from 'invariant';
+import _min from 'lodash/fp/min.js';
import t, { type TInterface } from 'tcomb';
import { onlyOneEmojiRegex } from 'lib/shared/emojis.js';
@@ -27,6 +28,8 @@
rawMessageInfoValidator,
type SearchMessagesResponse,
type SearchMessagesRequest,
+ type FetchLatestMessagesRequest,
+ type FetchLatestMessagesResponse,
} from 'lib/types/message-types.js';
import type { EditMessageData } from 'lib/types/messages/edit.js';
import type { ReactionMessageData } from 'lib/types/messages/reaction.js';
@@ -52,7 +55,10 @@
fetchPinnedMessageInfos,
searchMessagesInSingleChat,
} from '../fetchers/message-fetchers.js';
-import { fetchServerThreadInfos } from '../fetchers/thread-fetchers.js';
+import {
+ fetchServerThreadInfos,
+ fetchThreadsWithLatestMessages,
+} from '../fetchers/thread-fetchers.js';
import { checkThreadPermission } from '../fetchers/thread-permission-fetchers.js';
import {
fetchImages,
@@ -514,6 +520,58 @@
);
}
+const fetchLatestMessagesInputValidator = tShape<FetchLatestMessagesRequest>({
+ home: t.Boolean,
+ fromMessage: tID,
+});
+
+const fetchLatestMessagesResponseValidator =
+ tShape<FetchLatestMessagesResponse>({
+ rawMessageInfos: t.list(rawMessageInfoValidator),
+ truncationStatuses: messageTruncationStatusesValidator,
+ oldestMessage: t.maybe(tID),
+ });
+
+async function fetchLatestMessages(
+ viewer: Viewer,
+ input: mixed,
+): Promise<FetchLatestMessagesResponse> {
+ const request = await validateInput(
+ viewer,
+ fetchLatestMessagesInputValidator,
+ input,
+ );
+ const { allThreads, threadsExcludingParents } =
+ await fetchThreadsWithLatestMessages(
+ viewer.userID,
+ request.home,
+ request.fromMessage,
+ );
+
+ if (allThreads.length === 0) {
+ return { rawMessageInfos: [], truncationStatuses: {}, oldestMessage: null };
+ }
+
+ const threadCursors = {};
+ for (const threadID of allThreads) {
+ threadCursors[threadID] = null;
+ }
+
+ const response = await fetchMessageInfos(viewer, { threadCursors }, 1);
+
+ const oldestMessage = _min(
+ response.rawMessageInfos
+ .filter(message => threadsExcludingParents.has(message.threadID))
+ .map(message => Number(message.id)),
+ ).toString();
+
+ return validateOutput(
+ viewer.platformDetails,
+ fetchLatestMessagesResponseValidator,
+ { ...response, oldestMessage },
+ );
+}
+
export {
textMessageCreationResponder,
messageFetchResponder,
@@ -522,4 +580,5 @@
editMessageCreationResponder,
fetchPinnedMessagesResponder,
searchMessagesResponder,
+ fetchLatestMessages,
};
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
@@ -13,6 +13,8 @@
FetchPinnedMessagesResult,
SearchMessagesRequest,
SearchMessagesResponse,
+ FetchLatestMessagesRequest,
+ FetchLatestMessagesResponse,
} from '../types/message-types.js';
import type { MediaMessageServerDBContent } from '../types/messages/media.js';
import type {
@@ -302,6 +304,26 @@
};
};
+const fetchLatestMessagesActionTypes = Object.freeze({
+ started: 'FETCH_LATEST_MESSAGES_STARTED',
+ success: 'FETCH_LATEST_MESSAGES_SUCCESS',
+ failed: 'FETCH_LATEST_MESSAGES_FAILED',
+});
+const fetchLatestMessages =
+ (
+ callServerEndpoint: CallServerEndpoint,
+ ): ((
+ request: FetchLatestMessagesRequest,
+ ) => Promise<FetchLatestMessagesResponse>) =>
+ async request => {
+ const response = await callServerEndpoint('fetch_latest_messages', request);
+ return {
+ rawMessageInfos: response.rawMessageInfos,
+ truncationStatuses: response.truncationStatuses,
+ oldestMessage: response.oldestMessage,
+ };
+ };
+
export {
fetchMessagesBeforeCursorActionTypes,
fetchMessagesBeforeCursor,
@@ -326,4 +348,6 @@
sendEditMessage,
fetchPinnedMessages,
fetchPinnedMessageActionTypes,
+ fetchLatestMessagesActionTypes,
+ fetchLatestMessages,
};
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
@@ -33,6 +33,7 @@
messageStorePruneActionType,
createLocalMessageActionType,
fetchSingleMostRecentMessagesFromThreadsActionTypes,
+ fetchLatestMessagesActionTypes,
} from '../actions/message-actions.js';
import { sendMessageReportActionTypes } from '../actions/message-report-actions.js';
import { siweAuthActionTypes } from '../actions/siwe-actions.js';
@@ -887,7 +888,9 @@
action.type,
);
} else if (
- action.type === fetchSingleMostRecentMessagesFromThreadsActionTypes.success
+ action.type ===
+ fetchSingleMostRecentMessagesFromThreadsActionTypes.success ||
+ action.type === fetchLatestMessagesActionTypes.success
) {
return mergeNewMessages(
messageStore,
diff --git a/lib/types/endpoints.js b/lib/types/endpoints.js
--- a/lib/types/endpoints.js
+++ b/lib/types/endpoints.js
@@ -96,6 +96,7 @@
SEARCH_MESSAGES: 'search_messages',
GET_OLM_SESSION_INITIALIZATION_DATA: 'get_olm_session_initialization_data',
VERSION: 'version',
+ FETCH_LATEST_MESSAGES: 'fetch_latest_messages',
});
type SocketPreferredEndpoint = $Values<typeof socketPreferredEndpoints>;
diff --git a/lib/types/message-types.js b/lib/types/message-types.js
--- a/lib/types/message-types.js
+++ b/lib/types/message-types.js
@@ -728,3 +728,14 @@
+messages: $ReadOnlyArray<RawMessageInfo>,
+endReached: boolean,
};
+
+export type FetchLatestMessagesRequest = {
+ +home: boolean,
+ +fromMessage: string,
+};
+
+export type FetchLatestMessagesResponse = {
+ +rawMessageInfos: $ReadOnlyArray<RawMessageInfo>,
+ +truncationStatuses: MessageTruncationStatuses,
+ +oldestMessage: ?string,
+};
diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js
--- a/lib/types/redux-types.js
+++ b/lib/types/redux-types.js
@@ -62,6 +62,7 @@
ClientDBThreadMessageInfo,
FetchPinnedMessagesResult,
SearchMessagesResponse,
+ FetchLatestMessagesResponse,
} from './message-types.js';
import type { RawReactionMessageInfo } from './messages/reaction.js';
import type { RawTextMessageInfo } from './messages/text.js';
@@ -1159,6 +1160,22 @@
+error: true,
+payload: Error,
+loadingInfo: LoadingInfo,
+ }
+ | {
+ +type: 'FETCH_LATEST_MESSAGES_STARTED',
+ +payload: void,
+ +loadingInfo?: LoadingInfo,
+ }
+ | {
+ +type: 'FETCH_LATEST_MESSAGES_SUCCESS',
+ +payload: FetchLatestMessagesResponse,
+ +loadingInfo: LoadingInfo,
+ }
+ | {
+ +type: 'FETCH_LATEST_MESSAGES_FAILED',
+ +error: true,
+ +payload: Error,
+ +loadingInfo: LoadingInfo,
};
export type ActionPayload = ?(Object | Array<*> | $ReadOnlyArray<*> | string);

File Metadata

Mime Type
text/plain
Expires
Wed, Jan 14, 3:46 PM (8 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5932320
Default Alt Text
D8073.1768405590.diff (9 KB)

Event Timeline