Mail: moving between messages no longer rebuilds the whole page (only the reader and the selected row change)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-22 11:12:59 -04:00
1 parent 0f324bbf60
commit 1f08443c38
1 file changed
+10
+10
View File
@@ -138,6 +138,15 @@ async function mailAdminCard() {
async function viewMail(args = []) { async function viewMail(args = []) {
const v = $('#view'); const v = $('#view');
if (!cfg.mail) { v.innerHTML = '<div class="wrap"><h1>Mail</h1><p class="empty">Mail is not available to you.</p></div>'; return; } if (!cfg.mail) { v.innerHTML = '<div class="wrap"><h1>Mail</h1><p class="empty">Mail is not available to you.</p></div>'; return; }
// Moving between messages (or back to the list) in the same folder changes only the reader and the highlighted row: the page is not rebuilt,
// so there is no flash, and the list keeps its place.
const shell = document.querySelector('.mailapp'), k0 = args[0], key0 = args[1];
if (shell && v.contains(shell) && mail.st && mail.st.connected && mail.accts.length && (k0 === 'm' || k0 === undefined) && (k0 !== 'm' || !String(key0).includes('~') || String(key0).split('~')[0] === mail.acct)) {
const view = $('#view');
if (k0 === 'm') { if (shell.dataset.mode !== 'read') mail.listScroll = view.scrollTop; shell.dataset.mode = 'read'; mailMarkSel(key0); mailOpen(key0); }
else { shell.dataset.mode = 'list'; mail.msg = null; mailDrawReader(); mailMarkSel(''); requestAnimationFrame(() => { if (mail.listScroll) view.scrollTop = mail.listScroll; }); }
return;
}
// The accounts come from the server without any network call to the mail providers ("light"), so the page can draw at once; the folders, the message // The accounts come from the server without any network call to the mail providers ("light"), so the page can draw at once; the folders, the message
// list and the real unread counts then load side by side instead of one after another. // list and the real unread counts then load side by side instead of one after another.
let st = mail.st; let st = mail.st;
@@ -228,6 +237,7 @@ async function mailLoadList(reset) {
mailDrawList(); mailDrawList();
} catch (e) { if (showing) return; const el = $('#mrows'); if (el) el.innerHTML = `<p class="err" style="padding:12px">${esc(e.message)}</p>`; if (/Connect again/.test(e.message)) { mail.st = null; mcClear(); setTimeout(route, 1200); } } } catch (e) { if (showing) return; const el = $('#mrows'); if (el) el.innerHTML = `<p class="err" style="padding:12px">${esc(e.message)}</p>`; if (/Connect again/.test(e.message)) { mail.st = null; mcClear(); setTimeout(route, 1200); } }
} }
function mailMarkSel(id) { document.querySelectorAll('a.mrow').forEach(a => a.classList.toggle('sel', !!id && decodeURIComponent(a.getAttribute('href').slice(9)) === id)); }
function mailDrawList() { function mailDrawList() {
const rows = $('#mrows'); if (!rows) return; const rows = $('#mrows'); if (!rows) return;
const sel = (location.hash.match(/^#\/mail\/m\/([^/]+)/) || [])[1]; const sel = (location.hash.match(/^#\/mail\/m\/([^/]+)/) || [])[1];