nx-webmail: add robust paged inbox hydration after login
Some checks failed
Publish nx-webmail Image (Gitea) / publish (push) Has been cancelled
Some checks failed
Publish nx-webmail Image (Gitea) / publish (push) Has been cancelled
This commit is contained in:
@@ -533,6 +533,67 @@ export default function Webmail() {
|
||||
}
|
||||
};
|
||||
|
||||
const hydrateFolderFully = async (folderName, authOverride = authPayload, credOverride = credentials) => {
|
||||
const folder = folderName || activeFolder || 'INBOX';
|
||||
const accountId = makeAccountId(authOverride);
|
||||
const direction = String(sortOrder || 'newest');
|
||||
const seen = new Set();
|
||||
const merged = [];
|
||||
let offset = 0;
|
||||
let total = 0;
|
||||
let hasMore = true;
|
||||
let guard = 0;
|
||||
|
||||
while (hasMore && guard < 200) {
|
||||
const data = await postJson('/api/webmail/inbox', {
|
||||
...authOverride,
|
||||
folder,
|
||||
offset,
|
||||
limit: INBOX_PAGE_SIZE,
|
||||
fetchAll: false,
|
||||
direction
|
||||
});
|
||||
|
||||
const batch = Array.isArray(data?.emails) ? data.emails : [];
|
||||
for (const msg of batch) {
|
||||
const uid = Number(msg?.id || 0);
|
||||
if (!seen.has(uid)) {
|
||||
seen.add(uid);
|
||||
merged.push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
total = Number(data?.total || Math.max(total, merged.length));
|
||||
const nextOffset = Number(data?.nextOffset || (offset + batch.length));
|
||||
const canAdvance = nextOffset > offset;
|
||||
hasMore = Boolean(data?.hasMore) && canAdvance && batch.length > 0;
|
||||
offset = nextOffset;
|
||||
guard += 1;
|
||||
|
||||
if (activeFolderRef.current !== folder || activeAccountIdRef.current !== accountId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const safeTotal = Math.max(total, merged.length);
|
||||
const paging = {
|
||||
total: safeTotal,
|
||||
nextOffset: merged.length,
|
||||
hasMore: merged.length < safeTotal,
|
||||
loadedAll: merged.length >= safeTotal,
|
||||
direction,
|
||||
updatedAt: Date.now()
|
||||
};
|
||||
setEmails([...merged]);
|
||||
setFolderPaging(accountId, folder, paging);
|
||||
setViewCache(accountId, folder, direction, merged, paging);
|
||||
upsertAccountCache({
|
||||
accountId,
|
||||
folderName: folder,
|
||||
folderEmails: merged
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const connectWithCredentials = async (auth, lastFolder, credOverride = credentials, options = {}) => {
|
||||
const { skipInitialFetchIfCached = false } = options;
|
||||
try {
|
||||
@@ -573,12 +634,12 @@ export default function Webmail() {
|
||||
await fetchInbox(defaultFolder, auth, true, credOverride, {
|
||||
keepSelection: true,
|
||||
silent: Boolean(cachedDefaultEmails) || skipInitialFetchIfCached,
|
||||
fetchAll: true,
|
||||
resetToFirstPage: false
|
||||
resetToFirstPage: true
|
||||
});
|
||||
saveSession(credOverride, defaultFolder);
|
||||
upsertAccount(credOverride, defaultFolder);
|
||||
return true;
|
||||
await hydrateFolderFully(defaultFolder, auth, credOverride);
|
||||
saveSession(credOverride, defaultFolder);
|
||||
upsertAccount(credOverride, defaultFolder);
|
||||
return true;
|
||||
} catch (error) {
|
||||
setLoginError(error.message || 'Login failed.');
|
||||
setIsLoggedIn(false);
|
||||
@@ -1312,12 +1373,14 @@ export default function Webmail() {
|
||||
setIsRefreshingInbox(true);
|
||||
try {
|
||||
const shouldFetchAll = !Boolean(activeFolderPaging?.loadedAll);
|
||||
await fetchInbox(activeFolder, authPayload, true, credentials, {
|
||||
keepSelection: true,
|
||||
syncOnly: !shouldFetchAll,
|
||||
fetchAll: shouldFetchAll,
|
||||
forceRefresh: shouldFetchAll
|
||||
});
|
||||
if (shouldFetchAll) {
|
||||
await hydrateFolderFully(activeFolder, authPayload, credentials);
|
||||
} else {
|
||||
await fetchInbox(activeFolder, authPayload, true, credentials, {
|
||||
keepSelection: true,
|
||||
syncOnly: true
|
||||
});
|
||||
}
|
||||
await fetchFolderSizes(authPayload);
|
||||
await fetchQuota(authPayload);
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user