Fix external replies in topic groups.

This commit is contained in:
John Preston 2023-10-31 10:39:54 +04:00
parent 475b2ac739
commit b793c06759
14 changed files with 65 additions and 33 deletions

View File

@ -270,7 +270,6 @@ bool SendDice(MessageToSend &message) {
flags |= MessageFlag::HasReplyInfo; flags |= MessageFlag::HasReplyInfo;
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to; sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to;
} }
const auto replyHeader = NewMessageReplyHeader(message.action);
const auto anonymousPost = peer->amAnonymous(); const auto anonymousPost = peer->amAnonymous();
const auto silentPost = ShouldSendSilent(peer, message.action.options); const auto silentPost = ShouldSendSilent(peer, message.action.options);
InnerFillMessagePostFlags(message.action.options, peer, flags); InnerFillMessagePostFlags(message.action.options, peer, flags);
@ -399,7 +398,6 @@ void SendConfirmedFile(
if (file->to.replyTo) { if (file->to.replyTo) {
flags |= MessageFlag::HasReplyInfo; flags |= MessageFlag::HasReplyInfo;
} }
const auto replyHeader = NewMessageReplyHeader(action);
const auto anonymousPost = peer->amAnonymous(); const auto anonymousPost = peer->amAnonymous();
const auto silentPost = ShouldSendSilent(peer, file->to.options); const auto silentPost = ShouldSendSilent(peer, file->to.options);
FillMessagePostFlags(action, peer, flags); FillMessagePostFlags(action, peer, flags);

View File

@ -3376,7 +3376,6 @@ void ApiWrap::sendSharedContact(
if (action.replyTo) { if (action.replyTo) {
flags |= MessageFlag::HasReplyInfo; flags |= MessageFlag::HasReplyInfo;
} }
const auto replyHeader = NewMessageReplyHeader(action);
FillMessagePostFlags(action, peer, flags); FillMessagePostFlags(action, peer, flags);
if (action.options.scheduled) { if (action.options.scheduled) {
flags |= MessageFlag::IsOrWasScheduled; flags |= MessageFlag::IsOrWasScheduled;
@ -3640,7 +3639,6 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
const auto manualWebPage = exactWebPage const auto manualWebPage = exactWebPage
&& !ignoreWebPage && !ignoreWebPage
&& (message.webPage.manual || (isLast && !isFirst)); && (message.webPage.manual || (isLast && !isFirst));
const auto replyHeader = NewMessageReplyHeader(action);
MTPMessageMedia media = MTP_messageMediaEmpty(); MTPMessageMedia media = MTP_messageMediaEmpty();
if (ignoreWebPage) { if (ignoreWebPage) {
sendFlags |= MTPmessages_SendMessage::Flag::f_no_webpage; sendFlags |= MTPmessages_SendMessage::Flag::f_no_webpage;

View File

@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/notifications_manager.h" #include "window/notifications_manager.h"
#include "history/history.h" #include "history/history.h"
#include "history/history_item.h" #include "history/history_item.h"
#include "history/history_item_helpers.h"
#include "history/view/history_view_element.h" #include "history/view/history_view_element.h"
#include "core/application.h" #include "core/application.h"
#include "apiwrap.h" #include "apiwrap.h"
@ -46,8 +47,10 @@ MTPInputReplyTo ReplyToForMTP(
} }
} }
} else if (replyTo.messageId || replyTo.topicRootId) { } else if (replyTo.messageId || replyTo.topicRootId) {
const auto to = LookupReplyTo(history, replyTo.messageId);
const auto external = replyTo.messageId const auto external = replyTo.messageId
&& (replyTo.messageId.peer != history->peer->id); && (replyTo.messageId.peer != history->peer->id
|| (replyTo.topicRootId != to->topicRootId()));
const auto quoteEntities = Api::EntitiesToMTP( const auto quoteEntities = Api::EntitiesToMTP(
&history->session(), &history->session(),
replyTo.quote.entities, replyTo.quote.entities,

View File

@ -3337,16 +3337,28 @@ void HistoryItem::createComponentsHelper(
? replyTo.messageId.peer ? replyTo.messageId.peer
: PeerId(); : PeerId();
const auto to = LookupReplyTo(_history, replyTo.messageId); const auto to = LookupReplyTo(_history, replyTo.messageId);
const auto replyToTop = LookupReplyToTop(_history, to); const auto replyToTop = replyTo.topicRootId
? replyTo.topicRootId
: LookupReplyToTop(_history, to);
config.reply.topMessageId = replyToTop config.reply.topMessageId = replyToTop
? replyToTop ? replyToTop
: (replyTo.messageId.peer == history()->peer->id) : (replyTo.messageId.peer == history()->peer->id)
? replyTo.messageId.msg ? replyTo.messageId.msg
: MsgId(); : MsgId();
if (!config.reply.externalPeerId
&& to
&& config.reply.topicPost
&& replyTo.topicRootId != to->topicRootId()) {
config.reply.externalPeerId = replyTo.messageId.peer;
}
const auto forum = _history->asForum(); const auto forum = _history->asForum();
config.reply.topicPost = LookupReplyIsTopicPost(to) config.reply.topicPost = config.reply.externalPeerId
|| (to && to->Has<HistoryServiceTopicInfo>()) ? (replyTo.topicRootId
|| (forum && forum->creating(config.reply.topMessageId)); && (replyTo.topicRootId != Data::ForumTopic::kGeneralId))
: (LookupReplyIsTopicPost(to)
|| (to && to->Has<HistoryServiceTopicInfo>())
|| (forum && forum->creating(config.reply.topMessageId)));
config.reply.manualQuote = !replyTo.quote.empty();
config.reply.quote = std::move(replyTo.quote); config.reply.quote = std::move(replyTo.quote);
} }
config.markup = std::move(markup); config.markup = std::move(markup);

View File

@ -426,6 +426,7 @@ ReplyFields ReplyFieldsFromMTP(
&owner->session(), &owner->session(),
data.vquote_entities().value_or_empty()), data.vquote_entities().value_or_empty()),
}; };
result.manualQuote = data.is_quote();
return result; return result;
}, [&](const MTPDmessageReplyStoryHeader &data) { }, [&](const MTPDmessageReplyStoryHeader &data) {
return ReplyFields{ return ReplyFields{
@ -633,7 +634,7 @@ void HistoryMessageReply::setLinkFrom(
? JumpToMessageClickHandler( ? JumpToMessageClickHandler(
resolvedMessage.get(), resolvedMessage.get(),
holder->fullId(), holder->fullId(),
_fields.quote) _fields.manualQuote ? _fields.quote : TextWithEntities())
: resolvedStory : resolvedStory
? JumpToStoryClickHandler(resolvedStory.get()) ? JumpToStoryClickHandler(resolvedStory.get())
: (external && !_fields.messageId) : (external && !_fields.messageId)
@ -835,7 +836,7 @@ void HistoryMessageReply::paint(
y += st::historyReplyTop; y += st::historyReplyTop;
const auto rect = QRect(x, y, w, _height); const auto rect = QRect(x, y, w, _height);
const auto hasQuote = !_fields.quote.empty(); const auto hasQuote = _fields.manualQuote && !_fields.quote.empty();
const auto selected = context.selected(); const auto selected = context.selected();
const auto colorPeer = resolvedMessage const auto colorPeer = resolvedMessage
? resolvedMessage->displayFrom() ? resolvedMessage->displayFrom()

View File

@ -239,6 +239,7 @@ struct ReplyFields {
MsgId topMessageId = 0; MsgId topMessageId = 0;
StoryId storyId = 0; StoryId storyId = 0;
bool topicPost = false; bool topicPost = false;
bool manualQuote = false;
}; };
[[nodiscard]] ReplyFields ReplyFieldsFromMTP( [[nodiscard]] ReplyFields ReplyFieldsFromMTP(
@ -321,6 +322,9 @@ struct HistoryMessageReply
[[nodiscard]] bool topicPost() const { [[nodiscard]] bool topicPost() const {
return _fields.topicPost; return _fields.topicPost;
} }
[[nodiscard]] bool manualQuote() const {
return _fields.manualQuote;
}
[[nodiscard]] QString statePhrase() const; [[nodiscard]] QString statePhrase() const;
void setLinkFrom(not_null<HistoryItem*> holder); void setLinkFrom(not_null<HistoryItem*> holder);

View File

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "history/history_item_helpers.h" #include "history/history_item_helpers.h"
#include "api/api_text_entities.h"
#include "calls/calls_instance.h" #include "calls/calls_instance.h"
#include "data/notify/data_notify_settings.h" #include "data/notify/data_notify_settings.h"
#include "data/data_chat_participant_status.h" #include "data/data_chat_participant_status.h"
@ -202,6 +203,14 @@ MsgId LookupReplyToTop(not_null<History*> history, HistoryItem *replyTo) {
: 0; : 0;
} }
MsgId LookupReplyToTop(not_null<History*> history, FullReplyTo replyTo) {
return replyTo.topicRootId
? replyTo.topicRootId
: LookupReplyToTop(
history,
LookupReplyTo(history, replyTo.messageId));
}
bool LookupReplyIsTopicPost(HistoryItem *replyTo) { bool LookupReplyIsTopicPost(HistoryItem *replyTo) {
return replyTo return replyTo
&& (replyTo->topicRootId() != Data::ForumTopic::kGeneralId); && (replyTo->topicRootId() != Data::ForumTopic::kGeneralId);
@ -373,19 +382,27 @@ MTPMessageReplyHeader NewMessageReplyHeader(const Api::SendAction &action) {
const auto externalPeerId = (replyTo.messageId.peer == historyPeer) const auto externalPeerId = (replyTo.messageId.peer == historyPeer)
? PeerId() ? PeerId()
: replyTo.messageId.peer; : replyTo.messageId.peer;
const auto to = LookupReplyTo(action.history, replyTo.messageId); const auto replyToTop = LookupReplyToTop(action.history, replyTo);
const auto replyToTop = LookupReplyToTop(action.history, to); auto quoteEntities = Api::EntitiesToMTP(
&action.history->session(),
replyTo.quote.entities,
Api::ConvertOption::SkipLocal);
return MTP_messageReplyHeader( return MTP_messageReplyHeader(
MTP_flags(Flag::f_reply_to_msg_id MTP_flags(Flag::f_reply_to_msg_id
| (replyToTop ? Flag::f_reply_to_top_id : Flag()) | (replyToTop ? Flag::f_reply_to_top_id : Flag())
| (externalPeerId ? Flag::f_reply_to_peer_id : Flag())), | (externalPeerId ? Flag::f_reply_to_peer_id : Flag())
| (replyTo.quote.empty() ? Flag() : Flag::f_quote)
| (replyTo.quote.empty() ? Flag() : Flag::f_quote_text)
| (quoteEntities.v.empty()
? Flag()
: Flag::f_quote_entities)),
MTP_int(replyTo.messageId.msg), MTP_int(replyTo.messageId.msg),
peerToMTP(externalPeerId), peerToMTP(externalPeerId),
MTPMessageFwdHeader(), // reply_from MTPMessageFwdHeader(), // reply_from
MTPMessageMedia(), // reply_media MTPMessageMedia(), // reply_media
MTP_int(replyToTop), // reply_to_top_id MTP_int(replyToTop),
MTPstring(), // quote_text MTP_string(replyTo.quote.text),
MTPVector<MTPMessageEntity>()); // quote_entities quoteEntities);
} }
return MTPMessageReplyHeader(); return MTPMessageReplyHeader();
} }

View File

@ -89,6 +89,9 @@ void RequestDependentMessageStory(
[[nodiscard]] MsgId LookupReplyToTop( [[nodiscard]] MsgId LookupReplyToTop(
not_null<History*> history, not_null<History*> history,
HistoryItem *replyTo); HistoryItem *replyTo);
[[nodiscard]] MsgId LookupReplyToTop(
not_null<History*> history,
FullReplyTo replyTo);
[[nodiscard]] bool LookupReplyIsTopicPost(HistoryItem *replyTo); [[nodiscard]] bool LookupReplyIsTopicPost(HistoryItem *replyTo);
struct SendingErrorRequest { struct SendingErrorRequest {

View File

@ -6320,7 +6320,7 @@ void HistoryWidget::editDraftOptions() {
.resolver = _preview->resolver(), .resolver = _preview->resolver(),
.done = done, .done = done,
.highlight = highlight, .highlight = highlight,
.clearOldDraft = [=] { ClearDraftReplyTo(history, replyToId); }, .clearOldDraft = [=] { ClearDraftReplyTo(history, 0, replyToId); },
}); });
} }

View File

@ -1332,6 +1332,7 @@ void ComposeControls::init() {
_header->editOptionsRequests( _header->editOptionsRequests(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
const auto history = _history; const auto history = _history;
const auto topicRootId = _topicRootId;
const auto reply = _header->replyingToMessage(); const auto reply = _header->replyingToMessage();
const auto webpage = _preview->draft(); const auto webpage = _preview->draft();
@ -1360,7 +1361,10 @@ void ComposeControls::init() {
.resolver = _preview->resolver(), .resolver = _preview->resolver(),
.done = done, .done = done,
.highlight = highlight, .highlight = highlight,
.clearOldDraft = [=] { ClearDraftReplyTo(history, replyToId); }, .clearOldDraft = [=] { ClearDraftReplyTo(
history,
topicRootId,
replyToId); },
}); });
}, _wrap->lifetime()); }, _wrap->lifetime());

View File

@ -400,13 +400,6 @@ void ForwardPanel::paint(
}); });
} }
void ClearDraftReplyTo(not_null<Data::Thread*> thread, FullMsgId equalTo) {
ClearDraftReplyTo(
thread->owningHistory(),
thread->topicRootId(),
equalTo);
}
void ClearDraftReplyTo( void ClearDraftReplyTo(
not_null<History*> history, not_null<History*> history,
MsgId topicRootId, MsgId topicRootId,

View File

@ -72,7 +72,6 @@ private:
}; };
void ClearDraftReplyTo(not_null<Data::Thread*> thread, FullMsgId equalTo);
void ClearDraftReplyTo( void ClearDraftReplyTo(
not_null<History*> history, not_null<History*> history,
MsgId topicRootId, MsgId topicRootId,

View File

@ -330,6 +330,7 @@ RepliesWidget::RepliesWidget(
Controls::ShowReplyToChatBox(controller->uiShow(), { fullId }); Controls::ShowReplyToChatBox(controller->uiShow(), { fullId });
} else { } else {
replyToMessage(fullId); replyToMessage(fullId);
_composeControls->focus();
} }
}, _inner->lifetime()); }, _inner->lifetime());
@ -2016,7 +2017,7 @@ bool RepliesWidget::showMessage(
} }
const auto id = FullMsgId(_history->peer->id, messageId); const auto id = FullMsgId(_history->peer->id, messageId);
const auto message = _history->owner().message(id); const auto message = _history->owner().message(id);
if (!message) { if (!message || !message->inThread(_rootId)) {
return false; return false;
} }
const auto originMessage = [&]() -> HistoryItem* { const auto originMessage = [&]() -> HistoryItem* {
@ -2032,11 +2033,10 @@ bool RepliesWidget::showMessage(
} }
return nullptr; return nullptr;
}(); }();
if (!originMessage) {
return false;
}
const auto currentReplyReturn = _cornerButtons.replyReturn(); const auto currentReplyReturn = _cornerButtons.replyReturn();
const auto originItemId = (currentReplyReturn != originMessage) const auto originItemId = !originMessage
? FullMsgId()
: (currentReplyReturn != originMessage)
? originMessage->fullId() ? originMessage->fullId()
: FullMsgId(); : FullMsgId();
showAtPosition(message->position(), originItemId, params); showAtPosition(message->position(), originItemId, params);

@ -1 +1 @@
Subproject commit 6dc93b53a1c4d237dea0a458d2b02c4171529f18 Subproject commit 148be791963e32723056ae09de5f914f07df77b4