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 @@ -483,6 +483,7 @@ possiblePendingThreadTypes = [ threadTypes.LOCAL, threadTypes.COMMUNITY_SECRET_SUBTHREAD, + threadTypes.FARCASTER_GROUP, ]; } 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 @@ -624,7 +624,9 @@ threadType === threadTypes.PERSONAL || threadType === threadTypes.LOCAL || threadType === threadTypes.THICK_SIDEBAR || - threadType === threadTypes.PRIVATE + threadType === threadTypes.PRIVATE || + threadType === threadTypes.FARCASTER_GROUP || + threadType === threadTypes.FARCASTER_PERSONAL ); } diff --git a/lib/shared/threads/protocols/farcaster-thread-protocol.js b/lib/shared/threads/protocols/farcaster-thread-protocol.js --- a/lib/shared/threads/protocols/farcaster-thread-protocol.js +++ b/lib/shared/threads/protocols/farcaster-thread-protocol.js @@ -24,11 +24,14 @@ ThreadCurrentUserInfo, ThreadInfo, } from '../../../types/minimally-encoded-thread-permissions-types.js'; +import { minimallyEncodeThreadCurrentUserInfo } from '../../../types/minimally-encoded-thread-permissions-types.js'; import type { SubscriptionUpdateResult } from '../../../types/subscription-types.js'; +import { defaultThreadSubscription } from '../../../types/subscription-types.js'; import type { ThreadType } from '../../../types/thread-types-enum.js'; import { assertFarcasterThreadType, farcasterThreadTypes, + threadTypes, } from '../../../types/thread-types-enum.js'; import type { ChangeThreadSettingsPayload, @@ -41,13 +44,17 @@ import { convertFarcasterMessageToCommMessages } from '../../../utils/convert-farcaster-message-to-comm-messages.js'; import { createFarcasterRawThreadInfo } from '../../../utils/create-farcaster-raw-thread-info.js'; import { farcasterThreadIDRegExp } from '../../../utils/validation-utils.js'; +import { generatePendingThreadColor } from '../../color-utils.js'; import { farcasterMessageValidator } from '../../farcaster/farcaster-messages-types.js'; import { conversationIDFromFarcasterThreadID, userIDFromFID, } from '../../id-utils.js'; import { messageNotifyTypes } from '../../messages/message-spec.js'; -import { getSingleOtherUser } from '../../thread-utils.js'; +import { + getContainingThreadID, + getSingleOtherUser, +} from '../../thread-utils.js'; import type { ChangeThreadSettingsUtils, ProtocolChangeThreadSettingsInput, @@ -62,6 +69,7 @@ OnOpenThreadUtils, ProtocolOnOpenThreadInput, UpdateSubscriptionUtils, + ProtocolCreatePendingThreadInput, } from '../thread-spec.js'; const farcasterThreadProtocol: ThreadProtocol = { @@ -355,8 +363,57 @@ await promise; }, - createPendingThread: (): RawThreadInfo => { - throw new Error('createPendingThread method is not yet implemented'); + createPendingThread: ( + input: ProtocolCreatePendingThreadInput, + ): RawThreadInfo => { + const { + threadID, + creationTime, + membershipPermissions, + role, + memberIDs, + createPendingThreadArgs: { + threadType, + name, + threadColor, + parentThreadInfo, + members, + }, + } = input; + const farcasterThreadType = assertFarcasterThreadType(threadType); + return { + minimallyEncoded: true, + farcaster: true, + id: threadID, + type: farcasterThreadType, + name: name ?? null, + description: null, + color: threadColor ?? generatePendingThreadColor(memberIDs), + community: null, + creationTime, + parentThreadID: parentThreadInfo?.id ?? null, + containingThreadID: getContainingThreadID( + parentThreadInfo, + farcasterThreadType, + ), + members: members.map(member => ({ + id: member.id, + role: role.id, + minimallyEncoded: true, + isSender: false, + })), + roles: { + [role.id]: role, + }, + currentUser: minimallyEncodeThreadCurrentUserInfo({ + role: role.id, + permissions: membershipPermissions, + subscription: defaultThreadSubscription, + unread: false, + }), + repliesCount: 0, + pinnedCount: 0, + }; }, couldBeCreatedFromPendingThread: () => true, @@ -365,9 +422,7 @@ return thread.type === farcasterThreadTypes.FARCASTER_PERSONAL; }, - pendingThreadType: (): ThreadType => { - throw new Error('pendingThreadType method is not yet implemented'); - }, + pendingThreadType, createRealThreadFromPendingThread: async (): Promise<{ +threadID: string, @@ -435,4 +490,16 @@ supportsBackgroundNotifs: false, }; +function pendingThreadType(numberOfOtherMembers: number) { + invariant( + numberOfOtherMembers > 0, + 'Farcaster protocol does not support private thread type', + ); + if (numberOfOtherMembers === 1) { + return threadTypes.FARCASTER_PERSONAL; + } else { + return threadTypes.FARCASTER_GROUP; + } +} + export { farcasterThreadProtocol };