diff --git a/lib/actions/thread-actions.js b/lib/actions/thread-actions.js --- a/lib/actions/thread-actions.js +++ b/lib/actions/thread-actions.js @@ -14,12 +14,9 @@ } from '../shared/dm-ops/dm-op-types.js'; import { getCreateThickRawThreadInfoInputFromThreadInfo } from '../shared/dm-ops/dm-op-utils.js'; import { useProcessAndSendDMOperation } from '../shared/dm-ops/process-dm-ops.js'; +import { threadSpecs } from '../shared/threads/thread-specs.js'; import { permissionsAndAuthRelatedRequestTimeout } from '../shared/timeouts.js'; -import type { - DMChangeThreadSettingsOperation, - DMThreadSettingsChanges, - DMJoinThreadOperation, -} from '../types/dm-ops.js'; +import type { DMJoinThreadOperation } from '../types/dm-ops.js'; import type { ThreadInfo, RawThreadInfo, @@ -141,78 +138,14 @@ const keyserverCall = useKeyserverCall(changeThreadSettings); return React.useCallback( - async (input: UseChangeThreadSettingsInput) => { - if (!input.thick) { - const { thick, threadInfo, ...rest } = input; - return await keyserverCall({ ...rest }); - } - - invariant(viewerID, 'viewerID should be set'); - - const changes: { ...DMThreadSettingsChanges } = {}; - if (input.changes.name) { - changes.name = input.changes.name; - } - if (input.changes.description) { - changes.description = input.changes.description; - } - if (input.changes.color) { - changes.color = input.changes.color; - } - if (input.changes.avatar && input.changes.avatar.type === 'emoji') { - changes.avatar = { - type: 'emoji', - emoji: input.changes.avatar.emoji, - color: input.changes.avatar.color, - }; - } else if (input.changes.avatar && input.changes.avatar.type === 'ens') { - changes.avatar = { type: 'ens' }; - } else if ( - input.changes.avatar && - input.changes.avatar.type === 'non_keyserver_image' - ) { - changes.avatar = { - type: 'encrypted_image', - blobURI: input.changes.avatar.blobURI, - thumbHash: input.changes.avatar.thumbHash, - encryptionKey: input.changes.avatar.encryptionKey, - }; - } else if ( - input.changes.avatar && - input.changes.avatar.type === 'remove' - ) { - changes.avatar = null; - } - - const { threadInfo } = input; - const op: DMChangeThreadSettingsOperation = { - type: 'change_thread_settings', - threadID: threadInfo.id, - editorID: viewerID, - time: Date.now(), - changes, - messageIDsPrefix: uuid.v4(), - }; - const opSpecification: OutboundDMOperationSpecification = { - type: dmOperationSpecificationTypes.OUTBOUND, - op, - recipients: { - type: 'all_thread_members', - threadID: - threadInfo.type === thickThreadTypes.THICK_SIDEBAR && - threadInfo.parentThreadID - ? threadInfo.parentThreadID - : threadInfo.id, + async (input: UseChangeThreadSettingsInput) => + threadSpecs[input.threadInfo.type].protocol.changeThreadSettings( + { input, viewerID }, + { + processAndSendDMOperation, + keyserverChangeThreadSettings: keyserverCall, }, - }; - - await processAndSendDMOperation(opSpecification); - return ({ - threadID: threadInfo.id, - updatesResult: { newUpdates: [] }, - newMessageInfos: [], - }: ChangeThreadSettingsPayload); - }, + ), [keyserverCall, processAndSendDMOperation, viewerID], ); } diff --git a/lib/shared/threads/protocols/dm-thread-protocol.js b/lib/shared/threads/protocols/dm-thread-protocol.js --- a/lib/shared/threads/protocols/dm-thread-protocol.js +++ b/lib/shared/threads/protocols/dm-thread-protocol.js @@ -3,8 +3,13 @@ import invariant from 'invariant'; import uuid from 'uuid'; -import type { DMSendEditMessageOperation } from '../../../types/dm-ops.js'; +import type { + DMChangeThreadSettingsOperation, + DMSendEditMessageOperation, + DMThreadSettingsChanges, +} from '../../../types/dm-ops.js'; import { thickThreadTypes } from '../../../types/thread-types-enum.js'; +import type { ChangeThreadSettingsPayload } from '../../../types/thread-types.js'; import { SendMessageError } from '../../../utils/errors.js'; import { dmOperationSpecificationTypes, @@ -18,6 +23,8 @@ type ProtocolSendMultimediaMessageInput, type ProtocolEditTextMessageInput, type EditTextMessageUtils, + type ProtocolChangeThreadSettingsInput, + type ChangeThreadSettingsUtils, } from '../thread-spec.js'; const dmThreadProtocol: ThreadProtocol = Object.freeze({ @@ -163,6 +170,75 @@ }; await utils.processAndSendDMOperation(opSpecification); }, + + changeThreadSettings: async ( + protocolInput: ProtocolChangeThreadSettingsInput, + utils: ChangeThreadSettingsUtils, + ) => { + const { viewerID, input } = protocolInput; + invariant(viewerID, 'viewerID should be set'); + + const changes: { ...DMThreadSettingsChanges } = {}; + if (input.changes.name) { + changes.name = input.changes.name; + } + if (input.changes.description) { + changes.description = input.changes.description; + } + if (input.changes.color) { + changes.color = input.changes.color; + } + if (input.changes.avatar && input.changes.avatar.type === 'emoji') { + changes.avatar = { + type: 'emoji', + emoji: input.changes.avatar.emoji, + color: input.changes.avatar.color, + }; + } else if (input.changes.avatar && input.changes.avatar.type === 'ens') { + changes.avatar = { type: 'ens' }; + } else if ( + input.changes.avatar && + input.changes.avatar.type === 'non_keyserver_image' + ) { + changes.avatar = { + type: 'encrypted_image', + blobURI: input.changes.avatar.blobURI, + thumbHash: input.changes.avatar.thumbHash, + encryptionKey: input.changes.avatar.encryptionKey, + }; + } else if (input.changes.avatar && input.changes.avatar.type === 'remove') { + changes.avatar = null; + } + + const { threadInfo } = input; + const op: DMChangeThreadSettingsOperation = { + type: 'change_thread_settings', + threadID: threadInfo.id, + editorID: viewerID, + time: Date.now(), + changes, + messageIDsPrefix: uuid.v4(), + }; + const opSpecification: OutboundDMOperationSpecification = { + type: dmOperationSpecificationTypes.OUTBOUND, + op, + recipients: { + type: 'all_thread_members', + threadID: + threadInfo.type === thickThreadTypes.THICK_SIDEBAR && + threadInfo.parentThreadID + ? threadInfo.parentThreadID + : threadInfo.id, + }, + }; + + await utils.processAndSendDMOperation(opSpecification); + return ({ + threadID: threadInfo.id, + updatesResult: { newUpdates: [] }, + newMessageInfos: [], + }: ChangeThreadSettingsPayload); + }, }); export { dmThreadProtocol }; diff --git a/lib/shared/threads/protocols/keyserver-thread-protocol.js b/lib/shared/threads/protocols/keyserver-thread-protocol.js --- a/lib/shared/threads/protocols/keyserver-thread-protocol.js +++ b/lib/shared/threads/protocols/keyserver-thread-protocol.js @@ -38,6 +38,8 @@ type SendMultimediaMessageUtils, type ProtocolEditTextMessageInput, type EditTextMessageUtils, + type ProtocolChangeThreadSettingsInput, + type ChangeThreadSettingsUtils, } from '../thread-spec.js'; const keyserverThreadProtocol: ThreadProtocol = Object.freeze({ @@ -161,6 +163,14 @@ await editMessagePromise; }, + + changeThreadSettings: async ( + protocolInput: ProtocolChangeThreadSettingsInput, + utils: ChangeThreadSettingsUtils, + ) => { + const { thick, threadInfo, ...rest } = protocolInput.input; + return await utils.keyserverChangeThreadSettings({ ...rest }); + }, }); function mediaIDIsKeyserverID(mediaID: string): boolean { diff --git a/lib/shared/threads/thread-spec.js b/lib/shared/threads/thread-spec.js --- a/lib/shared/threads/thread-spec.js +++ b/lib/shared/threads/thread-spec.js @@ -6,6 +6,7 @@ type SendMultimediaMessageInput, type SendTextMessageInput, } from '../../actions/message-actions.js'; +import type { UseChangeThreadSettingsInput } from '../../actions/thread-actions.js'; import { type MediaMetadataReassignmentAction } from '../../actions/upload-actions.js'; import type { ProcessOutboundP2PMessagesResult } from '../../tunnelbroker/peer-to-peer-context.js'; import type { @@ -22,6 +23,10 @@ ThreadInfo, } from '../../types/minimally-encoded-thread-permissions-types.js'; import type { Dispatch } from '../../types/redux-types.js'; +import type { + ChangeThreadSettingsPayload, + UpdateThreadRequest, +} from '../../types/thread-types.js'; import type { DispatchActionPromise } from '../../utils/redux-promise-utils.js'; import type { OutboundComposableDMOperationSpecification, @@ -74,6 +79,15 @@ +processAndSendDMOperation: OutboundDMOperationSpecification => Promise, }; +export type ProtocolChangeThreadSettingsInput = { + +input: UseChangeThreadSettingsInput, + +viewerID: ?string, +}; +export type ChangeThreadSettingsUtils = { + +processAndSendDMOperation: OutboundDMOperationSpecification => Promise, + +keyserverChangeThreadSettings: UpdateThreadRequest => Promise, +}; + export type ThreadProtocol = { +sendTextMessage: ( message: ProtocolSendTextMessageInput, @@ -87,6 +101,10 @@ message: ProtocolEditTextMessageInput, utils: EditTextMessageUtils, ) => Promise, + +changeThreadSettings: ( + input: ProtocolChangeThreadSettingsInput, + utils: ChangeThreadSettingsUtils, + ) => Promise, }; export type ThreadSpec = {