Page MenuHomePhorge

D8845.1765323538.diff
No OneTemporary

Size
15 KB
Referenced Files
None
Subscribers
None

D8845.1765323538.diff

diff --git a/native/chat/chat-input-bar.react.js b/native/chat/chat-input-bar.react.js
--- a/native/chat/chat-input-bar.react.js
+++ b/native/chat/chat-input-bar.react.js
@@ -57,6 +57,7 @@
threadActualMembers,
checkIfDefaultMembersAreVoiced,
draftKeyFromThreadID,
+ useThreadChatMentionCandidates,
} from 'lib/shared/thread-utils.js';
import type { CalendarQuery } from 'lib/types/entry-types.js';
import type { LoadingStatus } from 'lib/types/loading-types.js';
@@ -1258,13 +1259,17 @@
parentThreadInfo,
);
+ const chatMentionCandidates = useThreadChatMentionCandidates(
+ props.threadInfo,
+ );
+
const messageEditingContext = React.useContext(MessageEditingContext);
const editedMessageInfo = messageEditingContext?.editState.editedMessage;
const editedMessagePreview = useMessagePreview(
editedMessageInfo,
props.threadInfo,
- getDefaultTextMessageRules().simpleMarkdownRules,
+ getDefaultTextMessageRules(chatMentionCandidates).simpleMarkdownRules,
);
const editMessage = useEditMessage();
diff --git a/native/chat/message-list-types.js b/native/chat/message-list-types.js
--- a/native/chat/message-list-types.js
+++ b/native/chat/message-list-types.js
@@ -1,16 +1,21 @@
// @flow
-import { useNavigation } from '@react-navigation/native';
+import { useNavigation, useNavigationState } from '@react-navigation/native';
import invariant from 'invariant';
import * as React from 'react';
+import { useThreadChatMentionCandidates } from 'lib/shared/thread-utils.js';
import type { ThreadInfo } from 'lib/types/thread-types.js';
import { type UserInfo } from 'lib/types/user-types.js';
+import { ChatContext } from './chat-context.js';
import type { ChatRouterNavigationAction } from './chat-router.js';
import type { MarkdownRules } from '../markdown/rules.react.js';
import { useTextMessageRulesFunc } from '../markdown/rules.react.js';
-import { MessageListRouteName } from '../navigation/route-names.js';
+import {
+ MessageListRouteName,
+ TextMessageTooltipModalRouteName,
+} from '../navigation/route-names.js';
export type MessageListParams = {
+threadInfo: ThreadInfo,
@@ -31,7 +36,11 @@
React.createContext<?MessageListContextType>();
function useMessageListContext(threadInfo: ThreadInfo) {
- const getTextMessageMarkdownRules = useTextMessageRulesFunc(threadInfo);
+ const chatMentionCandidates = useThreadChatMentionCandidates(threadInfo);
+ const getTextMessageMarkdownRules = useTextMessageRulesFunc(
+ threadInfo,
+ chatMentionCandidates,
+ );
return React.useMemo(
() => ({
getTextMessageMarkdownRules,
@@ -84,9 +93,40 @@
return messageListContext.getTextMessageMarkdownRules(useDarkStyle);
}
+function useNavigateToThreadWithFadeAnimation(
+ threadInfo: ThreadInfo,
+ messageKey: ?string,
+): () => mixed {
+ const chatContext = React.useContext(ChatContext);
+ invariant(chatContext, 'ChatContext should be set');
+ const setSidebarSourceID = chatContext?.setCurrentTransitionSidebarSourceID;
+ const setSidebarAnimationType = chatContext?.setSidebarAnimationType;
+ const navigateToThread = useNavigateToThread();
+ const navigationStack = useNavigationState(state => state.routes);
+
+ return React.useCallback(() => {
+ if (
+ navigationStack[navigationStack.length - 1].name ===
+ TextMessageTooltipModalRouteName
+ ) {
+ setSidebarSourceID && setSidebarSourceID(messageKey);
+ setSidebarAnimationType && setSidebarAnimationType('fade_source_message');
+ }
+ navigateToThread({ threadInfo });
+ }, [
+ messageKey,
+ navigateToThread,
+ navigationStack,
+ setSidebarAnimationType,
+ setSidebarSourceID,
+ threadInfo,
+ ]);
+}
+
export {
MessageListContextProvider,
createNavigateToThreadAction,
useNavigateToThread,
useTextMessageMarkdownRules,
+ useNavigateToThreadWithFadeAnimation,
};
diff --git a/native/chat/message-preview.react.js b/native/chat/message-preview.react.js
--- a/native/chat/message-preview.react.js
+++ b/native/chat/message-preview.react.js
@@ -5,6 +5,7 @@
import { Text } from 'react-native';
import { useMessagePreview } from 'lib/shared/message-utils.js';
+import { useThreadChatMentionCandidates } from 'lib/shared/thread-utils.js';
import { type MessageInfo } from 'lib/types/message-types.js';
import { type ThreadInfo } from 'lib/types/thread-types.js';
@@ -18,10 +19,12 @@
};
function MessagePreview(props: Props): React.Node {
const { messageInfo, threadInfo } = props;
+
+ const chatMentionCandidates = useThreadChatMentionCandidates(threadInfo);
const messagePreviewResult = useMessagePreview(
messageInfo,
threadInfo,
- getDefaultTextMessageRules().simpleMarkdownRules,
+ getDefaultTextMessageRules(chatMentionCandidates).simpleMarkdownRules,
);
invariant(
messagePreviewResult,
diff --git a/native/chat/sidebar-input-bar-height-measurer.react.js b/native/chat/sidebar-input-bar-height-measurer.react.js
--- a/native/chat/sidebar-input-bar-height-measurer.react.js
+++ b/native/chat/sidebar-input-bar-height-measurer.react.js
@@ -4,6 +4,7 @@
import { View, StyleSheet } from 'react-native';
import { useLoggedInUserInfo } from 'lib/hooks/account-hooks.js';
+import { useChatMentionCandidatesObj } from 'lib/shared/thread-utils.js';
import { DummyChatInputBar } from './chat-input-bar.react.js';
import { useMessageListScreenWidth } from './composed-message-width.js';
@@ -21,9 +22,15 @@
const width = useMessageListScreenWidth();
const loggedInUserInfo = useLoggedInUserInfo();
+ const chatMentionCandidatesObj = useChatMentionCandidatesObj();
const sidebarThreadInfo = React.useMemo(
- () => getUnresolvedSidebarThreadInfo({ sourceMessage, loggedInUserInfo }),
- [sourceMessage, loggedInUserInfo],
+ () =>
+ getUnresolvedSidebarThreadInfo({
+ sourceMessage,
+ loggedInUserInfo,
+ chatMentionCandidatesObj,
+ }),
+ [sourceMessage, loggedInUserInfo, chatMentionCandidatesObj],
);
if (!sidebarThreadInfo) {
return null;
diff --git a/native/chat/sidebar-navigation.js b/native/chat/sidebar-navigation.js
--- a/native/chat/sidebar-navigation.js
+++ b/native/chat/sidebar-navigation.js
@@ -8,8 +8,13 @@
import {
createPendingSidebar,
createUnresolvedPendingSidebar,
+ useChatMentionCandidatesObj,
+ threadChatMentionCandidates,
} from 'lib/shared/thread-utils.js';
-import type { ThreadInfo } from 'lib/types/thread-types.js';
+import type {
+ ThreadInfo,
+ ChatMentionCandidatesObj,
+} from 'lib/types/thread-types.js';
import type { LoggedInUserInfo } from 'lib/types/user-types.js';
import type { GetENSNames } from 'lib/utils/ens-helpers.js';
@@ -21,11 +26,12 @@
type GetUnresolvedSidebarThreadInfoInput = {
+sourceMessage: ChatMessageInfoItemWithHeight,
+loggedInUserInfo: ?LoggedInUserInfo,
+ +chatMentionCandidatesObj: ChatMentionCandidatesObj,
};
function getUnresolvedSidebarThreadInfo(
input: GetUnresolvedSidebarThreadInfoInput,
): ?ThreadInfo {
- const { sourceMessage, loggedInUserInfo } = input;
+ const { sourceMessage, loggedInUserInfo, chatMentionCandidatesObj } = input;
const threadCreatedFromMessage = sourceMessage.threadCreatedFromMessage;
if (threadCreatedFromMessage) {
return threadCreatedFromMessage;
@@ -36,22 +42,35 @@
}
const { messageInfo, threadInfo } = sourceMessage;
+ const chatMentionCandidates = threadChatMentionCandidates(
+ threadInfo,
+ chatMentionCandidatesObj,
+ );
+
return createUnresolvedPendingSidebar({
sourceMessageInfo: messageInfo,
parentThreadInfo: threadInfo,
loggedInUserInfo,
- markdownRules: getDefaultTextMessageRules().simpleMarkdownRules,
+ markdownRules: getDefaultTextMessageRules(chatMentionCandidates)
+ .simpleMarkdownRules,
});
}
type GetSidebarThreadInfoInput = {
- ...GetUnresolvedSidebarThreadInfoInput,
+ +sourceMessage: ChatMessageInfoItemWithHeight,
+ +loggedInUserInfo: ?LoggedInUserInfo,
+getENSNames: ?GetENSNames,
+ +chatMentionCandidatesObj: ChatMentionCandidatesObj,
};
async function getSidebarThreadInfo(
input: GetSidebarThreadInfoInput,
): Promise<?ThreadInfo> {
- const { sourceMessage, loggedInUserInfo, getENSNames } = input;
+ const {
+ sourceMessage,
+ loggedInUserInfo,
+ getENSNames,
+ chatMentionCandidatesObj,
+ } = input;
const threadCreatedFromMessage = sourceMessage.threadCreatedFromMessage;
if (threadCreatedFromMessage) {
return threadCreatedFromMessage;
@@ -62,11 +81,17 @@
}
const { messageInfo, threadInfo } = sourceMessage;
+ const chatMentionCandidates = threadChatMentionCandidates(
+ threadInfo,
+ chatMentionCandidatesObj,
+ );
+
return await createPendingSidebar({
sourceMessageInfo: messageInfo,
parentThreadInfo: threadInfo,
loggedInUserInfo,
- markdownRules: getDefaultTextMessageRules().simpleMarkdownRules,
+ markdownRules: getDefaultTextMessageRules(chatMentionCandidates)
+ .simpleMarkdownRules,
getENSNames,
});
}
@@ -77,16 +102,24 @@
const loggedInUserInfo = useLoggedInUserInfo();
const navigateToThread = useNavigateToThread();
const cacheContext = React.useContext(ENSCacheContext);
+ const chatMentionCandidatesObj = useChatMentionCandidatesObj();
const { getENSNames } = cacheContext;
return React.useCallback(async () => {
const threadInfo = await getSidebarThreadInfo({
sourceMessage: item,
loggedInUserInfo,
getENSNames,
+ chatMentionCandidatesObj,
});
invariant(threadInfo, 'threadInfo should be set');
navigateToThread({ threadInfo });
- }, [navigateToThread, item, loggedInUserInfo, getENSNames]);
+ }, [
+ item,
+ loggedInUserInfo,
+ getENSNames,
+ chatMentionCandidatesObj,
+ navigateToThread,
+ ]);
}
function useAnimatedNavigateToSidebar(
diff --git a/native/chat/utils.js b/native/chat/utils.js
--- a/native/chat/utils.js
+++ b/native/chat/utils.js
@@ -7,7 +7,10 @@
import { useLoggedInUserInfo } from 'lib/hooks/account-hooks.js';
import { colorIsDark } from 'lib/shared/color-utils.js';
import { messageKey } from 'lib/shared/message-utils.js';
-import { viewerIsMember } from 'lib/shared/thread-utils.js';
+import {
+ viewerIsMember,
+ useChatMentionCandidatesObj,
+} from 'lib/shared/thread-utils.js';
import type { ThreadInfo } from 'lib/types/thread-types.js';
import { clusterEndHeight } from './chat-constants.js';
@@ -206,9 +209,15 @@
} = chatContext;
const loggedInUserInfo = useLoggedInUserInfo();
+ const chatMentionCandidatesObj = useChatMentionCandidatesObj();
const sidebarThreadInfo = React.useMemo(
- () => getUnresolvedSidebarThreadInfo({ sourceMessage, loggedInUserInfo }),
- [sourceMessage, loggedInUserInfo],
+ () =>
+ getUnresolvedSidebarThreadInfo({
+ sourceMessage,
+ loggedInUserInfo,
+ chatMentionCandidatesObj,
+ }),
+ [sourceMessage, loggedInUserInfo, chatMentionCandidatesObj],
);
const currentInputBarHeight =
diff --git a/native/markdown/markdown-chat-mention.react.js b/native/markdown/markdown-chat-mention.react.js
new file mode 100644
--- /dev/null
+++ b/native/markdown/markdown-chat-mention.react.js
@@ -0,0 +1,35 @@
+// @flow
+
+import * as React from 'react';
+import { Text } from 'react-native';
+
+import type { ResolvedThreadInfo } from 'lib/types/thread-types.js';
+
+import {
+ useMarkdownOnPressUtils,
+ useHandleChatMentionClick,
+} from './markdown-utils.js';
+
+type TextProps = React.ElementConfig<typeof Text>;
+type Props = {
+ +threadInfo: ResolvedThreadInfo,
+ +hasAccessToChat: boolean,
+ +children: React.Node,
+ ...TextProps,
+};
+function MarkdownChatMention(props: Props): React.Node {
+ const { threadInfo, hasAccessToChat, style, ...rest } = props;
+ const { messageKey, shouldBePressable, onLongPressHandler } =
+ useMarkdownOnPressUtils(!hasAccessToChat);
+ const onPressHandler = useHandleChatMentionClick(threadInfo, messageKey);
+ return (
+ <Text
+ onPress={shouldBePressable ? onPressHandler : null}
+ onLongPress={shouldBePressable ? onLongPressHandler : null}
+ style={hasAccessToChat ? style : null}
+ {...rest}
+ />
+ );
+}
+
+export default MarkdownChatMention;
diff --git a/native/markdown/markdown-utils.js b/native/markdown/markdown-utils.js
--- a/native/markdown/markdown-utils.js
+++ b/native/markdown/markdown-utils.js
@@ -5,12 +5,14 @@
import { Linking } from 'react-native';
import { inviteLinkUrl } from 'lib/facts/links.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
import {
MarkdownContext,
type MarkdownContextType,
} from './markdown-context.js';
import { MarkdownSpoilerContext } from './markdown-spoiler-context.js';
+import { useNavigateToThreadWithFadeAnimation } from '../chat/message-list-types.js';
import { MessagePressResponderContext } from '../chat/message-press-responder-context.js';
import { TextMessageMarkdownContext } from '../chat/text-message-markdown-context.js';
import { InviteLinksContext } from '../invite-links/invite-links-context-provider.react.js';
@@ -101,4 +103,19 @@
]);
}
-export { useMarkdownOnPressUtils, useHandleLinkClick };
+function useHandleChatMentionClick(
+ threadInfo: ThreadInfo,
+ messageKey: ?string,
+): () => mixed {
+ const navigateToThreadWithFadeAnimation =
+ useNavigateToThreadWithFadeAnimation(threadInfo, messageKey);
+ return React.useCallback(() => {
+ navigateToThreadWithFadeAnimation();
+ }, [navigateToThreadWithFadeAnimation]);
+}
+
+export {
+ useMarkdownOnPressUtils,
+ useHandleLinkClick,
+ useHandleChatMentionClick,
+};
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
@@ -6,7 +6,11 @@
import * as SimpleMarkdown from 'simple-markdown';
import * as SharedMarkdown from 'lib/shared/markdown.js';
-import type { RelativeMemberInfo, ThreadInfo } from 'lib/types/thread-types.js';
+import type {
+ RelativeMemberInfo,
+ ThreadInfo,
+ ChatMentionCandidates,
+} from 'lib/types/thread-types.js';
import MarkdownLink from './markdown-link.react.js';
import MarkdownParagraph from './markdown-paragraph.react.js';
@@ -353,19 +357,21 @@
function useTextMessageRulesFunc(
threadInfo: ThreadInfo,
+ chatMentionCandidates: ChatMentionCandidates,
): (useDarkStyle: boolean) => MarkdownRules {
const { members } = threadInfo;
return React.useMemo(
() =>
_memoize<[boolean], MarkdownRules>((useDarkStyle: boolean) =>
- textMessageRules(members, useDarkStyle),
+ textMessageRules(members, chatMentionCandidates, useDarkStyle),
),
- [members],
+ [members, chatMentionCandidates],
);
}
function textMessageRules(
members: $ReadOnlyArray<RelativeMemberInfo>,
+ chatMentionCandidates: ChatMentionCandidates,
useDarkStyle: boolean,
): MarkdownRules {
const styles = getMarkdownStyles(useDarkStyle ? 'dark' : 'light');
@@ -395,8 +401,10 @@
};
}
-const getDefaultTextMessageRules: () => MarkdownRules = _memoize(() =>
- textMessageRules([], false),
+const getDefaultTextMessageRules: (
+ overrideDefaultChatMentionCandidates?: ChatMentionCandidates,
+) => MarkdownRules = _memoize((overrideDefaultChatMentionCandidates = {}) =>
+ textMessageRules([], overrideDefaultChatMentionCandidates, false),
);
export {

File Metadata

Mime Type
text/plain
Expires
Tue, Dec 9, 11:38 PM (15 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5858804
Default Alt Text
D8845.1765323538.diff (15 KB)

Event Timeline