From f5036171cf8ca4e6d2caf3e7ec9cbdce5e9ce7ec Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 20 Nov 2025 22:24:16 +0400 Subject: [PATCH] Add actions menu (about/copy/share) for auctions. --- .../boxes/star_gift_auction_box.cpp | 88 +++++++++++++++---- Telegram/SourceFiles/calls/calls.style | 6 +- .../calls/group/calls_group_common.cpp | 2 +- Telegram/lib_ui | 2 +- 4 files changed, 76 insertions(+), 22 deletions(-) diff --git a/Telegram/SourceFiles/boxes/star_gift_auction_box.cpp b/Telegram/SourceFiles/boxes/star_gift_auction_box.cpp index 40c9803174..469e5462f5 100644 --- a/Telegram/SourceFiles/boxes/star_gift_auction_box.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_auction_box.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/unixtime.h" #include "boxes/peers/replace_boost_box.h" #include "boxes/send_credits_box.h" // CreditsEmojiSmall +#include "boxes/share_box.h" #include "boxes/star_gift_box.h" #include "calls/group/calls_group_common.h" #include "core/credits_amount.h" @@ -42,8 +43,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/text/format_values.h" #include "ui/text/text_utilities.h" #include "ui/toast/toast.h" -#include "ui/widgets/buttons.h" #include "ui/widgets/fields/number_input.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/popup_menu.h" #include "ui/wrap/table_layout.h" #include "ui/color_int_conversion.h" #include "ui/dynamic_thumbnails.h" @@ -60,6 +62,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_premium.h" #include "styles/style_settings.h" +#include +#include + namespace Ui { namespace { @@ -266,6 +271,37 @@ struct BidSliderValues { return result; } +Fn MakeAuctionMenuCallback( + not_null parent, + std::shared_ptr show, + const Data::GiftAuctionState &state) { + const auto url = show->session().createInternalLinkFull( + u"auction/"_q + state.gift->auctionSlug); + const auto rounds = state.totalRounds; + const auto perRound = state.gift->auctionGiftsPerRound;; + const auto menu = std::make_shared>(); + return [=] { + *menu = base::make_unique_q( + parent, + st::popupMenuWithIcons); + + (*menu)->addAction(tr::lng_auction_menu_about(tr::now), [=] { + show->show(Box(AuctionAboutBox, rounds, perRound, nullptr)); + }, &st::menuIconInfo); + + (*menu)->addAction(tr::lng_auction_menu_copy_link(tr::now), [=] { + QApplication::clipboard()->setText(url); + show->showToast(tr::lng_username_copied(tr::now)); + }, &st::menuIconLink); + + (*menu)->addAction(tr::lng_auction_menu_share(tr::now), [=] { + FastShareLink(show, url); + }, &st::menuIconShare); + + (*menu)->popup(QCursor::pos()); + }; +} + void PlaceAuctionBid( std::shared_ptr show, not_null to, @@ -692,6 +728,11 @@ void AuctionBidBox(not_null box, AuctionBidBoxArgs &&args) { box->addTopButton( st::boxTitleClose, [=] { box->closeBox(); }); + if (const auto now = state->value.current(); !now.finished()) { + box->addTopButton( + st::boxTitleMenu, + MakeAuctionMenuCallback(box, show, now)); + } const auto skip = st::paidReactTitleSkip; box->addRow( @@ -1025,16 +1066,19 @@ void AuctionInfoBox( std::vector acquired; bool acquiredRequested = false; + + base::unique_qptr menu; }; const auto show = window->uiShow(); const auto state = box->lifetime().make_state(&show->session()); state->value = std::move(value); - state->minutesLeft = MinutesLeftTillValue( - state->value.current().endDate); + const auto &now = state->value.current(); + + state->minutesLeft = MinutesLeftTillValue(now.endDate); box->setStyle(st::giftBox); - const auto name = state->value.current().gift->resellTitle; + const auto name = now.gift->resellTitle; const auto extend = st::defaultDropdownMenu.wrap.shadow.extend; const auto side = st::giftBoxGiftSmall; const auto size = QSize(side, side).grownBy(extend); @@ -1044,7 +1088,7 @@ void AuctionInfoBox( const auto gift = CreateChild(preview, &state->delegate); gift->setAttribute(Qt::WA_TransparentForMouseEvents); gift->setDescriptor(GiftTypeStars{ - .info = *state->value.current().gift, + .info = *now.gift, }, GiftButtonMode::Minimal); preview->widthValue() | rpl::start_with_next([=](int width) { @@ -1179,25 +1223,39 @@ void AuctionInfoBox( AuctionButtonCountdownType::Join, state->value.value()); + box->setNoContentMargin(true); + const auto close = CreateChild( + box->verticalLayout(), + st::boxTitleClose); + close->setClickedCallback([=] { box->closeBox(); }); + + const auto menu = CreateChild( + box->verticalLayout(), + st::boxTitleMenu); + menu->setClickedCallback(MakeAuctionMenuCallback(menu, show, now)); + const auto weakMenu = base::make_weak(menu); + + box->verticalLayout()->widthValue() | rpl::start_with_next([=](int) { + close->moveToRight(0, 0); + if (const auto strong = weakMenu.get()) { + strong->moveToRight(close->width(), 0); + } + }, close->lifetime()); + rpl::combine( state->value.value(), state->minutesLeft.value() ) | rpl::start_with_next([=]( const Data::GiftAuctionState &state, int minutes) { - about->setTextColorOverride((state.finished() || minutes <= 0) + const auto finished = state.finished() || (minutes <= 0); + about->setTextColorOverride(finished ? st::attentionButtonFg->c : std::optional()); + if (const auto strong = finished ? weakMenu.get() : nullptr) { + delete strong; + } }, box->lifetime()); - - box->setNoContentMargin(true); - const auto close = CreateChild( - box->verticalLayout(), - st::boxTitleClose); - close->setClickedCallback([=] { box->closeBox(); }); - box->verticalLayout()->widthValue() | rpl::start_with_next([=](int) { - close->moveToRight(0, 0); - }, close->lifetime()); } base::weak_qptr ChooseAndShowAuctionBox( diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index 01fc76bbc2..9cb384513f 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -1727,11 +1727,7 @@ groupCallTopReactorBadge: RoundCheckbox(defaultRoundCheckbox) { border: groupCallMembersBg; } -confcallLinkMenu: IconButton(boxTitleClose) { - icon: icon {{ "title_menu_dots", boxTitleCloseFg }}; - iconOver: icon {{ "title_menu_dots", boxTitleCloseFgOver }}; -} -groupCallLinkMenu: IconButton(confcallLinkMenu) { +groupCallLinkMenu: IconButton(boxTitleMenu) { icon: icon {{ "title_menu_dots", groupCallMemberInactiveIcon }}; iconOver: icon {{ "title_menu_dots", groupCallMemberInactiveIcon }}; ripple: RippleAnimation(defaultRippleAnimation) { diff --git a/Telegram/SourceFiles/calls/group/calls_group_common.cpp b/Telegram/SourceFiles/calls/group/calls_group_common.cpp index c21168430f..d473d2ec1a 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_common.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_common.cpp @@ -279,7 +279,7 @@ void ShowConferenceCallLinkBox( if (!args.initial && call->canManage()) { const auto toggle = Ui::CreateChild( close->parentWidget(), - st.menuToggle ? *st.menuToggle : st::confcallLinkMenu); + st.menuToggle ? *st.menuToggle : st::boxTitleMenu); const auto handler = [=] { if (state->resetting) { return; diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 598912bd7f..9fbbcfd466 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 598912bd7fe300d3534547621a691ab72b5bcfb4 +Subproject commit 9fbbcfd46679f9f61ff072beb8bf507166f852a2