Spaces:
Runtime error
Runtime error
Commit ·
174e580
1
Parent(s): 3536abf
fixing
Browse files- static/script.js +30 -19
static/script.js
CHANGED
|
@@ -39,7 +39,6 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 39 |
}
|
| 40 |
});
|
| 41 |
|
| 42 |
-
// <-- NEW LISTENER FOR “CLEAR ALL” ---
|
| 43 |
clearAllButton.addEventListener("click", (e) => {
|
| 44 |
e.preventDefault();
|
| 45 |
clearAllConversations();
|
|
@@ -47,39 +46,29 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 47 |
|
| 48 |
// === 4. MAIN FUNCTIONS ===
|
| 49 |
|
| 50 |
-
/**
|
| 51 |
-
* NEW FEATURE: Delete all conversations
|
| 52 |
-
*/
|
| 53 |
async function clearAllConversations() {
|
| 54 |
if (!confirm("Are you sure you want to delete all conversations? This action cannot be undone.")) {
|
| 55 |
return;
|
| 56 |
}
|
| 57 |
-
|
| 58 |
try {
|
|
|
|
| 59 |
const response = await fetch("/api/conversations", {
|
| 60 |
method: "DELETE",
|
| 61 |
headers: { "Content-Type": "application/json" },
|
| 62 |
-
body: JSON.stringify({ userId: currentUserId })
|
| 63 |
});
|
| 64 |
-
|
| 65 |
if (!response.ok) {
|
| 66 |
throw new Error("Failed to delete history on the server.");
|
| 67 |
}
|
| 68 |
-
|
| 69 |
-
// If the server is successful, clear the frontend state
|
| 70 |
conversations = {};
|
| 71 |
-
startNewChat();
|
| 72 |
-
|
| 73 |
console.log("All conversations have been successfully deleted.");
|
| 74 |
-
|
| 75 |
} catch (error) {
|
| 76 |
console.error("Error clearing conversations:", error);
|
| 77 |
alert("An error occurred while deleting history.");
|
| 78 |
}
|
| 79 |
}
|
| 80 |
|
| 81 |
-
// ... (The functions getOrCreateUserId, startNewChat, sendMessage, etc. remain exactly the same) ...
|
| 82 |
-
|
| 83 |
function getOrCreateUserId() {
|
| 84 |
let userId = localStorage.getItem('anonymousUserId');
|
| 85 |
if (!userId) {
|
|
@@ -104,6 +93,9 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 104 |
let tempId = null;
|
| 105 |
let activeConversation;
|
| 106 |
|
|
|
|
|
|
|
|
|
|
| 107 |
if (currentConversationId === null) {
|
| 108 |
const title = messageText.length > 28 ? messageText.substring(0, 28) + "..." : messageText;
|
| 109 |
tempId = "temp-" + Date.now();
|
|
@@ -118,15 +110,22 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 118 |
activeConversation = conversations[currentConversationId];
|
| 119 |
}
|
| 120 |
|
| 121 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
renderChatLog();
|
| 123 |
-
renderHistory();
|
| 124 |
chatInput.value = "";
|
| 125 |
|
| 126 |
const loadingDiv = addMessageToLog("assistant", "...");
|
| 127 |
chatLog.scrollTop = chatLog.scrollHeight;
|
| 128 |
|
| 129 |
try {
|
|
|
|
| 130 |
const response = await fetch("/api/chat", {
|
| 131 |
method: "POST",
|
| 132 |
headers: { "Content-Type": "application/json" },
|
|
@@ -143,19 +142,29 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 143 |
|
| 144 |
const botText = data.answer;
|
| 145 |
const realConversationId = data.conversationId;
|
|
|
|
| 146 |
|
| 147 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
const p = loadingDiv.querySelector(".message-content p");
|
| 149 |
p.textContent = botText;
|
| 150 |
|
|
|
|
| 151 |
if (currentConversationId === tempId) {
|
| 152 |
activeConversation.id = realConversationId;
|
| 153 |
conversations[realConversationId] = activeConversation;
|
| 154 |
delete conversations[tempId];
|
| 155 |
currentConversationId = realConversationId;
|
| 156 |
-
renderHistory();
|
| 157 |
}
|
| 158 |
|
|
|
|
|
|
|
|
|
|
| 159 |
} catch (error) {
|
| 160 |
console.error("Error sending message:", error);
|
| 161 |
const p = loadingDiv.querySelector(".message-content p");
|
|
@@ -176,6 +185,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 176 |
historyList.innerHTML = "";
|
| 177 |
|
| 178 |
const sortedConversations = Object.values(conversations).sort((a, b) => {
|
|
|
|
| 179 |
const lastMsgA = a.messages[a.messages.length - 1]?.timestamp || a.id;
|
| 180 |
const lastMsgB = b.messages[b.messages.length - 1]?.timestamp || b.id;
|
| 181 |
return new Date(lastMsgB) - new Date(lastMsgA);
|
|
@@ -233,6 +243,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 233 |
async function initializeApp() {
|
| 234 |
if (!currentUserId) return;
|
| 235 |
try {
|
|
|
|
| 236 |
const response = await fetch(`/api/conversations?userId=${currentUserId}`);
|
| 237 |
if (!response.ok) {
|
| 238 |
throw new Error("Failed to load history");
|
|
@@ -242,7 +253,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
| 242 |
data.forEach(convo => {
|
| 243 |
conversations[convo.id] = convo;
|
| 244 |
});
|
| 245 |
-
renderHistory();
|
| 246 |
startNewChat();
|
| 247 |
} catch (error) {
|
| 248 |
console.error("Error initializing app:", error);
|
|
|
|
| 39 |
}
|
| 40 |
});
|
| 41 |
|
|
|
|
| 42 |
clearAllButton.addEventListener("click", (e) => {
|
| 43 |
e.preventDefault();
|
| 44 |
clearAllConversations();
|
|
|
|
| 46 |
|
| 47 |
// === 4. MAIN FUNCTIONS ===
|
| 48 |
|
|
|
|
|
|
|
|
|
|
| 49 |
async function clearAllConversations() {
|
| 50 |
if (!confirm("Are you sure you want to delete all conversations? This action cannot be undone.")) {
|
| 51 |
return;
|
| 52 |
}
|
|
|
|
| 53 |
try {
|
| 54 |
+
// Gunakan URL relatif (tanpa localhost) untuk hosting
|
| 55 |
const response = await fetch("/api/conversations", {
|
| 56 |
method: "DELETE",
|
| 57 |
headers: { "Content-Type": "application/json" },
|
| 58 |
+
body: JSON.stringify({ userId: currentUserId })
|
| 59 |
});
|
|
|
|
| 60 |
if (!response.ok) {
|
| 61 |
throw new Error("Failed to delete history on the server.");
|
| 62 |
}
|
|
|
|
|
|
|
| 63 |
conversations = {};
|
| 64 |
+
startNewChat();
|
|
|
|
| 65 |
console.log("All conversations have been successfully deleted.");
|
|
|
|
| 66 |
} catch (error) {
|
| 67 |
console.error("Error clearing conversations:", error);
|
| 68 |
alert("An error occurred while deleting history.");
|
| 69 |
}
|
| 70 |
}
|
| 71 |
|
|
|
|
|
|
|
| 72 |
function getOrCreateUserId() {
|
| 73 |
let userId = localStorage.getItem('anonymousUserId');
|
| 74 |
if (!userId) {
|
|
|
|
| 93 |
let tempId = null;
|
| 94 |
let activeConversation;
|
| 95 |
|
| 96 |
+
// --- INI PERBAIKANNYA (1) ---
|
| 97 |
+
const userTimestamp = new Date().toISOString();
|
| 98 |
+
|
| 99 |
if (currentConversationId === null) {
|
| 100 |
const title = messageText.length > 28 ? messageText.substring(0, 28) + "..." : messageText;
|
| 101 |
tempId = "temp-" + Date.now();
|
|
|
|
| 110 |
activeConversation = conversations[currentConversationId];
|
| 111 |
}
|
| 112 |
|
| 113 |
+
// --- INI PERBAIKANNYA (2) ---
|
| 114 |
+
// 1. Tambahkan & tampilkan pesan user (dengan timestamp)
|
| 115 |
+
activeConversation.messages.push({
|
| 116 |
+
role: "user",
|
| 117 |
+
content: messageText,
|
| 118 |
+
timestamp: userTimestamp // <-- DI SINI
|
| 119 |
+
});
|
| 120 |
renderChatLog();
|
| 121 |
+
renderHistory(); // Sekarang akan mengurutkan dengan benar
|
| 122 |
chatInput.value = "";
|
| 123 |
|
| 124 |
const loadingDiv = addMessageToLog("assistant", "...");
|
| 125 |
chatLog.scrollTop = chatLog.scrollHeight;
|
| 126 |
|
| 127 |
try {
|
| 128 |
+
// Gunakan URL relatif (tanpa localhost) untuk hosting
|
| 129 |
const response = await fetch("/api/chat", {
|
| 130 |
method: "POST",
|
| 131 |
headers: { "Content-Type": "application/json" },
|
|
|
|
| 142 |
|
| 143 |
const botText = data.answer;
|
| 144 |
const realConversationId = data.conversationId;
|
| 145 |
+
const botTimestamp = new Date().toISOString(); // Timestamp untuk bot
|
| 146 |
|
| 147 |
+
// --- INI PERBAIKANNYA (3) ---
|
| 148 |
+
// 4. Update pesan bot (dengan timestamp)
|
| 149 |
+
activeConversation.messages.push({
|
| 150 |
+
role: "assistant",
|
| 151 |
+
content: botText,
|
| 152 |
+
timestamp: botTimestamp // <-- DI SINI
|
| 153 |
+
});
|
| 154 |
const p = loadingDiv.querySelector(".message-content p");
|
| 155 |
p.textContent = botText;
|
| 156 |
|
| 157 |
+
// 5. Sinkronisasi ID
|
| 158 |
if (currentConversationId === tempId) {
|
| 159 |
activeConversation.id = realConversationId;
|
| 160 |
conversations[realConversationId] = activeConversation;
|
| 161 |
delete conversations[tempId];
|
| 162 |
currentConversationId = realConversationId;
|
|
|
|
| 163 |
}
|
| 164 |
|
| 165 |
+
// Urutkan ulang history setelah mendapat balasan
|
| 166 |
+
renderHistory();
|
| 167 |
+
|
| 168 |
} catch (error) {
|
| 169 |
console.error("Error sending message:", error);
|
| 170 |
const p = loadingDiv.querySelector(".message-content p");
|
|
|
|
| 185 |
historyList.innerHTML = "";
|
| 186 |
|
| 187 |
const sortedConversations = Object.values(conversations).sort((a, b) => {
|
| 188 |
+
// Logika ini sekarang akan bekerja karena 'timestamp' dijamin ada
|
| 189 |
const lastMsgA = a.messages[a.messages.length - 1]?.timestamp || a.id;
|
| 190 |
const lastMsgB = b.messages[b.messages.length - 1]?.timestamp || b.id;
|
| 191 |
return new Date(lastMsgB) - new Date(lastMsgA);
|
|
|
|
| 243 |
async function initializeApp() {
|
| 244 |
if (!currentUserId) return;
|
| 245 |
try {
|
| 246 |
+
// Gunakan URL relatif (tanpa localhost) untuk hosting
|
| 247 |
const response = await fetch(`/api/conversations?userId=${currentUserId}`);
|
| 248 |
if (!response.ok) {
|
| 249 |
throw new Error("Failed to load history");
|
|
|
|
| 253 |
data.forEach(convo => {
|
| 254 |
conversations[convo.id] = convo;
|
| 255 |
});
|
| 256 |
+
renderHistory(); // Ini akan mengurutkan dengan benar saat memuat
|
| 257 |
startNewChat();
|
| 258 |
} catch (error) {
|
| 259 |
console.error("Error initializing app:", error);
|