Пузырь ~sql как у кода: фикс невалидного CSS, разделители строк

- Удалены max-width:88%%/box-shadow: невалидный %% гасил весь
  style в Qt rich text (пузырь не красился); заодно в кодоблоке
- Таблица без width=100% (вылезала за панель), td вместо th
  (чёрная плашка заголовка), border-top разделители,
  zero-width space в путях для переносов
This commit is contained in:
2026-09-07 17:20:11 +03:00
parent 51372ace4e
commit e304f503e5
+20 -7
View File
@@ -459,6 +459,16 @@ QString vaultFileForCell(Database *db, const QString &cell)
return QString();
}
// Путь для показа: вставляем zero-width space после '/' — движок rich text
// умеет переносить только по пробелам, длинные пути иначе рвут пузырь.
// На href/копирование не влияет (только отображаемый текст).
QString breakablePath(const QString &cell)
{
QString d = esc(cell);
d.replace(QLatin1Char('/'), QStringLiteral("/\u200b"));
return d;
}
// ~sql-блок → результат в пузыре кодоблока (как в Telegram).
// Имена файлов — ссылки flora://open (новая вкладка), пути — flora://copycode
// (клик копирует путь). codeId — кнопка «скопировать запрос».
@@ -488,10 +498,13 @@ QString renderSqlBlock(Database *db, MdParser::Impl *impl, const QString &sql, c
const QVariantList rows = res.value("rows").toList();
const bool truncated = res.value("truncated").toBool();
const int colCount = cols.size();
inner = QStringLiteral("<table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" style=\"font-family:-apple-system,sans-serif;font-size:13px\">");
// th не используем: Qt рисует заголовкам свою чёрную плашку поверх стилей.
// width=100% тоже нельзя: такая таблица в Qt игнорирует padding'и
// родительских div'ов и вылезает за панель.
inner = QStringLiteral("<table cellspacing=\"0\" cellpadding=\"0\" style=\"font-family:-apple-system,sans-serif;font-size:13px\">");
inner += QStringLiteral("<tr>");
for (int c = 0; c < colCount; ++c) {
inner += QStringLiteral("<th style=\"padding:6px 10px;text-align:left;color:#9fb3c8;font-weight:600;font-size:12px;border-bottom:1px solid rgba(255,255,255,0.25)\">%1</th>")
inner += QStringLiteral("<td style=\"padding:8px 12px;text-align:left;color:#9fb3c8;font-weight:600;font-size:12px;border-bottom:1px solid rgba(255,255,255,0.25)\">%1</td>")
.arg(esc(cols[c]));
}
inner += QStringLiteral("</tr>");
@@ -508,7 +521,7 @@ QString renderSqlBlock(Database *db, MdParser::Impl *impl, const QString &sql, c
inner += QStringLiteral("<tr>");
for (int c = 0; c < colCount; ++c) {
const QString cell = c < row.size() ? row[c].toString() : QString();
const QString cs = QStringLiteral("padding:6px 10px;text-align:left;color:#ffffff;border-top:1px solid rgba(255,255,255,0.12);word-break:break-word");
const QString cs = QStringLiteral("padding:8px 12px;text-align:left;color:#ffffff;border-top:1px solid rgba(255,255,255,0.12)");
QString body;
if (cell == QLatin1String("NULL")) {
body = QStringLiteral("<i style=\"color:#8ea3b8\">NULL</i>");
@@ -521,9 +534,9 @@ QString renderSqlBlock(Database *db, MdParser::Impl *impl, const QString &sql, c
impl->codeBlocks.insert(pid, abs);
}
body = pid.isEmpty()
? esc(cell)
? breakablePath(cell)
: QStringLiteral("<a href=\"flora://copycode/%1\" style=\"color:#c9d6e2;text-decoration:underline\" title=\"Нажмите, чтобы скопировать путь\">%2</a>")
.arg(pid, esc(cell));
.arg(pid, breakablePath(cell));
} else if (c < cols.size()
&& cols[c].trimmed().compare(QLatin1String("title"), Qt::CaseInsensitive) == 0) {
// Имя: клик открывает файл в соседней вкладке
@@ -550,7 +563,7 @@ QString renderSqlBlock(Database *db, MdParser::Impl *impl, const QString &sql, c
QString out = QStringLiteral(
"<style>.copybtn:hover{background:rgba(255,255,255,0.22) !important;border-color:rgba(255,255,255,0.28) !important;color:#ffffff !important;}"
".copybtn:active{background:rgba(255,255,255,0.30) !important;}</style>"
"<div style=\"background:%1;border-radius:14px;padding:12px 14px 12px 14px;margin:12px 0;max-width:88%%;box-shadow:0 1px 2px rgba(0,0,0,0.18)\">"
"<div style=\"background:%1;border-radius:14px;padding:12px 14px 12px 14px;margin:12px 0\">"
"<div style=\"text-align:right;margin-bottom:8px\">%2</div>"
"<div style=\"background:rgba(0,0,0,0.22);border-radius:9px;padding:12px 14px\">%3</div>")
.arg(bubbleBg, copyLink, inner);
@@ -808,7 +821,7 @@ private:
return QStringLiteral(
"<style>.copybtn:hover{background:rgba(255,255,255,0.22) !important;border-color:rgba(255,255,255,0.28) !important;color:#ffffff !important;}"
".copybtn:active{background:rgba(255,255,255,0.30) !important;}</style>"
"<div style=\"background:%1;border-radius:14px;padding:12px 14px 12px 14px;margin:12px 0;max-width:88%%;box-shadow:0 1px 2px rgba(0,0,0,0.18)\">"
"<div style=\"background:%1;border-radius:14px;padding:12px 14px 12px 14px;margin:12px 0\">"
"<div style=\"text-align:right;margin-bottom:8px\">%2</div>"
"<div style=\"background:rgba(0,0,0,0.22);border-radius:9px;padding:12px 14px\">"
"<pre style=\"margin:0;font-family:'JetBrains Mono','Fira Code','Menlo',Consolas,monospace;font-size:13px;line-height:1.5;tab-size:4;white-space:pre-wrap;word-wrap:break-word;color:#ffffff\">"