diff --git a/Telegram/SourceFiles/ayu/ui/ayu_userpic.cpp b/Telegram/SourceFiles/ayu/ui/ayu_userpic.cpp index a504deda97..a09c2540d9 100644 --- a/Telegram/SourceFiles/ayu/ui/ayu_userpic.cpp +++ b/Telegram/SourceFiles/ayu/ui/ayu_userpic.cpp @@ -11,6 +11,7 @@ #include "media/streaming/media_streaming_common.h" #include "ui/image/image_prepare.h" #include "ui/style/style_core.h" +#include "base/algorithm.h" #include @@ -88,6 +89,15 @@ QPointF OnlineBadgePosition(int photoSize, double badgeSize, double stroke) { return QPointF(pos, pos); } +QRect OnlineBadgeRect(int photoSize, int badgeSize, int stroke) { + const auto pos = OnlineBadgePosition(photoSize, badgeSize, stroke); + return QRect( + int(base::SafeRound(pos.x())), + int(base::SafeRound(pos.y())), + badgeSize, + badgeSize); +} + void ApplyFrameRounding( ::Media::Streaming::FrameRequest &request, std::array &cornersCache, diff --git a/Telegram/SourceFiles/ayu/ui/ayu_userpic.h b/Telegram/SourceFiles/ayu/ui/ayu_userpic.h index 7006e2937b..c53de5efa3 100644 --- a/Telegram/SourceFiles/ayu/ui/ayu_userpic.h +++ b/Telegram/SourceFiles/ayu/ui/ayu_userpic.h @@ -8,6 +8,8 @@ #include "ui/userpic_view.h" +#include + namespace Media::Streaming { struct FrameRequest; } namespace AyuUserpic { @@ -23,6 +25,10 @@ void PaintShape(QPainter &p, int x, int y, int size); void PaintShape(QPainter &p, const QRectF &rect); [[nodiscard]] QPointF OnlineBadgePosition(int photoSize, double badgeSize, double stroke = 0); +[[nodiscard]] QRect OnlineBadgeRect( + int photoSize, + int badgeSize, + int stroke = 0); void ApplyFrameRounding( ::Media::Streaming::FrameRequest &request, diff --git a/Telegram/SourceFiles/ayu/utils/telegram_helpers.cpp b/Telegram/SourceFiles/ayu/utils/telegram_helpers.cpp index 1afa5f7a7c..a2af957c3d 100644 --- a/Telegram/SourceFiles/ayu/utils/telegram_helpers.cpp +++ b/Telegram/SourceFiles/ayu/utils/telegram_helpers.cpp @@ -994,25 +994,20 @@ static bool prependPseudoReplyImpl( QString() }); - auto accessHash = uint64(0); if (const auto user = from->asUser()) { - accessHash = user->accessHash(); - } else if (const auto channel = from->asChannel()) { - accessHash = channel->accessHash(); - } + if (const auto accessHash = user->accessHash()) { + const auto mentionData = QStringLiteral("%1.%2:%3") + .arg(user->id.value) + .arg(accessHash) + .arg(session->userId().bare); - if (accessHash != 0) { - const auto mentionData = QStringLiteral("%1.%2:%3") - .arg(from->id.value) - .arg(accessHash) - .arg(session->userId().bare); - - newEntities.push_back(EntityInText{ - EntityType::MentionName, - 0, - nameLength, - mentionData - }); + newEntities.push_back(EntityInText{ + EntityType::MentionName, + 0, + nameLength, + mentionData + }); + } } } diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 5e3c072846..35109bc8b3 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -93,6 +93,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include // AyuGram includes +#include "ayu/ui/ayu_userpic.h" #include "ayu/utils/telegram_helpers.h" #include "styles/style_ayu_icons.h" @@ -5419,14 +5420,10 @@ void InnerWidget::repaintDialogRowCornerStatus(not_null history) { ? st::dialogsOnlineBadgeSize : st::dialogsCallBadgeSize; const auto stroke = st::dialogsOnlineBadgeStroke; - const auto skip = user - ? st::dialogsOnlineBadgeSkip - : st::dialogsCallBadgeSkip; - const auto updateRect = QRect( - _st->photoSize - skip.x() - size, - _st->photoSize - skip.y() - size, + const auto updateRect = AyuUserpic::OnlineBadgeRect( + _st->photoSize, size, - size + stroke ).marginsAdded( { stroke, stroke, stroke, stroke } ).translated( diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.cpp b/Telegram/SourceFiles/dialogs/dialogs_row.cpp index 4a9d3c7be3..605563bc40 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_row.cpp @@ -115,7 +115,8 @@ constexpr auto kBlurRadius = 24; [[nodiscard]] QImage CornerBadgeTTL( not_null peer, Ui::PeerUserpicView &view, - int photoSize) { + int photoSize, + QColor background) { const auto ttl = peer->messagesTTL(); if (!ttl) { return QImage(); @@ -124,8 +125,21 @@ constexpr auto kBlurRadius = 24; const auto fullSize = photoSize; const auto partRect = CornerBadgeTTLRect(fullSize); const auto &partSize = partRect.width(); + auto source = PeerData::GenerateUserpicImage(peer, view, fullSize * ratio); + if (source.hasAlphaChannel()) { + auto flattened = QImage( + source.size(), + QImage::Format_ARGB32_Premultiplied); + flattened.setDevicePixelRatio(source.devicePixelRatio()); + flattened.fill(background); + { + auto painter = QPainter(&flattened); + painter.drawImage(0, 0, source); + } + source = std::move(flattened); + } auto result = Images::Circle(BlurredDarkenedPart( - PeerData::GenerateUserpicImage(peer, view, fullSize * ratio, 0), + std::move(source), QRect( partRect.topLeft() * ratio, QSize(partSize, partSize) * ratio))); @@ -169,13 +183,7 @@ constexpr auto kBlurRadius = 24; } // namespace QRect CornerBadgeTTLRect(int photoSize) { - const auto &partSize = st::dialogsTTLBadgeSize; - const auto pos = AyuUserpic::OnlineBadgePosition(photoSize, partSize); - return QRect( - int(pos.x()), - int(pos.y()), - partSize, - partSize); + return AyuUserpic::OnlineBadgeRect(photoSize, st::dialogsTTLBadgeSize); } QImage BlurredDarkenedPart(QImage image, QRect part) { @@ -520,7 +528,11 @@ void Row::PaintCornerBadgeFrame( if (const auto p = manager.progressForLayer(kBottomLayer); p > 0.) { const auto size = photoSize; if (data->cacheTTL.isNull() && peer && peer->messagesTTL()) { - data->cacheTTL = CornerBadgeTTL(peer, view, size); + data->cacheTTL = CornerBadgeTTL( + peer, + view, + size, + (context.active ? st::dialogsBgActive : st::dialogsBg)->c); } q.setOpacity(p); const auto point = CornerBadgeTTLRect(size).topLeft(); @@ -542,9 +554,6 @@ void Row::PaintCornerBadgeFrame( ? st::dialogsOnlineBadgeSize : st::dialogsCallBadgeSize; const auto stroke = st::dialogsOnlineBadgeStroke; - const auto skip = online - ? st::dialogsOnlineBadgeSkip - : st::dialogsCallBadgeSkip; const auto shrink = (size / 2) * (1. - topLayerProgress); auto pen = QPen(Qt::transparent); @@ -553,13 +562,13 @@ void Row::PaintCornerBadgeFrame( q.setBrush(data->active ? st::dialogsOnlineBadgeFgActive : st::dialogsOnlineBadgeFg); - const auto badge = AyuUserpic::OnlineBadgePosition(photoSize, size, stroke); - q.drawEllipse(QRectF( - badge.x(), - badge.y(), - size, - size - ).marginsRemoved({ shrink, shrink, shrink, shrink })); + const auto badge = AyuUserpic::OnlineBadgeRect(photoSize, size, stroke); + q.drawEllipse(QRectF(badge).marginsRemoved({ + shrink, + shrink, + shrink, + shrink, + })); } void Row::paintUserpic( @@ -640,16 +649,17 @@ void Row::paintUserpic( const auto paletteVersionReal = style::PaletteVersion(); const auto paletteVersion = (paletteVersionReal & ((1 << 17) - 1)); const auto active = context.active ? 1 : 0; + const auto activeChanged = (_cornerBadgeUserpic->active != active); const auto keyChanged = (_cornerBadgeUserpic->key != key) || (_cornerBadgeUserpic->paletteVersion != paletteVersion); - if (keyChanged) { + if (keyChanged || activeChanged) { _cornerBadgeUserpic->cacheTTL = QImage(); } const auto subscribed = Data::ChannelHasSubscriptionUntilDate( peer ? peer->asChannel() : nullptr); if (keyChanged || !_cornerBadgeUserpic->layersManager.isFinished() - || _cornerBadgeUserpic->active != active + || activeChanged || _cornerBadgeUserpic->frameIndex != frameIndex || _cornerBadgeUserpic->storiesCount != storiesCount || _cornerBadgeUserpic->storiesUnreadCount != storiesUnreadCount @@ -686,14 +696,18 @@ void Row::paintUserpic( ? st::dialogsBgActive : st::dialogsBg; const auto size = st::dialogsCallBadgeSize; - const auto skip = st::dialogsCallBadgeSkip; + const auto stroke = st::dialogsOnlineBadgeStroke; + const auto badge = AyuUserpic::OnlineBadgeRect( + context.st->photoSize, + size, + stroke); p.setOpacity( _cornerBadgeUserpic->layersManager.progressForLayer(kTopLayer)); p.translate(context.st->padding.left(), context.st->padding.top()); actionPainter->paintSpeaking( p, - context.st->photoSize - skip.x() - size, - context.st->photoSize - skip.y() - size, + badge.x(), + badge.y(), context.width, bg, context.now);