Skip to content
Merged
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
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5314,6 +5314,7 @@ const CONST = {

REPORT_VIOLATIONS: {
FIELD_REQUIRED: 'fieldRequired',
RBR_MESSAGE_MAX_CHARACTERS_FOR_PREVIEW: 40,
},

REPORT_VIOLATIONS_EXCLUDED_FIELDS: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ import {
} from '@libs/ReportUtils';
import type {TransactionDetails} from '@libs/ReportUtils';
import StringUtils from '@libs/StringUtils';
import type {TranslationPathOrText} from '@libs/TransactionPreviewUtils';
import {getViolationTranslatePath} from '@libs/TransactionPreviewUtils';
import {
compareDuplicateTransactionFields,
hasMissingSmartscanFields,
Expand Down Expand Up @@ -222,6 +224,8 @@ function MoneyRequestPreviewContent({
showContextMenuForReport(event, contextMenuAnchor, reportID, action, checkIfContextMenuActive);
};

const getTranslatedText = (item: TranslationPathOrText) => (item.translationPath ? translate(item.translationPath) : item.text ?? '');

const getPreviewHeaderText = (): string => {
let message = showCashOrCard;

Expand Down Expand Up @@ -256,11 +260,9 @@ function MoneyRequestPreviewContent({
if (firstViolation) {
const canEdit = isMoneyRequestAction && canEditMoneyRequest(action, transaction);
const violationMessage = ViolationsUtils.getViolationTranslation(firstViolation, translate, canEdit);
const violationsCount = violations?.filter((v) => v.type === CONST.VIOLATION_TYPES.VIOLATION).length ?? 0;
const isTooLong = violationsCount > 1 || violationMessage.length > 15;
const hasViolationsAndFieldErrors = violationsCount > 0 && hasFieldErrors;

return `${message} ${CONST.DOT_SEPARATOR} ${isTooLong || hasViolationsAndFieldErrors ? translate('violations.reviewRequired') : violationMessage}`;
const translationPath = getViolationTranslatePath(violations, hasFieldErrors, violationMessage);
return `${message} ${CONST.DOT_SEPARATOR} ${getTranslatedText(translationPath)}`;
}
if (hasFieldErrors) {
const isMerchantMissing = isMerchantMissingTransactionUtils(transaction);
Expand Down
6 changes: 3 additions & 3 deletions src/components/VideoPlayerPreview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import {useSearchContext} from '@components/Search/SearchContext';
import VideoPlayer from '@components/VideoPlayer';
import IconButton from '@components/VideoPlayer/IconButton';
import {usePlaybackContext} from '@components/VideoPlayerContexts/PlaybackContext';
import useCheckIfRouteHasRemainedUnchanged from '@hooks/useCheckIfRouteHasRemainedUnchanged';
import useFirstRenderRoute from '@hooks/useFirstRenderRoute';
import useIsOnInitialRenderReportScreen from '@hooks/useIsOnInitialRenderReportScreen';
import useLocalize from '@hooks/useLocalize';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
Expand Down Expand Up @@ -66,9 +66,9 @@ function VideoPlayerPreview({videoUrl, thumbnailUrl, reportID, fileName, videoDi
const {isOnSearch} = useSearchContext();
const navigation = useNavigation();

const isOnInitialRenderReportScreen = useIsOnInitialRenderReportScreen();
const didUserNavigateOutOfReportScreen = useCheckIfRouteHasRemainedUnchanged();
// We want to play the video only when the user is on the page where it was rendered
const firstRenderRoute = useFirstRenderRoute(isOnInitialRenderReportScreen);
const firstRenderRoute = useFirstRenderRoute(didUserNavigateOutOfReportScreen);

// `onVideoLoaded` is passed to VideoPlayerPreview's `Video` element which is displayed only on web.
// VideoReadyForDisplayEvent type is lacking srcElement, that's why it's added here
Expand Down
48 changes: 48 additions & 0 deletions src/hooks/useCheckIfRouteHasRemainedUnchanged.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {useNavigation} from '@react-navigation/native';
import {useCallback, useEffect, useRef} from 'react';
import Navigation from '@navigation/Navigation';
import ROUTES from '@src/ROUTES';

/**
* Hook that returns a function to check if the currently active route remains the same as the last known route.
* The last known route reference is updated every time the component experiences a 'blur' event,
* except when opening an attachments modal, which is treated as an exception and does not trigger a reference update.
*
* @return Function that checks if the last known route matches the currently active route.
*/
function useCheckIfRouteHasRemainedUnchanged(): () => boolean {
const lastKnownRouteRef = useRef<string | undefined>(undefined);
const navigation = useNavigation();

// Function to compare the last known route with the current active route
const hasRouteRemainedUnchanged = useCallback(() => {
return lastKnownRouteRef.current === Navigation.getActiveRouteWithoutParams();
}, []);

// Initialize the initial route when navigation is ready
useEffect(() => {
Navigation.isNavigationReady().then(() => {
if (lastKnownRouteRef.current !== undefined) {
return;
}

lastKnownRouteRef.current = Navigation.getActiveRouteWithoutParams();
});
}, []);

// Update the route reference on 'blur' events, except when opening attachments modal
useEffect(() => {
return navigation.addListener('blur', () => {
const currentRoute = Navigation.getActiveRouteWithoutParams();
if (currentRoute === `/${ROUTES.ATTACHMENTS.route}`) {
// Skip route update when attachment modal is opened
return;
}
lastKnownRouteRef.current = currentRoute;
});
}, [navigation]);

return hasRouteRemainedUnchanged;
}

export default useCheckIfRouteHasRemainedUnchanged;
36 changes: 0 additions & 36 deletions src/hooks/useIsOnInitialRenderReportScreen.ts

This file was deleted.

23 changes: 17 additions & 6 deletions src/libs/TransactionPreviewUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ const getOriginalTransactionIfBillIsSplit = (transaction: OnyxEntry<OnyxTypes.Tr
return {isBillSplit: !!originalTransaction, originalTransaction: originalTransaction ?? transaction};
};

function getViolationTranslatePath(violations: OnyxTypes.TransactionViolations, hasFieldErrors: boolean, violationMessage: string): TranslationPathOrText {
const violationsCount = violations?.filter((v) => v.type === CONST.VIOLATION_TYPES.VIOLATION).length ?? 0;

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.

Looks like we forgot a case, on how we should filter the violations more information here: #65477 (comment)

const isTooLong = violationsCount > 1 || violationMessage.length > CONST.REPORT_VIOLATIONS.RBR_MESSAGE_MAX_CHARACTERS_FOR_PREVIEW;
const hasViolationsAndFieldErrors = violationsCount > 0 && hasFieldErrors;

return isTooLong || hasViolationsAndFieldErrors ? {translationPath: 'violations.reviewRequired'} : {text: violationMessage};
}

function getTransactionPreviewTextAndTranslationPaths({
iouReport,
transaction,
Expand Down Expand Up @@ -171,11 +179,7 @@ function getTransactionPreviewTextAndTranslationPaths({
}

if (violationMessage && RBRMessage === undefined) {
const violationsCount = violations?.filter((v) => v.type === CONST.VIOLATION_TYPES.VIOLATION).length ?? 0;
const isTooLong = violationsCount > 1 || violationMessage.length > 15;
const hasViolationsAndFieldErrors = violationsCount > 0 && hasFieldErrors;

RBRMessage = isTooLong || hasViolationsAndFieldErrors ? {translationPath: 'violations.reviewRequired'} : {text: violationMessage};
RBRMessage = getViolationTranslatePath(violations, hasFieldErrors, violationMessage);
}

if (hasFieldErrors && RBRMessage === undefined) {
Expand Down Expand Up @@ -335,5 +339,12 @@ function createTransactionPreviewConditionals({
};
}

export {getReviewNavigationRoute, getIOUData, getTransactionPreviewTextAndTranslationPaths, createTransactionPreviewConditionals, getOriginalTransactionIfBillIsSplit};
export {
getReviewNavigationRoute,
getIOUData,
getTransactionPreviewTextAndTranslationPaths,
createTransactionPreviewConditionals,
getOriginalTransactionIfBillIsSplit,
getViolationTranslatePath,
};
export type {TranslationPathOrText};
8 changes: 7 additions & 1 deletion src/libs/__mocks__/TransactionPreviewUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,11 @@ function getIOUData(
return undefined;
}

export {getTransactionPreviewTextAndTranslationPaths, createTransactionPreviewConditionals, getReviewNavigationRoute, getOriginalTransactionIfBillIsSplit} from '../TransactionPreviewUtils';
export {
getTransactionPreviewTextAndTranslationPaths,
createTransactionPreviewConditionals,
getReviewNavigationRoute,
getOriginalTransactionIfBillIsSplit,
getViolationTranslatePath,
} from '../TransactionPreviewUtils';
export {getIOUData};