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 @@ -26,6 +26,9 @@ getPrekeyValueFromBlob, } from '../shared/crypto-utils.js'; import { fetchLatestDeviceList } from '../shared/device-list-utils.js'; +import type { OutboundDMOperationSpecification } from '../shared/dm-ops/dm-op-utils'; +import { dmOperationSpecificationTypes } from '../shared/dm-ops/dm-op-utils.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 { @@ -54,6 +57,7 @@ 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 { UserIdentitiesResponse, @@ -63,6 +67,7 @@ RawMessageInfo, MessageTruncationStatuses, } from '../types/message-types.js'; +import type { ThreadInfo } from '../types/minimally-encoded-thread-permissions-types'; import type { GetOlmSessionInitializationDataResponse } from '../types/olm-session-types.js'; import type { UserSearchResult, @@ -73,6 +78,10 @@ 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, @@ -1200,10 +1209,52 @@ }; }; -function useUpdateSubscription(): ( - input: SubscriptionUpdateRequest, -) => Promise { - return useKeyserverCall(updateSubscription); +function useUpdateSubscription( + threadInfo: ThreadInfo, +): (input: SubscriptionUpdateRequest) => Promise { + const processAndSendDMOperation = useProcessAndSendDMOperation(); + const viewerID = useSelector( + state => state.currentUserInfo && state.currentUserInfo.id, + ); + const keyserverCall = useKeyserverCall(updateSubscription); + + return React.useCallback( + async (input: SubscriptionUpdateRequest) => { + if (!threadTypeIsThick(threadInfo.type)) { + return await keyserverCall(input); + } + + invariant(viewerID, 'viewerID must be set'); + const subscription = { + ...threadInfo.currentUser.subscription, + ...input.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 processAndSendDMOperation(opSpecification); + return { threadID: threadInfo.id, subscription }; + }, + [keyserverCall, processAndSendDMOperation, viewerID, threadInfo], + ); } const setUserSettingsActionTypes = Object.freeze({ diff --git a/lib/shared/dm-ops/change-thread-subscription.js b/lib/shared/dm-ops/change-thread-subscription.js --- a/lib/shared/dm-ops/change-thread-subscription.js +++ b/lib/shared/dm-ops/change-thread-subscription.js @@ -42,10 +42,18 @@ member => member.id !== creatorID, ); const membersUpdate = [...otherMemberInfos, updatedCreatorMemberInfo]; + const currentUserUpdate = + viewerID === creatorID + ? { + ...threadInfo.currentUser, + subscription, + } + : threadInfo.currentUser; const threadInfoUpdate = { ...threadInfo, members: membersUpdate, + currentUser: currentUserUpdate, timestamps: { ...threadInfo.timestamps, members: { @@ -57,6 +65,7 @@ }, }, }; + const updateInfos: Array = [ { type: updateTypes.UPDATE_THREAD, diff --git a/lib/shared/thread-settings-notifications-utils.js b/lib/shared/thread-settings-notifications-utils.js --- a/lib/shared/thread-settings-notifications-utils.js +++ b/lib/shared/thread-settings-notifications-utils.js @@ -102,7 +102,7 @@ const dispatchActionPromise = useDispatchActionPromise(); - const callUpdateSubscription = useUpdateSubscription(); + const callUpdateSubscription = useUpdateSubscription(threadInfo); const updateSubscriptionPromise = React.useCallback(async () => { const res = await callUpdateSubscription({