Ashrafb commited on
Commit
3c43801
1 Parent(s): adbe9a0

Upload static_index (64).html

Browse files
Files changed (1) hide show
  1. static/static_index (64).html +532 -0
static/static_index (64).html ADDED
@@ -0,0 +1,532 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <!DOCTYPE html>
3
+ <html lang="en" dir="ltr">
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <!-- Google Fonts Link For Icons -->
8
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
9
+ <style>
10
+ /* Import Google font - Poppins */
11
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');
12
+ * {
13
+ margin: 0;
14
+ padding: 0;
15
+ box-sizing: border-box;
16
+ font-family: "Poppins", sans-serif;
17
+ }
18
+ :root {
19
+ --text-color: #FFFFFF;
20
+ --icon-color: #ACACBE;
21
+ --icon-hover-bg: #5b5e71;
22
+ --placeholder-color: #dcdcdc;
23
+ --outgoing-chat-bg: #343541;
24
+ --incoming-chat-bg: #444654;
25
+ --outgoing-chat-border: #343541;
26
+ --incoming-chat-border: #444654;
27
+ }
28
+ .light-mode {
29
+ --text-color: #343541;
30
+ --icon-color: #a9a9bc;
31
+ --icon-hover-bg: #f1f1f3;
32
+ --placeholder-color: #6c6c6c;
33
+ --outgoing-chat-bg: #FFFFFF;
34
+ --incoming-chat-bg: #F7F7F8;
35
+ --outgoing-chat-border: #FFFFFF;
36
+ --incoming-chat-border: #D9D9E3;
37
+ }
38
+ body {
39
+ background: var(--outgoing-chat-bg);
40
+ overflow: hidden; /* Prevent body from scrolling */
41
+ }
42
+ .top-bar {
43
+ background: var(--outgoing-chat-bg);
44
+ border-bottom: 1px solid var(--incoming-chat-border);
45
+ padding: 10px;
46
+ text-align: center;
47
+ color: var(--text-color);
48
+
49
+ top: 0;
50
+ width: 100%;
51
+ z-index: 1000;
52
+ }
53
+ .chat-container {
54
+ overflow-y: auto;
55
+ max-height: calc(100vh - 150px); /* Adjust max-height to account for top bar and typing container */
56
+ padding-top: 60px; /* Add padding to account for fixed top bar */
57
+ padding-bottom: 150px; /* Add padding to account for typing container */
58
+ position: relative;
59
+ }
60
+ :where(.chat-container, textarea)::-webkit-scrollbar {
61
+ width: 6px;
62
+ }
63
+ :where(.chat-container, textarea)::-webkit-scrollbar-track {
64
+ background: var(--incoming-chat-bg);
65
+ border-radius: 25px;
66
+ }
67
+ :where(.chat-container, textarea)::-webkit-scrollbar-thumb {
68
+ background: var(--icon-color);
69
+ border-radius: 25px;
70
+ }
71
+ .default-text {
72
+ display: flex;
73
+ align-items: center;
74
+ justify-content: center;
75
+ flex-direction: column;
76
+ height: 70vh;
77
+ padding: 0 10px;
78
+ text-align: center;
79
+ color: var(--text-color);
80
+ }
81
+ .default-text h1 {
82
+ font-size: 3.3rem;
83
+ }
84
+ .default-text p {
85
+ margin-top: 10px;
86
+ font-size: 1.1rem;
87
+ }
88
+ .chat-container .chat {
89
+ padding: 25px 10px;
90
+ display: flex;
91
+ justify-content: center;
92
+ color: var(--text-color);
93
+ position: relative;
94
+ word-break: break-word; /* Ensure long words break to fit within the container */
95
+ overflow-wrap: break-word; /* Ensure long words break to fit within the container */
96
+ }
97
+ .chat-container .chat.outgoing {
98
+ background: var(--outgoing-chat-bg);
99
+ border: 1px solid var(--outgoing-chat-border);
100
+ }
101
+ .chat-container .chat.incoming {
102
+ background: var(--incoming-chat-bg);
103
+ border: 1px solid var(--incoming-chat-border);
104
+ }
105
+ .chat .chat-content {
106
+ display: flex;
107
+ max-width: 1200px;
108
+ width: 100%;
109
+ align-items: flex-start;
110
+ justify-content: space-between;
111
+ word-break: break-word; /* Ensure long words break to fit within the container */
112
+ overflow-wrap: break-word; /* Ensure long words break to fit within the container */
113
+ }
114
+ span.material-symbols-rounded {
115
+ user-select: none;
116
+ cursor: pointer;
117
+ color: var(--icon-color); /* Ensure all icons use the same color */
118
+ }
119
+ .chat .chat-content span {
120
+ cursor: pointer;
121
+ font-size: 1.3rem;
122
+ color: var(--icon-color);
123
+ visibility: visible; /* Ensure icons are always visible */
124
+ }
125
+ .chat .chat-details {
126
+ display: flex;
127
+ align-items: center;
128
+ }
129
+ .chat .chat-details img {
130
+ width: 35px;
131
+ height: 35px;
132
+ align-self: flex-start;
133
+ object-fit: cover;
134
+ border-radius: 2px;
135
+ }
136
+ .chat .chat-details p {
137
+ white-space: pre-wrap;
138
+ font-size: 1.05rem;
139
+ padding: 0 50px 0 25px;
140
+ color: var(--text-color);
141
+ word-break: break-word;
142
+ overflow-wrap: break-word;
143
+ max-width: 100%; /* Ensure long words break to fit within the container */
144
+ }
145
+ .chat .chat-details p.error {
146
+ color: #e55865;
147
+ }
148
+ .chat .typing-animation {
149
+ padding-left: 25px;
150
+ display: inline-flex;
151
+ }
152
+ .typing-animation .typing-dot {
153
+ height: 7px;
154
+ width: 7px;
155
+ border-radius: 50%;
156
+ margin: 0 3px;
157
+ opacity: 0.7;
158
+ background: var(--text-color);
159
+ animation: animateDots 1.5s var(--delay) ease-in-out infinite;
160
+ }
161
+ .typing-animation .typing-dot:first-child {
162
+ margin-left: 0;
163
+ }
164
+ @keyframes animateDots {
165
+ 0%,
166
+ 44% {
167
+ transform: translateY(0px);
168
+ }
169
+ 28% {
170
+ opacity: 0.4;
171
+ transform: translateY(-6px);
172
+ }
173
+ 44% {
174
+ opacity: 0.2;
175
+ }
176
+ }
177
+ /* Typing container styling */
178
+ .typing-container {
179
+ position: fixed;
180
+ bottom: 0;
181
+ width: 100%;
182
+ display: flex;
183
+ flex-direction: column;
184
+ padding: 20px 10px;
185
+ justify-content: center;
186
+ background: var(--outgoing-chat-bg);
187
+ border-top: 1px solid var(--incoming-chat-border);
188
+ z-index: 1000;
189
+ }
190
+ .typing-content {
191
+ display: flex;
192
+ max-width: 950px;
193
+ width: 100%;
194
+ align-items: flex-end;
195
+ margin-bottom: 10px;
196
+ }
197
+ .typing-textarea {
198
+ width: 100%;
199
+ display: flex;
200
+ position: relative;
201
+ }
202
+ .typing-textarea textarea {
203
+ resize: none;
204
+ height: 55px;
205
+ width: 100%;
206
+ border: none;
207
+ padding: 15px 45px 15px 20px;
208
+ color: var(--text-color);
209
+ font-size: 1rem;
210
+ border-radius: 4px;
211
+ max-height: 250px;
212
+ overflow-y: auto;
213
+ background: var(--incoming-chat-bg);
214
+ outline: 1px solid var(--incoming-chat-border);
215
+ }
216
+ .typing-textarea textarea::placeholder {
217
+ color: var(--placeholder-color);
218
+ }
219
+ .typing-textarea span {
220
+ position: absolute;
221
+ right: 10px;
222
+ bottom: 10px;
223
+ font-size: 1.5rem;
224
+ cursor: pointer;
225
+ }
226
+ .typing-controls {
227
+ display: flex;
228
+ justify-content: center;
229
+ }
230
+ .typing-controls span {
231
+ margin-left: 7px;
232
+ font-size: 1.4rem;
233
+ background: var(--incoming-chat-bg);
234
+ outline: 1px solid var(--incoming-chat-border);
235
+ padding: 10px;
236
+ border-radius: 4px;
237
+ }
238
+ .typing-controls span:hover {
239
+ background: var(--icon-hover-bg);
240
+ }
241
+ /* Reponsive Media Query */
242
+ @media screen and (max-width: 600px) {
243
+ .default-text h1 {
244
+ font-size: 2.3rem;
245
+ }
246
+ :where(.default-text p, textarea, .chat p) {
247
+ font-size: 0.95rem!important;
248
+ }
249
+ .chat-container .chat {
250
+ padding: 20px 10px;
251
+ }
252
+ .chat-container .chat img {
253
+ height: 32px;
254
+ width: 32px;
255
+ }
256
+ .chat-container .chat p {
257
+ padding: 0 20px;
258
+ }
259
+ .chat .chat-content span {
260
+ visibility: visible; /* Ensure icons are always visible on smaller screens */
261
+ }
262
+ .typing-container {
263
+ padding: 15px 10px;
264
+ }
265
+ .typing-container .typing-content {
266
+ max-width: 100%;
267
+ }
268
+ .typing-controls span {
269
+ margin-left: 5px;
270
+ font-size: 1.2rem;
271
+ }
272
+ .typing-textarea textarea {
273
+ padding: 14px 45px 14px 15px;
274
+ font-size: 0.95rem;
275
+ }
276
+ }
277
+ .chat .icon-container {
278
+ display: flex;
279
+ justify-content: flex-end;
280
+ margin-top: 10px;
281
+ }
282
+ .top-bar img {
283
+ width: 50px; /* Sets the width of the image */
284
+ height: 50px; /* Sets the height of the image */
285
+ border-radius: 30%; /* Makes the image circular */
286
+ margin-right: 10px; /* Adds some space between the image and the text */
287
+ text-align: left;
288
+ }
289
+ .top-bar span {
290
+ font-size: 16px; /* Sets the font size */
291
+ text-align: center;
292
+ line-height: 1.5; /* Sets the line height */
293
+ }
294
+ </style>
295
+ </head>
296
+ <body>
297
+ <div class="top-bar">
298
+ <img src="img/chatbot.jpg">
299
+ <span>Hello there! How can I help you today.</span>
300
+ </div>
301
+ <div class="chat-container">
302
+ <div class="default-text">
303
+ <h1>Welcome</h1>
304
+ <p>Start a conversation with the AI assistant.</p>
305
+ </div>
306
+ </div>
307
+ <div class="typing-container">
308
+ <div class="typing-content">
309
+ <div class="typing-textarea">
310
+ <textarea spellcheck="false" placeholder="Type your message.."></textarea>
311
+ <span class="material-symbols-rounded">send</span>
312
+ </div>
313
+ </div>
314
+ <div class="typing-controls">
315
+ <span id="theme-toggle-btn" class="material-symbols-rounded">light_mode</span>
316
+ <span id="delete-btn" class="material-symbols-rounded">delete</span>
317
+ <span id="download-btn" class="material-symbols-rounded">download</span>
318
+ </div>
319
+ </div>
320
+ <script>
321
+ document.addEventListener("DOMContentLoaded", () => {
322
+ const textarea = document.querySelector("textarea"),
323
+ chatContainer = document.querySelector(".chat-container"),
324
+ sendChatBtn = document.querySelector(".typing-textarea .material-symbols-rounded"),
325
+ deleteBtn = document.getElementById("delete-btn"),
326
+ downloadBtn = document.getElementById("download-btn"),
327
+ toggleIcon = document.getElementById("theme-toggle-btn"),
328
+ defaultText = document.querySelector(".default-text");
329
+
330
+ let userMessage = null;
331
+
332
+ if (!textarea || !chatContainer || !sendChatBtn || !deleteBtn || !downloadBtn || !toggleIcon || !defaultText) {
333
+ console.error("One or more elements are not found in the DOM.");
334
+ return;
335
+ }
336
+
337
+ toggleIcon.onclick = () => {
338
+ document.body.classList.toggle("light-mode");
339
+ toggleIcon.innerText = document.body.classList.contains("light-mode") ? "dark_mode" : "light_mode";
340
+ };
341
+
342
+ const createTypingAnimation = () => {
343
+ const html = `
344
+ <div class="chat-content" style="display: flex; flex-direction: column;">
345
+ <div class="chat-details" style="flex-grow: 1;">
346
+ <img src="img/chatbot.jpg" alt="">
347
+ <div class="typing-animation">
348
+ <div class="typing-dot" style="--delay: 0s"></div>
349
+ <div class="typing-dot" style="--delay: 0.15s"></div>
350
+ <div class="typing-dot" style="--delay: 0.3s"></div>
351
+ </div>
352
+ </div>
353
+ </div>`;
354
+ const incomingChat = document.createElement("div");
355
+ incomingChat.classList.add("chat", "incoming");
356
+ incomingChat.innerHTML = html;
357
+ return incomingChat;
358
+ };
359
+
360
+ const generateResponse = (chatElement) => {
361
+ const API_URL = "/generate/";
362
+
363
+ const requestOptions = {
364
+ method: "POST",
365
+ headers: {
366
+ "Content-Type": "application/x-www-form-urlencoded"
367
+ },
368
+ body: new URLSearchParams({
369
+ prompt: userMessage,
370
+ history: "[]",
371
+ temperature: "0.9",
372
+ max_new_tokens: "512",
373
+ top_p: "0.95",
374
+ repetition_penalty: "1.0"
375
+ })
376
+ };
377
+
378
+ fetch(API_URL, requestOptions).then(res => res.json()).then(data => {
379
+ chatElement.querySelector(".typing-animation").remove();
380
+ const pElement = document.createElement("p");
381
+ pElement.textContent = data.response;
382
+ chatElement.querySelector(".chat-details").appendChild(pElement);
383
+
384
+ // Add regenerate and copy icons container
385
+ const iconContainer = document.createElement("div");
386
+ iconContainer.style.display = "flex";
387
+ iconContainer.style.justifyContent = "flex-end";
388
+ iconContainer.style.marginTop = "10px";
389
+
390
+ // Add regenerate icon
391
+ const regenerateIcon = document.createElement("span");
392
+ regenerateIcon.classList.add("material-symbols-rounded");
393
+ regenerateIcon.textContent = "refresh";
394
+ regenerateIcon.style.marginLeft = "10px";
395
+ regenerateIcon.addEventListener("click", () => regenerateResponse(chatElement, userMessage));
396
+ iconContainer.appendChild(regenerateIcon);
397
+
398
+ // Add copy icon
399
+ const copyIcon = document.createElement("span");
400
+ copyIcon.classList.add("material-symbols-rounded");
401
+ copyIcon.textContent = "content_copy";
402
+ copyIcon.style.marginLeft = "10px";
403
+ copyIcon.addEventListener("click", () => copyMessage(pElement));
404
+ iconContainer.appendChild(copyIcon);
405
+
406
+ // Append the iconContainer to the chat-details div
407
+ chatElement.querySelector(".chat-content").appendChild(iconContainer);
408
+
409
+ }).catch(() => {
410
+ chatElement.querySelector(".typing-animation").remove();
411
+ const pElement = document.createElement("p");
412
+ pElement.classList.add("error");
413
+ pElement.textContent = "Oops! Something went wrong. Please try again.";
414
+ chatElement.querySelector(".chat-details").appendChild(pElement);
415
+ }).finally(() => chatContainer.scrollTo(0, chatContainer.scrollHeight));
416
+ };
417
+
418
+ const regenerateResponse = (chatElement, message) => {
419
+ const typingAnimation = createTypingAnimation();
420
+ chatElement.replaceWith(typingAnimation);
421
+ generateResponse(typingAnimation);
422
+ };
423
+
424
+ const copyMessage = (element) => {
425
+ const originalText = element.textContent; // Store the original text
426
+ navigator.clipboard.writeText(element.innerText).then(() => {
427
+ element.textContent = "Copied";
428
+ setTimeout(() => {
429
+ element.textContent = originalText; // Restore the original text after a delay
430
+ }, 1000); // Adjust the delay as needed
431
+ });
432
+ };
433
+
434
+ const createChatElement = (message, className) => {
435
+ const chatElement = document.createElement("div");
436
+ chatElement.classList.add("chat", className);
437
+
438
+ const html = `
439
+ <div class="chat-content" style="display: flex; flex-direction: column;">
440
+ <div class="chat-details" style="flex-grow: 1;">
441
+ <img src="${className === "outgoing" ? "img/user.jpg" : "img/chatbot.jpg"}" alt="">
442
+ <p></p>
443
+ </div>
444
+ <div style="display: flex; justify-content: flex-end; margin-top: 10px;">
445
+ <span class="material-symbols-rounded">content_copy</span>
446
+ ${className === "outgoing" ? '<span class="material-symbols-rounded" style="margin-left: 10px;">edit</span>' : ''}
447
+ </div>
448
+ </div>`;
449
+ chatElement.innerHTML = html;
450
+
451
+ const pElement = chatElement.querySelector("p");
452
+ pElement.textContent = message; // Use textContent to prevent HTML/JavaScript execution
453
+
454
+ if (className === "outgoing") {
455
+ const editIcon = chatElement.querySelector(".material-symbols-rounded:nth-child(2)");
456
+ editIcon.addEventListener("click", () => {
457
+ textarea.value = message;
458
+ chatElement.remove();
459
+ textarea.focus();
460
+ });
461
+ }
462
+
463
+ const copyIcon = chatElement.querySelector(".material-symbols-rounded:nth-child(1)");
464
+ copyIcon.addEventListener("click", () => copyMessage(pElement));
465
+
466
+ return chatElement;
467
+ };
468
+
469
+
470
+ const handleChat = () => {
471
+ userMessage = textarea.value.trim();
472
+ if (!userMessage) return;
473
+
474
+ textarea.value = "";
475
+ textarea.style.height = "55px"; // Reset the height of the textarea
476
+
477
+ if (defaultText.style.display !== "none") {
478
+ defaultText.style.display = "none";
479
+ }
480
+
481
+ chatContainer.appendChild(createChatElement(userMessage, "outgoing"));
482
+ chatContainer.scrollTo(0, chatContainer.scrollHeight);
483
+
484
+ const incomingChat = createTypingAnimation();
485
+ chatContainer.appendChild(incomingChat);
486
+ chatContainer.scrollTo(0, chatContainer.scrollHeight);
487
+
488
+ generateResponse(incomingChat);
489
+ };
490
+
491
+ textarea.addEventListener("input", () => {
492
+ textarea.style.height = "auto";
493
+ textarea.style.height = `${textarea.scrollHeight}px`;
494
+ });
495
+
496
+ textarea.addEventListener("keydown", (e) => {
497
+ if (e.key === "Enter" && !e.shiftKey) {
498
+ e.preventDefault();
499
+ handleChat();
500
+ }
501
+ });
502
+
503
+ sendChatBtn.addEventListener("click", handleChat);
504
+
505
+ // Add event listener for delete button to clear chat
506
+ deleteBtn.addEventListener("click", () => {
507
+ chatContainer.innerHTML = "";
508
+ defaultText.style.display = "block";
509
+ });
510
+
511
+ // Add event listener for download button to download chat
512
+ downloadBtn.addEventListener("click", () => {
513
+ let chatText = "";
514
+ const chats = chatContainer.querySelectorAll(".chat p");
515
+ chats.forEach((chat) => {
516
+ chatText += chat.textContent + "\n";
517
+ });
518
+
519
+ const blob = new Blob([chatText], { type: "text/plain" });
520
+ const url = URL.createObjectURL(blob);
521
+ const a = document.createElement("a");
522
+ a.href = url;
523
+ a.download = "chat.txt";
524
+ document.body.appendChild(a);
525
+ a.click();
526
+ document.body.removeChild(a);
527
+ URL.revokeObjectURL(url);
528
+ });
529
+ });
530
+ </script>
531
+ </body>
532
+ </html>