From c861fcc763116e1662da7ba50093bb12c61357e4 Mon Sep 17 00:00:00 2001 From: grendervill Date: Tue, 1 Sep 2026 20:39:34 +0300 Subject: [PATCH] =?UTF-8?q?=D0=91=D0=BB=D0=BE=D0=BA=D0=B8=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=B4=D0=B0=20=D0=BA=D0=B0=D0=BA=20=D0=B2=20Telegram=20(=D1=81?= =?UTF-8?q?=D0=BA=D1=80=D0=B8=D0=BD):=20=D1=82=D1=91=D0=BC=D0=BD=D0=BE-?= =?UTF-8?q?=D1=81=D0=B8=D0=BD=D0=B8=D0=B9=20=D0=BF=D1=83=D0=B7=D1=8B=D1=80?= =?UTF-8?q?=D1=8C=20#3b5a7a,=20=D0=B2=D1=80=D0=B5=D0=BC=D1=8F=20=D0=B8=20?= =?UTF-8?q?=D0=B3=D0=B0=D0=BB=D0=BE=D1=87=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Bubble: background #3b5a7a (как на скрине #2e4d6a), radius 12, padding 10/14/6, max-width 88%, shadow, язык uppercase #8a9ba8 10px слева, кнопка 📋 справа (rgba 0.15, radius 12, border 0.2) - Код: контейнер rgba(0,0,0,0.18) radius 8, padding 10/12, JetBrains Mono 13px/1.45/tab-size 4, color #fff, подсветка форсирована тёмной темой (highlight(...,true) -> Breeze Dark) - Время: QTime::currentTime hh:mm + ✓✓ #5eb1f6 внизу справа, как в сообщении ТГ (20:31 ✓✓) - Сохранено автовыравнивание/скобки/отступы из предыдущего коммита (Tab 4 пробела, Enter сохраняет indent, Backspace удаляет 4, авто-закрытие ()[]{}''""<> и ) --- src/markdown/MdParser.cpp | 65 ++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/src/markdown/MdParser.cpp b/src/markdown/MdParser.cpp index b1974d6..a2dba20 100644 --- a/src/markdown/MdParser.cpp +++ b/src/markdown/MdParser.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include using KSyntaxHighlighting::AbstractHighlighter; @@ -194,7 +195,7 @@ public: m_segments.append(seg); } - QString highlight(const QString &code, const QString &lang) + QString highlight(const QString &code, const QString &lang, bool forceDark = false) { m_segments.clear(); Definition def = m_repo->definitionForName(lang); @@ -203,10 +204,11 @@ public: setDefinition(def); // Выбираем тему подсветки в зависимости от темы приложения (тёмная/светлая) Theme chosen = m_repo->defaultTheme(); - // Попытка получить тему из настроек (ui/theme) + // Попытка получить тему из настроек (ui/theme) или форсировать тёмную для пузырей { QSettings s; - if (s.value("ui/theme").toString() == "dark") { + bool wantDark = forceDark || s.value("ui/theme").toString() == "dark"; + if (wantDark) { for (auto t : m_repo->themes()) { if (t.name().contains("dark", Qt::CaseInsensitive) || t.name().contains("Dark")) { chosen = t; @@ -476,47 +478,46 @@ private: const char *info = cmark_node_get_fence_info(n); const QString lang = normalizeLang(QString::fromUtf8(info ? info : "")); const QString code = QString::fromUtf8(cmark_node_get_literal(n)); - CodeHighlighter hl(m_repo); - const QString highlighted = hl.highlight(code, lang); - - // сохраняем оригинал для копирования + // Telegram-стиль как на скрине: тёмно-синий пузырь (#2e4d6a) с кодом, время и галочки внизу справа + // Сохраняем оригинал для копирования QString codeId; if (m_impl) { codeId = QStringLiteral("code_%1").arg(m_impl->codeCounter++); m_impl->codeBlocks.insert(codeId, code); } - - // Telegram-стиль: пузырь сообщения с кодом, как в мессенджере - QSettings s; - const bool isDark = s.value("ui/theme").toString() == "dark"; - // Telegram-like цвета: светлая — #f5f5f7, тёмная — #1a1a1a / #212121 - const QString bg = isDark ? "#212121" : "#f5f5f7"; - const QString headerBg = isDark ? "#2a2a2a" : "#e8e8ea"; - const QString headerBorder = isDark ? "#333333" : "#d0d0d0"; - const QString headerText = isDark ? "#8e8e93" : "#6d6d72"; - const QString codeTextColor = isDark ? "#e0e0e0" : "#24292f"; + // Форсируем тёмную тему подсветки для контраста на синем фоне Telegram-пузыря + CodeHighlighter hl(m_repo); + const QString highlighted = hl.highlight(code, lang, true); + // Переопределяем lang после highlight (highlight уже сделал) const QString langDisplay = lang.isEmpty() ? "text" : esc(lang); const QString cls = lang.isEmpty() ? QString() : QStringLiteral(" class=\"language-%1\"").arg(esc(lang)); - // Кнопка копирования - Telegram стиль: маленькая, с hover/active - const QString copyBtnStyle = isDark - ? "display:inline-block;background:#333333;color:#8e8e93;text-decoration:none;font-size:12px;padding:4px 10px;border-radius:6px;border:1px solid #404040;font-family: -apple-system, sans-serif;" - : "display:inline-block;background:#ffffff;color:#0088cc;text-decoration:none;font-size:12px;padding:4px 10px;border-radius:6px;border:1px solid #d0d0d0;font-family: -apple-system, sans-serif;"; - const QString copyLink = codeId.isEmpty() ? QString() - : QStringLiteral("📋 Копировать").arg(codeId, copyBtnStyle); - // Пузырь как в Telegram: скругления 12px, тень, граница, header отделен + // Время как в Telegram — текущее время рендера (можно заменить на lastModified) + const QString timeStr = QTime::currentTime().toString("hh:mm"); + // Telegram bubble: #3a5068 или #2e4d6a, скругления 12, тень, max-width 85% + const QString bubbleBg = "#3b5a7a"; // тёмно-синий как на скрине #2e4d6a → #3b5a7a чуть светлее + const QString codeColor = "#ffffff"; + // Кнопка копирования — в правом верхнем углу пузыря, как в ТГ при наведении + // Делаем её заметной: полупрозрачная, скруглённая, с hover/active через CSS + const QString copyLink = codeId.isEmpty() ? QString() + : QStringLiteral("📋").arg(codeId); + + // Пузырь Telegram: используем таблицу для совместимости с QTextDocument (не поддерживает position:absolute) + // Верхняя строка — язык слева и кнопка справа, средняя — код, нижняя — время и галочки справа return QStringLiteral( - "
" - "
" - "" - "" - "" + "
" + "
%5%6
" + "" + "" + "" "
%2%3
" + "
" + "
"
+            "%5
" "
" - "
"
-            "%8
" + "
%7 ✓✓
" "
" - ).arg(bg, headerBorder, headerBg, headerText, langDisplay, copyLink, codeTextColor, highlighted, cls); + ).arg(bubbleBg, langDisplay, copyLink, codeColor, highlighted, cls, timeStr); } QString inlineAll(cmark_node *n)