@@ -4794,7 +4794,7 @@ async function _openEmailAsTab(em, folder) {
_snapEmailModalToLeftSidebar(ev.currentTarget.closest('.modal'));
if (state._onEmailClick) await state._onEmailClick({ email: em, emailData: data, mode: 'reply-all' });
});
- reader.querySelector('.ai-reply-split')?.addEventListener('click', (ev) => _handleAiReplyButton(ev, em, data));
+ reader.querySelector('[data-act="ai-reply"]')?.addEventListener('click', (ev) => _handleAiReplyButton(ev, em, data));
reader.querySelector('[data-act="forward"]')?.addEventListener('click', async (ev) => {
ev.stopPropagation();
if (state._onEmailClick) await state._onEmailClick({ email: em, emailData: data, mode: 'forward' });
@@ -4915,7 +4915,7 @@ async function _openEmailWindow(em, folder) {
@@ -4950,7 +4950,7 @@ async function _openEmailWindow(em, folder) {
_snapEmailModalToLeftSidebar(ev.currentTarget.closest('.modal'));
if (state._onEmailClick) await state._onEmailClick({ email: em, emailData: data, mode: 'reply-all' });
});
- bodyEl.querySelector('.ai-reply-split')?.addEventListener('click', (ev) => _handleAiReplyButton(ev, em, data));
+ bodyEl.querySelector('[data-act="ai-reply"]')?.addEventListener('click', (ev) => _handleAiReplyButton(ev, em, data));
bodyEl.querySelector('[data-act="forward"]')?.addEventListener('click', async (ev) => {
ev.stopPropagation();
if (state._onEmailClick) await state._onEmailClick({ email: em, emailData: data, mode: 'forward' });
@@ -5865,21 +5865,6 @@ function _summaryIcon(data) {
return `
`;
}
-// Split-button HTML for AI reply: main button + caret. Main button opens
-// the cached draft if one exists, otherwise generates fast. Caret opens
-// a popover with a custom-instructions textarea.
-function _aiReplySplitButtonHtml(data) {
- const mainTitle = data?.cached_ai_reply
- ? 'AI Reply (cached draft ready)'
- : 'AI Reply (generate a draft)';
- return `
-
-
- `;
-}
-
async function _runAiReplyFromButton(btn, em, data, mode, noteHint = '') {
_snapEmailModalToLeftSidebar(btn.closest('.modal'));
btn.disabled = true;
@@ -5905,79 +5890,102 @@ function _closeAiReplyChoice() {
document.removeEventListener('click', _closeAiReplyChoice, true);
}
-// Caret popover — just a custom-instructions textarea + generate button.
-// (Old version had Fast / Full / Draft-with-note; user wanted that
-// simplified.)
function _showAiReplyChoice(btn, em, data) {
_closeAiReplyChoice();
- const anchor = btn.closest('.ai-reply-split') || btn;
- const rect = anchor.getBoundingClientRect();
+ const rect = btn.getBoundingClientRect();
const menu = document.createElement('div');
menu.className = 'email-ai-reply-choice';
menu.style.cssText = [
'position:fixed',
- `left:${Math.max(8, Math.min(rect.left, window.innerWidth - 320))}px`,
- `top:${Math.min(window.innerHeight - 140, rect.bottom + 6)}px`,
+ `left:${Math.max(8, Math.min(rect.left, window.innerWidth - 190))}px`,
+ `top:${Math.min(window.innerHeight - 96, rect.bottom + 6)}px`,
'z-index:10060',
'display:flex',
- 'flex-direction:column',
'gap:6px',
- 'padding:8px',
+ 'padding:6px',
'background:var(--bg,#111)',
'border:1px solid var(--border,#333)',
'border-radius:7px',
'box-shadow:0 8px 24px rgba(0,0,0,.28)',
- 'min-width:260px',
].join(';');
+ // Fast = lightning bolt (already used as a 'fast' glyph elsewhere in the app).
+ // Full = layered concentric circles to suggest "more, deeper" — not a fully
+ // filled circle so it reads as a complement to the lightning, not as a "stop".
menu.innerHTML = `
-
Tell the AI how to reply
-
-
-