// All comments are in English. let conversationId = null; let conversations = []; async function login() { window.location = "/login"; // if (AUTH_MODE === "oauth") { ... } } function toggleTheme() { document.body.classList.toggle("dark"); } async function sendAsync() { const r = await fetch("/api/queue/generate", { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify({ conversation_id: conversationId, model: "llama3.2", prompt: document.getElementById("prompt").value }) }); const { task_id } = await r.json(); pollTask(task_id); } async function pollTask(taskId) { const interval = setInterval(async () => { const r = await fetch(`/api/queue/status/${taskId}`); const data = await r.json(); if (data.state === "SUCCESS") { clearInterval(interval); await loadHistory(); } }, 1500); } async function importExcel() { const file = document.getElementById("excelFile").files[0]; const form = new FormData(); form.append("file", file); const r = await fetch(`/api/import_excel/${conversationId}`, { method: "POST", body: form }); const data = await r.json(); console.log("Imported sheets:", data.sheets); await loadHistory(); } async function loadConversations() { const r = await fetch("/api/conversations"); conversations = await r.json(); renderTabs(); } function renderTabs() { const tabs = document.getElementById("tabs"); tabs.innerHTML = ""; conversations.forEach(c => { const btn = document.createElement("button"); btn.textContent = c.title; btn.onclick = () => selectConversation(c.id); tabs.appendChild(btn); }); } async function sendAudio() { const file = document.getElementById("audioFile").files[0]; const form = new FormData(); form.append("file", file); await fetch(`/api/audio/transcribe/${conversationId}`, { method: "POST", body: form }); await loadHistory(); } async function sendImage() { const file = document.getElementById("visionFile").files[0]; const form = new FormData(); form.append("file", file); await fetch(`/api/vision/${conversationId}`, { method: "POST", body: form }); await loadHistory(); } async function newConversation() { const title = prompt("Conversation title:"); const r = await fetch("/api/new_conversation", { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify({title}) }); const data = await r.json(); conversationId = data.conversation_id; await loadConversations(); await loadHistory(); } async function selectConversation(id) { conversationId = id; await loadHistory(); } async function loadHistory() { const r = await fetch(`/api/history/${conversationId}`); const msgs = await r.json(); const chat = document.getElementById("chat"); chat.innerHTML = ""; msgs.forEach(m => { const div = document.createElement("div"); div.className = "msg " + m.role; div.innerHTML = `
${m.role === "user" ? "🧑" : "🤖"}
${m.content}
`; chat.appendChild(div); }); // Load attachments const a = await fetch(`/api/attachments/${conversationId}`); const attachments = await a.json(); attachments.forEach(att => { const div = document.createElement("div"); div.className = "msg user"; div.innerHTML = `
🧑
Attachment: ${att.filename}
Download
`; chat.appendChild(div); }); } async function searchMessages() { const q = prompt("Search:"); const r = await fetch(`/api/search?q=${encodeURIComponent(q)}`); const results = await r.json(); console.log(results); } async function addTags() { const tags = prompt("Tags (comma separated):"); await fetch(`/api/tags/${conversationId}`, { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify({tags: tags.split(",")}) }); } async function shareConversation() { const email = prompt("Share with email:"); await fetch(`/api/share/${conversationId}`, { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify({email}) }); } function exportMD() { window.open(`/api/export/md/${conversationId}`, "_blank"); } function exportPDF() { window.open(`/api/export/pdf/${conversationId}`, "_blank"); } async function importFile() { const file = document.getElementById("importFile").files[0]; const form = new FormData(); form.append("file", file); await fetch(`/api/import/${conversationId}`, { method: "POST", body: form }); await loadHistory(); } async function sendMessage() { const promptText = document.getElementById("prompt").value; const file = document.getElementById("attachment").files[0]; if (!conversationId) { await newConversation(); } if (file) { const form = new FormData(); form.append("file", file); await fetch(`/api/attachment/${conversationId}`, { method: "POST", body: form }); } const chat = document.getElementById("chat"); const userDiv = document.createElement("div"); userDiv.className = "msg user"; userDiv.innerHTML = `
🧑
${marked.parse(promptText)}
`; chat.appendChild(userDiv); const assistantDiv = document.createElement("div"); assistantDiv.className = "msg assistant streaming"; assistantDiv.innerHTML = `
🤖
▌
`; chat.appendChild(assistantDiv); const url = `/api/stream?conversation_id=${conversationId}&model=llama3.2&prompt=${encodeURIComponent(promptText)}`; const evtSource = new EventSource(url); let buffer = ""; const streamSpan = document.getElementById("stream-text"); evtSource.onmessage = (event) => { const data = JSON.parse(event.data); buffer += data.token; streamSpan.innerHTML = marked.parse(buffer); }; evtSource.onerror = () => { evtSource.close(); assistantDiv.classList.remove("streaming"); }; } window.onload = loadConversations; const ws = new WebSocket("ws://" + window.location.host + "/ws/notifications"); ws.onmessage = (event) => { const data = JSON.parse(event.data); // Show toast, badge, etc. };