mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-16 09:45:24 -04:00
Email reader: regroup More menu + reshuffle toolbar rows
More menu reorganization: - Group 1: Open in new tab, Remind to reply - Group 2 (state): Mark as Unread/Read, Mark as Done/Not Done, Move to Archive, Save sender to contacts - Group 3 (destructive, unchanged): Move to Spam, Move to Trash, Delete Permanently - Renames: Done→'Mark as Done', Archive→'Move to Archive', Mark Read/Unread→'Mark as Read'/'Mark as Unread'. - Mark Unread moves out of group 1 down into the state-change group alongside Done; Save sender to contacts moves down into the same state group. Toolbar row reshuffle (applies to both the email-list card reader and the email document view): - Row 1 (primary): Reply, Reply all, Forward, Search, More — Forward no longer has to fight Search/More for space in the secondary row. - Row 2 (secondary): AI reply, Summary — gets its own dedicated row.
This commit is contained in:
+41
-41
@@ -2428,15 +2428,15 @@ async function _toggleCardPreview(card, em) {
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="reply" title="Reply"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 17 4 12 9 7"/><path d="M20 18v-2a4 4 0 0 0-4-4H4"/></svg><span class="reader-btn-label">Reply</span></button>
|
||||
${_hasMultipleRecipients(data) ? `<button class="memory-toolbar-btn reader-icon-btn" data-act="reply-all" title="Reply All"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="7 17 2 12 7 7"/><polyline points="12 17 7 12 12 7"/><path d="M22 18v-2a4 4 0 0 0-4-4H7"/></svg><span class="reader-btn-label">Reply all</span></button>` : ''}
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="forward" title="Forward"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 17 20 12 15 7"/><path d="M4 18v-2a4 4 0 0 1 4-4h12"/></svg><span class="reader-btn-label">Forward</span></button>
|
||||
</div>
|
||||
<div class="email-reader-actions-row email-reader-actions-row-secondary">
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="ai-reply" title="${data.cached_ai_reply ? 'AI Reply (cached draft ready)' : 'AI Reply (suggest a draft)'}">${_aiReplyIcon(data)}<span class="reader-btn-label">AI reply</span></button>
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="summarize" title="Summarize">${_summaryIcon(data)}<span class="reader-btn-label">Summary</span></button>
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="from-sender" title="Search text in this thread"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg><span class="reader-btn-label">Search</span></button>
|
||||
<div class="email-reader-more-wrap" style="position:relative">
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="more" title="More actions"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="5" r="2"/><circle cx="12" cy="12" r="2"/><circle cx="12" cy="19" r="2"/></svg><span class="reader-btn-label">More</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="email-reader-actions-row email-reader-actions-row-secondary">
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="ai-reply" title="${data.cached_ai_reply ? 'AI Reply (cached draft ready)' : 'AI Reply (suggest a draft)'}">${_aiReplyIcon(data)}<span class="reader-btn-label">AI reply</span></button>
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="summarize" title="Summarize">${_summaryIcon(data)}<span class="reader-btn-label">Summary</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
${attsHtml}
|
||||
@@ -4278,15 +4278,15 @@ async function _openEmailWindow(em, folder) {
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="reply" title="Reply"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 17 4 12 9 7"/><path d="M20 18v-2a4 4 0 0 0-4-4H4"/></svg><span class="reader-btn-label">Reply</span></button>
|
||||
${_hasMultipleRecipients(data) ? `<button class="memory-toolbar-btn reader-icon-btn" data-act="reply-all" title="Reply All"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="7 17 2 12 7 7"/><polyline points="12 17 7 12 12 7"/><path d="M22 18v-2a4 4 0 0 0-4-4H7"/></svg><span class="reader-btn-label">Reply all</span></button>` : ''}
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="forward" title="Forward"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 17 20 12 15 7"/><path d="M4 18v-2a4 4 0 0 1 4-4h12"/></svg><span class="reader-btn-label">Forward</span></button>
|
||||
</div>
|
||||
<div class="email-reader-actions-row email-reader-actions-row-secondary">
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="ai-reply" title="${data.cached_ai_reply ? 'AI Reply (cached draft ready)' : 'AI Reply (suggest a draft)'}">${_aiReplyIcon(data)}<span class="reader-btn-label">AI reply</span></button>
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="summarize" title="Summarize">${_summaryIcon(data)}<span class="reader-btn-label">Summary</span></button>
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="from-sender" title="Search text in this thread"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg><span class="reader-btn-label">Search</span></button>
|
||||
<div class="email-reader-more-wrap" style="position:relative">
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="more" title="More actions"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="5" r="2"/><circle cx="12" cy="12" r="2"/><circle cx="12" cy="19" r="2"/></svg><span class="reader-btn-label">More</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="email-reader-actions-row email-reader-actions-row-secondary">
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="ai-reply" title="${data.cached_ai_reply ? 'AI Reply (cached draft ready)' : 'AI Reply (suggest a draft)'}">${_aiReplyIcon(data)}<span class="reader-btn-label">AI reply</span></button>
|
||||
<button class="memory-toolbar-btn reader-icon-btn" data-act="summarize" title="Summarize">${_summaryIcon(data)}<span class="reader-btn-label">Summary</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
${attsHtml}
|
||||
@@ -4657,7 +4657,13 @@ function _showReaderMoreMenu(em, card, reader, anchor) {
|
||||
},
|
||||
},
|
||||
{
|
||||
label: em.is_read ? 'Mark Unread' : 'Mark Read',
|
||||
label: 'Remind to reply',
|
||||
icon: _bellIcon,
|
||||
submenu: 'remind',
|
||||
},
|
||||
{ separator: true },
|
||||
{
|
||||
label: em.is_read ? 'Mark as Unread' : 'Mark as Read',
|
||||
icon: _unreadIcon,
|
||||
action: async () => {
|
||||
const newRead = !em.is_read;
|
||||
@@ -4673,11 +4679,33 @@ function _showReaderMoreMenu(em, card, reader, anchor) {
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Remind to reply',
|
||||
icon: _bellIcon,
|
||||
submenu: 'remind',
|
||||
label: em.is_answered ? 'Mark as Not Done' : 'Mark as Done',
|
||||
icon: _checkIcon,
|
||||
action: async () => {
|
||||
const newState = !em.is_answered;
|
||||
em.is_answered = newState;
|
||||
if (newState) _syncEmailReadState(em.uid, true);
|
||||
try {
|
||||
if (newState) {
|
||||
await fetch(`${API_BASE}/api/email/mark-answered/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'POST' });
|
||||
await fetch(`${API_BASE}/api/email/mark-read/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'POST' });
|
||||
} else {
|
||||
await fetch(`${API_BASE}/api/email/clear-answered/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'POST' });
|
||||
}
|
||||
} catch (e) { console.error('Failed to toggle done:', e); }
|
||||
_renderGrid();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Move to Archive',
|
||||
icon: _archIcon,
|
||||
action: async () => {
|
||||
try {
|
||||
await fetch(`${API_BASE}/api/email/archive/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'POST' });
|
||||
} catch (e) { console.error(e); }
|
||||
await closeAndRemove();
|
||||
},
|
||||
},
|
||||
{ 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.
|
||||
@@ -4708,34 +4736,6 @@ function _showReaderMoreMenu(em, card, reader, anchor) {
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: em.is_answered ? 'Not Done' : 'Done',
|
||||
icon: _checkIcon,
|
||||
action: async () => {
|
||||
const newState = !em.is_answered;
|
||||
em.is_answered = newState;
|
||||
if (newState) _syncEmailReadState(em.uid, true);
|
||||
try {
|
||||
if (newState) {
|
||||
await fetch(`${API_BASE}/api/email/mark-answered/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'POST' });
|
||||
await fetch(`${API_BASE}/api/email/mark-read/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'POST' });
|
||||
} else {
|
||||
await fetch(`${API_BASE}/api/email/clear-answered/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'POST' });
|
||||
}
|
||||
} catch (e) { console.error('Failed to toggle done:', e); }
|
||||
_renderGrid();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Archive',
|
||||
icon: _archIcon,
|
||||
action: async () => {
|
||||
try {
|
||||
await fetch(`${API_BASE}/api/email/archive/${em.uid}?folder=${encodeURIComponent(state._libFolder)}${_acct()}`, { method: 'POST' });
|
||||
} catch (e) { console.error(e); }
|
||||
await closeAndRemove();
|
||||
},
|
||||
},
|
||||
{ separator: true },
|
||||
{
|
||||
label: 'Move to Spam',
|
||||
|
||||
Reference in New Issue
Block a user