diff --git a/lib/shared/dm-ops/create-sidebar-spec.js b/lib/shared/dm-ops/create-sidebar-spec.js --- a/lib/shared/dm-ops/create-sidebar-spec.js +++ b/lib/shared/dm-ops/create-sidebar-spec.js @@ -7,7 +7,6 @@ DMOperationSpec, ProcessDMOperationUtilities, } from './dm-op-spec.js'; -import { isInvalidSidebarSource } from '../../shared/message-utils.js'; import type { DMCreateSidebarOperation } from '../../types/dm-ops.js'; import { messageTypes } from '../../types/message-types-enum.js'; import { @@ -16,6 +15,7 @@ } from '../../types/message-types.js'; import { threadTypes } from '../../types/thread-types-enum.js'; import { updateTypes } from '../../types/update-types-enum.js'; +import { isInvalidSidebarSource } from '../message-utils.js'; const createSidebarSpec: DMOperationSpec = Object.freeze({ @@ -37,19 +37,20 @@ } = dmOperation; const allMemberIDs = [creatorID, ...memberIDs]; - const rawThreadInfo = createThickRawThreadInfo({ - threadID, - threadType: threadTypes.THICK_SIDEBAR, - creationTime: time, - parentThreadID, - allMemberIDs, - roleID, - creatorID, + const rawThreadInfo = createThickRawThreadInfo( + { + threadID, + threadType: threadTypes.THICK_SIDEBAR, + creationTime: time, + parentThreadID, + allMemberIDs, + roleID, + creatorID, + sourceMessageID, + containingThreadID: parentThreadID, + }, viewerID, - }); - - rawThreadInfo.sourceMessageID = sourceMessageID; - rawThreadInfo.containingThreadID = parentThreadID; + ); const sourceMessage = await utilities.fetchMessage(sourceMessageID); if (!sourceMessage) { diff --git a/lib/shared/dm-ops/create-thread-spec.js b/lib/shared/dm-ops/create-thread-spec.js --- a/lib/shared/dm-ops/create-thread-spec.js +++ b/lib/shared/dm-ops/create-thread-spec.js @@ -9,8 +9,10 @@ makePermissionsBlob, getThickThreadRolePermissionsBlob, } from '../../permissions/thread-permissions.js'; -import { generatePendingThreadColor } from '../../shared/color-utils.js'; -import type { DMCreateThreadOperation } from '../../types/dm-ops.js'; +import type { + CreateThickRawThreadInfoInput, + DMCreateThreadOperation, +} from '../../types/dm-ops.js'; import { messageTypes } from '../../types/message-types-enum.js'; import { type RawMessageInfo, @@ -24,23 +26,14 @@ minimallyEncodeThreadCurrentUserInfo, } from '../../types/minimally-encoded-thread-permissions-types.js'; import { joinThreadSubscription } from '../../types/subscription-types.js'; -import type { ThickThreadType } from '../../types/thread-types-enum.js'; import type { ThickMemberInfo } from '../../types/thread-types.js'; import { updateTypes } from '../../types/update-types-enum.js'; +import { generatePendingThreadColor } from '../color-utils.js'; -type CreateThickRawThreadInfoInput = { - +threadID: string, - +threadType: ThickThreadType, - +creationTime: number, - +parentThreadID?: ?string, - +allMemberIDs: $ReadOnlyArray, - +roleID: string, - +creatorID: string, - +viewerID: string, -}; type MutableThickRawThreadInfo = { ...ThickRawThreadInfo }; function createThickRawThreadInfo( input: CreateThickRawThreadInfoInput, + viewerID: string, ): MutableThickRawThreadInfo { const { threadID, @@ -50,10 +43,17 @@ allMemberIDs, roleID, creatorID, - viewerID, + name, + avatar, + description, + color, + containingThreadID, + sourceMessageID, + repliesCount, + pinnedCount, } = input; - const color = generatePendingThreadColor(allMemberIDs); + const threadColor = color ?? generatePendingThreadColor(allMemberIDs); const rolePermissions = getThickThreadRolePermissionsBlob(threadType); const membershipPermissions = getAllThreadPermissions( @@ -70,12 +70,12 @@ specialRole: specialRoles.DEFAULT_ROLE, }; - return { + const newThread: MutableThickRawThreadInfo = { thick: true, minimallyEncoded: true, id: threadID, type: threadType, - color, + color: threadColor, creationTime, parentThreadID, members: allMemberIDs.map(memberID => @@ -96,8 +96,19 @@ subscription: joinThreadSubscription, unread: creatorID !== viewerID, }), - repliesCount: 0, + repliesCount: repliesCount ?? 0, + name, + avatar, + description, + containingThreadID, }; + if (sourceMessageID) { + newThread.sourceMessageID = sourceMessageID; + } + if (pinnedCount) { + newThread.pinnedCount = pinnedCount; + } + return newThread; } const createThreadSpec: DMOperationSpec = @@ -117,15 +128,17 @@ } = dmOperation; const allMemberIDs = [creatorID, ...memberIDs]; - const rawThreadInfo = createThickRawThreadInfo({ - threadID, - threadType, - creationTime: time, - allMemberIDs, - roleID, - creatorID, + const rawThreadInfo = createThickRawThreadInfo( + { + threadID, + threadType, + creationTime: time, + allMemberIDs, + roleID, + creatorID, + }, viewerID, - }); + ); const rawMessageInfos: Array = [ { 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 @@ -3,11 +3,15 @@ import type { TInterface, TUnion } from 'tcomb'; import t from 'tcomb'; +import type { ClientAvatar } from './avatar-types.js'; +import { clientAvatarValidator } from './avatar-types.js'; import type { RawMessageInfo } from './message-types.js'; import type { OutboundP2PMessage } from './sqlite-types.js'; import { type NonSidebarThickThreadType, nonSidebarThickThreadTypes, + type ThickThreadType, + thickThreadTypeValidator, } from './thread-types-enum.js'; import type { ClientUpdateInfo } from './update-types.js'; import { values } from '../utils/objects.js'; @@ -22,6 +26,42 @@ }); export type DMOperationType = $Values; +export type CreateThickRawThreadInfoInput = { + +threadID: string, + +threadType: ThickThreadType, + +creationTime: number, + +parentThreadID?: ?string, + +allMemberIDs: $ReadOnlyArray, + +roleID: string, + +creatorID: string, + +name?: ?string, + +avatar?: ?ClientAvatar, + +description?: ?string, + +color?: ?string, + +containingThreadID?: ?string, + +sourceMessageID?: ?string, + +repliesCount?: ?number, + +pinnedCount?: ?number, +}; +export const createThickRawThreadInfoInputValidator: TInterface = + tShape({ + threadID: t.String, + threadType: thickThreadTypeValidator, + creationTime: t.Number, + parentThreadID: t.maybe(t.String), + allMemberIDs: t.list(tUserID), + roleID: t.String, + creatorID: tUserID, + name: t.maybe(t.String), + avatar: t.maybe(clientAvatarValidator), + description: t.maybe(t.String), + color: t.maybe(t.String), + containingThreadID: t.maybe(t.String), + sourceMessageID: t.maybe(t.String), + repliesCount: t.maybe(t.Number), + pinnedCount: t.maybe(t.Number), + }); + export type DMCreateThreadOperation = { +type: 'create_thread', +threadID: string, diff --git a/lib/types/thread-types-enum.js b/lib/types/thread-types-enum.js --- a/lib/types/thread-types-enum.js +++ b/lib/types/thread-types-enum.js @@ -105,6 +105,9 @@ ); return threadType; } +export const thickThreadTypeValidator: TRefinement = tNumEnum( + values(thickThreadTypes), +); export function assertThreadType(threadType: number): ThreadType { invariant(