From ef749e695e51843e1c16200a0ac60c6e8ce536f8 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 25 Nov 2025 18:30:09 +0400 Subject: [PATCH] Show nice layout of stars-only messages. --- Telegram/SourceFiles/calls/calls.style | 1 + .../calls/group/calls_group_messages_ui.cpp | 73 +++++++++++++++---- .../calls/group/calls_group_messages_ui.h | 1 + 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index 58d112d03e..be663744a6 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -1698,6 +1698,7 @@ groupCallMessagesScroll: ScrollArea(defaultScrollArea) { barHidden: true; } groupCallMessagePadding: margins(8px, 3px, 8px, 2px); +groupCallPricePadding: margins(5px, 0px, 5px, 0px); groupCallMessageSkip: 8px; groupCallMessagePalette: TextPalette(defaultTextPalette) { linkFg: radialFg; diff --git a/Telegram/SourceFiles/calls/group/calls_group_messages_ui.cpp b/Telegram/SourceFiles/calls/group/calls_group_messages_ui.cpp index 03ac456660..0fac740cfc 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_messages_ui.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_messages_ui.cpp @@ -73,6 +73,13 @@ constexpr auto kAdminBadgeTextOpacity = 0.6; return minHeight / 2; } +[[nodiscard]] int CountPriceRadius() { + const auto height = st::groupCallPricePadding.top() + + st::normalFont->height + + st::groupCallPricePadding.bottom(); + return height / 2; +} + [[nodiscard]] int CountPinnedRadius() { const auto height = st::groupCallUserpicPadding.top() + st::groupCallPinnedUserpic @@ -304,6 +311,7 @@ struct MessagesUi::MessageView { bool removed = false; bool sending = false; bool failed = false; + bool simple = false; bool admin = false; bool mine = false; }; @@ -333,6 +341,7 @@ MessagesUi::PayedBg::PayedBg(const Ui::StarsColoring &coloring) , pinnedLight(CountPinnedRadius(), light.color()) , pinnedDark(CountPinnedRadius(), dark.color()) , messageLight(CountMessageRadius(), light.color()) +, priceDark(CountPriceRadius(), dark.color()) , badgeDark(st::roundRadiusLarge, dark.color()) { } @@ -518,6 +527,7 @@ void MessagesUi::animateMessageSent(MessageView &entry) { void MessagesUi::updateMessageSize(MessageView &entry) { const auto &padding = st::groupCallMessagePadding; + const auto &pricePadding = st::groupCallPricePadding; const auto hasUserpic = !entry.failed; const auto userpicPadding = st::groupCallUserpicPadding; @@ -532,6 +542,9 @@ void MessagesUi::updateMessageSize(MessageView &entry) { entry.text, std::min(st::groupCallWidth / 2, inner), inner); + const auto price = entry.simple + ? (pricePadding.left() + pricePadding.right() + entry.price.maxWidth()) + : 0; const auto space = st::normalFont->spacew; const auto nameWidth = entry.name.isEmpty() ? 0 : entry.name.maxWidth(); const auto nameLineWidth = nameWidth @@ -546,8 +559,8 @@ void MessagesUi::updateMessageSize(MessageView &entry) { ? 0 : st::messageTextStyle.font->height; const auto textHeight = size.height(); - entry.width = std::max(size.width(), std::min(nameLineWidth, inner)) - + widthSkip; + entry.width = widthSkip + + std::max(size.width() + price, std::min(nameLineWidth, inner)); entry.left = _streamMode ? 0 : (_width - entry.width) / 2; entry.textLeft = leftSkip; entry.textTop = padding.top() + nameHeight; @@ -637,6 +650,8 @@ void MessagesUi::setContentFailed(MessageView &entry) { } void MessagesUi::setContent(MessageView &entry) { + entry.simple = !entry.admin && entry.original.empty() && entry.stars > 0; + const auto name = nameText(entry.from, entry.place); entry.name = entry.admin ? Ui::Text::String( @@ -648,7 +663,7 @@ void MessagesUi::setContent(MessageView &entry) { : Ui::Text::String(); if (const auto stars = entry.stars) { entry.price = Ui::Text::String( - st::whoReadDateStyle, + entry.simple ? st::messageTextStyle : st::whoReadDateStyle, Ui::Text::IconEmoji( &st::starIconEmojiSmall ).append(Lang::FormatCountDecimal(stars)), @@ -668,12 +683,14 @@ void MessagesUi::setContent(MessageView &entry) { kMarkupTextOptions, st::groupCallWidth / 8, _crownHelper.context([this, id = entry.id] { repaintMessage(id); })); - if (!entry.price.isEmpty()) { + if (!entry.simple && !entry.price.isEmpty()) { entry.text.updateSkipBlock( entry.price.maxWidth(), st::normalFont->height); } - entry.text.setLink(1, entry.fromLink); + if (!entry.simple && !entry.admin) { + entry.text.setLink(1, entry.fromLink); + } if (entry.text.hasSpoilers()) { const auto id = entry.id; const auto guard = base::make_weak(_messages); @@ -1207,18 +1224,19 @@ void MessagesUi::setupMessagesWidget() { p.setOpacity(scale); p.translate(-mx, -my); } + auto bg = (std::unique_ptr*)nullptr; if (!_streamMode) { _messageBgRect.paint(p, { x, y, width, use }); } else if (entry.stars) { const auto coloring = Ui::StarsColoringForCount( colorings, entry.stars); - auto &bg = _bgs[ColoringKey(coloring)]; - if (!bg) { - bg = std::make_unique(coloring); + bg = &_bgs[ColoringKey(coloring)]; + if (!*bg) { + *bg = std::make_unique(coloring); } p.setOpacity(kColoredMessageBgOpacity); - bg->messageLight.paint(p, { x, y, width, use }); + (*bg)->messageLight.paint(p, { x, y, width, use }); p.setOpacity(1.); if (_highlightAnimation.animating() && entry.id == _highlightId) { @@ -1236,7 +1254,6 @@ void MessagesUi::setupMessagesWidget() { } const auto textLeft = entry.textLeft; - const auto priceSkip = padding.right() / 2; const auto hasUserpic = !entry.failed; if (hasUserpic) { const auto userpicSize = st::groupCallUserpic; @@ -1299,23 +1316,49 @@ void MessagesUi::setupMessagesWidget() { }); p.setOpacity(1.); } + const auto pricePadding = st::groupCallPricePadding; + const auto textRight = padding.right() + + (entry.simple + ? (entry.price.maxWidth() + + pricePadding.left() + + pricePadding.right()) + : 0); entry.text.draw(p, { .position = { x + textLeft, y + entry.textTop, }, - .availableWidth = entry.width - textLeft - padding.right(), + .availableWidth = entry.width - textLeft - textRight, .palette = &st::groupCallMessagePalette, .spoiler = Ui::Text::DefaultSpoilerCache(), .now = now, .paused = !_messages->window()->isActiveWindow(), }); if (!entry.price.isEmpty()) { + const auto priceRight = x + + entry.width + - entry.price.maxWidth(); + const auto priceLeft = entry.simple + ? (priceRight + - (padding.top() - pricePadding.top()) + - pricePadding.right()) + : (priceRight - (padding.right() / 2)); + const auto priceTop = entry.simple + ? (y + entry.textTop) + : (y + use - st::normalFont->height); + if (entry.simple && bg) { + p.setOpacity(kDarkOverOpacity); + const auto r = QRect( + priceLeft, + priceTop, + entry.price.maxWidth(), + st::normalFont->height + ).marginsAdded(pricePadding); + (*bg)->priceDark.paint(p, r); + p.setOpacity(1.); + } entry.price.draw(p, { - .position = { - x + entry.width - entry.price.maxWidth() - priceSkip, - y + use - st::normalFont->height, - }, + .position = { priceLeft, priceTop }, .availableWidth = entry.price.maxWidth(), }); } diff --git a/Telegram/SourceFiles/calls/group/calls_group_messages_ui.h b/Telegram/SourceFiles/calls/group/calls_group_messages_ui.h index c661004fc2..635be93661 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_messages_ui.h +++ b/Telegram/SourceFiles/calls/group/calls_group_messages_ui.h @@ -80,6 +80,7 @@ private: Ui::RoundRect pinnedLight; Ui::RoundRect pinnedDark; Ui::RoundRect messageLight; + Ui::RoundRect priceDark; Ui::RoundRect badgeDark; };