Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
0aaf97e
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Feb 17, 2025
e385396
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Feb 18, 2025
4e27760
add config to pass methods to confirm and dismiss tooltips
kubabutkiewicz Feb 18, 2025
f9ef4d6
add local image for a test receipt, remove unnecessary things, add me…
kubabutkiewicz Feb 19, 2025
82e11a4
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Feb 19, 2025
964f7e4
add onDissmis method to product training context, teting changes rela…
kubabutkiewicz Feb 19, 2025
3967917
fix lint problems, add creating money request with test receipt on mo…
kubabutkiewicz Feb 20, 2025
5be29c7
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Feb 21, 2025
905216e
fix displaying tooltips when chaning tabs
kubabutkiewicz Feb 24, 2025
6113a97
add marking optimistically manager mctest transactions as paid and fi…
kubabutkiewicz Feb 24, 2025
273ccfd
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Feb 24, 2025
106c76a
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Feb 25, 2025
a9982cf
resolve issues after self review
kubabutkiewicz Feb 25, 2025
bb037a4
removed unwanted change
kubabutkiewicz Feb 25, 2025
9673da4
resolve comments
kubabutkiewicz Feb 25, 2025
f02c4bb
fixes after review
kubabutkiewicz Feb 27, 2025
763bd77
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Feb 28, 2025
71ee090
fix lint
kubabutkiewicz Feb 28, 2025
fc54f1f
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 3, 2025
b40ddcf
fix resolve comments
kubabutkiewicz Mar 3, 2025
fbbb9d3
run prettier
kubabutkiewicz Mar 3, 2025
10b26a0
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 4, 2025
c46e28b
when using 'try it out' button move directly to confirmation screen
kubabutkiewicz Mar 4, 2025
db8187e
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 4, 2025
6c8210a
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 4, 2025
e9f7bf7
fix prettier and lint
kubabutkiewicz Mar 4, 2025
9771ea8
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 5, 2025
0590958
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 6, 2025
cf79436
fix prettier
kubabutkiewicz Mar 6, 2025
3e4d8b2
kubabutkiewicz Mar 9, 2025
1fc71e1
fix optimistic update and styles
kubabutkiewicz Mar 10, 2025
2fe06f3
added design fixes
kubabutkiewicz Mar 11, 2025
de5d373
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 11, 2025
45641f7
fix lint
kubabutkiewicz Mar 11, 2025
4e5c8a0
resolve comment
kubabutkiewicz Mar 11, 2025
9a61f88
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 11, 2025
bb30fa3
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 11, 2025
4d51b5d
fix failing scans
kubabutkiewicz Mar 11, 2025
a9a9cb7
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 12, 2025
4d3f07e
add optimistic amount and currency only for test receipt
kubabutkiewicz Mar 12, 2025
ff2bf90
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 13, 2025
95afcae
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 13, 2025
0681f9b
fix wrong report action for manager mc test expense
kubabutkiewicz Mar 13, 2025
0d149e2
resolve lint errors
kubabutkiewicz Mar 13, 2025
dfa22ed
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 14, 2025
51668fb
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 14, 2025
1f86c13
Merge branch 'main' of github.com:callstack-internal/Expensify-App in…
kubabutkiewicz Mar 14, 2025
4398d93
fix ts check
kubabutkiewicz Mar 14, 2025
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
Binary file added assets/images/fake-receipt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3494,6 +3494,13 @@ const CONST = {
WORKSPACE_NAME_CHARACTER_LIMIT: 80,
STATE_CHARACTER_LIMIT: 32,

// Test receipt data
TEST_RECEIPT: {
AMOUNT: 1800,
CURRENCY: 'USD',
FILENAME: 'test_receipt',
},

AVATAR_CROP_MODAL: {
// The next two constants control what is min and max value of the image crop scale.
// Values define in how many times the image can be bigger than its container.
Expand Down
3 changes: 2 additions & 1 deletion src/components/MoneyRequestConfirmationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ import {calculateAmount, insertTagIntoTransactionTagsString, isMovingTransaction
import Log from '@libs/Log';
import {validateAmount} from '@libs/MoneyRequestUtils';
import Navigation from '@libs/Navigation/Navigation';
import {getIOUConfirmationOptionsFromPayeePersonalDetail, hasEnabledOptions, isSelectedManagerMcTest} from '@libs/OptionsListUtils';
import {getIOUConfirmationOptionsFromPayeePersonalDetail, hasEnabledOptions} from '@libs/OptionsListUtils';
import Permissions from '@libs/Permissions';
import {getDistanceRateCustomUnitRate, getTagLists, isTaxTrackingEnabled} from '@libs/PolicyUtils';
import {isSelectedManagerMcTest} from '@libs/ReportUtils';
import type {OptionData} from '@libs/ReportUtils';
import playSound, {SOUNDS} from '@libs/Sound';
import {
Expand Down
40 changes: 34 additions & 6 deletions src/components/ProductTrainingContext/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ type ProductTrainingContextType = {
unregisterTooltip: (tooltipName: ProductTrainingTooltipName) => void;
};

type ProductTrainingContextConfig = {
/**
* Callback to be called when the tooltip is dismissed
*/
onDismiss?: () => void;
Comment thread
kubabutkiewicz marked this conversation as resolved.

/**
* Callback to be called when the tooltip is confirmed
*/
onConfirm?: () => void;
};

const ProductTrainingContext = createContext<ProductTrainingContextType>({
shouldRenderTooltip: () => false,
registerTooltip: () => {},
Expand Down Expand Up @@ -161,7 +173,7 @@ function ProductTrainingContextProvider({children}: ChildrenProps) {
return <ProductTrainingContext.Provider value={contextValue}>{children}</ProductTrainingContext.Provider>;
}

const useProductTrainingContext = (tooltipName: ProductTrainingTooltipName, shouldShow = true) => {
const useProductTrainingContext = (tooltipName: ProductTrainingTooltipName, shouldShow = true, config: ProductTrainingContextConfig = {}) => {
const context = useContext(ProductTrainingContext);
const styles = useThemeStyles();
const theme = useTheme();
Expand Down Expand Up @@ -198,7 +210,17 @@ const useProductTrainingContext = (tooltipName: ProductTrainingTooltipName, shou
fsClass={CONST.FULL_STORY.UNMASK}
testID={CONST.FULL_STORY.UNMASK}
>
<View style={[styles.alignItemsCenter, styles.flexRow, styles.justifyContentCenter, styles.flexWrap, styles.textAlignCenter, styles.gap3, styles.p2]}>
<View
style={[
styles.alignItemsCenter,
styles.flexRow,
tooltip?.shouldRenderActionButtons ? styles.justifyContentStart : styles.justifyContentCenter,
styles.flexWrap,
styles.textAlignCenter,
styles.gap3,
styles.p2,
]}
>
<Icon
src={Expensicons.Lightbulb}
fill={theme.tooltipHighlightText}
Expand All @@ -219,21 +241,25 @@ const useProductTrainingContext = (tooltipName: ProductTrainingTooltipName, shou
</Text>
</View>
{!!tooltip?.shouldRenderActionButtons && (
<View style={[styles.alignItemsCenter, styles.justifyContentBetween, styles.flexRow, styles.ph1, styles.pv2]}>
<View style={[styles.alignItemsCenter, styles.justifyContentBetween, styles.flexRow, styles.ph2, styles.pv2, styles.gap2]}>
<Button
success
text={translate('productTrainingTooltip.scanTestTooltip.tryItOut')}
style={[styles.flex1, styles.ph1]}
style={[styles.flex1]}
onPress={config.onConfirm}
/>
<Button
text={translate('productTrainingTooltip.scanTestTooltip.noThanks')}
style={[styles.flex1, styles.ph1]}
style={[styles.flex1]}
onPress={config.onDismiss}
/>
</View>
)}
</View>
);
}, [
config.onConfirm,
config.onDismiss,
styles.alignItemsCenter,
styles.flex1,
styles.flexRow,
Expand All @@ -243,12 +269,14 @@ const useProductTrainingContext = (tooltipName: ProductTrainingTooltipName, shou
styles.justifyContentCenter,
styles.mw100,
styles.p2,
styles.ph1,
styles.productTrainingTooltipText,
styles.pv2,
styles.textAlignCenter,
styles.textBold,
styles.textWrap,
styles.gap2,
styles.justifyContentStart,
styles.ph2,
theme.tooltipHighlightText,
tooltipName,
translate,
Expand Down
3 changes: 2 additions & 1 deletion src/components/SelectionList/InviteMemberListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import useLocalize from '@hooks/useLocalize';
import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import {getIsUserSubmittedExpenseOrScannedReceipt, isSelectedManagerMcTest} from '@libs/OptionsListUtils';
import {getIsUserSubmittedExpenseOrScannedReceipt} from '@libs/OptionsListUtils';
import Permissions from '@libs/Permissions';
import {isSelectedManagerMcTest} from '@libs/ReportUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Icon} from '@src/types/onyx/OnyxCommon';
Expand Down
9 changes: 0 additions & 9 deletions src/components/TabSelector/TabSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import type {MaterialTopTabBarProps} from '@react-navigation/material-top-tabs/lib/typescript/src/types';
import React, {useEffect, useMemo, useState} from 'react';
import {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import FocusTrapContainerElement from '@components/FocusTrap/FocusTrapContainerElement';
import * as Expensicons from '@components/Icon/Expensicons';
import type {LocaleContextProps} from '@components/LocaleContextProvider';
import useLocalize from '@hooks/useLocalize';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import {getIsUserSubmittedExpenseOrScannedReceipt} from '@libs/OptionsListUtils';
import Permissions from '@libs/Permissions';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type IconAsset from '@src/types/utils/IconAsset';
import getBackgroundColor from './getBackground';
import getOpacity from './getOpacity';
Expand Down Expand Up @@ -58,7 +54,6 @@ function TabSelector({state, navigation, onTabPress = () => {}, position, onFocu
const styles = useThemeStyles();
const defaultAffectedAnimatedTabs = useMemo(() => Array.from({length: state.routes.length}, (v, i) => i), [state.routes.length]);
const [affectedAnimatedTabs, setAffectedAnimatedTabs] = useState(defaultAffectedAnimatedTabs);
const [betas] = useOnyx(ONYXKEYS.BETAS);

useEffect(() => {
// It is required to wait transition end to reset affectedAnimatedTabs because tabs style is still animating during transition.
Expand All @@ -76,9 +71,6 @@ function TabSelector({state, navigation, onTabPress = () => {}, position, onFocu
const inactiveOpacity = getOpacity({routesLength: state.routes.length, tabIndex: index, active: false, affectedTabs: affectedAnimatedTabs, position, isActive});
const backgroundColor = getBackgroundColor({routesLength: state.routes.length, tabIndex: index, affectedTabs: affectedAnimatedTabs, theme, position, isActive});
const {icon, title} = getIconAndTitle(route.name, translate);
const shouldShowTestReceiptTooltip =
route.name === CONST.TAB_REQUEST.SCAN && isActive && !getIsUserSubmittedExpenseOrScannedReceipt() && Permissions.canUseManagerMcTest(betas);

const onPress = () => {
if (isActive) {
return;
Expand Down Expand Up @@ -111,7 +103,6 @@ function TabSelector({state, navigation, onTabPress = () => {}, position, onFocu
backgroundColor={backgroundColor}
isActive={isActive}
shouldShowLabelWhenInactive={shouldShowLabelWhenInactive}
shouldShowTestReceiptTooltip={shouldShowTestReceiptTooltip}
/>
);
})}
Expand Down
73 changes: 24 additions & 49 deletions src/components/TabSelector/TabSelectorItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import React, {useState} from 'react';
// eslint-disable-next-line no-restricted-imports
import {Animated} from 'react-native';
import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
import {useProductTrainingContext} from '@components/ProductTrainingContext';
import Tooltip from '@components/Tooltip';
import EducationalTooltip from '@components/Tooltip/EducationalTooltip';
import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';
import type IconAsset from '@src/types/utils/IconAsset';
Expand Down Expand Up @@ -37,9 +35,6 @@ type TabSelectorItemProps = {

/** Whether to show the label when the tab is inactive */
shouldShowLabelWhenInactive?: boolean;

/** Whether to show the test receipt tooltip */
shouldShowTestReceiptTooltip?: boolean;
};

function TabSelectorItem({
Expand All @@ -51,58 +46,38 @@ function TabSelectorItem({
inactiveOpacity = 1,
isActive = false,
shouldShowLabelWhenInactive = true,
shouldShowTestReceiptTooltip = false,
}: TabSelectorItemProps) {
const styles = useThemeStyles();
const [isHovered, setIsHovered] = useState(false);
const {shouldShowProductTrainingTooltip, renderProductTrainingTooltip} = useProductTrainingContext(CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.SCAN_TEST_TOOLTIP, shouldShowTestReceiptTooltip);

const content = () => (
<AnimatedPressableWithFeedback
accessibilityLabel={title}
style={[styles.tabSelectorButton, styles.tabBackground(isHovered, isActive, backgroundColor), styles.userSelectNone]}
wrapperStyle={[styles.flexGrow1]}
onPress={onPress}
onHoverIn={() => setIsHovered(true)}
onHoverOut={() => setIsHovered(false)}
role={CONST.ROLE.BUTTON}
dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}}
>
<TabIcon
icon={icon}
activeOpacity={styles.tabOpacity(isHovered, isActive, activeOpacity, inactiveOpacity).opacity}
inactiveOpacity={styles.tabOpacity(isHovered, isActive, inactiveOpacity, activeOpacity).opacity}
/>
{(shouldShowLabelWhenInactive || isActive) && (
<TabLabel
title={title}
activeOpacity={styles.tabOpacity(isHovered, isActive, activeOpacity, inactiveOpacity).opacity}
inactiveOpacity={styles.tabOpacity(isHovered, isActive, inactiveOpacity, activeOpacity).opacity}
/>
)}
</AnimatedPressableWithFeedback>
);

return shouldShowTestReceiptTooltip ? (
<EducationalTooltip

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you remove EducationalTooltip here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is moved to IOURequestStepScan screens, but lets wait until this #57480

shouldRender={shouldShowProductTrainingTooltip}
renderTooltipContent={renderProductTrainingTooltip}
shouldHideOnNavigate
anchorAlignment={{
horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.CENTER,
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP,
}}
wrapperStyle={styles.productTrainingTooltipWrapper}
shiftVertical={18}
>
{content()}
</EducationalTooltip>
) : (
return (
<Tooltip
shouldRender={!shouldShowLabelWhenInactive && !isActive}
text={title}
>
{content()}
<AnimatedPressableWithFeedback
accessibilityLabel={title}
style={[styles.tabSelectorButton, styles.tabBackground(isHovered, isActive, backgroundColor), styles.userSelectNone]}
wrapperStyle={[styles.flexGrow1]}
onPress={onPress}
onHoverIn={() => setIsHovered(true)}
onHoverOut={() => setIsHovered(false)}
role={CONST.ROLE.BUTTON}
dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}}
>
<TabIcon
icon={icon}
activeOpacity={styles.tabOpacity(isHovered, isActive, activeOpacity, inactiveOpacity).opacity}
inactiveOpacity={styles.tabOpacity(isHovered, isActive, inactiveOpacity, activeOpacity).opacity}
/>
{(shouldShowLabelWhenInactive || isActive) && (
<TabLabel
title={title}
activeOpacity={styles.tabOpacity(isHovered, isActive, activeOpacity, inactiveOpacity).opacity}
inactiveOpacity={styles.tabOpacity(isHovered, isActive, inactiveOpacity, activeOpacity).opacity}
/>
)}
</AnimatedPressableWithFeedback>
</Tooltip>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5980,7 +5980,7 @@ const translations = {
},
scanTestTooltip: {
part1: 'Want to see how Scan works?',
part2: ' Try a test \nreceipt!',
part2: ' Try a test receipt!',
part3: 'Choose our',
part4: ' test manager',
part5: ' to try it out!',
Expand Down
2 changes: 1 addition & 1 deletion src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6502,7 +6502,7 @@ const translations = {
},
scanTestTooltip: {
part1: '¿Quieres ver cómo funciona Escanear?',
part2: ' \n¡Prueba con un recibo de prueba!',
part2: '¡Prueba con un recibo de prueba!',
part3: '¡Elige a',
part4: ' nuestro gerente',
part5: ' de prueba para probarlo!',
Expand Down
14 changes: 6 additions & 8 deletions src/libs/OptionsListUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1468,13 +1468,6 @@ function getIsUserSubmittedExpenseOrScannedReceipt(): boolean {
return !!nvpDismissedProductTraining?.[CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.SCAN_TEST_TOOLTIP];
}

/**
* Helper method to check if participant email is Manager McTest
*/
function isSelectedManagerMcTest(email: string | null | undefined): boolean {
return email === CONST.EMAIL.MANAGER_MCTEST;
}

/**
* Options are reports and personal details. This function filters out the options that are not valid to be displayed.
*/
Expand Down Expand Up @@ -2161,6 +2154,11 @@ function shouldUseBoldText(report: OptionData): boolean {
return report.isUnread === true && notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.MUTE && !isHiddenForCurrentUser(notificationPreference);
}

function getManagerMcTestParticipant(): Participant | undefined {
const managerMcTestPersonalDetails = Object.values(allPersonalDetails ?? {}).find((personalDetails) => personalDetails?.login === CONST.EMAIL.MANAGER_MCTEST);
return managerMcTestPersonalDetails ? getParticipantsOption(managerMcTestPersonalDetails, allPersonalDetails) : undefined;
}

export {
getAvatarsForAccountIDs,
isCurrentUser,
Expand Down Expand Up @@ -2215,7 +2213,7 @@ export {
filterSelfDMChat,
filterReports,
getIsUserSubmittedExpenseOrScannedReceipt,
isSelectedManagerMcTest,
getManagerMcTestParticipant,
};

export type {Section, SectionBase, MemberForList, Options, OptionList, SearchOption, PayeePersonalDetails, Option, OptionTree, ReportAndPersonalDetailOptions, GetUserToInviteConfig};
Loading