Page MenuHomePhabricator

D9240.diff
No OneTemporary

D9240.diff

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
@@ -15,36 +15,59 @@
SearchMessagesResponse,
} from '../types/message-types.js';
import type { MediaMessageServerDBContent } from '../types/messages/media.js';
-import type {
- CallServerEndpoint,
- CallServerEndpointResultInfo,
-} from '../utils/call-server-endpoint.js';
+import {
+ extractKeyserverIDFromID,
+ sortThreadIDsPerKeyserver,
+} from '../utils/action-utils.js';
+import type { CallServerEndpointResultInfo } from '../utils/call-server-endpoint.js';
+import { useKeyserverCall } from '../utils/keyserver-call.js';
+import type { CallKeyserverEndpoint } from '../utils/keyserver-call.js';
const fetchMessagesBeforeCursorActionTypes = Object.freeze({
started: 'FETCH_MESSAGES_BEFORE_CURSOR_STARTED',
success: 'FETCH_MESSAGES_BEFORE_CURSOR_SUCCESS',
failed: 'FETCH_MESSAGES_BEFORE_CURSOR_FAILED',
});
+export type FetchMessagesBeforeCursorInput = {
+ +threadID: string,
+ +beforeMessageID: string,
+};
const fetchMessagesBeforeCursor =
(
- callServerEndpoint: CallServerEndpoint,
+ callKeyserverEndpoint: CallKeyserverEndpoint,
): ((
- threadID: string,
- beforeMessageID: string,
+ input: FetchMessagesBeforeCursorInput,
) => Promise<FetchMessageInfosPayload>) =>
- async (threadID, beforeMessageID) => {
- const response = await callServerEndpoint('fetch_messages', {
- cursors: {
- [threadID]: beforeMessageID,
+ async input => {
+ const { threadID, beforeMessageID } = input;
+
+ const keyserverID = extractKeyserverIDFromID(input.threadID);
+ const requests = {
+ [keyserverID]: {
+ cursors: {
+ [threadID]: beforeMessageID,
+ },
},
- });
+ };
+
+ const responses = await callKeyserverEndpoint('fetch_messages', requests);
return {
threadID,
- rawMessageInfos: response.rawMessageInfos,
- truncationStatus: response.truncationStatuses[threadID],
+ rawMessageInfos: responses[keyserverID].rawMessageInfos,
+ truncationStatus: responses[keyserverID].truncationStatuses[threadID],
};
};
+function useFetchMessagesBeforeCursor(): (
+ input: FetchMessagesBeforeCursorInput,
+) => Promise<FetchMessageInfosPayload> {
+ return useKeyserverCall(fetchMessagesBeforeCursor);
+}
+
+export type FetchMostRecentMessagesInput = {
+ +threadID: string,
+};
+
const fetchMostRecentMessagesActionTypes = Object.freeze({
started: 'FETCH_MOST_RECENT_MESSAGES_STARTED',
success: 'FETCH_MOST_RECENT_MESSAGES_SUCCESS',
@@ -52,21 +75,36 @@
});
const fetchMostRecentMessages =
(
- callServerEndpoint: CallServerEndpoint,
- ): ((threadID: string) => Promise<FetchMessageInfosPayload>) =>
- async threadID => {
- const response = await callServerEndpoint('fetch_messages', {
- cursors: {
- [threadID]: null,
+ callKeyserverEndpoint: CallKeyserverEndpoint,
+ ): ((
+ input: FetchMostRecentMessagesInput,
+ ) => Promise<FetchMessageInfosPayload>) =>
+ async input => {
+ const { threadID } = input;
+
+ const keyserverID = extractKeyserverIDFromID(input.threadID);
+ const requests = {
+ [keyserverID]: {
+ cursors: {
+ [threadID]: null,
+ },
},
- });
+ };
+
+ const responses = await callKeyserverEndpoint('fetch_messages', requests);
return {
threadID,
- rawMessageInfos: response.rawMessageInfos,
- truncationStatus: response.truncationStatuses[threadID],
+ rawMessageInfos: responses[keyserverID].rawMessageInfos,
+ truncationStatus: responses[keyserverID].truncationStatuses[threadID],
};
};
+function useFetchMostRecentMessages(): (
+ input: FetchMostRecentMessagesInput,
+) => Promise<FetchMessageInfosPayload> {
+ return useKeyserverCall(fetchMostRecentMessages);
+}
+
const fetchSingleMostRecentMessagesFromThreadsActionTypes = Object.freeze({
started: 'FETCH_SINGLE_MOST_RECENT_MESSAGES_FROM_THREADS_STARTED',
success: 'FETCH_SINGLE_MOST_RECENT_MESSAGES_FROM_THREADS_SUCCESS',
@@ -74,22 +112,54 @@
});
const fetchSingleMostRecentMessagesFromThreads =
(
- callServerEndpoint: CallServerEndpoint,
+ callKeyserverEndpoint: CallKeyserverEndpoint,
): ((threadIDs: $ReadOnlyArray<string>) => Promise<SimpleMessagesPayload>) =>
async threadIDs => {
- const cursors = Object.fromEntries(
- threadIDs.map(threadID => [threadID, null]),
- );
- const response = await callServerEndpoint('fetch_messages', {
- cursors,
- numberPerThread: 1,
- });
+ const sortedThreadIDs = sortThreadIDsPerKeyserver(threadIDs);
+
+ const requests = {};
+ for (const keyserverID in sortedThreadIDs) {
+ const cursors = Object.fromEntries(
+ sortedThreadIDs[keyserverID].map(threadID => [threadID, null]),
+ );
+ requests[keyserverID] = {
+ cursors,
+ numberPerThread: 1,
+ };
+ }
+
+ const responses = await callKeyserverEndpoint('fetch_messages', requests);
+ let rawMessageInfos = [];
+ let truncationStatuses = {};
+ for (const keyserverID in responses) {
+ rawMessageInfos = rawMessageInfos.concat(
+ responses[keyserverID].rawMessageInfos,
+ );
+ truncationStatuses = {
+ ...truncationStatuses,
+ ...responses[keyserverID].truncationStatuses,
+ };
+ }
+
return {
- rawMessageInfos: response.rawMessageInfos,
- truncationStatuses: response.truncationStatuses,
+ rawMessageInfos,
+ truncationStatuses,
};
};
+function useFetchSingleMostRecentMessagesFromThreads(): (
+ threadIDs: $ReadOnlyArray<string>,
+) => Promise<SimpleMessagesPayload> {
+ return useKeyserverCall(fetchSingleMostRecentMessagesFromThreads);
+}
+
+export type SendTextMessageInput = {
+ +threadID: string,
+ +localID: string,
+ +text: string,
+ +sidebarCreation?: boolean,
+};
+
const sendTextMessageActionTypes = Object.freeze({
started: 'SEND_TEXT_MESSAGE_STARTED',
success: 'SEND_TEXT_MESSAGE_SUCCESS',
@@ -97,39 +167,56 @@
});
const sendTextMessage =
(
- callServerEndpoint: CallServerEndpoint,
- ): ((
- threadID: string,
- localID: string,
- text: string,
- sidebarCreation?: boolean,
- ) => Promise<SendMessageResult>) =>
- async (threadID, localID, text, sidebarCreation) => {
+ callKeyserverEndpoint: CallKeyserverEndpoint,
+ ): ((input: SendTextMessageInput) => Promise<SendMessageResult>) =>
+ async input => {
let resultInfo;
const getResultInfo = (passedResultInfo: CallServerEndpointResultInfo) => {
resultInfo = passedResultInfo;
};
+ const { threadID, localID, text, sidebarCreation } = input;
let payload = { threadID, localID, text };
if (sidebarCreation) {
payload = { ...payload, sidebarCreation };
}
- const response = await callServerEndpoint('create_text_message', payload, {
- getResultInfo,
- });
+
+ const keyserverID = extractKeyserverIDFromID(input.threadID);
+ const requests = { [keyserverID]: payload };
+
+ const responses = await callKeyserverEndpoint(
+ 'create_text_message',
+ requests,
+ {
+ getResultInfo,
+ },
+ );
const resultInterface = resultInfo?.interface;
invariant(
resultInterface,
- 'getResultInfo not called before callServerEndpoint resolves',
+ 'getResultInfo not called before callKeyserverEndpoint resolves',
);
return {
- id: response.newMessageInfo.id,
- time: response.newMessageInfo.time,
+ id: responses[keyserverID].newMessageInfo.id,
+ time: responses[keyserverID].newMessageInfo.time,
interface: resultInterface,
};
};
+function useSendTextMessage(): (
+ input: SendTextMessageInput,
+) => Promise<SendMessageResult> {
+ return useKeyserverCall(sendTextMessage);
+}
+
const createLocalMessageActionType = 'CREATE_LOCAL_MESSAGE';
+export type SendMultimediaMessageInput = {
+ +threadID: string,
+ +localID: string,
+ +mediaMessageContents: $ReadOnlyArray<MediaMessageServerDBContent>,
+ +sidebarCreation?: boolean,
+};
+
const sendMultimediaMessageActionTypes = Object.freeze({
started: 'SEND_MULTIMEDIA_MESSAGE_STARTED',
success: 'SEND_MULTIMEDIA_MESSAGE_SUCCESS',
@@ -137,74 +224,95 @@
});
const sendMultimediaMessage =
(
- callServerEndpoint: CallServerEndpoint,
- ): ((
- threadID: string,
- localID: string,
- mediaMessageContents: $ReadOnlyArray<MediaMessageServerDBContent>,
- sidebarCreation?: boolean,
- ) => Promise<SendMessageResult>) =>
- async (threadID, localID, mediaMessageContents, sidebarCreation) => {
+ callKeyserverEndpoint: CallKeyserverEndpoint,
+ ): ((input: SendMultimediaMessageInput) => Promise<SendMessageResult>) =>
+ async input => {
let resultInfo;
const getResultInfo = (passedResultInfo: CallServerEndpointResultInfo) => {
resultInfo = passedResultInfo;
};
+ const { threadID, localID, mediaMessageContents, sidebarCreation } = input;
let payload = { threadID, localID, mediaMessageContents };
if (sidebarCreation) {
payload = { ...payload, sidebarCreation };
}
- const response = await callServerEndpoint(
+
+ const keyserverID = extractKeyserverIDFromID(input.threadID);
+ const requests = { [keyserverID]: payload };
+
+ const responses = await callKeyserverEndpoint(
'create_multimedia_message',
- payload,
+ requests,
{ getResultInfo },
);
const resultInterface = resultInfo?.interface;
invariant(
resultInterface,
- 'getResultInfo not called before callServerEndpoint resolves',
+ 'getResultInfo not called before callKeyserverEndpoint resolves',
);
return {
- id: response.newMessageInfo.id,
- time: response.newMessageInfo.time,
+ id: responses[keyserverID].newMessageInfo.id,
+ time: responses[keyserverID].newMessageInfo.time,
interface: resultInterface,
};
};
+function useSendMultimediaMessage(): (
+ input: SendMultimediaMessageInput,
+) => Promise<SendMessageResult> {
+ return useKeyserverCall(sendMultimediaMessage);
+}
+
+export type LegacySendMultimediaMessageInput = {
+ +threadID: string,
+ +localID: string,
+ +mediaIDs: $ReadOnlyArray<string>,
+ +sidebarCreation?: boolean,
+};
+
const legacySendMultimediaMessage =
(
- callServerEndpoint: CallServerEndpoint,
+ callKeyserverEndpoint: CallKeyserverEndpoint,
): ((
- threadID: string,
- localID: string,
- mediaIDs: $ReadOnlyArray<string>,
- sidebarCreation?: boolean,
+ input: LegacySendMultimediaMessageInput,
) => Promise<SendMessageResult>) =>
- async (threadID, localID, mediaIDs, sidebarCreation) => {
+ async input => {
let resultInfo;
const getResultInfo = (passedResultInfo: CallServerEndpointResultInfo) => {
resultInfo = passedResultInfo;
};
+ const { threadID, localID, mediaIDs, sidebarCreation } = input;
let payload = { threadID, localID, mediaIDs };
if (sidebarCreation) {
payload = { ...payload, sidebarCreation };
}
- const response = await callServerEndpoint(
+
+ const keyserverID = extractKeyserverIDFromID(input.threadID);
+ const requests = { [keyserverID]: payload };
+
+ const responses = await callKeyserverEndpoint(
'create_multimedia_message',
- payload,
+ requests,
{ getResultInfo },
);
const resultInterface = resultInfo?.interface;
invariant(
resultInterface,
- 'getResultInfo not called before callServerEndpoint resolves',
+ 'getResultInfo not called before callKeyserverEndpoint resolves',
);
return {
- id: response.newMessageInfo.id,
- time: response.newMessageInfo.time,
+ id: responses[keyserverID].newMessageInfo.id,
+ time: responses[keyserverID].newMessageInfo.time,
interface: resultInterface,
};
};
+function useLegacySendMultimediaMessage(): (
+ input: LegacySendMultimediaMessageInput,
+) => Promise<SendMessageResult> {
+ return useKeyserverCall(legacySendMultimediaMessage);
+}
+
const sendReactionMessageActionTypes = Object.freeze({
started: 'SEND_REACTION_MESSAGE_STARTED',
success: 'SEND_REACTION_MESSAGE_SUCCESS',
@@ -212,39 +320,50 @@
});
const sendReactionMessage =
(
- callServerEndpoint: CallServerEndpoint,
- ): ((request: SendReactionMessageRequest) => Promise<SendMessageResult>) =>
- async request => {
+ callKeyserverEndpoint: CallKeyserverEndpoint,
+ ): ((input: SendReactionMessageRequest) => Promise<SendMessageResult>) =>
+ async input => {
let resultInfo;
const getResultInfo = (passedResultInfo: CallServerEndpointResultInfo) => {
resultInfo = passedResultInfo;
};
- const response = await callServerEndpoint(
- 'create_reaction_message',
- {
- threadID: request.threadID,
- localID: request.localID,
- targetMessageID: request.targetMessageID,
- reaction: request.reaction,
- action: request.action,
+ const keyserverID = extractKeyserverIDFromID(input.threadID);
+ const requests = {
+ [keyserverID]: {
+ threadID: input.threadID,
+ localID: input.localID,
+ targetMessageID: input.targetMessageID,
+ reaction: input.reaction,
+ action: input.action,
},
+ };
+
+ const responses = await callKeyserverEndpoint(
+ 'create_reaction_message',
+ requests,
{ getResultInfo },
);
const resultInterface = resultInfo?.interface;
invariant(
resultInterface,
- 'getResultInfo not called before callServerEndpoint resolves',
+ 'getResultInfo not called before callKeyserverEndpoint resolves',
);
return {
- id: response.newMessageInfo.id,
- time: response.newMessageInfo.time,
+ id: responses[keyserverID].newMessageInfo.id,
+ time: responses[keyserverID].newMessageInfo.time,
interface: resultInterface,
};
};
+function useSendReactionMessage(): (
+ input: SendReactionMessageRequest,
+) => Promise<SendMessageResult> {
+ return useKeyserverCall(sendReactionMessage);
+}
+
const sendEditMessageActionTypes = Object.freeze({
started: 'SEND_EDIT_MESSAGE_STARTED',
success: 'SEND_EDIT_MESSAGE_SUCCESS',
@@ -252,18 +371,30 @@
});
const sendEditMessage =
(
- callServerEndpoint: CallServerEndpoint,
- ): ((request: SendEditMessageRequest) => Promise<SendEditMessageResult>) =>
- async request => {
- const response = await callServerEndpoint('edit_message', {
- targetMessageID: request.targetMessageID,
- text: request.text,
- });
+ callKeyserverEndpoint: CallKeyserverEndpoint,
+ ): ((input: SendEditMessageRequest) => Promise<SendEditMessageResult>) =>
+ async input => {
+ const keyserverID = extractKeyserverIDFromID(input.targetMessageID);
+ const requests = {
+ [keyserverID]: {
+ targetMessageID: input.targetMessageID,
+ text: input.text,
+ },
+ };
+
+ const responses = await callKeyserverEndpoint('edit_message', requests);
+
return {
- newMessageInfos: response.newMessageInfos,
+ newMessageInfos: responses[keyserverID].newMessageInfos,
};
};
+function useSendEditMessage(): (
+ input: SendEditMessageRequest,
+) => Promise<SendEditMessageResult> {
+ return useKeyserverCall(sendEditMessage);
+}
+
const saveMessagesActionType = 'SAVE_MESSAGES';
const processMessagesActionType = 'PROCESS_MESSAGES';
const messageStorePruneActionType = 'MESSAGE_STORE_PRUNE';
@@ -275,15 +406,28 @@
});
const fetchPinnedMessages =
(
- callServerEndpoint: CallServerEndpoint,
+ callKeyserverEndpoint: CallKeyserverEndpoint,
): ((
- request: FetchPinnedMessagesRequest,
+ input: FetchPinnedMessagesRequest,
) => Promise<FetchPinnedMessagesResult>) =>
- async request => {
- const response = await callServerEndpoint('fetch_pinned_messages', request);
- return { pinnedMessages: response.pinnedMessages };
+ async input => {
+ const keyserverID = extractKeyserverIDFromID(input.threadID);
+ const requests = { [keyserverID]: input };
+
+ const responses = await callKeyserverEndpoint(
+ 'fetch_pinned_messages',
+ requests,
+ );
+
+ return { pinnedMessages: responses[keyserverID].pinnedMessages };
};
+function useFetchPinnedMessages(): (
+ input: FetchPinnedMessagesRequest,
+) => Promise<FetchPinnedMessagesResult> {
+ return useKeyserverCall(fetchPinnedMessages);
+}
+
const searchMessagesActionTypes = Object.freeze({
started: 'SEARCH_MESSAGES_STARTED',
success: 'SEARCH_MESSAGES_SUCCESS',
@@ -292,38 +436,48 @@
const searchMessages =
(
- callServerEndpoint: CallServerEndpoint,
- ): ((request: SearchMessagesRequest) => Promise<SearchMessagesResponse>) =>
- async request => {
- const response = await callServerEndpoint('search_messages', request);
+ callKeyserverEndpoint: CallKeyserverEndpoint,
+ ): ((input: SearchMessagesRequest) => Promise<SearchMessagesResponse>) =>
+ async input => {
+ const keyserverID = extractKeyserverIDFromID(input.threadID);
+ const requests = { [keyserverID]: input };
+
+ const responses = await callKeyserverEndpoint('search_messages', requests);
+
return {
- messages: response.messages,
- endReached: response.endReached,
+ messages: responses[keyserverID].messages,
+ endReached: responses[keyserverID].endReached,
};
};
+function useSearchMessages(): (
+ input: SearchMessagesRequest,
+) => Promise<SearchMessagesResponse> {
+ return useKeyserverCall(searchMessages);
+}
+
export {
fetchMessagesBeforeCursorActionTypes,
- fetchMessagesBeforeCursor,
+ useFetchMessagesBeforeCursor,
fetchMostRecentMessagesActionTypes,
- fetchMostRecentMessages,
+ useFetchMostRecentMessages,
fetchSingleMostRecentMessagesFromThreadsActionTypes,
- fetchSingleMostRecentMessagesFromThreads,
+ useFetchSingleMostRecentMessagesFromThreads,
sendTextMessageActionTypes,
- sendTextMessage,
+ useSendTextMessage,
createLocalMessageActionType,
sendMultimediaMessageActionTypes,
- sendMultimediaMessage,
- legacySendMultimediaMessage,
+ useSendMultimediaMessage,
+ useLegacySendMultimediaMessage,
searchMessagesActionTypes,
- searchMessages,
+ useSearchMessages,
sendReactionMessageActionTypes,
- sendReactionMessage,
+ useSendReactionMessage,
saveMessagesActionType,
processMessagesActionType,
messageStorePruneActionType,
sendEditMessageActionTypes,
- sendEditMessage,
- fetchPinnedMessages,
+ useSendEditMessage,
+ useFetchPinnedMessages,
fetchPinnedMessageActionTypes,
};
diff --git a/lib/hooks/child-threads.js b/lib/hooks/child-threads.js
--- a/lib/hooks/child-threads.js
+++ b/lib/hooks/child-threads.js
@@ -3,7 +3,7 @@
import * as React from 'react';
import {
- fetchSingleMostRecentMessagesFromThreads,
+ useFetchSingleMostRecentMessagesFromThreads,
fetchSingleMostRecentMessagesFromThreadsActionTypes,
} from '../actions/message-actions.js';
import {
@@ -15,10 +15,7 @@
import { threadInChatList } from '../shared/thread-utils.js';
import threadWatcher from '../shared/thread-watcher.js';
import type { ThreadInfo } from '../types/thread-types.js';
-import {
- useDispatchActionPromise,
- useServerCall,
-} from '../utils/action-utils.js';
+import { useDispatchActionPromise } from '../utils/action-utils.js';
import { useSelector } from '../utils/redux-utils.js';
type ThreadFilter = {
@@ -96,9 +93,8 @@
[filteredSubchannelsChatList],
);
const dispatchActionPromise = useDispatchActionPromise();
- const fetchSingleMostRecentMessages = useServerCall(
- fetchSingleMostRecentMessagesFromThreads,
- );
+ const fetchSingleMostRecentMessages =
+ useFetchSingleMostRecentMessagesFromThreads();
React.useEffect(() => {
if (!threadIDsWithNoMessages.size) {
diff --git a/lib/shared/edit-messages-utils.js b/lib/shared/edit-messages-utils.js
--- a/lib/shared/edit-messages-utils.js
+++ b/lib/shared/edit-messages-utils.js
@@ -5,7 +5,7 @@
import { threadIsPending, threadHasPermission } from './thread-utils.js';
import {
sendEditMessageActionTypes,
- sendEditMessage,
+ useSendEditMessage,
} from '../actions/message-actions.js';
import type {
SendEditMessageResult,
@@ -16,17 +16,14 @@
import { messageTypes } from '../types/message-types-enum.js';
import { threadPermissions } from '../types/thread-permission-types.js';
import { type ThreadInfo } from '../types/thread-types.js';
-import {
- useDispatchActionPromise,
- useServerCall,
-} from '../utils/action-utils.js';
+import { useDispatchActionPromise } from '../utils/action-utils.js';
import { useSelector } from '../utils/redux-utils.js';
function useEditMessage(): (
messageID: string,
newText: string,
) => Promise<SendEditMessageResult> {
- const callEditMessage = useServerCall(sendEditMessage);
+ const callEditMessage = useSendEditMessage();
const dispatchActionPromise = useDispatchActionPromise();
return React.useCallback(
diff --git a/lib/shared/search-utils.js b/lib/shared/search-utils.js
--- a/lib/shared/search-utils.js
+++ b/lib/shared/search-utils.js
@@ -10,7 +10,7 @@
getContainingThreadID,
} from './thread-utils.js';
import {
- searchMessages,
+ useSearchMessages as useSearchMessagesAction,
searchMessagesActionTypes,
} from '../actions/message-actions.js';
import {
@@ -240,7 +240,7 @@
queryID: number,
cursor?: string,
) => void {
- const callSearchMessages = useServerCall(searchMessages);
+ const callSearchMessages = useSearchMessagesAction();
const dispatchActionPromise = useDispatchActionPromise();
return React.useCallback(
diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js
--- a/lib/shared/thread-utils.js
+++ b/lib/shared/thread-utils.js
@@ -14,7 +14,7 @@
import threadWatcher from './thread-watcher.js';
import {
fetchMostRecentMessagesActionTypes,
- fetchMostRecentMessages,
+ useFetchMostRecentMessages,
} from '../actions/message-actions.js';
import {
changeThreadMemberRolesActionTypes,
@@ -1109,7 +1109,7 @@
function useWatchThread(threadInfo: ?ThreadInfo) {
const dispatchActionPromise = useDispatchActionPromise();
- const callFetchMostRecentMessages = useServerCall(fetchMostRecentMessages);
+ const callFetchMostRecentMessages = useFetchMostRecentMessages();
const threadID = threadInfo?.id;
const threadNotInChatList = !threadInChatList(threadInfo);
@@ -1118,7 +1118,7 @@
threadWatcher.watchID(threadID);
dispatchActionPromise(
fetchMostRecentMessagesActionTypes,
- callFetchMostRecentMessages(threadID),
+ callFetchMostRecentMessages({ threadID }),
);
}
return () => {
diff --git a/lib/utils/action-utils.js b/lib/utils/action-utils.js
--- a/lib/utils/action-utils.js
+++ b/lib/utils/action-utils.js
@@ -458,6 +458,21 @@
socketAPIHandler = passedSocketAPIHandler;
}
+function sortThreadIDsPerKeyserver(threadIDs: $ReadOnlyArray<string>): {
+ +[keyserverID: string]: $ReadOnlyArray<string>,
+} {
+ const results = {};
+ for (const threadID of threadIDs) {
+ const keyserverID = extractKeyserverIDFromID(threadID);
+ invariant(keyserverID, 'keyserver data missing from thread id');
+ if (results[keyserverID] === undefined) {
+ results[keyserverID] = [];
+ }
+ results[keyserverID].push(threadID);
+ }
+ return results;
+}
+
export {
useDispatchActionPromise,
setNewSessionActionType,
@@ -467,4 +482,5 @@
useServerCall,
bindCookieAndUtilsIntoCallServerEndpoint,
extractKeyserverIDFromID,
+ sortThreadIDsPerKeyserver,
};
diff --git a/native/chat/message-list.react.js b/native/chat/message-list.react.js
--- a/native/chat/message-list.react.js
+++ b/native/chat/message-list.react.js
@@ -8,9 +8,11 @@
import {
fetchMessagesBeforeCursorActionTypes,
- fetchMessagesBeforeCursor,
+ useFetchMessagesBeforeCursor,
fetchMostRecentMessagesActionTypes,
- fetchMostRecentMessages,
+ useFetchMostRecentMessages,
+ type FetchMostRecentMessagesInput,
+ type FetchMessagesBeforeCursorInput,
} from 'lib/actions/message-actions.js';
import { useOldestMessageServerID } from 'lib/hooks/message-hooks.js';
import { registerFetchKey } from 'lib/reducers/loading-reducer.js';
@@ -21,7 +23,6 @@
import { type ThreadInfo } from 'lib/types/thread-types.js';
import {
type DispatchActionPromise,
- useServerCall,
useDispatchActionPromise,
} from 'lib/utils/action-utils.js';
@@ -66,11 +67,10 @@
+indicatorStyle: IndicatorStyle,
+dispatchActionPromise: DispatchActionPromise,
+fetchMessagesBeforeCursor: (
- threadID: string,
- beforeMessageID: string,
+ input: FetchMessagesBeforeCursorInput,
) => Promise<FetchMessageInfosPayload>,
+fetchMostRecentMessages: (
- threadID: string,
+ input: FetchMostRecentMessagesInput,
) => Promise<FetchMessageInfosPayload>,
+overlayContext: ?OverlayContextType,
+keyboardState: ?KeyboardState,
@@ -292,15 +292,15 @@
if (oldestMessageServerID) {
await this.props.dispatchActionPromise(
fetchMessagesBeforeCursorActionTypes,
- this.props.fetchMessagesBeforeCursor(
+ this.props.fetchMessagesBeforeCursor({
threadID,
- oldestMessageServerID,
- ),
+ beforeMessageID: oldestMessageServerID,
+ }),
);
} else {
await this.props.dispatchActionPromise(
fetchMostRecentMessagesActionTypes,
- this.props.fetchMostRecentMessages(threadID),
+ this.props.fetchMostRecentMessages({ threadID }),
);
}
} finally {
@@ -344,10 +344,8 @@
const indicatorStyle = useIndicatorStyle();
const dispatchActionPromise = useDispatchActionPromise();
- const callFetchMessagesBeforeCursor = useServerCall(
- fetchMessagesBeforeCursor,
- );
- const callFetchMostRecentMessages = useServerCall(fetchMostRecentMessages);
+ const callFetchMessagesBeforeCursor = useFetchMessagesBeforeCursor();
+ const callFetchMostRecentMessages = useFetchMostRecentMessages();
const oldestMessageServerID = useOldestMessageServerID(threadID);
diff --git a/native/chat/message-results-screen.react.js b/native/chat/message-results-screen.react.js
--- a/native/chat/message-results-screen.react.js
+++ b/native/chat/message-results-screen.react.js
@@ -5,14 +5,13 @@
import { View } from 'react-native';
import { ScrollView } from 'react-native-gesture-handler';
-import { fetchPinnedMessages } from 'lib/actions/message-actions.js';
+import { useFetchPinnedMessages } from 'lib/actions/message-actions.js';
import { messageListData } from 'lib/selectors/chat-selectors.js';
import {
createMessageInfo,
isInvalidPinSourceForThread,
} from 'lib/shared/message-utils.js';
import type { ThreadInfo } from 'lib/types/thread-types.js';
-import { useServerCall } from 'lib/utils/action-utils.js';
import { useHeightMeasurer } from './chat-context.js';
import type { ChatNavigationProp } from './chat.react';
@@ -44,7 +43,7 @@
const [messageVerticalBounds, setMessageVerticalBounds] = React.useState();
const scrollViewContainerRef = React.useRef();
- const callFetchPinnedMessages = useServerCall(fetchPinnedMessages);
+ const callFetchPinnedMessages = useFetchPinnedMessages();
const userInfos = useSelector(state => state.userStore.userInfos);
React.useEffect(() => {
diff --git a/native/chat/reaction-message-utils.js b/native/chat/reaction-message-utils.js
--- a/native/chat/reaction-message-utils.js
+++ b/native/chat/reaction-message-utils.js
@@ -4,16 +4,13 @@
import * as React from 'react';
import {
- sendReactionMessage,
+ useSendReactionMessage,
sendReactionMessageActionTypes,
} from 'lib/actions/message-actions.js';
import type { ReactionInfo } from 'lib/selectors/chat-selectors.js';
import { messageTypes } from 'lib/types/message-types-enum.js';
import type { RawReactionMessageInfo } from 'lib/types/messages/reaction.js';
-import {
- useDispatchActionPromise,
- useServerCall,
-} from 'lib/utils/action-utils.js';
+import { useDispatchActionPromise } from 'lib/utils/action-utils.js';
import { cloneError } from 'lib/utils/errors.js';
import { useSelector } from '../redux/redux-utils.js';
@@ -33,7 +30,7 @@
state => state.currentUserInfo && state.currentUserInfo.id,
);
- const callSendReactionMessage = useServerCall(sendReactionMessage);
+ const callSendReactionMessage = useSendReactionMessage();
const dispatchActionPromise = useDispatchActionPromise();
return React.useCallback(
diff --git a/native/input/input-state-container.react.js b/native/input/input-state-container.react.js
--- a/native/input/input-state-container.react.js
+++ b/native/input/input-state-container.react.js
@@ -10,9 +10,13 @@
import {
createLocalMessageActionType,
sendMultimediaMessageActionTypes,
- sendMultimediaMessage,
+ useSendMultimediaMessage,
sendTextMessageActionTypes,
- sendTextMessage,
+ useSendTextMessage,
+} from 'lib/actions/message-actions.js';
+import type {
+ SendMultimediaMessageInput,
+ SendTextMessageInput,
} from 'lib/actions/message-actions.js';
import { queueReportsActionType } from 'lib/actions/report-actions.js';
import { newThread } from 'lib/actions/thread-actions.js';
@@ -66,10 +70,7 @@
type SendMessagePayload,
} from 'lib/types/message-types.js';
import type { RawImagesMessageInfo } from 'lib/types/messages/images.js';
-import type {
- MediaMessageServerDBContent,
- RawMediaMessageInfo,
-} from 'lib/types/messages/media.js';
+import type { RawMediaMessageInfo } from 'lib/types/messages/media.js';
import { getMediaMessageServerDBContentsFromMedia } from 'lib/types/messages/media.js';
import type { RawTextMessageInfo } from 'lib/types/messages/text.js';
import type { Dispatch } from 'lib/types/redux-types.js';
@@ -149,17 +150,9 @@
) => Promise<UploadMultimediaResult>,
+blobServiceUpload: BlobServiceUploadAction,
+sendMultimediaMessage: (
- threadID: string,
- localID: string,
- mediaMessageContents: $ReadOnlyArray<MediaMessageServerDBContent>,
- sidebarCreation?: boolean,
- ) => Promise<SendMessageResult>,
- +sendTextMessage: (
- threadID: string,
- localID: string,
- text: string,
- sidebarCreation?: boolean,
+ input: SendMultimediaMessageInput,
) => Promise<SendMessageResult>,
+ +sendTextMessage: (input: SendTextMessageInput) => Promise<SendMessageResult>,
+newThread: (request: ClientNewThreadRequest) => Promise<NewThreadResult>,
+textMessageCreationSideEffectsFunc: CreationSideEffectsFunc<RawTextMessageInfo>,
};
@@ -375,12 +368,12 @@
messageInfo.media,
);
try {
- const result = await this.props.sendMultimediaMessage(
+ const result = await this.props.sendMultimediaMessage({
threadID,
localID,
mediaMessageContents,
sidebarCreation,
- );
+ });
this.pendingSidebarCreationMessageLocalIDs.delete(localID);
return {
localID,
@@ -574,12 +567,12 @@
);
const sidebarCreation =
this.pendingSidebarCreationMessageLocalIDs.has(localID);
- const result = await this.props.sendTextMessage(
- messageInfo.threadID,
+ const result = await this.props.sendTextMessage({
+ threadID: messageInfo.threadID,
localID,
- messageInfo.text,
+ text: messageInfo.text,
sidebarCreation,
- );
+ });
this.pendingSidebarCreationMessageLocalIDs.delete(localID);
return {
localID,
@@ -1702,8 +1695,8 @@
const callUploadMultimedia = useServerCall(uploadMultimedia);
const callUploadMediaMetadata = useServerCall(uploadMediaMetadata);
const callBlobServiceUpload = useServerCall(blobServiceUpload);
- const callSendMultimediaMessage = useServerCall(sendMultimediaMessage);
- const callSendTextMessage = useServerCall(sendTextMessage);
+ const callSendMultimediaMessage = useSendMultimediaMessage();
+ const callSendTextMessage = useSendTextMessage();
const callNewThread = useServerCall(newThread);
const dispatchActionPromise = useDispatchActionPromise();
const dispatch = useDispatch();
diff --git a/web/chat/chat-message-list.react.js b/web/chat/chat-message-list.react.js
--- a/web/chat/chat-message-list.react.js
+++ b/web/chat/chat-message-list.react.js
@@ -8,9 +8,13 @@
import {
fetchMessagesBeforeCursorActionTypes,
- fetchMessagesBeforeCursor,
+ useFetchMessagesBeforeCursor,
fetchMostRecentMessagesActionTypes,
- fetchMostRecentMessages,
+ useFetchMostRecentMessages,
+} from 'lib/actions/message-actions.js';
+import type {
+ FetchMostRecentMessagesInput,
+ FetchMessagesBeforeCursorInput,
} from 'lib/actions/message-actions.js';
import { useThreadChatMentionCandidates } from 'lib/hooks/chat-mention-hooks.js';
import { useOldestMessageServerID } from 'lib/hooks/message-hooks.js';
@@ -26,7 +30,6 @@
import { type ThreadInfo } from 'lib/types/thread-types.js';
import {
type DispatchActionPromise,
- useServerCall,
useDispatchActionPromise,
} from 'lib/utils/action-utils.js';
@@ -62,11 +65,10 @@
+startReached: boolean,
+dispatchActionPromise: DispatchActionPromise,
+fetchMessagesBeforeCursor: (
- threadID: string,
- beforeMessageID: string,
+ input: FetchMessagesBeforeCursorInput,
) => Promise<FetchMessageInfosPayload>,
+fetchMostRecentMessages: (
- threadID: string,
+ input: FetchMostRecentMessagesInput,
) => Promise<FetchMessageInfosPayload>,
+inputState: ?InputState,
+clearTooltip: () => mixed,
@@ -384,12 +386,15 @@
if (oldestMessageServerID) {
await this.props.dispatchActionPromise(
fetchMessagesBeforeCursorActionTypes,
- this.props.fetchMessagesBeforeCursor(threadID, oldestMessageServerID),
+ this.props.fetchMessagesBeforeCursor({
+ threadID,
+ beforeMessageID: oldestMessageServerID,
+ }),
);
} else {
await this.props.dispatchActionPromise(
fetchMostRecentMessagesActionTypes,
- this.props.fetchMostRecentMessages(threadID),
+ this.props.fetchMostRecentMessages({ threadID }),
);
}
} finally {
@@ -429,10 +434,8 @@
});
const dispatchActionPromise = useDispatchActionPromise();
- const callFetchMessagesBeforeCursor = useServerCall(
- fetchMessagesBeforeCursor,
- );
- const callFetchMostRecentMessages = useServerCall(fetchMostRecentMessages);
+ const callFetchMessagesBeforeCursor = useFetchMessagesBeforeCursor();
+ const callFetchMostRecentMessages = useFetchMostRecentMessages();
const inputState = React.useContext(InputStateContext);
diff --git a/web/chat/reaction-message-utils.js b/web/chat/reaction-message-utils.js
--- a/web/chat/reaction-message-utils.js
+++ b/web/chat/reaction-message-utils.js
@@ -4,17 +4,14 @@
import * as React from 'react';
import {
- sendReactionMessage,
+ useSendReactionMessage,
sendReactionMessageActionTypes,
} from 'lib/actions/message-actions.js';
import { useModalContext } from 'lib/components/modal-provider.react.js';
import type { ReactionInfo } from 'lib/selectors/chat-selectors';
import { messageTypes } from 'lib/types/message-types-enum.js';
import type { RawReactionMessageInfo } from 'lib/types/messages/reaction.js';
-import {
- useDispatchActionPromise,
- useServerCall,
-} from 'lib/utils/action-utils.js';
+import { useDispatchActionPromise } from 'lib/utils/action-utils.js';
import { cloneError } from 'lib/utils/errors.js';
import Alert from '../modals/alert.react.js';
@@ -37,7 +34,7 @@
state => state.currentUserInfo && state.currentUserInfo.id,
);
- const callSendReactionMessage = useServerCall(sendReactionMessage);
+ const callSendReactionMessage = useSendReactionMessage();
const dispatchActionPromise = useDispatchActionPromise();
return React.useCallback(
diff --git a/web/input/input-state-container.react.js b/web/input/input-state-container.react.js
--- a/web/input/input-state-container.react.js
+++ b/web/input/input-state-container.react.js
@@ -14,9 +14,13 @@
import {
createLocalMessageActionType,
sendMultimediaMessageActionTypes,
- legacySendMultimediaMessage,
+ useLegacySendMultimediaMessage,
sendTextMessageActionTypes,
- sendTextMessage,
+ useSendTextMessage,
+} from 'lib/actions/message-actions.js';
+import type {
+ LegacySendMultimediaMessageInput,
+ SendTextMessageInput,
} from 'lib/actions/message-actions.js';
import { queueReportsActionType } from 'lib/actions/report-actions.js';
import { newThread } from 'lib/actions/thread-actions.js';
@@ -134,17 +138,9 @@
) => Promise<UploadMultimediaResult>,
+deleteUpload: (id: string) => Promise<void>,
+sendMultimediaMessage: (
- threadID: string,
- localID: string,
- mediaIDs: $ReadOnlyArray<string>,
- sidebarCreation?: boolean,
- ) => Promise<SendMessageResult>,
- +sendTextMessage: (
- threadID: string,
- localID: string,
- text: string,
- sidebarCreation?: boolean,
+ input: LegacySendMultimediaMessageInput,
) => Promise<SendMessageResult>,
+ +sendTextMessage: (input: SendTextMessageInput) => Promise<SendMessageResult>,
+newThread: (request: ClientNewThreadRequest) => Promise<NewThreadResult>,
+pushModal: PushModal,
+sendCallbacks: $ReadOnlyArray<() => mixed>,
@@ -508,12 +504,12 @@
mediaIDs.push(id);
}
try {
- const result = await this.props.sendMultimediaMessage(
+ const result = await this.props.sendMultimediaMessage({
threadID,
localID,
mediaIDs,
sidebarCreation,
- );
+ });
this.pendingSidebarCreationMessageLocalIDs.delete(localID);
this.setState(prevState => {
const newThreadID = this.getRealizedOrPendingThreadID(threadID);
@@ -1318,12 +1314,12 @@
);
const sidebarCreation =
this.pendingSidebarCreationMessageLocalIDs.has(localID);
- const result = await this.props.sendTextMessage(
- messageInfo.threadID,
+ const result = await this.props.sendTextMessage({
+ threadID: messageInfo.threadID,
localID,
- messageInfo.text,
+ text: messageInfo.text,
sidebarCreation,
- );
+ });
this.pendingSidebarCreationMessageLocalIDs.delete(localID);
return {
localID,
@@ -1618,10 +1614,8 @@
const callBlobServiceUpload = useServerCall(blobServiceUpload);
const callUploadMediaMetadata = useServerCall(uploadMediaMetadata);
const callDeleteUpload = useServerCall(deleteUpload);
- const callSendMultimediaMessage = useServerCall(
- legacySendMultimediaMessage,
- );
- const callSendTextMessage = useServerCall(sendTextMessage);
+ const callSendMultimediaMessage = useLegacySendMultimediaMessage();
+ const callSendTextMessage = useSendTextMessage();
const callNewThread = useServerCall(newThread);
const dispatch = useDispatch();
const dispatchActionPromise = useDispatchActionPromise();
diff --git a/web/modals/chat/message-results-modal.react.js b/web/modals/chat/message-results-modal.react.js
--- a/web/modals/chat/message-results-modal.react.js
+++ b/web/modals/chat/message-results-modal.react.js
@@ -3,8 +3,8 @@
import * as React from 'react';
import {
- fetchPinnedMessages,
fetchPinnedMessageActionTypes,
+ useFetchPinnedMessages,
} from 'lib/actions/message-actions.js';
import { useModalContext } from 'lib/components/modal-provider.react.js';
import { messageListData } from 'lib/selectors/chat-selectors.js';
@@ -15,10 +15,7 @@
modifyItemForResultScreen,
} from 'lib/shared/message-utils.js';
import { type ThreadInfo } from 'lib/types/thread-types.js';
-import {
- useServerCall,
- useDispatchActionPromise,
-} from 'lib/utils/action-utils.js';
+import { useDispatchActionPromise } from 'lib/utils/action-utils.js';
import css from './message-results-modal.css';
import MessageResult from '../../components/message-result.react.js';
@@ -41,7 +38,7 @@
const { popModal } = useModalContext();
const [rawMessageResults, setRawMessageResults] = React.useState([]);
- const callFetchPinnedMessages = useServerCall(fetchPinnedMessages);
+ const callFetchPinnedMessages = useFetchPinnedMessages();
const dispatchActionPromise = useDispatchActionPromise();
const userInfos = useSelector(state => state.userStore.userInfos);

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 24, 5:38 PM (21 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2576578
Default Alt Text
D9240.diff (39 KB)

Event Timeline