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(
     () =>