File size: 7,093 Bytes
a68743b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
<!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 to add a loader element
function addLoader() {
const loaderEle = document.createElement('div');
loaderEle.classList.add('dot-loader');
loaderEle.innerHTML = `
<div></div>
<div></div>
<div></div>
`;
chatBox.appendChild(loaderEle);
}
// Function to append a message to the chat box
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 to handle image as Base64 and send with message
function readImageAsBase64(imageFile) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(imageFile);
});
}
// Function to handle sending the message and image
sendButton.addEventListener('click', async () => {
const message = chatInput.value.trim();
const imageFile = imageInput.files[0];
// Prepare the message object
let messageData = {
message: message,
session_id: 'abc123'
};
// If there is an image, read it as base64 and add to messageData
if (imageFile) {
try {
const imageBase64 = await readImageAsBase64(imageFile);
messageData.image = imageBase64;
} catch (error) {
console.error('Error reading image file:', error);
}
}
if (message || imageFile) {
// appendMessage(imageFile || 'Image sent', 'user');
appendMessage(message || 'Image sent', 'user');
// Send message and image (if available) to the server via socket
socket.emit('message', messageData);
// Clear inputs
chatInput.value = '';
imageInput.value = ''; // Clear the image input
response = "";
} else {
console.error("Message or image cannot be empty.");
}
});
// Event listener for 'Enter' key press in the chat input
chatInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendButton.click();
}
});
// Handle incoming responses from the server
socket.on('response', (data) => {
if (data && typeof data === 'string') {
appendMessage(data, 'bot');
} else {
console.error("Invalid response format received from the server.");
}
});
// Handle connection errors
socket.on('connect_error', (error) => {
appendMessage("Sorry, there was a problem connecting to the server. Please try again later.", 'bot');
});
// Handle connection
socket.on('connect', (reason) => {
console.log("Connected to server.");
});
// Handle disconnection
socket.on('disconnect', (reason) => {
appendMessage("You have been disconnected from the server. Please refresh the page to reconnect.", 'bot');
});
</script>
</body>
</html>
|