feat: Lucide SVG icons throughout main UI
Replace all emoji/unicode icons with Lucide SVG icons: - Mode select dropdown: message-circle / pencil / lock / bot - Send button: arrow-up (chat/OTR), pencil (note), zap (agent) - Stop button: square icon - Header nav already had Lucide SVGs; render_icons() now called at init Add icon_html() + render_icons() helpers; update update_mode_ui() and open_mode_dropdown() to use innerHTML + lucide.createIcons(). CSS: .btn-icon alignment, inline-flex on .hdr-btn / .hdr-dd-item / #send / #stop. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,12 @@
|
||||
const settings_btn_el = document.getElementById('settings-btn');
|
||||
const settings_dd_el = document.getElementById('settings-dropdown');
|
||||
|
||||
// ── Lucide icon helpers ───────────────────────────────────────
|
||||
function icon_html(name, size = 16) {
|
||||
return `<svg data-lucide="${name}" width="${size}" height="${size}" class="btn-icon"></svg>`;
|
||||
}
|
||||
function render_icons() { if (window.lucide) lucide.createIcons(); }
|
||||
|
||||
// User/persona injected by the server at /{user}/{persona}
|
||||
const CORTEX_USER = (window.CORTEX_CONFIG || {}).user || 'scott';
|
||||
const CORTEX_PERSONA = (window.CORTEX_CONFIG || {}).persona || 'inara';
|
||||
@@ -69,12 +75,17 @@
|
||||
|
||||
// ── Input mode — dropdown select with MRU ordering ──────────
|
||||
const MODES = {
|
||||
chat: { icon: '💬', label: 'Chat' },
|
||||
note: { icon: '📝', label: 'Note' },
|
||||
otr: { icon: '🔒', label: 'OTR' },
|
||||
agent: { icon: '🥸', label: 'Agent' },
|
||||
chat: { icon: 'message-circle', label: 'Chat' },
|
||||
note: { icon: 'pencil', label: 'Note' },
|
||||
otr: { icon: 'lock', label: 'OTR' },
|
||||
agent: { icon: 'bot', label: 'Agent' },
|
||||
};
|
||||
const send_defs = {
|
||||
chat: { icon: 'arrow-up', label: 'Send' },
|
||||
note: { icon: 'pencil', label: 'Note' },
|
||||
otr: { icon: 'arrow-up', label: 'Send' },
|
||||
agent: { icon: 'zap', label: 'Run' },
|
||||
};
|
||||
const send_labels = { chat: '↑ Send', note: '📝 Note', otr: '↑ Send', agent: '⚡ Run' };
|
||||
|
||||
let current_mode = localStorage.getItem('current_mode') || 'chat';
|
||||
let note_public = false;
|
||||
@@ -105,12 +116,13 @@
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'mode-option' + (mode === current_mode ? ' current' : '');
|
||||
btn.innerHTML =
|
||||
`<span class="opt-icon">${m.icon}</span>${m.label}`
|
||||
`<span class="opt-icon">${icon_html(m.icon, 15)}</span>${m.label}`
|
||||
+ (mode === current_mode ? '<span class="opt-check">✓</span>' : '');
|
||||
btn.addEventListener('click', () => set_mode(mode));
|
||||
mode_dropdown_el.appendChild(btn);
|
||||
});
|
||||
mode_dropdown_el.classList.add('open');
|
||||
render_icons();
|
||||
}
|
||||
|
||||
function close_mode_dropdown() {
|
||||
@@ -130,10 +142,11 @@
|
||||
});
|
||||
|
||||
function update_mode_ui() {
|
||||
const m = MODES[current_mode];
|
||||
const m = MODES[current_mode];
|
||||
const sd = send_defs[current_mode] || send_defs.chat;
|
||||
|
||||
// Update trigger button
|
||||
mode_icon_el.textContent = m.icon;
|
||||
mode_icon_el.innerHTML = icon_html(m.icon, 15);
|
||||
mode_label_el.textContent = m.label;
|
||||
mode_select_btn_el.className = current_mode === 'chat'
|
||||
? '' : `mode-${current_mode}`;
|
||||
@@ -150,9 +163,10 @@
|
||||
inputEl.classList.toggle('mode-otr', current_mode === 'otr');
|
||||
inputEl.classList.toggle('mode-agent', current_mode === 'agent');
|
||||
|
||||
// Send button label
|
||||
sendBtn.textContent = send_labels[current_mode] || 'Send';
|
||||
// Send button label + icon
|
||||
sendBtn.innerHTML = icon_html(sd.icon) + ' ' + sd.label;
|
||||
|
||||
render_icons();
|
||||
updateInputPlaceholder();
|
||||
}
|
||||
|
||||
@@ -716,7 +730,7 @@
|
||||
inputEl.value = '';
|
||||
syncHeight();
|
||||
sendBtn.style.display = 'none';
|
||||
stopBtn.style.display = 'block';
|
||||
stopBtn.style.display = 'flex';
|
||||
headerEmoji.classList.add('processing');
|
||||
|
||||
activeController = new AbortController();
|
||||
@@ -808,7 +822,7 @@
|
||||
inputEl.value = '';
|
||||
syncHeight();
|
||||
sendBtn.style.display = 'none';
|
||||
stopBtn.style.display = 'block';
|
||||
stopBtn.style.display = 'flex';
|
||||
headerEmoji.classList.add('processing');
|
||||
|
||||
activeController = new AbortController();
|
||||
@@ -1286,3 +1300,9 @@
|
||||
checkAuthStatus();
|
||||
// Re-check every 30 minutes
|
||||
setInterval(checkAuthStatus, 30 * 60 * 1000);
|
||||
|
||||
// ── Initial render ────────────────────────────────────────────
|
||||
// Process all static Lucide SVGs in the header + stop button,
|
||||
// and seed the mode UI (which also calls render_icons internally).
|
||||
update_mode_ui();
|
||||
render_icons();
|
||||
|
||||
Reference in New Issue
Block a user