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

fix: Use local Onyx key to throttle location permission prompts. #48237

Merged
merged 14 commits into from
Oct 8, 2024
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 @@ -2046,6 +2046,7 @@ const CONST = {
OPTIMISTIC_TRANSACTION_ID: '1',
// Note: These payment types are used when building IOU reportAction message values in the server and should
// not be changed.
LOCATION_PERMISSION_PROMPT_THRESHOLD_DAYS: 7,
PAYMENT_TYPE: {
ELSEWHERE: 'Elsewhere',
EXPENSIFY: 'Expensify',
Expand Down
4 changes: 4 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ const ONYXKEYS = {
/** The NVP with the last payment method used per policy */
NVP_LAST_PAYMENT_METHOD: 'nvp_private_lastPaymentMethod',

/** Last date (yyyy-MM-dd HH:mm:ss) when the location permission prompt was shown. */
NVP_LAST_LOCATION_PERMISSION_PROMPT: 'nvp_lastLocalPermissionPrompt',

/** This NVP holds to most recent waypoints that a person has used when creating a distance expense */
NVP_RECENT_WAYPOINTS: 'nvp_expensify_recentWaypoints',

Expand Down Expand Up @@ -903,6 +906,7 @@ type OnyxValuesMapping = {
[ONYXKEYS.NVP_DISMISSED_HOLD_USE_EXPLANATION]: boolean;
[ONYXKEYS.FOCUS_MODE_NOTIFICATION]: boolean;
[ONYXKEYS.NVP_LAST_PAYMENT_METHOD]: OnyxTypes.LastPaymentMethod;
[ONYXKEYS.NVP_LAST_LOCATION_PERMISSION_PROMPT]: string;
[ONYXKEYS.LAST_EXPORT_METHOD]: OnyxTypes.LastExportMethod;
[ONYXKEYS.NVP_RECENT_WAYPOINTS]: OnyxTypes.RecentWaypoint[];
[ONYXKEYS.NVP_INTRO_SELECTED]: OnyxTypes.IntroSelected;
Expand Down
22 changes: 22 additions & 0 deletions src/libs/DateUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
addHours,
addMilliseconds,
addMinutes,
differenceInDays,
eachDayOfInterval,
eachMonthOfInterval,
endOfDay,
Expand Down Expand Up @@ -825,6 +826,25 @@ function isCardExpired(expiryMonth: number, expiryYear: number): boolean {
return expiryYear < currentYear || (expiryYear === currentYear && expiryMonth < currentMonth);
}

/**
* Returns the difference in the number of days from the provided date to/from now.
* @param - The date to compare.
* @returns The difference in days as an integer.
*/
function getDifferenceInDaysFromNow(date: Date) {
return differenceInDays(new Date(), date);
}

/**
* Returns a boolean value indicating whether the provided date string can be parsed as a valid date.
* @param dateString string
* @returns True if the date string is valid, otherwise false.
*/
function isValidDateString(dateString: string) {
const date = new Date(dateString);
return !Number.isNaN(date.getTime());
}

const DateUtils = {
isDate,
formatToDayOfWeek,
Expand Down Expand Up @@ -870,6 +890,8 @@ const DateUtils = {
getFormattedTransportDate,
doesDateBelongToAPastYear,
isCardExpired,
getDifferenceInDaysFromNow,
isValidDateString,
};

export default DateUtils;
5 changes: 5 additions & 0 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8289,6 +8289,10 @@ function mergeDuplicates(params: TransactionMergeParams) {
API.write(WRITE_COMMANDS.TRANSACTION_MERGE, params, {optimisticData, failureData});
}

function updateLastLocationPermissionPrompt() {
Onyx.set(ONYXKEYS.NVP_LAST_LOCATION_PERMISSION_PROMPT, new Date().toISOString());
}

/** Instead of merging the duplicates, it updates the transaction we want to keep and puts the others on hold without deleting them */
function resolveDuplicates(params: TransactionMergeParams) {
const originalSelectedTransaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${params.transactionID}`];
Expand Down Expand Up @@ -8479,6 +8483,7 @@ export {
updateMoneyRequestTaxAmount,
updateMoneyRequestTaxRate,
mergeDuplicates,
updateLastLocationPermissionPrompt,
resolveDuplicates,
getIOUReportActionToApproveOrPay,
};
Expand Down
19 changes: 16 additions & 3 deletions src/pages/iou/request/step/IOURequestStepConfirmation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import DateUtils from '@libs/DateUtils';
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
import * as FileUtils from '@libs/fileDownload/FileUtils';
import getCurrentPosition from '@libs/getCurrentPosition';
Expand Down Expand Up @@ -74,6 +75,7 @@ function IOURequestStepConfirmation({
const [receiptFile, setReceiptFile] = useState<OnyxEntry<Receipt>>();
const requestType = TransactionUtils.getRequestType(transaction);
const isDistanceRequest = requestType === CONST.IOU.REQUEST_TYPE.DISTANCE;
const [lastLocationPermissionPrompt] = useOnyx(ONYXKEYS.NVP_LAST_LOCATION_PERMISSION_PROMPT);

const receiptFilename = transaction?.filename;
const receiptPath = transaction?.receipt?.source;
Expand Down Expand Up @@ -580,9 +582,17 @@ function IOURequestStepConfirmation({

const onConfirm = (listOfParticipants: Participant[]) => {
setSelectedParticipantList(listOfParticipants);

if (gpsRequired) {
setStartLocationPermissionFlow(true);
return;
const shouldStartLocationPermissionFlow =
!lastLocationPermissionPrompt ||
(DateUtils.isValidDateString(lastLocationPermissionPrompt ?? '') &&
DateUtils.getDifferenceInDaysFromNow(new Date(lastLocationPermissionPrompt ?? '')) > CONST.IOU.LOCATION_PERMISSION_PROMPT_THRESHOLD_DAYS);

if (shouldStartLocationPermissionFlow) {
setStartLocationPermissionFlow(true);
return;
}
}

createTransaction(listOfParticipants);
Expand Down Expand Up @@ -617,7 +627,10 @@ function IOURequestStepConfirmation({
startPermissionFlow={startLocationPermissionFlow}
resetPermissionFlow={() => setStartLocationPermissionFlow(false)}
onGrant={() => createTransaction(selectedParticipantList, true)}
onDeny={() => createTransaction(selectedParticipantList, false)}
onDeny={() => {
IOU.updateLastLocationPermissionPrompt();
createTransaction(selectedParticipantList, false);
}}
/>
)}
<MoneyRequestConfirmationList
Expand Down
Loading