mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-16 01:35:36 -04:00
Email: bookmark icon everywhere for favorites; subject matches in suggestions
Star → bookmark banner SVG also in the card title row (em.is_flagged glyph) and the inbox toolbar's _starIcon / _starFilledIcon, so every favorites affordance matches the chats sidebar bookmark. Search dropdown gains a third suggestion kind: - kind: 'email' rows surface emails from the snapshot whose subject or sender name match the typed term (top 4, scored by startsWith vs substring). Render row carries a small envelope glyph + bolded subject + 'from name' on the right. - Picking one closes the dropdown and expands that exact card via _toggleCardPreview, scrolling it into view.
This commit is contained in:
@@ -22,8 +22,8 @@ const _replyIcon = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none"
|
||||
const _archiveIcon = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="5" rx="1"/><path d="M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8"/><path d="M10 12h4"/></svg>';
|
||||
const _deleteIcon = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/></svg>';
|
||||
const _unreadIcon = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="3" fill="currentColor"/></svg>';
|
||||
const _starIcon = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>';
|
||||
const _starFilledIcon = '<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>';
|
||||
const _starIcon = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></svg>';
|
||||
const _starFilledIcon = '<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></svg>';
|
||||
const _bellIcon = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>';
|
||||
const _icon = (svg) => `<span class="dropdown-icon">${svg}</span>`;
|
||||
const _replySeparator = '---------- Previous message ----------';
|
||||
|
||||
@@ -1992,6 +1992,13 @@ function _renderSearchSuggestions(items) {
|
||||
<span style="font-weight:600;">${esc(s.label)}</span>
|
||||
</div>`;
|
||||
}
|
||||
if (s.kind === 'email') {
|
||||
return `<div class="email-lib-suggest-item" data-idx="${i}" style="display:flex;align-items:center;gap:6px;padding:6px 10px;cursor:pointer;font-size:12px;${highlight}">
|
||||
<span style="display:inline-flex;align-items:center;width:13px;height:13px;color:var(--fg-muted, var(--fg));opacity:0.55;flex-shrink:0;"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="4" width="20" height="16" rx="2"/><polyline points="2 6 12 13 22 6"/></svg></span>
|
||||
<span style="font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${esc(s.subject)}</span>
|
||||
${s.from_name ? `<span style="opacity:0.55;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">— ${esc(s.from_name)}</span>` : ''}
|
||||
</div>`;
|
||||
}
|
||||
return `<div class="email-lib-suggest-item" data-idx="${i}" style="display:flex;align-items:center;gap:6px;padding:6px 10px;cursor:pointer;font-size:12px;${highlight}">
|
||||
<span style="font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${esc(s.name || s.email)}</span>
|
||||
${s.name ? `<span style="opacity:0.55;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${esc(s.email)}</span>` : ''}
|
||||
@@ -2019,6 +2026,21 @@ function _acceptSuggestion(s) {
|
||||
const input = document.getElementById('email-lib-search');
|
||||
if (s.kind === 'filter') {
|
||||
_addSearchPill({ type: 'filter', value: s.value, label: s.label });
|
||||
} else if (s.kind === 'email') {
|
||||
// Clear the draft + dropdown and open the matching card directly.
|
||||
if (input) input.value = '';
|
||||
state._libSearchDraft = '';
|
||||
_hideSearchSuggestions();
|
||||
_applyPillFilter();
|
||||
const grid = document.getElementById('email-lib-grid');
|
||||
const card = grid?.querySelector(`.doclib-card[data-uid="${CSS.escape(String(s.uid))}"]`);
|
||||
const em = (state._libEmails || []).find(x => String(x.uid) === String(s.uid))
|
||||
|| (_libPreSearchEmails || []).find(x => String(x.uid) === String(s.uid));
|
||||
if (card && em) {
|
||||
card.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
_toggleCardPreview(card, em);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
_addSearchPill({ type: 'contact', name: s.name, email: s.email });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user