Skip to content
Closed
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
37 changes: 34 additions & 3 deletions src/hooks/useAutoUpdateTimezone.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,57 @@
import {useEffect} from 'react';
import {useEffect, useRef} from 'react';
import {updateAutomaticTimezone} from '@userActions/PersonalDetails';
import {isActingAsDelegateSelector} from '@selectors/Account';
import type {SelectedTimezone} from '@src/types/onyx/PersonalDetails';
import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails';
import useOnyx from './useOnyx';
import ONYXKEYS from '@src/ONYXKEYS';

const THROTTLE_INTERVAL_MS = 60 * 60 * 1000; // 1 hour

const useAutoUpdateTimezone = () => {
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
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.

❌ CLEAN-REACT-PATTERNS-2 (docs)

currentUserPersonalDetails?.account accesses a property that does not exist on the PersonalDetails type (nor on CurrentUserPersonalDetails). This will always be undefined, so isActingAsDelegateSelector(account) will always return false, making the delegate check completely non-functional.

The isActingAsDelegateSelector expects OnyxEntry<Account> from the ONYXKEYS.ACCOUNT Onyx key, not a field from personal details. The established pattern used elsewhere in the codebase (e.g., ProductTrainingContext/index.tsx:62, AddNewCardPage.tsx:50) is:

import useOnyx from '@hooks/useOnyx';
import ONYXKEYS from '@src/ONYXKEYS';

const [isActingAsDelegate] = useOnyx(ONYXKEYS.ACCOUNT, {selector: isActingAsDelegateSelector});

Replace lines 12-13 with:

const [isActingAsDelegate] = useOnyx(ONYXKEYS.ACCOUNT, {selector: isActingAsDelegateSelector});

And update the references from isDelegate to isActingAsDelegate (or rename as preferred).


Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.

const timezone = currentUserPersonalDetails?.timezone ?? {};
const accountID = currentUserPersonalDetails?.accountID;

// Use useOnyx to get the Account data (contains delegatedAccess)
const [account] = useOnyx(ONYXKEYS.ACCOUNT);
const isDelegate = isActingAsDelegateSelector(account);

// Use useRef to store per-account timestamps
const lastUpdateTimestamps = useRef<Record<number, number>>({});

useEffect(() => {
// Skip auto-timezone updates for copilot/delegate sessions
if (isDelegate) {
return;
}

const currentTime = Date.now();

// Get the last update timestamp for this specific account
const lastUpdateTimestamp = lastUpdateTimestamps.current[accountID] ?? 0;

// Throttle timezone updates to once per hour (per account)
if (currentTime - lastUpdateTimestamp < THROTTLE_INTERVAL_MS) {
return;
}

const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone as SelectedTimezone;
const hasValidCurrentTimezone = typeof currentTimezone === 'string' && currentTimezone.trim().length > 0;

if (hasValidCurrentTimezone && timezone?.automatic && timezone?.selected !== currentTimezone) {
// Update the timestamp for this specific account
lastUpdateTimestamps.current[accountID] = currentTime;
updateAutomaticTimezone(
{
automatic: true,
selected: currentTimezone,
},
currentUserPersonalDetails.accountID,
accountID,
);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [timezone?.automatic, timezone?.selected]);
}, [timezone?.automatic, timezone?.selected, isDelegate, accountID]);
};

export default useAutoUpdateTimezone;
Loading