diff --git a/lib/hooks/thread-search-hooks.js b/lib/hooks/thread-search-hooks.js --- a/lib/hooks/thread-search-hooks.js +++ b/lib/hooks/thread-search-hooks.js @@ -1,15 +1,28 @@ // @flow +import invariant from 'invariant'; import * as React from 'react'; +import uuid from 'uuid'; import { searchUsers as searchUserCall } from '../actions/user-actions.js'; import { useLegacyAshoatKeyserverCall } from '../keyserver-conn/legacy-keyserver-call.js'; import { useGlobalThreadSearchIndex } from '../selectors/nav-selectors.js'; import { usersWithPersonalThreadSelector } from '../selectors/user-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 { useForwardLookupSearchText, useSearchUsers, } from '../shared/search-utils.js'; +import type { + DMCreateSidebarOperation, + DMCreateThreadOperation, +} from '../types/dm-ops'; +import { threadTypes } from '../types/thread-types-enum.js'; +import type { NewThickThreadRequest } from '../types/thread-types.js'; import type { GlobalAccountUserInfo } from '../types/user-types.js'; import { useSelector } from '../utils/redux-utils.js'; import { usingCommServicesAccessToken } from '../utils/services-utils.js'; @@ -82,4 +95,68 @@ return { threadSearchResults, usersSearchResults }; } -export { useThreadListSearch }; +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 { useThreadListSearch, 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 @@ -321,6 +321,18 @@ +calendarQuery?: ?CalendarQuery, }; +export type NewThickThreadRequest = + | { + +type: 13 | 14 | 15, + ...BaseNewThreadRequest, + } + | { + +type: 16, + +sourceMessageID: string, + ...BaseNewThreadRequest, + +parentThreadID: string, + }; + export type NewThreadResponse = { +updatesResult: { +newUpdates: $ReadOnlyArray,