Page MenuHomePhabricator

D13404.id44396.diff
No OneTemporary

D13404.id44396.diff

diff --git a/lib/selectors/thread-selectors.js b/lib/selectors/thread-selectors.js
--- a/lib/selectors/thread-selectors.js
+++ b/lib/selectors/thread-selectors.js
@@ -33,6 +33,7 @@
roleIsAdminRole,
threadIsPending,
getPendingThreadID,
+ pendingThreadType,
} from '../shared/thread-utils.js';
import type { ClientAvatar, ClientEmojiAvatar } from '../types/avatar-types';
import type { EntryInfo } from '../types/entry-types.js';
@@ -461,17 +462,28 @@
const actualMemberIDs = rawThreadInfo.members
.filter(member => member.role)
.map(member => member.id);
- const pendingThreadID = getPendingThreadID(
- rawThreadInfo.type,
- actualMemberIDs,
- rawThreadInfo.sourceMessageID,
- );
- const existingResult = result.get(pendingThreadID);
- if (
- !existingResult ||
- rawThreadInfos[existingResult].creationTime > rawThreadInfo.creationTime
- ) {
- result.set(pendingThreadID, threadID);
+ // In this function we're generating possible pending thread IDs that
+ // could become `rawThreadInfos`. It is possible that a thick pending
+ // thread becomes a thin thread, so we're including it twice in a map -
+ // for each possible pending thread ID.
+ const possiblePendingThreadTypes = [
+ pendingThreadType(actualMemberIDs.length - 1, 'thin', true),
+ pendingThreadType(actualMemberIDs.length - 1, 'thick', true),
+ ];
+ for (const type of possiblePendingThreadTypes) {
+ const pendingThreadID = getPendingThreadID(
+ type,
+ actualMemberIDs,
+ rawThreadInfo.sourceMessageID,
+ );
+ const existingResult = result.get(pendingThreadID);
+ if (
+ !existingResult ||
+ rawThreadInfos[existingResult].creationTime >
+ rawThreadInfo.creationTime
+ ) {
+ result.set(pendingThreadID, threadID);
+ }
}
}
return result;
diff --git a/lib/shared/thread-actions-utils.js b/lib/shared/thread-actions-utils.js
--- a/lib/shared/thread-actions-utils.js
+++ b/lib/shared/thread-actions-utils.js
@@ -12,6 +12,7 @@
removeUsersFromThreadActionTypes,
type RemoveUsersFromThreadInput,
} from '../actions/thread-actions.js';
+import type { AuxUserInfos } from '../types/aux-user-types.js';
import type { CalendarQuery } from '../types/entry-types.js';
import type {
RelativeMemberInfo,
@@ -23,6 +24,7 @@
assertThickThreadType,
threadTypeIsThick,
} from '../types/thread-types-enum.js';
+import type { ThreadType } from '../types/thread-types-enum.js';
import type {
ChangeThreadSettingsPayload,
ClientNewThinThreadRequest,
@@ -60,6 +62,7 @@
+handleError?: () => mixed,
+calendarQuery: CalendarQuery,
+usingOlmViaTunnelbrokerForDMs: boolean,
+ +auxUserInfos: AuxUserInfos,
};
async function createRealThreadFromPendingThread({
@@ -71,12 +74,20 @@
viewerID,
calendarQuery,
usingOlmViaTunnelbrokerForDMs,
-}: CreateRealThreadParameters): Promise<string> {
+ auxUserInfos,
+}: CreateRealThreadParameters): Promise<{
+ +threadID: string,
+ +threadType: ThreadType,
+}> {
if (!threadIsPending(threadInfo.id)) {
- return threadInfo.id;
+ return {
+ threadID: threadInfo.id,
+ threadType: threadInfo.type,
+ };
}
let newThreadID;
+ let newThreadType = threadInfo.type;
const otherMemberIDs = threadOtherMembers(threadInfo.members, viewerID).map(
member => member.id,
@@ -125,7 +136,12 @@
otherMemberIDs.length > 0,
'otherMemberIDs should not be empty for threads',
);
- if (threadTypeIsThick(threadInfo.type)) {
+ const allUsersSupportThickThreads = otherMemberIDs.every(
+ memberID =>
+ auxUserInfos[memberID]?.deviceList &&
+ auxUserInfos[memberID].deviceList.devices.length > 0,
+ );
+ if (threadTypeIsThick(threadInfo.type) && allUsersSupportThickThreads) {
const type = assertThickThreadType(
pendingThreadType(
otherMemberIDs.length,
@@ -144,6 +160,7 @@
initialMemberIDs: otherMemberIDs,
color: threadInfo.color,
});
+ newThreadType = type;
} else {
const type = assertThinThreadType(
pendingThreadType(
@@ -166,9 +183,13 @@
void dispatchActionPromise(newThreadActionTypes, resultPromise);
const result = await resultPromise;
newThreadID = result.newThreadID;
+ newThreadType = type;
}
}
- return newThreadID;
+ return {
+ threadID: newThreadID,
+ threadType: newThreadType,
+ };
}
export { removeMemberFromThread, createRealThreadFromPendingThread };
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
@@ -57,6 +57,7 @@
threadIsPending,
threadIsPendingSidebar,
} from 'lib/shared/thread-utils.js';
+import type { AuxUserInfos } from 'lib/types/aux-user-types';
import type { CalendarQuery } from 'lib/types/entry-types.js';
import type {
Media,
@@ -85,6 +86,7 @@
threadTypeIsThick,
threadTypeIsSidebar,
} from 'lib/types/thread-types-enum.js';
+import type { ThreadType } from 'lib/types/thread-types-enum.js';
import {
type ClientNewThinThreadRequest,
type NewThreadResult,
@@ -170,6 +172,7 @@
+newThickThread: (request: NewThickThreadRequest) => Promise<string>,
+textMessageCreationSideEffectsFunc: CreationSideEffectsFunc<RawTextMessageInfo>,
+usingOlmViaTunnelbrokerForDMs: boolean,
+ +auxUserInfos: AuxUserInfos,
};
type State = {
+pendingUploads: PendingMultimediaUploads,
@@ -185,7 +188,13 @@
(params: EditInputBarMessageParameters) => void,
> = [];
scrollToMessageCallbacks: Array<(messageID: string) => void> = [];
- pendingThreadCreations: Map<string, Promise<string>> = new Map();
+ pendingThreadCreations: Map<
+ string,
+ Promise<{
+ +threadID: string,
+ +threadType: ThreadType,
+ }>,
+ > = new Map();
pendingThreadUpdateHandlers: Map<string, (ThreadInfo) => mixed> = new Map();
// TODO: flip the switch
// Note that this enables Blob service for encrypted media only
@@ -349,7 +358,8 @@
// again.
throw new Error('Thread creation failed');
}
- newThreadID = await threadCreationPromise;
+ const result = await threadCreationPromise;
+ newThreadID = result.threadID;
} catch (e) {
const copy = cloneError(e);
copy.localID = messageInfo.localID;
@@ -505,9 +515,9 @@
}
}
- let newThreadID = null;
+ let threadCreationResult = null;
try {
- newThreadID = await this.startThreadCreation(threadInfo);
+ threadCreationResult = await this.startThreadCreation(threadInfo);
} catch (e) {
const copy = cloneError(e);
copy.localID = messageInfo.localID;
@@ -524,13 +534,14 @@
const newMessageInfo = {
...messageInfo,
- threadID: newThreadID,
+ threadID: threadCreationResult?.threadID,
time: Date.now(),
};
const newThreadInfo = {
...threadInfo,
- id: newThreadID,
+ id: threadCreationResult?.threadID,
+ type: threadCreationResult?.threadType ?? threadInfo.type,
};
void this.props.dispatchActionPromise(
@@ -545,9 +556,14 @@
);
};
- startThreadCreation(threadInfo: ThreadInfo): Promise<string> {
+ startThreadCreation(
+ threadInfo: ThreadInfo,
+ ): Promise<{ +threadID: string, +threadType: ThreadType }> {
if (!threadIsPending(threadInfo.id)) {
- return Promise.resolve(threadInfo.id);
+ return Promise.resolve({
+ threadID: threadInfo.id,
+ threadType: threadInfo.type,
+ });
}
let threadCreationPromise = this.pendingThreadCreations.get(threadInfo.id);
if (!threadCreationPromise) {
@@ -561,6 +577,7 @@
viewerID: this.props.viewerID,
calendarQuery,
usingOlmViaTunnelbrokerForDMs: this.props.usingOlmViaTunnelbrokerForDMs,
+ auxUserInfos: this.props.auxUserInfos,
});
this.pendingThreadCreations.set(threadInfo.id, threadCreationPromise);
}
@@ -1773,6 +1790,7 @@
const textMessageCreationSideEffectsFunc =
useMessageCreationSideEffectsFunc<RawTextMessageInfo>(messageTypes.TEXT);
const usingOlmViaTunnelbrokerForDMs = useAllowOlmViaTunnelbrokerForDMs();
+ const auxUserInfos = useSelector(state => state.auxUserStore.auxUserInfos);
return (
<InputStateContainer
@@ -1794,6 +1812,7 @@
staffCanSee={staffCanSee}
textMessageCreationSideEffectsFunc={textMessageCreationSideEffectsFunc}
usingOlmViaTunnelbrokerForDMs={usingOlmViaTunnelbrokerForDMs}
+ auxUserInfos={auxUserInfos}
/>
);
});
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
@@ -59,6 +59,7 @@
threadIsPending,
threadIsPendingSidebar,
} from 'lib/shared/thread-utils.js';
+import type { AuxUserInfos } from 'lib/types/aux-user-types.js';
import type { CalendarQuery } from 'lib/types/entry-types.js';
import type {
MediaMission,
@@ -83,6 +84,7 @@
threadTypeIsSidebar,
threadTypeIsThick,
} from 'lib/types/thread-types-enum.js';
+import type { ThreadType } from 'lib/types/thread-types-enum.js';
import {
type ClientNewThinThreadRequest,
type NewThreadResult,
@@ -170,6 +172,7 @@
+textMessageCreationSideEffectsFunc: CreationSideEffectsFunc<RawTextMessageInfo>,
+identityContext: ?IdentityClientContextType,
+usingOlmViaTunnelbrokerForDMs: boolean,
+ +auxUserInfos: AuxUserInfos,
};
type WritableState = {
pendingUploads: {
@@ -201,9 +204,18 @@
},
};
replyCallbacks: Array<(message: string) => void> = [];
- pendingThreadCreations: Map<string, Promise<string>> = new Map<
+ pendingThreadCreations: Map<
string,
- Promise<string>,
+ Promise<{
+ +threadID: string,
+ +threadType: ThreadType,
+ }>,
+ > = new Map<
+ string,
+ Promise<{
+ +threadID: string,
+ +threadType: ThreadType,
+ }>,
>();
// TODO: flip the switch
// Note that this enables Blob service for encrypted media only
@@ -481,7 +493,8 @@
// again.
throw new Error('Thread creation failed');
}
- newThreadID = await threadCreationPromise;
+ const result = await threadCreationPromise;
+ newThreadID = result.threadID;
} catch (e) {
const copy = cloneError(e);
copy.localID = messageInfo.localID;
@@ -577,9 +590,15 @@
}
}
- startThreadCreation(threadInfo: ThreadInfo): Promise<string> {
+ startThreadCreation(threadInfo: ThreadInfo): Promise<{
+ +threadID: string,
+ +threadType: ThreadType,
+ }> {
if (!threadIsPending(threadInfo.id)) {
- return Promise.resolve(threadInfo.id);
+ return Promise.resolve({
+ threadID: threadInfo.id,
+ threadType: threadInfo.type,
+ });
}
let threadCreationPromise = this.pendingThreadCreations.get(threadInfo.id);
if (!threadCreationPromise) {
@@ -593,6 +612,7 @@
viewerID: this.props.viewerID,
calendarQuery,
usingOlmViaTunnelbrokerForDMs: this.props.usingOlmViaTunnelbrokerForDMs,
+ auxUserInfos: this.props.auxUserInfos,
});
this.pendingThreadCreations.set(threadInfo.id, threadCreationPromise);
}
@@ -1323,9 +1343,9 @@
}
}
- let newThreadID = null;
+ let threadCreationResult = null;
try {
- newThreadID = await this.startThreadCreation(threadInfo);
+ threadCreationResult = await this.startThreadCreation(threadInfo);
} catch (e) {
const copy = cloneError(e);
copy.localID = messageInfo.localID;
@@ -1342,13 +1362,14 @@
const newMessageInfo = {
...messageInfo,
- threadID: newThreadID,
+ threadID: threadCreationResult?.threadID,
time: Date.now(),
};
const newThreadInfo = {
...threadInfo,
- id: newThreadID,
+ id: threadCreationResult?.threadID,
+ type: threadCreationResult?.threadType ?? threadInfo.type,
};
void this.props.dispatchActionPromise(
sendTextMessageActionTypes,
@@ -1709,6 +1730,7 @@
const textMessageCreationSideEffectsFunc =
useMessageCreationSideEffectsFunc<RawTextMessageInfo>(messageTypes.TEXT);
const usingOlmViaTunnelbrokerForDMs = useAllowOlmViaTunnelbrokerForDMs();
+ const auxUserInfos = useSelector(state => state.auxUserStore.auxUserInfos);
return (
<InputStateContainer
@@ -1735,6 +1757,7 @@
textMessageCreationSideEffectsFunc={textMessageCreationSideEffectsFunc}
identityContext={identityContext}
usingOlmViaTunnelbrokerForDMs={usingOlmViaTunnelbrokerForDMs}
+ auxUserInfos={auxUserInfos}
/>
);
});

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 18, 3:33 PM (21 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2534968
Default Alt Text
D13404.id44396.diff (12 KB)

Event Timeline