Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[$500] Make it possible to click the element the product training tooltip is pointing to. #54068

Open
ishpaul777 opened this issue Dec 12, 2024 · 19 comments
Assignees
Labels
Daily KSv2 External Added to denote the issue can be worked on by a contributor Help Wanted Apply this label when an issue is open to proposals by contributors NewFeature Something to build that is a new item.

Comments

@ishpaul777
Copy link
Contributor

ishpaul777 commented Dec 12, 2024

Part of the Migrate Existing Users to NewDot project

Main issue: https://github.com/Expensify/Expensify/issues/437980
Doc section: https://docs.google.com/document/d/1m8e1ASwG70t651qSO6OfsSvW18RFrcWkO897iUllDLs/edit?tab=t.0#heading=h.yh89nmhpipyt
Project:

Feature Description

Make it possible to click the element the product training tooltip is pointing to.

Ideal Expected Behaviour:

  1. you should be able to interact with anything on the screen. The presence of a tooltip shouldn't change what you can do
  2. you should be able to click the element the tooltip is pointing to
  3. the tooltip should remain until you click that element. So if you click something else that's fine, we allow you. But the tooltip isn't dismissed as a result

Manual tests scenario:

  1. Tooltip pointing to Concierge chat in LHN shows.
  2. Click on conceirge chat, tooltip should disappear.
  3. if user clicks on any other chat than Concierge, tooltip should disappear but when user goes back to LHN Tooltip should appear again.

Note: None of the tooltips should be autodismissed after few seconds

We have 4 tooltips at this time see list here and other 4 will be added in #54064 this should be the expected behavior for all tooltips

Issue OwnerCurrent Issue Owner: @
Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~021867697197444537249
  • Upwork Job ID: 1867697197444537249
  • Last Price Increase: 2024-12-27
Issue OwnerCurrent Issue Owner: @ishpaul777
@puneetlath puneetlath added External Added to denote the issue can be worked on by a contributor NewFeature Something to build that is a new item. labels Dec 13, 2024
@melvin-bot melvin-bot bot changed the title Make it possible to click the element the product training tooltip is pointing to. [$250] Make it possible to click the element the product training tooltip is pointing to. Dec 13, 2024
Copy link

melvin-bot bot commented Dec 13, 2024

Job added to Upwork: https://www.upwork.com/jobs/~021867697197444537249

@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label Dec 13, 2024
Copy link

melvin-bot bot commented Dec 13, 2024

Current assignee @ishpaul777 is eligible for the External assigner, not assigning anyone new.

@melvin-bot melvin-bot bot added the Daily KSv2 label Dec 13, 2024
Copy link

melvin-bot bot commented Dec 13, 2024

Triggered auto assignment to @twisterdotcom (NewFeature), see https://stackoverflowteams.com/c/expensify/questions/14418#:~:text=BugZero%20process%20steps%20for%20feature%20requests for more details. Please add this Feature request to a GH project, as outlined in the SO.

@melvin-bot melvin-bot bot added Weekly KSv2 and removed Weekly KSv2 Daily KSv2 labels Dec 13, 2024
@puneetlath puneetlath changed the title [$250] Make it possible to click the element the product training tooltip is pointing to. [$500] Make it possible to click the element the product training tooltip is pointing to. Dec 13, 2024
Copy link

melvin-bot bot commented Dec 13, 2024

Upwork job price has been updated to $500

@puneetlath
Copy link
Contributor

Updating the price since this is part of an important migrate initiative.

@storm21-tecn
Copy link

The core issue here is that operations that should happen outside of the render cycle are being executed at the wrong time and in the wrong way. Functions like useSharedValue and useState, which manage state, should be properly synchronized using hooks like useEffect. This ensures that side effects are handled outside of the render cycle, preventing unnecessary re-renders and ensuring smoother performance.

Using useEffect: Values should not be updated directly during the render cycle. Instead, hooks like useEffect should be used to update values after the component is initially rendered or after specific dependencies change. This ensures that updates are done in a controlled manner and helps avoid unnecessary renders.

    height.set(-reanimated.height.get());
    heightWhenOpened.set(-reanimated.height.get());
    progress.set(reanimated.progress.get());
    isClosed.set(reanimated.progress.get() === 0);
}, []);

This approach ensures that values are updated only after the component has mounted, preventing unnecessary re-renders.

Synchronized Value Management: Shared values with useSharedValue should only be updated outside the render cycle—specifically in hooks like useEffect or useAnimatedStyle. This ensures that React processes updates correctly and optimizes performance.

Conditional Checks: The shouldShow function should only be called under the appropriate conditions. Screen size, user interactions, or other conditions should be checked only when necessary to avoid redundant checks.

Copy link

melvin-bot bot commented Dec 14, 2024

📣 @storm21-tecn! 📣
Hey, it seems we don’t have your contributor details yet! You'll only have to do this once, and this is how we'll hire you on Upwork.
Please follow these steps:

  1. Make sure you've read and understood the contributing guidelines.
  2. Get the email address used to login to your Expensify account. If you don't already have an Expensify account, create one here. If you have multiple accounts (e.g. one for testing), please use your main account email.
  3. Get the link to your Upwork profile. It's necessary because we only pay via Upwork. You can access it by logging in, and then clicking on your name. It'll look like this. If you don't already have an account, sign up for one here.
  4. Copy the format below and paste it in a comment on this issue. Replace the placeholder text with your actual details.
    Screen Shot 2022-11-16 at 4 42 54 PM
    Format:
Contributor details
Your Expensify account email: <REPLACE EMAIL HERE>
Upwork Profile Link: <REPLACE LINK HERE>

Copy link

melvin-bot bot commented Dec 14, 2024

⚠️ Missing/invalid email or upwork profile link. Please make sure you add both your Expensify email and Upwork profile link in the format specified.

@rayane-djouah
Copy link
Contributor

rayane-djouah commented Dec 14, 2024

Edited by proposal-police: This proposal was edited at the latest timestamp recorded during the edit.

Proposal

Please re-state the problem that we are trying to solve in this issue.

Make it possible to click the element the product training tooltip is pointing to.

What is the root cause of that problem?

New feature

What changes do you think we should make in order to solve the problem?

  • Removed all auto-dismiss behavior (no more hiding tooltips after a few seconds).
  • Removed various onHideTooltip props and related logic throughout the code.
  • Removed shouldUseOverlay from several tooltip usages so clicking the other elements is possible.
  • Ensured clicking the tooltip’s target element (e.g., FAB, chats, filter button) hides the tooltip as expected.
  • Added calls to hideProductTrainingTooltip() when clicking the element the tooltip is pointing to.
  • Standardized hiding tooltips by calling hideProductTrainingTooltip()
  • Prevented tooltips from rendering if a modal is open (ensures tooltips don’t overlap modals).
  • Removed the TooltipManager file and all references to it.
  • Updated the useProductTrainingContext hook to handle tooltip registration and unregistration without TooltipManager.
  • Switched from useIsFocused to useFocusEffect in some components for better focus handling.
  • Refactored places where tooltips are hidden on button presses or when navigating away.

Test branch:

main...rayane-djouah:z:Make-it-possible-to-click-the-element-the-product-training-tooltip-is-pointing-to-2

Previous solution

  1. Captures the user’s click coordinates on the transparent overlay.
  2. Compares these coordinates against the position and dimensions of the target element that the tooltip references.
  3. If the click falls within the target element’s bounding box, the tooltip is hidden, and a callback (onChildrenElementPress) is invoked to trigget the underlying element onPress function, and a callback onHideTooltip is triggered to ensure that the tooltip is not displayed again
  4. If the click is outside the target element, the tooltip is simply hidden (onDismissTooltip callback) without triggering the underlying element’s action. The onHideTooltip is not called in this case to make sure that the tooltip will appear again.
    const handleOverlayClick = (event?: MouseEvent | KeyboardEvent) => {

        // Captures the user’s click coordinates on the transparent overlay.
        const clickX = event?.clientX;
        const clickY = event?.clientY;

        // Check if the click falls within the target element bounds
        const isWithinTarget = !!clickX && !!clickY && clickX >= xOffset && clickX <= xOffset + targetWidth && clickY >= yOffset && clickY <= yOffset + targetHeight;

        // Hide the tooltip
        onDismissTooltip();

        // If the click is within target bounds, trigger the children element's press callback
        requestAnimationFrame(() => {
            if (!isWithinTarget) {
                return;
            }
            onHideTooltip();
            onChildrenElementPress?.();
        });
    };

On native:

    const handleOverlayClick = (event?: GestureEvent) => {

        // Captures the user’s click coordinates on the transparent overlay.
        const pageX = event?.nativeEvent.pageX;
        const pageY = event?.nativeEvent.pageY;

        // Compares these coordinates against the position and dimensions of the target element that the tooltip references.
        const isWithinTarget = !!pageX && !!pageY && pageX >= xOffset && pageX <= xOffset + targetWidth && pageY >= yOffset && pageY <= yOffset + targetHeight;

        onDismissTooltip();();

        requestAnimationFrame(() => {
            if (!isWithinTarget) {
                return;
            }
            // the tooltip should not be displayed again
            onHideTooltip();
            onChildrenElementPress?.();
        });
    };
  1. a "hole" overlay area with the same dimensions of the target element’s bounding box is introduced in TransparentOverlay component to display a hand cursor within the target element
    const holeStyle = useMemo(
        () => ({
            position: styles.pFixed,
            top: holeY,
            left: holeX,
            width: holeWidth,
            height: holeHeight,
            zIndex: 1500,
        }),
        [holeX, holeY, holeWidth, holeHeight, styles.pFixed],
    );
    return (
        <View
            onPointerDown={handlePointerDown}
            style={styles.fullScreen}
        >
            <PressableWithoutFeedback
                onPress={onPress}
                style={[styles.flex1, styles.cursorDefault, overlay]}
                accessibilityLabel={translate('common.close')}
                role={CONST.ROLE.BUTTON}
            />
            >
               {/* "Hole" area with a hand cursor */}
                <PressableWithoutFeedback
                    onPress={onPress}
                    style={holeStyle}
                    role={CONST.ROLE.BUTTON}
                />
            </PressableWithoutFeedback>
        </View>
    );
  1. we pass the dimensions of the hole as follows:
{shouldUseOverlay && (
    <TransparentOverlay
        onPress={handleOverlayClick}
        holeX={xOffset}
        holeY={yOffset}
        holeWidth={targetWidth}
        holeHeight={targetHeight}
    />
)}
  1. we need to remove auto dismissing tooltip logic here

Test branch:

main...rayane-djouah:z:Make-it-possible-to-click-the-product-training-tooltip-element

Result:

Screen.Recording.2024-12-14.at.4.56.17.PM.mov
Screen.Recording.2024-12-14.at.4.53.36.PM.mov

What alternative solutions did you explore? (Optional)

On web, we can dispatch the mouse press event to the underlaying element, but we can't do this on native, so onChildrenElementPress callback is a better approach

// If the click is within the target element, re-dispatch the event to the element
const targetElement = document.elementFromPoint(clickX, clickY) as HTMLElement | null;
if (targetElement) {
    // Create a new MouseEvent and dispatch it to simulate a click
    const simulatedClick = new MouseEvent('click', {bubbles: true, cancelable: true, clientX: clickX, clientY: clickY});
    targetElement.dispatchEvent(simulatedClick);
}

@melvin-bot melvin-bot bot added the Daily KSv2 label Dec 14, 2024
@rayane-djouah
Copy link
Contributor

Updated the proposal with more details

@melvin-bot melvin-bot bot added the Overdue label Dec 16, 2024
@ishpaul777
Copy link
Contributor Author

NOT OVERDUE DISCUSSING HERE https://expensify.slack.com/archives/C02NK2DQWUX/p1733780305744839

@melvin-bot melvin-bot bot removed the Overdue label Dec 16, 2024
@flaviadefaria flaviadefaria moved this to First Cohort - CRITICAL in [#whatsnext] #migrate Dec 17, 2024
Copy link

melvin-bot bot commented Dec 20, 2024

@puneetlath, @twisterdotcom, @ishpaul777 Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

@melvin-bot melvin-bot bot added the Overdue label Dec 20, 2024
@ishpaul777
Copy link
Contributor Author

No proposal this is on hold for #54263

@melvin-bot melvin-bot bot removed the Overdue label Dec 20, 2024
Copy link

melvin-bot bot commented Dec 20, 2024

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

Copy link

melvin-bot bot commented Dec 24, 2024

@puneetlath, @twisterdotcom, @ishpaul777 Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

@melvin-bot melvin-bot bot added the Overdue label Dec 24, 2024
@ishpaul777
Copy link
Contributor Author

On hold

@melvin-bot melvin-bot bot removed the Overdue label Dec 24, 2024
Copy link

melvin-bot bot commented Dec 27, 2024

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

@melvin-bot melvin-bot bot added the Overdue label Dec 27, 2024
@ishpaul777
Copy link
Contributor Author

not on hold anymore we are looking for proposals

@melvin-bot melvin-bot bot removed the Overdue label Dec 27, 2024
@rayane-djouah
Copy link
Contributor

Proposal updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Daily KSv2 External Added to denote the issue can be worked on by a contributor Help Wanted Apply this label when an issue is open to proposals by contributors NewFeature Something to build that is a new item.
Projects
Status: First Cohort - CRITICAL
Development

No branches or pull requests

5 participants