joermd commited on
Commit
0a5d1e4
·
verified ·
1 Parent(s): ebaa44f

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +156 -144
index.html CHANGED
@@ -5,6 +5,10 @@
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Speedy Chat</title>
7
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
 
 
 
 
8
  <style>
9
  @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans+Arabic:wght@100;200;300;400;500;600;700&display=swap');
10
  @import url('https://fonts.googleapis.com/css2?family=Noto+Kufi+Arabic:wght@100;200;300;400;500;600;700;800;900&display=swap');
@@ -58,6 +62,17 @@
58
  background-color: #404040;
59
  }
60
 
 
 
 
 
 
 
 
 
 
 
 
61
  .welcome-text {
62
  font-family: 'Noto Kufi Arabic', sans-serif;
63
  font-size: 2rem;
@@ -110,7 +125,7 @@
110
  display: inline-flex;
111
  align-items: center;
112
  gap: 0.25rem;
113
- font-size: 0.75rem;
114
  color: #6B7280;
115
  background-color: #F3F4F6;
116
  }
@@ -119,45 +134,48 @@
119
  background-color: #E5E7EB;
120
  }
121
 
122
- .header-button {
123
- color: #6B7280;
124
- padding: 0.5rem;
125
- border-radius: 9999px;
126
- transition: all 0.2s;
127
- display: flex;
128
- align-items: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  justify-content: center;
130
- }
131
-
132
- .header-button:hover {
133
- background-color: #F3F4F6;
134
- }
135
-
136
- .style-select {
137
- appearance: none;
138
- background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
139
- background-repeat: no-repeat;
140
- background-position: left 0.5rem center;
141
- background-size: 1em;
142
- }
143
-
144
- .stop-generation {
145
- background-color: #EF4444 !important;
146
- color: white !important;
147
  }
148
 
149
- .search-toggle.active {
150
- background-color: #3b82f6;
151
- color: white;
 
 
 
 
 
152
  }
153
 
154
- .thinking-steps {
155
- background-color: #f8fafc;
 
 
156
  border-radius: 0.5rem;
157
- padding: 1rem;
158
- margin: 0.5rem 0;
159
- font-size: 0.9rem;
160
- color: #64748b;
161
  }
162
 
163
  .chat-input {
@@ -172,46 +190,14 @@
172
  }
173
  }
174
 
175
- .message p {
176
- font-size: 0.875rem;
177
- line-height: 1.5;
178
- }
179
-
180
- .bot-avatar {
181
- width: 36px;
182
- height: 36px;
183
- border-radius: 50%;
184
- object-fit: cover;
185
- }
186
-
187
- .message-input-container {
188
- padding: 0.5rem !important;
189
- }
190
-
191
- .input-actions {
192
- padding-top: 0.25rem !important;
193
- }
194
-
195
- /* Remove footer border */
196
- footer {
197
- border-top: none !important;
198
- }
199
-
200
- /* Reduce message container padding */
201
- .bot-message {
202
- padding: 0.75rem !important;
203
- }
204
-
205
- /* Adjust message actions spacing */
206
  .message-actions {
207
- margin-top: 0.25rem;
208
  display: flex;
209
- gap: 0.25rem;
210
  }
211
  </style>
212
  </head>
213
  <body class="text-lg light-mode">
214
- <!-- Rest of the HTML remains exactly the same -->
215
  <header class="fixed top-0 left-0 right-0 bg-white border-b border-gray-100 z-50 shadow-sm">
216
  <div class="flex items-center px-4 py-2">
217
  <div class="flex items-center flex-1">
@@ -228,11 +214,6 @@
228
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"></path>
229
  </svg>
230
  </a>
231
- <a href="/account" class="header-button">
232
- <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
233
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path>
234
- </svg>
235
- </a>
236
  <button id="darkModeToggle" class="header-button">
237
  <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
238
  <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"></path>
@@ -254,9 +235,20 @@
254
  </div>
255
  </main>
256
 
 
 
 
 
 
 
 
 
 
 
 
257
  <footer class="fixed bottom-0 left-0 right-0 bg-white shadow-sm">
258
  <div class="max-w-3xl mx-auto px-4 py-3">
259
- <div class="relative bg-white rounded-xl border border-gray-200 p-2 message-input-container">
260
  <textarea
261
  id="messageInput"
262
  class="chat-input w-full text-gray-600 text-lg p-2 rounded-lg resize-none border-none"
@@ -264,7 +256,7 @@
264
  rows="1"
265
  ></textarea>
266
 
267
- <div class="flex items-center justify-between mt-2 input-actions">
268
  <div class="flex gap-3">
269
  <button class="text-gray-400 hover:text-gray-600" id="attachButton">
270
  <svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor">
@@ -276,7 +268,7 @@
276
  <path d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z"/>
277
  </svg>
278
  </a>
279
- <button id="searchButton" class="text-gray-400 hover:text-gray-600 search-toggle">
280
  <svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor">
281
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
282
  </svg>
@@ -284,7 +276,7 @@
284
  </div>
285
 
286
  <div class="flex items-center gap-3">
287
- <select id="styleSelect" class="style-select bg-gray-50 border border-gray-200 text-gray-600 text-sm rounded-lg pl-8 pr-2 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-200">
288
  <option value="short">⚡ ردود قصيرة</option>
289
  <option value="normal" selected>◯ عادي</option>
290
  <option value="long">↔ ردود مفصلة</option>
@@ -308,7 +300,7 @@
308
  </footer>
309
 
310
  <script>
311
- const API_URL = 'https://975yry7ibyersz-7777.proxy.runpod.net/proxy/6000/chat';
312
  const messagesContainer = document.getElementById('messagesContainer');
313
  const messageInput = document.getElementById('messageInput');
314
  const sendButton = document.getElementById('sendMessage');
@@ -317,31 +309,24 @@
317
  const darkModeToggle = document.getElementById('darkModeToggle');
318
  const aiToggle = document.getElementById('aiToggle');
319
  const searchButton = document.getElementById('searchButton');
 
 
 
 
 
320
  let chatHistory = [];
321
  let currentStyle = 'normal';
322
  let currentController = null;
323
  let isSearchEnabled = false;
 
324
 
325
- // Search button toggle
326
- searchButton.addEventListener('click', () => {
327
- isSearchEnabled = !isSearchEnabled;
328
- searchButton.classList.toggle('active');
329
- messageInput.placeholder = isSearchEnabled ? "ابحث عن..." : "اكتب رسالتك هنا...";
330
- });
331
-
332
- // Dark mode toggle
333
- darkModeToggle.addEventListener('click', () => {
334
- document.body.classList.toggle('dark-mode');
335
- document.body.classList.toggle('light-mode');
336
- });
337
-
338
- aiToggle.addEventListener('click', function() {
339
- this.classList.toggle('active');
340
- });
341
-
342
- styleSelect.addEventListener('change', (e) => {
343
- currentStyle = e.target.value;
344
- });
345
 
346
  function createThinkingSteps(messageId) {
347
  return `
@@ -354,13 +339,6 @@
354
  }
355
 
356
  function createUserMessage(text) {
357
- let prefix = '';
358
- if (currentStyle === 'short') {
359
- prefix = 'اعطني رد باختصار وسرعة: ';
360
- } else if (currentStyle === 'long') {
361
- prefix = 'اعطني رد مفصل وموسع: ';
362
- }
363
-
364
  return `
365
  <div class="message flex justify-end mb-4">
366
  <div class="max-w-[80%]">
@@ -376,7 +354,7 @@
376
  return `
377
  <div class="message flex justify-start mb-4">
378
  <div class="flex-shrink-0 mt-1">
379
- <img src="https://ufastpro.com/wp-content/uploads/2024/12/3.png" alt="Bot Avatar" class="bot-avatar">
380
  </div>
381
  <div class="max-w-[80%] mr-3">
382
  <div class="bot-message bg-white rounded-lg p-3 shadow-sm">
@@ -384,27 +362,21 @@
384
  <div class="message-actions">
385
  <button class="action-button copy-button" data-message-id="${messageId}">
386
  <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
387
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"></path>
388
  </svg>
389
  نسخ
390
  </button>
391
- <button class="action-button regenerate-button" data-message-id="${messageId}">
392
- <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
393
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
394
- </svg>
395
- إعادة التوليد
396
- </button>
397
- <button class="action-button like-button" data-message-id="${messageId}">
398
  <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
399
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 10h4.764a2 2 0 011.789 2.894l-3.5 7A2 2 0 0115.263 21h-4.017c-.163 0-.326-.02-.485-.06L7 20m7-10V5a2 2 0 00-2-2h-.095c-.5 0-.905.405-.905.905 0 .714-.211 1.412-.608 2.006L7 11v9m7-10h-2M7 20H5a2 2 0 01-2-2v-6a2 2 0 012-2h2.5"></path>
400
  </svg>
401
- أعجبني
402
  </button>
403
- <button class="action-button dislike-button" data-message-id="${messageId}">
404
  <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
405
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14H5.236a2 2 0 01-1.789-2.894l3.5-7A2 2 0 018.736 3h4.018c.163 0 .326.02.485.06L17 4m-7 10v5a2 2 0 002 2h.095c.5 0 .905-.405.905-.905 0-.714.211-1.412.608-2.006L17 13V4m-7 10h2m5 0v2a2 2 0 01-2 2h-2.5"></path>
406
  </svg>
407
- لم يعجبني
408
  </button>
409
  </div>
410
  </div>
@@ -415,16 +387,26 @@
415
 
416
  async function typeText(elementId, text) {
417
  const element = document.getElementById(elementId);
418
- element.innerHTML = '';
419
- const words = text.split(' ');
420
-
421
- for (let i = 0; i < words.length; i++) {
422
- const span = document.createElement('span');
423
- span.textContent = words[i] + ' ';
424
- span.className = 'typing-animation';
425
- element.appendChild(span);
426
- await new Promise(resolve => setTimeout(resolve, 50));
427
- }
 
 
 
 
 
 
 
 
 
 
428
  }
429
 
430
  function toggleSendButton(isGenerating) {
@@ -549,32 +531,26 @@
549
  setTimeout(() => {
550
  button.innerHTML = `
551
  <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
552
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"></path>
553
  </svg>
554
  نسخ
555
  `;
556
  }, 2000);
557
  }
558
 
559
- if (e.target.closest('.regenerate-button')) {
560
- if (chatHistory.length > 0) {
561
- const lastMessage = chatHistory[chatHistory.length - 1].human;
562
- messageInput.value = lastMessage;
563
- sendMessage();
564
- }
565
- }
566
-
567
- if (e.target.closest('.like-button')) {
568
- const button = e.target.closest('.like-button');
569
- button.classList.toggle('text-green-500');
570
  }
571
 
572
- if (e.target.closest('.dislike-button')) {
573
- const button = e.target.closest('.dislike-button');
574
- button.classList.toggle('text-red-500');
575
  }
576
  });
577
 
 
578
  sendButton.addEventListener('click', sendMessage);
579
  messageInput.addEventListener('keypress', (e) => {
580
  if (e.key === 'Enter' && !e.shiftKey) {
@@ -583,6 +559,37 @@
583
  }
584
  });
585
  messageInput.addEventListener('input', adjustTextareaHeight);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
586
  clearButton.addEventListener('click', () => {
587
  messagesContainer.innerHTML = '';
588
  chatHistory = [];
@@ -592,6 +599,11 @@
592
  const initialMessageId = 'msg-initial';
593
  messagesContainer.insertAdjacentHTML('beforeend', createBotMessage('', initialMessageId));
594
  typeText(initialMessageId, 'مرحباً! كيف يمكنني مساعدتك اليوم؟');
 
 
 
 
 
595
  </script>
596
  </body>
597
  </html>
 
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Speedy Chat</title>
7
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
8
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/themes/prism.min.css" rel="stylesheet">
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/prism.min.js"></script>
10
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/components/prism-python.min.js"></script>
11
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/components/prism-javascript.min.js"></script>
12
  <style>
13
  @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans+Arabic:wght@100;200;300;400;500;600;700&display=swap');
14
  @import url('https://fonts.googleapis.com/css2?family=Noto+Kufi+Arabic:wght@100;200;300;400;500;600;700;800;900&display=swap');
 
62
  background-color: #404040;
63
  }
64
 
65
+ .dark-mode .modal-content {
66
+ background-color: #2d2d2d;
67
+ color: #e5e5e5;
68
+ }
69
+
70
+ .dark-mode .modal-content textarea {
71
+ background-color: #363636;
72
+ color: #e5e5e5;
73
+ border-color: #404040;
74
+ }
75
+
76
  .welcome-text {
77
  font-family: 'Noto Kufi Arabic', sans-serif;
78
  font-size: 2rem;
 
125
  display: inline-flex;
126
  align-items: center;
127
  gap: 0.25rem;
128
+ font-size: 0.7rem;
129
  color: #6B7280;
130
  background-color: #F3F4F6;
131
  }
 
134
  background-color: #E5E7EB;
135
  }
136
 
137
+ .thinking-steps {
138
+ margin: 10px 0;
139
+ padding: 10px;
140
+ background-color: #f8f9fa;
141
+ border-radius: 8px;
142
+ font-size: 0.9em;
143
+ }
144
+
145
+ .thinking-steps div {
146
+ margin: 5px 0;
147
+ color: #666;
148
+ }
149
+
150
+ .modal {
151
+ display: none;
152
+ position: fixed;
153
+ top: 0;
154
+ left: 0;
155
+ right: 0;
156
+ bottom: 0;
157
+ background-color: rgba(0, 0, 0, 0.5);
158
+ z-index: 1000;
159
  justify-content: center;
160
+ align-items: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  }
162
 
163
+ .modal-content {
164
+ background-color: white;
165
+ padding: 2rem;
166
+ border-radius: 0.5rem;
167
+ max-width: 600px;
168
+ width: 90%;
169
+ max-height: 80vh;
170
+ overflow-y: auto;
171
  }
172
 
173
+ pre[class*="language-"] {
174
+ direction: ltr;
175
+ text-align: left;
176
+ margin: 1em 0;
177
  border-radius: 0.5rem;
178
+ padding: 1em;
 
 
 
179
  }
180
 
181
  .chat-input {
 
190
  }
191
  }
192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  .message-actions {
194
+ margin-top: 0.5rem;
195
  display: flex;
196
+ gap: 0.5rem;
197
  }
198
  </style>
199
  </head>
200
  <body class="text-lg light-mode">
 
201
  <header class="fixed top-0 left-0 right-0 bg-white border-b border-gray-100 z-50 shadow-sm">
202
  <div class="flex items-center px-4 py-2">
203
  <div class="flex items-center flex-1">
 
214
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"></path>
215
  </svg>
216
  </a>
 
 
 
 
 
217
  <button id="darkModeToggle" class="header-button">
218
  <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
219
  <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"></path>
 
235
  </div>
236
  </main>
237
 
238
+ <div id="editModal" class="modal">
239
+ <div class="modal-content">
240
+ <h2 class="text-xl font-bold mb-4">تعديل النص</h2>
241
+ <textarea id="editText" class="w-full h-40 p-2 border rounded-lg mb-4"></textarea>
242
+ <div class="flex justify-end gap-2">
243
+ <button id="cancelEdit" class="px-4 py-2 bg-gray-200 rounded-lg">إلغاء</button>
244
+ <button id="saveEdit" class="px-4 py-2 bg-black text-white rounded-lg">حفظ</button>
245
+ </div>
246
+ </div>
247
+ </div>
248
+
249
  <footer class="fixed bottom-0 left-0 right-0 bg-white shadow-sm">
250
  <div class="max-w-3xl mx-auto px-4 py-3">
251
+ <div class="relative bg-white rounded-xl border border-gray-200 p-2">
252
  <textarea
253
  id="messageInput"
254
  class="chat-input w-full text-gray-600 text-lg p-2 rounded-lg resize-none border-none"
 
256
  rows="1"
257
  ></textarea>
258
 
259
+ <div class="flex items-center justify-between mt-2">
260
  <div class="flex gap-3">
261
  <button class="text-gray-400 hover:text-gray-600" id="attachButton">
262
  <svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor">
 
268
  <path d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z"/>
269
  </svg>
270
  </a>
271
+ <button id="searchButton" class="text-gray-400 hover:text-gray-600">
272
  <svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor">
273
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
274
  </svg>
 
276
  </div>
277
 
278
  <div class="flex items-center gap-3">
279
+ <select id="styleSelect" class="style-select bg-gray-50 border border-gray-200 text-gray-600 text-sm rounded-lg pl-8 pr-2 py-2">
280
  <option value="short">⚡ ردود قصيرة</option>
281
  <option value="normal" selected>◯ عادي</option>
282
  <option value="long">↔ ردود مفصلة</option>
 
300
  </footer>
301
 
302
  <script>
303
+ const API_URL = 'https://975yry7ibyersz-7777.proxy.runpod.net/proxy/8000/chat';
304
  const messagesContainer = document.getElementById('messagesContainer');
305
  const messageInput = document.getElementById('messageInput');
306
  const sendButton = document.getElementById('sendMessage');
 
309
  const darkModeToggle = document.getElementById('darkModeToggle');
310
  const aiToggle = document.getElementById('aiToggle');
311
  const searchButton = document.getElementById('searchButton');
312
+ const editModal = document.getElementById('editModal');
313
+ const editText = document.getElementById('editText');
314
+ const saveEdit = document.getElementById('saveEdit');
315
+ const cancelEdit = document.getElementById('cancelEdit');
316
+
317
  let chatHistory = [];
318
  let currentStyle = 'normal';
319
  let currentController = null;
320
  let isSearchEnabled = false;
321
+ let currentEditMessageId = null;
322
 
323
+ function formatCode(text) {
324
+ const codeBlockRegex = /```(\w+)?\n([\s\S]*?)```/g;
325
+ return text.replace(codeBlockRegex, (match, lang, code) => {
326
+ const language = lang || 'plaintext';
327
+ return `<pre><code class="language-${language}">${code.trim()}</code></pre>`;
328
+ });
329
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
330
 
331
  function createThinkingSteps(messageId) {
332
  return `
 
339
  }
340
 
341
  function createUserMessage(text) {
 
 
 
 
 
 
 
342
  return `
343
  <div class="message flex justify-end mb-4">
344
  <div class="max-w-[80%]">
 
354
  return `
355
  <div class="message flex justify-start mb-4">
356
  <div class="flex-shrink-0 mt-1">
357
+ <img src="https://ufastpro.com/wp-content/uploads/2024/12/3.png" alt="Bot Avatar" class="w-8 h-8 rounded-full">
358
  </div>
359
  <div class="max-w-[80%] mr-3">
360
  <div class="bot-message bg-white rounded-lg p-3 shadow-sm">
 
362
  <div class="message-actions">
363
  <button class="action-button copy-button" data-message-id="${messageId}">
364
  <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
365
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2"></path>
366
  </svg>
367
  نسخ
368
  </button>
369
+ <button class="action-button speak-button" data-message-id="${messageId}">
 
 
 
 
 
 
370
  <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
371
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z"></path>
372
  </svg>
373
+ قراءة
374
  </button>
375
+ <button class="action-button edit-button" data-message-id="${messageId}">
376
  <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
377
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
378
  </svg>
379
+ تعديل
380
  </button>
381
  </div>
382
  </div>
 
387
 
388
  async function typeText(elementId, text) {
389
  const element = document.getElementById(elementId);
390
+ element.innerHTML = formatCode(text);
391
+ Prism.highlightAllUnder(element);
392
+ }
393
+
394
+ function speakText(text) {
395
+ const utterance = new SpeechSynthesisUtterance(text);
396
+ utterance.lang = 'ar';
397
+ speechSynthesis.speak(utterance);
398
+ }
399
+
400
+ function openEditModal(messageId) {
401
+ const messageElement = document.getElementById(messageId);
402
+ editText.value = messageElement.textContent;
403
+ editModal.style.display = 'flex';
404
+ currentEditMessageId = messageId;
405
+ }
406
+
407
+ function closeEditModal() {
408
+ editModal.style.display = 'none';
409
+ currentEditMessageId = null;
410
  }
411
 
412
  function toggleSendButton(isGenerating) {
 
531
  setTimeout(() => {
532
  button.innerHTML = `
533
  <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
534
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2"></path>
535
  </svg>
536
  نسخ
537
  `;
538
  }, 2000);
539
  }
540
 
541
+ if (e.target.closest('.speak-button')) {
542
+ const messageId = e.target.closest('.speak-button').dataset.messageId;
543
+ const text = document.getElementById(messageId).textContent;
544
+ speakText(text);
 
 
 
 
 
 
 
545
  }
546
 
547
+ if (e.target.closest('.edit-button')) {
548
+ const messageId = e.target.closest('.edit-button').dataset.messageId;
549
+ openEditModal(messageId);
550
  }
551
  });
552
 
553
+ // Event listeners for buttons and inputs
554
  sendButton.addEventListener('click', sendMessage);
555
  messageInput.addEventListener('keypress', (e) => {
556
  if (e.key === 'Enter' && !e.shiftKey) {
 
559
  }
560
  });
561
  messageInput.addEventListener('input', adjustTextareaHeight);
562
+
563
+ saveEdit.addEventListener('click', () => {
564
+ if (currentEditMessageId) {
565
+ const messageElement = document.getElementById(currentEditMessageId);
566
+ messageElement.innerHTML = formatCode(editText.value);
567
+ Prism.highlightAllUnder(messageElement);
568
+ }
569
+ closeEditModal();
570
+ });
571
+
572
+ cancelEdit.addEventListener('click', closeEditModal);
573
+
574
+ searchButton.addEventListener('click', () => {
575
+ isSearchEnabled = !isSearchEnabled;
576
+ searchButton.classList.toggle('active');
577
+ messageInput.placeholder = isSearchEnabled ? "ابحث عن..." : "اكتب رسالتك هنا...";
578
+ });
579
+
580
+ darkModeToggle.addEventListener('click', () => {
581
+ document.body.classList.toggle('dark-mode');
582
+ document.body.classList.toggle('light-mode');
583
+ });
584
+
585
+ aiToggle.addEventListener('click', function() {
586
+ this.classList.toggle('active');
587
+ });
588
+
589
+ styleSelect.addEventListener('change', (e) => {
590
+ currentStyle = e.target.value;
591
+ });
592
+
593
  clearButton.addEventListener('click', () => {
594
  messagesContainer.innerHTML = '';
595
  chatHistory = [];
 
599
  const initialMessageId = 'msg-initial';
600
  messagesContainer.insertAdjacentHTML('beforeend', createBotMessage('', initialMessageId));
601
  typeText(initialMessageId, 'مرحباً! كيف يمكنني مساعدتك اليوم؟');
602
+
603
+ // Initialize Prism.js
604
+ document.addEventListener('DOMContentLoaded', () => {
605
+ Prism.highlightAll();
606
+ });
607
  </script>
608
  </body>
609
  </html>