diff --git a/native/chat/message-context.react.js b/native/chat/message-context.react.js --- a/native/chat/message-context.react.js +++ b/native/chat/message-context.react.js @@ -4,11 +4,13 @@ export type MessageContextType = { +messageID: string, + +messageText: ?string, }; const MessageContext: React.Context = React.createContext( { messageID: '', + messageText: null, }, ); 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 @@ -11,7 +11,10 @@ } from 'lib/shared/thread-utils'; import { threadPermissions } from 'lib/types/thread-types'; -import { MarkdownContext } from '../markdown/markdown-context'; +import { + MarkdownContext, + type MarkdownContextType, +} from '../markdown/markdown-context'; import { OverlayContext, type OverlayContextType, @@ -44,8 +47,10 @@ // withOverlayContext +overlayContext: ?OverlayContextType, // MarkdownContext + +markdownContext: MarkdownContextType, +isLinkModalActive: boolean, +linkIsBlockingPresses: boolean, + +spoilerIsBlockingTooltip: boolean, }; class TextMessage extends React.PureComponent { message: ?React.ElementRef; @@ -59,8 +64,10 @@ toggleFocus, verticalBounds, overlayContext, + markdownContext, isLinkModalActive, linkIsBlockingPresses, + spoilerIsBlockingTooltip, canCreateSidebarFromMessage, ...viewProps } = this.props; @@ -141,10 +148,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; } @@ -207,10 +227,11 @@ const { linkModalActive, linkPressActive, + spoilerPressActive, clearMarkdownContextData, } = markdownContext; - const { id } = props.item.messageInfo; + const { id, text } = props.item.messageInfo; invariant(id, 'messageInfo.id should exist'); // We check if there is an ID in the respective objects - if not, we @@ -221,6 +242,8 @@ const isLinkModalActive = linkModalActive[id] ?? false; + const spoilerIsBlockingTooltip = spoilerPressActive ?? false; + const canCreateSidebarFromMessage = useCanCreateSidebarFromMessage( props.item.threadInfo, props.item.messageInfo, @@ -231,8 +254,9 @@ const contextValue = React.useMemo( () => ({ messageID: id, + messageText: text ?? '', }), - [id], + [id, text], ); React.useEffect(() => { @@ -249,7 +273,9 @@ canCreateSidebarFromMessage={canCreateSidebarFromMessage} overlayContext={overlayContext} isLinkModalActive={isLinkModalActive} + markdownContext={markdownContext} linkIsBlockingPresses={linkIsBlockingPresses} + spoilerIsBlockingTooltip={spoilerIsBlockingTooltip} /> ); 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( + 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, + +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,7 +5,9 @@ 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 = { +text: ReactElement, @@ -13,24 +15,54 @@ }; 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, messageText } = messageContext; + const text = props.text; + + const setSpoilerRevealed = markdownContext?.setSpoilerRevealed; + const spoilerRevealed = markdownContext?.spoilerRevealed; + const setSpoilerPressActive = markdownContext?.setSpoilerPressActive; + + const spoilerIndex = messageText?.indexOf(text.toString()); const onSpoilerClick = React.useCallback(() => { - setIsRevealed(true); - }, []); + if (styleBasedOnState === null) { + setSpoilerPressActive && setSpoilerPressActive(false); + return; + } + + spoilerRevealed && + setSpoilerRevealed && + spoilerIndex && + setSpoilerRevealed({ + ...spoilerRevealed, + [messageID]: { ...spoilerRevealed[messageID], [spoilerIndex]: true }, + }); + setSpoilerPressActive && setSpoilerPressActive(true); + setStyleBasedOnState(null); + }, [ + setSpoilerPressActive, + spoilerRevealed, + setSpoilerRevealed, + messageID, + spoilerIndex, + styleBasedOnState, + ]); const memoizedSpoiler = React.useMemo(() => { return ( - + {text} ); - }, [onSpoilerClick, isRevealed, styles.spoilerHidden, text]); + }, [onSpoilerClick, styleBasedOnState, text]); return memoizedSpoiler; }