From 5deee18247be95b2d53f8c3e2ecb7608495c4535 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 5 Apr 2019 15:50:16 +0400 Subject: [PATCH] Use channels.exportMessageLink to check links. --- Telegram/SourceFiles/apiwrap.cpp | 44 ++++++++++++++++++- Telegram/SourceFiles/apiwrap.h | 5 ++- Telegram/SourceFiles/history/history_item.cpp | 23 ---------- Telegram/SourceFiles/history/history_item.h | 1 - .../view/history_view_context_menu.cpp | 34 +++++++++----- 5 files changed, 68 insertions(+), 39 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 4db98063d..32e2e08e3 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -615,6 +615,46 @@ void ApiWrap::finalizeMessageDataRequest( } } +QString ApiWrap::exportDirectMessageLink(not_null item) { + Expects(item->history()->peer->isChannel()); + + const auto itemId = item->fullId(); + const auto channel = item->history()->peer->asChannel(); + const auto fallback = [&] { + const auto base = channel->isPublic() + ? channel->username + : "c/" + QString::number(channel->bareId()); + const auto query = base + '/' + QString::number(item->id); + if (channel->isPublic() && !channel->isMegagroup()) { + if (const auto media = item->media()) { + if (const auto document = media->document()) { + if (document->isVideoMessage()) { + return qsl("https://telesco.pe/") + query; + } + } + } + } + return Core::App().createInternalLinkFull(query); + }; + const auto i = _unlikelyMessageLinks.find(itemId); + const auto current = (i != end(_unlikelyMessageLinks)) + ? i->second + : fallback(); + request(MTPchannels_ExportMessageLink( + channel->inputChannel, + MTP_int(item->id), + MTP_bool(false) + )).done([=](const MTPExportedMessageLink &result) { + const auto link = result.match([&](const auto &data) { + return qs(data.vlink); + }); + if (current != link) { + _unlikelyMessageLinks.emplace_or_assign(itemId, link); + } + }).send(); + return current; +} + void ApiWrap::requestContacts() { if (_session->data().contactsLoaded().value() || _contactsRequestId) { return; @@ -5711,11 +5751,11 @@ void ApiWrap::sendPollVotes( _pollVotesRequestIds.emplace(itemId, requestId); } -void ApiWrap::closePoll(FullMsgId itemId) { +void ApiWrap::closePoll(not_null item) { + const auto itemId = item->fullId(); if (_pollCloseRequestIds.contains(itemId)) { return; } - const auto item = App::histItemById(itemId); const auto media = item ? item->media() : nullptr; const auto poll = media ? media->poll() : nullptr; if (!poll) { diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 637ade3ad..b1d4f32ef 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -76,6 +76,7 @@ public: ChannelData *channel, MsgId msgId, RequestMessageDataCallback callback); + QString exportDirectMessageLink(not_null item); void requestContacts(); void requestDialogEntry(not_null feed); @@ -427,7 +428,7 @@ public: void sendPollVotes( FullMsgId itemId, const std::vector &options); - void closePoll(FullMsgId itemId); + void closePoll(not_null item); void reloadPollResults(not_null item); ~ApiWrap(); @@ -822,4 +823,6 @@ private: mtpRequestId _attachedStickerSetsRequestId = 0; + base::flat_map _unlikelyMessageLinks; + }; diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index dda1d51c4..a58e52fae 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -552,29 +552,6 @@ bool HistoryItem::hasDirectLink() const { return IsServerMsgId(id) && _history->peer->isChannel(); } -QString HistoryItem::directLink() const { - if (hasDirectLink()) { - const auto channel = _history->peer->asChannel(); - Assert(channel != nullptr); - - const auto base = channel->isPublic() - ? channel->username - : "c/" + QString::number(channel->bareId()); - const auto query = base + '/' + QString::number(id); - if (channel->isPublic() && !channel->isMegagroup()) { - if (const auto media = this->media()) { - if (const auto document = media->document()) { - if (document->isVideoMessage()) { - return qsl("https://telesco.pe/") + query; - } - } - } - } - return Core::App().createInternalLinkFull(query); - } - return QString(); -} - ChannelId HistoryItem::channelId() const { return _history->channelId(); } diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index a006a6f8b..3566382ac 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -254,7 +254,6 @@ public: bool suggestDeleteAllReport() const; bool hasDirectLink() const; - QString directLink() const; MsgId id; diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp index bbb597d85..4fe79cf2a 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp @@ -38,6 +38,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace HistoryView { namespace { +// If we can't cloud-export link for such time we export it locally. +constexpr auto kExportLocalTimeout = crl::time(1000); + void AddToggleGroupingAction( not_null menu, not_null peer) { @@ -506,26 +509,33 @@ base::unique_qptr FillContextMenu( } void CopyPostLink(FullMsgId itemId) { - if (const auto item = App::histItemById(itemId)) { - if (item->hasDirectLink()) { - QApplication::clipboard()->setText(item->directLink()); - - const auto channel = item->history()->peer->asChannel(); - Assert(channel != nullptr); - - Ui::Toast::Show(lang(channel->isPublic() - ? lng_channel_public_link_copied - : lng_context_about_private_link)); - } + const auto item = App::histItemById(itemId); + if (!item || !item->hasDirectLink()) { + return; } + QApplication::clipboard()->setText( + item->history()->session().api().exportDirectMessageLink(item)); + + const auto channel = item->history()->peer->asChannel(); + Assert(channel != nullptr); + + Ui::Toast::Show(lang(channel->isPublic() + ? lng_channel_public_link_copied + : lng_context_about_private_link)); } void StopPoll(FullMsgId itemId) { + const auto stop = [=] { + Ui::hideLayer(); + if (const auto item = App::histItemById(itemId)) { + item->history()->session().api().closePoll(item); + } + }; Ui::show(Box( lang(lng_polls_stop_warning), lang(lng_polls_stop_sure), lang(lng_cancel), - [=] { Ui::hideLayer(); Auth().api().closePoll(itemId); })); + stop)); } } // namespace HistoryView