diff --git a/native/chat/multimedia-message-tooltip-button.react.js b/native/chat/multimedia-message-tooltip-button.react.js index e5650a6a3..8a963916d 100644 --- a/native/chat/multimedia-message-tooltip-button.react.js +++ b/native/chat/multimedia-message-tooltip-button.react.js @@ -1,190 +1,177 @@ // @flow import * as React from 'react'; import Animated from 'react-native-reanimated'; import EmojiPicker from 'rn-emoji-keyboard'; import { localIDPrefix } from 'lib/shared/message-utils.js'; import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils.js'; import { TooltipInlineEngagement } from './inline-engagement.react.js'; import { InnerMultimediaMessage } from './inner-multimedia-message.react.js'; import { MessageHeader } from './message-header.react.js'; -import { - useSendReaction, - useReactionSelectionPopoverPosition, -} from './reaction-message-utils.js'; +import { useSendReaction } from './reaction-message-utils.js'; import ReactionSelectionPopover from './reaction-selection-popover.react.js'; import SidebarInputBarHeightMeasurer from './sidebar-input-bar-height-measurer.react.js'; import { useAnimatedMessageTooltipButton } from './utils.js'; import type { AppNavigationProp } from '../navigation/app-navigator.react.js'; import { useSelector } from '../redux/redux-utils.js'; import { useTooltipActions } from '../tooltip/tooltip-hooks.js'; import type { TooltipRoute } from '../tooltip/tooltip.react.js'; /* eslint-disable import/no-named-as-default-member */ const { Node, Extrapolate, interpolateNode } = Animated; /* eslint-enable import/no-named-as-default-member */ function noop() {} type Props = { +navigation: AppNavigationProp<'MultimediaMessageTooltipModal'>, +route: TooltipRoute<'MultimediaMessageTooltipModal'>, +progress: Node, +isOpeningSidebar: boolean, }; function MultimediaMessageTooltipButton(props: Props): React.Node { const { navigation, route, progress, isOpeningSidebar } = props; const windowWidth = useSelector(state => state.dimensions.width); const [sidebarInputBarHeight, setSidebarInputBarHeight] = React.useState(null); const onInputBarMeasured = React.useCallback((height: number) => { setSidebarInputBarHeight(height); }, []); - const { item, verticalBounds, initialCoordinates, margin } = route.params; + const { item, verticalBounds, initialCoordinates } = route.params; const { style: messageContainerStyle } = useAnimatedMessageTooltipButton({ sourceMessage: item, initialCoordinates, messageListVerticalBounds: verticalBounds, progress, targetInputBarHeight: sidebarInputBarHeight, }); const headerStyle = React.useMemo(() => { const bottom = initialCoordinates.height; const opacity = interpolateNode(progress, { inputRange: [0, 0.05], outputRange: [0, 1], extrapolate: Extrapolate.CLAMP, }); return { opacity, position: 'absolute', left: -initialCoordinates.x, width: windowWidth, bottom, }; }, [initialCoordinates.height, initialCoordinates.x, progress, windowWidth]); const inlineEngagement = React.useMemo(() => { if (!item.threadCreatedFromMessage) { return null; } return ( ); }, [initialCoordinates, isOpeningSidebar, item, progress, windowWidth]); const innerMultimediaMessage = React.useMemo( () => ( ), [item, navigation.goBackOnce, verticalBounds], ); 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 [emojiPickerOpen, setEmojiPickerOpen] = React.useState(false); const openEmojiPicker = React.useCallback(() => { setEmojiPickerOpen(true); }, []); const reactionSelectionPopover = React.useMemo(() => { if (!canCreateReactionFromMessage) { return null; } return ( ); }, [ navigation, route, openEmojiPicker, canCreateReactionFromMessage, - reactionSelectionPopoverPosition, sendReaction, ]); const tooltipRouteKey = route.key; const { dismissTooltip } = useTooltipActions(navigation, tooltipRouteKey); const onEmojiSelected = React.useCallback( emoji => { sendReaction(emoji.emoji); dismissTooltip(); }, [sendReaction, dismissTooltip], ); return ( <> {reactionSelectionPopover} {innerMultimediaMessage} {inlineEngagement} ); } export default MultimediaMessageTooltipButton; diff --git a/native/chat/reaction-selection-popover.react.js b/native/chat/reaction-selection-popover.react.js index a27c3aaba..98f5452a3 100644 --- a/native/chat/reaction-selection-popover.react.js +++ b/native/chat/reaction-selection-popover.react.js @@ -1,129 +1,130 @@ // @flow import * as React from 'react'; import { View, TouchableOpacity, Text } from 'react-native'; +import { useReactionSelectionPopoverPosition } from './reaction-message-utils.js'; import SWMansionIcon from '../components/swmansion-icon.react.js'; import type { AppNavigationProp } from '../navigation/app-navigator.react.js'; import type { TooltipModalParamList } from '../navigation/route-names.js'; import { useStyles } from '../themes/colors.js'; import { useTooltipActions } from '../tooltip/tooltip-hooks.js'; import type { TooltipRoute } from '../tooltip/tooltip.react.js'; -import type { ViewStyle } from '../types/styles.js'; type Props> = { +navigation: AppNavigationProp, +route: TooltipRoute, +openEmojiPicker: () => mixed, - +reactionSelectionPopoverContainerStyle: ViewStyle, +sendReaction: (reaction: string) => mixed, }; function ReactionSelectionPopover>( props: Props, ): React.Node { - const { - navigation, - route, - openEmojiPicker, - reactionSelectionPopoverContainerStyle, - sendReaction, - } = props; + const { navigation, route, openEmojiPicker, sendReaction } = props; + + const { verticalBounds, initialCoordinates, margin } = route.params; + const reactionSelectionPopoverContainerStyle = + useReactionSelectionPopoverPosition({ + initialCoordinates, + verticalBounds, + margin, + }); const styles = useStyles(unboundStyles); const containerStyle = React.useMemo( () => [ styles.reactionSelectionPopoverContainer, reactionSelectionPopoverContainerStyle, ], [ reactionSelectionPopoverContainerStyle, styles.reactionSelectionPopoverContainer, ], ); const tooltipRouteKey = route.key; const { hideTooltip, dismissTooltip } = useTooltipActions( navigation, tooltipRouteKey, ); const onPressDefaultEmoji = React.useCallback( (emoji: string) => { sendReaction(emoji); dismissTooltip(); }, [sendReaction, dismissTooltip], ); const onPressEmojiKeyboardButton = React.useCallback(() => { openEmojiPicker(); hideTooltip(); }, [openEmojiPicker, hideTooltip]); const defaultEmojis = React.useMemo(() => { const defaultEmojisData = ['❤️', '😆', '😮', '😠', '👍']; return defaultEmojisData.map(emoji => ( onPressDefaultEmoji(emoji)}> {emoji} )); }, [ onPressDefaultEmoji, styles.reactionSelectionItemContainer, styles.reactionSelectionItemEmoji, ]); return ( {defaultEmojis} ); } 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, }, emojiKeyboardButtonContainer: { backgroundColor: 'reactionSelectionPopoverItemBackground', justifyContent: 'center', alignItems: 'center', padding: 8, borderRadius: 20, width: 40, height: 40, }, icon: { color: 'modalForegroundLabel', }, }; export default ReactionSelectionPopover; diff --git a/native/chat/robotext-message-tooltip-button.react.js b/native/chat/robotext-message-tooltip-button.react.js index 43e72240f..a1ea482b7 100644 --- a/native/chat/robotext-message-tooltip-button.react.js +++ b/native/chat/robotext-message-tooltip-button.react.js @@ -1,174 +1,161 @@ // @flow import * as React from 'react'; import Animated from 'react-native-reanimated'; import EmojiPicker from 'rn-emoji-keyboard'; import { localIDPrefix } from 'lib/shared/message-utils.js'; import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils.js'; import { TooltipInlineEngagement } from './inline-engagement.react.js'; import { InnerRobotextMessage } from './inner-robotext-message.react.js'; -import { - useSendReaction, - useReactionSelectionPopoverPosition, -} from './reaction-message-utils.js'; +import { useSendReaction } from './reaction-message-utils.js'; import ReactionSelectionPopover from './reaction-selection-popover.react.js'; import SidebarInputBarHeightMeasurer from './sidebar-input-bar-height-measurer.react.js'; import { Timestamp } from './timestamp.react.js'; import { useAnimatedMessageTooltipButton } from './utils.js'; import type { AppNavigationProp } from '../navigation/app-navigator.react.js'; import { useSelector } from '../redux/redux-utils.js'; import { useTooltipActions } from '../tooltip/tooltip-hooks.js'; import type { TooltipRoute } from '../tooltip/tooltip.react.js'; /* eslint-disable import/no-named-as-default-member */ const { Node, interpolateNode, Extrapolate } = Animated; /* eslint-enable import/no-named-as-default-member */ type Props = { +navigation: AppNavigationProp<'RobotextMessageTooltipModal'>, +route: TooltipRoute<'RobotextMessageTooltipModal'>, +progress: Node, +isOpeningSidebar: boolean, }; function RobotextMessageTooltipButton(props: Props): React.Node { const { navigation, route, progress, isOpeningSidebar } = props; const windowWidth = useSelector(state => state.dimensions.width); const [sidebarInputBarHeight, setSidebarInputBarHeight] = React.useState(null); const onInputBarMeasured = React.useCallback((height: number) => { setSidebarInputBarHeight(height); }, []); - const { item, verticalBounds, initialCoordinates, margin } = route.params; + const { item, verticalBounds, initialCoordinates } = route.params; const { style: messageContainerStyle } = useAnimatedMessageTooltipButton({ sourceMessage: item, initialCoordinates, messageListVerticalBounds: verticalBounds, progress, targetInputBarHeight: sidebarInputBarHeight, }); const headerStyle = React.useMemo(() => { const bottom = initialCoordinates.height; const opacity = interpolateNode(progress, { inputRange: [0, 0.05], outputRange: [0, 1], extrapolate: Extrapolate.CLAMP, }); return { opacity, position: 'absolute', left: -initialCoordinates.x, width: windowWidth, bottom, }; }, [initialCoordinates.height, initialCoordinates.x, progress, windowWidth]); const inlineEngagement = React.useMemo(() => { if (!item.threadCreatedFromMessage) { return null; } return ( ); }, [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 [emojiPickerOpen, setEmojiPickerOpen] = React.useState(false); const openEmojiPicker = React.useCallback(() => { setEmojiPickerOpen(true); }, []); const reactionSelectionPopover = React.useMemo(() => { if (!canCreateReactionFromMessage) { return null; } return ( ); }, [ navigation, route, openEmojiPicker, canCreateReactionFromMessage, - reactionSelectionPopoverPosition, sendReaction, ]); const tooltipRouteKey = route.key; const { dismissTooltip } = useTooltipActions(navigation, tooltipRouteKey); const onEmojiSelected = React.useCallback( emoji => { sendReaction(emoji.emoji); dismissTooltip(); }, [sendReaction, dismissTooltip], ); return ( <> {reactionSelectionPopover} {inlineEngagement} ); } export default RobotextMessageTooltipButton; diff --git a/native/chat/text-message-tooltip-button.react.js b/native/chat/text-message-tooltip-button.react.js index ffcf5fd0c..719537cf2 100644 --- a/native/chat/text-message-tooltip-button.react.js +++ b/native/chat/text-message-tooltip-button.react.js @@ -1,196 +1,183 @@ // @flow import * as React from 'react'; import Animated from 'react-native-reanimated'; import EmojiPicker from 'rn-emoji-keyboard'; import { localIDPrefix } from 'lib/shared/message-utils.js'; import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils.js'; import { TooltipInlineEngagement } from './inline-engagement.react.js'; import { InnerTextMessage } from './inner-text-message.react.js'; import { MessageHeader } from './message-header.react.js'; import { MessageListContextProvider } from './message-list-types.js'; import { MessagePressResponderContext } from './message-press-responder-context.js'; -import { - useSendReaction, - useReactionSelectionPopoverPosition, -} from './reaction-message-utils.js'; +import { useSendReaction } from './reaction-message-utils.js'; import ReactionSelectionPopover from './reaction-selection-popover.react.js'; import SidebarInputBarHeightMeasurer from './sidebar-input-bar-height-measurer.react.js'; import { useAnimatedMessageTooltipButton } from './utils.js'; import type { AppNavigationProp } from '../navigation/app-navigator.react.js'; import { useSelector } from '../redux/redux-utils.js'; import { useTooltipActions } from '../tooltip/tooltip-hooks.js'; import type { TooltipRoute } from '../tooltip/tooltip.react.js'; /* eslint-disable import/no-named-as-default-member */ const { Node, interpolateNode, Extrapolate } = Animated; /* eslint-enable import/no-named-as-default-member */ type Props = { +navigation: AppNavigationProp<'TextMessageTooltipModal'>, +route: TooltipRoute<'TextMessageTooltipModal'>, +progress: Node, +isOpeningSidebar: boolean, }; function TextMessageTooltipButton(props: Props): React.Node { const { navigation, route, progress, isOpeningSidebar } = props; const windowWidth = useSelector(state => state.dimensions.width); const [sidebarInputBarHeight, setSidebarInputBarHeight] = React.useState(null); const onInputBarMeasured = React.useCallback((height: number) => { setSidebarInputBarHeight(height); }, []); - const { item, verticalBounds, initialCoordinates, margin } = route.params; + const { item, verticalBounds, initialCoordinates } = route.params; const { style: messageContainerStyle, threadColorOverride, isThreadColorDarkOverride, } = useAnimatedMessageTooltipButton({ sourceMessage: item, initialCoordinates, messageListVerticalBounds: verticalBounds, progress, targetInputBarHeight: sidebarInputBarHeight, }); const headerStyle = React.useMemo(() => { const bottom = initialCoordinates.height; const opacity = interpolateNode(progress, { inputRange: [0, 0.05], outputRange: [0, 1], extrapolate: Extrapolate.CLAMP, }); return { opacity, position: 'absolute', left: -initialCoordinates.x, width: windowWidth, bottom, }; }, [initialCoordinates.height, initialCoordinates.x, progress, windowWidth]); const messagePressResponderContext = React.useMemo( () => ({ onPressMessage: navigation.goBackOnce, }), [navigation.goBackOnce], ); const inlineEngagement = React.useMemo(() => { if (!item.threadCreatedFromMessage) { return null; } return ( ); }, [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 [emojiPickerOpen, setEmojiPickerOpen] = React.useState(false); const openEmojiPicker = React.useCallback(() => { setEmojiPickerOpen(true); }, []); const reactionSelectionPopover = React.useMemo(() => { if (!canCreateReactionFromMessage) { return null; } return ( ); }, [ navigation, route, openEmojiPicker, canCreateReactionFromMessage, - reactionSelectionPopoverPosition, sendReaction, ]); const tooltipRouteKey = route.key; const { dismissTooltip } = useTooltipActions(navigation, tooltipRouteKey); const onEmojiSelected = React.useCallback( emoji => { sendReaction(emoji.emoji); dismissTooltip(); }, [sendReaction, dismissTooltip], ); return ( {reactionSelectionPopover} {inlineEngagement} ); } export default TextMessageTooltipButton;