109 lines
3.9 KiB
JavaScript
109 lines
3.9 KiB
JavaScript
const loginView = document.querySelector("#login-view");
|
|
const chatView = document.querySelector("#chat-view");
|
|
const loginForm = document.querySelector("#login-form");
|
|
const loginError = document.querySelector("#login-error");
|
|
const messages = document.querySelector("#messages");
|
|
const chatForm = document.querySelector("#chat-form");
|
|
const messageInput = document.querySelector("#message");
|
|
const sendButton = document.querySelector("#send");
|
|
const logoutButton = document.querySelector("#logout");
|
|
const activeFocus = document.querySelector("#active-focus");
|
|
|
|
let token = sessionStorage.getItem("domovoy.chat.token") || "";
|
|
let conversationID = sessionStorage.getItem("domovoy.chat.conversation") || "";
|
|
|
|
function showChat() {
|
|
loginView.hidden = true;
|
|
chatView.hidden = false;
|
|
if (!messages.children.length) {
|
|
appendMessage("assistant", "Я рядом. Напишите обычное сообщение, без внутренних идентификаторов.");
|
|
}
|
|
messageInput.focus();
|
|
}
|
|
|
|
function showLogin() {
|
|
chatView.hidden = true;
|
|
loginView.hidden = false;
|
|
}
|
|
|
|
function appendMessage(kind, text, meta = "") {
|
|
const node = document.createElement("div");
|
|
node.className = `message ${kind}`;
|
|
node.textContent = text;
|
|
if (meta) {
|
|
const small = document.createElement("small");
|
|
small.textContent = meta;
|
|
node.appendChild(small);
|
|
}
|
|
messages.appendChild(node);
|
|
messages.scrollTop = messages.scrollHeight;
|
|
}
|
|
|
|
function updateActiveFocus(value, provenance = "") {
|
|
if (!activeFocus) return;
|
|
activeFocus.textContent = value ? `фокус: ${value}${provenance ? ` · ${provenance}` : ""}` : "фокус: не выбран";
|
|
}
|
|
|
|
async function api(path, options = {}) {
|
|
const headers = {"Content-Type": "application/json", ...(options.headers || {})};
|
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
const response = await fetch(path, {...options, headers});
|
|
if (!response.ok) throw new Error(await response.text());
|
|
return response.json();
|
|
}
|
|
|
|
loginForm.addEventListener("submit", async (event) => {
|
|
event.preventDefault();
|
|
loginError.textContent = "";
|
|
const username = document.querySelector("#username").value;
|
|
const password = document.querySelector("#password").value;
|
|
try {
|
|
const result = await api("/api/session", {method: "POST", body: JSON.stringify({username, password})});
|
|
token = result.Token || result.token;
|
|
sessionStorage.setItem("domovoy.chat.token", token);
|
|
showChat();
|
|
} catch {
|
|
loginError.textContent = "Вход не выполнен";
|
|
}
|
|
});
|
|
|
|
chatForm.addEventListener("submit", async (event) => {
|
|
event.preventDefault();
|
|
const text = messageInput.value.trim();
|
|
if (!text) return;
|
|
appendMessage("user", text);
|
|
messageInput.value = "";
|
|
sendButton.disabled = true;
|
|
try {
|
|
const result = await api("/api/chat/messages", {method: "POST", body: JSON.stringify({conversation_id: conversationID, message: text})});
|
|
conversationID = result.conversation_id;
|
|
sessionStorage.setItem("domovoy.chat.conversation", conversationID);
|
|
updateActiveFocus(result.active_focus, result.project_provenance);
|
|
const semanticMeta = [result.speech_act, `cognition=${result.cognition}`];
|
|
if (result.work_planned) semanticMeta.push("work=planned");
|
|
if (result.clarification) semanticMeta.push(`clarification=${result.clarification}`);
|
|
appendMessage("assistant", result.reply_text || "Сообщение записано.", semanticMeta.join("; "));
|
|
} catch {
|
|
appendMessage("assistant", "Чат сейчас недоступен. Сообщение не принято runtime.");
|
|
} finally {
|
|
sendButton.disabled = false;
|
|
messageInput.focus();
|
|
}
|
|
});
|
|
|
|
logoutButton.addEventListener("click", () => {
|
|
token = "";
|
|
conversationID = "";
|
|
sessionStorage.removeItem("domovoy.chat.token");
|
|
sessionStorage.removeItem("domovoy.chat.conversation");
|
|
messages.replaceChildren();
|
|
updateActiveFocus("");
|
|
showLogin();
|
|
});
|
|
|
|
if (token) {
|
|
showChat();
|
|
} else {
|
|
showLogin();
|
|
}
|