|
<!DOCTYPE html> |
|
<html lang="en"> |
|
|
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Chat with LLM</title> |
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/flowbite/1.6.5/flowbite.min.css" rel="stylesheet"> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
</head> |
|
|
|
<body class="bg-gray-100 p-5 pb-50 h-screen flex flex-col"> |
|
<div class="chat-container max-w-5xl w-full h-full flex flex-col mx-auto bg-white shadow-lg rounded-lg p-4"> |
|
<div class="chat-box w-full h-full overflow-y-auto mb-4 p-3 border border-gray-200 rounded-lg" id="chat-box"></div> |
|
<div class="input-container flex flex-col flex-none space-x-y"> |
|
<input type="file" id="image-input" |
|
class="block w-96 px-4 py-2 text-sm text-gray-500 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 focus:outline-none mb-2" |
|
accept="image/*"> |
|
<div class="input-container flex space-x-2"> |
|
<input type="text" id="chat-input" |
|
class="block w-full px-4 py-4 text-sm text-gray-700 bg-gray-50 border border-gray-300 rounded-lg focus:ring-blue-500 focus:border-blue-500" |
|
placeholder="Type your message here..."> |
|
|
|
<button id="send-button" |
|
class="bg-blue-600 text-white px-10 py-2 rounded-lg hover:bg-blue-700 focus:ring-4 focus:ring-blue-300"> |
|
Send |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<script src="https://cdn.socket.io/4.5.0/socket.io.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/2.1.0/showdown.min.js" |
|
integrity="sha512-LhccdVNGe2QMEfI3x4DVV3ckMRe36TfydKss6mJpdHjNFiV07dFpS2xzeZedptKZrwxfICJpez09iNioiSZ3hA==" |
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/flowbite/1.6.5/flowbite.min.js"></script> |
|
|
|
<script> |
|
const socket = io.connect(document.baseURI); |
|
const chatBox = document.getElementById('chat-box'); |
|
const chatInput = document.getElementById('chat-input'); |
|
const imageInput = document.getElementById('image-input'); |
|
const sendButton = document.getElementById('send-button'); |
|
const converter = new showdown.Converter(); |
|
let response = ""; |
|
|
|
function addLoader() { |
|
const loaderEle = document.createElement('div'); |
|
loaderEle.classList.add('dot-loader'); |
|
loaderEle.innerHTML = ` |
|
<div></div> |
|
<div></div> |
|
<div></div> |
|
`; |
|
chatBox.appendChild(loaderEle); |
|
} |
|
|
|
function appendMessage(message, sender) { |
|
if (sender === 'bot') { |
|
response += message; |
|
const loaderEle = chatBox.lastElementChild; |
|
if (loaderEle && loaderEle.classList.contains('dot-loader')) { |
|
chatBox.removeChild(loaderEle); |
|
const messageElement = document.createElement('div'); |
|
messageElement.classList.add('chat-message', sender); |
|
messageElement.innerHTML = `<span>${response}</span>`; |
|
chatBox.append(messageElement); |
|
chatBox.scrollTop = chatBox.scrollHeight; |
|
} else { |
|
const lastMessageEle = chatBox.lastElementChild; |
|
if (lastMessageEle) { |
|
lastMessageEle.innerHTML = response; |
|
} |
|
chatBox.scrollTop = chatBox.scrollHeight; |
|
} |
|
} else { |
|
const messageElement = document.createElement('div'); |
|
messageElement.classList.add('chat-message', sender); |
|
messageElement.innerHTML = `<span>${message}</span>`; |
|
chatBox.append(messageElement); |
|
chatBox.scrollTop = chatBox.scrollHeight; |
|
setTimeout(addLoader, 500); |
|
} |
|
} |
|
|
|
function readImageAsBase64(imageFile) { |
|
return new Promise((resolve, reject) => { |
|
const reader = new FileReader(); |
|
reader.onload = () => resolve(reader.result); |
|
reader.onerror = reject; |
|
reader.readAsDataURL(imageFile); |
|
}); |
|
} |
|
|
|
sendButton.addEventListener('click', async () => { |
|
const message = chatInput.value.trim(); |
|
const imageFile = imageInput.files[0]; |
|
|
|
let messageData = { |
|
message: message, |
|
session_id: 'abc123' |
|
}; |
|
|
|
if (imageFile) { |
|
try { |
|
const imageBase64 = await readImageAsBase64(imageFile); |
|
messageData.image = imageBase64; |
|
} catch (error) { |
|
console.error('Error reading image file:', error); |
|
} |
|
} |
|
if (message || imageFile) { |
|
|
|
appendMessage(message || 'Image sent', 'user'); |
|
|
|
|
|
socket.emit('message', messageData); |
|
|
|
chatInput.value = ''; |
|
imageInput.value = ''; |
|
response = ""; |
|
} else { |
|
console.error("Message or image cannot be empty."); |
|
} |
|
}); |
|
|
|
chatInput.addEventListener('keypress', (e) => { |
|
if (e.key === 'Enter') { |
|
sendButton.click(); |
|
} |
|
}); |
|
|
|
socket.on('response', (data) => { |
|
if (data && typeof data === 'string') { |
|
appendMessage(data, 'bot'); |
|
} else { |
|
console.error("Invalid response format received from the server."); |
|
} |
|
}); |
|
|
|
socket.on('connect_error', (error) => { |
|
appendMessage("Sorry, there was a problem connecting to the server. Please try again later.", 'bot'); |
|
}); |
|
|
|
socket.on('connect', (reason) => { |
|
console.log("Connected to server."); |
|
}); |
|
|
|
socket.on('disconnect', (reason) => { |
|
appendMessage("You have been disconnected from the server. Please refresh the page to reconnect.", 'bot'); |
|
}); |
|
</script> |
|
</body> |
|
|
|
</html> |
|
|