diff --git a/native/chat/text-message.react.js b/native/chat/text-message.react.js
--- a/native/chat/text-message.react.js
+++ b/native/chat/text-message.react.js
@@ -12,7 +12,10 @@
 import { threadPermissions } from 'lib/types/thread-types';
 
 import { ChatContext, type ChatContextType } from '../chat/chat-context';
-import { MarkdownContext } from '../markdown/markdown-context';
+import {
+  MarkdownContext,
+  type MarkdownContextType,
+} from '../markdown/markdown-context';
 import {
   OverlayContext,
   type OverlayContextType,
@@ -47,8 +50,10 @@
   // ChatContext
   +chatContext: ?ChatContextType,
   // MarkdownContext
+  +markdownContext: MarkdownContextType,
   +isLinkModalActive: boolean,
   +linkIsBlockingPresses: boolean,
+  +spoilerIsBlockingTooltip: boolean,
 };
 class TextMessage extends React.PureComponent<Props> {
   message: ?React.ElementRef<typeof View>;
@@ -63,8 +68,10 @@
       verticalBounds,
       overlayContext,
       chatContext,
+      markdownContext,
       isLinkModalActive,
       linkIsBlockingPresses,
+      spoilerIsBlockingTooltip,
       canCreateSidebarFromMessage,
       ...viewProps
     } = this.props;
@@ -146,10 +153,23 @@
 
     const {
       message,
-      props: { verticalBounds, linkIsBlockingPresses },
+      props: {
+        verticalBounds,
+        markdownContext,
+        linkIsBlockingPresses,
+        spoilerIsBlockingTooltip,
+      },
     } = this;
 
-    if (!message || !verticalBounds || linkIsBlockingPresses) {
+    const { setSpoilerPressActive } = markdownContext;
+    setSpoilerPressActive(false);
+
+    if (
+      !message ||
+      !verticalBounds ||
+      linkIsBlockingPresses ||
+      spoilerIsBlockingTooltip
+    ) {
       return;
     }
 
@@ -216,6 +236,7 @@
     const {
       linkModalActive,
       linkPressActive,
+      spoilerPressActive,
       clearMarkdownContextData,
     } = markdownContext;
 
@@ -230,6 +251,8 @@
 
     const isLinkModalActive = linkModalActive[id] ?? false;
 
+    const spoilerIsBlockingTooltip = spoilerPressActive;
+
     const canCreateSidebarFromMessage = useCanCreateSidebarFromMessage(
       props.item.threadInfo,
       props.item.messageInfo,
@@ -258,7 +281,9 @@
           overlayContext={overlayContext}
           chatContext={chatContext}
           isLinkModalActive={isLinkModalActive}
+          markdownContext={markdownContext}
           linkIsBlockingPresses={linkIsBlockingPresses}
+          spoilerIsBlockingTooltip={spoilerIsBlockingTooltip}
         />
       </MessageContext.Provider>
     );
diff --git a/native/markdown/markdown-context-provider.react.js b/native/markdown/markdown-context-provider.react.js
--- a/native/markdown/markdown-context-provider.react.js
+++ b/native/markdown/markdown-context-provider.react.js
@@ -16,9 +16,20 @@
     [key: string]: boolean,
   }>({});
 
+  const [spoilerRevealed, setSpoilerRevealed] = React.useState<{
+    [key: string]: {
+      [key: number]: boolean,
+    },
+  }>({});
+  const [spoilerPressActive, setSpoilerPressActive] = React.useState<boolean>(
+    false,
+  );
+
   const clearMarkdownContextData = React.useCallback(() => {
     setLinkModalActive({});
     setLinkPressActive({});
+    setSpoilerRevealed({});
+    setSpoilerPressActive(false);
   }, []);
 
   const contextValue = React.useMemo(
@@ -27,6 +38,10 @@
       linkModalActive,
       setLinkPressActive,
       linkPressActive,
+      setSpoilerRevealed,
+      spoilerRevealed,
+      setSpoilerPressActive,
+      spoilerPressActive,
       clearMarkdownContextData,
     }),
     [
@@ -34,6 +49,10 @@
       linkModalActive,
       setLinkPressActive,
       linkPressActive,
+      setSpoilerRevealed,
+      spoilerRevealed,
+      setSpoilerPressActive,
+      spoilerPressActive,
       clearMarkdownContextData,
     ],
   );
diff --git a/native/markdown/markdown-context.js b/native/markdown/markdown-context.js
--- a/native/markdown/markdown-context.js
+++ b/native/markdown/markdown-context.js
@@ -9,6 +9,11 @@
   +linkModalActive: { [key: string]: boolean },
   +setLinkPressActive: SetState<{ [key: string]: boolean }>,
   +linkPressActive: { [key: string]: boolean },
+  +setSpoilerRevealed: SetState<{ [key: string]: { [key: number]: boolean } }>,
+  +spoilerRevealed: { [key: string]: { [key: number]: boolean } },
+  +setSpoilerPressActive: SetState<boolean>,
+  +spoilerPressActive: boolean,
+
   +clearMarkdownContextData: () => void,
 };
 
diff --git a/native/markdown/markdown-spoiler.react.js b/native/markdown/markdown-spoiler.react.js
--- a/native/markdown/markdown-spoiler.react.js
+++ b/native/markdown/markdown-spoiler.react.js
@@ -5,32 +5,62 @@
 
 import type { ReactElement } from 'lib/shared/markdown';
 
+import { MessageContext } from '../chat/message-context.react';
 import { useStyles } from '../themes/colors';
+import { MarkdownContext } from './markdown-context';
 
 type MarkdownSpoilerProps = {
+  +identifier: string | number | void,
   +text: ReactElement,
   +children?: React.Node,
 };
 
 function MarkdownSpoiler(props: MarkdownSpoilerProps): React.Node {
-  const [isRevealed, setIsRevealed] = React.useState(false);
+  const markdownContext = React.useContext(MarkdownContext);
+  const messageContext = React.useContext(MessageContext);
   const styles = useStyles(unboundStyles);
-  const { text } = props;
+
+  const [styleBasedOnState, setStyleBasedOnState] = React.useState(
+    styles.spoilerHidden,
+  );
+
+  const { messageID } = messageContext;
+  const { text, identifier } = props;
+
+  const setSpoilerRevealed = markdownContext?.setSpoilerRevealed;
+  const spoilerRevealed = markdownContext?.spoilerRevealed;
+  const setSpoilerPressActive = markdownContext?.setSpoilerPressActive;
 
   const onSpoilerClick = React.useCallback(() => {
-    setIsRevealed(true);
-  }, []);
+    if (styleBasedOnState === null) {
+      setSpoilerPressActive && setSpoilerPressActive(false);
+      return;
+    }
+
+    if (spoilerRevealed && setSpoilerRevealed && messageID && identifier) {
+      setSpoilerRevealed({
+        ...spoilerRevealed,
+        [messageID]: { ...spoilerRevealed[messageID], [identifier]: true },
+      });
+    }
+    setSpoilerPressActive && setSpoilerPressActive(true);
+    setStyleBasedOnState(null);
+  }, [
+    setSpoilerPressActive,
+    spoilerRevealed,
+    setSpoilerRevealed,
+    messageID,
+    identifier,
+    styleBasedOnState,
+  ]);
 
   const memoizedSpoiler = React.useMemo(() => {
     return (
-      <Text
-        onPress={onSpoilerClick}
-        style={!isRevealed ? styles.spoilerHidden : null}
-      >
+      <Text onPress={onSpoilerClick} style={styleBasedOnState}>
         {text}
       </Text>
     );
-  }, [onSpoilerClick, isRevealed, styles.spoilerHidden, text]);
+  }, [onSpoilerClick, styleBasedOnState, text]);
 
   return memoizedSpoiler;
 }
diff --git a/native/markdown/rules.react.js b/native/markdown/rules.react.js
--- a/native/markdown/rules.react.js
+++ b/native/markdown/rules.react.js
@@ -200,7 +200,11 @@
         output: SharedMarkdown.Output<SharedMarkdown.ReactElement>,
         state: SharedMarkdown.State,
       ) => (
-        <MarkdownSpoiler key={state.key} text={output(node.content, state)} />
+        <MarkdownSpoiler
+          key={state.key}
+          identifier={state.key}
+          text={output(node.content, state)}
+        />
       ),
     },
     inlineCode: {