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 ? '›' : '';