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

View File

@ -3376,7 +3376,6 @@ void ApiWrap::sendSharedContact(
if (action.replyTo) {
flags |= MessageFlag::HasReplyInfo;
}
const auto replyHeader = NewMessageReplyHeader(action);
FillMessagePostFlags(action, peer, flags);
if (action.options.scheduled) {
flags |= MessageFlag::IsOrWasScheduled;
@ -3640,7 +3639,6 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
const auto manualWebPage = exactWebPage
&& !ignoreWebPage
&& (message.webPage.manual || (isLast && !isFirst));
const auto replyHeader = NewMessageReplyHeader(action);
MTPMessageMedia media = MTP_messageMediaEmpty();
if (ignoreWebPage) {
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 "history/history.h"
#include "history/history_item.h"
#include "history/history_item_helpers.h"
#include "history/view/history_view_element.h"
#include "core/application.h"
#include "apiwrap.h"
@ -46,8 +47,10 @@ MTPInputReplyTo ReplyToForMTP(
}
}
} else if (replyTo.messageId || replyTo.topicRootId) {
const auto to = LookupReplyTo(history, 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(
&history->session(),
replyTo.quote.entities,

View File

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

View File

@ -426,6 +426,7 @@ ReplyFields ReplyFieldsFromMTP(
&owner->session(),
data.vquote_entities().value_or_empty()),
};
result.manualQuote = data.is_quote();
return result;
}, [&](const MTPDmessageReplyStoryHeader &data) {
return ReplyFields{
@ -633,7 +634,7 @@ void HistoryMessageReply::setLinkFrom(
? JumpToMessageClickHandler(
resolvedMessage.get(),
holder->fullId(),
_fields.quote)
_fields.manualQuote ? _fields.quote : TextWithEntities())
: resolvedStory
? JumpToStoryClickHandler(resolvedStory.get())
: (external && !_fields.messageId)
@ -835,7 +836,7 @@ void HistoryMessageReply::paint(
y += st::historyReplyTop;
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 colorPeer = resolvedMessage
? resolvedMessage->displayFrom()

View File

@ -239,6 +239,7 @@ struct ReplyFields {
MsgId topMessageId = 0;
StoryId storyId = 0;
bool topicPost = false;
bool manualQuote = false;
};
[[nodiscard]] ReplyFields ReplyFieldsFromMTP(
@ -321,6 +322,9 @@ struct HistoryMessageReply
[[nodiscard]] bool topicPost() const {
return _fields.topicPost;
}
[[nodiscard]] bool manualQuote() const {
return _fields.manualQuote;
}
[[nodiscard]] QString statePhrase() const;
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 "api/api_text_entities.h"
#include "calls/calls_instance.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_chat_participant_status.h"
@ -202,6 +203,14 @@ MsgId LookupReplyToTop(not_null<History*> history, HistoryItem *replyTo) {
: 0;
}
MsgId LookupReplyToTop(not_null<History*> history, FullReplyTo replyTo) {
return replyTo.topicRootId
? replyTo.topicRootId
: LookupReplyToTop(
history,
LookupReplyTo(history, replyTo.messageId));
}
bool LookupReplyIsTopicPost(HistoryItem *replyTo) {
return replyTo
&& (replyTo->topicRootId() != Data::ForumTopic::kGeneralId);
@ -373,19 +382,27 @@ MTPMessageReplyHeader NewMessageReplyHeader(const Api::SendAction &action) {
const auto externalPeerId = (replyTo.messageId.peer == historyPeer)
? PeerId()
: replyTo.messageId.peer;
const auto to = LookupReplyTo(action.history, replyTo.messageId);
const auto replyToTop = LookupReplyToTop(action.history, to);
const auto replyToTop = LookupReplyToTop(action.history, replyTo);
auto quoteEntities = Api::EntitiesToMTP(
&action.history->session(),
replyTo.quote.entities,
Api::ConvertOption::SkipLocal);
return MTP_messageReplyHeader(
MTP_flags(Flag::f_reply_to_msg_id
| (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),
peerToMTP(externalPeerId),
MTPMessageFwdHeader(), // reply_from
MTPMessageMedia(), // reply_media
MTP_int(replyToTop), // reply_to_top_id
MTPstring(), // quote_text
MTPVector<MTPMessageEntity>()); // quote_entities
MTP_int(replyToTop),
MTP_string(replyTo.quote.text),
quoteEntities);
}
return MTPMessageReplyHeader();
}

View File

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

View File

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

View File

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

View File

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

View File

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

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