85 lines
2.3 KiB
JavaScript
85 lines
2.3 KiB
JavaScript
const form = document.querySelector("#chatForm");
|
|
const promptInput = document.querySelector("#prompt");
|
|
const messagesEl = document.querySelector("#messages");
|
|
const sendButton = document.querySelector("#sendButton");
|
|
const newChatButton = document.querySelector("#newChat");
|
|
|
|
let messages = [];
|
|
|
|
function addMessage(role, content) {
|
|
const article = document.createElement("article");
|
|
article.className = `message ${role}`;
|
|
|
|
const avatar = document.createElement("div");
|
|
avatar.className = "avatar";
|
|
avatar.textContent = role === "user" ? "U" : "L";
|
|
|
|
const bubble = document.createElement("div");
|
|
bubble.className = "bubble";
|
|
bubble.textContent = content;
|
|
|
|
article.append(avatar, bubble);
|
|
messagesEl.append(article);
|
|
messagesEl.scrollTop = messagesEl.scrollHeight;
|
|
return bubble;
|
|
}
|
|
|
|
function resetChat() {
|
|
messages = [];
|
|
messagesEl.innerHTML = "";
|
|
addMessage("assistant", "새 대화를 시작합니다.");
|
|
promptInput.focus();
|
|
}
|
|
|
|
promptInput.addEventListener("input", () => {
|
|
promptInput.style.height = "auto";
|
|
promptInput.style.height = `${promptInput.scrollHeight}px`;
|
|
});
|
|
|
|
promptInput.addEventListener("keydown", (event) => {
|
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
event.preventDefault();
|
|
form.requestSubmit();
|
|
}
|
|
});
|
|
|
|
newChatButton.addEventListener("click", resetChat);
|
|
|
|
form.addEventListener("submit", async (event) => {
|
|
event.preventDefault();
|
|
|
|
const content = promptInput.value.trim();
|
|
if (!content || sendButton.disabled) {
|
|
return;
|
|
}
|
|
|
|
promptInput.value = "";
|
|
promptInput.style.height = "auto";
|
|
addMessage("user", content);
|
|
messages.push({ role: "user", content });
|
|
|
|
sendButton.disabled = true;
|
|
const pending = addMessage("assistant", "생각 중...");
|
|
|
|
try {
|
|
const response = await fetch("/api/chat", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ messages }),
|
|
});
|
|
|
|
const data = await response.json();
|
|
if (!response.ok) {
|
|
throw new Error(data.error || "응답 생성 실패");
|
|
}
|
|
|
|
pending.textContent = data.reply;
|
|
messages.push({ role: "assistant", content: data.reply });
|
|
} catch (error) {
|
|
pending.textContent = `오류: ${error.message}`;
|
|
} finally {
|
|
sendButton.disabled = false;
|
|
promptInput.focus();
|
|
}
|
|
});
|