ParthSadaria commited on
Commit
bda7485
·
verified ·
1 Parent(s): 8ef5ca7

Update playground.html

Browse files
Files changed (1) hide show
  1. playground.html +252 -42
playground.html CHANGED
@@ -4,26 +4,39 @@
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>LOKI.AI Playground</title>
 
 
 
7
  <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
 
8
  <script src="https://cdn.tailwindcss.com"></script>
 
9
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
 
 
 
 
 
10
  <script>
11
  tailwind.config = {
12
  darkMode: 'class',
13
  theme: {
14
  extend: {
15
  fontFamily: {
 
16
  mono: ['"JetBrains Mono"', 'monospace'],
17
  },
18
  colors: {
19
  primary: {
20
  DEFAULT: '#10B981',
21
  dark: '#059669',
 
22
  },
23
  dark: {
24
- DEFAULT: '#111827',
25
- lighter: '#1F2937',
26
- card: '#1E293B',
 
27
  },
28
  },
29
  animation: {
@@ -40,12 +53,162 @@
40
  }
41
  }
42
  </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  </head>
44
 
45
- <body class="dark:bg-dark dark:text-gray-200 min-h-screen transition-colors duration-300">
46
  <!-- GitHub Link -->
47
  <a href="https://github.com/ParthSadaria" target="_blank" rel="noopener noreferrer"
48
- class="fixed top-4 right-4 text-gray-500 hover:text-primary transition-colors duration-300 z-10"
49
  aria-label="Visit Parth Sadaria's GitHub profile">
50
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
51
  class="w-6 h-6" stroke-linecap="round" stroke-linejoin="round">
@@ -55,33 +218,36 @@
55
 
56
  <!-- Chat Container -->
57
  <div class="max-w-4xl mx-auto py-8 px-4 sm:px-6 opacity-0 transform translate-y-4" id="chatWrapper">
58
- <!-- Header -->
59
- <div class="flex justify-between items-center mb-6 p-4 bg-gray-100 dark:bg-dark-lighter rounded-lg shadow-md">
60
- <h2 class="text-xl font-mono font-bold text-gray-800 dark:text-gray-100">LOKI.AI Playground</h2>
 
 
 
61
  <div class="flex space-x-2">
62
  <!-- Model Selector -->
63
  <div class="relative" id="modelSelector">
64
- <button class="px-3 py-2 bg-gray-200 dark:bg-dark-card rounded-md text-sm flex items-center space-x-1 hover:bg-gray-300 dark:hover:bg-gray-700 transition-colors" id="modelSelectButton">
65
  <span id="modelSelectDisplay">Select Model</span>
66
- <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
67
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
68
  </svg>
69
  </button>
70
- <div class="absolute mt-1 w-56 rounded-md shadow-lg bg-white dark:bg-dark-card ring-1 ring-black ring-opacity-5 hidden max-h-64 overflow-y-auto z-20" id="modelOptions">
71
  <div class="py-2 px-3 text-sm text-gray-400" id="modelLoader">Loading models...</div>
72
  </div>
73
  </div>
74
 
75
  <!-- Clear Chat Button -->
76
- <button id="clearChatButton" class="p-2 rounded-md hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors">
77
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
78
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
79
  </svg>
80
  </button>
81
 
82
  <!-- Theme Toggle Button -->
83
- <button id="themeToggle" class="p-2 rounded-md hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors">
84
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
85
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
86
  </svg>
87
  </button>
@@ -90,12 +256,12 @@
90
 
91
  <!-- Initial Input -->
92
  <div class="flex flex-col items-center justify-center space-y-6 py-12" id="initialInput">
93
- <h2 class="text-2xl font-mono font-semibold">Welcome to LOKI.AI</h2>
94
  <div class="w-full max-w-2xl relative">
95
  <input type="text" id="initialChatInput"
96
- class="w-full p-4 pr-12 rounded-lg border-2 border-gray-300 dark:border-gray-700 bg-white dark:bg-dark-card focus:outline-none focus:ring-2 focus:ring-primary dark:text-white shadow-md transition-all"
97
  placeholder="What can I help you with today?">
98
- <button id="initialSendIcon" class="absolute right-3 top-3 text-gray-400 hover:text-primary transition-colors">
99
  <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
100
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" />
101
  </svg>
@@ -104,33 +270,33 @@
104
  </div>
105
 
106
  <!-- Chat Area -->
107
- <div class="hidden flex-col h-[70vh] bg-white dark:bg-dark-card rounded-lg shadow-lg overflow-hidden" id="chatContainer">
108
  <!-- Messages Area -->
109
- <div class="flex-1 overflow-y-auto p-4 space-y-4" id="chatMessages"></div>
110
 
111
  <!-- Input Area -->
112
- <div class="border-t border-gray-200 dark:border-gray-700 p-4">
113
  <div class="relative">
114
  <input type="text" id="chatInput"
115
- class="w-full p-3 pr-12 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-dark-card focus:outline-none focus:ring-2 focus:ring-primary dark:text-white transition-all"
116
  placeholder="Type your message...">
117
- <button id="sendButton" class="absolute right-3 top-3 text-gray-400 hover:text-primary transition-colors">
118
  <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" id="sendIcon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
119
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" />
120
  </svg>
121
  <div id="sendLoader" class="hidden">
122
- <div class="w-5 h-5 border-2 border-primary border-t-transparent rounded-full animate-spin"></div>
123
  </div>
124
  </button>
125
  </div>
126
- <p class="text-center text-gray-500 text-xs mt-2">Models can make mistakes. Check important info.</p>
127
  </div>
128
  </div>
129
  </div>
130
 
131
  <!-- Watermark -->
132
  <div class="fixed bottom-2 right-4 text-xs text-gray-500 font-mono">
133
- Made with ❤️ by Parth Sadaria
134
  </div>
135
 
136
  <script>
@@ -294,22 +460,41 @@ document.addEventListener('DOMContentLoaded', function() {
294
  function scrollToBottom() {
295
  chatMessages.scrollTop = chatMessages.scrollHeight;
296
  }
297
-
298
- function createMessageElement(type) {
299
- const messageBox = document.createElement('div');
300
- messageBox.className = `p-3 rounded-lg ${type === 'user' ? 'bg-primary bg-opacity-10 ml-8' : 'bg-gray-100 dark:bg-gray-800 mr-8'}`;
301
-
302
- // Add animation
303
- anime({
304
- targets: messageBox,
305
- opacity: [0, 1],
306
- translateY: [10, 0],
307
- easing: 'easeOutExpo',
308
- duration: 400
309
  });
310
-
311
- return messageBox;
312
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
 
314
  function appendMessage(content, type = 'bot', isStreaming = false) {
315
  if (type === 'bot' && isStreaming) {
@@ -659,7 +844,32 @@ document.addEventListener('DOMContentLoaded', function() {
659
  chatContainer.style.height = '70vh';
660
  }
661
  }
662
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
663
  window.addEventListener('resize', resizeChat);
664
  resizeChat();
665
 
 
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>LOKI.AI Playground</title>
7
+ <!-- DM Sans font -->
8
+ <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&display=swap" rel="stylesheet">
9
+ <!-- JetBrains Mono for code blocks -->
10
  <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
11
+ <!-- Tailwind CSS -->
12
  <script src="https://cdn.tailwindcss.com"></script>
13
+ <!-- Anime.js for animations -->
14
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
15
+ <!-- Marked.js for Markdown support -->
16
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.3.0/marked.min.js"></script>
17
+ <!-- Highlight.js for code syntax highlighting -->
18
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-dark.min.css">
19
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
20
  <script>
21
  tailwind.config = {
22
  darkMode: 'class',
23
  theme: {
24
  extend: {
25
  fontFamily: {
26
+ sans: ['"DM Sans"', 'sans-serif'],
27
  mono: ['"JetBrains Mono"', 'monospace'],
28
  },
29
  colors: {
30
  primary: {
31
  DEFAULT: '#10B981',
32
  dark: '#059669',
33
+ light: '#6EE7B7',
34
  },
35
  dark: {
36
+ DEFAULT: '#0F172A', // Darker blue-black
37
+ lighter: '#1E293B', // Slate 800
38
+ card: '#1E293B', // Slate 800
39
+ input: '#334155', // Slate 700
40
  },
41
  },
42
  animation: {
 
53
  }
54
  }
55
  </script>
56
+ <style>
57
+ /* Custom scrollbar for dark theme */
58
+ .dark ::-webkit-scrollbar {
59
+ width: 8px;
60
+ height: 8px;
61
+ }
62
+
63
+ .dark ::-webkit-scrollbar-track {
64
+ background: #1E293B;
65
+ }
66
+
67
+ .dark ::-webkit-scrollbar-thumb {
68
+ background: #475569;
69
+ border-radius: 4px;
70
+ }
71
+
72
+ .dark ::-webkit-scrollbar-thumb:hover {
73
+ background: #64748B;
74
+ }
75
+
76
+ /* Markdown styles */
77
+ .markdown-content h1 {
78
+ font-size: 1.8rem;
79
+ font-weight: 700;
80
+ margin-top: 1.5rem;
81
+ margin-bottom: 1rem;
82
+ border-bottom: 1px solid #334155;
83
+ padding-bottom: 0.5rem;
84
+ }
85
+
86
+ .markdown-content h2 {
87
+ font-size: 1.5rem;
88
+ font-weight: 600;
89
+ margin-top: 1.2rem;
90
+ margin-bottom: 0.8rem;
91
+ }
92
+
93
+ .markdown-content h3 {
94
+ font-size: 1.3rem;
95
+ font-weight: 600;
96
+ margin-top: 1rem;
97
+ margin-bottom: 0.7rem;
98
+ }
99
+
100
+ .markdown-content p {
101
+ margin-bottom: 1rem;
102
+ line-height: 1.6;
103
+ }
104
+
105
+ .markdown-content ul, .markdown-content ol {
106
+ margin-top: 0.5rem;
107
+ margin-bottom: 1rem;
108
+ padding-left: 1.5rem;
109
+ }
110
+
111
+ .markdown-content ul {
112
+ list-style-type: disc;
113
+ }
114
+
115
+ .markdown-content ol {
116
+ list-style-type: decimal;
117
+ }
118
+
119
+ .markdown-content li {
120
+ margin-bottom: 0.5rem;
121
+ }
122
+
123
+ .markdown-content blockquote {
124
+ border-left: 4px solid #6EE7B7;
125
+ padding-left: 1rem;
126
+ margin-left: 0;
127
+ margin-right: 0;
128
+ font-style: italic;
129
+ background-color: rgba(30, 41, 59, 0.5);
130
+ padding: 0.5rem 1rem;
131
+ border-radius: 0 4px 4px 0;
132
+ }
133
+
134
+ .markdown-content img {
135
+ max-width: 100%;
136
+ margin: 1rem 0;
137
+ border-radius: 8px;
138
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
139
+ }
140
+
141
+ .markdown-content table {
142
+ width: 100%;
143
+ border-collapse: collapse;
144
+ margin: 1rem 0;
145
+ }
146
+
147
+ .markdown-content table th,
148
+ .markdown-content table td {
149
+ padding: 0.5rem;
150
+ border: 1px solid #334155;
151
+ }
152
+
153
+ .markdown-content table th {
154
+ background-color: #1E293B;
155
+ font-weight: 600;
156
+ }
157
+
158
+ .markdown-content table tr:nth-child(even) {
159
+ background-color: rgba(30, 41, 59, 0.5);
160
+ }
161
+
162
+ .markdown-content pre {
163
+ margin: 1rem 0;
164
+ padding: 1rem;
165
+ border-radius: 8px;
166
+ background-color: #1E293B !important;
167
+ overflow-x: auto;
168
+ }
169
+
170
+ .markdown-content code {
171
+ font-family: 'JetBrains Mono', monospace;
172
+ font-size: 0.9rem;
173
+ background-color: #334155;
174
+ padding: 0.2rem 0.4rem;
175
+ border-radius: 4px;
176
+ }
177
+
178
+ .markdown-content pre code {
179
+ background-color: transparent;
180
+ padding: 0;
181
+ border-radius: 0;
182
+ }
183
+
184
+ .typing-indicator span {
185
+ animation: typing 1s infinite;
186
+ animation-delay: calc(var(--dot-index) * 0.3s);
187
+ }
188
+
189
+ /* Message bubbles with improved styling */
190
+ .message-bubble {
191
+ border-radius: 1rem;
192
+ max-width: 90%;
193
+ }
194
+
195
+ .user-message {
196
+ background-color: #334155;
197
+ margin-left: auto;
198
+ border-top-right-radius: 0.25rem;
199
+ }
200
+
201
+ .assistant-message {
202
+ background-color: #0F172A;
203
+ border-top-left-radius: 0.25rem;
204
+ }
205
+ </style>
206
  </head>
207
 
208
+ <body class="dark:bg-dark dark:text-gray-200 min-h-screen transition-colors duration-300 font-sans">
209
  <!-- GitHub Link -->
210
  <a href="https://github.com/ParthSadaria" target="_blank" rel="noopener noreferrer"
211
+ class="fixed top-4 right-4 text-gray-500 hover:text-primary-light transition-colors duration-300 z-10"
212
  aria-label="Visit Parth Sadaria's GitHub profile">
213
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
214
  class="w-6 h-6" stroke-linecap="round" stroke-linejoin="round">
 
218
 
219
  <!-- Chat Container -->
220
  <div class="max-w-4xl mx-auto py-8 px-4 sm:px-6 opacity-0 transform translate-y-4" id="chatWrapper">
221
+ <!-- Header with Logo -->
222
+ <div class="flex justify-between items-center mb-6 p-4 bg-dark-lighter rounded-xl shadow-lg border border-dark-input">
223
+ <div class="flex items-center">
224
+ <span class="text-xl font-mono font-bold bg-gradient-to-r from-primary to-primary-light bg-clip-text text-transparent">LOKI.AI</span>
225
+ <span class="ml-2 text-sm bg-dark-input px-2 py-0.5 rounded-full text-gray-300">Playground</span>
226
+ </div>
227
  <div class="flex space-x-2">
228
  <!-- Model Selector -->
229
  <div class="relative" id="modelSelector">
230
+ <button class="px-3 py-2 bg-dark-input rounded-md text-sm flex items-center space-x-1 hover:bg-gray-700 transition-colors shadow-sm" id="modelSelectButton">
231
  <span id="modelSelectDisplay">Select Model</span>
232
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 ml-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
233
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
234
  </svg>
235
  </button>
236
+ <div class="absolute mt-1 w-56 rounded-md shadow-lg bg-dark-card ring-1 ring-black ring-opacity-5 hidden max-h-64 overflow-y-auto z-20" id="modelOptions">
237
  <div class="py-2 px-3 text-sm text-gray-400" id="modelLoader">Loading models...</div>
238
  </div>
239
  </div>
240
 
241
  <!-- Clear Chat Button -->
242
+ <button id="clearChatButton" class="p-2 rounded-md hover:bg-gray-700 transition-colors bg-dark-input shadow-sm group">
243
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 group-hover:text-primary-light transition-colors" fill="none" viewBox="0 0 24 24" stroke="currentColor">
244
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
245
  </svg>
246
  </button>
247
 
248
  <!-- Theme Toggle Button -->
249
+ <button id="themeToggle" class="p-2 rounded-md hover:bg-gray-700 transition-colors bg-dark-input shadow-sm group">
250
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 group-hover:text-primary-light transition-colors" fill="none" viewBox="0 0 24 24" stroke="currentColor">
251
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
252
  </svg>
253
  </button>
 
256
 
257
  <!-- Initial Input -->
258
  <div class="flex flex-col items-center justify-center space-y-6 py-12" id="initialInput">
259
+ <h2 class="text-2xl font-semibold bg-gradient-to-r from-primary to-primary-light bg-clip-text text-transparent">Welcome to LOKI.AI</h2>
260
  <div class="w-full max-w-2xl relative">
261
  <input type="text" id="initialChatInput"
262
+ class="w-full p-4 pr-12 rounded-xl border-2 border-dark-input bg-dark-lighter focus:outline-none focus:ring-2 focus:ring-primary-light dark:text-white shadow-lg transition-all"
263
  placeholder="What can I help you with today?">
264
+ <button id="initialSendIcon" class="absolute right-4 top-4 text-gray-400 hover:text-primary-light transition-colors">
265
  <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
266
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" />
267
  </svg>
 
270
  </div>
271
 
272
  <!-- Chat Area -->
273
+ <div class="hidden flex-col h-[70vh] bg-dark-lighter rounded-xl shadow-lg overflow-hidden border border-dark-input" id="chatContainer">
274
  <!-- Messages Area -->
275
+ <div class="flex-1 overflow-y-auto p-4 space-y-5" id="chatMessages"></div>
276
 
277
  <!-- Input Area -->
278
+ <div class="border-t border-dark-input p-4">
279
  <div class="relative">
280
  <input type="text" id="chatInput"
281
+ class="w-full p-3 pr-12 rounded-xl border border-dark-input bg-dark-input focus:outline-none focus:ring-2 focus:ring-primary-light dark:text-white transition-all shadow-inner"
282
  placeholder="Type your message...">
283
+ <button id="sendButton" class="absolute right-3 top-3 text-gray-400 hover:text-primary-light transition-colors">
284
  <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" id="sendIcon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
285
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" />
286
  </svg>
287
  <div id="sendLoader" class="hidden">
288
+ <div class="w-5 h-5 border-2 border-primary-light border-t-transparent rounded-full animate-spin"></div>
289
  </div>
290
  </button>
291
  </div>
292
+ <p class="text-center text-gray-500 text-xs mt-2">Models can make mistakes. Check important information.</p>
293
  </div>
294
  </div>
295
  </div>
296
 
297
  <!-- Watermark -->
298
  <div class="fixed bottom-2 right-4 text-xs text-gray-500 font-mono">
299
+ Made with <span class="text-primary-light">❤️</span> by Parth Sadaria
300
  </div>
301
 
302
  <script>
 
460
  function scrollToBottom() {
461
  chatMessages.scrollTop = chatMessages.scrollHeight;
462
  }
463
+ marked.setOptions({
464
+ highlight: function(code, lang) {
465
+ if (lang && hljs.getLanguage(lang)) {
466
+ return hljs.highlight(code, { language: lang }).value;
467
+ }
468
+ return hljs.highlightAuto(code).value;
469
+ },
470
+ breaks: true,
471
+ gfm: true
 
 
 
472
  });
473
+
474
+ function createMessageElement(message, sender) {
475
+ const messageEl = document.createElement('div');
476
+ messageEl.className = `message-bubble p-4 ${sender === 'user' ? 'user-message' : 'assistant-message'}`;
477
+
478
+ if (sender === 'assistant') {
479
+ // Use markdown parsing for assistant messages
480
+ messageEl.classList.add('markdown-content');
481
+ messageEl.innerHTML = marked.parse(message);
482
+
483
+ // Apply syntax highlighting to code blocks
484
+ messageEl.querySelectorAll('pre code').forEach((block) => {
485
+ hljs.highlightElement(block);
486
+ });
487
+ } else {
488
+ // For user messages, just use the plain text
489
+ messageEl.textContent = message;
490
+ }
491
+
492
+ const wrapperEl = document.createElement('div');
493
+ wrapperEl.className = `flex ${sender === 'user' ? 'justify-end' : 'justify-start'}`;
494
+ wrapperEl.appendChild(messageEl);
495
+
496
+ return wrapperEl;
497
+ }
498
 
499
  function appendMessage(content, type = 'bot', isStreaming = false) {
500
  if (type === 'bot' && isStreaming) {
 
844
  chatContainer.style.height = '70vh';
845
  }
846
  }
847
+ function showTypingIndicator() {
848
+ const typingEl = document.createElement('div');
849
+ typingEl.className = 'message-bubble assistant-message p-3 typing-indicator flex';
850
+ typingEl.innerHTML = `
851
+ <span class="h-2 w-2 bg-primary-light rounded-full mx-0.5" style="--dot-index: 0"></span>
852
+ <span class="h-2 w-2 bg-primary-light rounded-full mx-0.5" style="--dot-index: 1"></span>
853
+ <span class="h-2 w-2 bg-primary-light rounded-full mx-0.5" style="--dot-index: 2"></span>
854
+ `;
855
+
856
+ const wrapperEl = document.createElement('div');
857
+ wrapperEl.className = 'flex justify-start typing-wrapper';
858
+ wrapperEl.appendChild(typingEl);
859
+
860
+ document.getElementById('chatMessages').appendChild(wrapperEl);
861
+ document.getElementById('chatMessages').scrollTop = document.getElementById('chatMessages').scrollHeight;
862
+
863
+ return wrapperEl;
864
+ }
865
+
866
+ // Function to remove typing indicator
867
+ function removeTypingIndicator() {
868
+ const typingWrapper = document.querySelector('.typing-wrapper');
869
+ if (typingWrapper) {
870
+ typingWrapper.remove();
871
+ }
872
+ }
873
  window.addEventListener('resize', resizeChat);
874
  resizeChat();
875