diff --git a/wwwroot/css/chat.css b/wwwroot/css/chat.css index 3550303..6d11469 100644 --- a/wwwroot/css/chat.css +++ b/wwwroot/css/chat.css @@ -98,6 +98,40 @@ margin-inline: auto; } +/* Workspace Refs */ + +.ref-preview { + padding: var(--s2) var(--s4); + background: var(--f1-bg); + border-top: var(--border-width) solid var(--f1-border); + flex-wrap: wrap; + gap: var(--s2); +} + +.ref-preview:not([hidden]) { + display: flex; +} + +.ref-preview-item { + display: flex; + align-items: center; + gap: var(--s2); + padding: var(--s1) var(--s2); + background: var(--f2-bg); + border: var(--border-width) solid var(--f2-border); +} + +.ref-icon { + flex-shrink: 0; +} + +.ref-label { + font-size: 0.9em; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + /* File Upload */ .file-btn { diff --git a/wwwroot/index.html b/wwwroot/index.html index 0c9ad85..d9302b9 100644 --- a/wwwroot/index.html +++ b/wwwroot/index.html @@ -123,6 +123,7 @@
+
diff --git a/wwwroot/js/chat.js b/wwwroot/js/chat.js index ba9bb17..92f3046 100644 --- a/wwwroot/js/chat.js +++ b/wwwroot/js/chat.js @@ -3,6 +3,7 @@ const messages = []; let isStreaming = false; let pendingFiles = []; // [{ name, type, base64 }] +let pendingRefs = []; // [{ path, from, to }] - Workspace-Dateireferenzen async function clearChat() { const archive = await apiArchive(getCurrentSessionId()); @@ -23,12 +24,23 @@ async function sendMessage() { const input = $('#input'); const btn = $('#send'); const text = input.value.trim(); - if (!text && pendingFiles.length === 0) return; + if (!text && pendingFiles.length === 0 && pendingRefs.length === 0) return; // Content bauen: string oder array mit file-blocks let content; let bubbleText = text; + // Refs in den Text einbauen + let msgText = text; + if (pendingRefs.length > 0) { + const refTags = pendingRefs.map(r => { + if (r.from && r.to) return `[Datei: ${r.path}:${r.from}-${r.to}]`; + return `[Datei: ${r.path}]`; + }); + msgText = refTags.join('\n') + (text ? '\n' + text : ''); + clearPendingRefs(); + } + if (pendingFiles.length > 0) { content = []; const labels = []; @@ -41,11 +53,12 @@ async function sendMessage() { }); labels.push((blockType === 'image' ? '📷 ' : '📄 ') + f.name); } - if (text) content.push({ type: 'text', text }); - bubbleText = labels.join('\n') + (text ? '\n' + text : ''); + if (msgText) content.push({ type: 'text', text: msgText }); + bubbleText = labels.join('\n') + (msgText ? '\n' + msgText : ''); clearPendingFiles(); } else { - content = text; + content = msgText; + bubbleText = msgText; } messages.push({ role: 'user', content }); @@ -197,6 +210,50 @@ function removePendingFile(index) { renderFilePreview(); } +// ── Workspace Refs ── + +function addPendingRef(ref) { + // ref = "path" oder "path:from-to" + const match = ref.match(/^(.+?):(\d+)-(\d+)$/); + if (match) { + pendingRefs.push({ path: match[1], from: parseInt(match[2]), to: parseInt(match[3]) }); + } else { + pendingRefs.push({ path: ref, from: null, to: null }); + } + renderRefPreview(); +} + +function removePendingRef(index) { + pendingRefs.splice(index, 1); + renderRefPreview(); +} + +function clearPendingRefs() { + pendingRefs.length = 0; + renderRefPreview(); +} + +function renderRefPreview() { + const container = $('#refPreview'); + if (!container) return; + + if (pendingRefs.length === 0) { + container.innerHTML = ''; + container.hidden = true; + return; + } + + container.innerHTML = pendingRefs.map((r, i) => { + const label = r.from && r.to ? `${r.path}:${r.from}-${r.to}` : r.path; + return `
+ 📂 + ${esc(label)} + +
`; + }).join(''); + container.hidden = false; +} + function clearPendingFiles() { pendingFiles.length = 0; const preview = $('#filePreview'); diff --git a/wwwroot/js/pages/chat-page.js b/wwwroot/js/pages/chat-page.js index 4442228..ab75eef 100644 --- a/wwwroot/js/pages/chat-page.js +++ b/wwwroot/js/pages/chat-page.js @@ -50,12 +50,8 @@ registerPage('chat', { openFileExplorer({ sessionId, onSelect(ref) { - const input = document.getElementById('input'); - if (!input) return; - const tag = `[Datei: ${ref}]`; - const pos = input.selectionStart || input.value.length; - input.value = input.value.substring(0, pos) + tag + input.value.substring(pos); - input.focus(); + addPendingRef(ref); + document.getElementById('input')?.focus(); } }); }); @@ -117,5 +113,6 @@ registerPage('chat', { loadedArchiveCount = 0; isStreaming = false; clearPendingFiles(); + clearPendingRefs(); } });