refactor: ui.js, chat.js, history.js in 13 modulare Dateien aufteilen
Die monolithische ui.js (1534 Zeilen) zusammen mit chat.js (612) und history.js (626) in fokussierte Module aufgeteilt: Neue Dateien aus ui.js: - ui-helpers.js (126) - DOM-Utilities, $, esc, truncate, scrollDown, Toast - markdown.js (143) - renderMarkdown, wrapKreaGalleries, LaTeX/Code-Schutz - cards.js (90) - buildSessionCard, buildAgentCard - msg-actions.js (208) - Delete, Mark, Share, Reply-Button, Timestamp - tool-ui.js (332) - Tool-Boxes, Diffs, Todo-Liste, Visibility - modals.js (190) - System-Prompt, Command-Output, Krea-Image Modals - stream-ui.js (124) - Stream-Bubble, Review-Streaming - bubbles.js (312) - User/Assistant/Error/Warning/Choice/Review Bubbles Neue Dateien aus chat.js: - reply.js (54) - Reply/Quote-Handling mit pendingReply State - files.js (110) - File-Upload, Workspace-Refs mit pendingFiles/Refs State Neue Datei aus history.js: - archive.js (173) - Archiv-Loading mit loadedArchiveCount State Verbleibend: - chat.js (448) - Stream-Events, sendMessage, handleChoiceClick, Plan-Mode - history.js (464) - History laden, Polling, Message-Rendering Kein Code verändert, nur verschoben. Alle 94 Funktionen verifiziert. Globale Variablen in die Module verschoben, wo sie primär genutzt werden.
This commit is contained in:
1 parent
a82d8cfb05
commit
0dcc05ebf9
15 files changed
+1885
-1873
No files matched your search
@@ -0,0 +1,126 @@
|
||||
// ── DOM Helpers ──
|
||||
|
||||
const $ = (sel) => document.querySelector(sel);
|
||||
const chatEl = () => $('#chat');
|
||||
const metaEl = () => $('#meta');
|
||||
|
||||
function esc(s) {
|
||||
const d = document.createElement('div');
|
||||
d.textContent = s;
|
||||
return d.innerHTML;
|
||||
}
|
||||
|
||||
function truncate(s, max) {
|
||||
return s && s.length > max ? s.substring(0, max) + '...' : (s || '');
|
||||
}
|
||||
|
||||
function scrollDown() {
|
||||
const chat = chatEl();
|
||||
if (!chat) return;
|
||||
chat.scrollTop = chat.scrollHeight;
|
||||
// Nach Font-Swap kann sich die Höhe ändern → nochmal scrollen
|
||||
document.fonts.ready.then(() => {
|
||||
chat.scrollTop = chat.scrollHeight;
|
||||
});
|
||||
}
|
||||
|
||||
function prettyModelName(model) {
|
||||
if (!model) return '?';
|
||||
model = model.split('claude-').join('');
|
||||
if (model == 'sonnet') return 'Sonnet';
|
||||
if (model == 'sonnet-4-5') return 'Sonnet 4.5';
|
||||
if (model == 'sonnet-4-6') return 'Sonnet 4.6';
|
||||
if (model == 'opus') return 'Opus';
|
||||
if (model == 'opus-4-5') return 'Opus 4.5';
|
||||
if (model == 'opus-4-6') return 'Opus 4.6';
|
||||
if (model == 'haiku') return 'Haiku';
|
||||
if (model == 'haiku-4-5') return 'Haiku 4.5';
|
||||
return 'Unbekannt (' + model + ')';
|
||||
}
|
||||
|
||||
// ── Toast Notifications ──
|
||||
|
||||
function showToast(message, type) {
|
||||
type = type || 'info';
|
||||
var container = document.getElementById('toastContainer');
|
||||
if (!container) {
|
||||
container = document.createElement('div');
|
||||
container.id = 'toastContainer';
|
||||
document.body.appendChild(container);
|
||||
}
|
||||
var toast = document.createElement('div');
|
||||
toast.className = 'toast toast-' + type;
|
||||
var icon = type === 'success' ? 'fa-check-circle' : type === 'error' ? 'fa-times-circle' : 'fa-info-circle';
|
||||
toast.innerHTML = '<i class="fa ' + icon + '"></i> ' + (message || '');
|
||||
container.appendChild(toast);
|
||||
// Einblenden
|
||||
requestAnimationFrame(function() { toast.classList.add('toast-visible'); });
|
||||
// Automatisch ausblenden
|
||||
var timeout = setTimeout(function() { removeToast(toast); }, 4000);
|
||||
toast.addEventListener('click', function() {
|
||||
clearTimeout(timeout);
|
||||
removeToast(toast);
|
||||
});
|
||||
}
|
||||
|
||||
function removeToast(toast) {
|
||||
toast.classList.remove('toast-visible');
|
||||
toast.addEventListener('transitionend', function() { toast.remove(); });
|
||||
}
|
||||
|
||||
// ── Meta Bar ──
|
||||
|
||||
function setMeta(text) {
|
||||
metaEl().textContent = text;
|
||||
}
|
||||
|
||||
function setMetaHtml(html) {
|
||||
metaEl().innerHTML = html;
|
||||
}
|
||||
|
||||
// ── Older Messages Button ──
|
||||
|
||||
function showOlderMessagesButton(remainingCount) {
|
||||
removeOlderMessagesButton();
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'archive-load-btn older-messages-btn';
|
||||
btn.innerHTML = '<i class="fa fa-arrow-up"></i> ' + remainingCount + ' ältere Nachrichten laden';
|
||||
btn.addEventListener('click', () => loadOlderMessages());
|
||||
chatEl().prepend(btn);
|
||||
}
|
||||
|
||||
function removeOlderMessagesButton() {
|
||||
const btn = chatEl().querySelector('.older-messages-btn');
|
||||
if (btn) btn.remove();
|
||||
}
|
||||
|
||||
// ── Archive Button ──
|
||||
|
||||
function showArchiveLoadButton() {
|
||||
const existing = chatEl().querySelector('.archive-load-btn:not(.older-messages-btn)');
|
||||
if (existing) existing.remove();
|
||||
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'archive-load-btn';
|
||||
btn.innerHTML = '<i class="fa fa-archive"></i> Archivierte Nachrichten laden';
|
||||
btn.addEventListener('click', loadLatestArchive);
|
||||
|
||||
// Immer ganz oben im Chat (aber nach dem older-messages-btn falls vorhanden)
|
||||
const olderBtn = chatEl().querySelector('.older-messages-btn');
|
||||
if (olderBtn) {
|
||||
olderBtn.after(btn);
|
||||
} else {
|
||||
chatEl().prepend(btn);
|
||||
}
|
||||
}
|
||||
|
||||
function removeArchiveLoadButton() {
|
||||
const btns = chatEl().querySelectorAll('.archive-load-btn:not(.older-messages-btn)');
|
||||
btns.forEach(b => b.remove());
|
||||
}
|
||||
|
||||
// ── Streamed Elements ──
|
||||
|
||||
function removeStreamedElements() {
|
||||
chatEl().querySelectorAll('.streamed').forEach(el => el.remove());
|
||||
}
|
||||
Reference in new issue
Block a user