Page MenuHomePhabricator

D13290.id44043.diff
No OneTemporary

D13290.id44043.diff

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
@@ -80,7 +80,7 @@
import { unshimMessageInfos } from '../shared/unshim-utils.js';
import { updateSpecs } from '../shared/updates/update-specs.js';
import { recoveryFromReduxActionSources } from '../types/account-types.js';
-import { processDMOpsActionType, sendDMActionTypes } from '../types/dm-ops.js';
+import { processDMOpsActionType } from '../types/dm-ops.js';
import type { Media, Image } from '../types/media-types.js';
import { messageTypes } from '../types/message-types-enum.js';
import {
@@ -1166,16 +1166,24 @@
action.type === sendTextMessageActionTypes.failed ||
action.type === sendMultimediaMessageActionTypes.failed
) {
- const { localID } = action.payload;
+ const { localID, failedOutboundMessageIDs } = action.payload;
+ let newLocalMessageInfo = {
+ sendFailed: true,
+ };
+ // Handling DMs
+ if (failedOutboundMessageIDs && failedOutboundMessageIDs.length > 0) {
+ newLocalMessageInfo = {
+ ...newLocalMessageInfo,
+ outboundP2PMessageIDs: failedOutboundMessageIDs,
+ };
+ }
const messageStoreOperations = [
{
type: 'replace_local_message_info',
payload: {
id: localID,
- localMessageInfo: {
- sendFailed: true,
- },
+ localMessageInfo: newLocalMessageInfo,
},
},
];
@@ -1865,10 +1873,47 @@
outboundP2PMessages,
messageIDWithoutAutoRetry,
} = action.payload;
- if (rawMessageInfos.length === 0 && updateInfos.length === 0) {
+
+ if (
+ rawMessageInfos.length === 0 &&
+ updateInfos.length === 0 &&
+ !messageIDWithoutAutoRetry
+ ) {
return { messageStoreOperations: [], messageStore };
}
+ if (
+ messageIDWithoutAutoRetry &&
+ outboundP2PMessages &&
+ outboundP2PMessages.length > 0 &&
+ !messageStore.local[messageIDWithoutAutoRetry]
+ ) {
+ const newMessageID: string = messageIDWithoutAutoRetry;
+
+ // Messages to other peers that can be retried from UI,
+ // we need to track statuses of each one.
+ const outboundP2PMessageIDs = outboundP2PMessages.map(
+ msg => msg.messageID,
+ );
+ const localOperation: ReplaceMessageStoreLocalMessageInfoOperation = {
+ type: 'replace_local_message_info',
+ payload: {
+ id: newMessageID,
+ localMessageInfo: {
+ sendFailed: false,
+ outboundP2PMessageIDs,
+ },
+ },
+ };
+
+ return {
+ messageStoreOperations: [localOperation],
+ messageStore: processMessageStoreOperations(messageStore, [
+ localOperation,
+ ]),
+ };
+ }
+
const messagesResult = mergeUpdatesWithMessageInfos(
rawMessageInfos,
updateInfos,
@@ -1883,93 +1928,13 @@
newThreadInfos,
);
- if (
- !messageIDWithoutAutoRetry ||
- !outboundP2PMessages ||
- outboundP2PMessages.length === 0
- ) {
- return { messageStoreOperations, messageStore: newMessageStore };
- }
-
- const newMessageID: string = messageIDWithoutAutoRetry;
-
- // Messages to other peers that can be retried from UI,
- // we need to track statuses of each one.
- const outboundP2PMessageIDs = outboundP2PMessages.map(msg => msg.messageID);
- const localOperation: ReplaceMessageStoreLocalMessageInfoOperation = {
- type: 'replace_local_message_info',
- payload: {
- id: newMessageID,
- localMessageInfo: {
- sendFailed: false,
- outboundP2PMessageIDs,
- },
- },
- };
-
- return {
- messageStoreOperations: [...messageStoreOperations, localOperation],
- messageStore: processMessageStoreOperations(newMessageStore, [
- localOperation,
- ]),
- };
- } else if (action.type === sendDMActionTypes.success) {
- const { messageID: sentMessageID, outboundP2PMessageIDs } = action.payload;
-
- const outboundP2PMessageIDsSet = new Set(outboundP2PMessageIDs);
- const localOutboundP2PMessageIDs =
- messageStore.local[sentMessageID]?.outboundP2PMessageIDs ?? [];
- const remainingOutboundP2PMessageIDs = localOutboundP2PMessageIDs.filter(
- id => !outboundP2PMessageIDsSet.has(id),
- );
-
- const messageStoreOperations: Array<MessageStoreOperation> = [];
- if (remainingOutboundP2PMessageIDs.length > 0) {
- messageStoreOperations.push({
- type: 'replace_local_message_info',
- payload: {
- id: sentMessageID,
- localMessageInfo: {
- sendFailed: true,
- outboundP2PMessageIDs: remainingOutboundP2PMessageIDs,
- },
- },
- });
- } else {
- messageStoreOperations.push({
- type: 'remove_local_message_infos',
- payload: {
- ids: [sentMessageID],
- },
- });
- }
-
return {
messageStoreOperations,
messageStore: processMessageStoreOperations(
- messageStore,
+ newMessageStore,
messageStoreOperations,
),
};
- } else if (action.type === sendDMActionTypes.started) {
- const { messageID: sentMessageID } = action.payload;
- const localOperation: ReplaceMessageStoreLocalMessageInfoOperation = {
- type: 'replace_local_message_info',
- payload: {
- id: sentMessageID,
- localMessageInfo: {
- ...messageStore.local[sentMessageID],
- sendFailed: false,
- },
- },
- };
-
- return {
- messageStoreOperations: [localOperation],
- messageStore: processMessageStoreOperations(messageStore, [
- localOperation,
- ]),
- };
}
return { messageStoreOperations: [], messageStore };
}
diff --git a/lib/shared/dm-ops/process-dm-ops.js b/lib/shared/dm-ops/process-dm-ops.js
--- a/lib/shared/dm-ops/process-dm-ops.js
+++ b/lib/shared/dm-ops/process-dm-ops.js
@@ -24,18 +24,14 @@
import {
processDMOpsActionType,
queueDMOpsActionType,
- sendDMActionTypes,
- type SendDMOpsSuccessPayload,
+ dmOperationValidator,
} from '../../types/dm-ops.js';
-import { dmOperationValidator } from '../../types/dm-ops.js';
-import type { LocalMessageInfo } from '../../types/message-types.js';
import type { RawThreadInfo } from '../../types/minimally-encoded-thread-permissions-types.js';
import type { DispatchMetadata } from '../../types/redux-types.js';
import type { OutboundP2PMessage } from '../../types/sqlite-types.js';
import type { LegacyRawThreadInfo } from '../../types/thread-types.js';
import { updateTypes } from '../../types/update-types-enum.js';
import { extractUserIDsFromPayload } from '../../utils/conversion-utils.js';
-import { useDispatchActionPromise } from '../../utils/redux-promise-utils.js';
import { useSelector, useDispatch } from '../../utils/redux-utils.js';
import { messageSpecs } from '../messages/message-specs.js';
import { updateSpecs } from '../updates/update-specs.js';
@@ -43,6 +39,7 @@
function useProcessDMOperation(): (
dmOperationSpecification: DMOperationSpecification,
dmOpID: ?string,
+ localMessageID: ?string,
) => Promise<void> {
const fetchMessage = useGetLatestMessageEdit();
const threadInfos = useSelector(state => state.threadStore.threadInfos);
@@ -67,6 +64,7 @@
async (
dmOperationSpecification: DMOperationSpecification,
dmOpID: ?string,
+ localMessageID: ?string,
) => {
if (!viewerID) {
console.log('ignored DMOperation because logged out');
@@ -102,15 +100,6 @@
dispatchMetadata = dmOperationSpecification.metadata;
}
- let messageIDWithoutAutoRetry: ?string = null;
- if (
- dmOperationSpecification.type ===
- dmOperationSpecificationTypes.OUTBOUND &&
- !dmOpSpecs[dmOp.type].supportsAutoRetry
- ) {
- messageIDWithoutAutoRetry = dmOp.messageID;
- }
-
if (
dmOperationSpecification.type ===
dmOperationSpecificationTypes.OUTBOUND &&
@@ -127,7 +116,8 @@
rawMessageInfos: [],
updateInfos: [],
outboundP2PMessages,
- messageIDWithoutAutoRetry,
+ //TODO rename to something descriptive
+ messageIDWithoutAutoRetry: localMessageID,
notificationsCreationData,
},
},
@@ -285,7 +275,8 @@
rawMessageInfos,
updateInfos,
outboundP2PMessages,
- messageIDWithoutAutoRetry,
+ //TODO rename to something descriptive
+ messageIDWithoutAutoRetry: localMessageID,
notificationsCreationData,
},
},
@@ -306,76 +297,26 @@
function useProcessAndSendDMOperation(): (
dmOperationSpecification: OutboundDMOperationSpecification,
-) => Promise<void> {
+ localMessageID?: string,
+) => Promise<$ReadOnlyArray<string>> {
const processDMOps = useProcessDMOperation();
- const dispatchActionPromise = useDispatchActionPromise();
const { getDMOpsSendingPromise } = usePeerToPeerCommunication();
return React.useCallback(
- async (dmOperationSpecification: OutboundDMOperationSpecification) => {
- const { promise, dmOpID } = getDMOpsSendingPromise();
- await processDMOps(dmOperationSpecification, dmOpID);
-
- if (
- dmOperationSpecification.type ===
- dmOperationSpecificationTypes.OUTBOUND &&
- !dmOpSpecs[dmOperationSpecification.op.type].supportsAutoRetry &&
- dmOperationSpecification.op.messageID
- ) {
- const messageID: string = dmOperationSpecification.op.messageID;
-
- const sendingPromise: Promise<SendDMOpsSuccessPayload> = (async () => {
- const outboundP2PMessageIDs = await promise;
- return {
- messageID,
- outboundP2PMessageIDs,
- };
- })();
-
- void dispatchActionPromise(
- sendDMActionTypes,
- sendingPromise,
- undefined,
- {
- messageID,
- },
- );
- }
- },
- [dispatchActionPromise, getDMOpsSendingPromise, processDMOps],
- );
-}
-
-function useRetrySendDMOperation(): (
- messageID: string,
- localMessageInfo: LocalMessageInfo,
-) => Promise<void> {
- const { processOutboundMessages, getDMOpsSendingPromise } =
- usePeerToPeerCommunication();
- const dispatchActionPromise = useDispatchActionPromise();
-
- return React.useCallback(
- async (messageID: string, localMessageInfo: LocalMessageInfo) => {
+ async (
+ dmOperationSpecification: OutboundDMOperationSpecification,
+ localMessageID?: string,
+ ) => {
+ // Creates promise that will be resolved when
+ // Tunnelbroker will queue messages
const { promise, dmOpID } = getDMOpsSendingPromise();
- processOutboundMessages(localMessageInfo.outboundP2PMessageIDs, dmOpID);
-
- const sendingPromise: Promise<SendDMOpsSuccessPayload> = (async () => {
- const outboundP2PMessageIDs = await promise;
- return {
- messageID,
- outboundP2PMessageIDs,
- };
- })();
- void dispatchActionPromise(sendDMActionTypes, sendingPromise, undefined, {
- messageID,
- });
+ // Processing DM Ops and generating messages to peers
+ await processDMOps(dmOperationSpecification, dmOpID, localMessageID);
+ // Returning promise, resolved after queuing messages
+ return promise;
},
- [dispatchActionPromise, getDMOpsSendingPromise, processOutboundMessages],
+ [getDMOpsSendingPromise, processDMOps],
);
}
-export {
- useProcessDMOperation,
- useProcessAndSendDMOperation,
- useRetrySendDMOperation,
-};
+export { useProcessDMOperation, useProcessAndSendDMOperation };
diff --git a/lib/tunnelbroker/peer-to-peer-context.js b/lib/tunnelbroker/peer-to-peer-context.js
--- a/lib/tunnelbroker/peer-to-peer-context.js
+++ b/lib/tunnelbroker/peer-to-peer-context.js
@@ -194,7 +194,9 @@
);
await Promise.all(devicePromises);
- return Object.keys(sentMessagesMap);
+ // now we need to return failed messages
+ const sentMessages = new Set(Object.keys(sentMessagesMap));
+ return messageIDs?.filter(id => !sentMessages.has(id)) ?? [];
}
const AUTOMATIC_RETRY_FREQUENCY = 30 * 1000;
diff --git a/lib/types/dm-ops.js b/lib/types/dm-ops.js
--- a/lib/types/dm-ops.js
+++ b/lib/types/dm-ops.js
@@ -442,18 +442,3 @@
}>,
},
};
-
-export type SendDMStartedPayload = {
- +messageID: string,
-};
-
-export type SendDMOpsSuccessPayload = {
- +messageID: string,
- +outboundP2PMessageIDs: $ReadOnlyArray<string>,
-};
-
-export const sendDMActionTypes = Object.freeze({
- started: 'SEND_DM_STARTED',
- success: 'SEND_DM_SUCCESS',
- failed: 'SEND_DM_FAILED',
-});
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
@@ -47,8 +47,6 @@
QueueDMOpsPayload,
PruneDMOpsQueuePayload,
ClearQueuedThreadDMOpsPayload,
- SendDMStartedPayload,
- SendDMOpsSuccessPayload,
} from './dm-ops.js';
import type { DraftStore } from './draft-types.js';
import type { EnabledApps, SupportedApps } from './enabled-apps.js';
@@ -724,6 +722,7 @@
+payload: Error & {
+localID: string,
+threadID: string,
+ +failedOutboundMessageIDs?: $ReadOnlyArray<string>,
},
+loadingInfo?: LoadingInfo,
}
@@ -743,6 +742,7 @@
+payload: Error & {
+localID: string,
+threadID: string,
+ +failedOutboundMessageIDs?: $ReadOnlyArray<string>,
},
+loadingInfo?: LoadingInfo,
}
@@ -1580,22 +1580,6 @@
+type: 'PROCESS_DM_OPS',
+payload: ProcessDMOpsPayload,
}
- | {
- +type: 'SEND_DM_STARTED',
- +payload: SendDMStartedPayload,
- +loadingInfo: LoadingInfo,
- }
- | {
- +type: 'SEND_DM_FAILED',
- +error: true,
- +payload: Error,
- +loadingInfo: LoadingInfo,
- }
- | {
- +type: 'SEND_DM_SUCCESS',
- +payload: SendDMOpsSuccessPayload,
- +loadingInfo: LoadingInfo,
- }
| {
+type: 'INVALIDATE_TUNNELBROKER_DEVICE_TOKEN',
+payload: {
diff --git a/native/chat/failed-send.react.js b/native/chat/failed-send.react.js
--- a/native/chat/failed-send.react.js
+++ b/native/chat/failed-send.react.js
@@ -5,16 +5,13 @@
import { Text, View } from 'react-native';
import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
-import { useRetrySendDMOperation } from 'lib/shared/dm-ops/process-dm-ops.js';
import { messageID } from 'lib/shared/message-utils.js';
import { messageTypes } from 'lib/types/message-types-enum.js';
import {
type RawComposableMessageInfo,
assertComposableRawMessage,
- type LocalMessageInfo,
} from 'lib/types/message-types.js';
import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
-import { threadTypeIsThick } from 'lib/types/thread-types-enum.js';
import { multimediaMessageSendFailed } from './multimedia-message-utils.js';
import textMessageSendFailed from './text-message-send-failed.js';
@@ -52,10 +49,6 @@
+styles: $ReadOnly<typeof unboundStyles>,
+inputState: ?InputState,
+parentThreadInfo: ?ThreadInfo,
- +retrySendDMOperation: (
- messageID: string,
- localMessageInfo: LocalMessageInfo,
- ) => Promise<void>,
};
class FailedSend extends React.PureComponent<Props> {
retryingText = false;
@@ -144,18 +137,6 @@
this.retryingMedia = true;
}
- if (threadTypeIsThick(this.props.item.threadInfo.type)) {
- const failedMessageID = this.props.rawMessageInfo?.id;
- invariant(failedMessageID, 'failedMessageID should be set for DMs');
- const localMessageInfo = this.props.item.localMessageInfo;
- invariant(
- localMessageInfo,
- 'localMessageInfo should be set for failed message',
- );
- void this.props.retrySendDMOperation(failedMessageID, localMessageInfo);
- return;
- }
-
const { inputState } = this.props;
invariant(
inputState,
@@ -184,7 +165,6 @@
const parentThreadInfo = useSelector(state =>
parentThreadID ? threadInfoSelector(state)[parentThreadID] : null,
);
- const retrySendDMOperation = useRetrySendDMOperation();
return (
<FailedSend
@@ -193,7 +173,6 @@
styles={styles}
inputState={inputState}
parentThreadInfo={parentThreadInfo}
- retrySendDMOperation={retrySendDMOperation}
/>
);
});
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
@@ -97,6 +97,7 @@
import {
type ClientNewThinThreadRequest,
type NewThreadResult,
+ type RawThreadInfos,
} from 'lib/types/thread-types.js';
import { getConfig } from 'lib/utils/config.js';
import { cloneError, getMessageForException } from 'lib/utils/errors.js';
@@ -167,11 +168,14 @@
+sendTextMessage: (input: SendTextMessageInput) => Promise<SendMessageResult>,
+processAndSendDMOperation: (
dmOperationSpecification: OutboundDMOperationSpecification,
- ) => Promise<void>,
+ localMessageID?: string,
+ ) => Promise<$ReadOnlyArray<string>>,
+newThinThread: (
request: ClientNewThinThreadRequest,
) => Promise<NewThreadResult>,
+textMessageCreationSideEffectsFunc: CreationSideEffectsFunc<RawTextMessageInfo>,
+ //TODO improve this
+ +threadInfos: RawThreadInfos,
};
type State = {
+pendingUploads: PendingMultimediaUploads,
@@ -392,6 +396,51 @@
const mediaMessageContents = getMediaMessageServerDBContentsFromMedia(
messageInfo.media,
);
+ const threadInfo = this.props.threadInfos[threadID];
+ const messageID = uuid.v4();
+
+ if (threadInfo.thick) {
+ const messageIDs = await this.props.processAndSendDMOperation(
+ {
+ type: dmOperationSpecificationTypes.OUTBOUND,
+ op: {
+ type: 'send_media_message',
+ threadID,
+ creatorID: messageInfo.creatorID,
+ time: Date.now(),
+ messageID,
+ media: messageInfo.media,
+ },
+ recipients: {
+ type: 'all_thread_members',
+ threadID:
+ threadInfo.type === thickThreadTypes.THICK_SIDEBAR &&
+ threadInfo.parentThreadID
+ ? threadInfo.parentThreadID
+ : threadInfo.id,
+ },
+ sendOnly: true,
+ },
+ localID,
+ );
+ if (messageIDs.length > 0) {
+ const copy: any = cloneError({});
+ copy.localID = messageInfo.localID;
+ copy.threadID = messageInfo.threadID;
+ copy.messageIDs = messageIDs;
+ throw copy;
+ }
+ this.pendingSidebarCreationMessageLocalIDs.delete(localID);
+ return {
+ localID,
+ serverID: messageID,
+ threadID: threadID,
+ time: Date.now(),
+ //TODO
+ interface: 'socket',
+ };
+ }
+
try {
const result = await this.props.sendMultimediaMessage({
threadID,
@@ -471,31 +520,6 @@
) => {
this.sendCallbacks.forEach(callback => callback());
- // TODO: this should be update according to thread creation logic
- // (ENG-8567)
- if (threadTypeIsThick(inputThreadInfo.type)) {
- void this.props.processAndSendDMOperation({
- type: dmOperationSpecificationTypes.OUTBOUND,
- op: {
- type: 'send_text_message',
- threadID: inputThreadInfo.id,
- creatorID: messageInfo.creatorID,
- time: Date.now(),
- messageID: uuid.v4(),
- text: messageInfo.text,
- },
- recipients: {
- type: 'all_thread_members',
- threadID:
- inputThreadInfo.type === thickThreadTypes.THICK_SIDEBAR &&
- inputThreadInfo.parentThreadID
- ? inputThreadInfo.parentThreadID
- : inputThreadInfo.id,
- },
- });
- return;
- }
-
const { localID } = messageInfo;
invariant(
localID !== null && localID !== undefined,
@@ -620,6 +644,51 @@
);
const sidebarCreation =
this.pendingSidebarCreationMessageLocalIDs.has(localID);
+
+ const messageID = uuid.v4();
+
+ if (threadTypeIsThick(threadInfo.type)) {
+ const messageIDs = await this.props.processAndSendDMOperation(
+ {
+ type: dmOperationSpecificationTypes.OUTBOUND,
+ op: {
+ type: 'send_text_message',
+ threadID: threadInfo.id,
+ creatorID: messageInfo.creatorID,
+ time: Date.now(),
+ messageID,
+ text: messageInfo.text,
+ },
+ recipients: {
+ type: 'all_thread_members',
+ threadID:
+ threadInfo.type === thickThreadTypes.THICK_SIDEBAR &&
+ threadInfo.parentThreadID
+ ? threadInfo.parentThreadID
+ : threadInfo.id,
+ },
+ sendOnly: true,
+ },
+ localID,
+ );
+ if (messageIDs.length > 0) {
+ const copy: any = cloneError({});
+ copy.localID = messageInfo.localID;
+ copy.threadID = messageInfo.threadID;
+ copy.messageIDs = messageIDs;
+ throw copy;
+ }
+ this.pendingSidebarCreationMessageLocalIDs.delete(localID);
+ return {
+ localID,
+ serverID: messageID,
+ threadID: messageInfo.threadID,
+ time: Date.now(),
+ //TODO
+ interface: 'socket',
+ };
+ }
+
const result = await this.props.sendTextMessage({
threadID: messageInfo.threadID,
localID,
@@ -1794,6 +1863,7 @@
const textMessageCreationSideEffectsFunc =
useMessageCreationSideEffectsFunc<RawTextMessageInfo>(messageTypes.TEXT);
const processAndSendDMOperation = useProcessAndSendDMOperation();
+ const threads = useSelector(state => state.threadStore.threadInfos);
return (
<InputStateContainer
@@ -1814,6 +1884,7 @@
dispatch={dispatch}
staffCanSee={staffCanSee}
textMessageCreationSideEffectsFunc={textMessageCreationSideEffectsFunc}
+ threadInfos={threads}
/>
);
});
diff --git a/web/chat/failed-send.react.js b/web/chat/failed-send.react.js
--- a/web/chat/failed-send.react.js
+++ b/web/chat/failed-send.react.js
@@ -5,16 +5,13 @@
import { type ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
-import { useRetrySendDMOperation } from 'lib/shared/dm-ops/process-dm-ops.js';
import { messageID } from 'lib/shared/message-utils.js';
import { messageTypes } from 'lib/types/message-types-enum.js';
import {
assertComposableMessageType,
- type LocalMessageInfo,
type RawComposableMessageInfo,
} from 'lib/types/message-types.js';
import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
-import { threadTypeIsThick } from 'lib/types/thread-types-enum.js';
import css from './chat-message-list.css';
import multimediaMessageSendFailed from './multimedia-message-send-failed.js';
@@ -32,10 +29,6 @@
+rawMessageInfo: RawComposableMessageInfo,
+inputState: ?InputState,
+parentThreadInfo: ?ThreadInfo,
- +retrySendDMOperation: (
- messageID: string,
- localMessageInfo: LocalMessageInfo,
- ) => Promise<void>,
};
class FailedSend extends React.PureComponent<Props> {
retryingText = false;
@@ -113,17 +106,7 @@
return;
}
this.retryingText = true;
- if (threadTypeIsThick(this.props.threadInfo.type)) {
- const failedMessageID = this.props.rawMessageInfo.id;
- invariant(failedMessageID, 'failedMessageID should be set for DMs');
- const localMessageInfo = this.props.item.localMessageInfo;
- invariant(
- localMessageInfo,
- 'localMessageInfo should be set for failed message',
- );
- void this.props.retrySendDMOperation(failedMessageID, localMessageInfo);
- return;
- }
+
void inputState.sendTextMessage(
{
...rawMessageInfo,
@@ -167,7 +150,6 @@
const parentThreadInfo = useSelector(state =>
parentThreadID ? threadInfoSelector(state)[parentThreadID] : null,
);
- const retrySendDMOperation = useRetrySendDMOperation();
return (
<FailedSend
@@ -175,7 +157,6 @@
rawMessageInfo={rawMessageInfo}
inputState={inputState}
parentThreadInfo={parentThreadInfo}
- retrySendDMOperation={retrySendDMOperation}
/>
);
});
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
@@ -94,6 +94,7 @@
import {
type ClientNewThinThreadRequest,
type NewThreadResult,
+ type RawThreadInfos,
} from 'lib/types/thread-types.js';
import {
blobHashFromBlobServiceURI,
@@ -161,7 +162,8 @@
+sendTextMessage: (input: SendTextMessageInput) => Promise<SendMessageResult>,
+processAndSendDMOperation: (
dmOperationSpecification: OutboundDMOperationSpecification,
- ) => Promise<void>,
+ localMessageID?: string,
+ ) => Promise<$ReadOnlyArray<string>>,
+newThinThread: (
request: ClientNewThinThreadRequest,
) => Promise<NewThreadResult>,
@@ -171,6 +173,8 @@
+unregisterSendCallback: (() => mixed) => void,
+textMessageCreationSideEffectsFunc: CreationSideEffectsFunc<RawTextMessageInfo>,
+identityContext: ?IdentityClientContextType,
+ //TODO improve this
+ +threadInfos: RawThreadInfos,
};
type WritableState = {
pendingUploads: {
@@ -541,6 +545,52 @@
for (const { id } of messageInfo.media) {
mediaIDs.push(id);
}
+
+ const messageID = uuid.v4();
+
+ const threadInfo = this.props.threadInfos[threadID];
+ if (threadInfo.thick) {
+ const messageIDs = await this.props.processAndSendDMOperation(
+ {
+ type: dmOperationSpecificationTypes.OUTBOUND,
+ op: {
+ type: 'send_media_message',
+ threadID,
+ creatorID: messageInfo.creatorID,
+ time: Date.now(),
+ messageID,
+ media: messageInfo.media,
+ },
+ recipients: {
+ type: 'all_thread_members',
+ threadID:
+ threadInfo.type === thickThreadTypes.THICK_SIDEBAR &&
+ threadInfo.parentThreadID
+ ? threadInfo.parentThreadID
+ : threadInfo.id,
+ },
+ sendOnly: true,
+ },
+ localID,
+ );
+ if (messageIDs.length > 0) {
+ const copy: any = cloneError({});
+ copy.localID = messageInfo.localID;
+ copy.threadID = messageInfo.threadID;
+ copy.messageIDs = messageIDs;
+ throw copy;
+ }
+ this.pendingSidebarCreationMessageLocalIDs.delete(localID);
+ return {
+ localID,
+ serverID: messageID,
+ threadID: threadID,
+ time: Date.now(),
+ //TODO
+ interface: 'socket',
+ };
+ }
+
try {
const result = await this.props.sendMultimediaMessage({
threadID,
@@ -1281,31 +1331,6 @@
) {
this.props.sendCallbacks.forEach(callback => callback());
- // TODO: this should be update according to thread creation logic
- // (ENG-8567)
- if (threadTypeIsThick(inputThreadInfo.type)) {
- void this.props.processAndSendDMOperation({
- type: dmOperationSpecificationTypes.OUTBOUND,
- op: {
- type: 'send_text_message',
- threadID: inputThreadInfo.id,
- creatorID: messageInfo.creatorID,
- time: Date.now(),
- messageID: uuid.v4(),
- text: messageInfo.text,
- },
- recipients: {
- type: 'all_thread_members',
- threadID:
- inputThreadInfo.type === thickThreadTypes.THICK_SIDEBAR &&
- inputThreadInfo.parentThreadID
- ? inputThreadInfo.parentThreadID
- : inputThreadInfo.id,
- },
- });
- return;
- }
-
const { localID } = messageInfo;
invariant(
localID !== null && localID !== undefined,
@@ -1410,6 +1435,51 @@
);
const sidebarCreation =
this.pendingSidebarCreationMessageLocalIDs.has(localID);
+
+ const messageID = uuid.v4();
+
+ if (threadTypeIsThick(threadInfo.type)) {
+ const messageIDs = await this.props.processAndSendDMOperation(
+ {
+ type: dmOperationSpecificationTypes.OUTBOUND,
+ op: {
+ type: 'send_text_message',
+ threadID: threadInfo.id,
+ creatorID: messageInfo.creatorID,
+ time: Date.now(),
+ messageID,
+ text: messageInfo.text,
+ },
+ recipients: {
+ type: 'all_thread_members',
+ threadID:
+ threadInfo.type === thickThreadTypes.THICK_SIDEBAR &&
+ threadInfo.parentThreadID
+ ? threadInfo.parentThreadID
+ : threadInfo.id,
+ },
+ sendOnly: true,
+ },
+ localID,
+ );
+ if (messageIDs.length > 0) {
+ const copy: any = cloneError({});
+ copy.localID = messageInfo.localID;
+ copy.threadID = messageInfo.threadID;
+ copy.messageIDs = messageIDs;
+ throw copy;
+ }
+ this.pendingSidebarCreationMessageLocalIDs.delete(localID);
+ return {
+ localID,
+ serverID: messageID,
+ threadID: messageInfo.threadID,
+ time: Date.now(),
+ //TODO
+ interface: 'socket',
+ };
+ }
+
const result = await this.props.sendTextMessage({
threadID: messageInfo.threadID,
localID,
@@ -1735,6 +1805,8 @@
const textMessageCreationSideEffectsFunc =
useMessageCreationSideEffectsFunc<RawTextMessageInfo>(messageTypes.TEXT);
+ const threads = useSelector(state => state.threadStore.threadInfos);
+
return (
<InputStateContainer
{...props}
@@ -1759,6 +1831,7 @@
unregisterSendCallback={unregisterSendCallback}
textMessageCreationSideEffectsFunc={textMessageCreationSideEffectsFunc}
identityContext={identityContext}
+ threadInfos={threads}
/>
);
});

File Metadata

Mime Type
text/plain
Expires
Mon, Dec 23, 10:16 PM (19 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2695716
Default Alt Text
D13290.id44043.diff (30 KB)

Event Timeline