mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-17 02:05:22 -04:00
Prewarm email list before first open
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import spinnerModule from './spinner.js';
|
import spinnerModule from './spinner.js';
|
||||||
import sessionModule from './sessions.js';
|
import sessionModule from './sessions.js';
|
||||||
import { initEmailLibrary, openEmailLibrary, closeEmailLibrary, isOpen as isLibOpen } from './emailLibrary.js';
|
import { initEmailLibrary, openEmailLibrary, closeEmailLibrary, isOpen as isLibOpen, prewarmEmailLibrary } from './emailLibrary.js';
|
||||||
import * as Modals from './modalManager.js';
|
import * as Modals from './modalManager.js';
|
||||||
import { applyEdgeDock } from './modalSnap.js';
|
import { applyEdgeDock } from './modalSnap.js';
|
||||||
|
|
||||||
@@ -161,6 +161,7 @@ function _bindEvents() {
|
|||||||
// Initial unread count check, refresh every 60s
|
// Initial unread count check, refresh every 60s
|
||||||
_refreshUnreadCount();
|
_refreshUnreadCount();
|
||||||
setInterval(_refreshUnreadCount, 60000);
|
setInterval(_refreshUnreadCount, 60000);
|
||||||
|
prewarmEmailLibrary({ delay: 3000 });
|
||||||
|
|
||||||
// Deep-link: #email=<folder>:<uid> opens the library and expands that card
|
// Deep-link: #email=<folder>:<uid> opens the library and expands that card
|
||||||
_maybeOpenFromHash();
|
_maybeOpenFromHash();
|
||||||
|
|||||||
@@ -402,14 +402,25 @@ function _acct() {
|
|||||||
// results and __scheduled__ are deliberately not cached.
|
// results and __scheduled__ are deliberately not cached.
|
||||||
const _libListCache = new Map();
|
const _libListCache = new Map();
|
||||||
const _LIB_CACHE_MAX = 24;
|
const _LIB_CACHE_MAX = 24;
|
||||||
|
let _libPrewarmTimer = null;
|
||||||
|
let _libPrewarmPromise = null;
|
||||||
|
let _libLastPrewarmAt = 0;
|
||||||
|
|
||||||
function _libCacheKey() {
|
function _libCacheKeyFor(accountId, folder, filter, hasAttachments) {
|
||||||
return [
|
return [
|
||||||
|
accountId || '',
|
||||||
|
folder || '',
|
||||||
|
filter || '',
|
||||||
|
hasAttachments ? 1 : 0,
|
||||||
|
].join('|');
|
||||||
|
}
|
||||||
|
function _libCacheKey() {
|
||||||
|
return _libCacheKeyFor(
|
||||||
state._libAccountId || '',
|
state._libAccountId || '',
|
||||||
state._libFolder || '',
|
state._libFolder || '',
|
||||||
state._libFilter || '',
|
state._libFilter || '',
|
||||||
state._libHasAttachments ? 1 : 0,
|
state._libHasAttachments
|
||||||
].join('|');
|
);
|
||||||
}
|
}
|
||||||
function _libCacheGet(key) { return _libListCache.get(key) || null; }
|
function _libCacheGet(key) { return _libListCache.get(key) || null; }
|
||||||
function _libCachePut(key, value) {
|
function _libCachePut(key, value) {
|
||||||
@@ -421,6 +432,48 @@ function _libCachePut(key, value) {
|
|||||||
_libListCache.delete(oldest);
|
_libListCache.delete(oldest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function prewarmEmailLibrary({ delay = 2500 } = {}) {
|
||||||
|
if (_libPrewarmTimer || _libPrewarmPromise) return;
|
||||||
|
const elapsed = Date.now() - _libLastPrewarmAt;
|
||||||
|
if (elapsed >= 0 && elapsed < 60000) return;
|
||||||
|
_libPrewarmTimer = setTimeout(() => {
|
||||||
|
_libPrewarmTimer = null;
|
||||||
|
_libPrewarmPromise = _prewarmDefaultEmailView()
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => { _libPrewarmPromise = null; });
|
||||||
|
}, Math.max(0, Number(delay) || 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _prewarmDefaultEmailView() {
|
||||||
|
if (state._libOpen) return;
|
||||||
|
_libLastPrewarmAt = Date.now();
|
||||||
|
const folder = 'INBOX';
|
||||||
|
const filter = 'all';
|
||||||
|
const accountId = state._libAccountId || '';
|
||||||
|
const ck = _libCacheKeyFor(accountId, folder, filter, false);
|
||||||
|
if (_libCacheGet(ck)) return;
|
||||||
|
|
||||||
|
// The accounts request is cheap and warms the account strip for first open.
|
||||||
|
// Then the list request warms both the client cache and the backend IMAP/read
|
||||||
|
// cache. Failure stays silent: no configured mail should not nag on app boot.
|
||||||
|
try {
|
||||||
|
const accountsRes = await fetch(`${API_BASE}/api/email/accounts`, { credentials: 'same-origin' });
|
||||||
|
if (accountsRes.ok) {
|
||||||
|
const accountsData = await accountsRes.json().catch(() => ({}));
|
||||||
|
if (Array.isArray(accountsData.accounts)) state._libAccounts = accountsData.accounts;
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
|
const accountQS = accountId ? `&account_id=${encodeURIComponent(accountId)}` : '';
|
||||||
|
const res = await fetch(`${API_BASE}/api/email/list?folder=${encodeURIComponent(folder)}${accountQS}&limit=100&offset=0&filter=${filter}`, {
|
||||||
|
credentials: 'same-origin',
|
||||||
|
});
|
||||||
|
if (!res.ok) return;
|
||||||
|
const data = await res.json().catch(() => null);
|
||||||
|
if (!data || data.error) return;
|
||||||
|
_libCachePut(ck, { emails: data.emails || [], total: data.total || 0 });
|
||||||
|
}
|
||||||
function _libCacheWriteBack() {
|
function _libCacheWriteBack() {
|
||||||
// After a local mutation that already updated state._libEmails
|
// After a local mutation that already updated state._libEmails
|
||||||
// (delete / archive / bulk), sync the change into the cache so the
|
// (delete / archive / bulk), sync the change into the cache so the
|
||||||
|
|||||||
Reference in New Issue
Block a user