Support _suggestOptions for changes in ComposeControls.

This commit is contained in:
John Preston 2025-06-24 15:00:05 +04:00
parent 6272b79f70
commit 881aed50ea
9 changed files with 118 additions and 46 deletions

View file

@ -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

View file

@ -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"

View file

@ -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*> History::migrateToOrMe() const {

View file

@ -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<SuggestOptions>(
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();
}

View file

@ -216,7 +216,8 @@ public:
not_null<PeerData*> 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);

View file

@ -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<bool> 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<FullMsgId> _editMsgId;
rpl::variable<FullReplyTo> _replyTo;
std::unique_ptr<ForwardPanel> _forwardPanel;
std::unique_ptr<SuggestOptions> _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<SuggestOptions>(
_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();
}
}
}

View file

@ -331,6 +331,7 @@ private:
[[nodiscard]] Data::DraftKey draftKeyCurrent() const;
void saveDraft(bool delayed = false);
void saveDraftDelayed();
void saveDraftWithTextNow();
void saveCloudDraft();
void writeDrafts();

View file

@ -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<HistoryItem*> item) {
}
SuggestOptions::SuggestOptions(
not_null<Window::SessionController*> controller,
std::shared_ptr<ChatHelpers::Show> show,
not_null<PeerData*> 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,

View file

@ -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<Window::SessionController*> controller,
std::shared_ptr<ChatHelpers::Show> show,
not_null<PeerData*> peer,
SuggestPostOptions values,
SuggestMode mode);
@ -77,7 +81,7 @@ private:
[[nodiscard]] TextWithEntities composeText() const;
const not_null<Window::SessionController*> _controller;
const std::shared_ptr<ChatHelpers::Show> _show;
const not_null<PeerData*> _peer;
const SuggestMode _mode = SuggestMode::New;