Page MenuHomePhorge

D5515.1765109818.diff
No OneTemporary

Size
13 KB
Referenced Files
None
Subscribers
None

D5515.1765109818.diff

diff --git a/native/chat/message-context.react.js b/native/chat/message-context.react.js
new file mode 100644
--- /dev/null
+++ b/native/chat/message-context.react.js
@@ -0,0 +1,13 @@
+// @flow
+
+import * as React from 'react';
+
+export type MessageContextType = {
+ +messageID: string,
+};
+
+const MessageContext: React.Context<?MessageContextType> = React.createContext<?MessageContextType>(
+ null,
+);
+
+export { MessageContext };
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
@@ -23,6 +23,7 @@
import type { ChatNavigationProp } from './chat.react';
import ComposedMessage from './composed-message.react';
import { InnerTextMessage } from './inner-text-message.react';
+import { MessageContext } from './message-context.react';
import textMessageSendFailed from './text-message-send-failed';
import { textMessageTooltipHeight } from './text-message-tooltip-modal.react';
import { getMessageTooltipKey } from './utils';
@@ -49,6 +50,8 @@
class TextMessage extends React.PureComponent<Props> {
message: ?React.ElementRef<typeof View>;
+ static contextType = MarkdownContext;
+
render() {
const {
item,
@@ -140,8 +143,18 @@
const {
message,
- props: { verticalBounds, linkIsBlockingPresses },
+ props: { verticalBounds },
} = this;
+
+ let { linkIsBlockingPresses } = this.props;
+
+ /* We run an "updated check" against the Context to check whether the
+ specific message should be blocked from the tooltip appearing */
+ const { messagesLinkModalActive, messagesLinkPressActive } = this.context;
+ linkIsBlockingPresses =
+ messagesLinkModalActive.get(this.props.item.messageInfo.id) ||
+ messagesLinkPressActive.get(this.props.item.messageInfo.id);
+
if (!message || !verticalBounds || linkIsBlockingPresses) {
return;
}
@@ -200,23 +213,65 @@
function ConnectedTextMessage(props: BaseProps) {
const overlayContext = React.useContext(OverlayContext);
- const [linkModalActive, setLinkModalActive] = React.useState(false);
- const [linkPressActive, setLinkPressActive] = React.useState(false);
- const markdownContext = React.useMemo(
- () => ({
- setLinkModalActive,
- setLinkPressActive,
- }),
- [setLinkModalActive, setLinkPressActive],
- );
+ /* We get the Markdown Context */
+ const markdownContext = React.useContext(MarkdownContext);
+ invariant(markdownContext, 'should be set');
+
+ /* Extract the methods & maps */
+ const {
+ setLinkModalActive,
+ setLinkPressActive,
+ clearMessageData,
+ messagesLinkModalActive,
+ messagesLinkPressActive,
+ } = markdownContext;
+
+ /* Extract the messageID */
+ const { id } = props.item.messageInfo;
+ invariant(id, 'should exist');
+
+ /* Set `linkModalActive` & `linkPressActive` to either the
+ value inside the map, or if it does
+ not exist, defualt to false There most likely
+ is not a value for the message if the thread has
+ just been opened */
+ const linkModalActive = messagesLinkModalActive.get(id) ?? false;
+ const linkPressActive = messagesLinkPressActive.get(id) ?? false;
+ setLinkModalActive(id, linkModalActive);
+ setLinkPressActive(id, linkPressActive);
+
+ /* Same logic is before to check if linkIsBlockingPresses */
+ const linkIsBlockingPresses = linkModalActive || linkPressActive;
+
+ /* Not relevant for Markdown refactoring */
const canCreateSidebarFromMessage = useCanCreateSidebarFromMessage(
props.item.threadInfo,
props.item.messageInfo,
);
- const linkIsBlockingPresses = linkModalActive || linkPressActive;
+ /* We use a MessageContext to allow MarkdownLink
+ (and MarkdownSpoiler soon) to access
+ the messageID so it is 'self-aware' */
+ const contextValue = React.useMemo(
+ () => ({
+ messageID: id,
+ }),
+ [id],
+ );
+
+ /* This is how we want to check if the component is
+ unmounted (a specific message),
+ and thus we will clear the data for that message stored
+ in the Context maps */
+ React.useEffect(() => {
+ return () => {
+ // Anything in here is fired on component unmount.
+ id ? clearMessageData(id) : null;
+ };
+ }, [clearMessageData, id]);
+
return (
- <MarkdownContext.Provider value={markdownContext}>
+ <MessageContext.Provider value={contextValue}>
<TextMessage
{...props}
canCreateSidebarFromMessage={canCreateSidebarFromMessage}
@@ -224,7 +279,7 @@
linkModalActive={linkModalActive}
linkIsBlockingPresses={linkIsBlockingPresses}
/>
- </MarkdownContext.Provider>
+ </MessageContext.Provider>
);
},
);
diff --git a/native/markdown/markdown-context-provider.react.js b/native/markdown/markdown-context-provider.react.js
new file mode 100644
--- /dev/null
+++ b/native/markdown/markdown-context-provider.react.js
@@ -0,0 +1,49 @@
+// @flow
+
+import * as React from 'react';
+
+import { MarkdownContext } from './markdown-context.js';
+
+type Props = {
+ +children: React.Node,
+};
+
+function MarkdownContextProvider(props: Props): React.Node {
+ const messagesLinkModalActive = React.useRef<Map<string, boolean>>(new Map());
+ const setLinkModalActive = React.useCallback(
+ (messageID: string, active: boolean) =>
+ messagesLinkModalActive.current.set(messageID, active),
+ [],
+ );
+
+ const messagesLinkPressActive = React.useRef<Map<string, boolean>>(new Map());
+ const setLinkPressActive = React.useCallback(
+ (messageID: string, active: boolean) =>
+ messagesLinkPressActive.current.set(messageID, active),
+ [],
+ );
+
+ const clearMessageData = React.useCallback((messageID: string) => {
+ messagesLinkModalActive.current.delete(messageID);
+ messagesLinkPressActive.current.delete(messageID);
+ }, []);
+
+ const contextValue = React.useMemo(
+ () => ({
+ setLinkModalActive,
+ setLinkPressActive,
+ clearMessageData,
+ messagesLinkModalActive: messagesLinkModalActive.current,
+ messagesLinkPressActive: messagesLinkPressActive.current,
+ }),
+ [setLinkModalActive, setLinkPressActive, clearMessageData],
+ );
+
+ return (
+ <MarkdownContext.Provider value={contextValue}>
+ {props.children}
+ </MarkdownContext.Provider>
+ );
+}
+
+export default MarkdownContextProvider;
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
@@ -3,8 +3,11 @@
import * as React from 'react';
export type MarkdownContextType = {
- +setLinkModalActive: boolean => void,
- +setLinkPressActive: boolean => void,
+ +setLinkModalActive: (messageID: string, active: boolean) => mixed,
+ +setLinkPressActive: (messageID: string, active: boolean) => mixed,
+ +clearMessageData: (messageID: string) => void,
+ +messagesLinkModalActive: $ReadOnlyMap<string, boolean>,
+ +messagesLinkPressActive: $ReadOnlyMap<string, boolean>,
};
const MarkdownContext: React.Context<?MarkdownContextType> = React.createContext<?MarkdownContextType>(
diff --git a/native/markdown/markdown-link.react.js b/native/markdown/markdown-link.react.js
--- a/native/markdown/markdown-link.react.js
+++ b/native/markdown/markdown-link.react.js
@@ -5,16 +5,18 @@
import { normalizeURL } from 'lib/utils/url-utils';
+import { MessageContext } from '../chat/message-context.react';
import { MarkdownContext, type MarkdownContextType } from './markdown-context';
function useDisplayLinkPrompt(
inputURL: string,
markdownContext: ?MarkdownContextType,
+ messageID: string,
) {
const setLinkModalActive = markdownContext?.setLinkModalActive;
const onDismiss = React.useCallback(() => {
- setLinkModalActive?.(false);
- }, [setLinkModalActive]);
+ setLinkModalActive?.(messageID, false);
+ }, [setLinkModalActive, messageID]);
const url = normalizeURL(inputURL);
const onConfirm = React.useCallback(() => {
@@ -27,7 +29,8 @@
displayURL += '…';
}
return React.useCallback(() => {
- setLinkModalActive && setLinkModalActive(true);
+ console.log('`MarkdownLink` messageID: ', messageID);
+ setLinkModalActive && setLinkModalActive(messageID, true);
Alert.alert(
'External link',
`You sure you want to open this link?\n\n${displayURL}`,
@@ -37,7 +40,7 @@
],
{ cancelable: true, onDismiss },
);
- }, [setLinkModalActive, displayURL, onConfirm, onDismiss]);
+ }, [setLinkModalActive, messageID, displayURL, onConfirm, onDismiss]);
}
type TextProps = React.ElementConfig<typeof Text>;
@@ -48,15 +51,18 @@
};
function MarkdownLink(props: Props): React.Node {
const markdownContext = React.useContext(MarkdownContext);
+ const messageContext = React.useContext(MessageContext);
+
+ const messageID = messageContext?.messageID ?? '';
const { target, ...rest } = props;
- const onPressLink = useDisplayLinkPrompt(target, markdownContext);
+ const onPressLink = useDisplayLinkPrompt(target, markdownContext, messageID);
const setLinkPressActive = markdownContext?.setLinkPressActive;
const androidOnStartShouldSetResponderCapture = React.useCallback(() => {
- setLinkPressActive?.(true);
+ setLinkPressActive?.(messageID, true);
return true;
- }, [setLinkPressActive]);
+ }, [setLinkPressActive, messageID]);
const activePressHasMoved = React.useRef(false);
const androidOnResponderMove = React.useCallback(() => {
@@ -68,8 +74,8 @@
onPressLink();
}
activePressHasMoved.current = false;
- setLinkPressActive?.(false);
- }, [onPressLink, setLinkPressActive]);
+ setLinkPressActive?.(messageID, false);
+ }, [onPressLink, setLinkPressActive, messageID]);
if (Platform.OS !== 'android') {
return <Text onPress={onPressLink} {...rest} />;
diff --git a/native/navigation/app-navigator.react.js b/native/navigation/app-navigator.react.js
--- a/native/navigation/app-navigator.react.js
+++ b/native/navigation/app-navigator.react.js
@@ -21,6 +21,7 @@
import SWMansionIcon from '../components/swmansion-icon.react';
import { type SQLiteContextType, SQLiteContext } from '../data/sqlite-context';
import KeyboardStateContainer from '../keyboard/keyboard-state-container.react';
+import MarkdownContextProvider from '../markdown/markdown-context-provider.react';
import CameraModal from '../media/camera-modal.react';
import ImageModal from '../media/image-modal.react';
import VideoPlaybackModal from '../media/video-playback-modal.react';
@@ -212,39 +213,41 @@
}
return (
<KeyboardStateContainer>
- <App.Navigator>
- <App.Screen name={TabNavigatorRouteName} component={TabNavigator} />
- <App.Screen name={ImageModalRouteName} component={ImageModal} />
- <App.Screen
- name={MultimediaMessageTooltipModalRouteName}
- component={MultimediaMessageTooltipModal}
- />
- <App.Screen
- name={ActionResultModalRouteName}
- component={ActionResultModal}
- />
- <App.Screen
- name={TextMessageTooltipModalRouteName}
- component={TextMessageTooltipModal}
- />
- <App.Screen
- name={ThreadSettingsMemberTooltipModalRouteName}
- component={ThreadSettingsMemberTooltipModal}
- />
- <App.Screen
- name={RelationshipListItemTooltipModalRouteName}
- component={RelationshipListItemTooltipModal}
- />
- <App.Screen
- name={RobotextMessageTooltipModalRouteName}
- component={RobotextMessageTooltipModal}
- />
- <App.Screen name={CameraModalRouteName} component={CameraModal} />
- <App.Screen
- name={VideoPlaybackModalRouteName}
- component={VideoPlaybackModal}
- />
- </App.Navigator>
+ <MarkdownContextProvider>
+ <App.Navigator>
+ <App.Screen name={TabNavigatorRouteName} component={TabNavigator} />
+ <App.Screen name={ImageModalRouteName} component={ImageModal} />
+ <App.Screen
+ name={MultimediaMessageTooltipModalRouteName}
+ component={MultimediaMessageTooltipModal}
+ />
+ <App.Screen
+ name={ActionResultModalRouteName}
+ component={ActionResultModal}
+ />
+ <App.Screen
+ name={TextMessageTooltipModalRouteName}
+ component={TextMessageTooltipModal}
+ />
+ <App.Screen
+ name={ThreadSettingsMemberTooltipModalRouteName}
+ component={ThreadSettingsMemberTooltipModal}
+ />
+ <App.Screen
+ name={RelationshipListItemTooltipModalRouteName}
+ component={RelationshipListItemTooltipModal}
+ />
+ <App.Screen
+ name={RobotextMessageTooltipModalRouteName}
+ component={RobotextMessageTooltipModal}
+ />
+ <App.Screen name={CameraModalRouteName} component={CameraModal} />
+ <App.Screen
+ name={VideoPlaybackModalRouteName}
+ component={VideoPlaybackModal}
+ />
+ </App.Navigator>
+ </MarkdownContextProvider>
{pushHandler}
</KeyboardStateContainer>
);

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 7, 12:16 PM (18 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5844147
Default Alt Text
D5515.1765109818.diff (13 KB)

Event Timeline