From f0aca45b113f934408a8679ec629c29190ec1cf0 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 4 Jul 2025 10:04:35 +0400 Subject: [PATCH 01/10] Update API scheme on layer 207. --- Telegram/SourceFiles/api/api_premium.cpp | 16 ++++++++++++++++ Telegram/SourceFiles/data/data_star_gift.h | 1 + Telegram/SourceFiles/mtproto/scheme/api.tl | 8 ++++---- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Telegram/SourceFiles/api/api_premium.cpp b/Telegram/SourceFiles/api/api_premium.cpp index 5119f3908c..946d954466 100644 --- a/Telegram/SourceFiles/api/api_premium.cpp +++ b/Telegram/SourceFiles/api/api_premium.cpp @@ -619,6 +619,8 @@ auto PremiumGiftCodeOptions::requestStarGifts() MTP_int(0) )).done([=](const MTPpayments_StarGifts &result) { result.match([&](const MTPDpayments_starGifts &data) { + _peer->owner().processUsers(data.vusers()); + _peer->owner().processChats(data.vchats()); _giftsHash = data.vhash().v; const auto &list = data.vgifts().v; const auto session = &_peer->session(); @@ -805,6 +807,12 @@ std::optional FromTL( if (!document->sticker()) { return std::optional(); } + const auto releasedById = data.vreleased_by() + ? peerFromMTP(*data.vreleased_by()) + : PeerId(); + const auto releasedBy = releasedById + ? session->data().peer(releasedById).get() + : nullptr; return std::optional(Data::StarGift{ .id = uint64(data.vid().v), .stars = int64(data.vstars().v), @@ -812,6 +820,7 @@ std::optional FromTL( .starsToUpgrade = int64(data.vupgrade_stars().value_or_empty()), .starsResellMin = int64(resellPrice), .document = document, + .releasedBy = releasedBy, .resellTitle = qs(data.vtitle().value_or_empty()), .resellCount = int(data.vavailability_resale().value_or_empty()), .limitedLeft = remaining.value_or_empty(), @@ -841,6 +850,12 @@ std::optional FromTL( || !pattern->document->sticker()) { return std::optional(); } + const auto releasedById = data.vreleased_by() + ? peerFromMTP(*data.vreleased_by()) + : PeerId(); + const auto releasedBy = releasedById + ? session->data().peer(releasedById).get() + : nullptr; auto result = Data::StarGift{ .id = uint64(data.vid().v), .unique = std::make_shared(Data::UniqueGift{ @@ -858,6 +873,7 @@ std::optional FromTL( .pattern = *pattern, }), .document = model->document, + .releasedBy = releasedBy, .limitedLeft = (total - data.vavailability_issued().v), .limitedCount = total, }; diff --git a/Telegram/SourceFiles/data/data_star_gift.h b/Telegram/SourceFiles/data/data_star_gift.h index 3de6c85531..e6e6bc9ca2 100644 --- a/Telegram/SourceFiles/data/data_star_gift.h +++ b/Telegram/SourceFiles/data/data_star_gift.h @@ -68,6 +68,7 @@ struct StarGift { int64 starsToUpgrade = 0; int64 starsResellMin = 0; not_null document; + PeerData *releasedBy = nullptr; QString resellTitle; int resellCount = 0; int limitedLeft = 0; diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index 61aff7c1f2..e33dd8366b 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -1890,11 +1890,11 @@ starsGiveawayOption#94ce852a flags:# extended:flags.0?true default:flags.1?true starsGiveawayWinnersOption#54236209 flags:# default:flags.0?true users:int per_user_stars:long = StarsGiveawayWinnersOption; -starGift#c62aca28 flags:# limited:flags.0?true sold_out:flags.1?true birthday:flags.2?true id:long sticker:Document stars:long availability_remains:flags.0?int availability_total:flags.0?int availability_resale:flags.4?long convert_stars:long first_sale_date:flags.1?int last_sale_date:flags.1?int upgrade_stars:flags.3?long resell_min_stars:flags.4?long title:flags.5?string = StarGift; -starGiftUnique#6411db89 flags:# id:long title:string slug:string num:int owner_id:flags.0?Peer owner_name:flags.1?string owner_address:flags.2?string attributes:Vector availability_issued:int availability_total:int gift_address:flags.3?string resell_stars:flags.4?long = StarGift; +starGift#7f853c12 flags:# limited:flags.0?true sold_out:flags.1?true birthday:flags.2?true id:long sticker:Document stars:long availability_remains:flags.0?int availability_total:flags.0?int availability_resale:flags.4?long convert_stars:long first_sale_date:flags.1?int last_sale_date:flags.1?int upgrade_stars:flags.3?long resell_min_stars:flags.4?long title:flags.5?string released_by:flags.6?Peer = StarGift; +starGiftUnique#f63778ae flags:# id:long title:string slug:string num:int owner_id:flags.0?Peer owner_name:flags.1?string owner_address:flags.2?string attributes:Vector availability_issued:int availability_total:int gift_address:flags.3?string resell_stars:flags.4?long released_by:flags.5?Peer = StarGift; payments.starGiftsNotModified#a388a368 = payments.StarGifts; -payments.starGifts#901689ea hash:int gifts:Vector = payments.StarGifts; +payments.starGifts#2ed82995 hash:int gifts:Vector chats:Vector users:Vector = payments.StarGifts; messageReportOption#7903e3d9 text:string option:bytes = MessageReportOption; @@ -2720,4 +2720,4 @@ smsjobs.finishJob#4f1ebf24 flags:# job_id:string error:flags.0?string = Bool; fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo; -// LAYER 206 +// LAYER 207 From d05155a403706297ee2f4609eccead2413c706a4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 4 Jul 2025 16:29:53 +0400 Subject: [PATCH 02/10] Show who released the gift. --- Telegram/Resources/langs/lang.strings | 3 + Telegram/SourceFiles/api/api_premium.cpp | 1 + Telegram/SourceFiles/boxes/star_gift_box.cpp | 166 +++++++++++++++++- Telegram/SourceFiles/boxes/star_gift_box.h | 2 + Telegram/SourceFiles/data/data_credits.h | 1 + .../SourceFiles/data/data_media_types.cpp | 4 +- Telegram/SourceFiles/data/data_media_types.h | 1 + Telegram/SourceFiles/data/data_star_gift.h | 1 + Telegram/SourceFiles/history/history_item.cpp | 2 + .../view/media/history_view_premium_gift.cpp | 29 ++- .../view/media/history_view_premium_gift.h | 3 + .../view/media/history_view_service_box.cpp | 60 +++++++ .../view/media/history_view_service_box.h | 7 + .../view/media/history_view_unique_gift.cpp | 104 +++++++++++ .../settings/settings_credits_graphics.cpp | 21 ++- Telegram/SourceFiles/ui/chat/chat.style | 2 + Telegram/SourceFiles/ui/effects/credits.style | 4 + 17 files changed, 400 insertions(+), 11 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 734a93e453..9c50c0e773 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2863,6 +2863,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_credits_box_history_entry_gift_converted" = "Converted Gift"; "lng_credits_box_history_entry_gift_transfer" = "Gift Transfer"; "lng_credits_box_history_entry_gift_unavailable" = "Unavailable"; +"lng_credits_box_history_entry_gift_released" = "released by {name}"; "lng_credits_box_history_entry_gift_sold_out" = "This gift has sold out"; "lng_credits_box_history_entry_gift_out_about" = "With Stars, **{user}** will be able to unlock content and services on Telegram.\n{link}"; "lng_credits_box_history_entry_gift_in_about" = "Use Stars to unlock content and services on Telegram. {link}"; @@ -3581,12 +3582,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_gift_self_about" = "Buy yourself a gift to display on your page or reserve for later.\n\nLimited-edition gifts upgraded to collectibles can be gifted to others later."; "lng_gift_channel_title" = "Send a Gift"; "lng_gift_channel_about" = "Select a gift to show appreciation for {name}."; +"lng_gift_released_by" = "Released by {name}"; "lng_gift_unique_owner" = "Owner"; "lng_gift_unique_address_copied" = "Address copied to clipboard."; "lng_gift_unique_status" = "Status"; "lng_gift_unique_status_non" = "Non-Unique"; "lng_gift_unique_status_upgrade" = "upgrade"; "lng_gift_unique_number" = "Collectible #{index}"; +"lng_gift_unique_number_by" = "Collectible #{index} by {name}"; "lng_gift_unique_model" = "Model"; "lng_gift_unique_backdrop" = "Backdrop"; "lng_gift_unique_symbol" = "Symbol"; diff --git a/Telegram/SourceFiles/api/api_premium.cpp b/Telegram/SourceFiles/api/api_premium.cpp index 946d954466..5065541e27 100644 --- a/Telegram/SourceFiles/api/api_premium.cpp +++ b/Telegram/SourceFiles/api/api_premium.cpp @@ -867,6 +867,7 @@ std::optional FromTL( .ownerId = (data.vowner_id() ? peerFromMTP(*data.vowner_id()) : PeerId()), + .releasedBy = releasedBy, .number = data.vnum().v, .starsForResale = int(data.vresell_stars().value_or_empty()), .model = *model, diff --git a/Telegram/SourceFiles/boxes/star_gift_box.cpp b/Telegram/SourceFiles/boxes/star_gift_box.cpp index 6e4608a47d..473e840881 100644 --- a/Telegram/SourceFiles/boxes/star_gift_box.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_box.cpp @@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "chat_helpers/stickers_lottie.h" #include "chat_helpers/tabbed_panel.h" #include "chat_helpers/tabbed_selector.h" +#include "core/application.h" #include "core/ui_integration.h" #include "data/components/promo_suggestions.h" #include "data/data_birthday.h" @@ -94,6 +95,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/wrap/slide_wrap.h" #include "window/themes/window_theme.h" #include "window/section_widget.h" +#include "window/window_controller.h" #include "window/window_session_controller.h" #include "styles/style_boxes.h" #include "styles/style_chat.h" @@ -333,6 +335,69 @@ private: }; +class TextBubblePart final : public MediaGenericTextPart { +public: + TextBubblePart( + TextWithEntities text, + QMargins margins, + const style::TextStyle &st = st::defaultTextStyle, + const base::flat_map &links = {}, + const Ui::Text::MarkedContext &context = {}, + style::align align = style::al_top); + + void draw( + Painter &p, + not_null owner, + const PaintContext &context, + int outerWidth) const override; + +private: + void setupPen( + Painter &p, + not_null owner, + const PaintContext &context) const override; + int elisionLines() const override; + +}; + +TextBubblePart::TextBubblePart( + TextWithEntities text, + QMargins margins, + const style::TextStyle &st, + const base::flat_map &links, + const Ui::Text::MarkedContext &context, + style::align align) +: MediaGenericTextPart(std::move(text), margins, st, links, context, align) { +} + +void TextBubblePart::draw( + Painter &p, + not_null owner, + const PaintContext &context, + int outerWidth) const { + p.setPen(Qt::NoPen); + p.setBrush(context.st->msgServiceBg()); + const auto radius = height() / 2.; + const auto left = (outerWidth - width()) / 2; + const auto r = QRect(left, 0, width(), height()); + p.drawRoundedRect(r, radius, radius); + + MediaGenericTextPart::draw(p, owner, context, outerWidth); +} + +void TextBubblePart::setupPen( + Painter &p, + not_null owner, + const PaintContext &context) const { + auto pen = context.st->msgServiceFg()->c; + pen.setAlphaF(pen.alphaF() * 0.65); + p.setPen(pen); +} + +int TextBubblePart::elisionLines() const { + return 1; +} + [[nodiscard]] AttributeId FromTL(const MTPStarGiftAttributeId &id) { return id.match([&](const MTPDstarGiftAttributeIdBackdrop &data) { return AttributeId{ @@ -526,6 +591,21 @@ auto GenerateGiftMedia( st::giftBoxPreviewTitlePadding, {}, context); + + if (v::is(descriptor)) { + const auto &stars = v::get(descriptor); + if (const auto by = stars.info.releasedBy) { + push(std::make_unique( + tr::lng_gift_released_by( + tr::now, + lt_name, + Ui::Text::Link('@' + by->username()), + Ui::Text::WithEntities), + st::giftBoxReleasedByMargin, + st::defaultTextStyle)); + } + } + pushText( std::move(description), st::giftBoxPreviewTextPadding, @@ -778,7 +858,7 @@ void PreviewWrap::prepare(rpl::producer details) { owned.get(), GenerateGiftMedia(owned.get(), _item.get(), _recipient, details), MediaGenericDescriptor{ - .maxWidth = st::chatIntroWidth, + .maxWidth = st::chatGiftPreviewWidth, .service = true, })); _item = std::move(owned); @@ -3820,6 +3900,19 @@ void AddUniqueGiftCover( Fn resaleClick) { const auto cover = container->add(object_ptr(container)); + struct Released { + Released() : white(QColor(255, 255, 255)) { + } + + style::owned_color white; + style::FlatLabel st; + PeerData *by = nullptr; + QColor bg; + }; + const auto released = cover->lifetime().make_state(); + released->st = st::uniqueGiftSubtitle; + released->st.palette.linkFg = released->white.color(); + if (resalePrice) { auto background = rpl::duplicate( data @@ -3841,17 +3934,56 @@ void AddUniqueGiftCover( st::uniqueGiftTitle); title->setTextColorOverride(QColor(255, 255, 255)); auto subtitleText = subtitleOverride - ? std::move(subtitleOverride) - : rpl::duplicate(data) | rpl::map([](const Data::UniqueGift &gift) { - return tr::lng_gift_unique_number( - tr::now, - lt_index, - QString::number(gift.number)); + ? std::move(subtitleOverride) | Ui::Text::ToWithEntities() + : rpl::duplicate(data) | rpl::map([=](const Data::UniqueGift &gift) { + released->by = gift.releasedBy; + released->bg = gift.backdrop.patternColor; + return gift.releasedBy + ? tr::lng_gift_unique_number_by( + tr::now, + lt_index, + TextWithEntities{ QString::number(gift.number) }, + lt_name, + Ui::Text::Link('@' + gift.releasedBy->username()), + Ui::Text::WithEntities) + : tr::lng_gift_unique_number( + tr::now, + lt_index, + TextWithEntities{ QString::number(gift.number) }, + Ui::Text::WithEntities); }); const auto subtitle = CreateChild( cover, std::move(subtitleText), - st::uniqueGiftSubtitle); + released->st); + if (released->by) { + const auto button = CreateChild(cover); + subtitle->raise(); + subtitle->setAttribute(Qt::WA_TransparentForMouseEvents); + + button->setClickedCallback([=] { + GiftReleasedByHandler(released->by); + }); + subtitle->geometryValue( + ) | rpl::start_with_next([=](QRect geometry) { + button->setGeometry( + geometry.marginsAdded(st::giftBoxReleasedByMargin)); + }, button->lifetime()); + button->paintRequest() | rpl::start_with_next([=] { + auto p = QPainter(button); + auto hq = PainterHighQualityEnabler(p); + const auto use = subtitle->textMaxWidth(); + const auto add = button->width() - subtitle->width(); + const auto full = use + add; + const auto left = (button->width() - full) / 2; + const auto height = button->height(); + const auto radius = height / 2.; + p.setPen(Qt::NoPen); + p.setBrush(released->bg); + p.setOpacity(0.5); + p.drawRoundedRect(left, 0, full, height, radius, radius); + }, button->lifetime()); + } struct GiftView { QImage gradient; @@ -4417,6 +4549,24 @@ void ShowUniqueGiftSellBox( })); } +void GiftReleasedByHandler(not_null peer) { + const auto session = &peer->session(); + const auto window = session->tryResolveWindow(peer); + if (window) { + window->showPeerHistory(peer); + return; + } + const auto account = not_null(&session->account()); + if (const auto window = Core::App().windowFor(account)) { + window->invokeForSessionController( + &session->account(), + peer, + [=](not_null window) { + window->showPeerHistory(peer); + }); + } +} + struct UpgradeArgs : StarGiftUpgradeArgs { std::vector models; std::vector patterns; diff --git a/Telegram/SourceFiles/boxes/star_gift_box.h b/Telegram/SourceFiles/boxes/star_gift_box.h index d26270d1a4..78ee14a028 100644 --- a/Telegram/SourceFiles/boxes/star_gift_box.h +++ b/Telegram/SourceFiles/boxes/star_gift_box.h @@ -82,6 +82,8 @@ void ShowUniqueGiftSellBox( Data::SavedStarGiftId savedId, Settings::GiftWearBoxStyleOverride st); +void GiftReleasedByHandler(not_null peer); + struct PatternPoint { QPointF position; float64 scale = 1.; diff --git a/Telegram/SourceFiles/data/data_credits.h b/Telegram/SourceFiles/data/data_credits.h index 21f2427a4e..0b0b9382ed 100644 --- a/Telegram/SourceFiles/data/data_credits.h +++ b/Telegram/SourceFiles/data/data_credits.h @@ -65,6 +65,7 @@ struct CreditsHistoryEntry final { uint64 bareGiveawayMsgId = 0; uint64 bareGiftStickerId = 0; uint64 bareGiftOwnerId = 0; + uint64 bareGiftReleasedById = 0; uint64 bareGiftResaleRecipientId = 0; uint64 bareActorId = 0; uint64 bareEntryOwnerId = 0; diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index 30b3929be7..c8a1d35d07 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -2569,7 +2569,9 @@ std::unique_ptr MediaGiftBox::createView( message, HistoryView::GenerateUniqueGiftMedia(message, replacing, unique), HistoryView::MediaGenericDescriptor{ - .maxWidth = st::msgServiceGiftBoxSize.width(), + .maxWidth = (_data.stargiftReleasedBy + ? st::msgServiceStarGiftByWidth + : st::msgServiceGiftBoxSize.width()), .paintBg = HistoryView::UniqueGiftBg(message, unique), .service = true, }); diff --git a/Telegram/SourceFiles/data/data_media_types.h b/Telegram/SourceFiles/data/data_media_types.h index dab3e57b2e..bf5d003830 100644 --- a/Telegram/SourceFiles/data/data_media_types.h +++ b/Telegram/SourceFiles/data/data_media_types.h @@ -144,6 +144,7 @@ struct GiftCode { QString slug; uint64 stargiftId = 0; DocumentData *document = nullptr; + PeerData *stargiftReleasedBy = nullptr; std::shared_ptr unique; TextWithEntities message; ChannelData *channel = nullptr; diff --git a/Telegram/SourceFiles/data/data_star_gift.h b/Telegram/SourceFiles/data/data_star_gift.h index e6e6bc9ca2..df0aacc953 100644 --- a/Telegram/SourceFiles/data/data_star_gift.h +++ b/Telegram/SourceFiles/data/data_star_gift.h @@ -44,6 +44,7 @@ struct UniqueGift { QString ownerAddress; QString ownerName; PeerId ownerId = 0; + PeerData *releasedBy = nullptr; int number = 0; int starsForTransfer = -1; int starsForResale = -1; diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 691661d8c0..2f8c24b60f 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -6349,6 +6349,7 @@ void HistoryItem::applyAction(const MTPMessageAction &action) { fields.stargiftId = gift->id; fields.starsToUpgrade = gift->starsToUpgrade; fields.document = gift->document; + fields.stargiftReleasedBy = gift->releasedBy; fields.limitedCount = gift->limitedCount; fields.limitedLeft = gift->limitedLeft; fields.count = gift->stars; @@ -6384,6 +6385,7 @@ void HistoryItem::applyAction(const MTPMessageAction &action) { if (auto gift = Api::FromTL(&history()->session(), data.vgift())) { fields.stargiftId = gift->id; fields.document = gift->document; + fields.stargiftReleasedBy = gift->releasedBy; fields.limitedCount = gift->limitedCount; fields.limitedLeft = gift->limitedLeft; fields.count = gift->stars; diff --git a/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp b/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp index d3ef5e26a1..bcbcaf70e2 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_premium.h" #include "base/unixtime.h" #include "boxes/gift_premium_box.h" // ResolveGiftCode +#include "boxes/star_gift_box.h" // GiftReleasedByHandler #include "chat_helpers/stickers_gift_box_pack.h" #include "core/click_handler_types.h" // ClickHandlerContext #include "data/stickers/data_custom_emoji.h" @@ -54,7 +55,9 @@ int PremiumGift::top() { } int PremiumGift::width() { - return st::msgServiceStarGiftBoxWidth; + return _data.stargiftReleasedBy + ? st::msgServiceStarGiftByWidth + : st::msgServiceStarGiftBoxWidth; } QSize PremiumGift::size() { @@ -120,6 +123,18 @@ TextWithEntities PremiumGift::title() { : tr::lng_prize_title(tr::now, WithEntities); } +TextWithEntities PremiumGift::author() { + using namespace Ui::Text; + if (!_data.stargiftReleasedBy) { + return {}; + } + return tr::lng_gift_released_by( + tr::now, + lt_name, + Ui::Text::Link('@' + _data.stargiftReleasedBy->username()), + Ui::Text::WithEntities); +} + TextWithEntities PremiumGift::subtitle() { if (tonGift()) { return tr::lng_action_gift_got_ton(tr::now, Ui::Text::WithEntities); @@ -319,6 +334,18 @@ ClickHandlerPtr PremiumGift::createViewLink() { }); } +ClickHandlerPtr PremiumGift::authorLink() { + if (const auto by = _data.stargiftReleasedBy) { + if (!_authorLink) { + _authorLink = std::make_shared([=] { + Ui::GiftReleasedByHandler(by); + }); + } + return _authorLink; + } + return nullptr; +} + int PremiumGift::buttonSkip() { return st::msgServiceGiftBoxButtonMargins.top(); } diff --git a/Telegram/SourceFiles/history/view/media/history_view_premium_gift.h b/Telegram/SourceFiles/history/view/media/history_view_premium_gift.h index ef0bf67612..10be8b9bcb 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_premium_gift.h +++ b/Telegram/SourceFiles/history/view/media/history_view_premium_gift.h @@ -29,6 +29,7 @@ public: int width() override; QSize size() override; TextWithEntities title() override; + TextWithEntities author() override; TextWithEntities subtitle() override; rpl::producer button() override; std::optional buttonMinistars() override; @@ -39,6 +40,7 @@ public: const PaintContext &context, const QRect &geometry) override; ClickHandlerPtr createViewLink() override; + ClickHandlerPtr authorLink() override; bool hideServiceText() override; void stickerClearLoopPlayed() override; @@ -63,6 +65,7 @@ private: const not_null _parent; const not_null _gift; const Data::GiftCode &_data; + ClickHandlerPtr _authorLink; QImage _badgeCache; Info::PeerGifts::GiftBadge _badgeKey; mutable std::optional _sticker; diff --git a/Telegram/SourceFiles/history/view/media/history_view_service_box.cpp b/Telegram/SourceFiles/history/view/media/history_view_service_box.cpp index 5e078f7d19..4e5e11d65f 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_service_box.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_service_box.cpp @@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/rect.h" #include "ui/power_saving.h" #include "styles/style_chat.h" +#include "styles/style_credits.h" #include "styles/style_premium.h" #include "styles/style_layers.h" @@ -51,6 +52,11 @@ ServiceBox::ServiceBox( .session = &parent->history()->session(), .repaint = [parent] { parent->customEmojiRepaint(); }, })) +, _author( + st::defaultTextStyle, + _content->author(), + kMarkupTextOptions, + _maxWidth) , _subtitle( st::premiumPreviewAbout.style, Ui::Text::Filtered( @@ -79,6 +85,12 @@ ServiceBox::ServiceBox( ? 0 : (_title.countHeight(_maxWidth) + st::msgServiceGiftBoxTitlePadding.bottom())) + + (_author.isEmpty() + ? 0 + : (st::giftBoxReleasedByMargin.top() + + st::defaultTextStyle.font->height + + st::giftBoxReleasedByMargin.bottom() + + st::msgServiceGiftBoxTitlePadding.bottom())) + _subtitle.countHeight(_maxWidth) + (!_content->button() ? 0 @@ -164,6 +176,37 @@ void ServiceBox::draw(Painter &p, const PaintContext &context) const { }); top += _title.countHeight(_maxWidth) + padding.bottom(); } + if (!_author.isEmpty()) { + auto hq = PainterHighQualityEnabler(p); + p.setPen(Qt::NoPen); + p.setBrush(context.st->msgServiceBg()); + const auto use = std::min(_maxWidth, _author.maxWidth()) + + st::giftBoxReleasedByMargin.left() + + st::giftBoxReleasedByMargin.right(); + const auto left = st::msgPadding.left() + (_maxWidth - use) / 2; + const auto height = st::giftBoxReleasedByMargin.top() + + st::defaultTextStyle.font->height + + st::giftBoxReleasedByMargin.bottom(); + const auto radius = height / 2.; + p.drawRoundedRect(left, top, use, height, radius, radius); + + auto fg = context.st->msgServiceFg()->c; + fg.setAlphaF(0.65 * fg.alphaF()); + p.setPen(fg); + _author.draw(p, { + .position = QPoint( + left + st::giftBoxReleasedByMargin.left(), + top + st::giftBoxReleasedByMargin.top()), + .availableWidth = (use + - st::giftBoxReleasedByMargin.left() + - st::giftBoxReleasedByMargin.right()), + .palette = &context.st->serviceTextPalette(), + .elisionLines = 1, + }); + p.setPen(context.st->msgServiceFg()); + + top += height + st::msgServiceGiftBoxTitlePadding.bottom(); + } _parent->prepareCustomEmojiPaint(p, context, _subtitle); _subtitle.draw(p, { .position = QPoint(st::msgPadding.left(), top), @@ -231,6 +274,23 @@ TextState ServiceBox::textState(QPoint point, StateRequest request) const { if (!_title.isEmpty()) { top += _title.countHeight(_maxWidth) + padding.bottom(); } + if (!_author.isEmpty()) { + const auto use = std::min(_maxWidth, _author.maxWidth()) + + st::giftBoxReleasedByMargin.left() + + st::giftBoxReleasedByMargin.right(); + const auto left = st::msgPadding.left() + (_maxWidth - use) / 2; + const auto height = st::giftBoxReleasedByMargin.top() + + st::defaultTextStyle.font->height + + st::giftBoxReleasedByMargin.bottom(); + if (point.x() >= left + && point.y() >= top + && point.x() < left + use + && point.y() < top + height) { + result.link = _content->authorLink(); + } + top += height + st::msgServiceGiftBoxTitlePadding.bottom(); + } + auto subtitleRequest = request.forText(); subtitleRequest.align = style::al_top; const auto state = _subtitle.getState( diff --git a/Telegram/SourceFiles/history/view/media/history_view_service_box.h b/Telegram/SourceFiles/history/view/media/history_view_service_box.h index fe7018e849..b15ded3306 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_service_box.h +++ b/Telegram/SourceFiles/history/view/media/history_view_service_box.h @@ -28,6 +28,9 @@ public: [[nodiscard]] virtual int top() = 0; [[nodiscard]] virtual QSize size() = 0; [[nodiscard]] virtual TextWithEntities title() = 0; + [[nodiscard]] virtual TextWithEntities author() { + return {}; + } [[nodiscard]] virtual TextWithEntities subtitle() = 0; [[nodiscard]] virtual int buttonSkip() { return top(); @@ -45,6 +48,9 @@ public: const PaintContext &context, const QRect &geometry) = 0; [[nodiscard]] virtual ClickHandlerPtr createViewLink() = 0; + [[nodiscard]] virtual ClickHandlerPtr authorLink() { + return nullptr; + } [[nodiscard]] virtual bool hideServiceText() = 0; @@ -123,6 +129,7 @@ private: const int _maxWidth = 0; Ui::Text::String _title; + Ui::Text::String _author; Ui::Text::String _subtitle; const QSize _size; const QSize _innerSize; diff --git a/Telegram/SourceFiles/history/view/media/history_view_unique_gift.cpp b/Telegram/SourceFiles/history/view/media/history_view_unique_gift.cpp index b44d10f000..350b7846c5 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_unique_gift.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_unique_gift.cpp @@ -81,6 +81,95 @@ private: }; +class TextBubblePart final : public MediaGenericTextPart { +public: + TextBubblePart( + TextWithEntities text, + QMargins margins, + Data::UniqueGiftBackdrop backdrop, + ClickHandlerPtr link); + + void draw( + Painter &p, + not_null owner, + const PaintContext &context, + int outerWidth) const override; + TextState textState( + QPoint point, + StateRequest request, + int outerWidth) const override; + +private: + void setupPen( + Painter &p, + not_null owner, + const PaintContext &context) const override; + int elisionLines() const override; + + Data::UniqueGiftBackdrop _backdrop; + ClickHandlerPtr _link; + +}; + +TextBubblePart::TextBubblePart( + TextWithEntities text, + QMargins margins, + Data::UniqueGiftBackdrop backdrop, + ClickHandlerPtr link) +: MediaGenericTextPart( + std::move(text), + margins, + st::defaultTextStyle, + {}, + {}, + style::al_top) +, _backdrop(backdrop) +, _link(std::move(link)) { +} + +void TextBubblePart::draw( + Painter &p, + not_null owner, + const PaintContext &context, + int outerWidth) const { + p.setPen(Qt::NoPen); + p.setOpacity(0.5); + p.setBrush(_backdrop.patternColor); + const auto radius = height() / 2.; + const auto left = (outerWidth - width()) / 2; + const auto r = QRect(left, 0, width(), height()); + p.drawRoundedRect(r, radius, radius); + p.setOpacity(1.); + + MediaGenericTextPart::draw(p, owner, context, outerWidth); +} + +TextState TextBubblePart::textState( + QPoint point, + StateRequest request, + int outerWidth) const { + auto result = TextState(); + const auto left = (outerWidth - width()) / 2; + if (point.x() >= left + && point.y() >= 0 + && point.x() < left + width() + && point.y() < height()) { + result.link = _link; + } + return result; +} + +void TextBubblePart::setupPen( + Painter &p, + not_null owner, + const PaintContext &context) const { + p.setPen(_backdrop.textColor); +} + +int TextBubblePart::elisionLines() const { + return 1; +} + ButtonPart::ButtonPart( const QString &text, QMargins margins, @@ -284,6 +373,21 @@ auto GenerateUniqueGiftMedia( gift->backdrop.textColor, st::chatUniqueTextPadding); + if (const auto by = gift->releasedBy) { + const auto handler = std::make_shared([=] { + Ui::GiftReleasedByHandler(by); + }); + push(std::make_unique( + tr::lng_gift_released_by( + tr::now, + lt_name, + Ui::Text::Link('@' + by->username()), + Ui::Text::WithEntities), + st::giftBoxReleasedByMargin, + gift->backdrop, + handler)); + } + const auto name = [](const Data::UniqueGiftAttribute &value) { return Ui::Text::Bold(value.name); }; diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp index 15d889fea8..afb9b9c64b 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp @@ -1434,7 +1434,23 @@ void GenericCreditsEntryBox( Ui::AddSkip(content); } - if (!isStarGift || creditsHistoryStarGift || e.soldOutInfo) { + if (e.bareGiftReleasedById && !e.uniqueGift) { + const auto peer = owner->peer(PeerId(e.bareGiftReleasedById)); + const auto released = content->add( + object_ptr>( + box, + object_ptr( + content, + tr::lng_credits_box_history_entry_gift_released( + lt_name, + rpl::single(Ui::Text::Link('@' + peer->username())), + Ui::Text::WithEntities), + st::creditsReleasedByLabel))); + released->entity()->setClickHandlerFilter([=](const auto &...) { + Ui::GiftReleasedByHandler(peer); + return false; + }); + } else if (!isStarGift || creditsHistoryStarGift || e.soldOutInfo) { constexpr auto kMinus = QChar(0x2212); auto &lifetime = content->lifetime(); const auto text = lifetime.make_state(); @@ -2282,6 +2298,9 @@ void StarGiftViewBox( .bareGiftOwnerId = (data.unique ? data.unique->ownerId.value : toId.value), + .bareGiftReleasedById = (data.stargiftReleasedBy + ? data.stargiftReleasedBy->id.value + : 0), .bareActorId = (toChannel ? data.channelFrom->id.value : 0), .bareEntryOwnerId = (toChannel ? data.channel->id.value : 0), .giftChannelSavedId = data.channelSavedId, diff --git a/Telegram/SourceFiles/ui/chat/chat.style b/Telegram/SourceFiles/ui/chat/chat.style index 37a16ad80f..cdc6d2be56 100644 --- a/Telegram/SourceFiles/ui/chat/chat.style +++ b/Telegram/SourceFiles/ui/chat/chat.style @@ -936,6 +936,7 @@ msgServiceGiftBoxTitlePadding: margins(0px, 20px, 0px, 6px); msgServiceGiftBoxStickerTop: -19px; msgServiceGiftBoxStickerSize: 140px; msgServiceStarGiftBoxWidth: 224px; +msgServiceStarGiftByWidth: 272px; msgServiceStarGiftStickerTop: 24px; msgServiceStarGiftStickerSize: 100px; @@ -1105,6 +1106,7 @@ chatIntroWidth: 224px; chatIntroTitleMargin: margins(11px, 16px, 11px, 4px); chatIntroMargin: margins(11px, 0px, 11px, 0px); chatIntroStickerPadding: margins(10px, 8px, 10px, 16px); +chatGiftPreviewWidth: 264px; liveLocationLongInIcon: icon {{ "chat/live_location_long", msgInServiceFg }}; liveLocationLongInIconSelected: icon {{ "chat/live_location_long", msgInServiceFgSelected }}; diff --git a/Telegram/SourceFiles/ui/effects/credits.style b/Telegram/SourceFiles/ui/effects/credits.style index 3c865fead6..b9c69f00e5 100644 --- a/Telegram/SourceFiles/ui/effects/credits.style +++ b/Telegram/SourceFiles/ui/effects/credits.style @@ -66,6 +66,9 @@ creditsBoxAboutDivider: FlatLabel(boxDividerLabel) { creditsBoxButtonLabel: FlatLabel(defaultFlatLabel) { style: semiboldTextStyle; } +creditsReleasedByLabel: FlatLabel(defaultFlatLabel) { + textFg: windowSubTextFg; +} starIconEmoji: IconEmoji { icon: icon{{ "payments/premium_emoji", creditsBg1 }}; @@ -175,6 +178,7 @@ giftBoxButtonBottomByStars: 18px; giftBoxButtonPadding: margins(8px, 4px, 8px, 4px); giftBoxPreviewStickerPadding: margins(10px, 12px, 10px, 16px); giftBoxPreviewTitlePadding: margins(12px, 4px, 12px, 4px); +giftBoxReleasedByMargin: margins(12px, 2px, 12px, 2px); giftBoxPreviewTextPadding: margins(12px, 4px, 12px, 4px); giftBoxButtonMargin: margins(12px, 8px, 12px, 12px); giftBoxStickerTop: 0px; From 35b129287b332d5810e0a5df835917119d1de189 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 8 Jul 2025 11:33:04 +0400 Subject: [PATCH 03/10] Support RemoveFee/ChargeFee in monoforums. --- Telegram/Resources/icons/menu/cancel_fee.png | Bin 0 -> 865 bytes .../Resources/icons/menu/cancel_fee@2x.png | Bin 0 -> 1810 bytes .../Resources/icons/menu/cancel_fee@3x.png | Bin 0 -> 2662 bytes Telegram/Resources/langs/lang.strings | 5 + .../SourceFiles/data/data_saved_sublist.cpp | 18 +++ .../SourceFiles/data/data_saved_sublist.h | 3 + .../view/history_view_contact_status.cpp | 66 +------- .../view/history_view_contact_status.h | 2 +- .../view/history_view_top_bar_widget.cpp | 5 + Telegram/SourceFiles/ui/menu_icons.style | 1 + Telegram/SourceFiles/window/window.style | 8 + .../SourceFiles/window/window_peer_menu.cpp | 146 ++++++++++++++++++ .../SourceFiles/window/window_peer_menu.h | 7 + Telegram/lib_ui | 2 +- 14 files changed, 202 insertions(+), 61 deletions(-) create mode 100644 Telegram/Resources/icons/menu/cancel_fee.png create mode 100644 Telegram/Resources/icons/menu/cancel_fee@2x.png create mode 100644 Telegram/Resources/icons/menu/cancel_fee@3x.png diff --git a/Telegram/Resources/icons/menu/cancel_fee.png b/Telegram/Resources/icons/menu/cancel_fee.png new file mode 100644 index 0000000000000000000000000000000000000000..467c369cec28a1ec2c2f9947fc199d6f56eec69a GIT binary patch literal 865 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 AdH?_b literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/menu/cancel_fee@3x.png b/Telegram/Resources/icons/menu/cancel_fee@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..73fee9f98a6b702e08f9debc2576aa2d33f06340 GIT binary patch literal 2662 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 diff --git a/Telegram/SourceFiles/history/view/history_view_contact_status.cpp b/Telegram/SourceFiles/history/view/history_view_contact_status.cpp index f5710124bb..99c135f6f3 100644 --- a/Telegram/SourceFiles/history/view/history_view_contact_status.cpp +++ b/Telegram/SourceFiles/history/view/history_view_contact_status.cpp @@ -1194,6 +1194,7 @@ PaysStatus::PaysStatus( not_null user) : _controller(window) , _user(user) +, _paidAlready(std::make_shared>()) , _inner(Ui::CreateChild(parent.get(), user)) , _bar(parent, object_ptr::fromRaw(_inner)) { setupState(); @@ -1220,65 +1221,12 @@ void PaysStatus::setupState() { void PaysStatus::setupHandlers() { _inner->removeClicks( ) | rpl::start_with_next([=] { - const auto user = _user; - const auto exception = [=](bool refund) { - using Flag = MTPaccount_ToggleNoPaidMessagesException::Flag; - const auto api = &user->session().api(); - const auto require = false; - api->request(MTPaccount_ToggleNoPaidMessagesException( - MTP_flags((refund ? Flag::f_refund_charged : Flag()) - | (require ? Flag::f_require_payment : Flag())), - MTPInputPeer(), // parent_peer // #TODO monoforum - user->inputUser - )).done([=] { - user->clearPaysPerMessage(); - }).send(); - }; - _controller->show(Box([=](not_null box) { - const auto refund = std::make_shared>(); - Ui::ConfirmBox(box, { - .text = tr::lng_payment_refund_text( - tr::now, - lt_name, - Ui::Text::Bold(user->shortName()), - Ui::Text::WithEntities), - .confirmed = [=](Fn close) { - exception(*refund && (*refund)->checked()); - close(); - }, - .confirmText = tr::lng_payment_refund_confirm(tr::now), - .title = tr::lng_payment_refund_title(tr::now), - }); - const auto paid = box->lifetime().make_state< - rpl::variable - >(); - *paid = _paidAlready.value(); - paid->value() | rpl::start_with_next([=](int already) { - if (!already) { - delete base::take(*refund); - } else if (!*refund) { - const auto skip = st::defaultCheckbox.margin.top(); - *refund = box->addRow( - object_ptr( - box, - tr::lng_payment_refund_also( - lt_count, - paid->value() | tr::to_count()), - false, - st::defaultCheckbox), - st::boxRowPadding + QMargins(0, skip, 0, skip)); - } - }, box->lifetime()); - - user->session().api().request(MTPaccount_GetPaidMessagesRevenue( - MTP_flags(0), - MTPInputPeer(), // parent_peer // #TODO monoforum - user->inputUser - )).done(crl::guard(_inner, [=]( - const MTPaccount_PaidMessagesRevenue &result) { - _paidAlready = result.data().vstars_amount().v; - })).send(); - })); + Window::PeerMenuConfirmToggleFee( + _controller, + _paidAlready, + _user->session().user(), + _user, + true); }, _bar.lifetime()); } diff --git a/Telegram/SourceFiles/history/view/history_view_contact_status.h b/Telegram/SourceFiles/history/view/history_view_contact_status.h index 0c540a36c4..47aa1232ce 100644 --- a/Telegram/SourceFiles/history/view/history_view_contact_status.h +++ b/Telegram/SourceFiles/history/view/history_view_contact_status.h @@ -208,7 +208,7 @@ private: const not_null _controller; const not_null _user; - rpl::variable _paidAlready; + std::shared_ptr> _paidAlready; State _state; QPointer _inner; SlidingBar _bar; diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp index 2ecbe5ce3a..97edfbdc52 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -1171,6 +1171,11 @@ void TopBarWidget::updateControlsVisibility() { ? (hasPollsMenu || hasTodoListsMenu || hasTopicMenu) : (section == Section::ChatsList) ? (_activeChat.key.peer() && _activeChat.key.peer()->isForum()) + : (section == Section::SavedSublist) + ? (_activeChat.key.peer() + && _activeChat.key.peer()->isChannel() + && _activeChat.key.peer()->owner().commonStarsPerMessage( + _activeChat.key.peer()->asChannel())) : false); const auto hasInfo = !_activeChat.key.folder() && (section == Section::History diff --git a/Telegram/SourceFiles/ui/menu_icons.style b/Telegram/SourceFiles/ui/menu_icons.style index 9c3233f0e2..fcd6d2bbb8 100644 --- a/Telegram/SourceFiles/ui/menu_icons.style +++ b/Telegram/SourceFiles/ui/menu_icons.style @@ -56,6 +56,7 @@ menuIconDiscussion: icon {{ "menu/discussion", menuIconColor }}; menuIconStats: icon {{ "menu/stats", menuIconColor }}; menuIconBoosts: icon {{ "menu/boosts", menuIconColor }}; menuIconEarn: icon {{ "menu/earn", menuIconColor }}; +menuIconCancelFee: icon {{ "menu/cancel_fee", menuIconColor }}; menuIconCreatePoll: icon {{ "menu/create_poll", menuIconColor }}; menuIconCreateTodoList: icon {{ "menu/select", menuIconColor }}; menuIconQrCode: icon {{ "menu/qr_code", menuIconColor }}; diff --git a/Telegram/SourceFiles/window/window.style b/Telegram/SourceFiles/window/window.style index acdda31299..26e77ab1f1 100644 --- a/Telegram/SourceFiles/window/window.style +++ b/Telegram/SourceFiles/window/window.style @@ -316,6 +316,14 @@ windowArchiveToast: Toast(defaultToast) { maxWidth: boxWideWidth; } +windowFeeItem: Menu(defaultMenu) { + itemPadding: margins(17px, 3px, 17px, 4px); + itemRightSkip: 0px; + itemStyle: whenReadStyle; + itemFgOver: windowFg; + itemFgDisabled: windowFg; +} + ivWidthMin: 380px; ivHeightMin: 480px; ivWidthDefault: 600px; diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 114f0ec207..8519ddf620 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/random.h" #include "base/options.h" #include "base/unixtime.h" +#include "base/unique_qptr.h" #include "base/qt/qt_key_modifiers.h" #include "boxes/delete_messages_box.h" #include "boxes/max_invite_box.h" @@ -83,6 +84,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/stories/info_stories_widget.h" #include "data/components/scheduled_messages.h" #include "data/notify/data_notify_settings.h" +#include "data/stickers/data_custom_emoji.h" #include "data/data_changes.h" #include "data/data_session.h" #include "data/data_folder.h" @@ -98,10 +100,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_chat_filters.h" #include "dialogs/dialogs_key.h" #include "core/application.h" +#include "core/ui_integration.h" #include "export/export_manager.h" #include "boxes/peers/edit_peer_info_box.h" #include "boxes/premium_preview_box.h" #include "styles/style_chat.h" +#include "styles/style_credits.h" #include "styles/style_layers.h" #include "styles/style_boxes.h" #include "styles/style_window.h" // st::windowMinWidth @@ -277,6 +281,7 @@ private: void fillArchiveActions(); void fillSavedSublistActions(); void fillContextMenuActions(); + void fillMonoforumPeerActions(); void addHidePromotion(); void addTogglePin(); @@ -321,6 +326,7 @@ private: void addVideoChat(); void addViewStatistics(); void addBoostChat(); + void addToggleFee(); [[nodiscard]] bool skipCreateActions() const; @@ -1360,6 +1366,7 @@ void Filler::fill() { case Section::Scheduled: fillScheduledActions(); break; case Section::ContextMenu: case Section::SubsectionTabsMenu: fillContextMenuActions(); break; + case Section::SavedSublist: fillMonoforumPeerActions(); break; default: Unexpected("_request.section in Filler::fill."); } } @@ -1647,6 +1654,68 @@ void Filler::fillSavedSublistActions() { addTogglePin(); } +void Filler::fillMonoforumPeerActions() { + Expects(_sublist != nullptr); + + addToggleFee(); +} + +void Filler::addToggleFee() { + const auto feeRemoved = _sublist->isFeeRemoved(); + const auto text = feeRemoved + ? tr::lng_context_charge_fee(tr::now) + : tr::lng_context_remove_fee(tr::now); + const auto navigation = _controller; + const auto parent = _sublist->parentChat(); + const auto user = _sublist->sublistPeer()->asUser(); + if (!parent || !user) { + return; + } + const auto paidAmount = std::make_shared>(); + _addAction(text, [=] { + const auto removeFee = !feeRemoved; + PeerMenuConfirmToggleFee( + navigation, + paidAmount, + parent, + user, + removeFee); + }, feeRemoved ? &st::menuIconEarn : &st::menuIconCancelFee); + _addAction({ .isSeparator = true }); + _addAction({ .make = [=](not_null actionParent) { + const auto text = feeRemoved + ? tr::lng_context_fee_free( + tr::now, + lt_name, + TextWithEntities{ user->shortName() }, + Ui::Text::WithEntities) + : tr::lng_context_fee_now( + tr::now, + lt_name, + TextWithEntities{ user->shortName() }, + lt_amount, + user->owner().customEmojiManager().ministarEmoji( + { 0, st::giftBoxByStarsStarTop, 0, 0 } + ).append(Lang::FormatCountDecimal( + user->owner().commonStarsPerMessage(parent) + )), + Ui::Text::WithEntities); + const auto action = new QAction(actionParent); + action->setDisabled(true); + auto result = base::make_unique_q( + actionParent, + st::windowFeeItem, + action, + nullptr, + nullptr); + result->setMarkedText( + text, + QString(), + Core::TextContext({ .session = &user->session() })); + return result; + } }); +} + } // namespace void PeerMenuExportChat( @@ -3726,4 +3795,81 @@ bool CanArchive(History *history, PeerData *peer) { return true; } +void PeerMenuConfirmToggleFee( + not_null navigation, + std::shared_ptr> paidAmount, + not_null peer, + not_null user, + bool removeFee) { + const auto parent = peer->isChannel() ? peer->asChannel() : nullptr; + const auto exception = [=](bool refund) { + using Flag = MTPaccount_ToggleNoPaidMessagesException::Flag; + const auto api = &user->session().api(); + api->request(MTPaccount_ToggleNoPaidMessagesException( + MTP_flags((refund ? Flag::f_refund_charged : Flag()) + | (removeFee ? Flag() : Flag::f_require_payment) + | (parent ? Flag::f_parent_peer : Flag())), + parent->input, + user->inputUser + )).done([=] { + if (!parent) { + user->clearPaysPerMessage(); + } else if (const auto monoforum = peer->monoforum()) { + if (const auto sublist = monoforum->sublistLoaded(user)) { + sublist->toggleFeeRemoved(removeFee); + } + } + }).send(); + }; + if (!removeFee) { + exception(false); + return; + } + navigation->uiShow()->show(Box([=](not_null box) { + const auto refund = std::make_shared>(); + Ui::ConfirmBox(box, { + .text = tr::lng_payment_refund_text( + tr::now, + lt_name, + Ui::Text::Bold(user->shortName()), + Ui::Text::WithEntities), + .confirmed = [=](Fn close) { + exception(*refund && (*refund)->checked()); + close(); + }, + .confirmText = tr::lng_payment_refund_confirm(tr::now), + .title = tr::lng_payment_refund_title(tr::now), + }); + const auto paid = box->lifetime().make_state< + rpl::variable + >(); + *paid = paidAmount->value(); + paid->value() | rpl::start_with_next([=](int already) { + if (!already) { + delete base::take(*refund); + } else if (!*refund) { + const auto skip = st::defaultCheckbox.margin.top(); + *refund = box->addRow( + object_ptr( + box, + tr::lng_payment_refund_also( + lt_count, + paid->value() | tr::to_count()), + false, + st::defaultCheckbox), + st::boxRowPadding + QMargins(0, skip, 0, skip)); + } + }, box->lifetime()); + + using Flag = MTPaccount_GetPaidMessagesRevenue::Flag; + user->session().api().request(MTPaccount_GetPaidMessagesRevenue( + MTP_flags(parent ? Flag::f_parent_peer : Flag()), + parent ? parent->input : MTPInputPeer(), + user->inputUser + )).done([=](const MTPaccount_PaidMessagesRevenue &result) { + *paidAmount = result.data().vstars_amount().v; + }).send(); + })); +} + } // namespace Window diff --git a/Telegram/SourceFiles/window/window_peer_menu.h b/Telegram/SourceFiles/window/window_peer_menu.h index f01801423f..56c4a6baec 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.h +++ b/Telegram/SourceFiles/window/window_peer_menu.h @@ -253,4 +253,11 @@ void AddSeparatorAndShiftUp(const PeerMenuCallback &addAction); [[nodiscard]] bool IsArchived(not_null history); [[nodiscard]] bool CanArchive(History *history, PeerData *peer); +void PeerMenuConfirmToggleFee( + not_null navigation, + std::shared_ptr> paidAmount, + not_null peer, + not_null user, + bool removeFee); + } // namespace Window diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 0b7933ad11..d905dad9c9 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 0b7933ad1189076233b69fac0a5a475d2a5deb8b +Subproject commit d905dad9c9b0e7e2b6755bb13957f37862888464 From c3157fe90d0d59191028f3a40b3244947345dc1a Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 7 Jul 2025 18:06:38 +0400 Subject: [PATCH 04/10] Fix incorrect dc for stars revenue requests. --- Telegram/SourceFiles/api/api_credits.cpp | 4 ++-- Telegram/SourceFiles/api/api_statistics.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/api/api_credits.cpp b/Telegram/SourceFiles/api/api_credits.cpp index d274d424d2..0670972d68 100644 --- a/Telegram/SourceFiles/api/api_credits.cpp +++ b/Telegram/SourceFiles/api/api_credits.cpp @@ -283,7 +283,7 @@ rpl::producer CreditsEarnStatistics::request() { auto lifetime = rpl::lifetime(); const auto finish = [=](const QString &url) { - makeRequest(MTPpayments_GetStarsRevenueStats( + api().request(MTPpayments_GetStarsRevenueStats( MTP_flags(0), (_isUser ? user()->input : channel()->input) )).done([=](const MTPpayments_StarsRevenueStats &result) { @@ -313,7 +313,7 @@ rpl::producer CreditsEarnStatistics::request() { }).send(); }; - makeRequest( + api().request( MTPpayments_GetStarsRevenueAdsAccountUrl( (_isUser ? user()->input : channel()->input)) ).done([=](const MTPpayments_StarsRevenueAdsAccountUrl &result) { diff --git a/Telegram/SourceFiles/api/api_statistics.cpp b/Telegram/SourceFiles/api/api_statistics.cpp index 430af6f158..04f471e923 100644 --- a/Telegram/SourceFiles/api/api_statistics.cpp +++ b/Telegram/SourceFiles/api/api_statistics.cpp @@ -696,7 +696,7 @@ rpl::producer EarnStatistics::request() { return [=](auto consumer) { auto lifetime = rpl::lifetime(); - makeRequest(MTPpayments_GetStarsRevenueStats( + api().request(MTPpayments_GetStarsRevenueStats( MTP_flags(MTPpayments_getStarsRevenueStats::Flag::f_ton), (_isUser ? user()->input : channel()->input) )).done([=](const MTPpayments_StarsRevenueStats &result) { From f8acc55365bf48084356803f19b4c67e2723cf4a Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 8 Jul 2025 20:22:22 +0400 Subject: [PATCH 05/10] Remove checklist creation in broadcasts. --- Telegram/SourceFiles/data/data_peer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 14610cf5f9..cbc27b596a 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -685,7 +685,7 @@ bool PeerData::canCreatePolls() const { } bool PeerData::canCreateTodoLists() const { - if (isMonoforum()) { + if (isMonoforum() || isBroadcast()) { return false; } return session().premium() From 7d78de0673d3dade50e28df13e48dc3da4d299e5 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Fri, 4 Jul 2025 12:22:04 +0000 Subject: [PATCH 06/10] Get rid of QT_GENERATE_SBOM=OFF --- Telegram/build/docker/centos_env/Dockerfile | 1 - snap/snapcraft.yaml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Telegram/build/docker/centos_env/Dockerfile b/Telegram/build/docker/centos_env/Dockerfile index 99fb373035..4df1a8508b 100644 --- a/Telegram/build/docker/centos_env/Dockerfile +++ b/Telegram/build/docker/centos_env/Dockerfile @@ -760,7 +760,6 @@ RUN git clone -b v$QT --depth=1 https://github.com/qt/qt5.git \ && cmake -B build . \ -DCMAKE_INSTALL_PREFIX=/usr/local \ -DBUILD_SHARED_LIBS=OFF \ - -DQT_GENERATE_SBOM=OFF \ -DQT_QPA_PLATFORMS="wayland;xcb" \ -DINPUT_libpng=qt \ -DINPUT_harfbuzz=qt \ diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 8316efd89e..e62a3e9117 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -414,7 +414,6 @@ parts: - -DCMAKE_INSTALL_PREFIX=/usr - -DCMAKE_PREFIX_PATH=$CRAFT_STAGE/usr - -DINSTALL_LIBDIR=/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR - - -DQT_GENERATE_SBOM=OFF - -DINPUT_openssl=linked override-pull: | craftctl default @@ -438,6 +437,7 @@ parts: - -./usr/metatypes - -./usr/mkspecs - -./usr/modules + - -./usr/sbom - -./**/objects-* after: - libjxl From 1c53fca925fa37479aaa470a681eb69e796b9b24 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Sat, 5 Jul 2025 21:44:08 +0000 Subject: [PATCH 07/10] Remove unused yasm dependency from snap --- snap/snapcraft.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index e62a3e9117..16da44ab9c 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -504,7 +504,6 @@ parts: build-environment: - LDFLAGS: ${LDFLAGS:+$LDFLAGS} -s build-packages: - - yasm - libdrm-dev - libegl-dev - libgbm-dev From 8e9630459b91a6def5130e50ec71c4c0bad08fa9 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 8 Jul 2025 21:32:15 +0400 Subject: [PATCH 08/10] Add session_id to mtproto logs. --- Telegram/SourceFiles/mtproto/session_private.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Telegram/SourceFiles/mtproto/session_private.cpp b/Telegram/SourceFiles/mtproto/session_private.cpp index 0786eb68ea..4458537725 100644 --- a/Telegram/SourceFiles/mtproto/session_private.cpp +++ b/Telegram/SourceFiles/mtproto/session_private.cpp @@ -1388,9 +1388,10 @@ void SessionPrivate::handleReceived() { auto sfrom = decryptedInts + 4U; // msg_id + seq_no + length + message MTP_LOG(_shiftedDcId, ("Recv: ") + DumpToText(sfrom, end) - + QString(" (dc:%1,key:%2)" + + QString(" (dc:%1,key:%2,session:%3)" ).arg(AbstractConnection::ProtocolDcDebugId(getProtocolDcId()) - ).arg(_encryptionKey->keyId())); + ).arg(_encryptionKey->keyId() + ).arg(_sessionId)); const auto registered = _receivedMessageIds.registerMsgId( msgId, @@ -2663,9 +2664,10 @@ bool SessionPrivate::sendSecureRequest( auto from = request->constData() + 4; MTP_LOG(_shiftedDcId, ("Send: ") + DumpToText(from, from + messageSize) - + QString(" (dc:%1,key:%2)" + + QString(" (dc:%1,key:%2,session:%3)" ).arg(AbstractConnection::ProtocolDcDebugId(getProtocolDcId()) - ).arg(_encryptionKey->keyId())); + ).arg(_encryptionKey->keyId() + ).arg(_sessionId)); uchar encryptedSHA256[32]; MTPint128 &msgKey(*(MTPint128*)(encryptedSHA256 + 8)); From c7c8e39e20036a89d8b57668a633b447fbe1ce18 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 8 Jul 2025 22:44:23 +0400 Subject: [PATCH 09/10] Fix build with Xcode. --- Telegram/SourceFiles/boxes/star_gift_box.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/boxes/star_gift_box.cpp b/Telegram/SourceFiles/boxes/star_gift_box.cpp index 473e840881..64ce31f976 100644 --- a/Telegram/SourceFiles/boxes/star_gift_box.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_box.cpp @@ -3934,7 +3934,9 @@ void AddUniqueGiftCover( st::uniqueGiftTitle); title->setTextColorOverride(QColor(255, 255, 255)); auto subtitleText = subtitleOverride - ? std::move(subtitleOverride) | Ui::Text::ToWithEntities() + ? std::move( + subtitleOverride + ) | Ui::Text::ToWithEntities() | rpl::type_erased() : rpl::duplicate(data) | rpl::map([=](const Data::UniqueGift &gift) { released->by = gift.releasedBy; released->bg = gift.backdrop.patternColor; From 36bb1d0cf36311503b87aa38a573e82fb835f86a Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 8 Jul 2025 20:36:01 +0400 Subject: [PATCH 10/10] Version 5.16.3. - Allow removing / charging fee in channel direct messages. - Don't offer creating checklists in channels. - Support author channel in gifts. --- Telegram/Resources/uwp/AppX/AppxManifest.xml | 2 +- Telegram/Resources/winrc/Telegram.rc | 8 ++++---- Telegram/Resources/winrc/Updater.rc | 8 ++++---- Telegram/SourceFiles/core/version.h | 4 ++-- Telegram/build/version | 8 ++++---- changelog.txt | 6 ++++++ 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml index 135f939788..d83d286216 100644 --- a/Telegram/Resources/uwp/AppX/AppxManifest.xml +++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml @@ -10,7 +10,7 @@ + Version="5.16.3.0" /> Telegram Desktop Telegram Messenger LLP diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 2aeaf0992a..a81de76d0c 100644 --- a/Telegram/Resources/winrc/Telegram.rc +++ b/Telegram/Resources/winrc/Telegram.rc @@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,16,2,0 - PRODUCTVERSION 5,16,2,0 + FILEVERSION 5,16,3,0 + PRODUCTVERSION 5,16,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -62,10 +62,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram FZ-LLC" VALUE "FileDescription", "Telegram Desktop" - VALUE "FileVersion", "5.16.2.0" + VALUE "FileVersion", "5.16.3.0" VALUE "LegalCopyright", "Copyright (C) 2014-2025" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "5.16.2.0" + VALUE "ProductVersion", "5.16.3.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index 4862417ab9..57117fa387 100644 --- a/Telegram/Resources/winrc/Updater.rc +++ b/Telegram/Resources/winrc/Updater.rc @@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,16,2,0 - PRODUCTVERSION 5,16,2,0 + FILEVERSION 5,16,3,0 + PRODUCTVERSION 5,16,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -53,10 +53,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram FZ-LLC" VALUE "FileDescription", "Telegram Desktop Updater" - VALUE "FileVersion", "5.16.2.0" + VALUE "FileVersion", "5.16.3.0" VALUE "LegalCopyright", "Copyright (C) 2014-2025" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "5.16.2.0" + VALUE "ProductVersion", "5.16.3.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index ec622ba213..ff09ba824e 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D1ED}"_cs; constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs; constexpr auto AppName = "Telegram Desktop"_cs; constexpr auto AppFile = "Telegram"_cs; -constexpr auto AppVersion = 5016002; -constexpr auto AppVersionStr = "5.16.2"; +constexpr auto AppVersion = 5016003; +constexpr auto AppVersionStr = "5.16.3"; constexpr auto AppBetaVersion = false; constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION; diff --git a/Telegram/build/version b/Telegram/build/version index ecab5bf25c..4d8e1cfc6a 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,7 +1,7 @@ -AppVersion 5016002 +AppVersion 5016003 AppVersionStrMajor 5.16 -AppVersionStrSmall 5.16.2 -AppVersionStr 5.16.2 +AppVersionStrSmall 5.16.3 +AppVersionStr 5.16.3 BetaChannel 0 AlphaVersion 0 -AppVersionOriginal 5.16.2 +AppVersionOriginal 5.16.3 diff --git a/changelog.txt b/changelog.txt index 91d27aedda..3474436d1e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,9 @@ +5.16.3 (08.07.25) + +- Allow removing / charging fee in channel direct messages. +- Don't offer creating checklists in channels. +- Support author channel in gifts. + 5.16.2 (04.07.25) - Fix crash in some checklists.