From 881aed50eafa41db62c59acaab685ee859ba3fd9 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 24 Jun 2025 15:00:05 +0400 Subject: [PATCH] Support _suggestOptions for changes in ComposeControls. --- Telegram/CMakeLists.txt | 4 +- Telegram/SourceFiles/api/api_suggest_post.cpp | 2 +- Telegram/SourceFiles/history/history.cpp | 2 +- .../SourceFiles/history/history_widget.cpp | 19 +-- Telegram/SourceFiles/history/history_widget.h | 3 +- .../history_view_compose_controls.cpp | 115 ++++++++++++++---- .../controls/history_view_compose_controls.h | 1 + .../history_view_suggest_options.cpp | 10 +- .../history_view_suggest_options.h | 8 +- 9 files changed, 118 insertions(+), 46 deletions(-) rename Telegram/SourceFiles/history/view/{ => controls}/history_view_suggest_options.cpp (98%) rename Telegram/SourceFiles/history/view/{ => controls}/history_view_suggest_options.h (92%) diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index d36f0213fa..a27e737f1e 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -757,6 +757,8 @@ PRIVATE history/view/controls/history_view_draft_options.h history/view/controls/history_view_forward_panel.cpp history/view/controls/history_view_forward_panel.h + history/view/controls/history_view_suggest_options.cpp + history/view/controls/history_view_suggest_options.h history/view/controls/history_view_ttl_button.cpp history/view/controls/history_view_ttl_button.h history/view/controls/history_view_voice_record_bar.cpp @@ -902,8 +904,6 @@ PRIVATE history/view/history_view_sticker_toast.h history/view/history_view_subsection_tabs.cpp history/view/history_view_subsection_tabs.h - history/view/history_view_suggest_options.cpp - history/view/history_view_suggest_options.h history/view/history_view_text_helper.cpp history/view/history_view_text_helper.h history/view/history_view_transcribe_button.cpp diff --git a/Telegram/SourceFiles/api/api_suggest_post.cpp b/Telegram/SourceFiles/api/api_suggest_post.cpp index b6a04474d3..1c5299e647 100644 --- a/Telegram/SourceFiles/api/api_suggest_post.cpp +++ b/Telegram/SourceFiles/api/api_suggest_post.cpp @@ -14,7 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_changes.h" #include "data/data_session.h" #include "data/data_saved_sublist.h" -#include "history/view/history_view_suggest_options.h" +#include "history/view/controls/history_view_suggest_options.h" #include "history/history.h" #include "history/history_item.h" #include "history/history_item_components.h" diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 431bf17de1..04da9df94b 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -3394,7 +3394,7 @@ bool History::amMonoforumAdmin() const { } bool History::suggestDraftAllowed() const { - return peer->isMonoforum() || !peer->amMonoforumAdmin(); + return peer->isMonoforum() && !peer->amMonoforumAdmin(); } not_null History::migrateToOrMe() const { diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 17eabdada5..93c1f62a2d 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -97,8 +97,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/controls/history_view_compose_search.h" #include "history/view/controls/history_view_forward_panel.h" #include "history/view/controls/history_view_draft_options.h" -#include "history/view/controls/history_view_voice_record_bar.h" +#include "history/view/controls/history_view_suggest_options.h" #include "history/view/controls/history_view_ttl_button.h" +#include "history/view/controls/history_view_voice_record_bar.h" #include "history/view/controls/history_view_webpage_processor.h" #include "history/view/reactions/history_view_reactions_button.h" #include "history/view/history_view_cursor_state.h" @@ -118,7 +119,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_requests_bar.h" #include "history/view/history_view_sticker_toast.h" #include "history/view/history_view_subsection_tabs.h" -#include "history/view/history_view_suggest_options.h" #include "history/view/history_view_translate_bar.h" #include "history/view/media/history_view_media.h" #include "profile/profile_block_group_members.h" @@ -1902,7 +1902,7 @@ void HistoryWidget::saveFieldToHistoryLocalDraft() { .topicRootId = topicRootId, .monoforumPeerId = monoforumPeerId, }, - SuggestPostOptions(), + suggestOptions(true), _preview->draft(), _saveEditMsgRequestId)); } else { @@ -2935,7 +2935,7 @@ void HistoryWidget::registerDraftSource() { (editMsgId ? FullReplyTo{ FullMsgId(peerId, editMsgId) } : _replyTo), - (editMsgId ? SuggestPostOptions() : suggestOptions()), + suggestOptions(editMsgId != 0), _field->getTextWithTags(), _preview->draft(), }; @@ -3180,7 +3180,7 @@ void HistoryWidget::applySuggestOptions( using namespace HistoryView; _suggestOptions = std::make_unique( - controller(), + controller()->uiShow(), _peer, suggest, mode); @@ -4522,7 +4522,7 @@ void HistoryWidget::saveEditMessage(Api::SendOptions options) { }; options.invertCaption = _mediaEditManager.invertCaption(); - options.suggest = suggestOptions(); + options.suggest = suggestOptions(true); const auto withPaymentApproved = [=](int approved) { auto copy = options; @@ -6700,8 +6700,11 @@ FullReplyTo HistoryWidget::replyTo() const { : FullReplyTo(); } -SuggestPostOptions HistoryWidget::suggestOptions() const { - return (_history && _history->suggestDraftAllowed() && _suggestOptions) +SuggestPostOptions HistoryWidget::suggestOptions( + bool skipNoAdminCheck) const { + const auto checked = skipNoAdminCheck + || (_history && _history->suggestDraftAllowed()); + return (checked && _suggestOptions) ? _suggestOptions->values() : SuggestPostOptions(); } diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index ec81821ee6..8c6a61f8b3 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -216,7 +216,8 @@ public: not_null peer); [[nodiscard]] FullReplyTo replyTo() const; - [[nodiscard]] SuggestPostOptions suggestOptions() const; + [[nodiscard]] SuggestPostOptions suggestOptions( + bool skipNoAdminCheck = false) const; bool lastForceReplyReplied(const FullMsgId &replyTo) const; bool lastForceReplyReplied() const; bool cancelReplyOrSuggest(bool lastKeyboardUsed = false); 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 294ffd9ca5..a64e31d825 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -54,8 +54,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/controls/history_view_compose_media_edit_manager.h" #include "history/view/controls/history_view_forward_panel.h" #include "history/view/controls/history_view_draft_options.h" -#include "history/view/controls/history_view_voice_record_bar.h" +#include "history/view/controls/history_view_suggest_options.h" #include "history/view/controls/history_view_ttl_button.h" +#include "history/view/controls/history_view_voice_record_bar.h" #include "history/view/controls/history_view_webpage_processor.h" #include "history/view/history_view_reply.h" #include "history/view/history_view_webpage_preview.h" @@ -134,7 +135,10 @@ public: void updateTopicRootId(MsgId topicRootId); void init(); - void editMessage(FullMsgId id, bool photoEditAllowed = false); + void editMessage( + FullMsgId id, + SuggestPostOptions suggest, + bool photoEditAllowed = false); void replyToMessage(FullReplyTo id); void updateForwarding( Data::Thread *thread, @@ -159,6 +163,7 @@ public: [[nodiscard]] SendMenu::Details saveMenuDetails(bool hasSendText) const; [[nodiscard]] FullReplyTo getDraftReply() const; + [[nodiscard]] SuggestPostOptions suggestOptions() const; [[nodiscard]] rpl::producer<> editCancelled() const { return _editCancelled.events(); } @@ -171,6 +176,9 @@ public: [[nodiscard]] rpl::producer<> previewCancelled() const { return _previewCancelled.events(); } + [[nodiscard]] rpl::producer<> saveDraftRequests() const { + return _saveDraftRequests.events(); + } [[nodiscard]] rpl::producer visibleChanged(); @@ -188,6 +196,9 @@ private: bool hasPreview() const; + void applySuggestOptions(SuggestPostOptions suggest, SuggestMode mode); + void cancelSuggestPost(); + struct Preview { Controls::WebpageParsed parsed; Ui::Text::String title; @@ -206,11 +217,13 @@ private: rpl::event_stream<> _replyCancelled; rpl::event_stream<> _forwardCancelled; rpl::event_stream<> _previewCancelled; + rpl::event_stream<> _saveDraftRequests; rpl::lifetime _previewLifetime; rpl::variable _editMsgId; rpl::variable _replyTo; std::unique_ptr _forwardPanel; + std::unique_ptr _suggestOptions; rpl::producer<> _toForwardUpdated; HistoryItem *_shownMessage = nullptr; @@ -282,7 +295,9 @@ void FieldHeader::init() { p.fillRect(rect(), st::historyComposeAreaBg); const auto position = st::historyReplyIconPosition; - if (_preview.parsed) { + if (_suggestOptions) { + _suggestOptions->paintIcon(p, 0, 0, width()); + } else if (_preview.parsed) { st::historyLinkIcon.paint(p, position, width()); } else if (isEditingMessage()) { st::historyEditIcon.paint(p, position, width()); @@ -647,7 +662,11 @@ void FieldHeader::paintEditOrReplyToMessage(Painter &p) { st::historyEditMedia.paintInCenter(p, to); p.setOpacity(1.); } + } + if (_suggestOptions) { + _suggestOptions->paintLines(p, textLeft, 0, width()); + return; } p.setPen(st::historyReplyNameFg); @@ -734,6 +753,12 @@ FullReplyTo FieldHeader::getDraftReply() const { : _replyTo.current(); } +SuggestPostOptions FieldHeader::suggestOptions() const { + return _suggestOptions + ? _suggestOptions->values() + : SuggestPostOptions(); +} + void FieldHeader::updateControlsGeometry(QSize size) { _cancel->moveToRight(0, 0); _clickableRect = QRect( @@ -748,7 +773,10 @@ void FieldHeader::updateControlsGeometry(QSize size) { st::historyReplyPreview); } -void FieldHeader::editMessage(FullMsgId id, bool photoEditAllowed) { +void FieldHeader::editMessage( + FullMsgId id, + SuggestPostOptions suggest, + bool photoEditAllowed) { _photoEditAllowed = photoEditAllowed; _editMsgId = id; if (!id) { @@ -760,9 +788,38 @@ void FieldHeader::editMessage(FullMsgId id, bool photoEditAllowed) { _inPhotoEdit = false; _inPhotoEditOver.stop(); } + if (id && suggest) { + applySuggestOptions(suggest, SuggestMode::Change); + } else { + cancelSuggestPost(); + } update(); } +void FieldHeader::applySuggestOptions( + SuggestPostOptions suggest, + SuggestMode mode) { + Expects(suggest.exists); + + using namespace HistoryView; + _suggestOptions = std::make_unique( + _show, + _history->peer, + suggest, + mode); + _suggestOptions->updates() | rpl::start_with_next([=] { + update(); + _saveDraftRequests.fire({}); + }, _suggestOptions->lifetime()); +} + +void FieldHeader::cancelSuggestPost() { + if (!_suggestOptions) { + return; + } + _suggestOptions = nullptr; +} + void FieldHeader::replyToMessage(FullReplyTo id) { id.monoforumPeerId = 0; _replyTo = id; @@ -802,6 +859,7 @@ MessageToEdit FieldHeader::queryToEdit() { .scheduled = item->isScheduled() ? item->date() : 0, .shortcutId = item->shortcutId(), .invertCaption = _mediaEditManager.invertCaption(), + .suggest = suggestOptions(), }, .spoilered = _mediaEditManager.spoilered(), }; @@ -1467,9 +1525,12 @@ void ComposeControls::init() { if (_preview) { _preview->apply({ .removed = true }); } - _saveDraftText = true; - _saveDraftStart = crl::now(); - saveDraft(); + saveDraftWithTextNow(); + }, _wrap->lifetime()); + + _header->saveDraftRequests( + ) | rpl::start_with_next([=] { + saveDraftWithTextNow(); }, _wrap->lifetime()); _header->editCancelled( @@ -1704,9 +1765,7 @@ void ComposeControls::initFieldAutocomplete() { if (!_showSlowmodeError || !_showSlowmodeError()) { setText({}); } - //_saveDraftText = true; - //_saveDraftStart = crl::now(); - //saveDraft(); + //saveDraftWithTextNow(); // Won't be needed if SendInlineBotResult clears the cloud draft. //saveCloudDraft(); _fileChosen.fire(std::move(data)); @@ -1845,6 +1904,12 @@ Data::DraftKey ComposeControls::draftKeyCurrent() const { return draftKey(isEditingMessage() ? DraftType::Edit : DraftType::Normal); } +void ComposeControls::saveDraftWithTextNow() { + _saveDraftText = true; + _saveDraftStart = crl::now(); + saveDraft(); +} + void ComposeControls::saveDraft(bool delayed) { if (delayed) { const auto now = crl::now(); @@ -1897,7 +1962,7 @@ void ComposeControls::registerDraftSource() { const auto draft = [=] { return Storage::MessageDraft{ _header->getDraftReply(), - SuggestPostOptions(), + _header->suggestOptions(), _field->getTextWithTags(), _preview->draft(), }; @@ -1948,6 +2013,9 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) { const auto editingId = (draft && draft == editDraft) ? draft->reply.messageId : FullMsgId(); + const auto editingSuggest = (draft && draft == editDraft) + ? draft->suggest + : SuggestPostOptions(); InvokeQueued(_autocomplete.get(), [=] { if (_autocomplete) { @@ -1968,7 +2036,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) { if (hadFocus) { _field->setFocus(); } - _header->editMessage({}); + _header->editMessage({}, {}); _header->replyToMessage({}); if (_preview) { _preview->apply({ .removed = true }); @@ -2015,7 +2083,10 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) { Data::PhotoSize::Large, item->fullId()); } - _header->editMessage(editingId, _photoEditMedia != nullptr); + _header->editMessage( + editingId, + editingSuggest, + _photoEditMedia != nullptr); if (_preview) { _preview->apply( Data::WebPageDraft::FromItem(item), @@ -2026,7 +2097,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) { } _canReplaceMedia = _canAddMedia = false; _photoEditMedia = nullptr; - _header->editMessage(editingId, false); + _header->editMessage(editingId, SuggestPostOptions(), false); return false; }; if (!resolve()) { @@ -2048,7 +2119,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) { _canReplaceMedia = _canAddMedia = false; _photoEditMedia = nullptr; _header->replyToMessage(draft->reply); - _header->editMessage({}); + _header->editMessage({}, {}); if (_preview) { _preview->setDisabled(false); } @@ -3036,10 +3107,7 @@ void ComposeControls::cancelEditMessage() { _history->clearDraft(draftKey(DraftType::Edit)); applyDraft(); - - _saveDraftText = true; - _saveDraftStart = crl::now(); - saveDraft(); + saveDraftWithTextNow(); } void ComposeControls::maybeCancelEditMessage() { @@ -3091,10 +3159,7 @@ void ComposeControls::replyToMessage(FullReplyTo id) { } else { _header->replyToMessage(id); } - - _saveDraftText = true; - _saveDraftStart = crl::now(); - saveDraft(); + saveDraftWithTextNow(); } void ComposeControls::cancelReplyMessage() { @@ -3112,9 +3177,7 @@ void ComposeControls::cancelReplyMessage() { } } if (wasReply) { - _saveDraftText = true; - _saveDraftStart = crl::now(); - saveDraft(); + saveDraftWithTextNow(); } } } 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 cd391e0078..4efc974160 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h @@ -331,6 +331,7 @@ private: [[nodiscard]] Data::DraftKey draftKeyCurrent() const; void saveDraft(bool delayed = false); void saveDraftDelayed(); + void saveDraftWithTextNow(); void saveCloudDraft(); void writeDrafts(); diff --git a/Telegram/SourceFiles/history/view/history_view_suggest_options.cpp b/Telegram/SourceFiles/history/view/controls/history_view_suggest_options.cpp similarity index 98% rename from Telegram/SourceFiles/history/view/history_view_suggest_options.cpp rename to Telegram/SourceFiles/history/view/controls/history_view_suggest_options.cpp index be36d9e24d..b8fe4fe0ab 100644 --- a/Telegram/SourceFiles/history/view/history_view_suggest_options.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_suggest_options.cpp @@ -5,9 +5,10 @@ the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ -#include "history/view/history_view_suggest_options.h" +#include "history/view/controls/history_view_suggest_options.h" #include "base/unixtime.h" +#include "chat_helpers/compose/compose_show.h" #include "core/ui_integration.h" #include "data/stickers/data_custom_emoji.h" #include "data/data_channel.h" @@ -29,7 +30,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/wrap/slide_wrap.h" #include "ui/painter.h" #include "ui/vertical_list.h" -#include "window/window_session_controller.h" #include "styles/style_channel_earn.h" #include "styles/style_chat.h" #include "styles/style_chat_helpers.h" @@ -381,11 +381,11 @@ bool CanEditSuggestedMessage(not_null item) { } SuggestOptions::SuggestOptions( - not_null controller, + std::shared_ptr show, not_null peer, SuggestPostOptions values, SuggestMode mode) -: _controller(controller) +: _show(std::move(show)) , _peer(peer) , _mode(mode) , _values(values) { @@ -435,7 +435,7 @@ void SuggestOptions::edit() { strong->closeBox(); } }; - *weak = _controller->show(Box(ChooseSuggestPriceBox, SuggestPriceBoxArgs{ + *weak = _show->show(Box(ChooseSuggestPriceBox, SuggestPriceBoxArgs{ .session = &_peer->session(), .done = apply, .value = _values, diff --git a/Telegram/SourceFiles/history/view/history_view_suggest_options.h b/Telegram/SourceFiles/history/view/controls/history_view_suggest_options.h similarity index 92% rename from Telegram/SourceFiles/history/view/history_view_suggest_options.h rename to Telegram/SourceFiles/history/view/controls/history_view_suggest_options.h index fbf15d12b7..b4b49fd671 100644 --- a/Telegram/SourceFiles/history/view/history_view_suggest_options.h +++ b/Telegram/SourceFiles/history/view/controls/history_view_suggest_options.h @@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_common.h" +namespace ChatHelpers { +class Show; +} // namespace ChatHelpers + namespace Ui { class GenericBox; } // namespace Ui @@ -54,7 +58,7 @@ void ChooseSuggestPriceBox( class SuggestOptions final { public: SuggestOptions( - not_null controller, + std::shared_ptr show, not_null peer, SuggestPostOptions values, SuggestMode mode); @@ -77,7 +81,7 @@ private: [[nodiscard]] TextWithEntities composeText() const; - const not_null _controller; + const std::shared_ptr _show; const not_null _peer; const SuggestMode _mode = SuggestMode::New;