diff --git a/lib/hooks/thread-hooks.js b/lib/hooks/thread-hooks.js --- a/lib/hooks/thread-hooks.js +++ b/lib/hooks/thread-hooks.js @@ -1,11 +1,24 @@ // @flow +import invariant from 'invariant'; import * as React from 'react'; +import uuid from 'uuid'; import { useChatMentionContext } from './chat-mention-hooks.js'; import genesis from '../facts/genesis.js'; import { childThreadInfos } from '../selectors/thread-selectors.js'; +import { + type OutboundDMOperationSpecification, + dmOperationSpecificationTypes, +} from '../shared/dm-ops/dm-op-utils.js'; +import { useProcessAndSendDMOperation } from '../shared/dm-ops/process-dm-ops.js'; +import type { + DMCreateSidebarOperation, + DMCreateThreadOperation, +} from '../types/dm-ops'; import type { ResolvedThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js'; +import { threadTypes } from '../types/thread-types-enum.js'; +import type { NewThickThreadRequest } from '../types/thread-types.js'; import { useSelector } from '../utils/redux-utils.js'; function useChildThreadInfosMap(): { @@ -46,4 +59,68 @@ ]); } -export { useChildThreadInfosMap }; +function useNewThickThread(): ( + input: NewThickThreadRequest, +) => Promise { + const processAndSendDMOperation = useProcessAndSendDMOperation(); + const viewerID = useSelector( + state => state.currentUserInfo && state.currentUserInfo.id, + ); + + return React.useCallback( + async (input: NewThickThreadRequest) => { + invariant(viewerID, 'viewerID must be defined'); + const threadID = input.id ?? uuid.v4(); + + let op; + if (input.type === threadTypes.THICK_SIDEBAR) { + const { parentThreadID, sourceMessageID, initialMemberIDs } = input; + invariant( + parentThreadID, + 'parentThreadID has to be defined for thick sidebar', + ); + const sidebarOP: DMCreateSidebarOperation = { + creatorID: viewerID, + memberIDs: initialMemberIDs ?? [], + newCreateSidebarMessageID: uuid.v4(), + newSidebarSourceMessageID: uuid.v4(), + parentThreadID: parentThreadID, + roleID: uuid.v4(), + sourceMessageID: sourceMessageID, + threadID, + time: Date.now(), + type: 'create_sidebar', + }; + op = sidebarOP; + } else { + const { type, initialMemberIDs } = input; + + const threadOP: DMCreateThreadOperation = { + creatorID: viewerID, + memberIDs: initialMemberIDs ?? [], + newMessageID: uuid.v4(), + roleID: uuid.v4(), + threadID, + threadType: type, + time: Date.now(), + type: 'create_thread', + }; + op = threadOP; + } + const userIDs = [...(input.initialMemberIDs ?? []), viewerID]; + const opSpecification: OutboundDMOperationSpecification = { + type: dmOperationSpecificationTypes.OUTBOUND, + op, + recipients: { + type: 'some_users', + userIDs, + }, + }; + await processAndSendDMOperation(opSpecification); + return threadID; + }, + [processAndSendDMOperation, viewerID], + ); +} + +export { useChildThreadInfosMap, useNewThickThread }; diff --git a/lib/types/thread-types.js b/lib/types/thread-types.js --- a/lib/types/thread-types.js +++ b/lib/types/thread-types.js @@ -357,6 +357,18 @@ +calendarQuery?: ?CalendarQuery, }>; +export type NewThickThreadRequest = + | $ReadOnly<{ + +type: 13 | 14 | 15, + ...BaseNewThreadRequest, + }> + | $ReadOnly<{ + +type: 16, + +sourceMessageID: string, + ...BaseNewThreadRequest, + +parentThreadID: string, + }>; + export type NewThreadResponse = { +updatesResult: { +newUpdates: $ReadOnlyArray,