Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3496784
D6454.id21797.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
15 KB
Referenced Files
None
Subscribers
None
D6454.id21797.diff
View Options
diff --git a/native/chat/multimedia-message-tooltip-button.react.js b/native/chat/multimedia-message-tooltip-button.react.js
--- a/native/chat/multimedia-message-tooltip-button.react.js
+++ b/native/chat/multimedia-message-tooltip-button.react.js
@@ -3,12 +3,21 @@
import * as React from 'react';
import Animated from 'react-native-reanimated';
+import { localIDPrefix } from 'lib/shared/message-utils';
+import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils';
+import type { SetState } from 'lib/types/hook-types';
+
import type { AppNavigationProp } from '../navigation/app-navigator.react';
import type { TooltipRoute } from '../navigation/tooltip.react';
import { useSelector } from '../redux/redux-utils';
import { TooltipInlineEngagement } from './inline-engagement.react';
import { InnerMultimediaMessage } from './inner-multimedia-message.react';
import { MessageHeader } from './message-header.react';
+import {
+ useSendReaction,
+ useReactionSelectionPopoverPosition,
+} from './reaction-message-utils';
+import ReactionSelectionPopover from './reaction-selection-popover.react';
import SidebarInputBarHeightMeasurer from './sidebar-input-bar-height-measurer.react';
import { useAnimatedMessageTooltipButton } from './utils';
@@ -23,10 +32,12 @@
+route: TooltipRoute<'MultimediaMessageTooltipModal'>,
+progress: Node,
+isOpeningSidebar: boolean,
+ +setHideTooltip: SetState<boolean>,
};
function MultimediaMessageTooltipButton(props: Props): React.Node {
+ const { navigation, progress, isOpeningSidebar, setHideTooltip } = props;
+
const windowWidth = useSelector(state => state.dimensions.width);
- const { progress } = props;
const [
sidebarInputBarHeight,
@@ -36,7 +47,13 @@
setSidebarInputBarHeight(height);
}, []);
- const { item, verticalBounds, initialCoordinates } = props.route.params;
+ const {
+ item,
+ verticalBounds,
+ initialCoordinates,
+ margin,
+ } = props.route.params;
+
const { style: messageContainerStyle } = useAnimatedMessageTooltipButton({
sourceMessage: item,
initialCoordinates,
@@ -61,8 +78,6 @@
};
}, [initialCoordinates.height, initialCoordinates.x, progress, windowWidth]);
- const { navigation, isOpeningSidebar } = props;
-
const inlineEngagement = React.useMemo(() => {
if (!item.threadCreatedFromMessage) {
return null;
@@ -79,6 +94,49 @@
);
}, [initialCoordinates, isOpeningSidebar, item, progress, windowWidth]);
+ const { messageInfo, threadInfo, reactions } = item;
+ const nextLocalID = useSelector(state => state.nextLocalID);
+ const localID = `${localIDPrefix}${nextLocalID}`;
+
+ const canCreateReactionFromMessage = useCanCreateReactionFromMessage(
+ threadInfo,
+ messageInfo,
+ );
+
+ const sendReaction = useSendReaction(
+ messageInfo.id,
+ localID,
+ threadInfo.id,
+ reactions,
+ );
+
+ const reactionSelectionPopoverPosition = useReactionSelectionPopoverPosition({
+ initialCoordinates,
+ verticalBounds,
+ margin,
+ });
+
+ const reactionSelectionPopover = React.useMemo(() => {
+ if (!canCreateReactionFromMessage) {
+ return null;
+ }
+
+ return (
+ <ReactionSelectionPopover
+ setHideTooltip={setHideTooltip}
+ reactionSelectionPopoverContainerStyle={
+ reactionSelectionPopoverPosition
+ }
+ sendReaction={sendReaction}
+ />
+ );
+ }, [
+ canCreateReactionFromMessage,
+ reactionSelectionPopoverPosition,
+ sendReaction,
+ setHideTooltip,
+ ]);
+
return (
<Animated.View style={messageContainerStyle}>
<SidebarInputBarHeightMeasurer
@@ -88,6 +146,7 @@
<Animated.View style={headerStyle}>
<MessageHeader item={item} focused={true} display="modal" />
</Animated.View>
+ {reactionSelectionPopover}
<InnerMultimediaMessage
item={item}
verticalBounds={verticalBounds}
diff --git a/native/chat/reaction-selection-popover.react.js b/native/chat/reaction-selection-popover.react.js
new file mode 100644
--- /dev/null
+++ b/native/chat/reaction-selection-popover.react.js
@@ -0,0 +1,90 @@
+// @flow
+
+import * as React from 'react';
+import { View, TouchableOpacity, Text } from 'react-native';
+
+import type { SetState } from 'lib/types/hook-types';
+
+import { useStyles } from '../themes/colors';
+import type { ViewStyle } from '../types/styles';
+
+type ReactionSelectionPopoverProps = {
+ +setHideTooltip: SetState<boolean>,
+ +reactionSelectionPopoverContainerStyle: ViewStyle,
+ +sendReaction: (reaction: string) => mixed,
+};
+
+function ReactionSelectionPopover(
+ props: ReactionSelectionPopoverProps,
+): React.Node {
+ const {
+ setHideTooltip,
+ reactionSelectionPopoverContainerStyle,
+ sendReaction,
+ } = props;
+
+ const styles = useStyles(unboundStyles);
+
+ const containerStyle = React.useMemo(
+ () => [
+ styles.reactionSelectionPopoverContainer,
+ reactionSelectionPopoverContainerStyle,
+ ],
+ [
+ reactionSelectionPopoverContainerStyle,
+ styles.reactionSelectionPopoverContainer,
+ ],
+ );
+
+ const onPressDefaultEmoji = React.useCallback(
+ (emoji: string) => {
+ sendReaction(emoji);
+ setHideTooltip(true);
+ },
+ [sendReaction, setHideTooltip],
+ );
+
+ const defaultEmojis = React.useMemo(() => {
+ const defaultEmojisData = ['❤️', '😆', '😮', '😠', '👍'];
+
+ return defaultEmojisData.map(emoji => (
+ <TouchableOpacity key={emoji} onPress={() => onPressDefaultEmoji(emoji)}>
+ <View style={styles.reactionSelectionItemContainer}>
+ <Text style={styles.reactionSelectionItemEmoji}>{emoji}</Text>
+ </View>
+ </TouchableOpacity>
+ ));
+ }, [
+ onPressDefaultEmoji,
+ styles.reactionSelectionItemContainer,
+ styles.reactionSelectionItemEmoji,
+ ]);
+
+ return <View style={containerStyle}>{defaultEmojis}</View>;
+}
+
+const unboundStyles = {
+ reactionSelectionPopoverContainer: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ backgroundColor: 'tooltipBackground',
+ padding: 8,
+ borderRadius: 8,
+ flex: 1,
+ },
+ reactionSelectionItemContainer: {
+ backgroundColor: 'reactionSelectionPopoverItemBackground',
+ justifyContent: 'center',
+ alignItems: 'center',
+ padding: 8,
+ borderRadius: 20,
+ width: 40,
+ height: 40,
+ marginRight: 12,
+ },
+ reactionSelectionItemEmoji: {
+ fontSize: 18,
+ },
+};
+
+export default ReactionSelectionPopover;
diff --git a/native/chat/robotext-message-tooltip-button.react.js b/native/chat/robotext-message-tooltip-button.react.js
--- a/native/chat/robotext-message-tooltip-button.react.js
+++ b/native/chat/robotext-message-tooltip-button.react.js
@@ -3,11 +3,20 @@
import * as React from 'react';
import Animated from 'react-native-reanimated';
+import { localIDPrefix } from 'lib/shared/message-utils';
+import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils';
+import type { SetState } from 'lib/types/hook-types';
+
import type { AppNavigationProp } from '../navigation/app-navigator.react';
import type { TooltipRoute } from '../navigation/tooltip.react';
import { useSelector } from '../redux/redux-utils';
import { TooltipInlineEngagement } from './inline-engagement.react';
import { InnerRobotextMessage } from './inner-robotext-message.react';
+import {
+ useSendReaction,
+ useReactionSelectionPopoverPosition,
+} from './reaction-message-utils';
+import ReactionSelectionPopover from './reaction-selection-popover.react';
import SidebarInputBarHeightMeasurer from './sidebar-input-bar-height-measurer.react';
import { Timestamp } from './timestamp.react';
import { useAnimatedMessageTooltipButton } from './utils';
@@ -21,9 +30,11 @@
+route: TooltipRoute<'RobotextMessageTooltipModal'>,
+progress: Node,
+isOpeningSidebar: boolean,
+ +setHideTooltip: SetState<boolean>,
};
function RobotextMessageTooltipButton(props: Props): React.Node {
- const { progress } = props;
+ const { navigation, progress, isOpeningSidebar, setHideTooltip } = props;
+
const windowWidth = useSelector(state => state.dimensions.width);
const [
@@ -34,7 +45,13 @@
setSidebarInputBarHeight(height);
}, []);
- const { item, verticalBounds, initialCoordinates } = props.route.params;
+ const {
+ item,
+ verticalBounds,
+ initialCoordinates,
+ margin,
+ } = props.route.params;
+
const { style: messageContainerStyle } = useAnimatedMessageTooltipButton({
sourceMessage: item,
initialCoordinates,
@@ -59,8 +76,6 @@
};
}, [initialCoordinates.height, initialCoordinates.x, progress, windowWidth]);
- const { navigation, isOpeningSidebar } = props;
-
const inlineEngagement = React.useMemo(() => {
if (!item.threadCreatedFromMessage) {
return null;
@@ -77,6 +92,49 @@
);
}, [initialCoordinates, isOpeningSidebar, item, progress, windowWidth]);
+ const { messageInfo, threadInfo, reactions } = item;
+ const nextLocalID = useSelector(state => state.nextLocalID);
+ const localID = `${localIDPrefix}${nextLocalID}`;
+
+ const canCreateReactionFromMessage = useCanCreateReactionFromMessage(
+ threadInfo,
+ messageInfo,
+ );
+
+ const sendReaction = useSendReaction(
+ messageInfo.id,
+ localID,
+ threadInfo.id,
+ reactions,
+ );
+
+ const reactionSelectionPopoverPosition = useReactionSelectionPopoverPosition({
+ initialCoordinates,
+ verticalBounds,
+ margin,
+ });
+
+ const reactionSelectionPopover = React.useMemo(() => {
+ if (!canCreateReactionFromMessage) {
+ return null;
+ }
+
+ return (
+ <ReactionSelectionPopover
+ setHideTooltip={setHideTooltip}
+ reactionSelectionPopoverContainerStyle={
+ reactionSelectionPopoverPosition
+ }
+ sendReaction={sendReaction}
+ />
+ );
+ }, [
+ canCreateReactionFromMessage,
+ reactionSelectionPopoverPosition,
+ sendReaction,
+ setHideTooltip,
+ ]);
+
return (
<Animated.View style={messageContainerStyle}>
<SidebarInputBarHeightMeasurer
@@ -86,6 +144,7 @@
<Animated.View style={headerStyle}>
<Timestamp time={item.messageInfo.time} display="modal" />
</Animated.View>
+ {reactionSelectionPopover}
<InnerRobotextMessage item={item} onPress={navigation.goBackOnce} />
{inlineEngagement}
</Animated.View>
diff --git a/native/chat/text-message-tooltip-button.react.js b/native/chat/text-message-tooltip-button.react.js
--- a/native/chat/text-message-tooltip-button.react.js
+++ b/native/chat/text-message-tooltip-button.react.js
@@ -3,6 +3,10 @@
import * as React from 'react';
import Animated from 'react-native-reanimated';
+import { localIDPrefix } from 'lib/shared/message-utils';
+import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils';
+import type { SetState } from 'lib/types/hook-types';
+
import type { AppNavigationProp } from '../navigation/app-navigator.react';
import type { TooltipRoute } from '../navigation/tooltip.react';
import { useSelector } from '../redux/redux-utils';
@@ -11,6 +15,11 @@
import { MessageHeader } from './message-header.react';
import { MessageListContextProvider } from './message-list-types';
import { MessagePressResponderContext } from './message-press-responder-context';
+import {
+ useSendReaction,
+ useReactionSelectionPopoverPosition,
+} from './reaction-message-utils';
+import ReactionSelectionPopover from './reaction-selection-popover.react';
import SidebarInputBarHeightMeasurer from './sidebar-input-bar-height-measurer.react';
import { useAnimatedMessageTooltipButton } from './utils';
@@ -23,9 +32,11 @@
+route: TooltipRoute<'TextMessageTooltipModal'>,
+progress: Node,
+isOpeningSidebar: boolean,
+ +setHideTooltip: SetState<boolean>,
};
function TextMessageTooltipButton(props: Props): React.Node {
- const { progress } = props;
+ const { navigation, progress, isOpeningSidebar, setHideTooltip } = props;
+
const windowWidth = useSelector(state => state.dimensions.width);
const [
@@ -36,7 +47,13 @@
setSidebarInputBarHeight(height);
}, []);
- const { item, verticalBounds, initialCoordinates } = props.route.params;
+ const {
+ item,
+ verticalBounds,
+ initialCoordinates,
+ margin,
+ } = props.route.params;
+
const {
style: messageContainerStyle,
threadColorOverride,
@@ -66,7 +83,6 @@
}, [initialCoordinates.height, initialCoordinates.x, progress, windowWidth]);
const threadID = item.threadInfo.id;
- const { navigation, isOpeningSidebar } = props;
const messagePressResponderContext = React.useMemo(
() => ({
@@ -90,6 +106,50 @@
/>
);
}, [initialCoordinates, isOpeningSidebar, item, progress, windowWidth]);
+
+ const { messageInfo, threadInfo, reactions } = item;
+ const nextLocalID = useSelector(state => state.nextLocalID);
+ const localID = `${localIDPrefix}${nextLocalID}`;
+
+ const canCreateReactionFromMessage = useCanCreateReactionFromMessage(
+ threadInfo,
+ messageInfo,
+ );
+
+ const sendReaction = useSendReaction(
+ messageInfo.id,
+ localID,
+ threadInfo.id,
+ reactions,
+ );
+
+ const reactionSelectionPopoverPosition = useReactionSelectionPopoverPosition({
+ initialCoordinates,
+ verticalBounds,
+ margin,
+ });
+
+ const reactionSelectionPopover = React.useMemo(() => {
+ if (!canCreateReactionFromMessage) {
+ return null;
+ }
+
+ return (
+ <ReactionSelectionPopover
+ setHideTooltip={setHideTooltip}
+ reactionSelectionPopoverContainerStyle={
+ reactionSelectionPopoverPosition
+ }
+ sendReaction={sendReaction}
+ />
+ );
+ }, [
+ canCreateReactionFromMessage,
+ reactionSelectionPopoverPosition,
+ sendReaction,
+ setHideTooltip,
+ ]);
+
return (
<MessageListContextProvider threadID={threadID}>
<SidebarInputBarHeightMeasurer
@@ -100,6 +160,7 @@
<Animated.View style={headerStyle}>
<MessageHeader item={item} focused={true} display="modal" />
</Animated.View>
+ {reactionSelectionPopover}
<MessagePressResponderContext.Provider
value={messagePressResponderContext}
>
diff --git a/native/navigation/tooltip.react.js b/native/navigation/tooltip.react.js
--- a/native/navigation/tooltip.react.js
+++ b/native/navigation/tooltip.react.js
@@ -111,6 +111,7 @@
...Base,
+progress: Node,
+isOpeningSidebar: boolean,
+ +setHideTooltip: SetState<boolean>,
};
type TooltipProps<Base> = {
...Base,
@@ -510,6 +511,7 @@
...navAndRouteForFlow,
progress: position,
isOpeningSidebar,
+ setHideTooltip,
};
const itemsStyles = [styles.items, styles.itemsFixed];
diff --git a/native/themes/colors.js b/native/themes/colors.js
--- a/native/themes/colors.js
+++ b/native/themes/colors.js
@@ -68,6 +68,7 @@
panelSecondaryForegroundBorder: '#CCCCCC',
purpleLink: '#7E57C2',
purpleButton: '#7E57C2',
+ reactionSelectionPopoverItemBackground: '#404040',
redText: '#F53100',
spoiler: '#33332C',
tabBarAccent: '#7E57C2',
@@ -151,6 +152,7 @@
panelSecondaryForegroundBorder: '#666666',
purpleLink: '#AE94DB',
purpleButton: '#7E57C2',
+ reactionSelectionPopoverItemBackground: '#404040',
redText: '#F53100',
spoiler: '#33332C',
tabBarAccent: '#AE94DB',
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 20, 2:54 PM (16 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2681497
Default Alt Text
D6454.id21797.diff (15 KB)
Attached To
Mode
D6454: [native] introduce reaction selection popover component
Attached
Detach File
Event Timeline
Log In to Comment