diff --git a/lib/shared/thread-actions-utils.js b/lib/shared/thread-actions-utils.js new file mode 100644 --- /dev/null +++ b/lib/shared/thread-actions-utils.js @@ -0,0 +1,104 @@ +// @flow + +import invariant from 'invariant'; + +import { + threadIsPending, + threadOtherMembers, + pendingThreadType, +} from './thread-utils.js'; +import { + newThreadActionTypes, + removeUsersFromThreadActionTypes, + type RemoveUsersFromThreadInput, +} from '../actions/thread-actions.js'; +import type { CalendarQuery } from '../types/entry-types.js'; +import type { + RelativeMemberInfo, + ThreadInfo, +} from '../types/minimally-encoded-thread-permissions-types.js'; +import { threadTypes } from '../types/thread-types-enum.js'; +import type { + ChangeThreadSettingsPayload, + ClientNewThreadRequest, + NewThreadResult, +} from '../types/thread-types.js'; +import type { DispatchActionPromise } from '../utils/redux-promise-utils.js'; + +function removeMemberFromThread( + threadInfo: ThreadInfo, + memberInfo: RelativeMemberInfo, + dispatchActionPromise: DispatchActionPromise, + removeUserFromThreadServerCall: ( + input: RemoveUsersFromThreadInput, + ) => Promise, +) { + const customKeyName = `${removeUsersFromThreadActionTypes.started}:${memberInfo.id}`; + void dispatchActionPromise( + removeUsersFromThreadActionTypes, + removeUserFromThreadServerCall({ + threadID: threadInfo.id, + memberIDs: [memberInfo.id], + }), + { customKeyName }, + ); +} + +type CreateRealThreadParameters = { + +threadInfo: ThreadInfo, + +dispatchActionPromise: DispatchActionPromise, + +createNewThread: ClientNewThreadRequest => Promise, + +sourceMessageID: ?string, + +viewerID: ?string, + +handleError?: () => mixed, + +calendarQuery: CalendarQuery, +}; + +async function createRealThreadFromPendingThread({ + threadInfo, + dispatchActionPromise, + createNewThread, + sourceMessageID, + viewerID, + calendarQuery, +}: CreateRealThreadParameters): Promise { + if (!threadIsPending(threadInfo.id)) { + return threadInfo.id; + } + + const otherMemberIDs = threadOtherMembers(threadInfo.members, viewerID).map( + member => member.id, + ); + let resultPromise; + if (threadInfo.type !== threadTypes.SIDEBAR) { + invariant( + otherMemberIDs.length > 0, + 'otherMemberIDs should not be empty for threads', + ); + resultPromise = createNewThread({ + type: pendingThreadType(otherMemberIDs.length), + initialMemberIDs: otherMemberIDs, + color: threadInfo.color, + calendarQuery, + }); + } else { + invariant( + sourceMessageID, + 'sourceMessageID should be set when creating a sidebar', + ); + resultPromise = createNewThread({ + type: threadTypes.SIDEBAR, + initialMemberIDs: otherMemberIDs, + color: threadInfo.color, + sourceMessageID, + parentThreadID: threadInfo.parentThreadID, + name: threadInfo.name, + calendarQuery, + }); + } + void dispatchActionPromise(newThreadActionTypes, resultPromise); + const { newThreadID } = await resultPromise; + return newThreadID; +} + +export { removeMemberFromThread, createRealThreadFromPendingThread }; diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js --- a/lib/shared/thread-utils.js +++ b/lib/shared/thread-utils.js @@ -14,11 +14,6 @@ import { getMessageTitle, isInvalidSidebarSource } from './message-utils.js'; import { relationshipBlockedInEitherDirection } from './relationship-utils.js'; import { useForwardLookupSearchText, useSearchUsers } from './search-utils.js'; -import type { RemoveUsersFromThreadInput } from '../actions/thread-actions'; -import { - newThreadActionTypes, - removeUsersFromThreadActionTypes, -} from '../actions/thread-actions.js'; import { searchUsers as searchUserCall } from '../actions/user-actions.js'; import ashoat from '../facts/ashoat.js'; import genesis from '../facts/genesis.js'; @@ -52,7 +47,6 @@ getRelativeMemberInfos, usersWithPersonalThreadSelector, } from '../selectors/user-selectors.js'; -import type { CalendarQuery } from '../types/entry-types.js'; import { messageTypes } from '../types/message-types-enum.js'; import { type RobotextMessageInfo, @@ -95,9 +89,6 @@ ClientLegacyRoleInfo, ServerThreadInfo, ServerMemberInfo, - ClientNewThreadRequest, - NewThreadResult, - ChangeThreadSettingsPayload, UserProfileThreadInfo, MixedRawThreadInfos, LegacyMemberInfo, @@ -121,7 +112,6 @@ } from '../utils/entity-text.js'; import type { GetFCNames } from '../utils/farcaster-helpers.js'; import { entries, values } from '../utils/objects.js'; -import type { DispatchActionPromise } from '../utils/redux-promise-utils.js'; import { useSelector } from '../utils/redux-utils.js'; import { usingCommServicesAccessToken } from '../utils/services-utils.js'; import { firstLine } from '../utils/string-utils.js'; @@ -746,63 +736,6 @@ ); } -type CreateRealThreadParameters = { - +threadInfo: ThreadInfo, - +dispatchActionPromise: DispatchActionPromise, - +createNewThread: ClientNewThreadRequest => Promise, - +sourceMessageID: ?string, - +viewerID: ?string, - +handleError?: () => mixed, - +calendarQuery: CalendarQuery, -}; - -async function createRealThreadFromPendingThread({ - threadInfo, - dispatchActionPromise, - createNewThread, - sourceMessageID, - viewerID, - calendarQuery, -}: CreateRealThreadParameters): Promise { - if (!threadIsPending(threadInfo.id)) { - return threadInfo.id; - } - - const otherMemberIDs = threadOtherMembers(threadInfo.members, viewerID).map( - member => member.id, - ); - let resultPromise; - if (threadInfo.type !== threadTypes.SIDEBAR) { - invariant( - otherMemberIDs.length > 0, - 'otherMemberIDs should not be empty for threads', - ); - resultPromise = createNewThread({ - type: pendingThreadType(otherMemberIDs.length), - initialMemberIDs: otherMemberIDs, - color: threadInfo.color, - calendarQuery, - }); - } else { - invariant( - sourceMessageID, - 'sourceMessageID should be set when creating a sidebar', - ); - resultPromise = createNewThread({ - type: threadTypes.SIDEBAR, - initialMemberIDs: otherMemberIDs, - color: threadInfo.color, - sourceMessageID, - parentThreadID: threadInfo.parentThreadID, - name: threadInfo.name, - calendarQuery, - }); - } - void dispatchActionPromise(newThreadActionTypes, resultPromise); - const { newThreadID } = await resultPromise; - return newThreadID; -} - type RawThreadInfoOptions = { +filterThreadEditAvatarPermission?: boolean, +excludePinInfo?: boolean, @@ -1619,25 +1552,6 @@ return { threadSearchResults, usersSearchResults }; } -function removeMemberFromThread( - threadInfo: ThreadInfo, - memberInfo: RelativeMemberInfo, - dispatchActionPromise: DispatchActionPromise, - removeUserFromThreadServerCall: ( - input: RemoveUsersFromThreadInput, - ) => Promise, -) { - const customKeyName = `${removeUsersFromThreadActionTypes.started}:${memberInfo.id}`; - void dispatchActionPromise( - removeUsersFromThreadActionTypes, - removeUserFromThreadServerCall({ - threadID: threadInfo.id, - memberIDs: [memberInfo.id], - }), - { customKeyName }, - ); -} - function useAvailableThreadMemberActions( memberInfo: RelativeMemberInfo, threadInfo: ThreadInfo, @@ -1938,7 +1852,6 @@ extractNewMentionedParentMembers, createPendingSidebar, pendingThreadType, - createRealThreadFromPendingThread, filterOutDisabledPermissions, getCurrentUser, threadFrozenDueToBlock, @@ -1969,7 +1882,6 @@ getCommunity, getThreadListSearchResults, useThreadListSearch, - removeMemberFromThread, useAvailableThreadMemberActions, threadMembersWithoutAddedAdmin, patchThreadInfoToIncludeMentionedMembersOfParent, diff --git a/native/chat/settings/thread-settings-member-tooltip-modal.react.js b/native/chat/settings/thread-settings-member-tooltip-modal.react.js --- a/native/chat/settings/thread-settings-member-tooltip-modal.react.js +++ b/native/chat/settings/thread-settings-member-tooltip-modal.react.js @@ -3,7 +3,7 @@ import * as React from 'react'; import { useRemoveUsersFromThread } from 'lib/actions/thread-actions.js'; -import { removeMemberFromThread } from 'lib/shared/thread-utils.js'; +import { removeMemberFromThread } from 'lib/shared/thread-actions-utils.js'; import { stringForUser } from 'lib/shared/user-utils.js'; import type { RelativeMemberInfo, 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 @@ -50,8 +50,8 @@ getNextLocalID, } from 'lib/shared/message-utils.js'; import type { CreationSideEffectsFunc } from 'lib/shared/messages/message-spec.js'; +import { createRealThreadFromPendingThread } from 'lib/shared/thread-actions-utils.js'; import { - createRealThreadFromPendingThread, patchThreadInfoToIncludeMentionedMembersOfParent, threadInfoInsideCommunity, threadIsPending, 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 @@ -51,8 +51,8 @@ getNextLocalID, } from 'lib/shared/message-utils.js'; import type { CreationSideEffectsFunc } from 'lib/shared/messages/message-spec.js'; +import { createRealThreadFromPendingThread } from 'lib/shared/thread-actions-utils.js'; import { - createRealThreadFromPendingThread, draftKeyFromThreadID, patchThreadInfoToIncludeMentionedMembersOfParent, threadInfoInsideCommunity, diff --git a/web/modals/threads/members/member.react.js b/web/modals/threads/members/member.react.js --- a/web/modals/threads/members/member.react.js +++ b/web/modals/threads/members/member.react.js @@ -5,10 +5,8 @@ import { useRemoveUsersFromThread } from 'lib/actions/thread-actions.js'; import { useModalContext } from 'lib/components/modal-provider.react.js'; import SWMansionIcon from 'lib/components/swmansion-icon.react.js'; -import { - removeMemberFromThread, - useAvailableThreadMemberActions, -} from 'lib/shared/thread-utils.js'; +import { removeMemberFromThread } from 'lib/shared/thread-actions-utils.js'; +import { useAvailableThreadMemberActions } from 'lib/shared/thread-utils.js'; import { stringForUser } from 'lib/shared/user-utils.js'; import type { SetState } from 'lib/types/hook-types.js'; import type {