Skip to content

Commit

Permalink
Merge pull request Expensify#49682 from daledah/fix/49517
Browse files Browse the repository at this point in the history
  • Loading branch information
luacmartins authored Sep 26, 2024
2 parents b655040 + 722afaf commit 15d5641
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 44 deletions.
2 changes: 1 addition & 1 deletion src/components/LHNOptionsList/OptionRowLHN.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti
shiftHorizontal={variables.gbrTooltipShiftHorizontal}
shiftVertical={variables.composerTooltipShiftVertical}
wrapperStyle={styles.quickActionTooltipWrapper}
onPressOverlay={() => User.dismissGBRTooltip()}
onHideTooltip={() => User.dismissGBRTooltip()}
>
<View>
<Hoverable>
Expand Down
5 changes: 5 additions & 0 deletions src/components/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,9 @@ type MenuItemBaseProps = {

/** Should selected item be marked with checkmark */
shouldShowSelectedItemCheck?: boolean;

/** Handles what to do when hiding the tooltip */
onHideTooltip?: () => void;
};

type MenuItemProps = (IconProps | AvatarProps | NoIcon) & MenuItemBaseProps;
Expand Down Expand Up @@ -428,6 +431,7 @@ function MenuItem(
tooltipShiftVertical = 0,
renderTooltipContent,
shouldShowSelectedItemCheck = false,
onHideTooltip,
}: MenuItemProps,
ref: PressableRef,
) {
Expand Down Expand Up @@ -559,6 +563,7 @@ function MenuItem(
shiftHorizontal={tooltipShiftHorizontal}
shiftVertical={tooltipShiftVertical}
shouldAutoDismiss
onHideTooltip={onHideTooltip}
>
<View>
<Hoverable>
Expand Down
4 changes: 2 additions & 2 deletions src/components/Tooltip/BaseGenericTooltip/index.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function BaseGenericTooltip({
},
wrapperStyle = {},
shouldUseOverlay = false,
onPressOverlay = () => {},
onHideTooltip = () => {},
}: BaseGenericTooltipProps) {
// The width of tooltip's inner content. Has to be undefined in the beginning
// as a width of 0 will cause the content to be rendered of a width of 0,
Expand Down Expand Up @@ -102,7 +102,7 @@ function BaseGenericTooltip({

return (
<Portal hostName={!shouldUseOverlay ? 'modal' : undefined}>
{shouldUseOverlay && <TransparentOverlay onPress={onPressOverlay} />}
{shouldUseOverlay && <TransparentOverlay onPress={onHideTooltip} />}
<Animated.View
ref={rootWrapper}
style={[rootWrapperStyle, animationStyle]}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Tooltip/BaseGenericTooltip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function BaseGenericTooltip({
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.BOTTOM,
},
shouldUseOverlay = false,
onPressOverlay = () => {},
onHideTooltip = () => {},
}: BaseGenericTooltipProps) {
// The width of tooltip's inner content. Has to be undefined in the beginning
// as a width of 0 will cause the content to be rendered of a width of 0,
Expand Down Expand Up @@ -119,7 +119,7 @@ function BaseGenericTooltip({

return ReactDOM.createPortal(
<>
{shouldUseOverlay && <TransparentOverlay onPress={onPressOverlay} />}
{shouldUseOverlay && <TransparentOverlay onPress={onHideTooltip} />}
<Animated.View
ref={viewRef(rootWrapper)}
style={[rootWrapperStyle, animationStyle]}
Expand Down
5 changes: 4 additions & 1 deletion src/components/Tooltip/BaseGenericTooltip/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ type BaseGenericTooltipProps = {
/** Any additional amount to manually adjust the vertical position of the tooltip.
A positive value shifts the tooltip down, and a negative value shifts it up. */
shiftVertical?: number;

/** Handles what to do when hiding the tooltip */
onHideTooltip?: () => void;
} & Pick<
SharedTooltipProps,
'renderTooltipContent' | 'maxWidth' | 'numberOfLines' | 'text' | 'shouldForceRenderingBelow' | 'wrapperStyle' | 'anchorAlignment' | 'shouldUseOverlay' | 'onPressOverlay'
'renderTooltipContent' | 'maxWidth' | 'numberOfLines' | 'text' | 'shouldForceRenderingBelow' | 'wrapperStyle' | 'anchorAlignment' | 'shouldUseOverlay' | 'onHideTooltip'
>;

// eslint-disable-next-line import/prefer-default-export
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React, {memo, useEffect, useRef, useState} from 'react';
import type {LayoutRectangle, NativeSyntheticEvent} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import GenericTooltip from '@components/Tooltip/GenericTooltip';
import type {EducationalTooltipProps} from '@components/Tooltip/types';
import ONYXKEYS from '@src/ONYXKEYS';
import measureTooltipCoordinate from './measureTooltipCoordinate';

type LayoutChangeEventWithTarget = NativeSyntheticEvent<{layout: LayoutRectangle; target: HTMLElement}>;
Expand All @@ -10,11 +12,14 @@ type LayoutChangeEventWithTarget = NativeSyntheticEvent<{layout: LayoutRectangle
* A component used to wrap an element intended for displaying a tooltip.
* This tooltip would show immediately without user's interaction and hide after 5 seconds.
*/
function BaseEducationalTooltip({children, shouldAutoDismiss = false, shouldRender = false, ...props}: EducationalTooltipProps) {
function BaseEducationalTooltip({children, onHideTooltip, shouldAutoDismiss = false, ...props}: EducationalTooltipProps) {
const hideTooltipRef = useRef<() => void>();

const [shouldMeasure, setShouldMeasure] = useState(false);
const show = useRef<() => void>();
const [modal] = useOnyx(ONYXKEYS.MODAL);

const shouldShow = !modal?.willAlertModalBecomeVisible && !modal?.isVisible;

useEffect(
() => () => {
Expand All @@ -33,27 +38,38 @@ function BaseEducationalTooltip({children, shouldAutoDismiss = false, shouldRend
return;
}

const timerID = setTimeout(hideTooltipRef.current, 5000);
// If the modal is open, hide the tooltip immediately and clear the timeout
if (!shouldShow) {
hideTooltipRef.current();
return;
}

// Automatically hide tooltip after 5 seconds if shouldAutoDismiss is true
const timerID = setTimeout(() => {
hideTooltipRef.current?.();
onHideTooltip?.();
}, 5000);
return () => {
clearTimeout(timerID);
};
}, [shouldAutoDismiss]);
}, [shouldAutoDismiss, shouldShow, onHideTooltip]);

useEffect(() => {
if (!shouldRender || !shouldMeasure) {
if (!shouldMeasure || !shouldShow) {
return;
}
// When tooltip is used inside an animated view (e.g. popover), we need to wait for the animation to finish before measuring content.
setTimeout(() => {
show.current?.();
}, 500);
}, [shouldMeasure, shouldRender]);
}, [shouldMeasure, shouldShow]);

return (
<GenericTooltip
shouldForceAnimate
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
onHideTooltip={onHideTooltip}
>
{({showTooltip, hideTooltip, updateTargetBounds}) => {
// eslint-disable-next-line react-compiler/react-compiler
Expand Down
6 changes: 5 additions & 1 deletion src/components/Tooltip/EducationalTooltip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import React from 'react';
import type {TooltipExtendedProps} from '@components/Tooltip/types';
import BaseEducationalTooltip from './BaseEducationalTooltip';

function EducationalTooltip({children, ...props}: TooltipExtendedProps) {
function EducationalTooltip({children, shouldRender = false, ...props}: TooltipExtendedProps) {
if (!shouldRender) {
return children;
}

return (
<BaseEducationalTooltip
// eslint-disable-next-line react/jsx-props-no-spreading
Expand Down
8 changes: 4 additions & 4 deletions src/components/Tooltip/GenericTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function GenericTooltip({
},
shouldForceAnimate = false,
shouldUseOverlay: shouldUseOverlayProp = false,
onPressOverlay: onPressOverlayProp = () => {},
onHideTooltip = () => {},
}: GenericTooltipProps) {
const {preferredLocale} = useLocalize();
const {windowWidth} = useWindowDimensions();
Expand Down Expand Up @@ -150,8 +150,8 @@ function GenericTooltip({
}
setShouldUseOverlay(false);
hideTooltip();
onPressOverlayProp();
}, [shouldUseOverlay, onPressOverlayProp, hideTooltip]);
onHideTooltip();
}, [shouldUseOverlay, onHideTooltip, hideTooltip]);

useImperativeHandle(TooltipRefManager.ref, () => ({hideTooltip}), [hideTooltip]);

Expand Down Expand Up @@ -183,7 +183,7 @@ function GenericTooltip({
wrapperStyle={wrapperStyle}
anchorAlignment={anchorAlignment}
shouldUseOverlay={shouldUseOverlay}
onPressOverlay={onPressOverlay}
onHideTooltip={onPressOverlay}
/>
)}

Expand Down
4 changes: 2 additions & 2 deletions src/components/Tooltip/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ type SharedTooltipProps = {
/** Should render a fullscreen transparent overlay */
shouldUseOverlay?: boolean;

/** Callback to fire when the transparent overlay is pressed */
onPressOverlay?: () => void;
/** Handles what to do when hiding the tooltip */
onHideTooltip?: () => void;
};

type GenericTooltipState = {
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Search/SearchTypeMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ function SearchTypeMenu({queryJSON}: SearchTypeMenuProps) {
tooltipShiftHorizontal: -32,
tooltipShiftVertical: 15,
tooltipWrapperStyle: [styles.bgPaleGreen, styles.mh4, styles.pv2],
onHideTooltip: () => SearchActions.dismissSavedSearchRenameTooltip(),
renderTooltipContent: () => {
SearchActions.dismissSavedSearchRenameTooltip();
return (
<View style={[styles.flexRow, styles.alignItemsCenter]}>
<Expensicons.Lightbulb
Expand Down
31 changes: 6 additions & 25 deletions src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 're
import type {MeasureInWindowOnSuccessCallback, NativeSyntheticEvent, TextInputFocusEventData, TextInputSelectionChangeEventData} from 'react-native';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import {useOnyx} from 'react-native-onyx';
import {runOnUI, useSharedValue} from 'react-native-reanimated';
import type {Emoji} from '@assets/emojis/types';
import type {FileObject} from '@components/AttachmentModal';
Expand Down Expand Up @@ -63,16 +63,7 @@ type SuggestionsRef = {
getIsSuggestionsMenuVisible: () => boolean;
};

type ReportActionComposeOnyxProps = {
/** The NVP describing a user's block status */
blockedFromConcierge: OnyxEntry<OnyxTypes.BlockedFromConcierge>;

/** Whether the composer input should be shown */
shouldShowComposeInput: OnyxEntry<boolean>;
};

type ReportActionComposeProps = ReportActionComposeOnyxProps &
WithCurrentUserPersonalDetailsProps &
type ReportActionComposeProps = WithCurrentUserPersonalDetailsProps &
Pick<ComposerWithSuggestionsProps, 'reportID' | 'isEmptyChat' | 'isComposerFullSize' | 'lastReportAction'> & {
/** A method to call when the form is submitted */
onSubmit: (newComment: string) => void;
Expand Down Expand Up @@ -109,15 +100,13 @@ const willBlurTextInputOnTapOutside = willBlurTextInputOnTapOutsideFunc();
let onSubmitAction = noop;

function ReportActionCompose({
blockedFromConcierge,
currentUserPersonalDetails,
disabled = false,
isComposerFullSize = false,
onSubmit,
pendingAction,
report,
reportID,
shouldShowComposeInput = true,
isReportReadyForDisplay = true,
isEmptyChat,
lastReportAction,
Expand All @@ -133,7 +122,8 @@ function ReportActionCompose({
const actionButtonRef = useRef<View | HTMLDivElement | null>(null);
const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT;
const navigation = useNavigation();

const [blockedFromConcierge] = useOnyx(ONYXKEYS.NVP_BLOCKED_FROM_CONCIERGE);
const [shouldShowComposeInput = true] = useOnyx(ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT);
/**
* Updates the Highlight state of the composer
*/
Expand Down Expand Up @@ -425,7 +415,7 @@ function ReportActionCompose({
shouldRender={!shouldHideEducationalTooltip && shouldShowEducationalTooltip}
renderTooltipContent={renderWorkspaceChatTooltip}
shouldUseOverlay
onPressOverlay={() => User.dismissWorkspaceTooltip()}
onHideTooltip={() => User.dismissWorkspaceTooltip()}
anchorAlignment={{
horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT,
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.BOTTOM,
Expand Down Expand Up @@ -571,15 +561,6 @@ function ReportActionCompose({

ReportActionCompose.displayName = 'ReportActionCompose';

export default withCurrentUserPersonalDetails(
withOnyx<ReportActionComposeProps, ReportActionComposeOnyxProps>({
blockedFromConcierge: {
key: ONYXKEYS.NVP_BLOCKED_FROM_CONCIERGE,
},
shouldShowComposeInput: {
key: ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT,
},
})(memo(ReportActionCompose)),
);
export default withCurrentUserPersonalDetails(memo(ReportActionCompose));
export {onSubmitAction};
export type {SuggestionsRef, ComposerRef};

0 comments on commit 15d5641

Please sign in to comment.