From b3f9a77ba7154d26ab6d7c8f950368f3bc488e9e Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 28 Feb 2025 12:08:26 +0400 Subject: [PATCH] Star-count button in SendFilesBox/ShareBox. --- .../boxes/peers/edit_peer_invite_link.cpp | 8 ++- .../SourceFiles/boxes/send_credits_box.cpp | 8 +-- Telegram/SourceFiles/boxes/send_files_box.cpp | 28 ++++++++- Telegram/SourceFiles/boxes/send_files_box.h | 2 + Telegram/SourceFiles/boxes/share_box.cpp | 59 ++++++++++++++++--- Telegram/SourceFiles/boxes/share_box.h | 9 ++- .../calls/group/calls_group_settings.cpp | 8 ++- .../chat_helpers/chat_helpers.style | 5 ++ .../media/stories/media_stories_share.cpp | 11 +++- .../SourceFiles/window/window_peer_menu.cpp | 15 +++-- Telegram/lib_ui | 2 +- 11 files changed, 128 insertions(+), 27 deletions(-) diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp index 288a09353..38eb775f6 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp @@ -1484,9 +1484,12 @@ object_ptr ShareInviteLinkBox( ? tr::lng_group_invite_copied(tr::now) : copied); }; + auto countMessagesCallback = [=](const TextWithTags &comment) { + return 1; + }; auto submitCallback = [=]( std::vector> &&result, - Fn checkPaid, + Fn checkPaid, TextWithTags &&comment, Api::SendOptions options, Data::ForwardOptions) { @@ -1504,7 +1507,7 @@ object_ptr ShareInviteLinkBox( result.size() > 1)); } return; - } else if (!checkPaid(1)) { + } else if (!checkPaid()) { return; } @@ -1542,6 +1545,7 @@ object_ptr ShareInviteLinkBox( auto object = Box(ShareBox::Descriptor{ .session = session, .copyCallback = std::move(copyCallback), + .countMessagesCallback = std::move(countMessagesCallback), .submitCallback = std::move(submitCallback), .filterCallback = std::move(filterCallback), .moneyRestrictionError = ShareMessageMoneyRestrictionError(), diff --git a/Telegram/SourceFiles/boxes/send_credits_box.cpp b/Telegram/SourceFiles/boxes/send_credits_box.cpp index 204afadac..e7c9d0f9a 100644 --- a/Telegram/SourceFiles/boxes/send_credits_box.cpp +++ b/Telegram/SourceFiles/boxes/send_credits_box.cpp @@ -39,6 +39,7 @@ 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 @@ -511,11 +512,8 @@ TextWithEntities CreditsEmoji(not_null session) { } TextWithEntities CreditsEmojiSmall(not_null session) { - return Ui::Text::SingleCustomEmoji( - session->data().customEmojiManager().registerInternalEmoji( - st::starIconSmall, - st::starIconSmallPadding, - true), + return Ui::Text::IconEmoji( + &st::boxStarIconEmoji, QString(QChar(0x2B50))); } diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index b7e987b6e..b86be64c8 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -59,9 +59,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_session_controller.h" #include "core/application.h" #include "core/core_settings.h" -#include "styles/style_layers.h" #include "styles/style_boxes.h" #include "styles/style_chat_helpers.h" +#include "styles/style_layers.h" #include @@ -714,6 +714,18 @@ void SendFilesBox::openDialogToAddFileToAlbum() { crl::guard(this, callback)); } +void SendFilesBox::refreshMessagesCount() { + const auto way = _sendWay.current(); + const auto withCaption = _list.canAddCaption( + way.groupFiles() && way.sendImagesAsPhotos(), + way.sendImagesAsPhotos()); + const auto withComment = !withCaption + && _caption + && !_caption->isHidden() + && !_caption->getTextWithTags().text.isEmpty(); + _messagesCount = _list.files.size() + (withComment ? 1 : 0); +} + void SendFilesBox::refreshButtons() { clearButtons(); @@ -722,6 +734,19 @@ void SendFilesBox::refreshButtons() { ? tr::lng_send_button() : tr::lng_create_group_next()), [=] { send({}); }); + refreshMessagesCount(); + + const auto perMessage = _captionToPeer + ? _captionToPeer->starsPerMessageChecked() + : 0; + if (perMessage > 0) { + _send->setText(_messagesCount.value( + ) | rpl::map([=](int count) { + const auto stars = count * perMessage; + return Ui::Text::IconEmoji(&st::boxStarIconEmoji).append( + Lang::FormatCountToShort(stars).string); + })); + } if (_sendType == Api::SendType::Normal) { SendMenu::SetupMenuAndShortcuts( _send, @@ -1451,6 +1476,7 @@ void SendFilesBox::setupCaption() { _caption->changes() ) | rpl::start_with_next([=] { checkCharsLimitation(); + refreshMessagesCount(); }, _caption->lifetime()); } diff --git a/Telegram/SourceFiles/boxes/send_files_box.h b/Telegram/SourceFiles/boxes/send_files_box.h index 9a0fea06d..92ba0e3c3 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.h +++ b/Telegram/SourceFiles/boxes/send_files_box.h @@ -246,6 +246,7 @@ private: void addPreparedAsyncFile(Ui::PreparedFile &&file); void checkCharsLimitation(); + void refreshMessagesCount(); [[nodiscard]] Fn prepareSendMenuDetails( const SendFilesBoxDescriptor &descriptor); @@ -261,6 +262,7 @@ private: Ui::PreparedList _list; std::optional _removingIndex; + rpl::variable _messagesCount; SendFilesLimits _limits = {}; Fn _sendMenuDetails; diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index e23dd7165..ad0f7ef97 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -54,6 +54,7 @@ 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" @@ -620,6 +621,13 @@ void ShareBox::createButtons() { showMenu(send); } }, send->lifetime()); + send->setText(_starsToSend.value() | rpl::map([=](int stars) { + using namespace Ui; + return stars + ? Text::IconEmoji(&st::boxStarIconEmoji).append( + Lang::FormatCountToShort(stars).string) + : tr::lng_share_confirm(tr::now, Text::WithEntities); + })); } else if (_descriptor.copyCallback) { addButton(_copyLinkText.value(), [=] { copyLink(); }); } @@ -667,13 +675,19 @@ void ShareBox::submit(Api::SendOptions options) { auto threads = _inner->selected(); const auto weak = Ui::MakeWeak(this); - const auto checkPaid = [=](int messagesCount) { + const auto field = _comment->entity(); + auto comment = field->getTextWithAppliedMarkdown(); + const auto checkPaid = [=] { + if (!_descriptor.countMessagesCallback) { + return true; + } const auto withPaymentApproved = crl::guard(weak, [=](int approved) { auto copy = options; copy.starsApproved = approved; submit(copy); }); - + const auto messagesCount = _descriptor.countMessagesCallback( + comment); const auto alreadyApproved = options.starsApproved; auto paid = std::vector>(); auto waiting = base::flat_set>(); @@ -734,7 +748,7 @@ void ShareBox::submit(Api::SendOptions options) { onstack( std::move(threads), checkPaid, - _comment->entity()->getTextWithAppliedMarkdown(), + std::move(comment), options, forwardOptions); } @@ -754,9 +768,23 @@ void ShareBox::selectedChanged() { _comment->toggle(_hasSelected, anim::type::normal); _comment->resizeToWidth(st::boxWideWidth); } + computeStarsCount(); update(); } +void ShareBox::computeStarsCount() { + auto perMessage = 0; + for (const auto &thread : _inner->selected()) { + perMessage += thread->peer()->starsPerMessageChecked(); + } + const auto messagesCount = _descriptor.countMessagesCallback + ? _descriptor.countMessagesCallback(_comment + ? _comment->entity()->getTextWithTags() + : TextWithTags()) + : 0; + _starsToSend = perMessage * messagesCount; +} + void ShareBox::scrollTo(Ui::ScrollToRequest request) { scrollToY(request.ymin, request.ymax); //auto scrollTop = scrollArea()->scrollTop(), scrollBottom = scrollTop + scrollArea()->height(); @@ -1568,6 +1596,15 @@ ChatHelpers::ForwardedMessagePhraseArgs CreateForwardedMessagePhraseArgs( }; } +ShareBox::CountMessagesCallback ShareBox::DefaultForwardCountMessages( + not_null history, + MessageIdsList msgIds) { + return [=](const TextWithTags &comment) { + const auto items = history->owner().idsToItems(msgIds); + return int(items.size()) + (comment.empty() ? 0 : 1); + }; +} + ShareBox::SubmitCallback ShareBox::DefaultForwardCallback( std::shared_ptr show, not_null history, @@ -1579,7 +1616,7 @@ ShareBox::SubmitCallback ShareBox::DefaultForwardCallback( const auto state = std::make_shared(); return [=]( std::vector> &&result, - Fn checkPaid, + Fn checkPaid, TextWithTags comment, Api::SendOptions options, Data::ForwardOptions forwardOptions) { @@ -1593,14 +1630,13 @@ ShareBox::SubmitCallback ShareBox::DefaultForwardCallback( return; } - auto messagesCount = int(items.size()) + (comment.empty() ? 0 : 1); const auto error = GetErrorForSending( result, { .forward = &items, .text = &comment }); if (error.error) { show->showBox(MakeSendErrorBox(error, result.size() > 1)); return; - } else if (!checkPaid(messagesCount)) { + } else if (!checkPaid()) { return; } @@ -1811,6 +1847,9 @@ void FastShareMessage( show->show(Box(ShareBox::Descriptor{ .session = session, .copyCallback = std::move(copyLinkCallback), + .countMessagesCallback = ShareBox::DefaultForwardCountMessages( + history, + msgIds), .submitCallback = ShareBox::DefaultForwardCallback( show, history, @@ -1850,9 +1889,12 @@ void FastShareLink( QGuiApplication::clipboard()->setText(url); show->showToast(tr::lng_background_link_copied(tr::now)); }; + auto countMessagesCallback = [=](const TextWithTags &comment) { + return 1; + }; auto submitCallback = [=]( std::vector> &&result, - Fn checkPaid, + Fn checkPaid, TextWithTags &&comment, Api::SendOptions options, ::Data::ForwardOptions) { @@ -1869,7 +1911,7 @@ void FastShareLink( MakeSendErrorBox(error, result.size() > 1)); } return; - } else if (!checkPaid(1)) { + } else if (!checkPaid()) { return; } @@ -1908,6 +1950,7 @@ void FastShareLink( Box(ShareBox::Descriptor{ .session = &show->session(), .copyCallback = std::move(copyCallback), + .countMessagesCallback = std::move(countMessagesCallback), .submitCallback = std::move(submitCallback), .filterCallback = std::move(filterCallback), .st = st, diff --git a/Telegram/SourceFiles/boxes/share_box.h b/Telegram/SourceFiles/boxes/share_box.h index 07227ee98..5cbfb794d 100644 --- a/Telegram/SourceFiles/boxes/share_box.h +++ b/Telegram/SourceFiles/boxes/share_box.h @@ -95,14 +95,18 @@ struct RecipientMoneyRestrictionError; class ShareBox final : public Ui::BoxContent { public: using CopyCallback = Fn; + using CountMessagesCallback = Fn; using SubmitCallback = Fn>&&, - Fn checkPaid, + Fn checkPaid, TextWithTags&&, Api::SendOptions, Data::ForwardOptions)>; using FilterCallback = Fn)>; + [[nodiscard]] static auto DefaultForwardCountMessages( + not_null history, + MessageIdsList msgIds) -> CountMessagesCallback; [[nodiscard]] static SubmitCallback DefaultForwardCallback( std::shared_ptr show, not_null history, @@ -112,6 +116,7 @@ public: struct Descriptor { not_null session; CopyCallback copyCallback; + CountMessagesCallback countMessagesCallback; SubmitCallback submitCallback; FilterCallback filterCallback; object_ptr bottomWidget = { nullptr }; @@ -152,6 +157,7 @@ private: void needSearchByUsername(); void applyFilterUpdate(const QString &query); void selectedChanged(); + void computeStarsCount(); void createButtons(); int getTopScrollSkip() const; int getBottomScrollSkip() const; @@ -183,6 +189,7 @@ private: bool _hasSelected = false; rpl::variable _copyLinkText; + rpl::variable _starsToSend; base::Timer _searchTimer; QString _peopleQuery; diff --git a/Telegram/SourceFiles/calls/group/calls_group_settings.cpp b/Telegram/SourceFiles/calls/group/calls_group_settings.cpp index dec18b742..7c2bdfd4c 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_settings.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_settings.cpp @@ -132,9 +132,12 @@ object_ptr ShareInviteLinkBox( QGuiApplication::clipboard()->setText(currentLink()); show->showToast(tr::lng_group_invite_copied(tr::now)); }; + auto countMessagesCallback = [=](const TextWithTags &comment) { + return 1; + }; auto submitCallback = [=]( std::vector> &&result, - Fn checkPaid, + Fn checkPaid, TextWithTags &&comment, Api::SendOptions options, Data::ForwardOptions) { @@ -151,7 +154,7 @@ object_ptr ShareInviteLinkBox( MakeSendErrorBox(error, result.size() > 1)); } return; - } else if (!checkPaid(1)) { + } else if (!checkPaid()) { return; } @@ -192,6 +195,7 @@ object_ptr ShareInviteLinkBox( auto result = Box(ShareBox::Descriptor{ .session = &peer->session(), .copyCallback = std::move(copyCallback), + .countMessagesCallback = std::move(countMessagesCallback), .submitCallback = std::move(submitCallback), .filterCallback = std::move(filterCallback), .bottomWidget = std::move(bottom), diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style index d0d59bb5a..cf7eec9de 100644 --- a/Telegram/SourceFiles/chat_helpers/chat_helpers.style +++ b/Telegram/SourceFiles/chat_helpers/chat_helpers.style @@ -1364,6 +1364,11 @@ 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/media/stories/media_stories_share.cpp b/Telegram/SourceFiles/media/stories/media_stories_share.cpp index d00da018c..80ec8e75b 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_share.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_share.cpp @@ -76,9 +76,12 @@ namespace Media::Stories { auto copyLinkCallback = canCopyLink ? Fn(std::move(copyCallback)) : Fn(); + auto countMessagesCallback = [=](const TextWithTags &comment) { + return comment.text.isEmpty() ? 1 : 2; + }; auto submitCallback = [=]( std::vector> &&result, - Fn checkPaid, + Fn checkPaid, TextWithTags &&comment, Api::SendOptions options, Data::ForwardOptions forwardOptions) { @@ -96,7 +99,7 @@ namespace Media::Stories { if (error.error) { show->showBox(MakeSendErrorBox(error, result.size() > 1)); return; - } else if (!checkPaid(comment.text.isEmpty() ? 1 : 2)) { + } else if (!checkPaid()) { return; } @@ -187,6 +190,7 @@ namespace Media::Stories { return Box(ShareBox::Descriptor{ .session = session, .copyCallback = std::move(copyLinkCallback), + .countMessagesCallback = std::move(countMessagesCallback), .submitCallback = std::move(submitCallback), .filterCallback = std::move(filterCallback), .st = st.shareBox ? *st.shareBox : ShareBoxStyleOverrides(), @@ -254,6 +258,9 @@ object_ptr PrepareShareAtTimeBox( return Box(ShareBox::Descriptor{ .session = session, .copyCallback = std::move(copyLinkCallback), + .countMessagesCallback = ShareBox::DefaultForwardCountMessages( + history, + { id }), .submitCallback = ShareBox::DefaultForwardCallback( show, history, diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 1e794a30f..7cf15e6ee 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -2463,15 +2463,21 @@ QPointer ShowForwardMessagesBox( tr::lng_photos_comment()), st::shareCommentPadding); + const auto history = session->data().message(msgIds.front())->history(); const auto send = ShareBox::DefaultForwardCallback( show, - session->data().message(msgIds.front())->history(), + history, + msgIds); + const auto countMessages = ShareBox::DefaultForwardCountMessages( + history, msgIds); const auto weak = Ui::MakeWeak(state->box); + const auto field = comment->entity(); state->submit = [=](Api::SendOptions options) { const auto peers = state->box->collectSelectedRows(); - const auto checkPaid = [=](int messagesCount) { + auto comment = field->getTextWithAppliedMarkdown(); + const auto checkPaid = [=] { const auto withPaymentApproved = crl::guard(weak, [=]( int approved) { auto copy = options; @@ -2482,6 +2488,7 @@ QPointer ShowForwardMessagesBox( }); const auto alreadyApproved = options.starsApproved; + const auto messagesCount = countMessages(comment); auto paid = std::vector>(); auto waiting = base::flat_set>(); auto totalStars = 0; @@ -2532,7 +2539,7 @@ QPointer ShowForwardMessagesBox( return peer->owner().history(peer); }) | ranges::to_vector, checkPaid, - comment->entity()->getTextWithAppliedMarkdown(), + std::move(comment), options, state->box->forwardOptionsData()); if (!state->submit && successCallback) { @@ -2628,8 +2635,6 @@ QPointer ShowForwardMessagesBox( state->box->setBottomSkip(comment->isHidden() ? 0 : commentHeight); }, comment->lifetime()); - const auto field = comment->entity(); - field->submits( ) | rpl::start_with_next([=] { if (const auto onstack = state->submit) { diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 2a5d66fb1..cfecbd3df 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 2a5d66fb1b9f97eacc3e73c324944a8d77c38e51 +Subproject commit cfecbd3df4c1d0bfba3d708dfb49387c8ae2127b