From d1106e5ae66a30baf21004755ea123f0d5b01d39 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 10 May 2024 14:10:53 +0400 Subject: [PATCH] Check effects availability in all SendMenu-s. --- .../SourceFiles/boxes/create_poll_box.cpp | 43 ++--- Telegram/SourceFiles/boxes/create_poll_box.h | 6 +- Telegram/SourceFiles/boxes/send_files_box.cpp | 53 +++--- Telegram/SourceFiles/boxes/send_files_box.h | 12 +- Telegram/SourceFiles/boxes/share_box.cpp | 43 +++-- Telegram/SourceFiles/boxes/share_box.h | 6 +- .../SourceFiles/boxes/sticker_set_box.cpp | 15 +- Telegram/SourceFiles/boxes/sticker_set_box.h | 4 - .../chat_helpers/compose/compose_show.h | 4 +- .../chat_helpers/emoji_list_widget.cpp | 2 +- .../chat_helpers/emoji_list_widget.h | 2 +- .../chat_helpers/field_autocomplete.cpp | 33 ++-- .../chat_helpers/field_autocomplete.h | 4 +- .../chat_helpers/gifs_list_widget.cpp | 14 +- .../chat_helpers/gifs_list_widget.h | 4 +- .../chat_helpers/stickers_list_widget.cpp | 13 +- .../chat_helpers/stickers_list_widget.h | 2 +- .../chat_helpers/tabbed_selector.cpp | 4 +- .../chat_helpers/tabbed_selector.h | 6 +- .../data/data_message_reactions.cpp | 5 +- .../SourceFiles/history/history_widget.cpp | 61 ++++--- Telegram/SourceFiles/history/history_widget.h | 8 +- .../history_view_compose_controls.cpp | 30 ++-- .../controls/history_view_compose_controls.h | 10 +- .../view/history_view_context_menu.cpp | 2 +- .../view/history_view_replies_section.cpp | 15 +- .../view/history_view_replies_section.h | 4 +- .../view/history_view_schedule_box.cpp | 28 ++- .../history/view/history_view_schedule_box.h | 8 +- .../view/history_view_scheduled_section.cpp | 24 +-- .../view/history_view_scheduled_section.h | 4 +- .../history_view_reactions_selector.cpp | 23 ++- .../history_view_reactions_selector.h | 2 +- .../info_profile_emoji_status_panel.cpp | 2 +- .../inline_bots/bot_attach_web_view.cpp | 2 +- .../inline_bots/inline_results_inner.cpp | 22 +-- .../inline_bots/inline_results_inner.h | 6 +- .../inline_bots/inline_results_widget.cpp | 4 +- .../inline_bots/inline_results_widget.h | 4 +- Telegram/SourceFiles/mainwidget.cpp | 4 +- Telegram/SourceFiles/mainwidget.h | 4 +- .../media/stories/media_stories_reply.cpp | 13 +- .../media/stories/media_stories_reply.h | 6 + .../media/view/media_view_overlay_widget.cpp | 4 +- Telegram/SourceFiles/menu/menu_send.cpp | 166 ++++++++---------- Telegram/SourceFiles/menu/menu_send.h | 38 ++-- .../business/settings_shortcut_messages.cpp | 11 +- .../SourceFiles/window/window_peer_menu.cpp | 21 +-- .../SourceFiles/window/window_peer_menu.h | 2 +- .../window/window_session_controller.cpp | 8 +- 50 files changed, 394 insertions(+), 417 deletions(-) diff --git a/Telegram/SourceFiles/boxes/create_poll_box.cpp b/Telegram/SourceFiles/boxes/create_poll_box.cpp index c7de2a065..8b032b81a 100644 --- a/Telegram/SourceFiles/boxes/create_poll_box.cpp +++ b/Telegram/SourceFiles/boxes/create_poll_box.cpp @@ -910,12 +910,12 @@ CreatePollBox::CreatePollBox( PollData::Flags chosen, PollData::Flags disabled, Api::SendType sendType, - SendMenu::Type sendMenuType) + SendMenu::Details sendMenuDetails) : _controller(controller) , _chosen(chosen) , _disabled(disabled) , _sendType(sendType) -, _sendMenuType(sendMenuType) { +, _sendMenuDetails([result = sendMenuDetails] { return result; }) { } rpl::producer CreatePollBox::submitRequests() const { @@ -1288,20 +1288,9 @@ object_ptr CreatePollBox::setupContent() { _submitRequests.fire({ collectResult(), sendOptions }); } }; - const auto sendSilent = [=] { - send({ .silent = true }); - }; - const auto sendScheduled = [=] { - _controller->show( - HistoryView::PrepareScheduleBox( - this, - _controller->uiShow(), - SendMenu::Type::Scheduled, - send)); - }; - const auto sendWhenOnline = [=] { - send(Api::DefaultSendWhenOnlineOptions()); - }; + const auto sendAction = SendMenu::DefaultCallback( + _controller->uiShow(), + crl::guard(this, send)); options->scrollToWidget( ) | rpl::start_with_next([=](not_null widget) { @@ -1314,25 +1303,23 @@ object_ptr CreatePollBox::setupContent() { }, lifetime()); const auto isNormal = (_sendType == Api::SendType::Normal); - + const auto schedule = [=] { + sendAction(SendMenu::ActionType::Schedule, _sendMenuDetails()); + }; const auto submit = addButton( - isNormal + (isNormal ? tr::lng_polls_create_button() - : tr::lng_schedule_button(), - [=] { isNormal ? send({}) : sendScheduled(); }); - const auto sendMenuType = [=] { + : tr::lng_schedule_button()), + [=] { isNormal ? send({}) : schedule(); }); + const auto sendMenuDetails = [=] { collectError(); - return (*error) - ? SendMenu::Type::Disabled - : _sendMenuType; + return (*error) ? SendMenu::Details() : _sendMenuDetails(); }; SendMenu::SetupMenuAndShortcuts( submit.data(), _controller->uiShow(), - sendMenuType, - sendSilent, - sendScheduled, - sendWhenOnline); + sendMenuDetails, + sendAction); addButton(tr::lng_cancel(), [=] { closeBox(); }); return result; diff --git a/Telegram/SourceFiles/boxes/create_poll_box.h b/Telegram/SourceFiles/boxes/create_poll_box.h index 91805f0d8..91fc290ca 100644 --- a/Telegram/SourceFiles/boxes/create_poll_box.h +++ b/Telegram/SourceFiles/boxes/create_poll_box.h @@ -27,7 +27,7 @@ class SessionController; } // namespace Window namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu class CreatePollBox : public Ui::BoxContent { @@ -43,7 +43,7 @@ public: PollData::Flags chosen, PollData::Flags disabled, Api::SendType sendType, - SendMenu::Type sendMenuType); + SendMenu::Details sendMenuDetails); [[nodiscard]] rpl::producer submitRequests() const; void submitFailed(const QString &error); @@ -75,7 +75,7 @@ private: const PollData::Flags _chosen = PollData::Flags(); const PollData::Flags _disabled = PollData::Flags(); const Api::SendType _sendType = Api::SendType(); - const SendMenu::Type _sendMenuType; + const Fn _sendMenuDetails; base::unique_qptr _emojiPanel; Fn _setInnerFocus; Fn()> _dataIsValidValue; diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index 8e1280f89..6ba4771f8 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -328,7 +328,7 @@ SendFilesBox::SendFilesBox( const TextWithTags &caption, not_null toPeer, Api::SendType sendType, - SendMenu::Type sendMenuType) + SendMenu::Details sendMenuDetails) : SendFilesBox(nullptr, { .show = controller->uiShow(), .list = std::move(list), @@ -337,7 +337,7 @@ SendFilesBox::SendFilesBox( .limits = DefaultLimitsForPeer(toPeer), .check = DefaultCheckForPeer(controller, toPeer), .sendType = sendType, - .sendMenuType = sendMenuType, + .sendMenuDetails = [=] { return sendMenuDetails; }, }) { } @@ -350,7 +350,9 @@ SendFilesBox::SendFilesBox(QWidget*, SendFilesBoxDescriptor &&descriptor) , _titleHeight(st::boxTitleHeight) , _list(std::move(descriptor.list)) , _limits(descriptor.limits) -, _sendMenuType(descriptor.sendMenuType) +, _sendMenuDetails(descriptor.sendMenuDetails + ? descriptor.sendMenuDetails + : [] { return SendMenu::Details(); }) , _captionToPeer(descriptor.captionToPeer) , _check(std::move(descriptor.check)) , _confirmedCallback(std::move(descriptor.confirmed)) @@ -530,10 +532,8 @@ void SendFilesBox::refreshButtons() { SendMenu::SetupMenuAndShortcuts( _send, _show, - [=] { return _sendMenuType; }, - [=] { sendSilent(); }, - [=] { sendScheduled(); }, - [=] { sendWhenOnline(); }); + _sendMenuDetails, + SendMenu::DefaultCallback(_show, sendCallback())); } addButton(tr::lng_cancel(), [=] { closeBox(); }); _addFile = addLeftButton( @@ -546,7 +546,7 @@ void SendFilesBox::refreshButtons() { } bool SendFilesBox::hasSendMenu() const { - return (_sendMenuType != SendMenu::Type::Disabled); + return (_sendMenuDetails().type != SendMenu::Type::Disabled); } bool SendFilesBox::hasSpoilerMenu() const { @@ -607,11 +607,11 @@ void SendFilesBox::addMenuButton() { if (hasSendMenu()) { SendMenu::FillSendMenu( _menu.get(), - _sendMenuType, - [=] { sendSilent(); }, - [=] { sendScheduled(); }, - [=] { sendWhenOnline(); }, - &_st.tabbed.icons); + _show, + _sendMenuDetails(), + SendMenu::DefaultCallback(_show, sendCallback()), + &_st.tabbed.icons, + QCursor::pos()); } _menu->popup(QCursor::pos()); return true; @@ -1426,7 +1426,9 @@ void SendFilesBox::send( if ((_sendType == Api::SendType::Scheduled || _sendType == Api::SendType::ScheduledToUser) && !options.scheduled) { - return sendScheduled(); + return SendMenu::DefaultCallback(_show, sendCallback())( + SendMenu::ActionType::Schedule, + _sendMenuDetails()); } if (_preparing) { _whenReadySend = [=] { @@ -1464,25 +1466,10 @@ void SendFilesBox::send( closeBox(); } -void SendFilesBox::sendSilent() { - send({ .silent = true }); -} - -void SendFilesBox::sendScheduled() { - const auto type = (_sendType == Api::SendType::ScheduledToUser) - ? SendMenu::Type::ScheduledToUser - : _sendMenuType; - const auto callback = [=](Api::SendOptions options) { send(options); }; - auto box = HistoryView::PrepareScheduleBox(this, _show, type, callback); - const auto weak = Ui::MakeWeak(box.data()); - _show->showBox(std::move(box)); - if (const auto strong = weak.data()) { - strong->setCloseByOutsideClick(false); - } -} - -void SendFilesBox::sendWhenOnline() { - send(Api::DefaultSendWhenOnlineOptions()); +Fn SendFilesBox::sendCallback() { + return crl::guard(this, [=](Api::SendOptions options) { + send(options, false); + }); } SendFilesBox::~SendFilesBox() = default; diff --git a/Telegram/SourceFiles/boxes/send_files_box.h b/Telegram/SourceFiles/boxes/send_files_box.h index af712eda1..f6de4a4f8 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.h +++ b/Telegram/SourceFiles/boxes/send_files_box.h @@ -47,7 +47,7 @@ class SessionController; } // namespace Window namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace HistoryView::Controls { @@ -96,7 +96,7 @@ struct SendFilesBoxDescriptor { SendFilesLimits limits = {}; SendFilesCheck check; Api::SendType sendType = {}; - SendMenu::Type sendMenuType = {}; + Fn sendMenuDetails = nullptr; const style::ComposeControls *stOverride = nullptr; SendFilesConfirmed confirmed; Fn cancelled; @@ -115,7 +115,7 @@ public: const TextWithTags &caption, not_null toPeer, Api::SendType sendType, - SendMenu::Type sendMenuType); + SendMenu::Details sendMenuDetails); SendFilesBox(QWidget*, SendFilesBoxDescriptor &&descriptor); void setConfirmedCallback(SendFilesConfirmed callback) { @@ -202,9 +202,7 @@ private: void generatePreviewFrom(int fromBlock); void send(Api::SendOptions options, bool ctrlShiftEnter = false); - void sendSilent(); - void sendScheduled(); - void sendWhenOnline(); + [[nodiscard]] Fn sendCallback(); void captionResized(); void saveSendWaySettings(); @@ -238,7 +236,7 @@ private: std::optional _removingIndex; SendFilesLimits _limits = {}; - SendMenu::Type _sendMenuType = {}; + Fn _sendMenuDetails = nullptr; PeerData *_captionToPeer = nullptr; SendFilesCheck _check; SendFilesConfirmed _confirmedCallback; diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index 2d9ba4d3a..3d42c5afe 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -473,15 +473,18 @@ void ShareBox::keyPressEvent(QKeyEvent *e) { } } -SendMenu::Type ShareBox::sendMenuType() const { +SendMenu::Details ShareBox::sendMenuDetails() const { const auto selected = _inner->selected(); - return ranges::all_of( + const auto type = ranges::all_of( selected | ranges::views::transform(&Data::Thread::peer), HistoryView::CanScheduleUntilOnline) ? SendMenu::Type::ScheduledToUser : (selected.size() == 1 && selected.front()->peer()->isSelf()) ? SendMenu::Type::Reminder : SendMenu::Type::Scheduled; + + // We can't support effect here because we don't have ChatHelpers::Show. + return { .type = type, .effectAllowed = false }; } void ShareBox::showMenu(not_null parent) { @@ -518,15 +521,25 @@ void ShareBox::showMenu(not_null parent) { _menu->addSeparator(); } - const auto result = SendMenu::FillSendMenu( + using namespace SendMenu; + const auto sendAction = crl::guard(this, [=](Action action, Details) { + const auto options = std::get_if(&action); + if (options || v::get(action) == ActionType::Send) { + submit(options ? *options : Api::SendOptions()); + } else { + submitScheduled(); + } + }); + _menu->setForcedVerticalOrigin(Ui::PopupMenu::VerticalOrigin::Bottom); + const auto result = FillSendMenu( _menu.get(), - sendMenuType(), - [=] { submitSilent(); }, - [=] { submitScheduled(); }, - [=] { submitWhenOnline(); }); - const auto success = (result == SendMenu::FillMenuResult::Success); - if (_descriptor.forwardOptions.show || success) { - _menu->setForcedVerticalOrigin(Ui::PopupMenu::VerticalOrigin::Bottom); + nullptr, // showForEffect. + sendMenuDetails(), + sendAction); + if (result == SendMenu::FillMenuResult::Prepared) { + _menu->popupPrepared(); + } else if (_descriptor.forwardOptions.show + && result != SendMenu::FillMenuResult::Failed) { _menu->popup(QCursor::pos()); } } @@ -607,26 +620,18 @@ void ShareBox::submit(Api::SendOptions options) { } } -void ShareBox::submitSilent() { - submit({ .silent = true }); -} - void ShareBox::submitScheduled() { const auto callback = [=](Api::SendOptions options) { submit(options); }; uiShow()->showBox( HistoryView::PrepareScheduleBox( this, nullptr, // ChatHelpers::Show for effect attachment. - sendMenuType(), + sendMenuDetails(), callback, HistoryView::DefaultScheduleTime(), _descriptor.scheduleBoxStyle)); } -void ShareBox::submitWhenOnline() { - submit(Api::DefaultSendWhenOnlineOptions()); -} - void ShareBox::copyLink() const { if (const auto onstack = _descriptor.copyCallback) { onstack(); diff --git a/Telegram/SourceFiles/boxes/share_box.h b/Telegram/SourceFiles/boxes/share_box.h index 253a8228e..5e48430cd 100644 --- a/Telegram/SourceFiles/boxes/share_box.h +++ b/Telegram/SourceFiles/boxes/share_box.h @@ -24,7 +24,7 @@ struct PeerList; } // namespace style namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace Window { @@ -130,13 +130,11 @@ private: void scrollAnimationCallback(); void submit(Api::SendOptions options); - void submitSilent(); void submitScheduled(); - void submitWhenOnline(); void copyLink() const; bool searchByUsername(bool useCache = false); - SendMenu::Type sendMenuType() const; + [[nodiscard]] SendMenu::Details sendMenuDetails() const; void scrollTo(Ui::ScrollToRequest request); void needSearchByUsername(); diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index ac4555120..efd034843 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -1014,7 +1014,7 @@ void StickerSetBox::Inner::contextMenuEvent(QContextMenuEvent *e) { _menu = base::make_unique_q( this, st::popupMenuWithIcons); - const auto type = _show->sendMenuType(); + const auto details = _show->sendMenuDetails(); if (setType() == Data::StickersType::Emoji) { if (const auto t = PrepareTextFromEmoji(_pack[index]); !t.empty()) { _menu->addAction(tr::lng_mediaview_copy(tr::now), [=] { @@ -1023,17 +1023,16 @@ void StickerSetBox::Inner::contextMenuEvent(QContextMenuEvent *e) { } }, &st::menuIconCopy); } - } else if (type != SendMenu::Type::Disabled) { + } else if (details.type != SendMenu::Type::Disabled) { const auto document = _pack[index]; - const auto sendSelected = [=](Api::SendOptions options) { + const auto send = crl::guard(this, [=](Api::SendOptions options) { chosen(index, document, options); - }; + }); SendMenu::FillSendMenu( _menu.get(), - type, - SendMenu::DefaultSilentCallback(sendSelected), - SendMenu::DefaultScheduleCallback(_show, type, sendSelected), - SendMenu::DefaultWhenOnlineCallback(sendSelected)); + _show, + details, + SendMenu::DefaultCallback(_show, send)); const auto show = _show; const auto toggleFavedSticker = [=] { diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.h b/Telegram/SourceFiles/boxes/sticker_set_box.h index c57a1f484..72dd38320 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.h +++ b/Telegram/SourceFiles/boxes/sticker_set_box.h @@ -23,10 +23,6 @@ namespace Data { class StickersSet; } // namespace Data -namespace SendMenu { -enum class Type; -} // namespace SendMenu - namespace ChatHelpers { struct FileChosen; class Show; diff --git a/Telegram/SourceFiles/chat_helpers/compose/compose_show.h b/Telegram/SourceFiles/chat_helpers/compose/compose_show.h index 7dcbab513..28fc7ff47 100644 --- a/Telegram/SourceFiles/chat_helpers/compose/compose_show.h +++ b/Telegram/SourceFiles/chat_helpers/compose/compose_show.h @@ -22,7 +22,7 @@ class SessionController; } // namespace Window namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace ChatHelpers { @@ -57,7 +57,7 @@ public: [[nodiscard]] virtual rpl::producer<> pauseChanged() const = 0; [[nodiscard]] virtual rpl::producer adjustShadowLeft() const; - [[nodiscard]] virtual SendMenu::Type sendMenuType() const = 0; + [[nodiscard]] virtual SendMenu::Details sendMenuDetails() const = 0; virtual bool showMediaPreview( Data::FileOrigin origin, diff --git a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp index a5b72ca7b..8482d8b81 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp @@ -1104,7 +1104,7 @@ void EmojiListWidget::fillRecentFrom(const std::vector &list) { } base::unique_qptr EmojiListWidget::fillContextMenu( - SendMenu::Type type) { + const SendMenu::Details &details) { if (v::is_null(_selected)) { return nullptr; } diff --git a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h index 3159d340e..219add05b 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h +++ b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h @@ -144,7 +144,7 @@ public: RectPart origin); base::unique_qptr fillContextMenu( - SendMenu::Type type) override; + const SendMenu::Details &details) override; protected: void visibleTopBottomUpdated( diff --git a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp index 20f32f6e8..90f11e978 100644 --- a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp +++ b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp @@ -87,7 +87,7 @@ public: Api::SendOptions options = {}) const; void setRecentInlineBotsInRows(int32 bots); - void setSendMenuType(Fn &&callback); + void setSendMenuDetails(Fn &&callback); void rowsUpdated(); rpl::producer mentionChosen() const; @@ -155,7 +155,7 @@ private: const std::unique_ptr _pathGradient; StickerPremiumMark _premiumMark; - Fn _sendMenuType; + Fn _sendMenuDetails; rpl::event_stream _mentionChosen; rpl::event_stream _hashtagChosen; @@ -835,8 +835,9 @@ bool FieldAutocomplete::chooseSelected(ChooseMethod method) const { return _inner->chooseSelected(method); } -void FieldAutocomplete::setSendMenuType(Fn &&callback) { - _inner->setSendMenuType(std::move(callback)); +void FieldAutocomplete::setSendMenuDetails( + Fn &&callback) { + _inner->setSendMenuDetails(std::move(callback)); } bool FieldAutocomplete::eventFilter(QObject *obj, QEvent *e) { @@ -1364,24 +1365,22 @@ void FieldAutocomplete::Inner::contextMenuEvent(QContextMenuEvent *e) { return; } const auto index = _sel; - const auto type = _sendMenuType - ? _sendMenuType() - : SendMenu::Type::Disabled; + const auto details = _sendMenuDetails + ? _sendMenuDetails() + : SendMenu::Details(); const auto method = FieldAutocomplete::ChooseMethod::ByClick; _menu = base::make_unique_q( this, st::popupMenuWithIcons); - const auto send = [=](Api::SendOptions options) { + const auto send = crl::guard(this, [=](Api::SendOptions options) { chooseAtIndex(method, index, options); - }; + }); SendMenu::FillSendMenu( _menu, - type, - SendMenu::DefaultSilentCallback(send), - SendMenu::DefaultScheduleCallback(_show, type, send), - SendMenu::DefaultWhenOnlineCallback(send)); - + _show, + details, + SendMenu::DefaultCallback(_show, send)); if (!_menu->empty()) { _menu->popup(QCursor::pos()); } @@ -1604,9 +1603,9 @@ void FieldAutocomplete::Inner::showPreview() { } } -void FieldAutocomplete::Inner::setSendMenuType( - Fn &&callback) { - _sendMenuType = std::move(callback); +void FieldAutocomplete::Inner::setSendMenuDetails( + Fn &&callback) { + _sendMenuDetails = std::move(callback); } auto FieldAutocomplete::Inner::mentionChosen() const diff --git a/Telegram/SourceFiles/chat_helpers/field_autocomplete.h b/Telegram/SourceFiles/chat_helpers/field_autocomplete.h index 5c9e291f3..d95b7e394 100644 --- a/Telegram/SourceFiles/chat_helpers/field_autocomplete.h +++ b/Telegram/SourceFiles/chat_helpers/field_autocomplete.h @@ -42,7 +42,7 @@ class DocumentMedia; } // namespace Data namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace ChatHelpers { @@ -123,7 +123,7 @@ public: void setModerateKeyActivateCallback(Fn callback) { _moderateKeyActivateCallback = std::move(callback); } - void setSendMenuType(Fn &&callback); + void setSendMenuDetails(Fn &&callback); void hideFast(); void showAnimated(); diff --git a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp index 609f21989..ab2fe0b98 100644 --- a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp @@ -380,22 +380,22 @@ void GifsListWidget::mousePressEvent(QMouseEvent *e) { } base::unique_qptr GifsListWidget::fillContextMenu( - SendMenu::Type type) { + const SendMenu::Details &details) { if (_selected < 0 || _pressed >= 0) { return nullptr; } auto menu = base::make_unique_q(this, st().menu); - const auto send = [=, selected = _selected](Api::SendOptions options) { + const auto selected = _selected; + const auto send = crl::guard(this, [=](Api::SendOptions options) { selectInlineResult(selected, options, true); - }; + }); const auto icons = &st().icons; SendMenu::FillSendMenu( menu, - type, - SendMenu::DefaultSilentCallback(send), - SendMenu::DefaultScheduleCallback(_show, type, send), - SendMenu::DefaultWhenOnlineCallback(send), + _show, + details, + SendMenu::DefaultCallback(_show, send), icons); if (const auto item = _mosaic.maybeItemAt(_selected)) { diff --git a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.h b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.h index 84e20c864..ad6c26ae6 100644 --- a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.h +++ b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.h @@ -40,7 +40,7 @@ class SessionController; } // namespace Window namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace Data { @@ -102,7 +102,7 @@ public: rpl::producer<> cancelRequests() const; base::unique_qptr fillContextMenu( - SendMenu::Type type) override; + const SendMenu::Details &details) override; ~GifsListWidget(); diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp index e44b8aaef..1425f6dd8 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp @@ -1634,7 +1634,7 @@ void StickersListWidget::showStickerSetBox(not_null document) { } base::unique_qptr StickersListWidget::fillContextMenu( - SendMenu::Type type) { + const SendMenu::Details &details) { auto selected = _selected; auto &sets = shownSets(); if (v::is_null(selected) || !v::is_null(_pressed)) { @@ -1653,7 +1653,7 @@ base::unique_qptr StickersListWidget::fillContextMenu( auto menu = base::make_unique_q(this, st().menu); const auto document = set.stickers[sticker->index].document; - const auto send = [=](Api::SendOptions options) { + const auto send = crl::guard(this, [=](Api::SendOptions options) { _chosen.fire({ .document = document, .options = options, @@ -1661,14 +1661,13 @@ base::unique_qptr StickersListWidget::fillContextMenu( ? Ui::MessageSendingAnimationFrom() : messageSentAnimationInfo(section, index, document), }); - }; + }); const auto icons = &st().icons; SendMenu::FillSendMenu( menu, - type, - SendMenu::DefaultSilentCallback(send), - SendMenu::DefaultScheduleCallback(_show, type, send), - SendMenu::DefaultWhenOnlineCallback(send), + _show, + details, + SendMenu::DefaultCallback(_show, send), icons); const auto show = _show; diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h index aff2cf287..34838b364 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h @@ -116,7 +116,7 @@ public: std::shared_ptr getLottieRenderer(); base::unique_qptr fillContextMenu( - SendMenu::Type type) override; + const SendMenu::Details &details) override; bool mySetsEmpty() const; diff --git a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp index b63ae6967..5e8967541 100644 --- a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp +++ b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp @@ -1297,8 +1297,8 @@ void TabbedSelector::scrollToY(int y) { } } -void TabbedSelector::showMenuWithType(SendMenu::Type type) { - _menu = currentTab()->widget()->fillContextMenu(type); +void TabbedSelector::showMenuWithDetails(SendMenu::Details details) { + _menu = currentTab()->widget()->fillContextMenu(details); if (_menu && !_menu->empty()) { _menu->popup(QCursor::pos()); } diff --git a/Telegram/SourceFiles/chat_helpers/tabbed_selector.h b/Telegram/SourceFiles/chat_helpers/tabbed_selector.h index b9b03b33b..bb780797c 100644 --- a/Telegram/SourceFiles/chat_helpers/tabbed_selector.h +++ b/Telegram/SourceFiles/chat_helpers/tabbed_selector.h @@ -36,7 +36,7 @@ class TabbedSearch; } // namespace Ui namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace style { @@ -178,7 +178,7 @@ public: _beforeHidingCallback = std::move(callback); } - void showMenuWithType(SendMenu::Type type); + void showMenuWithDetails(SendMenu::Details details); void setDropDown(bool dropDown); // Float player interface. @@ -380,7 +380,7 @@ public: virtual void beforeHiding() { } [[nodiscard]] virtual base::unique_qptr fillContextMenu( - SendMenu::Type type) { + const SendMenu::Details &details) { return nullptr; } diff --git a/Telegram/SourceFiles/data/data_message_reactions.cpp b/Telegram/SourceFiles/data/data_message_reactions.cpp index a04cbcbfb..cdab73fb6 100644 --- a/Telegram/SourceFiles/data/data_message_reactions.cpp +++ b/Telegram/SourceFiles/data/data_message_reactions.cpp @@ -1297,9 +1297,10 @@ std::optional Reactions::parse(const MTPAvailableEffect &entry) { return std::nullopt; } const auto id = DocumentId(data.vid().v); - const auto document = _owner->document(id); + const auto stickerId = data.veffect_sticker_id().v; + const auto document = _owner->document(stickerId); if (!document->sticker()) { - LOG(("API Error: Bad sticker in effects: %1").arg(id)); + LOG(("API Error: Bad sticker in effects: %1").arg(stickerId)); return std::nullopt; } const auto aroundId = data.veffect_animation_id().value_or_empty(); diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index c89d3b0c7..e76900180 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -321,14 +321,22 @@ HistoryWidget::HistoryWidget( _fieldBarCancel->addClickHandler([=] { cancelFieldAreaState(); }); _send->addClickHandler([=] { sendButtonClicked(); }); - SendMenu::SetupMenuAndShortcuts( - _send.get(), - controller->uiShow(), - [=] { return sendButtonMenuType(); }, - [=] { sendSilent(); }, - [=] { sendScheduled(); }, - [=] { sendWhenOnline(); }); - + { + using namespace SendMenu; + const auto sendAction = [=](Action action, Details) { + const auto options = std::get_if(&action); + if (options || v::get(action) == ActionType::Send) { + send(options ? *options : Api::SendOptions()); + } else { + sendScheduled(); + } + }; + SetupMenuAndShortcuts( + _send.get(), + controller->uiShow(), + [=] { return sendButtonMenuDetails(); }, + sendAction); + } _unblock->addClickHandler([=] { unblockUser(); }); _botStart->addClickHandler([=] { sendBotStartCommand(); }); _joinChannel->addClickHandler([=] { joinChannel(); }); @@ -514,7 +522,9 @@ HistoryWidget::HistoryWidget( } }, lifetime()); - _fieldAutocomplete->setSendMenuType([=] { return sendMenuType(); }); + _fieldAutocomplete->setSendMenuDetails([=] { + return sendMenuDetails(); + }); if (_supportAutocomplete) { supportInitAutocomplete(); @@ -1185,7 +1195,7 @@ void HistoryWidget::initTabbedSelector() { selector->contextMenuRequested( ) | filter | rpl::start_with_next([=] { - selector->showMenuWithType(sendMenuType()); + selector->showMenuWithDetails(sendMenuDetails()); }, lifetime()); selector->choosingStickerUpdated( @@ -1564,7 +1574,9 @@ void HistoryWidget::applyInlineBotQuery(UserData *bot, const QString &query) { sendInlineResult(result); } }); - _inlineResults->setSendMenuType([=] { return sendMenuType(); }); + _inlineResults->setSendMenuDetails([=] { + return sendMenuDetails(); + }); _inlineResults->requesting( ) | rpl::start_with_next([=](bool requesting) { _tabbedSelectorToggle->setLoading(requesting); @@ -4177,10 +4189,6 @@ void HistoryWidget::sendWithModifiers(Qt::KeyboardModifiers modifiers) { send({ .handleSupportSwitch = Support::HandleSwitch(modifiers) }); } -void HistoryWidget::sendSilent() { - send({ .silent = true }); -} - void HistoryWidget::sendScheduled() { if (!_list) { return; @@ -4196,22 +4204,20 @@ void HistoryWidget::sendScheduled() { HistoryView::PrepareScheduleBox( _list, controller()->uiShow(), - sendMenuType(), + sendMenuDetails(), callback)); } -void HistoryWidget::sendWhenOnline() { - send(Api::DefaultSendWhenOnlineOptions()); -} - -SendMenu::Type HistoryWidget::sendMenuType() const { - return !_peer +SendMenu::Details HistoryWidget::sendMenuDetails() const { + const auto type = !_peer ? SendMenu::Type::Disabled : _peer->isSelf() ? SendMenu::Type::Reminder : HistoryView::CanScheduleUntilOnline(_peer) ? SendMenu::Type::ScheduledToUser : SendMenu::Type::Scheduled; + const auto effectAllowed = _peer && _peer->isUser(); + return { .type = type, .effectAllowed = effectAllowed }; } auto HistoryWidget::computeSendButtonType() const { @@ -4227,10 +4233,11 @@ auto HistoryWidget::computeSendButtonType() const { return Type::Send; } -SendMenu::Type HistoryWidget::sendButtonMenuType() const { - return (computeSendButtonType() == Ui::SendButton::Type::Send) - ? sendMenuType() - : SendMenu::Type::Disabled; +SendMenu::Details HistoryWidget::sendButtonMenuDetails() const { + if (computeSendButtonType() != Ui::SendButton::Type::Send) { + return {}; + } + return sendMenuDetails(); } void HistoryWidget::unblockUser() { @@ -5609,7 +5616,7 @@ bool HistoryWidget::confirmSendingFiles( text, _peer, Api::SendType::Normal, - sendMenuType()); + sendMenuDetails()); _field->setTextWithTags({}); box->setConfirmedCallback(crl::guard(this, [=]( Ui::PreparedList &&list, diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index b731507b2..ca2a9ed47 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -33,7 +33,7 @@ class PhotoMedia; } // namespace Data namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace Api { @@ -268,7 +268,7 @@ public: void confirmDeleteSelected(); void clearSelected(); - [[nodiscard]] SendMenu::Type sendMenuType() const; + [[nodiscard]] SendMenu::Details sendMenuDetails() const; bool sendExistingDocument( not_null document, Api::SendOptions options, @@ -395,10 +395,8 @@ private: Api::SendOptions options) const; void send(Api::SendOptions options); void sendWithModifiers(Qt::KeyboardModifiers modifiers); - void sendSilent(); void sendScheduled(); - void sendWhenOnline(); - [[nodiscard]] SendMenu::Type sendButtonMenuType() const; + [[nodiscard]] SendMenu::Details sendButtonMenuDetails() const; void handlePendingHistoryUpdate(); void fullInfoUpdated(); void toggleTabbedSelectorMode(); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp index 7dcf2373b..c81c59b8c 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -854,7 +854,7 @@ ComposeControls::ComposeControls( .recorderHeight = st::historySendSize.height(), .lockFromBottom = descriptor.voiceLockFromBottom, })) -, _sendMenuType(descriptor.sendMenuType) +, _sendMenuDetails(descriptor.sendMenuDetails) , _unavailableEmojiPasted(std::move(descriptor.unavailableEmojiPasted)) , _saveDraftTimer([=] { saveDraft(); }) , _saveCloudDraftTimer([=] { saveCloudDraft(); }) { @@ -1719,7 +1719,7 @@ void ComposeControls::initAutocomplete() { } }, _autocomplete->lifetime()); - _autocomplete->setSendMenuType([=] { return sendMenuType(); }); + _autocomplete->setSendMenuDetails([=] { return sendMenuDetails(); }); //_autocomplete->setModerateKeyActivateCallback([=](int key) { // return _keyboard->isHidden() @@ -2162,7 +2162,7 @@ void ComposeControls::initTabbedSelector() { _selector->contextMenuRequested( ) | rpl::start_with_next([=] { - _selector->showMenuWithType(sendMenuType()); + _selector->showMenuWithDetails(sendMenuDetails()); }, wrap->lifetime()); _selector->choosingStickerUpdated( @@ -2191,17 +2191,15 @@ void ComposeControls::initSendButton() { cancelInlineBot(); }, _send->lifetime()); - const auto send = [=](Api::SendOptions options) { + const auto send = crl::guard(_send.get(), [=](Api::SendOptions options) { _sendCustomRequests.fire(std::move(options)); - }; + }); SendMenu::SetupMenuAndShortcuts( _send.get(), _show, - [=] { return sendButtonMenuType(); }, - SendMenu::DefaultSilentCallback(send), - SendMenu::DefaultScheduleCallback(_show, sendMenuType(), send), - SendMenu::DefaultWhenOnlineCallback(send)); + [=] { return sendButtonMenuDetails(); }, + SendMenu::DefaultCallback(_show, send)); } void ComposeControls::initSendAsButton(not_null peer) { @@ -2510,14 +2508,14 @@ auto ComposeControls::computeSendButtonType() const { return (_mode == Mode::Normal) ? Type::Send : Type::Schedule; } -SendMenu::Type ComposeControls::sendMenuType() const { - return !_history ? SendMenu::Type::Disabled : _sendMenuType; +SendMenu::Details ComposeControls::sendMenuDetails() const { + return !_history ? SendMenu::Details() : _sendMenuDetails(); } -SendMenu::Type ComposeControls::sendButtonMenuType() const { +SendMenu::Details ComposeControls::sendButtonMenuDetails() const { return (computeSendButtonType() == Ui::SendButton::Type::Send) - ? sendMenuType() - : SendMenu::Type::Disabled; + ? sendMenuDetails() + : SendMenu::Details(); } void ComposeControls::updateSendButtonType() { @@ -3325,7 +3323,9 @@ void ComposeControls::applyInlineBotQuery( _inlineResultChosen.fire_copy(result); } }); - _inlineResults->setSendMenuType([=] { return sendMenuType(); }); + _inlineResults->setSendMenuDetails([=] { + return sendMenuDetails(); + }); _inlineResults->requesting( ) | rpl::start_with_next([=](bool requesting) { _tabbedSelectorToggle->setLoading(requesting); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h index f6c915968..11e7429e2 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h @@ -29,7 +29,7 @@ struct ComposeControls; } // namespace style namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace ChatHelpers { @@ -104,7 +104,7 @@ struct ComposeControlsDescriptor { std::shared_ptr show; Fn)> unavailableEmojiPasted; ComposeControlsMode mode = ComposeControlsMode::Normal; - SendMenu::Type sendMenuType = {}; + Fn sendMenuDetails = nullptr; Window::SessionController *regularWindow = nullptr; rpl::producer stickerOrEmojiChosen; rpl::producer customPlaceholder; @@ -282,8 +282,8 @@ private: void paintBackground(QPainter &p, QRect full, QRect clip); [[nodiscard]] auto computeSendButtonType() const; - [[nodiscard]] SendMenu::Type sendMenuType() const; - [[nodiscard]] SendMenu::Type sendButtonMenuType() const; + [[nodiscard]] SendMenu::Details sendMenuDetails() const; + [[nodiscard]] SendMenu::Details sendButtonMenuDetails() const; [[nodiscard]] auto sendContentRequests( SendRequestType requestType = SendRequestType::Text) const; @@ -396,7 +396,7 @@ private: const std::unique_ptr _header; const std::unique_ptr _voiceRecordBar; - const SendMenu::Type _sendMenuType; + const Fn _sendMenuDetails; const Fn)> _unavailableEmojiPasted; rpl::event_stream _sendCustomRequests; diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp index 12e0b06c6..781a4875d 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp @@ -590,7 +590,7 @@ bool AddRescheduleAction( HistoryView::PrepareScheduleBox( &request.navigation->session(), request.navigation->uiShow(), - sendMenuType, + { .type = sendMenuType, .effectAllowed = false }, callback, date)); diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index b1dcb13db..7f7ded51a 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -224,9 +224,11 @@ RepliesWidget::RepliesWidget( listShowPremiumToast(emoji); }, .mode = ComposeControls::Mode::Normal, - .sendMenuType = _topic - ? SendMenu::Type::Scheduled - : SendMenu::Type::SilentOnly, + .sendMenuDetails = [=] { + using Type = SendMenu::Type; + const auto type = _topic ? Type::Scheduled : Type::SilentOnly; + return SendMenu::Details{ .type = type }; + }, .regularWindow = controller, .stickerOrEmojiChosen = controller->stickerOrEmojiChosen(), .scheduledToggleValue = _topic @@ -950,7 +952,7 @@ bool RepliesWidget::confirmSendingFiles( _composeControls->getTextWithAppliedMarkdown(), _history->peer, Api::SendType::Normal, - SendMenu::Type::SilentOnly); // #TODO replies schedule + SendMenu::Details{ SendMenu::Type::SilentOnly }); // #TODO replies schedule box->setConfirmedCallback(crl::guard(this, [=]( Ui::PreparedList &&list, @@ -1445,13 +1447,14 @@ void RepliesWidget::sendInlineResult( finishSending(); } -SendMenu::Type RepliesWidget::sendMenuType() const { +SendMenu::Details RepliesWidget::sendMenuDetails() const { // #TODO replies schedule - return _history->peer->isSelf() + const auto type = _history->peer->isSelf() ? SendMenu::Type::Reminder : HistoryView::CanScheduleUntilOnline(_history->peer) ? SendMenu::Type::ScheduledToUser : SendMenu::Type::Scheduled; + return { .type = type, .effectAllowed = _history->peer->isUser() }; } FullReplyTo RepliesWidget::replyTo() const { diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.h b/Telegram/SourceFiles/history/view/history_view_replies_section.h index e3d05920e..54f02ef16 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.h +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.h @@ -19,7 +19,7 @@ enum class SendMediaType; struct SendingAlbum; namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace Api { @@ -249,7 +249,7 @@ private: mtpRequestId *const saveEditMsgRequestId, std::optional spoilerMediaOverride); void chooseAttach(std::optional overrideSendImagesAsPhotos); - [[nodiscard]] SendMenu::Type sendMenuType() const; + [[nodiscard]] SendMenu::Details sendMenuDetails() const; [[nodiscard]] FullReplyTo replyTo() const; [[nodiscard]] HistoryItem *lookupRoot() const; [[nodiscard]] Data::ForumTopic *lookupTopic(); diff --git a/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp b/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp index 83891717c..09288fed7 100644 --- a/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp +++ b/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp @@ -70,7 +70,7 @@ bool CanScheduleUntilOnline(not_null peer) { void ScheduleBox( not_null box, std::shared_ptr show, - SendMenu::Type type, + const SendMenu::Details &details, Fn done, TimeId time, ScheduleBoxStyleArgs style) { @@ -87,7 +87,7 @@ void ScheduleBox( copy(result); }; auto descriptor = Ui::ChooseDateTimeBox(box, { - .title = (type == SendMenu::Type::Reminder + .title = (details.type == SendMenu::Type::Reminder ? tr::lng_remind_title() : tr::lng_schedule_title()), .submit = tr::lng_schedule_button(), @@ -96,16 +96,26 @@ void ScheduleBox( .style = style.chooseDateTimeArgs, }); - using T = SendMenu::Type; - SendMenu::SetupMenuAndShortcuts( + using namespace SendMenu; + const auto childType = (details.type == Type::Disabled) + ? Type::Disabled + : Type::SilentOnly; + const auto childDetails = Details{ + .type = childType, + .effectAllowed = details.effectAllowed, + }; + const auto sendAction = crl::guard(box, [=](Action action, Details) { + save( + v::get(action).silent, + descriptor.collect()); + }); + SetupMenuAndShortcuts( descriptor.submit.data(), show, - [t = type == T::Disabled ? T::Disabled : T::SilentOnly] { return t; }, - [=] { save(true, descriptor.collect()); }, - nullptr, - nullptr); + [=] { return childDetails; }, + sendAction); - if (type == SendMenu::Type::ScheduledToUser) { + if (details.type == Type::ScheduledToUser) { const auto sendUntilOnline = box->addTopButton(*style.topButtonStyle); const auto timestamp = Api::kScheduledUntilOnlineTimestamp; FillSendUntilOnlineMenu( diff --git a/Telegram/SourceFiles/history/view/history_view_schedule_box.h b/Telegram/SourceFiles/history/view/history_view_schedule_box.h index 72c2b4b89..a69177102 100644 --- a/Telegram/SourceFiles/history/view/history_view_schedule_box.h +++ b/Telegram/SourceFiles/history/view/history_view_schedule_box.h @@ -23,7 +23,7 @@ class Show; } // namespace ChatHelpers namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace HistoryView { @@ -41,7 +41,7 @@ struct ScheduleBoxStyleArgs { void ScheduleBox( not_null box, std::shared_ptr show, - SendMenu::Type type, + const SendMenu::Details &details, Fn done, TimeId time, ScheduleBoxStyleArgs style); @@ -50,14 +50,14 @@ template [[nodiscard]] object_ptr PrepareScheduleBox( Guard &&guard, std::shared_ptr show, - SendMenu::Type type, + const SendMenu::Details &details, Submit &&submit, TimeId scheduleTime = DefaultScheduleTime(), ScheduleBoxStyleArgs style = ScheduleBoxStyleArgs()) { return Box( ScheduleBox, std::move(show), - type, + details, crl::guard(std::forward(guard), std::forward(submit)), scheduleTime, std::move(style)); diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index e0522acb0..6535958be 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -115,7 +115,7 @@ ScheduledWidget::ScheduledWidget( listShowPremiumToast(emoji); }, .mode = ComposeControls::Mode::Scheduled, - .sendMenuType = SendMenu::Type::Disabled, + .sendMenuDetails = [] { return SendMenu::Details(); }, .regularWindow = controller, .stickerOrEmojiChosen = controller->stickerOrEmojiChosen(), })) @@ -493,7 +493,7 @@ bool ScheduledWidget::confirmSendingFiles( (CanScheduleUntilOnline(_history->peer) ? Api::SendType::ScheduledToUser : Api::SendType::Scheduled), - SendMenu::Type::Disabled); + SendMenu::Details()); box->setConfirmedCallback(crl::guard(this, [=]( Ui::PreparedList &&list, @@ -602,7 +602,7 @@ void ScheduledWidget::uploadFile( prepareSendAction(options)); }; controller()->show( - PrepareScheduleBox(this, _show, sendMenuType(), callback)); + PrepareScheduleBox(this, _show, sendMenuDetails(), callback)); } bool ScheduledWidget::showSendingFilesError( @@ -681,7 +681,7 @@ void ScheduledWidget::send() { } const auto callback = [=](Api::SendOptions options) { send(options); }; controller()->show( - PrepareScheduleBox(this, _show, sendMenuType(), callback)); + PrepareScheduleBox(this, _show, sendMenuDetails(), callback)); } void ScheduledWidget::send(Api::SendOptions options) { @@ -713,7 +713,7 @@ void ScheduledWidget::sendVoice( sendVoice(bytes, waveform, duration, options); }; controller()->show( - PrepareScheduleBox(this, _show, sendMenuType(), callback)); + PrepareScheduleBox(this, _show, sendMenuDetails(), callback)); } void ScheduledWidget::sendVoice( @@ -814,7 +814,7 @@ void ScheduledWidget::sendExistingDocument( sendExistingDocument(document, options); }; controller()->show( - PrepareScheduleBox(this, _show, sendMenuType(), callback)); + PrepareScheduleBox(this, _show, sendMenuDetails(), callback)); } bool ScheduledWidget::sendExistingDocument( @@ -844,7 +844,7 @@ void ScheduledWidget::sendExistingPhoto(not_null photo) { sendExistingPhoto(photo, options); }; controller()->show( - PrepareScheduleBox(this, _show, sendMenuType(), callback)); + PrepareScheduleBox(this, _show, sendMenuDetails(), callback)); } bool ScheduledWidget::sendExistingPhoto( @@ -879,7 +879,7 @@ void ScheduledWidget::sendInlineResult( sendInlineResult(result, bot, options); }; controller()->show( - PrepareScheduleBox(this, _show, sendMenuType(), callback)); + PrepareScheduleBox(this, _show, sendMenuDetails(), callback)); } void ScheduledWidget::sendInlineResult( @@ -911,12 +911,14 @@ void ScheduledWidget::sendInlineResult( _composeControls->focus(); } -SendMenu::Type ScheduledWidget::sendMenuType() const { - return _history->peer->isSelf() +SendMenu::Details ScheduledWidget::sendMenuDetails() const { + const auto type = _history->peer->isSelf() ? SendMenu::Type::Reminder : HistoryView::CanScheduleUntilOnline(_history->peer) ? SendMenu::Type::ScheduledToUser : SendMenu::Type::Scheduled; + const auto effectAllowed = _history->peer->isUser(); + return { .type = type, .effectAllowed = effectAllowed }; } void ScheduledWidget::cornerButtonsShowAtPosition( @@ -1368,7 +1370,7 @@ void ScheduledWidget::listSendBotCommand( session().api().sendMessage(std::move(message)); }; controller()->show( - PrepareScheduleBox(this, _show, sendMenuType(), callback)); + PrepareScheduleBox(this, _show, sendMenuDetails(), callback)); } void ScheduledWidget::listSearch( diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h index cb5ead98f..e79304691 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h @@ -22,7 +22,7 @@ class Show; } // namespace ChatHelpers namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace Api { @@ -221,7 +221,7 @@ private: std::optional spoilerMediaOverride); void highlightSingleNewMessage(const Data::MessagesSlice &slice); void chooseAttach(); - [[nodiscard]] SendMenu::Type sendMenuType() const; + [[nodiscard]] SendMenu::Details sendMenuDetails() const; void pushReplyReturn(not_null item); void checkReplyReturns(); diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.cpp b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.cpp index 61c46a157..9ab46ef14 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.cpp +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.cpp @@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/stickers/data_custom_emoji.h" #include "lang/lang_keys.h" #include "main/main_session.h" +#include "menu/menu_send.h" #include "chat_helpers/emoji_list_widget.h" #include "chat_helpers/stickers_list_footer.h" #include "window/window_session_controller.h" @@ -123,15 +124,11 @@ UnifiedFactoryOwner::UnifiedFactoryOwner( const auto inStrip = _strip ? _strip->count() : 0; _unifiedIdsList.reserve(reactions.size()); for (const auto &reaction : reactions) { - if (const auto id = reaction.id.custom()) { - _unifiedIdsList.push_back(id); - } else { - _unifiedIdsList.push_back(reaction.selectAnimation->id); - } + _unifiedIdsList.push_back(reaction.selectAnimation->id); const auto unifiedId = _unifiedIdsList.back(); - if (!reaction.id.custom()) { - _defaultReactionIds.emplace(unifiedId, reaction.id.emoji()); + if (unifiedId != reaction.id.custom()) { + _defaultReactionIds.emplace(unifiedId, reaction.id); } if (index + 1 < inStrip) { _defaultReactionInStripMap.emplace(unifiedId, index++); @@ -165,7 +162,7 @@ Data::ReactionId UnifiedFactoryOwner::lookupReactionId( DocumentId unifiedId) const { const auto i = _defaultReactionIds.find(unifiedId); return (i != end(_defaultReactionIds)) - ? Data::ReactionId{ i->second } + ? i->second : Data::ReactionId{ unifiedId }; } @@ -174,21 +171,23 @@ UnifiedFactoryOwner::RecentFactory UnifiedFactoryOwner::factory() { -> std::unique_ptr { const auto tag = Data::CustomEmojiManager::SizeTag::Large; const auto sizeOverride = st::reactStripImage; - const auto isDefaultReaction = _defaultReactionIds.contains(id); + const auto i = _defaultReactionIds.find(id); + const auto isDefaultReaction = (i != end(_defaultReactionIds)) + && !i->second.custom(); const auto manager = &_session->data().customEmojiManager(); auto result = isDefaultReaction ? std::make_unique( manager->create(id, std::move(repaint), tag, sizeOverride), _defaultReactionShift) : manager->create(id, std::move(repaint), tag); - const auto i = _defaultReactionInStripMap.find(id); - if (i != end(_defaultReactionInStripMap)) { + const auto j = _defaultReactionInStripMap.find(id); + if (j != end(_defaultReactionInStripMap)) { Assert(_strip != nullptr); return std::make_unique( std::move(result), _strip, -_stripPaintOneShift, - i->second); + j->second); } return result; }; diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.h b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.h index cb9b8a68f..06de4e7cd 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.h +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.h @@ -66,7 +66,7 @@ private: Strip *_strip = nullptr; std::vector _unifiedIdsList; - base::flat_map _defaultReactionIds; + base::flat_map _defaultReactionIds; base::flat_map _defaultReactionInStripMap; QPoint _defaultReactionShift; diff --git a/Telegram/SourceFiles/info/profile/info_profile_emoji_status_panel.cpp b/Telegram/SourceFiles/info/profile/info_profile_emoji_status_panel.cpp index 3a3176908..02f6f986e 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_emoji_status_panel.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_emoji_status_panel.cpp @@ -229,7 +229,7 @@ void EmojiStatusPanel::create(const Descriptor &descriptor) { _panel->selector()->contextMenuRequested( ) | rpl::start_with_next([=] { - _panel->selector()->showMenuWithType(SendMenu::Type::Scheduled); + _panel->selector()->showMenuWithDetails({}); }, _panel->lifetime()); auto statusChosen = _panel->selector()->customEmojiChosen( diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp index 95e7630e4..1eb99362b 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp @@ -1703,7 +1703,7 @@ std::unique_ptr MakeAttachBotsMenu( flag, flag, source, - sendMenuType); + { sendMenuType }); }, &st::menuIconCreatePoll); } for (const auto &bot : bots->attachBots()) { diff --git a/Telegram/SourceFiles/inline_bots/inline_results_inner.cpp b/Telegram/SourceFiles/inline_bots/inline_results_inner.cpp index 5e45b3d4a..74219011d 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_inner.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_results_inner.cpp @@ -329,23 +329,23 @@ void Inner::contextMenuEvent(QContextMenuEvent *e) { if (_selected < 0 || _pressed >= 0) { return; } - const auto type = _sendMenuType - ? _sendMenuType() - : SendMenu::Type::Disabled; + const auto details = _sendMenuDetails + ? _sendMenuDetails() + : SendMenu::Details(); _menu = base::make_unique_q( this, st::popupMenuWithIcons); - const auto send = [=, selected = _selected](Api::SendOptions options) { + const auto selected = _selected; + const auto send = crl::guard(this, [=](Api::SendOptions options) { selectInlineResult(selected, options, false); - }; + }); SendMenu::FillSendMenu( _menu, - type, - SendMenu::DefaultSilentCallback(send), - SendMenu::DefaultScheduleCallback(_controller->uiShow(), type, send), - SendMenu::DefaultWhenOnlineCallback(send)); + _controller->uiShow(), + details, + SendMenu::DefaultCallback(_controller->uiShow(), send)); const auto item = _mosaic.itemAt(_selected); if (const auto previewDocument = item->getPreviewDocument()) { @@ -689,8 +689,8 @@ void Inner::switchPm() { } } -void Inner::setSendMenuType(Fn &&callback) { - _sendMenuType = std::move(callback); +void Inner::setSendMenuDetails(Fn &&callback) { + _sendMenuDetails = std::move(callback); } } // namespace Layout diff --git a/Telegram/SourceFiles/inline_bots/inline_results_inner.h b/Telegram/SourceFiles/inline_bots/inline_results_inner.h index 5aa22578a..4e6195e19 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_inner.h +++ b/Telegram/SourceFiles/inline_bots/inline_results_inner.h @@ -43,7 +43,7 @@ struct ResultSelected; } // namespace InlineBots namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace InlineBots { @@ -89,7 +89,7 @@ public: void setResultSelectedCallback(Fn callback) { _resultSelectedCallback = std::move(callback); } - void setSendMenuType(Fn &&callback); + void setSendMenuDetails(Fn &&callback); // Ui::AbstractTooltipShower interface. QString tooltipText() const override; @@ -179,7 +179,7 @@ private: bool _previewShown = false; Fn _resultSelectedCallback; - Fn _sendMenuType; + Fn _sendMenuDetails; }; diff --git a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp index c6e4b3380..12dfbb5f9 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp @@ -265,8 +265,8 @@ void Widget::setResultSelectedCallback(Fn callback) { _inner->setResultSelectedCallback(std::move(callback)); } -void Widget::setSendMenuType(Fn &&callback) { - _inner->setSendMenuType(std::move(callback)); +void Widget::setSendMenuDetails(Fn &&callback) { + _inner->setSendMenuDetails(std::move(callback)); } void Widget::hideAnimated() { diff --git a/Telegram/SourceFiles/inline_bots/inline_results_widget.h b/Telegram/SourceFiles/inline_bots/inline_results_widget.h index 00b39e0d3..166287c58 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_widget.h +++ b/Telegram/SourceFiles/inline_bots/inline_results_widget.h @@ -45,7 +45,7 @@ struct ResultSelected; } // namespace InlineBots namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace InlineBots { @@ -75,7 +75,7 @@ public: void hideAnimated(); void setResultSelectedCallback(Fn callback); - void setSendMenuType(Fn &&callback); + void setSendMenuDetails(Fn &&callback); [[nodiscard]] rpl::producer requesting() const { return _requesting.events(); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 4dd47970d..5f94f8a22 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1047,8 +1047,8 @@ void MainWidget::exportTopBarHeightUpdated() { } } -SendMenu::Type MainWidget::sendMenuType() const { - return _history->sendMenuType(); +SendMenu::Details MainWidget::sendMenuDetails() const { + return _history->sendMenuDetails(); } bool MainWidget::sendExistingDocument(not_null document) { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 14e1ef2ab..3653070ac 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -29,7 +29,7 @@ struct SendOptions; } // namespace Api namespace SendMenu { -enum class Type; +struct Details; } // namespace SendMenu namespace Main { @@ -157,7 +157,7 @@ public: QPixmap grabForShowAnimation(const Window::SectionSlideParams ¶ms); void checkMainSectionToLayer(); - [[nodiscard]] SendMenu::Type sendMenuType() const; + [[nodiscard]] SendMenu::Details sendMenuDetails() const; bool sendExistingDocument(not_null document); bool sendExistingDocument( not_null document, diff --git a/Telegram/SourceFiles/media/stories/media_stories_reply.cpp b/Telegram/SourceFiles/media/stories/media_stories_reply.cpp index b1a33d9c1..d93f49bf1 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_reply.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_reply.cpp @@ -123,7 +123,7 @@ ReplyArea::ReplyArea(not_null controller) showPremiumToast(emoji); }, .mode = HistoryView::ComposeControlsMode::Normal, - .sendMenuType = SendMenu::Type::SilentOnly, + .sendMenuDetails = sendMenuDetails(), .stickerOrEmojiChosen = _controller->stickerOrEmojiChosen(), .customPlaceholder = PlaceholderText( _controller->uiShow(), @@ -473,6 +473,15 @@ void ReplyArea::chooseAttach( crl::guard(this, [=] { _choosingAttach = false; })); } +Fn ReplyArea::sendMenuDetails() const { + return crl::guard(this, [=] { + return SendMenu::Details{ + .type = SendMenu::Type::SilentOnly, + .effectAllowed = _data.peer && _data.peer->isUser(), + }; + }); +} + bool ReplyArea::confirmSendingFiles( not_null data, std::optional overrideSendImagesAsPhotos, @@ -528,7 +537,7 @@ bool ReplyArea::confirmSendingFiles( .limits = DefaultLimitsForPeer(_data.peer), .check = DefaultCheckForPeer(show, _data.peer), .sendType = Api::SendType::Normal, - .sendMenuType = SendMenu::Type::SilentOnly, + .sendMenuDetails = sendMenuDetails(), .stOverride = &st::storiesComposeControls, .confirmed = crl::guard(this, confirmed), .cancelled = _controls->restoreTextCallback(insertTextOnCancel), diff --git a/Telegram/SourceFiles/media/stories/media_stories_reply.h b/Telegram/SourceFiles/media/stories/media_stories_reply.h index 90214b421..3e4ff217b 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_reply.h +++ b/Telegram/SourceFiles/media/stories/media_stories_reply.h @@ -38,6 +38,10 @@ namespace Main { class Session; } // namespace Main +namespace SendMenu { +struct Details; +} // namespace SendMenu + namespace Ui { struct PreparedList; class SendFilesWay; @@ -141,6 +145,8 @@ private: void sendVoice(VoiceToSend &&data); void chooseAttach(std::optional overrideSendImagesAsPhotos); + [[nodiscard]] Fn sendMenuDetails() const; + void showPremiumToast(not_null emoji); [[nodiscard]] bool showSlowmodeError(); diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 94dede7e9..836887e8c 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -348,8 +348,8 @@ public: rpl::producer adjustShadowLeft() const override { return rpl::single(false); } - SendMenu::Type sendMenuType() const override { - return SendMenu::Type::SilentOnly; + SendMenu::Details sendMenuDetails() const override { + return { SendMenu::Type::SilentOnly }; } bool showMediaPreview( diff --git a/Telegram/SourceFiles/menu/menu_send.cpp b/Telegram/SourceFiles/menu/menu_send.cpp index 1a1b09757..1f216122b 100644 --- a/Telegram/SourceFiles/menu/menu_send.cpp +++ b/Telegram/SourceFiles/menu/menu_send.cpp @@ -37,140 +37,121 @@ namespace { not_null session) { auto result = Data::PossibleItemReactionsRef(); const auto reactions = &session->data().reactions(); - const auto &full = reactions->list(Data::Reactions::Type::Active); - const auto &top = reactions->list(Data::Reactions::Type::Top); - const auto &recent = reactions->list(Data::Reactions::Type::Recent); + const auto &effects = reactions->list(Data::Reactions::Type::Effects); const auto premiumPossible = session->premiumPossible(); auto added = base::flat_set(); - result.recent.reserve(full.size()); - for (const auto &reaction : ranges::views::concat(top, recent, full)) { - if (premiumPossible || !reaction.id.custom()) { + result.recent.reserve(effects.size()); + for (const auto &reaction : effects) { + if (premiumPossible || !reaction.premium) { if (added.emplace(reaction.id).second) { result.recent.push_back(&reaction); } } } - result.customAllowed = premiumPossible; - const auto i = ranges::find( - result.recent, - reactions->favoriteId(), - &Data::Reaction::id); - if (i != end(result.recent) && i != begin(result.recent)) { - std::rotate(begin(result.recent), i, i + 1); - } return result; } } // namespace -Fn DefaultSilentCallback(Fn send) { - return [=] { send({ .silent = true }); }; -} - -Fn DefaultScheduleCallback( +Fn DefaultCallback( std::shared_ptr show, - Type type, Fn send) { - return [=, weak = Ui::MakeWeak(show->toastParent())] { - show->showBox( - HistoryView::PrepareScheduleBox( - weak, - show, - type, - [=](Api::SendOptions options) { send(options); }), - Ui::LayerOption::KeepOther); + const auto guard = Ui::MakeWeak(show->toastParent()); + return [=](Action action, Details details) { + if (const auto options = std::get_if(&action)) { + send(*options); + } else if (v::get(action) == ActionType::Send) { + send({}); + } else { + using namespace HistoryView; + auto box = PrepareScheduleBox(guard, show, details, send); + const auto weak = Ui::MakeWeak(box.data()); + show->showBox(std::move(box)); + if (const auto strong = weak.data()) { + strong->setCloseByOutsideClick(false); + } + } }; } -Fn DefaultWhenOnlineCallback(Fn send) { - return [=] { send(Api::DefaultSendWhenOnlineOptions()); }; -} - FillMenuResult FillSendMenu( not_null menu, - Type type, - Fn silent, - Fn schedule, - Fn whenOnline, - const style::ComposeIcons *iconsOverride) { - if (!silent && !schedule) { - return FillMenuResult::None; + std::shared_ptr showForEffect, + Details details, + Fn action, + const style::ComposeIcons *iconsOverride, + std::optional desiredPositionOverride) { + const auto type = details.type; + if (type == Type::Disabled || !action) { + return FillMenuResult::Skipped; } const auto &icons = iconsOverride ? *iconsOverride : st::defaultComposeIcons; - const auto now = type; - if (now == Type::Disabled - || (!silent && now == Type::SilentOnly)) { - return FillMenuResult::None; - } - if (silent && now != Type::Reminder) { + if (type != Type::Reminder) { menu->addAction( tr::lng_send_silent_message(tr::now), - silent, + [=] { action(Api::SendOptions{ .silent = true }, details); }, &icons.menuMute); } - if (schedule && now != Type::SilentOnly) { + if (type != Type::SilentOnly) { menu->addAction( - (now == Type::Reminder + (type == Type::Reminder ? tr::lng_reminder_message(tr::now) : tr::lng_schedule_message(tr::now)), - schedule, + [=] { action(ActionType::Schedule, details); }, &icons.menuSchedule); } - if (whenOnline && now == Type::ScheduledToUser) { + if (type == Type::ScheduledToUser) { menu->addAction( tr::lng_scheduled_send_until_online(tr::now), - whenOnline, + [=] { action(Api::DefaultSendWhenOnlineOptions(), details); }, &icons.menuWhenOnline); } - return FillMenuResult::Success; + + using namespace HistoryView::Reactions; + const auto position = desiredPositionOverride.value_or(QCursor::pos()); + const auto selector = (showForEffect && details.effectAllowed) + ? AttachSelectorToMenu( + menu, + position, + st::reactPanelEmojiPan, + showForEffect, + LookupPossibleEffects(&showForEffect->session()), + { tr::lng_effect_add_title(tr::now) }) + : base::make_unexpected(AttachSelectorResult::Skipped); + if (!selector) { + if (selector.error() == AttachSelectorResult::Failed) { + return FillMenuResult::Failed; + } + menu->prepareGeometryFor(position); + return FillMenuResult::Prepared; + } + + (*selector)->chosen( + ) | rpl::start_with_next([=](ChosenReaction chosen) { + + }, menu->lifetime()); + + return FillMenuResult::Prepared; } void SetupMenuAndShortcuts( not_null button, std::shared_ptr show, - Fn type, - Fn silent, - Fn schedule, - Fn whenOnline) { - if (!silent && !schedule && !whenOnline) { - return; - } + Fn details, + Fn action) { const auto menu = std::make_shared>(); const auto showMenu = [=] { *menu = base::make_unique_q( button, st::popupMenuWithIcons); - const auto result = FillSendMenu( - *menu, - type(), - silent, - schedule, - whenOnline); - if (result != FillMenuResult::Success) { + const auto result = FillSendMenu(*menu, show, details(), action); + if (result != FillMenuResult::Prepared) { return false; } - const auto desiredPosition = QCursor::pos(); - using namespace HistoryView::Reactions; - const auto selector = show - ? AttachSelectorToMenu( - menu->get(), - desiredPosition, - st::reactPanelEmojiPan, - show, - LookupPossibleEffects(&show->session()), - { tr::lng_effect_add_title(tr::now) }) - : base::make_unexpected(AttachSelectorResult::Skipped); - if (selector) { - //(*selector)->chosen(); - (*menu)->popupPrepared(); - } else if (selector.error() == AttachSelectorResult::Failed) { - return false; - } else { - (*menu)->popup(desiredPosition); - } + (*menu)->popupPrepared(); return true; }; base::install_event_filter(button, [=](not_null e) { @@ -186,24 +167,21 @@ void SetupMenuAndShortcuts( }) | rpl::start_with_next([=](not_null request) { using Command = Shortcuts::Command; - const auto now = type(); - if (now == Type::Disabled - || (!silent && now == Type::SilentOnly)) { + const auto now = details().type; + if (now == Type::Disabled) { return; } - (silent - && (now != Type::Reminder) + ((now != Type::Reminder) && request->check(Command::SendSilentMessage) && request->handle([=] { - silent(); + action(Api::SendOptions{ .silent = true }, details()); return true; })) || - (schedule - && (now != Type::SilentOnly) + ((now != Type::SilentOnly) && request->check(Command::ScheduleMessage) && request->handle([=] { - schedule(); + action(ActionType::Schedule, details()); return true; })) || diff --git a/Telegram/SourceFiles/menu/menu_send.h b/Telegram/SourceFiles/menu/menu_send.h index 250ac1e77..66004c179 100644 --- a/Telegram/SourceFiles/menu/menu_send.h +++ b/Telegram/SourceFiles/menu/menu_send.h @@ -39,33 +39,39 @@ enum class Type { Reminder, }; -enum class FillMenuResult { - Success, - None, +struct Details { + Type type = Type::Disabled; + bool effectAllowed = false; }; -Fn DefaultSilentCallback(Fn send); -Fn DefaultScheduleCallback( +enum class FillMenuResult { + Prepared, + Skipped, + Failed, +}; + +enum class ActionType { + Send, + Schedule, +}; +using Action = std::variant; +[[nodiscard]] Fn DefaultCallback( std::shared_ptr show, - Type type, Fn send); -Fn DefaultWhenOnlineCallback(Fn send); FillMenuResult FillSendMenu( not_null menu, - Type type, - Fn silent, - Fn schedule, - Fn whenOnline, - const style::ComposeIcons *iconsOverride = nullptr); + std::shared_ptr showForEffect, + Details details, + Fn action, + const style::ComposeIcons *iconsOverride = nullptr, + std::optional desiredPositionOverride = std::nullopt); void SetupMenuAndShortcuts( not_null button, std::shared_ptr show, - Fn type, - Fn silent, - Fn schedule, - Fn whenOnline); + Fn details, + Fn action); void SetupUnreadMentionsMenu( not_null button, diff --git a/Telegram/SourceFiles/settings/business/settings_shortcut_messages.cpp b/Telegram/SourceFiles/settings/business/settings_shortcut_messages.cpp index 22e419efa..ccbb1aea2 100644 --- a/Telegram/SourceFiles/settings/business/settings_shortcut_messages.cpp +++ b/Telegram/SourceFiles/settings/business/settings_shortcut_messages.cpp @@ -242,7 +242,6 @@ private: mtpRequestId *const saveEditMsgRequestId, std::optional spoilerMediaOverride); void chooseAttach(std::optional overrideSendImagesAsPhotos); - [[nodiscard]] SendMenu::Type sendMenuType() const; [[nodiscard]] FullReplyTo replyTo() const; void doSetInnerFocus(); void showAtPosition( @@ -792,7 +791,7 @@ QPointer ShortcutMessages::createPinnedToBottom( listShowPremiumToast(emoji); }, .mode = HistoryView::ComposeControlsMode::Normal, - .sendMenuType = SendMenu::Type::Disabled, + .sendMenuDetails = [] { return SendMenu::Details(); }, .regularWindow = _controller, .stickerOrEmojiChosen = _controller->stickerOrEmojiChosen(), .customPlaceholder = std::move(placeholder), @@ -1346,7 +1345,7 @@ bool ShortcutMessages::confirmSendingFiles( _composeControls->getTextWithAppliedMarkdown(), _history->peer, Api::SendType::Normal, - SendMenu::Type::Disabled); + SendMenu::Details()); box->setConfirmedCallback(crl::guard(this, [=]( Ui::PreparedList &&list, @@ -1543,12 +1542,6 @@ void ShortcutMessages::sendInlineResult( return; } sendInlineResult(result, bot, {}, std::nullopt); - //const auto callback = [=](Api::SendOptions options) { - // sendInlineResult(result, bot, options); - //}; - //Ui::show( - // PrepareScheduleBox(this, sendMenuType(), callback), - // Ui::LayerOption::KeepOther); } void ShortcutMessages::sendInlineResult( diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index a4d57f791..cea289668 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -1141,7 +1141,7 @@ void Filler::addCreatePoll() { flag, flag, source, - sendMenuType); + { sendMenuType }); }; _addAction( tr::lng_polls_create(tr::now), @@ -1589,7 +1589,7 @@ void PeerMenuCreatePoll( PollData::Flags chosen, PollData::Flags disabled, Api::SendType sendType, - SendMenu::Type sendMenuType) { + SendMenu::Details sendMenuDetails) { if (peer->isChannel() && !peer->isMegagroup()) { chosen &= ~PollData::Flag::PublicVotes; disabled |= PollData::Flag::PublicVotes; @@ -1599,7 +1599,7 @@ void PeerMenuCreatePoll( chosen, disabled, sendType, - sendMenuType); + sendMenuDetails); const auto weak = Ui::MakeWeak(box.data()); const auto lock = box->lifetime().make_state(false); box->submitRequests( @@ -2071,17 +2071,14 @@ QPointer ShowForwardMessagesBox( state->menu->addSeparator(); } - const auto type = sendMenuType(); + state->menu->setForcedVerticalOrigin( + Ui::PopupMenu::VerticalOrigin::Bottom); const auto result = SendMenu::FillSendMenu( state->menu.get(), - type, - SendMenu::DefaultSilentCallback(submit), - SendMenu::DefaultScheduleCallback(show, type, submit), - SendMenu::DefaultWhenOnlineCallback(submit)); - const auto success = (result == SendMenu::FillMenuResult::Success); - if (showForwardOptions || success) { - state->menu->setForcedVerticalOrigin( - Ui::PopupMenu::VerticalOrigin::Bottom); + show, + SendMenu::Details{ sendMenuType() }, + SendMenu::DefaultCallback(show, crl::guard(parent, submit))); + if (showForwardOptions || !state->menu->empty()) { state->menu->popup(QCursor::pos()); } }; diff --git a/Telegram/SourceFiles/window/window_peer_menu.h b/Telegram/SourceFiles/window/window_peer_menu.h index cc4f56178..4bf6c4d13 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.h +++ b/Telegram/SourceFiles/window/window_peer_menu.h @@ -91,7 +91,7 @@ void PeerMenuCreatePoll( PollData::Flags chosen = PollData::Flags(), PollData::Flags disabled = PollData::Flags(), Api::SendType sendType = Api::SendType::Normal, - SendMenu::Type sendMenuType = SendMenu::Type::Scheduled); + SendMenu::Details sendMenuDetails = SendMenu::Details()); void PeerMenuDeleteTopicWithConfirmation( not_null navigation, not_null topic); diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index d611652f7..37acebe47 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -122,7 +122,7 @@ public: rpl::producer<> pauseChanged() const override; rpl::producer adjustShadowLeft() const override; - SendMenu::Type sendMenuType() const override; + SendMenu::Details sendMenuDetails() const override; bool showMediaPreview( Data::FileOrigin origin, @@ -272,12 +272,12 @@ rpl::producer MainWindowShow::adjustShadowLeft() const { }); } -SendMenu::Type MainWindowShow::sendMenuType() const { +SendMenu::Details MainWindowShow::sendMenuDetails() const { const auto window = _window.get(); if (!window) { - return SendMenu::Type::Disabled; + return SendMenu::Details(); } - return window->content()->sendMenuType(); + return window->content()->sendMenuDetails(); } bool MainWindowShow::showMediaPreview(