Spaces:
Paused
Paused
Update templates/index.html
Browse files- 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:
|
| 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:
|
| 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:
|
| 402 |
resize: none;
|
| 403 |
-
height:
|
| 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
|
| 912 |
-
|
| 913 |
-
document.body.appendChild(
|
| 914 |
-
|
| 915 |
try { document.execCommand('copy'); showSuccess(); } catch(e) {}
|
| 916 |
-
|
| 917 |
}
|
| 918 |
}
|
| 919 |
/* ---------------------------------------------------- */
|
|
@@ -1016,21 +1020,21 @@
|
|
| 1016 |
fallbackCopy();
|
| 1017 |
}
|
| 1018 |
function fallbackCopy() {
|
| 1019 |
-
const
|
| 1020 |
-
|
| 1021 |
-
|
| 1022 |
-
|
| 1023 |
-
|
| 1024 |
-
document.body.appendChild(
|
| 1025 |
-
|
| 1026 |
-
|
| 1027 |
try {
|
| 1028 |
document.execCommand('copy');
|
| 1029 |
showCopiedSuccess();
|
| 1030 |
} catch (err) {
|
| 1031 |
console.error('Copy failed', err);
|
| 1032 |
}
|
| 1033 |
-
|
| 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 |
-
|
| 1623 |
-
|
| 1624 |
-
|
| 1625 |
-
|
| 1626 |
-
|
| 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 = "";
|
| 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 |
|