courrier multi account restore compose
This commit is contained in:
parent
6939ad5e35
commit
eb557d16dd
@ -614,141 +614,6 @@ export const useEmailState = () => {
|
||||
}
|
||||
}, [session?.user?.id, state.page, state.currentFolder, loadEmails, logEmailOp]);
|
||||
|
||||
// Calculate and update unread counts from emails
|
||||
const updateUnreadCounts = useCallback(() => {
|
||||
// This function will count unread emails in each folder and update the unreadCountMap
|
||||
if (state.emails.length === 0) return;
|
||||
|
||||
// Create a temporary count map
|
||||
const tempUnreadMap: Record<string, Record<string, number>> = {};
|
||||
|
||||
// Initialize with existing accounts and folders to avoid losing counts
|
||||
// when switching folders
|
||||
state.accounts.forEach(account => {
|
||||
tempUnreadMap[account.id] = { ...state.unreadCountMap[account.id] || {} };
|
||||
|
||||
// Initialize each folder with 0 if it doesn't exist
|
||||
account.folders.forEach(folder => {
|
||||
// Extract base folder name if it has a prefix
|
||||
const baseFolderName = folder.includes(':') ? folder.split(':')[1] : folder;
|
||||
const prefixedFolder = folder.includes(':') ? folder : `${account.id}:${baseFolderName}`;
|
||||
|
||||
// Initialize both prefixed and unprefixed versions
|
||||
if (tempUnreadMap[account.id][baseFolderName] === undefined) {
|
||||
tempUnreadMap[account.id][baseFolderName] = 0;
|
||||
}
|
||||
if (tempUnreadMap[account.id][prefixedFolder] === undefined) {
|
||||
tempUnreadMap[account.id][prefixedFolder] = 0;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Count unread emails from current folder
|
||||
state.emails.forEach(email => {
|
||||
// Check if email is unread
|
||||
const isUnread = email.flags && !email.flags.seen;
|
||||
|
||||
// Only count if it's unread
|
||||
if (isUnread && email.accountId) {
|
||||
// Get folder information
|
||||
let folder = email.folder;
|
||||
let accountId = email.accountId;
|
||||
|
||||
// Make sure the account exists in our map
|
||||
if (!tempUnreadMap[accountId]) {
|
||||
tempUnreadMap[accountId] = {};
|
||||
}
|
||||
|
||||
// Extract folder name if it has a prefix
|
||||
let baseFolderName = folder;
|
||||
if (folder.includes(':')) {
|
||||
const parts = folder.split(':');
|
||||
// Don't override accountId from the folder prefix
|
||||
baseFolderName = parts[1];
|
||||
}
|
||||
|
||||
// Ensure we have entries for both formats
|
||||
if (!tempUnreadMap[accountId][baseFolderName]) {
|
||||
tempUnreadMap[accountId][baseFolderName] = 0;
|
||||
}
|
||||
if (!tempUnreadMap[accountId][folder]) {
|
||||
tempUnreadMap[accountId][folder] = 0;
|
||||
}
|
||||
|
||||
// Increment both formats to ensure they're both available
|
||||
tempUnreadMap[accountId][baseFolderName]++;
|
||||
tempUnreadMap[accountId][folder]++;
|
||||
}
|
||||
});
|
||||
|
||||
// Store the current update for comparison
|
||||
if (!(window as any).__lastUnreadUpdate) {
|
||||
(window as any).__lastUnreadUpdate = {
|
||||
timestamp: 0,
|
||||
map: {}
|
||||
};
|
||||
}
|
||||
|
||||
// Check if the unread counts have actually changed before updating state
|
||||
let hasChanged = false;
|
||||
|
||||
// Compare with current unread count map
|
||||
Object.entries(tempUnreadMap).forEach(([accountId, folderCounts]) => {
|
||||
Object.entries(folderCounts).forEach(([folder, count]) => {
|
||||
if (state.unreadCountMap[accountId]?.[folder] !== count) {
|
||||
hasChanged = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Check if we've updated recently
|
||||
const now = Date.now();
|
||||
const lastUpdate = (window as any).__lastUnreadUpdate;
|
||||
const timeSinceLastUpdate = now - lastUpdate.timestamp;
|
||||
|
||||
// If changes found and not updated too recently, update state
|
||||
if (hasChanged && timeSinceLastUpdate > 500) {
|
||||
// Log only on actual change
|
||||
logEmailOp('UNREAD_COUNTS', 'Updated unread counts:', tempUnreadMap);
|
||||
|
||||
// Create a single dispatch to update all counts at once
|
||||
dispatch({
|
||||
type: 'SET_UNREAD_COUNTS',
|
||||
payload: tempUnreadMap
|
||||
});
|
||||
|
||||
// Update timestamp of last update
|
||||
lastUpdate.timestamp = now;
|
||||
lastUpdate.map = tempUnreadMap;
|
||||
}
|
||||
}, [state.emails, state.accounts, state.unreadCountMap, dispatch, logEmailOp]);
|
||||
|
||||
// Call updateUnreadCounts when relevant state changes
|
||||
useEffect(() => {
|
||||
if (!state.emails || state.emails.length === 0) return;
|
||||
|
||||
// Debounce unread count updates to prevent rapid multiple updates
|
||||
let updateTimeoutId: ReturnType<typeof setTimeout>;
|
||||
|
||||
const debounceMs = 500; // 500ms debounce
|
||||
|
||||
// Function to call after debounce period
|
||||
const debouncedUpdate = () => {
|
||||
updateTimeoutId = setTimeout(() => {
|
||||
updateUnreadCounts();
|
||||
}, debounceMs);
|
||||
};
|
||||
|
||||
// Clear any existing timeout and start a new one
|
||||
debouncedUpdate();
|
||||
|
||||
// Cleanup timeout on unmount or state change
|
||||
return () => {
|
||||
clearTimeout(updateTimeoutId);
|
||||
};
|
||||
// Deliberately exclude unreadCountMap to prevent infinite loops
|
||||
}, [state.emails, updateUnreadCounts]);
|
||||
|
||||
// Fetch unread counts from API
|
||||
const fetchUnreadCounts = useCallback(async () => {
|
||||
// Don't fetch if user is not logged in
|
||||
@ -827,7 +692,59 @@ export const useEmailState = () => {
|
||||
dispatch({ type: 'SET_LOADING_UNREAD_COUNTS', payload: false });
|
||||
}
|
||||
}, [dispatch, session?.user, state.isLoadingUnreadCounts, logEmailOp]);
|
||||
|
||||
// Calculate and update unread counts
|
||||
const updateUnreadCounts = useCallback(() => {
|
||||
// Skip if no emails or accounts
|
||||
if (state.emails.length === 0 || state.accounts.length === 0) return;
|
||||
|
||||
// To avoid running this too frequently, check the timestamp of last update
|
||||
if (!(window as any).__lastUnreadUpdate) {
|
||||
(window as any).__lastUnreadUpdate = { timestamp: 0 };
|
||||
}
|
||||
|
||||
const now = Date.now();
|
||||
const lastUpdate = (window as any).__lastUnreadUpdate;
|
||||
const MIN_UPDATE_INTERVAL = 2000; // 2 seconds minimum between updates
|
||||
|
||||
if (now - lastUpdate.timestamp < MIN_UPDATE_INTERVAL) {
|
||||
return; // Skip if updated too recently
|
||||
}
|
||||
|
||||
// Rather than calculating locally, let's fetch from the API
|
||||
// This ensures we get accurate server-side counts
|
||||
fetchUnreadCounts();
|
||||
|
||||
// Update timestamp of last update
|
||||
lastUpdate.timestamp = now;
|
||||
}, [state.emails.length, state.accounts.length, fetchUnreadCounts]);
|
||||
|
||||
// Call updateUnreadCounts when relevant state changes
|
||||
useEffect(() => {
|
||||
if (!state.emails || state.emails.length === 0) return;
|
||||
|
||||
// Debounce unread count updates to prevent rapid multiple updates
|
||||
let updateTimeoutId: ReturnType<typeof setTimeout>;
|
||||
|
||||
const debounceMs = 2000; // Increase debounce to 2 seconds
|
||||
|
||||
// Function to call after debounce period
|
||||
const debouncedUpdate = () => {
|
||||
updateTimeoutId = setTimeout(() => {
|
||||
updateUnreadCounts();
|
||||
}, debounceMs);
|
||||
};
|
||||
|
||||
// Clear any existing timeout and start a new one
|
||||
debouncedUpdate();
|
||||
|
||||
// Cleanup timeout on unmount or state change
|
||||
return () => {
|
||||
clearTimeout(updateTimeoutId);
|
||||
};
|
||||
// Deliberately exclude unreadCountMap to prevent infinite loops
|
||||
}, [state.emails, updateUnreadCounts]);
|
||||
|
||||
// Tracking when an email is viewed to optimize unread count refreshes
|
||||
const lastViewedEmailRef = useRef<number | null>(null);
|
||||
const fetchFailuresRef = useRef<number>(0);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user