diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js --- a/lib/actions/user-actions.js +++ b/lib/actions/user-actions.js @@ -31,13 +31,10 @@ getPrekeyValueFromBlob, } from '../shared/crypto-utils.js'; import { fetchLatestDeviceList } from '../shared/device-list-utils.js'; -import { - type OutboundDMOperationSpecification, - dmOperationSpecificationTypes, -} from '../shared/dm-ops/dm-op-types.js'; import { useProcessAndSendDMOperation } from '../shared/dm-ops/process-dm-ops.js'; import { IdentityClientContext } from '../shared/identity-client-context.js'; import threadWatcher from '../shared/thread-watcher.js'; +import { threadSpecs } from '../shared/threads/thread-specs.js'; import { permissionsAndAuthRelatedRequestTimeout, callIdentityServiceTimeout, @@ -67,7 +64,6 @@ UpdateUserAvatarRequest, UpdateUserAvatarResponse, } from '../types/avatar-types.js'; -import type { DMChangeThreadSubscriptionOperation } from '../types/dm-ops'; import type { RawEntryInfo, CalendarQuery } from '../types/entry-types.js'; import type { IdentityAuthResult } from '../types/identity-service-types.js'; import type { @@ -85,10 +81,6 @@ SubscriptionUpdateRequest, SubscriptionUpdateResult, } from '../types/subscription-types.js'; -import { - thickThreadTypes, - threadTypeIsThick, -} from '../types/thread-types-enum.js'; import type { RawThreadInfos } from '../types/thread-types.js'; import { userActionsP2PMessageTypes, @@ -1302,7 +1294,7 @@ }; }; -type UseUpdateSubscriptionInput = $ReadOnly<{ +export type UseUpdateSubscriptionInput = $ReadOnly<{ +threadInfo: ThreadInfo, ...SubscriptionUpdateRequest, }>; @@ -1316,44 +1308,14 @@ const keyserverCall = useKeyserverCall(updateSubscription); return React.useCallback( - async (input: UseUpdateSubscriptionInput) => { - if (!threadTypeIsThick(input.threadInfo.type)) { - const { threadInfo, ...rest } = input; - return await keyserverCall({ ...rest }); - } - - invariant(viewerID, 'viewerID must be set'); - - const { threadInfo, updatedFields } = input; - const subscription = { - ...threadInfo.currentUser.subscription, - ...updatedFields, - }; - - const op: DMChangeThreadSubscriptionOperation = { - type: 'change_thread_subscription', - time: Date.now(), - threadID: threadInfo.id, - creatorID: viewerID, - subscription, - }; - - 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: UseUpdateSubscriptionInput) => + threadSpecs[input.threadInfo.type].protocol.updateSubscription( + { input, viewerID }, + { + processAndSendDMOperation, + keyserverUpdateSubscription: keyserverCall, }, - }; - - await processAndSendDMOperation(opSpecification); - return { threadID: threadInfo.id, subscription }; - }, + ), [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 @@ -7,6 +7,7 @@ import type { DMChangeThreadReadStatusOperation, DMChangeThreadSettingsOperation, + DMChangeThreadSubscriptionOperation, DMCreateEntryOperation, DMDeleteEntryOperation, DMEditEntryOperation, @@ -45,6 +46,8 @@ SendReactionUtils, AddThreadMembersUtils, ProtocolAddThreadMembersInput, + ProtocolUpdateSubscriptionInput, + UpdateSubscriptionUtils, } from '../thread-spec.js'; const dmThreadProtocol: ThreadProtocol = Object.freeze({ @@ -478,6 +481,44 @@ utils: AddThreadMembersUtils, ) => utils.dmAddThreadMembers(input.newMemberIDs, input.threadInfo), + updateSubscription: async ( + protocolInput: ProtocolUpdateSubscriptionInput, + utils: UpdateSubscriptionUtils, + ) => { + const { viewerID, input } = protocolInput; + invariant(viewerID, 'viewerID must be set'); + + const { threadInfo, updatedFields } = input; + const subscription = { + ...threadInfo.currentUser.subscription, + ...updatedFields, + }; + + const op: DMChangeThreadSubscriptionOperation = { + type: 'change_thread_subscription', + time: Date.now(), + threadID: threadInfo.id, + creatorID: viewerID, + subscription, + }; + + 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, subscription }; + }, + allowsDeletingSidebarSource: false, presentationDetails: { 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 @@ -67,6 +67,8 @@ SendReactionUtils, AddThreadMembersUtils, ProtocolAddThreadMembersInput, + ProtocolUpdateSubscriptionInput, + UpdateSubscriptionUtils, } from '../thread-spec.js'; const keyserverThreadProtocol: ThreadProtocol = Object.freeze({ @@ -316,6 +318,14 @@ await addMembersPromise; }, + updateSubscription: ( + protocolInput: ProtocolUpdateSubscriptionInput, + utils: UpdateSubscriptionUtils, + ) => { + const { threadInfo, ...rest } = protocolInput.input; + return utils.keyserverUpdateSubscription(rest); + }, + allowsDeletingSidebarSource: true, presentationDetails: { 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 @@ -15,6 +15,7 @@ type SendTextMessageInput, } from '../../actions/message-actions.js'; import { type MediaMetadataReassignmentAction } from '../../actions/upload-actions.js'; +import type { UseUpdateSubscriptionInput } from '../../actions/user-actions.js'; import type { UseChangeThreadSettingsInput } from '../../hooks/thread-hooks.js'; import type { ProcessOutboundP2PMessagesResult } from '../../tunnelbroker/peer-to-peer-context.js'; import type { TunnelbrokerSocketState } from '../../tunnelbroker/tunnelbroker-context.js'; @@ -46,6 +47,10 @@ ThreadInfo, } from '../../types/minimally-encoded-thread-permissions-types.js'; import type { Dispatch } from '../../types/redux-types.js'; +import type { + SubscriptionUpdateRequest, + SubscriptionUpdateResult, +} from '../../types/subscription-types.js'; import type { ThreadType } from '../../types/thread-types-enum.js'; import type { ChangeThreadSettingsPayload, @@ -177,6 +182,15 @@ +dispatchActionPromise: DispatchActionPromise, }; +export type ProtocolUpdateSubscriptionInput = { + +input: UseUpdateSubscriptionInput, + +viewerID: ?string, +}; +export type UpdateSubscriptionUtils = { + +processAndSendDMOperation: OutboundDMOperationSpecification => Promise, + +keyserverUpdateSubscription: SubscriptionUpdateRequest => Promise, +}; + export type ThreadProtocol = { +sendTextMessage: ( message: ProtocolSendTextMessageInput, @@ -223,6 +237,10 @@ input: ProtocolAddThreadMembersInput, utils: AddThreadMembersUtils, ) => Promise, + +updateSubscription: ( + input: ProtocolUpdateSubscriptionInput, + utils: UpdateSubscriptionUtils, + ) => Promise, +allowsDeletingSidebarSource: boolean, +presentationDetails: { +membershipChangesShownInThreadPreview: boolean,