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

Feature: Tooltip for GBR #44277

Merged
merged 25 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e289ec9
Merge branch 'main' of https://github.com/tienifr/App into feature/to…
tienifr Jul 23, 2024
e08e392
Merge branch 'main' of https://github.com/tienifr/App into feature/to…
tienifr Jul 27, 2024
5552ef9
Merge branch 'main' of https://github.com/tienifr/App into feature/to…
tienifr Jul 29, 2024
947babf
fix: tooltip is overlap on native
tienifr Jul 30, 2024
2bd2317
hide tooltip on navigating
tienifr Jul 30, 2024
b57704a
remove redundant changes
tienifr Jul 30, 2024
c43f1af
add condition to show tooltip: has completed onboarding
tienifr Jul 30, 2024
f53155f
fix lint
tienifr Jul 30, 2024
d7bef8b
Merge branch 'main' of https://github.com/tienifr/App into feature/to…
tienifr Jul 31, 2024
191bc7a
Merge branch 'main' of https://github.com/tienifr/App into feature/to…
tienifr Aug 8, 2024
fa37e38
Merge branch 'main' of https://github.com/tienifr/App into feature/to…
tienifr Aug 8, 2024
b33c7cc
show tooltip when in lhn only
tienifr Aug 8, 2024
3dba0d7
remove hide tooltip on navigate
tienifr Aug 8, 2024
88e0299
create platform independant files
tienifr Aug 8, 2024
9768b00
fix lint
tienifr Aug 8, 2024
5e68892
fix: tooltip position
tienifr Aug 9, 2024
fae7803
lint fix
tienifr Aug 9, 2024
4636950
Merge branch 'main' into feature/tooltip-for-gbr
tienifr Sep 4, 2024
4096a9e
position
tienifr Sep 5, 2024
38b68d1
lint fi
tienifr Sep 5, 2024
a03c1d9
hide tooltip
tienifr Sep 6, 2024
e7a58cc
android position
tienifr Sep 6, 2024
863617e
flash issue
tienifr Sep 6, 2024
b9d1865
lint fix
tienifr Sep 6, 2024
8883a82
resolve conflicts
tienifr Sep 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ const ONYXKEYS = {
/** The NVP containing all information related to educational tooltip in workspace chat */
NVP_WORKSPACE_TOOLTIP: 'workspaceTooltip',

/** Whether to hide gbr tooltip */
NVP_SHOULD_HIDE_GBR_TOOLTIP: 'nvp_should_hide_gbr_tooltip',
grgia marked this conversation as resolved.
Show resolved Hide resolved

/** Does this user have push notifications enabled for this device? */
PUSH_NOTIFICATIONS_ENABLED: 'pushNotificationsEnabled',

Expand Down Expand Up @@ -949,6 +952,7 @@ type OnyxValuesMapping = {
[ONYXKEYS.NVP_PRIVATE_AMOUNT_OWED]: number;
[ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END]: number;
[ONYXKEYS.NVP_WORKSPACE_TOOLTIP]: OnyxTypes.WorkspaceTooltip;
[ONYXKEYS.NVP_SHOULD_HIDE_GBR_TOOLTIP]: boolean;
[ONYXKEYS.NVP_PRIVATE_CANCELLATION_DETAILS]: OnyxTypes.CancellationDetails[];
[ONYXKEYS.APPROVAL_WORKFLOW]: OnyxTypes.ApprovalWorkflowOnyx;
[ONYXKEYS.IMPORTED_SPREADSHEET]: OnyxTypes.ImportedSpreadsheet;
Expand Down
2 changes: 2 additions & 0 deletions src/components/LHNOptionsList/LHNOptionsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {PersonalDetails} from '@src/types/onyx';
import OptionRowLHNData from './OptionRowLHNData';
import OptionRowRendererComponent from './OptionRowRendererComponent';
import type {LHNOptionsListProps, RenderItemProps} from './types';

const keyExtractor = (item: string) => `report_${item}`;
Expand Down Expand Up @@ -267,6 +268,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio
ref={flashListRef}
indicatorStyle="white"
keyboardShouldPersistTaps="always"
CellRendererComponent={OptionRowRendererComponent}
contentContainerStyle={StyleSheet.flatten(contentContainerStyles)}
data={data}
testID="lhn-options-list"
Expand Down
388 changes: 222 additions & 166 deletions src/components/LHNOptionsList/OptionRowLHN.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {CellContainer} from '@shopify/flash-list';
import type {CellContainerProps} from '@shopify/flash-list/dist/native/cell-container/CellContainer';

function OptionRowRendererComponent(props: CellContainerProps) {
return (
<CellContainer
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
style={[props.style, {zIndex: -props.index}]}
/>
);
}

OptionRowRendererComponent.displayName = 'OptionRowRendererComponent';

export default OptionRowRendererComponent;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const OptionRowRendererComponent = undefined;

export default OptionRowRendererComponent;
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import React, {memo, useEffect, useRef} from 'react';
import {InteractionManager} from 'react-native';
import React, {memo, useEffect, useRef, useState} from 'react';
import type {LayoutRectangle, NativeSyntheticEvent} from 'react-native';
import GenericTooltip from '@components/Tooltip/GenericTooltip';
import type {EducationalTooltipProps} from '@components/Tooltip/types';
import CONST from '@src/CONST';
import measureTooltipCoordinate from './measureTooltipCoordinate';

type LayoutChangeEventWithTarget = NativeSyntheticEvent<{layout: LayoutRectangle; target: HTMLElement}>;

/**
* 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, ...props}: EducationalTooltipProps) {
function BaseEducationalTooltip({children, shouldAutoDismiss = false, shouldRender = true, ...props}: EducationalTooltipProps) {
const hideTooltipRef = useRef<() => void>();

const [shouldMeasure, setShouldMeasure] = useState(false);
const show = useRef<() => void>();

useEffect(
() => () => {
if (!hideTooltipRef.current) {
Expand All @@ -37,6 +39,16 @@ function BaseEducationalTooltip({children, shouldAutoDismiss = false, ...props}:
};
}, [shouldAutoDismiss]);

useEffect(() => {
if (!shouldRender || !shouldMeasure) {
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]);

return (
<GenericTooltip
shouldForceAnimate
Expand All @@ -48,22 +60,12 @@ function BaseEducationalTooltip({children, shouldAutoDismiss = false, ...props}:
hideTooltipRef.current = hideTooltip;
return React.cloneElement(children as React.ReactElement, {
onLayout: (e: LayoutChangeEventWithTarget) => {
if (!shouldMeasure) {
setShouldMeasure(true);
}
// e.target is specific to native, use e.nativeEvent.target on web instead
const target = e.target || e.nativeEvent.target;
// When tooltip is used inside an animated view (e.g. popover), we need to wait for the animation to finish before measuring content.
setTimeout(() => {
InteractionManager.runAfterInteractions(() => {
target?.measure((fx, fy, width, height, px, py) => {
updateTargetBounds({
height,
width,
x: px,
y: py,
});
showTooltip();
});
});
}, CONST.ANIMATED_TRANSITION);
show.current = () => measureTooltipCoordinate(target, updateTargetBounds, showTooltip);
},
});
}}
Expand Down
6 changes: 1 addition & 5 deletions src/components/Tooltip/EducationalTooltip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@ import React from 'react';
import type {TooltipExtendedProps} from '@components/Tooltip/types';
import BaseEducationalTooltip from './BaseEducationalTooltip';

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

function EducationalTooltip({children, ...props}: TooltipExtendedProps) {
return (
<BaseEducationalTooltip
// eslint-disable-next-line react/jsx-props-no-spreading
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type React from 'react';
import type {LayoutRectangle, NativeMethods} from 'react-native';

export default function measureTooltipCoordinate(target: React.Component & Readonly<NativeMethods>, updateTargetBounds: (rect: LayoutRectangle) => void, showTooltip: () => void) {
return target?.measure((x, y, width, height, px, py) => {
updateTargetBounds({height, width, x: px, y: py});
showTooltip();
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type React from 'react';
import type {LayoutRectangle, NativeMethods} from 'react-native';

export default function measureTooltipCoordinate(target: React.Component & Readonly<NativeMethods>, updateTargetBounds: (rect: LayoutRectangle) => void, showTooltip: () => void) {
return target?.measureInWindow((x, y, width, height) => {
updateTargetBounds({height, width, x, y});
showTooltip();
});
}
3 changes: 3 additions & 0 deletions src/components/Tooltip/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ type EducationalTooltipProps = ChildrenProps &
SharedTooltipProps & {
/** Whether to automatically dismiss the tooltip after 5 seconds */
shouldAutoDismiss?: boolean;

/** Whether the actual Tooltip should be rendered. If false, it's just going to return the children */
shouldRender?: boolean;
};

type TooltipExtendedProps = (EducationalTooltipProps | TooltipProps) & {
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ export default {
listOfChatMessages: 'List of chat messages',
listOfChats: 'List of chats',
saveTheWorld: 'Save the world',
tooltip: 'Get started here!',
},
allSettingsScreen: {
subscription: 'Subscription',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,7 @@ export default {
listOfChatMessages: 'Lista de mensajes del chat',
listOfChats: 'lista de chats',
saveTheWorld: 'Salvar el mundo',
tooltip: '¡Comienza aquí!',
},
allSettingsScreen: {
subscription: 'Suscripcion',
Expand Down
5 changes: 5 additions & 0 deletions src/libs/actions/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1307,6 +1307,10 @@ function dismissWorkspaceTooltip() {
Onyx.merge(ONYXKEYS.NVP_WORKSPACE_TOOLTIP, {shouldShow: false});
}

function dismissGBRTooltip() {
Onyx.merge(ONYXKEYS.NVP_SHOULD_HIDE_GBR_TOOLTIP, true);
}

function requestRefund() {
API.write(WRITE_COMMANDS.REQUEST_REFUND, null);
}
Expand Down Expand Up @@ -1349,4 +1353,5 @@ export {
requestValidateCodeAction,
addPendingContactMethod,
clearValidateCodeActionError,
dismissGBRTooltip,
};
1 change: 1 addition & 0 deletions src/styles/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ export default {

composerTooltipShiftHorizontal: 10,
composerTooltipShiftVertical: -10,
gbrTooltipShiftHorizontal: -20,

h20: 20,
h28: 28,
Expand Down
Loading