binuser007 commited on
Commit
f9b5484
·
verified ·
1 Parent(s): 8c8d210

Create templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +638 -0
templates/index.html ADDED
@@ -0,0 +1,638 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>GitHub Navigator</title>
7
+ <!-- Bootstrap CSS -->
8
+ <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
9
+ <!-- Font Awesome -->
10
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
11
+ <!-- Google Fonts -->
12
+ <link rel="preconnect" href="https://fonts.googleapis.com">
13
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
14
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
15
+ <style>
16
+ :root {
17
+ --github-dark: #0d1117;
18
+ --github-darker: #010409;
19
+ --github-light: #f6f8fa;
20
+ --github-border: #30363d;
21
+ --github-primary: #238636;
22
+ --github-primary-hover: #2ea043;
23
+ --github-text: #c9d1d9;
24
+ --github-link: #58a6ff;
25
+ --accent-color: #2188ff;
26
+ --danger-color: #f85149;
27
+ }
28
+
29
+ body {
30
+ background-color: var(--github-dark);
31
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
32
+ color: var(--github-text);
33
+ transition: all 0.3s ease;
34
+ padding-bottom: 2rem;
35
+ }
36
+
37
+ .chat-container {
38
+ max-width: 1100px;
39
+ margin: 2rem auto;
40
+ border-radius: 12px;
41
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
42
+ background-color: var(--github-darker);
43
+ overflow: hidden;
44
+ border: 1px solid var(--github-border);
45
+ }
46
+
47
+ .chat-header {
48
+ background: linear-gradient(to right, #161b22, #0d1117);
49
+ color: white;
50
+ padding: 1.2rem 1.5rem;
51
+ font-weight: 600;
52
+ display: flex;
53
+ align-items: center;
54
+ justify-content: space-between;
55
+ border-bottom: 1px solid var(--github-border);
56
+ }
57
+
58
+ .chat-header .brand {
59
+ display: flex;
60
+ align-items: center;
61
+ font-size: 1.25rem;
62
+ }
63
+
64
+ .chat-header .github-icon {
65
+ margin-right: 12px;
66
+ font-size: 1.5rem;
67
+ color: white;
68
+ }
69
+
70
+ .chat-messages {
71
+ height: 65vh;
72
+ overflow-y: auto;
73
+ padding: 1.5rem;
74
+ background-color: var(--github-dark);
75
+ scrollbar-width: thin;
76
+ scrollbar-color: var(--github-border) var(--github-dark);
77
+ }
78
+
79
+ .chat-messages::-webkit-scrollbar {
80
+ width: 8px;
81
+ }
82
+
83
+ .chat-messages::-webkit-scrollbar-track {
84
+ background: var(--github-dark);
85
+ }
86
+
87
+ .chat-messages::-webkit-scrollbar-thumb {
88
+ background-color: var(--github-border);
89
+ border-radius: 20px;
90
+ border: 2px solid var(--github-dark);
91
+ }
92
+
93
+ .message {
94
+ margin-bottom: 1.5rem;
95
+ max-width: 85%;
96
+ clear: both;
97
+ position: relative;
98
+ animation: fadeIn 0.3s ease-out;
99
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
100
+ }
101
+
102
+ @keyframes fadeIn {
103
+ from { opacity: 0; transform: translateY(10px); }
104
+ to { opacity: 1; transform: translateY(0); }
105
+ }
106
+
107
+ .user-message {
108
+ float: right;
109
+ background: linear-gradient(135deg, #2188ff, #004182);
110
+ color: white;
111
+ border-radius: 18px 18px 0 18px;
112
+ padding: 1rem 1.2rem;
113
+ }
114
+
115
+ .user-message::after {
116
+ content: '';
117
+ position: absolute;
118
+ bottom: 0;
119
+ right: -8px;
120
+ width: 16px;
121
+ height: 16px;
122
+ background: linear-gradient(225deg, #004182, transparent);
123
+ border-bottom-left-radius: 15px;
124
+ }
125
+
126
+ .bot-message {
127
+ float: left;
128
+ background-color: #161b22;
129
+ color: #e6edf3;
130
+ border-radius: 18px 18px 18px 0;
131
+ padding: 1rem 1.2rem;
132
+ border: 1px solid var(--github-border);
133
+ }
134
+
135
+ .bot-message::after {
136
+ content: '';
137
+ position: absolute;
138
+ bottom: 0;
139
+ left: -8px;
140
+ width: 16px;
141
+ height: 16px;
142
+ background: linear-gradient(135deg, transparent, #161b22);
143
+ border-bottom-right-radius: 15px;
144
+ }
145
+
146
+ .message-input {
147
+ padding: 1.2rem 1.5rem;
148
+ background-color: var(--github-darker);
149
+ border-top: 1px solid var(--github-border);
150
+ }
151
+
152
+ .token-counter {
153
+ font-size: 0.8rem;
154
+ color: #8b949e;
155
+ text-align: right;
156
+ padding: 0.5rem 1.5rem;
157
+ background-color: var(--github-darker);
158
+ border-top: 1px solid var(--github-border);
159
+ }
160
+
161
+ .typing-indicator {
162
+ display: inline-block;
163
+ margin-left: 15px;
164
+ }
165
+
166
+ .typing-indicator span {
167
+ height: 8px;
168
+ width: 8px;
169
+ background-color: var(--github-text);
170
+ border-radius: 50%;
171
+ display: inline-block;
172
+ margin-right: 3px;
173
+ animation: typing 1s infinite;
174
+ }
175
+
176
+ .typing-indicator span:nth-child(2) {
177
+ animation-delay: 0.2s;
178
+ }
179
+
180
+ .typing-indicator span:nth-child(3) {
181
+ animation-delay: 0.4s;
182
+ }
183
+
184
+ @keyframes typing {
185
+ 0% { transform: translateY(0); }
186
+ 50% { transform: translateY(-5px); }
187
+ 100% { transform: translateY(0); }
188
+ }
189
+
190
+ pre {
191
+ background-color: #0d1117;
192
+ padding: 15px;
193
+ border-radius: 8px;
194
+ overflow-x: auto;
195
+ font-size: 0.9rem;
196
+ border: 1px solid var(--github-border);
197
+ margin: 0.5rem 0;
198
+ }
199
+
200
+ code {
201
+ font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
202
+ }
203
+
204
+ .error-message {
205
+ color: var(--danger-color);
206
+ margin-top: 0.75rem;
207
+ font-size: 0.9rem;
208
+ }
209
+
210
+ .loading {
211
+ display: none;
212
+ margin-left: 15px;
213
+ }
214
+
215
+ .message a {
216
+ color: var(--github-link);
217
+ text-decoration: none;
218
+ border-bottom: 1px dashed var(--github-link);
219
+ transition: all 0.2s ease;
220
+ }
221
+
222
+ .message a:hover {
223
+ border-bottom: 1px solid var(--github-link);
224
+ }
225
+
226
+ .bot-message a {
227
+ color: var(--github-link);
228
+ }
229
+
230
+ input.form-control {
231
+ background-color: #161b22;
232
+ border: 1px solid var(--github-border);
233
+ color: var(--github-text);
234
+ padding: 0.8rem 1rem;
235
+ border-radius: 8px;
236
+ }
237
+
238
+ input.form-control:focus {
239
+ background-color: #161b22;
240
+ border-color: var(--accent-color);
241
+ box-shadow: 0 0 0 3px rgba(33, 136, 255, 0.15);
242
+ color: white;
243
+ }
244
+
245
+ input.form-control::placeholder {
246
+ color: #8b949e;
247
+ }
248
+
249
+ .btn-primary {
250
+ background-color: var(--github-primary);
251
+ border-color: var(--github-primary);
252
+ padding: 0.8rem 1.2rem;
253
+ border-radius: 8px;
254
+ transition: all 0.2s ease;
255
+ }
256
+
257
+ .btn-primary:hover, .btn-primary:focus {
258
+ background-color: var(--github-primary-hover);
259
+ border-color: var(--github-primary-hover);
260
+ box-shadow: 0 0 0 3px rgba(45, 164, 78, 0.2);
261
+ }
262
+
263
+ .btn-outline-light {
264
+ color: #e6edf3;
265
+ border-color: #30363d;
266
+ background: transparent;
267
+ transition: all 0.2s ease;
268
+ }
269
+
270
+ .btn-outline-light:hover {
271
+ background-color: #30363d;
272
+ border-color: #8b949e;
273
+ color: white;
274
+ }
275
+
276
+ .message-metadata {
277
+ font-size: 0.75rem;
278
+ margin-top: 0.3rem;
279
+ color: #8b949e;
280
+ clear: both;
281
+ }
282
+
283
+ .user-message-container, .bot-message-container {
284
+ clear: both;
285
+ overflow: hidden;
286
+ margin-bottom: 1rem;
287
+ }
288
+
289
+ .app-title {
290
+ text-align: center;
291
+ margin: 2rem 0 0.5rem;
292
+ color: white;
293
+ font-weight: 600;
294
+ }
295
+
296
+ .app-subtitle {
297
+ text-align: center;
298
+ color: #8b949e;
299
+ margin-bottom: 1.5rem;
300
+ font-weight: 300;
301
+ }
302
+
303
+ .repo-info {
304
+ background-color: rgba(33, 136, 255, 0.1);
305
+ border: 1px solid rgba(33, 136, 255, 0.2);
306
+ border-radius: 8px;
307
+ padding: 0.5rem 1rem;
308
+ margin-bottom: 1rem;
309
+ font-size: 0.9rem;
310
+ color: #e6edf3;
311
+ }
312
+
313
+ .repo-info i {
314
+ color: var(--github-link);
315
+ margin-right: 0.5rem;
316
+ }
317
+
318
+ .bot-welcome {
319
+ display: flex;
320
+ align-items: flex-start;
321
+ margin-bottom: 1.5rem;
322
+ }
323
+
324
+ .bot-avatar {
325
+ width: 38px;
326
+ height: 38px;
327
+ border-radius: 50%;
328
+ background-color: #238636;
329
+ color: white;
330
+ display: flex;
331
+ align-items: center;
332
+ justify-content: center;
333
+ margin-right: 12px;
334
+ flex-shrink: 0;
335
+ }
336
+ </style>
337
+ </head>
338
+ <body>
339
+ <h1 class="app-title">GitHub Navigator</h1>
340
+ <p class="app-subtitle">Your AI assistant for GitHub repositories</p>
341
+
342
+ <div class="container">
343
+ <div class="chat-container">
344
+ <div class="chat-header">
345
+ <div class="brand">
346
+ <i class="fab fa-github github-icon"></i>
347
+ GitHub Navigator
348
+ </div>
349
+ <button id="resetBtn" class="btn btn-sm btn-outline-light">
350
+ <i class="fas fa-redo-alt"></i> New Chat
351
+ </button>
352
+ </div>
353
+
354
+ <div id="chatMessages" class="chat-messages">
355
+ <div class="bot-welcome">
356
+ <div class="bot-avatar">
357
+ <i class="fas fa-robot"></i>
358
+ </div>
359
+ <div class="message bot-message">
360
+ <p>Hi! I'm your GitHub Navigator. I can help you understand and work with any GitHub repository.</p>
361
+ <p>To get started, paste a GitHub repository URL below.</p>
362
+ <p><small>Example: <code>https://github.com/username/repository</code></small></p>
363
+ </div>
364
+ </div>
365
+ </div>
366
+
367
+ <div id="tokenCounter" class="token-counter">
368
+ Token count: 0
369
+ </div>
370
+
371
+ <div class="message-input">
372
+ <form id="chatForm" class="d-flex">
373
+ <input
374
+ type="text"
375
+ id="messageInput"
376
+ class="form-control"
377
+ placeholder="Enter a GitHub URL or ask a question..."
378
+ autocomplete="off"
379
+ >
380
+ <button type="submit" class="btn btn-primary ms-2">
381
+ <i class="fas fa-paper-plane"></i>
382
+ </button>
383
+ <div id="loading" class="loading">
384
+ <div class="typing-indicator">
385
+ <span></span>
386
+ <span></span>
387
+ <span></span>
388
+ </div>
389
+ </div>
390
+ </form>
391
+ <div id="errorMessage" class="error-message"></div>
392
+ </div>
393
+ </div>
394
+ </div>
395
+
396
+ <!-- Bootstrap & jQuery -->
397
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
398
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
399
+ <!-- Marked.js for Markdown parsing -->
400
+ <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
401
+ <!-- Highlight.js for code syntax highlighting -->
402
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
403
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/github-dark.min.css">
404
+
405
+ <script>
406
+ $(document).ready(function() {
407
+ // Setup variables for rate limiting
408
+ let isRateLimited = false;
409
+ let lastMessage = '';
410
+ let retryTimeout = null;
411
+ let currentRepo = null;
412
+
413
+ // Setup marked.js with highlight.js
414
+ marked.setOptions({
415
+ highlight: function(code, lang) {
416
+ if (lang && hljs.getLanguage(lang)) {
417
+ return hljs.highlight(code, { language: lang }).value;
418
+ } else {
419
+ return hljs.highlightAuto(code).value;
420
+ }
421
+ },
422
+ breaks: true
423
+ });
424
+
425
+ // Function to send a message to the server
426
+ function sendMessage(message, isRetry = false) {
427
+ // Show loading indicator
428
+ $('#loading').show();
429
+
430
+ // Check if this is a GitHub URL and we don't have a repo yet
431
+ const githubUrlRegex = /https?:\/\/github\.com\/[a-zA-Z0-9_-]+\/[a-zA-Z0-9_-]+/;
432
+ if (!currentRepo && githubUrlRegex.test(message)) {
433
+ currentRepo = message;
434
+
435
+ // Add repo info banner
436
+ const repoName = message.split('/').slice(-2).join('/');
437
+ const repoInfo = $('<div class="repo-info"><i class="fas fa-info-circle"></i>Connecting to repository: <strong>' + repoName + '</strong></div>');
438
+ $('#chatMessages').append(repoInfo);
439
+
440
+ // Scroll to bottom
441
+ scrollToBottom();
442
+ }
443
+
444
+ // Send message to server
445
+ $.ajax({
446
+ url: '/chat',
447
+ type: 'POST',
448
+ contentType: 'application/json',
449
+ data: JSON.stringify({ message: message }),
450
+ success: function(data) {
451
+ // Hide loading indicator
452
+ $('#loading').hide();
453
+
454
+ // Add bot response to chat
455
+ addMessage(data.response, 'bot');
456
+
457
+ // Update token counter
458
+ $('#tokenCounter').text('Token count: ' + data.token_count);
459
+
460
+ // Handle rate limiting
461
+ if (data.rate_limited) {
462
+ isRateLimited = true;
463
+ // Show rate limit message
464
+ const rateMsg = 'Rate limit reached. The API has a limit of 5 requests per minute. Please wait a moment before trying again.';
465
+ $('#errorMessage').text(rateMsg);
466
+
467
+ // Set up retry after 10 seconds if this wasn't already a retry
468
+ if (!isRetry) {
469
+ lastMessage = message;
470
+ const retryMsg = "I'll automatically retry in 10 seconds...";
471
+ const retryElement = $('<div class="message bot-message" style="font-style: italic; opacity: 0.8;"></div>');
472
+ retryElement.text(retryMsg);
473
+ $('#chatMessages').append(retryElement);
474
+
475
+ // Scroll to bottom
476
+ scrollToBottom();
477
+
478
+ // Set retry timeout
479
+ retryTimeout = setTimeout(function() {
480
+ sendMessage(lastMessage, true);
481
+ }, 10000);
482
+ }
483
+
484
+ setTimeout(function() {
485
+ $('#errorMessage').text('');
486
+ }, 5000);
487
+ } else {
488
+ // Reset rate limiting if successful
489
+ isRateLimited = false;
490
+ lastMessage = '';
491
+ if (retryTimeout) {
492
+ clearTimeout(retryTimeout);
493
+ retryTimeout = null;
494
+ }
495
+ }
496
+ },
497
+ error: function(xhr, status, error) {
498
+ // Hide loading indicator
499
+ $('#loading').hide();
500
+
501
+ // Show error message
502
+ let errorMessage = 'Error: ' + error;
503
+ if (xhr.responseJSON && xhr.responseJSON.error) {
504
+ errorMessage = xhr.responseJSON.error;
505
+ }
506
+ $('#errorMessage').text(errorMessage);
507
+
508
+ // Add error message to chat
509
+ const errorElement = $('<div class="message bot-message" style="color: var(--danger-color); border-color: var(--danger-color);"></div>');
510
+ errorElement.html('<i class="fas fa-exclamation-triangle"></i> Error: ' + errorMessage);
511
+ $('#chatMessages').append(errorElement);
512
+
513
+ // Scroll to bottom
514
+ scrollToBottom();
515
+
516
+ // Clear error after 5 seconds
517
+ setTimeout(function() {
518
+ $('#errorMessage').text('');
519
+ }, 5000);
520
+ }
521
+ });
522
+ }
523
+
524
+ // Function to scroll to bottom of chat
525
+ function scrollToBottom() {
526
+ const chatMessages = document.getElementById('chatMessages');
527
+ chatMessages.scrollTop = chatMessages.scrollHeight;
528
+ }
529
+
530
+ // Function to get formatted timestamp
531
+ function getFormattedTime() {
532
+ const now = new Date();
533
+ return now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
534
+ }
535
+
536
+ // Handle form submission
537
+ $('#chatForm').on('submit', function(e) {
538
+ e.preventDefault();
539
+
540
+ const messageInput = $('#messageInput');
541
+ const message = messageInput.val().trim();
542
+
543
+ if (message) {
544
+ // Clear input
545
+ messageInput.val('');
546
+
547
+ // Add user message to chat
548
+ addMessage(message, 'user');
549
+
550
+ // Send message to server
551
+ sendMessage(message);
552
+ }
553
+ });
554
+
555
+ // Handle reset button click
556
+ $('#resetBtn').on('click', function() {
557
+ if (confirm('Are you sure you want to start a new chat? This will clear the current conversation.')) {
558
+ $.ajax({
559
+ url: '/reset',
560
+ type: 'POST',
561
+ success: function(data) {
562
+ // Clear chat messages
563
+ $('#chatMessages').html('');
564
+
565
+ // Add welcome message
566
+ const welcomeMessage = `
567
+ <div class="bot-welcome">
568
+ <div class="bot-avatar">
569
+ <i class="fas fa-robot"></i>
570
+ </div>
571
+ <div class="message bot-message">
572
+ <p>Hi! I'm your GitHub Navigator. I can help you understand and work with any GitHub repository.</p>
573
+ <p>To get started, paste a GitHub repository URL below.</p>
574
+ <p><small>Example: <code>https://github.com/username/repository</code></small></p>
575
+ </div>
576
+ </div>
577
+ `;
578
+
579
+ $('#chatMessages').html(welcomeMessage);
580
+
581
+ // Reset token counter
582
+ $('#tokenCounter').text('Token count: 0');
583
+
584
+ // Reset current repo
585
+ currentRepo = null;
586
+ }
587
+ });
588
+ }
589
+ });
590
+
591
+ // Function to add a message to the chat
592
+ function addMessage(message, sender) {
593
+ const timestamp = getFormattedTime();
594
+ let messageContainer;
595
+
596
+ if (sender === 'user') {
597
+ messageContainer = $('<div class="user-message-container"></div>');
598
+ const messageElement = $('<div class="message user-message"></div>');
599
+ messageElement.text(message);
600
+ messageContainer.append(messageElement);
601
+
602
+ // Add timestamp
603
+ const timestampElement = $('<div class="message-metadata text-end"></div>');
604
+ timestampElement.text(timestamp);
605
+ messageContainer.append(timestampElement);
606
+ } else {
607
+ messageContainer = $('<div class="bot-message-container"></div>');
608
+
609
+ // Add bot avatar for bot messages
610
+ const avatarContainer = $('<div class="bot-welcome"></div>');
611
+ const avatar = $('<div class="bot-avatar"><i class="fas fa-robot"></i></div>');
612
+
613
+ const messageElement = $('<div class="message bot-message"></div>');
614
+ // Convert markdown to HTML
615
+ messageElement.html(marked.parse(message));
616
+
617
+ // Make URLs clickable
618
+ messageElement.find('a').attr('target', '_blank');
619
+
620
+ avatarContainer.append(avatar);
621
+ avatarContainer.append(messageElement);
622
+ messageContainer.append(avatarContainer);
623
+
624
+ // Add timestamp
625
+ const timestampElement = $('<div class="message-metadata text-start ms-5"></div>');
626
+ timestampElement.text(timestamp);
627
+ messageContainer.append(timestampElement);
628
+ }
629
+
630
+ $('#chatMessages').append(messageContainer);
631
+
632
+ // Scroll to bottom
633
+ scrollToBottom();
634
+ }
635
+ });
636
+ </script>
637
+ </body>
638
+ </html>