-
Notifications
You must be signed in to change notification settings - Fork 4k
Refactor TransactionItemRow for better performance #66169
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
Changes from all commits
72ede6e
35419da
3b5a502
dec4b04
44b4bbb
cc70c4d
527f58c
3b387cf
ada7989
ad134d7
5a580ca
559fa63
da15e31
c968035
2e663de
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import {useIsFocused} from '@react-navigation/native'; | ||
| import React from 'react'; | ||
| import {View} from 'react-native'; | ||
| import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'; | ||
| import Text from '@components/Text'; | ||
| import useLocalize from '@hooks/useLocalize'; | ||
| import useResponsiveLayout from '@hooks/useResponsiveLayout'; | ||
| import useThemeStyles from '@hooks/useThemeStyles'; | ||
| import {convertToDisplayString} from '@libs/CurrencyUtils'; | ||
| import type * as OnyxTypes from '@src/types/onyx'; | ||
|
|
||
| type MoneyRequestReportTotalSpendProps = { | ||
| /** Report for which the total spend is being displayed */ | ||
| report: OnyxTypes.Report; | ||
|
|
||
| /** Whether the report has any comments */ | ||
| hasComments: boolean; | ||
|
|
||
| /** Whether the report is loading report actions */ | ||
| isLoadingReportActions: boolean; | ||
|
|
||
| /** Whether the report has any transactions */ | ||
| isEmptyTransactions: boolean; | ||
|
|
||
| /** The total display spend of the report */ | ||
| totalDisplaySpend: number; | ||
|
|
||
| /** Whether the report has any pending actions */ | ||
| hasPendingAction: boolean; | ||
| }; | ||
|
|
||
| function MoneyRequestReportTotalSpend({hasComments, isLoadingReportActions, isEmptyTransactions, totalDisplaySpend, report, hasPendingAction}: MoneyRequestReportTotalSpendProps) { | ||
| const styles = useThemeStyles(); | ||
| const {translate} = useLocalize(); | ||
| const {shouldUseNarrowLayout} = useResponsiveLayout(); | ||
| const isFocused = useIsFocused(); | ||
|
|
||
| return ( | ||
| <View style={[styles.dFlex, styles.flexRow, styles.ph5, styles.justifyContentBetween, styles.mb2]}> | ||
| <Animated.Text | ||
| style={[styles.textLabelSupporting]} | ||
| entering={hasComments ? undefined : FadeIn} | ||
| exiting={isFocused ? FadeOut : undefined} | ||
| > | ||
| {hasComments || isLoadingReportActions ? translate('common.comments') : ''} | ||
| </Animated.Text> | ||
| {!isEmptyTransactions && ( | ||
| <View style={[styles.dFlex, styles.flexRow, styles.alignItemsCenter, styles.pr3]}> | ||
| <Text style={[styles.mr3, styles.textLabelSupporting]}>{translate('common.total')}</Text> | ||
| <Text style={[shouldUseNarrowLayout ? styles.mnw64p : styles.mnw100p, styles.textAlignRight, styles.textBold, hasPendingAction && styles.opacitySemiTransparent]}> | ||
| {convertToDisplayString(totalDisplaySpend, report?.currency)} | ||
| </Text> | ||
| </View> | ||
| )} | ||
| </View> | ||
| ); | ||
| } | ||
|
|
||
| MoneyRequestReportTotalSpend.displayName = 'MoneyRequestReportTotalSpend'; | ||
|
|
||
| export default MoneyRequestReportTotalSpend; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| import React, {useEffect, useRef} from 'react'; | ||
| import type {View} from 'react-native'; | ||
| import {getButtonRole} from '@components/Button/utils'; | ||
| import OfflineWithFeedback from '@components/OfflineWithFeedback'; | ||
| import {PressableWithFeedback} from '@components/Pressable'; | ||
| import type {TableColumnSize} from '@components/Search/types'; | ||
| import TransactionItemRow from '@components/TransactionItemRow'; | ||
| import useAnimatedHighlightStyle from '@hooks/useAnimatedHighlightStyle'; | ||
| import useLocalize from '@hooks/useLocalize'; | ||
| import useResponsiveLayout from '@hooks/useResponsiveLayout'; | ||
| import useTheme from '@hooks/useTheme'; | ||
| import useThemeStyles from '@hooks/useThemeStyles'; | ||
| import ControlSelection from '@libs/ControlSelection'; | ||
| import canUseTouchScreen from '@libs/DeviceCapabilities/canUseTouchScreen'; | ||
| import {getTransactionPendingAction, isTransactionPendingDelete} from '@libs/TransactionUtils'; | ||
| import variables from '@styles/variables'; | ||
| import CONST from '@src/CONST'; | ||
| import type {TransactionWithOptionalHighlight} from './MoneyRequestReportTransactionList'; | ||
|
|
||
| const allReportColumns = [ | ||
| CONST.REPORT.TRANSACTION_LIST.COLUMNS.RECEIPT, | ||
| CONST.REPORT.TRANSACTION_LIST.COLUMNS.TYPE, | ||
| CONST.REPORT.TRANSACTION_LIST.COLUMNS.DATE, | ||
| CONST.REPORT.TRANSACTION_LIST.COLUMNS.MERCHANT, | ||
| CONST.REPORT.TRANSACTION_LIST.COLUMNS.CATEGORY, | ||
| CONST.REPORT.TRANSACTION_LIST.COLUMNS.TAG, | ||
| CONST.REPORT.TRANSACTION_LIST.COLUMNS.COMMENTS, | ||
| CONST.REPORT.TRANSACTION_LIST.COLUMNS.TOTAL_AMOUNT, | ||
| ]; | ||
|
|
||
| type MoneyRequestReportTransactionItemProps = { | ||
| /** The transaction that is being displayed */ | ||
| transaction: TransactionWithOptionalHighlight; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is still missing the comment |
||
|
|
||
| /** Whether the mobile selection mode is enabled */ | ||
| isSelectionModeEnabled: boolean; | ||
|
|
||
| /** Callback function triggered upon pressing a transaction checkbox. */ | ||
| toggleTransaction: (transactionID: string) => void; | ||
|
|
||
| /** Callback function triggered upon pressing a transaction. */ | ||
| handleOnPress: (transactionID: string) => void; | ||
|
|
||
| /** Callback function triggered upon long pressing a transaction. */ | ||
| handleLongPress: (transactionID: string) => void; | ||
|
|
||
| /** Whether the transaction is selected */ | ||
| isSelected: boolean; | ||
|
|
||
| /** The size of the date column */ | ||
| dateColumnSize: TableColumnSize; | ||
|
|
||
| /** The size of the amount column */ | ||
| amountColumnSize: TableColumnSize; | ||
|
|
||
| /** The size of the tax amount column */ | ||
| taxAmountColumnSize: TableColumnSize; | ||
|
|
||
| /** Callback function that scrolls to this transaction in case it is newly added */ | ||
| scrollToNewTransaction?: (offset: number) => void; | ||
|
SzymczakJ marked this conversation as resolved.
|
||
| }; | ||
|
|
||
| function MoneyRequestReportTransactionItem({ | ||
| transaction, | ||
| isSelectionModeEnabled, | ||
| toggleTransaction, | ||
| isSelected, | ||
| handleOnPress, | ||
| handleLongPress, | ||
| dateColumnSize, | ||
| amountColumnSize, | ||
| taxAmountColumnSize, | ||
| scrollToNewTransaction, | ||
| }: MoneyRequestReportTransactionItemProps) { | ||
| const {translate} = useLocalize(); | ||
| const styles = useThemeStyles(); | ||
| // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth | ||
| const {isSmallScreenWidth, isMediumScreenWidth, shouldUseNarrowLayout} = useResponsiveLayout(); | ||
| const theme = useTheme(); | ||
| const isPendingDelete = isTransactionPendingDelete(transaction); | ||
| const pendingAction = getTransactionPendingAction(transaction); | ||
|
|
||
| const viewRef = useRef<View>(null); | ||
|
|
||
| // This useEffect scrolls to this transaction when it is newly added to the report | ||
| useEffect(() => { | ||
| if (!transaction.shouldBeHighlighted || !scrollToNewTransaction) { | ||
| return; | ||
| } | ||
| viewRef?.current?.measure((x, y, width, height, pageX, pageY) => { | ||
|
SzymczakJ marked this conversation as resolved.
|
||
| scrollToNewTransaction?.(pageY); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The typesript specifically points to |
||
| }); | ||
| }, [scrollToNewTransaction, transaction.shouldBeHighlighted]); | ||
|
|
||
| const animatedHighlightStyle = useAnimatedHighlightStyle({ | ||
| borderRadius: variables.componentBorderRadius, | ||
| shouldHighlight: transaction.shouldBeHighlighted ?? false, | ||
| highlightColor: theme.messageHighlightBG, | ||
| backgroundColor: theme.highlightBG, | ||
| }); | ||
|
|
||
| return ( | ||
| <OfflineWithFeedback pendingAction={pendingAction}> | ||
| <PressableWithFeedback | ||
| key={transaction.transactionID} | ||
| onPress={() => { | ||
| handleOnPress(transaction.transactionID); | ||
| }} | ||
| accessibilityLabel={translate('iou.viewDetails')} | ||
| role={getButtonRole(true)} | ||
| isNested | ||
| id={transaction.transactionID} | ||
| style={[styles.transactionListItemStyle]} | ||
| hoverStyle={[!isPendingDelete && styles.hoveredComponentBG, isSelected && styles.activeComponentBG]} | ||
| dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}} | ||
| onPressIn={() => canUseTouchScreen() && ControlSelection.block()} | ||
| onPressOut={() => ControlSelection.unblock()} | ||
| onLongPress={() => { | ||
| handleLongPress(transaction.transactionID); | ||
| }} | ||
| disabled={isTransactionPendingDelete(transaction)} | ||
| ref={viewRef} | ||
| wrapperStyle={[animatedHighlightStyle, styles.userSelectNone]} | ||
| > | ||
| <TransactionItemRow | ||
| transactionItem={transaction} | ||
| isSelected={isSelected} | ||
| dateColumnSize={dateColumnSize} | ||
| amountColumnSize={amountColumnSize} | ||
| taxAmountColumnSize={taxAmountColumnSize} | ||
| shouldShowTooltip | ||
| shouldUseNarrowLayout={shouldUseNarrowLayout || isMediumScreenWidth} | ||
| shouldShowCheckbox={!!isSelectionModeEnabled || !isSmallScreenWidth} | ||
| onCheckboxPress={toggleTransaction} | ||
| columns={allReportColumns} | ||
| isDisabled={isPendingDelete} | ||
| /> | ||
| </PressableWithFeedback> | ||
| </OfflineWithFeedback> | ||
| ); | ||
| } | ||
|
|
||
| MoneyRequestReportTransactionItem.displayName = 'MoneyRequestReportTransactionItem'; | ||
|
|
||
| export default MoneyRequestReportTransactionItem; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still missing the comment