Update index.html
Browse files- index.html +38 -12
index.html
CHANGED
|
@@ -5,11 +5,12 @@
|
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 6 |
<title>Genisi AI - ู
ุณุงุนุฏู ุงูุฐูู</title>
|
| 7 |
|
| 8 |
-
<!-- ๐ Lucide Icons -
|
| 9 |
<script src="https://unpkg.com/lucide@latest"></script>
|
| 10 |
|
| 11 |
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"/>
|
| 12 |
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
|
|
| 13 |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css"/>
|
| 14 |
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js"></script>
|
| 15 |
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/contrib/auto-render.min.js"></script>
|
|
@@ -46,7 +47,7 @@
|
|
| 46 |
|
| 47 |
.app{display:flex;height:100vh;overflow:hidden}
|
| 48 |
|
| 49 |
-
/* SIDEBAR
|
| 50 |
.sidebar{width:var(--sidebar-w);min-width:var(--sidebar-w);background:var(--surface);
|
| 51 |
border-right:1px solid var(--border);display:flex;flex-direction:column;
|
| 52 |
transition:width var(--tr),min-width var(--tr);overflow:hidden;
|
|
@@ -141,7 +142,7 @@
|
|
| 141 |
.msg-row.bot .bubble{background:transparent;border:none;padding:8px 4px;box-shadow:none;}
|
| 142 |
.msg-row.user .bubble{background:var(--user-bubble);border:none;}
|
| 143 |
|
| 144 |
-
/*
|
| 145 |
.thinking-container {
|
| 146 |
margin: 16px 0;
|
| 147 |
padding: 16px 18px;
|
|
@@ -322,7 +323,7 @@
|
|
| 322 |
<body>
|
| 323 |
<div class="app">
|
| 324 |
|
| 325 |
-
<!-- SIDEBAR -
|
| 326 |
<aside class="sidebar collapsed" id="sidebar">
|
| 327 |
<div class="sidebar-header">
|
| 328 |
<div class="s-logo">
|
|
@@ -439,7 +440,7 @@
|
|
| 439 |
|
| 440 |
<script>
|
| 441 |
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 442 |
-
// ๐ GENISI AI -
|
| 443 |
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 444 |
|
| 445 |
// i18n
|
|
@@ -510,6 +511,25 @@ const getChat = (id) => chats.find(c => c.id === (id ?? activeChatId));
|
|
| 510 |
const esc = (t) => String(t).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
| 511 |
const scrollToBottom = () => { const area = document.getElementById('chat-area'); area.scrollTop = area.scrollHeight; };
|
| 512 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 513 |
// Copy code
|
| 514 |
window.copyCode = function(btn, encodedCode) {
|
| 515 |
navigator.clipboard.writeText(decodeURIComponent(encodedCode)).then(() => {
|
|
@@ -670,6 +690,8 @@ function loadChat(id) {
|
|
| 670 |
});
|
| 671 |
scrollToBottom();
|
| 672 |
renderChatList();
|
|
|
|
|
|
|
| 673 |
}
|
| 674 |
|
| 675 |
function deleteChat(id, e) {
|
|
@@ -695,7 +717,6 @@ async function sendMessage() {
|
|
| 695 |
let text = input.value.trim();
|
| 696 |
if (!text && pendingFiles.length === 0) return;
|
| 697 |
|
| 698 |
-
// ุฅุฎูุงุก ุดุงุดุฉ ุงูุชุฑุญูุจ
|
| 699 |
const welcome = document.getElementById('welcome');
|
| 700 |
if (welcome) welcome.remove();
|
| 701 |
|
|
@@ -728,7 +749,6 @@ async function sendMessage() {
|
|
| 728 |
let thinkingContainer = null, thinkingContent = null, responseContainer = null;
|
| 729 |
let thinkingText = '', finalResponse = '', isThinkingPhase = currentModel === 'pro';
|
| 730 |
|
| 731 |
-
// ุฅุนุฏุงุฏ ุญุงููุฉ ุงูุชูููุฑ ููู
ูุฐุฌ Pro
|
| 732 |
if (currentModel === 'pro') {
|
| 733 |
const t = i18n[currentLang];
|
| 734 |
thinkingContainer = document.createElement('div');
|
|
@@ -790,18 +810,21 @@ async function sendMessage() {
|
|
| 790 |
finalResponse = fullResponse.substring(fullResponse.indexOf(" instant") + 8);
|
| 791 |
if (responseContainer) responseContainer.innerHTML = marked.parse(finalResponse) + '<span class="genisi-cursor"></span>';
|
| 792 |
}
|
|
|
|
|
|
|
|
|
|
| 793 |
} else {
|
| 794 |
botContentDiv.innerHTML = marked.parse(fullResponse) + '<span class="genisi-cursor"></span>';
|
|
|
|
|
|
|
| 795 |
}
|
| 796 |
|
| 797 |
lucide.createIcons();
|
| 798 |
scrollToBottom();
|
| 799 |
}
|
| 800 |
|
| 801 |
-
// ุฅุฒุงูุฉ ุงูู
ุคุดุฑ
|
| 802 |
document.querySelector('.genisi-cursor')?.remove();
|
| 803 |
|
| 804 |
-
// ุญูุธ ุงูู
ุญุงุฏุซุฉ
|
| 805 |
const historyEntry = {
|
| 806 |
user: text, bot: fullResponse, uiFiles,
|
| 807 |
thinking: currentModel === 'pro' ? thinkingText : null
|
|
@@ -819,6 +842,8 @@ async function sendMessage() {
|
|
| 819 |
botContentDiv.innerHTML = `<span style="color:var(--danger)"><i data-lucide="alert-circle"></i> ${i18n[currentLang].errConnect}: ${err.message}</span>`;
|
| 820 |
}
|
| 821 |
lucide.createIcons();
|
|
|
|
|
|
|
| 822 |
} finally {
|
| 823 |
isGenerating = false;
|
| 824 |
document.getElementById('send-btn').style.display = 'flex';
|
|
@@ -858,6 +883,10 @@ function appendBubble(role, text, isMarkdown, filesList = [], thinkingText = nul
|
|
| 858 |
bub.appendChild(contentDiv);
|
| 859 |
row.appendChild(av); row.appendChild(bub);
|
| 860 |
area.appendChild(row);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 861 |
scrollToBottom();
|
| 862 |
lucide.createIcons();
|
| 863 |
return contentDiv;
|
|
@@ -875,7 +904,6 @@ applyTheme(localStorage.getItem('genisi_theme') || 'dark');
|
|
| 875 |
document.getElementById('lang-select').value = currentLang;
|
| 876 |
applyI18n();
|
| 877 |
|
| 878 |
-
// ุชุญู
ูู ุงููู
ูุฐุฌ ุงูู
ุญููุธ
|
| 879 |
(function loadSavedModel() {
|
| 880 |
const toggleBtn = document.getElementById('model-toggle-btn');
|
| 881 |
const icon = document.getElementById('model-icon-input');
|
|
@@ -889,7 +917,6 @@ applyI18n();
|
|
| 889 |
|
| 890 |
lucide.createIcons();
|
| 891 |
|
| 892 |
-
// Close dropdown on outside click
|
| 893 |
document.addEventListener('click', (e) => {
|
| 894 |
const selector = document.querySelector('.model-selector-input');
|
| 895 |
const dropdown = document.getElementById('model-dropdown-input');
|
|
@@ -898,7 +925,6 @@ document.addEventListener('click', (e) => {
|
|
| 898 |
}
|
| 899 |
});
|
| 900 |
|
| 901 |
-
// Ensure sidebar is collapsed by default
|
| 902 |
document.getElementById('sidebar').classList.add('collapsed');
|
| 903 |
</script>
|
| 904 |
</body>
|
|
|
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 6 |
<title>Genisi AI - ู
ุณุงุนุฏู ุงูุฐูู</title>
|
| 7 |
|
| 8 |
+
<!-- ๐ Lucide Icons -->
|
| 9 |
<script src="https://unpkg.com/lucide@latest"></script>
|
| 10 |
|
| 11 |
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"/>
|
| 12 |
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
| 13 |
+
<!-- KaTeX CSS + JS -->
|
| 14 |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css"/>
|
| 15 |
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js"></script>
|
| 16 |
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/contrib/auto-render.min.js"></script>
|
|
|
|
| 47 |
|
| 48 |
.app{display:flex;height:100vh;overflow:hidden}
|
| 49 |
|
| 50 |
+
/* SIDEBAR */
|
| 51 |
.sidebar{width:var(--sidebar-w);min-width:var(--sidebar-w);background:var(--surface);
|
| 52 |
border-right:1px solid var(--border);display:flex;flex-direction:column;
|
| 53 |
transition:width var(--tr),min-width var(--tr);overflow:hidden;
|
|
|
|
| 142 |
.msg-row.bot .bubble{background:transparent;border:none;padding:8px 4px;box-shadow:none;}
|
| 143 |
.msg-row.user .bubble{background:var(--user-bubble);border:none;}
|
| 144 |
|
| 145 |
+
/* ุญุงููุฉ ุงูุชูููุฑ */
|
| 146 |
.thinking-container {
|
| 147 |
margin: 16px 0;
|
| 148 |
padding: 16px 18px;
|
|
|
|
| 323 |
<body>
|
| 324 |
<div class="app">
|
| 325 |
|
| 326 |
+
<!-- SIDEBAR -->
|
| 327 |
<aside class="sidebar collapsed" id="sidebar">
|
| 328 |
<div class="sidebar-header">
|
| 329 |
<div class="s-logo">
|
|
|
|
| 440 |
|
| 441 |
<script>
|
| 442 |
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 443 |
+
// ๐ GENISI AI - ู
ุน ุฏุนู
ุฏููุงู
ููู ูุงู
ู ูู KaTeX
|
| 444 |
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 445 |
|
| 446 |
// i18n
|
|
|
|
| 511 |
const esc = (t) => String(t).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
| 512 |
const scrollToBottom = () => { const area = document.getElementById('chat-area'); area.scrollTop = area.scrollHeight; };
|
| 513 |
|
| 514 |
+
// ๐๐๐ ุฏุงูุฉ ุชุตููุฑ KaTeX ูุฏููุงู (ุงูุชุญุณูู ุงูุฃุณุงุณู)
|
| 515 |
+
function renderMath(element) {
|
| 516 |
+
if (window.renderMathInElement) {
|
| 517 |
+
try {
|
| 518 |
+
renderMathInElement(element, {
|
| 519 |
+
delimiters: [
|
| 520 |
+
{left: '$$', right: '$$', display: true},
|
| 521 |
+
{left: '$', right: '$', display: false},
|
| 522 |
+
{left: '\\(', right: '\\)', display: false},
|
| 523 |
+
{left: '\\[', right: '\\]', display: true}
|
| 524 |
+
],
|
| 525 |
+
throwOnError: false
|
| 526 |
+
});
|
| 527 |
+
} catch (e) {
|
| 528 |
+
console.warn('KaTeX render error:', e);
|
| 529 |
+
}
|
| 530 |
+
}
|
| 531 |
+
}
|
| 532 |
+
|
| 533 |
// Copy code
|
| 534 |
window.copyCode = function(btn, encodedCode) {
|
| 535 |
navigator.clipboard.writeText(decodeURIComponent(encodedCode)).then(() => {
|
|
|
|
| 690 |
});
|
| 691 |
scrollToBottom();
|
| 692 |
renderChatList();
|
| 693 |
+
// ๐ข ุฅุนุงุฏุฉ ุชุตููุฑ ุงูุฑูุงุถูุงุช ุจุนุฏ ุชุญู
ูู ุงูู
ุญุงุฏุซุฉ
|
| 694 |
+
document.querySelectorAll('.bubble').forEach(bubble => renderMath(bubble));
|
| 695 |
}
|
| 696 |
|
| 697 |
function deleteChat(id, e) {
|
|
|
|
| 717 |
let text = input.value.trim();
|
| 718 |
if (!text && pendingFiles.length === 0) return;
|
| 719 |
|
|
|
|
| 720 |
const welcome = document.getElementById('welcome');
|
| 721 |
if (welcome) welcome.remove();
|
| 722 |
|
|
|
|
| 749 |
let thinkingContainer = null, thinkingContent = null, responseContainer = null;
|
| 750 |
let thinkingText = '', finalResponse = '', isThinkingPhase = currentModel === 'pro';
|
| 751 |
|
|
|
|
| 752 |
if (currentModel === 'pro') {
|
| 753 |
const t = i18n[currentLang];
|
| 754 |
thinkingContainer = document.createElement('div');
|
|
|
|
| 810 |
finalResponse = fullResponse.substring(fullResponse.indexOf(" instant") + 8);
|
| 811 |
if (responseContainer) responseContainer.innerHTML = marked.parse(finalResponse) + '<span class="genisi-cursor"></span>';
|
| 812 |
}
|
| 813 |
+
// ๐ข ุชุตููุฑ ุงูุฑูุงุถูุงุช ุฃุซูุงุก ุงูุชุฏูู
|
| 814 |
+
if (thinkingContainer) renderMath(thinkingContainer);
|
| 815 |
+
if (responseContainer) renderMath(responseContainer);
|
| 816 |
} else {
|
| 817 |
botContentDiv.innerHTML = marked.parse(fullResponse) + '<span class="genisi-cursor"></span>';
|
| 818 |
+
// ๐ข ุชุตููุฑ ุงูุฑูุงุถูุงุช ุฃุซูุงุก ุงูุชุฏูู
|
| 819 |
+
renderMath(botContentDiv);
|
| 820 |
}
|
| 821 |
|
| 822 |
lucide.createIcons();
|
| 823 |
scrollToBottom();
|
| 824 |
}
|
| 825 |
|
|
|
|
| 826 |
document.querySelector('.genisi-cursor')?.remove();
|
| 827 |
|
|
|
|
| 828 |
const historyEntry = {
|
| 829 |
user: text, bot: fullResponse, uiFiles,
|
| 830 |
thinking: currentModel === 'pro' ? thinkingText : null
|
|
|
|
| 842 |
botContentDiv.innerHTML = `<span style="color:var(--danger)"><i data-lucide="alert-circle"></i> ${i18n[currentLang].errConnect}: ${err.message}</span>`;
|
| 843 |
}
|
| 844 |
lucide.createIcons();
|
| 845 |
+
// ๐ข ุชุตููุฑ ุงูุฑูุงุถูุงุช ูู ุญุงูุฉ ุงูุฎุทุฃ
|
| 846 |
+
renderMath(botContentDiv);
|
| 847 |
} finally {
|
| 848 |
isGenerating = false;
|
| 849 |
document.getElementById('send-btn').style.display = 'flex';
|
|
|
|
| 883 |
bub.appendChild(contentDiv);
|
| 884 |
row.appendChild(av); row.appendChild(bub);
|
| 885 |
area.appendChild(row);
|
| 886 |
+
|
| 887 |
+
// ๐ข ุชุตููุฑ ุงูุฑูุงุถูุงุช ุจุนุฏ ุฅุถุงูุฉ ุงูููุงุนุฉ
|
| 888 |
+
renderMath(bub);
|
| 889 |
+
|
| 890 |
scrollToBottom();
|
| 891 |
lucide.createIcons();
|
| 892 |
return contentDiv;
|
|
|
|
| 904 |
document.getElementById('lang-select').value = currentLang;
|
| 905 |
applyI18n();
|
| 906 |
|
|
|
|
| 907 |
(function loadSavedModel() {
|
| 908 |
const toggleBtn = document.getElementById('model-toggle-btn');
|
| 909 |
const icon = document.getElementById('model-icon-input');
|
|
|
|
| 917 |
|
| 918 |
lucide.createIcons();
|
| 919 |
|
|
|
|
| 920 |
document.addEventListener('click', (e) => {
|
| 921 |
const selector = document.querySelector('.model-selector-input');
|
| 922 |
const dropdown = document.getElementById('model-dropdown-input');
|
|
|
|
| 925 |
}
|
| 926 |
});
|
| 927 |
|
|
|
|
| 928 |
document.getElementById('sidebar').classList.add('collapsed');
|
| 929 |
</script>
|
| 930 |
</body>
|