Mail: on a phone the message is as tall as its text, so there is one scroll instead of a scrolling box inside a scrolling page
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UaC9HmtHMdRP8dAbN4wAKj
This commit is contained in:
3 files changed
+13
-4
No files matched your search
+10
-1
@@ -33,6 +33,14 @@ function mailDoc(html, images) {
|
||||
return `<!doctype html><meta charset="utf-8"><meta http-equiv="Content-Security-Policy" content="${csp}"><base target="_blank"><meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<style>body{margin:14px;font:15px/1.45 -apple-system,Segoe UI,Roboto,sans-serif;color:#111;background:#fff;overflow-wrap:anywhere}img{max-width:100%;height:auto}table{max-width:100%}a{color:#1a5fd1}blockquote{margin:0 0 0 6px;padding-left:10px;border-left:3px solid #ccc;color:#555}</style>${html}`;
|
||||
}
|
||||
/** On a phone the message is as tall as its text and the page scrolls, so there is one scroll, not a box inside a page. (The box keeps its own scroll on a wide screen.) No scripts run in it: only same-origin so its height can be read. */
|
||||
function mailFit(fr) {
|
||||
if (!fr) return;
|
||||
const fit = () => { if (!fr.isConnected) return; if (innerWidth >= 1024) { fr.style.height = ''; return; } try { const d = fr.contentDocument; d.documentElement.style.overflowY = 'hidden'; fr.style.height = Math.max(160, Math.ceil(d.documentElement.scrollHeight) + 2) + 'px'; } catch {} };
|
||||
fr.addEventListener('load', () => { fit(); try { fr.contentDocument.addEventListener('load', fit, true); } catch {} setTimeout(fit, 300); setTimeout(fit, 1200); });
|
||||
if (!mailFit.on) { mailFit.on = true; addEventListener('resize', () => { const f = document.querySelector('.mbody'); if (f) f.dispatchEvent(new Event('fit')); }); }
|
||||
fr.addEventListener('fit', fit);
|
||||
}
|
||||
const mailHasRemote = html => /<img[^>]+src=["']?https?:|url\(\s*["']?https?:/i.test(html || '');
|
||||
|
||||
// ---- unread badge and Home card
|
||||
@@ -462,8 +470,9 @@ function mailDrawReader() {
|
||||
<button class="btn ghost" data-a="archive">Archive</button><button class="btn ghost" data-a="unread">Mark unread</button><button class="btn ghost" data-a="flag">${m.flagged ? 'Unflag' : 'Flag'}</button><button class="btn danger" data-a="delete">Delete</button></div>
|
||||
${m.attachments.length ? `<div class="matt">${m.attachments.map(a => `<a class="btn ghost" href="/api/mail/attachment?id=${encodeURIComponent(m.id)}&aid=${encodeURIComponent(a.id)}" download>${icon('clip')}${esc(a.name)} <small>${esc(fmtSize(a.size || 0))}</small></a>`).join('')}</div>` : ''}
|
||||
${remote ? '<div class="mimg">Pictures are hidden to protect your privacy. <button class="btn ghost" id="mshow" style="min-height:32px">Show pictures</button></div>' : ''}</div>
|
||||
<iframe class="mbody" title="Message" sandbox="allow-popups allow-popups-to-escape-sandbox" referrerpolicy="no-referrer" srcdoc="${esc(mailDoc(m.html, mail.images))}"></iframe>`;
|
||||
<iframe class="mbody" title="Message" sandbox="allow-same-origin allow-popups allow-popups-to-escape-sandbox" referrerpolicy="no-referrer" srcdoc="${esc(mailDoc(m.html, mail.images))}"></iframe>`;
|
||||
if ($('#mshow')) $('#mshow').onclick = () => { mail.images = true; mailDrawReader(); };
|
||||
mailFit(rd.querySelector('.mbody'));
|
||||
rd.querySelectorAll('[data-a]').forEach(b => b.onclick = () => mailAction(b.dataset.a));
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -539,14 +539,14 @@ body.lyropen { overflow: hidden; }
|
||||
.mact, .matt { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
|
||||
.mact .btn, .matt .btn { min-height: 38px; }
|
||||
.mimg { background: var(--panel2); border-radius: 10px; padding: 8px 12px; font-size: 14px; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
|
||||
.mbody { width: 100%; flex: 1; min-height: 55dvh; border: 1px solid var(--line); border-radius: 12px; background: #fff; }
|
||||
.mbody { width: 100%; flex: none; height: 60dvh; min-height: 0; border: 1px solid var(--line); border-radius: 12px; background: #fff; }
|
||||
@media (min-width: 1024px) {
|
||||
.mailapp { grid-template-columns: 340px minmax(0, 1fr); height: calc(100dvh - 40px); min-height: 0; }
|
||||
.mailapp[data-mode] .mlist, .mailapp[data-mode] .mread { display: block; }
|
||||
.mailapp[data-mode] .mread { display: flex; }
|
||||
.mlist, .mread { overflow-y: auto; min-height: 0; }
|
||||
.mback { display: none; }
|
||||
.mbody { min-height: 0; }
|
||||
.mbody { flex: 1; height: auto; }
|
||||
}
|
||||
@media (min-width: 1500px) {
|
||||
.mailapp { grid-template-columns: 190px 340px minmax(0, 1fr); }
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// App-shell cache only; Seafile/API traffic always goes to the network.
|
||||
const CACHE = 'hub-v48';
|
||||
const CACHE = 'hub-v49';
|
||||
const SHARE = 'hub-share'; // files shared into the app from other apps, held until the person picks a folder
|
||||
const SHELL = ['/icon.svg', '/manifest.webmanifest', '/icons/icon-192.png', '/icons/apple-touch-icon.png'];
|
||||
|
||||
|
||||
Reference in new issue
Block a user