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>