diff --git a/web/chat/thread-menu.react.js b/web/chat/thread-menu.react.js --- a/web/chat/thread-menu.react.js +++ b/web/chat/thread-menu.react.js @@ -1,6 +1,8 @@ // @flow +import invariant from 'invariant'; import * as React from 'react'; +import uuid from 'uuid'; import { leaveThreadActionTypes, @@ -10,16 +12,24 @@ import SWMansionIcon from 'lib/components/swmansion-icon.react.js'; import { usePromoteSidebar } from 'lib/hooks/promote-sidebar.react.js'; import { childThreadInfos } from 'lib/selectors/thread-selectors.js'; +import { + type OutboundDMOperationSpecification, + dmOperationSpecificationTypes, +} from 'lib/shared/dm-ops/dm-op-utils.js'; +import { useProcessAndSendDMOperation } from 'lib/shared/dm-ops/process-dm-ops.js'; import { threadIsChannel, useThreadHasPermission, viewerIsMember, } from 'lib/shared/thread-utils.js'; +import { type DMLeaveThreadOperation } from 'lib/types/dm-ops.js'; import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import { threadPermissions } from 'lib/types/thread-permission-types.js'; import { threadTypes, threadTypeIsSidebar, + threadTypeIsThick, + thickThreadTypes, } from 'lib/types/thread-types-enum.js'; import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; @@ -196,14 +206,51 @@ const dispatchActionPromise = useDispatchActionPromise(); const callLeaveThread = useLeaveThread(); + const processAndSendDMOperation = useProcessAndSendDMOperation(); + const viewerID = useSelector( + state => state.currentUserInfo && state.currentUserInfo.id, + ); const onConfirmLeaveThread = React.useCallback(() => { - void dispatchActionPromise( - leaveThreadActionTypes, - callLeaveThread({ threadID: threadInfo.id }), - ); + if (threadTypeIsThick(threadInfo.type)) { + invariant(viewerID, 'viewerID should be set'); + const op: DMLeaveThreadOperation = { + type: 'leave_thread', + editorID: viewerID, + time: Date.now(), + messageID: uuid.v4(), + threadID: threadInfo.id, + }; + const opSpecification: OutboundDMOperationSpecification = { + type: dmOperationSpecificationTypes.OUTBOUND, + op, + recipients: { + type: 'all_thread_members', + threadID: + threadInfo.type === thickThreadTypes.THICK_SIDEBAR && + threadInfo.parentThreadID + ? threadInfo.parentThreadID + : threadInfo.id, + }, + }; + void processAndSendDMOperation(opSpecification); + } else { + void dispatchActionPromise( + leaveThreadActionTypes, + callLeaveThread({ threadID: threadInfo.id }), + ); + } popModal(); - }, [callLeaveThread, popModal, dispatchActionPromise, threadInfo.id]); + }, [ + threadInfo.type, + threadInfo.id, + threadInfo.parentThreadID, + popModal, + viewerID, + processAndSendDMOperation, + dispatchActionPromise, + callLeaveThread, + ]); const onClickLeaveThread = React.useCallback( () =>