Generate correct links to replies section.

This commit is contained in:
John Preston 2020-09-22 18:28:49 +03:00
parent 889139f31f
commit 891b4a91a3
6 changed files with 92 additions and 18 deletions

View File

@ -683,17 +683,57 @@ void ApiWrap::finalizeMessageDataRequest(
} }
} }
QString ApiWrap::exportDirectMessageLink(not_null<HistoryItem*> item) { QString ApiWrap::exportDirectMessageLink(
not_null<HistoryItem*> item,
bool inRepliesContext) {
Expects(item->history()->peer->isChannel()); Expects(item->history()->peer->isChannel());
const auto itemId = item->fullId(); const auto itemId = item->fullId();
const auto channel = item->history()->peer->asChannel(); const auto channel = item->history()->peer->asChannel();
const auto fallback = [&] { const auto fallback = [&] {
const auto base = channel->hasUsername() auto linkChannel = channel;
? channel->username auto linkItemId = item->id;
: "c/" + QString::number(channel->bareId()); auto linkCommentId = 0;
const auto query = base + '/' + QString::number(item->id); auto linkThreadId = 0;
if (channel->hasUsername() && !channel->isMegagroup()) { if (inRepliesContext) {
if (const auto rootId = item->replyToTop()) {
const auto root = item->history()->owner().message(
channel->bareId(),
rootId);
const auto sender = root
? root->discussionPostOriginalSender()
: nullptr;
if (sender && sender->hasUsername()) {
// Comment to a public channel.
const auto forwarded = root->Get<HistoryMessageForwarded>();
linkItemId = forwarded->savedFromMsgId;
if (linkItemId) {
linkChannel = sender;
linkCommentId = item->id;
} else {
linkItemId = item->id;
}
} else {
// Reply in a thread, maybe comment in a private channel.
linkThreadId = rootId;
}
}
}
const auto base = linkChannel->hasUsername()
? linkChannel->username
: "c/" + QString::number(linkChannel->bareId());
const auto query = base
+ '/'
+ QString::number(linkItemId)
+ (linkCommentId
? "?comment=" + QString::number(linkCommentId)
: linkThreadId
? "?thread=" + QString::number(linkThreadId)
: "");
if (linkChannel->hasUsername()
&& !linkChannel->isMegagroup()
&& !linkCommentId
&& !linkThreadId) {
if (const auto media = item->media()) { if (const auto media = item->media()) {
if (const auto document = media->document()) { if (const auto document = media->document()) {
if (document->isVideoMessage()) { if (document->isVideoMessage()) {
@ -709,7 +749,9 @@ QString ApiWrap::exportDirectMessageLink(not_null<HistoryItem*> item) {
? i->second ? i->second
: fallback(); : fallback();
request(MTPchannels_ExportMessageLink( request(MTPchannels_ExportMessageLink(
MTP_flags(0), MTP_flags(inRepliesContext
? MTPchannels_ExportMessageLink::Flag::f_thread
: MTPchannels_ExportMessageLink::Flag(0)),
channel->inputChannel, channel->inputChannel,
MTP_int(item->id) MTP_int(item->id)
)).done([=](const MTPExportedMessageLink &result) { )).done([=](const MTPExportedMessageLink &result) {

View File

@ -172,7 +172,9 @@ public:
ChannelData *channel, ChannelData *channel,
MsgId msgId, MsgId msgId,
RequestMessageDataCallback callback); RequestMessageDataCallback callback);
QString exportDirectMessageLink(not_null<HistoryItem*> item); QString exportDirectMessageLink(
not_null<HistoryItem*> item,
bool inRepliesContext);
void requestContacts(); void requestContacts();
void requestDialogs(Data::Folder *folder = nullptr); void requestDialogs(Data::Folder *folder = nullptr);

View File

@ -1647,7 +1647,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
} }
if (item && item->hasDirectLink() && isUponSelected != 2 && isUponSelected != -2) { if (item && item->hasDirectLink() && isUponSelected != 2 && isUponSelected != -2) {
_menu->addAction(item->history()->peer->isMegagroup() ? tr::lng_context_copy_link(tr::now) : tr::lng_context_copy_post_link(tr::now), [=] { _menu->addAction(item->history()->peer->isMegagroup() ? tr::lng_context_copy_link(tr::now) : tr::lng_context_copy_post_link(tr::now), [=] {
HistoryView::CopyPostLink(session, itemId); HistoryView::CopyPostLink(session, itemId, HistoryView::Context::History);
}); });
} }
if (isUponSelected > 1) { if (isUponSelected > 1) {
@ -1792,7 +1792,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
}); });
} else if (item && item->hasDirectLink() && isUponSelected != 2 && isUponSelected != -2) { } else if (item && item->hasDirectLink() && isUponSelected != 2 && isUponSelected != -2) {
_menu->addAction(item->history()->peer->isMegagroup() ? tr::lng_context_copy_link(tr::now) : tr::lng_context_copy_post_link(tr::now), [=] { _menu->addAction(item->history()->peer->isMegagroup() ? tr::lng_context_copy_link(tr::now) : tr::lng_context_copy_post_link(tr::now), [=] {
HistoryView::CopyPostLink(session, itemId); HistoryView::CopyPostLink(session, itemId, HistoryView::Context::History);
}); });
} }
if (isUponSelected > 1) { if (isUponSelected > 1) {

View File

@ -218,7 +218,10 @@ void FastShareMessage(not_null<HistoryItem*> item) {
auto copyCallback = [=]() { auto copyCallback = [=]() {
if (const auto item = owner->message(data->msgIds[0])) { if (const auto item = owner->message(data->msgIds[0])) {
if (item->hasDirectLink()) { if (item->hasDirectLink()) {
HistoryView::CopyPostLink(session, item->fullId()); HistoryView::CopyPostLink(
session,
item->fullId(),
HistoryView::Context::History);
} else if (const auto bot = item->getMessageBot()) { } else if (const auto bot = item->getMessageBot()) {
if (const auto media = item->media()) { if (const auto media = item->media()) {
if (const auto game = media->game()) { if (const auto game = media->game()) {

View File

@ -254,11 +254,14 @@ void AddPostLinkAction(
} }
const auto session = &item->history()->session(); const auto session = &item->history()->session();
const auto itemId = item->fullId(); const auto itemId = item->fullId();
const auto context = request.view
? request.view->context()
: Context::History;
menu->addAction( menu->addAction(
(item->history()->peer->isMegagroup() (item->history()->peer->isMegagroup()
? tr::lng_context_copy_link ? tr::lng_context_copy_link
: tr::lng_context_copy_post_link)(tr::now), : tr::lng_context_copy_post_link)(tr::now),
[=] { CopyPostLink(session, itemId); }); [=] { CopyPostLink(session, itemId, context); });
} }
MessageIdsList ExtractIdsList(const SelectedItems &items) { MessageIdsList ExtractIdsList(const SelectedItems &items) {
@ -774,18 +777,38 @@ base::unique_qptr<Ui::PopupMenu> FillContextMenu(
return result; return result;
} }
void CopyPostLink(not_null<Main::Session*> session, FullMsgId itemId) { void CopyPostLink(
not_null<Main::Session*> session,
FullMsgId itemId,
Context context) {
const auto item = session->data().message(itemId); const auto item = session->data().message(itemId);
if (!item || !item->hasDirectLink()) { if (!item || !item->hasDirectLink()) {
return; return;
} }
const auto inRepliesContext = (context == Context::Replies);
QGuiApplication::clipboard()->setText( QGuiApplication::clipboard()->setText(
item->history()->session().api().exportDirectMessageLink(item)); item->history()->session().api().exportDirectMessageLink(
item,
inRepliesContext));
const auto isPublicLink = [&] {
const auto channel = item->history()->peer->asChannel(); const auto channel = item->history()->peer->asChannel();
Assert(channel != nullptr); Assert(channel != nullptr);
if (const auto rootId = item->replyToTop()) {
const auto root = item->history()->owner().message(
channel->bareId(),
rootId);
const auto sender = root
? root->discussionPostOriginalSender()
: nullptr;
if (sender && sender->hasUsername()) {
return true;
}
}
return channel->hasUsername();
}();
Ui::Toast::Show(channel->hasUsername() Ui::Toast::Show(isPublicLink
? tr::lng_channel_public_link_copied(tr::now) ? tr::lng_channel_public_link_copied(tr::now)
: tr::lng_context_about_private_link(tr::now)); : tr::lng_context_about_private_link(tr::now));
} }

View File

@ -19,6 +19,7 @@ class SessionNavigation;
namespace HistoryView { namespace HistoryView {
enum class Context : char;
enum class PointState : char; enum class PointState : char;
class ListWidget; class ListWidget;
class Element; class Element;
@ -43,7 +44,10 @@ base::unique_qptr<Ui::PopupMenu> FillContextMenu(
not_null<ListWidget*> list, not_null<ListWidget*> list,
const ContextMenuRequest &request); const ContextMenuRequest &request);
void CopyPostLink(not_null<Main::Session*> session, FullMsgId itemId); void CopyPostLink(
not_null<Main::Session*> session,
FullMsgId itemId,
Context context);
void StopPoll(not_null<Main::Session*> session, FullMsgId itemId); void StopPoll(not_null<Main::Session*> session, FullMsgId itemId);
} // namespace } // namespace