Page MenuHomePhabricator

D12870.id42880.diff
No OneTemporary

D12870.id42880.diff

diff --git a/lib/shared/dm-ops/dm-op-specs.js b/lib/shared/dm-ops/dm-op-specs.js
--- a/lib/shared/dm-ops/dm-op-specs.js
+++ b/lib/shared/dm-ops/dm-op-specs.js
@@ -4,6 +4,7 @@
import { createSidebarSpec } from './create-sidebar-spec.js';
import { createThreadSpec } from './create-thread-spec.js';
import type { DMOperationSpec } from './dm-op-spec.js';
+import { joinThreadSpec } from './join-thread-spec.js';
import { sendEditMessageSpec } from './send-edit-message-spec.js';
import { sendReactionMessageSpec } from './send-reaction-message-spec.js';
import { sendTextMessageSpec } from './send-text-message-spec.js';
@@ -18,4 +19,5 @@
[dmOperationTypes.SEND_REACTION_MESSAGE]: sendReactionMessageSpec,
[dmOperationTypes.SEND_EDIT_MESSAGE]: sendEditMessageSpec,
[dmOperationTypes.ADD_MEMBERS]: addMembersSpec,
+ [dmOperationTypes.JOIN_THREAD]: joinThreadSpec,
});
diff --git a/lib/shared/dm-ops/join-thread-spec.js b/lib/shared/dm-ops/join-thread-spec.js
new file mode 100644
--- /dev/null
+++ b/lib/shared/dm-ops/join-thread-spec.js
@@ -0,0 +1,132 @@
+// @flow
+
+import invariant from 'invariant';
+import uuid from 'uuid';
+
+import {
+ createRoleAndPermissionForThickThreads,
+ createThickRawThreadInfo,
+} from './create-thread-spec.js';
+import type {
+ DMOperationSpec,
+ ProcessDMOperationUtilities,
+} from './dm-op-spec.js';
+import type { DMJoinThreadOperation } from '../../types/dm-ops.js';
+import { messageTypes } from '../../types/message-types-enum.js';
+import { messageTruncationStatus } from '../../types/message-types.js';
+import type { RawMessageInfo } from '../../types/message-types.js';
+import { minimallyEncodeMemberInfo } from '../../types/minimally-encoded-thread-permissions-types.js';
+import type { ThickRawThreadInfo } from '../../types/minimally-encoded-thread-permissions-types.js';
+import { joinThreadSubscription } from '../../types/subscription-types.js';
+import type { ThickMemberInfo } from '../../types/thread-types.js';
+import { updateTypes } from '../../types/update-types-enum.js';
+import type { ClientUpdateInfo } from '../../types/update-types.js';
+import { values } from '../../utils/objects.js';
+import { roleIsDefaultRole, userIsMember } from '../thread-utils.js';
+
+const joinThreadSpec: DMOperationSpec<DMJoinThreadOperation> = Object.freeze({
+ processDMOperation: async (
+ dmOperation: DMJoinThreadOperation,
+ viewerID: string,
+ utilities: ProcessDMOperationUtilities,
+ ) => {
+ const { editorID, time, messageID, existingThreadDetails } = dmOperation;
+
+ const currentThreadInfoOptional = utilities.getThreadInfo(
+ existingThreadDetails.threadID,
+ );
+ if (userIsMember(currentThreadInfoOptional, editorID)) {
+ return {
+ rawMessageInfos: [],
+ updateInfos: [],
+ };
+ }
+
+ const joinThreadMessage = {
+ type: messageTypes.JOIN_THREAD,
+ id: messageID,
+ threadID: existingThreadDetails.threadID,
+ creatorID: editorID,
+ time,
+ };
+
+ const updateInfos: Array<ClientUpdateInfo> = [];
+ const rawMessageInfos: Array<RawMessageInfo> = [];
+ if (viewerID === editorID) {
+ updateInfos.push(
+ {
+ type: updateTypes.JOIN_THREAD,
+ id: uuid.v4(),
+ time,
+ threadInfo: createThickRawThreadInfo(existingThreadDetails, viewerID),
+ rawMessageInfos: [joinThreadMessage],
+ truncationStatus: messageTruncationStatus.EXHAUSTIVE,
+ rawEntryInfos: [],
+ },
+ {
+ type: updateTypes.UPDATE_THREAD_READ_STATUS,
+ id: uuid.v4(),
+ time,
+ threadID: existingThreadDetails.threadID,
+ unread: true,
+ },
+ );
+ } else {
+ if (!currentThreadInfoOptional || !currentThreadInfoOptional.thick) {
+ // We can't perform this operation now. It should be queued for later.
+ return {
+ rawMessageInfos: [],
+ updateInfos: [],
+ };
+ }
+ const currentThreadInfo: ThickRawThreadInfo = currentThreadInfoOptional;
+
+ rawMessageInfos.push(joinThreadMessage);
+ if (!userIsMember(currentThreadInfo, editorID)) {
+ const defaultRoleID = values(currentThreadInfo.roles).find(role =>
+ roleIsDefaultRole(role),
+ )?.id;
+ invariant(defaultRoleID, 'Default role ID must exist');
+ const { membershipPermissions } =
+ createRoleAndPermissionForThickThreads(
+ currentThreadInfo.type,
+ currentThreadInfo.id,
+ defaultRoleID,
+ );
+
+ const member = minimallyEncodeMemberInfo<ThickMemberInfo>({
+ id: editorID,
+ role: defaultRoleID,
+ permissions: membershipPermissions,
+ isSender: editorID === viewerID,
+ subscription: joinThreadSubscription,
+ });
+ const updatedThreadInfo = {
+ ...currentThreadInfo,
+ members: [...currentThreadInfo.members, member],
+ };
+ updateInfos.push(
+ {
+ type: updateTypes.UPDATE_THREAD,
+ id: uuid.v4(),
+ time,
+ threadInfo: updatedThreadInfo,
+ },
+ {
+ type: updateTypes.UPDATE_THREAD_READ_STATUS,
+ id: uuid.v4(),
+ time,
+ threadID: existingThreadDetails.threadID,
+ unread: true,
+ },
+ );
+ }
+ }
+ return {
+ rawMessageInfos,
+ updateInfos,
+ };
+ },
+});
+
+export { joinThreadSpec };
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
@@ -23,6 +23,7 @@
SEND_REACTION_MESSAGE: 'send_reaction_message',
SEND_EDIT_MESSAGE: 'send_edit_message',
ADD_MEMBERS: 'add_members',
+ JOIN_THREAD: 'join_thread',
});
export type DMOperationType = $Values<typeof dmOperationTypes>;
@@ -188,13 +189,30 @@
existingThreadDetails: createThickRawThreadInfoInputValidator,
});
+export type DMJoinThreadOperation = {
+ +type: 'join_thread',
+ +editorID: string,
+ +time: number,
+ +messageID: string,
+ +existingThreadDetails: CreateThickRawThreadInfoInput,
+};
+export const dmJoinThreadOperationValidator: TInterface<DMJoinThreadOperation> =
+ tShape<DMJoinThreadOperation>({
+ type: tString(dmOperationTypes.JOIN_THREAD),
+ editorID: tUserID,
+ time: t.Number,
+ messageID: t.String,
+ existingThreadDetails: createThickRawThreadInfoInputValidator,
+ });
+
export type DMOperation =
| DMCreateThreadOperation
| DMCreateSidebarOperation
| DMSendTextMessageOperation
| DMSendReactionMessageOperation
| DMSendEditMessageOperation
- | DMAddMembersOperation;
+ | DMAddMembersOperation
+ | DMJoinThreadOperation;
export const dmOperationValidator: TUnion<DMOperation> = t.union([
dmCreateThreadOperationValidator,
dmCreateSidebarOperationValidator,
@@ -202,6 +220,7 @@
dmSendReactionMessageOperationValidator,
dmSendEditMessageOperationValidator,
dmAddMembersOperationValidator,
+ dmJoinThreadOperationValidator,
]);
export type DMOperationResult = {

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 5, 12:52 PM (16 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2425758
Default Alt Text
D12870.id42880.diff (6 KB)

Event Timeline