From 97b021efaf66a67ca27ce41fd2e78570eeb3fd34 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 28 Feb 2025 12:57:39 +0400 Subject: [PATCH] Star-count button in multi-Forward/CreatePoll. --- Telegram/SourceFiles/boxes/boxes.style | 5 + .../SourceFiles/boxes/create_poll_box.cpp | 18 ++- Telegram/SourceFiles/boxes/create_poll_box.h | 2 + .../SourceFiles/boxes/send_credits_box.cpp | 1 - Telegram/SourceFiles/boxes/share_box.cpp | 1 - .../chat_helpers/chat_helpers.style | 5 - .../SourceFiles/window/window_peer_menu.cpp | 120 +++++++++++++----- 7 files changed, 111 insertions(+), 41 deletions(-) diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 827b0c0b34..90e59cd78a 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -30,6 +30,11 @@ ShortInfoBox { labeledOneLine: FlatLabel; } +boxStarIconEmoji: IconEmoji { + icon: icon{{ "payments/small_star", windowFg }}; + padding: margins(0px, -2px, 0px, 0px); +} + countryRowHeight: 36px; countryRowNameFont: semiboldFont; countryRowNameFg: boxTextFg; diff --git a/Telegram/SourceFiles/boxes/create_poll_box.cpp b/Telegram/SourceFiles/boxes/create_poll_box.cpp index 223c5cab47..517b1f5e35 100644 --- a/Telegram/SourceFiles/boxes/create_poll_box.cpp +++ b/Telegram/SourceFiles/boxes/create_poll_box.cpp @@ -817,13 +817,15 @@ CreatePollBox::CreatePollBox( not_null controller, PollData::Flags chosen, PollData::Flags disabled, + rpl::producer starsRequired, Api::SendType sendType, SendMenu::Details sendMenuDetails) : _controller(controller) , _chosen(chosen) , _disabled(disabled) , _sendType(sendType) -, _sendMenuDetails([result = sendMenuDetails] { return result; }) { +, _sendMenuDetails([result = sendMenuDetails] { return result; }) +, _starsRequired(std::move(starsRequired)) { } rpl::producer CreatePollBox::submitRequests() const { @@ -1226,10 +1228,18 @@ object_ptr CreatePollBox::setupContent() { _sendMenuDetails()); }; const auto submit = addButton( - (isNormal - ? tr::lng_polls_create_button() - : tr::lng_schedule_button()), + tr::lng_polls_create_button(), [=] { isNormal ? send({}) : schedule(); }); + submit->setText(_starsRequired.value() | rpl::map([=](int stars) { + using namespace Ui; + if (!stars) { + return (isNormal + ? tr::lng_polls_create_button + : tr::lng_schedule_button)(tr::now, Text::WithEntities); + } + return Text::IconEmoji(&st::boxStarIconEmoji).append( + Lang::FormatCountToShort(stars).string); + })); const auto sendMenuDetails = [=] { collectError(); return (*error) ? SendMenu::Details() : _sendMenuDetails(); diff --git a/Telegram/SourceFiles/boxes/create_poll_box.h b/Telegram/SourceFiles/boxes/create_poll_box.h index 91fc290ca4..33fbdd3f1e 100644 --- a/Telegram/SourceFiles/boxes/create_poll_box.h +++ b/Telegram/SourceFiles/boxes/create_poll_box.h @@ -42,6 +42,7 @@ public: not_null controller, PollData::Flags chosen, PollData::Flags disabled, + rpl::producer starsRequired, Api::SendType sendType, SendMenu::Details sendMenuDetails); @@ -76,6 +77,7 @@ private: const PollData::Flags _disabled = PollData::Flags(); const Api::SendType _sendType = Api::SendType(); const Fn _sendMenuDetails; + rpl::variable _starsRequired; base::unique_qptr _emojiPanel; Fn _setInnerFocus; Fn()> _dataIsValidValue; diff --git a/Telegram/SourceFiles/boxes/send_credits_box.cpp b/Telegram/SourceFiles/boxes/send_credits_box.cpp index e7c9d0f9aa..d1e74eeed2 100644 --- a/Telegram/SourceFiles/boxes/send_credits_box.cpp +++ b/Telegram/SourceFiles/boxes/send_credits_box.cpp @@ -39,7 +39,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/peer_bubble.h" #include "styles/style_boxes.h" #include "styles/style_chat.h" -#include "styles/style_chat_helpers.h" #include "styles/style_credits.h" #include "styles/style_giveaway.h" #include "styles/style_info.h" // inviteLinkSubscribeBoxTerms diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index ad0f7ef972..5912dd3126 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -54,7 +54,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/application.h" #include "core/core_settings.h" #include "styles/style_calls.h" -#include "styles/style_chat_helpers.h" #include "styles/style_layers.h" #include "styles/style_boxes.h" #include "styles/style_menu_icons.h" diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style index cf7eec9de3..d0d59bb5ac 100644 --- a/Telegram/SourceFiles/chat_helpers/chat_helpers.style +++ b/Telegram/SourceFiles/chat_helpers/chat_helpers.style @@ -1364,11 +1364,6 @@ defaultComposeControls: ComposeControls { restrictionLabel: defaultRestrictionLabel; } -boxStarIconEmoji: IconEmoji { - icon: icon{{ "payments/small_star", windowFg }}; - padding: margins(0px, -2px, 0px, 0px); -} - moreChatsBarHeight: 48px; moreChatsBarTextPosition: point(12px, 4px); moreChatsBarStatusPosition: point(12px, 24px); diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 7cf15e6ee5..fd2c666f15 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -1762,10 +1762,18 @@ void PeerMenuCreatePoll( chosen &= ~PollData::Flag::PublicVotes; disabled |= PollData::Flag::PublicVotes; } + auto starsRequired = peer->session().changes().peerFlagsValue( + peer, + Data::PeerUpdate::Flag::FullInfo + | Data::PeerUpdate::Flag::StarsPerMessage + ) | rpl::map([=] { + return peer->starsPerMessageChecked(); + }); auto box = Box( controller, chosen, disabled, + std::move(starsRequired), sendType, sendMenuDetails); struct State { @@ -1996,8 +2004,7 @@ object_ptr PrepareChooseRecipientBox( ChooseRecipientBoxController::rowClicked(row); } else { delegate()->peerListSetRowChecked(row, !row->checked()); - _hasSelectedChanges.fire( - delegate()->peerListSelectedRowsCount() > 0); + _selectionChanges.fire({}); } } @@ -2015,16 +2022,18 @@ object_ptr PrepareChooseRecipientBox( st::popupMenuWithIcons); menu->addAction(tr::lng_bot_choose_chat(tr::now), [=] { delegate()->peerListSetRowChecked(row, true); - _hasSelectedChanges.fire( - delegate()->peerListSelectedRowsCount() > 0); + _selectionChanges.fire({}); }, &st::menuIconSelect); return menu; } return nullptr; } - [[nodiscard]] rpl::producer hasSelectedChanges() const { - return _hasSelectedChanges.events_starting_with(false); + [[nodiscard]] rpl::producer<> selectionChanges() const { + return _selectionChanges.events_starting_with({}); + } + [[nodiscard]] bool hasSelected() const { + return delegate()->peerListSelectedRowsCount() > 0; } [[nodiscard]] rpl::producer singleChosen() const { @@ -2033,7 +2042,7 @@ object_ptr PrepareChooseRecipientBox( private: rpl::event_stream _singleChosen; - rpl::event_stream _hasSelectedChanges; + rpl::event_stream<> _selectionChanges; bool _selectable = false; }; @@ -2078,13 +2087,24 @@ object_ptr PrepareChooseRecipientBox( struct State { Fn submit; + rpl::variable starsToSend; + Fn refreshStarsToSend; rpl::lifetime submitLifetime; }; const auto state = std::make_shared(); auto initBox = [=](not_null box) { - raw->hasSelectedChanges( - ) | rpl::start_with_next([=](bool shown) { + state->refreshStarsToSend = [=] { + auto perMessage = 0; + for (const auto &peer : box->collectSelectedRows()) { + perMessage += peer->starsPerMessageChecked(); + } + state->starsToSend = perMessage; + }; + raw->selectionChanges( + ) | rpl::start_with_next([=] { box->clearButtons(); + state->refreshStarsToSend(); + const auto shown = raw->hasSelected(); if (shown) { const auto weak = Ui::MakeWeak(box); state->submit = [=](Api::SendOptions options) { @@ -2147,11 +2167,21 @@ object_ptr PrepareChooseRecipientBox( return peer->owner().history(peer); }) | ranges::to_vector, options); }; - box->addButton(tr::lng_send_button(), [=] { - if (const auto onstack = state->submit) { - onstack({}); - } - }); + const auto send = box->addButton( + tr::lng_send_button(), + [=] { + if (const auto onstack = state->submit) { + onstack({}); + } + }); + send->setText(state->starsToSend.value( + ) | rpl::map([=](int stars) { + using namespace Ui; + return stars + ? Text::IconEmoji(&st::boxStarIconEmoji).append( + Lang::FormatCountToShort(stars).string) + : tr::lng_send_button(tr::now, Text::WithEntities); + })); } box->addButton(tr::lng_cancel(), [=] { box->closeBox(); @@ -2282,8 +2312,7 @@ QPointer ShowForwardMessagesBox( ChooseRecipientBoxController::rowClicked(row); } else if (count) { delegate()->peerListSetRowChecked(row, !row->checked()); - _hasSelectedChanges.fire( - delegate()->peerListSelectedRowsCount() > 0); + _selectionChanges.fire({}); } } @@ -2296,16 +2325,18 @@ QPointer ShowForwardMessagesBox( st::popupMenuWithIcons); menu->addAction(tr::lng_bot_choose_chat(tr::now), [=] { delegate()->peerListSetRowChecked(row, true); - _hasSelectedChanges.fire( - delegate()->peerListSelectedRowsCount() > 0); + _selectionChanges.fire({}); }, &st::menuIconSelect); return menu; } return nullptr; } - [[nodiscard]] rpl::producer hasSelectedChanges() const { - return _hasSelectedChanges.events_starting_with(false); + [[nodiscard]] rpl::producer<> selectionChanges() const { + return _selectionChanges.events_starting_with({}); + } + [[nodiscard]] bool hasSelected() const { + return delegate()->peerListSelectedRowsCount() > 0; } [[nodiscard]] rpl::producer singleChosen() const{ @@ -2314,7 +2345,7 @@ QPointer ShowForwardMessagesBox( private: rpl::event_stream _singleChosen; - rpl::event_stream _hasSelectedChanges; + rpl::event_stream<> _selectionChanges; }; @@ -2323,6 +2354,8 @@ QPointer ShowForwardMessagesBox( not_null controller; base::unique_qptr menu; Fn submit; + rpl::variable starsToSend; + Fn refreshStarsToSend; rpl::lifetime submitLifetime; }; @@ -2622,8 +2655,20 @@ QPointer ShowForwardMessagesBox( } }; + state->refreshStarsToSend = [=] { + auto perMessage = 0; + for (const auto &peer : state->box->collectSelectedRows()) { + perMessage += peer->starsPerMessageChecked(); + } + state->starsToSend = perMessage + * countMessages(field->getTextWithTags()); + }; + comment->hide(anim::type::instant); - comment->toggleOn(state->controller->hasSelectedChanges()); + comment->toggleOn(state->controller->selectionChanges( + ) | rpl::map([=] { + return state->controller->hasSelected(); + })); rpl::combine( state->box->sizeValue(), @@ -2650,6 +2695,9 @@ QPointer ShowForwardMessagesBox( }, }); field->setSubmitSettings(Core::App().settings().sendSubmitWay()); + field->changes() | rpl::start_with_next([=] { + state->refreshStarsToSend(); + }, field->lifetime()); Ui::SendPendingMoveResizeEvents(comment); @@ -2660,16 +2708,20 @@ QPointer ShowForwardMessagesBox( } }, comment->lifetime()); - state->controller->hasSelectedChanges( - ) | rpl::start_with_next([=](bool shown) { + state->controller->selectionChanges( + ) | rpl::start_with_next([=] { + const auto shown = state->controller->hasSelected(); + state->box->clearButtons(); + state->refreshStarsToSend(); if (shown) { - auto text = tr::lng_send_button(); - const auto send = state->box->addButton(std::move(text), [=] { - if (const auto onstack = state->submit) { - onstack({}); - } - }); + const auto send = state->box->addButton( + tr::lng_send_button(), + [=] { + if (const auto onstack = state->submit) { + onstack({}); + } + }); send->setAcceptBoth(); send->clicks( ) | rpl::start_with_next([=](Qt::MouseButton button) { @@ -2677,6 +2729,14 @@ QPointer ShowForwardMessagesBox( showMenu(send); } }, send->lifetime()); + send->setText(state->starsToSend.value( + ) | rpl::map([=](int stars) { + using namespace Ui; + return stars + ? Text::IconEmoji(&st::boxStarIconEmoji).append( + Lang::FormatCountToShort(stars).string) + : tr::lng_send_button(tr::now, Text::WithEntities); + })); } state->box->addButton(tr::lng_cancel(), [=] { state->box->closeBox();