Opera10 commited on
Commit
e42fc72
·
verified ·
1 Parent(s): d51ea3e

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +41 -67
templates/index.html CHANGED
@@ -384,7 +384,7 @@
384
 
385
  .input-wrapper {
386
  display: flex; align-items: flex-end; background-color: #ffffff;
387
- border: 1.5px solid #e8e8e8; border-radius: 22px; padding: 6px 6px 6px 16px;
388
  box-shadow: 0 8px 25px rgba(0,0,0,0.06); transition: border-color 0.3s ease, background 0.3s;
389
  }
390
  .input-wrapper:focus-within { border-color: #c0caff; }
@@ -392,18 +392,20 @@
392
  .attach-btn {
393
  background: none; border: none; padding: 6px; color: #666; cursor: pointer;
394
  display: flex; align-items: center; justify-content: center; transition: all 0.2s;
395
- margin-bottom: 4px;
396
  }
397
  .attach-btn:hover { color: #5a67d8; }
398
 
 
399
  .input-wrapper textarea {
400
  flex-grow: 1; border: none; background: transparent; outline: none;
401
- font-size: 15px; padding: 10px 5px; font-family: inherit; color: #333; transition: color 0.3s;
402
  resize: none;
403
- height: 24px;
404
- max-height: 140px; /* محدوده ارتفاعی برابر با حدود ۶ تا ۷ خط */
405
  line-height: 1.5;
406
  overflow-y: auto;
 
407
  }
408
  .input-wrapper textarea::placeholder { color: #bbb; }
409
 
@@ -413,6 +415,7 @@
413
  display: flex; align-items: center; justify-content: center;
414
  cursor: pointer; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
415
  margin-bottom: 2px;
 
416
  }
417
  .send-btn:hover { background-color: #111; }
418
  .send-btn:active { transform: scale(0.85); }
@@ -634,6 +637,7 @@
634
  </svg>
635
  </button>
636
 
 
637
  <textarea id="textInput" placeholder="پیام خودتو اینجا بنویس..." autocomplete="off" rows="1"></textarea>
638
 
639
  <button type="button" class="send-btn" id="sendBtn">
@@ -908,12 +912,12 @@
908
  }
909
 
910
  function fallbackCopy() {
911
- const textArea = document.createElement("textarea");
912
- textArea.value = textToCopy;
913
- document.body.appendChild(textArea);
914
- textArea.select();
915
  try { document.execCommand('copy'); showSuccess(); } catch(e) {}
916
- textArea.remove();
917
  }
918
  }
919
  /* ---------------------------------------------------- */
@@ -1016,21 +1020,21 @@
1016
  fallbackCopy();
1017
  }
1018
  function fallbackCopy() {
1019
- const textArea = document.createElement("textarea");
1020
- textArea.value = textToCopy;
1021
- textArea.style.position = "fixed";
1022
- textArea.style.left = "-999999px";
1023
- textArea.style.top = "-999999px";
1024
- document.body.appendChild(textArea);
1025
- textArea.focus();
1026
- textArea.select();
1027
  try {
1028
  document.execCommand('copy');
1029
  showCopiedSuccess();
1030
  } catch (err) {
1031
  console.error('Copy failed', err);
1032
  }
1033
- textArea.remove();
1034
  }
1035
  }
1036
 
@@ -1400,38 +1404,18 @@
1400
  }
1401
  // -----------------------
1402
 
1403
- function confirmDeleteSession() {
1404
- if (!sessionToDelete) return;
1405
- const tx = db.transaction(['sessions', 'messages'], 'readwrite');
1406
- tx.objectStore('sessions').delete(sessionToDelete);
1407
- const msgStore = tx.objectStore('messages');
1408
- const index = msgStore.index('sessionId');
1409
- const request = index.openCursor(IDBKeyRange.only(sessionToDelete));
1410
- request.onsuccess = (e) => {
1411
- const cursor = e.target.result;
1412
- if (cursor) {
1413
- cursor.delete();
1414
- cursor.continue();
1415
- }
1416
- };
1417
- tx.oncomplete = () => {
1418
- closeAllModals();
1419
- if (modelActiveSession.gpt5 === sessionToDelete) modelActiveSession.gpt5 = null;
1420
- if (modelActiveSession.audio === sessionToDelete) modelActiveSession.audio = null;
1421
-
1422
- if (currentSessionId === sessionToDelete) {
1423
- startNewSession();
1424
- } else {
1425
- loadSessionsToMenu();
1426
- }
1427
- };
1428
- }
1429
-
1430
  const chatArea = document.getElementById('chatArea');
1431
  const textInput = document.getElementById('textInput');
1432
  const sendBtn = document.getElementById('sendBtn');
1433
  const statusBar = document.getElementById('statusBar');
1434
 
 
 
 
 
 
 
 
1435
  function toggleSidebar() {
1436
  document.getElementById('sidebar').classList.toggle('open');
1437
  document.getElementById('overlay').classList.toggle('visible');
@@ -1619,11 +1603,11 @@
1619
 
1620
  /* --- منطق جدید برای ساخت فایل (مقاله) بصورت استریم مشابه عکس --- */
1621
  async function proceedToCreateFile(topic) {
1622
- const msgTimestamp = Date.now();
1623
- appendUserMessageUI(topic, false, null, msgTimestamp);
1624
- await saveMessage('user', topic, null, null, msgTimestamp);
1625
-
1626
- isGenerating = true;
1627
  sendBtn.innerHTML = `<svg viewBox="0 0 24 24"><rect x="7" y="7" width="10" height="10" fill="white" stroke="none" rx="2" ry="2"/></svg>`;
1628
  sendBtn.style.backgroundColor = "#5a67d8";
1629
  statusBar.textContent = "در حال ایجاد مقاله...";
@@ -1636,7 +1620,7 @@
1636
  const pdfCardContainerId = 'pdf-container-' + cardId;
1637
  const wordCardContainerId = 'word-container-' + cardId;
1638
 
1639
- // قالب کارت مقاله (کادر اول فقط حاوی متن تایپ شده و کادرهای دانلود پس از اتمام زیر آن ظاهر می‌شوند)
1640
  currentBotRow.innerHTML = `
1641
  <div style="display:flex; flex-direction:column; gap:12px; width:100%; max-width:320px;">
1642
  <!-- کادر اول: فقط متن مقاله‌ تایپ شده بدون دکمه‌های دانلود -->
@@ -1680,7 +1664,7 @@
1680
  const reader = response.body.getReader();
1681
  const decoder = new TextDecoder("utf-8");
1682
  let isFirstChunk = true;
1683
- let buffer = ""; // بافر کمکی برای جلوگیری از شکستگی کاراکترها و فرمت JSON در استریمینگ
1684
 
1685
  while (true) {
1686
  const { done, value } = await reader.read();
@@ -1688,7 +1672,7 @@
1688
 
1689
  buffer += decoder.decode(value, { stream: true });
1690
  let lines = buffer.split('\n');
1691
- buffer = lines.pop(); // بخش ناقص آخر را در بافر نگه دار
1692
 
1693
  for (let line of lines) {
1694
  line = line.trim();
@@ -1709,7 +1693,6 @@
1709
  statusBar.textContent = data.content;
1710
  }
1711
  else if (data.type === 'done') {
1712
- // ظاهر شدن کادر فایل PDF هم‌اندازه با فایل Word بالای آن با دکمه دانلود در سمت راست (در حالت راست‌چین)
1713
  if(data.pdf_url) {
1714
  const pdfBox = document.getElementById(pdfCardContainerId);
1715
  pdfBox.innerHTML = `
@@ -1733,7 +1716,6 @@
1733
  `;
1734
  }
1735
 
1736
- // کادر سوم: نمایش کادر فایل Word بدون تکرار متن و با آیکون دانلود مجزا
1737
  if(data.docx_url) {
1738
  const wordBox = document.getElementById(wordCardContainerId);
1739
  wordBox.innerHTML = `
@@ -1762,9 +1744,7 @@
1762
  else if (data.type === 'error') {
1763
  contentBox.innerHTML += `<br><span style="color:red;">خطا: ${data.message}</span>`;
1764
  }
1765
- } catch(e) {
1766
- console.error("خطا در پردازش سطر استریم:", e);
1767
- }
1768
  }
1769
  }
1770
  }
@@ -1935,7 +1915,7 @@
1935
  if (isFileCreationMode && text) {
1936
  isFileCreationMode = false; // خروج از حالت فایل پس از ا��سال
1937
  textInput.value = '';
1938
- textInput.style.height = 'auto'; // ریست کردن ارتفاع پس از ارسال
1939
  proceedToCreateFile(text);
1940
  return;
1941
  }
@@ -1952,7 +1932,7 @@
1952
  incrementUsage(hasImage);
1953
 
1954
  textInput.value = '';
1955
- textInput.style.height = 'auto'; // ریست کردن ارتفاع پس از ارسال
1956
  clearSelectedImage();
1957
 
1958
  if (!currentSessionId) {
@@ -1966,12 +1946,6 @@
1966
  }
1967
  });
1968
 
1969
- // تنظیم تغییر اندازه خودکار ارتفاع textarea با توجه به حجم متن ورودی
1970
- textInput.addEventListener('input', function() {
1971
- this.style.height = 'auto';
1972
- this.style.height = (this.scrollHeight) + 'px';
1973
- });
1974
-
1975
  window.onload = async () => {
1976
  document.getElementById('emptyState').style.display = 'block';
1977
 
 
384
 
385
  .input-wrapper {
386
  display: flex; align-items: flex-end; background-color: #ffffff;
387
+ border: 1.5px solid #e8e8e8; border-radius: 24px; padding: 6px 6px 6px 16px;
388
  box-shadow: 0 8px 25px rgba(0,0,0,0.06); transition: border-color 0.3s ease, background 0.3s;
389
  }
390
  .input-wrapper:focus-within { border-color: #c0caff; }
 
392
  .attach-btn {
393
  background: none; border: none; padding: 6px; color: #666; cursor: pointer;
394
  display: flex; align-items: center; justify-content: center; transition: all 0.2s;
395
+ margin-bottom: 6px;
396
  }
397
  .attach-btn:hover { color: #5a67d8; }
398
 
399
+ /* استایل بهینه‌سازی‌شده برای کادر متنی چندخطی */
400
  .input-wrapper textarea {
401
  flex-grow: 1; border: none; background: transparent; outline: none;
402
+ font-size: 15px; padding: 12px 5px; font-family: inherit; color: #333; transition: color 0.3s;
403
  resize: none;
404
+ height: 44px;
405
+ max-height: 140px; /* حداکثر اندازه برای ۶ الی ۷ خط */
406
  line-height: 1.5;
407
  overflow-y: auto;
408
+ box-sizing: border-box;
409
  }
410
  .input-wrapper textarea::placeholder { color: #bbb; }
411
 
 
415
  display: flex; align-items: center; justify-content: center;
416
  cursor: pointer; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
417
  margin-bottom: 2px;
418
+ flex-shrink: 0;
419
  }
420
  .send-btn:hover { background-color: #111; }
421
  .send-btn:active { transform: scale(0.85); }
 
637
  </svg>
638
  </button>
639
 
640
+ <!-- کادر ورودی به textarea تغییر یافت -->
641
  <textarea id="textInput" placeholder="پیام خودتو اینجا بنویس..." autocomplete="off" rows="1"></textarea>
642
 
643
  <button type="button" class="send-btn" id="sendBtn">
 
912
  }
913
 
914
  function fallbackCopy() {
915
+ const textarea = document.createElement("textarea");
916
+ textarea.value = textToCopy;
917
+ document.body.appendChild(textarea);
918
+ textarea.select();
919
  try { document.execCommand('copy'); showSuccess(); } catch(e) {}
920
+ textarea.remove();
921
  }
922
  }
923
  /* ---------------------------------------------------- */
 
1020
  fallbackCopy();
1021
  }
1022
  function fallbackCopy() {
1023
+ const textarea = document.createElement("textarea");
1024
+ textarea.value = textToCopy;
1025
+ textarea.style.position = "fixed";
1026
+ textarea.style.left = "-999999px";
1027
+ textarea.style.top = "-999999px";
1028
+ document.body.appendChild(textarea);
1029
+ textarea.focus();
1030
+ textarea.select();
1031
  try {
1032
  document.execCommand('copy');
1033
  showCopiedSuccess();
1034
  } catch (err) {
1035
  console.error('Copy failed', err);
1036
  }
1037
+ textarea.remove();
1038
  }
1039
  }
1040
 
 
1404
  }
1405
  // -----------------------
1406
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1407
  const chatArea = document.getElementById('chatArea');
1408
  const textInput = document.getElementById('textInput');
1409
  const sendBtn = document.getElementById('sendBtn');
1410
  const statusBar = document.getElementById('statusBar');
1411
 
1412
+ // منطق تنظیم ارتفاع خودکار و بهینه کادر متنی
1413
+ function adjustTextInputHeight() {
1414
+ textInput.style.height = 'auto';
1415
+ textInput.style.height = textInput.scrollHeight + 'px';
1416
+ }
1417
+ textInput.addEventListener('input', adjustTextInputHeight);
1418
+
1419
  function toggleSidebar() {
1420
  document.getElementById('sidebar').classList.toggle('open');
1421
  document.getElementById('overlay').classList.toggle('visible');
 
1603
 
1604
  /* --- منطق جدید برای ساخت فایل (مقاله) بصورت استریم مشابه عکس --- */
1605
  async function proceedToCreateFile(topic) {
1606
+ const msgTimestamp = Date.now();
1607
+ appendUserMessageUI(topic, false, null, msgTimestamp);
1608
+ await saveMessage('user', topic, null, null, msgTimestamp);
1609
+
1610
+ isGenerating = true;
1611
  sendBtn.innerHTML = `<svg viewBox="0 0 24 24"><rect x="7" y="7" width="10" height="10" fill="white" stroke="none" rx="2" ry="2"/></svg>`;
1612
  sendBtn.style.backgroundColor = "#5a67d8";
1613
  statusBar.textContent = "در حال ایجاد مقاله...";
 
1620
  const pdfCardContainerId = 'pdf-container-' + cardId;
1621
  const wordCardContainerId = 'word-container-' + cardId;
1622
 
1623
+ // قالب کارت مقاله
1624
  currentBotRow.innerHTML = `
1625
  <div style="display:flex; flex-direction:column; gap:12px; width:100%; max-width:320px;">
1626
  <!-- کادر اول: فقط متن مقاله‌ تایپ شده بدون دکمه‌های دانلود -->
 
1664
  const reader = response.body.getReader();
1665
  const decoder = new TextDecoder("utf-8");
1666
  let isFirstChunk = true;
1667
+ let buffer = "";
1668
 
1669
  while (true) {
1670
  const { done, value } = await reader.read();
 
1672
 
1673
  buffer += decoder.decode(value, { stream: true });
1674
  let lines = buffer.split('\n');
1675
+ buffer = lines.pop();
1676
 
1677
  for (let line of lines) {
1678
  line = line.trim();
 
1693
  statusBar.textContent = data.content;
1694
  }
1695
  else if (data.type === 'done') {
 
1696
  if(data.pdf_url) {
1697
  const pdfBox = document.getElementById(pdfCardContainerId);
1698
  pdfBox.innerHTML = `
 
1716
  `;
1717
  }
1718
 
 
1719
  if(data.docx_url) {
1720
  const wordBox = document.getElementById(wordCardContainerId);
1721
  wordBox.innerHTML = `
 
1744
  else if (data.type === 'error') {
1745
  contentBox.innerHTML += `<br><span style="color:red;">خطا: ${data.message}</span>`;
1746
  }
1747
+ } catch(e) {}
 
 
1748
  }
1749
  }
1750
  }
 
1915
  if (isFileCreationMode && text) {
1916
  isFileCreationMode = false; // خروج از حالت فایل پس از ا��سال
1917
  textInput.value = '';
1918
+ textInput.style.height = 'auto'; // ریست کردن ارتفاع کادر
1919
  proceedToCreateFile(text);
1920
  return;
1921
  }
 
1932
  incrementUsage(hasImage);
1933
 
1934
  textInput.value = '';
1935
+ textInput.style.height = 'auto'; // ریست کردن ارتفاع کادر ورودی پس از ارسال پیام
1936
  clearSelectedImage();
1937
 
1938
  if (!currentSessionId) {
 
1946
  }
1947
  });
1948
 
 
 
 
 
 
 
1949
  window.onload = async () => {
1950
  document.getElementById('emptyState').style.display = 'block';
1951