diff --git a/static/js/emailLibrary.js b/static/js/emailLibrary.js index b77e932a2..a52e541d4 100644 --- a/static/js/emailLibrary.js +++ b/static/js/emailLibrary.js @@ -4563,6 +4563,10 @@ function _showReaderMoreMenu(em, card, reader, anchor) { const _bubblesIcon = ''; const _contactIcon = ''; + // Three groups separated by dividers: + // 1. Open / Mark Unread / Remind — the per-email view actions + // 2. Save sender / Not Done / Archive — non-destructive state changes + // 3. Move to Spam / Move to Trash / Delete — destructive const actions = [ { label: 'Open in new tab', @@ -4572,6 +4576,28 @@ function _showReaderMoreMenu(em, card, reader, anchor) { await _openEmailAsTab(em, folder); }, }, + { + label: em.is_read ? 'Mark Unread' : 'Mark Read', + icon: _unreadIcon, + action: async () => { + const newRead = !em.is_read; + _syncEmailReadState(em.uid, newRead); + try { + if (newRead) { + await fetch(`${API_BASE}/api/email/mark-read/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'POST' }); + } else { + await fetch(`${API_BASE}/api/email/mark-unread/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'POST' }); + } + } catch (e) { console.error(e); } + _renderGrid(); + }, + }, + { + label: 'Remind to reply', + icon: _bellIcon, + submenu: 'remind', + }, + { separator: true }, { // Save the sender to CardDAV contacts. Pulls name + address off the // list-item (em); falls back to splitting the local-part for a name. @@ -4602,25 +4628,6 @@ function _showReaderMoreMenu(em, card, reader, anchor) { } }, }, - // Threaded ⇄ Plain-text view toggle removed — threaded view disabled - // for now (too buggy). Emails always render plain text. Restore this - // menu item + _bubblesDisabled() localStorage logic to bring it back. - { - label: em.is_read ? 'Mark Unread' : 'Mark Read', - icon: _unreadIcon, - action: async () => { - const newRead = !em.is_read; - _syncEmailReadState(em.uid, newRead); - try { - if (newRead) { - await fetch(`${API_BASE}/api/email/mark-read/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'POST' }); - } else { - await fetch(`${API_BASE}/api/email/mark-unread/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'POST' }); - } - } catch (e) { console.error(e); } - _renderGrid(); - }, - }, { label: em.is_answered ? 'Not Done' : 'Done', icon: _checkIcon, @@ -4649,11 +4656,7 @@ function _showReaderMoreMenu(em, card, reader, anchor) { await closeAndRemove(); }, }, - { - label: 'Remind to reply', - icon: _bellIcon, - submenu: 'remind', - }, + { separator: true }, { label: 'Move to Spam', icon: _spamIcon, @@ -4694,6 +4697,12 @@ function _showReaderMoreMenu(em, card, reader, anchor) { ]; for (const a of actions) { + if (a.separator) { + const sep = document.createElement('div'); + sep.className = 'dropdown-divider'; + dropdown.appendChild(sep); + continue; + } const item = document.createElement('div'); item.className = 'dropdown-item-compact' + (a.danger ? ' dropdown-item-danger' : ''); const arrow = a.submenu ? '' : '';