mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-17 10:15:27 -04:00
AI reply menu: click Fast/Full → context input → OK
Restructured flow:
1. Click Fast or Full → reveals an optional context textarea
("Add context (optional)") below
2. Type optional steering note or leave blank
3. Click OK → triggers the draft with the chosen mode + note
Dropped the standalone … note-toggle button — the textarea is now
gated on picking a mode, which makes it easier to discover.
This commit is contained in:
+27
-27
@@ -5923,8 +5923,8 @@ function _showAiReplyChoice(btn, em, data) {
|
|||||||
// Full = layered concentric circles to suggest "more, deeper" — not a fully
|
// 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".
|
// filled circle so it reads as a complement to the lightning, not as a "stop".
|
||||||
menu.innerHTML = `
|
menu.innerHTML = `
|
||||||
<div class="email-ai-reply-row" style="display:flex;flex-direction:column;gap:6px;min-width:180px;">
|
<div class="email-ai-reply-row" data-step="choose" style="display:flex;flex-direction:column;gap:6px;min-width:180px;">
|
||||||
<div style="display:flex;align-items:center;gap:4px;">
|
<div data-mode-row style="display:flex;align-items:center;gap:4px;">
|
||||||
<button class="memory-toolbar-btn" data-mode="ai-reply-fast" title="Shorter, faster draft" style="display:inline-flex;align-items:center;gap:5px;">
|
<button class="memory-toolbar-btn" data-mode="ai-reply-fast" title="Shorter, faster draft" style="display:inline-flex;align-items:center;gap:5px;">
|
||||||
<svg width="11" height="11" viewBox="0 0 24 24" fill="var(--accent, var(--red))" aria-hidden="true"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>
|
<svg width="11" height="11" viewBox="0 0 24 24" fill="var(--accent, var(--red))" aria-hidden="true"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>
|
||||||
Fast
|
Fast
|
||||||
@@ -5933,39 +5933,39 @@ function _showAiReplyChoice(btn, em, data) {
|
|||||||
<svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" style="color:var(--accent, var(--red));"><circle cx="12" cy="12" r="6"/></svg>
|
<svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" style="color:var(--accent, var(--red));"><circle cx="12" cy="12" r="6"/></svg>
|
||||||
Full
|
Full
|
||||||
</button>
|
</button>
|
||||||
<button class="memory-toolbar-btn" data-act="note-toggle" title="Add a note about how to reply" style="display:inline-flex;align-items:center;justify-content:center;padding:4px 6px;line-height:1;margin-left:auto;">
|
|
||||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><circle cx="5" cy="12" r="2"/><circle cx="12" cy="12" r="2"/><circle cx="19" cy="12" r="2"/></svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div data-note-panel hidden>
|
<div data-note-panel hidden style="display:flex;flex-direction:column;gap:6px;">
|
||||||
<textarea data-note-input rows="2" placeholder="e.g. reply nicely but say no" style="width:100%;box-sizing:border-box;resize:vertical;min-height:38px;font-family:inherit;font-size:11px;padding:5px 6px;border-radius:5px;border:1px solid var(--border,#333);background:var(--bg-elev,#1a1a1a);color:var(--fg);"></textarea>
|
<textarea data-note-input rows="2" placeholder="Add context (optional)" style="width:100%;box-sizing:border-box;resize:vertical;min-height:42px;font-family:inherit;font-size:11px;padding:5px 6px;border-radius:5px;border:1px solid var(--border,#333);background:var(--bg-elev,#1a1a1a);color:var(--fg);"></textarea>
|
||||||
|
<button data-act="note-ok" class="memory-toolbar-btn" style="display:inline-flex;align-items:center;justify-content:center;gap:5px;">OK</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
const modeRow = menu.querySelector('[data-mode-row]');
|
||||||
const notePanel = menu.querySelector('[data-note-panel]');
|
const notePanel = menu.querySelector('[data-note-panel]');
|
||||||
const noteInput = menu.querySelector('[data-note-input]');
|
const noteInput = menu.querySelector('[data-note-input]');
|
||||||
menu.querySelector('[data-act="note-toggle"]').addEventListener('click', (ev) => {
|
let pendingMode = null;
|
||||||
ev.preventDefault();
|
|
||||||
ev.stopPropagation();
|
|
||||||
const opening = notePanel.hasAttribute('hidden');
|
|
||||||
if (opening) {
|
|
||||||
notePanel.removeAttribute('hidden');
|
|
||||||
setTimeout(() => noteInput.focus(), 0);
|
|
||||||
} else {
|
|
||||||
notePanel.setAttribute('hidden', '');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
menu.addEventListener('click', async (ev) => {
|
menu.addEventListener('click', async (ev) => {
|
||||||
const choice = ev.target.closest('[data-mode]');
|
const choice = ev.target.closest('[data-mode]');
|
||||||
if (!choice) return;
|
if (choice) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const mode = choice.getAttribute('data-mode') || 'ai-reply';
|
// First click reveals the optional-context textarea; the actual
|
||||||
// Always pick up whatever's in the textarea — empty = no note,
|
// draft runs on OK. Empty context just runs the chosen mode.
|
||||||
// typed = passed through as steering context.
|
pendingMode = choice.getAttribute('data-mode') || 'ai-reply';
|
||||||
const noteHint = (noteInput.value || '').trim();
|
modeRow.setAttribute('hidden', '');
|
||||||
_closeAiReplyChoice();
|
notePanel.removeAttribute('hidden');
|
||||||
await _runAiReplyFromButton(btn, em, data, mode, noteHint);
|
setTimeout(() => noteInput.focus(), 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const ok = ev.target.closest('[data-act="note-ok"]');
|
||||||
|
if (ok) {
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
const noteHint = (noteInput.value || '').trim();
|
||||||
|
const mode = pendingMode || 'ai-reply';
|
||||||
|
_closeAiReplyChoice();
|
||||||
|
await _runAiReplyFromButton(btn, em, data, mode, noteHint);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// Esc closes the popover; ignore plain clicks inside the menu so the
|
// Esc closes the popover; ignore plain clicks inside the menu so the
|
||||||
// textarea stays focused.
|
// textarea stays focused.
|
||||||
|
|||||||
Reference in New Issue
Block a user