From 553665c61ed1799ba8d3bb22ba50e0023c0de7b2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?=
Date: Mon, 1 Jun 2026 22:56:11 +0300
Subject: [PATCH] =?UTF-8?q?feat:=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82?=
=?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=E2=80=94=20?=
=?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=BE=D1=81=D1=8B=20=D1=81=D1=82?=
=?UTF-8?q?=D1=80=D0=BE=D0=BA,=20=D0=B6=D0=B8=D1=80=D0=BD=D1=8B=D0=B9,=20?=
=?UTF-8?q?=D1=81=D0=BF=D0=B8=D1=81=D0=BA=D0=B8,=20=D1=86=D0=B2=D0=B5?=
=?UTF-8?q?=D1=82=D0=BD=D1=8B=D0=B5=20=D0=B1=D0=BB=D0=BE=D0=BA=D0=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
public/index.html | 35 +++++++++++++++++++++++++++++++----
public/style.css | 14 +++++++++++---
2 files changed, 42 insertions(+), 7 deletions(-)
diff --git a/public/index.html b/public/index.html
index 2761af5..ffe85ef 100644
--- a/public/index.html
+++ b/public/index.html
@@ -63,13 +63,40 @@
document.querySelectorAll('.hitem').forEach(el => {
el.onclick = () => {
const h = history[+el.dataset.idx];
- chat.innerHTML += '📋 ' + esc(h.q) + '
';
- chat.innerHTML += '🤖 ' + esc(h.a) + '
';
+ chat.innerHTML += '📋 ' + fmt(h.q) + '
';
+ chat.innerHTML += '🤖 ' + fmt(h.a) + '
';
chat.scrollTop = chat.scrollHeight;
};
});
}
function esc(s) { return String(s).replace(//g,'>'); }
+ function fmt(s) {
+ s = esc(s);
+ // Заменяем **жирный**
+ s = s.replace(/\*\*(.+?)\*\*/g, '$1');
+ // Заменяем `код`
+ s = s.replace(/`(.+?)`/g, '$1');
+ // Заменяем *курсив*
+ s = s.replace(/\*(.+?)\*/g, '$1');
+ // Горизонтальная линия ---
+ s = s.replace(/^---+/gm, '
');
+ // Заголовки ###
+ s = s.replace(/^### (.+)$/gm, '$1
');
+ s = s.replace(/^## (.+)$/gm, '$1
');
+ s = s.replace(/^# (.+)$/gm, '$1
');
+ // Маркированный список
+ s = s.replace(/^[•\-*] (.+)$/gm, '$1');
+ s = s.replace(/([\s\S]*?<\/li>)/g, '');
+ // Нумерованный список
+ s = s.replace(/^\d+\.\s+(.+)$/gm, '$1');
+ // Абзацы (двойной перенос строки)
+ s = s.replace(/\n\n+/g, '
');
+ // Одинарный перенос →
+ s = s.replace(/\n/g, '
');
+ // Убираем пустые
+ s = s.replace(/\s*<\/ul>/g, '');
+ return '' + s + '
';
+ }
renderHistory();
@@ -152,7 +179,7 @@
clearTimeout(to);
const tData = await tRes.json();
const text = tData.text || '(не распознано)';
- chat.innerHTML += '🗣 ' + esc(text) + '
';
+ chat.innerHTML += '🗣 ' + fmt(text) + '
';
chat.scrollTop = chat.scrollHeight;
startThinkTimer();
@@ -166,7 +193,7 @@
const cData = await cRes.json();
if (cData.sid) sessionSid = cData.sid;
const resp = cData.response || cData.error || 'Ошибка';
- chat.innerHTML += '🤖 ' + esc(resp) + '
';
+ chat.innerHTML += '🤖 ' + fmt(resp) + '
';
chat.scrollTop = chat.scrollHeight;
setStatus('✅ Готово — ' + ((Date.now() - thinkStart) / 1000).toFixed(1) + 'с');
diff --git a/public/style.css b/public/style.css
index 216408b..78b7db0 100644
--- a/public/style.css
+++ b/public/style.css
@@ -20,9 +20,17 @@ h1 { color: #7c6ff7; margin: 0 0 8px; font-size: 20px; }
#status { text-align: center; color: #888; font-size: 14px; min-height: 20px; margin: 6px 0; }
-#chat { border: 1px solid #2a2a3e; border-radius: 8px; padding: 12px; min-height: 200px; max-height: 340px; overflow-y: auto; background: #13132a; }
-.user { color: #00cec9; margin: 6px 0; word-break: break-word; font-size: 14px; }
-.bot { color: #a29bfe; margin: 6px 0 12px; word-break: break-word; font-size: 14px; }
+#chat { border: 1px solid #2a2a3e; border-radius: 8px; padding: 14px; min-height: 200px; max-height: 340px; overflow-y: auto; background: #13132a; line-height: 1.6; }
+.user { background: #0d2d2d; border-left: 3px solid #00cec9; padding: 8px 12px; margin: 8px 0; border-radius: 0 6px 6px 0; color: #00cec9; font-size: 14px; }
+.user p { margin: 0; }
+.bot { background: #1a1a3e; border-left: 3px solid #a29bfe; padding: 10px 14px; margin: 8px 0 16px; border-radius: 0 6px 6px 0; color: #d0d0f0; font-size: 14px; }
+.bot p { margin: 4px 0; }
+.bot h1, .bot h2, .bot h3 { color: #7c6ff7; margin: 8px 0 4px; font-size: 15px; }
+.bot b { color: #fff; }
+.bot code { background: #2a2a4e; padding: 1px 5px; border-radius: 3px; font-size: 13px; color: #f8c291; }
+.bot ul, .bot ol { margin: 4px 0; padding-left: 20px; }
+.bot li { margin: 2px 0; }
+.bot hr { border: none; border-top: 1px solid #2a2a3e; margin: 10px 0; }
#sidebar { width: 280px; background: #111122; border-left: 1px solid #2a2a3e; padding: 14px; overflow-y: auto; }
#history-title { color: #7c6ff7; font-weight: bold; margin-bottom: 10px; font-size: 15px; }