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,16 @@
[key: string]: boolean,
}>({});
+ const [spoilerRevealed, setSpoilerRevealed] = React.useState<{
+ [key: string]: {
+ [key: number]: boolean,
+ },
+ }>({});
+
const clearMarkdownContextData = React.useCallback(() => {
setLinkModalActive({});
setLinkPressActive({});
+ setSpoilerRevealed({});
}, []);
const contextValue = React.useMemo(
@@ -27,6 +34,8 @@
linkModalActive,
setLinkPressActive,
linkPressActive,
+ setSpoilerRevealed,
+ spoilerRevealed,
clearMarkdownContextData,
}),
[
@@ -34,6 +43,8 @@
linkModalActive,
setLinkPressActive,
linkPressActive,
+ setSpoilerRevealed,
+ spoilerRevealed,
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,8 @@
+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 } },
+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
@@ -1,36 +1,76 @@
// @flow
+import invariant from 'invariant';
import * as React from 'react';
import { Text } from 'react-native';
import type { ReactElement } from 'lib/shared/markdown';
+import { MessageContext } from '../chat/message-context.react';
+import GestureTouchableOpacity from '../components/gesture-touchable-opacity.react';
import { useStyles } from '../themes/colors';
+import { MarkdownContext } from './markdown-context';
type MarkdownSpoilerProps = {
+ +spoilerIdentifier: 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);
+ invariant(markdownContext, 'MarkdownContext should be set');
+
+ const messageContext = React.useContext(MessageContext);
const styles = useStyles(unboundStyles);
- const { text } = props;
+
+ const { text, spoilerIdentifier } = props;
+ const { spoilerRevealed, setSpoilerRevealed } = markdownContext;
+ const { messageKey } = messageContext;
+
+ const parsedSpoilerIdentifier = spoilerIdentifier
+ ? parseInt(spoilerIdentifier)
+ : -1;
+
+ const isRevealed =
+ spoilerRevealed[messageKey]?.[parsedSpoilerIdentifier] ?? false;
+
+ const styleBasedOnSpoilerState = React.useMemo(() => {
+ if (isRevealed) {
+ return null;
+ }
+ return styles.spoilerHidden;
+ }, [isRevealed, styles.spoilerHidden]);
const onSpoilerClick = React.useCallback(() => {
- setIsRevealed(true);
- }, []);
+ if (isRevealed) {
+ return;
+ }
+
+ if (messageKey && parsedSpoilerIdentifier !== -1) {
+ setSpoilerRevealed({
+ ...spoilerRevealed,
+ [messageKey]: {
+ ...spoilerRevealed[messageKey],
+ [parsedSpoilerIdentifier]: true,
+ },
+ });
+ }
+ }, [
+ isRevealed,
+ spoilerRevealed,
+ setSpoilerRevealed,
+ messageKey,
+ parsedSpoilerIdentifier,
+ ]);
const memoizedSpoiler = React.useMemo(() => {
return (
-
- {text}
-
+
+ {text}
+
);
- }, [onSpoilerClick, isRevealed, styles.spoilerHidden, text]);
+ }, [onSpoilerClick, styleBasedOnSpoilerState, 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,
state: SharedMarkdown.State,
) => (
-
+
),
},
inlineCode: {