From dca61541d671546908ae0caeb91521fd04cf0c94 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 11 Aug 2024 13:40:43 +0300 Subject: [PATCH] Added ability to emplace badge in dialog row for subscribed channels. --- Telegram/SourceFiles/data/data_channel.cpp | 8 +++++ Telegram/SourceFiles/data/data_channel.h | 4 +++ .../SourceFiles/data/data_peer_values.cpp | 4 +++ Telegram/SourceFiles/data/data_peer_values.h | 1 + Telegram/SourceFiles/data/data_session.cpp | 2 ++ Telegram/SourceFiles/dialogs/dialogs_row.cpp | 31 +++++++++++++------ Telegram/SourceFiles/dialogs/dialogs_row.h | 3 +- 7 files changed, 42 insertions(+), 11 deletions(-) diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index 28c1a1b38..42c335fe1 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -1028,6 +1028,14 @@ void ChannelData::updateLevelHint(int levelHint) { _levelHint = levelHint; } +TimeId ChannelData::subscriptionUntilDate() const { + return _subscriptionUntilDate; +} + +void ChannelData::updateSubscriptionUntilDate(TimeId subscriptionUntilDate) { + _subscriptionUntilDate = subscriptionUntilDate; +} + namespace Data { void ApplyMigration( diff --git a/Telegram/SourceFiles/data/data_channel.h b/Telegram/SourceFiles/data/data_channel.h index 457e759a0..178890107 100644 --- a/Telegram/SourceFiles/data/data_channel.h +++ b/Telegram/SourceFiles/data/data_channel.h @@ -489,6 +489,9 @@ public: [[nodiscard]] int levelHint() const; void updateLevelHint(int levelHint); + [[nodiscard]] TimeId subscriptionUntilDate() const; + void updateSubscriptionUntilDate(TimeId subscriptionUntilDate); + // Still public data members. uint64 access = 0; @@ -531,6 +534,7 @@ private: AdminRightFlags _adminRights; RestrictionFlags _restrictions; TimeId _restrictedUntil; + TimeId _subscriptionUntilDate; std::vector _unavailableReasons; std::unique_ptr _invitePeek; diff --git a/Telegram/SourceFiles/data/data_peer_values.cpp b/Telegram/SourceFiles/data/data_peer_values.cpp index a0578000f..92c1f1d95 100644 --- a/Telegram/SourceFiles/data/data_peer_values.cpp +++ b/Telegram/SourceFiles/data/data_peer_values.cpp @@ -508,6 +508,10 @@ bool ChannelHasActiveCall(not_null channel) { return (channel->flags() & ChannelDataFlag::CallNotEmpty); } +bool ChannelHasSubscriptionUntilDate(ChannelData *channel) { + return channel && channel->subscriptionUntilDate() > 0; +} + rpl::producer PeerUserpicImageValue( not_null peer, int size, diff --git a/Telegram/SourceFiles/data/data_peer_values.h b/Telegram/SourceFiles/data/data_peer_values.h index c3a1ac9ad..b726746be 100644 --- a/Telegram/SourceFiles/data/data_peer_values.h +++ b/Telegram/SourceFiles/data/data_peer_values.h @@ -164,6 +164,7 @@ inline auto PeerFullFlagValue( [[nodiscard]] bool OnlineTextActive(not_null user, TimeId now); [[nodiscard]] bool IsUserOnline(not_null user, TimeId now = 0); [[nodiscard]] bool ChannelHasActiveCall(not_null channel); +[[nodiscard]] bool ChannelHasSubscriptionUntilDate(ChannelData *channel); [[nodiscard]] rpl::producer PeerUserpicImageValue( not_null peer, diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index ec4d1c6e4..d5a53eba6 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -880,6 +880,8 @@ not_null Session::processChat(const MTPChat &data) { const auto wasCallNotEmpty = Data::ChannelHasActiveCall(channel); channel->updateLevelHint(data.vlevel().value_or_empty()); + channel->updateSubscriptionUntilDate( + data.vsubscription_until_date().value_or_empty()); if (const auto count = data.vparticipants_count()) { channel->setMembersCount(count->v); } diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.cpp b/Telegram/SourceFiles/dialogs/dialogs_row.cpp index 9ecddf88f..f08e17636 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_row.cpp @@ -301,11 +301,13 @@ void Row::updateCornerBadgeShown( Fn updateCallback) const { const auto user = peer->asUser(); const auto now = user ? base::unixtime::now() : TimeId(); + const auto channel = user ? nullptr : peer->asChannel(); const auto nextLayer = [&] { if (user && Data::IsUserOnline(user, now)) { return kTopLayer; - } else if (peer->isChannel() - && Data::ChannelHasActiveCall(peer->asChannel())) { + } else if (channel + && (Data::ChannelHasActiveCall(channel) + || Data::ChannelHasSubscriptionUntilDate(channel))) { return kTopLayer; } else if (peer->messagesTTL()) { return kBottomLayer; @@ -332,7 +334,8 @@ void Row::PaintCornerBadgeFrame( PeerData *peer, Ui::VideoUserpic *videoUserpic, Ui::PeerUserpicView &view, - const Ui::PaintContext &context) { + const Ui::PaintContext &context, + bool subscribed) { data->frame.fill(Qt::transparent); Painter q(&data->frame); @@ -389,6 +392,11 @@ void Row::PaintCornerBadgeFrame( Ui::PaintOutlineSegments(q, outline, segments); } + if (subscribed) { + // Draw badge. + return; + } + const auto &manager = data->layersManager; if (const auto p = manager.progressForLayer(kBottomLayer); p > 0.) { const auto size = photoSize; @@ -419,6 +427,7 @@ void Row::PaintCornerBadgeFrame( ? st::dialogsOnlineBadgeSkip : st::dialogsCallBadgeSkip; const auto shrink = (size / 2) * (1. - topLayerProgress); + const auto doubleShrink = shrink * 2; auto pen = QPen(Qt::transparent); pen.setWidthF(stroke * topLayerProgress); @@ -427,11 +436,10 @@ void Row::PaintCornerBadgeFrame( ? st::dialogsOnlineBadgeFgActive : st::dialogsOnlineBadgeFg); q.drawEllipse(QRectF( - photoSize - skip.x() - size, - photoSize - skip.y() - size, - size, - size - ).marginsRemoved({ shrink, shrink, shrink, shrink })); + photoSize - skip.x() - size - shrink, + photoSize - skip.y() - size - shrink, + size + doubleShrink, + size + doubleShrink)); } void Row::paintUserpic( @@ -509,6 +517,8 @@ void Row::paintUserpic( if (keyChanged) { _cornerBadgeUserpic->cacheTTL = QImage(); } + const auto subscribed = Data::ChannelHasSubscriptionUntilDate( + peer ? peer->asChannel() : nullptr); if (keyChanged || !_cornerBadgeUserpic->layersManager.isFinished() || _cornerBadgeUserpic->active != active @@ -530,14 +540,15 @@ void Row::paintUserpic( peer, videoUserpic, userpicView(), - context); + context, + subscribed); } p.drawImage( context.st->padding.left() - framePadding, context.st->padding.top() - framePadding, _cornerBadgeUserpic->frame); const auto history = _id.history(); - if (!history || history->peer->isUser()) { + if (!history || history->peer->isUser() || subscribed) { return; } const auto actionPainter = history->sendActionPainter(); diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.h b/Telegram/SourceFiles/dialogs/dialogs_row.h index 738c9faa4..a4ddde404 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.h +++ b/Telegram/SourceFiles/dialogs/dialogs_row.h @@ -192,7 +192,8 @@ private: PeerData *peer, Ui::VideoUserpic *videoUserpic, Ui::PeerUserpicView &view, - const Ui::PaintContext &context); + const Ui::PaintContext &context, + bool subscribed); Key _id; mutable std::unique_ptr _cornerBadgeUserpic;