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

Revert "Revert 54064 and 53396" #54263

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import KeyboardProvider from './components/KeyboardProvider';
import {LocaleContextProvider} from './components/LocaleContextProvider';
import OnyxProvider from './components/OnyxProvider';
import PopoverContextProvider from './components/PopoverProvider';
import {ProductTrainingContextProvider} from './components/ProductTrainingContext';
import SafeArea from './components/SafeArea';
import ScrollOffsetContextProvider from './components/ScrollOffsetContextProvider';
import {SearchRouterContextProvider} from './components/Search/SearchRouter/SearchRouterContext';
Expand Down Expand Up @@ -95,6 +96,7 @@ function App({url}: AppProps) {
VideoPopoverMenuContextProvider,
KeyboardProvider,
SearchRouterContextProvider,
ProductTrainingContextProvider,
]}
>
<CustomStatusBarAndBackground />
Expand Down
11 changes: 11 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6437,6 +6437,17 @@ const CONST = {
},

MIGRATED_USER_WELCOME_MODAL: 'migratedUserWelcomeModal',

PRODUCT_TRAINING_TOOLTIP_NAMES: {
CONCEIRGE_LHN_GBR: 'conciergeLHNGBR',
RENAME_SAVED_SEARCH: 'renameSavedSearch',
QUICK_ACTION_BUTTON: 'quickActionButton',
WORKSAPCE_CHAT_CREATE: 'workspaceChatCreate',
SEARCH_FILTER_BUTTON_TOOLTIP: 'filterButtonTooltip',
BOTTOM_NAV_INBOX_TOOLTIP: 'bottomNavInboxTooltip',
LHN_WORKSPACE_CHAT_TOOLTIP: 'workspaceChatLHNTooltip',
GLOBAL_CREATE_TOOLTIP: 'globalCreateTooltip',
},
} as const;

type Country = keyof typeof CONST.ALL_COUNTRIES;
Expand Down
16 changes: 0 additions & 16 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,6 @@ const ONYXKEYS = {

/** NVP keys */

/** Boolean flag only true when first set */
NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER: 'nvp_isFirstTimeNewExpensifyUser',

/** This NVP contains list of at most 5 recent attendees */
NVP_RECENT_ATTENDEES: 'nvp_expensify_recentAttendees',

Expand Down Expand Up @@ -222,18 +219,9 @@ const ONYXKEYS = {
/** The end date (epoch timestamp) of the workspace owner’s grace period after the free trial ends. */
NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END: 'nvp_private_billingGracePeriodEnd',

/** The NVP containing all information related to educational tooltip in workspace chat */
NVP_WORKSPACE_TOOLTIP: 'workspaceTooltip',

/** The NVP containing the target url to navigate to when deleting a transaction */
NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL: 'nvp_deleteTransactionNavigateBackURL',

/** Whether to show save search rename tooltip */
SHOULD_SHOW_SAVED_SEARCH_RENAME_TOOLTIP: 'shouldShowSavedSearchRenameTooltip',

/** Whether to hide gbr tooltip */
NVP_SHOULD_HIDE_GBR_TOOLTIP: 'nvp_should_hide_gbr_tooltip',

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

Expand Down Expand Up @@ -882,7 +870,6 @@ type OnyxCollectionValuesMapping = {
type OnyxValuesMapping = {
[ONYXKEYS.ACCOUNT]: OnyxTypes.Account;
[ONYXKEYS.ACCOUNT_MANAGER_REPORT_ID]: string;
[ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER]: boolean;

// NVP_ONBOARDING is an array for old users.
[ONYXKEYS.NVP_ONBOARDING]: Onboarding | [];
Expand Down Expand Up @@ -1025,17 +1012,14 @@ type OnyxValuesMapping = {
[ONYXKEYS.NVP_BILLING_FUND_ID]: number;
[ONYXKEYS.NVP_PRIVATE_AMOUNT_OWED]: number;
[ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END]: number;
[ONYXKEYS.NVP_WORKSPACE_TOOLTIP]: OnyxTypes.WorkspaceTooltip;
[ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL]: string | undefined;
[ONYXKEYS.NVP_SHOULD_HIDE_GBR_TOOLTIP]: boolean;
[ONYXKEYS.NVP_PRIVATE_CANCELLATION_DETAILS]: OnyxTypes.CancellationDetails[];
[ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE]: string;
[ONYXKEYS.APPROVAL_WORKFLOW]: OnyxTypes.ApprovalWorkflowOnyx;
[ONYXKEYS.IMPORTED_SPREADSHEET]: OnyxTypes.ImportedSpreadsheet;
[ONYXKEYS.LAST_ROUTE]: string;
[ONYXKEYS.IS_SINGLE_NEW_DOT_ENTRY]: boolean | undefined;
[ONYXKEYS.IS_USING_IMPORTED_STATE]: boolean;
[ONYXKEYS.SHOULD_SHOW_SAVED_SEARCH_RENAME_TOOLTIP]: boolean;
[ONYXKEYS.NVP_EXPENSIFY_COMPANY_CARDS_CUSTOM_NAMES]: Record<string, string>;
[ONYXKEYS.CONCIERGE_REPORT_ID]: string;
[ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING]: OnyxTypes.DismissedProductTraining;
Expand Down
75 changes: 51 additions & 24 deletions src/components/FloatingActionButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@ import type {GestureResponderEvent, Role, Text, View} from 'react-native';
import {Platform} from 'react-native';
import Animated, {createAnimatedPropAdapter, Easing, interpolateColor, processColor, useAnimatedProps, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
import Svg, {Path} from 'react-native-svg';
import useBottomTabIsFocused from '@hooks/useBottomTabIsFocused';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import getPlatform from '@libs/getPlatform';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import {PressableWithoutFeedback} from './Pressable';
import {useProductTrainingContext} from './ProductTrainingContext';
import EducationalTooltip from './Tooltip/EducationalTooltip';

const AnimatedPath = Animated.createAnimatedComponent(Path);
AnimatedPath.displayName = 'AnimatedPath';
Expand Down Expand Up @@ -56,6 +62,14 @@ function FloatingActionButton({onPress, isActive, accessibilityLabel, role}: Flo
const styles = useThemeStyles();
const borderRadius = styles.floatingActionButton.borderRadius;
const fabPressable = useRef<HTMLDivElement | View | Text | null>(null);
const {shouldUseNarrowLayout} = useResponsiveLayout();
const platform = getPlatform();
const isNarrowScreenOnWeb = shouldUseNarrowLayout && platform === CONST.PLATFORM.WEB;
const isFocused = useBottomTabIsFocused();
const {renderProductTrainingTooltip, shouldShowProductTrainingTooltip, hideProductTrainingTooltip} = useProductTrainingContext(
CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.GLOBAL_CREATE_TOOLTIP,
isFocused,
);
const sharedValue = useSharedValue(isActive ? 1 : 0);
const buttonRef = ref;

Expand Down Expand Up @@ -97,32 +111,45 @@ function FloatingActionButton({onPress, isActive, accessibilityLabel, role}: Flo
};

return (
<PressableWithoutFeedback
ref={(el) => {
fabPressable.current = el ?? null;
if (buttonRef && 'current' in buttonRef) {
buttonRef.current = el ?? null;
}
<EducationalTooltip
shouldRender={shouldShowProductTrainingTooltip}
anchorAlignment={{
horizontal: isNarrowScreenOnWeb ? CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.CENTER : CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.RIGHT,
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.BOTTOM,
}}
style={[styles.h100, styles.bottomTabBarItem]}
accessibilityLabel={accessibilityLabel}
onPress={toggleFabAction}
onLongPress={() => {}}
role={role}
shouldUseHapticsOnLongPress={false}
shouldUseOverlay
shiftHorizontal={isNarrowScreenOnWeb ? 0 : variables.fabTooltipShiftHorizontal}
renderTooltipContent={renderProductTrainingTooltip}
wrapperStyle={styles.productTrainingTooltipWrapper}
onHideTooltip={hideProductTrainingTooltip}
>
<Animated.View style={[styles.floatingActionButton, animatedStyle]}>
<Svg
width={variables.iconSizeNormal}
height={variables.iconSizeNormal}
>
<AnimatedPath
d="M12,3c0-1.1-0.9-2-2-2C8.9,1,8,1.9,8,3v5H3c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2h5v5c0,1.1,0.9,2,2,2c1.1,0,2-0.9,2-2v-5h5c1.1,0,2-0.9,2-2c0-1.1-0.9-2-2-2h-5V3z"
animatedProps={animatedProps}
/>
</Svg>
</Animated.View>
</PressableWithoutFeedback>
<PressableWithoutFeedback
ref={(el) => {
fabPressable.current = el ?? null;
if (buttonRef && 'current' in buttonRef) {
buttonRef.current = el ?? null;
}
}}
style={[styles.h100, styles.bottomTabBarItem]}
accessibilityLabel={accessibilityLabel}
onPress={toggleFabAction}
onLongPress={() => {}}
role={role}
shouldUseHapticsOnLongPress={false}
>
<Animated.View style={[styles.floatingActionButton, animatedStyle]}>
<Svg
width={variables.iconSizeNormal}
height={variables.iconSizeNormal}
>
<AnimatedPath
d="M12,3c0-1.1-0.9-2-2-2C8.9,1,8,1.9,8,3v5H3c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2h5v5c0,1.1,0.9,2,2,2c1.1,0,2-0.9,2-2v-5h5c1.1,0,2-0.9,2-2c0-1.1-0.9-2-2-2h-5V3z"
animatedProps={animatedProps}
/>
</Svg>
</Animated.View>
</PressableWithoutFeedback>
</EducationalTooltip>
);
}

Expand Down
63 changes: 21 additions & 42 deletions src/components/LHNOptionsList/OptionRowLHN.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useFocusEffect} from '@react-navigation/native';
import React, {useCallback, useRef, useState} from 'react';
import React, {useCallback, useMemo, useRef, useState} from 'react';
import type {GestureResponderEvent, ViewStyle} from 'react-native';
import {StyleSheet, View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
Expand All @@ -11,6 +11,7 @@
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import {useSession} from '@components/OnyxProvider';
import PressableWithSecondaryInteraction from '@components/PressableWithSecondaryInteraction';
import {useProductTrainingContext} from '@components/ProductTrainingContext';
import SubscriptAvatar from '@components/SubscriptAvatar';
import Text from '@components/Text';
import Tooltip from '@components/Tooltip';
Expand All @@ -22,7 +23,6 @@
import useThemeStyles from '@hooks/useThemeStyles';
import DateUtils from '@libs/DateUtils';
import DomUtils from '@libs/DomUtils';
import {hasCompletedGuidedSetupFlowSelector} from '@libs/onboardingSelectors';
import * as OptionsListUtils from '@libs/OptionsListUtils';
import Parser from '@libs/Parser';
import Performance from '@libs/Performance';
Expand All @@ -32,7 +32,6 @@
import FreeTrial from '@pages/settings/Subscription/FreeTrial';
import variables from '@styles/variables';
import Timing from '@userActions/Timing';
import * as User from '@userActions/User';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
Expand All @@ -47,19 +46,22 @@
const {shouldUseNarrowLayout} = useResponsiveLayout();

// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${optionItem?.reportID || -1}`);

Check failure on line 49 in src/components/LHNOptionsList/OptionRowLHN.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

const [isFirstTimeNewExpensifyUser] = useOnyx(ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER);
const [isOnboardingCompleted = true] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {
selector: hasCompletedGuidedSetupFlowSelector,
});
const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID);
const isActiveWorkspaceChat = ReportUtils.isPolicyExpenseChat(report) && report?.isOwnPolicyExpenseChat && activePolicyID === report?.policyID;
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED);
const session = useSession();

// Guides are assigned for the MANAGE_TEAM onboarding action, except for emails that have a '+'.
const isOnboardingGuideAssigned = introSelected?.choice === CONST.ONBOARDING_CHOICES.MANAGE_TEAM && !session?.email?.includes('+');
const shouldShowToooltipOnThisReport = isOnboardingGuideAssigned ? ReportUtils.isAdminRoom(report) : ReportUtils.isConciergeChatReport(report);
const [shouldHideGBRTooltip] = useOnyx(ONYXKEYS.NVP_SHOULD_HIDE_GBR_TOOLTIP, {initialValue: true});
const shouldShowGetStartedTooltip = isOnboardingGuideAssigned ? ReportUtils.isAdminRoom(report) : ReportUtils.isConciergeChatReport(report);

const {tooltipToRender, shouldShowTooltip} = useMemo(() => {
const tooltip = shouldShowGetStartedTooltip ? CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.CONCEIRGE_LHN_GBR : CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.LHN_WORKSPACE_CHAT_TOOLTIP;

// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
return {tooltipToRender: tooltip, shouldShowTooltip: shouldUseNarrowLayout ? isScreenFocused : true};
}, [shouldShowGetStartedTooltip, isScreenFocused, shouldUseNarrowLayout]);

const {shouldShowProductTrainingTooltip, renderProductTrainingTooltip, hideProductTrainingTooltip} = useProductTrainingContext(tooltipToRender, shouldShowTooltip);
const {translate} = useLocalize();
const [isContextMenuActive, setIsContextMenuActive] = useState(false);

Expand All @@ -72,30 +74,6 @@
}, []),
);

const renderGBRTooltip = useCallback(
() => (
<View style={[styles.alignItemsCenter, styles.flexRow, styles.justifyContentCenter, styles.flexWrap, styles.textAlignCenter, styles.gap1]}>
<Icon
src={Expensicons.Lightbulb}
fill={theme.tooltipHighlightText}
medium
/>
<Text style={styles.quickActionTooltipSubtitle}>{translate('sidebarScreen.tooltip')}</Text>
</View>
),
[
styles.alignItemsCenter,
styles.flexRow,
styles.justifyContentCenter,
styles.flexWrap,
styles.textAlignCenter,
styles.gap1,
styles.quickActionTooltipSubtitle,
theme.tooltipHighlightText,
translate,
],
);

const isInFocusMode = viewMode === CONST.OPTION_MODE.COMPACT;
const sidebarInnerRowStyle = StyleSheet.flatten<ViewStyle>(
isInFocusMode
Expand Down Expand Up @@ -180,17 +158,18 @@
needsOffscreenAlphaCompositing
>
<EducationalTooltip
shouldRender={isFirstTimeNewExpensifyUser && !shouldHideGBRTooltip && isOnboardingCompleted && isScreenFocused && shouldUseNarrowLayout && shouldShowToooltipOnThisReport}
renderTooltipContent={renderGBRTooltip}
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
shouldRender={shouldShowProductTrainingTooltip && (isActiveWorkspaceChat || shouldShowGetStartedTooltip)}
renderTooltipContent={renderProductTrainingTooltip}
anchorAlignment={{
horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.RIGHT,
horizontal: isActiveWorkspaceChat ? CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT : CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.RIGHT,
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP,
}}
shouldUseOverlay
shiftHorizontal={variables.gbrTooltipShiftHorizontal}
shiftVertical={variables.composerTooltipShiftVertical}
wrapperStyle={styles.quickActionTooltipWrapper}
onHideTooltip={User.dismissGBRTooltip}
shiftHorizontal={isActiveWorkspaceChat ? variables.workspaceLHNtooltipShiftHorizontal : variables.gbrTooltipShiftHorizontal}
shiftVertical={isActiveWorkspaceChat ? 0 : variables.composerTooltipShiftVertical}
onHideTooltip={hideProductTrainingTooltip}
wrapperStyle={styles.productTrainingTooltipWrapper}
>
<View>
<Hoverable>
Expand Down
Loading
Loading