From 73470c3a95fa40082f81bbd100a987816ff764b7 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Apr 2019 13:33:41 +0400 Subject: [PATCH] Handle private channel post links. --- Telegram/Resources/langs/lang.strings | 1 + .../SourceFiles/core/click_handler_types.cpp | 2 + .../SourceFiles/core/local_url_handlers.cpp | 58 ++++++++++++++++++- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index edbf31f2a..04b995c43 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -141,6 +141,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_error_cant_ban_admin" = "Sorry, you can't ban this user because they are an admin in this group and you are not allowed to demote them."; "lng_error_admin_limit" = "Sorry, you've reached the maximum number of admins for this group."; "lng_error_admin_limit_channel" = "Sorry, you've reached the maximum number of admins for this channel."; +"lng_error_post_link_invalid" = "Unfortunately, you can't access this message. You are not a member of the chat where it was posted."; "lng_sure_add_admin_invite" = "This user is not a member of this group. Add them to the group and promote them to admin?"; "lng_sure_add_admin_invite_channel" = "This user is not a subscriber of this channel. Add them to the channel and promote them to admin?"; "lng_sure_add_admin_unremove" = "This user is currently restricted or removed. Are you sure you want to promote them?"; diff --git a/Telegram/SourceFiles/core/click_handler_types.cpp b/Telegram/SourceFiles/core/click_handler_types.cpp index a0ed5aca1..d5175165c 100644 --- a/Telegram/SourceFiles/core/click_handler_types.cpp +++ b/Telegram/SourceFiles/core/click_handler_types.cpp @@ -64,6 +64,8 @@ QString tryConvertUrlToLocal(QString url) { } else if (auto bgMatch = regex_match(qsl("^bg/([a-zA-Z0-9\\.\\_\\-]+)(\\?(.+)?)?$"), query, matchOptions)) { const auto params = bgMatch->captured(3); return qsl("tg://bg?slug=") + bgMatch->captured(1) + (params.isEmpty() ? QString() : '&' + params); + } else if (auto postMatch = regex_match(qsl("^c/(\\-?\\d+)/(\\d+)(#|$)"), query, matchOptions)) { + return qsl("tg://privatepost?channel=%1&post=%2").arg(postMatch->captured(1)).arg(postMatch->captured(2)); } else if (auto usernameMatch = regex_match(qsl("^([a-zA-Z0-9\\.\\_]+)(/?\\?|/?$|/(\\d+)/?(?:\\?|$))"), query, matchOptions)) { auto params = query.mid(usernameMatch->captured(0).size()).toString(); auto postParam = QString(); diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp index eb6aa0dfc..d2ccbbc4a 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.cpp +++ b/Telegram/SourceFiles/core/local_url_handlers.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_cloud_manager.h" #include "lang/lang_keys.h" #include "core/update_checker.h" +#include "core/application.h" #include "boxes/confirm_phone_box.h" #include "boxes/background_preview_box.h" #include "boxes/confirm_box.h" @@ -21,9 +22,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "passport/passport_form_controller.h" #include "window/window_controller.h" #include "data/data_session.h" +#include "data/data_channel.h" #include "mainwindow.h" #include "mainwidget.h" -#include "core/application.h" #include "auth_session.h" #include "apiwrap.h" @@ -205,12 +206,14 @@ bool ResolveUsername(const Match &match, const QVariant &context) { start = QString(); } } - auto post = (start == qsl("startgroup")) ? ShowAtProfileMsgId : ShowAtUnreadMsgId; + auto post = (start == qsl("startgroup")) + ? ShowAtProfileMsgId + : ShowAtUnreadMsgId; auto postParam = params.value(qsl("post")); if (auto postId = postParam.toInt()) { post = postId; } - auto gameParam = params.value(qsl("game")); + const auto gameParam = params.value(qsl("game")); if (!gameParam.isEmpty() && valid(gameParam)) { startToken = gameParam; post = ShowAtGameShareMsgId; @@ -224,6 +227,51 @@ bool ResolveUsername(const Match &match, const QVariant &context) { return true; } +bool ResolvePrivatePost(const Match &match, const QVariant &context) { + if (!AuthSession::Exists()) { + return false; + } + const auto params = url_parse_params( + match->captured(1), + qthelp::UrlParamNameTransform::ToLower); + const auto channelId = params.value(qsl("channel")).toInt(); + const auto msgId = params.value(qsl("post")).toInt(); + if (!channelId || !IsServerMsgId(msgId)) { + return false; + } + const auto done = [=](not_null peer) { + App::wnd()->controller()->showPeerHistory( + peer->id, + Window::SectionShow::Way::Forward, + msgId); + }; + const auto fail = [=] { + Ui::show(Box(lang(lng_error_post_link_invalid))); + }; + const auto auth = &Auth(); + if (const auto channel = auth->data().channelLoaded(channelId)) { + done(channel); + return true; + } + auth->api().request(MTPchannels_GetChannels( + MTP_vector( + 1, + MTP_inputChannel(MTP_int(channelId), MTP_long(0))) + )).done([=](const MTPmessages_Chats &result) { + result.match([&](const auto &data) { + const auto peer = auth->data().processChats(data.vchats); + if (peer && peer->id == peerFromChannel(channelId)) { + done(peer); + } else { + fail(); + } + }); + }).fail([=](const RPCError &error) { + fail(); + }).send(); + return true; +} + bool HandleUnknown(const Match &match, const QVariant &context) { if (!AuthSession::Exists()) { return false; @@ -302,6 +350,10 @@ const std::vector &LocalUrlHandlers() { qsl("^resolve/?\\?(.+)(#|$)"), ResolveUsername }, + { + qsl("^privatepost/?\\?(.+)(#|$)"), + ResolvePrivatePost + }, { qsl("^([^\\?]+)(\\?|#|$)"), HandleUnknown